DatabaseManager

Manages per-device Room database instances for node data, with LRU eviction.

Constructors

Link copied to clipboard
constructor(datastore: DatabaseDataStore, dispatchers: CoroutineDispatchers)

Properties

Link copied to clipboard
open override val cacheLimit: StateFlow<Int>
Link copied to clipboard
val currentAddress: StateFlow<String?>
Link copied to clipboard
open override val currentDb: StateFlow<MeshtasticDatabase>

Reactive stream of the currently active database instance.

Functions

Link copied to clipboard
open suspend override fun associateDevice(address: String, nodeNum: Int, deviceId: String?, isSessionActive: () -> Boolean)
Link copied to clipboard
open suspend override fun cachedDeviceDbCount(): Int
Link copied to clipboard
suspend fun close()

Establishes an orderly shutdown boundary: rejects new work, bounds manager-job cancellation, admitted manager-operation draining, and admitted-writer draining, waits for the last serialized switch/association to finalize, then closes every manager-owned Room instance. If a cancelled child, admitted operation, writer, or pool close cannot finish successfully, ownership is retained and physical cleanup is skipped so a later close call can retry without losing track of live resources. Retried attempts may call Room's idempotent close() again for pools that completed during an earlier partial attempt.

Link copied to clipboard
open override fun getCurrentCacheLimit(): Int
Link copied to clipboard
open override fun hasDatabaseFor(address: String?): Boolean

Returns true if a database exists for the given device address. Android Room stores DB files without an extension; JVM/iOS append .db. We check both to stay platform-agnostic.

Link copied to clipboard
suspend fun init(address: String?)

Initialize the active database for address.

Link copied to clipboard
open override fun <T> observeCurrentDb(query: (MeshtasticDatabase) -> Flow<T>): Flow<T>

Re-latches long-lived DAO flows on database switches and recovers the active Room pool after a reader/writer acquisition timeout. A failed query is never replayed on the same pool; publishing the replacement causes flatMapLatest to start a fresh DAO flow. Concurrent failing collectors converge on the same replacement.

Link copied to clipboard
open override fun setCacheLimit(limit: Int)
Link copied to clipboard
open suspend override fun switchActiveDatabase(address: String?)

Switch active database to the one associated with address. Serialized via mutex.

Link copied to clipboard
open suspend override fun <T> withDb(block: suspend (MeshtasticDatabase) -> T): T?

Executes block once against the admitted current DB instance, bounding the caller's wait at withDbTimeoutMillis.

Link copied to clipboard
open suspend override fun <T> withReadDb(block: suspend (MeshtasticDatabase) -> T): T

Executes one bounded read without writer admission or the serialized write-containment lane. Active database publication is synchronous and the captured pool is registered against eviction until the callback completes. The read is also admitted into the shutdown drain, is never replayed automatically, and new reads are rejected once shutdown begins.