arkon 1 год назад
Родитель
Сommit
6a558ad119

+ 1 - 0
app/build.gradle.kts

@@ -170,6 +170,7 @@ dependencies {
     implementation(androidx.paging.compose)
 
     implementation(libs.bundles.sqlite)
+    implementation(libs.sqldelight.primitive.adapters)
 
     implementation(kotlinx.reflect)
 

+ 11 - 2
app/src/main/java/eu/kanade/tachiyomi/AppModule.kt

@@ -5,8 +5,9 @@ import android.os.Build
 import androidx.core.content.ContextCompat
 import androidx.sqlite.db.SupportSQLiteDatabase
 import androidx.sqlite.db.framework.FrameworkSQLiteOpenHelperFactory
-import com.squareup.sqldelight.android.AndroidSqliteDriver
-import com.squareup.sqldelight.db.SqlDriver
+import app.cash.sqldelight.adapter.primitive.FloatColumnAdapter
+import app.cash.sqldelight.db.SqlDriver
+import app.cash.sqldelight.driver.android.AndroidSqliteDriver
 import eu.kanade.domain.base.BasePreferences
 import eu.kanade.domain.source.service.SourcePreferences
 import eu.kanade.domain.track.service.TrackPreferences
@@ -37,9 +38,11 @@ import tachiyomi.core.preference.PreferenceStore
 import tachiyomi.core.provider.AndroidBackupFolderProvider
 import tachiyomi.core.provider.AndroidDownloadFolderProvider
 import tachiyomi.data.AndroidDatabaseHandler
+import tachiyomi.data.Chapters
 import tachiyomi.data.Database
 import tachiyomi.data.DatabaseHandler
 import tachiyomi.data.History
+import tachiyomi.data.Manga_sync
 import tachiyomi.data.Mangas
 import tachiyomi.data.dateAdapter
 import tachiyomi.data.listOfStringsAdapter
@@ -90,9 +93,15 @@ class AppModule(val app: Application) : InjektModule {
         addSingletonFactory {
             Database(
                 driver = get(),
+                chaptersAdapter = Chapters.Adapter(
+                    chapter_numberAdapter = FloatColumnAdapter,
+                ),
                 historyAdapter = History.Adapter(
                     last_readAdapter = dateAdapter,
                 ),
+                manga_syncAdapter = Manga_sync.Adapter(
+                    scoreAdapter = FloatColumnAdapter,
+                ),
                 mangasAdapter = Mangas.Adapter(
                     genreAdapter = listOfStringsAdapter,
                     update_strategyAdapter = updateStrategyAdapter,

+ 6 - 6
app/src/main/java/eu/kanade/tachiyomi/data/backup/BackupManager.kt

@@ -264,7 +264,7 @@ class BackupManager(
             }
             if (!found) {
                 // Let the db assign the id
-                val id = handler.awaitOne {
+                val id = handler.awaitOneExecutable {
                     categoriesQueries.insert(category.name, category.order, category.flags)
                     categoriesQueries.selectLastInsertedRowId()
                 }
@@ -488,7 +488,7 @@ class BackupManager(
      * @return id of [Manga], null if not found
      */
     private suspend fun insertManga(manga: Manga): Long {
-        return handler.awaitOne(true) {
+        return handler.awaitOneExecutable(true) {
             mangasQueries.insert(
                 source = manga.source,
                 url = manga.url,
@@ -526,11 +526,11 @@ class BackupManager(
                 title = manga.title,
                 status = manga.status,
                 thumbnailUrl = manga.thumbnailUrl,
-                favorite = manga.favorite.toLong(),
+                favorite = manga.favorite,
                 lastUpdate = manga.lastUpdate,
                 nextUpdate = null,
                 calculateInterval = null,
-                initialized = manga.initialized.toLong(),
+                initialized = manga.initialized,
                 viewer = manga.viewerFlags,
                 chapterFlags = manga.chapterFlags,
                 coverLastModified = manga.coverLastModified,
@@ -576,8 +576,8 @@ class BackupManager(
                     url = null,
                     name = null,
                     scanlator = null,
-                    read = chapter.read.toLong(),
-                    bookmark = chapter.bookmark.toLong(),
+                    read = chapter.read,
+                    bookmark = chapter.bookmark,
                     lastPageRead = chapter.lastPageRead,
                     chapterNumber = null,
                     sourceOrder = null,

+ 8 - 8
data/build.gradle.kts

@@ -2,7 +2,7 @@ plugins {
     id("com.android.library")
     kotlin("android")
     kotlin("plugin.serialization")
-    id("com.squareup.sqldelight")
+    id("app.cash.sqldelight")
 }
 
 android {
@@ -13,10 +13,12 @@ android {
     }
 
     sqldelight {
-        database("Database") {
-            packageName = "tachiyomi.data"
-            dialect = "sqlite:3.24"
-            schemaOutputDirectory = project.file("./src/main/sqldelight")
+        databases {
+            create("Database") {
+                packageName.set("tachiyomi.data")
+                dialect(libs.sqldelight.dialects.sql)
+                schemaOutputDirectory.set(project.file("./src/main/sqldelight"))
+            }
         }
     }
 }
@@ -26,9 +28,7 @@ dependencies {
     implementation(project(":domain"))
     implementation(project(":core"))
 
-    api(libs.sqldelight.android.driver)
-    api(libs.sqldelight.coroutines)
-    api(libs.sqldelight.android.paging)
+    api(libs.bundles.sqldelight)
 }
 
 tasks {

+ 21 - 6
data/src/main/java/tachiyomi/data/AndroidDatabaseHandler.kt

@@ -1,12 +1,13 @@
 package tachiyomi.data
 
 import androidx.paging.PagingSource
-import com.squareup.sqldelight.Query
-import com.squareup.sqldelight.db.SqlDriver
-import com.squareup.sqldelight.runtime.coroutines.asFlow
-import com.squareup.sqldelight.runtime.coroutines.mapToList
-import com.squareup.sqldelight.runtime.coroutines.mapToOne
-import com.squareup.sqldelight.runtime.coroutines.mapToOneOrNull
+import app.cash.sqldelight.ExecutableQuery
+import app.cash.sqldelight.Query
+import app.cash.sqldelight.coroutines.asFlow
+import app.cash.sqldelight.coroutines.mapToList
+import app.cash.sqldelight.coroutines.mapToOne
+import app.cash.sqldelight.coroutines.mapToOneOrNull
+import app.cash.sqldelight.db.SqlDriver
 import kotlinx.coroutines.CoroutineDispatcher
 import kotlinx.coroutines.Dispatchers
 import kotlinx.coroutines.flow.Flow
@@ -39,6 +40,13 @@ class AndroidDatabaseHandler(
         return dispatch(inTransaction) { block(db).executeAsOne() }
     }
 
+    override suspend fun <T : Any> awaitOneExecutable(
+        inTransaction: Boolean,
+        block: suspend Database.() -> ExecutableQuery<T>,
+    ): T {
+        return dispatch(inTransaction) { block(db).executeAsOne() }
+    }
+
     override suspend fun <T : Any> awaitOneOrNull(
         inTransaction: Boolean,
         block: suspend Database.() -> Query<T>,
@@ -46,6 +54,13 @@ class AndroidDatabaseHandler(
         return dispatch(inTransaction) { block(db).executeAsOneOrNull() }
     }
 
+    override suspend fun <T : Any> awaitOneOrNullExecutable(
+        inTransaction: Boolean,
+        block: suspend Database.() -> ExecutableQuery<T>,
+    ): T? {
+        return dispatch(inTransaction) { block(db).executeAsOneOrNull() }
+    }
+
     override fun <T : Any> subscribeToList(block: Database.() -> Query<T>): Flow<List<T>> {
         return block(db).asFlow().mapToList(queryDispatcher)
     }

+ 1 - 1
data/src/main/java/tachiyomi/data/DatabaseAdapter.kt

@@ -1,6 +1,6 @@
 package tachiyomi.data
 
-import com.squareup.sqldelight.ColumnAdapter
+import app.cash.sqldelight.ColumnAdapter
 import eu.kanade.tachiyomi.source.model.UpdateStrategy
 import java.util.Date
 

+ 12 - 1
data/src/main/java/tachiyomi/data/DatabaseHandler.kt

@@ -1,7 +1,8 @@
 package tachiyomi.data
 
 import androidx.paging.PagingSource
-import com.squareup.sqldelight.Query
+import app.cash.sqldelight.ExecutableQuery
+import app.cash.sqldelight.Query
 import kotlinx.coroutines.flow.Flow
 
 interface DatabaseHandler {
@@ -18,11 +19,21 @@ interface DatabaseHandler {
         block: suspend Database.() -> Query<T>,
     ): T
 
+    suspend fun <T : Any> awaitOneExecutable(
+        inTransaction: Boolean = false,
+        block: suspend Database.() -> ExecutableQuery<T>,
+    ): T
+
     suspend fun <T : Any> awaitOneOrNull(
         inTransaction: Boolean = false,
         block: suspend Database.() -> Query<T>,
     ): T?
 
+    suspend fun <T : Any> awaitOneOrNullExecutable(
+        inTransaction: Boolean = false,
+        block: suspend Database.() -> ExecutableQuery<T>,
+    ): T?
+
     fun <T : Any> subscribeToList(block: Database.() -> Query<T>): Flow<List<T>>
 
     fun <T : Any> subscribeToOne(block: Database.() -> Query<T>): Flow<T>

+ 1 - 1
data/src/main/java/tachiyomi/data/QueryPagingSource.kt

@@ -2,7 +2,7 @@ package tachiyomi.data
 
 import androidx.paging.PagingSource
 import androidx.paging.PagingState
-import com.squareup.sqldelight.Query
+import app.cash.sqldelight.Query
 import kotlin.properties.Delegates
 
 class QueryPagingSource<RowType : Any>(

+ 2 - 3
data/src/main/java/tachiyomi/data/chapter/ChapterRepositoryImpl.kt

@@ -2,7 +2,6 @@ package tachiyomi.data.chapter
 
 import kotlinx.coroutines.flow.Flow
 import logcat.LogPriority
-import tachiyomi.core.util.lang.toLong
 import tachiyomi.core.util.system.logcat
 import tachiyomi.data.DatabaseHandler
 import tachiyomi.domain.chapter.model.Chapter
@@ -56,8 +55,8 @@ class ChapterRepositoryImpl(
                     url = chapterUpdate.url,
                     name = chapterUpdate.name,
                     scanlator = chapterUpdate.scanlator,
-                    read = chapterUpdate.read?.toLong(),
-                    bookmark = chapterUpdate.bookmark?.toLong(),
+                    read = chapterUpdate.read,
+                    bookmark = chapterUpdate.bookmark,
                     lastPageRead = chapterUpdate.lastPageRead,
                     chapterNumber = chapterUpdate.chapterNumber?.toDouble(),
                     sourceOrder = chapterUpdate.sourceOrder,

+ 3 - 3
data/src/main/java/tachiyomi/data/manga/MangaMapper.kt

@@ -32,7 +32,7 @@ val mangaMapper: (Long, Long, String, String?, String?, String?, List<String>?,
         )
     }
 
-val libraryManga: (Long, Long, String, String?, String?, String?, List<String>?, String, Long, String?, Boolean, Long?, Long?, Boolean, Long, Long, Long, Long, UpdateStrategy, Long, Long, Long?, Long, Long, Long, Long, Long, Long, Long) -> LibraryManga =
+val libraryManga: (Long, Long, String, String?, String?, String?, List<String>?, String, Long, String?, Boolean, Long?, Long?, Boolean, Long, Long, Long, Long, UpdateStrategy, Long, Long, Long?, Long, Double, Long, Long, Long, Double, Long) -> LibraryManga =
     { id, source, url, artist, author, description, genre, title, status, thumbnailUrl, favorite, lastUpdate, nextUpdate, initialized, viewerFlags, chapterFlags, coverLastModified, dateAdded, updateStrategy, calculateInterval, lastModifiedAt, favoriteModifiedAt, totalCount, readCount, latestUpload, chapterFetchedAt, lastRead, bookmarkCount, category ->
         LibraryManga(
             manga = mangaMapper(
@@ -61,8 +61,8 @@ val libraryManga: (Long, Long, String, String?, String?, String?, List<String>?,
             ),
             category = category,
             totalChapters = totalCount,
-            readCount = readCount,
-            bookmarkCount = bookmarkCount,
+            readCount = readCount.toLong(),
+            bookmarkCount = bookmarkCount.toLong(),
             latestUpload = latestUpload,
             chapterFetchedAt = chapterFetchedAt,
             lastRead = lastRead,

+ 3 - 3
data/src/main/java/tachiyomi/data/manga/MangaRepositoryImpl.kt

@@ -74,7 +74,7 @@ class MangaRepositoryImpl(
     }
 
     override suspend fun insert(manga: Manga): Long? {
-        return handler.awaitOneOrNull(inTransaction = true) {
+        return handler.awaitOneOrNullExecutable(inTransaction = true) {
             mangasQueries.insert(
                 source = manga.source,
                 url = manga.url,
@@ -133,11 +133,11 @@ class MangaRepositoryImpl(
                     title = value.title,
                     status = value.status,
                     thumbnailUrl = value.thumbnailUrl,
-                    favorite = value.favorite?.toLong(),
+                    favorite = value.favorite,
                     lastUpdate = value.lastUpdate,
                     nextUpdate = value.nextUpdate,
                     calculateInterval = value.fetchInterval?.toLong(),
-                    initialized = value.initialized?.toLong(),
+                    initialized = value.initialized,
                     viewer = value.viewerFlags,
                     chapterFlags = value.chapterFlags,
                     coverLastModified = value.coverLastModified,

+ 6 - 3
data/src/main/sqldelight/tachiyomi/data/chapters.sq

@@ -1,3 +1,6 @@
+import kotlin.Boolean;
+import kotlin.Float;
+
 CREATE TABLE chapters(
     _id INTEGER NOT NULL PRIMARY KEY,
     manga_id INTEGER NOT NULL,
@@ -9,9 +12,9 @@ CREATE TABLE chapters(
     last_page_read INTEGER NOT NULL,
     chapter_number REAL AS Float NOT NULL,
     source_order INTEGER NOT NULL,
-    date_fetch INTEGER AS Long NOT NULL,
-    date_upload INTEGER AS Long NOT NULL,
-    last_modified_at INTEGER AS Long NOT NULL DEFAULT 0,
+    date_fetch INTEGER NOT NULL,
+    date_upload INTEGER NOT NULL,
+    last_modified_at INTEGER NOT NULL DEFAULT 0,
     FOREIGN KEY(manga_id) REFERENCES mangas (_id)
     ON DELETE CASCADE
 );

+ 4 - 2
data/src/main/sqldelight/tachiyomi/data/manga_sync.sq

@@ -1,3 +1,5 @@
+import kotlin.Float;
+
 CREATE TABLE manga_sync(
     _id INTEGER NOT NULL PRIMARY KEY,
     manga_id INTEGER NOT NULL,
@@ -10,8 +12,8 @@ CREATE TABLE manga_sync(
     status INTEGER NOT NULL,
     score REAL AS Float NOT NULL,
     remote_url TEXT NOT NULL,
-    start_date INTEGER AS Long NOT NULL,
-    finish_date INTEGER AS Long NOT NULL,
+    start_date INTEGER NOT NULL,
+    finish_date INTEGER NOT NULL,
     UNIQUE (manga_id, sync_id) ON CONFLICT REPLACE,
     FOREIGN KEY(manga_id) REFERENCES mangas (_id)
     ON DELETE CASCADE

+ 8 - 7
data/src/main/sqldelight/tachiyomi/data/mangas.sq

@@ -1,6 +1,7 @@
 import eu.kanade.tachiyomi.source.model.UpdateStrategy;
-import java.lang.String;
 import kotlin.collections.List;
+import kotlin.Boolean;
+import kotlin.String;
 
 CREATE TABLE mangas(
     _id INTEGER NOT NULL PRIMARY KEY,
@@ -14,17 +15,17 @@ CREATE TABLE mangas(
     status INTEGER NOT NULL,
     thumbnail_url TEXT,
     favorite INTEGER AS Boolean NOT NULL,
-    last_update INTEGER AS Long,
-    next_update INTEGER AS Long,
+    last_update INTEGER,
+    next_update INTEGER,
     initialized INTEGER AS Boolean NOT NULL,
     viewer INTEGER NOT NULL,
     chapter_flags INTEGER NOT NULL,
-    cover_last_modified INTEGER AS Long NOT NULL,
-    date_added INTEGER AS Long NOT NULL,
+    cover_last_modified INTEGER NOT NULL,
+    date_added INTEGER NOT NULL,
     update_strategy INTEGER AS UpdateStrategy NOT NULL DEFAULT 0,
     calculate_interval INTEGER DEFAULT 0 NOT NULL,
-    last_modified_at INTEGER AS Long NOT NULL DEFAULT 0,
-    favorite_modified_at INTEGER AS Long
+    last_modified_at INTEGER NOT NULL DEFAULT 0,
+    favorite_modified_at INTEGER
 );
 
 CREATE INDEX library_favorite_index ON mangas(favorite) WHERE favorite = 1;

+ 1 - 1
data/src/main/sqldelight/tachiyomi/data/mangas_categories.sq

@@ -2,7 +2,7 @@ CREATE TABLE mangas_categories(
     _id INTEGER NOT NULL PRIMARY KEY,
     manga_id INTEGER NOT NULL,
     category_id INTEGER NOT NULL,
-    last_modified_at INTEGER AS Long NOT NULL DEFAULT 0,
+    last_modified_at INTEGER NOT NULL DEFAULT 0,
     FOREIGN KEY(category_id) REFERENCES categories (_id)
     ON DELETE CASCADE,
     FOREIGN KEY(manga_id) REFERENCES mangas (_id)

+ 8 - 5
gradle/libs.versions.toml

@@ -3,7 +3,7 @@ aboutlib_version = "10.8.3"
 okhttp_version = "5.0.0-alpha.11"
 shizuku_version = "12.2.0"
 sqlite = "2.3.1"
-sqldelight = "1.5.5"
+sqldelight = "2.0.0"
 leakcanary = "2.12"
 voyager = "1.0.0-rc06"
 richtext = "0.17.0"
@@ -77,10 +77,12 @@ 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-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" }
-sqldelight-gradle = { module = "com.squareup.sqldelight:gradle-plugin", version.ref = "sqldelight" }
+sqldelight-android-driver = { module = "app.cash.sqldelight:android-driver", version.ref = "sqldelight" }
+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-primitive-adapters = { module = "app.cash.sqldelight:primitive-adapters", version.ref = "sqldelight" }
+sqldelight-dialects-sql = { module = "app.cash.sqldelight:sqlite-3-38-dialect", version.ref = "sqldelight" }
+sqldelight-gradle = { module = "app.cash.sqldelight:gradle-plugin", version.ref = "sqldelight" }
 
 junit = "org.junit.jupiter:junit-jupiter:5.10.0"
 kotest-assertions = "io.kotest:kotest-assertions-core:5.6.2"
@@ -99,6 +101,7 @@ js-engine = ["quickjs-android"]
 sqlite = ["sqlite-framework", "sqlite-ktx", "sqlite-android"]
 coil = ["coil-core", "coil-gif", "coil-compose"]
 shizuku = ["shizuku-api", "shizuku-provider"]
+sqldelight = ["sqldelight-android-driver", "sqldelight-coroutines", "sqldelight-android-paging", "sqldelight-primitive-adapters"]
 voyager = ["voyager-navigator", "voyager-tab-navigator", "voyager-transitions"]
 richtext = ["richtext-commonmark", "richtext-m3"]
 test = ["junit", "kotest-assertions", "mockk"]

+ 1 - 1
source-api/build.gradle.kts

@@ -5,7 +5,7 @@ plugins {
 }
 
 kotlin {
-    android()
+    androidTarget()
     sourceSets {
         val commonMain by getting {
             dependencies {

+ 1 - 1
source-local/build.gradle.kts

@@ -4,7 +4,7 @@ plugins {
 }
 
 kotlin {
-    android()
+    androidTarget()
     sourceSets {
         val commonMain by getting {
             dependencies {