Created
October 5, 2022 20:46
-
-
Save nhalase/244a89dadf1b57c33c3c2179c3a46d85 to your computer and use it in GitHub Desktop.
JSONB support (PostgreSQL)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import kotlinx.serialization.KSerializer | |
import kotlinx.serialization.json.Json | |
import kotlinx.serialization.serializer | |
import org.jetbrains.exposed.sql.Column | |
import org.jetbrains.exposed.sql.ColumnType | |
import org.jetbrains.exposed.sql.Table | |
import org.jetbrains.exposed.sql.statements.api.PreparedStatementApi | |
import org.postgresql.util.PGobject | |
inline fun <reified T : Any> Table.jsonb( | |
name: String, | |
kSerializer: KSerializer<T> = serializer(), | |
json: Json | |
): Column<T> = this.jsonb( | |
name = name, | |
stringify = { json.encodeToString(kSerializer, it) }, | |
parse = { json.decodeFromString(kSerializer, it) } | |
) | |
fun <T : Any> Table.jsonb(name: String, stringify: (T) -> String, parse: (String) -> T): Column<T> = | |
registerColumn(name, JsonbColumnType(stringify, parse)) | |
class JsonbColumnType<T : Any>(private val stringify: (T) -> String, private val parse: (String) -> T) : ColumnType() { | |
override fun setParameter(stmt: PreparedStatementApi, index: Int, value: Any?) { | |
val obj = PGobject() | |
obj.type = "jsonb" | |
if (value != null) { | |
obj.value = value as String | |
} | |
stmt[index] = obj | |
} | |
override fun sqlType(): String = "jsonb" | |
override fun valueFromDB(value: Any): Any { | |
return when (value) { | |
is PGobject -> parse(value.value ?: "") | |
is Map<*, *> -> value | |
is List<*> -> value | |
is Set<*> -> value | |
is Array<*> -> value | |
else -> { | |
println("unhandled value type: ${value::class}") | |
value | |
} | |
} | |
} | |
@Suppress("UNCHECKED_CAST") | |
override fun notNullValueToDB(value: Any) = stringify(value as T) | |
override fun valueToString(value: Any?): String = when (value) { | |
is Iterable<*> -> notNullValueToDB(value) | |
else -> super.valueToString(value) | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment