Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ interface ApiEncoders<Session, Stmt> {
val ShortEncoder: SqlEncoder<Session, Stmt, Short>
val StringEncoder: SqlEncoder<Session, Stmt, String>
val ByteArrayEncoder: SqlEncoder<Session, Stmt, ByteArray>
val EnumEncoder: SqlEncoder<Session, Stmt, String>
}
// Used by the RowDecoder
interface ApiDecoders<Session, Row> {
Expand All @@ -67,6 +68,7 @@ interface ApiDecoders<Session, Row> {
val ShortDecoder: SqlDecoder<Session, Row, Short>
val StringDecoder: SqlDecoder<Session, Row, String>
val ByteArrayDecoder: SqlDecoder<Session, Row, ByteArray>
val EnumDecoder: SqlDecoder<Session, Row, String>

abstract fun isNull(index: Int, row: Row): Boolean
abstract fun preview(index: Int, row: Row): String?
Expand Down Expand Up @@ -106,6 +108,7 @@ interface SqlEncoding<Session, Stmt, Row>:
ShortEncoder,
StringEncoder,
ByteArrayEncoder,
EnumEncoder,
LocalDateEncoder,
LocalDateTimeEncoder,
LocalTimeEncoder,
Expand All @@ -124,6 +127,7 @@ interface SqlEncoding<Session, Stmt, Row>:
ShortDecoder,
StringDecoder,
ByteArrayDecoder,
EnumDecoder,
LocalDateDecoder,
LocalDateTimeDecoder,
LocalTimeDecoder,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,8 +53,11 @@ class PreparedStatementElementEncoder<Session, Stmt>(
override fun encodeShort(value: Short) = api.ShortEncoder.encode(ctx, value, index)
override fun encodeString(value: String) = api.StringEncoder.encode(ctx, value, index)

override fun encodeEnum(enumDescriptor: SerialDescriptor, index: Int) =
TODO("Enum encoding not yet supported")
@Suppress("PARAMETER_NAME_CHANGED_ON_OVERRIDE") // Or they'd both be called `index`
@OptIn(ExperimentalSerializationApi::class)
override fun encodeEnum(enumDescriptor: SerialDescriptor, i: Int) =
api.EnumEncoder.encode(ctx, enumDescriptor.getElementName(i), index)


/**
* Since the assumption of this encoder is that it is created per every single value that needs to be inserted, we pass a serializer for that particular value
Expand Down Expand Up @@ -142,6 +145,8 @@ class PreparedStatementElementEncoder<Session, Stmt>(
// if it is a primitive type then use the encoder defined in the serialization. Note that
// if it is a wrappedType (e.g. NewTypeInt(value: Int) then this serializer will be the wrapped one
serializer.serialize(this, value)
} else if (desc.kind == SerialKind.ENUM) {
serializer.serialize(this, value)
}
else {
throw IllegalArgumentException("Unsupported serial-kind: ${desc.kind} for the value ${value} with the descriptor ${desc} could not be decoded as a Array, Contextual, or Primitive value")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -390,6 +390,13 @@ class RowDecoder<Session, Row> private constructor(
out
}

desc.kind == SerialKind.ENUM -> {
validNullOrElse(desc, index) {
val out = alternateDeserializer.deserialize(this)
out
}
}

else ->
throw IllegalArgumentException("Unsupported kind: `${desc.kind}` at (${ctx.startingIndex.description}) index: ${index} (info:${ctx.columnInfos?.get(index)})")
}
Expand Down Expand Up @@ -424,7 +431,22 @@ class RowDecoder<Session, Row> private constructor(
}

override fun decodeEnum(enumDescriptor: SerialDescriptor): Int {
TODO("Not yet implemented")
val stringValue = api.StringDecoder.decode(ctx, rowIndex)
nextRowIndex(enumDescriptor, rowIndex)

val enumIndex = (0 until enumDescriptor.elementsCount).firstOrNull { i ->
// This checks for any @SerialName annotation specified name on the enum value, otherwise matches the value's constant name.
enumDescriptor.getElementName(i) == stringValue
}

if (enumIndex == null) {
val enumValuesAsString = enumDescriptor.elementNames.joinToString(", ")
throw IllegalArgumentException(
"Unknown enum value '$stringValue' for ${enumDescriptor.serialName}. Valid values are: $enumValuesAsString"
)
}

return enumIndex
}


Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -157,6 +157,9 @@ object SqliteBasicEncoding: BasicEncoding<Unused, SqliteStatementWrapper, Sqlite
override val ByteArrayEncoder: SqliteEncoderAny<ByteArray> = SqliteEncoderAny(SqliteFieldType.TYPE_BLOB, ByteArray::class) { ctx, value, index -> ctx.stmt.bindBytes(index, value) }
override val ByteArrayDecoder: SqliteDecoderAny<ByteArray> = SqliteDecoderAny(ByteArray::class) { ctx, index -> ctx.row.getBytes(index) }

override val EnumEncoder: SqliteEncoderAny<String> = SqliteEncoderAny(SqliteFieldType.TYPE_TEXT, String::class) { ctx, value, index -> ctx.stmt.bindString(index, value) }
override val EnumDecoder: SqliteDecoderAny<String> = SqliteDecoderAny(String::class) { ctx, index -> ctx.row.getString(index) }

override fun preview(index: Int, row: SqliteCursorWrapper): String? = row.getString(index)
override fun isNull(index: Int, row: SqliteCursorWrapper): Boolean = row.isNull(index)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ open class JdbcBasicEncoding:
override val ShortEncoder: JdbcEncoderAny<Short> = JdbcEncoderAny(Types.SMALLINT, Short::class) { ctx, v, i -> ctx.stmt.setShort(i, v) }
override val StringEncoder: JdbcEncoderAny<String> = JdbcEncoderAny(Types.VARCHAR, String::class) { ctx, v, i -> ctx.stmt.setString(i, v) }
override val ByteArrayEncoder: JdbcEncoderAny<ByteArray> = JdbcEncoderAny(Types.VARBINARY, ByteArray::class) { ctx, v, i -> ctx.stmt.setBytes(i, v) }
override val EnumEncoder: JdbcEncoderAny<String> = JdbcEncoderAny(Types.OTHER, String::class) { ctx, v, i -> ctx.stmt.setObject(i, v) }


override fun preview(index: Int, row: ResultSet): String? = row.getObject(index)?.let { it.toString() }
Expand All @@ -62,6 +63,7 @@ open class JdbcBasicEncoding:
override val ShortDecoder: JdbcDecoderAny<Short> = JdbcDecoderAny(Short::class) { ctx, i -> ctx.row.getShort(i) }
override val StringDecoder: JdbcDecoderAny<String> = JdbcDecoderAny(String::class) { ctx, i -> ctx.row.getString(i) }
override val ByteArrayDecoder: JdbcDecoderAny<ByteArray> = JdbcDecoderAny(ByteArray::class) { ctx, i -> ctx.row.getBytes(i) }
override val EnumDecoder: JdbcDecoderAny<String> = JdbcDecoderAny(String::class) { ctx, i -> ctx.row.getString(i) }
}

object JsonObjectEncoding {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,8 @@ object R2dbcBasicEncodingOracle: R2dbcBasicEncodingBase() {
R2dbcDecoderAny(String::class) { ctx, i -> ctx.row.get(i, String::class.java) ?: "" }
override val ByteArrayDecoder: R2dbcDecoder<ByteArray> =
R2dbcDecoderAny(ByteArray::class) { ctx, i -> ctx.row.get(i, ByteArray::class.java) ?: byteArrayOf() }
override val EnumDecoder: R2dbcDecoder<String> =
R2dbcDecoderAny(String::class) { ctx, i -> ctx.row.get(i, String::class.java) ?: "" }

// More oracle crazy behavior that requires encoding booleans as ints
//override val BooleanEncoder: R2dbcEncoderAny<Boolean> =
Expand Down Expand Up @@ -148,6 +150,8 @@ abstract class R2dbcBasicEncodingBase: BasicEncoding<Connection, Statement, Row>
R2dbcEncoderAny(NA, String::class) { ctx, v, i -> ctx.stmt.bind(i, v) }
override val ByteArrayEncoder: R2dbcEncoderAny<ByteArray> =
R2dbcEncoderAny(NA, ByteArray::class) { ctx, v, i -> ctx.stmt.bind(i, v) }
override val EnumEncoder: R2dbcEncoderAny<String> =
R2dbcEncoderAny(NA, String::class) { ctx, v, i -> ctx.stmt.bind(i, v) }

override fun preview(index: Int, row: Row): String? =
row.get(index)?.let { it.toString() }
Expand All @@ -174,6 +178,8 @@ abstract class R2dbcBasicEncodingBase: BasicEncoding<Connection, Statement, Row>
R2dbcDecoderAny(String::class) { ctx, i -> ctx.row.get(i, String::class.java) }
override val ByteArrayDecoder: R2dbcDecoder<ByteArray> =
R2dbcDecoderAny(ByteArray::class) { ctx, i -> ctx.row.get(i, ByteArray::class.java) }
override val EnumDecoder: R2dbcDecoder<String> =
R2dbcDecoderAny(String::class) { ctx, i -> ctx.row.get(i, String::class.java) }
}

private fun kotlinx.datetime.TimeZone.toJava(): TimeZone = TimeZone.getTimeZone(this.toJavaZoneId())
Expand Down
Loading