Skip to content

Commit 964f95d

Browse files
committed
Introduce encoders() method in Connection for retrieving ValueEncoderRegistry. Enhance PooledConnection with overridden SQL execution methods, connection status management, and lifecycle consistency. Update tests to validate connection release behavior.
1 parent 90beae3 commit 964f95d

File tree

4 files changed

+51
-6
lines changed

4 files changed

+51
-6
lines changed

sqlx4k-sqlite/src/jvmMain/kotlin/io/github/smyrgeorge/sqlx4k/sqlite/SQLite.kt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -176,6 +176,8 @@ class SQLite(
176176
}
177177
}
178178
}
179+
180+
override fun encoders(): Statement.ValueEncoderRegistry = encoders
179181
}
180182

181183
/**

sqlx4k/src/commonMain/kotlin/io/github/smyrgeorge/sqlx4k/Connection.kt

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,15 @@ interface Connection : QueryExecutor, QueryExecutor.Transactional {
3737
*/
3838
suspend fun close(): Result<Unit>
3939

40+
/**
41+
* Retrieves the `ValueEncoderRegistry` associated with the current connection.
42+
* The `ValueEncoderRegistry` provides access to registered value encoders, which
43+
* are responsible for converting types into formats suitable for use in SQL statements.
44+
*
45+
* @return A `ValueEncoderRegistry` instance that manages the encoders for this connection.
46+
*/
47+
fun encoders(): Statement.ValueEncoderRegistry = Statement.ValueEncoderRegistry.EMPTY
48+
4049
/**
4150
* Represents the operational state of a connection.
4251
*

sqlx4k/src/commonMain/kotlin/io/github/smyrgeorge/sqlx4k/impl/pool/PooledConnection.kt

Lines changed: 37 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,7 @@
22

33
package io.github.smyrgeorge.sqlx4k.impl.pool
44

5-
import io.github.smyrgeorge.sqlx4k.Connection
6-
import io.github.smyrgeorge.sqlx4k.SQLError
5+
import io.github.smyrgeorge.sqlx4k.*
76
import kotlinx.coroutines.sync.Mutex
87
import kotlinx.coroutines.sync.withLock
98
import kotlin.concurrent.atomics.ExperimentalAtomicApi
@@ -15,13 +14,15 @@ import kotlin.time.TimeSource
1514
class PooledConnection(
1615
private val connection: Connection,
1716
private val pool: ConnectionPoolImpl
18-
) : Connection by connection {
17+
) : Connection {
1918
private val mutex = Mutex()
2019
private var acquired = true
2120
private val released get() = !acquired
2221
private val createdAt: TimeMark = TIME_SOURCE.markNow()
2322
private var lastUsedAt: TimeMark = createdAt
2423

24+
override var status: Connection.Status = Connection.Status.Open
25+
2526
fun isReleased(): Boolean = released
2627

2728
fun isExpired(): Boolean {
@@ -39,15 +40,18 @@ class PooledConnection(
3940

4041
acquired = true
4142
lastUsedAt = TIME_SOURCE.markNow()
43+
status = Connection.Status.Open
4244
}
4345
return this
4446
}
4547

4648
override suspend fun close(): Result<Unit> = runCatching {
4749
mutex.withLock {
50+
assertIsOpen()
4851
if (released) return@runCatching
4952
acquired = false
5053
lastUsedAt = TIME_SOURCE.markNow()
54+
status = Connection.Status.Closed
5155
}
5256

5357
if (pool.closed.load()) {
@@ -101,6 +105,36 @@ class PooledConnection(
101105
}
102106
}
103107

108+
override suspend fun execute(sql: String): Result<Long> = runCatching {
109+
mutex.withLock {
110+
assertIsOpen()
111+
return connection.execute(sql)
112+
}
113+
}
114+
115+
override suspend fun execute(statement: Statement): Result<Long> =
116+
execute(statement.render(connection.encoders()))
117+
118+
override suspend fun fetchAll(sql: String): Result<ResultSet> = runCatching {
119+
return mutex.withLock {
120+
assertIsOpen()
121+
connection.fetchAll(sql)
122+
}
123+
}
124+
125+
override suspend fun fetchAll(statement: Statement): Result<ResultSet> =
126+
fetchAll(statement.render(connection.encoders()))
127+
128+
override suspend fun <T> fetchAll(statement: Statement, rowMapper: RowMapper<T>): Result<List<T>> =
129+
fetchAll(statement.render(connection.encoders()), rowMapper)
130+
131+
override suspend fun begin(): Result<Transaction> = runCatching {
132+
mutex.withLock {
133+
assertIsOpen()
134+
return connection.begin()
135+
}
136+
}
137+
104138
companion object {
105139
private val TIME_SOURCE = TimeSource.Monotonic
106140
}

sqlx4k/src/commonTest/kotlin/io/github/smyrgeorge/sqlx4k/impl/pool/ConnectionPoolErrorHandlingTests.kt

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import io.github.smyrgeorge.sqlx4k.impl.pool.util.FakeConnection
1010
import kotlinx.coroutines.delay
1111
import kotlinx.coroutines.runBlocking
1212
import kotlin.test.Test
13+
import kotlin.test.assertFails
1314
import kotlin.test.assertFailsWith
1415
import kotlin.time.Duration
1516
import kotlin.time.Duration.Companion.milliseconds
@@ -55,13 +56,12 @@ class ConnectionPoolErrorHandlingTests {
5556
}
5657

5758
@Test
58-
fun `Multiple release calls on same connection are idempotent`() = runBlocking {
59+
fun `Multiple release calls on same connection should fail`() = runBlocking {
5960
val pool = newPool(max = 1)
6061

6162
val c = pool.acquire().getOrThrow()
6263
c.close().getOrThrow()
63-
c.close().getOrThrow() // Second release should be safe
64-
c.close().getOrThrow() // Third release should be safe
64+
assertFails { c.close().getOrThrow() }
6565

6666
assertThat(pool.poolIdleSize()).isEqualTo(1)
6767
assertThat(pool.poolSize()).isEqualTo(1)

0 commit comments

Comments
 (0)