Eduardo Ruesta
12/04/2024, 2:32 PMsuspend fun logout(): Flow<Any> {
return flow {
userDao.clearAll()
profileDao.clearAll()
qrCodeDao.clearAll()
teamDao.clearFavoriteCategory()
}
}
this is my Dao for QrCode:
@Query("DELETE FROM QRCode")
suspend fun clearAll()
when the user clicks on logout and then login again in the same session (without killing the app) and goes to the Qr code screen will see again the old Qr codeEduardo Ruesta
12/10/2024, 12:14 AMPablo
12/16/2024, 11:35 AMval uiState: StateFlow<BusStopsDBScreenUiState> = busDataRepository.getBusStops()
.map<List<BusStop>, BusStopsDBScreenUiState> { busStops ->
BusStopsDBScreenUiState.Success(busStops, Res.string.bus_stops_db_filled)
}
.catch { throwable ->
emit(BusStopsDBScreenUiState.Error(throwable))
}.stateIn(viewModelScope, SharingStarted.WhileSubscribed(5000), BusStopsDBScreenUiState.Loading)
getBusStops returns a flow
@Query("SELECT * FROM BusStops")
fun getBusStops(): Flow<List<BusStopEntity>>
Giorgi
12/19/2024, 7:31 PMe: KLIB resolver: Could not find "/Users/Giorgi_Shalvashvili/IdeaProjects/app/data/build/kotlinTransformedMetadataLibraries/commonMain/androidx.room-room-runtime-2.7.0-alpha12-commonMain-Tlq32w.klib" in [/Users/Giorgi_Shalvashvili/Library/Application Support/kotlin/daemon]
Pablo
12/23/2024, 11:42 PM@Entity(tableName = "BusStops")
data class BusStopEntity(
@PrimaryKey val id: Int = 0,
val name: String,
val lat: Double,
val lon: Double
)
@Entity(tableName = "Lines")
data class LineEntity(
@PrimaryKey val id: Int = 0,
val name: String
)
@Entity(primaryKeys = ["busStopId", "lineId"])
data class BusStopLineEntity(
val busStopId: Int,
val lineId: Int
)
hafiz
01/06/2025, 2:34 AM// The Room compiler generates the `actual` implementations.
@Suppress("NO_ACTUAL_FOR_EXPECT")
expect object AppDatabaseConstructor : RoomDatabaseConstructor<AppDatabase>
calidion
01/13/2025, 5:13 AM@Transaction
@Query("SELECT * FROM peer where id = :${peer.id}")
fun getMessage(peer: Peer): List<PeerMessages>
Pablo
01/13/2025, 10:07 PMFlowFan
01/17/2025, 8:42 AMCaused by: java.lang.RuntimeException: Cannot find implementation for com.develop.db.AppDatabase. AppDatabase_Impl does not exist. Is Room annotation processor correctly configured?
calidion
01/30/2025, 5:45 PMRoom 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: 38767ca95e25ff4f114395416eb5f824, found: b6766d3311ce100dfdedbb4695613e5b
creation code, useless even when i deleted the db file.
fun getDatabaseBuilder(): RoomDatabase.Builder<AppDatabase> {
val dbFile = File(System.getProperty("java.io.tmpdir"), "room.db")
dbFile.delete()
return Room.databaseBuilder<AppDatabase>(
name = dbFile.absolutePath,
)
}
fun getRoomDatabase(
builder: RoomDatabase.Builder<AppDatabase>
): AppDatabase {
return builder
// .addMigrations(MIGRATIONS)
// .fallbackToDestructiveMigrationOnDowngrade(true)
.setDriver(BundledSQLiteDriver())
.setQueryCoroutineContext(<http://Dispatchers.IO|Dispatchers.IO>)
.build()
}
hafiz
02/07/2025, 9:19 AMBradleycorn
02/13/2025, 1:58 PM-lsqlite3
to the "Other Linker Flags" build setting, but the problem persists.
That shouldn't be necessary, because I am using the BundledSqliteDriver ...
I have also tried using the NativeSqliteDriver, but I get the same results
Error message looks like:
Undefined symbols for architecture arm64:
"_sqlite3_mutex_held", referenced from:
_sqlite3_sqlite3_mutex_held_wrapper226 in RailBirdKit[81](libandroidx.sqlite:sqlite-framework-cinterop-sqlite3-cache.a.o)
"_sqlite3_mutex_notheld", referenced from:
_sqlite3_sqlite3_mutex_notheld_wrapper227 in RailBirdKit[81](libandroidx.sqlite:sqlite-framework-cinterop-sqlite3-cache.a.o)
"_sqlite3_unlock_notify", referenced from:
_sqlite3_sqlite3_unlock_notify_wrapper252 in RailBirdKit[81](libandroidx.sqlite:sqlite-framework-cinterop-sqlite3-cache.a.o)
"_sqlite3_win32_set_directory", referenced from:
_sqlite3_sqlite3_win32_set_directory_wrapper181 in RailBirdKit[81](libandroidx.sqlite:sqlite-framework-cinterop-sqlite3-cache.a.o)
"_sqlite3_win32_set_directory16", referenced from:
_sqlite3_sqlite3_win32_set_directory16_wrapper183 in RailBirdKit[81](libandroidx.sqlite:sqlite-framework-cinterop-sqlite3-cache.a.o)
"_sqlite3_win32_set_directory8", referenced from:
_sqlite3_sqlite3_win32_set_directory8_wrapper182 in RailBirdKit[81](libandroidx.sqlite:sqlite-framework-cinterop-sqlite3-cache.a.o)
ld: symbol(s) not found for architecture arm64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
Eduardo Ruesta
02/13/2025, 6:50 PMJohn O'Reilly
02/13/2025, 9:17 PMjava.lang.ClassNotFoundException: androidx.sqlite.SQLiteDriver
in Compose for Desktop client using. 2.7.0-beta01 https://kotlinlang.slack.com/archives/C3PQML5NU/p1739479027685279Tlaster
02/14/2025, 7:11 AMjava.lang.NullPointerException: null cannot be cast to non-null type androidx.room.compiler.processing.XAnnotation
when building iOS project after upgrading room to 2.7.0-beta01, but the Android project builds fine, full stack trace in thread.Bradleycorn
02/14/2025, 7:57 PMВасилий
02/19/2025, 1:51 PMcalidion
03/03/2025, 9:19 AMdata class ExamWithDates(
@Embedded val exam: Exam,
@Relation(
parentColumn = "id",
entityColumn = "id",
associateBy = Junction(
value = ExamDate::class,
parentColumn = "examId",
entityColumn = "dateId",
)
)
val dates: List<Date>
)
I need dates ordered by dateThomas Hormes
03/05/2025, 6:32 AM:database
module where most Entities, Daos, etc. live.
However i now have a different module, say :test
where I want to add another Entity that I can add to my @Database
Declaration in the :database
module.
Whenever I try, i get an error saying I need to add a migration. When I add a migration however, I get the following error (see 🧵 )Pablo
03/14/2025, 5:26 PMAhmed
03/16/2025, 3:16 PMPablo
03/16/2025, 4:01 PMNote: Automated Room migrations rely on the generated database schema for both the old and the new versions of the database. If exportSchema is set to false, or if you have not yet compiled the database with the new version number, then automated migrations fail.
Specifically the part on if you have not yet compiled the database with the new version number. What is refering to? maybe google is telling that we need to open the sqlite file with an external tool and edit the pragma user_version value? Is that mandatory to make room migrations work?Morgane Soula
03/18/2025, 4:02 PM[ksp] [MissingType]: Element 'com.msoula.hobbymatchmaker.core.database.dao.converters.Converters' references a type that is not present
My build.gradle (dao module - database is pretty similar)
import org.jetbrains.kotlin.gradle.dsl.JvmTarget
plugins {
`kotlin-multiplatform`
`android-library`
alias(libs.plugins.compose.compiler)
alias(libs.plugins.compose.multiplatform)
alias(libs.plugins.serialization)
alias(libs.plugins.room.multiplatform)
alias(libs.plugins.ksp)
}
kotlin {
applyDefaultHierarchyTemplate()
androidTarget {
compilerOptions {
jvmTarget.set(JvmTarget.JVM_21)
}
}
iosX64()
iosArm64()
iosSimulatorArm64()
sourceSets {
commonMain.dependencies {
implementation(compose.runtime)
implementation(libs.kotlinx.coroutines.kmp)
implementation(libs.kotlinx.serialization)
//
implementation(libs.room.common)
implementation(libs.room.runtime)
}
androidMain.dependencies {
// Room
implementation(libs.room.runtime.android)
}
}
}
room { schemaDirectory("$projectDir/schemas") }
android {
namespace = "com.msoula.hobbymatchmaker.core.database.dao"
compileSdk = AndroidConfig.COMPILE_SDK
compileOptions {
sourceCompatibility = JavaVersion.VERSION_21
targetCompatibility = JavaVersion.VERSION_21
}
defaultConfig {
minSdk = AndroidConfig.MIN_SDK
}
}
dependencies {
add("kspCommonMainMetadata", libs.room.compiler)
add("kspAndroid", libs.room.compiler)
add("kspIosX64", libs.room.compiler)
add("kspIosArm64", libs.room.compiler)
add("kspIosSimulatorArm64", libs.room.compiler)
}
And the converter class
class Converters {
val jsonParser = Json { encodeDefaults = true; ignoreUnknownKeys = true }
@TypeConverter
fun fromGenreStringList(genres: List<String>?): String? {
return genres?.joinToString(",")
}
@TypeConverter
fun toGenreStringList(data: String?): List<String>? {
return data?.split(",")?.map { it.trim() }
}
@TypeConverter
fun fromGenreList(genres: List<Genre>?): String? {
return genres?.let { jsonParser.encodeToString(it) }
}
@TypeConverter
fun toGenreList(genreString: String?): List<Genre> {
return genreString?.let { jsonParser.decodeFromString<List<Genre>>(it) } ?: emptyList()
}
@TypeConverter
fun fromActorList(actors: List<Actor>?): String? {
return actors?.let { jsonParser.encodeToString(it) }
}
@TypeConverter
fun toActorList(actorString: String?): List<Actor> {
return actorString?.let { jsonParser.decodeFromString<List<Actor>>(it) } ?: emptyList()
}
}
Manoj Kumar
03/19/2025, 9:41 AMinternal fun getDatabaseBuilder(app: Application): RoomDatabase.Builder<MyDatabase> {
val passphrase: ByteArray = SQLiteDatabase.getBytes("temp_passphrase".toCharArray())
val factory = SupportFactory(passphrase)
val dbFile = app.getDatabasePath(KMPConstants.DB_FILE_NAME)
return Room.databaseBuilder<MyDatabase>(
context = app,
name = dbFile.absolutePath,
)
.openHelperFactory(factory)
}
How do I do it for iOS?Istvan Lorincz
03/21/2025, 3:58 PMkotlin.code.style=official
kotlin.daemon.jvmargs=-Xmx6g
#Gradle
org.gradle.jvmargs=-Xmx6g -Dfile.encoding=UTF-8 -XX:+UseG1GC
#Android
android.nonTransitiveRClass=true
android.useAndroidX=true
# Enable Gradle Daemon
org.gradle.daemon=true
# Enable Configure on demand
org.gradle.configureondemand=true
# Enable parallel builds
org.gradle.parallel=true
# Enable Build Cache
#android.enableBuildCache=true
# Enable simple gradle caching
org.gradle.caching=true
# Increase memory allotted to JVM
ksp.incremental=true
#
## Enable Kotlin Incremental Compilation
kotlin.incremental=true
kotlin.incremental.multiplatform=true
#
## Enable Configuration Cache
#org.gradle.configuration-cache=true
Istvan Lorincz
03/22/2025, 11:31 PMPablichjenkov
04/02/2025, 4:24 PMGrigory Panko
04/11/2025, 11:34 AM@Upsert
and @Insert(onConflict = OnConflictStrategy.REPLACE)
. It seems to me that @Upsert
should be more efficient (it was introduced more recently and has semantics of INSERT ... ON CONFLICT DO UPDATE
within single query), while OnConflictStrategy.REPLACE
looks like it will try to insert row in first query, and if it fails, run another query with update. But looking at the generated dao implementation, I see that OnConflictStrategy.REPLACE
uses INSERT OR REPLACE INTO
, while @Upsert
has 2 separate INSERT
and UPDATE
queries. Does it mean that OnConflictStrategy.REPLACE
should be more efficient when updating rows?alexhelder
05/12/2025, 12:57 AMFoos
(from network) in Room. There can be some ‘local only’ state (like DownloadManager ID and favorite status) that also needs to be associated with each Foo
. Would you put those ‘local state’ columns in the same Room table storing the Paged Foos
, or do a 1:1 relationship with the paged Foo
table and another table, like LocalFooState
?Olivier Patry
05/12/2025, 5:51 PM@Query(
"""
SELECT * FROM task
WHERE parent_list_local_id = :taskListLocalId
AND parent_local_id = :parentTaskLocalId
AND position <= :position
AND is_completed = false
ORDER BY position ASC
"""
)
suspend fun getTasksUpToPosition(taskListLocalId: Long, parentTaskLocalId: Long?, position: String): List<TaskEntity>
If I force parent_local_id IS NULL
, it's ok
If I force parent_local_id = 0L
, it's ok
But can't have both at the same time using (equivalent of = NULL
)
I went for COALESCE(parent_local_id, -1) = COALESCE(:parentTaskLocalId, -1)
for concision (knowing my ID is always positive)
I also made it work with an OR
parent_local_id = :parentTaskLocalId OR (:parentTaskLocalId IS NULL AND parent_local_id IS NULL)
I was expecting the generator to deal with nullable parameter itself.
In the generated code, it deals with it, and use bindNull
but nothing more fancy.
Do I miss something? Is it a requirement of Room somehow? Why? Would it be desirable to have it working?
(FTR, I'm using Room on desktop with SQLite Bundled)