From a1cf25db924d1a56ace2f6751e6ae58bee7cbf2a Mon Sep 17 00:00:00 2001 From: Dries Samyn <5557551+driessamyn@users.noreply.github.com> Date: Fri, 7 Mar 2025 08:44:40 +0000 Subject: [PATCH] Refactor: rename `query` as `queryAsFlow` to avoid confusion when using the API. --- .../DatasourceWithConnectionDbTest.kt | 8 ++--- .../net/samyn/kapper/coroutines/FlowTest.kt | 22 +++++++------- .../coroutines/DatasourceWithConnection.kt | 4 +-- .../coroutines/KapperKotlinFlowQueryFun.kt | 30 +++++++++---------- .../samyn/kapper/coroutines/FlowQueryTest.kt | 16 +++++----- 5 files changed, 40 insertions(+), 40 deletions(-) diff --git a/coroutines/src/integrationTest/kotlin/net/samyn/kapper/coroutines/DatasourceWithConnectionDbTest.kt b/coroutines/src/integrationTest/kotlin/net/samyn/kapper/coroutines/DatasourceWithConnectionDbTest.kt index 5eef211..a8268c9 100644 --- a/coroutines/src/integrationTest/kotlin/net/samyn/kapper/coroutines/DatasourceWithConnectionDbTest.kt +++ b/coroutines/src/integrationTest/kotlin/net/samyn/kapper/coroutines/DatasourceWithConnectionDbTest.kt @@ -24,7 +24,7 @@ class DatasourceWithConnectionDbTest { @Test fun `slow query on IO dispatcher`() { // this is a bit of a naughty test as it includes a sleep, - // but wanted to validate this against a real JDBC driver and a real slow query. + // but wanted to validate this against a real JDBC driver and a real slow queryAsFlow. runBlocking { val dataSource = createDataSource(postgresql) var slept = false @@ -32,7 +32,7 @@ class DatasourceWithConnectionDbTest { launch { val int = dataSource.withConnection { connection -> - println("Executing slow query - $connection") + println("Executing slow queryAsFlow - $connection") connection.querySingle( "SELECT 1, pg_sleep(1)", { rs, _ -> rs.getInt(1) }, @@ -51,7 +51,7 @@ class DatasourceWithConnectionDbTest { @Test fun `execute tx on IO dispatcher`() { // this is a bit of a naughty test as it includes a sleep, - // but wanted to validate this against a real JDBC driver and a real slow query. + // but wanted to validate this against a real JDBC driver and a real slow queryAsFlow. runBlocking { val dataSource = createDataSource(postgresql) val insertJob = @@ -82,7 +82,7 @@ class DatasourceWithConnectionDbTest { @Test fun `execute failed tx on IO dispatcher`() { // this is a bit of a naughty test as it includes a sleep, - // but wanted to validate this against a real JDBC driver and a real slow query. + // but wanted to validate this against a real JDBC driver and a real slow queryAsFlow. runBlocking { val dataSource = createDataSource(postgresql) val queryJob = diff --git a/coroutines/src/integrationTest/kotlin/net/samyn/kapper/coroutines/FlowTest.kt b/coroutines/src/integrationTest/kotlin/net/samyn/kapper/coroutines/FlowTest.kt index 8518e8b..460c56a 100644 --- a/coroutines/src/integrationTest/kotlin/net/samyn/kapper/coroutines/FlowTest.kt +++ b/coroutines/src/integrationTest/kotlin/net/samyn/kapper/coroutines/FlowTest.kt @@ -72,9 +72,9 @@ class FlowTest { createDataSource(postgresql).withConnection { connection -> val one = async { - printGreen("Executing query - $connection, filtering even ages") + printGreen("Executing queryAsFlow - $connection, filtering even ages") connection - .query( + .queryAsFlow( "SELECT * FROM super_heroes", ) .filter { @@ -86,9 +86,9 @@ class FlowTest { } val two = async { - printRed("Executing query - $connection, filtering odd ages") + printRed("Executing queryAsFlow - $connection, filtering odd ages") connection - .query( + .queryAsFlow( "SELECT * FROM super_heroes", ) .filter { @@ -131,9 +131,9 @@ class FlowTest { createDataSource(postgresql).withConnection { connection -> val one = async { - printGreen("Executing query - $connection, filtering even ages") + printGreen("Executing queryAsFlow - $connection, filtering even ages") connection - .query( + .queryAsFlow( "SELECT * FROM super_heroes", ) .filter { @@ -153,9 +153,9 @@ class FlowTest { } val two = async { - printRed("Executing query - $connection, filtering odd ages") + printRed("Executing queryAsFlow - $connection, filtering odd ages") connection - .query( + .queryAsFlow( "SELECT * FROM super_heroes", ) .filter { @@ -196,9 +196,9 @@ class FlowTest { createDataSource(postgresql).withConnection { connection -> val job = async { - println("Executing query - $connection, exit when age 20 is exceeded") + println("Executing queryAsFlow - $connection, exit when age 20 is exceeded") connection - .query( + .queryAsFlow( "SELECT * FROM super_heroes", ) .map { @@ -209,7 +209,7 @@ class FlowTest { printGreen("[${Thread.currentThread().name}] acc=$a") a.also { if (a > 20) { - println("Cancelling query as cumulative age is $a") + println("Cancelling queryAsFlow as cumulative age is $a") cancel("Cumulative age exceeded 20") } } diff --git a/coroutines/src/main/kotlin/net/samyn/kapper/coroutines/DatasourceWithConnection.kt b/coroutines/src/main/kotlin/net/samyn/kapper/coroutines/DatasourceWithConnection.kt index e52b402..b27cfc2 100644 --- a/coroutines/src/main/kotlin/net/samyn/kapper/coroutines/DatasourceWithConnection.kt +++ b/coroutines/src/main/kotlin/net/samyn/kapper/coroutines/DatasourceWithConnection.kt @@ -7,14 +7,14 @@ import javax.sql.DataSource import kotlin.coroutines.CoroutineContext /** - * create a DB connection and execute query/aueries using the `Dispatchers.IO` CoroutineScope. + * create a DB connection and execute queryAsFlow/aueries using the `Dispatchers.IO` CoroutineScope. * The connection is closed after the block is executed. * @param block The block of code to execute. */ suspend inline fun DataSource.withConnection(crossinline block: suspend (Connection) -> T): T = withConnection(Dispatchers.IO, block) /** - * create a DB connection and execute query/aueries using the given CoroutineScope. + * create a DB connection and execute queryAsFlow/aueries using the given CoroutineScope. * The connection is closed after the block is executed. * @param context The CoroutineContext to use. * @param block The block of code to execute. diff --git a/coroutines/src/main/kotlin/net/samyn/kapper/coroutines/KapperKotlinFlowQueryFun.kt b/coroutines/src/main/kotlin/net/samyn/kapper/coroutines/KapperKotlinFlowQueryFun.kt index c8f31b7..5b0239a 100644 --- a/coroutines/src/main/kotlin/net/samyn/kapper/coroutines/KapperKotlinFlowQueryFun.kt +++ b/coroutines/src/main/kotlin/net/samyn/kapper/coroutines/KapperKotlinFlowQueryFun.kt @@ -15,7 +15,7 @@ import java.sql.ResultSet import java.sql.SQLException /** - * Execute a SQL query and map the results to a Flow of instances of the specified class. + * Execute a SQL queryAsFlow and map the results to a Flow of instances of the specified class. * * This function uses reflection to automatically map the result set columns to the properties of the specified class. * For advanced mappings, use the overloaded version with a custom `mapper` function. @@ -26,7 +26,7 @@ import java.sql.SQLException * data class User(val id: Int, val name: String) * * // Fetch all users where "active" is true - * val users: Flow = connection.query( + * val users: Flow = connection.queryAsFlow( * sql = "SELECT id, name FROM users WHERE active = :active", * "active" to true * ) @@ -35,27 +35,27 @@ import java.sql.SQLException * users.collect { println(it) } * ``` * - * @param sql The SQL query to execute. - * @param args Optional key-value pairs representing named parameters to substitute into the query. - * @return The query result as a [Flow] of [T] instances. + * @param sql The SQL queryAsFlow to execute. + * @param args Optional key-value pairs representing named parameters to substitute into the queryAsFlow. + * @return The queryAsFlow result as a [Flow] of [T] instances. * @throws java.sql.SQLException If there's a database error. */ -inline fun Connection.query( +inline fun Connection.queryAsFlow( sql: String, vararg args: Pair, ): Flow = - query( + queryAsFlow( sql, createMapper(T::class.java)::createInstance, *args, ) /** - * Execute a SQL query and map the results to a Flow of instances of the specified class with a custom mapper. + * Execute a SQL queryAsFlow and map the results to a Flow of instances of the specified class with a custom mapper. * * **Example**: * ```kotlin - * val users: Flow = connection.query( + * val users: Flow = connection.queryAsFlow( * sql = "SELECT id, name FROM users", * mapper = { resultSet, _ -> * User( @@ -67,18 +67,18 @@ inline fun Connection.query( * users.collect { println(it) } * ``` * - * @param sql The SQL query to execute. + * @param sql The SQL queryAsFlow to execute. * @param mapper Custom mapping function to transform the [ResultSet] into the target class. - * @param args Optional parameters to be substituted in the SQL query during execution. - * @return The query result as a [Flow] of [T] instances. + * @param args Optional parameters to be substituted in the SQL queryAsFlow during execution. + * @return The queryAsFlow result as a [Flow] of [T] instances. * @throws KapperQueryException If there's a database error. */ -inline fun Connection.query( +inline fun Connection.queryAsFlow( sql: String, noinline mapper: (ResultSet, Map) -> T, vararg args: Pair, ): Flow { - require(sql.isNotBlank()) { "SQL query cannot be empty or blank" } + require(sql.isNotBlank()) { "SQL queryAsFlow cannot be empty or blank" } this.executeQuery(Query(sql), args.toMap()).let { rs -> return queryFlow(rs, mapper, sql) } @@ -102,7 +102,7 @@ fun queryFlow( logger.info("Query results processing cancelled: ${e.message}") throw e } catch (e: SQLException) { - "Error executing query: $sql".also { + "Error executing queryAsFlow: $sql".also { logger.warn(it, e) throw KapperQueryException(it, e) } diff --git a/coroutines/src/test/kotlin/net/samyn/kapper/coroutines/FlowQueryTest.kt b/coroutines/src/test/kotlin/net/samyn/kapper/coroutines/FlowQueryTest.kt index 7513aac..a74b6de 100644 --- a/coroutines/src/test/kotlin/net/samyn/kapper/coroutines/FlowQueryTest.kt +++ b/coroutines/src/test/kotlin/net/samyn/kapper/coroutines/FlowQueryTest.kt @@ -51,7 +51,7 @@ class FlowQueryTest { @Test fun `when query emit each row as a flow item`() { runBlocking { - connection.query( + connection.queryAsFlow( queryTemplate, mapper, "id" to 1, @@ -64,7 +64,7 @@ class FlowQueryTest { runBlocking { mockkStatic("net.samyn.kapper.MapperFactoryKt") { every { createMapper(Hero::class.java).createInstance(any(), any()) } returns result - connection.query( + connection.queryAsFlow( queryTemplate, "id" to 1, ).toList() shouldBe listOf(result) @@ -75,7 +75,7 @@ class FlowQueryTest { @Test fun `when query emit close after collection`() { runBlocking { - connection.query( + connection.queryAsFlow( queryTemplate, mapper, "id" to 1, @@ -89,7 +89,7 @@ class FlowQueryTest { val ex = Exception("test") runBlocking { try { - connection.query( + connection.queryAsFlow( queryTemplate, mapper, "id" to 1, @@ -105,13 +105,13 @@ class FlowQueryTest { @Test fun `when cancel close`() { - // never finish the query + // never finish the queryAsFlow every { resultSet.next() } returns true runBlocking { var count = 0 val job = async { - connection.query( + connection.queryAsFlow( queryTemplate, mapper, "id" to 1, @@ -134,7 +134,7 @@ class FlowQueryTest { every { resultSet.next() } throws ex runBlocking { shouldThrow { - connection.query( + connection.queryAsFlow( queryTemplate, mapper, "id" to 1, @@ -147,7 +147,7 @@ class FlowQueryTest { fun `when sql blank throw`() { runBlocking { shouldThrow { - connection.query( + connection.queryAsFlow( "", mapper, "id" to 1,