icerockdev / moko-template

Template project of a Mobile (Android & iOS) Kotlin MultiPlatform project with the MOKO libraries and modularized architecture
https://moko.icerock.dev/
Apache License 2.0
461 stars 47 forks source link

Adding SQLDelight to the project #19

Closed Jaime97 closed 3 years ago

Jaime97 commented 4 years ago

I would like to ask a question, if you can help me with it: I'm trying to add SQLDelight to the project. In its doc page it is said to add these dependencies:

kotlin {
  // The drivers needed will change depending on what platforms you target:

  sourceSets.androidMain.dependencies {
    implementation "com.squareup.sqldelight:android-driver:1.4.3"
  }

  // or sourceSets.iosMain, sourceSets.windowsMain, etc.
  sourceSets.nativeMain.dependencies {
    implementation "com.squareup.sqldelight:native-driver:1.4.3"
  }

  sourceSets.jvmMain.dependencies {
    implementation "com.squareup.sqldelight:sqlite-driver:1.4.3"
  }
}

So, in which part of the template should this be added? I have failed to find specific sourceSet for native, to tell the truth.

Thanks

rhonyabdullah commented 4 years ago

Firstly you have to add this line, for more details see here

kotlin {
    val onPhone = System.getenv("SDK_NAME")?.startsWith("iphoneos") ?: false
    if (onPhone) iosArm64("ios")
    else iosX64("ios")

//optional if you want to mark sqldelight as resource folder
    sourceSets {
        val commonMain by getting {
            resources.srcDir("src/commonMain/sqldelight")
        }
    }
}

then you can add those the dependencies using mppLibrary command

object Versions {
  const val sqlDelight = "1.4.4"
}
val sqlDelight = MultiPlatformLibrary(
                common = "com.squareup.sqldelight:runtime:${Versions.sqlDelight}",
                android = "com.squareup.sqldelight:android-driver:${Versions.sqlDelight}",
                ios = "com.squareup.sqldelight:native-driver:${Versions.sqlDelight}"
            )
dependencies {
     mppLibrary(sqlDelight)
    ///actual NativeSqliteDriver somehow not found on iosMain package because this template is using their own plugin @see https://github.com/icerockdev/mobile-multiplatform-gradle-plugin , workaround
   iosMainApi("com.squareup.sqldelight:native-driver:${Versions.sqlDelight}")
}

\ If you now using Xcode 12, after fixing that issue above, you will land into another issue of this library on here

Currently i don't have any idea, just waiting their fix versions.

Jaime97 commented 3 years ago

@rhonyabdullah Thanks, could you please tell me where in the template should I add this lines of code? There's a large number of build.gradle.kts files in the project and I don't really know where should I do it.

rhonyabdullah commented 3 years ago

It depends on your kmm library, but if you use sql delight on domain module, you can put that code inside domain build.gradle

Jaime97 commented 3 years ago

@rhonyabdullah I've done it in the domain module but I keep getting problems: In SqlDelight they say we should load the native driver in path src/nativeMain/kotlin:

// in src/nativeMain/kotlin
actual class DriverFactory {
  actual fun createDriver(): SqlDriver {
    return NativeSqliteDriver(Database.Schema, "test.db")
  }
}

Where is that path in this template? I'm failing to find where should I instantiate this Driver for native, so I can't check if the dependency is working. Could you help me with this?

Jaime97 commented 3 years ago

@rhonyabdullah Here's how I've done it: This is my current domain structure: screenshot_domain

And here's my domain gradle.kts:

/*
 * Copyright 2019 IceRock MAG Inc. Use of this source code is governed by the Apache 2.0 license.
 */

plugins {
    plugin(Deps.Plugins.androidLibrary)
    plugin(Deps.Plugins.kotlinMultiplatform)
    plugin(Deps.Plugins.kotlinAndroidExtensions)
    plugin(Deps.Plugins.kotlinSerialization)
    plugin(Deps.Plugins.mobileMultiplatform)
    plugin(Deps.Plugins.mokoNetwork)
    plugin(Deps.Plugins.sqlDelight)
}

object Versions {
    const val sqlDelight = "1.4.4"
}
val sqlDelight = MultiPlatformLibrary(
    common = "com.squareup.sqldelight:runtime:${Versions.sqlDelight}",
    android = "com.squareup.sqldelight:android-driver:${Versions.sqlDelight}",
    ios = "com.squareup.sqldelight:native-driver:${Versions.sqlDelight}"
)

