@livestore/wa-sqlite 1.0.1-dev.0
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/LICENSE +21 -0
- package/README.md +78 -0
- package/dist/wa-sqlite-async.mjs +16 -0
- package/dist/wa-sqlite-async.wasm +0 -0
- package/dist/wa-sqlite-jspi.mjs +16 -0
- package/dist/wa-sqlite-jspi.wasm +0 -0
- package/dist/wa-sqlite.mjs +16 -0
- package/dist/wa-sqlite.wasm +0 -0
- package/package.json +45 -0
- package/src/FacadeVFS.js +508 -0
- package/src/VFS.js +222 -0
- package/src/WebLocksMixin.js +412 -0
- package/src/examples/AccessHandlePoolVFS.js +458 -0
- package/src/examples/IDBBatchAtomicVFS.js +820 -0
- package/src/examples/IDBMirrorVFS.js +875 -0
- package/src/examples/MemoryAsyncVFS.js +100 -0
- package/src/examples/MemoryVFS.js +176 -0
- package/src/examples/OPFSAdaptiveVFS.js +437 -0
- package/src/examples/OPFSAnyContextVFS.js +300 -0
- package/src/examples/OPFSCoopSyncVFS.js +590 -0
- package/src/examples/OPFSPermutedVFS.js +1214 -0
- package/src/examples/README.md +89 -0
- package/src/examples/tag.js +82 -0
- package/src/sqlite-api.js +914 -0
- package/src/sqlite-constants.js +275 -0
- package/src/types/globals.d.ts +60 -0
- package/src/types/index.d.ts +1302 -0
- package/src/types/tsconfig.json +6 -0
- package/test/AccessHandlePoolVFS.test.js +27 -0
- package/test/IDBBatchAtomicVFS.test.js +97 -0
- package/test/IDBMirrorVFS.test.js +27 -0
- package/test/MemoryAsyncVFS.test.js +27 -0
- package/test/MemoryVFS.test.js +27 -0
- package/test/OPFSAdaptiveVFS.test.js +27 -0
- package/test/OPFSAnyContextVFS.test.js +27 -0
- package/test/OPFSCoopSyncVFS.test.js +27 -0
- package/test/OPFSPermutedVFS.test.js +27 -0
- package/test/TestContext.js +96 -0
- package/test/WebLocksMixin.test.js +521 -0
- package/test/api.test.js +49 -0
- package/test/api_exec.js +89 -0
- package/test/api_misc.js +63 -0
- package/test/api_statements.js +426 -0
- package/test/callbacks.test.js +373 -0
- package/test/sql.test.js +64 -0
- package/test/sql_0001.js +49 -0
- package/test/sql_0002.js +52 -0
- package/test/sql_0003.js +83 -0
- package/test/sql_0004.js +81 -0
- package/test/sql_0005.js +76 -0
- package/test/test-worker.js +204 -0
- package/test/vfs_xAccess.js +2 -0
- package/test/vfs_xClose.js +52 -0
- package/test/vfs_xOpen.js +91 -0
- package/test/vfs_xRead.js +38 -0
- package/test/vfs_xWrite.js +36 -0
|
@@ -0,0 +1,914 @@
|
|
|
1
|
+
// Copyright 2021 Roy T. Hashimoto. All Rights Reserved.
|
|
2
|
+
|
|
3
|
+
import * as SQLite from './sqlite-constants.js';
|
|
4
|
+
export * from './sqlite-constants.js';
|
|
5
|
+
|
|
6
|
+
const MAX_INT64 = 0x7fffffffffffffffn;
|
|
7
|
+
const MIN_INT64 = -0x8000000000000000n;
|
|
8
|
+
|
|
9
|
+
// const AsyncFunction = Object.getPrototypeOf(async function(){}).constructor;
|
|
10
|
+
|
|
11
|
+
export class SQLiteError extends Error {
|
|
12
|
+
constructor(message, code) {
|
|
13
|
+
super(message);
|
|
14
|
+
this.code = code;
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
// const async = true;
|
|
19
|
+
const async = false;
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* Builds a Javascript API from the Emscripten module. This API is still
|
|
23
|
+
* low-level and closely corresponds to the C API exported by the module,
|
|
24
|
+
* but differs in some specifics like throwing exceptions on errors.
|
|
25
|
+
* @param {*} Module SQLite Emscripten module
|
|
26
|
+
* @returns {SQLiteAPI}
|
|
27
|
+
*/
|
|
28
|
+
export function Factory(Module) {
|
|
29
|
+
/** @type {SQLiteAPI} */ const sqlite3 = {};
|
|
30
|
+
|
|
31
|
+
Module.retryOps = [];
|
|
32
|
+
const sqliteFreeAddress = Module._getSqliteFree();
|
|
33
|
+
|
|
34
|
+
// Allocate some space for 32-bit returned values.
|
|
35
|
+
const tmp = Module._malloc(8);
|
|
36
|
+
const tmpPtr = [tmp, tmp + 4];
|
|
37
|
+
|
|
38
|
+
// Convert a JS string to a C string. sqlite3_malloc is used to allocate
|
|
39
|
+
// memory (use sqlite3_free to deallocate).
|
|
40
|
+
function createUTF8(s) {
|
|
41
|
+
if (typeof s !== 'string') return 0;
|
|
42
|
+
const utf8 = new TextEncoder().encode(s);
|
|
43
|
+
const zts = Module._sqlite3_malloc(utf8.byteLength + 1);
|
|
44
|
+
Module.HEAPU8.set(utf8, zts);
|
|
45
|
+
Module.HEAPU8[zts + utf8.byteLength] = 0;
|
|
46
|
+
return zts;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* Concatenate 32-bit numbers into a 64-bit (signed) BigInt.
|
|
51
|
+
* @param {number} lo32
|
|
52
|
+
* @param {number} hi32
|
|
53
|
+
* @returns {bigint}
|
|
54
|
+
*/
|
|
55
|
+
function cvt32x2ToBigInt(lo32, hi32) {
|
|
56
|
+
return (BigInt(hi32) << 32n) | (BigInt(lo32) & 0xffffffffn);
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* Concatenate 32-bit numbers and return as number or BigInt, depending
|
|
61
|
+
* on the value.
|
|
62
|
+
* @param {number} lo32
|
|
63
|
+
* @param {number} hi32
|
|
64
|
+
* @returns {number|bigint}
|
|
65
|
+
*/
|
|
66
|
+
const cvt32x2AsSafe = (function() {
|
|
67
|
+
const hiMax = BigInt(Number.MAX_SAFE_INTEGER) >> 32n;
|
|
68
|
+
const hiMin = BigInt(Number.MIN_SAFE_INTEGER) >> 32n;
|
|
69
|
+
|
|
70
|
+
return function(lo32, hi32) {
|
|
71
|
+
if (hi32 > hiMax || hi32 < hiMin) {
|
|
72
|
+
// Can't be expressed as a Number so use BigInt.
|
|
73
|
+
return cvt32x2ToBigInt(lo32, hi32);
|
|
74
|
+
} else {
|
|
75
|
+
// Combine the upper and lower 32-bit numbers. The complication is
|
|
76
|
+
// that lo32 is a signed integer which makes manipulating its bits
|
|
77
|
+
// a little tricky - the sign bit gets handled separately.
|
|
78
|
+
return (hi32 * 0x100000000) + (lo32 & 0x7fffffff) - (lo32 & 0x80000000);
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
})();
|
|
82
|
+
|
|
83
|
+
const databases = new Set();
|
|
84
|
+
function verifyDatabase(db) {
|
|
85
|
+
if (!databases.has(db)) {
|
|
86
|
+
throw new SQLiteError('not a database', SQLite.SQLITE_MISUSE);
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
const mapStmtToDB = new Map();
|
|
91
|
+
function verifyStatement(stmt) {
|
|
92
|
+
if (!mapStmtToDB.has(stmt)) {
|
|
93
|
+
throw new SQLiteError('not a statement', SQLite.SQLITE_MISUSE);
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
sqlite3.bind_collection = function(stmt, bindings) {
|
|
98
|
+
verifyStatement(stmt);
|
|
99
|
+
const isArray = Array.isArray(bindings);
|
|
100
|
+
const nBindings = sqlite3.bind_parameter_count(stmt);
|
|
101
|
+
for (let i = 1; i <= nBindings; ++i) {
|
|
102
|
+
const key = isArray ? i - 1 : sqlite3.bind_parameter_name(stmt, i);
|
|
103
|
+
const value = bindings[key];
|
|
104
|
+
if (value !== undefined) {
|
|
105
|
+
sqlite3.bind(stmt, i, value);
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
return SQLite.SQLITE_OK;
|
|
109
|
+
};
|
|
110
|
+
|
|
111
|
+
sqlite3.bind = function(stmt, i, value) {
|
|
112
|
+
verifyStatement(stmt);
|
|
113
|
+
switch (typeof value) {
|
|
114
|
+
case 'number':
|
|
115
|
+
if (value === (value | 0)) {
|
|
116
|
+
return sqlite3.bind_int(stmt, i, value);
|
|
117
|
+
} else {
|
|
118
|
+
return sqlite3.bind_double(stmt, i, value);
|
|
119
|
+
}
|
|
120
|
+
case 'string':
|
|
121
|
+
return sqlite3.bind_text(stmt, i, value);
|
|
122
|
+
default:
|
|
123
|
+
if (value instanceof Uint8Array || Array.isArray(value)) {
|
|
124
|
+
return sqlite3.bind_blob(stmt, i, value);
|
|
125
|
+
} else if (value === null) {
|
|
126
|
+
return sqlite3.bind_null(stmt, i);
|
|
127
|
+
} else if (typeof value === 'bigint') {
|
|
128
|
+
return sqlite3.bind_int64(stmt, i, value);
|
|
129
|
+
} else if (value === undefined) {
|
|
130
|
+
// Existing binding (or NULL) will be used.
|
|
131
|
+
return SQLite.SQLITE_NOTICE;
|
|
132
|
+
} else {
|
|
133
|
+
console.warn('unknown binding converted to null', value);
|
|
134
|
+
return sqlite3.bind_null(stmt, i);
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
};
|
|
138
|
+
|
|
139
|
+
sqlite3.bind_blob = (function() {
|
|
140
|
+
const fname = 'sqlite3_bind_blob';
|
|
141
|
+
const f = Module.cwrap(fname, ...decl('nnnnn:n'));
|
|
142
|
+
return function(stmt, i, value) {
|
|
143
|
+
verifyStatement(stmt);
|
|
144
|
+
// @ts-ignore
|
|
145
|
+
const byteLength = value.byteLength ?? value.length;
|
|
146
|
+
const ptr = Module._sqlite3_malloc(byteLength);
|
|
147
|
+
Module.HEAPU8.subarray(ptr).set(value);
|
|
148
|
+
const result = f(stmt, i, ptr, byteLength, sqliteFreeAddress);
|
|
149
|
+
return check(fname, result, mapStmtToDB.get(stmt));
|
|
150
|
+
};
|
|
151
|
+
})();
|
|
152
|
+
|
|
153
|
+
sqlite3.bind_parameter_count = (function() {
|
|
154
|
+
const fname = 'sqlite3_bind_parameter_count';
|
|
155
|
+
const f = Module.cwrap(fname, ...decl('n:n'));
|
|
156
|
+
return function(stmt) {
|
|
157
|
+
verifyStatement(stmt);
|
|
158
|
+
const result = f(stmt);
|
|
159
|
+
return result;
|
|
160
|
+
};
|
|
161
|
+
})();
|
|
162
|
+
|
|
163
|
+
sqlite3.bind_double = (function() {
|
|
164
|
+
const fname = 'sqlite3_bind_double';
|
|
165
|
+
const f = Module.cwrap(fname, ...decl('nnn:n'));
|
|
166
|
+
return function(stmt, i, value) {
|
|
167
|
+
verifyStatement(stmt);
|
|
168
|
+
const result = f(stmt, i, value);
|
|
169
|
+
return check(fname, result, mapStmtToDB.get(stmt));
|
|
170
|
+
};
|
|
171
|
+
})();
|
|
172
|
+
|
|
173
|
+
sqlite3.bind_int = (function() {
|
|
174
|
+
const fname = 'sqlite3_bind_int';
|
|
175
|
+
const f = Module.cwrap(fname, ...decl('nnn:n'));
|
|
176
|
+
return function(stmt, i, value) {
|
|
177
|
+
verifyStatement(stmt);
|
|
178
|
+
if (value > 0x7fffffff || value < -0x80000000) return SQLite.SQLITE_RANGE;
|
|
179
|
+
|
|
180
|
+
const result = f(stmt, i, value);
|
|
181
|
+
return check(fname, result, mapStmtToDB.get(stmt));
|
|
182
|
+
};
|
|
183
|
+
})();
|
|
184
|
+
|
|
185
|
+
sqlite3.bind_int64 = (function() {
|
|
186
|
+
const fname = 'sqlite3_bind_int64';
|
|
187
|
+
const f = Module.cwrap(fname, ...decl('nnnn:n'));
|
|
188
|
+
return function(stmt, i, value) {
|
|
189
|
+
verifyStatement(stmt);
|
|
190
|
+
if (value > MAX_INT64 || value < MIN_INT64) return SQLite.SQLITE_RANGE;
|
|
191
|
+
|
|
192
|
+
const lo32 = value & 0xffffffffn;
|
|
193
|
+
const hi32 = value >> 32n;
|
|
194
|
+
const result = f(stmt, i, Number(lo32), Number(hi32));
|
|
195
|
+
return check(fname, result, mapStmtToDB.get(stmt));
|
|
196
|
+
};
|
|
197
|
+
})();
|
|
198
|
+
|
|
199
|
+
sqlite3.bind_null = (function() {
|
|
200
|
+
const fname = 'sqlite3_bind_null';
|
|
201
|
+
const f = Module.cwrap(fname, ...decl('nn:n'));
|
|
202
|
+
return function(stmt, i) {
|
|
203
|
+
verifyStatement(stmt);
|
|
204
|
+
const result = f(stmt, i);
|
|
205
|
+
return check(fname, result, mapStmtToDB.get(stmt));
|
|
206
|
+
};
|
|
207
|
+
})();
|
|
208
|
+
|
|
209
|
+
sqlite3.bind_parameter_name = (function() {
|
|
210
|
+
const fname = 'sqlite3_bind_parameter_name';
|
|
211
|
+
const f = Module.cwrap(fname, ...decl('n:s'));
|
|
212
|
+
return function(stmt, i) {
|
|
213
|
+
verifyStatement(stmt);
|
|
214
|
+
const result = f(stmt, i);
|
|
215
|
+
return result;
|
|
216
|
+
};
|
|
217
|
+
})();
|
|
218
|
+
|
|
219
|
+
sqlite3.bind_text = (function() {
|
|
220
|
+
const fname = 'sqlite3_bind_text';
|
|
221
|
+
const f = Module.cwrap(fname, ...decl('nnnnn:n'));
|
|
222
|
+
return function(stmt, i, value) {
|
|
223
|
+
verifyStatement(stmt);
|
|
224
|
+
const ptr = createUTF8(value);
|
|
225
|
+
const result = f(stmt, i, ptr, -1, sqliteFreeAddress);
|
|
226
|
+
return check(fname, result, mapStmtToDB.get(stmt));
|
|
227
|
+
};
|
|
228
|
+
})();
|
|
229
|
+
|
|
230
|
+
sqlite3.changes = (function() {
|
|
231
|
+
const fname = 'sqlite3_changes';
|
|
232
|
+
const f = Module.cwrap(fname, ...decl('n:n'));
|
|
233
|
+
return function(db) {
|
|
234
|
+
verifyDatabase(db);
|
|
235
|
+
const result = f(db);
|
|
236
|
+
return result;
|
|
237
|
+
};
|
|
238
|
+
})();
|
|
239
|
+
|
|
240
|
+
sqlite3.clear_bindings = (function() {
|
|
241
|
+
const fname = 'sqlite3_clear_bindings';
|
|
242
|
+
const f = Module.cwrap(fname, ...decl('n:n'));
|
|
243
|
+
return function(stmt) {
|
|
244
|
+
verifyStatement(stmt);
|
|
245
|
+
const result = f(stmt);
|
|
246
|
+
return check(fname, result, mapStmtToDB.get(stmt));
|
|
247
|
+
};
|
|
248
|
+
})();
|
|
249
|
+
|
|
250
|
+
sqlite3.close = (function() {
|
|
251
|
+
const fname = 'sqlite3_close';
|
|
252
|
+
const f = Module.cwrap(fname, ...decl('n:n'), { async });
|
|
253
|
+
// return async function(db) {
|
|
254
|
+
return function(db) {
|
|
255
|
+
verifyDatabase(db);
|
|
256
|
+
// const result = await f(db);
|
|
257
|
+
const result = f(db);
|
|
258
|
+
databases.delete(db);
|
|
259
|
+
return check(fname, result, db);
|
|
260
|
+
};
|
|
261
|
+
})();
|
|
262
|
+
|
|
263
|
+
sqlite3.column = function(stmt, iCol) {
|
|
264
|
+
verifyStatement(stmt);
|
|
265
|
+
const type = sqlite3.column_type(stmt, iCol);
|
|
266
|
+
switch (type) {
|
|
267
|
+
case SQLite.SQLITE_BLOB:
|
|
268
|
+
return sqlite3.column_blob(stmt, iCol);
|
|
269
|
+
case SQLite.SQLITE_FLOAT:
|
|
270
|
+
return sqlite3.column_double(stmt, iCol);
|
|
271
|
+
case SQLite.SQLITE_INTEGER:
|
|
272
|
+
const lo32 = sqlite3.column_int(stmt, iCol);
|
|
273
|
+
const hi32 = Module.getTempRet0();
|
|
274
|
+
return cvt32x2AsSafe(lo32, hi32);
|
|
275
|
+
case SQLite.SQLITE_NULL:
|
|
276
|
+
return null;
|
|
277
|
+
case SQLite.SQLITE_TEXT:
|
|
278
|
+
return sqlite3.column_text(stmt, iCol);
|
|
279
|
+
default:
|
|
280
|
+
throw new SQLiteError('unknown type', type);
|
|
281
|
+
}
|
|
282
|
+
};
|
|
283
|
+
|
|
284
|
+
sqlite3.column_blob = (function() {
|
|
285
|
+
const fname = 'sqlite3_column_blob';
|
|
286
|
+
const f = Module.cwrap(fname, ...decl('nn:n'));
|
|
287
|
+
return function(stmt, iCol) {
|
|
288
|
+
verifyStatement(stmt);
|
|
289
|
+
const nBytes = sqlite3.column_bytes(stmt, iCol);
|
|
290
|
+
const address = f(stmt, iCol);
|
|
291
|
+
const result = Module.HEAPU8.subarray(address, address + nBytes);
|
|
292
|
+
return result;
|
|
293
|
+
};
|
|
294
|
+
})();
|
|
295
|
+
|
|
296
|
+
sqlite3.column_bytes = (function() {
|
|
297
|
+
const fname = 'sqlite3_column_bytes';
|
|
298
|
+
const f = Module.cwrap(fname, ...decl('nn:n'));
|
|
299
|
+
return function(stmt, iCol) {
|
|
300
|
+
verifyStatement(stmt);
|
|
301
|
+
const result = f(stmt, iCol);
|
|
302
|
+
return result;
|
|
303
|
+
};
|
|
304
|
+
})();
|
|
305
|
+
|
|
306
|
+
sqlite3.column_count = (function() {
|
|
307
|
+
const fname = 'sqlite3_column_count';
|
|
308
|
+
const f = Module.cwrap(fname, ...decl('n:n'));
|
|
309
|
+
return function(stmt) {
|
|
310
|
+
verifyStatement(stmt);
|
|
311
|
+
const result = f(stmt);
|
|
312
|
+
return result;
|
|
313
|
+
};
|
|
314
|
+
})();
|
|
315
|
+
|
|
316
|
+
sqlite3.column_double = (function() {
|
|
317
|
+
const fname = 'sqlite3_column_double';
|
|
318
|
+
const f = Module.cwrap(fname, ...decl('nn:n'));
|
|
319
|
+
return function(stmt, iCol) {
|
|
320
|
+
verifyStatement(stmt);
|
|
321
|
+
const result = f(stmt, iCol);
|
|
322
|
+
return result;
|
|
323
|
+
};
|
|
324
|
+
})();
|
|
325
|
+
|
|
326
|
+
sqlite3.column_int = (function() {
|
|
327
|
+
// Retrieve int64 but use only the lower 32 bits. The upper 32-bits are
|
|
328
|
+
// accessible with Module.getTempRet0().
|
|
329
|
+
const fname = 'sqlite3_column_int64';
|
|
330
|
+
const f = Module.cwrap(fname, ...decl('nn:n'));
|
|
331
|
+
return function(stmt, iCol) {
|
|
332
|
+
verifyStatement(stmt);
|
|
333
|
+
const result = f(stmt, iCol);
|
|
334
|
+
return result;
|
|
335
|
+
};
|
|
336
|
+
})();
|
|
337
|
+
|
|
338
|
+
sqlite3.column_int64 = (function() {
|
|
339
|
+
const fname = 'sqlite3_column_int64';
|
|
340
|
+
const f = Module.cwrap(fname, ...decl('nn:n'));
|
|
341
|
+
return function(stmt, iCol) {
|
|
342
|
+
verifyStatement(stmt);
|
|
343
|
+
const lo32 = f(stmt, iCol);
|
|
344
|
+
const hi32 = Module.getTempRet0();
|
|
345
|
+
const result = cvt32x2ToBigInt(lo32, hi32);
|
|
346
|
+
return result;
|
|
347
|
+
};
|
|
348
|
+
})();
|
|
349
|
+
|
|
350
|
+
sqlite3.column_name = (function() {
|
|
351
|
+
const fname = 'sqlite3_column_name';
|
|
352
|
+
const f = Module.cwrap(fname, ...decl('nn:s'));
|
|
353
|
+
return function(stmt, iCol) {
|
|
354
|
+
verifyStatement(stmt);
|
|
355
|
+
const result = f(stmt, iCol);
|
|
356
|
+
return result;
|
|
357
|
+
};
|
|
358
|
+
})();
|
|
359
|
+
|
|
360
|
+
sqlite3.column_names = function(stmt) {
|
|
361
|
+
const columns = [];
|
|
362
|
+
const nColumns = sqlite3.column_count(stmt);
|
|
363
|
+
for (let i = 0; i < nColumns; ++i) {
|
|
364
|
+
columns.push(sqlite3.column_name(stmt, i));
|
|
365
|
+
}
|
|
366
|
+
return columns;
|
|
367
|
+
};
|
|
368
|
+
|
|
369
|
+
sqlite3.column_text = (function() {
|
|
370
|
+
const fname = 'sqlite3_column_text';
|
|
371
|
+
const f = Module.cwrap(fname, ...decl('nn:s'));
|
|
372
|
+
return function(stmt, iCol) {
|
|
373
|
+
verifyStatement(stmt);
|
|
374
|
+
const result = f(stmt, iCol);
|
|
375
|
+
return result;
|
|
376
|
+
};
|
|
377
|
+
})();
|
|
378
|
+
|
|
379
|
+
sqlite3.column_type = (function() {
|
|
380
|
+
const fname = 'sqlite3_column_type';
|
|
381
|
+
const f = Module.cwrap(fname, ...decl('nn:n'));
|
|
382
|
+
return function(stmt, iCol) {
|
|
383
|
+
verifyStatement(stmt);
|
|
384
|
+
const result = f(stmt, iCol);
|
|
385
|
+
return result;
|
|
386
|
+
};
|
|
387
|
+
})();
|
|
388
|
+
|
|
389
|
+
sqlite3.create_function = function(db, zFunctionName, nArg, eTextRep, pApp, xFunc, xStep, xFinal) {
|
|
390
|
+
verifyDatabase(db);
|
|
391
|
+
|
|
392
|
+
// Convert SQLite callback arguments to JavaScript-friendly arguments.
|
|
393
|
+
function adapt(f) {
|
|
394
|
+
// return f instanceof AsyncFunction ?
|
|
395
|
+
// (async (ctx, n, values) => f(ctx, Module.HEAP32.subarray(values / 4, values / 4 + n))) :
|
|
396
|
+
// ((ctx, n, values) => f(ctx, Module.HEAP32.subarray(values / 4, values / 4 + n)));
|
|
397
|
+
return ((ctx, n, values) => f(ctx, Module.HEAP32.subarray(values / 4, values / 4 + n)));
|
|
398
|
+
}
|
|
399
|
+
|
|
400
|
+
const result = Module.create_function(
|
|
401
|
+
db,
|
|
402
|
+
zFunctionName,
|
|
403
|
+
nArg,
|
|
404
|
+
eTextRep,
|
|
405
|
+
pApp,
|
|
406
|
+
xFunc && adapt(xFunc),
|
|
407
|
+
xStep && adapt(xStep),
|
|
408
|
+
xFinal);
|
|
409
|
+
return check('sqlite3_create_function', result, db);
|
|
410
|
+
};
|
|
411
|
+
|
|
412
|
+
sqlite3.data_count = (function() {
|
|
413
|
+
const fname = 'sqlite3_data_count';
|
|
414
|
+
const f = Module.cwrap(fname, ...decl('n:n'));
|
|
415
|
+
return function(stmt) {
|
|
416
|
+
verifyStatement(stmt);
|
|
417
|
+
const result = f(stmt);
|
|
418
|
+
return result;
|
|
419
|
+
};
|
|
420
|
+
})();
|
|
421
|
+
|
|
422
|
+
// sqlite3.exec = async function(db, sql, callback) {
|
|
423
|
+
// for await (const stmt of sqlite3.statements(db, sql)) {
|
|
424
|
+
// let columns;
|
|
425
|
+
// while (await sqlite3.step(stmt) === SQLite.SQLITE_ROW) {
|
|
426
|
+
// if (callback) {
|
|
427
|
+
// columns = columns ?? sqlite3.column_names(stmt);
|
|
428
|
+
// const row = sqlite3.row(stmt);
|
|
429
|
+
// await callback(row, columns);
|
|
430
|
+
// }
|
|
431
|
+
// }
|
|
432
|
+
// }
|
|
433
|
+
// return SQLite.SQLITE_OK;
|
|
434
|
+
// };
|
|
435
|
+
sqlite3.exec = function(db, sql, callback) {
|
|
436
|
+
for (const stmt of sqlite3.statements(db, sql)) {
|
|
437
|
+
let columns;
|
|
438
|
+
while (sqlite3.step(stmt) === SQLite.SQLITE_ROW) {
|
|
439
|
+
if (callback) {
|
|
440
|
+
columns = columns ?? sqlite3.column_names(stmt);
|
|
441
|
+
const row = sqlite3.row(stmt);
|
|
442
|
+
callback(row, columns);
|
|
443
|
+
}
|
|
444
|
+
}
|
|
445
|
+
}
|
|
446
|
+
return SQLite.SQLITE_OK;
|
|
447
|
+
};
|
|
448
|
+
|
|
449
|
+
sqlite3.finalize = (function() {
|
|
450
|
+
const fname = 'sqlite3_finalize';
|
|
451
|
+
const f = Module.cwrap(fname, ...decl('n:n'), { async });
|
|
452
|
+
// return async function(stmt) {
|
|
453
|
+
// const result = await f(stmt);
|
|
454
|
+
return function(stmt) {
|
|
455
|
+
const result = f(stmt);
|
|
456
|
+
mapStmtToDB.delete(stmt)
|
|
457
|
+
|
|
458
|
+
// Don't throw on error here. Typically the error has already been
|
|
459
|
+
// thrown and finalize() is part of the cleanup.
|
|
460
|
+
return result;
|
|
461
|
+
};
|
|
462
|
+
})();
|
|
463
|
+
|
|
464
|
+
sqlite3.get_autocommit = (function() {
|
|
465
|
+
const fname = 'sqlite3_get_autocommit';
|
|
466
|
+
const f = Module.cwrap(fname, ...decl('n:n'));
|
|
467
|
+
return function(db) {
|
|
468
|
+
const result = f(db);
|
|
469
|
+
return result;
|
|
470
|
+
};
|
|
471
|
+
})();
|
|
472
|
+
|
|
473
|
+
sqlite3.libversion = (function() {
|
|
474
|
+
const fname = 'sqlite3_libversion';
|
|
475
|
+
const f = Module.cwrap(fname, ...decl(':s'));
|
|
476
|
+
return function() {
|
|
477
|
+
const result = f();
|
|
478
|
+
return result;
|
|
479
|
+
};
|
|
480
|
+
})();
|
|
481
|
+
|
|
482
|
+
sqlite3.libversion_number = (function() {
|
|
483
|
+
const fname = 'sqlite3_libversion_number';
|
|
484
|
+
const f = Module.cwrap(fname, ...decl(':n'));
|
|
485
|
+
return function() {
|
|
486
|
+
const result = f();
|
|
487
|
+
return result;
|
|
488
|
+
};
|
|
489
|
+
})();
|
|
490
|
+
|
|
491
|
+
sqlite3.limit = (function() {
|
|
492
|
+
const fname = 'sqlite3_limit';
|
|
493
|
+
const f = Module.cwrap(fname, ...decl('nnn:n'));
|
|
494
|
+
return function(db, id, newVal) {
|
|
495
|
+
const result = f(db, id, newVal);
|
|
496
|
+
return result;
|
|
497
|
+
};
|
|
498
|
+
})();
|
|
499
|
+
|
|
500
|
+
sqlite3.open_v2 = (function() {
|
|
501
|
+
const fname = 'sqlite3_open_v2';
|
|
502
|
+
const f = Module.cwrap(fname, ...decl('snnn:n'), { async });
|
|
503
|
+
return function(zFilename, flags, zVfs) {
|
|
504
|
+
flags = flags || SQLite.SQLITE_OPEN_CREATE | SQLite.SQLITE_OPEN_READWRITE;
|
|
505
|
+
zVfs = createUTF8(zVfs);
|
|
506
|
+
try {
|
|
507
|
+
// Allow retry operations.
|
|
508
|
+
// const rc = await retry(() => f(zFilename, tmpPtr[0], flags, zVfs));
|
|
509
|
+
const rc = f(zFilename, tmpPtr[0], flags, zVfs);
|
|
510
|
+
|
|
511
|
+
const db = Module.getValue(tmpPtr[0], '*');
|
|
512
|
+
databases.add(db);
|
|
513
|
+
|
|
514
|
+
Module.ccall('RegisterExtensionFunctions', 'void', ['number'], [db]);
|
|
515
|
+
check(fname, rc);
|
|
516
|
+
return db;
|
|
517
|
+
} finally {
|
|
518
|
+
Module._sqlite3_free(zVfs);
|
|
519
|
+
}
|
|
520
|
+
};
|
|
521
|
+
})();
|
|
522
|
+
|
|
523
|
+
sqlite3.progress_handler = function(db, nProgressOps, handler, userData) {
|
|
524
|
+
verifyDatabase(db);
|
|
525
|
+
Module.progress_handler(db, nProgressOps, handler, userData);
|
|
526
|
+
};;
|
|
527
|
+
|
|
528
|
+
sqlite3.reset = (function() {
|
|
529
|
+
const fname = 'sqlite3_reset';
|
|
530
|
+
const f = Module.cwrap(fname, ...decl('n:n'), { async });
|
|
531
|
+
return function(stmt) {
|
|
532
|
+
verifyStatement(stmt);
|
|
533
|
+
const result = f(stmt);
|
|
534
|
+
return check(fname, result, mapStmtToDB.get(stmt));
|
|
535
|
+
};
|
|
536
|
+
})();
|
|
537
|
+
|
|
538
|
+
sqlite3.result = function(context, value) {
|
|
539
|
+
switch (typeof value) {
|
|
540
|
+
case 'number':
|
|
541
|
+
if (value === (value | 0)) {
|
|
542
|
+
sqlite3.result_int(context, value);
|
|
543
|
+
} else {
|
|
544
|
+
sqlite3.result_double(context, value);
|
|
545
|
+
}
|
|
546
|
+
break;
|
|
547
|
+
case 'string':
|
|
548
|
+
sqlite3.result_text(context, value);
|
|
549
|
+
break;
|
|
550
|
+
default:
|
|
551
|
+
if (value instanceof Uint8Array || Array.isArray(value)) {
|
|
552
|
+
sqlite3.result_blob(context, value);
|
|
553
|
+
} else if (value === null) {
|
|
554
|
+
sqlite3.result_null(context);
|
|
555
|
+
} else if (typeof value === 'bigint') {
|
|
556
|
+
return sqlite3.result_int64(context, value);
|
|
557
|
+
} else {
|
|
558
|
+
console.warn('unknown result converted to null', value);
|
|
559
|
+
sqlite3.result_null(context);
|
|
560
|
+
}
|
|
561
|
+
break;
|
|
562
|
+
}
|
|
563
|
+
|
|
564
|
+
};
|
|
565
|
+
|
|
566
|
+
sqlite3.result_blob = (function() {
|
|
567
|
+
const fname = 'sqlite3_result_blob';
|
|
568
|
+
const f = Module.cwrap(fname, ...decl('nnnn:n'));
|
|
569
|
+
return function(context, value) {
|
|
570
|
+
// @ts-ignore
|
|
571
|
+
const byteLength = value.byteLength ?? value.length;
|
|
572
|
+
const ptr = Module._sqlite3_malloc(byteLength);
|
|
573
|
+
Module.HEAPU8.subarray(ptr).set(value);
|
|
574
|
+
f(context, ptr, byteLength, sqliteFreeAddress); // void return
|
|
575
|
+
};
|
|
576
|
+
})();
|
|
577
|
+
|
|
578
|
+
sqlite3.result_double = (function() {
|
|
579
|
+
const fname = 'sqlite3_result_double';
|
|
580
|
+
const f = Module.cwrap(fname, ...decl('nn:n'));
|
|
581
|
+
return function(context, value) {
|
|
582
|
+
f(context, value); // void return
|
|
583
|
+
};
|
|
584
|
+
})();
|
|
585
|
+
|
|
586
|
+
sqlite3.result_int = (function() {
|
|
587
|
+
const fname = 'sqlite3_result_int';
|
|
588
|
+
const f = Module.cwrap(fname, ...decl('nn:n'));
|
|
589
|
+
return function(context, value) {
|
|
590
|
+
f(context, value); // void return
|
|
591
|
+
};
|
|
592
|
+
})();
|
|
593
|
+
|
|
594
|
+
sqlite3.result_int64 = (function() {
|
|
595
|
+
const fname = 'sqlite3_result_int64';
|
|
596
|
+
const f = Module.cwrap(fname, ...decl('nnn:n'));
|
|
597
|
+
return function(context, value) {
|
|
598
|
+
if (value > MAX_INT64 || value < MIN_INT64) return SQLite.SQLITE_RANGE;
|
|
599
|
+
|
|
600
|
+
const lo32 = value & 0xffffffffn;
|
|
601
|
+
const hi32 = value >> 32n;
|
|
602
|
+
f(context, Number(lo32), Number(hi32)); // void return
|
|
603
|
+
};
|
|
604
|
+
})();
|
|
605
|
+
|
|
606
|
+
sqlite3.result_null = (function() {
|
|
607
|
+
const fname = 'sqlite3_result_null';
|
|
608
|
+
const f = Module.cwrap(fname, ...decl('n:n'));
|
|
609
|
+
return function(context) {
|
|
610
|
+
f(context); // void return
|
|
611
|
+
};
|
|
612
|
+
})();
|
|
613
|
+
|
|
614
|
+
sqlite3.result_text = (function() {
|
|
615
|
+
const fname = 'sqlite3_result_text';
|
|
616
|
+
const f = Module.cwrap(fname, ...decl('nnnn:n'));
|
|
617
|
+
return function(context, value) {
|
|
618
|
+
const ptr = createUTF8(value);
|
|
619
|
+
f(context, ptr, -1, sqliteFreeAddress); // void return
|
|
620
|
+
};
|
|
621
|
+
})();
|
|
622
|
+
|
|
623
|
+
sqlite3.row = function(stmt) {
|
|
624
|
+
const row = [];
|
|
625
|
+
const nColumns = sqlite3.data_count(stmt);
|
|
626
|
+
for (let i = 0; i < nColumns; ++i) {
|
|
627
|
+
const value = sqlite3.column(stmt, i);
|
|
628
|
+
|
|
629
|
+
// Copy blob if aliasing volatile WebAssembly memory. This avoids an
|
|
630
|
+
// unnecessary copy if users monkey patch column_blob to copy.
|
|
631
|
+
// @ts-ignore
|
|
632
|
+
row.push(value?.buffer === Module.HEAPU8.buffer ? value.slice() : value);
|
|
633
|
+
}
|
|
634
|
+
return row;
|
|
635
|
+
};
|
|
636
|
+
|
|
637
|
+
sqlite3.set_authorizer = function(db, xAuth, pApp) {
|
|
638
|
+
verifyDatabase(db);
|
|
639
|
+
|
|
640
|
+
// Convert SQLite callback arguments to JavaScript-friendly arguments.
|
|
641
|
+
function cvtArgs(_, iAction, p3, p4, p5, p6) {
|
|
642
|
+
return [
|
|
643
|
+
_,
|
|
644
|
+
iAction,
|
|
645
|
+
Module.UTF8ToString(p3),
|
|
646
|
+
Module.UTF8ToString(p4),
|
|
647
|
+
Module.UTF8ToString(p5),
|
|
648
|
+
Module.UTF8ToString(p6)
|
|
649
|
+
];
|
|
650
|
+
};
|
|
651
|
+
function adapt(f) {
|
|
652
|
+
// return f instanceof AsyncFunction ?
|
|
653
|
+
// (async (_, iAction, p3, p4, p5, p6) => f(cvtArgs(_, iAction, p3, p4, p5, p6))) :
|
|
654
|
+
// ((_, iAction, p3, p4, p5, p6) => f(cvtArgs(_, iAction, p3, p4, p5, p6)));
|
|
655
|
+
return ((_, iAction, p3, p4, p5, p6) => f(cvtArgs(_, iAction, p3, p4, p5, p6)));
|
|
656
|
+
}
|
|
657
|
+
|
|
658
|
+
const result = Module.set_authorizer(db, adapt(xAuth), pApp);
|
|
659
|
+
return check('sqlite3_set_authorizer', result, db);
|
|
660
|
+
};;
|
|
661
|
+
|
|
662
|
+
sqlite3.sql = (function() {
|
|
663
|
+
const fname = 'sqlite3_sql';
|
|
664
|
+
const f = Module.cwrap(fname, ...decl('n:s'));
|
|
665
|
+
return function(stmt) {
|
|
666
|
+
verifyStatement(stmt);
|
|
667
|
+
const result = f(stmt);
|
|
668
|
+
return result;
|
|
669
|
+
};
|
|
670
|
+
})();
|
|
671
|
+
|
|
672
|
+
sqlite3.statements = function(db, sql, options = {}) {
|
|
673
|
+
const prepare = Module.cwrap(
|
|
674
|
+
'sqlite3_prepare_v3',
|
|
675
|
+
'number',
|
|
676
|
+
['number', 'number', 'number', 'number', 'number', 'number'],
|
|
677
|
+
// { async: true });
|
|
678
|
+
{ async: false });
|
|
679
|
+
|
|
680
|
+
const results = [];
|
|
681
|
+
|
|
682
|
+
const onFinally = [];
|
|
683
|
+
try {
|
|
684
|
+
// Encode SQL string to UTF-8.
|
|
685
|
+
const utf8 = new TextEncoder().encode(sql);
|
|
686
|
+
|
|
687
|
+
// Copy encoded string to WebAssembly memory. The SQLite docs say
|
|
688
|
+
// zero-termination is a minor optimization so add room for that.
|
|
689
|
+
// Also add space for the statement handle and SQL tail pointer.
|
|
690
|
+
const allocSize = utf8.byteLength - (utf8.byteLength % 4) + 12;
|
|
691
|
+
const pzHead = Module._sqlite3_malloc(allocSize);
|
|
692
|
+
const pzEnd = pzHead + utf8.byteLength + 1;
|
|
693
|
+
onFinally.push(() => Module._sqlite3_free(pzHead));
|
|
694
|
+
Module.HEAPU8.set(utf8, pzHead);
|
|
695
|
+
Module.HEAPU8[pzEnd - 1] = 0;
|
|
696
|
+
|
|
697
|
+
// Use extra space for the statement handle and SQL tail pointer.
|
|
698
|
+
const pStmt = pzHead + allocSize - 8;
|
|
699
|
+
const pzTail = pzHead + allocSize - 4;
|
|
700
|
+
|
|
701
|
+
// Ensure that statement handles are not leaked.
|
|
702
|
+
let stmt;
|
|
703
|
+
function maybeFinalize() {
|
|
704
|
+
if (stmt && !options.unscoped) {
|
|
705
|
+
sqlite3.finalize(stmt);
|
|
706
|
+
}
|
|
707
|
+
stmt = 0;
|
|
708
|
+
}
|
|
709
|
+
onFinally.push(maybeFinalize);
|
|
710
|
+
|
|
711
|
+
// Loop over statements.
|
|
712
|
+
Module.setValue(pzTail, pzHead, '*');
|
|
713
|
+
do {
|
|
714
|
+
// Reclaim resources for the previous iteration.
|
|
715
|
+
maybeFinalize();
|
|
716
|
+
|
|
717
|
+
// Call sqlite3_prepare_v3() for the next statement.
|
|
718
|
+
// Allow retry operations.
|
|
719
|
+
const zTail = Module.getValue(pzTail, '*');
|
|
720
|
+
// const rc = await retry(() => {
|
|
721
|
+
// return prepare(
|
|
722
|
+
// db,
|
|
723
|
+
// zTail,
|
|
724
|
+
// pzEnd - pzTail,
|
|
725
|
+
// options.flags || 0,
|
|
726
|
+
// pStmt,
|
|
727
|
+
// pzTail);
|
|
728
|
+
// });
|
|
729
|
+
const rc = prepare(
|
|
730
|
+
db,
|
|
731
|
+
zTail,
|
|
732
|
+
pzEnd - pzTail,
|
|
733
|
+
options.flags || 0,
|
|
734
|
+
pStmt,
|
|
735
|
+
pzTail);
|
|
736
|
+
|
|
737
|
+
if (rc !== SQLite.SQLITE_OK) {
|
|
738
|
+
check('sqlite3_prepare_v3', rc, db);
|
|
739
|
+
}
|
|
740
|
+
|
|
741
|
+
stmt = Module.getValue(pStmt, '*');
|
|
742
|
+
if (stmt) {
|
|
743
|
+
mapStmtToDB.set(stmt, db);
|
|
744
|
+
// yield stmt;
|
|
745
|
+
results.push(stmt);
|
|
746
|
+
}
|
|
747
|
+
} while (stmt);
|
|
748
|
+
} finally {
|
|
749
|
+
while (onFinally.length) {
|
|
750
|
+
onFinally.pop()();
|
|
751
|
+
}
|
|
752
|
+
}
|
|
753
|
+
|
|
754
|
+
return results;
|
|
755
|
+
};
|
|
756
|
+
|
|
757
|
+
sqlite3.step = (function() {
|
|
758
|
+
const fname = 'sqlite3_step';
|
|
759
|
+
const f = Module.cwrap(fname, ...decl('n:n'), { async });
|
|
760
|
+
// return async function(stmt) {
|
|
761
|
+
return function(stmt) {
|
|
762
|
+
verifyStatement(stmt);
|
|
763
|
+
|
|
764
|
+
// Allow retry operations.
|
|
765
|
+
// const rc = await retry(() => f(stmt));
|
|
766
|
+
const rc = f(stmt);
|
|
767
|
+
|
|
768
|
+
return check(fname, rc, mapStmtToDB.get(stmt), [SQLite.SQLITE_ROW, SQLite.SQLITE_DONE]);
|
|
769
|
+
};
|
|
770
|
+
})();
|
|
771
|
+
|
|
772
|
+
sqlite3.value = function(pValue) {
|
|
773
|
+
const type = sqlite3.value_type(pValue);
|
|
774
|
+
switch (type) {
|
|
775
|
+
case SQLite.SQLITE_BLOB:
|
|
776
|
+
return sqlite3.value_blob(pValue);
|
|
777
|
+
case SQLite.SQLITE_FLOAT:
|
|
778
|
+
return sqlite3.value_double(pValue);
|
|
779
|
+
case SQLite.SQLITE_INTEGER:
|
|
780
|
+
const lo32 = sqlite3.value_int(pValue);
|
|
781
|
+
const hi32 = Module.getTempRet0();
|
|
782
|
+
return cvt32x2AsSafe(lo32, hi32);
|
|
783
|
+
case SQLite.SQLITE_NULL:
|
|
784
|
+
return null;
|
|
785
|
+
case SQLite.SQLITE_TEXT:
|
|
786
|
+
return sqlite3.value_text(pValue);
|
|
787
|
+
default:
|
|
788
|
+
throw new SQLiteError('unknown type', type);
|
|
789
|
+
}
|
|
790
|
+
};
|
|
791
|
+
|
|
792
|
+
sqlite3.value_blob = (function() {
|
|
793
|
+
const fname = 'sqlite3_value_blob';
|
|
794
|
+
const f = Module.cwrap(fname, ...decl('n:n'));
|
|
795
|
+
return function(pValue) {
|
|
796
|
+
const nBytes = sqlite3.value_bytes(pValue);
|
|
797
|
+
const address = f(pValue);
|
|
798
|
+
const result = Module.HEAPU8.subarray(address, address + nBytes);
|
|
799
|
+
return result;
|
|
800
|
+
};
|
|
801
|
+
})();
|
|
802
|
+
|
|
803
|
+
sqlite3.value_bytes = (function() {
|
|
804
|
+
const fname = 'sqlite3_value_bytes';
|
|
805
|
+
const f = Module.cwrap(fname, ...decl('n:n'));
|
|
806
|
+
return function(pValue) {
|
|
807
|
+
const result = f(pValue);
|
|
808
|
+
return result;
|
|
809
|
+
};
|
|
810
|
+
})();
|
|
811
|
+
|
|
812
|
+
sqlite3.value_double = (function() {
|
|
813
|
+
const fname = 'sqlite3_value_double';
|
|
814
|
+
const f = Module.cwrap(fname, ...decl('n:n'));
|
|
815
|
+
return function(pValue) {
|
|
816
|
+
const result = f(pValue);
|
|
817
|
+
return result;
|
|
818
|
+
};
|
|
819
|
+
})();
|
|
820
|
+
|
|
821
|
+
sqlite3.value_int = (function() {
|
|
822
|
+
const fname = 'sqlite3_value_int64';
|
|
823
|
+
const f = Module.cwrap(fname, ...decl('n:n'));
|
|
824
|
+
return function(pValue) {
|
|
825
|
+
const result = f(pValue);
|
|
826
|
+
return result;
|
|
827
|
+
};
|
|
828
|
+
})();
|
|
829
|
+
|
|
830
|
+
sqlite3.value_int64 = (function() {
|
|
831
|
+
const fname = 'sqlite3_value_int64';
|
|
832
|
+
const f = Module.cwrap(fname, ...decl('n:n'));
|
|
833
|
+
return function(pValue) {
|
|
834
|
+
const lo32 = f(pValue);
|
|
835
|
+
const hi32 = Module.getTempRet0();
|
|
836
|
+
const result = cvt32x2ToBigInt(lo32, hi32);
|
|
837
|
+
return result;
|
|
838
|
+
};
|
|
839
|
+
})();
|
|
840
|
+
|
|
841
|
+
sqlite3.value_text = (function() {
|
|
842
|
+
const fname = 'sqlite3_value_text';
|
|
843
|
+
const f = Module.cwrap(fname, ...decl('n:s'));
|
|
844
|
+
return function(pValue) {
|
|
845
|
+
const result = f(pValue);
|
|
846
|
+
return result;
|
|
847
|
+
};
|
|
848
|
+
})();
|
|
849
|
+
|
|
850
|
+
sqlite3.value_type = (function() {
|
|
851
|
+
const fname = 'sqlite3_value_type';
|
|
852
|
+
const f = Module.cwrap(fname, ...decl('n:n'));
|
|
853
|
+
return function(pValue) {
|
|
854
|
+
const result = f(pValue);
|
|
855
|
+
return result;
|
|
856
|
+
};
|
|
857
|
+
})();
|
|
858
|
+
|
|
859
|
+
sqlite3.vfs_register = function(vfs, makeDefault) {
|
|
860
|
+
const result = Module.vfs_register(vfs, makeDefault);
|
|
861
|
+
return check('sqlite3_vfs_register', result);
|
|
862
|
+
};
|
|
863
|
+
|
|
864
|
+
function check(fname, result, db = null, allowed = [SQLite.SQLITE_OK]) {
|
|
865
|
+
if (allowed.includes(result)) return result;
|
|
866
|
+
const message = db ?
|
|
867
|
+
Module.ccall('sqlite3_errmsg', 'string', ['number'], [db]) :
|
|
868
|
+
fname;
|
|
869
|
+
throw new SQLiteError(message, result);
|
|
870
|
+
}
|
|
871
|
+
|
|
872
|
+
// This function is used to automatically retry failed calls that
|
|
873
|
+
// have pending retry operations that should allow the retry to
|
|
874
|
+
// succeed.
|
|
875
|
+
// async function retry(f) {
|
|
876
|
+
// let rc;
|
|
877
|
+
// do {
|
|
878
|
+
// // Wait for all pending retry operations to complete. This is
|
|
879
|
+
// // normally empty on the first loop iteration.
|
|
880
|
+
// if (Module.retryOps.length) {
|
|
881
|
+
// await Promise.all(Module.retryOps);
|
|
882
|
+
// Module.retryOps = [];
|
|
883
|
+
// }
|
|
884
|
+
|
|
885
|
+
// rc = await f();
|
|
886
|
+
|
|
887
|
+
// // Retry on failure with new pending retry operations.
|
|
888
|
+
// } while (rc && Module.retryOps.length);
|
|
889
|
+
// return rc;
|
|
890
|
+
// }
|
|
891
|
+
|
|
892
|
+
return sqlite3;
|
|
893
|
+
}
|
|
894
|
+
|
|
895
|
+
// Helper function to use a more compact signature specification.
|
|
896
|
+
function decl(s) {
|
|
897
|
+
const result = [];
|
|
898
|
+
const m = s.match(/([ns@]*):([nsv@])/);
|
|
899
|
+
switch (m[2]) {
|
|
900
|
+
case 'n': result.push('number'); break;
|
|
901
|
+
case 's': result.push('string'); break;
|
|
902
|
+
case 'v': result.push(null); break;
|
|
903
|
+
}
|
|
904
|
+
|
|
905
|
+
const args = [];
|
|
906
|
+
for (let c of m[1]) {
|
|
907
|
+
switch (c) {
|
|
908
|
+
case 'n': args.push('number'); break;
|
|
909
|
+
case 's': args.push('string'); break;
|
|
910
|
+
}
|
|
911
|
+
}
|
|
912
|
+
result.push(args);
|
|
913
|
+
return result;
|
|
914
|
+
}
|