1
+ import 'dart:ffi' ;
1
2
import 'dart:io' ;
2
3
3
4
import 'package:powersync_core/powersync_core.dart' ;
4
5
import '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;
5
10
6
11
const schema = Schema ([
7
12
Table ('customers' , [Column .text ('name' ), Column .text ('email' )])
@@ -25,13 +30,73 @@ class BackendConnector extends PowerSyncBackendConnector {
25
30
}
26
31
}
27
32
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 {
29
89
const dbFilename = 'powersync-demo.db' ;
30
90
final dir = (Directory .current.uri).toFilePath ();
31
- var path = join (dir, dbFilename);
91
+ return join (dir, dbFilename);
92
+ }
32
93
94
+ openDatabase () async {
33
95
// 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.
35
100
await db.initialize ();
36
101
37
102
// Run local statements.
0 commit comments