From 5d8d2ce48a6cccf9d21c0b4fd6c32a89603d36d8 Mon Sep 17 00:00:00 2001 From: AntsyLich <59261191+AntsyLich@users.noreply.github.com> Date: Wed, 18 Mar 2026 16:08:40 +0600 Subject: [PATCH] Switch to AndroidX bundled sqlite driver (#3082) # Conflicts: # app/build.gradle.kts # app/src/main/java/eu/kanade/tachiyomi/di/AppModule.kt --- app/build.gradle.kts | 2 +- .../java/eu/kanade/tachiyomi/di/AppModule.kt | 71 +++++++++---------- gradle/androidx.versions.toml | 3 + gradle/libs.versions.toml | 9 +-- 4 files changed, 39 insertions(+), 46 deletions(-) diff --git a/app/build.gradle.kts b/app/build.gradle.kts index 5767d05ae..48604d3c1 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -192,7 +192,7 @@ dependencies { implementation(androidx.paging.runtime) implementation(androidx.paging.compose) - implementation(libs.bundles.sqlite) + implementation(androidx.sqlite.bundled) // SY --> implementation(sylibs.sqlcipher) // SY <-- diff --git a/app/src/main/java/eu/kanade/tachiyomi/di/AppModule.kt b/app/src/main/java/eu/kanade/tachiyomi/di/AppModule.kt index 86ed42a32..0df083fd6 100755 --- a/app/src/main/java/eu/kanade/tachiyomi/di/AppModule.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/di/AppModule.kt @@ -1,12 +1,15 @@ package eu.kanade.tachiyomi.di import android.app.Application -import android.os.Build import androidx.core.content.ContextCompat import androidx.sqlite.db.SupportSQLiteDatabase -import androidx.sqlite.db.framework.FrameworkSQLiteOpenHelperFactory +import androidx.sqlite.driver.bundled.BundledSQLiteDriver import app.cash.sqldelight.db.SqlDriver import app.cash.sqldelight.driver.android.AndroidSqliteDriver +import com.eygraber.sqldelight.androidx.driver.AndroidxSqliteConfiguration +import com.eygraber.sqldelight.androidx.driver.AndroidxSqliteDatabaseType +import com.eygraber.sqldelight.androidx.driver.AndroidxSqliteDriver +import com.eygraber.sqldelight.androidx.driver.FileProvider import eu.kanade.domain.track.store.DelayedTrackingStore import eu.kanade.tachiyomi.BuildConfig import eu.kanade.tachiyomi.core.security.SecurityPreferences @@ -25,7 +28,6 @@ import eu.kanade.tachiyomi.network.NetworkHelper import eu.kanade.tachiyomi.source.AndroidSourceManager import eu.kanade.tachiyomi.util.storage.CbzCrypto import exh.eh.EHentaiUpdateHelper -import io.requery.android.database.sqlite.RequerySQLiteOpenHelperFactory import kotlinx.serialization.json.Json import kotlinx.serialization.protobuf.ProtoBuf import net.zetetic.database.sqlcipher.SupportOpenHelperFactory @@ -52,10 +54,6 @@ import uy.kohesive.injekt.api.InjektRegistrar import uy.kohesive.injekt.api.get import uy.kohesive.injekt.injectLazy -// SY --> -private const val LEGACY_DATABASE_NAME = "tachiyomi.db" -// SY <-- - class AppModule(val app: Application) : InjektModule { // SY --> private val securityPreferences: SecurityPreferences by injectLazy() @@ -68,40 +66,37 @@ class AppModule(val app: Application) : InjektModule { // SY --> if (securityPreferences.encryptDatabase().get()) { System.loadLibrary("sqlcipher") - } + return@addSingletonFactory AndroidSqliteDriver( + schema = Database.Schema, + context = app, + name = CbzCrypto.DATABASE_NAME, + factory = SupportOpenHelperFactory(CbzCrypto.getDecryptedPasswordSql(), null, false, 25), + callback = object : AndroidSqliteDriver.Callback(Database.Schema) { + override fun onOpen(db: SupportSQLiteDatabase) { + super.onOpen(db) + setPragma(db, "foreign_keys = ON") + setPragma(db, "journal_mode = WAL") + setPragma(db, "synchronous = NORMAL") + } + + private fun setPragma(db: SupportSQLiteDatabase, pragma: String) { + val cursor = db.query("PRAGMA $pragma") + cursor.moveToFirst() + cursor.close() + } + }, + ) + } // SY <-- - AndroidSqliteDriver( + + AndroidxSqliteDriver( + driver = BundledSQLiteDriver(), + databaseType = AndroidxSqliteDatabaseType.FileProvider(app, "tachiyomi.db"), schema = Database.Schema, - context = app, - // SY --> - name = if (securityPreferences.encryptDatabase().get()) { - CbzCrypto.DATABASE_NAME - } else { - LEGACY_DATABASE_NAME - }, - factory = if (securityPreferences.encryptDatabase().get()) { - SupportOpenHelperFactory(CbzCrypto.getDecryptedPasswordSql(), null, false, 25) - } else if (BuildConfig.DEBUG && Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) { - // Support database inspector in Android Studio - FrameworkSQLiteOpenHelperFactory() - } else { - RequerySQLiteOpenHelperFactory() - }, - // SY <-- - callback = object : AndroidSqliteDriver.Callback(Database.Schema) { - override fun onOpen(db: SupportSQLiteDatabase) { - super.onOpen(db) - setPragma(db, "foreign_keys = ON") - setPragma(db, "journal_mode = WAL") - setPragma(db, "synchronous = NORMAL") - } - private fun setPragma(db: SupportSQLiteDatabase, pragma: String) { - val cursor = db.query("PRAGMA $pragma") - cursor.moveToFirst() - cursor.close() - } - }, + configuration = AndroidxSqliteConfiguration( + isForeignKeyConstraintsEnabled = true, + ), ) } addSingletonFactory { diff --git a/gradle/androidx.versions.toml b/gradle/androidx.versions.toml index 863c1d0b9..43296b647 100644 --- a/gradle/androidx.versions.toml +++ b/gradle/androidx.versions.toml @@ -3,6 +3,7 @@ agp_version = "8.13.2" lifecycle_version = "2.10.0" paging_version = "3.4.2" interpolator_version = "1.0.0" +sqlite = "2.6.2" [libraries] gradle = { module = "com.android.tools.build:gradle", version.ref = "agp_version" } @@ -33,5 +34,7 @@ test-ext = "androidx.test.ext:junit-ktx:1.3.0" test-espresso-core = "androidx.test.espresso:espresso-core:3.7.0" test-uiautomator = "androidx.test.uiautomator:uiautomator:2.3.0" +sqlite-bundled = { module = "androidx.sqlite:sqlite-bundled", version.ref = "sqlite" } + [bundles] lifecycle = ["lifecycle-common", "lifecycle-process", "lifecycle-runtimektx"] diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index dd64c47d9..f8eb82bed 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -5,7 +5,6 @@ moko = "0.26.1" okhttp_version = "5.3.2" shizuku_version = "13.1.5" sqldelight = "2.3.2" -sqlite = "2.6.2" voyager = "1.1.0-beta03" spotless = "8.3.0" ktlint-core = "1.8.0" @@ -36,10 +35,6 @@ disklrucache = "com.jakewharton:disklrucache:2.0.2" unifile = "com.github.tachiyomiorg:unifile:e0def6b3dc" libarchive = "me.zhanghai.android.libarchive:library:1.1.6" -sqlite-framework = { module = "androidx.sqlite:sqlite-framework", version.ref = "sqlite" } -sqlite-ktx = { module = "androidx.sqlite:sqlite-ktx", version.ref = "sqlite" } -sqlite-android = "com.github.requery:sqlite-android:3.49.0" - preferencektx = "androidx.preference:preference-ktx:1.2.1" injekt = "com.github.null2264:injekt-koin:ee267b2e27" @@ -85,6 +80,7 @@ leakcanary-android = { module = "com.squareup.leakcanary:leakcanary-android", ve leakcanary-plumber = { module = "com.squareup.leakcanary:plumber-android", version.ref = "leakcanary" } sqldelight-android-driver = { module = "app.cash.sqldelight:android-driver", version.ref = "sqldelight" } +sqldelight-androidx-driver = { module = "com.eygraber:sqldelight-androidx-driver", version = "0.0.17" } sqldelight-coroutines = { module = "app.cash.sqldelight:coroutines-extensions-jvm", version.ref = "sqldelight" } sqldelight-android-paging = { module = "app.cash.sqldelight:androidx-paging3-extensions", version.ref = "sqldelight" } sqldelight-dialects-sql = { module = "app.cash.sqldelight:sqlite-3-38-dialect", version.ref = "sqldelight" } @@ -119,10 +115,9 @@ firebase-crashlytics = { id = "com.google.firebase.crashlytics", version = "3.0. [bundles] okhttp = ["okhttp-core", "okhttp-logging", "okhttp-brotli", "okhttp-dnsoverhttps"] js-engine = ["quickjs-android"] -sqlite = ["sqlite-framework", "sqlite-ktx", "sqlite-android"] coil = ["coil-core", "coil-gif", "coil-compose", "coil-network-okhttp"] shizuku = ["shizuku-api", "shizuku-provider"] -sqldelight = ["sqldelight-android-driver", "sqldelight-coroutines", "sqldelight-android-paging"] +sqldelight = ["sqldelight-android-driver", "sqldelight-androidx-driver", "sqldelight-coroutines", "sqldelight-android-paging"] voyager = ["voyager-navigator", "voyager-screenmodel", "voyager-tab-navigator", "voyager-transitions"] test = ["junit-jupiter", "kotest-assertions", "mockk"] markdown = ["markdown-core", "markdown-coil"]