Skip to content
Merged
Show file tree
Hide file tree
Changes from 38 commits
Commits
Show all changes
52 commits
Select commit Hold shift + click to select a range
622a89b
add unit tests. set jdbc to WAL
stevensJourney Mar 11, 2025
24afc55
wip read and write locks
stevensJourney Mar 12, 2025
651482e
wip android notifications
stevensJourney Mar 12, 2025
8f5ccf0
wip android jdbc
stevensJourney Mar 12, 2025
81822e9
wip share jdbc
stevensJourney Mar 13, 2025
c57f443
cleanup
stevensJourney Mar 13, 2025
30d420d
wip remove interop
stevensJourney Mar 15, 2025
2701d87
update core
stevensJourney Mar 17, 2025
f88a4bc
wip
stevensJourney Mar 17, 2025
747fbd9
Improve drivers for ios
stevensJourney Mar 17, 2025
f069a62
remove unused core interop
stevensJourney Mar 17, 2025
a28e11c
Merge remote-tracking branch 'origin/main' into concurrent
stevensJourney Mar 17, 2025
611b806
cleanup transactions
stevensJourney Mar 17, 2025
f8bf9c9
Gradle task for Android JNI. Catch Swift transaction errors
stevensJourney Mar 17, 2025
4242e9a
lint
stevensJourney Mar 17, 2025
d81122a
proguard rules
stevensJourney Mar 17, 2025
dacf29f
Don't link sqlite from dependencies
simolus3 Mar 18, 2025
73d0866
Don't include cinterop at all
simolus3 Mar 18, 2025
eea8fc4
Get static driver test working
simolus3 Mar 19, 2025
5dd5f28
Link core framework again
simolus3 Mar 19, 2025
dea89c0
Back to upstream dependencies
simolus3 Mar 19, 2025
4aee79d
Some build docs
simolus3 Mar 19, 2025
458c84d
Merge pull request #147 from powersync-ja/native-static-link-sqlite
simolus3 Mar 20, 2025
522a909
cleanup requery
stevensJourney Mar 18, 2025
afd82e7
cleanup readme
stevensJourney Mar 20, 2025
50ed399
Merge remote-tracking branch 'origin/main' into concurrent
stevensJourney Mar 22, 2025
15729e2
update connection pool to use channel implementation
stevensJourney Mar 24, 2025
f9a2218
cleanup
stevensJourney Mar 24, 2025
394507b
Merge remote-tracking branch 'origin/main' into concurrent
stevensJourney Mar 24, 2025
824e559
update global locks
stevensJourney Mar 24, 2025
0a9bae6
add tests for connection pool close
stevensJourney Mar 24, 2025
6b83087
update readme
stevensJourney Mar 24, 2025
7853359
cleanup
stevensJourney Mar 24, 2025
814b52d
test
stevensJourney Mar 24, 2025
bc78c36
Fix NPE when compiling sqlite3 for iOS
simolus3 Mar 24, 2025
c4f88f7
Add unit tests for db directory
stevensJourney Mar 24, 2025
91de8c0
cleanup
stevensJourney Mar 24, 2025
dfa419d
update changelog
stevensJourney Mar 24, 2025
c27f39f
Update core/README.md
stevensJourney Mar 24, 2025
58f5890
Update core/src/commonMain/kotlin/com/powersync/db/internal/PowerSync…
stevensJourney Mar 24, 2025
fe1cb3f
Add changelog entry for removing requery dependnecy. Cleanup gradle s…
stevensJourney Mar 25, 2025
7e9e537
Add readLock check to closed database test. Assert no nested transact…
stevensJourney Mar 25, 2025
0548d62
Ensure read connections are readonly
stevensJourney Mar 25, 2025
17913ba
fix test
stevensJourney Mar 25, 2025
47a2700
test: print exceptions in setup
stevensJourney Mar 25, 2025
d584cd2
test
stevensJourney Mar 25, 2025
318df0a
add logs for tests
stevensJourney Mar 25, 2025
5f83328
change read only setup for ios
stevensJourney Mar 25, 2025
11ca77f
remove test
stevensJourney Mar 25, 2025
6603ad8
Hack to lookup bundle earlier
simolus3 Mar 25, 2025
11bd61e
remove test code
stevensJourney Mar 25, 2025
fdc340a
remove unecessary log config in build script
stevensJourney Mar 25, 2025
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
8 changes: 4 additions & 4 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
# Changelog

