Skip to content
Merged
Show file tree
Hide file tree
Changes from 10 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
21 changes: 13 additions & 8 deletions .github/workflows/test.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ jobs:
- name: Check publish score
run: |
dart pub global activate pana
dart pub global run pana --no-warning --exit-code-threshold 0
dart pub global run pana --no-warning --exit-code-threshold 10

test:
runs-on: ubuntu-latest
Expand All @@ -32,19 +32,19 @@ jobs:
include:
- sqlite_version: "3440200"
sqlite_url: "https://www.sqlite.org/2023/sqlite-autoconf-3440200.tar.gz"
dart_sdk: 3.3.3
dart_sdk: 3.4.0
- sqlite_version: "3430200"
sqlite_url: "https://www.sqlite.org/2023/sqlite-autoconf-3430200.tar.gz"
dart_sdk: 3.3.3
dart_sdk: 3.4.0
- sqlite_version: "3420000"
sqlite_url: "https://www.sqlite.org/2023/sqlite-autoconf-3420000.tar.gz"
dart_sdk: 3.3.3
dart_sdk: 3.4.0
- sqlite_version: "3410100"
sqlite_url: "https://www.sqlite.org/2023/sqlite-autoconf-3410100.tar.gz"
dart_sdk: 3.3.3
dart_sdk: 3.4.0
- sqlite_version: "3380000"
sqlite_url: "https://www.sqlite.org/2022/sqlite-autoconf-3380000.tar.gz"
dart_sdk: 3.3.3
dart_sdk: 3.4.0
steps:
- uses: actions/checkout@v3
- uses: dart-lang/setup-dart@v1
Expand All @@ -55,9 +55,14 @@ jobs:
run: dart pub get

- name: Install SQLite
run: ./scripts/install_sqlite.sh ${{ matrix.sqlite_version }} ${{ matrix.sqlite_url }}
run: |
./scripts/install_sqlite.sh ${{ matrix.sqlite_version }} ${{ matrix.sqlite_url }}
mkdir -p assets && curl -LJ https://github.com/simolus3/sqlite3.dart/releases/download/sqlite3-2.4.3/sqlite3.wasm -o assets/sqlite3.wasm

- name: Compile WebWorker
run: dart compile js -o assets/db_worker.js -O0 lib/src/web/worker/worker.dart

- name: Run Tests
run: |
export LD_LIBRARY_PATH=./sqlite-autoconf-${{ matrix.sqlite_version }}/.libs
dart test
dart test -p vm,chrome
5 changes: 5 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,12 @@
# https://dart.dev/guides/libraries/private-files#pubspeclock.
pubspec.lock

# Test assets
assets

.idea
.vscode
.devcontainer
*.db
*.db-*
test-db
Expand Down
23 changes: 23 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,26 @@
## 0.7.0-alpha.5

- The dependency for the `Drift` package is now removed in favour of using the new `sqlite3_web` package.
- A new implementation for WebDatabase is used for SQL database connections on web.
- New exports are added for downstream consumers of this package to extended custom workers with custom SQLite function capabilities.
- Update minimum Dart SDK to 3.4.0

## 0.7.0-alpha.4

- Add latest changes from master

## 0.7.0-alpha.3

- Add latest changes from master

## 0.7.0-alpha.2

- Fix re-using a shared Mutex from <https://github.com/powersync-ja/sqlite_async.dart/pull/31>

## 0.7.0-alpha.1

- Added initial support for web platform.

## 0.6.1

- Fix errors when closing a `SqliteDatabase`.
Expand Down
9 changes: 9 additions & 0 deletions DEVELOPING.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# Developing Instructions

## Testing

Running tests for the `web` platform requires some preparation to be executed. The `sqlite3.wasm` and `db_worker.js` files need to be available in the Git ignored `./assets` folder.

See the [test action](./.github/workflows/test.yaml) for the latest steps.

On your local machine run the commands from the `Install SQLite`, `Compile WebWorker` and `Run Tests` steps.
27 changes: 26 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -74,4 +74,29 @@ void main() async {

await db.close();
}
```
```

# Web

