Skip to content
Open
Show file tree
Hide file tree
Changes from 6 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions build-logic/convention/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ dependencies {
compileOnly(libs.spotless.gradle)
implementation(libs.truth)
compileOnly(libs.androidx.room.gradle.plugin)
compileOnly(libs.sqldelight.gradlePlugin)
compileOnly(libs.firebase.crashlytics.gradlePlugin)
compileOnly(libs.firebase.performance.gradlePlugin)
}
Expand Down Expand Up @@ -125,5 +126,10 @@ gradlePlugin {
description = "Configures Room for the project"
}

register("KMPSQLDelight") {
id = "mifos.kmp.sqldelight"
implementationClass = "KMPSQLDelightConventionPlugin"
description = "Configures SQLDelight for the project"
}
}
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@

import com.android.build.gradle.LibraryExtension
import org.convention.configureFlavors
import org.convention.configureKotlinAndroid
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
import app.cash.sqldelight.gradle.SqlDelightExtension
import org.convention.libs
import org.gradle.api.Plugin
import org.gradle.api.Project
import org.gradle.internal.Actions.with
import org.gradle.kotlin.dsl.configure
import org.gradle.kotlin.dsl.dependencies


private const val DATABASE_NAME = "MifosSQLDelightDatabase"

class KMPSQLDelightConventionPlugin : Plugin<Project> {
override fun apply(target: Project) {
with(target) {
pluginManager.apply("app.cash.sqldelight")

extensions.configure<SqlDelightExtension> {
databases.create(DATABASE_NAME) {
packageName.set("org.mifos.core.database")
generateAsync.set(true)
schemaOutputDirectory.set(
file("$projectDir/schemas")
)
verifyMigrations.set(true)
}
Comment thread
coderabbitai[bot] marked this conversation as resolved.
}


dependencies {
add("androidMainImplementation",libs.findLibrary("sqldelight.android.driver").get())
add("nativeMainImplementation",libs.findLibrary("sqldelight.native.driver").get())
add("desktopMainImplementation",libs.findLibrary("sqldelight.sqlite.driver").get())
add("jsMainImplementation",libs.findLibrary("sqldelight.web.worker.driver").get())
add("wasmJsMainImplementation",libs.findLibrary("sqldelight.web.worker.driver").get())

add("commonMainImplementation", libs.findLibrary("sqldelight.coroutines").get())
add("commonMainImplementation", libs.findLibrary("sqldelight.primitive.adapters").get())
}

}

}
}
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,8 @@ internal fun Project.configureKotlinMultiplatform() {
iosX64()
iosArm64()
js(IR) {
this.nodejs()
browser()
nodejs()
binaries.executable()
}
wasmJs() {
Expand Down
1 change: 1 addition & 0 deletions build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ plugins {
alias(libs.plugins.ktrofit) apply false

alias(libs.plugins.room) apply false
alias(libs.plugins.sqldelight) apply false
}

object DynamicVersion {
Expand Down
2 changes: 1 addition & 1 deletion cmp-shared/cmp_shared.podspec
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
Pod::Spec.new do |spec|
spec.name = 'cmp_shared'
spec.version = '2026.2.4'
spec.version = '2026.3.2'
spec.homepage = 'https://github.com/openMF/kmp-project-template'
spec.source = { :http=> ''}
spec.authors = ''
Expand Down
20 changes: 20 additions & 0 deletions cmp-web/karma.config.d/sqljs.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
const path = require("path");
const CopyWebpackPlugin = require("copy-webpack-plugin");

config.set({
webpack: {
plugins: [
new CopyWebpackPlugin({
patterns: [
{
from: path.resolve(
__dirname,
"../node_modules/sql.js/dist/sql-wasm.wasm"
),
to: path.resolve(__dirname, "../kotlin/"),
},
],
}),
],
},
});
16 changes: 16 additions & 0 deletions cmp-web/webpack.config.d/sqljs.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
const path = require("path");
const CopyWebpackPlugin = require("copy-webpack-plugin");

config.plugins.push(
new CopyWebpackPlugin({
patterns: [
{
from: path.resolve(
__dirname,
"node_modules/sql.js/dist/sql-wasm.wasm"
),
to: path.resolve(__dirname, "kotlin/"),
},
],
})
);
3 changes: 2 additions & 1 deletion core-base/database/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
*
* See https://github.com/openMF/kmp-project-template/blob/main/LICENSE
*/
import org.gradle.declarative.dsl.schema.FqName.Empty.packageName
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

remove the changes from this file

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

import org.jetbrains.compose.compose

/*
Expand All @@ -28,6 +29,7 @@ android {

kotlin {
sourceSets {

androidMain.dependencies {
implementation(libs.androidx.room.runtime)
}
Expand All @@ -39,7 +41,6 @@ kotlin {
nativeMain.dependencies {
implementation(libs.androidx.room.runtime)
}

nonJsCommonMain.dependencies {
implementation(libs.androidx.room.runtime)
}
Expand Down
70 changes: 69 additions & 1 deletion core/database/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -1,3 +1,14 @@
/*
* Copyright 2026 Mifos Initiative
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*
* See https://github.com/openMF/kmp-project-template/blob/main/LICENSE
*/
import org.gradle.kotlin.dsl.invoke

/*
* Copyright 2025 Mifos Initiative
*
Expand All @@ -12,35 +23,92 @@ plugins {
alias(libs.plugins.kotlin.serialization)
alias(libs.plugins.kotlin.parcelize)
alias(libs.plugins.mifos.kmp.room)
alias(libs.plugins.mifos.kmp.sqldelight)
}

android {
namespace = "org.mifos.core.database"
}

fun isInstalled(binary: String) = try {
Runtime.getRuntime().exec(arrayOf("which", binary)).waitFor() == 0
} catch (e: Exception) {
false
}

kotlin {
js(IR) {
browser {
testTask {
useKarma {
when {
isInstalled("brave") || isInstalled("brave-browser") -> useChrome()
isInstalled("firefox") -> useFirefox()
else -> useChrome()
}
}
if (isInstalled("brave") && !isInstalled("google-chrome")) {
environment("CHROME_BIN", "brave")
}
Comment thread
coderabbitai[bot] marked this conversation as resolved.
}
}
}
wasmJs {
browser {
testTask {
useKarma {
when {
isInstalled("brave") || isInstalled("brave-browser") -> useChrome()
isInstalled("firefox") -> useFirefox()
else -> useChrome()
}
}
if (isInstalled("brave") && !isInstalled("google-chrome")) {
environment("CHROME_BIN", "brave")
}
}
}
}
sourceSets {
val desktopMain by getting
androidMain.dependencies {
implementation(libs.koin.android)
implementation(libs.androidx.room.runtime)
implementation(libs.sqldelight.runtime)
}
androidUnitTest.dependencies {
implementation(libs.androidx.core)
implementation(libs.sqldelight.sqlite.driver)
implementation(libs.robolectric)
implementation(libs.androidx.test.ext.junit)
}

nativeMain.dependencies {
implementation(libs.androidx.room.runtime)
implementation(libs.androidx.sqlite.bundled)
implementation(libs.sqldelight.runtime)
}

desktopMain.dependencies {
implementation(libs.androidx.room.runtime)
implementation(libs.androidx.sqlite.bundled)
}
implementation(libs.sqldelight.runtime)

}
jsCommonMain.dependencies {
implementation(libs.sqldelight.runtime)
implementation(npm("@cashapp/sqldelight-sqljs-worker", "2.2.1"))
implementation(npm("sql.js", "1.10.3"))
implementation(devNpm("copy-webpack-plugin", "12.0.2"))
}
Comment thread
TheKalpeshPawar marked this conversation as resolved.
Outdated
commonMain.dependencies {
implementation(libs.kotlinx.coroutines.core)
implementation(libs.kotlinx.serialization.json)
api(projects.core.common)
api(projects.coreBase.database)
}
commonTest.dependencies {
implementation(libs.turbine)
}
}
}
30 changes: 30 additions & 0 deletions core/database/karma.config.d/sqljs-config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
const path = require("path");
const os = require("os");
const dist = path.resolve("../../node_modules/sql.js/dist/")
const wasm = path.join(dist, "sql-wasm.wasm")

config.files.push({
pattern: wasm,
served: true,
watched: false,
included: false,
nocache: false,
});

config.proxies["/sql-wasm.wasm"] = `/absolute${wasm}`

Comment thread
TheKalpeshPawar marked this conversation as resolved.
Outdated
// Adapted from: https://github.com/ryanclark/karma-webpack/issues/498#issuecomment-790040818
const output = {
path: path.join(os.tmpdir(), '_karma_webpack_') + Math.floor(Math.random() * 1000000),
}
config.set({
webpack: {...config.webpack, output}
});
config.files.push({
pattern: `${output.path}/**/*`,
watched: false,
included: false,
});

// TODO: Figure out why on earth this is necessary. Presumably a karma-webpack bug???
delete config.webpack.optimization;
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
/*
* Copyright 2026 Mifos Initiative
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*
* See See https://github.com/openMF/kmp-project-template/blob/main/LICENSE
*/
package org.mifos.core.database.di

import app.cash.sqldelight.async.coroutines.synchronous
import app.cash.sqldelight.db.SqlDriver
import app.cash.sqldelight.driver.android.AndroidSqliteDriver
import org.koin.dsl.module
import org.mifos.core.database.MifosSQLDelightDatabase

actual val driverModule: org.koin.core.module.Module = module {
single<SqlDriver> {
AndroidSqliteDriver(
MifosSQLDelightDatabase.Schema.synchronous(),
get(),
DB_FILE_NAME,
)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
/*
* Copyright 2026 Mifos Initiative
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*
* See See https://github.com/openMF/kmp-project-template/blob/main/LICENSE
*/
package org.mifos.core.database

import android.content.Context
import androidx.test.core.app.ApplicationProvider
import androidx.test.ext.junit.runners.AndroidJUnit4
import org.junit.runner.RunWith
import org.koin.android.ext.koin.androidContext
import org.koin.core.context.startKoin
import org.mifos.core.database.di.TestSQLDelightModule
import kotlin.test.AfterTest
import kotlin.test.BeforeTest

@RunWith(AndroidJUnit4::class)
class SQLDelightRepositoryAndroidTest : SQLDelightRepositoryTest() {

@BeforeTest
override fun setup() {
val context = ApplicationProvider.getApplicationContext<Context>()
koinApp = startKoin {
androidContext(context)
modules(TestSQLDelightModule)
}
repository = koinApp!!.koin.get()
}

@AfterTest
override fun teardown() {
super.teardown()
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,9 @@ package org.mifos.core.database.di
import android.content.Context
import androidx.room.Room
import androidx.test.core.app.ApplicationProvider
import kotlinx.coroutines.CoroutineDispatcher
import kotlinx.coroutines.Dispatchers
import org.koin.core.module.Module
import org.koin.core.qualifier.named
import org.koin.dsl.module
import org.mifos.core.common.di.AppDispatchers
import org.mifos.core.database.AppDatabase
import kotlin.coroutines.CoroutineContext

Expand All @@ -27,7 +25,7 @@ actual val testPlatformModule: Module = module {
context = context,
AppDatabase::class.java,
)
.setQueryCoroutineContext(get<CoroutineDispatcher>(named(AppDispatchers.IO.name)) as CoroutineContext)
.setQueryCoroutineContext(Dispatchers.IO as CoroutineContext)
.build()
}
}
Loading