ScopedLeaksDb.kt
TLDR
This file contains the ScopedLeaksDb
object, which provides methods for accessing a SQLite database. It manages the opening and closing of the database, and provides access to both readable and writable instances of the database.
Methods
readableDatabase
This method takes a Context
parameter and a lambda function that accepts a SQLiteDatabase
parameter. It opens the database in readable mode using the provided context, and passes it to the lambda function. The result of the lambda function is then returned.
writableDatabase
This method is similar to readableDatabase
, but opens the database in writable mode.
open
This method takes a Context
parameter and returns a DbOpener
instance. It initializes the LeaksDbHelper
if necessary and increments the open count.
DbOpener.close
This method is called to close the database. It checks if the database is already closed, and if not, it decrements the open count. If the open count reaches 0, it closes the database.
Classes
No classes in this file.
package leakcanary.internal.activity.db
import android.content.Context
import android.database.sqlite.SQLiteDatabase
import java.io.Closeable
internal object ScopedLeaksDb {
@Volatile
private lateinit var leaksDbHelper: LeaksDbHelper
private val lock = Any()
@Volatile
private var openCount: Int = 0
fun <T> readableDatabase(context: Context, block: (SQLiteDatabase) -> T): T {
return open(context).use {
block(it.readableDatabase)
}
}
fun <T> writableDatabase(context: Context, block: (SQLiteDatabase) -> T): T {
return open(context).use {
block(it.writableDatabase)
}
}
fun open(context: Context): DbOpener {
synchronized(lock) {
if (!::leaksDbHelper.isInitialized) {
leaksDbHelper = LeaksDbHelper(context.applicationContext)
}
openCount++
return DbOpener()
}
}
class DbOpener : Closeable {
private var closed = false
val readableDatabase: SQLiteDatabase
get() {
checkClosed()
return leaksDbHelper.readableDatabase
}
val writableDatabase: SQLiteDatabase
get() {
checkClosed()
return leaksDbHelper.writableDatabase
}
override fun close() {
synchronized(lock) {
checkClosed()
closed = true
openCount--
if (openCount == 0) {
// No one else needs this right now, let's close the database (will reopen on
// next use)
leaksDbHelper.close()
}
}
}
private fun checkClosed() {
check(!closed) {
"Already closed"
}
}
}
}