Skip to content

Commit 0d8a1a8

Browse files
committed
Support SQLite libraries without auto-init
simolus3#277
1 parent 67e5e44 commit 0d8a1a8

File tree

11 files changed

+112
-13
lines changed

11 files changed

+112
-13
lines changed

.github/workflows/main.yml

Lines changed: 25 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,15 +15,15 @@ jobs:
1515
name: Compile sqlite3 for ${{ matrix.os }}
1616
runs-on: ${{ matrix.os }}
1717
env:
18-
SQLITE_YEAR: "2024"
19-
SQLITE_VERSION: "3470200"
18+
SQLITE_YEAR: "2025"
19+
SQLITE_VERSION: "3480000"
2020

2121
steps:
2222
- uses: actions/cache@v4
2323
id: cache_sqlite_build
2424
with:
2525
path: sqlite/out
26-
key: sqlite-v3-${{ runner.os }}-${{ env.SQLITE_VERSION }}
26+
key: sqlite-v4-${{ runner.os }}-${{ env.SQLITE_VERSION }}
2727
- name: Compile sqlite3 on Linux
2828
if: steps.cache_sqlite_build.outputs.cache-hit != 'true' && runner.os == 'Linux'
2929
run: |
@@ -38,6 +38,18 @@ jobs:
3838
cp sqlite3 ../out
3939
cp .libs/libsqlite3.so ../out
4040
cp *.h ../out
41+
- name: Compile sqlite3 on Linux (no autoinit)
42+
if: steps.cache_sqlite_build.outputs.cache-hit != 'true' && runner.os == 'Linux'
43+
working-directory: sqlite
44+
run: |
45+
curl https://www.sqlite.org/$SQLITE_YEAR/sqlite-amalgamation-$SQLITE_VERSION.zip --output sqlite.zip
46+
unzip sqlite.zip
47+
48+
cd sqlite-amalgamation-$SQLITE_VERSION
49+
gcc -DSQLITE_OMIT_AUTOINIT=1 -c -fPIC sqlite3.c -o sqlite3.o
50+
gcc -shared sqlite3.o -o libsqlite3.so
51+
mkdir ../out/without_autoinit
52+
cp libsqlite3.so ../out/without_autoinit
4153
- name: Compile sqlite3 on macOS
4254
if: steps.cache_sqlite_build.outputs.cache-hit != 'true' && runner.os == 'macOS'
4355
run: |
@@ -179,6 +191,16 @@ jobs:
179191
dart test -P ci
180192
working-directory: sqlite3/
181193

194+
- name: Test with SQLITE_OMIT_AUTOINIT
195+
if: runner.os == 'Linux'
196+
run: |
197+
ls $LD_LIBRARY_PATH
198+
dart run tool/check_compile_time_option.dart OMIT_AUTOINIT
199+
dart test -P ci
200+
env:
201+
LD_LIBRARY_PATH: ../sqlite/out/without_autoinit
202+
working-directory: sqlite3/
203+
182204
- name: Test sqlite3_test package
183205
run: |
184206
dart pub get

sqlite3/CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
- Fix out-of-bound reads in the `xWrite` implementation of the OPFS-locks based
44
file-system implementation when writing more than 64 KiB in one operation.
5+
- Support SQLite libraries compiled with `SQLITE_OMIT_AUTOINIT`.
56

67
## 2.6.0
78

sqlite3/assets/sqlite3.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
1+
// This file defines the definitions for which we generate FFI bindings on
2+
// native platforms. To re-generate bindings, run:
3+
// `dart run ffigen --config ffigen.yaml`.
14
#include <stdint.h>
25

36
typedef struct sqlite3_char sqlite3_char;
@@ -8,6 +11,8 @@ typedef struct sqlite3_api_routines sqlite3_api_routines;
811

912
sqlite3_char *sqlite3_temp_directory;
1013

14+
int sqlite3_initialize();
15+
1116
int sqlite3_open_v2(sqlite3_char *filename, sqlite3 **ppDb, int flags,
1217
sqlite3_char *zVfs);
1318
int sqlite3_close_v2(sqlite3 *db);

sqlite3/lib/src/ffi/bindings.dart

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,11 @@ final class FfiBindings extends RawSqliteBindings {
8484
}
8585
}
8686