dependencies {
    mppLibrary(sqlDelight)
    ///actual NativeSqliteDriver somehow not found on iosMain package because this template is using their own plugin @see https://github.com/icerockdev/mobile-multiplatform-gradle-plugin , workaround
    iosMainApi("com.squareup.sqldelight:native-driver:${Versions.sqlDelight}")
    commonMainImplementation(Deps.Libs.MultiPlatform.coroutines)
    commonMainImplementation(Deps.Libs.MultiPlatform.kotlinSerialization)
    commonMainImplementation(Deps.Libs.MultiPlatform.ktorClient)
    commonMainImplementation(Deps.Libs.MultiPlatform.ktorClientLogging)
    commonMainImplementation(Deps.Libs.MultiPlatform.mokoParcelize.common)
    commonMainImplementation(Deps.Libs.MultiPlatform.mokoNetwork.common)
    commonMainImplementation(Deps.Libs.MultiPlatform.napier.common)
    commonMainImplementation(Deps.Libs.MultiPlatform.multiplatformSettings.common)
}

sqldelight {
    database("FilmSqlDatabase") {
        packageName = "com.jaa.library.domain.dataSource.storage"
    }
    linkSqlite = false
}

kotlin {
    val onPhone = System.getenv("SDK_NAME")?.startsWith("iphoneos") ?: false
    if (onPhone) iosArm64("ios")
    else iosX64("ios")

//optional if you want to mark sqldelight as resource folder
    sourceSets {
        val commonMain by getting {
            resources.srcDir("src/commonMain/sqldelight")
        }
    }
}

openApiGenerate {
    inputSpec.set(file("src/openapi.yml").path)
    generatorName.set("kotlin-ktor-client")
    additionalProperties.set(mutableMapOf("nonPublicApi" to "false"))
}

But anyway the classes NativeSqliteDriver and SqlDriver are not recognized inside the actual definion of the DriverFactory, in iosMain. Is this the way you were talking about or it is something wrong?

rhonyabdullah commented 3 years ago

Did you have adding sql delight plugin on root build.gradle ? plugin(Deps.Plugins.sqlDelight)

rhonyabdullah commented 3 years ago

Error honestly, my build is successfully, but i got this error on common modul, @Alex009 may can help

Jaime97 commented 3 years ago

@rhonyabdullah I didn't but I have done it now and I have the same problem as you.

rhonyabdullah commented 3 years ago

@rhonyabdullah I didn't but I have done it now and I have the same problem as you.

Now if you have the same issue with iosArm64Main this is going to be this template scope i think, so i probably you also need some help from this template creator.

Jaime97 commented 3 years ago

@Alex009 if you (or someone in your team) could give us a hand with this, I'm in a hurry so I would appreciate it

Alex009 commented 3 years ago

@Jaime97 i will setup sample on this week with configured sqldelight in moko-template

Alex009 commented 3 years ago

@Jaime97 @rhonyabdullah here you can see how configure sqldelight with moko-template https://github.com/icerockdev/moko-template/commit/ccc530b9bbded174b2bdb992375ad5062862819b i use this docs for setup - https://kotlinlang.org/docs/mobile/configure-sqldelight-for-data-storage.html

rhonyabdullah commented 3 years ago

@Jaime97 @rhonyabdullah here you can see how configure sqldelight with moko-template ccc530b i use this docs for setup - https://kotlinlang.org/docs/mobile/configure-sqldelight-for-data-storage.html

I see, i'm just checking out to sqldelight branch and found that you create DatabaseDriverFactory class into each ios folder (x64 and arm64)

So, can you confirm that each time we need an ios platform specific the related classes should be created on both x64 and arm64 folder ? Any workaround about how to just put the ios actual class intoiosMain only ?

Alex009 commented 3 years ago

@Jaime97 @rhonyabdullah here you can see how configure sqldelight with moko-template

ccc530b

i use this docs for setup - https://kotlinlang.org/docs/mobile/configure-sqldelight-for-data-storage.html

I see, i'm just checking out to sqldelight branch and found that you create DatabaseDriverFactory class into each ios folder (x64 and arm64)

So, can you confirm that each time we need an ios platform specific the related classes should be created on both x64 and arm64 folder ? Any workaround about how to just put the ios actual class intoiosMain only ?

iosArm64Main is symbolic link to iosX64Main. It is workaround because sqldelight not provide iosMain metadata artifact. You will change only sources in iosX64Main - arm will use same code by symlink

Jaime97 commented 3 years ago

Ok, I have applied it to my project and it has (finally!!!) worked. Thanks to both of you for helping me with this, I'll leave the issue open just in case you want to add something, but feel free to close it now =)