## 1.0.0-BETA29

* Added queing protection and warnings when connecting multiple PowerSync clients to the same database file.

## 1.0.0-BETA28

* Update PowerSync SQLite core extension to 0.3.12.
* Added queing protection and warnings when connecting multiple PowerSync clients to the same database file.
* Improved concurrent SQLite connection support accross various platforms. All platforms now use a single write connection and multiple read connections for concurrent read queries.
* Added the ability to open a SQLite database given a custom `dbDirectory` path. This is currently not supported on iOS due to internal driver restrictions.
* Internaly improved the linking of SQLite for iOS.

## 1.0.0-BETA27

Expand Down
5 changes: 0 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -46,14 +46,9 @@ The PowerSync Kotlin Multiplatform SDK is currently in a beta release. It can be
Current limitations:

- Integration with SQLDelight schema and API generation (ORM) is not yet supported.
- Supports only a single database file.

Future work/ideas:

- Improved error handling.
- Attachments helper package.
- Management of DB connections on each platform natively.
- Supporting additional targets (JVM, Wasm).

## Installation

Expand Down
3 changes: 0 additions & 3 deletions build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,6 @@ allprojects {
maven("https://cache-redirector.jetbrains.com/intellij-dependencies")
// Repo for the backported Android IntelliJ Plugin by Jetbrains used in Ultimate
maven("https://maven.pkg.jetbrains.space/kotlin/p/kotlin/kotlin-ide-plugin-dependencies/")
maven("https://jitpack.io") {
content { includeGroup("com.github.requery") }
}
}

configurations.configureEach {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -93,4 +93,110 @@ class AndroidDatabaseTest {
query.cancel()
}
}

@Test
fun testConcurrentReads() =
runTest {
database.execute(
"INSERT INTO users (id, name, email) VALUES (uuid(), ?, ?)",
listOf(
"steven",
"[email protected]",
),
)

val pausedTransaction = CompletableDeferred<Unit>()
val transactionItemCreated = CompletableDeferred<Unit>()
// Start a long running writeTransaction
val transactionJob =
async {
database.writeTransaction { tx ->
// Create another user
// External readers should not see this user while the transaction is open
tx.execute(
"INSERT INTO users (id, name, email) VALUES (uuid(), ?, ?)",
listOf(
"steven",
"[email protected]",
),
)

transactionItemCreated.complete(Unit)

// Block this transaction until we free it
runBlocking {
pausedTransaction.await()
}
}
}

// Make sure to wait for the item to have been created in the transaction
transactionItemCreated.await()
// Try and read while the write transaction is busy
val result = database.getAll("SELECT * FROM users") { UserRow.from(it) }
// The transaction is not commited yet, we should only read 1 user
assertEquals(result.size, 1)

// Let the transaction complete
pausedTransaction.complete(Unit)
transactionJob.await()

val afterTx = database.getAll("SELECT * FROM users") { UserRow.from(it) }
assertEquals(afterTx.size, 2)
}