87+
@override
88+
int sqlite3_initialize() {
89+
return bindings.bindings.sqlite3_initialize();
90+
}
91+
8792
@override
8893
String sqlite3_errstr(int extendedErrorCode) {
8994
return bindings.bindings.sqlite3_errstr(extendedErrorCode).readString();

sqlite3/lib/src/ffi/implementation.dart

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,8 @@ final class FfiSqlite3 extends Sqlite3Implementation implements Sqlite3 {
5151

5252
@override
5353
void ensureExtensionLoaded(SqliteExtension extension) {
54+
initialize();
55+
5456
final entrypoint = (extension as SqliteExtensionImpl)._resolveEntrypoint;
5557
final functionPtr = entrypoint(ffiBindings.bindings.library);
5658

sqlite3/lib/src/ffi/sqlite3.g.dart

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,15 @@ class Bindings {
2828
set sqlite3_temp_directory(ffi.Pointer<sqlite3_char> value) =>
2929
_sqlite3_temp_directory.value = value;
3030

31+
int sqlite3_initialize() {
32+
return _sqlite3_initialize();
33+
}
34+
35+
late final _sqlite3_initializePtr =
36+
_lookup<ffi.NativeFunction<ffi.Int Function()>>('sqlite3_initialize');
37+
late final _sqlite3_initialize =
38+
_sqlite3_initializePtr.asFunction<int Function()>();
39+
3140
int sqlite3_open_v2(
3241
ffi.Pointer<sqlite3_char> filename,
3342
ffi.Pointer<ffi.Pointer<sqlite3>> ppDb,

sqlite3/lib/src/implementation/bindings.dart

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,8 @@ abstract base class RawSqliteBindings {
4040

4141
void registerVirtualFileSystem(VirtualFileSystem vfs, int makeDefault);
4242
void unregisterVirtualFileSystem(VirtualFileSystem vfs);
43+
44+
int sqlite3_initialize();
4345
}
4446

4547
/// Combines a sqlite result code and the result object.

sqlite3/lib/src/implementation/sqlite3.dart

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import 'package:meta/meta.dart';
22

33
import '../constants.dart';
44
import '../database.dart';
5+
import '../exception.dart';
56
import '../sqlite3.dart';
67
import '../vfs.dart';
78
import 'bindings.dart';
@@ -24,12 +25,21 @@ base class Sqlite3Implementation implements CommonSqlite3 {
2425
@override
2526
set tempDirectory(String? value) => bindings.sqlite3_temp_directory = value;
2627

28+
void initialize() {
29+
final rc = bindings.sqlite3_initialize();
30+
if (rc != 0) {
31+
throw SqliteException(rc, 'Error returned by sqlite3_initialize');
32+
}
33+
}
34+
2735
@override
2836
CommonDatabase open(String filename,
2937
{String? vfs,
3038
OpenMode mode = OpenMode.readWriteCreate,
3139
bool uri = false,
3240
bool? mutex}) {
41+
initialize();
42+
3343
int flags;
3444
switch (mode) {
3545
case OpenMode.readOnly:

sqlite3/lib/src/wasm/bindings.dart

Lines changed: 3 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@ import 'dart:typed_data';
55
import 'package:sqlite3/src/vfs.dart';
66

77
import '../constants.dart';
8-
import '../exception.dart';
98
import '../functions.dart';
109
import '../implementation/bindings.dart';
1110
import 'wasm_interop.dart' as wasm;
@@ -56,8 +55,6 @@ final class WasmSqliteBindings extends RawSqliteBindings {
5655
@override
5756
SqliteResult<RawSqliteDatabase> sqlite3_open_v2(
5857
String name, int flags, String? zVfs) {
59-
sqlite3_initialize();
60-
6158
final namePtr = bindings.allocateZeroTerminated(name);
6259
final outDb = bindings.malloc(wasm.WasmBindings.pointerSize);
6360
final vfsPtr = zVfs == null ? 0 : bindings.allocateZeroTerminated(zVfs);
@@ -79,11 +76,9 @@ final class WasmSqliteBindings extends RawSqliteBindings {
7976
return bindings.memory.readString(bindings.sqlite3_sourceid());
8077
}
8178

82-
void sqlite3_initialize() {
83-
final rc = bindings.sqlite3_initialize();
84-
if (rc != 0) {
85-
throw SqliteException(rc, 'sqlite3_initialize call failed');
86-
}
79+
@override
80+
int sqlite3_initialize() {
81+
return bindings.sqlite3_initialize();
8782
}
8883

8984
@override
@@ -95,7 +90,6 @@ final class WasmSqliteBindings extends RawSqliteBindings {
9590
if (ptr == 0) {
9691
throw StateError('could not register vfs');
9792
}
98-
sqlite3_initialize();
9993
DartCallbacks.sqliteVfsPointer[vfs] = ptr;
10094
}
10195

sqlite3/test/source_code_test.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ import 'package:analyzer/dart/analysis/utilities.dart';
88
import 'package:test/test.dart';
99

1010
void main() {
11-
test('drift does not import legacy JS interop files', () {
11+
test('does not import legacy JS interop files', () {
1212
final failures = <(String, String)>[];
1313

1414
void check(FileSystemEntity e) {

0 commit comments

Comments
 (0)