@@ -92,16 +92,25 @@ public class AndroidxSqliteDriver(
9292
9393 private val transactions = TransactionsThreadLocal ()
9494
95- private val statementsCache =
96- object : LruCache <Int , AndroidxStatement >(configuration.cacheSize) {
97- override fun entryRemoved (
98- evicted : Boolean ,
99- key : Int ,
100- oldValue : AndroidxStatement ,
101- newValue : AndroidxStatement ? ,
102- ) {
103- if (evicted) oldValue.close()
104- }
95+ private val statementsCache = HashMap <SQLiteConnection , LruCache <Int , AndroidxStatement >>()
96+
97+ private fun getStatementCache (connection : SQLiteConnection ) =
98+ when {
99+ configuration.cacheSize > 0 ->
100+ statementsCache.getOrPut(connection) {
101+ object : LruCache <Int , AndroidxStatement >(configuration.cacheSize) {
102+ override fun entryRemoved (
103+ evicted : Boolean ,
104+ key : Int ,
105+ oldValue : AndroidxStatement ,
106+ newValue : AndroidxStatement ? ,
107+ ) {
108+ if (evicted) oldValue.close()
109+ }
110+ }
111+ }
112+
113+ else -> null
105114 }
106115
107116 private var skipStatementsCache = true
@@ -228,7 +237,7 @@ public class AndroidxSqliteDriver(
228237 binders : (SqlPreparedStatement .() -> Unit )? ,
229238 result : AndroidxStatement .() -> T ,
230239 ): QueryResult .Value <T > {
231- val statementsCache = if (! skipStatementsCache) statementsCache else null
240+ val statementsCache = if (! skipStatementsCache) getStatementCache(connection) else null
232241 var statement: AndroidxStatement ? = null
233242 if (identifier != null && statementsCache != null ) {
234243 // remove temporarily from the cache if present
@@ -271,7 +280,12 @@ public class AndroidxSqliteDriver(
271280 return execute(
272281 identifier = identifier,
273282 connection = writerConnection,
274- createStatement = { AndroidxPreparedStatement (it.prepare(sql)) },
283+ createStatement = { c ->
284+ AndroidxPreparedStatement (
285+ sql = sql,
286+ statement = c.prepare(sql),
287+ )
288+ },
275289 binders = binders,
276290 result = { execute() },
277291 )
@@ -283,7 +297,12 @@ public class AndroidxSqliteDriver(
283297 return execute(
284298 identifier = identifier,
285299 connection = connection,
286- createStatement = { AndroidxPreparedStatement (it.prepare(sql)) },
300+ createStatement = { c ->
301+ AndroidxPreparedStatement (
302+ sql = sql,
303+ statement = c.prepare(sql),
304+ )
305+ },
287306 binders = binders,
288307 result = { execute() },
289308 )
@@ -306,7 +325,13 @@ public class AndroidxSqliteDriver(
306325 return execute(
307326 identifier = identifier,
308327 connection = connection,
309- createStatement = { AndroidxQuery (sql, it, parameters) },
328+ createStatement = { c ->
329+ AndroidxQuery (
330+ sql = sql,
331+ statement = c.prepare(sql),
332+ argCount = parameters,
333+ )
334+ },
310335 binders = binders,
311336 result = { executeQuery(mapper) },
312337 )
@@ -318,7 +343,13 @@ public class AndroidxSqliteDriver(
318343 return execute(
319344 identifier = identifier,
320345 connection = connection,
321- createStatement = { AndroidxQuery (sql, it, parameters) },
346+ createStatement = { c ->
347+ AndroidxQuery (
348+ sql = sql,
349+ statement = c.prepare(sql),
350+ argCount = parameters,
351+ )
352+ },
322353 binders = binders,
323354 result = { executeQuery(mapper) },
324355 )
@@ -330,7 +361,8 @@ public class AndroidxSqliteDriver(
330361 * are using any of the connections starting from when close is invoked
331362 */
332363 override fun close () {
333- statementsCache.evictAll()
364+ statementsCache.values.forEach { it.evictAll() }
365+ statementsCache.clear()
334366 connectionPool.close()
335367 }
336368
@@ -365,15 +397,15 @@ public class AndroidxSqliteDriver(
365397 0L -> schema.create(driver).value
366398 else -> schema.migrate(driver, currentVersion, schema.version, * migrationCallbacks).value
367399 }
368- skipStatementsCache = false
400+ skipStatementsCache = configuration.cacheSize == 0
369401 when (currentVersion) {
370402 0L -> onCreate()
371403 else -> onUpdate(currentVersion, schema.version)
372404 }
373405 writerConnection.prepare(" PRAGMA user_version = ${schema.version} " ).use { it.step() }
374406 }
375407 } else {
376- skipStatementsCache = false
408+ skipStatementsCache = configuration.cacheSize == 0
377409 }
378410
379411 onOpen()
@@ -393,6 +425,7 @@ internal interface AndroidxStatement : SqlPreparedStatement {
393425}
394426
395427private class AndroidxPreparedStatement (
428+ private val sql : String ,
396429 private val statement : SQLiteStatement ,
397430) : AndroidxStatement {
398431 override fun bindBytes (index : Int , bytes : ByteArray? ) {
@@ -430,6 +463,8 @@ private class AndroidxPreparedStatement(
430463 return statement.getColumnCount().toLong()
431464 }
432465
466+ override fun toString () = sql
467+
433468 override fun reset () {
434469 statement.reset()
435470 }
@@ -441,7 +476,7 @@ private class AndroidxPreparedStatement(
441476
442477private class AndroidxQuery (
443478 private val sql : String ,
444- private val connection : SQLiteConnection ,
479+ private val statement : SQLiteStatement ,
445480 argCount : Int ,
446481) : AndroidxStatement {
447482 private val binds = MutableList < ((SQLiteStatement ) -> Unit )? > (argCount) { null }
@@ -477,23 +512,22 @@ private class AndroidxQuery(
477512 override fun execute () = throw UnsupportedOperationException ()
478513
479514 override fun <R > executeQuery (mapper : (SqlCursor ) -> QueryResult <R >): R {
480- val statement = connection.prepare(sql)
481515 for (action in binds) {
482516 requireNotNull(action).invoke(statement)
483517 }
484518
485- return try {
486- mapper(AndroidxCursor (statement)).value
487- } finally {
488- statement.close()
489- }
519+ return mapper(AndroidxCursor (statement)).value
490520 }
491521
492522 override fun toString () = sql
493523
494- override fun reset () {}
524+ override fun reset () {
525+ statement.reset()
526+ }
495527
496- override fun close () {}
528+ override fun close () {
529+ statement.close()
530+ }
497531}
498532
499533private class AndroidxCursor (
0 commit comments