Skip to content

Conversation

stevensJourney
Copy link
Contributor

@stevensJourney stevensJourney commented Mar 17, 2025

Overview

This PR introduces minor improvements to the SQLite driver functionality.

Unified Concurrency

The PowerSync client now supports readLock and writeLock APIs, aligning with the functionality in other SDKs.

Previously, concurrency was implemented differently across the various platform SQLite drivers. The Android and iOS drivers had their own concurrency models. The iOS driver opened a single read and write connection, while the Android driver’s read connections were dependent on available system memory ("The maximum number of connections used for parallel queries depends on the device’s memory and possibly other factors.").

The JVM driver only created a single connection, preventing concurrent reads.

The current driver interface required substantial work on the driver implementation to route queries to the appropriate internal connection. Implementing concurrency for the JVM driver would have been complex. Instead, we unified the concurrency model across all platforms by modifying the implementation to use multiple SQLite drivers.

Now, a single write connection driver is used for write operations, while a pool of read connection drivers is maintained.

SQLite Driver Improvements

Android

The current Android SQLite driver uses Requery, which does not support SQLite table update hooks in its API. Although PRs for adding SQLite hooks were introduced recently, they have not been released yet.

We currently use custom native C interops to access SQLite hooks via C APIs. However, these interops are limited and only function properly with a single SQLite connection/driver.

Implementing update hooks for multiple connections in native C interops is complex. As a result, this PR switches the Android driver to use the Xerial JDBC SQLite library (which is also used in the JVM build). This library supports SQLite hooks as part of its API.

Although the Xerial library requires shipping JNI binaries with our SDK, the Gradle build scripts have been updated to include the necessary JNI libraries during the build process.

The JDBC driver code is now shared between the Android and JVM targets, simplifying the implementation.

Removing the Requery dependency also streamlines installation, as users no longer need to add the Jitpack Maven repository to their build scripts.

TODOs:

  • Update documentation and demos to reflect the removal of the Requery dependency.

iOS

The iOS driver currently uses SQLiteR, which interfaces closely with the SQLite C APIs. However, SQLiteR does not expose SQLite hooks in its API, requiring us to use a native C interop for hook functionality.

The current hook implementation only works with the last driver created by the DatabaseDriverFactory. This implementation has been updated to support multiple connections.

Previously, the iOS driver loaded the PowerSync SQLite core extension statically by calling sqlite3_auto_extension through a native C interop. This PR now dynamically loads the extension and throws exceptions if the PowerSync core framework cannot be located.

Full-text search is now enabled by default for iOS.

Native Interops

Much of the native interop code has been removed, as it is no longer necessary.

Database Options

The Android and JVM drivers now support opening a database using a dbDirectory parameter. This feature is not supported on iOS.

SQLDelight Queries

We currently use SQLDelight's dialect for internal PowerSync queries. These operations use the driver directly. Which easily can cause synchronous code execution to block the main thread (some examples of this have been removed). Using the driver directly also has some slight chance of interfering with connection locks.

The use of SQLDelight dialect internally has mostly been removed and replaced with raw SQLite queries.

@stevensJourney stevensJourney marked this pull request as ready for review March 24, 2025 13:43
@stevensJourney stevensJourney requested a review from simolus3 March 24, 2025 13:43
Copy link
Contributor

@simolus3 simolus3 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This generally looks really nice, it's awesome to see how much custom native code we can throw out with this.

I have a bunch of comments, but they're all pretty minor.

@stevensJourney stevensJourney requested a review from simolus3 March 25, 2025 14:38
simolus3
simolus3 previously approved these changes Mar 25, 2025
Copy link
Contributor

@simolus3 simolus3 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM 🚀

@stevensJourney stevensJourney merged commit 1d939cc into main Mar 25, 2025
3 checks passed
@stevensJourney stevensJourney deleted the concurrent branch March 25, 2025 14:59
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants