From 8de38066ff9a2d3a5e4e799d91ca744c659acb39 Mon Sep 17 00:00:00 2001 From: Roman Leukin Date: Wed, 31 Dec 2025 16:25:15 +0300 Subject: [PATCH] Convert Room DAO methods to suspend functions (#4102) Signed-off-by: James Rich <2199651+jamesarich@users.noreply.github.com> Co-authored-by: James Rich <2199651+jamesarich@users.noreply.github.com> --- core/database/build.gradle.kts | 1 + .../core/database/DatabaseManager.kt | 2 +- .../core/database/dao/MeshLogDao.kt | 8 ++-- .../core/database/dao/NodeInfoDao.kt | 44 +++++++++---------- .../core/database/dao/QuickChatActionDao.kt | 12 ++--- 5 files changed, 34 insertions(+), 33 deletions(-) diff --git a/core/database/build.gradle.kts b/core/database/build.gradle.kts index 6de311544..3bf3c04aa 100644 --- a/core/database/build.gradle.kts +++ b/core/database/build.gradle.kts @@ -61,4 +61,5 @@ dependencies { androidTestImplementation(libs.androidx.test.runner) androidTestImplementation(libs.androidx.test.ext.junit) + androidTestImplementation(libs.androidx.room.testing) } diff --git a/core/database/src/main/kotlin/org/meshtastic/core/database/DatabaseManager.kt b/core/database/src/main/kotlin/org/meshtastic/core/database/DatabaseManager.kt index 7f6250887..86884b421 100644 --- a/core/database/src/main/kotlin/org/meshtastic/core/database/DatabaseManager.kt +++ b/core/database/src/main/kotlin/org/meshtastic/core/database/DatabaseManager.kt @@ -110,7 +110,7 @@ class DatabaseManager @Inject constructor(private val app: Application) { } /** Execute [block] with the current DB instance. */ - fun withDb(block: (MeshtasticDatabase) -> T): T = block(currentDb.value) + inline fun withDb(block: (MeshtasticDatabase) -> T): T = block(currentDb.value) private fun markLastUsed(dbName: String) { prefs.edit().putLong(lastUsedKey(dbName), System.currentTimeMillis()).apply() diff --git a/core/database/src/main/kotlin/org/meshtastic/core/database/dao/MeshLogDao.kt b/core/database/src/main/kotlin/org/meshtastic/core/database/dao/MeshLogDao.kt index f0f471c05..83d7bb701 100644 --- a/core/database/src/main/kotlin/org/meshtastic/core/database/dao/MeshLogDao.kt +++ b/core/database/src/main/kotlin/org/meshtastic/core/database/dao/MeshLogDao.kt @@ -46,14 +46,14 @@ interface MeshLogDao { ) fun getLogsFrom(fromNum: Int, portNum: Int, maxItem: Int): Flow> - @Insert fun insert(log: MeshLog) + @Insert suspend fun insert(log: MeshLog) @Query("DELETE FROM log") - fun deleteAll() + suspend fun deleteAll() @Query("DELETE FROM log WHERE uuid = :uuid") - fun deleteLog(uuid: String) + suspend fun deleteLog(uuid: String) @Query("DELETE FROM log WHERE from_num = :fromNum AND port_num = :portNum") - fun deleteLogs(fromNum: Int, portNum: Int) + suspend fun deleteLogs(fromNum: Int, portNum: Int) } diff --git a/core/database/src/main/kotlin/org/meshtastic/core/database/dao/NodeInfoDao.kt b/core/database/src/main/kotlin/org/meshtastic/core/database/dao/NodeInfoDao.kt index bce9cedbe..d2ef0335e 100644 --- a/core/database/src/main/kotlin/org/meshtastic/core/database/dao/NodeInfoDao.kt +++ b/core/database/src/main/kotlin/org/meshtastic/core/database/dao/NodeInfoDao.kt @@ -45,7 +45,7 @@ interface NodeInfoDao { * @return A [NodeEntity] that is safe to upsert, or null if the upsert should be aborted (e.g., due to an * impersonation attempt, though this logic is currently commented out). */ - private fun getVerifiedNodeForUpsert(incomingNode: NodeEntity): NodeEntity { + private suspend fun getVerifiedNodeForUpsert(incomingNode: NodeEntity): NodeEntity { // Populate the NodeEntity.publicKey field from the User.publicKey for consistency // and to support lazy migration. incomingNode.publicKey = incomingNode.user.publicKey @@ -70,7 +70,7 @@ interface NodeInfoDao { } /** Validates a new node before it is inserted into the database. */ - private fun handleNewNodeUpsertValidation(newNode: NodeEntity): NodeEntity { + private suspend fun handleNewNodeUpsertValidation(newNode: NodeEntity): NodeEntity { // Check if the new node's public key (if present and not empty) // is already claimed by another existing node. if (newNode.publicKey?.isEmpty == false) { @@ -118,10 +118,10 @@ interface NodeInfoDao { fun getMyNodeInfo(): Flow @Insert(onConflict = OnConflictStrategy.REPLACE) - fun setMyNodeInfo(myInfo: MyNodeEntity) + suspend fun setMyNodeInfo(myInfo: MyNodeEntity) @Query("DELETE FROM my_node") - fun clearMyNodeInfo() + suspend fun clearMyNodeInfo() @Query( """ @@ -198,7 +198,7 @@ interface NodeInfoDao { ): Flow> @Transaction - fun clearNodeInfo(preserveFavorites: Boolean) { + suspend fun clearNodeInfo(preserveFavorites: Boolean) { if (preserveFavorites) { deleteNonFavoriteNodes() } else { @@ -207,50 +207,50 @@ interface NodeInfoDao { } @Query("DELETE FROM nodes WHERE is_favorite = 0") - fun deleteNonFavoriteNodes() + suspend fun deleteNonFavoriteNodes() @Query("DELETE FROM nodes") - fun deleteAllNodes() + suspend fun deleteAllNodes() @Query("DELETE FROM nodes WHERE num=:num") - fun deleteNode(num: Int) + suspend fun deleteNode(num: Int) @Query("DELETE FROM nodes WHERE num IN (:nodeNums)") - fun deleteNodes(nodeNums: List) + suspend fun deleteNodes(nodeNums: List) @Query("SELECT * FROM nodes WHERE last_heard < :lastHeard") - fun getNodesOlderThan(lastHeard: Int): List + suspend fun getNodesOlderThan(lastHeard: Int): List @Query("SELECT * FROM nodes WHERE short_name IS NULL") - fun getUnknownNodes(): List + suspend fun getUnknownNodes(): List - @Upsert fun upsert(meta: MetadataEntity) + @Upsert suspend fun upsert(meta: MetadataEntity) @Query("DELETE FROM metadata WHERE num=:num") - fun deleteMetadata(num: Int) + suspend fun deleteMetadata(num: Int) @Query("SELECT * FROM nodes WHERE num=:num") @Transaction - fun getNodeByNum(num: Int): NodeWithRelations? + suspend fun getNodeByNum(num: Int): NodeWithRelations? @Query("SELECT * FROM nodes WHERE public_key = :publicKey LIMIT 1") - fun findNodeByPublicKey(publicKey: ByteString?): NodeEntity? + suspend fun findNodeByPublicKey(publicKey: ByteString?): NodeEntity? - @Upsert fun doUpsert(node: NodeEntity) + @Upsert suspend fun doUpsert(node: NodeEntity) - fun upsert(node: NodeEntity) { + suspend fun upsert(node: NodeEntity) { val verifiedNode = getVerifiedNodeForUpsert(node) doUpsert(verifiedNode) } @Insert(onConflict = OnConflictStrategy.REPLACE) - fun putAll(nodes: List) + suspend fun putAll(nodes: List) @Query("UPDATE nodes SET notes = :notes WHERE num = :num") - fun setNodeNotes(num: Int, notes: String) + suspend fun setNodeNotes(num: Int, notes: String) @Transaction - fun installConfig(mi: MyNodeEntity, nodes: List) { + suspend fun installConfig(mi: MyNodeEntity, nodes: List) { clearMyNodeInfo() setMyNodeInfo(mi) putAll(nodes.map { getVerifiedNodeForUpsert(it) }) @@ -261,7 +261,7 @@ interface NodeInfoDao { * ensures search functionality works for all nodes. Skips placeholder/default users (hwModel == UNSET). */ @Transaction - fun backfillDenormalizedNames() { + suspend fun backfillDenormalizedNames() { val nodes = getAllNodesSnapshot() val nodesToUpdate = nodes @@ -277,5 +277,5 @@ interface NodeInfoDao { } @Query("SELECT * FROM nodes") - fun getAllNodesSnapshot(): List + suspend fun getAllNodesSnapshot(): List } diff --git a/core/database/src/main/kotlin/org/meshtastic/core/database/dao/QuickChatActionDao.kt b/core/database/src/main/kotlin/org/meshtastic/core/database/dao/QuickChatActionDao.kt index 52fcb2fcf..ea9f5b092 100644 --- a/core/database/src/main/kotlin/org/meshtastic/core/database/dao/QuickChatActionDao.kt +++ b/core/database/src/main/kotlin/org/meshtastic/core/database/dao/QuickChatActionDao.kt @@ -30,23 +30,23 @@ interface QuickChatActionDao { @Query("Select * from quick_chat order by position asc") fun getAll(): Flow> - @Upsert fun upsert(action: QuickChatAction) + @Upsert suspend fun upsert(action: QuickChatAction) @Query("Delete from quick_chat") - fun deleteAll() + suspend fun deleteAll() @Query("Delete from quick_chat where uuid=:uuid") - fun delete(uuid: Long) + suspend fun delete(uuid: Long) @Transaction - fun delete(action: QuickChatAction) { + suspend fun delete(action: QuickChatAction) { delete(action.uuid) decrementPositionsAfter(action.position) } @Query("Update quick_chat set position=:position WHERE uuid=:uuid") - fun updateActionPosition(uuid: Long, position: Int) + suspend fun updateActionPosition(uuid: Long, position: Int) @Query("Update quick_chat set position=position-1 where position>=:position") - fun decrementPositionsAfter(position: Int) + suspend fun decrementPositionsAfter(position: Int) }