Web support is provided by the [Drift](https://github.com/powersync-ja/drift/pull/1) library. Detailed instructions for compatibility and setup are listed in the link.

Web support requires Sqlite3 WASM and Drift worker Javascript files to be accessible via configurable URIs.

Default URIs are shown in the example below. URIs only need to be specified if they differ from default values.

Watched queries and table change notifications are only supported when using a custom Drift worker which is compiled by linking
https://github.com/powersync-ja/drift/pull/1.

Setup

``` Dart
import 'package:sqlite_async/sqlite_async.dart';

final db = SqliteDatabase(
path: 'test.db',
options: SqliteOptions(
webSqliteOptions: WebSqliteOptions(
wasmUri: 'sqlite3.wasm', workerUri: 'db_worker.js')));

```

5 changes: 5 additions & 0 deletions lib/sqlite3_wasm.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
/// Re-exports [sqlite3 WASM](https://pub.dev/packages/sqlite3) to expose sqlite3 without
/// adding it as a direct dependency.
library;

export 'package:sqlite3/wasm.dart';
5 changes: 5 additions & 0 deletions lib/sqlite3_web.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
/// Re-exports [sqlite3_web](https://pub.dev/packages/sqlite3_web) to expose sqlite3_web without
/// adding it as a direct dependency.
library;

export 'package:sqlite3_web/sqlite3_web.dart';
3 changes: 3 additions & 0 deletions lib/sqlite3_web_worker.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
// Items required for extending custom web workers
export './src/web/worker/worker_utils.dart';
export './src/web/protocol.dart';
3 changes: 0 additions & 3 deletions lib/src/common/sqlite_database.dart
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,6 @@ mixin SqliteDatabaseMixin implements SqliteConnection, SqliteQueries {
@override
Stream<UpdateNotification> get updates;

final StreamController<UpdateNotification> updatesController =
StreamController.broadcast();

@protected
Future<void> get isInitialized;

Expand Down
4 changes: 3 additions & 1 deletion lib/src/impl/isolate_connection_factory_impl.dart
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
export 'stub_isolate_connection_factory.dart'
// ignore: uri_does_not_exist
if (dart.library.io) '../native/native_isolate_connection_factory.dart';
if (dart.library.io) '../native/native_isolate_connection_factory.dart'
// ignore: uri_does_not_exist
if (dart.library.html) '../web/web_isolate_connection_factory.dart';
4 changes: 3 additions & 1 deletion lib/src/impl/mutex_impl.dart
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
export 'stub_mutex.dart'
// ignore: uri_does_not_exist
if (dart.library.io) '../native/native_isolate_mutex.dart';
if (dart.library.io) '../native/native_isolate_mutex.dart'
// ignore: uri_does_not_exist
if (dart.library.html) '../web/web_mutex.dart';
4 changes: 3 additions & 1 deletion lib/src/impl/open_factory_impl.dart
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
export 'stub_sqlite_open_factory.dart'
// ignore: uri_does_not_exist
if (dart.library.io) '../native/native_sqlite_open_factory.dart';
if (dart.library.io) '../native/native_sqlite_open_factory.dart'
// ignore: uri_does_not_exist
if (dart.library.html) '../web/web_sqlite_open_factory.dart';
4 changes: 3 additions & 1 deletion lib/src/impl/sqlite_database_impl.dart
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
export 'stub_sqlite_database.dart'
// ignore: uri_does_not_exist
if (dart.library.io) '../native/database/native_sqlite_database.dart';
if (dart.library.io) '../native/database/native_sqlite_database.dart'
// ignore: uri_does_not_exist
if (dart.library.html) '../web/database/web_sqlite_database.dart';
4 changes: 2 additions & 2 deletions lib/src/native/database/connection_pool.dart
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@ import 'dart:async';
import 'dart:collection';

import 'package:sqlite_async/sqlite_async.dart';
import '../database/native_sqlite_connection_impl.dart';
import '../native_isolate_mutex.dart';
import 'package:sqlite_async/src/native/database/native_sqlite_connection_impl.dart';
import 'package:sqlite_async/src/native/native_isolate_mutex.dart';

/// A connection pool with a single write connection and multiple read connections.
class SqliteConnectionPool with SqliteQueries implements SqliteConnection {
Expand Down
18 changes: 9 additions & 9 deletions lib/src/native/database/native_sqlite_connection_impl.dart
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,14 @@ import 'dart:isolate';

import 'package:sqlite3/sqlite3.dart' as sqlite;
import 'package:sqlite_async/sqlite3_common.dart';
import '../../common/abstract_open_factory.dart';
import '../../common/mutex.dart';
import '../../common/port_channel.dart';
import '../../native/native_isolate_mutex.dart';
import '../../sqlite_connection.dart';
import '../../sqlite_queries.dart';
import '../../update_notification.dart';
import '../../utils/shared_utils.dart';
import 'package:sqlite_async/src/common/abstract_open_factory.dart';
import 'package:sqlite_async/src/common/mutex.dart';
import 'package:sqlite_async/src/common/port_channel.dart';
import 'package:sqlite_async/src/native/native_isolate_mutex.dart';
import 'package:sqlite_async/src/sqlite_connection.dart';
import 'package:sqlite_async/src/sqlite_queries.dart';
import 'package:sqlite_async/src/update_notification.dart';
import 'package:sqlite_async/src/utils/shared_utils.dart';

import 'upstream_updates.dart';

Expand Down Expand Up @@ -42,6 +42,7 @@ class SqliteConnectionImpl
this.readOnly = false,
bool primary = false})
: _writeMutex = mutex {
isInitialized = _isolateClient.ready;
this.upstreamPort = upstreamPort ?? listenForEvents();
// Accept an incoming stream of updates, or expose one if not given.
this.updates = updates ?? updatesController.stream;
Expand Down Expand Up @@ -88,7 +89,6 @@ class SqliteConnectionImpl
paused: true);
_isolateClient.tieToIsolate(_isolate);
_isolate.resume(_isolate.pauseCapability!);
isInitialized = _isolateClient.ready;
await _isolateClient.ready;
});
}
Expand Down
25 changes: 14 additions & 11 deletions lib/src/native/database/native_sqlite_database.dart
Original file line number Diff line number Diff line change
@@ -1,17 +1,17 @@
import 'dart:async';

