expo-sqlite 58.0.10 → 58.0.12
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +19 -0
- package/android/build.gradle +6 -2
- package/android/src/main/cpp/NativeDatabaseBinding.cpp +11 -8
- package/android/src/main/cpp/NativeStatementBinding.cpp +43 -2
- package/android/src/main/cpp/NativeStatementBinding.h +3 -0
- package/android/src/main/cpp/SQLiteError.h +34 -0
- package/android/src/main/java/expo/modules/sqlite/DatabaseConnection.kt +68 -0
- package/android/src/main/java/expo/modules/sqlite/NativeDatabase.kt +135 -22
- package/android/src/main/java/expo/modules/sqlite/NativeSession.kt +126 -6
- package/android/src/main/java/expo/modules/sqlite/NativeStatement.kt +199 -14
- package/android/src/main/java/expo/modules/sqlite/NativeStatementBinding.kt +1 -0
- package/android/src/main/java/expo/modules/sqlite/SQLRecords.kt +19 -13
- package/android/src/main/java/expo/modules/sqlite/SQLiteModule.kt +176 -577
- package/android/src/main/java/expo/modules/sqlite/SQLiteOptions.kt +3 -10
- package/android/src/main/java/expo/modules/sqlite/SQLiteValues.kt +47 -0
- package/build/NativeDatabase.d.ts +2 -2
- package/build/SQLiteDatabase.js +9 -3
- package/build/SQLiteDatabase.js.map +1 -1
- package/build/WebConfiguration.d.ts +31 -0
- package/build/WebConfiguration.js +21 -0
- package/build/WebConfiguration.js.map +1 -0
- package/build/index.d.ts +1 -0
- package/build/index.js +1 -0
- package/build/index.js.map +1 -1
- package/dev-plugin-dist/+not-found.html +2 -4
- package/dev-plugin-dist/_expo/static/js/web/{__common-9b94dd2fbdbb825a662f42cf8d2077ee.js → __common-3e95e247f8ee6d975454b07047f39148.js} +52 -48
- package/dev-plugin-dist/_expo/static/js/web/{_layout-b2894030c1dfbd95b717a85901b6c271.js → _layout-0bc906c56b363d38baf86696db19957e.js} +23 -23
- package/dev-plugin-dist/_expo/static/js/web/{entry-04fdb7d857a65c0ed638ef2d774a4b6e.js → entry-293efbd088ab66af1b3334c3eeafa61f.js} +697 -696
- package/dev-plugin-dist/_expo/static/js/web/{index-4bf2da199f699eb47a42074d5e183c07.js → index-454a4f95007576080f4f47d70441d41a.js} +1740 -1740
- package/dev-plugin-dist/_expo/static/js/web/{worker-d51aa6be89e271e571111274ab8e7f5c.js → worker-172ab4a50823f055f5bd777d90d1a36a.js} +17 -17
- package/dev-plugin-dist/_sitemap.html +2 -4
- package/dev-plugin-dist/index.html +2 -4
- package/expo-module.config.json +0 -4
- package/ios/DatabaseFileUtils.swift +101 -5
- package/ios/NativeDatabase.swift +5 -8
- package/ios/NativeStatement.swift +20 -13
- package/ios/SQLiteModule.swift +8 -2
- package/ios/SQLiteResult.swift +31 -0
- package/ios/Tests/DatabaseFileUtilsTests.swift +119 -0
- package/ios/Tests/test_ErrorReporting.swift +25 -0
- package/local-maven-repo/host/exp/exponent/expo.modules.sqlite/58.0.12/expo.modules.sqlite-58.0.12-sources.jar +0 -0
- package/local-maven-repo/host/exp/exponent/expo.modules.sqlite/58.0.12/expo.modules.sqlite-58.0.12-sources.jar.md5 +1 -0
- package/local-maven-repo/host/exp/exponent/expo.modules.sqlite/58.0.12/expo.modules.sqlite-58.0.12-sources.jar.sha1 +1 -0
- package/local-maven-repo/host/exp/exponent/expo.modules.sqlite/58.0.12/expo.modules.sqlite-58.0.12-sources.jar.sha256 +1 -0
- package/local-maven-repo/host/exp/exponent/expo.modules.sqlite/58.0.12/expo.modules.sqlite-58.0.12-sources.jar.sha512 +1 -0
- package/local-maven-repo/host/exp/exponent/expo.modules.sqlite/58.0.12/expo.modules.sqlite-58.0.12.aar +0 -0
- package/local-maven-repo/host/exp/exponent/expo.modules.sqlite/58.0.12/expo.modules.sqlite-58.0.12.aar.md5 +1 -0
- package/local-maven-repo/host/exp/exponent/expo.modules.sqlite/58.0.12/expo.modules.sqlite-58.0.12.aar.sha1 +1 -0
- package/local-maven-repo/host/exp/exponent/expo.modules.sqlite/58.0.12/expo.modules.sqlite-58.0.12.aar.sha256 +1 -0
- package/local-maven-repo/host/exp/exponent/expo.modules.sqlite/58.0.12/expo.modules.sqlite-58.0.12.aar.sha512 +1 -0
- package/local-maven-repo/host/exp/exponent/expo.modules.sqlite/{58.0.10/expo.modules.sqlite-58.0.10.module → 58.0.12/expo.modules.sqlite-58.0.12.module} +22 -22
- package/local-maven-repo/host/exp/exponent/expo.modules.sqlite/58.0.12/expo.modules.sqlite-58.0.12.module.md5 +1 -0
- package/local-maven-repo/host/exp/exponent/expo.modules.sqlite/58.0.12/expo.modules.sqlite-58.0.12.module.sha1 +1 -0
- package/local-maven-repo/host/exp/exponent/expo.modules.sqlite/58.0.12/expo.modules.sqlite-58.0.12.module.sha256 +1 -0
- package/local-maven-repo/host/exp/exponent/expo.modules.sqlite/58.0.12/expo.modules.sqlite-58.0.12.module.sha512 +1 -0
- package/local-maven-repo/host/exp/exponent/expo.modules.sqlite/{58.0.10/expo.modules.sqlite-58.0.10.pom → 58.0.12/expo.modules.sqlite-58.0.12.pom} +1 -1
- package/local-maven-repo/host/exp/exponent/expo.modules.sqlite/58.0.12/expo.modules.sqlite-58.0.12.pom.md5 +1 -0
- package/local-maven-repo/host/exp/exponent/expo.modules.sqlite/58.0.12/expo.modules.sqlite-58.0.12.pom.sha1 +1 -0
- package/local-maven-repo/host/exp/exponent/expo.modules.sqlite/58.0.12/expo.modules.sqlite-58.0.12.pom.sha256 +1 -0
- package/local-maven-repo/host/exp/exponent/expo.modules.sqlite/58.0.12/expo.modules.sqlite-58.0.12.pom.sha512 +1 -0
- package/package.json +4 -4
- package/src/NativeDatabase.ts +2 -2
- package/src/SQLiteDatabase.ts +11 -3
- package/src/WebConfiguration.ts +36 -0
- package/src/index.ts +1 -0
- package/web/SQLiteModule.ts +16 -0
- package/web/WorkerChannel.ts +17 -9
- package/web/wa-sqlite/sqlite-api.js +4 -1
- package/web/web.types.ts +6 -0
- package/web/worker.ts +50 -38
- package/local-maven-repo/host/exp/exponent/expo.modules.sqlite/58.0.10/expo.modules.sqlite-58.0.10-sources.jar +0 -0
- package/local-maven-repo/host/exp/exponent/expo.modules.sqlite/58.0.10/expo.modules.sqlite-58.0.10-sources.jar.md5 +0 -1
- package/local-maven-repo/host/exp/exponent/expo.modules.sqlite/58.0.10/expo.modules.sqlite-58.0.10-sources.jar.sha1 +0 -1
- package/local-maven-repo/host/exp/exponent/expo.modules.sqlite/58.0.10/expo.modules.sqlite-58.0.10-sources.jar.sha256 +0 -1
- package/local-maven-repo/host/exp/exponent/expo.modules.sqlite/58.0.10/expo.modules.sqlite-58.0.10-sources.jar.sha512 +0 -1
- package/local-maven-repo/host/exp/exponent/expo.modules.sqlite/58.0.10/expo.modules.sqlite-58.0.10.aar +0 -0
- package/local-maven-repo/host/exp/exponent/expo.modules.sqlite/58.0.10/expo.modules.sqlite-58.0.10.aar.md5 +0 -1
- package/local-maven-repo/host/exp/exponent/expo.modules.sqlite/58.0.10/expo.modules.sqlite-58.0.10.aar.sha1 +0 -1
- package/local-maven-repo/host/exp/exponent/expo.modules.sqlite/58.0.10/expo.modules.sqlite-58.0.10.aar.sha256 +0 -1
- package/local-maven-repo/host/exp/exponent/expo.modules.sqlite/58.0.10/expo.modules.sqlite-58.0.10.aar.sha512 +0 -1
- package/local-maven-repo/host/exp/exponent/expo.modules.sqlite/58.0.10/expo.modules.sqlite-58.0.10.module.md5 +0 -1
- package/local-maven-repo/host/exp/exponent/expo.modules.sqlite/58.0.10/expo.modules.sqlite-58.0.10.module.sha1 +0 -1
- package/local-maven-repo/host/exp/exponent/expo.modules.sqlite/58.0.10/expo.modules.sqlite-58.0.10.module.sha256 +0 -1
- package/local-maven-repo/host/exp/exponent/expo.modules.sqlite/58.0.10/expo.modules.sqlite-58.0.10.module.sha512 +0 -1
- package/local-maven-repo/host/exp/exponent/expo.modules.sqlite/58.0.10/expo.modules.sqlite-58.0.10.pom.md5 +0 -1
- package/local-maven-repo/host/exp/exponent/expo.modules.sqlite/58.0.10/expo.modules.sqlite-58.0.10.pom.sha1 +0 -1
- package/local-maven-repo/host/exp/exponent/expo.modules.sqlite/58.0.10/expo.modules.sqlite-58.0.10.pom.sha256 +0 -1
- package/local-maven-repo/host/exp/exponent/expo.modules.sqlite/58.0.10/expo.modules.sqlite-58.0.10.pom.sha512 +0 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
48f8da8c6d5d961978b986c2e3c2b2326e76c82e330f2d6a5119d37a8330f4756480e0760a22c67dc74039b0e76abb796bdf07720490bfb2c2df4d912c692214
|
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
<modelVersion>4.0.0</modelVersion>
|
|
10
10
|
<groupId>host.exp.exponent</groupId>
|
|
11
11
|
<artifactId>expo.modules.sqlite</artifactId>
|
|
12
|
-
<version>58.0.
|
|
12
|
+
<version>58.0.12</version>
|
|
13
13
|
<packaging>aar</packaging>
|
|
14
14
|
<name>expo.modules.sqlite</name>
|
|
15
15
|
<url>https://github.com/expo/expo</url>
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
d4b5a8aecf75b8f63eacde650b9e485a
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
da889fb033227b171fdfe2d0acce68487af479b4
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
efe34bb452ecd1da1e59083dfef52aa7e884e163b6808b2bbc0b27bab0017754
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
b60567105d26b5f2ed28515989f0a566ad4609df6957e35e3d0f988e011de482e86fb975aa520196abcca1a91cdbf6f422a6db01c966312cd6a98bb5dd7e8b55
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "expo-sqlite",
|
|
3
|
-
"version": "58.0.
|
|
3
|
+
"version": "58.0.12",
|
|
4
4
|
"description": "Provides access to a database using SQLite (https://www.sqlite.org/). The database is persisted across restarts of your app.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"async-storage",
|
|
@@ -50,13 +50,13 @@
|
|
|
50
50
|
"await-lock": "^2.2.2"
|
|
51
51
|
},
|
|
52
52
|
"devDependencies": {
|
|
53
|
+
"@expo/internal-scripts": "58.0.1",
|
|
53
54
|
"@expo/spawn-async": "^1.8.0",
|
|
54
55
|
"@testing-library/react-native": "^14.0.1",
|
|
55
56
|
"@types/jest": "^30.0.0",
|
|
56
57
|
"@types/node": "^22.14.0",
|
|
57
58
|
"@types/react": "~19.3.0",
|
|
58
|
-
"expo": "58.0.
|
|
59
|
-
"expo-module-scripts": "56.0.7",
|
|
59
|
+
"expo": "58.0.8",
|
|
60
60
|
"react-error-boundary": "^4.0.11",
|
|
61
61
|
"tar": "^7.5.22"
|
|
62
62
|
},
|
|
@@ -66,7 +66,7 @@
|
|
|
66
66
|
"react-native": "*"
|
|
67
67
|
},
|
|
68
68
|
"jest": {
|
|
69
|
-
"preset": "expo-
|
|
69
|
+
"preset": "@expo/internal-scripts"
|
|
70
70
|
},
|
|
71
71
|
"scripts": {
|
|
72
72
|
"precompile-android": "et prebuild-android-package-for-publish",
|
package/src/NativeDatabase.ts
CHANGED
|
@@ -13,7 +13,7 @@ export declare class NativeDatabase {
|
|
|
13
13
|
public isInTransactionAsync(): Promise<boolean>;
|
|
14
14
|
public closeAsync(): Promise<void>;
|
|
15
15
|
public execAsync(source: string): Promise<void>;
|
|
16
|
-
public serializeAsync(databaseName: string): Promise<Uint8Array>;
|
|
16
|
+
public serializeAsync(databaseName: string): Promise<Uint8Array | ArrayBuffer>;
|
|
17
17
|
public prepareAsync(nativeStatement: NativeStatement, source: string): Promise<NativeStatement>;
|
|
18
18
|
public createSessionAsync(nativeSession: NativeSession, dbName: string): Promise<NativeSession>;
|
|
19
19
|
public loadExtensionAsync(libPath: string, entryPoint?: string): Promise<void>;
|
|
@@ -27,7 +27,7 @@ export declare class NativeDatabase {
|
|
|
27
27
|
public closeSync(): void;
|
|
28
28
|
public interruptSync(): void;
|
|
29
29
|
public execSync(source: string): void;
|
|
30
|
-
public serializeSync(databaseName: string): Uint8Array;
|
|
30
|
+
public serializeSync(databaseName: string): Uint8Array | ArrayBuffer;
|
|
31
31
|
public prepareSync(nativeStatement: NativeStatement, source: string): NativeStatement;
|
|
32
32
|
public createSessionSync(nativeSession: NativeSession, dbName: string): NativeSession;
|
|
33
33
|
public loadExtensionSync(libPath: string, entryPoint?: string): void;
|
package/src/SQLiteDatabase.ts
CHANGED
|
@@ -63,8 +63,8 @@ export class SQLiteDatabase {
|
|
|
63
63
|
*
|
|
64
64
|
* @param databaseName The name of the current attached databases. The default value is `main` which is the default database name.
|
|
65
65
|
*/
|
|
66
|
-
public serializeAsync(databaseName: string = 'main'): Promise<Uint8Array> {
|
|
67
|
-
return this.nativeDatabase.serializeAsync(databaseName);
|
|
66
|
+
public async serializeAsync(databaseName: string = 'main'): Promise<Uint8Array> {
|
|
67
|
+
return toUint8Array(await this.nativeDatabase.serializeAsync(databaseName));
|
|
68
68
|
}
|
|
69
69
|
|
|
70
70
|
/**
|
|
@@ -264,7 +264,7 @@ export class SQLiteDatabase {
|
|
|
264
264
|
* @param databaseName The name of the current attached databases. The default value is `main` which is the default database name.
|
|
265
265
|
*/
|
|
266
266
|
public serializeSync(databaseName: string = 'main'): Uint8Array {
|
|
267
|
-
return this.nativeDatabase.serializeSync(databaseName);
|
|
267
|
+
return toUint8Array(this.nativeDatabase.serializeSync(databaseName));
|
|
268
268
|
}
|
|
269
269
|
|
|
270
270
|
/**
|
|
@@ -802,3 +802,11 @@ class Transaction extends SQLiteDatabase {
|
|
|
802
802
|
return new Transaction(db.databasePath, options, nativeDatabase);
|
|
803
803
|
}
|
|
804
804
|
}
|
|
805
|
+
|
|
806
|
+
/**
|
|
807
|
+
* The native database hands serialized bytes over as a `Uint8Array` on iOS and as an `ArrayBuffer`
|
|
808
|
+
* on Android.
|
|
809
|
+
*/
|
|
810
|
+
function toUint8Array(data: Uint8Array | ArrayBuffer): Uint8Array {
|
|
811
|
+
return data instanceof Uint8Array ? data : new Uint8Array(data);
|
|
812
|
+
}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import ExpoSQLite from './ExpoSQLite';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Options for [`configureWeb()`](#sqliteconfigureweboptions).
|
|
5
|
+
* @platform web
|
|
6
|
+
*/
|
|
7
|
+
export interface SQLiteWebOptions {
|
|
8
|
+
/**
|
|
9
|
+
* The URL of a custom wa-sqlite WebAssembly build, for example one built with FTS enabled.
|
|
10
|
+
* When omitted, `expo-sqlite` uses its bundled build.
|
|
11
|
+
*
|
|
12
|
+
* The build must come from the [`expo/wa-sqlite`](https://github.com/expo/wa-sqlite) revision that matches your `expo-sqlite` version.
|
|
13
|
+
* A build from another revision may fail to load.
|
|
14
|
+
*/
|
|
15
|
+
wasmURL?: string;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* Configures how `expo-sqlite` runs on web.
|
|
20
|
+
* Each call replaces the options from the previous call.
|
|
21
|
+
* It has no effect on Android, iOS, and server rendering.
|
|
22
|
+
*
|
|
23
|
+
* Call it before opening any database.
|
|
24
|
+
* It throws if `wasmURL` changes after a database is opened, because the web worker loads SQLite only once.
|
|
25
|
+
*
|
|
26
|
+
* @example
|
|
27
|
+
* ```ts
|
|
28
|
+
* SQLite.configureWeb({ wasmURL: require('./assets/wa-sqlite-fts.wasm') });
|
|
29
|
+
* const db = await SQLite.openDatabaseAsync('app.db');
|
|
30
|
+
* ```
|
|
31
|
+
*
|
|
32
|
+
* @platform web
|
|
33
|
+
*/
|
|
34
|
+
export function configureWeb(options: SQLiteWebOptions): void {
|
|
35
|
+
ExpoSQLite.configureWeb?.(options);
|
|
36
|
+
}
|
package/src/index.ts
CHANGED
package/web/SQLiteModule.ts
CHANGED
|
@@ -11,9 +11,12 @@ import {
|
|
|
11
11
|
type SQLiteColumnValues,
|
|
12
12
|
type SQLiteRunResult,
|
|
13
13
|
} from '../src/NativeStatement';
|
|
14
|
+
import { type SQLiteWebOptions } from '../src/WebConfiguration';
|
|
14
15
|
import { invokeWorkerAsync, invokeWorkerSync, workerMessageHandler } from './WorkerChannel';
|
|
16
|
+
import { type ConfigureWorkerMessage } from './web.types';
|
|
15
17
|
|
|
16
18
|
let worker: Worker | null = null;
|
|
19
|
+
let webOptions: SQLiteWebOptions = {};
|
|
17
20
|
let nextNativeDatabaseId = 0;
|
|
18
21
|
let nextNativeStatementId = 0;
|
|
19
22
|
let nextNativeSessionId = 0;
|
|
@@ -29,6 +32,7 @@ function getWorker(): Worker {
|
|
|
29
32
|
}
|
|
30
33
|
workerMessageHandler(event);
|
|
31
34
|
});
|
|
35
|
+
worker.postMessage({ type: 'configure', data: webOptions } satisfies ConfigureWorkerMessage);
|
|
32
36
|
}
|
|
33
37
|
return worker;
|
|
34
38
|
}
|
|
@@ -427,6 +431,18 @@ export class SQLiteModule extends NativeModule {
|
|
|
427
431
|
});
|
|
428
432
|
}
|
|
429
433
|
|
|
434
|
+
configureWeb(options: SQLiteWebOptions): void {
|
|
435
|
+
if (worker != null) {
|
|
436
|
+
// Fast Refresh runs the same call again after a database is open.
|
|
437
|
+
if (options.wasmURL === webOptions.wasmURL) return;
|
|
438
|
+
throw new Error(
|
|
439
|
+
'Cannot change the SQLite WebAssembly URL because a database has already been opened, and the web worker loads SQLite only once. ' +
|
|
440
|
+
'Call `configureWeb()` before opening any database, and reload the app after you change `wasmURL`.'
|
|
441
|
+
);
|
|
442
|
+
}
|
|
443
|
+
webOptions = { ...options };
|
|
444
|
+
}
|
|
445
|
+
|
|
430
446
|
async ensureDatabasePathExistsAsync(databasePath: string): Promise<void> {
|
|
431
447
|
// No-op for web
|
|
432
448
|
}
|
package/web/WorkerChannel.ts
CHANGED
|
@@ -33,21 +33,29 @@ export function sendWorkerResult({
|
|
|
33
33
|
resultBuffer: SharedArrayBuffer;
|
|
34
34
|
};
|
|
35
35
|
}) {
|
|
36
|
+
// Send the message as a string. An Error doesn't survive JSON, and `String(error)` keeps it non-empty.
|
|
37
|
+
const errorMessage = error != null ? error.message || String(error) : null;
|
|
36
38
|
if (syncTrait) {
|
|
37
39
|
const { lockBuffer, resultBuffer } = syncTrait;
|
|
38
40
|
const lock = new Int32Array(lockBuffer);
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
41
|
+
let resultBytes = new TextEncoder().encode(
|
|
42
|
+
errorMessage != null ? serialize({ error: errorMessage }) : serialize({ result })
|
|
43
|
+
);
|
|
44
|
+
if (resultBytes.length + 4 > resultBuffer.byteLength) {
|
|
45
|
+
resultBytes = new TextEncoder().encode(
|
|
46
|
+
serialize({
|
|
47
|
+
error: `The synchronous result is ${resultBytes.length} bytes, which is more than the ${resultBuffer.byteLength - 4} bytes that synchronous calls can return on web. Use the async API for large results.`,
|
|
48
|
+
})
|
|
49
|
+
);
|
|
50
|
+
}
|
|
51
|
+
new Uint32Array(resultBuffer, 0, 1)[0] = resultBytes.length;
|
|
52
|
+
new Uint8Array(resultBuffer).set(resultBytes, 4);
|
|
45
53
|
Atomics.store(lock, 0, RESOLVED);
|
|
46
54
|
} else {
|
|
47
|
-
if (
|
|
48
|
-
self.postMessage({ id,
|
|
55
|
+
if (error != null) {
|
|
56
|
+
self.postMessage({ id, error: errorMessage });
|
|
49
57
|
} else {
|
|
50
|
-
self.postMessage({ id,
|
|
58
|
+
self.postMessage({ id, result });
|
|
51
59
|
}
|
|
52
60
|
}
|
|
53
61
|
}
|
|
@@ -300,7 +300,10 @@ export function Factory(Module) {
|
|
|
300
300
|
return async function (db) {
|
|
301
301
|
verifyDatabase(db);
|
|
302
302
|
const result = await f(db);
|
|
303
|
-
|
|
303
|
+
// expo-sqlite: SQLite keeps the connection open when close fails, so keep it usable for a retry.
|
|
304
|
+
if (result === SQLite.SQLITE_OK) {
|
|
305
|
+
databases.delete(db);
|
|
306
|
+
}
|
|
304
307
|
return check(fname, result, db);
|
|
305
308
|
};
|
|
306
309
|
})();
|
package/web/web.types.ts
CHANGED
|
@@ -8,6 +8,7 @@ import {
|
|
|
8
8
|
type SQLiteColumnNames,
|
|
9
9
|
type SQLiteColumnValues,
|
|
10
10
|
} from '../src/NativeStatement';
|
|
11
|
+
import { type SQLiteWebOptions } from '../src/WebConfiguration';
|
|
11
12
|
import { type SQLAction } from './SQLAction';
|
|
12
13
|
|
|
13
14
|
export interface SyncWorkerMessage {
|
|
@@ -250,6 +251,11 @@ type SessionInvertChangesetMessage = BaseWorkerMessage & {
|
|
|
250
251
|
};
|
|
251
252
|
};
|
|
252
253
|
|
|
254
|
+
export interface ConfigureWorkerMessage {
|
|
255
|
+
type: 'configure';
|
|
256
|
+
data: SQLiteWebOptions;
|
|
257
|
+
}
|
|
258
|
+
|
|
253
259
|
//#endregion Request messages
|
|
254
260
|
|
|
255
261
|
//#region Response messages
|
package/web/worker.ts
CHANGED
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
|
|
5
5
|
import { type Changeset } from '../src/NativeSession';
|
|
6
6
|
import { type SQLiteColumnNames, type SQLiteColumnValues } from '../src/NativeStatement';
|
|
7
|
+
import { type SQLiteWebOptions } from '../src/WebConfiguration';
|
|
7
8
|
import { createSQLAction } from './SQLAction';
|
|
8
9
|
import { SQLiteOptions } from './SQLiteOptions';
|
|
9
10
|
import { sendWorkerResult } from './WorkerChannel';
|
|
@@ -21,6 +22,7 @@ import WaSQLiteFactory from './wa-sqlite/wa-sqlite';
|
|
|
21
22
|
// @ts-expect-error wasm module is not typed
|
|
22
23
|
import wasmModule from './wa-sqlite/wa-sqlite.wasm';
|
|
23
24
|
import {
|
|
25
|
+
type ConfigureWorkerMessage,
|
|
24
26
|
type SQLiteWorkerMessage,
|
|
25
27
|
type SQLiteWorkerMessageType,
|
|
26
28
|
type MessageTypeMap,
|
|
@@ -40,6 +42,7 @@ interface DatabaseEntity {
|
|
|
40
42
|
}
|
|
41
43
|
interface StatementEntity {
|
|
42
44
|
pointer: StatementPointer;
|
|
45
|
+
databasePointer: DatabasePointer;
|
|
43
46
|
}
|
|
44
47
|
interface SessionEntity {
|
|
45
48
|
pointer: SessionPointer;
|
|
@@ -54,6 +57,7 @@ const MIN_INT32 = -0x80000000;
|
|
|
54
57
|
let _sqlite3: SQLiteAPI | null = null;
|
|
55
58
|
let _vfs: AccessHandlePoolVFS | null = null;
|
|
56
59
|
let _vfsMemory: MemoryVFS | null = null;
|
|
60
|
+
let _webOptions: SQLiteWebOptions = {};
|
|
57
61
|
|
|
58
62
|
const databaseIdMap = new Map<number, DatabaseEntity>();
|
|
59
63
|
const statementIdMap = new Map<number, StatementEntity>();
|
|
@@ -61,7 +65,12 @@ const sessionIdMap = new Map<number, SessionEntity>();
|
|
|
61
65
|
|
|
62
66
|
class SQLiteErrorException extends Error {}
|
|
63
67
|
|
|
64
|
-
self.onmessage = async (event: MessageEvent<SQLiteWorkerMessage>) => {
|
|
68
|
+
self.onmessage = async (event: MessageEvent<SQLiteWorkerMessage | ConfigureWorkerMessage>) => {
|
|
69
|
+
if (event.data.type === 'configure') {
|
|
70
|
+
_webOptions = event.data.data;
|
|
71
|
+
return;
|
|
72
|
+
}
|
|
73
|
+
|
|
65
74
|
let result: ResultType | null = null;
|
|
66
75
|
let error: Error | null = null;
|
|
67
76
|
try {
|
|
@@ -118,7 +127,7 @@ async function handleMessageImpl<T extends SQLiteWorkerMessageType>({
|
|
|
118
127
|
}
|
|
119
128
|
|
|
120
129
|
case 'finalize': {
|
|
121
|
-
await finalize(data.
|
|
130
|
+
await finalize(data.nativeStatementId);
|
|
122
131
|
break;
|
|
123
132
|
}
|
|
124
133
|
|
|
@@ -253,12 +262,20 @@ async function backupDatabase(
|
|
|
253
262
|
}
|
|
254
263
|
|
|
255
264
|
async function closeDatabase(nativeDatabaseId: number) {
|
|
256
|
-
maybeFinalizeAllStatements(nativeDatabaseId);
|
|
257
265
|
const { sqlite3 } = await maybeInitAsync();
|
|
258
266
|
const dbEntity = databaseIdMap.get(nativeDatabaseId);
|
|
259
|
-
if (dbEntity) {
|
|
260
|
-
|
|
267
|
+
if (!dbEntity) throw new Error(`Database not found - nativeDatabaseId[${nativeDatabaseId}]`);
|
|
268
|
+
|
|
269
|
+
databaseIdMap.delete(nativeDatabaseId);
|
|
270
|
+
if ([...databaseIdMap.values()].includes(dbEntity)) {
|
|
271
|
+
return;
|
|
272
|
+
}
|
|
273
|
+
try {
|
|
274
|
+
await maybeFinalizeAllStatements(sqlite3, dbEntity);
|
|
261
275
|
await sqlite3.close(dbEntity.pointer);
|
|
276
|
+
} catch (e) {
|
|
277
|
+
databaseIdMap.set(nativeDatabaseId, dbEntity);
|
|
278
|
+
throw e;
|
|
262
279
|
}
|
|
263
280
|
}
|
|
264
281
|
|
|
@@ -289,10 +306,9 @@ async function exec(nativeDatabaseId: number, source: string) {
|
|
|
289
306
|
await sqlite3.exec(dbEntity.pointer, source);
|
|
290
307
|
}
|
|
291
308
|
|
|
292
|
-
|
|
309
|
+
// A closed handle to a shared connection may still own statements, so don't require its id here.
|
|
310
|
+
async function finalize(nativeStatementId: number): Promise<void> {
|
|
293
311
|
const { sqlite3 } = await maybeInitAsync();
|
|
294
|
-
const dbEntity = databaseIdMap.get(nativeDatabaseId);
|
|
295
|
-
if (!dbEntity) throw new Error(`Database not found - nativeDatabaseId[${nativeDatabaseId}]`);
|
|
296
312
|
const stmt = statementIdMap.get(nativeStatementId);
|
|
297
313
|
if (!stmt) throw new Error(`Statement not found - nativeStatementId[${nativeStatementId}]`);
|
|
298
314
|
|
|
@@ -429,7 +445,10 @@ async function prepare(
|
|
|
429
445
|
const { value: statementPointer } = await asyncIterator.next();
|
|
430
446
|
asyncIterator.return?.();
|
|
431
447
|
if (!statementPointer) throw new Error('Failed to prepare statement');
|
|
432
|
-
statementIdMap.set(nativeStatementId, {
|
|
448
|
+
statementIdMap.set(nativeStatementId, {
|
|
449
|
+
pointer: statementPointer,
|
|
450
|
+
databasePointer: dbEntity.pointer,
|
|
451
|
+
});
|
|
433
452
|
}
|
|
434
453
|
|
|
435
454
|
async function run(
|
|
@@ -736,40 +755,21 @@ async function initDb(sqlite3: SQLiteAPI, dbEntity: DatabaseEntity) {
|
|
|
736
755
|
}
|
|
737
756
|
}
|
|
738
757
|
|
|
739
|
-
async function maybeFinalizeAllStatements(
|
|
740
|
-
const { sqlite3 } = await maybeInitAsync();
|
|
741
|
-
const dbEntity = databaseIdMap.get(nativeDatabaseId);
|
|
742
|
-
if (!dbEntity) throw new Error(`Database not found - nativeDatabaseId[${nativeDatabaseId}]`);
|
|
758
|
+
async function maybeFinalizeAllStatements(sqlite3: SQLiteAPI, dbEntity: DatabaseEntity) {
|
|
743
759
|
if (!dbEntity.openOptions.finalizeUnusedStatementsBeforeClosing) {
|
|
744
760
|
return;
|
|
745
761
|
}
|
|
746
762
|
|
|
747
|
-
let error: Error | null = null;
|
|
748
|
-
const finalizedStatements: StatementPointer[] = [];
|
|
749
|
-
let stmt: StatementPointer | null = sqlite3.next_stmt(dbEntity.pointer, null);
|
|
750
|
-
while (stmt != null && stmt !== 0) {
|
|
751
|
-
const nextStmt: StatementPointer = sqlite3.next_stmt(dbEntity.pointer, stmt);
|
|
752
|
-
try {
|
|
753
|
-
sqlite3.finalize(stmt);
|
|
754
|
-
finalizedStatements.push(stmt);
|
|
755
|
-
} catch (e) {
|
|
756
|
-
error = e;
|
|
757
|
-
}
|
|
758
|
-
stmt = nextStmt;
|
|
759
|
-
}
|
|
760
|
-
|
|
761
|
-
// Delete finalized statements from the map
|
|
762
|
-
const statementsToDelete: number[] = [];
|
|
763
763
|
for (const [nativeStatementId, stmtEntity] of statementIdMap.entries()) {
|
|
764
|
-
if (
|
|
765
|
-
|
|
764
|
+
if (stmtEntity.databasePointer !== dbEntity.pointer) {
|
|
765
|
+
continue;
|
|
766
766
|
}
|
|
767
|
-
}
|
|
768
|
-
for (const nativeStatementId of statementsToDelete) {
|
|
769
767
|
statementIdMap.delete(nativeStatementId);
|
|
768
|
+
const result = await sqlite3.finalize(stmtEntity.pointer);
|
|
769
|
+
if (result !== SQLITE_OK) {
|
|
770
|
+
console.warn(`Finalizing a statement during close failed - error code[${result}]`);
|
|
771
|
+
}
|
|
770
772
|
}
|
|
771
|
-
|
|
772
|
-
if (error) throw error;
|
|
773
773
|
}
|
|
774
774
|
|
|
775
775
|
async function maybeInitAsync(): Promise<{
|
|
@@ -778,9 +778,7 @@ async function maybeInitAsync(): Promise<{
|
|
|
778
778
|
vfsMemory: MemoryVFS;
|
|
779
779
|
}> {
|
|
780
780
|
if (!_sqlite3) {
|
|
781
|
-
const module = await
|
|
782
|
-
locateFile: () => wasmModule,
|
|
783
|
-
});
|
|
781
|
+
const module = await loadWaSQLiteModuleAsync();
|
|
784
782
|
_sqlite3 = SQLite.Factory(module) as SQLiteAPI;
|
|
785
783
|
if (!_sqlite3) {
|
|
786
784
|
throw new Error('Failed to initialize wa-sqlite');
|
|
@@ -808,4 +806,18 @@ async function maybeInitAsync(): Promise<{
|
|
|
808
806
|
return { sqlite3: _sqlite3, vfs: _vfs, vfsMemory: _vfsMemory };
|
|
809
807
|
}
|
|
810
808
|
|
|
809
|
+
async function loadWaSQLiteModuleAsync(): Promise<any> {
|
|
810
|
+
const { wasmURL } = _webOptions;
|
|
811
|
+
try {
|
|
812
|
+
return await WaSQLiteFactory({ locateFile: () => wasmURL ?? wasmModule });
|
|
813
|
+
} catch (e) {
|
|
814
|
+
if (wasmURL == null) throw e;
|
|
815
|
+
throw new Error(
|
|
816
|
+
`Failed to load the SQLite WebAssembly module from "${wasmURL}". ` +
|
|
817
|
+
'Check that the `wasmURL` passed to `configureWeb()` is reachable and built from the `expo/wa-sqlite` revision that this `expo-sqlite` uses. ' +
|
|
818
|
+
`Cause: ${e instanceof Error ? e.message : String(e)}`
|
|
819
|
+
);
|
|
820
|
+
}
|
|
821
|
+
}
|
|
822
|
+
|
|
811
823
|
//#endregion Internal helpers
|
|
Binary file
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
f9c01cec01c62d6a619fdc69f237e033
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
afa88d36ec945ad0442cc3582e05eb84b07cb9f1
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
67dbdc88a1d7fc60c31092ad150a98a30d93d8ca82bbf869609890965425524d
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
47d6b003042ef32b80e19b64fd015ffcfa159bb8f08971459211cd6ab971304da58dee6236c2be5319f606f9062d023530dcaa5c2e530bb17e42ab1465d5b95f
|
|
Binary file
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
fad06d1b56a5b3ce76fff8218367c30e
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
daaf8670dcbff2b9ab9410878e0a87e85eabad6f
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
c4c90adee96c2308551babad7ac1fca8e3782ab14771b68933f1151a03436333
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
8da2bcca001991403ad15af7ae5fe40b6f02cf613801c3c109fc64b0a25980c07019c47fca22cbfef180ce826225442d307fc3b4416cc29127fda0c3880c666c
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
ca75ac17a7818d5fc42a65c0840dfe04
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
c83619ccf6810e1e67de33d891531e884de12020
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
dfc2cb2d98cfef3bd6b5be8f805dd3444b34c4755dfc2f6ff0e0b653ba123cd3
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
73ae3ffc162990e89b804689ba3d929767b2619e57e56d78c277b4c772fd8cd284ff0cda1a1418342b5f21c68fd4538548ab273f38c390a31dbd5a6e8800143f
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
92a9db327ca2c2ad57ff6a10c3ad05bd
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
d104ae54dc9a284a629157c7f4bc6a76d4b1d5e3
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
d46287f54d70926645728cdb6a436ad843ea632fbdf9274a29c6227de2e61532
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
584fceef6dc748071a484a1cee817dbc73fc8ce8838fbcb29a1d429a2b8eb36d608d7acd3a17c10f8e35a78ded5064bc01bb839376dc11b59e5c82937a23f4bf
|