Merge changes I5b900314,I440fc9a8 into androidx-main
* changes:
Commonize RoomDatabase.Builder.setJournalMode API
Commonize addTypeConverter() API in RoomDatabase.Builder
diff --git a/room/integration-tests/multiplatformtestapp/src/androidInstrumentedTest/kotlin/androidx/room/integration/multiplatformtestapp/test/SimpleQueryTest.kt b/room/integration-tests/multiplatformtestapp/src/androidInstrumentedTest/kotlin/androidx/room/integration/multiplatformtestapp/test/QueryTest.kt
similarity index 96%
rename from room/integration-tests/multiplatformtestapp/src/androidInstrumentedTest/kotlin/androidx/room/integration/multiplatformtestapp/test/SimpleQueryTest.kt
rename to room/integration-tests/multiplatformtestapp/src/androidInstrumentedTest/kotlin/androidx/room/integration/multiplatformtestapp/test/QueryTest.kt
index 300ff8c..765680c 100644
--- a/room/integration-tests/multiplatformtestapp/src/androidInstrumentedTest/kotlin/androidx/room/integration/multiplatformtestapp/test/SimpleQueryTest.kt
+++ b/room/integration-tests/multiplatformtestapp/src/androidInstrumentedTest/kotlin/androidx/room/integration/multiplatformtestapp/test/QueryTest.kt
@@ -21,7 +21,7 @@
import androidx.test.platform.app.InstrumentationRegistry
import kotlinx.coroutines.Dispatchers
-class SimpleQueryTest : BaseSimpleQueryTest() {
+class QueryTest : BaseQueryTest() {
private val instrumentation = InstrumentationRegistry.getInstrumentation()
diff --git a/room/integration-tests/multiplatformtestapp/src/androidInstrumentedTest/kotlin/androidx/room/integration/multiplatformtestapp/test/SimpleQueryTest.kt b/room/integration-tests/multiplatformtestapp/src/androidInstrumentedTest/kotlin/androidx/room/integration/multiplatformtestapp/test/TypeConverterTest.kt
similarity index 78%
copy from room/integration-tests/multiplatformtestapp/src/androidInstrumentedTest/kotlin/androidx/room/integration/multiplatformtestapp/test/SimpleQueryTest.kt
copy to room/integration-tests/multiplatformtestapp/src/androidInstrumentedTest/kotlin/androidx/room/integration/multiplatformtestapp/test/TypeConverterTest.kt
index 300ff8c..d89288c 100644
--- a/room/integration-tests/multiplatformtestapp/src/androidInstrumentedTest/kotlin/androidx/room/integration/multiplatformtestapp/test/SimpleQueryTest.kt
+++ b/room/integration-tests/multiplatformtestapp/src/androidInstrumentedTest/kotlin/androidx/room/integration/multiplatformtestapp/test/TypeConverterTest.kt
@@ -17,19 +17,17 @@
package androidx.room.integration.multiplatformtestapp.test
import androidx.room.Room
+import androidx.room.RoomDatabase
import androidx.sqlite.driver.bundled.BundledSQLiteDriver
import androidx.test.platform.app.InstrumentationRegistry
-import kotlinx.coroutines.Dispatchers
-class SimpleQueryTest : BaseSimpleQueryTest() {
+class TypeConverterTest : BaseTypeConverterTest() {
private val instrumentation = InstrumentationRegistry.getInstrumentation()
- override fun getRoomDatabase(): SampleDatabase {
- return Room.inMemoryDatabaseBuilder<SampleDatabase>(
+ override fun getDatabaseBuilder(): RoomDatabase.Builder<TestDatabase> {
+ return Room.inMemoryDatabaseBuilder<TestDatabase>(
context = instrumentation.targetContext
).setDriver(BundledSQLiteDriver())
- .setQueryCoroutineContext(Dispatchers.IO)
- .build()
}
}
diff --git a/room/integration-tests/multiplatformtestapp/src/commonTest/kotlin/androidx/room/integration/multiplatformtestapp/test/BaseBuilderTest.kt b/room/integration-tests/multiplatformtestapp/src/commonTest/kotlin/androidx/room/integration/multiplatformtestapp/test/BaseBuilderTest.kt
index 90e3311..08a70e9 100644
--- a/room/integration-tests/multiplatformtestapp/src/commonTest/kotlin/androidx/room/integration/multiplatformtestapp/test/BaseBuilderTest.kt
+++ b/room/integration-tests/multiplatformtestapp/src/commonTest/kotlin/androidx/room/integration/multiplatformtestapp/test/BaseBuilderTest.kt
@@ -19,6 +19,7 @@
import androidx.kruth.assertThat
import androidx.kruth.assertThrows
import androidx.room.RoomDatabase
+import androidx.room.useReaderConnection
import androidx.sqlite.SQLiteConnection
import kotlin.coroutines.EmptyCoroutineContext
import kotlin.test.Test
@@ -76,4 +77,19 @@
}.hasMessageThat()
.contains("It is required that the coroutine context contain a dispatcher.")
}
+
+ @Test
+ fun setJournalMode() = runTest {
+ val database = getRoomDatabaseBuilder()
+ .setJournalMode(RoomDatabase.JournalMode.TRUNCATE)
+ .build()
+ val journalMode = database.useReaderConnection { connection ->
+ connection.usePrepared("PRAGMA journal_mode") {
+ it.step()
+ it.getText(0)
+ }
+ }
+ assertThat(journalMode).isEqualTo("truncate")
+ database.close()
+ }
}
diff --git a/room/integration-tests/multiplatformtestapp/src/commonTest/kotlin/androidx/room/integration/multiplatformtestapp/test/BaseSimpleQueryTest.kt b/room/integration-tests/multiplatformtestapp/src/commonTest/kotlin/androidx/room/integration/multiplatformtestapp/test/BaseQueryTest.kt
similarity index 99%
rename from room/integration-tests/multiplatformtestapp/src/commonTest/kotlin/androidx/room/integration/multiplatformtestapp/test/BaseSimpleQueryTest.kt
rename to room/integration-tests/multiplatformtestapp/src/commonTest/kotlin/androidx/room/integration/multiplatformtestapp/test/BaseQueryTest.kt
index 836f9c4..43909bf 100644
--- a/room/integration-tests/multiplatformtestapp/src/commonTest/kotlin/androidx/room/integration/multiplatformtestapp/test/BaseSimpleQueryTest.kt
+++ b/room/integration-tests/multiplatformtestapp/src/commonTest/kotlin/androidx/room/integration/multiplatformtestapp/test/BaseQueryTest.kt
@@ -37,7 +37,7 @@
import kotlinx.coroutines.test.runTest
import kotlinx.coroutines.yield
-abstract class BaseSimpleQueryTest {
+abstract class BaseQueryTest {
private lateinit var db: SampleDatabase
diff --git a/room/integration-tests/multiplatformtestapp/src/commonTest/kotlin/androidx/room/integration/multiplatformtestapp/test/BaseTypeConverterTest.kt b/room/integration-tests/multiplatformtestapp/src/commonTest/kotlin/androidx/room/integration/multiplatformtestapp/test/BaseTypeConverterTest.kt
new file mode 100644
index 0000000..93b06c4
--- /dev/null
+++ b/room/integration-tests/multiplatformtestapp/src/commonTest/kotlin/androidx/room/integration/multiplatformtestapp/test/BaseTypeConverterTest.kt
@@ -0,0 +1,95 @@
+/*
+ * Copyright 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package androidx.room.integration.multiplatformtestapp.test
+
+import androidx.kruth.assertThat
+import androidx.kruth.assertThrows
+import androidx.room.Dao
+import androidx.room.Database
+import androidx.room.Entity
+import androidx.room.Insert
+import androidx.room.PrimaryKey
+import androidx.room.ProvidedTypeConverter
+import androidx.room.Query
+import androidx.room.RoomDatabase
+import androidx.room.TypeConverter
+import androidx.room.TypeConverters
+import kotlin.test.Test
+import kotlinx.coroutines.test.runTest
+
+abstract class BaseTypeConverterTest {
+ abstract fun getDatabaseBuilder(): RoomDatabase.Builder<TestDatabase>
+
+ @Test
+ fun entityWithConverter() = runTest {
+ val database = getDatabaseBuilder()
+ .addTypeConverter(BarConverter())
+ .build()
+ val entity = TestEntity(1, Foo(1979), Bar("Mujer Boricua"))
+ database.getDao().insertItem(entity)
+ assertThat(database.getDao().getItem(1)).isEqualTo(entity)
+ database.close()
+ }
+
+ @Test
+ fun missingTypeConverter() {
+ assertThrows<IllegalArgumentException> {
+ getDatabaseBuilder().build()
+ }.hasMessageThat().isEqualTo("A required type converter (" +
+ "${BarConverter::class.qualifiedName}) for ${TestDao::class.qualifiedName} is " +
+ "missing in the database configuration.")
+ }
+
+ @Database(entities = [TestEntity::class], version = 1, exportSchema = false)
+ @TypeConverters(FooConverter::class, BarConverter::class)
+ abstract class TestDatabase : RoomDatabase() {
+ abstract fun getDao(): TestDao
+ }
+
+ @Dao
+ interface TestDao {
+ @Insert
+ suspend fun insertItem(item: TestEntity)
+
+ @Query("SELECT * FROM TestEntity WHERE id = :id")
+ suspend fun getItem(id: Long): TestEntity
+ }
+
+ @Entity
+ data class TestEntity(@PrimaryKey val id: Long, val foo: Foo, val bar: Bar)
+
+ data class Foo(val number: Int)
+
+ data class Bar(val text: String)
+
+ object FooConverter {
+ @TypeConverter
+ fun toFoo(number: Int): Foo = Foo(number)
+
+ @TypeConverter
+ fun fromFoo(foo: Foo): Int = foo.number
+ }
+
+ @ProvidedTypeConverter
+ class BarConverter {
+ @TypeConverter
+ fun toBar(text: String): Bar = Bar(text)
+
+ @TypeConverter
+ fun fromBar(bar: Bar): String = bar.text
+ }
+}
diff --git a/room/integration-tests/multiplatformtestapp/src/jvmTest/kotlin/androidx/room/integration/multiplatformtestapp/test/SimpleQueryTest.kt b/room/integration-tests/multiplatformtestapp/src/jvmTest/kotlin/androidx/room/integration/multiplatformtestapp/test/QueryTest.kt
similarity index 95%
rename from room/integration-tests/multiplatformtestapp/src/jvmTest/kotlin/androidx/room/integration/multiplatformtestapp/test/SimpleQueryTest.kt
rename to room/integration-tests/multiplatformtestapp/src/jvmTest/kotlin/androidx/room/integration/multiplatformtestapp/test/QueryTest.kt
index 6be6358f..fa91c34 100644
--- a/room/integration-tests/multiplatformtestapp/src/jvmTest/kotlin/androidx/room/integration/multiplatformtestapp/test/SimpleQueryTest.kt
+++ b/room/integration-tests/multiplatformtestapp/src/jvmTest/kotlin/androidx/room/integration/multiplatformtestapp/test/QueryTest.kt
@@ -20,7 +20,7 @@
import androidx.sqlite.driver.bundled.BundledSQLiteDriver
import kotlinx.coroutines.Dispatchers
-class SimpleQueryTest : BaseSimpleQueryTest() {
+class QueryTest : BaseQueryTest() {
override fun getRoomDatabase(): SampleDatabase {
return Room.inMemoryDatabaseBuilder<SampleDatabase>()
diff --git a/room/integration-tests/multiplatformtestapp/src/jvmTest/kotlin/androidx/room/integration/multiplatformtestapp/test/SimpleQueryTest.kt b/room/integration-tests/multiplatformtestapp/src/jvmTest/kotlin/androidx/room/integration/multiplatformtestapp/test/TypeConverterTest.kt
similarity index 74%
copy from room/integration-tests/multiplatformtestapp/src/jvmTest/kotlin/androidx/room/integration/multiplatformtestapp/test/SimpleQueryTest.kt
copy to room/integration-tests/multiplatformtestapp/src/jvmTest/kotlin/androidx/room/integration/multiplatformtestapp/test/TypeConverterTest.kt
index 6be6358f..35bdee5 100644
--- a/room/integration-tests/multiplatformtestapp/src/jvmTest/kotlin/androidx/room/integration/multiplatformtestapp/test/SimpleQueryTest.kt
+++ b/room/integration-tests/multiplatformtestapp/src/jvmTest/kotlin/androidx/room/integration/multiplatformtestapp/test/TypeConverterTest.kt
@@ -17,15 +17,13 @@
package androidx.room.integration.multiplatformtestapp.test
import androidx.room.Room
+import androidx.room.RoomDatabase
import androidx.sqlite.driver.bundled.BundledSQLiteDriver
-import kotlinx.coroutines.Dispatchers
-class SimpleQueryTest : BaseSimpleQueryTest() {
+class TypeConverterTest : BaseTypeConverterTest() {
- override fun getRoomDatabase(): SampleDatabase {
- return Room.inMemoryDatabaseBuilder<SampleDatabase>()
+ override fun getDatabaseBuilder(): RoomDatabase.Builder<TestDatabase> {
+ return Room.inMemoryDatabaseBuilder<TestDatabase>()
.setDriver(BundledSQLiteDriver())
- .setQueryCoroutineContext(Dispatchers.IO)
- .build()
}
}
diff --git a/room/integration-tests/multiplatformtestapp/src/nativeTest/kotlin/androidx/room/integration/multiplatformtestapp/test/SimpleQueryTest.kt b/room/integration-tests/multiplatformtestapp/src/nativeTest/kotlin/androidx/room/integration/multiplatformtestapp/test/QueryTest.kt
similarity index 86%
rename from room/integration-tests/multiplatformtestapp/src/nativeTest/kotlin/androidx/room/integration/multiplatformtestapp/test/SimpleQueryTest.kt
rename to room/integration-tests/multiplatformtestapp/src/nativeTest/kotlin/androidx/room/integration/multiplatformtestapp/test/QueryTest.kt
index 5a0d3c9..9ad0d65 100644
--- a/room/integration-tests/multiplatformtestapp/src/nativeTest/kotlin/androidx/room/integration/multiplatformtestapp/test/SimpleQueryTest.kt
+++ b/room/integration-tests/multiplatformtestapp/src/nativeTest/kotlin/androidx/room/integration/multiplatformtestapp/test/QueryTest.kt
@@ -21,10 +21,12 @@
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.IO
-class SimpleQueryTest : BaseSimpleQueryTest() {
+class QueryTest : BaseQueryTest() {
override fun getRoomDatabase(): SampleDatabase {
- return Room.inMemoryDatabaseBuilder { SampleDatabase::class.instantiateImpl() }
+ return Room.inMemoryDatabaseBuilder<SampleDatabase> {
+ SampleDatabase::class.instantiateImpl()
+ }
.setDriver(BundledSQLiteDriver())
.setQueryCoroutineContext(Dispatchers.IO)
.build()
diff --git a/room/integration-tests/multiplatformtestapp/src/jvmTest/kotlin/androidx/room/integration/multiplatformtestapp/test/SimpleQueryTest.kt b/room/integration-tests/multiplatformtestapp/src/nativeTest/kotlin/androidx/room/integration/multiplatformtestapp/test/TypeConverterTest.kt
similarity index 74%
copy from room/integration-tests/multiplatformtestapp/src/jvmTest/kotlin/androidx/room/integration/multiplatformtestapp/test/SimpleQueryTest.kt
copy to room/integration-tests/multiplatformtestapp/src/nativeTest/kotlin/androidx/room/integration/multiplatformtestapp/test/TypeConverterTest.kt
index 6be6358f..de89cdd 100644
--- a/room/integration-tests/multiplatformtestapp/src/jvmTest/kotlin/androidx/room/integration/multiplatformtestapp/test/SimpleQueryTest.kt
+++ b/room/integration-tests/multiplatformtestapp/src/nativeTest/kotlin/androidx/room/integration/multiplatformtestapp/test/TypeConverterTest.kt
@@ -17,15 +17,13 @@
package androidx.room.integration.multiplatformtestapp.test
import androidx.room.Room
+import androidx.room.RoomDatabase
import androidx.sqlite.driver.bundled.BundledSQLiteDriver
-import kotlinx.coroutines.Dispatchers
-class SimpleQueryTest : BaseSimpleQueryTest() {
+class TypeConverterTest : BaseTypeConverterTest() {
- override fun getRoomDatabase(): SampleDatabase {
- return Room.inMemoryDatabaseBuilder<SampleDatabase>()
+ override fun getDatabaseBuilder(): RoomDatabase.Builder<TestDatabase> {
+ return Room.inMemoryDatabaseBuilder<TestDatabase> { TestDatabase::class.instantiateImpl() }
.setDriver(BundledSQLiteDriver())
- .setQueryCoroutineContext(Dispatchers.IO)
- .build()
}
}
diff --git a/room/room-runtime/src/androidMain/kotlin/androidx/room/RoomDatabase.android.kt b/room/room-runtime/src/androidMain/kotlin/androidx/room/RoomDatabase.android.kt
index c90ae89c..7421bac 100644
--- a/room/room-runtime/src/androidMain/kotlin/androidx/room/RoomDatabase.android.kt
+++ b/room/room-runtime/src/androidMain/kotlin/androidx/room/RoomDatabase.android.kt
@@ -1208,18 +1208,16 @@
/**
* Sets the journal mode for this database.
*
- * This value is ignored if the builder is initialized with
- * [Room.inMemoryDatabaseBuilder].
- *
- * The journal mode should be consistent across multiple instances of
- * [RoomDatabase] for a single SQLite database file.
+ * The value is ignored if the builder is for an 'in-memory database'. The journal mode
+ * should be consistent across multiple instances of [RoomDatabase] for a single SQLite
+ * database file.
*
* The default value is [JournalMode.AUTOMATIC].
*
* @param journalMode The journal mode.
* @return This builder instance.
*/
- open fun setJournalMode(journalMode: JournalMode) = apply {
+ actual open fun setJournalMode(journalMode: JournalMode) = apply {
this.journalMode = journalMode
}
@@ -1536,13 +1534,13 @@
}
/**
- * Adds a type converter instance to this database.
+ * Adds a type converter instance to the builder.
*
- * @param typeConverter The converter. It must be an instance of a class annotated with
- * [ProvidedTypeConverter] otherwise Room will throw an exception.
+ * @param typeConverter The converter instance that is annotated with
+ * [ProvidedTypeConverter].
* @return This builder instance.
*/
- open fun addTypeConverter(typeConverter: Any) = apply {
+ actual open fun addTypeConverter(typeConverter: Any) = apply {
this.typeConverters.add(typeConverter)
}
diff --git a/room/room-runtime/src/commonMain/kotlin/androidx/room/RoomDatabase.kt b/room/room-runtime/src/commonMain/kotlin/androidx/room/RoomDatabase.kt
index 4b07c62..8e59497 100644
--- a/room/room-runtime/src/commonMain/kotlin/androidx/room/RoomDatabase.kt
+++ b/room/room-runtime/src/commonMain/kotlin/androidx/room/RoomDatabase.kt
@@ -314,6 +314,29 @@
): Builder<T>
/**
+ * Adds a type converter instance to the builder.
+ *
+ * @param typeConverter The converter instance that is annotated with
+ * [ProvidedTypeConverter].
+ * @return This builder instance.
+ */
+ fun addTypeConverter(typeConverter: Any): Builder<T>
+
+ /**
+ * Sets the journal mode for this database.
+ *
+ * The value is ignored if the builder is for an 'in-memory database'. The journal mode
+ * should be consistent across multiple instances of [RoomDatabase] for a single SQLite
+ * database file.
+ *
+ * The default value is [JournalMode.WRITE_AHEAD_LOGGING].
+ *
+ * @param journalMode The journal mode.
+ * @return This builder instance.
+ */
+ fun setJournalMode(journalMode: JournalMode): Builder<T>
+
+ /**
* Sets the [CoroutineContext] that will be used to execute all asynchronous queries and
* tasks, such as `Flow` emissions and [InvalidationTracker] notifications.
*
@@ -571,7 +594,7 @@
}
}
require(foundIndex >= 0) {
- "A required type converter ($converter) for" +
+ "A required type converter (${converter.qualifiedName}) for" +
" ${daoName.qualifiedName} is missing in the database configuration."
}
addTypeConverter(converter, configuration.typeConverters[foundIndex])
diff --git a/room/room-runtime/src/jvmNativeMain/kotlin/androidx/room/RoomDatabase.jvmNative.kt b/room/room-runtime/src/jvmNativeMain/kotlin/androidx/room/RoomDatabase.jvmNative.kt
index adabee5..89b1adf 100644
--- a/room/room-runtime/src/jvmNativeMain/kotlin/androidx/room/RoomDatabase.jvmNative.kt
+++ b/room/room-runtime/src/jvmNativeMain/kotlin/androidx/room/RoomDatabase.jvmNative.kt
@@ -289,6 +289,8 @@
private var driver: SQLiteDriver? = null
private val callbacks = mutableListOf<Callback>()
+ private val typeConverters: MutableList<Any> = mutableListOf()
+ private var journalMode: JournalMode = JournalMode.WRITE_AHEAD_LOGGING
private var queryCoroutineContext: CoroutineContext? = null
/**
@@ -437,6 +439,33 @@
}
/**
+ * Adds a type converter instance to the builder.
+ *
+ * @param typeConverter The converter instance that is annotated with
+ * [ProvidedTypeConverter].
+ * @return This builder instance.
+ */
+ actual fun addTypeConverter(typeConverter: Any) = apply {
+ this.typeConverters.add(typeConverter)
+ }
+
+ /**
+ * Sets the journal mode for this database.
+ *
+ * The value is ignored if the builder is for an 'in-memory database'. The journal mode
+ * should be consistent across multiple instances of [RoomDatabase] for a single SQLite
+ * database file.
+ *
+ * The default value is [JournalMode.WRITE_AHEAD_LOGGING].
+ *
+ * @param journalMode The journal mode.
+ * @return This builder instance.
+ */
+ actual fun setJournalMode(journalMode: JournalMode) = apply {
+ this.journalMode = journalMode
+ }
+
+ /**
* Sets the [CoroutineContext] that will be used to execute all asynchronous queries and
* tasks, such as `Flow` emissions and [InvalidationTracker] notifications.
*
@@ -483,11 +512,11 @@
name = name,
migrationContainer = migrationContainer,
callbacks = callbacks,
- journalMode = JournalMode.WRITE_AHEAD_LOGGING,
+ journalMode = journalMode,
requireMigration = requireMigration,
allowDestructiveMigrationOnDowngrade = allowDestructiveMigrationOnDowngrade,
migrationNotRequiredFrom = migrationsNotRequiredFrom,
- typeConverters = emptyList(),
+ typeConverters = typeConverters,
autoMigrationSpecs = autoMigrationSpecs,
allowDestructiveMigrationForAllTables = allowDestructiveMigrationForAllTables,
sqliteDriver = driver,