@Test
fun transactionReads() =
runTest {
database.execute(
"INSERT INTO users (id, name, email) VALUES (uuid(), ?, ?)",
listOf(
"steven",
"[email protected]",
),
)

database.writeTransaction { tx ->
val userCount =
tx.getAll("SELECT COUNT(*) as count FROM users") { cursor -> cursor.getLong(0)!! }
assertEquals(userCount[0], 1)

tx.execute(
"INSERT INTO users (id, name, email) VALUES (uuid(), ?, ?)",
listOf(
"steven",
"[email protected]",
),
)

// Getters inside the transaction should be able to see the latest update
val userCount2 =
tx.getAll("SELECT COUNT(*) as count FROM users") { cursor -> cursor.getLong(0)!! }
assertEquals(userCount2[0], 2)
}
}

@Test
fun openDBWithDirectory() =
runTest {
val tempDir =
InstrumentationRegistry
.getInstrumentation()
.targetContext.cacheDir.canonicalPath
val dbFilename = "testdb"

val db =
PowerSyncDatabase(
factory = DatabaseDriverFactory(InstrumentationRegistry.getInstrumentation().targetContext),
schema = Schema(UserRow.table),
dbDirectory = tempDir,
dbFilename = dbFilename,
)

val path = db.get("SELECT file FROM pragma_database_list;") { it.getString(0)!! }

assertEquals(path.contains(tempDir), true)

db.close()
}
}
4 changes: 4 additions & 0 deletions core/.gitignore
Original file line number Diff line number Diff line change
@@ -1 +1,5 @@
binaries/
# Required for the JDBC SQLite driver, but should not be commiteed
src/androidMain/jni

testdb-*
28 changes: 20 additions & 8 deletions core/README.md
Original file line number Diff line number Diff line change
@@ -1,19 +1,31 @@
# PowerSync core module

The PowerSync core module provides the core functionality for the PowerSync Kotlin Multiplatform SDK.
The PowerSync core module provides the core functionality for the PowerSync Kotlin Multiplatform
SDK.

## Structure

This is a Kotlin Multiplatform project targeting Android, iOS platforms, with the following structure:
This is a Kotlin Multiplatform project targeting Android, iOS platforms, with the following
structure:

- `commonMain` - Shared code for all targets, which includes the `PowerSyncBackendConnector` interface and `PowerSyncBuilder` for building a `PowerSync` instance. It also defines
- `commonMain` - Shared code for all targets, which includes the `PowerSyncBackendConnector`
interface and `PowerSyncBuilder` for building a `PowerSync` instance. It also defines
the `DatabaseDriverFactory` class to be implemented in each platform.
- `androidMain` - Android specific code, which includes a implementation of `DatabaseDriverFactory` class that creates an instance of `app.cash.sqldelight.driver.android.AndroidSqliteDriver` using
a `io.requery.android.database.sqlite.RequerySQLiteOpenHelperFactory`. It also includes native SQLite bindings for Android.
- `iosMain` - iOS specific code, which includes a implementation of `DatabaseDriverFactory` class that creates an instance of `app.cash.sqldelight.driver.native.NativeSqliteDriver` and also sets up native SQLite bindings for iOS.
- `commonJava` - Common Java code including a Java SQLite driver using
the [Xerial JDBC Driver](https://github.com/xerial/sqlite-jdbc). This is used by both the Android
and JVM drivers.
- `androidMain` - Android specific code, which includes an implementation of
`DatabaseDriverFactory`.
- `jvmMain` - JVM specific code which includes an implementation of `DatabaseDriverFactory`.
- `iosMain` - iOS specific code, which includes am implementation of `DatabaseDriverFactory` class
that creates an instance of `app.cash.sqldelight.driver.native.NativeSqliteDriver` and also sets
up native SQLite bindings for iOS.

## Note on SQLDelight

The PowerSync core module, internally makes use of [SQLDelight](https://cashapp.github.io/sqldelight) for it database API and typesafe database query generation.
The PowerSync core module, internally makes use
of [SQLDelight](https://cashapp.github.io/sqldelight) for it database API and typesafe database
query generation.

The PowerSync core module does not currently support integrating with SQLDelight from client applications.
The PowerSync core module does not currently support integrating with SQLDelight from client
applications.
Loading
Loading