1 /* 2 * Copyright 2024 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package androidx.room.driver 18 19 import androidx.room.TransactionScope 20 import androidx.room.Transactor 21 import androidx.room.coroutines.ConnectionPool 22 import androidx.room.coroutines.RawConnectionAccessor 23 import androidx.sqlite.SQLiteConnection 24 import androidx.sqlite.SQLiteStatement 25 26 /** 27 * An implementation of a connection pool used in compatibility mode. This impl doesn't do any 28 * connection management since the SupportSQLite* APIs already internally do. 29 */ 30 internal class SupportSQLiteConnectionPool(internal val supportDriver: SupportSQLiteDriver) : 31 ConnectionPool { 32 private val supportConnection: SupportSQLitePooledConnection 33 get() { 34 val fileName = supportDriver.openHelper.databaseName ?: ":memory:" 35 return SupportSQLitePooledConnection(supportDriver.open(fileName)) 36 } 37 useConnectionnull38 override suspend fun <R> useConnection( 39 isReadOnly: Boolean, 40 block: suspend (Transactor) -> R 41 ): R { 42 return block.invoke(supportConnection) 43 } 44 closenull45 override fun close() { 46 supportDriver.openHelper.close() 47 } 48 } 49 50 private class SupportSQLitePooledConnection(val delegate: SupportSQLiteConnection) : 51 Transactor, RawConnectionAccessor { 52 53 private var currentTransactionType: Transactor.SQLiteTransactionType? = null 54 55 override val rawConnection: SQLiteConnection 56 get() = delegate 57 usePreparednull58 override suspend fun <R> usePrepared(sql: String, block: (SQLiteStatement) -> R): R { 59 return delegate.prepare(sql).use { block.invoke(it) } 60 } 61 withTransactionnull62 override suspend fun <R> withTransaction( 63 type: Transactor.SQLiteTransactionType, 64 block: suspend TransactionScope<R>.() -> R 65 ): R { 66 return transaction(type, block) 67 } 68 transactionnull69 private suspend fun <R> transaction( 70 type: Transactor.SQLiteTransactionType, 71 block: suspend TransactionScope<R>.() -> R 72 ): R { 73 val db = delegate.db 74 if (!db.inTransaction()) { 75 currentTransactionType = type 76 } 77 when (type) { 78 Transactor.SQLiteTransactionType.DEFERRED -> db.beginTransactionReadOnly() 79 Transactor.SQLiteTransactionType.IMMEDIATE -> db.beginTransactionNonExclusive() 80 Transactor.SQLiteTransactionType.EXCLUSIVE -> db.beginTransaction() 81 } 82 try { 83 val result = SupportSQLiteTransactor<R>().block() 84 db.setTransactionSuccessful() 85 return result 86 } catch (rollback: ConnectionPool.RollbackException) { 87 @Suppress("UNCHECKED_CAST") return rollback.result as R 88 } finally { 89 db.endTransaction() 90 if (!db.inTransaction()) { 91 currentTransactionType = null 92 } 93 } 94 } 95 inTransactionnull96 override suspend fun inTransaction(): Boolean { 97 return delegate.db.inTransaction() 98 } 99 100 private inner class SupportSQLiteTransactor<T> : TransactionScope<T>, RawConnectionAccessor { 101 102 override val rawConnection: SQLiteConnection 103 get() = this@SupportSQLitePooledConnection.rawConnection 104 usePreparednull105 override suspend fun <R> usePrepared(sql: String, block: (SQLiteStatement) -> R): R { 106 return this@SupportSQLitePooledConnection.usePrepared(sql, block) 107 } 108 withNestedTransactionnull109 override suspend fun <R> withNestedTransaction( 110 block: suspend (TransactionScope<R>) -> R 111 ): R { 112 return transaction(checkNotNull(currentTransactionType), block) 113 } 114 rollbacknull115 override suspend fun rollback(result: T): Nothing { 116 throw ConnectionPool.RollbackException(result) 117 } 118 } 119 } 120