Skip to content

Commit bdc2672

Browse files
committed
Fixing implementation and tests
1 parent 61d0a21 commit bdc2672

8 files changed

Lines changed: 178 additions & 183 deletions

File tree

controller-core/src/commonMain/kotlin/io/exoquery/controller/DecoderAny.kt

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package io.exoquery.controller
22

3+
import kotlin.jvm.JvmInline
34
import kotlin.reflect.KClass
45

56
open class DecoderAny<T: Any, Session, Row> @PublishedApi internal constructor(
@@ -45,11 +46,14 @@ open class DecoderAny<T: Any, Session, Row> @PublishedApi internal constructor(
4546
* Transforms this decoder into another decoder by applying the given function to the decoded value.
4647
* Alias for [map].
4748
*/
48-
inline fun <reified R: Any> transformInto(crossinline into: (T) -> R): DecoderAny<R, Session, Row> =
49+
inline fun <reified R: Any> transformInto(crossinline into: MapContext<Session, Row>.(T) -> R): DecoderAny<R, Session, Row> =
4950
map(into)
5051

51-
inline fun <reified R: Any> map(crossinline into: (T) -> R): DecoderAny<R, Session, Row> =
52-
DecoderAny<R, Session, Row>(R::class, this@DecoderAny.originalType, isNull) { ctx, index -> into(this.decode(ctx, index)) }
52+
@JvmInline
53+
final value class MapContext<Session, Row>(val ctx: DecodingContext<Session, Row>)
54+
55+
inline fun <reified R: Any> map(crossinline into: MapContext<Session, Row>.(T) -> R): DecoderAny<R, Session, Row> =
56+
DecoderAny<R, Session, Row>(R::class, this@DecoderAny.originalType, isNull) { ctx, index -> into(MapContext(ctx), this.decode(ctx, index)) }
5357

5458
override fun asNullable(): SqlDecoder<Session, Row, T?> =
5559
object: SqlDecoder<Session, Row, T?>() {

controller-core/src/commonMain/kotlin/io/exoquery/controller/EncoderAny.kt

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package io.exoquery.controller
22

3+
import kotlin.jvm.JvmInline
34
import kotlin.reflect.KClass
45

56
open class EncoderAny<T: Any, TypeId: Any, Session, Stmt> @PublishedApi internal constructor(
@@ -47,9 +48,12 @@ open class EncoderAny<T: Any, TypeId: Any, Session, Stmt> @PublishedApi internal
4748
* Transforms this encoder into another encoder by applying the given function to the value before encoding it.
4849
* Alias for [contramap].
4950
*/
50-
inline fun <reified R: Any> transformFrom(crossinline from: (R) -> T): EncoderAny<R, TypeId, Session, Stmt> =
51+
inline fun <reified R: Any> transformFrom(crossinline from: ContrmapContext<Session, Stmt>.(R) -> T): EncoderAny<R, TypeId, Session, Stmt> =
5152
contramap(from)
5253

53-
inline fun <reified R: Any> contramap(crossinline from: (R) -> T): EncoderAny<R, TypeId, Session, Stmt> =
54-
EncoderAny<R, TypeId, Session, Stmt>(this@EncoderAny.dataType, R::class, this@EncoderAny.originalType, this@EncoderAny.setNull) { ctx, value, i -> this.f(ctx, from(value), i) }
54+
@JvmInline
55+
final value class ContrmapContext<Session, Stmt>(val ctx: EncodingContext<Session, Stmt>)
56+
57+
inline fun <reified R: Any> contramap(crossinline from: ContrmapContext<Session, Stmt>.(R) -> T): EncoderAny<R, TypeId, Session, Stmt> =
58+
EncoderAny<R, TypeId, Session, Stmt>(this@EncoderAny.dataType, R::class, this@EncoderAny.originalType, this@EncoderAny.setNull) { ctx, value, i -> this.f(ctx, from(ContrmapContext(ctx), value), i) }
5559
}

controller-jdbc/src/main/kotlin/io/exoquery/controller/jdbc/JdbcControllers.kt

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import io.exoquery.controller.JavaTimeEncoding
55
import io.exoquery.controller.JavaUuidEncoding
66
import io.exoquery.controller.*
77
import kotlinx.coroutines.flow.Flow
8+
import kotlinx.datetime.toJavaZoneId
89
import java.sql.Connection
910
import java.sql.PreparedStatement
1011
import java.sql.ResultSet
@@ -197,9 +198,22 @@ object JdbcControllers {
197198
override val encodingApi: JdbcSqlEncoding =
198199
object : JavaSqlEncoding<Connection, PreparedStatement, ResultSet>,
199200
BasicEncoding<Connection, PreparedStatement, ResultSet> by JdbcBasicEncoding,
200-
JavaTimeEncoding<Connection, PreparedStatement, ResultSet> by JdbcTimeEncoding(),
201+
JavaTimeEncoding<Connection, PreparedStatement, ResultSet> by SqlServerTimeEncoding,
201202
JavaUuidEncoding<Connection, PreparedStatement, ResultSet> by JdbcUuidStringEncoding {}
202203

204+
object SqlServerTimeEncoding: JdbcTimeEncoding() {
205+
// Override java.util.Date encoding to use TIMESTAMP_WITH_TIMEZONE for DATETIMEOFFSET columns
206+
override val JDateEncoder: JdbcEncoderAny<java.util.Date> = JdbcEncoderAny(Types.TIMESTAMP_WITH_TIMEZONE, java.util.Date::class) { ctx, v, i ->
207+
val instant = v.toInstant()
208+
val offsetDateTime = java.time.OffsetDateTime.ofInstant(instant, ctx.timeZone.toJavaZoneId())
209+
ctx.stmt.setObject(i, offsetDateTime, Types.TIMESTAMP_WITH_TIMEZONE)
210+
}
211+
override val JDateDecoder: JdbcDecoderAny<java.util.Date> = JdbcDecoderAny(java.util.Date::class) { ctx, i ->
212+
val offsetDateTime = ctx.row.getObject(i, java.time.OffsetDateTime::class.java)
213+
java.util.Date.from(offsetDateTime.toInstant())
214+
}
215+
}
216+
203217
override suspend fun <T> runActionReturningScoped(act: ControllerActionReturning<T>, options: JdbcExecutionOptions): Flow<T> =
204218
flowWithConnection(options) {
205219
val conn = localConnection()

controller-r2dbc/src/main/kotlin/io/exoquery/controller/r2dbc/R2dbcDecoders.kt

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@ import io.r2dbc.spi.Connection
66
import io.r2dbc.spi.Row
77
import kotlin.reflect.KClass
88

9+
typealias R2dbcDecoder<T> = DecoderAny<T, Connection, Row>
10+
911
class R2dbcDecoderAny<T: Any>(
1012
override val type: KClass<T>,
1113
override val f: (R2dbcDecodingContext, Int) -> T?
@@ -21,7 +23,7 @@ class R2dbcDecoderAny<T: Any>(
2123

2224
object R2dbcDecoders {
2325
@Suppress("UNCHECKED_CAST")
24-
val decoders: Set<SqlDecoder<Connection, Row, out Any>> = setOf(
26+
val decoders: Set<R2dbcDecoder<out Any>> = setOf(
2527
R2dbcBasicEncoding.BooleanDecoder,
2628
R2dbcBasicEncoding.ByteDecoder,
2729
R2dbcBasicEncoding.CharDecoder,

0 commit comments

Comments
 (0)