1+ import 'dart:ffi' ;
12import 'dart:io' ;
23
34import 'package:powersync_core/powersync_core.dart' ;
45import 'package:path/path.dart' ;
6+ import 'package:powersync_core/sqlite3.dart' as sqlite;
7+ import 'package:powersync_core/sqlite3_common.dart' ;
8+ import 'package:powersync_core/sqlite_async.dart' ;
9+ import 'package:powersync_core/sqlite3_open.dart' as sqlite_open;
510
611const schema = Schema ([
712 Table ('customers' , [Column .text ('name' ), Column .text ('email' )])
@@ -25,13 +30,73 @@ class BackendConnector extends PowerSyncBackendConnector {
2530 }
2631}
2732
28- openDatabase () async {
33+ /// Custom factory to load the PowerSync extension.
34+ /// This is required to load the extension from a custom location.
35+ /// The extension is required to sync data with the backend.
36+ /// On macOS and Linux, the default sqlite3 library is overridden to load the extension.
37+ class PowerSyncDartOpenFactory extends PowerSyncOpenFactory {
38+ PowerSyncDartOpenFactory ({required super .path, super .sqliteOptions});
39+
40+ @override
41+ CommonDatabase open (SqliteOpenOptions options) {
42+ sqlite_open.open.overrideFor (sqlite_open.OperatingSystem .linux, () {
43+ return DynamicLibrary .open ('libsqlite3.so.0' );
44+ });
45+ sqlite_open.open.overrideFor (sqlite_open.OperatingSystem .macOS, () {
46+ return DynamicLibrary .open ('libsqlite3.dylib' );
47+ });
48+ return super .open (options);
49+ }
50+
51+ @override
52+ void enableExtension () {
53+ var powersyncLib = DynamicLibrary .open (getLibraryForPlatform ());
54+ sqlite.sqlite3.ensureExtensionLoaded (sqlite.SqliteExtension .inLibrary (
55+ powersyncLib, 'sqlite3_powersync_init' ));
56+ }
57+
58+ @override
59+ String getLibraryForPlatform ({String ? path = "." }) {
60+ switch (Abi .current ()) {
61+ case Abi .androidArm:
62+ case Abi .androidArm64:
63+ case Abi .androidX64:
64+ return '$path /libpowersync.so' ;
65+ case Abi .macosArm64:
66+ case Abi .macosX64:
67+ return '$path /libpowersync.dylib' ;
68+ case Abi .linuxX64:
69+ case Abi .linuxArm64:
70+ return '$path /libpowersync.so' ;
71+ case Abi .windowsX64:
72+ return '$path /powersync.dll' ;
73+ case Abi .androidIA32:
74+ throw PowersyncNotReadyException (
75+ 'Unsupported processor architecture. X86 Android emulators are not '
76+ 'supported. Please use an x86_64 emulator instead. All physical '
77+ 'Android devices are supported including 32bit ARM.' ,
78+ );
79+ default :
80+ throw PowersyncNotReadyException (
81+ 'Unsupported processor architecture "${Abi .current ()}". '
82+ 'Please open an issue on GitHub to request it.' ,
83+ );
84+ }
85+ }
86+ }
87+
88+ Future <String > getDatabasePath () async {
2989 const dbFilename = 'powersync-demo.db' ;
3090 final dir = (Directory .current.uri).toFilePath ();
31- var path = join (dir, dbFilename);
91+ return join (dir, dbFilename);
92+ }
3293
94+ openDatabase () async {
3395 // Setup the database.
34- db = PowerSyncDatabase (schema: schema, path: path);
96+ final psFactory = PowerSyncDartOpenFactory (path: await getDatabasePath ());
97+ db = PowerSyncDatabase .withFactory (psFactory, schema: schema);
98+
99+ // Initialise the database.
35100 await db.initialize ();
36101
37102 // Run local statements.
0 commit comments