Fix database corruption (#7042)

When using SQLDelight and Storio at the same time
This commit is contained in:
Andreas 2022-04-29 14:04:59 +02:00 committed by GitHub
parent a5d767042c
commit 891406cc7f
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 27 additions and 20 deletions

View file

@ -152,6 +152,7 @@ dependencies {
implementation(androidx.paging.runtime) implementation(androidx.paging.runtime)
implementation(androidx.paging.compose) implementation(androidx.paging.compose)
implementation(libs.sqldelight.sqlite)
implementation(libs.sqldelight.android.driver) implementation(libs.sqldelight.android.driver)
implementation(libs.sqldelight.coroutines) implementation(libs.sqldelight.coroutines)
implementation(libs.sqldelight.android.paging) implementation(libs.sqldelight.android.paging)

View file

@ -2,6 +2,8 @@ package eu.kanade.tachiyomi
import android.app.Application import android.app.Application
import androidx.core.content.ContextCompat 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.android.AndroidSqliteDriver
import com.squareup.sqldelight.db.SqlDriver import com.squareup.sqldelight.db.SqlDriver
import data.History import data.History
@ -34,15 +36,19 @@ class AppModule(val app: Application) : InjektModule {
override fun InjektRegistrar.registerInjectables() { override fun InjektRegistrar.registerInjectables() {
addSingleton(app) addSingleton(app)
addSingletonFactory { DbOpenCallback() } // This is used to allow incremental migration from Storio
addSingletonFactory<SupportSQLiteOpenHelper> {
FrameworkSQLiteOpenHelperFactory().create(
SupportSQLiteOpenHelper.Configuration.builder(app)
.callback(DbOpenCallback())
.name(DbOpenCallback.DATABASE_NAME)
.noBackupDirectory(false)
.build()
)
}
addSingletonFactory<SqlDriver> { addSingletonFactory<SqlDriver> {
AndroidSqliteDriver( AndroidSqliteDriver(openHelper = get())
schema = Database.Schema,
context = app,
name = DbOpenCallback.DATABASE_NAME,
callback = get<DbOpenCallback>()
)
} }
addSingletonFactory { addSingletonFactory {

View file

@ -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.MangaCategoryQueries
import eu.kanade.tachiyomi.data.database.queries.MangaQueries import eu.kanade.tachiyomi.data.database.queries.MangaQueries
import eu.kanade.tachiyomi.data.database.queries.TrackQueries 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. * This class provides operations to manage the database through its interfaces.
*/ */
open class DatabaseHelper( open class DatabaseHelper(
context: Context, context: Context,
callback: DbOpenCallback openHelper: SupportSQLiteOpenHelper,
) : ) :
MangaQueries, ChapterQueries, TrackQueries, CategoryQueries, MangaCategoryQueries, HistoryQueries { 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() override val db = DefaultStorIOSQLite.builder()
.sqliteOpenHelper(RequerySQLiteOpenHelperFactory().create(configuration)) .sqliteOpenHelper(openHelper)
.addTypeMapping(Manga::class.java, MangaTypeMapping()) .addTypeMapping(Manga::class.java, MangaTypeMapping())
.addTypeMapping(Chapter::class.java, ChapterTypeMapping()) .addTypeMapping(Chapter::class.java, ChapterTypeMapping())
.addTypeMapping(Track::class.java, TrackTypeMapping()) .addTypeMapping(Track::class.java, TrackTypeMapping())

View file

@ -4,6 +4,7 @@ import androidx.sqlite.db.SupportSQLiteDatabase
import androidx.sqlite.db.SupportSQLiteOpenHelper import androidx.sqlite.db.SupportSQLiteOpenHelper
import com.squareup.sqldelight.android.AndroidSqliteDriver import com.squareup.sqldelight.android.AndroidSqliteDriver
import eu.kanade.tachiyomi.Database import eu.kanade.tachiyomi.Database
import logcat.logcat
class DbOpenCallback : SupportSQLiteOpenHelper.Callback(Database.Schema.version) { class DbOpenCallback : SupportSQLiteOpenHelper.Callback(Database.Schema.version) {
@ -15,16 +16,20 @@ class DbOpenCallback : SupportSQLiteOpenHelper.Callback(Database.Schema.version)
} }
override fun onCreate(db: SupportSQLiteDatabase) { override fun onCreate(db: SupportSQLiteDatabase) {
logcat { "Creating new database" }
Database.Schema.create(AndroidSqliteDriver(database = db, cacheSize = 1)) Database.Schema.create(AndroidSqliteDriver(database = db, cacheSize = 1))
} }
override fun onUpgrade(db: SupportSQLiteDatabase, oldVersion: Int, newVersion: Int) { override fun onUpgrade(db: SupportSQLiteDatabase, oldVersion: Int, newVersion: Int) {
if (oldVersion < newVersion) {
logcat { "Upgrading database from $oldVersion to $newVersion" }
Database.Schema.migrate( Database.Schema.migrate(
driver = AndroidSqliteDriver(database = db, cacheSize = 1), driver = AndroidSqliteDriver(database = db, cacheSize = 1),
oldVersion = oldVersion, oldVersion = oldVersion,
newVersion = newVersion newVersion = newVersion
) )
} }
}
override fun onConfigure(db: SupportSQLiteDatabase) { override fun onConfigure(db: SupportSQLiteDatabase) {
db.setForeignKeyConstraintsEnabled(true) db.setForeignKeyConstraintsEnabled(true)

View file

@ -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-android = { module = "com.squareup.leakcanary:leakcanary-android", version.ref ="leakcanary" }
leakcanary-plumber = { module = "com.squareup.leakcanary:plumber-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-android-driver = { module = "com.squareup.sqldelight:android-driver", version.ref ="sqldelight" }
sqldelight-coroutines = { module = "com.squareup.sqldelight:coroutines-extensions-jvm", 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" } sqldelight-android-paging = { module = "com.squareup.sqldelight:android-paging3-extensions", version.ref ="sqldelight" }