From 891406cc7fbf9b449f306222e16b041b9ba8a96c Mon Sep 17 00:00:00 2001 From: Andreas Date: Fri, 29 Apr 2022 14:04:59 +0200 Subject: [PATCH] Fix database corruption (#7042) When using SQLDelight and Storio at the same time --- app/build.gradle.kts | 1 + .../java/eu/kanade/tachiyomi/AppModule.kt | 20 ++++++++++++------- .../tachiyomi/data/database/DatabaseHelper.kt | 10 ++-------- .../tachiyomi/data/database/DbOpenCallback.kt | 15 +++++++++----- gradle/libs.versions.toml | 1 + 5 files changed, 27 insertions(+), 20 deletions(-) diff --git a/app/build.gradle.kts b/app/build.gradle.kts index 930ca07502..24ea960b0d 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -152,6 +152,7 @@ dependencies { implementation(androidx.paging.runtime) implementation(androidx.paging.compose) + implementation(libs.sqldelight.sqlite) implementation(libs.sqldelight.android.driver) implementation(libs.sqldelight.coroutines) implementation(libs.sqldelight.android.paging) diff --git a/app/src/main/java/eu/kanade/tachiyomi/AppModule.kt b/app/src/main/java/eu/kanade/tachiyomi/AppModule.kt index c9147b6c6c..a1291f94ce 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/AppModule.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/AppModule.kt @@ -2,6 +2,8 @@ package eu.kanade.tachiyomi import android.app.Application import androidx.core.content.ContextCompat +import androidx.sqlite.db.SupportSQLiteOpenHelper +import androidx.sqlite.db.framework.FrameworkSQLiteOpenHelperFactory import com.squareup.sqldelight.android.AndroidSqliteDriver import com.squareup.sqldelight.db.SqlDriver import data.History @@ -34,15 +36,19 @@ class AppModule(val app: Application) : InjektModule { override fun InjektRegistrar.registerInjectables() { addSingleton(app) - addSingletonFactory { DbOpenCallback() } + // This is used to allow incremental migration from Storio + addSingletonFactory { + FrameworkSQLiteOpenHelperFactory().create( + SupportSQLiteOpenHelper.Configuration.builder(app) + .callback(DbOpenCallback()) + .name(DbOpenCallback.DATABASE_NAME) + .noBackupDirectory(false) + .build() + ) + } addSingletonFactory { - AndroidSqliteDriver( - schema = Database.Schema, - context = app, - name = DbOpenCallback.DATABASE_NAME, - callback = get() - ) + AndroidSqliteDriver(openHelper = get()) } addSingletonFactory { diff --git a/app/src/main/java/eu/kanade/tachiyomi/data/database/DatabaseHelper.kt b/app/src/main/java/eu/kanade/tachiyomi/data/database/DatabaseHelper.kt index 36c1d3d49a..1fbf55ad6f 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/data/database/DatabaseHelper.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/data/database/DatabaseHelper.kt @@ -21,24 +21,18 @@ import eu.kanade.tachiyomi.data.database.queries.HistoryQueries import eu.kanade.tachiyomi.data.database.queries.MangaCategoryQueries import eu.kanade.tachiyomi.data.database.queries.MangaQueries import eu.kanade.tachiyomi.data.database.queries.TrackQueries -import io.requery.android.database.sqlite.RequerySQLiteOpenHelperFactory /** * This class provides operations to manage the database through its interfaces. */ open class DatabaseHelper( context: Context, - callback: DbOpenCallback + openHelper: SupportSQLiteOpenHelper, ) : MangaQueries, ChapterQueries, TrackQueries, CategoryQueries, MangaCategoryQueries, HistoryQueries { - private val configuration = SupportSQLiteOpenHelper.Configuration.builder(context) - .name(DbOpenCallback.DATABASE_NAME) - .callback(callback) - .build() - override val db = DefaultStorIOSQLite.builder() - .sqliteOpenHelper(RequerySQLiteOpenHelperFactory().create(configuration)) + .sqliteOpenHelper(openHelper) .addTypeMapping(Manga::class.java, MangaTypeMapping()) .addTypeMapping(Chapter::class.java, ChapterTypeMapping()) .addTypeMapping(Track::class.java, TrackTypeMapping()) diff --git a/app/src/main/java/eu/kanade/tachiyomi/data/database/DbOpenCallback.kt b/app/src/main/java/eu/kanade/tachiyomi/data/database/DbOpenCallback.kt index ef541ac426..a27e4cbad8 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/data/database/DbOpenCallback.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/data/database/DbOpenCallback.kt @@ -4,6 +4,7 @@ import androidx.sqlite.db.SupportSQLiteDatabase import androidx.sqlite.db.SupportSQLiteOpenHelper import com.squareup.sqldelight.android.AndroidSqliteDriver import eu.kanade.tachiyomi.Database +import logcat.logcat class DbOpenCallback : SupportSQLiteOpenHelper.Callback(Database.Schema.version) { @@ -15,15 +16,19 @@ class DbOpenCallback : SupportSQLiteOpenHelper.Callback(Database.Schema.version) } override fun onCreate(db: SupportSQLiteDatabase) { + logcat { "Creating new database" } Database.Schema.create(AndroidSqliteDriver(database = db, cacheSize = 1)) } override fun onUpgrade(db: SupportSQLiteDatabase, oldVersion: Int, newVersion: Int) { - Database.Schema.migrate( - driver = AndroidSqliteDriver(database = db, cacheSize = 1), - oldVersion = oldVersion, - newVersion = newVersion - ) + if (oldVersion < newVersion) { + logcat { "Upgrading database from $oldVersion to $newVersion" } + Database.Schema.migrate( + driver = AndroidSqliteDriver(database = db, cacheSize = 1), + oldVersion = oldVersion, + newVersion = newVersion + ) + } } override fun onConfigure(db: SupportSQLiteDatabase) { diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index d89d3480ef..bc14b87d9b 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -92,6 +92,7 @@ shizuku-provider = { module = "dev.rikka.shizuku:provider", version.ref = "shizu leakcanary-android = { module = "com.squareup.leakcanary:leakcanary-android", version.ref ="leakcanary" } leakcanary-plumber = { module = "com.squareup.leakcanary:plumber-android", version.ref ="leakcanary" } +sqldelight-sqlite = { module = "androidx.sqlite:sqlite-framework", version.ref ="sqldelight" } sqldelight-android-driver = { module = "com.squareup.sqldelight:android-driver", version.ref ="sqldelight" } sqldelight-coroutines = { module = "com.squareup.sqldelight:coroutines-extensions-jvm", version.ref ="sqldelight" } sqldelight-android-paging = { module = "com.squareup.sqldelight:android-paging3-extensions", version.ref ="sqldelight" }