From 45af270625cbd0bc759772bcba4d2087ee9d4bfc Mon Sep 17 00:00:00 2001 From: bog-walk <82039410+bog-walk@users.noreply.github.com> Date: Mon, 8 Jul 2024 17:53:59 -0400 Subject: [PATCH] feat: EXPOSED-435 Allow insertReturning() to set isIgnore = true (#2148) * feat: Allow insertReturning() to set isIgnore = true Add a new parameter to insertReturning() that allows the wrapped insert statement to use the IGNORE keyword. --- exposed-core/api/exposed-core.api | 4 +-- .../org/jetbrains/exposed/sql/Queries.kt | 5 +++- .../sql/tests/shared/dml/ReturningTests.kt | 29 +++++++++++++++++++ 3 files changed, 35 insertions(+), 3 deletions(-) diff --git a/exposed-core/api/exposed-core.api b/exposed-core/api/exposed-core.api index 9b9b8ddc8f..144a906ea8 100644 --- a/exposed-core/api/exposed-core.api +++ b/exposed-core/api/exposed-core.api @@ -1742,8 +1742,8 @@ public final class org/jetbrains/exposed/sql/QueriesKt { public static final fun insertIgnore (Lorg/jetbrains/exposed/sql/Table;Lorg/jetbrains/exposed/sql/AbstractQuery;Ljava/util/List;)Ljava/lang/Integer; public static synthetic fun insertIgnore$default (Lorg/jetbrains/exposed/sql/Table;Lorg/jetbrains/exposed/sql/AbstractQuery;Ljava/util/List;ILjava/lang/Object;)Ljava/lang/Integer; public static final fun insertIgnoreAndGetId (Lorg/jetbrains/exposed/dao/id/IdTable;Lkotlin/jvm/functions/Function2;)Lorg/jetbrains/exposed/dao/id/EntityID; - public static final fun insertReturning (Lorg/jetbrains/exposed/sql/Table;Ljava/util/List;Lkotlin/jvm/functions/Function2;)Lorg/jetbrains/exposed/sql/statements/ReturningStatement; - public static synthetic fun insertReturning$default (Lorg/jetbrains/exposed/sql/Table;Ljava/util/List;Lkotlin/jvm/functions/Function2;ILjava/lang/Object;)Lorg/jetbrains/exposed/sql/statements/ReturningStatement; + public static final fun insertReturning (Lorg/jetbrains/exposed/sql/Table;Ljava/util/List;ZLkotlin/jvm/functions/Function2;)Lorg/jetbrains/exposed/sql/statements/ReturningStatement; + public static synthetic fun insertReturning$default (Lorg/jetbrains/exposed/sql/Table;Ljava/util/List;ZLkotlin/jvm/functions/Function2;ILjava/lang/Object;)Lorg/jetbrains/exposed/sql/statements/ReturningStatement; public static final fun mergeFrom (Lorg/jetbrains/exposed/sql/Table;Lorg/jetbrains/exposed/sql/QueryAlias;Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function1;)Lorg/jetbrains/exposed/sql/statements/MergeSelectStatement; public static final fun mergeFrom (Lorg/jetbrains/exposed/sql/Table;Lorg/jetbrains/exposed/sql/Table;Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function1;)Lorg/jetbrains/exposed/sql/statements/MergeTableStatement; public static synthetic fun mergeFrom$default (Lorg/jetbrains/exposed/sql/Table;Lorg/jetbrains/exposed/sql/Table;Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function1;ILjava/lang/Object;)Lorg/jetbrains/exposed/sql/statements/MergeTableStatement; diff --git a/exposed-core/src/main/kotlin/org/jetbrains/exposed/sql/Queries.kt b/exposed-core/src/main/kotlin/org/jetbrains/exposed/sql/Queries.kt index 4962d8add3..d849126e34 100644 --- a/exposed-core/src/main/kotlin/org/jetbrains/exposed/sql/Queries.kt +++ b/exposed-core/src/main/kotlin/org/jetbrains/exposed/sql/Queries.kt @@ -391,15 +391,18 @@ fun T.insertIgnore( * Represents the SQL statement that inserts new rows into a table and returns specified data from the inserted rows. * * @param returning Columns and expressions to include in the returned data. This defaults to all columns in the table. + * @param ignoreErrors Whether to ignore any possible errors that occur during the process. + * Note `INSERT IGNORE` is not supported by all vendors. Please check the documentation. * @return A [ReturningStatement] that will be executed once iterated over, providing [ResultRow]s containing the specified * expressions mapped to their resulting data. * @sample org.jetbrains.exposed.sql.tests.shared.dml.ReturningTests.testInsertReturning */ fun T.insertReturning( returning: List> = columns, + ignoreErrors: Boolean = false, body: T.(InsertStatement) -> Unit ): ReturningStatement { - val insert = InsertStatement(this) + val insert = InsertStatement(this, ignoreErrors) body(insert) return ReturningStatement(this, returning, insert) } diff --git a/exposed-tests/src/test/kotlin/org/jetbrains/exposed/sql/tests/shared/dml/ReturningTests.kt b/exposed-tests/src/test/kotlin/org/jetbrains/exposed/sql/tests/shared/dml/ReturningTests.kt index a136065f04..225d64e9fc 100644 --- a/exposed-tests/src/test/kotlin/org/jetbrains/exposed/sql/tests/shared/dml/ReturningTests.kt +++ b/exposed-tests/src/test/kotlin/org/jetbrains/exposed/sql/tests/shared/dml/ReturningTests.kt @@ -48,6 +48,35 @@ class ReturningTests : DatabaseTestsBase() { } } + @Test + fun testInsertIgnoreReturning() { + val tester = object : Table("tester") { + val item = varchar("item", 32).uniqueIndex() + } + + withTables(TestDB.ALL - returningSupportedDb, tester) { + tester.insert { + it[item] = "Item A" + } + assertEquals(1, tester.selectAll().count()) + + // no result set is returned because insert is ignored + val resultWithConflict = tester.insertReturning(ignoreErrors = true) { + it[item] = "Item A" + }.toList() + + assertTrue { resultWithConflict.isEmpty() } + assertEquals(1, tester.selectAll().count()) + + val resultWithoutConflict = tester.insertReturning(ignoreErrors = true) { + it[item] = "Item B" + }.single() + + assertEquals("Item B", resultWithoutConflict[tester.item]) + assertEquals(2, tester.selectAll().count()) + } + } + @Test fun testUpsertReturning() { withTables(TestDB.ALL - returningSupportedDb, Items) {