Кажется, мое решение не работает, и я не знаю почему. Вот что я пытаюсь:
Logi c
Мое приложение имеет один экземпляр базы данных, и, если этот экземпляр создан, выполняется следующее:
- Получить текущий режим базы данных
- Если текущий режим базы данных == режим wal, я изменяю его на постоянный
- меняю режим на постоянный
- Проверьте, сохраняется ли новый режим
- создает один экземпляр базы данных и использует его до тех пор, пока существует процесс приложения
Код
// this object holds the ONLY instance of my database and initialises it lazily!
object DBManagerImpl : IDBManager {
val TAG = "DB-MANAGER"
internal val database: Database by lazy {
// 1) change db mode if necessary
DBJournalUtil.logInfos(null)
val mode = DBJournalUtil.getDBMode(null)
L.tag(DBJournalUtil.TAG_WAL_MODE).d { "DB journal_mode: $mode" }
if (mode.equals(DBJournalUtil.JOURNAL_MODE_WAL, true))
{
DBJournalUtil.disableWALMode()
val mode2 = DBJournalUtil.getDBMode(null)
L.tag(DBJournalUtil.TAG_WAL_MODE).d { "DB journal_mode - AFTER DISABLE: $mode2" }
}
// 2) create single database instance
L.tag(TAG).d { "database variable created!" }
val database = Database()
database
}
}
В общем, это основная часть кода:
// 1) disable the wal journal mode and change it to persist
DBJournalUtil.disableWALMode()
// 2) check the new journal mode => Problem: it's still WAL and not persist
val mode2 = DBJournalUtil.getDBMode(null)
Проблема
Похоже, мой код правильно меняет режим базы данных (на основе строки журнала 8), но затем в журнале Строка 10 снова сообщает о режиме Wal. Почему? Что я здесь упускаю или делаю не так?
Произведенный вывод журнала
1 [[DBJournalUtil: 14 b]]: LOG 2 - journal_mode: wal
2 [[DBManagerImpl $ database: 6 e]]: DB journal_mode: wal
3 [[DBJournalUtil: 23 a]]: изменить DB journal_mode с WAL на PERSIST - текущий journal_mode = wal
4 [[DBJournalUtil : 35 b]]: wal_checkpoint - ПЕРЕД wal (TRUNCATE): Busy = 0, LOG = 0, CHECKPOINTED = 0
5 [[DBJournalUtil: 6 c]]: контрольная точка (TRUNCATE): count = 1
6 [[DBJournalUtil: 35 b]]: wal_checkpoint - ПОСЛЕ wal (TRUNCATE): Busy = 0, LOG = 0, CHECKPOINTED = 0
7 [[DBJournalUtil: 48 a]]: setJournalMode: count = 1
8 [[DBJournalUtil: 32 a]]: новый journal_mode: persist // <= ЗДЕСЬ это сохраняется! </strong>
9 [[DBJournalUtil : 42 a]]: изменен режим DB journal_mode с WAL на PERSIST!
10 [[DBManagerImpl $ база данных: 12 e]]: DB journal_mode - ПОСЛЕ ОТКЛЮЧЕНИЯ: wal // <= ПОЧЕМУ это все еще режим валь и не сохраняется ?????? </strong>* 106 2 * 11 [[DBManagerImpl $ database: 15 e]]: переменная базы данных создана!
Код - DBJournalUtil
object DBJournalUtil {
val TAG_WAL_MODE = "DB-WAL-MODE"
val JOURNAL_MODE_WAL = "WAL"
val JOURNAL_MODE_PERSIST = "PERSIST"
val JOURNAL_MODE_DELETE = "DELETE"
val JOURNAL_MODE_TRUNCATE = "TRUNCATE"
fun logInfos(db: SQLiteDatabase?) {
var csr: Cursor? = null
var dbToUse: SQLiteDatabase? = null
val dbName = DBManagerProvider.get().dbFileName()
val dbFile = AppProvider.get().context.getDatabasePath(dbName)
val logFile = { file: File ->
val path = file.absolutePath
val exists = file.exists()
val size = file.length()
L.tag(TAG_WAL_MODE).d { "LOG 1 - file: $path | exists: $exists | size: $size" }
}
// 1) Dateien loggen
logFile(dbFile)
logFile(File(dbFile.getPath() + "-wal")) // WAL Mode file
logFile(File(dbFile.getPath() + "-shm")) // WAL Mode file
try {
dbToUse = db
?: SQLiteDatabase.openDatabase(dbFile.path, null, SQLiteDatabase.OPEN_READWRITE)
// 2) journal-mode loggen
csr = dbToUse!!.rawQuery("PRAGMA journal_mode", null)
if (csr.moveToFirst()) {
val mode = csr.getString(0)
L.tag(TAG_WAL_MODE).d { "LOG 2 - journal_mode: $mode" }
}
} catch (e: Exception) {
L.tag(TAG_WAL_MODE).e(e)
} finally {
csr?.close()
if (db == null)
dbToUse?.close()
}
}
fun getDBMode(db: SQLiteDatabase?): String? {
var mode: String? = null
var csr: Cursor? = null
var dbToUse: SQLiteDatabase? = null
val dbName = DBManagerProvider.get().dbFileName()
val dbFile = AppProvider.get().context.getDatabasePath(dbName)
try {
dbToUse = db
?: SQLiteDatabase.openDatabase(dbFile.path, null, SQLiteDatabase.OPEN_READWRITE)
csr = dbToUse!!.rawQuery("PRAGMA journal_mode", null)
if (csr.moveToFirst())
mode = csr.getString(0)
} catch (e: Exception) {
L.tag(TAG_WAL_MODE).e(e)
} finally {
csr?.close()
if (db == null)
dbToUse?.close()
}
return mode
}
fun disableWALMode() {
val modeFrom = JOURNAL_MODE_WAL
val modeTo = JOURNAL_MODE_PERSIST
val dbName = DBManagerProvider.get().dbFileName()
val dbFile = AppProvider.get().context.getDatabasePath(dbName)
var db: SQLiteDatabase? = null
try {
// 1) Datenbank öffnen
db = SQLiteDatabase.openDatabase(dbFile.path, null, SQLiteDatabase.OPEN_READWRITE)
// 2) Modus auslesen
val mode = getDBMode(db)
L.tag(TAG_WAL_MODE).d { "Change DB journal_mode from $modeFrom to $modeTo - current journal_mode = $mode" }
if (mode == null || mode.equals(modeTo, true)) {
L.tag(TAG_WAL_MODE).d { "Abbruch da aktueller journal_mode = $mode" }
} else {
// 3) wal_checkpoint ausführen
walCheckpoint(db, "BEFORE wal(TRUNCATE)")
// 4) wal_checkpoint(TRUNCATE) ausführen um pending operations in DB zu übertragen
walTruncate(db)
// 5) wal_checkpoint ausführen
walCheckpoint(db, "AFTER wal(TRUNCATE)")
// 6) journal_mode ändern
setJournalMode(db, modeTo)
// 7) nochmals aktuellen journal_mode holen
val newMode = getDBMode(db)
L.tag(TAG_WAL_MODE).d { "New journal_mode: $newMode" }
}
} catch (e: Exception) {
L.tag(TAG_WAL_MODE).e(e)
} finally {
db?.close()
}
L.tag(TAG_WAL_MODE).d { "Changed DB journal_mode from $modeFrom to $modeTo!" }
}
private fun walCheckpoint(db: SQLiteDatabase, logTag: String) {
var wal_busy = -99
var wal_log = -99
var wal_checkpointed = -99
var csr: Cursor? = null
try {
csr = db.rawQuery("PRAGMA wal_checkpoint", null)
if (csr.moveToFirst()) {
wal_busy = csr.getInt(0)
wal_log = csr.getInt(1)
wal_checkpointed = csr.getInt(2)
}
} catch (e: Exception) {
L.tag(TAG_WAL_MODE).e(e)
} finally {
csr?.close()
}
L.tag(TAG_WAL_MODE).d { "wal_checkpoint - $logTag: Busy = $wal_busy, LOG = $wal_log, CHECKPOINTED = $wal_checkpointed" }
}
private fun walTruncate(db: SQLiteDatabase) {
var csr: Cursor? = null
try {
// Checkpoint - Pending Operationen in DB überführen
csr = db.rawQuery("PRAGMA wal_checkpoint(TRUNCATE)", null)
val count = csr.count
L.tag(TAG_WAL_MODE).d { "Checkpoint (TRUNCATE): count = $count" }
} catch (e: Exception) {
L.tag(TAG_WAL_MODE).e(e)
} finally {
csr?.close()
}
}
private fun setJournalMode(db: SQLiteDatabase, mode: String) {
var csr: Cursor? = null
try {
// Checkpoint - Pending Operationen in DB überführen
csr = db.rawQuery("PRAGMA journal_mode=$mode", null)
val count = csr.count
L.tag(TAG_WAL_MODE).d { "setJournalMode: count = $count" }
} catch (e: Exception) {
L.tag(TAG_WAL_MODE).e(e)
} finally {
csr?.close()
}
}
}