From e243e3155a67567e991f857489afccb755f27cf4 Mon Sep 17 00:00:00 2001 From: Simon Binder Date: Thu, 15 Jan 2026 15:57:25 +0100 Subject: [PATCH 1/5] Use version 3 of sqlite3 package --- .github/workflows/tests.yml | 21 +--- dart/dart_test.yaml | 9 +- dart/pubspec.lock | 98 ++++++++------- dart/pubspec.yaml | 4 +- dart/test/crud_test.dart | 2 +- dart/test/error_test.dart | 2 +- dart/test/js_key_encoding_test.dart | 2 +- dart/test/legacy_sync_test.dart | 2 +- dart/test/migration_test.dart | 2 +- dart/test/schema_test.dart | 2 +- dart/test/sync_local_performance_test.dart | 2 +- dart/test/sync_stream_test.dart | 2 +- dart/test/sync_test.dart | 2 +- dart/test/update_hooks_test.dart | 4 +- dart/test/utils/native_test_utils.dart | 24 ---- dart/tool/download_sqlite3.dart | 136 --------------------- 16 files changed, 77 insertions(+), 237 deletions(-) delete mode 100644 dart/tool/download_sqlite3.dart diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 6fe7ed48..209da71f 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -131,7 +131,7 @@ jobs: working-directory: dart run: | dart pub get - dart run tool/download_sqlite3.dart + dart run tool/download_old_sqlite3.dart dart analyze - name: Download libs @@ -155,21 +155,11 @@ jobs: working-directory: dart run: | ls -al assets/ - - - name: Dart tests on Linux - if: runner.os == 'Linux' - working-directory: dart - run: | - CORE_TEST_SQLITE=.dart_tool/sqlite3/latest/libsqlite3.so dart test - CORE_TEST_SQLITE=.dart_tool/sqlite3/minimum/libsqlite3.so dart test - - name: Dart tests on macOS - if: runner.os == 'macOS' + - name: Dart tests working-directory: dart - # We skip sync_local_performance_test on macOS because the runners are just so slow... run: | - CORE_TEST_SQLITE=.dart_tool/sqlite3/latest/libsqlite3.dylib dart test -P skip_slow - CORE_TEST_SQLITE=.dart_tool/sqlite3/minimum/libsqlite3.dylib dart test -P skip_slow + dart test -P ci build_stable_rust: runs-on: ubuntu-latest @@ -190,7 +180,6 @@ jobs: working-directory: dart run: | dart pub get - dart run tool/download_sqlite3.dart dart analyze - name: Compile with stable Rust @@ -199,9 +188,7 @@ jobs: - name: Dart tests with stable Rust working-directory: dart - run: | - CORE_TEST_SQLITE=.dart_tool/sqlite3/latest/libsqlite3.so dart test - CORE_TEST_SQLITE=.dart_tool/sqlite3/minimum/libsqlite3.so dart test + run: dart test valgrind: name: Testing with Valgrind on ${{ matrix.os }} diff --git a/dart/dart_test.yaml b/dart/dart_test.yaml index 3727c8d7..8079b195 100644 --- a/dart/dart_test.yaml +++ b/dart/dart_test.yaml @@ -2,5 +2,10 @@ tags: slow: presets: - skip_slow: - exclude_tags: slow + ci: + # The macOS runners on GitHub are quite slow, so we only run slow tests on Linux + on_os: + mac-os: + tags: + slow: + skip: "Skipping slow tests on GH actions macOS runners" diff --git a/dart/pubspec.lock b/dart/pubspec.lock index f1e15419..53e52e23 100644 --- a/dart/pubspec.lock +++ b/dart/pubspec.lock @@ -5,18 +5,18 @@ packages: dependency: transitive description: name: _fe_analyzer_shared - sha256: da0d9209ca76bde579f2da330aeb9df62b6319c834fa7baae052021b0462401f + sha256: "8d7ff3948166b8ec5da0fbb5962000926b8e02f2ed9b3e51d1738905fbd4c98d" url: "https://pub.dev" source: hosted - version: "85.0.0" + version: "93.0.0" analyzer: dependency: transitive description: name: analyzer - sha256: de617bfdc64f3d8b00835ec2957441ceca0a29cdf7881f7ab231bc14f71159c0 + sha256: "92584d8f77b0095cb0cc7041dd4baea8bb3ec1a5a5f84037c93b1cf414942633" url: "https://pub.dev" source: hosted - version: "7.5.6" + version: "10.0.0" archive: dependency: "direct dev" description: @@ -73,6 +73,14 @@ packages: url: "https://pub.dev" source: hosted version: "1.1.2" + code_assets: + dependency: transitive + description: + name: code_assets + sha256: "83ccdaa064c980b5596c35dd64a8d3ecc68620174ab9b90b6343b753aa721687" + url: "https://pub.dev" + source: hosted + version: "1.0.0" collection: dependency: transitive description: @@ -101,10 +109,10 @@ packages: dependency: transitive description: name: crypto - sha256: "1e445881f28f22d6140f181e07737b22f1e099a5e1ff94b0af2f9e4a463f4855" + sha256: c8ea0233063ba03258fbcf2ca4d6dadfefe14f02fab57702265467a19f27fadf url: "https://pub.dev" source: hosted - version: "3.0.6" + version: "3.0.7" decimal: dependency: transitive description: @@ -125,10 +133,10 @@ packages: dependency: transitive description: name: ffi - sha256: "289279317b4b16eb2bb7e271abccd4bf84ec9bdcbe999e278a94b804f5630418" + sha256: d07d37192dbf97461359c1518788f203b0c9102cfd2c35a716b823741219542c url: "https://pub.dev" source: hosted - version: "2.1.4" + version: "2.1.5" file: dependency: "direct dev" description: @@ -161,14 +169,22 @@ packages: url: "https://pub.dev" source: hosted version: "2.1.3" + hooks: + dependency: transitive + description: + name: hooks + sha256: "5d309c86e7ce34cd8e37aa71cb30cb652d3829b900ab145e4d9da564b31d59f7" + url: "https://pub.dev" + source: hosted + version: "1.0.0" http: dependency: "direct dev" description: name: http - sha256: bb2ce4590bc2667c96f318d68cac1b5a7987ec819351d32b1c987239a815e007 + sha256: "87721a4a50b19c7f1d49001e51409bddc46303966ce89a65af4f4e6004896412" url: "https://pub.dev" source: hosted - version: "1.5.0" + version: "1.6.0" http_multi_server: dependency: transitive description: @@ -201,14 +217,6 @@ packages: url: "https://pub.dev" source: hosted version: "1.0.5" - js: - dependency: transitive - description: - name: js - sha256: "53385261521cc4a0c4658fd0ad07a7d14591cf8fc33abbceae306ddb974888dc" - url: "https://pub.dev" - source: hosted - version: "0.7.2" logging: dependency: transitive description: @@ -221,10 +229,10 @@ packages: dependency: transitive description: name: matcher - sha256: dc58c723c3c24bf8d3e2d3ad3f2f9d7bd9cf43ec6feaa64181775e60190153f2 + sha256: "12956d0ad8390bbcc63ca2e1469c0619946ccb52809807067a7020d57e647aa6" url: "https://pub.dev" source: hosted - version: "0.12.17" + version: "0.12.18" meta: dependency: "direct dev" description: @@ -241,6 +249,14 @@ packages: url: "https://pub.dev" source: hosted version: "2.0.0" + native_toolchain_c: + dependency: transitive + description: + name: native_toolchain_c + sha256: "89e83885ba09da5fdf2cdacc8002a712ca238c28b7f717910b34bcd27b0d03ac" + url: "https://pub.dev" + source: hosted + version: "0.17.4" node_preamble: dependency: transitive description: @@ -277,10 +293,10 @@ packages: dependency: transitive description: name: pool - sha256: "20fe868b6314b322ea036ba325e6fc0711a22948856475e2c2b6306e8ab39c2a" + sha256: "978783255c543aa3586a1b3c21f6e9d720eb315376a915872c61ef8b5c20177d" url: "https://pub.dev" source: hosted - version: "1.5.1" + version: "1.5.2" posix: dependency: transitive description: @@ -369,30 +385,22 @@ packages: url: "https://pub.dev" source: hosted version: "1.10.1" - sprintf: - dependency: transitive - description: - name: sprintf - sha256: "1fc9ffe69d4df602376b52949af107d8f5703b77cda567c4d7d86a0693120f23" - url: "https://pub.dev" - source: hosted - version: "7.0.0" sqlite3: dependency: "direct main" description: name: sqlite3 - sha256: c0503c69b44d5714e6abbf4c1f51a3c3cc42b75ce785f44404765e4635481d38 + sha256: "00e5e65f8e9b556ed3d999ad310881c956ffb656ed96bea487a4c50ffdff6d14" url: "https://pub.dev" source: hosted - version: "2.7.6" + version: "3.1.3" sqlite3_test: dependency: "direct dev" description: name: sqlite3_test - sha256: "0b6f76541385cbe0cebf9454854f78dc9aa18b8cb512d8e597e63385e61d4f45" + sha256: "88ba427a61d6b46f00d942a07615a5a4d0ce8665e38075f92afe6c9ec1c9a3bb" url: "https://pub.dev" source: hosted - version: "0.1.1" + version: "0.2.0" stack_trace: dependency: transitive description: @@ -429,26 +437,26 @@ packages: dependency: "direct dev" description: name: test - sha256: "65e29d831719be0591f7b3b1a32a3cda258ec98c58c7b25f7b84241bc31215bb" + sha256: "54c516bbb7cee2754d327ad4fca637f78abfc3cbcc5ace83b3eda117e42cd71a" url: "https://pub.dev" source: hosted - version: "1.26.2" + version: "1.29.0" test_api: dependency: transitive description: name: test_api - sha256: "522f00f556e73044315fa4585ec3270f1808a4b186c936e612cab0b565ff1e00" + sha256: "93167629bfc610f71560ab9312acdda4959de4df6fac7492c89ff0d3886f6636" url: "https://pub.dev" source: hosted - version: "0.7.6" + version: "0.7.9" test_core: dependency: transitive description: name: test_core - sha256: "80bf5a02b60af04b09e14f6fe68b921aad119493e26e490deaca5993fef1b05a" + sha256: "394f07d21f0f2255ec9e3989f21e54d3c7dc0e6e9dbce160e5a9c1a6be0e2943" url: "https://pub.dev" source: hosted - version: "0.6.11" + version: "0.6.15" test_descriptor: dependency: "direct dev" description: @@ -469,10 +477,10 @@ packages: dependency: transitive description: name: uuid - sha256: a5be9ef6618a7ac1e964353ef476418026db906c4facdedaa299b7a2e71690ff + sha256: a11b666489b1954e01d992f3d601b1804a33937b5a8fe677bd26b8a9f96f96e8 url: "https://pub.dev" source: hosted - version: "4.5.1" + version: "4.5.2" vm_service: dependency: transitive description: @@ -485,10 +493,10 @@ packages: dependency: transitive description: name: watcher - sha256: "0b7fd4a0bbc4b92641dbf20adfd7e3fd1398fe17102d94b674234563e110088a" + sha256: "1398c9f081a753f9226febe8900fce8f7d0a67163334e1c94a2438339d79d635" url: "https://pub.dev" source: hosted - version: "1.1.2" + version: "1.2.1" web: dependency: transitive description: @@ -530,4 +538,4 @@ packages: source: hosted version: "3.1.3" sdks: - dart: ">=3.7.0 <4.0.0" + dart: ">=3.9.999 <4.0.0" diff --git a/dart/pubspec.yaml b/dart/pubspec.yaml index 12a25c8a..1a798d7b 100644 --- a/dart/pubspec.yaml +++ b/dart/pubspec.yaml @@ -5,14 +5,14 @@ description: Tests for powersync-sqlite-core environment: sdk: ^3.4.0 dependencies: - sqlite3: ^2.7.6 + sqlite3: ^3.0.0 bson: ^5.0.5 dev_dependencies: test: ^1.25.0 test_descriptor: ^2.0.2 file: ^7.0.1 - sqlite3_test: ^0.1.1 + sqlite3_test: ^0.2.0 fake_async: ^1.3.3 convert: ^3.1.2 meta: ^1.16.0 diff --git a/dart/test/crud_test.dart b/dart/test/crud_test.dart index fc9c9e90..ec5e152d 100644 --- a/dart/test/crud_test.dart +++ b/dart/test/crud_test.dart @@ -14,7 +14,7 @@ void main() { }); tearDown(() { - db.dispose(); + db.close(); }); test('powersync_diff - single value', () { diff --git a/dart/test/error_test.dart b/dart/test/error_test.dart index 550bf5de..19e71683 100644 --- a/dart/test/error_test.dart +++ b/dart/test/error_test.dart @@ -13,7 +13,7 @@ void main() { }); tearDown(() { - db.dispose(); + db.close(); }); test('contain inner SQLite descriptions', () { diff --git a/dart/test/js_key_encoding_test.dart b/dart/test/js_key_encoding_test.dart index dd86e062..70299825 100644 --- a/dart/test/js_key_encoding_test.dart +++ b/dart/test/js_key_encoding_test.dart @@ -27,7 +27,7 @@ void main() { }); tearDown(() { - db.dispose(); + db.close(); }); test('can fix JS key encoding', () { diff --git a/dart/test/legacy_sync_test.dart b/dart/test/legacy_sync_test.dart index e67f7bb7..6eeffad3 100644 --- a/dart/test/legacy_sync_test.dart +++ b/dart/test/legacy_sync_test.dart @@ -31,7 +31,7 @@ void main() { }); tearDown(() { - db.dispose(); + db.close(); }); void pushSyncData( diff --git a/dart/test/migration_test.dart b/dart/test/migration_test.dart index b18d166f..f3a71a0f 100644 --- a/dart/test/migration_test.dart +++ b/dart/test/migration_test.dart @@ -23,7 +23,7 @@ void main() { }); tearDown(() { - db.dispose(); + db.close(); }); /// This tests that the extension can load diff --git a/dart/test/schema_test.dart b/dart/test/schema_test.dart index 995e6937..d54686e4 100644 --- a/dart/test/schema_test.dart +++ b/dart/test/schema_test.dart @@ -13,7 +13,7 @@ void main() { }); tearDown(() { - db.dispose(); + db.close(); }); group('Schema Tests', () { diff --git a/dart/test/sync_local_performance_test.dart b/dart/test/sync_local_performance_test.dart index 2db4fa5c..b5a0707e 100644 --- a/dart/test/sync_local_performance_test.dart +++ b/dart/test/sync_local_performance_test.dart @@ -40,7 +40,7 @@ void testFilesystemOperations( }); tearDown(() { - db.dispose(); + db.close(); sqlite3.unregisterVirtualFileSystem(vfs); }); diff --git a/dart/test/sync_stream_test.dart b/dart/test/sync_stream_test.dart index cf1f5dca..fce8719a 100644 --- a/dart/test/sync_stream_test.dart +++ b/dart/test/sync_stream_test.dart @@ -31,7 +31,7 @@ void main() { }); tearDown(() { - db.dispose(); + db.close(); }); List control(String operation, Object? data) { diff --git a/dart/test/sync_test.dart b/dart/test/sync_test.dart index 32ec3dea..68c320fc 100644 --- a/dart/test/sync_test.dart +++ b/dart/test/sync_test.dart @@ -85,7 +85,7 @@ void _syncTests({ tearDown(() { matcher.finish(); - db.dispose(); + db.close(); }); List syncLine(Object? line) { diff --git a/dart/test/update_hooks_test.dart b/dart/test/update_hooks_test.dart index 50a26d59..79bae0e2 100644 --- a/dart/test/update_hooks_test.dart +++ b/dart/test/update_hooks_test.dart @@ -16,7 +16,7 @@ void main() { }); tearDown(() { - db.dispose(); + db.close(); }); List collectUpdates() { @@ -38,7 +38,7 @@ void main() { for (var i = 0; i < 1000; i++) { stmt.execute([i]); } - stmt.dispose(); + stmt.close(); expect(collectUpdates(), ['foo']); }); diff --git a/dart/test/utils/native_test_utils.dart b/dart/test/utils/native_test_utils.dart index ea530934..0216efae 100644 --- a/dart/test/utils/native_test_utils.dart +++ b/dart/test/utils/native_test_utils.dart @@ -4,7 +4,6 @@ import 'dart:io'; import 'package:fake_async/fake_async.dart'; import 'package:meta/meta.dart'; import 'package:sqlite3/common.dart'; -import 'package:sqlite3/open.dart' as sqlite_open; import 'package:sqlite3/sqlite3.dart'; import 'package:path/path.dart' as p; import 'package:test/test.dart'; @@ -14,29 +13,8 @@ const defaultSqlitePath = 'libsqlite3.so.0'; const cargoDebugPath = '../target/debug'; var didLoadExtension = false; -void applyOpenOverride() { - if (Platform.environment['CORE_TEST_SQLITE'] case final sqlite?) { - sqlite_open.open - .overrideForAll(() => DynamicLibrary.open(p.absolute(sqlite))); - } - - sqlite_open.open.overrideFor(sqlite_open.OperatingSystem.linux, () { - return DynamicLibrary.open('libsqlite3.so.0'); - }); - sqlite_open.open.overrideFor(sqlite_open.OperatingSystem.macOS, () { - // Prefer using Homebrew's SQLite which allows loading extensions. - const fromHomebrew = '/opt/homebrew/opt/sqlite/lib/libsqlite3.dylib'; - if (File(fromHomebrew).existsSync()) { - return DynamicLibrary.open(fromHomebrew); - } - - return DynamicLibrary.open('libsqlite3.dylib'); - }); -} - CommonDatabase openTestDatabase( {VirtualFileSystem? vfs, String fileName = ':memory:'}) { - applyOpenOverride(); if (!didLoadExtension) { loadExtension(); } @@ -45,8 +23,6 @@ CommonDatabase openTestDatabase( } void loadExtension() { - applyOpenOverride(); - // Using an absolute path is required for macOS, where Dart can't dlopen // relative paths due to being a "hardened program". var lib = diff --git a/dart/tool/download_sqlite3.dart b/dart/tool/download_sqlite3.dart deleted file mode 100644 index 3215fd12..00000000 --- a/dart/tool/download_sqlite3.dart +++ /dev/null @@ -1,136 +0,0 @@ -import 'dart:ffi'; -import 'dart:io'; - -import 'package:archive/archive_io.dart'; -import 'package:path/path.dart' as p; -import 'package:http/http.dart'; - -typedef SqliteVersion = ({String version, String year}); - -const SqliteVersion latest = (version: '3500200', year: '2025'); -const SqliteVersion minimum = (version: '3440000', year: '2023'); - -Future main(List args) async { - if (args.contains('version')) { - print(latest.version); - exit(0); - } - - await _downloadAndCompile('latest', latest, force: args.contains('--force')); - await _downloadAndCompile('minimum', minimum, - force: args.contains('--force')); -} - -extension on SqliteVersion { - String get autoconfUrl => - 'https://sqlite.org/$year/sqlite-autoconf-$version.tar.gz'; - - String get windowsArm64Url => - 'https://sqlite.org/$year/sqlite-dll-win-arm64-$version.zip'; - - String get windowsX64Url => - 'https://sqlite.org/$year/sqlite-dll-win-x64-$version.zip'; -} - -Future _downloadAndCompile(String name, SqliteVersion version, - {bool force = false}) async { - final dartDirectory = p.dirname(p.dirname(Platform.script.toFilePath())); - final target = p.join(dartDirectory, '.dart_tool', 'sqlite3', name); - final versionFile = File(p.join(target, 'version')); - - final needsDownload = force || - !versionFile.existsSync() || - versionFile.readAsStringSync() != version.version; - - if (!needsDownload) { - print( - 'Not downloading sqlite3 $name as it has already been downloaded. Use ' - '--force to re-compile it.', - ); - return; - } - - print('Downloading and compiling sqlite3 $name (${version.version})'); - final targetDirectory = Directory(target); - - if (!targetDirectory.existsSync()) { - targetDirectory.createSync(recursive: true); - } - - final temporaryDir = - await Directory.systemTemp.createTemp('powersync-core-compile-sqlite3'); - final temporaryDirPath = temporaryDir.path; - - // Compiling on Windows is ugly because we need users to have Visual Studio - // installed and all those tools activated in the current shell. - // Much easier to just download precompiled builds. - if (Platform.isWindows) { - final windowsUri = Abi.current() == Abi.windowsX64 - ? version.windowsX64Url - : version.windowsArm64Url; - final sqlite3Zip = p.join(temporaryDirPath, 'sqlite3.zip'); - final client = Client(); - final response = await client - .send(Request('GET', Uri.parse(windowsUri))..followRedirects = true); - if (response.statusCode != 200) { - print( - 'Could not download $windowsUri, status code ${response.statusCode}'); - exit(1); - } - await response.stream.pipe(File(sqlite3Zip).openWrite()); - - final inputStream = InputFileStream(sqlite3Zip); - final archive = ZipDecoder().decodeStream(inputStream); - - for (final file in archive.files) { - if (file.isFile && file.name == 'sqlite3.dll') { - final outputStream = OutputFileStream(p.join(target, 'sqlite3.dll')); - - file.writeContent(outputStream); - outputStream.close(); - } - } - - await File(p.join(target, 'version')).writeAsString(version.version); - exit(0); - } - - await _run('curl -L ${version.autoconfUrl} --output sqlite.tar.gz', - workingDirectory: temporaryDirPath); - await _run('tar zxvf sqlite.tar.gz', workingDirectory: temporaryDirPath); - - final sqlitePath = - p.join(temporaryDirPath, 'sqlite-autoconf-${version.version}'); - - await _run('./configure', workingDirectory: sqlitePath); - await _run('make -j', workingDirectory: sqlitePath); - - await File(p.join(sqlitePath, 'sqlite3')).copy(p.join(target, 'sqlite3')); - final libsPath = name == 'latest' ? sqlitePath : p.join(sqlitePath, '.libs'); - - if (Platform.isLinux) { - await File(p.join(libsPath, 'libsqlite3.so')) - .copy(p.join(target, 'libsqlite3.so')); - } else if (Platform.isMacOS) { - await File(p.join(libsPath, 'libsqlite3.dylib')) - .copy(p.join(target, 'libsqlite3.dylib')); - } - - await File(p.join(target, 'version')).writeAsString(version.version); -} - -Future _run(String command, {String? workingDirectory}) async { - print('Running $command'); - - final proc = await Process.start( - 'sh', - ['-c', command], - mode: ProcessStartMode.inheritStdio, - workingDirectory: workingDirectory, - ); - final exitCode = await proc.exitCode; - - if (exitCode != 0) { - exit(exitCode); - } -} From 74cc60eae3dff1178c48dfefd14a35fb4172a4bb Mon Sep 17 00:00:00 2001 From: Simon Binder Date: Thu, 15 Jan 2026 16:07:31 +0100 Subject: [PATCH 2/5] Cache hook output --- .github/workflows/tests.yml | 26 ++++++++++++-------------- 1 file changed, 12 insertions(+), 14 deletions(-) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 209da71f..9fe28612 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -121,19 +121,17 @@ jobs: - uses: dart-lang/setup-dart@v1 - - uses: actions/cache@v4 - id: sqlite_build - with: - path: dart/.dart_tool/sqlite3/ - key: ${{ matrix.os }}-${{ hashFiles('dart/tool/') }} - - name: Setup Dart tests working-directory: dart run: | dart pub get - dart run tool/download_old_sqlite3.dart dart analyze - + - uses: actions/cache@v4 + with: + path: dart/.dart_tool/hooks_runner/ + key: hooks-${{ matrix.os }}-${{ hashFiles('dart/pubspec.lock') }} + restore-keys: hooks-${{ matrix.os }} + - name: Download libs uses: actions/download-artifact@v5 with: @@ -170,18 +168,18 @@ jobs: - name: Install Rust Stable uses: dtolnay/rust-toolchain@stable - - uses: actions/cache@v4 - id: sqlite_build - with: - path: dart/.dart_tool/sqlite3/ - key: ${{ matrix.os }}-${{ hashFiles('dart/tool/') }} - - name: Setup Dart tests working-directory: dart run: | dart pub get dart analyze + - uses: actions/cache@v4 + with: + path: dart/.dart_tool/hooks_runner/ + key: hooks-${{ matrix.os }}-${{ hashFiles('dart/pubspec.lock') }} + restore-keys: hooks-${{ matrix.os }} + - name: Compile with stable Rust run: | cargo +stable build -p powersync_loadable From e4e12043bf6f8c790d091539653d5cbee8b08b38 Mon Sep 17 00:00:00 2001 From: Simon Binder Date: Thu, 15 Jan 2026 16:16:56 +0100 Subject: [PATCH 3/5] Register close hook when opening db --- dart/test/crud_test.dart | 4 ---- dart/test/error_test.dart | 4 ---- dart/test/js_key_encoding_test.dart | 4 ---- dart/test/legacy_sync_test.dart | 4 ---- dart/test/migration_test.dart | 4 ---- dart/test/schema_test.dart | 4 ---- dart/test/sync_local_performance_test.dart | 1 - dart/test/sync_stream_test.dart | 4 ---- dart/test/sync_test.dart | 1 - dart/test/update_hooks_test.dart | 4 ---- dart/test/utils/native_test_utils.dart | 4 +++- 11 files changed, 3 insertions(+), 35 deletions(-) diff --git a/dart/test/crud_test.dart b/dart/test/crud_test.dart index ec5e152d..0f1c90e1 100644 --- a/dart/test/crud_test.dart +++ b/dart/test/crud_test.dart @@ -13,10 +13,6 @@ void main() { db = openTestDatabase(); }); - tearDown(() { - db.close(); - }); - test('powersync_diff - single value', () { var r1 = db.select('select powersync_diff(?, ?) as diff', ['{}', '{}']).first; diff --git a/dart/test/error_test.dart b/dart/test/error_test.dart index 19e71683..57403df1 100644 --- a/dart/test/error_test.dart +++ b/dart/test/error_test.dart @@ -12,10 +12,6 @@ void main() { db = openTestDatabase(); }); - tearDown(() { - db.close(); - }); - test('contain inner SQLite descriptions', () { // Create a wrong migrations table for the core extension to trip over. db.execute('CREATE TABLE IF NOT EXISTS ps_migration(foo TEXT)'); diff --git a/dart/test/js_key_encoding_test.dart b/dart/test/js_key_encoding_test.dart index 70299825..f084b813 100644 --- a/dart/test/js_key_encoding_test.dart +++ b/dart/test/js_key_encoding_test.dart @@ -26,10 +26,6 @@ void main() { ..select('select powersync_replace_schema(?)', [json.encode(_schema)]); }); - tearDown(() { - db.close(); - }); - test('can fix JS key encoding', () { db.execute('insert into powersync_operations (op, data) VALUES (?, ?);', [ 'save', diff --git a/dart/test/legacy_sync_test.dart b/dart/test/legacy_sync_test.dart index 6eeffad3..f2484105 100644 --- a/dart/test/legacy_sync_test.dart +++ b/dart/test/legacy_sync_test.dart @@ -30,10 +30,6 @@ void main() { ..select('select powersync_replace_schema(?)', [json.encode(_schema)]); }); - tearDown(() { - db.close(); - }); - void pushSyncData( String bucket, String opId, diff --git a/dart/test/migration_test.dart b/dart/test/migration_test.dart index f3a71a0f..9455e8e4 100644 --- a/dart/test/migration_test.dart +++ b/dart/test/migration_test.dart @@ -22,10 +22,6 @@ void main() { db = openTestDatabase(); }); - tearDown(() { - db.close(); - }); - /// This tests that the extension can load test('extension setup', () async { final row1 = db.select('select sqlite_version() as version').first; diff --git a/dart/test/schema_test.dart b/dart/test/schema_test.dart index d54686e4..357468f8 100644 --- a/dart/test/schema_test.dart +++ b/dart/test/schema_test.dart @@ -12,10 +12,6 @@ void main() { db = openTestDatabase(); }); - tearDown(() { - db.close(); - }); - group('Schema Tests', () { test('Schema versioning', () { // Test that powersync_replace_schema() is a no-op when the schema is not diff --git a/dart/test/sync_local_performance_test.dart b/dart/test/sync_local_performance_test.dart index b5a0707e..46a49252 100644 --- a/dart/test/sync_local_performance_test.dart +++ b/dart/test/sync_local_performance_test.dart @@ -40,7 +40,6 @@ void testFilesystemOperations( }); tearDown(() { - db.close(); sqlite3.unregisterVirtualFileSystem(vfs); }); diff --git a/dart/test/sync_stream_test.dart b/dart/test/sync_stream_test.dart index fce8719a..a7bf90de 100644 --- a/dart/test/sync_stream_test.dart +++ b/dart/test/sync_stream_test.dart @@ -30,10 +30,6 @@ void main() { ['client_id', 'test-test-test-test']); }); - tearDown(() { - db.close(); - }); - List control(String operation, Object? data) { db.execute('begin'); ResultSet result; diff --git a/dart/test/sync_test.dart b/dart/test/sync_test.dart index 68c320fc..be335ff8 100644 --- a/dart/test/sync_test.dart +++ b/dart/test/sync_test.dart @@ -85,7 +85,6 @@ void _syncTests({ tearDown(() { matcher.finish(); - db.close(); }); List syncLine(Object? line) { diff --git a/dart/test/update_hooks_test.dart b/dart/test/update_hooks_test.dart index 79bae0e2..1d36503d 100644 --- a/dart/test/update_hooks_test.dart +++ b/dart/test/update_hooks_test.dart @@ -15,10 +15,6 @@ void main() { ..select("SELECT powersync_update_hooks('install')"); }); - tearDown(() { - db.close(); - }); - List collectUpdates() { final [row] = db.select("SELECT powersync_update_hooks('get')"); return (json.decode(row.values[0] as String) as List).cast(); diff --git a/dart/test/utils/native_test_utils.dart b/dart/test/utils/native_test_utils.dart index 0216efae..8cb1412e 100644 --- a/dart/test/utils/native_test_utils.dart +++ b/dart/test/utils/native_test_utils.dart @@ -19,7 +19,9 @@ CommonDatabase openTestDatabase( loadExtension(); } - return sqlite3.open(fileName, vfs: vfs?.name); + final db = sqlite3.open(fileName, vfs: vfs?.name); + addTearDown(db.close); + return db; } void loadExtension() { From c289418fbf3bd8eb2a86b2ef1c62a80470b59321 Mon Sep 17 00:00:00 2001 From: Simon Binder Date: Thu, 22 Jan 2026 10:08:51 +0100 Subject: [PATCH 4/5] Enable statement vtab --- dart/pubspec.lock | 24 ---------------------- dart/pubspec.yaml | 14 +++++++++++-- dart/test/error_test.dart | 1 + dart/test/js_key_encoding_test.dart | 14 +------------ dart/test/sync_local_performance_test.dart | 4 ++-- dart/test/sync_test.dart | 7 +++---- 6 files changed, 19 insertions(+), 45 deletions(-) diff --git a/dart/pubspec.lock b/dart/pubspec.lock index 53e52e23..f1c1e56a 100644 --- a/dart/pubspec.lock +++ b/dart/pubspec.lock @@ -17,14 +17,6 @@ packages: url: "https://pub.dev" source: hosted version: "10.0.0" - archive: - dependency: "direct dev" - description: - name: archive - sha256: "2fde1607386ab523f7a36bb3e7edb43bd58e6edaf2ffb29d8a6d578b297fdbbd" - url: "https://pub.dev" - source: hosted - version: "4.0.7" args: dependency: transitive description: @@ -177,14 +169,6 @@ packages: url: "https://pub.dev" source: hosted version: "1.0.0" - http: - dependency: "direct dev" - description: - name: http - sha256: "87721a4a50b19c7f1d49001e51409bddc46303966ce89a65af4f4e6004896412" - url: "https://pub.dev" - source: hosted - version: "1.6.0" http_multi_server: dependency: transitive description: @@ -297,14 +281,6 @@ packages: url: "https://pub.dev" source: hosted version: "1.5.2" - posix: - dependency: transitive - description: - name: posix - sha256: "6323a5b0fa688b6a010df4905a56b00181479e6d10534cecfecede2aa55add61" - url: "https://pub.dev" - source: hosted - version: "6.0.3" power_extensions: dependency: transitive description: diff --git a/dart/pubspec.yaml b/dart/pubspec.yaml index 1a798d7b..f24fb86d 100644 --- a/dart/pubspec.yaml +++ b/dart/pubspec.yaml @@ -4,6 +4,7 @@ version: 0.0.1 description: Tests for powersync-sqlite-core environment: sdk: ^3.4.0 + dependencies: sqlite3: ^3.0.0 bson: ^5.0.5 @@ -17,5 +18,14 @@ dev_dependencies: convert: ^3.1.2 meta: ^1.16.0 path: ^1.9.1 - http: ^1.5.0 - archive: ^4.0.7 + +# See https://pub.dev/documentation/sqlite3/latest/topics/hook-topic.html +hooks: + user_defines: + sqlite3: + source: source + path: ../crates/sqlite/sqlite/sqlite3.c + # Used in sync_test.dart to ensure the core extension dosn't leave any + # busy statements behind. + defines: + - SQLITE_ENABLE_STMTVTAB diff --git a/dart/test/error_test.dart b/dart/test/error_test.dart index 57403df1..62a9bf69 100644 --- a/dart/test/error_test.dart +++ b/dart/test/error_test.dart @@ -55,6 +55,7 @@ void main() { 'powersync_control: Sync protocol error: invalid text line. cause: expected value at line 1 column 1', )), ); + control.close(); }); }); }); diff --git a/dart/test/js_key_encoding_test.dart b/dart/test/js_key_encoding_test.dart index f084b813..0b281162 100644 --- a/dart/test/js_key_encoding_test.dart +++ b/dart/test/js_key_encoding_test.dart @@ -1,27 +1,15 @@ import 'dart:convert'; -import 'package:file/local.dart'; import 'package:sqlite3/common.dart'; -import 'package:sqlite3/sqlite3.dart'; -import 'package:sqlite3_test/sqlite3_test.dart'; import 'package:test/test.dart'; import 'utils/native_test_utils.dart'; void main() { - // Needs an unique name per test file to avoid concurrency issues - final vfs = TestSqliteFileSystem( - fs: const LocalFileSystem(), name: 'js-key-encoding-test-vfs'); late CommonDatabase db; - setUpAll(() { - loadExtension(); - sqlite3.registerVirtualFileSystem(vfs, makeDefault: false); - }); - tearDownAll(() => sqlite3.unregisterVirtualFileSystem(vfs)); - setUp(() async { - db = openTestDatabase(vfs: vfs) + db = openTestDatabase() ..select('select powersync_init();') ..select('select powersync_replace_schema(?)', [json.encode(_schema)]); }); diff --git a/dart/test/sync_local_performance_test.dart b/dart/test/sync_local_performance_test.dart index 46a49252..ec0f5ba3 100644 --- a/dart/test/sync_local_performance_test.dart +++ b/dart/test/sync_local_performance_test.dart @@ -33,8 +33,8 @@ void testFilesystemOperations( setUp(() async { // Needs an unique name per test file to avoid concurrency issues - vfs = new TrackingFileSystem( - parent: new InMemoryFileSystem(), name: 'perf-test-vfs'); + vfs = + TrackingFileSystem(parent: InMemoryFileSystem(), name: 'perf-test-vfs'); sqlite3.registerVirtualFileSystem(vfs, makeDefault: false); db = openTestDatabase(vfs: vfs, fileName: 'test.db'); }); diff --git a/dart/test/sync_test.dart b/dart/test/sync_test.dart index be335ff8..8d0847dd 100644 --- a/dart/test/sync_test.dart +++ b/dart/test/sync_test.dart @@ -50,10 +50,9 @@ void _syncTests({ // Make sure that powersync_control doesn't leave any busy statements // behind. - // TODO: Re-enable after we can guarantee sqlite_stmt being available - // const statement = 'SELECT * FROM sqlite_stmt WHERE busy AND sql != ?;'; - // final busy = db.select(statement, [statement]); - // expect(busy, isEmpty); + const statement = 'SELECT * FROM sqlite_stmt WHERE busy AND sql != ?;'; + final busy = db.select(statement, [statement]); + expect(busy, isEmpty); } catch (e) { db.execute('rollback'); rethrow; From 571409b7ff6ee341288846237640479d5fa76f28 Mon Sep 17 00:00:00 2001 From: Simon Binder Date: Thu, 22 Jan 2026 12:32:34 +0100 Subject: [PATCH 5/5] Update sqlite3 package --- dart/pubspec.lock | 12 ++++++------ dart/pubspec.yaml | 2 +- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/dart/pubspec.lock b/dart/pubspec.lock index f1c1e56a..858f1601 100644 --- a/dart/pubspec.lock +++ b/dart/pubspec.lock @@ -13,10 +13,10 @@ packages: dependency: transitive description: name: analyzer - sha256: "92584d8f77b0095cb0cc7041dd4baea8bb3ec1a5a5f84037c93b1cf414942633" + sha256: de7148ed2fcec579b19f122c1800933dfa028f6d9fd38a152b04b1516cec120b url: "https://pub.dev" source: hosted - version: "10.0.0" + version: "10.0.1" args: dependency: transitive description: @@ -221,10 +221,10 @@ packages: dependency: "direct dev" description: name: meta - sha256: "23f08335362185a5ea2ad3a4e597f1375e78bce8a040df5c600c8d3552ef2394" + sha256: "1741988757a65eb6b36abe716829688cf01910bbf91c34354ff7ec1c3de2b349" url: "https://pub.dev" source: hosted - version: "1.17.0" + version: "1.18.0" mime: dependency: transitive description: @@ -365,10 +365,10 @@ packages: dependency: "direct main" description: name: sqlite3 - sha256: "00e5e65f8e9b556ed3d999ad310881c956ffb656ed96bea487a4c50ffdff6d14" + sha256: c6cfe9b1cc159c9eb8ba174b533a60b5126f9db8c6e34efb127d2bc04bc45034 url: "https://pub.dev" source: hosted - version: "3.1.3" + version: "3.1.4" sqlite3_test: dependency: "direct dev" description: diff --git a/dart/pubspec.yaml b/dart/pubspec.yaml index f24fb86d..ca5db351 100644 --- a/dart/pubspec.yaml +++ b/dart/pubspec.yaml @@ -6,7 +6,7 @@ environment: sdk: ^3.4.0 dependencies: - sqlite3: ^3.0.0 + sqlite3: ^3.1.4 bson: ^5.0.5 dev_dependencies: