Skip to content

Commit

Permalink
Sum batch results for inserts (#1641)
Browse files Browse the repository at this point in the history
* 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
  • Loading branch information
johnzeringue authored Jun 5, 2023
1 parent 4789feb commit 73c9972
Show file tree
Hide file tree
Showing 2 changed files with 33 additions and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,7 @@ open class InsertStatement<Key : Any>(val table: Table, val isIgnore: Boolean =
}

protected open fun PreparedStatementApi.execInsertFunction(): Pair<Int, ResultSet?> {
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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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)
}
}
}

0 comments on commit 73c9972

Please sign in to comment.