Add SqlDelight drivers

pull/1323/head
lihenggui 2 years ago
parent bdf201762e
commit 0712a7d26a

@ -18,6 +18,7 @@ package com.google.samples.apps.nowinandroid
import org.gradle.api.Project
import org.gradle.kotlin.dsl.configure
import org.jetbrains.kotlin.gradle.ExperimentalKotlinGradlePluginApi
import org.jetbrains.kotlin.gradle.dsl.KotlinMultiplatformExtension
import org.jetbrains.kotlin.konan.target.HostManager
@ -27,6 +28,10 @@ import org.jetbrains.kotlin.konan.target.HostManager
*/
internal fun Project.configureKotlinMultiplatform() {
extensions.configure<KotlinMultiplatformExtension> {
// Enable native group by default
// https://kotlinlang.org/docs/whatsnew1820.html#new-approach-to-source-set-hierarchy
applyDefaultHierarchyTemplate()
jvm()
androidTarget()
@ -52,18 +57,19 @@ internal fun Project.configureKotlinMultiplatform() {
iosSimulatorArm64()
iosX64()
// tier 2
linuxArm64()
watchosSimulatorArm64()
watchosX64()
watchosArm32()
watchosArm64()
tvosSimulatorArm64()
tvosX64()
tvosArm64()
// Fix :core:database:linuxArm64Main: Could not resolve me.tatarka.inject:kotlin-inject-runtime:0.6.3.
// // tier 2
// linuxArm64()
// watchosSimulatorArm64()
// watchosX64()
// watchosArm32()
// watchosArm64()
// tvosSimulatorArm64()
// tvosX64()
// tvosArm64()
iosArm64()
// fix :core:model:androidNativeArm32Main: Could not resolve org.jetbrains.kotlinx:kotlinx-datetime
// fix :core:model:androidNativeArm32Main: Could not resolve org.jetbrains.kotlinx:kotlinx-datetime
// // tier 3
// androidNativeArm32()
// androidNativeArm64()

@ -17,6 +17,7 @@
plugins {
alias(libs.plugins.nowinandroid.kmp.library)
alias(libs.plugins.sqldelight.gradle.plugin)
alias(libs.plugins.ksp)
}
android {
@ -33,6 +34,8 @@ kotlin {
dependencies {
api(projects.core.model)
implementation(libs.kotlinx.datetime)
implementation(libs.kotlinInject.runtime)
implementation(libs.sqldelight.coroutines.extensions)
}
}
val androidMain by getting {
@ -50,6 +53,14 @@ kotlin {
implementation(libs.sqldelight.sqlite.driver)
}
}
val jsMain by getting {
dependencies {
implementation(libs.sqldelight.sqljs.driver)
implementation(libs.sqldelight.webworker.driver)
implementation(npm("sql.js", "1.6.2"))
implementation(devNpm("copy-webpack-plugin", "9.1.0"))
}
}
val commonTest by getting {
dependencies {
implementation(libs.kotlin.test)
@ -57,3 +68,21 @@ kotlin {
}
}
}
sqldelight {
databases {
create("NiaDatabase") {
packageName.set("com.google.samples.apps.nowinandroid.core.database")
generateAsync.set(true)
}
}
}
dependencies {
// KSP will eventually have better multiplatform support and we'll be able to simply have
// `ksp libs.kotlinInject.compiler` in the dependencies block of each source set
// https://github.com/google/ksp/pull/1021
add("kspIosX64", libs.kotlinInject.compiler)
add("kspIosArm64", libs.kotlinInject.compiler)
add("kspIosSimulatorArm64", libs.kotlinInject.compiler)
}

@ -1,5 +1,5 @@
/*
* Copyright 2022 The Android Open Source Project
* Copyright 2024 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -17,24 +17,16 @@
package com.google.samples.apps.nowinandroid.core.database
import android.content.Context
import androidx.room.Room
import dagger.Module
import dagger.Provides
import dagger.hilt.InstallIn
import dagger.hilt.android.qualifiers.ApplicationContext
import dagger.hilt.components.SingletonComponent
import javax.inject.Singleton
import app.cash.sqldelight.async.coroutines.synchronous
import app.cash.sqldelight.db.QueryResult
import app.cash.sqldelight.db.SqlDriver
import app.cash.sqldelight.db.SqlSchema
import app.cash.sqldelight.driver.android.AndroidSqliteDriver
@Module
@InstallIn(SingletonComponent::class)
internal object DatabaseModule {
@Provides
@Singleton
fun providesNiaDatabase(
@ApplicationContext context: Context,
): NiaDatabase = Room.databaseBuilder(
context,
NiaDatabase::class.java,
"nia-database",
).build()
actual class DriverFactory(private val context: Context) {
actual suspend fun provideDbDriver(
schema: SqlSchema<QueryResult.AsyncValue<Unit>>,
): SqlDriver {
return AndroidSqliteDriver(schema.synchronous(), context, "nia-database.db")
}
}

@ -21,13 +21,10 @@ import com.google.samples.apps.nowinandroid.core.database.dao.NewsResourceFtsDao
import com.google.samples.apps.nowinandroid.core.database.dao.RecentSearchQueryDao
import com.google.samples.apps.nowinandroid.core.database.dao.TopicDao
import com.google.samples.apps.nowinandroid.core.database.dao.TopicFtsDao
import dagger.Module
import dagger.Provides
import dagger.hilt.InstallIn
import dagger.hilt.components.SingletonComponent
import me.tatarka.inject.annotations.Component
import me.tatarka.inject.annotations.Provides
@Module
@InstallIn(SingletonComponent::class)
@Component
internal object DaosModule {
@Provides
fun providesTopicsDao(

@ -1,63 +0,0 @@
/*
* Copyright 2022 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.google.samples.apps.nowinandroid.core.database
import androidx.room.DeleteColumn
import androidx.room.DeleteTable
import androidx.room.RenameColumn
import androidx.room.migration.AutoMigrationSpec
/**
* Automatic schema migrations sometimes require extra instructions to perform the migration, for
* example, when a column is renamed. These extra instructions are placed here by creating a class
* using the following naming convention `SchemaXtoY` where X is the schema version you're migrating
* from and Y is the schema version you're migrating to. The class should implement
* `AutoMigrationSpec`.
*/
internal object DatabaseMigrations {
@RenameColumn(
tableName = "topics",
fromColumnName = "description",
toColumnName = "shortDescription",
)
class Schema2to3 : AutoMigrationSpec
@DeleteColumn(
tableName = "news_resources",
columnName = "episode_id",
)
@DeleteTable.Entries(
DeleteTable(
tableName = "episodes_authors",
),
DeleteTable(
tableName = "episodes",
),
)
class Schema10to11 : AutoMigrationSpec
@DeleteTable.Entries(
DeleteTable(
tableName = "news_resources_authors",
),
DeleteTable(
tableName = "authors",
),
)
class Schema11to12 : AutoMigrationSpec
}

@ -0,0 +1,27 @@
/*
* Copyright 2024 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.google.samples.apps.nowinandroid.core.database
import app.cash.sqldelight.db.QueryResult
import app.cash.sqldelight.db.SqlDriver
import app.cash.sqldelight.db.SqlSchema
expect class DriverFactory {
suspend fun provideDbDriver(
schema: SqlSchema<QueryResult.AsyncValue<Unit>>,
): SqlDriver
}

@ -16,53 +16,12 @@
package com.google.samples.apps.nowinandroid.core.database
import androidx.room.AutoMigration
import androidx.room.Database
import androidx.room.RoomDatabase
import androidx.room.TypeConverters
import com.google.samples.apps.nowinandroid.core.database.dao.NewsResourceDao
import com.google.samples.apps.nowinandroid.core.database.dao.NewsResourceFtsDao
import com.google.samples.apps.nowinandroid.core.database.dao.RecentSearchQueryDao
import com.google.samples.apps.nowinandroid.core.database.dao.TopicDao
import com.google.samples.apps.nowinandroid.core.database.dao.TopicFtsDao
import com.google.samples.apps.nowinandroid.core.database.model.NewsResourceEntity
import com.google.samples.apps.nowinandroid.core.database.model.NewsResourceFtsEntity
import com.google.samples.apps.nowinandroid.core.database.model.NewsResourceTopicCrossRef
import com.google.samples.apps.nowinandroid.core.database.model.RecentSearchQueryEntity
import com.google.samples.apps.nowinandroid.core.database.model.TopicEntity
import com.google.samples.apps.nowinandroid.core.database.model.TopicFtsEntity
import com.google.samples.apps.nowinandroid.core.database.util.InstantConverter
@Database(
entities = [
NewsResourceEntity::class,
NewsResourceTopicCrossRef::class,
NewsResourceFtsEntity::class,
TopicEntity::class,
TopicFtsEntity::class,
RecentSearchQueryEntity::class,
],
version = 14,
autoMigrations = [
AutoMigration(from = 1, to = 2),
AutoMigration(from = 2, to = 3, spec = DatabaseMigrations.Schema2to3::class),
AutoMigration(from = 3, to = 4),
AutoMigration(from = 4, to = 5),
AutoMigration(from = 5, to = 6),
AutoMigration(from = 6, to = 7),
AutoMigration(from = 7, to = 8),
AutoMigration(from = 8, to = 9),
AutoMigration(from = 9, to = 10),
AutoMigration(from = 10, to = 11, spec = DatabaseMigrations.Schema10to11::class),
AutoMigration(from = 11, to = 12, spec = DatabaseMigrations.Schema11to12::class),
AutoMigration(from = 12, to = 13),
AutoMigration(from = 13, to = 14),
],
exportSchema = true,
)
@TypeConverters(
InstantConverter::class,
)
internal abstract class NiaDatabase : RoomDatabase() {
abstract fun topicDao(): TopicDao
abstract fun newsResourceDao(): NewsResourceDao

@ -0,0 +1,35 @@
/*
* Copyright 2024 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.google.samples.apps.nowinandroid.core.database
import app.cash.sqldelight.db.QueryResult
import app.cash.sqldelight.db.SqlDriver
import app.cash.sqldelight.db.SqlSchema
import app.cash.sqldelight.driver.worker.WebWorkerDriver
import org.w3c.dom.Worker
actual class DriverFactory {
actual suspend fun provideDbDriver(
schema: SqlSchema<QueryResult.AsyncValue<Unit>>,
): SqlDriver {
return WebWorkerDriver(
Worker(
js("""new URL("@cashapp/sqldelight-sqljs-worker/sqljs.worker.js", import.meta.url)"""),
),
).also { schema.create(it).await() }
}
}

@ -0,0 +1,31 @@
/*
* Copyright 2024 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.google.samples.apps.nowinandroid.core.database
import app.cash.sqldelight.db.QueryResult
import app.cash.sqldelight.db.SqlDriver
import app.cash.sqldelight.db.SqlSchema
import app.cash.sqldelight.driver.jdbc.sqlite.JdbcSqliteDriver
actual class DriverFactory {
actual suspend fun provideDbDriver(
schema: SqlSchema<QueryResult.AsyncValue<Unit>>,
): SqlDriver {
return JdbcSqliteDriver(JdbcSqliteDriver.IN_MEMORY)
.also { schema.create(it).await() }
}
}

@ -0,0 +1,31 @@
/*
* Copyright 2024 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.google.samples.apps.nowinandroid.core.database
import app.cash.sqldelight.async.coroutines.synchronous
import app.cash.sqldelight.db.QueryResult
import app.cash.sqldelight.db.SqlDriver
import app.cash.sqldelight.db.SqlSchema
import app.cash.sqldelight.driver.native.NativeSqliteDriver
actual class DriverFactory {
actual suspend fun provideDbDriver(
schema: SqlSchema<QueryResult.AsyncValue<Unit>>,
): SqlDriver {
return NativeSqliteDriver(schema.synchronous(), "nia-database.db")
}
}

@ -71,6 +71,7 @@ compose = "1.6.0"
compose-plugin = "1.6.0-alpha01"
junit = "4.13.2"
sqldelight = "2.0.1"
kotlinInject = '0.6.3'
[libraries]
accompanist-permissions = { group = "com.google.accompanist", name = "accompanist-permissions", version.ref = "accompanist" }
@ -160,6 +161,11 @@ compose-ui-tooling-preview = { module = "androidx.compose.ui:ui-tooling-preview"
sqldelight-android-driver = { group = "app.cash.sqldelight", name = "android-driver", version.ref = "sqldelight" }
sqldelight-native-driver = { group = "app.cash.sqldelight", name = "native-driver", version.ref = "sqldelight" }
sqldelight-sqlite-driver = { group = "app.cash.sqldelight", name = "sqlite-driver", version.ref = "sqldelight" }
sqldelight-sqljs-driver = { group = "app.cash.sqldelight", name = "sqljs-driver", version.ref = "sqldelight" }
sqldelight-webworker-driver = { group = "app.cash.sqldelight", name = "web-worker-driver", version.ref = "sqldelight" }
sqldelight-coroutines-extensions = { group = "app.cash.sqldelight", name = "coroutines-extensions", version.ref = "sqldelight" }
kotlinInject-compiler = { module = 'me.tatarka.inject:kotlin-inject-compiler-ksp', version.ref = 'kotlinInject' }
kotlinInject-runtime = { module = 'me.tatarka.inject:kotlin-inject-runtime', version.ref = 'kotlinInject' }
# Dependencies of the included build-logic
android-gradlePlugin = { group = "com.android.tools.build", name = "gradle", version.ref = "androidGradlePlugin" }

Loading…
Cancel
Save