From 73c9972ce32204ac5816f777202e8d924a629d5d Mon Sep 17 00:00:00 2001 From: John Zeringue Date: Mon, 5 Jun 2023 03:21:41 -0400 Subject: [PATCH] Sum batch results for inserts (#1641) * Sum batch results for inserts When executing a batch insert, the number of inserted rows is the sum of the batch rows instead of the count. Making this distinction allows extensions of batch insert like ``` class MyBatchInsertStatement( table: Table, ) : BatchInsertStatement(table) { override fun prepareSQL(transaction: Transaction) = buildString { append(super.prepareSQL(transaction)) append(" ON CONFLICT (id) DO NOTHING") } } ``` where the return value of `execute` is still accurate. * Add test --- .../exposed/sql/statements/InsertStatement.kt | 2 +- .../sql/tests/shared/dml/InsertTests.kt | 32 +++++++++++++++++++ 2 files changed, 33 insertions(+), 1 deletion(-) 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 a59aed11cd..8a16738aa4 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 @@ -123,7 +123,7 @@ open class InsertStatement(val table: Table, val isIgnore: Boolean = } protected open fun PreparedStatementApi.execInsertFunction(): Pair { - val inserted = if (arguments().count() > 1 || isAlwaysBatch) executeBatch().count() else executeUpdate() + val inserted = if (arguments().count() > 1 || isAlwaysBatch) executeBatch().sum() else executeUpdate() val rs = if (autoIncColumns.isNotEmpty()) { resultSet } else null diff --git a/exposed-tests/src/test/kotlin/org/jetbrains/exposed/sql/tests/shared/dml/InsertTests.kt b/exposed-tests/src/test/kotlin/org/jetbrains/exposed/sql/tests/shared/dml/InsertTests.kt index 025c472ecc..e5fca912a4 100644 --- a/exposed-tests/src/test/kotlin/org/jetbrains/exposed/sql/tests/shared/dml/InsertTests.kt +++ b/exposed-tests/src/test/kotlin/org/jetbrains/exposed/sql/tests/shared/dml/InsertTests.kt @@ -8,6 +8,7 @@ import org.jetbrains.exposed.dao.id.IdTable import org.jetbrains.exposed.dao.id.IntIdTable import org.jetbrains.exposed.sql.* import org.jetbrains.exposed.sql.SqlExpressionBuilder.eq +import org.jetbrains.exposed.sql.statements.BatchInsertStatement import org.jetbrains.exposed.sql.tests.DatabaseTestsBase import org.jetbrains.exposed.sql.tests.TestDB import org.jetbrains.exposed.sql.tests.currentDialectTest @@ -574,4 +575,35 @@ class InsertTests : DatabaseTestsBase() { } } + + class BatchInsertOnConflictDoNothing( + table: Table, + ) : BatchInsertStatement(table) { + override fun prepareSQL(transaction: Transaction) = buildString { + append(super.prepareSQL(transaction)) + append(" ON CONFLICT (id) DO NOTHING") + } + } + + @Test fun `batch insert number of inserted rows is accurate`() { + val tab = object : Table("tab") { + val id = varchar("id", 10).uniqueIndex() + } + + withTables(TestDB.allH2TestDB + listOf(TestDB.MYSQL), tab) { + tab.insert { it[id] = "foo" } + + val numInserted = BatchInsertOnConflictDoNothing(tab).run { + addBatch() + this[tab.id] = "foo" + + addBatch() + this[tab.id] = "bar" + + execute(this@withTables) + } + + assertEquals(1, numInserted) + } + } }