Skip to content

Commit 694524c

Browse files
Merge remote-tracking branch 'origin/main' into api-ref
2 parents 4c2c13b + 568c3b1 commit 694524c

File tree

36 files changed

+777
-499
lines changed

36 files changed

+777
-499
lines changed

.github/workflows/test.yml

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,9 @@ jobs:
1616
matrix:
1717
include:
1818
- os: macos-latest
19-
targets: iosSimulatorArm64Test jvmTest lintKotlin
19+
targets: iosSimulatorArm64Test macosArm64Test jvmTest
2020
- os: ubuntu-latest
21-
targets: testDebugUnitTest testReleaseUnitTest jvmTest
21+
targets: testDebugUnitTest testReleaseUnitTest jvmTest lintKotlin
2222
- os: windows-latest
2323
targets: jvmTest
2424
runs-on: ${{ matrix.os }}
@@ -44,4 +44,14 @@ jobs:
4444
./gradlew \
4545
-PGITHUB_PUBLISH_TOKEN=${{ secrets.GITHUB_TOKEN }} \
4646
${{ matrix.targets }}
47-
shell: bash
47+
shell: bash
48+
49+
# Credit: https://github.com/gradle/actions/issues/76#issuecomment-2007584323
50+
- name: Upload reports on failure
51+
if: failure()
52+
uses: actions/upload-artifact@v4
53+
with:
54+
name: report-for-${{ matrix.os }}
55+
path: |
56+
**/build/reports/
57+
**/build/test-results/

CHANGELOG.md

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,19 @@
11
# Changelog
22

3-
## 1.0.0-BETA29 (unreleased)
3+
## 1.0.0-BETA30
4+
5+
* Fix a deadlock when calling `connect()` immediately after opening a database.
6+
The issue has been introduced in version `1.0.0-BETA29`.
7+
8+
## 1.0.0-BETA29
49

510
* Fix potential race condition between jobs in `connect()` and `disconnect()`.
11+
* [JVM Windows] Fixed PowerSync Extension temporary file deletion error on process shutdown.
12+
* [iOS] Fixed issue where automatic driver migrations would fail with the error:
13+
```
14+
Sqlite operation failure database is locked attempted to run migration and failed. closing connection
15+
```
16+
* Fix race condition causing data received during uploads not to be applied.
617

718
## 1.0.0-BETA28
819

