From a4a4ef5f6f3fa726fbc49daa990068e953c74122 Mon Sep 17 00:00:00 2001 From: Fabrice Lecomte Date: Sun, 18 Jul 2021 01:19:27 +0200 Subject: [PATCH] Add more tests remove "sendQuery" on function sendQuery now return QueryResult remove null on queryError message --- .../fr/postgresjson/connexion/Connection.kt | 26 +++---- .../postgresjson/connexion/EmbedExecutable.kt | 13 ---- .../fr/postgresjson/connexion/Executable.kt | 8 +- .../fr/postgresjson/connexion/Function.kt | 16 ---- .../kotlin/fr/postgresjson/connexion/Query.kt | 8 +- .../fr/postgresjson/migration/Function.kt | 28 +++---- .../kotlin/fr/postgresjson/ConnectionTest.kt | 20 ++--- .../kotlin/fr/postgresjson/RequesterTest.kt | 73 +++++++++++++++++-- .../Test/selectMultipleDifferentArgs.sql | 1 + .../query/Test/selectMultipleWithSameArgs.sql | 1 + 10 files changed, 116 insertions(+), 78 deletions(-) create mode 100644 src/test/resources/sql/query/Test/selectMultipleDifferentArgs.sql create mode 100644 src/test/resources/sql/query/Test/selectMultipleWithSameArgs.sql diff --git a/src/main/kotlin/fr/postgresjson/connexion/Connection.kt b/src/main/kotlin/fr/postgresjson/connexion/Connection.kt index c716ecb..9a3609d 100644 --- a/src/main/kotlin/fr/postgresjson/connexion/Connection.kt +++ b/src/main/kotlin/fr/postgresjson/connexion/Connection.kt @@ -185,11 +185,11 @@ class Connection( /** * Warning: this method not use prepared statement */ - override fun sendQuery(sql: String, values: List): Int { + override fun sendQuery(sql: String, values: List): QueryResult { val compiledValues = compileArgs(values) return stopwatchQuery(sql, compiledValues) { replaceArgsIntoSql(sql, compiledValues) { - connect().sendQuery(it).join().rowsAffected.toInt() + connect().sendQuery(it).join() } } } @@ -197,7 +197,7 @@ class Connection( /** * Warning: this method not use prepared statement */ - override fun sendQuery(sql: String, values: Map): Int { + override fun sendQuery(sql: String, values: Map): QueryResult { return replaceArgs(sql, values) { sendQuery(this.sql, this.parameters) } @@ -217,7 +217,7 @@ class Connection( val paramRegex = "(? val name = match.groups[1]!!.value - values[name] ?: values[name.trimStart('_')] ?: queryError("Parameter $name missing", sql, values) + values[name] ?: values[name.trimStart('_')] ?: queryError("""Parameter "$name" missing""", sql, values) }.toList() var newSql = sql @@ -296,11 +296,11 @@ class Connection( """ |$msg | - |${parameters.joinToString(", ") { it.toString() }.prependIndent(" > ")} + |${parameters.joinToString(", ") { it.toString() }.prependIndent(" > ") ?: ""} |${sql.prependIndent(" > ")} - |${result?.let { "-----" }?.prependIndent(" > ")} - |${result?.columnNames()?.joinToString(" | ")?.prependIndent(" > ")} - |${result?.map { it.joinToString(" | ") }?.joinToString("\n")?.prependIndent(" > ")} + |${result?.let { "-----" }?.prependIndent(" > ") ?: ""} + |${result?.columnNames()?.joinToString(" | ")?.prependIndent(" > ") ?: ""} + |${result?.map { it.joinToString(" | ") }?.joinToString("\n")?.prependIndent(" > ") ?: ""} """.trimMargin().trim(' ', '\n') ) @@ -313,11 +313,11 @@ class Connection( """ |$msg | - |${parameters.map { it.key + ": " + it.value }.joinToString(", ").prependIndent(" > ")} + |${parameters.map { ":" + it.key + " = " + it.value }.joinToString(", ").prependIndent(" > ") ?: ""} |${sql.prependIndent(" > ")} - |${result?.let { "-----" }?.prependIndent(" > ")} - |${result?.columnNames()?.joinToString(" | ")?.prependIndent(" > ")} - |${result?.map { it.joinToString(" | ") }?.joinToString("\n")?.prependIndent(" > ")} - """.trimMargin().trim(' ') + |${result?.let { "-----" }?.prependIndent(" > ") ?: ""} + |${result?.columnNames()?.joinToString(" | ")?.prependIndent(" > ") ?: ""} + |${result?.map { it.joinToString(" | ") }?.joinToString("\n")?.prependIndent(" > ") ?: ""} + """.trimMargin().trim(' ', '\n') ) } diff --git a/src/main/kotlin/fr/postgresjson/connexion/EmbedExecutable.kt b/src/main/kotlin/fr/postgresjson/connexion/EmbedExecutable.kt index 6ec42b2..3b7b6e4 100644 --- a/src/main/kotlin/fr/postgresjson/connexion/EmbedExecutable.kt +++ b/src/main/kotlin/fr/postgresjson/connexion/EmbedExecutable.kt @@ -111,17 +111,4 @@ sealed interface EmbedExecutable { fun perform(values: List) { exec(values) } fun perform(values: Map) { exec(values) } fun perform(vararg values: Pair) = perform(values.toMap()) - - /** - * Warning: this method not use prepared statement - */ - fun sendQuery(values: List): Int - /** - * Warning: this method not use prepared statement - */ - fun sendQuery(values: Map): Int - /** - * Warning: this method not use prepared statement - */ - fun sendQuery(vararg values: Pair): Int = sendQuery(values.toMap()) } diff --git a/src/main/kotlin/fr/postgresjson/connexion/Executable.kt b/src/main/kotlin/fr/postgresjson/connexion/Executable.kt index 9114661..5d9b7d8 100644 --- a/src/main/kotlin/fr/postgresjson/connexion/Executable.kt +++ b/src/main/kotlin/fr/postgresjson/connexion/Executable.kt @@ -125,17 +125,17 @@ interface Executable { /** * Warning: this method not use prepared statement */ - fun sendQuery(sql: String, value: R): Int = sendQuery(sql, listOf(value)) + fun sendQuery(sql: String, value: R): QueryResult = sendQuery(sql, listOf(value)) /** * Warning: this method not use prepared statement */ - fun sendQuery(sql: String, values: List = emptyList()): Int + fun sendQuery(sql: String, values: List): QueryResult /** * Warning: this method not use prepared statement */ - fun sendQuery(sql: String, values: Map): Int + fun sendQuery(sql: String, values: Map): QueryResult /** * Warning: this method not use prepared statement */ - fun sendQuery(sql: String, vararg values: Pair): Int = sendQuery(sql, values.toMap()) + fun sendQuery(sql: String, vararg values: Pair): QueryResult = sendQuery(sql, values.toMap()) } diff --git a/src/main/kotlin/fr/postgresjson/connexion/Function.kt b/src/main/kotlin/fr/postgresjson/connexion/Function.kt index d110c67..83096f6 100644 --- a/src/main/kotlin/fr/postgresjson/connexion/Function.kt +++ b/src/main/kotlin/fr/postgresjson/connexion/Function.kt @@ -82,22 +82,6 @@ class Function(val definition: Function, override val connection: Connection) : override fun exec(values: Map): QueryResult = connection.exec(compileSql(values), values) - /** - * Warning: this method not use prepared statement - */ - override fun sendQuery(values: List): Int { - exec(values) - return 0 - } - - /** - * Warning: this method not use prepared statement - */ - override fun sendQuery(values: Map): Int { - exec(values) - return 0 - } - private fun compileArgs(value: R): String = compileArgs(listOf(value)) private fun compileArgs(values: List): String { diff --git a/src/main/kotlin/fr/postgresjson/connexion/Query.kt b/src/main/kotlin/fr/postgresjson/connexion/Query.kt index b4a246f..f3bb60b 100644 --- a/src/main/kotlin/fr/postgresjson/connexion/Query.kt +++ b/src/main/kotlin/fr/postgresjson/connexion/Query.kt @@ -76,10 +76,14 @@ class Query(override val name: String, private val sql: String, override val con /** * Warning: this method not use prepared statement */ - override fun sendQuery(values: List): Int = connection.sendQuery(sql, values) + fun sendQuery(values: List): QueryResult = connection.sendQuery(sql, values) /** * Warning: this method not use prepared statement */ - override fun sendQuery(values: Map): Int = connection.sendQuery(sql, values) + fun sendQuery(values: Map): QueryResult = connection.sendQuery(sql, values) + /** + * Warning: this method not use prepared statement + */ + fun sendQuery(vararg values: Pair): QueryResult = sendQuery(values.toMap()) } diff --git a/src/main/kotlin/fr/postgresjson/migration/Function.kt b/src/main/kotlin/fr/postgresjson/migration/Function.kt index b874fb3..05cca70 100644 --- a/src/main/kotlin/fr/postgresjson/migration/Function.kt +++ b/src/main/kotlin/fr/postgresjson/migration/Function.kt @@ -47,21 +47,25 @@ data class Function( } } - this::class.java.classLoader.getResource("sql/migration/insertFunction.sql")!!.readText().let { - connection.selectOne(it, listOf(up.name, up.getDefinition(), up.script, down.script))?.let { function -> + this::class.java.classLoader + .getResource("sql/migration/insertFunction.sql")!!.readText() + .let { connection.selectOne(it, listOf(up.name, up.getDefinition(), up.script, down.script)) } + ?.let { function -> executedAt = function.executedAt doExecute = Action.OK } - } + return Status.OK } override fun down(): Status { connection.sendQuery(down.script) - this::class.java.classLoader.getResource("sql/migration/deleteFunction.sql")!!.readText().let { - connection.sendQuery(it, listOf(down.name)) - } + this::class.java.classLoader + .getResource("sql/migration/deleteFunction.sql")!! + .readText() + .let { connection.sendQuery(it, listOf(down.name)) } + return Status.OK } @@ -75,13 +79,9 @@ data class Function( return Status.OK } - fun copy(): Function { - return this.copy(up = up, down = down, connection = connection, executedAt = executedAt).also { - it.doExecute = this.doExecute - } - } + fun copy(): Function = this + .copy(up = up, down = down, connection = connection, executedAt = executedAt) + .also { it.doExecute = this.doExecute } - infix fun `is different from`(other: DefinitionFunction): Boolean { - return other.script != this.up.script - } + infix fun `is different from`(other: DefinitionFunction): Boolean = other.script != this.up.script } diff --git a/src/test/kotlin/fr/postgresjson/ConnectionTest.kt b/src/test/kotlin/fr/postgresjson/ConnectionTest.kt index 817d402..7d0165f 100644 --- a/src/test/kotlin/fr/postgresjson/ConnectionTest.kt +++ b/src/test/kotlin/fr/postgresjson/ConnectionTest.kt @@ -236,16 +236,16 @@ class ConnectionTest : TestAbstract() { assertEquals( """ - |The query not return the "total" column - | - | > offset: 0, limit: 2 - | > SELECT null - | > LIMIT :limit - | > OFFSET :offset - | > ----- - | > ?column? - | > null - """.trimMargin(), + The query not return the "total" column + + > :offset = 0, :limit = 2 + > SELECT null + > LIMIT :limit + > OFFSET :offset + > ----- + > ?column? + > null + """.trimIndent(), exception.message ) } diff --git a/src/test/kotlin/fr/postgresjson/RequesterTest.kt b/src/test/kotlin/fr/postgresjson/RequesterTest.kt index 8a529ef..ec55c85 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 fr.postgresjson.connexion.Connection.QueryError import fr.postgresjson.connexion.Paginated import fr.postgresjson.connexion.Requester import fr.postgresjson.connexion.Requester.NoFunctionDefined @@ -160,23 +161,83 @@ class RequesterTest : TestAbstract() { } @Test - fun `call sendQuery on query with name`() { + fun `call exec on query with name`() { val resources = this::class.java.getResource("/sql/query")?.toURI() val result = Requester(connection, queriesDirectory = resources) .getQuery("DeleteTest") - .sendQuery() + .exec() - assertEquals(0, result) + assertEquals(0, result.rowsAffected) } @Test - fun `call sendQuery on function`() { + fun `call sendQuery with same name of arguments`() { + val resources = this::class.java.getResource("/sql/query")?.toURI() + Requester(connection, queriesDirectory = resources) + .getQuery("selectMultipleWithSameArgs") + .sendQuery("name" to "myName").run { + assertEquals("myName", rows[0].getString("firstName")) + assertEquals("myName", rows[0].getString("secondName")) + } + } + + @Test + fun `call sendQuery with arguments on not same orders`() { + val resources = this::class.java.getResource("/sql/query")?.toURI() + Requester(connection, queriesDirectory = resources) + .getQuery("selectMultipleDifferentArgs") + .sendQuery("first" to "firstName", "second" to "secondName").run { + assertEquals("firstName", rows[0].getString("firstName")) + assertEquals("secondName", rows[0].getString("secondName")) + } + + Requester(connection, queriesDirectory = resources) + .getQuery("selectMultipleDifferentArgs") + .sendQuery("second" to "secondName", "first" to "firstName").run { + assertEquals("firstName", rows[0].getString("firstName")) + assertEquals("secondName", rows[0].getString("secondName")) + } + + Requester(connection, queriesDirectory = resources) + .getQuery("selectMultipleDifferentArgs") + .sendQuery("second" to "secondName", "first" to "firstName").run { + assertEquals("firstName", rows[0].getString(0)) + assertEquals("secondName", rows[0].getString(1)) + } + } + + @Test + fun `call sendQuery with wrong number of arguments`() { + val resources = this::class.java.getResource("/sql/query")?.toURI() + + assertThrows(QueryError::class.java) { + Requester(connection, queriesDirectory = resources) + .getQuery("selectMultipleDifferentArgs") + .sendQuery("first" to "firstName").run { + assertEquals("firstName", rows[0].getString(0)) + assertEquals("secondName", rows[0].getString(1)) + } + }.let { + assertEquals( + """ + Parameter "second" missing + + > :first = firstName + > SELECT :first::text as "firstName", :second::text as "secondName"; + """.trimIndent(), + it.message + ) + } + } + + @Test + fun `call exec on function with pair as arguments`() { val resources = this::class.java.getResource("/sql/function/Test")?.toURI() val result = Requester(connection, functionsDirectory = resources) .getFunction("function_void") - .sendQuery(listOf("test")) + .exec("name" to "test") - assertEquals(0, result) + assertEquals(1, result.rowsAffected) } @Test diff --git a/src/test/resources/sql/query/Test/selectMultipleDifferentArgs.sql b/src/test/resources/sql/query/Test/selectMultipleDifferentArgs.sql new file mode 100644 index 0000000..b63306e --- /dev/null +++ b/src/test/resources/sql/query/Test/selectMultipleDifferentArgs.sql @@ -0,0 +1 @@ +SELECT :first::text as "firstName", :second::text as "secondName"; \ No newline at end of file diff --git a/src/test/resources/sql/query/Test/selectMultipleWithSameArgs.sql b/src/test/resources/sql/query/Test/selectMultipleWithSameArgs.sql new file mode 100644 index 0000000..9928968 --- /dev/null +++ b/src/test/resources/sql/query/Test/selectMultipleWithSameArgs.sql @@ -0,0 +1 @@ +SELECT :name::text as "firstName", :name::text as "secondName"; \ No newline at end of file