Skip to content
Draft
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
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
package com.powersync.db

import androidx.sqlite.SQLiteConnection
import com.powersync.PersistentConnectionFactory
import com.powersync.PowerSyncException
import com.powersync.sqlite.Database

/**
* A [PersistentConnectionFactory] implementation delegating to static `sqlite3_` invocations through cinterop.
*/
public abstract class NativeConnectionFactory: PersistentConnectionFactory {
override fun openConnection(path: String, openFlags: Int): SQLiteConnection {
val extensionPath = powersyncLoadableExtensionPath()
val db = Database.open(path, openFlags)

if (extensionPath != null) {
try {
db.loadExtension(extensionPath, "sqlite3_powersync_init")
} catch (e: PowerSyncException) {
db.close()
throw e
}
}

return db
}

override fun openInMemoryConnection(): SQLiteConnection {
return openConnection(":memory:", 0x02)
}

/**
* If the core extension should be loaded as a dynamic library, returns its path.
*
* Otherwise, installs the core extension as a static extension and returns null.
*/
protected abstract fun powersyncLoadableExtensionPath(): String?
}
Original file line number Diff line number Diff line change
@@ -1,29 +1,14 @@
package com.powersync

import androidx.sqlite.SQLiteConnection
import com.powersync.sqlite.Database
import com.powersync.db.NativeConnectionFactory

@Suppress(names = ["EXPECT_ACTUAL_CLASSIFIERS_ARE_IN_BETA_WARNING"])
public actual class DatabaseDriverFactory: PersistentConnectionFactory {
public actual class DatabaseDriverFactory: PersistentConnectionFactory, NativeConnectionFactory() {
actual override fun resolveDefaultDatabasePath(dbFilename: String): String = appleDefaultDatabasePath(dbFilename)

@OptIn(ExperimentalPowerSyncAPI::class)
actual override fun openConnection(
path: String,
openFlags: Int,
): SQLiteConnection {
val db = Database.open(path, openFlags)
try {
db.loadExtension(resolvePowerSyncLoadableExtensionPath()!!, "sqlite3_powersync_init")
} catch (e: PowerSyncException) {
db.close()
throw e
}
return db
}

actual override fun openInMemoryConnection(): SQLiteConnection {
return openConnection(":memory:", 0x02)
override fun powersyncLoadableExtensionPath(): String? {
return resolvePowerSyncLoadableExtensionPath()
}
}

Expand Down
5 changes: 3 additions & 2 deletions internal/PowerSyncKotlin/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ kotlin {
baseName = "PowerSyncKotlin"
xcf.add(this)

export(project(":core"))
export(projects.common)
isStatic = true

binaryOption("bundleId", "PowerSyncKotlin")
Expand All @@ -45,8 +45,9 @@ kotlin {

sourceSets {
commonMain.dependencies {
api(project(":core"))
api(projects.common)
implementation(libs.ktor.client.logging)
implementation(libs.ktor.client.darwin)
}
}
}
Expand Down
30 changes: 30 additions & 0 deletions internal/PowerSyncKotlin/src/appleMain/kotlin/com/powersync/SDK.kt
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@

package com.powersync

import androidx.sqlite.SQLiteConnection
import androidx.sqlite.execSQL
import com.powersync.db.NativeConnectionFactory
import com.powersync.db.crud.CrudTransaction
import com.powersync.sync.SyncClientConfiguration
import com.powersync.sync.SyncOptions
Expand All @@ -12,6 +15,33 @@ import kotlinx.coroutines.flow.catch
import kotlinx.coroutines.flow.map
import io.ktor.client.plugins.logging.Logger as KtorLogger

public fun sqlite3DatabaseFactory(initialStatements: List<String>): PersistentConnectionFactory {
@OptIn(ExperimentalPowerSyncAPI::class)
return object : NativeConnectionFactory() {
override fun powersyncLoadableExtensionPath(): String? {
return resolvePowerSyncLoadableExtensionPath()
}

override fun resolveDefaultDatabasePath(dbFilename: String): String {
return appleDefaultDatabasePath(dbFilename)
}

override fun openConnection(path: String, openFlags: Int): SQLiteConnection {
val conn = super.openConnection(path, openFlags)
try {
for (statement in initialStatements) {
conn.execSQL(statement)
}
} catch (e: PowerSyncException) {
conn.close()
throw e
}

return super.openConnection(path, openFlags)
}
}
}

/**
* Helper class designed to bridge SKIEE methods and allow them to throw
* `PowerSyncException`. This is necessary because these exceptions cannot
Expand Down