diff --git a/src/main/kotlin/fr/postgresjson/connexion/Connection.kt b/src/main/kotlin/fr/postgresjson/connexion/Connection.kt index 023dabc..afb9e89 100644 --- a/src/main/kotlin/fr/postgresjson/connexion/Connection.kt +++ b/src/main/kotlin/fr/postgresjson/connexion/Connection.kt @@ -95,7 +95,7 @@ class Connection( sql: String, typeReference: TypeReference>, values: List, - block: (QueryResult, List) -> Unit + block: QueryResult.(List) -> Unit ): List { val result = exec(sql, values) val json = result.rows[0].getString(0) @@ -115,7 +115,7 @@ class Connection( sql: String, typeReference: TypeReference>, values: Map, - block: (QueryResult, List) -> Unit + block: QueryResult.(List) -> Unit ): List { return replaceArgs(sql, values) { select(this.sql, typeReference, this.parameters, block) @@ -133,7 +133,7 @@ class Connection( limit: Int, typeReference: TypeReference>, values: Map, - block: (QueryResult, Paginated) -> Unit + block: QueryResult.(Paginated) -> Unit ): Paginated { val offset = (page - 1) * limit val newValues = values diff --git a/src/main/kotlin/fr/postgresjson/connexion/EmbedExecutable.kt b/src/main/kotlin/fr/postgresjson/connexion/EmbedExecutable.kt index 3b7b6e4..d77677c 100644 --- a/src/main/kotlin/fr/postgresjson/connexion/EmbedExecutable.kt +++ b/src/main/kotlin/fr/postgresjson/connexion/EmbedExecutable.kt @@ -26,7 +26,7 @@ sealed interface EmbedExecutable { */ fun selectOne( typeReference: TypeReference, - values: List = emptyList(), + values: List, block: SelectOneCallback = {} ): R? @@ -56,7 +56,7 @@ sealed interface EmbedExecutable { */ fun select( typeReference: TypeReference>, - values: List = emptyList(), + values: List, block: SelectCallback = {} ): List @@ -107,8 +107,4 @@ sealed interface EmbedExecutable { fun exec(values: List): QueryResult fun exec(values: Map): QueryResult fun exec(vararg values: Pair): QueryResult = exec(values.toMap()) - - fun perform(values: List) { exec(values) } - fun perform(values: Map) { exec(values) } - fun perform(vararg values: Pair) = perform(values.toMap()) } diff --git a/src/main/kotlin/fr/postgresjson/connexion/EmbedExecutableReified.kt b/src/main/kotlin/fr/postgresjson/connexion/EmbedExecutableReified.kt index ce64766..73e4df4 100644 --- a/src/main/kotlin/fr/postgresjson/connexion/EmbedExecutableReified.kt +++ b/src/main/kotlin/fr/postgresjson/connexion/EmbedExecutableReified.kt @@ -12,7 +12,7 @@ inline fun EmbedExecutable.update( update(object : TypeReference() {}, value, block) inline fun EmbedExecutable.selectOne( - values: List = emptyList(), + values: List, noinline block: SelectOneCallback = {} ): R? = selectOne(object : TypeReference() {}, values, block) @@ -32,7 +32,7 @@ inline fun EmbedExecutable.selectOne( /* Select Multiples */ inline fun EmbedExecutable.select( - values: List = emptyList(), + values: List, noinline block: SelectCallback = {} ): List = select(object : TypeReference>() {}, values, block) diff --git a/src/main/kotlin/fr/postgresjson/connexion/Executable.kt b/src/main/kotlin/fr/postgresjson/connexion/Executable.kt index 5d9b7d8..d4be1a5 100644 --- a/src/main/kotlin/fr/postgresjson/connexion/Executable.kt +++ b/src/main/kotlin/fr/postgresjson/connexion/Executable.kt @@ -113,15 +113,10 @@ interface Executable { select(sql, page, limit, typeReference, values.toMap(), block) fun exec(sql: String, value: R): QueryResult = exec(sql, listOf(value)) - fun exec(sql: String, values: List = emptyList()): QueryResult + fun exec(sql: String, values: List): QueryResult fun exec(sql: String, values: Map): QueryResult fun exec(sql: String, vararg values: Pair): QueryResult = exec(sql, values.toMap()) - fun perform(sql: String, value: R) { perform(sql, listOf(value)) } - fun perform(sql: String, values: List) { exec(sql, values) } - fun perform(sql: String, values: Map) { exec(sql, values) } - fun perform(sql: String, vararg values: Pair) = perform(sql, values.toMap()) - /** * Warning: this method not use prepared statement */ diff --git a/src/main/kotlin/fr/postgresjson/connexion/Query.kt b/src/main/kotlin/fr/postgresjson/connexion/Query.kt index f3bb60b..b2851c9 100644 --- a/src/main/kotlin/fr/postgresjson/connexion/Query.kt +++ b/src/main/kotlin/fr/postgresjson/connexion/Query.kt @@ -17,7 +17,7 @@ class Query(override val name: String, private val sql: String, override val con override fun selectOne( typeReference: TypeReference, values: List, - block: (QueryResult, R?) -> Unit + block: SelectOneCallback ): R? = connection.selectOne(sql, typeReference, values, block) @@ -27,7 +27,7 @@ class Query(override val name: String, private val sql: String, override val con override fun selectOne( typeReference: TypeReference, values: Map, - block: (QueryResult, R?) -> Unit + block: SelectOneCallback ): R? = connection.selectOne(sql, typeReference, values, block) @@ -39,7 +39,7 @@ class Query(override val name: String, private val sql: String, override val con override fun select( typeReference: TypeReference>, values: List, - block: (QueryResult, List) -> Unit + block: SelectCallback ): List = connection.select(sql, typeReference, values, block) @@ -49,7 +49,7 @@ class Query(override val name: String, private val sql: String, override val con override fun select( typeReference: TypeReference>, values: Map, - block: (QueryResult, List) -> Unit + block: SelectCallback ): List = connection.select(sql, typeReference, values, block) diff --git a/src/test/kotlin/fr/postgresjson/ConnectionTest.kt b/src/test/kotlin/fr/postgresjson/ConnectionTest.kt index b5afa7e..c3f5f2c 100644 --- a/src/test/kotlin/fr/postgresjson/ConnectionTest.kt +++ b/src/test/kotlin/fr/postgresjson/ConnectionTest.kt @@ -217,6 +217,34 @@ class ConnectionTest : TestAbstract() { assertEquals(result.offset, 0) } + @Test + fun `test select paginated`() { + val result: Paginated = connection.select( + """ + SELECT json_build_array( + jsonb_build_object( + 'name', :name::text, + 'id', 'e9f9a0f0-237c-47cf-98c5-be353f2f2ce3' + ) + ), + 10 as total + LIMIT :limit + OFFSET :offset + """.trimIndent(), + 1, + 2, + object : TypeReference>() {}, + mapOf( + "name" to "myName" + ) + ) + assertNotNull(result) + assertEquals("myName", result.result[0].name) + assertEquals(1, result.result.size) + assertEquals(result.total, 10) + assertEquals(result.offset, 0) + } + @Test fun `test select paginated without total`() { val exception = assertThrows { @@ -269,4 +297,20 @@ class ConnectionTest : TestAbstract() { assertEquals("sec", result.second) assertEquals(123, result.third) } + + @Test + fun `test exec without parameters`() { + connection.exec("select 42, 'hello';").run { + assertEquals(42, rows[0].getInt(0)) + assertEquals("hello", rows[0].getString(1)) + } + } + + @Test + fun `test exec with one object as parameter`() { + val obj = ObjTest("myName", UUID.fromString("c606e216-53b3-43c8-a900-e727cb4a017c")) + connection.exec("select ?::jsonb->>'name'", obj).run { + assertEquals("myName", rows[0].getString(0)) + } + } } diff --git a/src/test/kotlin/fr/postgresjson/RequesterTest.kt b/src/test/kotlin/fr/postgresjson/RequesterTest.kt index ac22209..897c747 100644 --- a/src/test/kotlin/fr/postgresjson/RequesterTest.kt +++ b/src/test/kotlin/fr/postgresjson/RequesterTest.kt @@ -1,5 +1,6 @@ package fr.postgresjson +import com.fasterxml.jackson.core.type.TypeReference import fr.postgresjson.connexion.Connection.QueryError import fr.postgresjson.connexion.Paginated import fr.postgresjson.connexion.Requester @@ -10,11 +11,11 @@ import fr.postgresjson.connexion.selectOne import fr.postgresjson.connexion.update import fr.postgresjson.entity.UuidEntity import fr.postgresjson.serializer.deserialize -import org.junit.Assert import org.junit.jupiter.api.Assertions.assertEquals import org.junit.jupiter.api.Assertions.assertThrows import org.junit.jupiter.api.Test import java.util.UUID +import kotlin.test.assertNotNull class RequesterTest : TestAbstract() { class ObjTest(val name: String, id: UUID = UUID.fromString("5623d902-3067-42f3-bfd9-095dbb12c29f")) : UuidEntity(id) @@ -339,34 +340,58 @@ class RequesterTest : TestAbstract() { @Test fun `call select multiple (named arguments)`() { val resources = this::class.java.getResource("/sql/query")?.toURI() - val result: List = Requester(connection, queriesDirectory = resources) - .getQuery("selectMultiple") - .select(mapOf("name" to "ff")) - Assert.assertNotNull(result) - Assert.assertEquals("ff", result[0].name) - Assert.assertEquals("ff-2", result[1].name) + Requester(connection, queriesDirectory = resources) + .getQuery("selectMultiple").apply { + select(mapOf("name" to "ff")).let { result -> + assertNotNull(result) + assertEquals("ff", result[0].name) + assertEquals("ff-2", result[1].name) + } + }.apply { + select(object : TypeReference>() {}, mapOf("name" to "ff")).let { result -> + assertNotNull(result) + assertEquals("ff", result[0].name) + assertEquals("ff-2", result[1].name) + } + } } @Test fun `call select multiple (named arguments as pair)`() { val resources = this::class.java.getResource("/sql/query")?.toURI() - val result: List = Requester(connection, queriesDirectory = resources) - .getQuery("selectMultiple") - .select("name" to "ff") - Assert.assertNotNull(result) - Assert.assertEquals("ff", result[0].name) - Assert.assertEquals("ff-2", result[1].name) + Requester(connection, queriesDirectory = resources) + .getQuery("selectMultiple").apply { + select("name" to "ff").let { result -> + assertNotNull(result) + assertEquals("ff", result[0].name) + assertEquals("ff-2", result[1].name) + } + }.apply { + select(object : TypeReference>() {}, "name" to "ff").let { result -> + assertNotNull(result) + assertEquals("ff", result[0].name) + assertEquals("ff-2", result[1].name) + } + } } @Test fun `call select multiple (ordered argument)`() { val resources = this::class.java.getResource("/sql/query")?.toURI() - val result: List = Requester(connection, queriesDirectory = resources) - .getQuery("selectMultipleOrderedArgs") - .select(listOf("ff", "aa")) - Assert.assertNotNull(result) - Assert.assertEquals("ff", result[0].name) - Assert.assertEquals("aa-2", result[1].name) + Requester(connection, queriesDirectory = resources) + .getQuery("selectMultipleOrderedArgs").apply { + select(listOf("ff", "aa")).let { result -> + assertNotNull(result) + assertEquals("ff", result[0].name) + assertEquals("aa-2", result[1].name) + } + }.apply { + select(object : TypeReference>() {}, listOf("ff", "aa")).let { result -> + assertNotNull(result) + assertEquals("ff", result[0].name) + assertEquals("aa-2", result[1].name) + } + } } @Test @@ -375,36 +400,78 @@ class RequesterTest : TestAbstract() { val result: Paginated = Requester(connection, queriesDirectory = resources) .getQuery("selectPaginated") .select(1, 2, mapOf("name" to "ff")) - Assert.assertNotNull(result) - Assert.assertEquals("ff", result.result[0].name) - Assert.assertEquals("ff-2", result.result[1].name) - Assert.assertEquals(10, result.total) - Assert.assertEquals(0, result.offset) + assertNotNull(result) + assertEquals("ff", result.result[0].name) + assertEquals("ff-2", result.result[1].name) + assertEquals(10, result.total) + assertEquals(0, result.offset) } @Test fun `call select paginated on function`() { val resources = this::class.java.getResource("/sql/function")?.toURI() - val result: Paginated = Requester(connection, functionsDirectory = resources) + Requester(connection, functionsDirectory = resources) + .getFunction("test_function_paginated").apply { + select(1, 2, mapOf("name" to "ff")).run { + assertNotNull(result) + assertEquals("ff", result[0].name) + assertEquals("ff-2", result[1].name) + assertEquals(10, total) + assertEquals(0, offset) + } + }.apply { + select(1, 2, object : TypeReference>() {}, mapOf("name" to "ff")).run { + assertNotNull(result) + assertEquals("ff", result[0].name) + assertEquals("ff-2", result[1].name) + assertEquals(10, total) + assertEquals(0, offset) + } + } + } + + @Test + fun `call select paginated on function with vararg`() { + val resources = this::class.java.getResource("/sql/function")?.toURI() + Requester(connection, functionsDirectory = resources) .getFunction("test_function_paginated") - .select(1, 2, mapOf("name" to "ff")) - Assert.assertNotNull(result) - Assert.assertEquals("ff", result.result[0].name) - Assert.assertEquals("ff-2", result.result[1].name) - Assert.assertEquals(10, result.total) - Assert.assertEquals(0, result.offset) + .select(1, 2, "name" to "ff").run { + assertNotNull(result) + assertEquals("ff", result[0].name) + assertEquals("ff-2", result[1].name) + assertEquals(10, total) + assertEquals(0, offset) + } + + Requester(connection, functionsDirectory = resources) + .getFunction("test_function_paginated") + .select(1, 2, object : TypeReference>() {}, "name" to "ff").run { + assertNotNull(result) + assertEquals("ff", result[0].name) + assertEquals("ff-2", result[1].name) + assertEquals(10, total) + assertEquals(0, offset) + } } @Test fun `call selectOne on query with extra parameter`() { val resources = this::class.java.getResource("/sql/query")?.toURI() - val obj: ObjTest = Requester(connection, queriesDirectory = resources) - .getQuery("selectOneWithParameters") - .selectOne(mapOf("name" to "myName")) { - assertEquals("myName", it!!.name) - Assert.assertEquals("plop", rows[0].getString("other")) - }!! - - assertEquals("myName", obj.name) + Requester(connection, queriesDirectory = resources) + .getQuery("selectOneWithParameters").apply { + selectOne(mapOf("name" to "myName")) { + assertEquals("myName", it!!.name) + assertEquals("plop", rows[0].getString("other")) + }!!.run { + assertEquals("myName", name) + } + }.apply { + selectOne(typeReference = object : TypeReference() {}, values = mapOf("name" to "myName")) { it -> + assertEquals("myName", it!!.name) + assertEquals("plop", rows[0].getString("other")) + }!!.run { + assertEquals("myName", name) + } + } } }