PowerSyncKotlin/build.gradle.kts

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@ kotlin {
1717
iosX64(),
1818
iosArm64(),
1919
iosSimulatorArm64(),
20+
macosArm64(),
21+
macosX64(),
2022
).forEach {
2123
it.binaries.framework {
2224
export(project(":core"))
@@ -41,6 +43,26 @@ kotlin {
4143
}
4244
}
4345

46+
repositories {
47+
maven {
48+
name = "PowerSyncSQLiterFork"
49+
url = uri("https://powersync-ja.github.io/SQLiter")
50+
content {
51+
includeModuleByRegex("co.touchlab", "sqliter-driver.*")
52+
}
53+
}
54+
}
55+
56+
configurations.all {
57+
resolutionStrategy {
58+
// This version has not been released yet (https://github.com/touchlab/SQLiter/pull/124), so we're pointing this
59+
// towards our fork with the repositories block above.
60+
// The API is identical, but we have to make sure this particular project builds the xcframework with the
61+
// patched SQLiter version to avoid linker errors on macOS.
62+
force("co.touchlab:sqliter-driver:1.3.2-powersync")
63+
}
64+
}
65+
4466
kmmbridge {
4567
artifactManager.set(SonatypePortalPublishArtifactManager(project, repositoryName = null))
4668
artifactManager.finalizeValue()

compose/build.gradle.kts

Lines changed: 2 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import com.powersync.plugins.sonatype.setupGithubRepository
2+
import com.powersync.plugins.utils.powersyncTargets
23

34
plugins {
45
alias(libs.plugins.kotlinMultiplatform)
@@ -10,15 +11,7 @@ plugins {
1011
}
1112

1213
kotlin {
13-
androidTarget {
14-
publishLibraryVariants("release", "debug")
15-
}
16-
17-
jvm()
18-
19-
iosX64()
20-
iosArm64()
21-
iosSimulatorArm64()
14+
powersyncTargets(includeTargetsWithoutComposeSupport = false)
2215

2316
explicitApi()
2417

connectors/supabase/build.gradle.kts

Lines changed: 2 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import com.powersync.plugins.sonatype.setupGithubRepository
2+
import com.powersync.plugins.utils.powersyncTargets
23
import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinNativeTarget
34

45
plugins {
@@ -10,12 +11,7 @@ plugins {
1011
}
1112

1213
kotlin {
13-
androidTarget {
14-
publishLibraryVariants("release", "debug")
15-
}
16-
17-
jvm()
18-
14+
powersyncTargets()
1915
targets.withType<KotlinNativeTarget> {
2016
compilations.named("main") {
2117
compileTaskProvider {
@@ -24,10 +20,6 @@ kotlin {
2420
}
2521
}
2622

27-
iosX64()
28-
iosArm64()
29-
iosSimulatorArm64()
30-
3123
explicitApi()
3224

3325
sourceSets {

core/build.gradle.kts

Lines changed: 37 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,8 @@
11
import com.powersync.plugins.sonatype.setupGithubRepository
2+
import com.powersync.plugins.utils.powersyncTargets
23
import de.undercouch.gradle.tasks.download.Download
34
import org.gradle.api.tasks.testing.logging.TestExceptionFormat
45
import org.gradle.internal.os.OperatingSystem
5-
import org.jetbrains.kotlin.gradle.ExperimentalKotlinGradlePluginApi
6-
import org.jetbrains.kotlin.gradle.dsl.JvmTarget
76
import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinNativeTarget
87
import org.jetbrains.kotlin.gradle.plugin.mpp.TestExecutable
98
import org.jetbrains.kotlin.gradle.targets.jvm.tasks.KotlinJvmTest
@@ -85,15 +84,22 @@ val downloadPowersyncFramework by tasks.registering(Download::class) {
8584
onlyIfModified(true)
8685
}
8786

88-
val unzipPowersyncFramework by tasks.registering(Copy::class) {
87+
val unzipPowersyncFramework by tasks.registering(Exec::class) {
8988
dependsOn(downloadPowersyncFramework)
9089

91-
from(
92-
zipTree(downloadPowersyncFramework.get().dest).matching {
93-
include("powersync-sqlite-core.xcframework/**")
94-
},
95-
)
96-
into(binariesFolder.map { it.dir("framework") })
90+
val zipfile = downloadPowersyncFramework.get().dest
91+
inputs.file(zipfile)
92+
val destination = File(zipfile.parentFile, "extracted")
93+
doFirst {
94+
destination.deleteRecursively()
95+
destination.mkdir()
96+
}
97+
98+
// We're using unzip here because the Gradle copy task doesn't support symlinks.
99+
executable = "unzip"
100+
args(zipfile.absolutePath)
101+
workingDir(destination)
102+
outputs.dir(destination)
97103
}
98104

99105
val sqliteJDBCFolder =
@@ -151,26 +157,7 @@ val moveJDBCJNIFiles by tasks.registering(Copy::class) {
151157
}
152158

153159
kotlin {
154-
androidTarget {
155-
publishLibraryVariants("release", "debug")
156-
157-
@OptIn(ExperimentalKotlinGradlePluginApi::class)
158-
compilerOptions {
159-
jvmTarget.set(JvmTarget.JVM_17)
160-
}
161-
}
162-
jvm {
163-
@OptIn(ExperimentalKotlinGradlePluginApi::class)
164-
compilerOptions {
165-
jvmTarget.set(JvmTarget.JVM_1_8)
166-
// https://jakewharton.com/kotlins-jdk-release-compatibility-flag/
167-
freeCompilerArgs.add("-Xjdk-release=8")
168-
}
169-
}
170-
171-
iosX64()
172-
iosArm64()
173-
iosSimulatorArm64()
160+
powersyncTargets()
174161

175162
targets.withType<KotlinNativeTarget> {
176163
compilations.named("main") {
@@ -185,7 +172,20 @@ kotlin {
185172
linkerOpts("-framework", "powersync-sqlite-core")
186173
val frameworkRoot =
187174
binariesFolder
188-
.map { it.dir("framework/powersync-sqlite-core.xcframework/ios-arm64_x86_64-simulator") }
175+
.map { it.dir("framework/extracted/powersync-sqlite-core.xcframework/ios-arm64_x86_64-simulator") }
176+
.get()
177+
.asFile.path
178+
179+
linkerOpts("-F", frameworkRoot)
180+
linkerOpts("-rpath", frameworkRoot)
181+
}
182+
} else if (konanTarget.family == Family.OSX) {
183+
binaries.withType<TestExecutable>().configureEach {
184+
linkTaskProvider.configure { dependsOn(unzipPowersyncFramework) }
185+
linkerOpts("-framework", "powersync-sqlite-core")
186+
var frameworkRoot =
187+
binariesFolder
188+
.map { it.dir("framework/extracted/powersync-sqlite-core.xcframework/macos-arm64_x86_64") }
189189
.get()
190190
.asFile.path
191191

@@ -254,14 +254,15 @@ kotlin {
254254
}
255255
}
256256

257-
iosMain.dependencies {
258-
implementation(libs.ktor.client.ios)
257+
appleMain.dependencies {
258+
implementation(libs.ktor.client.darwin)
259259
}
260260

261261
commonTest.dependencies {
262262
implementation(libs.kotlin.test)
263263
implementation(libs.test.coroutines)
264264
implementation(libs.test.turbine)
265+
implementation(libs.test.kotest.assertions)
265266
implementation(libs.kermit.test)
266267
implementation(libs.ktor.client.mock)
267268
implementation(libs.test.turbine)
@@ -271,8 +272,9 @@ kotlin {
271272
// tests.
272273
jvmTest.get().dependsOn(commonIntegrationTest)
273274

274-
// We're linking the xcframework for the simulator tests, so they can use integration tests too
275-
iosSimulatorArm64Test.orNull?.dependsOn(commonIntegrationTest)
275+
// We have special setup in this build configuration to make these tests link the PowerSync extension, so they
276+
// can run integration tests along with the executable for unit testing.
277+
appleTest.orNull?.dependsOn(commonIntegrationTest)
276278
}
277279
}
278280

@@ -346,6 +348,7 @@ tasks.withType<KotlinTest> {
346348
testLogging {
347349
events("PASSED", "FAILED", "SKIPPED")
348350
exceptionFormat = TestExceptionFormat.FULL
351+
showCauses = true
349352
showStandardStreams = true
350353
showStackTraces = true
351354
}

core/src/iosMain/kotlin/com/powersync/DatabaseDriverFactory.ios.kt renamed to core/src/appleMain/kotlin/com/powersync/DatabaseDriverFactory.ios.kt

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
11
package com.powersync
22

3+
import app.cash.sqldelight.db.QueryResult
34
import co.touchlab.sqliter.DatabaseConfiguration
45
import co.touchlab.sqliter.DatabaseConfiguration.Logging
56
import co.touchlab.sqliter.DatabaseConnection
7+
import co.touchlab.sqliter.NO_VERSION_CHECK
68
import co.touchlab.sqliter.interop.Logger
79
import co.touchlab.sqliter.interop.SqliteErrorType
810
import co.touchlab.sqliter.sqlite3.sqlite3_commit_hook
@@ -68,7 +70,13 @@ public actual class DatabaseDriverFactory {
6870
configuration =
6971
DatabaseConfiguration(
7072
name = dbFilename,
71-
version = schema.version.toInt(),
73+
version =
74+
if (!readOnly) {
75+
schema.version.toInt()
76+
} else {
77+
// Don't do migrations on read only connections
78+
NO_VERSION_CHECK
79+
},
7280
create = { connection ->
7381
wrapConnection(connection) {
7482
schema.create(
@@ -106,6 +114,15 @@ public actual class DatabaseDriverFactory {
106114
driver.execute("PRAGMA query_only=true")
107115
}
108116

117+
// Ensure internal read pool has created a connection at this point. This makes connection
118+
// initialization a bit more deterministic.
119+
driver.executeQuery(
120+
identifier = null,
121+
sql = "SELECT 1",
122+
mapper = { QueryResult.Value(it.getLong(0)) },
123+
parameters = 0,
124+
)
125+
109126
deferredDriver.setDriver(driver)
110127

111128
return driver

0 commit comments

Comments
 (0)