Skip to content
Open
Show file tree
Hide file tree
Changes from all 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
9 changes: 7 additions & 2 deletions data/persistence/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ plugins {

kaliumLibrary {
multiplatform {
enableJsTests.set(false)
enableJsTests.set(true)
}
}

Expand All @@ -36,6 +36,7 @@ sqldelight {
create("UserDatabase") {
dialect(libs.sqldelight.dialect.get().toString())
packageName.set("com.wire.kalium.persistence")
generateAsync.set(true)
val sourceFolderName = "db_user"
srcDirs.setFrom(listOf("src/commonMain/$sourceFolderName"))
schemaOutputDirectory.set(file("src/commonMain/$sourceFolderName/schemas"))
Expand All @@ -45,6 +46,7 @@ sqldelight {
create("GlobalDatabase") {
dialect(libs.sqldelight.dialect.get().toString())
packageName.set("com.wire.kalium.persistence")
generateAsync.set(true)
val sourceFolderName = "db_global"
srcDirs.setFrom(listOf("src/commonMain/$sourceFolderName"))
schemaOutputDirectory.set(file("src/commonMain/$sourceFolderName/schemas"))
Expand All @@ -63,6 +65,7 @@ kotlin {

implementation(libs.sqldelight.runtime)
implementation(libs.sqldelight.coroutinesExtension)
implementation(libs.sqldelight.async)
implementation(libs.sqldelight.primitiveAdapters)
implementation(libs.ktxSerialization)
implementation(libs.settings.kmp)
Expand Down Expand Up @@ -97,7 +100,9 @@ kotlin {
val jsMain by getting {
dependencies {
implementation(libs.sqldelight.jsDriver)
implementation(npm("sql.js", "1.6.2"))
implementation(npm("@cashapp/sqldelight-sqljs-worker", libs.versions.sqldelightSqljsWorker.get()))
implementation(npm("sql.js", "1.8.0"))
implementation(devNpm("webpack", "^5.1.0"))
implementation(devNpm("copy-webpack-plugin", "9.1.0"))
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
/*
* Wire
* Copyright (C) 2026 Wire Swiss GmbH
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see http://www.gnu.org/licenses/.
*/

package com.wire.kalium.persistence.utils

actual annotation class IgnoreJS
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
/*
* Wire
* Copyright (C) 2026 Wire Swiss GmbH
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see http://www.gnu.org/licenses/.
*/

package com.wire.kalium.persistence.utils

actual annotation class IgnoreJS
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
/*
* Wire
* Copyright (C) 2026 Wire Swiss GmbH
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see http://www.gnu.org/licenses/.
*/

package com.wire.kalium.persistence.db

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 kotlin.coroutines.cancellation.CancellationException

@Suppress("TooGenericExceptionCaught")
actual suspend fun SqlDriver.migrate(sqlSchema: SqlSchema<QueryResult.AsyncValue<Unit>>): Boolean {
val oldVersion = executeQuery(null, "PRAGMA user_version;", {
it.next().value
QueryResult.Value(it.getLong(0))
}, 0).value ?: return false

val newVersion = sqlSchema.version
return try {
if (oldVersion != newVersion) {
sqlSchema.synchronous().migrate(this, oldVersion, newVersion).value
}
true
} catch (exception: CancellationException) {
throw exception
} catch (_: Exception) {
false
}
}

actual suspend fun SqlDriver.checkFKViolations(): Boolean =
executeQuery(null, "PRAGMA foreign_key_check;", {
QueryResult.Value(it.next().value)
}, 0).value
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@

package com.wire.kalium.persistence.db

import app.cash.sqldelight.async.coroutines.synchronous
import com.wire.kalium.persistence.GlobalDatabase
import com.wire.kalium.persistence.util.FileNameUtil
import kotlinx.coroutines.CoroutineDispatcher
Expand All @@ -28,7 +29,7 @@ actual fun globalDatabaseProvider(
passphrase: GlobalDatabaseSecret?,
enableWAL: Boolean
): GlobalDatabaseBuilder {
val schema = GlobalDatabase.Schema
val schema = GlobalDatabase.Schema.synchronous()
val dbName = FileNameUtil.globalDBName()
val driver = databaseDriver(
platformDatabaseData.context,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ package com.wire.kalium.persistence.db

import android.content.Context
import androidx.sqlite.db.SupportSQLiteDatabase
import app.cash.sqldelight.async.coroutines.synchronous
import app.cash.sqldelight.db.SqlDriver
import app.cash.sqldelight.driver.android.AndroidSqliteDriver
import com.wire.kalium.persistence.UserDatabase
Expand Down Expand Up @@ -49,7 +50,7 @@ actual fun userDatabaseBuilder(
context = platformDatabaseData.context,
dbName = dbName,
passphrase = passphrase?.value,
schema = UserDatabase.Schema
schema = UserDatabase.Schema.synchronous()
) {
isWALEnabled = enableWAL
}
Expand Down Expand Up @@ -99,7 +100,7 @@ fun inMemoryDatabase(
val passphrase = "testPass".toByteArray()
System.loadLibrary("sqlcipher")
val rawDriver = AndroidSqliteDriver(
schema = UserDatabase.Schema,
schema = UserDatabase.Schema.synchronous(),
context = context,
name = null,
factory = SupportOpenHelperFactory(passphrase)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
/*
* Wire
* Copyright (C) 2026 Wire Swiss GmbH
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see http://www.gnu.org/licenses/.
*/

package com.wire.kalium.persistence.db

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 kotlin.coroutines.cancellation.CancellationException

@Suppress("TooGenericExceptionCaught")
actual suspend fun SqlDriver.migrate(sqlSchema: SqlSchema<QueryResult.AsyncValue<Unit>>): Boolean {
val oldVersion = executeQuery(null, "PRAGMA user_version;", {
it.next().value
QueryResult.Value(it.getLong(0))
}, 0).value ?: return false

val newVersion = sqlSchema.version
return try {
if (oldVersion != newVersion) {
sqlSchema.synchronous().migrate(this, oldVersion, newVersion).value
}
true
} catch (exception: CancellationException) {
throw exception
} catch (_: Exception) {
false
}
}

actual suspend fun SqlDriver.checkFKViolations(): Boolean =
executeQuery(null, "PRAGMA foreign_key_check;", {
QueryResult.Value(it.next().value)
}, 0).value
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@

package com.wire.kalium.persistence.db

import app.cash.sqldelight.async.coroutines.synchronous
import com.wire.kalium.persistence.GlobalDatabase
import com.wire.kalium.persistence.util.FileNameUtil
import kotlinx.coroutines.CoroutineDispatcher
Expand All @@ -32,15 +33,15 @@ actual fun globalDatabaseProvider(
val driver = when (val data = platformDatabaseData.storageData) {
is StorageData.FileBacked -> {
NSFileManager.defaultManager.createDirectoryAtPath(data.storePath, true, null, null)
val schema = GlobalDatabase.Schema
val schema = GlobalDatabase.Schema.synchronous()
databaseDriver(data.storePath, FileNameUtil.globalDBName(), schema) {
isWALEnabled = false
useGradleSafeSqliterLogging = platformDatabaseData.useGradleSafeSqliterLogging
}
}

StorageData.InMemory ->
databaseDriver(null, FileNameUtil.globalDBName(), GlobalDatabase.Schema) {
databaseDriver(null, FileNameUtil.globalDBName(), GlobalDatabase.Schema.synchronous()) {
isWALEnabled = false
useGradleSafeSqliterLogging = platformDatabaseData.useGradleSafeSqliterLogging
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@

package com.wire.kalium.persistence.db

import app.cash.sqldelight.async.coroutines.synchronous
import app.cash.sqldelight.db.SqlDriver
import app.cash.sqldelight.driver.native.NativeSqliteDriver
import com.wire.kalium.persistence.UserDatabase
Expand All @@ -46,14 +47,14 @@ actual fun userDatabaseBuilder(
null,
null
)
databaseDriver(platformDatabaseData.storageData.storePath, FileNameUtil.userDBName(userId), UserDatabase.Schema) {
databaseDriver(platformDatabaseData.storageData.storePath, FileNameUtil.userDBName(userId), UserDatabase.Schema.synchronous()) {
isWALEnabled = enableWAL
useGradleSafeSqliterLogging = platformDatabaseData.useGradleSafeSqliterLogging
}
}

StorageData.InMemory ->
databaseDriver(null, FileNameUtil.userDBName(userId), UserDatabase.Schema) {
databaseDriver(null, FileNameUtil.userDBName(userId), UserDatabase.Schema.synchronous()) {
isWALEnabled = false
useGradleSafeSqliterLogging = platformDatabaseData.useGradleSafeSqliterLogging
}
Expand Down Expand Up @@ -86,7 +87,7 @@ actual fun userDatabaseDriverByPath(
enableWAL: Boolean
): SqlDriver {
return NativeSqliteDriver(
UserDatabase.Schema,
UserDatabase.Schema.synchronous(),
path
)
}
Expand All @@ -103,7 +104,7 @@ fun inMemoryDatabase(
userId: UserIDEntity,
dispatcher: CoroutineDispatcher
): UserDatabaseBuilder = InMemoryDatabaseCache.getOrCreate(userId) {
val rawDriver = databaseDriver(null, FileNameUtil.userDBName(userId), UserDatabase.Schema) {
val rawDriver = databaseDriver(null, FileNameUtil.userDBName(userId), UserDatabase.Schema.synchronous()) {
isWALEnabled = false
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
/*
* Wire
* Copyright (C) 2026 Wire Swiss GmbH
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see http://www.gnu.org/licenses/.
*/

package com.wire.kalium.persistence.utils

actual annotation class IgnoreJS
2 changes: 1 addition & 1 deletion data/persistence/src/commonMain/db_user/migrations/1.sqm
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
DROP VIEW ConversatonDetails;
DROP VIEW IF EXISTS ConversatonDetails;
CREATE VIEW IF NOT EXISTS ConversationDetails AS
SELECT
Conversation.qualified_id AS qualifiedId,
Expand Down
4 changes: 2 additions & 2 deletions data/persistence/src/commonMain/db_user/migrations/10.sqm
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
DROP VIEW MessageDetailsView;
DROP VIEW ConversationDetails;
DROP VIEW IF EXISTS MessageDetailsView;
DROP VIEW IF EXISTS ConversationDetails;

CREATE VIEW IF NOT EXISTS MessageDetailsView
AS SELECT
Expand Down
4 changes: 2 additions & 2 deletions data/persistence/src/commonMain/db_user/migrations/11.sqm
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
DROP VIEW MessageDetailsView;
DROP VIEW ConversationDetails;
DROP VIEW IF EXISTS MessageDetailsView;
DROP VIEW IF EXISTS ConversationDetails;

CREATE VIEW IF NOT EXISTS MessageDetailsView
AS SELECT
Expand Down
6 changes: 3 additions & 3 deletions data/persistence/src/commonMain/db_user/migrations/12.sqm
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
DROP VIEW MessageDetailsView;
DROP VIEW ConversationDetails;
DROP VIEW MessageQuoteDetails;
DROP VIEW IF EXISTS MessageDetailsView;
DROP VIEW IF EXISTS ConversationDetails;
DROP VIEW IF EXISTS MessageQuoteDetails;

CREATE VIEW IF NOT EXISTS MessageDetailsView
AS SELECT
Expand Down
2 changes: 1 addition & 1 deletion data/persistence/src/commonMain/db_user/migrations/14.sqm
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
DROP VIEW MessagePreview;
DROP VIEW IF EXISTS MessagePreview;

CREATE VIEW IF NOT EXISTS MessagePreview
AS SELECT
Expand Down
4 changes: 2 additions & 2 deletions data/persistence/src/commonMain/db_user/migrations/15.sqm
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import kotlin.Boolean;

DROP VIEW MessageDetailsView;
DROP VIEW IF EXISTS MessageDetailsView;
ALTER TABLE Message ADD COLUMN expects_read_confirmation INTEGER AS Boolean NOT NULL DEFAULT(0);

CREATE VIEW IF NOT EXISTS MessageDetailsView
Expand Down Expand Up @@ -112,7 +112,7 @@ LEFT JOIN MessageConversationChangedContent AS ConversationNameChangedContent ON
LEFT JOIN MessageQuoteDetails AS QuotedMessage ON Message.id = QuotedMessage.messageId AND Message.conversation_id = QuotedMessage.conversationId
LEFT JOIN SelfUser;

DROP VIEW ReceiptDetails;
DROP VIEW IF EXISTS ReceiptDetails;
CREATE VIEW IF NOT EXISTS ReceiptDetails
AS SELECT
Receipt.type,
Expand Down
2 changes: 1 addition & 1 deletion data/persistence/src/commonMain/db_user/migrations/16.sqm
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import kotlin.Boolean;

DROP VIEW MessageDetailsView;
DROP VIEW IF EXISTS MessageDetailsView;
ALTER TABLE MessageFailedToDecryptContent ADD COLUMN is_decryption_resolved INTEGER AS Boolean NOT NULL DEFAULT(0);

CREATE VIEW IF NOT EXISTS MessageDetailsView
Expand Down
2 changes: 1 addition & 1 deletion data/persistence/src/commonMain/db_user/migrations/17.sqm
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import kotlin.Boolean;

DROP VIEW MessagePreview;
DROP VIEW IF EXISTS MessagePreview;

UPDATE Conversation
SET muted_status = 'ONLY_MENTIONS_AND_REPLIES_ALLOWED'
Expand Down
Loading