diff --git a/exposed-core/api/exposed-core.api b/exposed-core/api/exposed-core.api index f5fa8cf28d..818b458dd3 100644 --- a/exposed-core/api/exposed-core.api +++ b/exposed-core/api/exposed-core.api @@ -2963,6 +2963,8 @@ public class org/jetbrains/exposed/sql/statements/UpdateStatement : org/jetbrain public class org/jetbrains/exposed/sql/statements/UpsertStatement : org/jetbrains/exposed/sql/statements/InsertStatement { public fun (Lorg/jetbrains/exposed/sql/Table;[Lorg/jetbrains/exposed/sql/Column;Ljava/util/List;Lorg/jetbrains/exposed/sql/Op;)V + public synthetic fun arguments ()Ljava/lang/Iterable; + public fun arguments ()Ljava/util/List; public final fun getKeys ()[Lorg/jetbrains/exposed/sql/Column; public final fun getOnUpdate ()Ljava/util/List; public final fun getWhere ()Lorg/jetbrains/exposed/sql/Op; diff --git a/exposed-core/src/main/kotlin/org/jetbrains/exposed/sql/statements/InsertStatement.kt b/exposed-core/src/main/kotlin/org/jetbrains/exposed/sql/statements/InsertStatement.kt index 4c5cf05157..6f82f51250 100644 --- a/exposed-core/src/main/kotlin/org/jetbrains/exposed/sql/statements/InsertStatement.kt +++ b/exposed-core/src/main/kotlin/org/jetbrains/exposed/sql/statements/InsertStatement.kt @@ -209,7 +209,7 @@ open class InsertStatement( } override fun arguments(): List>> { - return arguments!!.map { args -> + return arguments?.map { args -> val builder = QueryBuilder(true) args.filter { (_, value) -> value != DefaultValueMarker @@ -217,6 +217,6 @@ open class InsertStatement( builder.registerArgument(column, value) } builder.args - } + } ?: emptyList() } } diff --git a/exposed-core/src/main/kotlin/org/jetbrains/exposed/sql/statements/UpsertStatement.kt b/exposed-core/src/main/kotlin/org/jetbrains/exposed/sql/statements/UpsertStatement.kt index de2e74da10..20cf632830 100644 --- a/exposed-core/src/main/kotlin/org/jetbrains/exposed/sql/statements/UpsertStatement.kt +++ b/exposed-core/src/main/kotlin/org/jetbrains/exposed/sql/statements/UpsertStatement.kt @@ -30,4 +30,17 @@ open class UpsertStatement( } return functionProvider.upsert(table, arguments!!.first(), onUpdate, where, transaction, keys = keys) } + + override fun arguments(): List>> { + return arguments?.map { args -> + val builder = QueryBuilder(true) + args.filter { (_, value) -> + value != DefaultValueMarker + }.forEach { (column, value) -> + builder.registerArgument(column, value) + } + where?.toQueryBuilder(builder) + builder.args + } ?: emptyList() + } } diff --git a/exposed-tests/src/test/kotlin/org/jetbrains/exposed/sql/tests/shared/dml/UpsertTests.kt b/exposed-tests/src/test/kotlin/org/jetbrains/exposed/sql/tests/shared/dml/UpsertTests.kt index 8a3ac4fba1..fe1047f24e 100644 --- a/exposed-tests/src/test/kotlin/org/jetbrains/exposed/sql/tests/shared/dml/UpsertTests.kt +++ b/exposed-tests/src/test/kotlin/org/jetbrains/exposed/sql/tests/shared/dml/UpsertTests.kt @@ -6,7 +6,9 @@ import org.jetbrains.exposed.exceptions.UnsupportedByDialectException import org.jetbrains.exposed.sql.* import org.jetbrains.exposed.sql.SqlExpressionBuilder.concat import org.jetbrains.exposed.sql.SqlExpressionBuilder.less +import org.jetbrains.exposed.sql.SqlExpressionBuilder.like import org.jetbrains.exposed.sql.SqlExpressionBuilder.minus +import org.jetbrains.exposed.sql.SqlExpressionBuilder.neq import org.jetbrains.exposed.sql.SqlExpressionBuilder.plus import org.jetbrains.exposed.sql.statements.BatchUpsertStatement import org.jetbrains.exposed.sql.tests.* @@ -383,6 +385,38 @@ class UpsertTests : DatabaseTestsBase() { } } + @Test + fun testUpsertWithWhereParameterized() { + val tester = object : IntIdTable("tester") { + val name = varchar("name", 64).uniqueIndex() + val age = integer("age") + } + + withTables(excludeSettings = TestDB.mySqlRelatedDB + upsertViaMergeDB, tester) { + val id1 = tester.upsert { + it[name] = "Anya" + it[age] = 10 + } get tester.id + tester.upsert { + it[name] = "Anna" + it[age] = 50 + } + + val nameStartsWithA = tester.name like "A%" + val nameEndsWithA = tester.name like stringLiteral("%a") + val nameIsNotAnna = tester.name neq stringParam("Anna") + val updatedAge = 20 + tester.upsert(tester.name, where = { nameStartsWithA and nameEndsWithA and nameIsNotAnna }) { + it[name] = "Anya" + it[age] = updatedAge + } + + assertEquals(2, tester.selectAll().count()) + val updatedResult = tester.selectAll().where { tester.age eq updatedAge }.single() + assertEquals(id1, updatedResult[tester.id]) + } + } + @Test fun testUpsertWithSubQuery() { val tester1 = object : IntIdTable("tester_1") {