From 6adea33d8aa9e5b208bb8b8dfce359428b335ecd Mon Sep 17 00:00:00 2001 From: Marco Gomiero Date: Sat, 2 Sep 2023 00:52:14 +0200 Subject: [PATCH] Migration to SQDelight 2.0 --- gradle/libs.versions.toml | 15 +++++----- shared/build.gradle.kts | 25 +++++++++-------- .../com/prof18/feedflow/di/KoinAndroid.kt | 4 +-- .../prof18/feedflow/data/DatabaseHelper.kt | 28 +++++++++++++------ .../kotlin/com/prof18/feedflow/di/Koin.kt | 3 +- .../com/prof18/feedflow/db/FeedItem.sq | 3 ++ .../com/prof18/feedflow/db/FeedSource.sq | 2 ++ .../com/prof18/feedflow/DbInitializer.kt | 23 ++++++++++----- .../com/prof18/feedflow/di/KoinDesktop.kt | 2 +- .../kotlin/com/prof18/feedflow/di/KoinIOS.kt | 4 +-- 10 files changed, 70 insertions(+), 39 deletions(-) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index a91df8e5..cc40f344 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -28,7 +28,7 @@ viewModel-compose = "2.6.1" lifecycle-runtime-compose = "2.6.1" kotlinx-serialization = "1.5.1" org-robolectric = "4.9" -sqlDelight = "1.5.5" +sql-delight = "2.0.0" rss-parser = "6.0.0" kotlinx-date-time = "0.4.0" accompanist = "0.28.0" @@ -82,11 +82,12 @@ touchlab-kermit-simple = { module = "co.touchlab:kermit-simple", version.ref = " touchlab-kermit-crashlytics = { module = "co.touchlab:kermit-crashlytics", version.ref = "kermit" } touchlab-kermit-test = { module = "co.touchlab:kermit-test", version.ref = "kermit" } org-robolectric = { module = "org.robolectric:robolectric", version.ref = "org-robolectric" } -squareup-sqldelight-android-driver = { module = "com.squareup.sqldelight:android-driver", version.ref = "sqlDelight" } -squareup-sqldelight-coroutine-extensions = { module = "com.squareup.sqldelight:coroutines-extensions", version.ref = "sqlDelight" } -squareup-sqldelight-native-driver = { module = "com.squareup.sqldelight:native-driver", version.ref = "sqlDelight" } -squareup-sqldelight-runtime = { module = "com.squareup.sqldelight:runtime", version.ref = "sqlDelight" } -squareup-sqldelight-sqlite-driver = { module = "com.squareup.sqldelight:sqlite-driver", version.ref = "sqlDelight" } +sqldelight-android-driver = { module = "app.cash.sqldelight:android-driver", version.ref = "sql-delight" } +sqldelight-coroutine-extensions = { module = "app.cash.sqldelight:coroutines-extensions", version.ref = "sql-delight" } +sqldelight-native-driver = { module = "app.cash.sqldelight:native-driver", version.ref = "sql-delight" } +sqldelight-runtime = { module = "app.cash.sqldelight:runtime", version.ref = "sql-delight" } +sqldelight-sqlite-driver = { module = "app.cash.sqldelight:sqlite-driver", version.ref = "sql-delight" } +sqldelight-primitive-adapter = { module = "app.cash.sqldelight:primitive-adapters", version.ref = "sql-delight" } com-prof18-rss-parser = { module = "com.prof18.rssparser:rssparser", version.ref = "rss-parser" } kotlinx-datetime = { module = "org.jetbrains.kotlinx:kotlinx-datetime", version.ref = "kotlinx-date-time" } accompanist-systemuicontroller = { group = "com.google.accompanist", name = "accompanist-systemuicontroller", version.ref = "accompanist" } @@ -121,7 +122,7 @@ kotlin-serialization = { id = "org.jetbrains.kotlin.plugin.serialization", versi kotlin-multiplatform = { id = "org.jetbrains.kotlin.multiplatform", version.ref = "kotlin" } versionsBenManes = { id = "com.github.ben-manes.versions", version.ref = "versions-ben-manes" } native-coroutines = { id = "com.rickclephas.kmp.nativecoroutines", version.ref = "native-coroutines" } -sqldelight = { id = "com.squareup.sqldelight", version.ref = "sqlDelight" } +sqldelight = { id = "app.cash.sqldelight", version.ref = "sql-delight" } triplet-play = { id = "com.github.triplet.play", version.ref = "triplet-play" } compose-multiplatform = { id = "org.jetbrains.compose", version.ref = "compose-multiplatform" } ksp = { id = "com.google.devtools.ksp", version.ref = "ksp" } diff --git a/shared/build.gradle.kts b/shared/build.gradle.kts index 5ad6ca83..aa1f99ab 100644 --- a/shared/build.gradle.kts +++ b/shared/build.gradle.kts @@ -52,8 +52,9 @@ kotlin { val commonMain by getting { dependencies { - implementation(libs.squareup.sqldelight.runtime) - implementation(libs.squareup.sqldelight.coroutine.extensions) + implementation(libs.sqldelight.runtime) + implementation(libs.sqldelight.coroutine.extensions) + implementation(libs.sqldelight.primitive.adapter) implementation(libs.koin.core) implementation(libs.kotlinx.coroutines.core) implementation(libs.com.prof18.rss.parser) @@ -100,7 +101,7 @@ kotlin { dependsOn(commonMobileMain) dependencies { - implementation(libs.squareup.sqldelight.android.driver) + implementation(libs.sqldelight.android.driver) implementation(libs.androidx.lifecycle.viewModel.ktx) implementation(libs.koin.android) implementation(libs.crashk.ios) @@ -113,7 +114,7 @@ kotlin { dependencies { implementation(libs.junit) implementation(libs.org.robolectric) - implementation(libs.squareup.sqldelight.sqlite.driver) + implementation(libs.sqldelight.sqlite.driver) implementation(libs.androidx.test.core.ktx) } } @@ -128,7 +129,7 @@ kotlin { iosSimulatorArm64Main.dependsOn(this) dependencies { - implementation(libs.squareup.sqldelight.native.driver) + implementation(libs.sqldelight.native.driver) api(libs.touchlab.kermit.simple) } @@ -143,7 +144,7 @@ kotlin { iosSimulatorArm64Test.dependsOn(this) dependencies { - implementation(libs.squareup.sqldelight.native.driver) + implementation(libs.sqldelight.native.driver) } } @@ -151,7 +152,7 @@ kotlin { dependsOn(commonJvmAndroidMain) dependencies { - implementation(libs.squareup.sqldelight.sqlite.driver) + implementation(libs.sqldelight.sqlite.driver) implementation(libs.kotlinx.coroutines.swing) api(libs.sentry) } @@ -164,11 +165,13 @@ kotlin { } sqldelight { - database("FeedFlowDB") { - packageName = "com.prof18.feedflow.db" - schemaOutputDirectory = file("src/commonMain/sqldelight/com/prof18/feedflow/schema") + databases { + create("FeedFlowDB") { + packageName.set("com.prof18.feedflow.db") + schemaOutputDirectory.set(file("src/commonMain/sqldelight/com/prof18/feedflow/schema")) - verifyMigrations = true + verifyMigrations.set(true) + } } } diff --git a/shared/src/androidMain/kotlin/com/prof18/feedflow/di/KoinAndroid.kt b/shared/src/androidMain/kotlin/com/prof18/feedflow/di/KoinAndroid.kt index 9c0343fd..fb1812c8 100644 --- a/shared/src/androidMain/kotlin/com/prof18/feedflow/di/KoinAndroid.kt +++ b/shared/src/androidMain/kotlin/com/prof18/feedflow/di/KoinAndroid.kt @@ -1,6 +1,8 @@ package com.prof18.feedflow.di import android.content.Context +import app.cash.sqldelight.db.SqlDriver +import app.cash.sqldelight.driver.android.AndroidSqliteDriver import com.prof18.feedflow.data.DatabaseHelper import com.prof18.feedflow.db.FeedFlowDB import com.prof18.feedflow.domain.DateFormatter @@ -12,8 +14,6 @@ import com.prof18.feedflow.presentation.BaseViewModel import com.prof18.feedflow.utils.DispatcherProvider import com.russhwolf.settings.Settings import com.russhwolf.settings.SharedPreferencesSettings -import com.squareup.sqldelight.android.AndroidSqliteDriver -import com.squareup.sqldelight.db.SqlDriver import kotlinx.coroutines.CoroutineDispatcher import kotlinx.coroutines.Dispatchers import org.koin.core.definition.Definition diff --git a/shared/src/commonMain/kotlin/com/prof18/feedflow/data/DatabaseHelper.kt b/shared/src/commonMain/kotlin/com/prof18/feedflow/data/DatabaseHelper.kt index 43fe4bb1..e80f69b9 100644 --- a/shared/src/commonMain/kotlin/com/prof18/feedflow/data/DatabaseHelper.kt +++ b/shared/src/commonMain/kotlin/com/prof18/feedflow/data/DatabaseHelper.kt @@ -1,17 +1,20 @@ package com.prof18.feedflow.data +import app.cash.sqldelight.Transacter +import app.cash.sqldelight.TransactionWithoutReturn +import app.cash.sqldelight.adapter.primitive.IntColumnAdapter +import app.cash.sqldelight.coroutines.asFlow +import app.cash.sqldelight.coroutines.mapToList +import app.cash.sqldelight.db.SqlDriver import co.touchlab.kermit.Logger import com.prof18.feedflow.core.model.FeedItem import com.prof18.feedflow.core.model.FeedSource import com.prof18.feedflow.core.model.ParsedFeedSource import com.prof18.feedflow.db.FeedFlowDB +import com.prof18.feedflow.db.Feed_item +import com.prof18.feedflow.db.Feed_source import com.prof18.feedflow.db.SelectFeeds import com.prof18.feedflow.domain.model.FeedItemId -import com.squareup.sqldelight.Transacter -import com.squareup.sqldelight.TransactionWithoutReturn -import com.squareup.sqldelight.db.SqlDriver -import com.squareup.sqldelight.runtime.coroutines.asFlow -import com.squareup.sqldelight.runtime.coroutines.mapToList import kotlinx.coroutines.CoroutineDispatcher import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.catch @@ -27,7 +30,16 @@ internal class DatabaseHelper( private val backgroundDispatcher: CoroutineDispatcher, private val logger: Logger, ) { - private val dbRef: FeedFlowDB = FeedFlowDB(sqlDriver) + private val dbRef: FeedFlowDB = FeedFlowDB( + sqlDriver, + feed_itemAdapter = Feed_item.Adapter( + url_hashAdapter = IntColumnAdapter, + feed_source_idAdapter = IntColumnAdapter, + ), + feed_sourceAdapter = Feed_source.Adapter( + url_hashAdapter = IntColumnAdapter, + ), + ) suspend fun getFeedSources(): List = withContext(backgroundDispatcher) { dbRef.feedSourceQueries @@ -50,7 +62,7 @@ internal class DatabaseHelper( .catch { logger.e(it) { "Something wrong while getting data from Database" } } - .mapToList() + .mapToList(backgroundDispatcher) .map { feedSources -> feedSources.map { feedSource -> FeedSource( @@ -68,7 +80,7 @@ internal class DatabaseHelper( dbRef.feedItemQueries .selectFeeds() .asFlow() - .mapToList() + .mapToList(backgroundDispatcher) .retry(3) { exception -> exception is NullPointerException } diff --git a/shared/src/commonMain/kotlin/com/prof18/feedflow/di/Koin.kt b/shared/src/commonMain/kotlin/com/prof18/feedflow/di/Koin.kt index 72ce52ae..2222f0d6 100644 --- a/shared/src/commonMain/kotlin/com/prof18/feedflow/di/Koin.kt +++ b/shared/src/commonMain/kotlin/com/prof18/feedflow/di/Koin.kt @@ -18,6 +18,7 @@ import com.prof18.feedflow.presentation.ImportExportViewModel import com.prof18.feedflow.utils.AppEnvironment import com.prof18.rssparser.RssParser import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.IO import org.koin.core.KoinApplication import org.koin.core.context.startKoin import org.koin.core.definition.Definition @@ -63,7 +64,7 @@ private val coreModule = module { single { DatabaseHelper( sqlDriver = get(), - backgroundDispatcher = Dispatchers.Default, + backgroundDispatcher = Dispatchers.IO, logger = getWith("DatabaseHelper"), ) } diff --git a/shared/src/commonMain/sqldelight/com/prof18/feedflow/db/FeedItem.sq b/shared/src/commonMain/sqldelight/com/prof18/feedflow/db/FeedItem.sq index b0778817..c3b9d78c 100644 --- a/shared/src/commonMain/sqldelight/com/prof18/feedflow/db/FeedItem.sq +++ b/shared/src/commonMain/sqldelight/com/prof18/feedflow/db/FeedItem.sq @@ -1,3 +1,6 @@ +import kotlin.Boolean; +import kotlin.Int; + CREATE TABLE feed_item ( url_hash INTEGER AS Int NOT NULL PRIMARY KEY, url TEXT NOT NULL, diff --git a/shared/src/commonMain/sqldelight/com/prof18/feedflow/db/FeedSource.sq b/shared/src/commonMain/sqldelight/com/prof18/feedflow/db/FeedSource.sq index 4b281853..8488c18d 100644 --- a/shared/src/commonMain/sqldelight/com/prof18/feedflow/db/FeedSource.sq +++ b/shared/src/commonMain/sqldelight/com/prof18/feedflow/db/FeedSource.sq @@ -1,3 +1,5 @@ +import kotlin.Int; + CREATE TABLE feed_source ( url_hash INTEGER AS Int NOT NULL PRIMARY KEY, url TEXT NOT NULL, diff --git a/shared/src/desktopMain/kotlin/com/prof18/feedflow/DbInitializer.kt b/shared/src/desktopMain/kotlin/com/prof18/feedflow/DbInitializer.kt index a227f50b..0fee2400 100644 --- a/shared/src/desktopMain/kotlin/com/prof18/feedflow/DbInitializer.kt +++ b/shared/src/desktopMain/kotlin/com/prof18/feedflow/DbInitializer.kt @@ -1,10 +1,11 @@ package com.prof18.feedflow +import app.cash.sqldelight.db.QueryResult +import app.cash.sqldelight.db.SqlDriver +import app.cash.sqldelight.driver.jdbc.sqlite.JdbcSqliteDriver import co.touchlab.kermit.Logger import com.prof18.feedflow.data.DatabaseHelper import com.prof18.feedflow.db.FeedFlowDB -import com.squareup.sqldelight.db.SqlDriver -import com.squareup.sqldelight.sqlite.driver.JdbcSqliteDriver import java.io.File import java.util.Properties @@ -15,15 +16,23 @@ internal fun initDatabase(logger: Logger): SqlDriver { val driver = JdbcSqliteDriver(JdbcSqliteDriver.IN_MEMORY + databasePath.absolutePath, Properties()) - val sqlCursor = driver.executeQuery(null, "PRAGMA user_version;", 0, null) - val currentVer: Int = sqlCursor.use { sqlCursor.getLong(0)?.toInt() ?: 0 } + val sqlCursor = driver.executeQuery( + null, + "PRAGMA user_version;", + { + QueryResult.Value(it.getLong(0)) + }, + 0, + null, + ) + val currentVer: Long = sqlCursor.value ?: -1L - if (currentVer == 0) { + if (currentVer == 0L) { FeedFlowDB.Schema.create(driver) setVersion(driver, 1) logger.d("init: created tables, setVersion to 1") } else { - val schemaVer: Int = FeedFlowDB.Schema.version + val schemaVer = FeedFlowDB.Schema.version if (schemaVer > currentVer) { FeedFlowDB.Schema.migrate(driver, currentVer, schemaVer) setVersion(driver, schemaVer) @@ -35,6 +44,6 @@ internal fun initDatabase(logger: Logger): SqlDriver { return driver } -fun setVersion(driver: SqlDriver, version: Int) { +fun setVersion(driver: SqlDriver, version: Long) { driver.execute(null, "PRAGMA user_version = $version;", 0, null) } diff --git a/shared/src/desktopMain/kotlin/com/prof18/feedflow/di/KoinDesktop.kt b/shared/src/desktopMain/kotlin/com/prof18/feedflow/di/KoinDesktop.kt index e12740ed..431a31d2 100644 --- a/shared/src/desktopMain/kotlin/com/prof18/feedflow/di/KoinDesktop.kt +++ b/shared/src/desktopMain/kotlin/com/prof18/feedflow/di/KoinDesktop.kt @@ -1,5 +1,6 @@ package com.prof18.feedflow.di +import app.cash.sqldelight.db.SqlDriver import com.prof18.feedflow.domain.DateFormatter import com.prof18.feedflow.domain.HtmlParser import com.prof18.feedflow.domain.JvmAndroidDateFormatter @@ -11,7 +12,6 @@ import com.prof18.feedflow.utils.AppEnvironment import com.prof18.feedflow.utils.DispatcherProvider import com.russhwolf.settings.PreferencesSettings import com.russhwolf.settings.Settings -import com.squareup.sqldelight.db.SqlDriver import kotlinx.coroutines.CoroutineDispatcher import kotlinx.coroutines.Dispatchers import org.koin.core.KoinApplication diff --git a/shared/src/iosMain/kotlin/com/prof18/feedflow/di/KoinIOS.kt b/shared/src/iosMain/kotlin/com/prof18/feedflow/di/KoinIOS.kt index 0171c0b8..040a1f11 100644 --- a/shared/src/iosMain/kotlin/com/prof18/feedflow/di/KoinIOS.kt +++ b/shared/src/iosMain/kotlin/com/prof18/feedflow/di/KoinIOS.kt @@ -1,5 +1,7 @@ package com.prof18.feedflow.di +import app.cash.sqldelight.db.SqlDriver +import app.cash.sqldelight.driver.native.NativeSqliteDriver import co.touchlab.kermit.Logger import com.prof18.feedflow.data.DatabaseHelper import com.prof18.feedflow.db.FeedFlowDB @@ -18,8 +20,6 @@ import com.prof18.feedflow.utils.DispatcherProvider import com.russhwolf.settings.ExperimentalSettingsImplementation import com.russhwolf.settings.KeychainSettings import com.russhwolf.settings.Settings -import com.squareup.sqldelight.db.SqlDriver -import com.squareup.sqldelight.drivers.native.NativeSqliteDriver import kotlinx.coroutines.CoroutineDispatcher import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.IO