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