-
Notifications
You must be signed in to change notification settings - Fork 18
Use androidx sqlite bindings internally #230
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
9b34eff
to
f532ba9
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm very very happy with the changes here. This is amazing.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull Request Overview
This PR removes internal dependencies on SQLDelight and SQLiter libraries and replaces them with Android's androidx.sqlite bindings internally. The main purpose is to make the PowerSync Kotlin and Swift SDKs easier to integrate with other database libraries by introducing a new SQLiteConnectionPool
interface.
Key changes:
- Introduced new
SQLiteConnectionPool
interface for external database integration - Replaced SQLiter/SQLDelight with androidx.sqlite bindings across all platforms
- Added new internal SQLite connection implementations for Apple platforms using cinterop
Reviewed Changes
Copilot reviewed 66 out of 67 changed files in this pull request and generated 1 comment.
Show a summary per file
File | Description |
---|---|
settings.gradle.kts | Updated module paths and removed deprecated modules |
gradle/libs.versions.toml | Updated dependencies, removed SQLDelight and SQLiter, updated androidx.sqlite version |
core/src/commonMain/kotlin/com/powersync/db/driver/SQLiteConnectionPool.kt | New interface for connection pool abstraction |
core/src/nativeMain/kotlin/com/powersync/sqlite/ | New SQLite implementation for Apple platforms using cinterop |
core/src/jvmMain/kotlin/com/powersync/DatabaseDriverFactory.jvm.kt | Updated to use BundledSQLiteDriver instead of JDBC |
core/src/androidMain/kotlin/com/powersync/DatabaseDriverFactory.android.kt | Updated to use BundledSQLiteDriver |
core/build.gradle.kts | Updated build configuration, removed JDBC dependencies, added sqlite3 cinterop |
Comments suppressed due to low confidence (2)
core/src/nativeMain/kotlin/com/powersync/sqlite/Statement.kt:1
- There's a grammatical error in the documentation comment: 'Block most only run' should be 'Block must only run'.
package com.powersync.sqlite
plugins/build-plugin/src/main/kotlin/com/powersync/compile/CreateSqliteCInterop.kt:1
- [nitpick] This import appears to be unused after the removal. Consider removing this import statement to clean up the code.
package com.powersync.compile
Tip: Customize your code reviews with copilot-instructions.md. Create the file or learn how to get started.
Overview
To make the PowerSync Kotlin and Swift SDKs easier to integrate with other database libraries providing asynchronous database access, users need the ability to use the SDK without the builtin connection pool.
To facilitate this, this adds the new
SQLiteConnectionPool
interface, whichread()
andwrite()
methods taking asuspend (SQLiteConnectionLease) -> T
to schedule read and write operations on the pool.SQLiteConnectionLease
in turn provides two methods:isInTransaction()
, reporting the autocommit stateusePrepared()
, giving users temporary access to a raw prepared statementPowerSyncDatabase
instance, with the newPowerSyncDatabase.opened
method. The internal opening logic has also been refactored to call that method after constructing a pool.This interface mirrors the semantics of a WAL connection pool, and has also been designed so that a
SQLiteConnectionPool
can easily be implemented ontop of Room: Theread()
andwrite()
methods correspond touseConnection
in Room, see the Transactor API from Room for a comparison.In
:core
, existing public interfaces like the cursor are then consistently implemented across the common underlying connection pool API.I've also added a new API to
PowerSyncDatabase
to give out a temporary view to an underlyingSQLiteConnection
. This would give users full control over the statements to run, while still letting the PowerSync SDK taking care of connection management.New SQLite interface
Previously, we've used SQLDelight and SQLiter libraries internally. The main issue with those is that they do too much, and don't give us enough control to implement the
SQLiteConnectionPool
API we need for Room or GRDB support:isInTransaction()
).This restructures our internal driver implementations to be aligned with cross-platform APIs from the
androidx.sqlite:sqlite
library, and removes all internal usages of SQLiter, SQLDelight and sqlite-jdbc.Because the higher layers of the SDK are implemented ontop of a
SQLiteConnectionPool
, this also adds a pool implementation based on multipleSQLiteConnection
instances (although we mostly had that before as well).New SQLite implementation
Because the interface to access SQLite databases has changed, we'll also need new implementations. The androidx project maintains a cross-platform
SQLiteConnection
implementation (in theandroidx.sqlite:sqlite-bundled
artifact). Ideally, we would just be using that. In practice however, we get linker errors then integrating our XCFramework into the Swift SDK :(I have send a PR upstream to fix this. In the meantime, using our existing
static-sqlite-driver
package to implementSQLiteConnection
with cinterop is not that bad of an alternative.So, to summarize which implementations are used:
androidx.sqlite:sqlite-bundled
androidx.sqlite:sqlite-bundled
static-slqite-driver
static-slqite-driver
TODOs: