Converting all RoomDatabase related files in `room-runtime` from Java to Kotlin.
Test: Existing tests
Bug: 206859668
Relnote: Converting all RoomDatabase related files in `room-runtime` from Java to Kotlin.
Change-Id: Ie4b55827902c6ddcc4cc004de8bb5286823e9ab5
diff --git a/development/build_log_simplifier/messages.ignore b/development/build_log_simplifier/messages.ignore
index 684c9866..babcf97 100644
--- a/development/build_log_simplifier/messages.ignore
+++ b/development/build_log_simplifier/messages.ignore
@@ -643,5 +643,28 @@
Setting the namespace via a source AndroidManifest\.xml's package attribute is deprecated\.
Please instead set the namespace \(or testNamespace\) in the module's build\.gradle file, as described here: https://developer\.android\.com/studio/build/configure\-app\-module\#set\-namespace
This migration can be done automatically using the AGP Upgrade Assistant, please refer to https://developer\.android\.com/studio/build/agp\-upgrade\-assistant for more information\.
+# Room unresolved type error messages
+Found an unresolved type in androidx\.room\.RoomDatabase\.Builder\$createFromAsset\(kotlin\.String\) \(RoomDatabase\.kt:[0-9]+\)
+Found an unresolved type in androidx\.room\.RoomDatabase\.Builder\$createFromAsset\(kotlin\.String\,\ androidx\.room\.RoomDatabase\.PrepackagedDatabaseCallback\) \(RoomDatabase\.kt:[0-9]+\)
+Found an unresolved type in androidx\.room\.RoomDatabase\.Builder\$createFromFile\(java\.io\.File\) \(RoomDatabase\.kt:[0-9]+\)
+Found an unresolved type in androidx\.room\.RoomDatabase\.Builder\$createFromFile\(java\.io\.File\,\ androidx\.room\.RoomDatabase\.PrepackagedDatabaseCallback\) \(RoomDatabase\.kt:[0-9]+\)
+Found an unresolved type in androidx\.room\.RoomDatabase\.Builder\$createFromInputStream\(java\.util\.concurrent\.Callable\(\(java\.io\.InputStream\)\)\) \(RoomDatabase\.kt:[0-9]+\)
+Found an unresolved type in androidx\.room\.RoomDatabase\.Builder\$createFromInputStream\(java\.util\.concurrent\.Callable\(\(java\.io\.InputStream\)\), androidx\.room\.RoomDatabase\.PrepackagedDatabaseCallback\) \(RoomDatabase\.kt:[0-9]+\)
+Found an unresolved type in androidx\.room\.RoomDatabase\.Builder\$openHelperFactory\(androidx\.sqlite\.db\.SupportSQLiteOpenHelper\.Factory\) \(RoomDatabase\.kt:[0-9]+\)
+Found an unresolved type in androidx\.room\.RoomDatabase\.Builder\$addMigrations\(kotlin\.Array\(\(androidx\.room\.migration\.Migration\)\)\) \(RoomDatabase\.kt:[0-9]+\)
+Found an unresolved type in androidx\.room\.RoomDatabase\.Builder\$addAutoMigrationSpec\(androidx\.room\.migration\.AutoMigrationSpec\) \(RoomDatabase\.kt:[0-9]+\)
+Found an unresolved type in androidx\.room\.RoomDatabase\.Builder\$allowMainThreadQueries\(\) \(RoomDatabase\.kt:[0-9]+\)
+Found an unresolved type in androidx\.room\.RoomDatabase\.Builder\$setJournalMode\(androidx\.room\.RoomDatabase\.JournalMode\) \(RoomDatabase\.kt:[0-9]+\)
+Found an unresolved type in androidx\.room\.RoomDatabase\.Builder\$setQueryExecutor\(java\.util\.concurrent\.Executor\) \(RoomDatabase\.kt:[0-9]+\)
+Found an unresolved type in androidx\.room\.RoomDatabase\.Builder\$setTransactionExecutor\(java\.util\.concurrent\.Executor\) \(RoomDatabase\.kt:[0-9]+\)
+Found an unresolved type in androidx\.room\.RoomDatabase\.Builder\$enableMultiInstanceInvalidation\(\) \(RoomDatabase\.kt:[0-9]+\)
+Found an unresolved type in androidx\.room\.RoomDatabase\.Builder\$setMultiInstanceInvalidationServiceIntent\(android\.content\.Intent\) \(RoomDatabase\.kt:[0-9]+\)
+Found an unresolved type in androidx\.room\.RoomDatabase\.Builder\$fallbackToDestructiveMigration\(\) \(RoomDatabase\.kt:[0-9]+\)
+Found an unresolved type in androidx\.room\.RoomDatabase\.Builder\$fallbackToDestructiveMigrationFrom\(kotlin\.IntArray\) \(RoomDatabase\.kt:[0-9]+\)
+Found an unresolved type in androidx\.room\.RoomDatabase\.Builder\$fallbackToDestructiveMigrationOnDowngrade\(\) \(RoomDatabase\.kt:[0-9]+\)
+Found an unresolved type in androidx\.room\.RoomDatabase\.Builder\$addCallback\(androidx\.room\.RoomDatabase\.Callback\) \(RoomDatabase\.kt:[0-9]+\)
+Found an unresolved type in androidx\.room\.RoomDatabase\.Builder\$setQueryCallback\(androidx\.room\.RoomDatabase\.QueryCallback, java\.util\.concurrent\.Executor\) \(RoomDatabase\.kt:[0-9]+\)
+Found an unresolved type in androidx\.room\.RoomDatabase\.Builder\$addTypeConverter\(kotlin\.Any\) \(RoomDatabase\.kt:[0-9]+\)
+Found an unresolved type in androidx\.room\.RoomDatabase\.Builder\$setAutoCloseTimeout\(kotlin\.Long, java\.util\.concurrent\.TimeUnit\) \(RoomDatabase\.kt:[0-9]+\)
# > Task :room:integration-tests:room-testapp:mergeDexWithExpandProjectionDebugAndroidTest b/233674378
WARNING:D8: Application does not contain `androidx\.tracing\.Trace` as referenced in main-dex-list\.
diff --git a/room/integration-tests/kotlintestapp/src/androidTest/java/androidx/room/integration/kotlintestapp/test/AlteredTableColumnOrderTest.kt b/room/integration-tests/kotlintestapp/src/androidTest/java/androidx/room/integration/kotlintestapp/test/AlteredTableColumnOrderTest.kt
index 624daee..bcca49f 100644
--- a/room/integration-tests/kotlintestapp/src/androidTest/java/androidx/room/integration/kotlintestapp/test/AlteredTableColumnOrderTest.kt
+++ b/room/integration-tests/kotlintestapp/src/androidTest/java/androidx/room/integration/kotlintestapp/test/AlteredTableColumnOrderTest.kt
@@ -84,8 +84,8 @@
@Test
fun verifyDifferentColumnOrder() {
- val c1 = cleanDb.openHelper.writableDatabase.query("SELECT * FROM Foo")
- val c2 = migratedDb.openHelper.writableDatabase.query("SELECT * FROM Foo")
+ val c1 = cleanDb.getOpenHelper().writableDatabase.query("SELECT * FROM Foo")
+ val c2 = migratedDb.getOpenHelper().writableDatabase.query("SELECT * FROM Foo")
try {
val columnNames1 = c1.columnNames
val columnNames2 = c2.columnNames
diff --git a/room/integration-tests/kotlintestapp/src/androidTest/java/androidx/room/integration/kotlintestapp/test/ListenableFuturePagingSourceTest.kt b/room/integration-tests/kotlintestapp/src/androidTest/java/androidx/room/integration/kotlintestapp/test/ListenableFuturePagingSourceTest.kt
index 7eec936..3e1c6fc 100644
--- a/room/integration-tests/kotlintestapp/src/androidTest/java/androidx/room/integration/kotlintestapp/test/ListenableFuturePagingSourceTest.kt
+++ b/room/integration-tests/kotlintestapp/src/androidTest/java/androidx/room/integration/kotlintestapp/test/ListenableFuturePagingSourceTest.kt
@@ -35,6 +35,7 @@
import androidx.paging.Pager
import androidx.paging.PagingState
import androidx.room.Room
+import androidx.room.RoomDatabase
import androidx.room.androidx.room.integration.kotlintestapp.testutil.ItemStore
import androidx.room.androidx.room.integration.kotlintestapp.testutil.PagingDb
import androidx.room.androidx.room.integration.kotlintestapp.testutil.PagingEntity
@@ -85,18 +86,19 @@
ApplicationProvider.getApplicationContext(),
PagingDb::class.java
).setQueryCallback(
- { sqlQuery, _ ->
- if (Thread.currentThread() === mainThread) {
- mainThreadQueries.add(
- sqlQuery to Throwable().stackTraceToString()
- )
+ object : RoomDatabase.QueryCallback {
+ override fun onQuery(sqlQuery: String, bindArgs: List<Any?>) {
+ if (Thread.currentThread() === mainThread) {
+ mainThreadQueries.add(
+ sqlQuery to Throwable().stackTraceToString()
+ )
+ }
}
- },
- {
- // instantly execute the log callback so that we can check the thread.
- it.run()
}
- ).setQueryExecutor(queryExecutor)
+ ) {
+ // instantly execute the log callback so that we can check the thread.
+ it.run()
+ }.setQueryExecutor(queryExecutor)
.build()
}
diff --git a/room/integration-tests/kotlintestapp/src/androidTest/java/androidx/room/integration/kotlintestapp/test/MultiTypedPagingSourceTest.kt b/room/integration-tests/kotlintestapp/src/androidTest/java/androidx/room/integration/kotlintestapp/test/MultiTypedPagingSourceTest.kt
index a04a861..0ad43ab 100644
--- a/room/integration-tests/kotlintestapp/src/androidTest/java/androidx/room/integration/kotlintestapp/test/MultiTypedPagingSourceTest.kt
+++ b/room/integration-tests/kotlintestapp/src/androidTest/java/androidx/room/integration/kotlintestapp/test/MultiTypedPagingSourceTest.kt
@@ -21,6 +21,7 @@
import androidx.paging.PagingSource
import androidx.room.InvalidationTracker
import androidx.room.Room
+import androidx.room.RoomDatabase
import androidx.room.androidx.room.integration.kotlintestapp.testutil.ItemStore
import androidx.room.androidx.room.integration.kotlintestapp.testutil.PagingEntityDao
import androidx.room.androidx.room.integration.kotlintestapp.testutil.PagingDb
@@ -496,7 +497,7 @@
) {
if (preOpenDb) {
// trigger db open
- db.openHelper.writableDatabase
+ db.getOpenHelper().writableDatabase
}
runTest {
@@ -757,18 +758,19 @@
ApplicationProvider.getApplicationContext(),
PagingDb::class.java
).setQueryCallback(
- { sqlQuery, _ ->
- if (Thread.currentThread() === mainThread) {
- mainThreadQueries.add(
- sqlQuery to Throwable().stackTraceToString()
- )
+ object : RoomDatabase.QueryCallback {
+ override fun onQuery(sqlQuery: String, bindArgs: List<Any?>) {
+ if (Thread.currentThread() === mainThread) {
+ mainThreadQueries.add(
+ sqlQuery to Throwable().stackTraceToString()
+ )
+ }
}
- },
- {
- // instantly execute the log callback so that we can check the thread.
- it.run()
}
- ).setQueryExecutor(queryExecutor)
+ ) {
+ // instantly execute the log callback so that we can check the thread.
+ it.run()
+ }.setQueryExecutor(queryExecutor)
.build()
}
diff --git a/room/integration-tests/kotlintestapp/src/androidTest/java/androidx/room/integration/kotlintestapp/test/QueryInterceptorTest.kt b/room/integration-tests/kotlintestapp/src/androidTest/java/androidx/room/integration/kotlintestapp/test/QueryInterceptorTest.kt
index 8ad0e02..950a0f1 100644
--- a/room/integration-tests/kotlintestapp/src/androidTest/java/androidx/room/integration/kotlintestapp/test/QueryInterceptorTest.kt
+++ b/room/integration-tests/kotlintestapp/src/androidTest/java/androidx/room/integration/kotlintestapp/test/QueryInterceptorTest.kt
@@ -48,7 +48,7 @@
@JvmField
val countingTaskExecutorRule = CountingTaskExecutorRule()
lateinit var mDatabase: QueryInterceptorTestDatabase
- var queryAndArgs = CopyOnWriteArrayList<Pair<String, ArrayList<Any>>>()
+ var queryAndArgs = CopyOnWriteArrayList<Pair<String, ArrayList<Any?>>>()
@Entity(tableName = "queryInterceptorTestDatabase")
data class QueryInterceptorEntity(@PrimaryKey val id: String, val description: String)
@@ -82,10 +82,12 @@
ApplicationProvider.getApplicationContext(),
QueryInterceptorTestDatabase::class.java
).setQueryCallback(
- RoomDatabase.QueryCallback { sqlQuery, bindArgs ->
- val argTrace = ArrayList<Any>()
- argTrace.addAll(bindArgs)
- queryAndArgs.add(Pair(sqlQuery, argTrace))
+ object : RoomDatabase.QueryCallback {
+ override fun onQuery(sqlQuery: String, bindArgs: List<Any?>) {
+ val argTrace = ArrayList<Any?>()
+ argTrace.addAll(bindArgs)
+ queryAndArgs.add(Pair(sqlQuery, argTrace))
+ }
},
MoreExecutors.directExecutor()
).build()
@@ -144,7 +146,7 @@
mDatabase.queryInterceptorDao().insert(
QueryInterceptorEntity("Insert", "Inserted a placeholder query")
)
- mDatabase.openHelper.writableDatabase.compileStatement(
+ mDatabase.getOpenHelper().writableDatabase.compileStatement(
"DELETE FROM queryInterceptorTestDatabase WHERE id=?"
).execute()
assertQueryLogged("DELETE FROM queryInterceptorTestDatabase WHERE id=?", emptyList())
@@ -152,7 +154,7 @@
@Test
fun testLoggingSupportSQLiteQuery() {
- mDatabase.openHelper.writableDatabase.query(
+ mDatabase.getOpenHelper().writableDatabase.query(
SimpleSQLiteQuery(
"INSERT OR ABORT INTO `queryInterceptorTestDatabase` (`id`,`description`) " +
"VALUES (?,?)",
@@ -168,7 +170,7 @@
@Test
fun testNullBindArgument() {
- mDatabase.openHelper.writableDatabase.query(
+ mDatabase.getOpenHelper().writableDatabase.query(
SimpleSQLiteQuery(
"INSERT OR ABORT INTO `queryInterceptorTestDatabase` (`id`,`description`) " +
"VALUES (?,?)",
@@ -188,10 +190,12 @@
ApplicationProvider.getApplicationContext(),
QueryInterceptorTestDatabase::class.java
).setQueryCallback(
- RoomDatabase.QueryCallback { sqlQuery, bindArgs ->
- val argTrace = ArrayList<Any>()
- argTrace.addAll(bindArgs)
- queryAndArgs.add(Pair(sqlQuery, argTrace))
+ object : RoomDatabase.QueryCallback {
+ override fun onQuery(sqlQuery: String, bindArgs: List<Any?>) {
+ val argTrace = ArrayList<Any?>()
+ argTrace.addAll(bindArgs)
+ queryAndArgs.add(Pair(sqlQuery, argTrace))
+ }
},
MoreExecutors.directExecutor()
)
diff --git a/room/integration-tests/kotlintestapp/src/androidTest/java/androidx/room/integration/kotlintestapp/test/Rx2PagingSourceTest.kt b/room/integration-tests/kotlintestapp/src/androidTest/java/androidx/room/integration/kotlintestapp/test/Rx2PagingSourceTest.kt
index fb55f16..25637bb 100644
--- a/room/integration-tests/kotlintestapp/src/androidTest/java/androidx/room/integration/kotlintestapp/test/Rx2PagingSourceTest.kt
+++ b/room/integration-tests/kotlintestapp/src/androidTest/java/androidx/room/integration/kotlintestapp/test/Rx2PagingSourceTest.kt
@@ -20,6 +20,7 @@
import androidx.paging.PagingState
import androidx.paging.rxjava2.RxPagingSource
import androidx.room.Room
+import androidx.room.RoomDatabase
import androidx.room.androidx.room.integration.kotlintestapp.testutil.ItemStore
import androidx.room.androidx.room.integration.kotlintestapp.testutil.PagingDb
import androidx.room.androidx.room.integration.kotlintestapp.testutil.PagingEntity
@@ -70,18 +71,19 @@
ApplicationProvider.getApplicationContext(),
PagingDb::class.java
).setQueryCallback(
- { sqlQuery, _ ->
- if (Thread.currentThread() === mainThread) {
- mainThreadQueries.add(
- sqlQuery to Throwable().stackTraceToString()
- )
+ object : RoomDatabase.QueryCallback {
+ override fun onQuery(sqlQuery: String, bindArgs: List<Any?>) {
+ if (Thread.currentThread() === mainThread) {
+ mainThreadQueries.add(
+ sqlQuery to Throwable().stackTraceToString()
+ )
+ }
}
- },
- {
- // instantly execute the log callback so that we can check the thread.
- it.run()
}
- ).build()
+ ) {
+ // instantly execute the log callback so that we can check the thread.
+ it.run()
+ }.build()
}
@After
diff --git a/room/integration-tests/kotlintestapp/src/androidTest/java/androidx/room/integration/kotlintestapp/test/Rx3PagingSourceTest.kt b/room/integration-tests/kotlintestapp/src/androidTest/java/androidx/room/integration/kotlintestapp/test/Rx3PagingSourceTest.kt
index ba13ecdb..4f64c587 100644
--- a/room/integration-tests/kotlintestapp/src/androidTest/java/androidx/room/integration/kotlintestapp/test/Rx3PagingSourceTest.kt
+++ b/room/integration-tests/kotlintestapp/src/androidTest/java/androidx/room/integration/kotlintestapp/test/Rx3PagingSourceTest.kt
@@ -20,6 +20,7 @@
import androidx.paging.PagingState
import androidx.paging.rxjava3.RxPagingSource
import androidx.room.Room
+import androidx.room.RoomDatabase
import androidx.room.androidx.room.integration.kotlintestapp.testutil.ItemStore
import androidx.room.androidx.room.integration.kotlintestapp.testutil.PagingDb
import androidx.room.androidx.room.integration.kotlintestapp.testutil.PagingEntity
@@ -67,18 +68,19 @@
ApplicationProvider.getApplicationContext(),
PagingDb::class.java
).setQueryCallback(
- { sqlQuery, _ ->
- if (Thread.currentThread() === mainThread) {
- mainThreadQueries.add(
- sqlQuery to Throwable().stackTraceToString()
- )
+ object : RoomDatabase.QueryCallback {
+ override fun onQuery(sqlQuery: String, bindArgs: List<Any?>) {
+ if (Thread.currentThread() === mainThread) {
+ mainThreadQueries.add(
+ sqlQuery to Throwable().stackTraceToString()
+ )
+ }
}
- },
- {
- // instantly execute the log callback so that we can check the thread.
- it.run()
}
- ).build()
+ ) {
+ // instantly execute the log callback so that we can check the thread.
+ it.run()
+ }.build()
}
@After
diff --git a/room/integration-tests/testapp/src/main/java/androidx/room/integration/testapp/SampleDatabaseService.java b/room/integration-tests/testapp/src/main/java/androidx/room/integration/testapp/SampleDatabaseService.java
index baafa36..38de612 100644
--- a/room/integration-tests/testapp/src/main/java/androidx/room/integration/testapp/SampleDatabaseService.java
+++ b/room/integration-tests/testapp/src/main/java/androidx/room/integration/testapp/SampleDatabaseService.java
@@ -27,6 +27,7 @@
import androidx.annotation.Nullable;
import androidx.lifecycle.LiveData;
import androidx.lifecycle.Observer;
+import androidx.room.ExperimentalRoomApi;
import androidx.room.Room;
import androidx.room.integration.testapp.database.Customer;
import androidx.room.integration.testapp.database.SampleDatabase;
@@ -104,6 +105,7 @@
@Nullable
@Override
+ @ExperimentalRoomApi
public IBinder onBind(Intent intent) {
String databaseName = intent.getStringExtra(DATABASE_NAME_PARAM);
if (databaseName == null) {
diff --git a/room/room-compiler/src/main/kotlin/androidx/room/writer/SQLiteOpenHelperWriter.kt b/room/room-compiler/src/main/kotlin/androidx/room/writer/SQLiteOpenHelperWriter.kt
index 600612d..14009da 100644
--- a/room/room-compiler/src/main/kotlin/androidx/room/writer/SQLiteOpenHelperWriter.kt
+++ b/room/room-compiler/src/main/kotlin/androidx/room/writer/SQLiteOpenHelperWriter.kt
@@ -33,7 +33,6 @@
import com.squareup.javapoet.TypeSpec
import java.util.ArrayDeque
import javax.lang.model.element.Modifier.PRIVATE
-import javax.lang.model.element.Modifier.PROTECTED
import javax.lang.model.element.Modifier.PUBLIC
/**
@@ -104,7 +103,7 @@
methodSpecs.add(
MethodSpec.methodBuilder(methodName).apply {
if (isPrimaryMethod) {
- addModifiers(PROTECTED)
+ addModifiers(PUBLIC)
addAnnotation(Override::class.java)
} else {
addModifiers(PRIVATE)
@@ -172,7 +171,7 @@
private fun createOnCreate(scope: CodeGenScope): MethodSpec {
return MethodSpec.methodBuilder("onCreate").apply {
- addModifiers(PROTECTED)
+ addModifiers(PUBLIC)
addAnnotation(Override::class.java)
addParameter(SupportDbTypeNames.DB, "_db")
invokeCallbacks(scope, "onCreate")
diff --git a/room/room-compiler/src/test/data/databasewriter/output/ComplexDatabase.java b/room/room-compiler/src/test/data/databasewriter/output/ComplexDatabase.java
index e9df8c9..c4529bd 100644
--- a/room/room-compiler/src/test/data/databasewriter/output/ComplexDatabase.java
+++ b/room/room-compiler/src/test/data/databasewriter/output/ComplexDatabase.java
@@ -62,7 +62,7 @@
}
@Override
- protected void onCreate(SupportSQLiteDatabase _db) {
+ public void onCreate(SupportSQLiteDatabase _db) {
if (mCallbacks != null) {
for (int _i = 0, _size = mCallbacks.size(); _i < _size; _i++) {
mCallbacks.get(_i).onCreate(_db);
@@ -91,7 +91,7 @@
}
@Override
- protected RoomOpenHelper.ValidationResult onValidateSchema(SupportSQLiteDatabase _db) {
+ public RoomOpenHelper.ValidationResult onValidateSchema(SupportSQLiteDatabase _db) {
final HashMap<String, TableInfo.Column> _columnsUser = new HashMap<String, TableInfo.Column>(4);
_columnsUser.put("uid", new TableInfo.Column("uid", "INTEGER", true, 1, null, TableInfo.CREATED_FROM_ENTITY));
_columnsUser.put("name", new TableInfo.Column("name", "TEXT", false, 0, null, TableInfo.CREATED_FROM_ENTITY));
diff --git a/room/room-ktx/src/androidTest/java/androidx/room/CoroutineRoomCancellationTest.kt b/room/room-ktx/src/androidTest/java/androidx/room/CoroutineRoomCancellationTest.kt
index 445b404..aaa8ba9 100644
--- a/room/room-ktx/src/androidTest/java/androidx/room/CoroutineRoomCancellationTest.kt
+++ b/room/room-ktx/src/androidTest/java/androidx/room/CoroutineRoomCancellationTest.kt
@@ -166,7 +166,7 @@
private class TestDatabase : RoomDatabase() {
- override fun createOpenHelper(config: DatabaseConfiguration?): SupportSQLiteOpenHelper {
+ override fun createOpenHelper(config: DatabaseConfiguration): SupportSQLiteOpenHelper {
throw UnsupportedOperationException("Shouldn't be called!")
}
diff --git a/room/room-ktx/src/main/java/androidx/room/CoroutinesRoom.kt b/room/room-ktx/src/main/java/androidx/room/CoroutinesRoom.kt
index 8d0b2a8..b552b3a 100644
--- a/room/room-ktx/src/main/java/androidx/room/CoroutinesRoom.kt
+++ b/room/room-ktx/src/main/java/androidx/room/CoroutinesRoom.kt
@@ -147,7 +147,7 @@
@RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
public fun RoomDatabase.getQueryDispatcher(): CoroutineDispatcher {
return backingFieldMap.getOrPut("QueryDispatcher") {
- queryExecutor.asCoroutineDispatcher()
+ getQueryExecutor().asCoroutineDispatcher()
} as CoroutineDispatcher
}
@@ -158,5 +158,5 @@
*/
internal val RoomDatabase.transactionDispatcher: CoroutineDispatcher
get() = backingFieldMap.getOrPut("TransactionDispatcher") {
- transactionExecutor.asCoroutineDispatcher()
+ getTransactionExecutor().asCoroutineDispatcher()
} as CoroutineDispatcher
diff --git a/room/room-ktx/src/main/java/androidx/room/RoomDatabase.kt b/room/room-ktx/src/main/java/androidx/room/RoomDatabaseExt.kt
similarity index 98%
rename from room/room-ktx/src/main/java/androidx/room/RoomDatabase.kt
rename to room/room-ktx/src/main/java/androidx/room/RoomDatabaseExt.kt
index 3f146ad..c46a15b 100644
--- a/room/room-ktx/src/main/java/androidx/room/RoomDatabase.kt
+++ b/room/room-ktx/src/main/java/androidx/room/RoomDatabaseExt.kt
@@ -13,6 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
+@file:JvmName("RoomDatabaseKt")
package androidx.room
@@ -96,7 +97,7 @@
coroutineContext[Job]?.invokeOnCompletion {
controlJob.cancel()
}
- val dispatcher = transactionExecutor.acquireTransactionThread(controlJob)
+ val dispatcher = getTransactionExecutor().acquireTransactionThread(controlJob)
val transactionElement = TransactionElement(controlJob, dispatcher)
val threadLocalElement =
suspendingTransactionId.asContextElement(System.identityHashCode(controlJob))
diff --git a/room/room-ktx/src/test/java/androidx/room/CoroutinesRoomTest.kt b/room/room-ktx/src/test/java/androidx/room/CoroutinesRoomTest.kt
index 28c8f23..46e43ec 100644
--- a/room/room-ktx/src/test/java/androidx/room/CoroutinesRoomTest.kt
+++ b/room/room-ktx/src/test/java/androidx/room/CoroutinesRoomTest.kt
@@ -26,7 +26,6 @@
import org.junit.Test
import org.junit.runner.RunWith
import org.junit.runners.JUnit4
-import java.util.concurrent.Callable
import kotlin.coroutines.ContinuationInterceptor
@RunWith(JUnit4::class)
@@ -43,7 +42,7 @@
db = database,
inTransaction = false,
tableNames = arrayOf("Pet"),
- callable = Callable {
+ callable = {
callableExecuted = true
expectedResult
}
@@ -66,12 +65,12 @@
// Use runBlocking dispatcher as query dispatchers, keeps the tests consistent.
private fun testRun(block: suspend CoroutineScope.() -> Unit) = runBlocking {
- database.backingFieldMap["QueryDispatcher"] = coroutineContext[ContinuationInterceptor]
+ database.backingFieldMap["QueryDispatcher"] = coroutineContext[ContinuationInterceptor]!!
block.invoke(this)
}
private class TestDatabase : RoomDatabase() {
- override fun createOpenHelper(config: DatabaseConfiguration?): SupportSQLiteOpenHelper {
+ override fun createOpenHelper(config: DatabaseConfiguration): SupportSQLiteOpenHelper {
throw UnsupportedOperationException("Shouldn't be called!")
}
diff --git a/room/room-paging-guava/src/main/java/androidx/room/paging/guava/LimitOffsetListenableFuturePagingSource.kt b/room/room-paging-guava/src/main/java/androidx/room/paging/guava/LimitOffsetListenableFuturePagingSource.kt
index 6e2839d..26a5e4e 100644
--- a/room/room-paging-guava/src/main/java/androidx/room/paging/guava/LimitOffsetListenableFuturePagingSource.kt
+++ b/room/room-paging-guava/src/main/java/androidx/room/paging/guava/LimitOffsetListenableFuturePagingSource.kt
@@ -77,7 +77,7 @@
nonInitialLoad(params, tempCount)
}
},
- db.queryExecutor
+ db.getQueryExecutor()
)
}
diff --git a/room/room-paging-rxjava2/src/main/java/androidx/room/paging/rxjava2/LimitOffsetRxPagingSource.kt b/room/room-paging-rxjava2/src/main/java/androidx/room/paging/rxjava2/LimitOffsetRxPagingSource.kt
index c4dab32..6a6a0ef 100644
--- a/room/room-paging-rxjava2/src/main/java/androidx/room/paging/rxjava2/LimitOffsetRxPagingSource.kt
+++ b/room/room-paging-rxjava2/src/main/java/androidx/room/paging/rxjava2/LimitOffsetRxPagingSource.kt
@@ -62,7 +62,7 @@
}
override fun loadSingle(params: LoadParams<Int>): Single<LoadResult<Int, Value>> {
- val scheduler = Schedulers.from(db.queryExecutor)
+ val scheduler = Schedulers.from(db.getQueryExecutor())
return createSingle {
observer.registerIfNecessary(db)
val tempCount = itemCount.get()
diff --git a/room/room-paging-rxjava3/src/main/java/androidx/room/paging/rxjava3/LimitOffsetRxPagingSource.kt b/room/room-paging-rxjava3/src/main/java/androidx/room/paging/rxjava3/LimitOffsetRxPagingSource.kt
index 55021b9..f907252 100644
--- a/room/room-paging-rxjava3/src/main/java/androidx/room/paging/rxjava3/LimitOffsetRxPagingSource.kt
+++ b/room/room-paging-rxjava3/src/main/java/androidx/room/paging/rxjava3/LimitOffsetRxPagingSource.kt
@@ -62,7 +62,7 @@
}
override fun loadSingle(params: LoadParams<Int>): Single<LoadResult<Int, Value>> {
- val scheduler = Schedulers.from(db.queryExecutor)
+ val scheduler = Schedulers.from(db.getQueryExecutor())
return createSingle {
observer.registerIfNecessary(db)
val tempCount = itemCount.get()
diff --git a/room/room-paging/src/androidTest/kotlin/androidx/room/paging/LimitOffsetPagingSourceTest.kt b/room/room-paging/src/androidTest/kotlin/androidx/room/paging/LimitOffsetPagingSourceTest.kt
index a8795ae..991314c 100644
--- a/room/room-paging/src/androidTest/kotlin/androidx/room/paging/LimitOffsetPagingSourceTest.kt
+++ b/room/room-paging/src/androidTest/kotlin/androidx/room/paging/LimitOffsetPagingSourceTest.kt
@@ -801,20 +801,20 @@
ApplicationProvider.getApplicationContext(),
LimitOffsetTestDb::class.java
).setQueryCallback(
- { sqlQuery, _ ->
- if (Thread.currentThread() === mainThread) {
- mainThreadQueries.add(
- sqlQuery to Throwable().stackTraceToString()
- )
+ object : RoomDatabase.QueryCallback {
+ override fun onQuery(sqlQuery: String, bindArgs: List<Any?>) {
+ if (Thread.currentThread() === mainThread) {
+ mainThreadQueries.add(
+ sqlQuery to Throwable().stackTraceToString()
+ )
+ }
}
- },
- {
- // instantly execute the log callback so that we can check the thread.
- it.run()
}
- ).setQueryExecutor(queryExecutor)
+ ) {
+ // instantly execute the log callback so that we can check the thread.
+ it.run()
+ }.setQueryExecutor(queryExecutor)
.build()
-
dao = db.dao
}
diff --git a/room/room-runtime/api/current.ignore b/room/room-runtime/api/current.ignore
index 7e52e76..8a044d9 100644
--- a/room/room-runtime/api/current.ignore
+++ b/room/room-runtime/api/current.ignore
@@ -11,3 +11,47 @@
Method androidx.room.Room.databaseBuilder has changed return type from androidx.room.RoomDatabase.Builder<T!> to androidx.room.RoomDatabase.Builder<T>
ChangedType: androidx.room.Room#inMemoryDatabaseBuilder(android.content.Context, Class<T>):
Method androidx.room.Room.inMemoryDatabaseBuilder has changed return type from androidx.room.RoomDatabase.Builder<T!> to androidx.room.RoomDatabase.Builder<T>
+ChangedType: androidx.room.RoomDatabase.Builder#addAutoMigrationSpec(androidx.room.migration.AutoMigrationSpec):
+ Method androidx.room.RoomDatabase.Builder.addAutoMigrationSpec has changed return type from androidx.room.RoomDatabase.Builder<T!> to androidx.room.RoomDatabase.Builder<T>
+ChangedType: androidx.room.RoomDatabase.Builder#addCallback(androidx.room.RoomDatabase.Callback):
+ Method androidx.room.RoomDatabase.Builder.addCallback has changed return type from androidx.room.RoomDatabase.Builder<T!> to androidx.room.RoomDatabase.Builder<T>
+ChangedType: androidx.room.RoomDatabase.Builder#addMigrations(androidx.room.migration.Migration...):
+ Method androidx.room.RoomDatabase.Builder.addMigrations has changed return type from androidx.room.RoomDatabase.Builder<T!> to androidx.room.RoomDatabase.Builder<T>
+ChangedType: androidx.room.RoomDatabase.Builder#addTypeConverter(Object):
+ Method androidx.room.RoomDatabase.Builder.addTypeConverter has changed return type from androidx.room.RoomDatabase.Builder<T!> to androidx.room.RoomDatabase.Builder<T>
+ChangedType: androidx.room.RoomDatabase.Builder#allowMainThreadQueries():
+ Method androidx.room.RoomDatabase.Builder.allowMainThreadQueries has changed return type from androidx.room.RoomDatabase.Builder<T!> to androidx.room.RoomDatabase.Builder<T>
+ChangedType: androidx.room.RoomDatabase.Builder#createFromAsset(String):
+ Method androidx.room.RoomDatabase.Builder.createFromAsset has changed return type from androidx.room.RoomDatabase.Builder<T!> to androidx.room.RoomDatabase.Builder<T>
+ChangedType: androidx.room.RoomDatabase.Builder#createFromAsset(String, androidx.room.RoomDatabase.PrepackagedDatabaseCallback):
+ Method androidx.room.RoomDatabase.Builder.createFromAsset has changed return type from androidx.room.RoomDatabase.Builder<T!> to androidx.room.RoomDatabase.Builder<T>
+ChangedType: androidx.room.RoomDatabase.Builder#createFromFile(java.io.File):
+ Method androidx.room.RoomDatabase.Builder.createFromFile has changed return type from androidx.room.RoomDatabase.Builder<T!> to androidx.room.RoomDatabase.Builder<T>
+ChangedType: androidx.room.RoomDatabase.Builder#createFromFile(java.io.File, androidx.room.RoomDatabase.PrepackagedDatabaseCallback):
+ Method androidx.room.RoomDatabase.Builder.createFromFile has changed return type from androidx.room.RoomDatabase.Builder<T!> to androidx.room.RoomDatabase.Builder<T>
+ChangedType: androidx.room.RoomDatabase.Builder#createFromInputStream(java.util.concurrent.Callable<java.io.InputStream>):
+ Method androidx.room.RoomDatabase.Builder.createFromInputStream has changed return type from androidx.room.RoomDatabase.Builder<T!> to androidx.room.RoomDatabase.Builder<T>
+ChangedType: androidx.room.RoomDatabase.Builder#createFromInputStream(java.util.concurrent.Callable<java.io.InputStream>, androidx.room.RoomDatabase.PrepackagedDatabaseCallback):
+ Method androidx.room.RoomDatabase.Builder.createFromInputStream has changed return type from androidx.room.RoomDatabase.Builder<T!> to androidx.room.RoomDatabase.Builder<T>
+ChangedType: androidx.room.RoomDatabase.Builder#enableMultiInstanceInvalidation():
+ Method androidx.room.RoomDatabase.Builder.enableMultiInstanceInvalidation has changed return type from androidx.room.RoomDatabase.Builder<T!> to androidx.room.RoomDatabase.Builder<T>
+ChangedType: androidx.room.RoomDatabase.Builder#fallbackToDestructiveMigration():
+ Method androidx.room.RoomDatabase.Builder.fallbackToDestructiveMigration has changed return type from androidx.room.RoomDatabase.Builder<T!> to androidx.room.RoomDatabase.Builder<T>
+ChangedType: androidx.room.RoomDatabase.Builder#fallbackToDestructiveMigrationFrom(int...):
+ Method androidx.room.RoomDatabase.Builder.fallbackToDestructiveMigrationFrom has changed return type from androidx.room.RoomDatabase.Builder<T!> to androidx.room.RoomDatabase.Builder<T>
+ChangedType: androidx.room.RoomDatabase.Builder#fallbackToDestructiveMigrationOnDowngrade():
+ Method androidx.room.RoomDatabase.Builder.fallbackToDestructiveMigrationOnDowngrade has changed return type from androidx.room.RoomDatabase.Builder<T!> to androidx.room.RoomDatabase.Builder<T>
+ChangedType: androidx.room.RoomDatabase.Builder#openHelperFactory(androidx.sqlite.db.SupportSQLiteOpenHelper.Factory):
+ Method androidx.room.RoomDatabase.Builder.openHelperFactory has changed return type from androidx.room.RoomDatabase.Builder<T!> to androidx.room.RoomDatabase.Builder<T>
+ChangedType: androidx.room.RoomDatabase.Builder#setJournalMode(androidx.room.RoomDatabase.JournalMode):
+ Method androidx.room.RoomDatabase.Builder.setJournalMode has changed return type from androidx.room.RoomDatabase.Builder<T!> to androidx.room.RoomDatabase.Builder<T>
+ChangedType: androidx.room.RoomDatabase.Builder#setQueryCallback(androidx.room.RoomDatabase.QueryCallback, java.util.concurrent.Executor):
+ Method androidx.room.RoomDatabase.Builder.setQueryCallback has changed return type from androidx.room.RoomDatabase.Builder<T!> to androidx.room.RoomDatabase.Builder<T>
+ChangedType: androidx.room.RoomDatabase.Builder#setQueryExecutor(java.util.concurrent.Executor):
+ Method androidx.room.RoomDatabase.Builder.setQueryExecutor has changed return type from androidx.room.RoomDatabase.Builder<T!> to androidx.room.RoomDatabase.Builder<T>
+ChangedType: androidx.room.RoomDatabase.Builder#setTransactionExecutor(java.util.concurrent.Executor):
+ Method androidx.room.RoomDatabase.Builder.setTransactionExecutor has changed return type from androidx.room.RoomDatabase.Builder<T!> to androidx.room.RoomDatabase.Builder<T>
+ChangedType: androidx.room.RoomDatabase.MigrationContainer#findMigrationPath(int, int):
+ Method androidx.room.RoomDatabase.MigrationContainer.findMigrationPath has changed return type from java.util.List<androidx.room.migration.Migration!> to java.util.List<androidx.room.migration.Migration>
+ChangedType: androidx.room.RoomDatabase.MigrationContainer#getMigrations():
+ Method androidx.room.RoomDatabase.MigrationContainer.getMigrations has changed return type from java.util.Map<java.lang.Integer!,java.util.Map<java.lang.Integer!,androidx.room.migration.Migration!>!> to java.util.Map<java.lang.Integer,java.util.Map<java.lang.Integer,androidx.room.migration.Migration>>
diff --git a/room/room-runtime/api/current.txt b/room/room-runtime/api/current.txt
index c627a7cb..1e4b78c 100644
--- a/room/room-runtime/api/current.txt
+++ b/room/room-runtime/api/current.txt
@@ -58,80 +58,86 @@
method @Deprecated public void beginTransaction();
method @WorkerThread public abstract void clearAllTables();
method public void close();
- method public androidx.sqlite.db.SupportSQLiteStatement! compileStatement(String);
+ method public androidx.sqlite.db.SupportSQLiteStatement compileStatement(String sql);
method protected abstract androidx.room.InvalidationTracker createInvalidationTracker();
- method protected abstract androidx.sqlite.db.SupportSQLiteOpenHelper createOpenHelper(androidx.room.DatabaseConfiguration!);
+ method protected abstract androidx.sqlite.db.SupportSQLiteOpenHelper createOpenHelper(androidx.room.DatabaseConfiguration config);
method @Deprecated public void endTransaction();
method public androidx.room.InvalidationTracker getInvalidationTracker();
method public androidx.sqlite.db.SupportSQLiteOpenHelper getOpenHelper();
method public java.util.concurrent.Executor getQueryExecutor();
method public java.util.concurrent.Executor getTransactionExecutor();
- method public <T> T? getTypeConverter(Class<T!>);
+ method public <T> T? getTypeConverter(Class<T> klass);
method public boolean inTransaction();
- method @CallSuper public void init(androidx.room.DatabaseConfiguration);
- method protected void internalInitInvalidationTracker(androidx.sqlite.db.SupportSQLiteDatabase);
+ method @CallSuper public void init(androidx.room.DatabaseConfiguration configuration);
+ method protected void internalInitInvalidationTracker(androidx.sqlite.db.SupportSQLiteDatabase db);
method public boolean isOpen();
- method public android.database.Cursor query(String, Object![]?);
- method public android.database.Cursor query(androidx.sqlite.db.SupportSQLiteQuery);
- method public android.database.Cursor query(androidx.sqlite.db.SupportSQLiteQuery, android.os.CancellationSignal?);
- method public void runInTransaction(Runnable);
- method public <V> V! runInTransaction(java.util.concurrent.Callable<V!>);
+ method public android.database.Cursor query(String query, Object![]? args);
+ method public android.database.Cursor query(androidx.sqlite.db.SupportSQLiteQuery query, optional android.os.CancellationSignal? signal);
+ method public android.database.Cursor query(androidx.sqlite.db.SupportSQLiteQuery query);
+ method public void runInTransaction(Runnable body);
+ method public <V> V! runInTransaction(java.util.concurrent.Callable<V> body);
method @Deprecated public void setTransactionSuccessful();
- field @Deprecated protected volatile androidx.sqlite.db.SupportSQLiteDatabase! mDatabase;
+ property public androidx.room.InvalidationTracker invalidationTracker;
+ property public boolean isOpen;
+ field public static final androidx.room.RoomDatabase.Companion Companion;
+ field @Deprecated @kotlin.jvm.Volatile protected volatile androidx.sqlite.db.SupportSQLiteDatabase? mDatabase;
}
public static class RoomDatabase.Builder<T extends androidx.room.RoomDatabase> {
- method public androidx.room.RoomDatabase.Builder<T!> addAutoMigrationSpec(androidx.room.migration.AutoMigrationSpec);
- method public androidx.room.RoomDatabase.Builder<T!> addCallback(androidx.room.RoomDatabase.Callback);
- method public androidx.room.RoomDatabase.Builder<T!> addMigrations(androidx.room.migration.Migration!...);
- method public androidx.room.RoomDatabase.Builder<T!> addTypeConverter(Object);
- method public androidx.room.RoomDatabase.Builder<T!> allowMainThreadQueries();
+ method public androidx.room.RoomDatabase.Builder<T> addAutoMigrationSpec(androidx.room.migration.AutoMigrationSpec autoMigrationSpec);
+ method public androidx.room.RoomDatabase.Builder<T> addCallback(androidx.room.RoomDatabase.Callback callback);
+ method public androidx.room.RoomDatabase.Builder<T> addMigrations(androidx.room.migration.Migration... migrations);
+ method public androidx.room.RoomDatabase.Builder<T> addTypeConverter(Object typeConverter);
+ method public androidx.room.RoomDatabase.Builder<T> allowMainThreadQueries();
method public T build();
- method public androidx.room.RoomDatabase.Builder<T!> createFromAsset(String);
- method public androidx.room.RoomDatabase.Builder<T!> createFromAsset(String, androidx.room.RoomDatabase.PrepackagedDatabaseCallback);
- method public androidx.room.RoomDatabase.Builder<T!> createFromFile(java.io.File);
- method public androidx.room.RoomDatabase.Builder<T!> createFromFile(java.io.File, androidx.room.RoomDatabase.PrepackagedDatabaseCallback);
- method public androidx.room.RoomDatabase.Builder<T!> createFromInputStream(java.util.concurrent.Callable<java.io.InputStream!>);
- method public androidx.room.RoomDatabase.Builder<T!> createFromInputStream(java.util.concurrent.Callable<java.io.InputStream!>, androidx.room.RoomDatabase.PrepackagedDatabaseCallback);
- method public androidx.room.RoomDatabase.Builder<T!> enableMultiInstanceInvalidation();
- method public androidx.room.RoomDatabase.Builder<T!> fallbackToDestructiveMigration();
- method public androidx.room.RoomDatabase.Builder<T!> fallbackToDestructiveMigrationFrom(int...);
- method public androidx.room.RoomDatabase.Builder<T!> fallbackToDestructiveMigrationOnDowngrade();
- method public androidx.room.RoomDatabase.Builder<T!> openHelperFactory(androidx.sqlite.db.SupportSQLiteOpenHelper.Factory?);
- method public androidx.room.RoomDatabase.Builder<T!> setJournalMode(androidx.room.RoomDatabase.JournalMode);
- method public androidx.room.RoomDatabase.Builder<T!> setQueryCallback(androidx.room.RoomDatabase.QueryCallback, java.util.concurrent.Executor);
- method public androidx.room.RoomDatabase.Builder<T!> setQueryExecutor(java.util.concurrent.Executor);
- method public androidx.room.RoomDatabase.Builder<T!> setTransactionExecutor(java.util.concurrent.Executor);
+ method public androidx.room.RoomDatabase.Builder<T> createFromAsset(String databaseFilePath);
+ method public androidx.room.RoomDatabase.Builder<T> createFromAsset(String databaseFilePath, androidx.room.RoomDatabase.PrepackagedDatabaseCallback callback);
+ method public androidx.room.RoomDatabase.Builder<T> createFromFile(java.io.File databaseFile);
+ method public androidx.room.RoomDatabase.Builder<T> createFromFile(java.io.File databaseFile, androidx.room.RoomDatabase.PrepackagedDatabaseCallback callback);
+ method public androidx.room.RoomDatabase.Builder<T> createFromInputStream(java.util.concurrent.Callable<java.io.InputStream> inputStreamCallable);
+ method public androidx.room.RoomDatabase.Builder<T> createFromInputStream(java.util.concurrent.Callable<java.io.InputStream> inputStreamCallable, androidx.room.RoomDatabase.PrepackagedDatabaseCallback callback);
+ method public androidx.room.RoomDatabase.Builder<T> enableMultiInstanceInvalidation();
+ method public androidx.room.RoomDatabase.Builder<T> fallbackToDestructiveMigration();
+ method public androidx.room.RoomDatabase.Builder<T> fallbackToDestructiveMigrationFrom(int... startVersions);
+ method public androidx.room.RoomDatabase.Builder<T> fallbackToDestructiveMigrationOnDowngrade();
+ method public androidx.room.RoomDatabase.Builder<T> openHelperFactory(androidx.sqlite.db.SupportSQLiteOpenHelper.Factory? factory);
+ method public androidx.room.RoomDatabase.Builder<T> setJournalMode(androidx.room.RoomDatabase.JournalMode journalMode);
+ method public androidx.room.RoomDatabase.Builder<T> setQueryCallback(androidx.room.RoomDatabase.QueryCallback queryCallback, java.util.concurrent.Executor executor);
+ method public androidx.room.RoomDatabase.Builder<T> setQueryExecutor(java.util.concurrent.Executor executor);
+ method public androidx.room.RoomDatabase.Builder<T> setTransactionExecutor(java.util.concurrent.Executor executor);
}
public abstract static class RoomDatabase.Callback {
ctor public RoomDatabase.Callback();
- method public void onCreate(androidx.sqlite.db.SupportSQLiteDatabase);
- method public void onDestructiveMigration(androidx.sqlite.db.SupportSQLiteDatabase);
- method public void onOpen(androidx.sqlite.db.SupportSQLiteDatabase);
+ method public void onCreate(androidx.sqlite.db.SupportSQLiteDatabase db);
+ method public void onDestructiveMigration(androidx.sqlite.db.SupportSQLiteDatabase db);
+ method public void onOpen(androidx.sqlite.db.SupportSQLiteDatabase db);
+ }
+
+ public static final class RoomDatabase.Companion {
}
public enum RoomDatabase.JournalMode {
enum_constant public static final androidx.room.RoomDatabase.JournalMode AUTOMATIC;
enum_constant public static final androidx.room.RoomDatabase.JournalMode TRUNCATE;
- enum_constant @RequiresApi(android.os.Build.VERSION_CODES.JELLY_BEAN) public static final androidx.room.RoomDatabase.JournalMode WRITE_AHEAD_LOGGING;
+ enum_constant public static final androidx.room.RoomDatabase.JournalMode WRITE_AHEAD_LOGGING;
}
public static class RoomDatabase.MigrationContainer {
ctor public RoomDatabase.MigrationContainer();
- method public void addMigrations(androidx.room.migration.Migration!...);
- method public void addMigrations(java.util.List<androidx.room.migration.Migration!>);
- method public java.util.List<androidx.room.migration.Migration!>? findMigrationPath(int, int);
- method public java.util.Map<java.lang.Integer!,java.util.Map<java.lang.Integer!,androidx.room.migration.Migration!>!> getMigrations();
+ method public void addMigrations(androidx.room.migration.Migration... migrations);
+ method public void addMigrations(java.util.List<? extends androidx.room.migration.Migration> migrations);
+ method public java.util.List<androidx.room.migration.Migration>? findMigrationPath(int start, int end);
+ method public java.util.Map<java.lang.Integer,java.util.Map<java.lang.Integer,androidx.room.migration.Migration>> getMigrations();
}
public abstract static class RoomDatabase.PrepackagedDatabaseCallback {
ctor public RoomDatabase.PrepackagedDatabaseCallback();
- method public void onOpenPrepackagedDatabase(androidx.sqlite.db.SupportSQLiteDatabase);
+ method public void onOpenPrepackagedDatabase(androidx.sqlite.db.SupportSQLiteDatabase db);
}
public static interface RoomDatabase.QueryCallback {
- method public void onQuery(String, java.util.List<java.lang.Object!>);
+ method public void onQuery(String sqlQuery, java.util.List<?> bindArgs);
}
}
diff --git a/room/room-runtime/api/public_plus_experimental_current.txt b/room/room-runtime/api/public_plus_experimental_current.txt
index 8eb135c..0232e3b 100644
--- a/room/room-runtime/api/public_plus_experimental_current.txt
+++ b/room/room-runtime/api/public_plus_experimental_current.txt
@@ -66,82 +66,88 @@
method @Deprecated public void beginTransaction();
method @WorkerThread public abstract void clearAllTables();
method public void close();
- method public androidx.sqlite.db.SupportSQLiteStatement! compileStatement(String);
+ method public androidx.sqlite.db.SupportSQLiteStatement compileStatement(String sql);
method protected abstract androidx.room.InvalidationTracker createInvalidationTracker();
- method protected abstract androidx.sqlite.db.SupportSQLiteOpenHelper createOpenHelper(androidx.room.DatabaseConfiguration!);
+ method protected abstract androidx.sqlite.db.SupportSQLiteOpenHelper createOpenHelper(androidx.room.DatabaseConfiguration config);
method @Deprecated public void endTransaction();
method public androidx.room.InvalidationTracker getInvalidationTracker();
method public androidx.sqlite.db.SupportSQLiteOpenHelper getOpenHelper();
method public java.util.concurrent.Executor getQueryExecutor();
method public java.util.concurrent.Executor getTransactionExecutor();
- method public <T> T? getTypeConverter(Class<T!>);
+ method public <T> T? getTypeConverter(Class<T> klass);
method public boolean inTransaction();
- method @CallSuper public void init(androidx.room.DatabaseConfiguration);
- method protected void internalInitInvalidationTracker(androidx.sqlite.db.SupportSQLiteDatabase);
+ method @CallSuper public void init(androidx.room.DatabaseConfiguration configuration);
+ method protected void internalInitInvalidationTracker(androidx.sqlite.db.SupportSQLiteDatabase db);
method public boolean isOpen();
- method public android.database.Cursor query(String, Object![]?);
- method public android.database.Cursor query(androidx.sqlite.db.SupportSQLiteQuery);
- method public android.database.Cursor query(androidx.sqlite.db.SupportSQLiteQuery, android.os.CancellationSignal?);
- method public void runInTransaction(Runnable);
- method public <V> V! runInTransaction(java.util.concurrent.Callable<V!>);
+ method public android.database.Cursor query(String query, Object![]? args);
+ method public android.database.Cursor query(androidx.sqlite.db.SupportSQLiteQuery query, optional android.os.CancellationSignal? signal);
+ method public android.database.Cursor query(androidx.sqlite.db.SupportSQLiteQuery query);
+ method public void runInTransaction(Runnable body);
+ method public <V> V! runInTransaction(java.util.concurrent.Callable<V> body);
method @Deprecated public void setTransactionSuccessful();
- field @Deprecated protected volatile androidx.sqlite.db.SupportSQLiteDatabase! mDatabase;
+ property public androidx.room.InvalidationTracker invalidationTracker;
+ property public boolean isOpen;
+ field public static final androidx.room.RoomDatabase.Companion Companion;
+ field @Deprecated @kotlin.jvm.Volatile protected volatile androidx.sqlite.db.SupportSQLiteDatabase? mDatabase;
}
public static class RoomDatabase.Builder<T extends androidx.room.RoomDatabase> {
- method public androidx.room.RoomDatabase.Builder<T!> addAutoMigrationSpec(androidx.room.migration.AutoMigrationSpec);
- method public androidx.room.RoomDatabase.Builder<T!> addCallback(androidx.room.RoomDatabase.Callback);
- method public androidx.room.RoomDatabase.Builder<T!> addMigrations(androidx.room.migration.Migration!...);
- method public androidx.room.RoomDatabase.Builder<T!> addTypeConverter(Object);
- method public androidx.room.RoomDatabase.Builder<T!> allowMainThreadQueries();
+ method public androidx.room.RoomDatabase.Builder<T> addAutoMigrationSpec(androidx.room.migration.AutoMigrationSpec autoMigrationSpec);
+ method public androidx.room.RoomDatabase.Builder<T> addCallback(androidx.room.RoomDatabase.Callback callback);
+ method public androidx.room.RoomDatabase.Builder<T> addMigrations(androidx.room.migration.Migration... migrations);
+ method public androidx.room.RoomDatabase.Builder<T> addTypeConverter(Object typeConverter);
+ method public androidx.room.RoomDatabase.Builder<T> allowMainThreadQueries();
method public T build();
- method public androidx.room.RoomDatabase.Builder<T!> createFromAsset(String);
- method public androidx.room.RoomDatabase.Builder<T!> createFromAsset(String, androidx.room.RoomDatabase.PrepackagedDatabaseCallback);
- method public androidx.room.RoomDatabase.Builder<T!> createFromFile(java.io.File);
- method public androidx.room.RoomDatabase.Builder<T!> createFromFile(java.io.File, androidx.room.RoomDatabase.PrepackagedDatabaseCallback);
- method public androidx.room.RoomDatabase.Builder<T!> createFromInputStream(java.util.concurrent.Callable<java.io.InputStream!>);
- method public androidx.room.RoomDatabase.Builder<T!> createFromInputStream(java.util.concurrent.Callable<java.io.InputStream!>, androidx.room.RoomDatabase.PrepackagedDatabaseCallback);
- method public androidx.room.RoomDatabase.Builder<T!> enableMultiInstanceInvalidation();
- method public androidx.room.RoomDatabase.Builder<T!> fallbackToDestructiveMigration();
- method public androidx.room.RoomDatabase.Builder<T!> fallbackToDestructiveMigrationFrom(int...);
- method public androidx.room.RoomDatabase.Builder<T!> fallbackToDestructiveMigrationOnDowngrade();
- method public androidx.room.RoomDatabase.Builder<T!> openHelperFactory(androidx.sqlite.db.SupportSQLiteOpenHelper.Factory?);
- method @androidx.room.ExperimentalRoomApi public androidx.room.RoomDatabase.Builder<T!> setAutoCloseTimeout(@IntRange(from=0) long, java.util.concurrent.TimeUnit);
- method public androidx.room.RoomDatabase.Builder<T!> setJournalMode(androidx.room.RoomDatabase.JournalMode);
- method @androidx.room.ExperimentalRoomApi public androidx.room.RoomDatabase.Builder<T!> setMultiInstanceInvalidationServiceIntent(android.content.Intent);
- method public androidx.room.RoomDatabase.Builder<T!> setQueryCallback(androidx.room.RoomDatabase.QueryCallback, java.util.concurrent.Executor);
- method public androidx.room.RoomDatabase.Builder<T!> setQueryExecutor(java.util.concurrent.Executor);
- method public androidx.room.RoomDatabase.Builder<T!> setTransactionExecutor(java.util.concurrent.Executor);
+ method public androidx.room.RoomDatabase.Builder<T> createFromAsset(String databaseFilePath);
+ method public androidx.room.RoomDatabase.Builder<T> createFromAsset(String databaseFilePath, androidx.room.RoomDatabase.PrepackagedDatabaseCallback callback);
+ method public androidx.room.RoomDatabase.Builder<T> createFromFile(java.io.File databaseFile);
+ method public androidx.room.RoomDatabase.Builder<T> createFromFile(java.io.File databaseFile, androidx.room.RoomDatabase.PrepackagedDatabaseCallback callback);
+ method public androidx.room.RoomDatabase.Builder<T> createFromInputStream(java.util.concurrent.Callable<java.io.InputStream> inputStreamCallable);
+ method public androidx.room.RoomDatabase.Builder<T> createFromInputStream(java.util.concurrent.Callable<java.io.InputStream> inputStreamCallable, androidx.room.RoomDatabase.PrepackagedDatabaseCallback callback);
+ method public androidx.room.RoomDatabase.Builder<T> enableMultiInstanceInvalidation();
+ method public androidx.room.RoomDatabase.Builder<T> fallbackToDestructiveMigration();
+ method public androidx.room.RoomDatabase.Builder<T> fallbackToDestructiveMigrationFrom(int... startVersions);
+ method public androidx.room.RoomDatabase.Builder<T> fallbackToDestructiveMigrationOnDowngrade();
+ method public androidx.room.RoomDatabase.Builder<T> openHelperFactory(androidx.sqlite.db.SupportSQLiteOpenHelper.Factory? factory);
+ method @androidx.room.ExperimentalRoomApi public androidx.room.RoomDatabase.Builder<T> setAutoCloseTimeout(@IntRange(from=0L) long autoCloseTimeout, java.util.concurrent.TimeUnit autoCloseTimeUnit);
+ method public androidx.room.RoomDatabase.Builder<T> setJournalMode(androidx.room.RoomDatabase.JournalMode journalMode);
+ method @androidx.room.ExperimentalRoomApi public androidx.room.RoomDatabase.Builder<T> setMultiInstanceInvalidationServiceIntent(android.content.Intent invalidationServiceIntent);
+ method public androidx.room.RoomDatabase.Builder<T> setQueryCallback(androidx.room.RoomDatabase.QueryCallback queryCallback, java.util.concurrent.Executor executor);
+ method public androidx.room.RoomDatabase.Builder<T> setQueryExecutor(java.util.concurrent.Executor executor);
+ method public androidx.room.RoomDatabase.Builder<T> setTransactionExecutor(java.util.concurrent.Executor executor);
}
public abstract static class RoomDatabase.Callback {
ctor public RoomDatabase.Callback();
- method public void onCreate(androidx.sqlite.db.SupportSQLiteDatabase);
- method public void onDestructiveMigration(androidx.sqlite.db.SupportSQLiteDatabase);
- method public void onOpen(androidx.sqlite.db.SupportSQLiteDatabase);
+ method public void onCreate(androidx.sqlite.db.SupportSQLiteDatabase db);
+ method public void onDestructiveMigration(androidx.sqlite.db.SupportSQLiteDatabase db);
+ method public void onOpen(androidx.sqlite.db.SupportSQLiteDatabase db);
+ }
+
+ public static final class RoomDatabase.Companion {
}
public enum RoomDatabase.JournalMode {
enum_constant public static final androidx.room.RoomDatabase.JournalMode AUTOMATIC;
enum_constant public static final androidx.room.RoomDatabase.JournalMode TRUNCATE;
- enum_constant @RequiresApi(android.os.Build.VERSION_CODES.JELLY_BEAN) public static final androidx.room.RoomDatabase.JournalMode WRITE_AHEAD_LOGGING;
+ enum_constant public static final androidx.room.RoomDatabase.JournalMode WRITE_AHEAD_LOGGING;
}
public static class RoomDatabase.MigrationContainer {
ctor public RoomDatabase.MigrationContainer();
- method public void addMigrations(androidx.room.migration.Migration!...);
- method public void addMigrations(java.util.List<androidx.room.migration.Migration!>);
- method public java.util.List<androidx.room.migration.Migration!>? findMigrationPath(int, int);
- method public java.util.Map<java.lang.Integer!,java.util.Map<java.lang.Integer!,androidx.room.migration.Migration!>!> getMigrations();
+ method public void addMigrations(androidx.room.migration.Migration... migrations);
+ method public void addMigrations(java.util.List<? extends androidx.room.migration.Migration> migrations);
+ method public java.util.List<androidx.room.migration.Migration>? findMigrationPath(int start, int end);
+ method public java.util.Map<java.lang.Integer,java.util.Map<java.lang.Integer,androidx.room.migration.Migration>> getMigrations();
}
public abstract static class RoomDatabase.PrepackagedDatabaseCallback {
ctor public RoomDatabase.PrepackagedDatabaseCallback();
- method public void onOpenPrepackagedDatabase(androidx.sqlite.db.SupportSQLiteDatabase);
+ method public void onOpenPrepackagedDatabase(androidx.sqlite.db.SupportSQLiteDatabase db);
}
public static interface RoomDatabase.QueryCallback {
- method public void onQuery(String, java.util.List<java.lang.Object!>);
+ method public void onQuery(String sqlQuery, java.util.List<?> bindArgs);
}
}
diff --git a/room/room-runtime/api/restricted_current.ignore b/room/room-runtime/api/restricted_current.ignore
index 6149a36..58e4397 100644
--- a/room/room-runtime/api/restricted_current.ignore
+++ b/room/room-runtime/api/restricted_current.ignore
@@ -19,6 +19,52 @@
Method androidx.room.Room.databaseBuilder has changed return type from androidx.room.RoomDatabase.Builder<T!> to androidx.room.RoomDatabase.Builder<T>
ChangedType: androidx.room.Room#inMemoryDatabaseBuilder(android.content.Context, Class<T>):
Method androidx.room.Room.inMemoryDatabaseBuilder has changed return type from androidx.room.RoomDatabase.Builder<T!> to androidx.room.RoomDatabase.Builder<T>
+ChangedType: androidx.room.RoomDatabase#mCallbacks:
+ Field androidx.room.RoomDatabase.mCallbacks has changed type from java.util.List<androidx.room.RoomDatabase.Callback!> to java.util.List<? extends androidx.room.RoomDatabase.Callback>
+ChangedType: androidx.room.RoomDatabase.Builder#addAutoMigrationSpec(androidx.room.migration.AutoMigrationSpec):
+ Method androidx.room.RoomDatabase.Builder.addAutoMigrationSpec has changed return type from androidx.room.RoomDatabase.Builder<T!> to androidx.room.RoomDatabase.Builder<T>
+ChangedType: androidx.room.RoomDatabase.Builder#addCallback(androidx.room.RoomDatabase.Callback):
+ Method androidx.room.RoomDatabase.Builder.addCallback has changed return type from androidx.room.RoomDatabase.Builder<T!> to androidx.room.RoomDatabase.Builder<T>
+ChangedType: androidx.room.RoomDatabase.Builder#addMigrations(androidx.room.migration.Migration...):
+ Method androidx.room.RoomDatabase.Builder.addMigrations has changed return type from androidx.room.RoomDatabase.Builder<T!> to androidx.room.RoomDatabase.Builder<T>
+ChangedType: androidx.room.RoomDatabase.Builder#addTypeConverter(Object):
+ Method androidx.room.RoomDatabase.Builder.addTypeConverter has changed return type from androidx.room.RoomDatabase.Builder<T!> to androidx.room.RoomDatabase.Builder<T>
+ChangedType: androidx.room.RoomDatabase.Builder#allowMainThreadQueries():
+ Method androidx.room.RoomDatabase.Builder.allowMainThreadQueries has changed return type from androidx.room.RoomDatabase.Builder<T!> to androidx.room.RoomDatabase.Builder<T>
+ChangedType: androidx.room.RoomDatabase.Builder#createFromAsset(String):
+ Method androidx.room.RoomDatabase.Builder.createFromAsset has changed return type from androidx.room.RoomDatabase.Builder<T!> to androidx.room.RoomDatabase.Builder<T>
+ChangedType: androidx.room.RoomDatabase.Builder#createFromAsset(String, androidx.room.RoomDatabase.PrepackagedDatabaseCallback):
+ Method androidx.room.RoomDatabase.Builder.createFromAsset has changed return type from androidx.room.RoomDatabase.Builder<T!> to androidx.room.RoomDatabase.Builder<T>
+ChangedType: androidx.room.RoomDatabase.Builder#createFromFile(java.io.File):
+ Method androidx.room.RoomDatabase.Builder.createFromFile has changed return type from androidx.room.RoomDatabase.Builder<T!> to androidx.room.RoomDatabase.Builder<T>
+ChangedType: androidx.room.RoomDatabase.Builder#createFromFile(java.io.File, androidx.room.RoomDatabase.PrepackagedDatabaseCallback):
+ Method androidx.room.RoomDatabase.Builder.createFromFile has changed return type from androidx.room.RoomDatabase.Builder<T!> to androidx.room.RoomDatabase.Builder<T>
+ChangedType: androidx.room.RoomDatabase.Builder#createFromInputStream(java.util.concurrent.Callable<java.io.InputStream>):
+ Method androidx.room.RoomDatabase.Builder.createFromInputStream has changed return type from androidx.room.RoomDatabase.Builder<T!> to androidx.room.RoomDatabase.Builder<T>
+ChangedType: androidx.room.RoomDatabase.Builder#createFromInputStream(java.util.concurrent.Callable<java.io.InputStream>, androidx.room.RoomDatabase.PrepackagedDatabaseCallback):
+ Method androidx.room.RoomDatabase.Builder.createFromInputStream has changed return type from androidx.room.RoomDatabase.Builder<T!> to androidx.room.RoomDatabase.Builder<T>
+ChangedType: androidx.room.RoomDatabase.Builder#enableMultiInstanceInvalidation():
+ Method androidx.room.RoomDatabase.Builder.enableMultiInstanceInvalidation has changed return type from androidx.room.RoomDatabase.Builder<T!> to androidx.room.RoomDatabase.Builder<T>
+ChangedType: androidx.room.RoomDatabase.Builder#fallbackToDestructiveMigration():
+ Method androidx.room.RoomDatabase.Builder.fallbackToDestructiveMigration has changed return type from androidx.room.RoomDatabase.Builder<T!> to androidx.room.RoomDatabase.Builder<T>
+ChangedType: androidx.room.RoomDatabase.Builder#fallbackToDestructiveMigrationFrom(int...):
+ Method androidx.room.RoomDatabase.Builder.fallbackToDestructiveMigrationFrom has changed return type from androidx.room.RoomDatabase.Builder<T!> to androidx.room.RoomDatabase.Builder<T>
+ChangedType: androidx.room.RoomDatabase.Builder#fallbackToDestructiveMigrationOnDowngrade():
+ Method androidx.room.RoomDatabase.Builder.fallbackToDestructiveMigrationOnDowngrade has changed return type from androidx.room.RoomDatabase.Builder<T!> to androidx.room.RoomDatabase.Builder<T>
+ChangedType: androidx.room.RoomDatabase.Builder#openHelperFactory(androidx.sqlite.db.SupportSQLiteOpenHelper.Factory):
+ Method androidx.room.RoomDatabase.Builder.openHelperFactory has changed return type from androidx.room.RoomDatabase.Builder<T!> to androidx.room.RoomDatabase.Builder<T>
+ChangedType: androidx.room.RoomDatabase.Builder#setJournalMode(androidx.room.RoomDatabase.JournalMode):
+ Method androidx.room.RoomDatabase.Builder.setJournalMode has changed return type from androidx.room.RoomDatabase.Builder<T!> to androidx.room.RoomDatabase.Builder<T>
+ChangedType: androidx.room.RoomDatabase.Builder#setQueryCallback(androidx.room.RoomDatabase.QueryCallback, java.util.concurrent.Executor):
+ Method androidx.room.RoomDatabase.Builder.setQueryCallback has changed return type from androidx.room.RoomDatabase.Builder<T!> to androidx.room.RoomDatabase.Builder<T>
+ChangedType: androidx.room.RoomDatabase.Builder#setQueryExecutor(java.util.concurrent.Executor):
+ Method androidx.room.RoomDatabase.Builder.setQueryExecutor has changed return type from androidx.room.RoomDatabase.Builder<T!> to androidx.room.RoomDatabase.Builder<T>
+ChangedType: androidx.room.RoomDatabase.Builder#setTransactionExecutor(java.util.concurrent.Executor):
+ Method androidx.room.RoomDatabase.Builder.setTransactionExecutor has changed return type from androidx.room.RoomDatabase.Builder<T!> to androidx.room.RoomDatabase.Builder<T>
+ChangedType: androidx.room.RoomDatabase.MigrationContainer#findMigrationPath(int, int):
+ Method androidx.room.RoomDatabase.MigrationContainer.findMigrationPath has changed return type from java.util.List<androidx.room.migration.Migration!> to java.util.List<androidx.room.migration.Migration>
+ChangedType: androidx.room.RoomDatabase.MigrationContainer#getMigrations():
+ Method androidx.room.RoomDatabase.MigrationContainer.getMigrations has changed return type from java.util.Map<java.lang.Integer!,java.util.Map<java.lang.Integer!,androidx.room.migration.Migration!>!> to java.util.Map<java.lang.Integer,java.util.Map<java.lang.Integer,androidx.room.migration.Migration>>
ChangedType: androidx.room.util.FtsTableInfo#columns:
Field androidx.room.util.FtsTableInfo.columns has changed type from java.util.Set<java.lang.String!> to java.util.Set<java.lang.String>
ChangedType: androidx.room.util.FtsTableInfo#options:
diff --git a/room/room-runtime/api/restricted_current.txt b/room/room-runtime/api/restricted_current.txt
index 84d16c9..0cfdc74 100644
--- a/room/room-runtime/api/restricted_current.txt
+++ b/room/room-runtime/api/restricted_current.txt
@@ -97,125 +97,152 @@
method @Deprecated public void beginTransaction();
method @WorkerThread public abstract void clearAllTables();
method public void close();
- method public androidx.sqlite.db.SupportSQLiteStatement! compileStatement(String);
+ method public androidx.sqlite.db.SupportSQLiteStatement compileStatement(String sql);
method protected abstract androidx.room.InvalidationTracker createInvalidationTracker();
- method protected abstract androidx.sqlite.db.SupportSQLiteOpenHelper createOpenHelper(androidx.room.DatabaseConfiguration!);
+ method protected abstract androidx.sqlite.db.SupportSQLiteOpenHelper createOpenHelper(androidx.room.DatabaseConfiguration config);
method @Deprecated public void endTransaction();
method public androidx.room.InvalidationTracker getInvalidationTracker();
method public androidx.sqlite.db.SupportSQLiteOpenHelper getOpenHelper();
method public java.util.concurrent.Executor getQueryExecutor();
method public java.util.concurrent.Executor getTransactionExecutor();
- method public <T> T? getTypeConverter(Class<T!>);
+ method public <T> T? getTypeConverter(Class<T> klass);
method public boolean inTransaction();
- method @CallSuper public void init(androidx.room.DatabaseConfiguration);
- method protected void internalInitInvalidationTracker(androidx.sqlite.db.SupportSQLiteDatabase);
+ method @CallSuper public void init(androidx.room.DatabaseConfiguration configuration);
+ method protected void internalInitInvalidationTracker(androidx.sqlite.db.SupportSQLiteDatabase db);
method public boolean isOpen();
- method public android.database.Cursor query(String, Object![]?);
- method public android.database.Cursor query(androidx.sqlite.db.SupportSQLiteQuery);
- method public android.database.Cursor query(androidx.sqlite.db.SupportSQLiteQuery, android.os.CancellationSignal?);
- method public void runInTransaction(Runnable);
- method public <V> V! runInTransaction(java.util.concurrent.Callable<V!>);
+ method public android.database.Cursor query(String query, Object![]? args);
+ method public android.database.Cursor query(androidx.sqlite.db.SupportSQLiteQuery query, optional android.os.CancellationSignal? signal);
+ method public android.database.Cursor query(androidx.sqlite.db.SupportSQLiteQuery query);
+ method public void runInTransaction(Runnable body);
+ method public <V> V! runInTransaction(java.util.concurrent.Callable<V> body);
method @Deprecated public void setTransactionSuccessful();
+ property public androidx.room.InvalidationTracker invalidationTracker;
+ property public boolean isOpen;
+ field public static final androidx.room.RoomDatabase.Companion Companion;
field @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public static final int MAX_BIND_PARAMETER_CNT = 999; // 0x3e7
- field @Deprecated @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) protected java.util.List<androidx.room.RoomDatabase.Callback!>? mCallbacks;
- field @Deprecated protected volatile androidx.sqlite.db.SupportSQLiteDatabase! mDatabase;
+ field @Deprecated @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) protected java.util.List<? extends androidx.room.RoomDatabase.Callback>? mCallbacks;
+ field @Deprecated @kotlin.jvm.Volatile protected volatile androidx.sqlite.db.SupportSQLiteDatabase? mDatabase;
}
public static class RoomDatabase.Builder<T extends androidx.room.RoomDatabase> {
- method public androidx.room.RoomDatabase.Builder<T!> addAutoMigrationSpec(androidx.room.migration.AutoMigrationSpec);
- method public androidx.room.RoomDatabase.Builder<T!> addCallback(androidx.room.RoomDatabase.Callback);
- method public androidx.room.RoomDatabase.Builder<T!> addMigrations(androidx.room.migration.Migration!...);
- method public androidx.room.RoomDatabase.Builder<T!> addTypeConverter(Object);
- method public androidx.room.RoomDatabase.Builder<T!> allowMainThreadQueries();
+ method public androidx.room.RoomDatabase.Builder<T> addAutoMigrationSpec(androidx.room.migration.AutoMigrationSpec autoMigrationSpec);
+ method public androidx.room.RoomDatabase.Builder<T> addCallback(androidx.room.RoomDatabase.Callback callback);
+ method public androidx.room.RoomDatabase.Builder<T> addMigrations(androidx.room.migration.Migration... migrations);
+ method public androidx.room.RoomDatabase.Builder<T> addTypeConverter(Object typeConverter);
+ method public androidx.room.RoomDatabase.Builder<T> allowMainThreadQueries();
method public T build();
- method public androidx.room.RoomDatabase.Builder<T!> createFromAsset(String);
- method public androidx.room.RoomDatabase.Builder<T!> createFromAsset(String, androidx.room.RoomDatabase.PrepackagedDatabaseCallback);
- method public androidx.room.RoomDatabase.Builder<T!> createFromFile(java.io.File);
- method public androidx.room.RoomDatabase.Builder<T!> createFromFile(java.io.File, androidx.room.RoomDatabase.PrepackagedDatabaseCallback);
- method public androidx.room.RoomDatabase.Builder<T!> createFromInputStream(java.util.concurrent.Callable<java.io.InputStream!>);
- method public androidx.room.RoomDatabase.Builder<T!> createFromInputStream(java.util.concurrent.Callable<java.io.InputStream!>, androidx.room.RoomDatabase.PrepackagedDatabaseCallback);
- method public androidx.room.RoomDatabase.Builder<T!> enableMultiInstanceInvalidation();
- method public androidx.room.RoomDatabase.Builder<T!> fallbackToDestructiveMigration();
- method public androidx.room.RoomDatabase.Builder<T!> fallbackToDestructiveMigrationFrom(int...);
- method public androidx.room.RoomDatabase.Builder<T!> fallbackToDestructiveMigrationOnDowngrade();
- method public androidx.room.RoomDatabase.Builder<T!> openHelperFactory(androidx.sqlite.db.SupportSQLiteOpenHelper.Factory?);
- method public androidx.room.RoomDatabase.Builder<T!> setJournalMode(androidx.room.RoomDatabase.JournalMode);
- method public androidx.room.RoomDatabase.Builder<T!> setQueryCallback(androidx.room.RoomDatabase.QueryCallback, java.util.concurrent.Executor);
- method public androidx.room.RoomDatabase.Builder<T!> setQueryExecutor(java.util.concurrent.Executor);
- method public androidx.room.RoomDatabase.Builder<T!> setTransactionExecutor(java.util.concurrent.Executor);
+ method public androidx.room.RoomDatabase.Builder<T> createFromAsset(String databaseFilePath);
+ method public androidx.room.RoomDatabase.Builder<T> createFromAsset(String databaseFilePath, androidx.room.RoomDatabase.PrepackagedDatabaseCallback callback);
+ method public androidx.room.RoomDatabase.Builder<T> createFromFile(java.io.File databaseFile);
+ method public androidx.room.RoomDatabase.Builder<T> createFromFile(java.io.File databaseFile, androidx.room.RoomDatabase.PrepackagedDatabaseCallback callback);
+ method public androidx.room.RoomDatabase.Builder<T> createFromInputStream(java.util.concurrent.Callable<java.io.InputStream> inputStreamCallable);
+ method public androidx.room.RoomDatabase.Builder<T> createFromInputStream(java.util.concurrent.Callable<java.io.InputStream> inputStreamCallable, androidx.room.RoomDatabase.PrepackagedDatabaseCallback callback);
+ method public androidx.room.RoomDatabase.Builder<T> enableMultiInstanceInvalidation();
+ method public androidx.room.RoomDatabase.Builder<T> fallbackToDestructiveMigration();
+ method public androidx.room.RoomDatabase.Builder<T> fallbackToDestructiveMigrationFrom(int... startVersions);
+ method public androidx.room.RoomDatabase.Builder<T> fallbackToDestructiveMigrationOnDowngrade();
+ method public androidx.room.RoomDatabase.Builder<T> openHelperFactory(androidx.sqlite.db.SupportSQLiteOpenHelper.Factory? factory);
+ method public androidx.room.RoomDatabase.Builder<T> setJournalMode(androidx.room.RoomDatabase.JournalMode journalMode);
+ method public androidx.room.RoomDatabase.Builder<T> setQueryCallback(androidx.room.RoomDatabase.QueryCallback queryCallback, java.util.concurrent.Executor executor);
+ method public androidx.room.RoomDatabase.Builder<T> setQueryExecutor(java.util.concurrent.Executor executor);
+ method public androidx.room.RoomDatabase.Builder<T> setTransactionExecutor(java.util.concurrent.Executor executor);
}
public abstract static class RoomDatabase.Callback {
ctor public RoomDatabase.Callback();
- method public void onCreate(androidx.sqlite.db.SupportSQLiteDatabase);
- method public void onDestructiveMigration(androidx.sqlite.db.SupportSQLiteDatabase);
- method public void onOpen(androidx.sqlite.db.SupportSQLiteDatabase);
+ method public void onCreate(androidx.sqlite.db.SupportSQLiteDatabase db);
+ method public void onDestructiveMigration(androidx.sqlite.db.SupportSQLiteDatabase db);
+ method public void onOpen(androidx.sqlite.db.SupportSQLiteDatabase db);
+ }
+
+ public static final class RoomDatabase.Companion {
}
public enum RoomDatabase.JournalMode {
enum_constant public static final androidx.room.RoomDatabase.JournalMode AUTOMATIC;
enum_constant public static final androidx.room.RoomDatabase.JournalMode TRUNCATE;
- enum_constant @RequiresApi(android.os.Build.VERSION_CODES.JELLY_BEAN) public static final androidx.room.RoomDatabase.JournalMode WRITE_AHEAD_LOGGING;
+ enum_constant public static final androidx.room.RoomDatabase.JournalMode WRITE_AHEAD_LOGGING;
}
public static class RoomDatabase.MigrationContainer {
ctor public RoomDatabase.MigrationContainer();
- method public void addMigrations(androidx.room.migration.Migration!...);
- method public void addMigrations(java.util.List<androidx.room.migration.Migration!>);
- method public java.util.List<androidx.room.migration.Migration!>? findMigrationPath(int, int);
- method public java.util.Map<java.lang.Integer!,java.util.Map<java.lang.Integer!,androidx.room.migration.Migration!>!> getMigrations();
+ method public void addMigrations(androidx.room.migration.Migration... migrations);
+ method public void addMigrations(java.util.List<? extends androidx.room.migration.Migration> migrations);
+ method public java.util.List<androidx.room.migration.Migration>? findMigrationPath(int start, int end);
+ method public java.util.Map<java.lang.Integer,java.util.Map<java.lang.Integer,androidx.room.migration.Migration>> getMigrations();
}
public abstract static class RoomDatabase.PrepackagedDatabaseCallback {
ctor public RoomDatabase.PrepackagedDatabaseCallback();
- method public void onOpenPrepackagedDatabase(androidx.sqlite.db.SupportSQLiteDatabase);
+ method public void onOpenPrepackagedDatabase(androidx.sqlite.db.SupportSQLiteDatabase db);
}
public static interface RoomDatabase.QueryCallback {
- method public void onQuery(String, java.util.List<java.lang.Object!>);
+ method public void onQuery(String sqlQuery, java.util.List<?> bindArgs);
}
@RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public class RoomOpenHelper extends androidx.sqlite.db.SupportSQLiteOpenHelper.Callback {
- ctor public RoomOpenHelper(androidx.room.DatabaseConfiguration, androidx.room.RoomOpenHelper.Delegate, String, String);
- ctor public RoomOpenHelper(androidx.room.DatabaseConfiguration, androidx.room.RoomOpenHelper.Delegate, String);
- method public void onCreate(androidx.sqlite.db.SupportSQLiteDatabase!);
- method public void onUpgrade(androidx.sqlite.db.SupportSQLiteDatabase!, int, int);
+ ctor public RoomOpenHelper(androidx.room.DatabaseConfiguration configuration, androidx.room.RoomOpenHelper.Delegate delegate, String identityHash, String legacyHash);
+ ctor public RoomOpenHelper(androidx.room.DatabaseConfiguration configuration, androidx.room.RoomOpenHelper.Delegate delegate, String legacyHash);
+ method public void onCreate(androidx.sqlite.db.SupportSQLiteDatabase db);
+ method public void onUpgrade(androidx.sqlite.db.SupportSQLiteDatabase db, int oldVersion, int newVersion);
+ field public static final androidx.room.RoomOpenHelper.Companion Companion;
+ }
+
+ public static final class RoomOpenHelper.Companion {
}
@RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public abstract static class RoomOpenHelper.Delegate {
- ctor public RoomOpenHelper.Delegate(int);
- method protected abstract void createAllTables(androidx.sqlite.db.SupportSQLiteDatabase!);
- method protected abstract void dropAllTables(androidx.sqlite.db.SupportSQLiteDatabase!);
- method protected abstract void onCreate(androidx.sqlite.db.SupportSQLiteDatabase!);
- method protected abstract void onOpen(androidx.sqlite.db.SupportSQLiteDatabase!);
- method protected void onPostMigrate(androidx.sqlite.db.SupportSQLiteDatabase!);
- method protected void onPreMigrate(androidx.sqlite.db.SupportSQLiteDatabase!);
- method protected androidx.room.RoomOpenHelper.ValidationResult onValidateSchema(androidx.sqlite.db.SupportSQLiteDatabase);
- method @Deprecated protected void validateMigration(androidx.sqlite.db.SupportSQLiteDatabase!);
+ ctor public RoomOpenHelper.Delegate(int version);
+ method public abstract void createAllTables(androidx.sqlite.db.SupportSQLiteDatabase database);
+ method public abstract void dropAllTables(androidx.sqlite.db.SupportSQLiteDatabase database);
+ method public abstract void onCreate(androidx.sqlite.db.SupportSQLiteDatabase database);
+ method public abstract void onOpen(androidx.sqlite.db.SupportSQLiteDatabase database);
+ method public void onPostMigrate(androidx.sqlite.db.SupportSQLiteDatabase database);
+ method public void onPreMigrate(androidx.sqlite.db.SupportSQLiteDatabase database);
+ method public androidx.room.RoomOpenHelper.ValidationResult onValidateSchema(androidx.sqlite.db.SupportSQLiteDatabase db);
+ method @Deprecated protected void validateMigration(androidx.sqlite.db.SupportSQLiteDatabase db);
field public final int version;
}
@RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public static class RoomOpenHelper.ValidationResult {
- ctor public RoomOpenHelper.ValidationResult(boolean, String?);
+ ctor public RoomOpenHelper.ValidationResult(boolean isValid, String? expectedFoundMsg);
field public final String? expectedFoundMsg;
field public final boolean isValid;
}
@RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public class RoomSQLiteQuery implements androidx.sqlite.db.SupportSQLiteProgram androidx.sqlite.db.SupportSQLiteQuery {
- method public static androidx.room.RoomSQLiteQuery! acquire(String!, int);
- method public void bindBlob(int, byte[]!);
- method public void bindDouble(int, double);
- method public void bindLong(int, long);
- method public void bindNull(int);
- method public void bindString(int, String!);
- method public void bindTo(androidx.sqlite.db.SupportSQLiteProgram!);
+ method public static final androidx.room.RoomSQLiteQuery acquire(String query, int argumentCount);
+ method public void bindBlob(int index, byte[] value);
+ method public void bindDouble(int index, double value);
+ method public void bindLong(int index, long value);
+ method public void bindNull(int index);
+ method public void bindString(int index, String value);
+ method public void bindTo(androidx.sqlite.db.SupportSQLiteProgram program);
method public void clearBindings();
method public void close();
- method public void copyArgumentsFrom(androidx.room.RoomSQLiteQuery!);
- method public static androidx.room.RoomSQLiteQuery! copyFrom(androidx.sqlite.db.SupportSQLiteQuery!);
+ method public void copyArgumentsFrom(androidx.room.RoomSQLiteQuery other);
+ method public static final androidx.room.RoomSQLiteQuery copyFrom(androidx.sqlite.db.SupportSQLiteQuery supportSQLiteQuery);
method public int getArgCount();
- method public String! getSql();
+ method public final int getCapacity();
+ method public String getSql();
+ method public void init(String query, int initArgCount);
method public void release();
+ property public final int capacity;
+ field public static final androidx.room.RoomSQLiteQuery.Companion Companion;
+ field @VisibleForTesting public static final int DESIRED_POOL_SIZE = 10; // 0xa
+ field @VisibleForTesting public static final int POOL_LIMIT = 15; // 0xf
+ field @VisibleForTesting public int argCount;
+ field @VisibleForTesting public final byte[]![] blobBindings;
+ field @VisibleForTesting public final double[] doubleBindings;
+ field @VisibleForTesting public final long[] longBindings;
+ field @VisibleForTesting public static final java.util.TreeMap<java.lang.Integer,androidx.room.RoomSQLiteQuery> queryPool;
+ field @VisibleForTesting public final String![] stringBindings;
+ }
+
+ public static final class RoomSQLiteQuery.Companion {
+ method public androidx.room.RoomSQLiteQuery acquire(String query, int argumentCount);
+ method public androidx.room.RoomSQLiteQuery copyFrom(androidx.sqlite.db.SupportSQLiteQuery supportSQLiteQuery);
}
@RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public abstract class SharedSQLiteStatement {
diff --git a/room/room-runtime/src/main/java/androidx/room/AutoCloser.kt b/room/room-runtime/src/main/java/androidx/room/AutoCloser.kt
index d4ec8f1..a0a5ea1 100644
--- a/room/room-runtime/src/main/java/androidx/room/AutoCloser.kt
+++ b/room/room-runtime/src/main/java/androidx/room/AutoCloser.kt
@@ -41,9 +41,8 @@
*
* @hide
*/
-// TODO: (b/218894771) Make internal once RoomDatabase is converted to Kotlin.
@RestrictTo(RestrictTo.Scope.LIBRARY)
-class AutoCloser(
+internal class AutoCloser(
autoCloseTimeoutAmount: Long,
autoCloseTimeUnit: TimeUnit,
autoCloseExecutor: Executor
diff --git a/room/room-runtime/src/main/java/androidx/room/InvalidationTracker.kt b/room/room-runtime/src/main/java/androidx/room/InvalidationTracker.kt
index 7352a17..d22305d 100644
--- a/room/room-runtime/src/main/java/androidx/room/InvalidationTracker.kt
+++ b/room/room-runtime/src/main/java/androidx/room/InvalidationTracker.kt
@@ -147,9 +147,7 @@
*
* @param autoCloser the autocloser associated with the db
*/
- // TODO (b/218894771): Make internal when RoomDatabase is converted to Kotlin
- @RestrictTo(RestrictTo.Scope.LIBRARY)
- fun setAutoCloser(autoCloser: AutoCloser) {
+ internal fun setAutoCloser(autoCloser: AutoCloser) {
this.autoCloser = autoCloser
autoCloser.setAutoCloseCallback(::onAutoCloseCallback)
}
@@ -187,21 +185,23 @@
}
}
- // TODO (b/218894771): Make internal when RoomDatabase is converted to Kotlin
@RestrictTo(RestrictTo.Scope.LIBRARY)
- fun startMultiInstanceInvalidation(context: Context, name: String, serviceIntent: Intent) {
+ internal fun startMultiInstanceInvalidation(
+ context: Context,
+ name: String,
+ serviceIntent: Intent
+ ) {
multiInstanceInvalidationClient = MultiInstanceInvalidationClient(
context = context,
name = name,
serviceIntent = serviceIntent,
invalidationTracker = this,
- executor = database.queryExecutor
+ executor = database.getQueryExecutor()
)
}
- // TODO (b/218894771): Make internal when RoomDatabase is converted to Kotlin
@RestrictTo(RestrictTo.Scope.LIBRARY)
- fun stopMultiInstanceInvalidation() {
+ internal fun stopMultiInstanceInvalidation() {
multiInstanceInvalidationClient?.stop()
multiInstanceInvalidationClient = null
}
@@ -352,7 +352,7 @@
}
if (!initialized) {
// trigger initialization
- database.openHelper.writableDatabase
+ database.getOpenHelper().writableDatabase
}
if (!initialized) {
Log.e(LOG_TAG, "database is not initialized even though it is open")
@@ -366,7 +366,7 @@
@RestrictTo(RestrictTo.Scope.LIBRARY)
val refreshRunnable: Runnable = object : Runnable {
override fun run() {
- val closeLock = database.closeLock
+ val closeLock = database.getCloseLock()
closeLock.lock()
val invalidatedTableIds: Set<Int> =
try {
@@ -386,7 +386,7 @@
// This transaction has to be on the underlying DB rather than the RoomDatabase
// in order to avoid a recursive loop after endTransaction.
- val db = database.openHelper.writableDatabase
+ val db = database.getOpenHelper().writableDatabase
db.beginTransactionNonExclusive()
val invalidatedTableIds: Set<Int>
try {
@@ -456,7 +456,7 @@
// db isn't closed until refresh is completed. This increment call must be
// matched with a corresponding call in refreshRunnable.
autoCloser?.incrementCountAndEnsureDbIsOpen()
- database.queryExecutor.execute(refreshRunnable)
+ database.getQueryExecutor().execute(refreshRunnable)
}
}
@@ -495,15 +495,14 @@
}
}
- // TODO (b/218894771): Make internal when RoomDatabase is converted to Kotlin
@RestrictTo(RestrictTo.Scope.LIBRARY)
- protected fun syncTriggers(database: SupportSQLiteDatabase) {
+ internal fun syncTriggers(database: SupportSQLiteDatabase) {
if (database.inTransaction()) {
// we won't run this inside another transaction.
return
}
try {
- val closeLock = this.database.closeLock
+ val closeLock = this.database.getCloseLock()
closeLock.lock()
try {
// Serialize adding and removing table trackers, this is specifically important
@@ -550,7 +549,7 @@
if (!database.isOpen) {
return
}
- syncTriggers(database.openHelper.writableDatabase)
+ syncTriggers(database.getOpenHelper().writableDatabase)
}
/**
diff --git a/room/room-runtime/src/main/java/androidx/room/RoomDatabase.kt b/room/room-runtime/src/main/java/androidx/room/RoomDatabase.kt
index 663ced0..c5dfbaf 100644
--- a/room/room-runtime/src/main/java/androidx/room/RoomDatabase.kt
+++ b/room/room-runtime/src/main/java/androidx/room/RoomDatabase.kt
@@ -13,94 +13,92 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
+package androidx.room
-package androidx.room;
-
-import android.annotation.SuppressLint;
-import android.app.ActivityManager;
-import android.content.Context;
-import android.content.Intent;
-import android.database.Cursor;
-import android.os.Build;
-import android.os.CancellationSignal;
-import android.os.Looper;
-import android.util.Log;
-
-import androidx.annotation.CallSuper;
-import androidx.annotation.IntRange;
-import androidx.annotation.NonNull;
-import androidx.annotation.Nullable;
-import androidx.annotation.RequiresApi;
-import androidx.annotation.RestrictTo;
-import androidx.annotation.WorkerThread;
-import androidx.arch.core.executor.ArchTaskExecutor;
-import androidx.room.migration.AutoMigrationSpec;
-import androidx.room.migration.Migration;
-import androidx.room.util.SneakyThrow;
-import androidx.sqlite.db.SimpleSQLiteQuery;
-import androidx.sqlite.db.SupportSQLiteCompat;
-import androidx.sqlite.db.SupportSQLiteDatabase;
-import androidx.sqlite.db.SupportSQLiteOpenHelper;
-import androidx.sqlite.db.SupportSQLiteQuery;
-import androidx.sqlite.db.SupportSQLiteStatement;
-import androidx.sqlite.db.framework.FrameworkSQLiteOpenHelperFactory;
-
-import java.io.File;
-import java.io.InputStream;
-import java.util.ArrayList;
-import java.util.BitSet;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.TreeMap;
-import java.util.concurrent.Callable;
-import java.util.concurrent.Executor;
-import java.util.concurrent.TimeUnit;
-import java.util.concurrent.locks.Lock;
-import java.util.concurrent.locks.ReentrantReadWriteLock;
+import android.annotation.SuppressLint
+import android.app.ActivityManager
+import android.content.Context
+import android.content.Intent
+import android.database.Cursor
+import android.os.Build
+import android.os.CancellationSignal
+import android.os.Looper
+import android.util.Log
+import androidx.annotation.CallSuper
+import androidx.annotation.IntRange
+import androidx.annotation.RestrictTo
+import androidx.annotation.VisibleForTesting
+import androidx.annotation.WorkerThread
+import androidx.arch.core.executor.ArchTaskExecutor
+import androidx.room.migration.AutoMigrationSpec
+import androidx.room.migration.Migration
+import androidx.sqlite.db.SimpleSQLiteQuery
+import androidx.sqlite.db.SupportSQLiteCompat
+import androidx.sqlite.db.SupportSQLiteDatabase
+import androidx.sqlite.db.SupportSQLiteOpenHelper
+import androidx.sqlite.db.SupportSQLiteQuery
+import androidx.sqlite.db.SupportSQLiteStatement
+import androidx.sqlite.db.framework.FrameworkSQLiteOpenHelperFactory
+import java.io.File
+import java.io.InputStream
+import java.util.BitSet
+import java.util.Collections
+import java.util.TreeMap
+import java.util.concurrent.Callable
+import java.util.concurrent.Executor
+import java.util.concurrent.TimeUnit
+import java.util.concurrent.locks.Lock
+import java.util.concurrent.locks.ReentrantReadWriteLock
/**
- * Base class for all Room databases. All classes that are annotated with {@link Database} must
+ * Base class for all Room databases. All classes that are annotated with [Database] must
* extend this class.
- * <p>
+ *
* RoomDatabase provides direct access to the underlying database implementation but you should
- * prefer using {@link Dao} classes.
+ * prefer using [Dao] classes.
+ *
+ * @constructor You cannot create an instance of a database, instead, you should acquire it via
+ * [#Room.databaseBuilder] or
+ * [#Room.inMemoryDatabaseBuilder].
*
* @see Database
*/
-public abstract class RoomDatabase {
- private static final String DB_IMPL_SUFFIX = "_Impl";
- /**
- * Unfortunately, we cannot read this value so we are only setting it to the SQLite default.
- *
- * @hide
- */
- @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP_PREFIX)
- public static final int MAX_BIND_PARAMETER_CNT = 999;
+abstract class RoomDatabase {
/**
* Set by the generated open helper.
*
- * @deprecated Will be hidden in the next release.
*/
- @Deprecated
- protected volatile SupportSQLiteDatabase mDatabase;
- private Executor mQueryExecutor;
- private Executor mTransactionExecutor;
- private SupportSQLiteOpenHelper mOpenHelper;
- private final InvalidationTracker mInvalidationTracker;
- private boolean mAllowMainThreadQueries;
- boolean mWriteAheadLoggingEnabled;
+ @Volatile
+ @Deprecated("Will be hidden in the next release.")
+ @JvmField
+ protected var mDatabase: SupportSQLiteDatabase? = null
+
+ private lateinit var queryExecutor: Executor
+
+ private lateinit var transactionExecutor: Executor
+
+ @VisibleForTesting
+ internal lateinit var openHelper: SupportSQLiteOpenHelper
+
+ /**
+ * The invalidation tracker for this database.
+ *
+ * You can use the invalidation tracker to get notified when certain tables in the database
+ * are modified.
+ *
+ * @return The invalidation tracker for the database.
+ */
+ open val invalidationTracker: InvalidationTracker = createInvalidationTracker()
+ private var allowMainThreadQueries = false
+ private var writeAheadLoggingEnabled = false
/**
* @hide
*/
@RestrictTo(RestrictTo.Scope.LIBRARY_GROUP_PREFIX)
- @Nullable
- @Deprecated
- protected List<Callback> mCallbacks;
+ @Deprecated("Will be hidden in a future release.")
+ @JvmField
+ protected var mCallbacks: List<Callback>? = null
/**
* A map of auto migration spec classes to their provided instance.
@@ -108,221 +106,188 @@
* @hide
*/
@RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
- @NonNull
- protected Map<Class<? extends AutoMigrationSpec>, AutoMigrationSpec> mAutoMigrationSpecs;
-
- private final ReentrantReadWriteLock mCloseLock = new ReentrantReadWriteLock();
-
- @Nullable
- private AutoCloser mAutoCloser;
+ protected var autoMigrationSpecs: MutableMap<Class<out AutoMigrationSpec>, AutoMigrationSpec> =
+ mutableMapOf()
+ private val readWriteLock = ReentrantReadWriteLock()
+ private var autoCloser: AutoCloser? = null
/**
- * {@link InvalidationTracker} uses this lock to prevent the database from closing while it is
+ * [InvalidationTracker] uses this lock to prevent the database from closing while it is
* querying database updates.
- * <p>
+ *
* The returned lock is reentrant and will allow multiple threads to acquire the lock
- * simultaneously until {@link #close()} is invoked in which the lock becomes exclusive as
+ * simultaneously until [close] is invoked in which the lock becomes exclusive as
* a way to let the InvalidationTracker finish its work before closing the database.
*
- * @return The lock for {@link #close()}.
+ * @return The lock for [close].
*/
- Lock getCloseLock() {
- return mCloseLock.readLock();
+ @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
+ open fun getCloseLock(): Lock {
+ return readWriteLock.readLock()
}
/**
+ * Suspending transaction id of the current thread.
+ *
* This id is only set on threads that are used to dispatch coroutines within a suspending
* database transaction.
*/
- private final ThreadLocal<Integer> mSuspendingTransactionId = new ThreadLocal<>();
-
- /**
- * Gets the suspending transaction id of the current thread.
- *
- * @hide
- */
- @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
- ThreadLocal<Integer> getSuspendingTransactionId() {
- return mSuspendingTransactionId;
- }
-
- private final Map<String, Object> mBackingFieldMap =
- Collections.synchronizedMap(new HashMap<>());
+ @get:RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
+ val suspendingTransactionId = ThreadLocal<Int>()
/**
* Gets the map for storing extension properties of Kotlin type.
*
* @hide
*/
- @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
- Map<String, Object> getBackingFieldMap() {
- return mBackingFieldMap;
- }
+ @get:RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
+ val backingFieldMap: MutableMap<String, Any> = Collections.synchronizedMap(mutableMapOf())
- // Updated later to an unmodifiable map when init is called.
- private final Map<Class<?>, Object> mTypeConverters;
+ private val typeConverters: MutableMap<Class<*>, Any> = mutableMapOf()
/**
* Gets the instance of the given Type Converter.
*
* @param klass The Type Converter class.
- * @param <T> The type of the expected Type Converter subclass.
+ * @param T The type of the expected Type Converter subclass.
* @return An instance of T if it is provided in the builder.
*/
- @SuppressWarnings("unchecked")
- @Nullable
- public <T> T getTypeConverter(@NonNull Class<T> klass) {
- return (T) mTypeConverters.get(klass);
+ @Suppress("UNCHECKED_CAST")
+ open fun <T> getTypeConverter(klass: Class<T>): T? {
+ return typeConverters[klass] as T?
}
/**
- * Creates a RoomDatabase.
- * <p>
- * You cannot create an instance of a database, instead, you should acquire it via
- * {@link Room#databaseBuilder(Context, Class, String)} or
- * {@link Room#inMemoryDatabaseBuilder(Context, Class)}.
- */
- public RoomDatabase() {
- mInvalidationTracker = createInvalidationTracker();
- mTypeConverters = new HashMap<>();
- mAutoMigrationSpecs = new HashMap<>();
- }
-
- /**
- * Called by {@link Room} when it is initialized.
+ * Called by [Room] when it is initialized.
+ *
+ * @throws IllegalArgumentException if initialization fails.
*
* @param configuration The database configuration.
*/
@CallSuper
- public void init(@NonNull DatabaseConfiguration configuration) {
- mOpenHelper = createOpenHelper(configuration);
- Set<Class<? extends AutoMigrationSpec>> requiredAutoMigrationSpecs =
- getRequiredAutoMigrationSpecs();
- BitSet usedSpecs = new BitSet();
- for (Class<? extends AutoMigrationSpec> spec : requiredAutoMigrationSpecs) {
- int foundIndex = -1;
- for (int providedIndex = configuration.autoMigrationSpecs.size() - 1;
- providedIndex >= 0; providedIndex--
- ) {
- Object provided = configuration.autoMigrationSpecs.get(providedIndex);
- if (spec.isAssignableFrom(provided.getClass())) {
- foundIndex = providedIndex;
- usedSpecs.set(foundIndex);
- break;
+ @Suppress("DEPRECATION")
+ open fun init(configuration: DatabaseConfiguration) {
+ openHelper = createOpenHelper(configuration)
+ val requiredAutoMigrationSpecs = getRequiredAutoMigrationSpecs()
+ val usedSpecs = BitSet()
+ for (spec in requiredAutoMigrationSpecs) {
+ var foundIndex = -1
+ for (providedIndex in configuration.autoMigrationSpecs.indices.reversed()) {
+ val provided: Any = configuration.autoMigrationSpecs[providedIndex]
+ if (spec.isAssignableFrom(provided.javaClass)) {
+ foundIndex = providedIndex
+ usedSpecs.set(foundIndex)
+ break
}
}
- if (foundIndex < 0) {
- throw new IllegalArgumentException(
- "A required auto migration spec (" + spec.getCanonicalName()
- + ") is missing in the database configuration.");
+ require(foundIndex >= 0) {
+ "A required auto migration spec (${spec.canonicalName}) is missing in the " +
+ "database configuration."
}
- mAutoMigrationSpecs.put(spec, configuration.autoMigrationSpecs.get(foundIndex));
+ autoMigrationSpecs[spec] = configuration.autoMigrationSpecs[foundIndex]
}
-
- for (int providedIndex = configuration.autoMigrationSpecs.size() - 1;
- providedIndex >= 0; providedIndex--) {
- if (!usedSpecs.get(providedIndex)) {
- throw new IllegalArgumentException("Unexpected auto migration specs found. "
- + "Annotate AutoMigrationSpec implementation with "
- + "@ProvidedAutoMigrationSpec annotation or remove this spec from the "
- + "builder.");
+ for (providedIndex in configuration.autoMigrationSpecs.indices.reversed()) {
+ require(usedSpecs[providedIndex]) {
+ "Unexpected auto migration specs found. " +
+ "Annotate AutoMigrationSpec implementation with " +
+ "@ProvidedAutoMigrationSpec annotation or remove this spec from the " +
+ "builder."
}
}
-
- List<Migration> autoMigrations = getAutoMigrations(mAutoMigrationSpecs);
- for (Migration autoMigration : autoMigrations) {
- boolean migrationExists = configuration.migrationContainer.getMigrations()
- .containsKey(autoMigration.startVersion);
+ val autoMigrations = getAutoMigrations(autoMigrationSpecs)
+ for (autoMigration in autoMigrations) {
+ val migrationExists = configuration.migrationContainer.getMigrations()
+ .containsKey(autoMigration.startVersion)
if (!migrationExists) {
- configuration.migrationContainer.addMigrations(autoMigration);
+ configuration.migrationContainer.addMigrations(autoMigration)
}
}
// Configure SqliteCopyOpenHelper if it is available:
- SQLiteCopyOpenHelper copyOpenHelper = unwrapOpenHelper(SQLiteCopyOpenHelper.class,
- mOpenHelper);
- if (copyOpenHelper != null) {
- copyOpenHelper.setDatabaseConfiguration(configuration);
+ unwrapOpenHelper(
+ clazz = SQLiteCopyOpenHelper::class.java,
+ openHelper = openHelper
+ )?.setDatabaseConfiguration(configuration)
+
+ unwrapOpenHelper(
+ clazz = AutoClosingRoomOpenHelper::class.java,
+ openHelper = openHelper
+ )?.let {
+ autoCloser = it.autoCloser
+ invalidationTracker.setAutoCloser(it.autoCloser)
}
- AutoClosingRoomOpenHelper autoClosingRoomOpenHelper =
- unwrapOpenHelper(AutoClosingRoomOpenHelper.class, mOpenHelper);
-
- if (autoClosingRoomOpenHelper != null) {
- mAutoCloser = autoClosingRoomOpenHelper.autoCloser;
- mInvalidationTracker.setAutoCloser(mAutoCloser);
+ val wal = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
+ val enabled = configuration.journalMode == JournalMode.WRITE_AHEAD_LOGGING
+ openHelper.setWriteAheadLoggingEnabled(enabled)
+ enabled
+ } else {
+ false
}
-
-
- boolean wal = false;
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
- wal = configuration.journalMode == JournalMode.WRITE_AHEAD_LOGGING;
- mOpenHelper.setWriteAheadLoggingEnabled(wal);
- }
- mCallbacks = configuration.callbacks;
- mQueryExecutor = configuration.queryExecutor;
- mTransactionExecutor = new TransactionExecutor(configuration.transactionExecutor);
- mAllowMainThreadQueries = configuration.allowMainThreadQueries;
- mWriteAheadLoggingEnabled = wal;
+ mCallbacks = configuration.callbacks
+ queryExecutor = configuration.queryExecutor
+ transactionExecutor = TransactionExecutor(configuration.transactionExecutor)
+ allowMainThreadQueries = configuration.allowMainThreadQueries
+ writeAheadLoggingEnabled = wal
if (configuration.multiInstanceInvalidationServiceIntent != null) {
- mInvalidationTracker.startMultiInstanceInvalidation(configuration.context,
- configuration.name, configuration.multiInstanceInvalidationServiceIntent);
+ requireNotNull(configuration.name)
+ invalidationTracker.startMultiInstanceInvalidation(
+ configuration.context,
+ configuration.name,
+ configuration.multiInstanceInvalidationServiceIntent
+ )
}
-
- Map<Class<?>, List<Class<?>>> requiredFactories = getRequiredTypeConverters();
+ val requiredFactories = getRequiredTypeConverters()
// indices for each converter on whether it is used or not so that we can throw an exception
// if developer provides an unused converter. It is not necessarily an error but likely
// to be because why would developer add a converter if it won't be used?
- BitSet used = new BitSet();
- for (Map.Entry<Class<?>, List<Class<?>>> entry : requiredFactories.entrySet()) {
- Class<?> daoName = entry.getKey();
- for (Class<?> converter : entry.getValue()) {
- int foundIndex = -1;
+ val used = BitSet()
+ requiredFactories.forEach { (daoName, converters) ->
+ for (converter in converters) {
+ var foundIndex = -1
// traverse provided converters in reverse so that newer one overrides
- for (int providedIndex = configuration.typeConverters.size() - 1;
- providedIndex >= 0; providedIndex--) {
- Object provided = configuration.typeConverters.get(providedIndex);
- if (converter.isAssignableFrom(provided.getClass())) {
- foundIndex = providedIndex;
- used.set(foundIndex);
- break;
+ for (providedIndex in configuration.typeConverters.indices.reversed()) {
+ val provided = configuration.typeConverters[providedIndex]
+ if (converter.isAssignableFrom(provided.javaClass)) {
+ foundIndex = providedIndex
+ used.set(foundIndex)
+ break
}
}
- if (foundIndex < 0) {
- throw new IllegalArgumentException(
- "A required type converter (" + converter + ") for"
- + " " + daoName.getCanonicalName()
- + " is missing in the database configuration.");
+ require(foundIndex >= 0) {
+ "A required type converter ($converter) for" +
+ " ${daoName.canonicalName} is missing in the database configuration."
}
- mTypeConverters.put(converter, configuration.typeConverters.get(foundIndex));
+ typeConverters[converter] = configuration.typeConverters[foundIndex]
}
}
// now, make sure all provided factories are used
- for (int providedIndex = configuration.typeConverters.size() - 1;
- providedIndex >= 0; providedIndex--) {
- if (!used.get(providedIndex)) {
- Object converter = configuration.typeConverters.get(providedIndex);
- throw new IllegalArgumentException("Unexpected type converter " + converter + ". "
- + "Annotate TypeConverter class with @ProvidedTypeConverter annotation "
- + "or remove this converter from the builder.");
+ for (providedIndex in configuration.typeConverters.indices.reversed()) {
+ if (!used[providedIndex]) {
+ val converter = configuration.typeConverters[providedIndex]
+ throw IllegalArgumentException(
+ "Unexpected type converter $converter. " +
+ "Annotate TypeConverter class with @ProvidedTypeConverter annotation " +
+ "or remove this converter from the builder."
+ )
}
}
}
/**
- * Returns a list of {@link Migration} of a database that have been automatically generated.
+ * Returns a list of [Migration] of a database that have been automatically generated.
*
* @return A list of migration instances each of which is a generated autoMigration
* @param autoMigrationSpecs
*
* @hide
*/
- @NonNull
@RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
- public List<Migration> getAutoMigrations(
- @NonNull Map<Class<? extends AutoMigrationSpec>, AutoMigrationSpec> autoMigrationSpecs
- ) {
- return Collections.emptyList();
+ @JvmSuppressWildcards // Suppress wildcards due to generated Java code
+ open fun getAutoMigrations(
+ autoMigrationSpecs: Map<Class<out AutoMigrationSpec>, AutoMigrationSpec>
+ ): List<Migration> {
+ return emptyList()
}
/**
@@ -330,29 +295,20 @@
*
* @param clazz the open helper type to search for
* @param openHelper the open helper to search through
- * @param <T> the type of clazz
+ * @param T the type of clazz
* @return the instance of clazz, otherwise null
*/
- @Nullable
- @SuppressWarnings("unchecked")
- private <T> T unwrapOpenHelper(Class<T> clazz, SupportSQLiteOpenHelper openHelper) {
+ @Suppress("UNCHECKED_CAST")
+ private fun <T> unwrapOpenHelper(clazz: Class<T>, openHelper: SupportSQLiteOpenHelper): T? {
if (clazz.isInstance(openHelper)) {
- return (T) openHelper;
+ return openHelper as T
}
- if (openHelper instanceof DelegatingOpenHelper) {
- return unwrapOpenHelper(clazz, ((DelegatingOpenHelper) openHelper).getDelegate());
- }
- return null;
- }
-
- /**
- * Returns the SQLite open helper used by this database.
- *
- * @return The SQLite open helper used by this database.
- */
- @NonNull
- public SupportSQLiteOpenHelper getOpenHelper() {
- return mOpenHelper;
+ return if (openHelper is DelegatingOpenHelper) {
+ unwrapOpenHelper(
+ clazz = clazz,
+ openHelper = openHelper.delegate
+ )
+ } else null
}
/**
@@ -363,111 +319,104 @@
* @param config The configuration of the Room database.
* @return A new SupportSQLiteOpenHelper to be used while connecting to the database.
*/
- @NonNull
- protected abstract SupportSQLiteOpenHelper createOpenHelper(DatabaseConfiguration config);
+ protected abstract fun createOpenHelper(config: DatabaseConfiguration): SupportSQLiteOpenHelper
/**
* Called when the RoomDatabase is created.
- * <p>
+ *
* This is already implemented by the generated code.
*
* @return Creates a new InvalidationTracker.
*/
- @NonNull
- protected abstract InvalidationTracker createInvalidationTracker();
+ protected abstract fun createInvalidationTracker(): InvalidationTracker
/**
* Returns a Map of String -> List<Class> where each entry has the `key` as the DAO name
* and `value` as the list of type converter classes that are necessary for the database to
* function.
- * <p>
+ *
* This is implemented by the generated code.
*
* @return Creates a map that will include all required type converters for this database.
*/
- @NonNull
@RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
- protected Map<Class<?>, List<Class<?>>> getRequiredTypeConverters() {
- return Collections.emptyMap();
+ protected open fun getRequiredTypeConverters(): Map<Class<*>, List<Class<*>>> {
+ return emptyMap()
}
/**
* Returns a Set of required AutoMigrationSpec classes.
- * <p>
+ *
* This is implemented by the generated code.
*
* @return Creates a set that will include all required auto migration specs for this database.
*
* @hide
*/
- @NonNull
@RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
- public Set<Class<? extends AutoMigrationSpec>> getRequiredAutoMigrationSpecs() {
- return Collections.emptySet();
+ open fun getRequiredAutoMigrationSpecs(): Set<Class<out AutoMigrationSpec>> {
+ return emptySet()
}
/**
* Deletes all rows from all the tables that are registered to this database as
- * {@link Database#entities()}.
- * <p>
- * This does NOT reset the auto-increment value generated by {@link PrimaryKey#autoGenerate()}.
- * <p>
+ * [Database.entities].
+ *
+ * This does NOT reset the auto-increment value generated by [PrimaryKey.autoGenerate].
+ *
* After deleting the rows, Room will set a WAL checkpoint and run VACUUM. This means that the
* data is completely erased. The space will be reclaimed by the system if the amount surpasses
* the threshold of database file size.
*
- * @see <a href="https://www.sqlite.org/fileformat.html">Database File Format</a>
+ * See SQLite documentation for details. [FileFormat](https://www.sqlite.org/fileformat.html)
*/
@WorkerThread
- public abstract void clearAllTables();
+ abstract fun clearAllTables()
/**
- * Returns true if database connection is open and initialized.
+ * True if database connection is open and initialized.
*
* @return true if the database connection is open, false otherwise.
*/
- public boolean isOpen() {
- // We need to special case for the auto closing database because mDatabase is the
- // underlying database and not the wrapped database.
- if (mAutoCloser != null) {
- return mAutoCloser.isActive();
+ @Suppress("Deprecation")
+ open val isOpen: Boolean
+ get() {
+ return (autoCloser?.isActive ?: mDatabase?.isOpen) == true
}
- final SupportSQLiteDatabase db = mDatabase;
- return db != null && db.isOpen();
- }
-
/**
* Closes the database if it is already open.
*/
- public void close() {
- if (isOpen()) {
- final Lock closeLock = mCloseLock.writeLock();
- closeLock.lock();
+ open fun close() {
+ if (isOpen) {
+ val closeLock: Lock = readWriteLock.writeLock()
+ closeLock.lock()
try {
- mInvalidationTracker.stopMultiInstanceInvalidation();
- mOpenHelper.close();
+ invalidationTracker.stopMultiInstanceInvalidation()
+ openHelper.close()
} finally {
- closeLock.unlock();
+ closeLock.unlock()
}
}
}
+ /** True if the calling thread is the main thread. */
+ internal val isMainThread: Boolean
+ get() = Looper.getMainLooper().thread === Thread.currentThread()
+
/**
* Asserts that we are not on the main thread.
*
* @hide
*/
- @SuppressWarnings("WeakerAccess")
- @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP_PREFIX)
- // used in generated code
- public void assertNotMainThread() {
- if (mAllowMainThreadQueries) {
- return;
+ @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP_PREFIX) // used in generated code
+ open fun assertNotMainThread() {
+ if (allowMainThreadQueries) {
+ return
}
- if (isMainThread()) {
- throw new IllegalStateException("Cannot access database on the main thread since"
- + " it may potentially lock the UI for a long period of time.");
+ check(!isMainThread) {
+ "Cannot access database on the main thread since" +
+ " it may potentially lock the UI for a long period of time."
}
}
@@ -476,20 +425,16 @@
*
* @hide
*/
- @SuppressWarnings("WeakerAccess")
- @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
- // used in generated code
- public void assertNotSuspendingTransaction() {
- if (!inTransaction() && mSuspendingTransactionId.get() != null) {
- throw new IllegalStateException("Cannot access database on a different coroutine"
- + " context inherited from a suspending transaction.");
+ @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP) // used in generated code
+ open fun assertNotSuspendingTransaction() {
+ check(inTransaction() || suspendingTransactionId.get() == null) {
+ "Cannot access database on a different coroutine" +
+ " context inherited from a suspending transaction."
}
}
-
// Below, there are wrapper methods for SupportSQLiteDatabase. This helps us track which
// methods we are using and also helps unit tests to mock this class without mocking
// all SQLite database methods.
-
/**
* Convenience method to query the database with arguments.
*
@@ -497,228 +442,210 @@
* @param args The bind arguments for the placeholders in the query
* @return A Cursor obtained by running the given query in the Room database.
*/
- @NonNull
- public Cursor query(@NonNull String query, @Nullable Object[] args) {
- return mOpenHelper.getWritableDatabase().query(new SimpleSQLiteQuery(query, args));
+ open fun query(query: String, args: Array<Any?>?): Cursor {
+ return openHelper.writableDatabase.query(SimpleSQLiteQuery(query, args))
}
/**
- * Wrapper for {@link SupportSQLiteDatabase#query(SupportSQLiteQuery)}.
- *
- * @param query The Query which includes the SQL and a bind callback for bind arguments.
- * @return Result of the query.
- */
- @NonNull
- public Cursor query(@NonNull SupportSQLiteQuery query) {
- return query(query, null);
- }
-
- /**
- * Wrapper for {@link SupportSQLiteDatabase#query(SupportSQLiteQuery)}.
+ * Wrapper for [SupportSQLiteDatabase.query].
*
* @param query The Query which includes the SQL and a bind callback for bind arguments.
* @param signal The cancellation signal to be attached to the query.
* @return Result of the query.
*/
- @NonNull
- public Cursor query(@NonNull SupportSQLiteQuery query, @Nullable CancellationSignal signal) {
- assertNotMainThread();
- assertNotSuspendingTransaction();
- if (signal != null && Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
- return mOpenHelper.getWritableDatabase().query(query, signal);
+ @JvmOverloads
+ open fun query(query: SupportSQLiteQuery, signal: CancellationSignal? = null): Cursor {
+ assertNotMainThread()
+ assertNotSuspendingTransaction()
+ return if (signal != null && Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
+ openHelper.writableDatabase.query(query, signal)
} else {
- return mOpenHelper.getWritableDatabase().query(query);
+ openHelper.writableDatabase.query(query)
}
}
/**
- * Wrapper for {@link SupportSQLiteDatabase#compileStatement(String)}.
+ * Wrapper for [SupportSQLiteDatabase.compileStatement].
*
* @param sql The query to compile.
* @return The compiled query.
*/
- public SupportSQLiteStatement compileStatement(@NonNull String sql) {
- assertNotMainThread();
- assertNotSuspendingTransaction();
- return mOpenHelper.getWritableDatabase().compileStatement(sql);
+ open fun compileStatement(sql: String): SupportSQLiteStatement {
+ assertNotMainThread()
+ assertNotSuspendingTransaction()
+ return openHelper.writableDatabase.compileStatement(sql)
}
/**
- * Wrapper for {@link SupportSQLiteDatabase#beginTransaction()}.
- *
- * @deprecated Use {@link #runInTransaction(Runnable)}
+ * Wrapper for [SupportSQLiteDatabase.beginTransaction].
*/
- @Deprecated
- public void beginTransaction() {
- assertNotMainThread();
- if (mAutoCloser == null) {
- internalBeginTransaction();
+ @Deprecated(
+ "beginTransaction() is deprecated",
+ ReplaceWith("runInTransaction(Runnable)")
+ )
+ open fun beginTransaction() {
+ assertNotMainThread()
+ val autoCloser = autoCloser
+ if (autoCloser == null) {
+ internalBeginTransaction()
} else {
- mAutoCloser.executeRefCountingFunction(db -> {
- internalBeginTransaction();
- return null;
- });
+ autoCloser.executeRefCountingFunction<Any?> {
+ internalBeginTransaction()
+ null
+ }
}
}
- private void internalBeginTransaction() {
- assertNotMainThread();
- SupportSQLiteDatabase database = mOpenHelper.getWritableDatabase();
- mInvalidationTracker.syncTriggers(database);
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN
- && database.isWriteAheadLoggingEnabled()) {
- database.beginTransactionNonExclusive();
+ private fun internalBeginTransaction() {
+ assertNotMainThread()
+ val database = openHelper.writableDatabase
+ invalidationTracker.syncTriggers(database)
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN &&
+ database.isWriteAheadLoggingEnabled
+ ) {
+ database.beginTransactionNonExclusive()
} else {
- database.beginTransaction();
+ database.beginTransaction()
}
}
/**
- * Wrapper for {@link SupportSQLiteDatabase#endTransaction()}.
- *
- * @deprecated Use {@link #runInTransaction(Runnable)}
+ * Wrapper for [SupportSQLiteDatabase.endTransaction].
*/
- @Deprecated
- public void endTransaction() {
- if (mAutoCloser == null) {
- internalEndTransaction();
+ @Deprecated(
+ "endTransaction() is deprecated",
+ ReplaceWith("runInTransaction(Runnable)")
+ )
+ open fun endTransaction() {
+ val autoCloser = autoCloser
+ if (autoCloser == null) {
+ internalEndTransaction()
} else {
- mAutoCloser.executeRefCountingFunction(db -> {
- internalEndTransaction();
- return null;
- });
+ autoCloser.executeRefCountingFunction<Any?> {
+ internalEndTransaction()
+ null
+ }
}
}
- private void internalEndTransaction() {
- mOpenHelper.getWritableDatabase().endTransaction();
+ private fun internalEndTransaction() {
+ openHelper.writableDatabase.endTransaction()
if (!inTransaction()) {
// enqueue refresh only if we are NOT in a transaction. Otherwise, wait for the last
// endTransaction call to do it.
- mInvalidationTracker.refreshVersionsAsync();
+ invalidationTracker.refreshVersionsAsync()
}
}
/**
+ * Returns the SQLite open helper used by this database.
+ *
+ * @return The SQLite open helper used by this database.
+ */
+ open fun getOpenHelper(): SupportSQLiteOpenHelper {
+ return openHelper
+ }
+
+ /**
* @return The Executor in use by this database for async queries.
*/
- @NonNull
- public Executor getQueryExecutor() {
- return mQueryExecutor;
+ open fun getQueryExecutor(): Executor {
+ return queryExecutor
}
/**
* @return The Executor in use by this database for async transactions.
*/
- @NonNull
- public Executor getTransactionExecutor() {
- return mTransactionExecutor;
+ open fun getTransactionExecutor(): Executor {
+ return transactionExecutor
}
/**
- * Wrapper for {@link SupportSQLiteDatabase#setTransactionSuccessful()}.
+ * Wrapper for [SupportSQLiteDatabase.setTransactionSuccessful].
*
- * @deprecated Use {@link #runInTransaction(Runnable)}
*/
- @Deprecated
- public void setTransactionSuccessful() {
- mOpenHelper.getWritableDatabase().setTransactionSuccessful();
+ @Deprecated(
+ "setTransactionSuccessful() is deprecated",
+ ReplaceWith("runInTransaction(Runnable)")
+ )
+ open fun setTransactionSuccessful() {
+ openHelper.writableDatabase.setTransactionSuccessful()
}
/**
- * Executes the specified {@link Runnable} in a database transaction. The transaction will be
- * marked as successful unless an exception is thrown in the {@link Runnable}.
- * <p>
+ * Executes the specified [Runnable] in a database transaction. The transaction will be
+ * marked as successful unless an exception is thrown in the [Runnable].
+ *
* Room will only perform at most one transaction at a time.
*
* @param body The piece of code to execute.
*/
- @SuppressWarnings("deprecation")
- public void runInTransaction(@NonNull Runnable body) {
- beginTransaction();
+ @Suppress("DEPRECATION")
+ open fun runInTransaction(body: Runnable) {
+ beginTransaction()
try {
- body.run();
- setTransactionSuccessful();
+ body.run()
+ setTransactionSuccessful()
} finally {
- endTransaction();
+ endTransaction()
}
}
/**
- * Executes the specified {@link Callable} in a database transaction. The transaction will be
- * marked as successful unless an exception is thrown in the {@link Callable}.
- * <p>
+ * Executes the specified [Callable] in a database transaction. The transaction will be
+ * marked as successful unless an exception is thrown in the [Callable].
+ *
* Room will only perform at most one transaction at a time.
*
* @param body The piece of code to execute.
- * @param <V> The type of the return value.
- * @return The value returned from the {@link Callable}.
+ * @param V The type of the return value.
+ * @return The value returned from the [Callable].
*/
- @SuppressWarnings("deprecation")
- public <V> V runInTransaction(@NonNull Callable<V> body) {
- beginTransaction();
- try {
- V result = body.call();
- setTransactionSuccessful();
- return result;
- } catch (RuntimeException e) {
- throw e;
- } catch (Exception e) {
- SneakyThrow.reThrow(e);
- return null; // Unreachable code, but compiler doesn't know it.
+ @Suppress("DEPRECATION")
+ open fun <V> runInTransaction(body: Callable<V>): V {
+ beginTransaction()
+ return try {
+ val result = body.call()
+ setTransactionSuccessful()
+ result
} finally {
- endTransaction();
+ endTransaction()
}
}
/**
* Called by the generated code when database is open.
- * <p>
+ *
* You should never call this method manually.
*
* @param db The database instance.
*/
- protected void internalInitInvalidationTracker(@NonNull SupportSQLiteDatabase db) {
- mInvalidationTracker.internalInit(db);
- }
-
- /**
- * Returns the invalidation tracker for this database.
- * <p>
- * You can use the invalidation tracker to get notified when certain tables in the database
- * are modified.
- *
- * @return The invalidation tracker for the database.
- */
- @NonNull
- public InvalidationTracker getInvalidationTracker() {
- return mInvalidationTracker;
+ protected open fun internalInitInvalidationTracker(db: SupportSQLiteDatabase) {
+ invalidationTracker.internalInit(db)
}
/**
* Returns true if current thread is in a transaction.
*
* @return True if there is an active transaction in current thread, false otherwise.
- * @see SupportSQLiteDatabase#inTransaction()
+ * @see SupportSQLiteDatabase.inTransaction
*/
- @SuppressWarnings("WeakerAccess")
- public boolean inTransaction() {
- return mOpenHelper.getWritableDatabase().inTransaction();
+ open fun inTransaction(): Boolean {
+ return openHelper.writableDatabase.inTransaction()
}
/**
* Journal modes for SQLite database.
*
- * @see Builder#setJournalMode(JournalMode)
+ * @see Builder.setJournalMode
*/
- public enum JournalMode {
-
+ enum class JournalMode {
/**
* Let Room choose the journal mode. This is the default value when no explicit value is
* specified.
- * <p>
- * The actual value will be {@link #TRUNCATE} when the device runs API Level lower than 16
- * or it is a low-RAM device. Otherwise, {@link #WRITE_AHEAD_LOGGING} will be used.
+ *
+ * The actual value will be [TRUNCATE] when the device runs API Level lower than 16
+ * or it is a low-RAM device. Otherwise, [WRITE_AHEAD_LOGGING] will be used.
*/
AUTOMATIC,
@@ -730,769 +657,702 @@
/**
* Write-Ahead Logging mode.
*/
- @RequiresApi(Build.VERSION_CODES.JELLY_BEAN)
WRITE_AHEAD_LOGGING;
/**
- * Resolves {@link #AUTOMATIC} to either {@link #TRUNCATE} or
- * {@link #WRITE_AHEAD_LOGGING}.
+ * Resolves [AUTOMATIC] to either [TRUNCATE] or [WRITE_AHEAD_LOGGING].
*/
- JournalMode resolve(Context context) {
+ @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
+ open fun resolve(context: Context): JournalMode {
if (this != AUTOMATIC) {
- return this;
+ return this
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
- ActivityManager manager = (ActivityManager)
- context.getSystemService(Context.ACTIVITY_SERVICE);
- if (manager != null && !isLowRamDevice(manager)) {
- return WRITE_AHEAD_LOGGING;
+ val manager = context.getSystemService(Context.ACTIVITY_SERVICE) as ActivityManager
+ if (!isLowRamDevice(manager)) {
+ return WRITE_AHEAD_LOGGING
}
}
- return TRUNCATE;
+ return TRUNCATE
}
- private static boolean isLowRamDevice(@NonNull ActivityManager activityManager) {
+ private fun isLowRamDevice(activityManager: ActivityManager) =
if (Build.VERSION.SDK_INT >= 19) {
- return SupportSQLiteCompat.Api19Impl.isLowRamDevice(activityManager);
+ SupportSQLiteCompat.Api19Impl.isLowRamDevice(activityManager)
+ } else {
+ false
}
- return false;
- }
}
/**
* Builder for RoomDatabase.
*
- * @param <T> The type of the abstract database class.
+ * @param T The type of the abstract database class.
*/
- public static class Builder<T extends RoomDatabase> {
- private final Class<T> mDatabaseClass;
- private final String mName;
- private final Context mContext;
- private ArrayList<Callback> mCallbacks;
- private PrepackagedDatabaseCallback mPrepackagedDatabaseCallback;
- private QueryCallback mQueryCallback;
- private Executor mQueryCallbackExecutor;
- private List<Object> mTypeConverters;
- private List<AutoMigrationSpec> mAutoMigrationSpecs;
+ @Suppress("GetterOnBuilder") // To keep ABI compatibility from Java
+ open class Builder<T : RoomDatabase> internal constructor(
+ private val context: Context,
+ private val klass: Class<T>,
+ private val name: String?
+ ) {
+ private val callbacks: MutableList<Callback> = mutableListOf()
+ private var prepackagedDatabaseCallback: PrepackagedDatabaseCallback? = null
+ private var queryCallback: QueryCallback? = null
+ private var queryCallbackExecutor: Executor? = null
+ private val typeConverters: MutableList<Any> = mutableListOf()
+ private var autoMigrationSpecs: MutableList<AutoMigrationSpec> = mutableListOf()
- /** The Executor used to run database queries. This should be background-threaded. */
- private Executor mQueryExecutor;
- /** The Executor used to run database transactions. This should be background-threaded. */
- private Executor mTransactionExecutor;
- private SupportSQLiteOpenHelper.Factory mFactory;
- private boolean mAllowMainThreadQueries;
- private JournalMode mJournalMode;
- private Intent mMultiInstanceInvalidationIntent;
- private boolean mRequireMigration;
- private boolean mAllowDestructiveMigrationOnDowngrade;
+ private var queryExecutor: Executor? = null
- private long mAutoCloseTimeout = -1L;
- private TimeUnit mAutoCloseTimeUnit;
+ private var transactionExecutor: Executor? = null
+ private var factory: SupportSQLiteOpenHelper.Factory? = null
+ private var allowMainThreadQueries = false
+ private var journalMode: JournalMode = JournalMode.AUTOMATIC
+ private var multiInstanceInvalidationIntent: Intent? = null
+ private var requireMigration: Boolean = true
+ private var allowDestructiveMigrationOnDowngrade = false
+ private var autoCloseTimeout = -1L
+ private var autoCloseTimeUnit: TimeUnit? = null
/**
* Migrations, mapped by from-to pairs.
*/
- private final MigrationContainer mMigrationContainer;
- private Set<Integer> mMigrationsNotRequiredFrom;
+ private val migrationContainer: MigrationContainer = MigrationContainer()
+ private var migrationsNotRequiredFrom: MutableSet<Int> = mutableSetOf()
+
/**
- * Keeps track of {@link Migration#startVersion}s and {@link Migration#endVersion}s added in
- * {@link #addMigrations(Migration...)} for later validation that makes those versions don't
- * match any versions passed to {@link #fallbackToDestructiveMigrationFrom(int...)}.
+ * Keeps track of [Migration.startVersion]s and [Migration.endVersion]s added in
+ * [addMigrations] for later validation that makes those versions don't
+ * match any versions passed to [fallbackToDestructiveMigrationFrom].
*/
- private Set<Integer> mMigrationStartAndEndVersions;
+ private var migrationStartAndEndVersions: MutableSet<Int>? = null
+ private var copyFromAssetPath: String? = null
+ private var copyFromFile: File? = null
+ private var copyFromInputStream: Callable<InputStream>? = null
- private String mCopyFromAssetPath;
- private File mCopyFromFile;
- private Callable<InputStream> mCopyFromInputStream;
-
- Builder(@NonNull Context context, @NonNull Class<T> klass, @Nullable String name) {
- mContext = context;
- mDatabaseClass = klass;
- mName = name;
- mJournalMode = JournalMode.AUTOMATIC;
- mRequireMigration = true;
- mMigrationContainer = new MigrationContainer();
- // TODO:(b/218894771) Initialize these as empty lists here for now, will be updated once
- // RoomDatabase is in Kotlin
- mTypeConverters = new ArrayList<>();
- mAutoMigrationSpecs = new ArrayList<>();
+ /**
+ * Configures Room to create and open the database using a pre-packaged database located in
+ * the application 'assets/' folder.
+ *
+ * Room does not open the pre-packaged database, instead it copies it into the internal
+ * app database folder and then opens it. The pre-packaged database file must be located in
+ * the "assets/" folder of your application. For example, the path for a file located in
+ * "assets/databases/products.db" would be "databases/products.db".
+ *
+ * The pre-packaged database schema will be validated. It might be best to create your
+ * pre-packaged database schema utilizing the exported schema files generated when
+ * [Database.exportSchema] is enabled.
+ *
+ * This method is not supported for an in memory database [Builder].
+ *
+ * @param databaseFilePath The file path within the 'assets/' directory of where the
+ * database file is located.
+ *
+ * @return This builder instance.
+ */
+ open fun createFromAsset(databaseFilePath: String) = apply {
+ this.copyFromAssetPath = databaseFilePath
}
/**
* Configures Room to create and open the database using a pre-packaged database located in
* the application 'assets/' folder.
- * <p>
+ *
* Room does not open the pre-packaged database, instead it copies it into the internal
* app database folder and then opens it. The pre-packaged database file must be located in
* the "assets/" folder of your application. For example, the path for a file located in
* "assets/databases/products.db" would be "databases/products.db".
- * <p>
+ *
* The pre-packaged database schema will be validated. It might be best to create your
* pre-packaged database schema utilizing the exported schema files generated when
- * {@link Database#exportSchema()} is enabled.
- * <p>
- * This method is not supported for an in memory database {@link Builder}.
+ * [Database.exportSchema] is enabled.
+ *
+ * This method is not supported for an in memory database [Builder].
*
* @param databaseFilePath The file path within the 'assets/' directory of where the
- * database file is located.
- *
- * @return This {@link Builder} instance.
- */
- @NonNull
- public Builder<T> createFromAsset(@NonNull String databaseFilePath) {
- mCopyFromAssetPath = databaseFilePath;
- return this;
- }
-
- /**
- * Configures Room to create and open the database using a pre-packaged database located in
- * the application 'assets/' folder.
- * <p>
- * Room does not open the pre-packaged database, instead it copies it into the internal
- * app database folder and then opens it. The pre-packaged database file must be located in
- * the "assets/" folder of your application. For example, the path for a file located in
- * "assets/databases/products.db" would be "databases/products.db".
- * <p>
- * The pre-packaged database schema will be validated. It might be best to create your
- * pre-packaged database schema utilizing the exported schema files generated when
- * {@link Database#exportSchema()} is enabled.
- * <p>
- * This method is not supported for an in memory database {@link Builder}.
- *
- * @param databaseFilePath The file path within the 'assets/' directory of where the
- * database file is located.
+ * database file is located.
* @param callback The pre-packaged callback.
*
- * @return This {@link Builder} instance.
+ * @return This builder instance.
*/
- @NonNull
@SuppressLint("BuilderSetStyle") // To keep naming consistency.
- public Builder<T> createFromAsset(
- @NonNull String databaseFilePath,
- @NonNull PrepackagedDatabaseCallback callback) {
- mPrepackagedDatabaseCallback = callback;
- mCopyFromAssetPath = databaseFilePath;
- return this;
+ open fun createFromAsset(
+ databaseFilePath: String,
+ callback: PrepackagedDatabaseCallback
+ ) = apply {
+ this.prepackagedDatabaseCallback = callback
+ this.copyFromAssetPath = databaseFilePath
}
/**
* Configures Room to create and open the database using a pre-packaged database file.
- * <p>
+ *
* Room does not open the pre-packaged database, instead it copies it into the internal
* app database folder and then opens it. The given file must be accessible and the right
* permissions must be granted for Room to copy the file.
- * <p>
+ *
* The pre-packaged database schema will be validated. It might be best to create your
* pre-packaged database schema utilizing the exported schema files generated when
- * {@link Database#exportSchema()} is enabled.
- * <p>
- * The {@link Callback#onOpen(SupportSQLiteDatabase)} method can be used as an indicator
+ * [Database.exportSchema] is enabled.
+ *
+ * The [Callback.onOpen] method can be used as an indicator
* that the pre-packaged database was successfully opened by Room and can be cleaned up.
- * <p>
- * This method is not supported for an in memory database {@link Builder}.
+ *
+ * This method is not supported for an in memory database [Builder].
*
* @param databaseFile The database file.
*
- * @return This {@link Builder} instance.
+ * @return This builder instance.
*/
- @NonNull
- public Builder<T> createFromFile(@NonNull File databaseFile) {
- mCopyFromFile = databaseFile;
- return this;
+ open fun createFromFile(databaseFile: File) = apply {
+ this.copyFromFile = databaseFile
}
/**
* Configures Room to create and open the database using a pre-packaged database file.
- * <p>
+ *
* Room does not open the pre-packaged database, instead it copies it into the internal
* app database folder and then opens it. The given file must be accessible and the right
* permissions must be granted for Room to copy the file.
- * <p>
+ *
* The pre-packaged database schema will be validated. It might be best to create your
* pre-packaged database schema utilizing the exported schema files generated when
- * {@link Database#exportSchema()} is enabled.
- * <p>
- * The {@link Callback#onOpen(SupportSQLiteDatabase)} method can be used as an indicator
+ * [Database.exportSchema] is enabled.
+ *
+ * The [Callback.onOpen] method can be used as an indicator
* that the pre-packaged database was successfully opened by Room and can be cleaned up.
- * <p>
- * This method is not supported for an in memory database {@link Builder}.
+ *
+ * This method is not supported for an in memory database [Builder].
*
* @param databaseFile The database file.
* @param callback The pre-packaged callback.
*
- * @return This {@link Builder} instance.
+ * @return This builder instance.
*/
- @NonNull
- @SuppressLint({"BuilderSetStyle", "StreamFiles"}) // To keep naming consistency.
- public Builder<T> createFromFile(
- @NonNull File databaseFile,
- @NonNull PrepackagedDatabaseCallback callback) {
- mPrepackagedDatabaseCallback = callback;
- mCopyFromFile = databaseFile;
- return this;
+ @SuppressLint("BuilderSetStyle", "StreamFiles") // To keep naming consistency.
+ open fun createFromFile(
+ databaseFile: File,
+ callback: PrepackagedDatabaseCallback
+ ) = apply {
+ this.prepackagedDatabaseCallback = callback
+ this.copyFromFile = databaseFile
}
/**
* Configures Room to create and open the database using a pre-packaged database via an
- * {@link InputStream}.
- * <p>
+ * [InputStream].
+ *
* This is useful for processing compressed database files. Room does not open the
* pre-packaged database, instead it copies it into the internal app database folder, and
- * then open it. The {@link InputStream} will be closed once Room is done consuming it.
- * <p>
+ * then open it. The [InputStream] will be closed once Room is done consuming it.
+ *
* The pre-packaged database schema will be validated. It might be best to create your
* pre-packaged database schema utilizing the exported schema files generated when
- * {@link Database#exportSchema()} is enabled.
- * <p>
- * The {@link Callback#onOpen(SupportSQLiteDatabase)} method can be used as an indicator
+ * [Database.exportSchema] is enabled.
+ *
+ * The [Callback.onOpen] method can be used as an indicator
* that the pre-packaged database was successfully opened by Room and can be cleaned up.
- * <p>
- * This method is not supported for an in memory database {@link Builder}.
+ *
+ * This method is not supported for an in memory database [Builder].
*
* @param inputStreamCallable A callable that returns an InputStream from which to copy
- * the database. The callable will be invoked in a thread from
- * the Executor set via {@link #setQueryExecutor(Executor)}. The
- * callable is only invoked if Room needs to create and open the
- * database from the pre-package database, usually the first time
- * it is created or during a destructive migration.
+ * the database. The callable will be invoked in a thread from
+ * the Executor set via [setQueryExecutor]. The
+ * callable is only invoked if Room needs to create and open the
+ * database from the pre-package database, usually the first time
+ * it is created or during a destructive migration.
*
- * @return This {@link Builder} instance.
+ * @return This builder instance.
*/
- @NonNull
@SuppressLint("BuilderSetStyle") // To keep naming consistency.
- public Builder<T> createFromInputStream(
- @NonNull Callable<InputStream> inputStreamCallable) {
- mCopyFromInputStream = inputStreamCallable;
- return this;
+ open fun createFromInputStream(
+ inputStreamCallable: Callable<InputStream>
+ ) = apply {
+ this.copyFromInputStream = inputStreamCallable
}
/**
* Configures Room to create and open the database using a pre-packaged database via an
- * {@link InputStream}.
- * <p>
+ * [InputStream].
+ *
* This is useful for processing compressed database files. Room does not open the
* pre-packaged database, instead it copies it into the internal app database folder, and
- * then open it. The {@link InputStream} will be closed once Room is done consuming it.
- * <p>
+ * then open it. The [InputStream] will be closed once Room is done consuming it.
+ *
* The pre-packaged database schema will be validated. It might be best to create your
* pre-packaged database schema utilizing the exported schema files generated when
- * {@link Database#exportSchema()} is enabled.
- * <p>
- * The {@link Callback#onOpen(SupportSQLiteDatabase)} method can be used as an indicator
+ * [Database.exportSchema] is enabled.
+ *
+ * The [Callback.onOpen] method can be used as an indicator
* that the pre-packaged database was successfully opened by Room and can be cleaned up.
- * <p>
- * This method is not supported for an in memory database {@link Builder}.
+ *
+ * This method is not supported for an in memory database [Builder].
*
* @param inputStreamCallable A callable that returns an InputStream from which to copy
- * the database. The callable will be invoked in a thread from
- * the Executor set via {@link #setQueryExecutor(Executor)}. The
- * callable is only invoked if Room needs to create and open the
- * database from the pre-package database, usually the first time
- * it is created or during a destructive migration.
+ * the database. The callable will be invoked in a thread from
+ * the Executor set via [setQueryExecutor]. The
+ * callable is only invoked if Room needs to create and open the
+ * database from the pre-package database, usually the first time
+ * it is created or during a destructive migration.
* @param callback The pre-packaged callback.
*
- * @return This {@link Builder} instance.
+ * @return This builder instance.
*/
- @NonNull
- @SuppressLint({"BuilderSetStyle", "LambdaLast"}) // To keep naming consistency.
- public Builder<T> createFromInputStream(
- @NonNull Callable<InputStream> inputStreamCallable,
- @NonNull PrepackagedDatabaseCallback callback) {
- mPrepackagedDatabaseCallback = callback;
- mCopyFromInputStream = inputStreamCallable;
- return this;
+ @SuppressLint("BuilderSetStyle", "LambdaLast") // To keep naming consistency.
+ open fun createFromInputStream(
+ inputStreamCallable: Callable<InputStream>,
+ callback: PrepackagedDatabaseCallback
+ ) = apply {
+ this.prepackagedDatabaseCallback = callback
+ this.copyFromInputStream = inputStreamCallable
}
/**
* Sets the database factory. If not set, it defaults to
- * {@link FrameworkSQLiteOpenHelperFactory}.
+ * [FrameworkSQLiteOpenHelperFactory].
*
* @param factory The factory to use to access the database.
- * @return This {@link Builder} instance.
+ * @return This builder instance.
*/
- @NonNull
- public Builder<T> openHelperFactory(@Nullable SupportSQLiteOpenHelper.Factory factory) {
- mFactory = factory;
- return this;
+ open fun openHelperFactory(factory: SupportSQLiteOpenHelper.Factory?) = apply {
+ this.factory = factory
}
/**
* Adds a migration to the builder.
- * <p>
+ *
* Each Migration has a start and end versions and Room runs these migrations to bring the
* database to the latest version.
- * <p>
+ *
* If a migration item is missing between current version and the latest version, Room
* will clear the database and recreate so even if you have no changes between 2 versions,
* you should still provide a Migration object to the builder.
- * <p>
+ *
* A migration can handle more than 1 version (e.g. if you have a faster path to choose when
* going version 3 to 5 without going to version 4). If Room opens a database at version
* 3 and latest version is >= 5, Room will use the migration object that can migrate from
* 3 to 5 instead of 3 to 4 and 4 to 5.
*
* @param migrations The migration object that can modify the database and to the necessary
- * changes.
- * @return This {@link Builder} instance.
+ * changes.
+ * @return This builder instance.
*/
- @NonNull
- public Builder<T> addMigrations(@NonNull Migration... migrations) {
- if (mMigrationStartAndEndVersions == null) {
- mMigrationStartAndEndVersions = new HashSet<>();
+ open fun addMigrations(vararg migrations: Migration) = apply {
+ if (migrationStartAndEndVersions == null) {
+ migrationStartAndEndVersions = HashSet()
}
- for (Migration migration : migrations) {
- mMigrationStartAndEndVersions.add(migration.startVersion);
- mMigrationStartAndEndVersions.add(migration.endVersion);
+ for (migration in migrations) {
+ migrationStartAndEndVersions!!.add(migration.startVersion)
+ migrationStartAndEndVersions!!.add(migration.endVersion)
}
-
- mMigrationContainer.addMigrations(migrations);
- return this;
+ migrationContainer.addMigrations(*migrations)
}
/**
* Adds an auto migration spec to the builder.
*
* @param autoMigrationSpec The auto migration object that is annotated with
- * {@link AutoMigrationSpec} and is declared in an {@link AutoMigration} annotation.
- * @return This {@link Builder} instance.
+ * [AutoMigrationSpec] and is declared in an [AutoMigration] annotation.
+ * @return This builder instance.
*/
- @NonNull
- @SuppressWarnings("MissingGetterMatchingBuilder")
- public Builder<T> addAutoMigrationSpec(@NonNull AutoMigrationSpec autoMigrationSpec) {
- if (mAutoMigrationSpecs == null) {
- mAutoMigrationSpecs = new ArrayList<>();
- }
- mAutoMigrationSpecs.add(autoMigrationSpec);
- return this;
+ @Suppress("MissingGetterMatchingBuilder")
+ open fun addAutoMigrationSpec(autoMigrationSpec: AutoMigrationSpec) = apply {
+ this.autoMigrationSpecs.add(autoMigrationSpec)
}
/**
* Disables the main thread query check for Room.
- * <p>
+ *
* Room ensures that Database is never accessed on the main thread because it may lock the
* main thread and trigger an ANR. If you need to access the database from the main thread,
* you should always use async alternatives or manually move the call to a background
* thread.
- * <p>
+ *
* You may want to turn this check off for testing.
*
- * @return This {@link Builder} instance.
+ * @return This builder instance.
*/
- @NonNull
- public Builder<T> allowMainThreadQueries() {
- mAllowMainThreadQueries = true;
- return this;
+ open fun allowMainThreadQueries() = apply {
+ this.allowMainThreadQueries = true
}
/**
* Sets the journal mode for this database.
*
- * <p>
* This value is ignored if the builder is initialized with
- * {@link Room#inMemoryDatabaseBuilder(Context, Class)}.
- * <p>
+ * [Room.inMemoryDatabaseBuilder].
+ *
* The journal mode should be consistent across multiple instances of
- * {@link RoomDatabase} for a single SQLite database file.
- * <p>
- * The default value is {@link JournalMode#AUTOMATIC}.
+ * [RoomDatabase] for a single SQLite database file.
+ *
+ * The default value is [JournalMode.AUTOMATIC].
*
* @param journalMode The journal mode.
- * @return This {@link Builder} instance.
+ * @return This builder instance.
*/
- @NonNull
- public Builder<T> setJournalMode(@NonNull JournalMode journalMode) {
- mJournalMode = journalMode;
- return this;
+ open fun setJournalMode(journalMode: JournalMode) = apply {
+ this.journalMode = journalMode
}
/**
- * Sets the {@link Executor} that will be used to execute all non-blocking asynchronous
- * queries and tasks, including {@code LiveData} invalidation, {@code Flowable} scheduling
- * and {@code ListenableFuture} tasks.
- * <p>
- * When both the query executor and transaction executor are unset, then a default
- * {@code Executor} will be used. The default {@code Executor} allocates and shares threads
- * amongst Architecture Components libraries. If the query executor is unset but a
- * transaction executor was set, then the same {@code Executor} will be used for queries.
- * <p>
- * For best performance the given {@code Executor} should be bounded (max number of threads
- * is limited).
- * <p>
- * The input {@code Executor} cannot run tasks on the UI thread.
- **
- * @return This {@link Builder} instance.
+ * Sets the [Executor] that will be used to execute all non-blocking asynchronous
+ * queries and tasks, including `LiveData` invalidation, `Flowable` scheduling
+ * and `ListenableFuture` tasks.
*
- * @see #setTransactionExecutor(Executor)
+ * When both the query executor and transaction executor are unset, then a default
+ * `Executor` will be used. The default `Executor` allocates and shares threads
+ * amongst Architecture Components libraries. If the query executor is unset but a
+ * transaction executor was set [setTransactionExecutor], then the same `Executor` will be
+ * used for queries.
+ *
+ * For best performance the given `Executor` should be bounded (max number of threads
+ * is limited).
+ *
+ * The input `Executor` cannot run tasks on the UI thread.
+ *
+ * @return This builder instance.
*/
- @NonNull
- public Builder<T> setQueryExecutor(@NonNull Executor executor) {
- mQueryExecutor = executor;
- return this;
+ open fun setQueryExecutor(executor: Executor) = apply {
+ this.queryExecutor = executor
}
/**
- * Sets the {@link Executor} that will be used to execute all non-blocking asynchronous
- * transaction queries and tasks, including {@code LiveData} invalidation, {@code Flowable}
- * scheduling and {@code ListenableFuture} tasks.
- * <p>
+ * Sets the [Executor] that will be used to execute all non-blocking asynchronous
+ * transaction queries and tasks, including `LiveData` invalidation, `Flowable`
+ * scheduling and `ListenableFuture` tasks.
+ *
* When both the transaction executor and query executor are unset, then a default
- * {@code Executor} will be used. The default {@code Executor} allocates and shares threads
+ * `Executor` will be used. The default `Executor` allocates and shares threads
* amongst Architecture Components libraries. If the transaction executor is unset but a
- * query executor was set, then the same {@code Executor} will be used for transactions.
- * <p>
- * If the given {@code Executor} is shared then it should be unbounded to avoid the
+ * query executor was set using [setQueryExecutor], then the same `Executor` will be used
+ * for transactions.
+ *
+ * If the given `Executor` is shared then it should be unbounded to avoid the
* possibility of a deadlock. Room will not use more than one thread at a time from this
* executor since only one transaction at a time can be executed, other transactions will
* be queued on a first come, first serve order.
- * <p>
- * The input {@code Executor} cannot run tasks on the UI thread.
*
- * @return This {@link Builder} instance.
+ * The input `Executor` cannot run tasks on the UI thread.
*
- * @see #setQueryExecutor(Executor)
+ * @return This builder instance.
*/
- @NonNull
- public Builder<T> setTransactionExecutor(@NonNull Executor executor) {
- mTransactionExecutor = executor;
- return this;
+ open fun setTransactionExecutor(executor: Executor) = apply {
+ this.transactionExecutor = executor
}
/**
- * Sets whether table invalidation in this instance of {@link RoomDatabase} should be
- * broadcast and synchronized with other instances of the same {@link RoomDatabase},
+ * Sets whether table invalidation in this instance of [RoomDatabase] should be
+ * broadcast and synchronized with other instances of the same [RoomDatabase],
* including those in a separate process. In order to enable multi-instance invalidation,
* this has to be turned on both ends.
- * <p>
+ *
* This is not enabled by default.
- * <p>
+ *
* This does not work for in-memory databases. This does not work between database instances
* targeting different database files.
*
- * @return This {@link Builder} instance.
+ * @return This builder instance.
*/
- @NonNull
- public Builder<T> enableMultiInstanceInvalidation() {
- mMultiInstanceInvalidationIntent = mName != null ? new Intent(mContext,
- MultiInstanceInvalidationService.class) : null;
- return this;
+ @Suppress("UnsafeOptInUsageError")
+ open fun enableMultiInstanceInvalidation() = apply {
+ this.multiInstanceInvalidationIntent = if (name != null) {
+ Intent(context, MultiInstanceInvalidationService::class.java)
+ } else {
+ null
+ }
}
/**
- * Sets whether table invalidation in this instance of {@link RoomDatabase} should be
- * broadcast and synchronized with other instances of the same {@link RoomDatabase},
+ * Sets whether table invalidation in this instance of [RoomDatabase] should be
+ * broadcast and synchronized with other instances of the same [RoomDatabase],
* including those in a separate process. In order to enable multi-instance invalidation,
* this has to be turned on both ends and need to point to the same
- * {@link MultiInstanceInvalidationService}.
- * <p>
+ * [MultiInstanceInvalidationService].
+ *
* This is not enabled by default.
- * <p>
+ *
* This does not work for in-memory databases. This does not work between database instances
* targeting different database files.
*
- * @return This {@link Builder} instance.
* @param invalidationServiceIntent Intent to bind to the
- * {@link MultiInstanceInvalidationService}.
+ * [MultiInstanceInvalidationService].
+ * @return This builder instance.
*/
- @SuppressWarnings("MissingGetterMatchingBuilder")
- @NonNull
@ExperimentalRoomApi
- public Builder<T> setMultiInstanceInvalidationServiceIntent(
- @NonNull Intent invalidationServiceIntent) {
- mMultiInstanceInvalidationIntent = mName != null ? invalidationServiceIntent : null;
- return this;
+ @Suppress("MissingGetterMatchingBuilder")
+ open fun setMultiInstanceInvalidationServiceIntent(
+ invalidationServiceIntent: Intent
+ ) = apply {
+ this.multiInstanceInvalidationIntent =
+ if (name != null) invalidationServiceIntent else null
}
/**
- * Allows Room to destructively recreate database tables if {@link Migration}s that would
+ * Allows Room to destructively recreate database tables if [Migration]s that would
* migrate old database schemas to the latest schema version are not found.
- * <p>
+ *
* When the database version on the device does not match the latest schema version, Room
- * runs necessary {@link Migration}s on the database.
- * <p>
- * If it cannot find the set of {@link Migration}s that will bring the database to the
- * current version, it will throw an {@link IllegalStateException}.
- * <p>
+ * runs necessary [Migration]s on the database.
+ *
+ * If it cannot find the set of [Migration]s that will bring the database to the
+ * current version, it will throw an [IllegalStateException].
+ *
* You can call this method to change this behavior to re-create the database instead of
* crashing.
- * <p>
+ *
* If the database was create from an asset or a file then Room will try to use the same
* file to re-create the database, otherwise this will delete all of the data in the
* database tables managed by Room.
- * <p>
+ *
* To let Room fallback to destructive migration only during a schema downgrade then use
- * {@link #fallbackToDestructiveMigrationOnDowngrade()}.
+ * [fallbackToDestructiveMigrationOnDowngrade].
*
- * @return This {@link Builder} instance.
- *
- * @see #fallbackToDestructiveMigrationOnDowngrade()
+ * @return This builder instance.
*/
- @NonNull
- public Builder<T> fallbackToDestructiveMigration() {
- mRequireMigration = false;
- mAllowDestructiveMigrationOnDowngrade = true;
- return this;
+ open fun fallbackToDestructiveMigration() = apply {
+ this.requireMigration = false
+ this.allowDestructiveMigrationOnDowngrade = true
}
/**
- * Allows Room to destructively recreate database tables if {@link Migration}s are not
+ * Allows Room to destructively recreate database tables if [Migration]s are not
* available when downgrading to old schema versions.
*
- * @return This {@link Builder} instance.
+ * For details, see [Builder.fallbackToDestructiveMigration].
*
- * @see Builder#fallbackToDestructiveMigration()
+ * @return This builder instance.
*/
- @NonNull
- public Builder<T> fallbackToDestructiveMigrationOnDowngrade() {
- mRequireMigration = true;
- mAllowDestructiveMigrationOnDowngrade = true;
- return this;
+ open fun fallbackToDestructiveMigrationOnDowngrade() = apply {
+ this.requireMigration = true
+ this.allowDestructiveMigrationOnDowngrade = true
}
/**
* Informs Room that it is allowed to destructively recreate database tables from specific
* starting schema versions.
- * <p>
+ *
* This functionality is the same as that provided by
- * {@link #fallbackToDestructiveMigration()}, except that this method allows the
+ * [fallbackToDestructiveMigration], except that this method allows the
* specification of a set of schema versions for which destructive recreation is allowed.
- * <p>
- * Using this method is preferable to {@link #fallbackToDestructiveMigration()} if you want
+ *
+ * Using this method is preferable to [fallbackToDestructiveMigration] if you want
* to allow destructive migrations from some schema versions while still taking advantage
* of exceptions being thrown due to unintentionally missing migrations.
- * <p>
+ *
* Note: No versions passed to this method may also exist as either starting or ending
- * versions in the {@link Migration}s provided to {@link #addMigrations(Migration...)}. If a
+ * versions in the [Migration]s provided to [addMigrations]. If a
* version passed to this method is found as a starting or ending version in a Migration, an
* exception will be thrown.
*
* @param startVersions The set of schema versions from which Room should use a destructive
- * migration.
- * @return This {@link Builder} instance.
+ * migration.
+ * @return This builder instance.
*/
- @NonNull
- public Builder<T> fallbackToDestructiveMigrationFrom(int... startVersions) {
- if (mMigrationsNotRequiredFrom == null) {
- mMigrationsNotRequiredFrom = new HashSet<>(startVersions.length);
+ open fun fallbackToDestructiveMigrationFrom(vararg startVersions: Int) = apply {
+ for (startVersion in startVersions) {
+ this.migrationsNotRequiredFrom.add(startVersion)
}
- for (int startVersion : startVersions) {
- mMigrationsNotRequiredFrom.add(startVersion);
- }
- return this;
}
/**
- * Adds a {@link Callback} to this database.
+ * Adds a [Callback] to this database.
*
* @param callback The callback.
- * @return This {@link Builder} instance.
+ * @return This builder instance.
*/
- @NonNull
- public Builder<T> addCallback(@NonNull Callback callback) {
- if (mCallbacks == null) {
- mCallbacks = new ArrayList<>();
- }
- mCallbacks.add(callback);
- return this;
+ open fun addCallback(callback: Callback) = apply {
+ this.callbacks.add(callback)
}
/**
- * Sets a {@link QueryCallback} to be invoked when queries are executed.
- * <p>
+ * Sets a [QueryCallback] to be invoked when queries are executed.
+ *
* The callback is invoked whenever a query is executed, note that adding this callback
* has a small cost and should be avoided in production builds unless needed.
- * <p>
+ *
* A use case for providing a callback is to allow logging executed queries. When the
* callback implementation logs then it is recommended to use an immediate executor.
*
* @param queryCallback The query callback.
* @param executor The executor on which the query callback will be invoked.
+ * @return This builder instance.
*/
- @SuppressWarnings("MissingGetterMatchingBuilder")
- @NonNull
- public Builder<T> setQueryCallback(@NonNull QueryCallback queryCallback,
- @NonNull Executor executor) {
- mQueryCallback = queryCallback;
- mQueryCallbackExecutor = executor;
- return this;
+ @Suppress("MissingGetterMatchingBuilder")
+ open fun setQueryCallback(
+ queryCallback: QueryCallback,
+ executor: Executor
+ ) = apply {
+ this.queryCallback = queryCallback
+ this.queryCallbackExecutor = executor
}
/**
* Adds a type converter instance to this database.
*
* @param typeConverter The converter. It must be an instance of a class annotated with
- * {@link ProvidedTypeConverter} otherwise Room will throw an exception.
- * @return This {@link Builder} instance.
+ * [ProvidedTypeConverter] otherwise Room will throw an exception.
+ * @return This builder instance.
*/
- @NonNull
- public Builder<T> addTypeConverter(@NonNull Object typeConverter) {
- if (mTypeConverters == null) {
- mTypeConverters = new ArrayList<>();
- }
- mTypeConverters.add(typeConverter);
- return this;
+ open fun addTypeConverter(typeConverter: Any) = apply {
+ this.typeConverters.add(typeConverter)
}
/**
* Enables auto-closing for the database to free up unused resources. The underlying
- * database will be closed after it's last use after the specified {@code
- * autoCloseTimeout} has elapsed since its last usage. The database will be automatically
+ * database will be closed after it's last use after the specified `autoCloseTimeout` has
+ * elapsed since its last usage. The database will be automatically
* re-opened the next time it is accessed.
- * <p>
+ *
* Auto-closing is not compatible with in-memory databases since the data will be lost
* when the database is auto-closed.
- * <p>
+ *
* Also, temp tables and temp triggers will be cleared each time the database is
* auto-closed. If you need to use them, please include them in your
- * {@link RoomDatabase.Callback#onOpen callback}.
- * <p>
- * All configuration should happen in your {@link RoomDatabase.Callback#onOpen}
+ * callback [RoomDatabase.Callback.onOpen].
+ *
+ * All configuration should happen in your [RoomDatabase.Callback.onOpen]
* callback so it is re-applied every time the database is re-opened. Note that the
- * {@link RoomDatabase.Callback#onOpen} will be called every time the database is re-opened.
- * <p>
+ * [RoomDatabase.Callback.onOpen] will be called every time the database is re-opened.
+ *
* The auto-closing database operation runs on the query executor.
- * <p>
+ *
* The database will not be reopened if the RoomDatabase or the
* SupportSqliteOpenHelper is closed manually (by calling
- * {@link RoomDatabase#close()} or {@link SupportSQLiteOpenHelper#close()}. If the
+ * [RoomDatabase.close] or [SupportSQLiteOpenHelper.close]. If the
* database is closed manually, you must create a new database using
- * {@link RoomDatabase.Builder#build()}.
+ * [RoomDatabase.Builder.build].
*
- * @param autoCloseTimeout the amount of time after the last usage before closing the
- * database. Must greater or equal to zero.
+ * @param autoCloseTimeout the amount of time after the last usage before closing the
+ * database. Must greater or equal to zero.
* @param autoCloseTimeUnit the timeunit for autoCloseTimeout.
- * @return This {@link Builder} instance
+ * @return This builder instance.
*/
- @NonNull
- @SuppressWarnings("MissingGetterMatchingBuilder")
@ExperimentalRoomApi // When experimental is removed, add these parameters to
// DatabaseConfiguration
- public Builder<T> setAutoCloseTimeout(
- @IntRange(from = 0) long autoCloseTimeout, @NonNull TimeUnit autoCloseTimeUnit) {
- if (autoCloseTimeout < 0) {
- throw new IllegalArgumentException("autoCloseTimeout must be >= 0");
- }
- mAutoCloseTimeout = autoCloseTimeout;
- mAutoCloseTimeUnit = autoCloseTimeUnit;
- return this;
+ @Suppress("MissingGetterMatchingBuilder")
+ open fun setAutoCloseTimeout(
+ @IntRange(from = 0) autoCloseTimeout: Long,
+ autoCloseTimeUnit: TimeUnit
+ ) = apply {
+ require(autoCloseTimeout >= 0) { "autoCloseTimeout must be >= 0" }
+ this.autoCloseTimeout = autoCloseTimeout
+ this.autoCloseTimeUnit = autoCloseTimeUnit
}
/**
* Creates the databases and initializes it.
- * <p>
+ *
* By default, all RoomDatabases use in memory storage for TEMP tables and enables recursive
* triggers.
*
* @return A new database instance.
*/
- @SuppressLint("RestrictedApi")
- @NonNull
- public T build() {
- //noinspection ConstantConditions
- if (mContext == null) {
- throw new IllegalArgumentException("Cannot provide null context for the database.");
+ open fun build(): T {
+ if (queryExecutor == null && transactionExecutor == null) {
+ transactionExecutor = ArchTaskExecutor.getIOThreadExecutor()
+ queryExecutor = transactionExecutor
+ } else if (queryExecutor != null && transactionExecutor == null) {
+ transactionExecutor = queryExecutor
+ } else if (queryExecutor == null) {
+ queryExecutor = transactionExecutor
}
- //noinspection ConstantConditions
- if (mDatabaseClass == null) {
- throw new IllegalArgumentException("Must provide an abstract class that"
- + " extends RoomDatabase");
- }
- if (mQueryExecutor == null && mTransactionExecutor == null) {
- mQueryExecutor = mTransactionExecutor = ArchTaskExecutor.getIOThreadExecutor();
- } else if (mQueryExecutor != null && mTransactionExecutor == null) {
- mTransactionExecutor = mQueryExecutor;
- } else if (mQueryExecutor == null && mTransactionExecutor != null) {
- mQueryExecutor = mTransactionExecutor;
- }
-
- if (mMigrationStartAndEndVersions != null && mMigrationsNotRequiredFrom != null) {
- for (Integer version : mMigrationStartAndEndVersions) {
- if (mMigrationsNotRequiredFrom.contains(version)) {
- throw new IllegalArgumentException(
- "Inconsistency detected. A Migration was supplied to "
- + "addMigration(Migration... migrations) that has a start "
- + "or end version equal to a start version supplied to "
- + "fallbackToDestructiveMigrationFrom(int... "
- + "startVersions). Start version: "
- + version);
+ if (migrationStartAndEndVersions != null) {
+ for (version in migrationStartAndEndVersions!!) {
+ require(!migrationsNotRequiredFrom.contains(version)) {
+ "Inconsistency detected. A Migration was supplied to " +
+ "addMigration(Migration... migrations) that has a start " +
+ "or end version equal to a start version supplied to " +
+ "fallbackToDestructiveMigrationFrom(int... " +
+ "startVersions). Start version: $version"
}
}
}
- SupportSQLiteOpenHelper.Factory factory;
-
- AutoCloser autoCloser = null;
-
- if (mFactory == null) {
- factory = new FrameworkSQLiteOpenHelperFactory();
+ val factory: SupportSQLiteOpenHelper.Factory = if (factory == null) {
+ FrameworkSQLiteOpenHelperFactory()
} else {
- factory = mFactory;
- }
-
- if (mAutoCloseTimeout > 0) {
- if (mName == null) {
- throw new IllegalArgumentException("Cannot create auto-closing database for "
- + "an in-memory database.");
+ factory
+ }?.let {
+ if (autoCloseTimeout > 0) {
+ requireNotNull(name) {
+ "Cannot create auto-closing database for an in-memory database."
+ }
+ val autoCloser = AutoCloser(
+ autoCloseTimeout,
+ requireNotNull(autoCloseTimeUnit),
+ requireNotNull(queryExecutor)
+ )
+ AutoClosingRoomOpenHelperFactory(it, autoCloser)
+ } else {
+ it
}
+ }?.let {
+ if (
+ copyFromAssetPath != null ||
+ copyFromFile != null ||
+ copyFromInputStream != null
+ ) {
+ requireNotNull(name) {
+ "Cannot create from asset or file for an in-memory database."
+ }
- autoCloser = new AutoCloser(mAutoCloseTimeout, mAutoCloseTimeUnit,
- mTransactionExecutor);
+ val copyFromAssetPathConfig = if (copyFromAssetPath == null) 0 else 1
+ val copyFromFileConfig = if (copyFromFile == null) 0 else 1
+ val copyFromInputStreamConfig = if (copyFromInputStream == null) 0 else 1
+ val copyConfigurations = copyFromAssetPathConfig + copyFromFileConfig +
+ copyFromInputStreamConfig
- factory = new AutoClosingRoomOpenHelperFactory(factory, autoCloser);
- }
-
- if (mCopyFromAssetPath != null
- || mCopyFromFile != null
- || mCopyFromInputStream != null) {
- if (mName == null) {
- throw new IllegalArgumentException("Cannot create from asset or file for an "
- + "in-memory database.");
+ require(copyConfigurations == 1) {
+ "More than one of createFromAsset(), " +
+ "createFromInputStream(), and createFromFile() were called on this " +
+ "Builder, but the database can only be created using one of the " +
+ "three configurations."
+ }
+ SQLiteCopyOpenHelperFactory(
+ copyFromAssetPath,
+ copyFromFile,
+ copyFromInputStream,
+ it
+ )
+ } else {
+ it
}
-
- final int copyConfigurations = (mCopyFromAssetPath == null ? 0 : 1) +
- (mCopyFromFile == null ? 0 : 1) +
- (mCopyFromInputStream == null ? 0 : 1);
- if (copyConfigurations != 1) {
- throw new IllegalArgumentException("More than one of createFromAsset(), "
- + "createFromInputStream(), and createFromFile() were called on this "
- + "Builder, but the database can only be created using one of the "
- + "three configurations.");
+ }.let {
+ requireNotNull(it)
+ if (queryCallback != null) {
+ QueryInterceptorOpenHelperFactory(
+ it,
+ requireNotNull(queryCallbackExecutor),
+ requireNotNull(queryCallback)
+ )
+ } else {
+ it
}
- factory = new SQLiteCopyOpenHelperFactory(mCopyFromAssetPath, mCopyFromFile,
- mCopyFromInputStream, factory);
}
-
- if (mQueryCallback != null) {
- factory = new QueryInterceptorOpenHelperFactory(
- factory,
- mQueryCallbackExecutor,
- mQueryCallback
- );
- }
-
- DatabaseConfiguration configuration =
- new DatabaseConfiguration(
- mContext,
- mName,
- factory,
- mMigrationContainer,
- mCallbacks,
- mAllowMainThreadQueries,
- mJournalMode.resolve(mContext),
- mQueryExecutor,
- mTransactionExecutor,
- mMultiInstanceInvalidationIntent,
- mRequireMigration,
- mAllowDestructiveMigrationOnDowngrade,
- mMigrationsNotRequiredFrom,
- mCopyFromAssetPath,
- mCopyFromFile,
- mCopyFromInputStream,
- mPrepackagedDatabaseCallback,
- mTypeConverters,
- mAutoMigrationSpecs);
- T db = Room.getGeneratedImplementation(mDatabaseClass, DB_IMPL_SUFFIX);
- db.init(configuration);
- return db;
+ val configuration = DatabaseConfiguration(
+ context,
+ name,
+ factory,
+ migrationContainer,
+ callbacks,
+ allowMainThreadQueries,
+ journalMode.resolve(context),
+ requireNotNull(queryExecutor),
+ requireNotNull(transactionExecutor),
+ multiInstanceInvalidationIntent,
+ requireMigration,
+ allowDestructiveMigrationOnDowngrade,
+ migrationsNotRequiredFrom,
+ copyFromAssetPath,
+ copyFromFile,
+ copyFromInputStream,
+ prepackagedDatabaseCallback,
+ typeConverters,
+ autoMigrationSpecs
+ )
+ val db = Room.getGeneratedImplementation<T, T>(klass, "_Impl")
+ db.init(configuration)
+ return db
}
}
@@ -1500,8 +1360,8 @@
* A container to hold migrations. It also allows querying its contents to find migrations
* between two versions.
*/
- public static class MigrationContainer {
- private HashMap<Integer, TreeMap<Integer, Migration>> mMigrations = new HashMap<>();
+ open class MigrationContainer {
+ private val migrations = mutableMapOf<Int, TreeMap<Int, Migration>>()
/**
* Adds the given migrations to the list of available migrations. If 2 migrations have the
@@ -1509,10 +1369,8 @@
*
* @param migrations List of available migrations.
*/
- public void addMigrations(@NonNull Migration... migrations) {
- for (Migration migration : migrations) {
- addMigration(migration);
- }
+ open fun addMigrations(vararg migrations: Migration) {
+ migrations.forEach(::addMigration)
}
/**
@@ -1521,25 +1379,19 @@
*
* @param migrations List of available migrations.
*/
- public void addMigrations(@NonNull List<Migration> migrations) {
- for (Migration migration : migrations) {
- addMigration(migration);
- }
+ open fun addMigrations(migrations: List<Migration>) {
+ migrations.forEach(::addMigration)
}
- private void addMigration(Migration migration) {
- final int start = migration.startVersion;
- final int end = migration.endVersion;
- TreeMap<Integer, Migration> targetMap = mMigrations.get(start);
- if (targetMap == null) {
- targetMap = new TreeMap<>();
- mMigrations.put(start, targetMap);
+ private fun addMigration(migration: Migration) {
+ val start = migration.startVersion
+ val end = migration.endVersion
+ val targetMap = migrations.getOrPut(start) { TreeMap<Int, Migration>() }
+
+ if (targetMap.contains(end)) {
+ Log.w(Room.LOG_TAG, "Overriding migration ${targetMap[end]} with $migration")
}
- Migration existing = targetMap.get(end);
- if (existing != null) {
- Log.w(Room.LOG_TAG, "Overriding migration " + existing + " with " + migration);
- }
- targetMap.put(end, migration);
+ targetMap[end] = migration
}
/**
@@ -1548,138 +1400,134 @@
*
* @return Map of migrations keyed by the start version
*/
- @NonNull
- public Map<Integer, Map<Integer, Migration>> getMigrations() {
- return Collections.unmodifiableMap(mMigrations);
+ open fun getMigrations(): Map<Int, Map<Int, Migration>> {
+ return migrations
}
/**
- * Finds the list of migrations that should be run to move from {@code start} version to
- * {@code end} version.
+ * Finds the list of migrations that should be run to move from `start` version to
+ * `end` version.
*
* @param start The current database version
* @param end The target database version
- * @return An ordered list of {@link Migration} objects that should be run to migrate
- * between the given versions. If a migration path cannot be found, returns {@code null}.
+ * @return An ordered list of [Migration] objects that should be run to migrate
+ * between the given versions. If a migration path cannot be found, returns `null`.
*/
- @SuppressWarnings("WeakerAccess")
- @Nullable
- public List<Migration> findMigrationPath(int start, int end) {
+ open fun findMigrationPath(start: Int, end: Int): List<Migration>? {
if (start == end) {
- return Collections.emptyList();
+ return emptyList()
}
- boolean migrateUp = end > start;
- List<Migration> result = new ArrayList<>();
- return findUpMigrationPath(result, migrateUp, start, end);
+ val migrateUp = end > start
+ val result = mutableListOf<Migration>()
+ return findUpMigrationPath(result, migrateUp, start, end)
}
- private List<Migration> findUpMigrationPath(List<Migration> result, boolean upgrade,
- int start, int end) {
- while (upgrade ? start < end : start > end) {
- TreeMap<Integer, Migration> targetNodes = mMigrations.get(start);
- if (targetNodes == null) {
- return null;
- }
+ private fun findUpMigrationPath(
+ result: MutableList<Migration>,
+ upgrade: Boolean,
+ start: Int,
+ end: Int
+ ): List<Migration>? {
+ var migrationStart = start
+ while (if (upgrade) migrationStart < end else migrationStart > end) {
+ val targetNodes = migrations[migrationStart] ?: return null
// keys are ordered so we can start searching from one end of them.
- Set<Integer> keySet;
- if (upgrade) {
- keySet = targetNodes.descendingKeySet();
+ val keySet = if (upgrade) {
+ targetNodes.descendingKeySet()
} else {
- keySet = targetNodes.keySet();
+ targetNodes.keys
}
- boolean found = false;
- for (int targetVersion : keySet) {
- final boolean shouldAddToPath;
- if (upgrade) {
- shouldAddToPath = targetVersion <= end && targetVersion > start;
+ var found = false
+ for (targetVersion in keySet) {
+ val shouldAddToPath = if (upgrade) {
+ targetVersion in (migrationStart + 1)..end
} else {
- shouldAddToPath = targetVersion >= end && targetVersion < start;
+ targetVersion in end until migrationStart
}
if (shouldAddToPath) {
- result.add(targetNodes.get(targetVersion));
- start = targetVersion;
- found = true;
- break;
+ // We are iterating over the key set of targetNodes, so we can assume it
+ // won't return a null value.
+ result.add(targetNodes[targetVersion]!!)
+ migrationStart = targetVersion
+ found = true
+ break
}
}
if (!found) {
- return null;
+ return null
}
}
- return result;
+ return result
}
}
- /** Returns true if the calling thread is the main thread. */
- private static boolean isMainThread() {
- return Looper.getMainLooper().getThread() == Thread.currentThread();
- }
-
/**
- * Callback for {@link RoomDatabase}.
+ * Callback for [RoomDatabase].
*/
- public abstract static class Callback {
-
+ abstract class Callback {
/**
* Called when the database is created for the first time. This is called after all the
* tables are created.
*
* @param db The database.
*/
- public void onCreate(@NonNull SupportSQLiteDatabase db) {
- }
+ open fun onCreate(db: SupportSQLiteDatabase) {}
/**
* Called when the database has been opened.
*
* @param db The database.
*/
- public void onOpen(@NonNull SupportSQLiteDatabase db) {
- }
+ open fun onOpen(db: SupportSQLiteDatabase) {}
/**
* Called after the database was destructively migrated
*
* @param db The database.
*/
- public void onDestructiveMigration(@NonNull SupportSQLiteDatabase db){
- }
+ open fun onDestructiveMigration(db: SupportSQLiteDatabase) {}
}
/**
- * Callback for {@link Builder#createFromAsset(String)}, {@link Builder#createFromFile(File)}
- * and {@link Builder#createFromInputStream(Callable)}
- * <p>
+ * Callback for [Builder.createFromAsset], [Builder.createFromFile]
+ * and [Builder.createFromInputStream]
+ *
* This callback will be invoked after the pre-package DB is copied but before Room had
- * a chance to open it and therefore before the {@link RoomDatabase.Callback} methods are
+ * a chance to open it and therefore before the [RoomDatabase.Callback] methods are
* invoked. This callback can be useful for updating the pre-package DB schema to satisfy
* Room's schema validation.
*/
- public abstract static class PrepackagedDatabaseCallback {
-
+ abstract class PrepackagedDatabaseCallback {
/**
* Called when the pre-packaged database has been copied.
*
* @param db The database.
*/
- public void onOpenPrepackagedDatabase(@NonNull SupportSQLiteDatabase db) {
- }
+ open fun onOpenPrepackagedDatabase(db: SupportSQLiteDatabase) {}
}
/**
* Callback interface for when SQLite queries are executed.
*
- * @see RoomDatabase.Builder#setQueryCallback
+ * Can be set using [RoomDatabase.Builder.setQueryCallback].
*/
- public interface QueryCallback {
-
+ interface QueryCallback {
/**
* Called when a SQL query is executed.
*
* @param sqlQuery The SQLite query statement.
* @param bindArgs Arguments of the query if available, empty list otherwise.
*/
- void onQuery(@NonNull String sqlQuery, @NonNull List<Object>
- bindArgs);
+ fun onQuery(sqlQuery: String, bindArgs: List<Any?>)
+ }
+
+ companion object {
+ /**
+ * Unfortunately, we cannot read this value so we are only setting it to the SQLite default.
+ *
+ * @hide
+ */
+ @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP_PREFIX)
+ const val MAX_BIND_PARAMETER_CNT = 999
}
}
diff --git a/room/room-runtime/src/main/java/androidx/room/RoomOpenHelper.kt b/room/room-runtime/src/main/java/androidx/room/RoomOpenHelper.kt
index 3913193..c3008b3 100644
--- a/room/room-runtime/src/main/java/androidx/room/RoomOpenHelper.kt
+++ b/room/room-runtime/src/main/java/androidx/room/RoomOpenHelper.kt
@@ -13,222 +13,185 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
+package androidx.room
-package androidx.room;
-
-import android.database.Cursor;
-
-import androidx.annotation.NonNull;
-import androidx.annotation.Nullable;
-import androidx.annotation.RestrictTo;
-import androidx.room.migration.Migration;
-import androidx.sqlite.db.SimpleSQLiteQuery;
-import androidx.sqlite.db.SupportSQLiteDatabase;
-import androidx.sqlite.db.SupportSQLiteOpenHelper;
-
-import java.util.List;
+import androidx.annotation.RestrictTo
+import androidx.room.util.useCursor
+import androidx.sqlite.db.SimpleSQLiteQuery
+import androidx.sqlite.db.SupportSQLiteDatabase
+import androidx.sqlite.db.SupportSQLiteOpenHelper
/**
* An open helper that holds a reference to the configuration until the database is opened.
*
* @hide
*/
-@SuppressWarnings("unused")
@RestrictTo(RestrictTo.Scope.LIBRARY_GROUP_PREFIX)
-public class RoomOpenHelper extends SupportSQLiteOpenHelper.Callback {
- @Nullable
- private DatabaseConfiguration mConfiguration;
- @NonNull
- private final Delegate mDelegate;
- @NonNull
- private final String mIdentityHash;
+open class RoomOpenHelper(
+ configuration: DatabaseConfiguration,
+ delegate: Delegate,
+ identityHash: String,
+ legacyHash: String
+) : SupportSQLiteOpenHelper.Callback(delegate.version) {
+ private var configuration: DatabaseConfiguration?
+ private val delegate: Delegate
+ private val identityHash: String
+
/**
* Room v1 had a bug where the hash was not consistent if fields are reordered.
* The new has fixes it but we still need to accept the legacy hash.
*/
- @NonNull // b/64290754
- private final String mLegacyHash;
+ // b/64290754
+ private val legacyHash: String
- public RoomOpenHelper(@NonNull DatabaseConfiguration configuration, @NonNull Delegate delegate,
- @NonNull String identityHash, @NonNull String legacyHash) {
- super(delegate.version);
- mConfiguration = configuration;
- mDelegate = delegate;
- mIdentityHash = identityHash;
- mLegacyHash = legacyHash;
+ init {
+ this.configuration = configuration
+ this.delegate = delegate
+ this.identityHash = identityHash
+ this.legacyHash = legacyHash
}
- public RoomOpenHelper(@NonNull DatabaseConfiguration configuration, @NonNull Delegate delegate,
- @NonNull String legacyHash) {
- this(configuration, delegate, "", legacyHash);
+ constructor(
+ configuration: DatabaseConfiguration,
+ delegate: Delegate,
+ legacyHash: String
+ ) : this(configuration, delegate, "", legacyHash)
+
+ override fun onConfigure(db: SupportSQLiteDatabase) {
+ super.onConfigure(db)
}
- @Override
- public void onConfigure(SupportSQLiteDatabase db) {
- super.onConfigure(db);
- }
-
- @Override
- public void onCreate(SupportSQLiteDatabase db) {
- boolean isEmptyDatabase = hasEmptySchema(db);
- mDelegate.createAllTables(db);
+ override fun onCreate(db: SupportSQLiteDatabase) {
+ val isEmptyDatabase = hasEmptySchema(db)
+ delegate.createAllTables(db)
if (!isEmptyDatabase) {
// A 0 version pre-populated database goes through the create path because the
// framework's SQLiteOpenHelper thinks the database was just created from scratch. If we
// find the database not to be empty, then it is a pre-populated, we must validate it to
// see if its suitable for usage.
- ValidationResult result = mDelegate.onValidateSchema(db);
+ val result = delegate.onValidateSchema(db)
if (!result.isValid) {
- throw new IllegalStateException("Pre-packaged database has an invalid schema: "
- + result.expectedFoundMsg);
+ throw IllegalStateException(
+ "Pre-packaged database has an invalid schema: ${result.expectedFoundMsg}"
+ )
}
}
- updateIdentity(db);
- mDelegate.onCreate(db);
+ updateIdentity(db)
+ delegate.onCreate(db)
}
- @Override
- public void onUpgrade(SupportSQLiteDatabase db, int oldVersion, int newVersion) {
- boolean migrated = false;
- if (mConfiguration != null) {
- List<Migration> migrations = mConfiguration.migrationContainer.findMigrationPath(
- oldVersion, newVersion);
+ override fun onUpgrade(db: SupportSQLiteDatabase, oldVersion: Int, newVersion: Int) {
+ var migrated = false
+ configuration?.let { config ->
+ val migrations = config.migrationContainer.findMigrationPath(
+ oldVersion, newVersion
+ )
if (migrations != null) {
- mDelegate.onPreMigrate(db);
- for (Migration migration : migrations) {
- migration.migrate(db);
- }
- ValidationResult result = mDelegate.onValidateSchema(db);
+ delegate.onPreMigrate(db)
+ migrations.forEach { it.migrate(db) }
+ val result = delegate.onValidateSchema(db)
if (!result.isValid) {
- throw new IllegalStateException("Migration didn't properly handle: "
- + result.expectedFoundMsg);
+ throw IllegalStateException(
+ ("Migration didn't properly handle: " +
+ result.expectedFoundMsg)
+ )
}
- mDelegate.onPostMigrate(db);
- updateIdentity(db);
- migrated = true;
+ delegate.onPostMigrate(db)
+ updateIdentity(db)
+ migrated = true
}
}
if (!migrated) {
- if (mConfiguration != null
- && !mConfiguration.isMigrationRequired(oldVersion, newVersion)) {
- mDelegate.dropAllTables(db);
- mDelegate.createAllTables(db);
+ val config = this.configuration
+ if (config != null && !config.isMigrationRequired(oldVersion, newVersion)) {
+ delegate.dropAllTables(db)
+ delegate.createAllTables(db)
} else {
- throw new IllegalStateException("A migration from " + oldVersion + " to "
- + newVersion + " was required but not found. Please provide the "
- + "necessary Migration path via "
- + "RoomDatabase.Builder.addMigration(Migration ...) or allow for "
- + "destructive migrations via one of the "
- + "RoomDatabase.Builder.fallbackToDestructiveMigration* methods.");
+ throw IllegalStateException(
+ "A migration from $oldVersion to $newVersion was required but not found. " +
+ "Please provide the " +
+ "necessary Migration path via " +
+ "RoomDatabase.Builder.addMigration(Migration ...) or allow for " +
+ "destructive migrations via one of the " +
+ "RoomDatabase.Builder.fallbackToDestructiveMigration* methods."
+ )
}
}
}
- @Override
- public void onDowngrade(SupportSQLiteDatabase db, int oldVersion, int newVersion) {
- onUpgrade(db, oldVersion, newVersion);
+ override fun onDowngrade(db: SupportSQLiteDatabase, oldVersion: Int, newVersion: Int) {
+ onUpgrade(db, oldVersion, newVersion)
}
- @Override
- public void onOpen(SupportSQLiteDatabase db) {
- super.onOpen(db);
- checkIdentity(db);
- mDelegate.onOpen(db);
+ override fun onOpen(db: SupportSQLiteDatabase) {
+ super.onOpen(db)
+ checkIdentity(db)
+ delegate.onOpen(db)
// there might be too many configurations etc, just clear it.
- mConfiguration = null;
+ configuration = null
}
- private void checkIdentity(SupportSQLiteDatabase db) {
+ private fun checkIdentity(db: SupportSQLiteDatabase) {
if (hasRoomMasterTable(db)) {
- String identityHash = null;
- Cursor cursor = db.query(new SimpleSQLiteQuery(RoomMasterTable.READ_QUERY));
- //noinspection TryFinallyCanBeTryWithResources
- try {
+ val identityHash: String? = db.query(
+ SimpleSQLiteQuery(RoomMasterTable.READ_QUERY)
+ ).useCursor { cursor ->
if (cursor.moveToFirst()) {
- identityHash = cursor.getString(0);
+ cursor.getString(0)
+ } else {
+ null
}
- } finally {
- cursor.close();
}
- if (!mIdentityHash.equals(identityHash) && !mLegacyHash.equals(identityHash)) {
- throw new IllegalStateException("Room cannot verify the data integrity. Looks like"
- + " you've changed schema but forgot to update the version number. You can"
- + " simply fix this by increasing the version number. Expected identity"
- + " hash: " + mIdentityHash + ", found: " + identityHash);
+
+ if (this.identityHash != identityHash && this.legacyHash != identityHash) {
+ throw IllegalStateException(
+ "Room cannot verify the data integrity. Looks like" +
+ " you've changed schema but forgot to update the version number. You can" +
+ " simply fix this by increasing the version number. Expected identity" +
+ " hash: ${ this.identityHash }, found: $identityHash"
+ )
}
} else {
// No room_master_table, this might an a pre-populated DB, we must validate to see if
// its suitable for usage.
- ValidationResult result = mDelegate.onValidateSchema(db);
+ val result = delegate.onValidateSchema(db)
if (!result.isValid) {
- throw new IllegalStateException("Pre-packaged database has an invalid schema: "
- + result.expectedFoundMsg);
+ throw IllegalStateException(
+ "Pre-packaged database has an invalid schema: ${result.expectedFoundMsg}"
+ )
}
- mDelegate.onPostMigrate(db);
- updateIdentity(db);
+ delegate.onPostMigrate(db)
+ updateIdentity(db)
}
}
- private void updateIdentity(SupportSQLiteDatabase db) {
- createMasterTableIfNotExists(db);
- db.execSQL(RoomMasterTable.createInsertQuery(mIdentityHash));
+ private fun updateIdentity(db: SupportSQLiteDatabase) {
+ createMasterTableIfNotExists(db)
+ db.execSQL(RoomMasterTable.createInsertQuery(identityHash))
}
- private void createMasterTableIfNotExists(SupportSQLiteDatabase db) {
- db.execSQL(RoomMasterTable.CREATE_QUERY);
- }
-
- private static boolean hasRoomMasterTable(SupportSQLiteDatabase db) {
- Cursor cursor = db.query("SELECT 1 FROM sqlite_master WHERE type = 'table' AND name='"
- + RoomMasterTable.TABLE_NAME + "'");
- //noinspection TryFinallyCanBeTryWithResources
- try {
- return cursor.moveToFirst() && cursor.getInt(0) != 0;
- } finally {
- cursor.close();
- }
- }
-
- private static boolean hasEmptySchema(SupportSQLiteDatabase db) {
- Cursor cursor = db.query(
- "SELECT count(*) FROM sqlite_master WHERE name != 'android_metadata'");
- //noinspection TryFinallyCanBeTryWithResources
- try {
- return cursor.moveToFirst() && cursor.getInt(0) == 0;
- } finally {
- cursor.close();
- }
+ private fun createMasterTableIfNotExists(db: SupportSQLiteDatabase) {
+ db.execSQL(RoomMasterTable.CREATE_QUERY)
}
/**
* @hide
*/
@RestrictTo(RestrictTo.Scope.LIBRARY_GROUP_PREFIX)
- public abstract static class Delegate {
- public final int version;
-
- public Delegate(int version) {
- this.version = version;
- }
-
- protected abstract void dropAllTables(SupportSQLiteDatabase database);
-
- protected abstract void createAllTables(SupportSQLiteDatabase database);
-
- protected abstract void onOpen(SupportSQLiteDatabase database);
-
- protected abstract void onCreate(SupportSQLiteDatabase database);
+ abstract class Delegate(@JvmField val version: Int) {
+ abstract fun dropAllTables(database: SupportSQLiteDatabase)
+ abstract fun createAllTables(database: SupportSQLiteDatabase)
+ abstract fun onOpen(database: SupportSQLiteDatabase)
+ abstract fun onCreate(database: SupportSQLiteDatabase)
/**
* Called after a migration run to validate database integrity.
*
* @param db The SQLite database.
- *
- * @deprecated Use {@link #onValidateSchema(SupportSQLiteDatabase)}
*/
- @Deprecated
- protected void validateMigration(SupportSQLiteDatabase db) {
- throw new UnsupportedOperationException("validateMigration is deprecated");
+ @Deprecated("Use [onValidateSchema(SupportSQLiteDatabase)]")
+ protected open fun validateMigration(db: SupportSQLiteDatabase) {
+ throw UnsupportedOperationException("validateMigration is deprecated")
}
/**
@@ -236,43 +199,49 @@
*
* @param db The SQLite database.
*/
- @SuppressWarnings("deprecation")
- @NonNull
- protected ValidationResult onValidateSchema(@NonNull SupportSQLiteDatabase db) {
- validateMigration(db);
- return new ValidationResult(true, null);
+ @Suppress("DEPRECATION")
+ open fun onValidateSchema(db: SupportSQLiteDatabase): ValidationResult {
+ validateMigration(db)
+ return ValidationResult(true, null)
}
/**
* Called before migrations execute to perform preliminary work.
* @param database The SQLite database.
*/
- protected void onPreMigrate(SupportSQLiteDatabase database) {
-
- }
+ open fun onPreMigrate(database: SupportSQLiteDatabase) {}
/**
* Called after migrations execute to perform additional work.
* @param database The SQLite database.
*/
- protected void onPostMigrate(SupportSQLiteDatabase database) {
-
- }
+ open fun onPostMigrate(database: SupportSQLiteDatabase) {}
}
/**
* @hide
*/
@RestrictTo(RestrictTo.Scope.LIBRARY_GROUP_PREFIX)
- public static class ValidationResult {
+ open class ValidationResult(
+ @JvmField val isValid: Boolean,
+ @JvmField val expectedFoundMsg: String?
+ )
+ companion object {
+ internal fun hasRoomMasterTable(db: SupportSQLiteDatabase): Boolean {
+ db.query(
+ "SELECT 1 FROM sqlite_master WHERE type = 'table' AND " +
+ "name='${ RoomMasterTable.TABLE_NAME }'"
+ ).useCursor { cursor ->
+ return cursor.moveToFirst() && cursor.getInt(0) != 0
+ }
+ }
- public final boolean isValid;
- @Nullable
- public final String expectedFoundMsg;
-
- public ValidationResult(boolean isValid, @Nullable String expectedFoundMsg) {
- this.isValid = isValid;
- this.expectedFoundMsg = expectedFoundMsg;
+ internal fun hasEmptySchema(db: SupportSQLiteDatabase): Boolean {
+ db.query(
+ "SELECT count(*) FROM sqlite_master WHERE name != 'android_metadata'"
+ ).useCursor { cursor ->
+ return cursor.moveToFirst() && cursor.getInt(0) == 0
+ }
}
}
-}
+}
\ No newline at end of file
diff --git a/room/room-runtime/src/main/java/androidx/room/RoomSQLiteQuery.kt b/room/room-runtime/src/main/java/androidx/room/RoomSQLiteQuery.kt
index 689352c..8f9ed4d 100644
--- a/room/room-runtime/src/main/java/androidx/room/RoomSQLiteQuery.kt
+++ b/room/room-runtime/src/main/java/androidx/room/RoomSQLiteQuery.kt
@@ -13,253 +13,128 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
+package androidx.room
-package androidx.room;
-
-import androidx.annotation.IntDef;
-import androidx.annotation.RestrictTo;
-import androidx.annotation.VisibleForTesting;
-import androidx.sqlite.db.SupportSQLiteProgram;
-import androidx.sqlite.db.SupportSQLiteQuery;
-
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.util.Arrays;
-import java.util.Iterator;
-import java.util.Map;
-import java.util.TreeMap;
+import androidx.annotation.IntDef
+import androidx.annotation.RestrictTo
+import androidx.annotation.VisibleForTesting
+import androidx.sqlite.db.SupportSQLiteProgram
+import androidx.sqlite.db.SupportSQLiteQuery
+import java.util.Arrays
+import java.util.TreeMap
/**
* This class is used as an intermediate place to keep binding arguments so that we can run
* Cursor queries with correct types rather than passing everything as a string.
- * <p>
+ *
* Because it is relatively a big object, they are pooled and must be released after each use.
*
* @hide
*/
-@SuppressWarnings("unused")
@RestrictTo(RestrictTo.Scope.LIBRARY_GROUP_PREFIX)
-public class RoomSQLiteQuery implements SupportSQLiteQuery, SupportSQLiteProgram {
- @SuppressWarnings("WeakerAccess")
+open class RoomSQLiteQuery private constructor(
+ @field:VisibleForTesting val capacity: Int
+) : SupportSQLiteQuery, SupportSQLiteProgram {
+ @Volatile
+ private var query: String? = null
+
+ @JvmField
@VisibleForTesting
- // Maximum number of queries we'll keep cached.
- static final int POOL_LIMIT = 15;
- @SuppressWarnings("WeakerAccess")
+ val longBindings: LongArray
+
+ @JvmField
@VisibleForTesting
- // Once we hit POOL_LIMIT, we'll bring the pool size back to the desired number. We always
- // clear the bigger queries (# of arguments).
- static final int DESIRED_POOL_SIZE = 10;
- private volatile String mQuery;
- @SuppressWarnings("WeakerAccess")
+ val doubleBindings: DoubleArray
+
+ @JvmField
@VisibleForTesting
- final long[] mLongBindings;
- @SuppressWarnings("WeakerAccess")
+ val stringBindings: Array<String?>
+
+ @JvmField
@VisibleForTesting
- final double[] mDoubleBindings;
- @SuppressWarnings("WeakerAccess")
- @VisibleForTesting
- final String[] mStringBindings;
- @SuppressWarnings("WeakerAccess")
- @VisibleForTesting
- final byte[][] mBlobBindings;
+ val blobBindings: Array<ByteArray?>
@Binding
- private final int[] mBindingTypes;
- @SuppressWarnings("WeakerAccess")
- @VisibleForTesting
- final int mCapacity;
+ private val bindingTypes: IntArray
+
// number of arguments in the query
- @SuppressWarnings("WeakerAccess")
+ @JvmField
@VisibleForTesting
- int mArgCount;
+ var argCount = 0
-
- @SuppressWarnings("WeakerAccess")
- @VisibleForTesting
- static final TreeMap<Integer, RoomSQLiteQuery> sQueryPool = new TreeMap<>();
-
- /**
- * Copies the given SupportSQLiteQuery and converts it into RoomSQLiteQuery.
- *
- * @param supportSQLiteQuery The query to copy from
- * @return A new query copied from the provided one.
- */
- public static RoomSQLiteQuery copyFrom(SupportSQLiteQuery supportSQLiteQuery) {
- final RoomSQLiteQuery query = RoomSQLiteQuery.acquire(
- supportSQLiteQuery.getSql(),
- supportSQLiteQuery.getArgCount());
- supportSQLiteQuery.bindTo(new SupportSQLiteProgram() {
- @Override
- public void bindNull(int index) {
- query.bindNull(index);
- }
-
- @Override
- public void bindLong(int index, long value) {
- query.bindLong(index, value);
- }
-
- @Override
- public void bindDouble(int index, double value) {
- query.bindDouble(index, value);
- }
-
- @Override
- public void bindString(int index, String value) {
- query.bindString(index, value);
- }
-
- @Override
- public void bindBlob(int index, byte[] value) {
- query.bindBlob(index, value);
- }
-
- @Override
- public void clearBindings() {
- query.clearBindings();
- }
-
- @Override
- public void close() {
- // ignored.
- }
- });
- return query;
+ open fun init(query: String, initArgCount: Int) {
+ this.query = query
+ argCount = initArgCount
}
- /**
- * Returns a new RoomSQLiteQuery that can accept the given number of arguments and holds the
- * given query.
- *
- * @param query The query to prepare
- * @param argumentCount The number of query arguments
- * @return A RoomSQLiteQuery that holds the given query and has space for the given number of
- * arguments.
- */
- @SuppressWarnings("WeakerAccess")
- public static RoomSQLiteQuery acquire(String query, int argumentCount) {
- synchronized (sQueryPool) {
- final Map.Entry<Integer, RoomSQLiteQuery> entry =
- sQueryPool.ceilingEntry(argumentCount);
- if (entry != null) {
- sQueryPool.remove(entry.getKey());
- final RoomSQLiteQuery sqliteQuery = entry.getValue();
- sqliteQuery.init(query, argumentCount);
- return sqliteQuery;
- }
- }
- RoomSQLiteQuery sqLiteQuery = new RoomSQLiteQuery(argumentCount);
- sqLiteQuery.init(query, argumentCount);
- return sqLiteQuery;
- }
-
- private RoomSQLiteQuery(int capacity) {
- mCapacity = capacity;
+ init {
// because, 1 based indices... we don't want to offsets everything with 1 all the time.
- int limit = capacity + 1;
- //noinspection WrongConstant
- mBindingTypes = new int[limit];
- mLongBindings = new long[limit];
- mDoubleBindings = new double[limit];
- mStringBindings = new String[limit];
- mBlobBindings = new byte[limit][];
- }
-
- @SuppressWarnings("WeakerAccess")
- void init(String query, int argCount) {
- mQuery = query;
- mArgCount = argCount;
+ val limit = capacity + 1
+ bindingTypes = IntArray(limit)
+ longBindings = LongArray(limit)
+ doubleBindings = DoubleArray(limit)
+ stringBindings = arrayOfNulls(limit)
+ blobBindings = arrayOfNulls(limit)
}
/**
* Releases the query back to the pool.
- * <p>
- * After released, the statement might be returned when {@link #acquire(String, int)} is called
+ *
+ * After released, the statement might be returned when [.acquire] is called
* so you should never re-use it after releasing.
*/
- @SuppressWarnings("WeakerAccess")
- public void release() {
- synchronized (sQueryPool) {
- sQueryPool.put(mCapacity, this);
- prunePoolLocked();
+ open fun release() {
+ synchronized(queryPool) {
+ queryPool[capacity] = this
+ prunePoolLocked()
}
}
- private static void prunePoolLocked() {
- if (sQueryPool.size() > POOL_LIMIT) {
- int toBeRemoved = sQueryPool.size() - DESIRED_POOL_SIZE;
- final Iterator<Integer> iterator = sQueryPool.descendingKeySet().iterator();
- while (toBeRemoved-- > 0) {
- iterator.next();
- iterator.remove();
+ override fun getSql(): String {
+ return requireNotNull(query)
+ }
+
+ override fun getArgCount(): Int {
+ return argCount
+ }
+
+ override fun bindTo(program: SupportSQLiteProgram) {
+ for (index in 1..argCount) {
+ when (bindingTypes[index]) {
+ NULL -> program.bindNull(index)
+ LONG -> program.bindLong(index, longBindings[index])
+ DOUBLE -> program.bindDouble(index, doubleBindings[index])
+ STRING -> program.bindString(index, stringBindings[index])
+ BLOB -> program.bindBlob(index, blobBindings[index])
}
}
}
- @Override
- public String getSql() {
- return mQuery;
+ override fun bindNull(index: Int) {
+ bindingTypes[index] = NULL
}
- @Override
- public int getArgCount() {
- return mArgCount;
+ override fun bindLong(index: Int, value: Long) {
+ bindingTypes[index] = LONG
+ longBindings[index] = value
}
- @Override
- public void bindTo(SupportSQLiteProgram program) {
- for (int index = 1; index <= mArgCount; index++) {
- switch (mBindingTypes[index]) {
- case NULL:
- program.bindNull(index);
- break;
- case LONG:
- program.bindLong(index, mLongBindings[index]);
- break;
- case DOUBLE:
- program.bindDouble(index, mDoubleBindings[index]);
- break;
- case STRING:
- program.bindString(index, mStringBindings[index]);
- break;
- case BLOB:
- program.bindBlob(index, mBlobBindings[index]);
- break;
- }
- }
+ override fun bindDouble(index: Int, value: Double) {
+ bindingTypes[index] = DOUBLE
+ doubleBindings[index] = value
}
- @Override
- public void bindNull(int index) {
- mBindingTypes[index] = NULL;
+ override fun bindString(index: Int, value: String) {
+ bindingTypes[index] = STRING
+ stringBindings[index] = value
}
- @Override
- public void bindLong(int index, long value) {
- mBindingTypes[index] = LONG;
- mLongBindings[index] = value;
+ override fun bindBlob(index: Int, value: ByteArray) {
+ bindingTypes[index] = BLOB
+ blobBindings[index] = value
}
- @Override
- public void bindDouble(int index, double value) {
- mBindingTypes[index] = DOUBLE;
- mDoubleBindings[index] = value;
- }
-
- @Override
- public void bindString(int index, String value) {
- mBindingTypes[index] = STRING;
- mStringBindings[index] = value;
- }
-
- @Override
- public void bindBlob(int index, byte[] value) {
- mBindingTypes[index] = BLOB;
- mBlobBindings[index] = value;
- }
-
- @Override
- public void close() {
+ override fun close() {
// no-op. not calling release because it is internal API.
}
@@ -268,32 +143,98 @@
*
* @param other The other query, which holds the arguments to be copied.
*/
- public void copyArgumentsFrom(RoomSQLiteQuery other) {
- int argCount = other.getArgCount() + 1; // +1 for the binding offsets
- System.arraycopy(other.mBindingTypes, 0, mBindingTypes, 0, argCount);
- System.arraycopy(other.mLongBindings, 0, mLongBindings, 0, argCount);
- System.arraycopy(other.mStringBindings, 0, mStringBindings, 0, argCount);
- System.arraycopy(other.mBlobBindings, 0, mBlobBindings, 0, argCount);
- System.arraycopy(other.mDoubleBindings, 0, mDoubleBindings, 0, argCount);
+ open fun copyArgumentsFrom(other: RoomSQLiteQuery) {
+ val argCount = other.argCount + 1 // +1 for the binding offsets
+ System.arraycopy(other.bindingTypes, 0, bindingTypes, 0, argCount)
+ System.arraycopy(other.longBindings, 0, longBindings, 0, argCount)
+ System.arraycopy(other.stringBindings, 0, stringBindings, 0, argCount)
+ System.arraycopy(other.blobBindings, 0, blobBindings, 0, argCount)
+ System.arraycopy(other.doubleBindings, 0, doubleBindings, 0, argCount)
}
- @Override
- public void clearBindings() {
- Arrays.fill(mBindingTypes, NULL);
- Arrays.fill(mStringBindings, null);
- Arrays.fill(mBlobBindings, null);
- mQuery = null;
+ override fun clearBindings() {
+ Arrays.fill(bindingTypes, NULL)
+ Arrays.fill(stringBindings, null)
+ Arrays.fill(blobBindings, null)
+ query = null
// no need to clear others
}
- private static final int NULL = 1;
- private static final int LONG = 2;
- private static final int DOUBLE = 3;
- private static final int STRING = 4;
- private static final int BLOB = 5;
+ @Retention(AnnotationRetention.SOURCE)
+ @IntDef(NULL, LONG, DOUBLE, STRING, BLOB)
+ internal annotation class Binding
- @Retention(RetentionPolicy.SOURCE)
- @IntDef({NULL, LONG, DOUBLE, STRING, BLOB})
- @interface Binding {
+ companion object {
+ // Maximum number of queries we'll keep cached.
+ @VisibleForTesting
+ const val POOL_LIMIT = 15
+
+ // Once we hit POOL_LIMIT, we'll bring the pool size back to the desired number. We always
+ // clear the bigger queries (# of arguments).
+ @VisibleForTesting
+ const val DESIRED_POOL_SIZE = 10
+
+ @JvmField
+ @VisibleForTesting
+ val queryPool = TreeMap<Int, RoomSQLiteQuery>()
+
+ /**
+ * Copies the given SupportSQLiteQuery and converts it into RoomSQLiteQuery.
+ *
+ * @param supportSQLiteQuery The query to copy from
+ * @return A new query copied from the provided one.
+ */
+ @JvmStatic
+ fun copyFrom(supportSQLiteQuery: SupportSQLiteQuery): RoomSQLiteQuery {
+ val query = acquire(
+ supportSQLiteQuery.sql,
+ supportSQLiteQuery.argCount
+ )
+
+ supportSQLiteQuery.bindTo(object : SupportSQLiteProgram by query {})
+ return query
+ }
+
+ /**
+ * Returns a new RoomSQLiteQuery that can accept the given number of arguments and holds the
+ * given query.
+ *
+ * @param query The query to prepare
+ * @param argumentCount The number of query arguments
+ * @return A RoomSQLiteQuery that holds the given query and has space for the given number
+ * of arguments.
+ */
+ @JvmStatic
+ fun acquire(query: String, argumentCount: Int): RoomSQLiteQuery {
+ synchronized(queryPool) {
+ val entry = queryPool.ceilingEntry(argumentCount)
+ if (entry != null) {
+ queryPool.remove(entry.key)
+ val sqliteQuery = entry.value
+ sqliteQuery.init(query, argumentCount)
+ return sqliteQuery
+ }
+ }
+ val sqLiteQuery = RoomSQLiteQuery(argumentCount)
+ sqLiteQuery.init(query, argumentCount)
+ return sqLiteQuery
+ }
+
+ internal fun prunePoolLocked() {
+ if (queryPool.size > POOL_LIMIT) {
+ var toBeRemoved = queryPool.size - DESIRED_POOL_SIZE
+ val iterator = queryPool.descendingKeySet().iterator()
+ while (toBeRemoved-- > 0) {
+ iterator.next()
+ iterator.remove()
+ }
+ }
+ }
+
+ private const val NULL = 1
+ private const val LONG = 2
+ private const val DOUBLE = 3
+ private const val STRING = 4
+ private const val BLOB = 5
}
-}
+}
\ No newline at end of file
diff --git a/room/room-runtime/src/main/java/androidx/room/RoomTrackingLiveData.kt b/room/room-runtime/src/main/java/androidx/room/RoomTrackingLiveData.kt
index a2785b8..1cacf6d 100644
--- a/room/room-runtime/src/main/java/androidx/room/RoomTrackingLiveData.kt
+++ b/room/room-runtime/src/main/java/androidx/room/RoomTrackingLiveData.kt
@@ -119,8 +119,8 @@
val queryExecutor: Executor
get() = if (inTransaction) {
- database.transactionExecutor
+ database.getTransactionExecutor()
} else {
- database.queryExecutor
+ database.getQueryExecutor()
}
}
\ No newline at end of file
diff --git a/room/room-runtime/src/main/java/androidx/room/TransactionExecutor.kt b/room/room-runtime/src/main/java/androidx/room/TransactionExecutor.kt
index 53648d3..c143951 100644
--- a/room/room-runtime/src/main/java/androidx/room/TransactionExecutor.kt
+++ b/room/room-runtime/src/main/java/androidx/room/TransactionExecutor.kt
@@ -13,52 +13,45 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
+package androidx.room
-package androidx.room;
-
-import androidx.annotation.NonNull;
-
-import java.util.ArrayDeque;
-import java.util.concurrent.Executor;
+import android.annotation.SuppressLint
+import java.util.ArrayDeque
+import java.util.concurrent.Executor
/**
* Executor wrapper for performing database transactions serially.
- * <p>
+ *
* Since database transactions are exclusive, this executor ensures that transactions are performed
* in-order and one at a time, preventing threads from blocking each other when multiple concurrent
* transactions are attempted.
*/
-class TransactionExecutor implements Executor {
-
- private final Executor mExecutor;
- private final ArrayDeque<Runnable> mTasks = new ArrayDeque<>();
- private Runnable mActive;
-
- TransactionExecutor(@NonNull Executor executor) {
- mExecutor = executor;
- }
-
- @Override
- public synchronized void execute(final Runnable command) {
- mTasks.offer(new Runnable() {
- @Override
- public void run() {
+internal class TransactionExecutor(private val executor: Executor) : Executor {
+ private val tasks = ArrayDeque<Runnable>()
+ private var active: Runnable? = null
+ private val syncLock = Any()
+ override fun execute(command: Runnable) {
+ synchronized(syncLock) {
+ tasks.offer(Runnable {
try {
- command.run();
+ command.run()
} finally {
- scheduleNext();
+ scheduleNext()
}
+ })
+ if (active == null) {
+ scheduleNext()
}
- });
- if (mActive == null) {
- scheduleNext();
}
}
- @SuppressWarnings("WeakerAccess")
- synchronized void scheduleNext() {
- if ((mActive = mTasks.poll()) != null) {
- mExecutor.execute(mActive);
+ @SuppressLint("BanSynchronizedMethods")
+ @Synchronized
+ fun scheduleNext() {
+ synchronized(syncLock) {
+ if (tasks.poll().also { active = it } != null) {
+ executor.execute(active)
+ }
}
}
-}
+}
\ No newline at end of file
diff --git a/room/room-runtime/src/test/java/androidx/room/InvalidationTrackerTest.java b/room/room-runtime/src/test/java/androidx/room/InvalidationTrackerTest.java
index b5bd363..0805fac 100644
--- a/room/room-runtime/src/test/java/androidx/room/InvalidationTrackerTest.java
+++ b/room/room-runtime/src/test/java/androidx/room/InvalidationTrackerTest.java
@@ -76,6 +76,7 @@
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.locks.ReentrantLock;
[email protected] // TODO(b/233855234) - disabled until test is moved to Kotlin
@RunWith(JUnit4.class)
public class InvalidationTrackerTest {
private InvalidationTracker mTracker;
diff --git a/room/room-runtime/src/test/java/androidx/room/RoomSQLiteQueryTest.java b/room/room-runtime/src/test/java/androidx/room/RoomSQLiteQueryTest.java
index 9a70c2e..3ff9773 100644
--- a/room/room-runtime/src/test/java/androidx/room/RoomSQLiteQueryTest.java
+++ b/room/room-runtime/src/test/java/androidx/room/RoomSQLiteQueryTest.java
@@ -38,18 +38,18 @@
public class RoomSQLiteQueryTest {
@Before
public void clear() {
- RoomSQLiteQuery.sQueryPool.clear();
+ RoomSQLiteQuery.queryPool.clear();
}
@Test
public void acquireBasic() {
RoomSQLiteQuery query = RoomSQLiteQuery.acquire("abc", 3);
assertThat(query.getSql(), is("abc"));
- assertThat(query.mArgCount, is(3));
- assertThat(query.mBlobBindings.length, is(4));
- assertThat(query.mLongBindings.length, is(4));
- assertThat(query.mStringBindings.length, is(4));
- assertThat(query.mDoubleBindings.length, is(4));
+ assertThat(query.argCount, is(3));
+ assertThat(query.blobBindings.length, is(4));
+ assertThat(query.longBindings.length, is(4));
+ assertThat(query.stringBindings.length, is(4));
+ assertThat(query.doubleBindings.length, is(4));
}
@Test
@@ -97,10 +97,10 @@
query1.release();
query2.release();
- assertThat(RoomSQLiteQuery.sQueryPool.size(), is(1));
+ assertThat(RoomSQLiteQuery.queryPool.size(), is(1));
query3.release();
- assertThat(RoomSQLiteQuery.sQueryPool.size(), is(2));
+ assertThat(RoomSQLiteQuery.queryPool.size(), is(2));
}
@Test
@@ -138,12 +138,12 @@
}
private void pruneCacheTest() {
- assertThat(RoomSQLiteQuery.sQueryPool.size(), is(RoomSQLiteQuery.POOL_LIMIT));
+ assertThat(RoomSQLiteQuery.queryPool.size(), is(RoomSQLiteQuery.POOL_LIMIT));
RoomSQLiteQuery.acquire("dsadsa", RoomSQLiteQuery.POOL_LIMIT + 1).release();
- assertThat(RoomSQLiteQuery.sQueryPool.size(), is(RoomSQLiteQuery.DESIRED_POOL_SIZE));
- Iterator<RoomSQLiteQuery> itr = RoomSQLiteQuery.sQueryPool.values().iterator();
+ assertThat(RoomSQLiteQuery.queryPool.size(), is(RoomSQLiteQuery.DESIRED_POOL_SIZE));
+ Iterator<RoomSQLiteQuery> itr = RoomSQLiteQuery.queryPool.values().iterator();
for (int i = 0; i < RoomSQLiteQuery.DESIRED_POOL_SIZE; i++) {
- assertThat(itr.next().mCapacity, is(i));
+ assertThat(itr.next().getCapacity(), is(i));
}
}
}
diff --git a/room/room-testing/src/main/java/androidx/room/testing/MigrationTestHelper.java b/room/room-testing/src/main/java/androidx/room/testing/MigrationTestHelper.java
index 89277ef..c0a4a9f 100644
--- a/room/room-testing/src/main/java/androidx/room/testing/MigrationTestHelper.java
+++ b/room/room-testing/src/main/java/androidx/room/testing/MigrationTestHelper.java
@@ -580,14 +580,14 @@
}
@Override
- protected void createAllTables(SupportSQLiteDatabase database) {
+ public void createAllTables(SupportSQLiteDatabase database) {
throw new UnsupportedOperationException("Was expecting to migrate but received create."
+ "Make sure you have created the database first.");
}
@NonNull
@Override
- protected RoomOpenHelper.ValidationResult onValidateSchema(
+ public RoomOpenHelper.ValidationResult onValidateSchema(
@NonNull SupportSQLiteDatabase db) {
final Map<String, EntityBundle> tables = mDatabaseBundle.getEntitiesByTableName();
for (EntityBundle entity : tables.values()) {
@@ -652,7 +652,7 @@
}
@Override
- protected void createAllTables(SupportSQLiteDatabase database) {
+ public void createAllTables(SupportSQLiteDatabase database) {
for (String query : mDatabaseBundle.buildCreateQueries()) {
database.execSQL(query);
}
@@ -660,7 +660,7 @@
@NonNull
@Override
- protected RoomOpenHelper.ValidationResult onValidateSchema(
+ public RoomOpenHelper.ValidationResult onValidateSchema(
@NonNull SupportSQLiteDatabase db) {
throw new UnsupportedOperationException("This open helper just creates the database but"
+ " it received a migration request.");
@@ -676,16 +676,16 @@
}
@Override
- protected void dropAllTables(SupportSQLiteDatabase database) {
+ public void dropAllTables(SupportSQLiteDatabase database) {
throw new UnsupportedOperationException("cannot drop all tables in the test");
}
@Override
- protected void onCreate(SupportSQLiteDatabase database) {
+ public void onCreate(SupportSQLiteDatabase database) {
}
@Override
- protected void onOpen(SupportSQLiteDatabase database) {
+ public void onOpen(SupportSQLiteDatabase database) {
}
}
}
diff --git a/sqlite/integration-tests/inspection-room-testapp/src/androidTest/java/androidx/sqlite/inspection/RoomInvalidationHookTest.kt b/sqlite/integration-tests/inspection-room-testapp/src/androidTest/java/androidx/sqlite/inspection/RoomInvalidationHookTest.kt
index 6c745b8..b7e4a6f 100644
--- a/sqlite/integration-tests/inspection-room-testapp/src/androidTest/java/androidx/sqlite/inspection/RoomInvalidationHookTest.kt
+++ b/sqlite/integration-tests/inspection-room-testapp/src/androidTest/java/androidx/sqlite/inspection/RoomInvalidationHookTest.kt
@@ -129,7 +129,7 @@
* extract the framework sqlite database instance from a room database via reflection.
*/
private fun RoomDatabase.getSqliteDb(): SQLiteDatabase {
- val supportDb = this.openHelper.writableDatabase
+ val supportDb = this.getOpenHelper().writableDatabase
// this runs with defaults so we can extract db from it until inspection supports support
// instances directly
return supportDb::class.java.getDeclaredField("mDelegate").let {