Skip to content

Commit

Permalink
fix: EXPOSED-162 SQLite generatedKeys exception
Browse files Browse the repository at this point in the history
Support for getGeneratedKeys() was dropped in the sqlite jdbc version 3.43.0.0. This caused a SQLFeatureNotSupportedException when using this version with Exposed, so the old implementation of getGeneratedKeys() was used in Exposed to retain the previous behaviour.
  • Loading branch information
joc-a committed Sep 12, 2023
1 parent fa73510 commit ec74743
Show file tree
Hide file tree
Showing 5 changed files with 37 additions and 9 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ object Versions {
const val oracle12 = "12.2.0.1"
const val postgre = "42.6.0"
const val postgreNG = "0.8.9"
const val sqlLite3 = "3.42.0.0"
const val sqlLite3 = "3.43.0.0"
const val sqlserver = "9.4.1.jre8"

/** Spring **/
Expand Down
2 changes: 1 addition & 1 deletion exposed-jdbc/api/exposed-jdbc.api
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ public final class org/jetbrains/exposed/sql/statements/jdbc/JdbcDatabaseMetadat
}

public final class org/jetbrains/exposed/sql/statements/jdbc/JdbcPreparedStatementImpl : org/jetbrains/exposed/sql/statements/api/PreparedStatementApi {
public fun <init> (Ljava/sql/PreparedStatement;Z)V
public fun <init> (Ljava/sql/PreparedStatement;ZZ)V
public fun addBatch ()V
public fun cancel ()V
public fun closeIfPossible ()V
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -74,11 +74,19 @@ class JdbcConnectionImpl(override val connection: Connection) : ExposedConnectio
} else {
PreparedStatement.NO_GENERATED_KEYS
}
return JdbcPreparedStatementImpl(connection.prepareStatement(sql, generated), returnKeys)
return JdbcPreparedStatementImpl(
connection.prepareStatement(sql, generated),
returnKeys,
connection.metaData.supportsGetGeneratedKeys()
)
}

override fun prepareStatement(sql: String, columns: Array<String>): PreparedStatementApi {
return JdbcPreparedStatementImpl(connection.prepareStatement(sql, columns), true)
return JdbcPreparedStatementImpl(
connection.prepareStatement(sql, columns),
true,
connection.metaData.supportsGetGeneratedKeys()
)
}

override fun executeInBatch(sqls: List<String>) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,18 +4,33 @@ import org.jetbrains.exposed.sql.BinaryColumnType
import org.jetbrains.exposed.sql.BlobColumnType
import org.jetbrains.exposed.sql.IColumnType
import org.jetbrains.exposed.sql.statements.api.PreparedStatementApi
import org.jetbrains.exposed.sql.vendors.SQLiteDialect
import org.jetbrains.exposed.sql.vendors.currentDialect
import java.io.InputStream
import java.sql.PreparedStatement
import java.sql.ResultSet
import java.sql.Types

class JdbcPreparedStatementImpl(val statement: PreparedStatement, val wasGeneratedKeysRequested: Boolean) : PreparedStatementApi {
class JdbcPreparedStatementImpl(
val statement: PreparedStatement,
private val wasGeneratedKeysRequested: Boolean,
private val supportsGetGeneratedKeys: Boolean
) : PreparedStatementApi {
override val resultSet: ResultSet?
get() = if (wasGeneratedKeysRequested) statement.generatedKeys else statement.resultSet
get() = when {
!wasGeneratedKeysRequested -> statement.resultSet
supportsGetGeneratedKeys -> statement.generatedKeys
currentDialect is SQLiteDialect -> {
statement.connection.prepareStatement("select last_insert_rowid();").executeQuery()
}
else -> statement.resultSet
}

override var fetchSize: Int?
get() = statement.fetchSize
set(value) { value?.let { statement.fetchSize = value } }
set(value) {
value?.let { statement.fetchSize = value }
}

override fun addBatch() {
statement.addBatch()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -103,12 +103,17 @@ class MathFunctionTests : FunctionsTestBase() {

@Test
fun testRoundFunction() {
withTable {
withTable { testDb ->
assertExpressionEqual(BigDecimal(10), RoundFunction(intLiteral(10), 0))
assertExpressionEqual(BigDecimal("10.00"), RoundFunction(intLiteral(10), 2))
assertExpressionEqual(BigDecimal(10), RoundFunction(doubleLiteral(10.455), 0))
assertExpressionEqual(BigDecimal(11), RoundFunction(doubleLiteral(10.555), 0))
assertExpressionEqual(BigDecimal("10.56"), RoundFunction(doubleLiteral(10.555), 2))
if (testDb == TestDB.SQLITE) {
// Change this when this issue is resolved https://www.sqlite.org/forum/forumpost/2801f84063
assertExpressionEqual(BigDecimal("10.55"), RoundFunction(doubleLiteral(10.555), 2))
} else {
assertExpressionEqual(BigDecimal("10.56"), RoundFunction(doubleLiteral(10.555), 2))
}
}
}

Expand Down

0 comments on commit ec74743

Please sign in to comment.