import 'package:meta/meta.dart';
import '../../common/abstract_open_factory.dart';
import '../../common/sqlite_database.dart';
import '../../native/database/connection_pool.dart';
import '../../native/database/native_sqlite_connection_impl.dart';
import '../../native/native_isolate_connection_factory.dart';
import '../../native/native_isolate_mutex.dart';
import '../../native/native_sqlite_open_factory.dart';
import '../../sqlite_connection.dart';
import '../../sqlite_options.dart';
import '../../sqlite_queries.dart';
import '../../update_notification.dart';
import 'package:sqlite_async/src/common/abstract_open_factory.dart';
import 'package:sqlite_async/src/common/sqlite_database.dart';
import 'package:sqlite_async/src/native/database/connection_pool.dart';
import 'package:sqlite_async/src/native/database/native_sqlite_connection_impl.dart';
import 'package:sqlite_async/src/native/native_isolate_connection_factory.dart';
import 'package:sqlite_async/src/native/native_isolate_mutex.dart';
import 'package:sqlite_async/src/native/native_sqlite_open_factory.dart';
import 'package:sqlite_async/src/sqlite_connection.dart';
import 'package:sqlite_async/src/sqlite_options.dart';
import 'package:sqlite_async/src/sqlite_queries.dart';
import 'package:sqlite_async/src/update_notification.dart';

/// A SQLite database instance.
///
Expand Down Expand Up @@ -40,6 +40,9 @@ class SqliteDatabaseImpl
late final SqliteConnectionImpl _internalConnection;
late final SqliteConnectionPool _pool;

final StreamController<UpdateNotification> updatesController =
StreamController.broadcast();

/// Open a SqliteDatabase.
///
/// Only a single SqliteDatabase per [path] should be opened at a time.
Expand Down
8 changes: 4 additions & 4 deletions lib/src/native/database/upstream_updates.dart
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,10 @@ import 'dart:async';
import 'dart:isolate';

import 'package:meta/meta.dart';
import '../../common/port_channel.dart';
import '../../update_notification.dart';
import '../../utils/native_database_utils.dart';
import '../../utils/shared_utils.dart';
import 'package:sqlite_async/src/common/port_channel.dart';
import 'package:sqlite_async/src/update_notification.dart';
import 'package:sqlite_async/src/utils/native_database_utils.dart';
import 'package:sqlite_async/src/utils/shared_utils.dart';

mixin UpStreamTableUpdates {
final StreamController<UpdateNotification> updatesController =
Expand Down
2 changes: 1 addition & 1 deletion lib/src/sqlite_migrations.dart
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import 'dart:async';
import 'dart:convert';

import 'package:sqlite3/sqlite3.dart';
import 'package:sqlite3/common.dart';

import 'sqlite_connection.dart';

Expand Down
16 changes: 16 additions & 0 deletions lib/src/sqlite_options.dart
Original file line number Diff line number Diff line change
@@ -1,3 +1,15 @@
class WebSqliteOptions {
final String workerUri;
final String wasmUri;

const WebSqliteOptions.defaults()
: workerUri = 'db_worker.js',
wasmUri = 'sqlite3.wasm';

const WebSqliteOptions(
{this.wasmUri = 'sqlite3.wasm', this.workerUri = 'db_worker.js'});
}

class SqliteOptions {
/// SQLite journal mode. Defaults to [SqliteJournalMode.wal].
final SqliteJournalMode? journalMode;
Expand All @@ -11,6 +23,8 @@ class SqliteOptions {
/// attempt to truncate the file afterwards.
final int? journalSizeLimit;

final WebSqliteOptions webSqliteOptions;

/// Timeout waiting for locks to be released by other connections.
/// Defaults to 30 seconds.
/// Set to null or [Duration.zero] to fail immediately when the database is locked.
Expand All @@ -20,12 +34,14 @@ class SqliteOptions {
: journalMode = SqliteJournalMode.wal,
journalSizeLimit = 6 * 1024 * 1024, // 1.5x the default checkpoint size
synchronous = SqliteSynchronous.normal,
webSqliteOptions = const WebSqliteOptions.defaults(),
lockTimeout = const Duration(seconds: 30);

const SqliteOptions(
{this.journalMode = SqliteJournalMode.wal,
this.journalSizeLimit = 6 * 1024 * 1024,
this.synchronous = SqliteSynchronous.normal,
this.webSqliteOptions = const WebSqliteOptions.defaults(),
this.lockTimeout = const Duration(seconds: 30)});
}

Expand Down
Loading