indexeddbshim 17.4.3 → 17.6.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/dist/IDBFactory.d.ts +1 -3
- package/dist/IDBFactory.d.ts.map +1 -1
- package/dist/IDBTransaction.d.ts +1 -77
- package/dist/IDBTransaction.d.ts.map +1 -1
- package/dist/indexeddbshim-Key.js +1 -1
- package/dist/indexeddbshim-Key.min.js +1 -1
- package/dist/indexeddbshim-UnicodeIdentifiers-node.cjs +30 -2011
- package/dist/indexeddbshim-UnicodeIdentifiers-node.cjs.map +1 -1
- package/dist/indexeddbshim-UnicodeIdentifiers.js +22 -9
- package/dist/indexeddbshim-UnicodeIdentifiers.js.map +1 -1
- package/dist/indexeddbshim-UnicodeIdentifiers.min.js +3 -3
- package/dist/indexeddbshim-UnicodeIdentifiers.min.js.map +1 -1
- package/dist/indexeddbshim-node.cjs +30 -2011
- package/dist/indexeddbshim-node.cjs.map +1 -1
- package/dist/indexeddbshim-noninvasive.js +22 -9
- package/dist/indexeddbshim-noninvasive.js.map +1 -1
- package/dist/indexeddbshim-noninvasive.min.js +3 -3
- package/dist/indexeddbshim-noninvasive.min.js.map +1 -1
- package/dist/indexeddbshim.js +22 -9
- package/dist/indexeddbshim.js.map +1 -1
- package/dist/indexeddbshim.min.js +3 -3
- package/dist/indexeddbshim.min.js.map +1 -1
- package/dist/nodeWebSQL.d.ts +1 -1
- package/dist/nodeWebSQL.d.ts.map +1 -1
- package/package.json +4 -8
- package/src/IDBFactory.js +5 -7
- package/src/IDBTransaction.js +16 -1
- package/src/nodeWebSQL.js +5 -5
- package/dist/nodeSQLiteDatabase.d.ts +0 -64
- package/dist/nodeSQLiteDatabase.d.ts.map +0 -1
- package/src/nodeSQLiteDatabase.js +0 -314
|
@@ -1,12 +1,11 @@
|
|
|
1
|
-
/*! indexeddbshim - v17.
|
|
1
|
+
/*! indexeddbshim - v17.6.0 - 9/1/2026 */
|
|
2
2
|
|
|
3
3
|
'use strict';
|
|
4
4
|
|
|
5
5
|
var fs$1 = require('node:fs');
|
|
6
6
|
var path = require('node:path');
|
|
7
|
-
var
|
|
8
|
-
var
|
|
9
|
-
var require$$2 = require('util');
|
|
7
|
+
var customOpenDatabase = require('websql-configurable/custom/index.js');
|
|
8
|
+
var SQLiteDatabase = require('websql-configurable/lib/sqlite/SQLiteDatabase.js');
|
|
10
9
|
|
|
11
10
|
/* eslint-disable no-restricted-syntax -- Instanceof checks */
|
|
12
11
|
/* eslint-disable unicorn/no-this-assignment -- TS */
|
|
@@ -1567,7 +1566,7 @@ val => {
|
|
|
1567
1566
|
|
|
1568
1567
|
// @ts-nocheck
|
|
1569
1568
|
|
|
1570
|
-
function getDefaultExportFromCjs
|
|
1569
|
+
function getDefaultExportFromCjs(x) {
|
|
1571
1570
|
return x && x.__esModule && Object.prototype.hasOwnProperty.call(x, 'default') ? x['default'] : x;
|
|
1572
1571
|
}
|
|
1573
1572
|
var regex$1;
|
|
@@ -1579,7 +1578,7 @@ function requireRegex() {
|
|
|
1579
1578
|
return regex$1;
|
|
1580
1579
|
}
|
|
1581
1580
|
var regexExports = requireRegex();
|
|
1582
|
-
var regex = /*@__PURE__*/getDefaultExportFromCjs
|
|
1581
|
+
var regex = /*@__PURE__*/getDefaultExportFromCjs(regexExports);
|
|
1583
1582
|
|
|
1584
1583
|
/* eslint-disable new-cap -- ToString is how it is defined */
|
|
1585
1584
|
|
|
@@ -4948,7 +4947,7 @@ const readonlyProperties$4 = ['objectStoreNames', 'mode', 'durability', 'db', 'e
|
|
|
4948
4947
|
* __requestsFinished: boolean,
|
|
4949
4948
|
* __transFinishedCb: (err: boolean, cb: ((bool?: boolean) => void)) => void,
|
|
4950
4949
|
* __callTransFinishedCb: (err: boolean, cb: ((bool?: boolean) => void)) => void,
|
|
4951
|
-
* __transactionEndCallback: () => void,
|
|
4950
|
+
* __transactionEndCallback: (() => void)|undefined,
|
|
4952
4951
|
* __transactionFinished: boolean,
|
|
4953
4952
|
* __completed: boolean,
|
|
4954
4953
|
* __transFinishedCbFired: boolean,
|
|
@@ -4983,6 +4982,19 @@ const readonlyProperties$4 = ['objectStoreNames', 'mode', 'durability', 'db', 'e
|
|
|
4983
4982
|
* }} IDBTransactionFull
|
|
4984
4983
|
*/
|
|
4985
4984
|
|
|
4985
|
+
/**
|
|
4986
|
+
* @param {IDBTransactionFull} tx
|
|
4987
|
+
* @returns {void}
|
|
4988
|
+
*/
|
|
4989
|
+
function releaseFinishedTransaction(tx) {
|
|
4990
|
+
const pos = tx.db.__transactions.indexOf(tx);
|
|
4991
|
+
if (pos !== -1) {
|
|
4992
|
+
tx.db.__transactions.splice(pos, 1);
|
|
4993
|
+
}
|
|
4994
|
+
tx.__transactionEndCallback = undefined;
|
|
4995
|
+
tx.__requests = [];
|
|
4996
|
+
}
|
|
4997
|
+
|
|
4986
4998
|
/**
|
|
4987
4999
|
* The IndexedDB Transaction.
|
|
4988
5000
|
* @see https://dvcs.w3.org/hg/IndexedDB/raw-file/tip/Overview.html#idl-def-IDBTransaction
|
|
@@ -5540,6 +5552,7 @@ IDBTransaction.prototype.__executeRequests = function () {
|
|
|
5540
5552
|
} finally {
|
|
5541
5553
|
activeTransactions.delete(me);
|
|
5542
5554
|
me.__storeHandles = {};
|
|
5555
|
+
releaseFinishedTransaction(me);
|
|
5543
5556
|
}
|
|
5544
5557
|
}
|
|
5545
5558
|
if (me.mode === 'readwrite' || me.mode === 'readonly') {
|
|
@@ -5824,6 +5837,7 @@ IDBTransaction.prototype.__abortTransaction = function (err) {
|
|
|
5824
5837
|
me.dispatchEvent(evt);
|
|
5825
5838
|
me.__storeHandles = {};
|
|
5826
5839
|
me.dispatchEvent(createEvent('__abort'));
|
|
5840
|
+
releaseFinishedTransaction(me);
|
|
5827
5841
|
}, 0);
|
|
5828
5842
|
return undefined;
|
|
5829
5843
|
}).catch(err => {
|
|
@@ -10229,9 +10243,7 @@ function triggerAnyVersionChangeAndBlockedEvents(openConnections, req, oldVersio
|
|
|
10229
10243
|
/**
|
|
10230
10244
|
* @typedef {import('websql-configurable/lib/websql/WebSQLDatabase.js').default & {
|
|
10231
10245
|
* _db: {
|
|
10232
|
-
*
|
|
10233
|
-
* close: (errBack: (err: Error) => void) => void
|
|
10234
|
-
* }
|
|
10246
|
+
* close: (errBack: (err: Error) => void) => void
|
|
10235
10247
|
* }
|
|
10236
10248
|
* }} DatabaseFull
|
|
10237
10249
|
*/
|
|
@@ -10309,7 +10321,7 @@ function closeCachedWebSQLConnections(name, cb) {
|
|
|
10309
10321
|
return;
|
|
10310
10322
|
}
|
|
10311
10323
|
dbs.forEach(db => {
|
|
10312
|
-
const sqliteDB = db._db
|
|
10324
|
+
const sqliteDB = db._db;
|
|
10313
10325
|
if (!sqliteDB || !sqliteDB.close) {
|
|
10314
10326
|
remaining--;
|
|
10315
10327
|
if (remaining === 0) {
|
|
@@ -10351,9 +10363,9 @@ function cleanupDatabaseResources(__openDatabase, name, escapedDatabaseName, dat
|
|
|
10351
10363
|
databaseDeleted();
|
|
10352
10364
|
return;
|
|
10353
10365
|
}
|
|
10354
|
-
const sqliteDB = latestSQLiteDBCached._db
|
|
10366
|
+
const sqliteDB = latestSQLiteDBCached._db;
|
|
10355
10367
|
if (!sqliteDB || !sqliteDB.close) {
|
|
10356
|
-
console.error('The `openDatabase` implementation does not have the expected `._db.
|
|
10368
|
+
console.error('The `openDatabase` implementation does not have the expected `._db.close` method for closing the database');
|
|
10357
10369
|
return;
|
|
10358
10370
|
}
|
|
10359
10371
|
sqliteDB.close(
|
|
@@ -11159,7 +11171,7 @@ IDBFactory.prototype.databases = function () {
|
|
|
11159
11171
|
let calledDbCreateError = false;
|
|
11160
11172
|
// Snapshotted *now*, synchronously, at call time -- not read later
|
|
11161
11173
|
// from inside the SQL query's callback below, which runs on a
|
|
11162
|
-
// deferred macrotask (see `
|
|
11174
|
+
// deferred macrotask (see `websql-configurable`'s `SQLiteDatabase#exec`) and so
|
|
11163
11175
|
// could otherwise race against (and lose to) an in-flight upgrade's
|
|
11164
11176
|
// own commit/abort handler clearing its `pendingVersionChanges`
|
|
11165
11177
|
// entry in the meantime -- which would make this method incorrectly
|
|
@@ -12970,1999 +12982,6 @@ function setGlobalVars(idb, initialConfig) {
|
|
|
12970
12982
|
return /** @type {ShimmedObject} */IDB;
|
|
12971
12983
|
}
|
|
12972
12984
|
|
|
12973
|
-
var commonjsGlobal = typeof globalThis !== 'undefined' ? globalThis : typeof window !== 'undefined' ? window : typeof global !== 'undefined' ? global : typeof self !== 'undefined' ? self : {};
|
|
12974
|
-
|
|
12975
|
-
function getDefaultExportFromCjs (x) {
|
|
12976
|
-
return x && x.__esModule && Object.prototype.hasOwnProperty.call(x, 'default') ? x['default'] : x;
|
|
12977
|
-
}
|
|
12978
|
-
|
|
12979
|
-
var nextTick = {};
|
|
12980
|
-
|
|
12981
|
-
var hasRequiredNextTick;
|
|
12982
|
-
function requireNextTick() {
|
|
12983
|
-
if (hasRequiredNextTick) return nextTick;
|
|
12984
|
-
hasRequiredNextTick = 1;
|
|
12985
|
-
nextTick.test = function () {
|
|
12986
|
-
// Don't get fooled by e.g. browserify environments.
|
|
12987
|
-
return typeof process !== 'undefined' && !process.browser;
|
|
12988
|
-
};
|
|
12989
|
-
nextTick.install = function (func) {
|
|
12990
|
-
return function () {
|
|
12991
|
-
process.nextTick(func);
|
|
12992
|
-
};
|
|
12993
|
-
};
|
|
12994
|
-
return nextTick;
|
|
12995
|
-
}
|
|
12996
|
-
|
|
12997
|
-
var queueMicrotask$1 = {};
|
|
12998
|
-
|
|
12999
|
-
var hasRequiredQueueMicrotask;
|
|
13000
|
-
function requireQueueMicrotask() {
|
|
13001
|
-
if (hasRequiredQueueMicrotask) return queueMicrotask$1;
|
|
13002
|
-
hasRequiredQueueMicrotask = 1;
|
|
13003
|
-
queueMicrotask$1.test = function () {
|
|
13004
|
-
return typeof commonjsGlobal.queueMicrotask === 'function';
|
|
13005
|
-
};
|
|
13006
|
-
queueMicrotask$1.install = function (func) {
|
|
13007
|
-
return function () {
|
|
13008
|
-
commonjsGlobal.queueMicrotask(func);
|
|
13009
|
-
};
|
|
13010
|
-
};
|
|
13011
|
-
return queueMicrotask$1;
|
|
13012
|
-
}
|
|
13013
|
-
|
|
13014
|
-
var mutation = {};
|
|
13015
|
-
|
|
13016
|
-
var hasRequiredMutation;
|
|
13017
|
-
function requireMutation() {
|
|
13018
|
-
if (hasRequiredMutation) return mutation;
|
|
13019
|
-
hasRequiredMutation = 1;
|
|
13020
|
-
//based off rsvp https://github.com/tildeio/rsvp.js
|
|
13021
|
-
//license https://github.com/tildeio/rsvp.js/blob/master/LICENSE
|
|
13022
|
-
//https://github.com/tildeio/rsvp.js/blob/master/lib/rsvp/asap.js
|
|
13023
|
-
|
|
13024
|
-
var Mutation = commonjsGlobal.MutationObserver || commonjsGlobal.WebKitMutationObserver;
|
|
13025
|
-
mutation.test = function () {
|
|
13026
|
-
return Mutation;
|
|
13027
|
-
};
|
|
13028
|
-
mutation.install = function (handle) {
|
|
13029
|
-
var called = 0;
|
|
13030
|
-
var observer = new Mutation(handle);
|
|
13031
|
-
var element = commonjsGlobal.document.createTextNode('');
|
|
13032
|
-
observer.observe(element, {
|
|
13033
|
-
characterData: true
|
|
13034
|
-
});
|
|
13035
|
-
return function () {
|
|
13036
|
-
element.data = called = ++called % 2;
|
|
13037
|
-
};
|
|
13038
|
-
};
|
|
13039
|
-
return mutation;
|
|
13040
|
-
}
|
|
13041
|
-
|
|
13042
|
-
var messageChannel = {};
|
|
13043
|
-
|
|
13044
|
-
var hasRequiredMessageChannel;
|
|
13045
|
-
function requireMessageChannel() {
|
|
13046
|
-
if (hasRequiredMessageChannel) return messageChannel;
|
|
13047
|
-
hasRequiredMessageChannel = 1;
|
|
13048
|
-
messageChannel.test = function () {
|
|
13049
|
-
if (commonjsGlobal.setImmediate) {
|
|
13050
|
-
// we can only get here in IE10
|
|
13051
|
-
// which doesn't handel postMessage well
|
|
13052
|
-
return false;
|
|
13053
|
-
}
|
|
13054
|
-
return typeof commonjsGlobal.MessageChannel !== 'undefined';
|
|
13055
|
-
};
|
|
13056
|
-
messageChannel.install = function (func) {
|
|
13057
|
-
var channel = new commonjsGlobal.MessageChannel();
|
|
13058
|
-
channel.port1.onmessage = func;
|
|
13059
|
-
return function () {
|
|
13060
|
-
channel.port2.postMessage(0);
|
|
13061
|
-
};
|
|
13062
|
-
};
|
|
13063
|
-
return messageChannel;
|
|
13064
|
-
}
|
|
13065
|
-
|
|
13066
|
-
var stateChange = {};
|
|
13067
|
-
|
|
13068
|
-
var hasRequiredStateChange;
|
|
13069
|
-
function requireStateChange() {
|
|
13070
|
-
if (hasRequiredStateChange) return stateChange;
|
|
13071
|
-
hasRequiredStateChange = 1;
|
|
13072
|
-
stateChange.test = function () {
|
|
13073
|
-
return 'document' in commonjsGlobal && 'onreadystatechange' in commonjsGlobal.document.createElement('script');
|
|
13074
|
-
};
|
|
13075
|
-
stateChange.install = function (handle) {
|
|
13076
|
-
return function () {
|
|
13077
|
-
// Create a <script> element; its readystatechange event will be fired asynchronously once it is inserted
|
|
13078
|
-
// into the document. Do so, thus queuing up the task. Remember to clean up once it's been called.
|
|
13079
|
-
var scriptEl = commonjsGlobal.document.createElement('script');
|
|
13080
|
-
scriptEl.onreadystatechange = function () {
|
|
13081
|
-
handle();
|
|
13082
|
-
scriptEl.onreadystatechange = null;
|
|
13083
|
-
scriptEl.parentNode.removeChild(scriptEl);
|
|
13084
|
-
scriptEl = null;
|
|
13085
|
-
};
|
|
13086
|
-
commonjsGlobal.document.documentElement.appendChild(scriptEl);
|
|
13087
|
-
return handle;
|
|
13088
|
-
};
|
|
13089
|
-
};
|
|
13090
|
-
return stateChange;
|
|
13091
|
-
}
|
|
13092
|
-
|
|
13093
|
-
var timeout = {};
|
|
13094
|
-
|
|
13095
|
-
var hasRequiredTimeout;
|
|
13096
|
-
function requireTimeout() {
|
|
13097
|
-
if (hasRequiredTimeout) return timeout;
|
|
13098
|
-
hasRequiredTimeout = 1;
|
|
13099
|
-
timeout.test = function () {
|
|
13100
|
-
return true;
|
|
13101
|
-
};
|
|
13102
|
-
timeout.install = function (t) {
|
|
13103
|
-
return function () {
|
|
13104
|
-
setTimeout(t, 0);
|
|
13105
|
-
};
|
|
13106
|
-
};
|
|
13107
|
-
return timeout;
|
|
13108
|
-
}
|
|
13109
|
-
|
|
13110
|
-
var lib$1;
|
|
13111
|
-
var hasRequiredLib$1;
|
|
13112
|
-
function requireLib$1() {
|
|
13113
|
-
if (hasRequiredLib$1) return lib$1;
|
|
13114
|
-
hasRequiredLib$1 = 1;
|
|
13115
|
-
var types = [requireNextTick(), requireQueueMicrotask(), requireMutation(), requireMessageChannel(), requireStateChange(), requireTimeout()];
|
|
13116
|
-
var draining;
|
|
13117
|
-
var currentQueue;
|
|
13118
|
-
var queueIndex = -1;
|
|
13119
|
-
var queue = [];
|
|
13120
|
-
var scheduled = false;
|
|
13121
|
-
function cleanUpNextTick() {
|
|
13122
|
-
if (!draining || !currentQueue) {
|
|
13123
|
-
return;
|
|
13124
|
-
}
|
|
13125
|
-
draining = false;
|
|
13126
|
-
if (currentQueue.length) {
|
|
13127
|
-
queue = currentQueue.concat(queue);
|
|
13128
|
-
} else {
|
|
13129
|
-
queueIndex = -1;
|
|
13130
|
-
}
|
|
13131
|
-
if (queue.length) {
|
|
13132
|
-
nextTick();
|
|
13133
|
-
}
|
|
13134
|
-
}
|
|
13135
|
-
|
|
13136
|
-
//named nextTick for less confusing stack traces
|
|
13137
|
-
function nextTick() {
|
|
13138
|
-
if (draining) {
|
|
13139
|
-
return;
|
|
13140
|
-
}
|
|
13141
|
-
scheduled = false;
|
|
13142
|
-
draining = true;
|
|
13143
|
-
var len = queue.length;
|
|
13144
|
-
var timeout = setTimeout(cleanUpNextTick);
|
|
13145
|
-
while (len) {
|
|
13146
|
-
currentQueue = queue;
|
|
13147
|
-
queue = [];
|
|
13148
|
-
while (currentQueue && ++queueIndex < len) {
|
|
13149
|
-
currentQueue[queueIndex].run();
|
|
13150
|
-
}
|
|
13151
|
-
queueIndex = -1;
|
|
13152
|
-
len = queue.length;
|
|
13153
|
-
}
|
|
13154
|
-
currentQueue = null;
|
|
13155
|
-
queueIndex = -1;
|
|
13156
|
-
draining = false;
|
|
13157
|
-
clearTimeout(timeout);
|
|
13158
|
-
}
|
|
13159
|
-
var scheduleDrain;
|
|
13160
|
-
var i = -1;
|
|
13161
|
-
var len = types.length;
|
|
13162
|
-
while (++i < len) {
|
|
13163
|
-
if (types[i] && types[i].test && types[i].test()) {
|
|
13164
|
-
scheduleDrain = types[i].install(nextTick);
|
|
13165
|
-
break;
|
|
13166
|
-
}
|
|
13167
|
-
}
|
|
13168
|
-
// v8 likes predictible objects
|
|
13169
|
-
function Item(fun, array) {
|
|
13170
|
-
this.fun = fun;
|
|
13171
|
-
this.array = array;
|
|
13172
|
-
}
|
|
13173
|
-
Item.prototype.run = function () {
|
|
13174
|
-
var fun = this.fun;
|
|
13175
|
-
var array = this.array;
|
|
13176
|
-
switch (array.length) {
|
|
13177
|
-
case 0:
|
|
13178
|
-
return fun();
|
|
13179
|
-
case 1:
|
|
13180
|
-
return fun(array[0]);
|
|
13181
|
-
case 2:
|
|
13182
|
-
return fun(array[0], array[1]);
|
|
13183
|
-
case 3:
|
|
13184
|
-
return fun(array[0], array[1], array[2]);
|
|
13185
|
-
default:
|
|
13186
|
-
return fun.apply(null, array);
|
|
13187
|
-
}
|
|
13188
|
-
};
|
|
13189
|
-
lib$1 = immediate;
|
|
13190
|
-
function immediate(task) {
|
|
13191
|
-
var args = new Array(arguments.length - 1);
|
|
13192
|
-
if (arguments.length > 1) {
|
|
13193
|
-
for (var i = 1; i < arguments.length; i++) {
|
|
13194
|
-
args[i - 1] = arguments[i];
|
|
13195
|
-
}
|
|
13196
|
-
}
|
|
13197
|
-
queue.push(new Item(task, args));
|
|
13198
|
-
if (!scheduled && !draining) {
|
|
13199
|
-
scheduled = true;
|
|
13200
|
-
scheduleDrain();
|
|
13201
|
-
}
|
|
13202
|
-
}
|
|
13203
|
-
return lib$1;
|
|
13204
|
-
}
|
|
13205
|
-
|
|
13206
|
-
var libExports$1 = requireLib$1();
|
|
13207
|
-
var immediate = /*@__PURE__*/getDefaultExportFromCjs(libExports$1);
|
|
13208
|
-
|
|
13209
|
-
var tinyQueue;
|
|
13210
|
-
var hasRequiredTinyQueue;
|
|
13211
|
-
function requireTinyQueue() {
|
|
13212
|
-
if (hasRequiredTinyQueue) return tinyQueue;
|
|
13213
|
-
hasRequiredTinyQueue = 1;
|
|
13214
|
-
|
|
13215
|
-
// Simple FIFO queue implementation to avoid having to do shift()
|
|
13216
|
-
// on an array, which is slow.
|
|
13217
|
-
|
|
13218
|
-
function Queue() {
|
|
13219
|
-
this.length = 0;
|
|
13220
|
-
}
|
|
13221
|
-
Queue.prototype.push = function (item) {
|
|
13222
|
-
var node = {
|
|
13223
|
-
item: item
|
|
13224
|
-
};
|
|
13225
|
-
if (this.last) {
|
|
13226
|
-
this.last = this.last.next = node;
|
|
13227
|
-
} else {
|
|
13228
|
-
this.last = this.first = node;
|
|
13229
|
-
}
|
|
13230
|
-
this.length++;
|
|
13231
|
-
};
|
|
13232
|
-
Queue.prototype.shift = function () {
|
|
13233
|
-
var node = this.first;
|
|
13234
|
-
if (node) {
|
|
13235
|
-
this.first = node.next;
|
|
13236
|
-
if (! --this.length) {
|
|
13237
|
-
this.last = undefined;
|
|
13238
|
-
}
|
|
13239
|
-
return node.item;
|
|
13240
|
-
}
|
|
13241
|
-
};
|
|
13242
|
-
Queue.prototype.slice = function (start, end) {
|
|
13243
|
-
start = typeof start === 'undefined' ? 0 : start;
|
|
13244
|
-
end = typeof end === 'undefined' ? Infinity : end;
|
|
13245
|
-
var output = [];
|
|
13246
|
-
var i = 0;
|
|
13247
|
-
for (var node = this.first; node; node = node.next) {
|
|
13248
|
-
if (--end < 0) {
|
|
13249
|
-
break;
|
|
13250
|
-
} else if (++i > start) {
|
|
13251
|
-
output.push(node.item);
|
|
13252
|
-
}
|
|
13253
|
-
}
|
|
13254
|
-
return output;
|
|
13255
|
-
};
|
|
13256
|
-
tinyQueue = Queue;
|
|
13257
|
-
return tinyQueue;
|
|
13258
|
-
}
|
|
13259
|
-
|
|
13260
|
-
var tinyQueueExports = requireTinyQueue();
|
|
13261
|
-
var Queue = /*@__PURE__*/getDefaultExportFromCjs(tinyQueueExports);
|
|
13262
|
-
|
|
13263
|
-
var noopFn;
|
|
13264
|
-
var hasRequiredNoopFn;
|
|
13265
|
-
function requireNoopFn() {
|
|
13266
|
-
if (hasRequiredNoopFn) return noopFn;
|
|
13267
|
-
hasRequiredNoopFn = 1;
|
|
13268
|
-
noopFn = function () {};
|
|
13269
|
-
return noopFn;
|
|
13270
|
-
}
|
|
13271
|
-
|
|
13272
|
-
var noopFnExports = requireNoopFn();
|
|
13273
|
-
var noop = /*@__PURE__*/getDefaultExportFromCjs(noopFnExports);
|
|
13274
|
-
|
|
13275
|
-
/**
|
|
13276
|
-
*
|
|
13277
|
-
*/
|
|
13278
|
-
class WebSQLRows {
|
|
13279
|
-
/**
|
|
13280
|
-
* @param {unknown[]} array
|
|
13281
|
-
*/
|
|
13282
|
-
constructor(array) {
|
|
13283
|
-
this._array = array;
|
|
13284
|
-
this.length = array.length;
|
|
13285
|
-
}
|
|
13286
|
-
|
|
13287
|
-
/**
|
|
13288
|
-
* @param {number} i
|
|
13289
|
-
*/
|
|
13290
|
-
item(i) {
|
|
13291
|
-
return this._array[i];
|
|
13292
|
-
}
|
|
13293
|
-
}
|
|
13294
|
-
|
|
13295
|
-
/**
|
|
13296
|
-
*
|
|
13297
|
-
*/
|
|
13298
|
-
class WebSQLResultSet {
|
|
13299
|
-
/**
|
|
13300
|
-
* @param {number} [insertId]
|
|
13301
|
-
* @param {number} [rowsAffected]
|
|
13302
|
-
* @param {unknown[]} [rows]
|
|
13303
|
-
*/
|
|
13304
|
-
constructor(insertId, rowsAffected, rows) {
|
|
13305
|
-
this.insertId = insertId;
|
|
13306
|
-
this.rowsAffected = rowsAffected;
|
|
13307
|
-
this.rows = new WebSQLRows(rows || []);
|
|
13308
|
-
}
|
|
13309
|
-
}
|
|
13310
|
-
|
|
13311
|
-
/**
|
|
13312
|
-
* These deliberately don't reuse the WebSQL spec's global
|
|
13313
|
-
* `SQLStatementCallback`/`SQLStatementErrorCallback`/`SQLError` types:
|
|
13314
|
-
* this library never constructs a real `SQLError` (errors here are
|
|
13315
|
-
* always plain `Error`s coming from the underlying SQL driver), and
|
|
13316
|
-
* `WebSQLResultSet#insertId`/`rowsAffected` are genuinely `number |
|
|
13317
|
-
* undefined` (see `massageSQLResult` below), which the spec's
|
|
13318
|
-
* `SQLResultSet` doesn't allow. Typing against the spec here would just
|
|
13319
|
-
* paper over that mismatch with unsound casts.
|
|
13320
|
-
* @typedef {(transaction: WebSQLTransaction, resultSet: WebSQLResultSet) => void} SqlCallback
|
|
13321
|
-
* @typedef {(transaction: WebSQLTransaction, error: Error) => boolean | void} SqlErrorCallback
|
|
13322
|
-
*/
|
|
13323
|
-
|
|
13324
|
-
/**
|
|
13325
|
-
*
|
|
13326
|
-
*/
|
|
13327
|
-
function errorUnhandled() {
|
|
13328
|
-
return true; // a non-truthy return indicates error was handled
|
|
13329
|
-
}
|
|
13330
|
-
|
|
13331
|
-
// WebSQL has some bizarre behavior regarding insertId/rowsAffected. To try
|
|
13332
|
-
// to match the observed behavior of Chrome/Safari as much as possible, we
|
|
13333
|
-
// sniff the SQL message to try to massage the returned insertId/rowsAffected.
|
|
13334
|
-
// This helps us pass the tests, although it's error-prone and should
|
|
13335
|
-
// probably be revised.
|
|
13336
|
-
/**
|
|
13337
|
-
* @param {string} sql
|
|
13338
|
-
* @param {number} [insertId]
|
|
13339
|
-
* @param {number} [rowsAffected]
|
|
13340
|
-
* @param {unknown[]} [rows]
|
|
13341
|
-
*/
|
|
13342
|
-
function massageSQLResult(sql, insertId, rowsAffected, rows) {
|
|
13343
|
-
if (/^\s*UPDATE\b/iu.test(sql)) {
|
|
13344
|
-
// insertId is always undefined for "UPDATE" statements
|
|
13345
|
-
insertId = undefined;
|
|
13346
|
-
} else if (/^\s*CREATE\s+TABLE\b/iu.test(sql)) {
|
|
13347
|
-
// WebSQL always returns an insertId of 0 for "CREATE TABLE" statements
|
|
13348
|
-
insertId = 0;
|
|
13349
|
-
rowsAffected = 0;
|
|
13350
|
-
} else if (/^\s*DROP\s+TABLE\b/iu.test(sql)) {
|
|
13351
|
-
// WebSQL always returns insertId=undefined and rowsAffected=0
|
|
13352
|
-
// for "DROP TABLE" statements. Go figure.
|
|
13353
|
-
insertId = undefined;
|
|
13354
|
-
rowsAffected = 0;
|
|
13355
|
-
} else if (!/^\s*INSERT\b/iu.test(sql)) {
|
|
13356
|
-
// for all non-inserts (deletes, etc.) insertId is always undefined
|
|
13357
|
-
// ¯\_(ツ)_/¯
|
|
13358
|
-
insertId = undefined;
|
|
13359
|
-
}
|
|
13360
|
-
return new WebSQLResultSet(insertId, rowsAffected, rows);
|
|
13361
|
-
}
|
|
13362
|
-
|
|
13363
|
-
/**
|
|
13364
|
-
*
|
|
13365
|
-
*/
|
|
13366
|
-
class SQLTask {
|
|
13367
|
-
/**
|
|
13368
|
-
* @param {string} sql
|
|
13369
|
-
* @param {unknown[]} args
|
|
13370
|
-
* @param {SqlCallback} sqlCallback
|
|
13371
|
-
* @param {SqlErrorCallback} sqlErrorCallback
|
|
13372
|
-
*/
|
|
13373
|
-
constructor(sql, args, sqlCallback, sqlErrorCallback) {
|
|
13374
|
-
this.sql = sql;
|
|
13375
|
-
this.args = args;
|
|
13376
|
-
this.sqlCallback = sqlCallback;
|
|
13377
|
-
this.sqlErrorCallback = sqlErrorCallback;
|
|
13378
|
-
}
|
|
13379
|
-
}
|
|
13380
|
-
|
|
13381
|
-
/**
|
|
13382
|
-
* @param {WebSQLTransaction} self
|
|
13383
|
-
* @param {SQLTask[]} batch
|
|
13384
|
-
*/
|
|
13385
|
-
function runBatch(self, batch) {
|
|
13386
|
-
/**
|
|
13387
|
-
*
|
|
13388
|
-
*/
|
|
13389
|
-
function onDone() {
|
|
13390
|
-
self._running = false;
|
|
13391
|
-
runAllSql(self);
|
|
13392
|
-
}
|
|
13393
|
-
const {
|
|
13394
|
-
readOnly
|
|
13395
|
-
} = self._task;
|
|
13396
|
-
self._websqlDatabase._db.exec(batch, readOnly, function (err, results) {
|
|
13397
|
-
/* c8 ignore next */
|
|
13398
|
-
if (err || !results) {
|
|
13399
|
-
self._error = err || new Error('exec() did not return results');
|
|
13400
|
-
onDone();
|
|
13401
|
-
return;
|
|
13402
|
-
}
|
|
13403
|
-
for (const [i, res] of results.entries()) {
|
|
13404
|
-
const batchTask = batch[i];
|
|
13405
|
-
if (res.error) {
|
|
13406
|
-
if (batchTask.sqlErrorCallback(self, res.error)) {
|
|
13407
|
-
// user didn't handle the error
|
|
13408
|
-
self._error = res.error;
|
|
13409
|
-
onDone();
|
|
13410
|
-
return;
|
|
13411
|
-
}
|
|
13412
|
-
} else {
|
|
13413
|
-
try {
|
|
13414
|
-
batchTask.sqlCallback(self, massageSQLResult(batch[i].sql, res.insertId, res.rowsAffected, res.rows));
|
|
13415
|
-
} catch (err) {
|
|
13416
|
-
self._error = /** @type {Error} */err;
|
|
13417
|
-
runAllSql(self);
|
|
13418
|
-
}
|
|
13419
|
-
}
|
|
13420
|
-
}
|
|
13421
|
-
onDone();
|
|
13422
|
-
});
|
|
13423
|
-
}
|
|
13424
|
-
|
|
13425
|
-
/**
|
|
13426
|
-
* @param {WebSQLTransaction} self
|
|
13427
|
-
*/
|
|
13428
|
-
function runAllSql(self) {
|
|
13429
|
-
if (self._running || self._complete) {
|
|
13430
|
-
return;
|
|
13431
|
-
}
|
|
13432
|
-
if (self._error) {
|
|
13433
|
-
self._complete = true;
|
|
13434
|
-
self._websqlDatabase._onTransactionComplete(self._error, self);
|
|
13435
|
-
return;
|
|
13436
|
-
}
|
|
13437
|
-
if (!self._sqlQueue.length) {
|
|
13438
|
-
// Do not mark `_complete` here: the caller (via `nonstandardTransCb`,
|
|
13439
|
-
// see `WebSQLDatabase#_onTransactionComplete`) may choose to defer the
|
|
13440
|
-
// actual commit/rollback decision, in which case more SQL might still
|
|
13441
|
-
// be queued via `executeSql()` later and must still be able to run.
|
|
13442
|
-
// `_complete` is only set once that decision is actually final (see
|
|
13443
|
-
// `_onTransactionComplete`'s `done`).
|
|
13444
|
-
self._websqlDatabase._onTransactionComplete(self._error, self);
|
|
13445
|
-
return;
|
|
13446
|
-
}
|
|
13447
|
-
self._running = true;
|
|
13448
|
-
/** @type {SQLTask[]} */
|
|
13449
|
-
const batch = [];
|
|
13450
|
-
let task;
|
|
13451
|
-
while (task = self._sqlQueue.shift()) {
|
|
13452
|
-
batch.push(task);
|
|
13453
|
-
}
|
|
13454
|
-
runBatch(self, batch);
|
|
13455
|
-
}
|
|
13456
|
-
|
|
13457
|
-
/**
|
|
13458
|
-
* @param {WebSQLTransaction} self
|
|
13459
|
-
* @param {string} sql
|
|
13460
|
-
* @param {unknown[]} args
|
|
13461
|
-
* @param {SqlCallback} sqlCallback
|
|
13462
|
-
* @param {SqlErrorCallback} sqlErrorCallback
|
|
13463
|
-
* @param {import('../types.js').Delay} executeDelay
|
|
13464
|
-
*/
|
|
13465
|
-
function executeSql(self, sql, args, sqlCallback, sqlErrorCallback, executeDelay) {
|
|
13466
|
-
self._sqlQueue.push(new SQLTask(sql, args, sqlCallback, sqlErrorCallback));
|
|
13467
|
-
if (self._runningTimeout) {
|
|
13468
|
-
return;
|
|
13469
|
-
}
|
|
13470
|
-
self._runningTimeout = true;
|
|
13471
|
-
executeDelay(function () {
|
|
13472
|
-
self._runningTimeout = false;
|
|
13473
|
-
runAllSql(self);
|
|
13474
|
-
});
|
|
13475
|
-
}
|
|
13476
|
-
|
|
13477
|
-
/**
|
|
13478
|
-
*
|
|
13479
|
-
*/
|
|
13480
|
-
class WebSQLTransaction {
|
|
13481
|
-
/**
|
|
13482
|
-
* @param {import('./WebSQLDatabase.js').default} websqlDatabase
|
|
13483
|
-
* @param {import('./WebSQLDatabase.js').TransactionTask} task
|
|
13484
|
-
* @param {import('../types.js').Delay} [executeDelay]
|
|
13485
|
-
*/
|
|
13486
|
-
constructor(websqlDatabase, task, executeDelay) {
|
|
13487
|
-
this._websqlDatabase = websqlDatabase;
|
|
13488
|
-
this._task = task;
|
|
13489
|
-
/** @type {Error | null} */
|
|
13490
|
-
this._error = null;
|
|
13491
|
-
this._complete = false;
|
|
13492
|
-
this._running = false;
|
|
13493
|
-
this._runningTimeout = false;
|
|
13494
|
-
this._executeDelay = executeDelay || immediate;
|
|
13495
|
-
/** @type {import('tiny-queue').default<SQLTask>} */
|
|
13496
|
-
this._sqlQueue = new Queue();
|
|
13497
|
-
if (!task.readOnly) {
|
|
13498
|
-
// A read-only task never needs a transaction wrapper for its own
|
|
13499
|
-
// sake (reads don't need atomicity against each other) -- true
|
|
13500
|
-
// whether or not `concurrentReaders` (see `WebSQLDatabase`) lets
|
|
13501
|
-
// multiple read-only tasks actually run at once. This is a perf
|
|
13502
|
-
// boost either way. A non-read-only task always still gets one, and
|
|
13503
|
-
// always still runs with full exclusivity (see
|
|
13504
|
-
// `WebSQLDatabase#runNextTransaction`).
|
|
13505
|
-
this._sqlQueue.push(new SQLTask('BEGIN;', [], noop, noop));
|
|
13506
|
-
}
|
|
13507
|
-
}
|
|
13508
|
-
|
|
13509
|
-
/**
|
|
13510
|
-
* @param {string} sql
|
|
13511
|
-
* @param {unknown[]} [args]
|
|
13512
|
-
* @param {SqlCallback} [sqlCallback]
|
|
13513
|
-
* @param {SqlErrorCallback} [sqlErrorCallback]
|
|
13514
|
-
*/
|
|
13515
|
-
executeSql(sql, args, sqlCallback, sqlErrorCallback) {
|
|
13516
|
-
args = Array.isArray(args) ? args : [];
|
|
13517
|
-
sqlCallback = typeof sqlCallback === 'function' ? sqlCallback : noop;
|
|
13518
|
-
sqlErrorCallback = typeof sqlErrorCallback === 'function' ? sqlErrorCallback : errorUnhandled;
|
|
13519
|
-
executeSql(this, sql, args, sqlCallback, sqlErrorCallback, this._executeDelay);
|
|
13520
|
-
}
|
|
13521
|
-
|
|
13522
|
-
/**
|
|
13523
|
-
* Not a true `#private` method: `WebSQLDatabase` calls this right after
|
|
13524
|
-
* handing a freshly-created transaction to the caller's `txnCallback`.
|
|
13525
|
-
*/
|
|
13526
|
-
// eslint-disable-next-line unicorn/prefer-private-class-fields -- see above
|
|
13527
|
-
_checkDone() {
|
|
13528
|
-
runAllSql(this);
|
|
13529
|
-
}
|
|
13530
|
-
}
|
|
13531
|
-
|
|
13532
|
-
/**
|
|
13533
|
-
* @typedef {(
|
|
13534
|
-
* currentTask: TransactionTask,
|
|
13535
|
-
* err: Error | null,
|
|
13536
|
-
* done: (er?: Error | boolean | null) => void,
|
|
13537
|
-
* rollback: (err: Error | boolean, cb: () => void) => void,
|
|
13538
|
-
* commit: (cb: () => void) => void
|
|
13539
|
-
* ) => boolean} NonstandardTransCb
|
|
13540
|
-
*/
|
|
13541
|
-
|
|
13542
|
-
const ROLLBACK = [{
|
|
13543
|
-
sql: 'ROLLBACK;',
|
|
13544
|
-
args: []
|
|
13545
|
-
}];
|
|
13546
|
-
const COMMIT = [{
|
|
13547
|
-
sql: 'END;',
|
|
13548
|
-
args: []
|
|
13549
|
-
}];
|
|
13550
|
-
|
|
13551
|
-
/**
|
|
13552
|
-
* V8 likes predictable objects.
|
|
13553
|
-
*/
|
|
13554
|
-
class TransactionTask {
|
|
13555
|
-
/**
|
|
13556
|
-
* @param {boolean} readOnly
|
|
13557
|
-
* @param {(trans: WebSQLTransaction) => void} txnCallback
|
|
13558
|
-
* @param {(err: Error) => void} errorCallback
|
|
13559
|
-
* @param {() => void} successCallback
|
|
13560
|
-
* @param {NonstandardTransCb} [nonstandardTransCb]
|
|
13561
|
-
*/
|
|
13562
|
-
constructor(readOnly, txnCallback, errorCallback, successCallback, nonstandardTransCb) {
|
|
13563
|
-
this.readOnly = readOnly;
|
|
13564
|
-
this.txnCallback = txnCallback;
|
|
13565
|
-
this.errorCallback = errorCallback;
|
|
13566
|
-
this.successCallback = successCallback;
|
|
13567
|
-
this.nonstandardTransCb = nonstandardTransCb;
|
|
13568
|
-
}
|
|
13569
|
-
}
|
|
13570
|
-
|
|
13571
|
-
/**
|
|
13572
|
-
* The WebSQL `Database` object.
|
|
13573
|
-
*/
|
|
13574
|
-
class WebSQLDatabase {
|
|
13575
|
-
/**
|
|
13576
|
-
* @param {string} dbVersion
|
|
13577
|
-
* @param {import('../types.js').SqlDriver} db
|
|
13578
|
-
* @param {import('../types.js').WebSQLOverrides} webSQLOverrides
|
|
13579
|
-
*/
|
|
13580
|
-
constructor(dbVersion, db, webSQLOverrides) {
|
|
13581
|
-
this.version = dbVersion;
|
|
13582
|
-
this._db = db;
|
|
13583
|
-
/** @type {import('tiny-queue').default<TransactionTask>} */
|
|
13584
|
-
this._txnQueue = new Queue();
|
|
13585
|
-
// Off by default: queued transactions -- read or write alike -- run
|
|
13586
|
-
// strictly one at a time, in the order requested, per the WebSQL spec
|
|
13587
|
-
// (see `#runNextTransaction`). When true, any number of read-only
|
|
13588
|
-
// tasks may instead run concurrently; a non-read-only task still
|
|
13589
|
-
// always runs with full exclusivity either way.
|
|
13590
|
-
this._concurrentReaders = Boolean(webSQLOverrides.concurrentReaders);
|
|
13591
|
-
/** @type {Set<TransactionTask>} */
|
|
13592
|
-
this._activeReaders = new Set();
|
|
13593
|
-
/** @type {TransactionTask | null} */
|
|
13594
|
-
this._activeWriter = null;
|
|
13595
|
-
this._transactionDelay = webSQLOverrides.transactionDelay || immediate;
|
|
13596
|
-
this._executeDelay = webSQLOverrides.executeDelay || immediate;
|
|
13597
|
-
}
|
|
13598
|
-
|
|
13599
|
-
/**
|
|
13600
|
-
* @param {TransactionTask} task
|
|
13601
|
-
*/
|
|
13602
|
-
#runTransaction(task) {
|
|
13603
|
-
const txn = new WebSQLTransaction(this, task, this._executeDelay);
|
|
13604
|
-
this._transactionDelay(() => {
|
|
13605
|
-
task.txnCallback(txn);
|
|
13606
|
-
txn._checkDone();
|
|
13607
|
-
});
|
|
13608
|
-
}
|
|
13609
|
-
|
|
13610
|
-
/**
|
|
13611
|
-
* Starts as many queued tasks as the current lock state allows. With
|
|
13612
|
-
* `concurrentReaders` off (the default), a task only starts once
|
|
13613
|
-
* nothing else is active at all -- full mutual exclusion, matching the
|
|
13614
|
-
* WebSQL spec's strict one-at-a-time, in-request-order guarantee (see
|
|
13615
|
-
* this file's own test suite, "callback order 2"). With it on, any
|
|
13616
|
-
* leading run of read-only tasks can all start together instead
|
|
13617
|
-
* (concurrent reads are always fine); a non-read-only task still needs
|
|
13618
|
-
* exclusivity regardless, so nothing past it may start until it
|
|
13619
|
-
* finishes. Not starvation-proof in the `concurrentReaders` case -- a
|
|
13620
|
-
* steady stream of arriving readers could in principle keep a waiting
|
|
13621
|
-
* writer waiting indefinitely -- but that's an acceptable tradeoff over
|
|
13622
|
-
* the added complexity of tracking arrival order across reader/writer
|
|
13623
|
-
* kinds.
|
|
13624
|
-
*/
|
|
13625
|
-
#runNextTransaction() {
|
|
13626
|
-
for (;;) {
|
|
13627
|
-
const [nextTask] = this._txnQueue.slice(0, 1);
|
|
13628
|
-
if (!nextTask) {
|
|
13629
|
-
return;
|
|
13630
|
-
}
|
|
13631
|
-
const readerMayShare = this._concurrentReaders && nextTask.readOnly;
|
|
13632
|
-
if (readerMayShare) {
|
|
13633
|
-
if (this._activeWriter) {
|
|
13634
|
-
return;
|
|
13635
|
-
}
|
|
13636
|
-
} else if (this._activeWriter || this._activeReaders.size) {
|
|
13637
|
-
return;
|
|
13638
|
-
}
|
|
13639
|
-
this._txnQueue.shift();
|
|
13640
|
-
if (nextTask.readOnly) {
|
|
13641
|
-
this._activeReaders.add(nextTask);
|
|
13642
|
-
} else {
|
|
13643
|
-
this._activeWriter = nextTask;
|
|
13644
|
-
}
|
|
13645
|
-
this.#runTransaction(nextTask);
|
|
13646
|
-
}
|
|
13647
|
-
}
|
|
13648
|
-
|
|
13649
|
-
/**
|
|
13650
|
-
* @param {boolean} readOnly
|
|
13651
|
-
* @param {(trans: WebSQLTransaction) => void} txnCallback
|
|
13652
|
-
* @param {(err: Error) => void} [errorCallback]
|
|
13653
|
-
* @param {() => void} [successCallback]
|
|
13654
|
-
* @param {NonstandardTransCb} [nonstandardTransCb]
|
|
13655
|
-
*/
|
|
13656
|
-
#createTransaction(readOnly, txnCallback, errorCallback, successCallback, nonstandardTransCb) {
|
|
13657
|
-
errorCallback ||= noop;
|
|
13658
|
-
successCallback ||= noop;
|
|
13659
|
-
if (typeof txnCallback !== 'function') {
|
|
13660
|
-
throw new TypeError('The callback provided as parameter 1 is not a function.');
|
|
13661
|
-
}
|
|
13662
|
-
this._txnQueue.push(new TransactionTask(readOnly, txnCallback, errorCallback, successCallback, nonstandardTransCb));
|
|
13663
|
-
this.#runNextTransaction();
|
|
13664
|
-
}
|
|
13665
|
-
|
|
13666
|
-
/**
|
|
13667
|
-
* Not a true `#private` method: `WebSQLTransaction` calls this on its
|
|
13668
|
-
* owning `WebSQLDatabase` once it's finished running its SQL queue.
|
|
13669
|
-
* @param {Error | null} err
|
|
13670
|
-
* @param {WebSQLTransaction} transaction
|
|
13671
|
-
*/
|
|
13672
|
-
// eslint-disable-next-line unicorn/prefer-private-class-fields -- see above
|
|
13673
|
-
_onTransactionComplete(err, transaction) {
|
|
13674
|
-
const task = transaction._task;
|
|
13675
|
-
/**
|
|
13676
|
-
* @param {Error | boolean | null} [er]
|
|
13677
|
-
*/
|
|
13678
|
-
const done = er => {
|
|
13679
|
-
if (transaction) {
|
|
13680
|
-
// Only now -- once the transaction has genuinely committed, rolled
|
|
13681
|
-
// back, or been confirmed read-only-complete -- is it truly done.
|
|
13682
|
-
// Marking this any earlier (e.g. as soon as its SQL queue merely
|
|
13683
|
-
// looked empty) would permanently stop it from accepting further
|
|
13684
|
-
// `executeSql()` calls even when `nonstandardTransCb` (below) chose
|
|
13685
|
-
// to defer the commit/rollback decision instead of finalizing here.
|
|
13686
|
-
transaction._complete = true;
|
|
13687
|
-
}
|
|
13688
|
-
if (er) {
|
|
13689
|
-
task.errorCallback(/** @type {Error} */er);
|
|
13690
|
-
} else {
|
|
13691
|
-
task.successCallback();
|
|
13692
|
-
}
|
|
13693
|
-
if (task.readOnly) {
|
|
13694
|
-
this._activeReaders.delete(task);
|
|
13695
|
-
} else if (this._activeWriter === task) {
|
|
13696
|
-
this._activeWriter = null;
|
|
13697
|
-
}
|
|
13698
|
-
this.#runNextTransaction();
|
|
13699
|
-
};
|
|
13700
|
-
/**
|
|
13701
|
-
* @param {Error | boolean} er
|
|
13702
|
-
* @param {() => void} [cb]
|
|
13703
|
-
*/
|
|
13704
|
-
const rollback = (er, cb) => {
|
|
13705
|
-
this._db.exec(ROLLBACK, false, () => {
|
|
13706
|
-
done(er);
|
|
13707
|
-
if (cb) {
|
|
13708
|
-
cb();
|
|
13709
|
-
}
|
|
13710
|
-
});
|
|
13711
|
-
};
|
|
13712
|
-
/**
|
|
13713
|
-
* @param {() => void} [cb]
|
|
13714
|
-
*/
|
|
13715
|
-
const commit = cb => {
|
|
13716
|
-
this._db.exec(COMMIT, false, () => {
|
|
13717
|
-
done();
|
|
13718
|
-
if (cb) {
|
|
13719
|
-
cb();
|
|
13720
|
-
}
|
|
13721
|
-
});
|
|
13722
|
-
};
|
|
13723
|
-
if (task.nonstandardTransCb) {
|
|
13724
|
-
const cont = task.nonstandardTransCb.call(this, task, err, done, rollback, commit);
|
|
13725
|
-
if (!cont) {
|
|
13726
|
-
return;
|
|
13727
|
-
}
|
|
13728
|
-
}
|
|
13729
|
-
if (task.readOnly) {
|
|
13730
|
-
done(err); // read-only doesn't require a transaction
|
|
13731
|
-
} else if (err) {
|
|
13732
|
-
rollback(err);
|
|
13733
|
-
} else {
|
|
13734
|
-
commit();
|
|
13735
|
-
}
|
|
13736
|
-
}
|
|
13737
|
-
|
|
13738
|
-
/**
|
|
13739
|
-
* @param {(trans: WebSQLTransaction) => void} txnCallback
|
|
13740
|
-
* @param {(err: Error) => void} [errorCallback]
|
|
13741
|
-
* @param {() => void} [successCallback]
|
|
13742
|
-
* @param {NonstandardTransCb} [nonstandardTransCb]
|
|
13743
|
-
*/
|
|
13744
|
-
transaction(txnCallback, errorCallback, successCallback, nonstandardTransCb) {
|
|
13745
|
-
this.#createTransaction(false, txnCallback, errorCallback, successCallback, nonstandardTransCb);
|
|
13746
|
-
}
|
|
13747
|
-
|
|
13748
|
-
/**
|
|
13749
|
-
* @param {(trans: WebSQLTransaction) => void} txnCallback
|
|
13750
|
-
* @param {(err: Error) => void} [errorCallback]
|
|
13751
|
-
* @param {() => void} [successCallback]
|
|
13752
|
-
* @param {NonstandardTransCb} [nonstandardTransCb]
|
|
13753
|
-
*/
|
|
13754
|
-
readTransaction(txnCallback, errorCallback, successCallback, nonstandardTransCb) {
|
|
13755
|
-
this.#createTransaction(true, txnCallback, errorCallback, successCallback, nonstandardTransCb);
|
|
13756
|
-
}
|
|
13757
|
-
}
|
|
13758
|
-
|
|
13759
|
-
/**
|
|
13760
|
-
* @template Opts
|
|
13761
|
-
* @param {import('./types.js').SqlDriverConstructor<Opts>} SQLiteDatabase
|
|
13762
|
-
* @param {{ sqlite?: Opts, websql?: import('./types.js').WebSQLOverrides }} [opts]
|
|
13763
|
-
*/
|
|
13764
|
-
function customOpenDatabase(SQLiteDatabase, opts) {
|
|
13765
|
-
opts ||= {};
|
|
13766
|
-
const sqliteOpts = opts.sqlite;
|
|
13767
|
-
const webSQLOverrides = opts.websql || {};
|
|
13768
|
-
const openDelay = webSQLOverrides.openDelay || immediate;
|
|
13769
|
-
|
|
13770
|
-
/**
|
|
13771
|
-
* @param {string} dbName
|
|
13772
|
-
* @param {string} dbVersion
|
|
13773
|
-
*/
|
|
13774
|
-
function createDb(dbName, dbVersion) {
|
|
13775
|
-
const sqliteDatabase = new SQLiteDatabase(dbName, sqliteOpts);
|
|
13776
|
-
return new WebSQLDatabase(dbVersion, sqliteDatabase, webSQLOverrides);
|
|
13777
|
-
}
|
|
13778
|
-
|
|
13779
|
-
/**
|
|
13780
|
-
* @param {unknown[]} args
|
|
13781
|
-
* @throws {Error} If fewer than 4 arguments are given.
|
|
13782
|
-
*/
|
|
13783
|
-
function openDatabase(args) {
|
|
13784
|
-
if (args.length < 4) {
|
|
13785
|
-
throw new Error('Failed to execute \'openDatabase\': ' + '4 arguments required, but only ' + args.length + ' present');
|
|
13786
|
-
}
|
|
13787
|
-
const dbName = /** @type {string} */args[0];
|
|
13788
|
-
const dbVersion = /** @type {string} */args[1];
|
|
13789
|
-
// db description and size are ignored
|
|
13790
|
-
const callback = /** @type {((db: WebSQLDatabase) => void) | undefined} */args[4];
|
|
13791
|
-
const db = createDb(dbName, dbVersion);
|
|
13792
|
-
if (typeof callback === 'function') {
|
|
13793
|
-
const onOpen = callback;
|
|
13794
|
-
openDelay(function () {
|
|
13795
|
-
onOpen(db);
|
|
13796
|
-
});
|
|
13797
|
-
}
|
|
13798
|
-
return db;
|
|
13799
|
-
}
|
|
13800
|
-
return (/** @type {unknown[]} */...args) => openDatabase(args);
|
|
13801
|
-
}
|
|
13802
|
-
|
|
13803
|
-
var lib = {exports: {}};
|
|
13804
|
-
|
|
13805
|
-
var util = {};
|
|
13806
|
-
|
|
13807
|
-
var hasRequiredUtil;
|
|
13808
|
-
function requireUtil() {
|
|
13809
|
-
if (hasRequiredUtil) return util;
|
|
13810
|
-
hasRequiredUtil = 1;
|
|
13811
|
-
util.getBooleanOption = (options, key) => {
|
|
13812
|
-
let value = false;
|
|
13813
|
-
if (key in options && typeof (value = options[key]) !== 'boolean') {
|
|
13814
|
-
throw new TypeError(`Expected the "${key}" option to be a boolean`);
|
|
13815
|
-
}
|
|
13816
|
-
return value;
|
|
13817
|
-
};
|
|
13818
|
-
util.cppdb = Symbol();
|
|
13819
|
-
util.inspect = Symbol.for('nodejs.util.inspect.custom');
|
|
13820
|
-
return util;
|
|
13821
|
-
}
|
|
13822
|
-
|
|
13823
|
-
var sqliteError;
|
|
13824
|
-
var hasRequiredSqliteError;
|
|
13825
|
-
function requireSqliteError() {
|
|
13826
|
-
if (hasRequiredSqliteError) return sqliteError;
|
|
13827
|
-
hasRequiredSqliteError = 1;
|
|
13828
|
-
class SqliteError extends Error {
|
|
13829
|
-
constructor(message, code) {
|
|
13830
|
-
if (typeof code !== 'string') {
|
|
13831
|
-
throw new TypeError('Expected second argument to be a string');
|
|
13832
|
-
}
|
|
13833
|
-
super('' + message);
|
|
13834
|
-
this.code = code;
|
|
13835
|
-
if (typeof Error.captureStackTrace === 'function') {
|
|
13836
|
-
Error.captureStackTrace(this, SqliteError);
|
|
13837
|
-
}
|
|
13838
|
-
}
|
|
13839
|
-
}
|
|
13840
|
-
Object.defineProperty(SqliteError.prototype, 'name', {
|
|
13841
|
-
value: 'SqliteError',
|
|
13842
|
-
writable: true,
|
|
13843
|
-
enumerable: false,
|
|
13844
|
-
configurable: true
|
|
13845
|
-
});
|
|
13846
|
-
sqliteError = SqliteError;
|
|
13847
|
-
return sqliteError;
|
|
13848
|
-
}
|
|
13849
|
-
|
|
13850
|
-
var wrappers = {};
|
|
13851
|
-
|
|
13852
|
-
var hasRequiredWrappers;
|
|
13853
|
-
function requireWrappers() {
|
|
13854
|
-
if (hasRequiredWrappers) return wrappers;
|
|
13855
|
-
hasRequiredWrappers = 1;
|
|
13856
|
-
const {
|
|
13857
|
-
cppdb
|
|
13858
|
-
} = requireUtil();
|
|
13859
|
-
wrappers.prepare = function prepare(sql) {
|
|
13860
|
-
return this[cppdb].prepare(sql, this, false, false);
|
|
13861
|
-
};
|
|
13862
|
-
wrappers.exec = function exec(sql) {
|
|
13863
|
-
this[cppdb].exec(sql);
|
|
13864
|
-
return this;
|
|
13865
|
-
};
|
|
13866
|
-
wrappers.close = function close() {
|
|
13867
|
-
this[cppdb].close();
|
|
13868
|
-
return this;
|
|
13869
|
-
};
|
|
13870
|
-
wrappers.loadExtension = function loadExtension(...args) {
|
|
13871
|
-
this[cppdb].loadExtension(...args);
|
|
13872
|
-
return this;
|
|
13873
|
-
};
|
|
13874
|
-
wrappers.defaultSafeIntegers = function defaultSafeIntegers(...args) {
|
|
13875
|
-
this[cppdb].defaultSafeIntegers(...args);
|
|
13876
|
-
return this;
|
|
13877
|
-
};
|
|
13878
|
-
wrappers.unsafeMode = function unsafeMode(...args) {
|
|
13879
|
-
this[cppdb].unsafeMode(...args);
|
|
13880
|
-
return this;
|
|
13881
|
-
};
|
|
13882
|
-
wrappers.getters = {
|
|
13883
|
-
name: {
|
|
13884
|
-
get: function name() {
|
|
13885
|
-
return this[cppdb].name;
|
|
13886
|
-
},
|
|
13887
|
-
enumerable: true
|
|
13888
|
-
},
|
|
13889
|
-
open: {
|
|
13890
|
-
get: function open() {
|
|
13891
|
-
return this[cppdb].open;
|
|
13892
|
-
},
|
|
13893
|
-
enumerable: true
|
|
13894
|
-
},
|
|
13895
|
-
inTransaction: {
|
|
13896
|
-
get: function inTransaction() {
|
|
13897
|
-
return this[cppdb].inTransaction;
|
|
13898
|
-
},
|
|
13899
|
-
enumerable: true
|
|
13900
|
-
},
|
|
13901
|
-
readonly: {
|
|
13902
|
-
get: function readonly() {
|
|
13903
|
-
return this[cppdb].readonly;
|
|
13904
|
-
},
|
|
13905
|
-
enumerable: true
|
|
13906
|
-
},
|
|
13907
|
-
memory: {
|
|
13908
|
-
get: function memory() {
|
|
13909
|
-
return this[cppdb].memory;
|
|
13910
|
-
},
|
|
13911
|
-
enumerable: true
|
|
13912
|
-
}
|
|
13913
|
-
};
|
|
13914
|
-
return wrappers;
|
|
13915
|
-
}
|
|
13916
|
-
|
|
13917
|
-
var transaction;
|
|
13918
|
-
var hasRequiredTransaction;
|
|
13919
|
-
function requireTransaction() {
|
|
13920
|
-
if (hasRequiredTransaction) return transaction;
|
|
13921
|
-
hasRequiredTransaction = 1;
|
|
13922
|
-
const {
|
|
13923
|
-
cppdb
|
|
13924
|
-
} = requireUtil();
|
|
13925
|
-
const controllers = new WeakMap();
|
|
13926
|
-
transaction = function transaction(fn) {
|
|
13927
|
-
if (typeof fn !== 'function') throw new TypeError('Expected first argument to be a function');
|
|
13928
|
-
const db = this[cppdb];
|
|
13929
|
-
const controller = getController(db, this);
|
|
13930
|
-
const {
|
|
13931
|
-
apply
|
|
13932
|
-
} = Function.prototype;
|
|
13933
|
-
|
|
13934
|
-
// Each version of the transaction function has these same properties
|
|
13935
|
-
const properties = {
|
|
13936
|
-
default: {
|
|
13937
|
-
value: wrapTransaction(apply, fn, db, controller.default)
|
|
13938
|
-
},
|
|
13939
|
-
deferred: {
|
|
13940
|
-
value: wrapTransaction(apply, fn, db, controller.deferred)
|
|
13941
|
-
},
|
|
13942
|
-
immediate: {
|
|
13943
|
-
value: wrapTransaction(apply, fn, db, controller.immediate)
|
|
13944
|
-
},
|
|
13945
|
-
exclusive: {
|
|
13946
|
-
value: wrapTransaction(apply, fn, db, controller.exclusive)
|
|
13947
|
-
},
|
|
13948
|
-
database: {
|
|
13949
|
-
value: this,
|
|
13950
|
-
enumerable: true
|
|
13951
|
-
}
|
|
13952
|
-
};
|
|
13953
|
-
Object.defineProperties(properties.default.value, properties);
|
|
13954
|
-
Object.defineProperties(properties.deferred.value, properties);
|
|
13955
|
-
Object.defineProperties(properties.immediate.value, properties);
|
|
13956
|
-
Object.defineProperties(properties.exclusive.value, properties);
|
|
13957
|
-
|
|
13958
|
-
// Return the default version of the transaction function
|
|
13959
|
-
return properties.default.value;
|
|
13960
|
-
};
|
|
13961
|
-
|
|
13962
|
-
// Return the database's cached transaction controller, or create a new one
|
|
13963
|
-
const getController = (db, self) => {
|
|
13964
|
-
let controller = controllers.get(db);
|
|
13965
|
-
if (!controller) {
|
|
13966
|
-
const shared = {
|
|
13967
|
-
commit: db.prepare('COMMIT', self, false, false),
|
|
13968
|
-
rollback: db.prepare('ROLLBACK', self, false, false),
|
|
13969
|
-
savepoint: db.prepare('SAVEPOINT `\t_bs3.\t`', self, false, false),
|
|
13970
|
-
release: db.prepare('RELEASE `\t_bs3.\t`', self, false, false),
|
|
13971
|
-
rollbackTo: db.prepare('ROLLBACK TO `\t_bs3.\t`', self, false, false)
|
|
13972
|
-
};
|
|
13973
|
-
controllers.set(db, controller = {
|
|
13974
|
-
default: Object.assign({
|
|
13975
|
-
begin: db.prepare('BEGIN', self, false, false)
|
|
13976
|
-
}, shared),
|
|
13977
|
-
deferred: Object.assign({
|
|
13978
|
-
begin: db.prepare('BEGIN DEFERRED', self, false, false)
|
|
13979
|
-
}, shared),
|
|
13980
|
-
immediate: Object.assign({
|
|
13981
|
-
begin: db.prepare('BEGIN IMMEDIATE', self, false, false)
|
|
13982
|
-
}, shared),
|
|
13983
|
-
exclusive: Object.assign({
|
|
13984
|
-
begin: db.prepare('BEGIN EXCLUSIVE', self, false, false)
|
|
13985
|
-
}, shared)
|
|
13986
|
-
});
|
|
13987
|
-
}
|
|
13988
|
-
return controller;
|
|
13989
|
-
};
|
|
13990
|
-
|
|
13991
|
-
// Return a new transaction function by wrapping the given function
|
|
13992
|
-
const wrapTransaction = (apply, fn, db, {
|
|
13993
|
-
begin,
|
|
13994
|
-
commit,
|
|
13995
|
-
rollback,
|
|
13996
|
-
savepoint,
|
|
13997
|
-
release,
|
|
13998
|
-
rollbackTo
|
|
13999
|
-
}) => function sqliteTransaction() {
|
|
14000
|
-
let before, after, undo;
|
|
14001
|
-
if (db.inTransaction) {
|
|
14002
|
-
before = savepoint;
|
|
14003
|
-
after = release;
|
|
14004
|
-
undo = rollbackTo;
|
|
14005
|
-
} else {
|
|
14006
|
-
before = begin;
|
|
14007
|
-
after = commit;
|
|
14008
|
-
undo = rollback;
|
|
14009
|
-
}
|
|
14010
|
-
before.run();
|
|
14011
|
-
try {
|
|
14012
|
-
const result = apply.call(fn, this, arguments);
|
|
14013
|
-
if (result && typeof result.then === 'function') {
|
|
14014
|
-
throw new TypeError('Transaction function cannot return a promise');
|
|
14015
|
-
}
|
|
14016
|
-
after.run();
|
|
14017
|
-
return result;
|
|
14018
|
-
} catch (ex) {
|
|
14019
|
-
if (db.inTransaction) {
|
|
14020
|
-
undo.run();
|
|
14021
|
-
if (undo !== rollback) after.run();
|
|
14022
|
-
}
|
|
14023
|
-
throw ex;
|
|
14024
|
-
}
|
|
14025
|
-
};
|
|
14026
|
-
return transaction;
|
|
14027
|
-
}
|
|
14028
|
-
|
|
14029
|
-
var pragma;
|
|
14030
|
-
var hasRequiredPragma;
|
|
14031
|
-
function requirePragma() {
|
|
14032
|
-
if (hasRequiredPragma) return pragma;
|
|
14033
|
-
hasRequiredPragma = 1;
|
|
14034
|
-
const {
|
|
14035
|
-
getBooleanOption,
|
|
14036
|
-
cppdb
|
|
14037
|
-
} = requireUtil();
|
|
14038
|
-
pragma = function pragma(source, options) {
|
|
14039
|
-
if (options == null) options = {};
|
|
14040
|
-
if (typeof source !== 'string') throw new TypeError('Expected first argument to be a string');
|
|
14041
|
-
if (typeof options !== 'object') throw new TypeError('Expected second argument to be an options object');
|
|
14042
|
-
const simple = getBooleanOption(options, 'simple');
|
|
14043
|
-
const stmt = this[cppdb].prepare(`PRAGMA ${source}`, this, true, false);
|
|
14044
|
-
return simple ? stmt.pluck().get() : stmt.all();
|
|
14045
|
-
};
|
|
14046
|
-
return pragma;
|
|
14047
|
-
}
|
|
14048
|
-
|
|
14049
|
-
var explain;
|
|
14050
|
-
var hasRequiredExplain;
|
|
14051
|
-
function requireExplain() {
|
|
14052
|
-
if (hasRequiredExplain) return explain;
|
|
14053
|
-
hasRequiredExplain = 1;
|
|
14054
|
-
const {
|
|
14055
|
-
cppdb
|
|
14056
|
-
} = requireUtil();
|
|
14057
|
-
explain = function explain(source) {
|
|
14058
|
-
if (typeof source !== 'string') throw new TypeError('Expected first argument to be a string');
|
|
14059
|
-
const stmt = this[cppdb].prepare(`EXPLAIN ${source}`, this, false, true);
|
|
14060
|
-
return stmt.all();
|
|
14061
|
-
};
|
|
14062
|
-
return explain;
|
|
14063
|
-
}
|
|
14064
|
-
|
|
14065
|
-
var backup;
|
|
14066
|
-
var hasRequiredBackup;
|
|
14067
|
-
function requireBackup() {
|
|
14068
|
-
if (hasRequiredBackup) return backup;
|
|
14069
|
-
hasRequiredBackup = 1;
|
|
14070
|
-
const fs = require$$0;
|
|
14071
|
-
const path = require$$1;
|
|
14072
|
-
const {
|
|
14073
|
-
promisify
|
|
14074
|
-
} = require$$2;
|
|
14075
|
-
const {
|
|
14076
|
-
cppdb
|
|
14077
|
-
} = requireUtil();
|
|
14078
|
-
const fsAccess = promisify(fs.access);
|
|
14079
|
-
backup = async function backup(filename, options) {
|
|
14080
|
-
if (options == null) options = {};
|
|
14081
|
-
|
|
14082
|
-
// Validate arguments
|
|
14083
|
-
if (typeof filename !== 'string') throw new TypeError('Expected first argument to be a string');
|
|
14084
|
-
if (typeof options !== 'object') throw new TypeError('Expected second argument to be an options object');
|
|
14085
|
-
|
|
14086
|
-
// Interpret options
|
|
14087
|
-
filename = filename.trim();
|
|
14088
|
-
const attachedName = 'attached' in options ? options.attached : 'main';
|
|
14089
|
-
const handler = 'progress' in options ? options.progress : null;
|
|
14090
|
-
|
|
14091
|
-
// Validate interpreted options
|
|
14092
|
-
if (!filename) throw new TypeError('Backup filename cannot be an empty string');
|
|
14093
|
-
if (filename === ':memory:') throw new TypeError('Invalid backup filename ":memory:"');
|
|
14094
|
-
if (typeof attachedName !== 'string') throw new TypeError('Expected the "attached" option to be a string');
|
|
14095
|
-
if (!attachedName) throw new TypeError('The "attached" option cannot be an empty string');
|
|
14096
|
-
if (handler != null && typeof handler !== 'function') throw new TypeError('Expected the "progress" option to be a function');
|
|
14097
|
-
|
|
14098
|
-
// Make sure the specified directory exists
|
|
14099
|
-
await fsAccess(path.dirname(filename)).catch(() => {
|
|
14100
|
-
throw new TypeError('Cannot save backup because the directory does not exist');
|
|
14101
|
-
});
|
|
14102
|
-
const isNewFile = await fsAccess(filename).then(() => false, () => true);
|
|
14103
|
-
return runBackup(this[cppdb].backup(this, attachedName, filename, isNewFile), handler || null);
|
|
14104
|
-
};
|
|
14105
|
-
const runBackup = (backup, handler) => {
|
|
14106
|
-
let rate = 0;
|
|
14107
|
-
let useDefault = true;
|
|
14108
|
-
return new Promise((resolve, reject) => {
|
|
14109
|
-
setImmediate(function step() {
|
|
14110
|
-
try {
|
|
14111
|
-
const progress = backup.transfer(rate);
|
|
14112
|
-
if (!progress.remainingPages) {
|
|
14113
|
-
backup.close();
|
|
14114
|
-
resolve(progress);
|
|
14115
|
-
return;
|
|
14116
|
-
}
|
|
14117
|
-
if (useDefault) {
|
|
14118
|
-
useDefault = false;
|
|
14119
|
-
rate = 100;
|
|
14120
|
-
}
|
|
14121
|
-
if (handler) {
|
|
14122
|
-
const ret = handler(progress);
|
|
14123
|
-
if (ret !== undefined) {
|
|
14124
|
-
if (typeof ret === 'number' && ret === ret) rate = Math.max(0, Math.min(0x7fffffff, Math.round(ret)));else throw new TypeError('Expected progress callback to return a number or undefined');
|
|
14125
|
-
}
|
|
14126
|
-
}
|
|
14127
|
-
setImmediate(step);
|
|
14128
|
-
} catch (err) {
|
|
14129
|
-
backup.close();
|
|
14130
|
-
reject(err);
|
|
14131
|
-
}
|
|
14132
|
-
});
|
|
14133
|
-
});
|
|
14134
|
-
};
|
|
14135
|
-
return backup;
|
|
14136
|
-
}
|
|
14137
|
-
|
|
14138
|
-
var serialize;
|
|
14139
|
-
var hasRequiredSerialize;
|
|
14140
|
-
function requireSerialize() {
|
|
14141
|
-
if (hasRequiredSerialize) return serialize;
|
|
14142
|
-
hasRequiredSerialize = 1;
|
|
14143
|
-
const {
|
|
14144
|
-
cppdb
|
|
14145
|
-
} = requireUtil();
|
|
14146
|
-
serialize = function serialize(options) {
|
|
14147
|
-
if (options == null) options = {};
|
|
14148
|
-
|
|
14149
|
-
// Validate arguments
|
|
14150
|
-
if (typeof options !== 'object') throw new TypeError('Expected first argument to be an options object');
|
|
14151
|
-
|
|
14152
|
-
// Interpret and validate options
|
|
14153
|
-
const attachedName = 'attached' in options ? options.attached : 'main';
|
|
14154
|
-
if (typeof attachedName !== 'string') throw new TypeError('Expected the "attached" option to be a string');
|
|
14155
|
-
if (!attachedName) throw new TypeError('The "attached" option cannot be an empty string');
|
|
14156
|
-
return this[cppdb].serialize(attachedName);
|
|
14157
|
-
};
|
|
14158
|
-
return serialize;
|
|
14159
|
-
}
|
|
14160
|
-
|
|
14161
|
-
var _function;
|
|
14162
|
-
var hasRequired_function;
|
|
14163
|
-
function require_function() {
|
|
14164
|
-
if (hasRequired_function) return _function;
|
|
14165
|
-
hasRequired_function = 1;
|
|
14166
|
-
const {
|
|
14167
|
-
getBooleanOption,
|
|
14168
|
-
cppdb
|
|
14169
|
-
} = requireUtil();
|
|
14170
|
-
_function = function defineFunction(name, options, fn) {
|
|
14171
|
-
// Apply defaults
|
|
14172
|
-
if (options == null) options = {};
|
|
14173
|
-
if (typeof options === 'function') {
|
|
14174
|
-
fn = options;
|
|
14175
|
-
options = {};
|
|
14176
|
-
}
|
|
14177
|
-
|
|
14178
|
-
// Validate arguments
|
|
14179
|
-
if (typeof name !== 'string') throw new TypeError('Expected first argument to be a string');
|
|
14180
|
-
if (typeof fn !== 'function') throw new TypeError('Expected last argument to be a function');
|
|
14181
|
-
if (typeof options !== 'object') throw new TypeError('Expected second argument to be an options object');
|
|
14182
|
-
if (!name) throw new TypeError('User-defined function name cannot be an empty string');
|
|
14183
|
-
|
|
14184
|
-
// Interpret options
|
|
14185
|
-
const safeIntegers = 'safeIntegers' in options ? +getBooleanOption(options, 'safeIntegers') : 2;
|
|
14186
|
-
const deterministic = getBooleanOption(options, 'deterministic');
|
|
14187
|
-
const directOnly = getBooleanOption(options, 'directOnly');
|
|
14188
|
-
const varargs = getBooleanOption(options, 'varargs');
|
|
14189
|
-
let argCount = -1;
|
|
14190
|
-
|
|
14191
|
-
// Determine argument count
|
|
14192
|
-
if (!varargs) {
|
|
14193
|
-
argCount = fn.length;
|
|
14194
|
-
if (!Number.isInteger(argCount) || argCount < 0) throw new TypeError('Expected function.length to be a positive integer');
|
|
14195
|
-
if (argCount > 100) throw new RangeError('User-defined functions cannot have more than 100 arguments');
|
|
14196
|
-
}
|
|
14197
|
-
this[cppdb].function(fn, name, argCount, safeIntegers, deterministic, directOnly);
|
|
14198
|
-
return this;
|
|
14199
|
-
};
|
|
14200
|
-
return _function;
|
|
14201
|
-
}
|
|
14202
|
-
|
|
14203
|
-
var aggregate;
|
|
14204
|
-
var hasRequiredAggregate;
|
|
14205
|
-
function requireAggregate() {
|
|
14206
|
-
if (hasRequiredAggregate) return aggregate;
|
|
14207
|
-
hasRequiredAggregate = 1;
|
|
14208
|
-
const {
|
|
14209
|
-
getBooleanOption,
|
|
14210
|
-
cppdb
|
|
14211
|
-
} = requireUtil();
|
|
14212
|
-
aggregate = function defineAggregate(name, options) {
|
|
14213
|
-
// Validate arguments
|
|
14214
|
-
if (typeof name !== 'string') throw new TypeError('Expected first argument to be a string');
|
|
14215
|
-
if (typeof options !== 'object' || options === null) throw new TypeError('Expected second argument to be an options object');
|
|
14216
|
-
if (!name) throw new TypeError('User-defined function name cannot be an empty string');
|
|
14217
|
-
|
|
14218
|
-
// Interpret options
|
|
14219
|
-
const start = 'start' in options ? options.start : null;
|
|
14220
|
-
const step = getFunctionOption(options, 'step', true);
|
|
14221
|
-
const inverse = getFunctionOption(options, 'inverse', false);
|
|
14222
|
-
const result = getFunctionOption(options, 'result', false);
|
|
14223
|
-
const safeIntegers = 'safeIntegers' in options ? +getBooleanOption(options, 'safeIntegers') : 2;
|
|
14224
|
-
const deterministic = getBooleanOption(options, 'deterministic');
|
|
14225
|
-
const directOnly = getBooleanOption(options, 'directOnly');
|
|
14226
|
-
const varargs = getBooleanOption(options, 'varargs');
|
|
14227
|
-
let argCount = -1;
|
|
14228
|
-
|
|
14229
|
-
// Determine argument count
|
|
14230
|
-
if (!varargs) {
|
|
14231
|
-
argCount = Math.max(getLength(step), inverse ? getLength(inverse) : 0);
|
|
14232
|
-
if (argCount > 0) argCount -= 1;
|
|
14233
|
-
if (argCount > 100) throw new RangeError('User-defined functions cannot have more than 100 arguments');
|
|
14234
|
-
}
|
|
14235
|
-
this[cppdb].aggregate(start, step, inverse, result, name, argCount, safeIntegers, deterministic, directOnly);
|
|
14236
|
-
return this;
|
|
14237
|
-
};
|
|
14238
|
-
const getFunctionOption = (options, key, required) => {
|
|
14239
|
-
const value = key in options ? options[key] : null;
|
|
14240
|
-
if (typeof value === 'function') return value;
|
|
14241
|
-
if (value != null) throw new TypeError(`Expected the "${key}" option to be a function`);
|
|
14242
|
-
if (required) throw new TypeError(`Missing required option "${key}"`);
|
|
14243
|
-
return null;
|
|
14244
|
-
};
|
|
14245
|
-
const getLength = ({
|
|
14246
|
-
length
|
|
14247
|
-
}) => {
|
|
14248
|
-
if (Number.isInteger(length) && length >= 0) return length;
|
|
14249
|
-
throw new TypeError('Expected function.length to be a positive integer');
|
|
14250
|
-
};
|
|
14251
|
-
return aggregate;
|
|
14252
|
-
}
|
|
14253
|
-
|
|
14254
|
-
var table;
|
|
14255
|
-
var hasRequiredTable;
|
|
14256
|
-
function requireTable() {
|
|
14257
|
-
if (hasRequiredTable) return table;
|
|
14258
|
-
hasRequiredTable = 1;
|
|
14259
|
-
const {
|
|
14260
|
-
cppdb
|
|
14261
|
-
} = requireUtil();
|
|
14262
|
-
table = function defineTable(name, factory) {
|
|
14263
|
-
// Validate arguments
|
|
14264
|
-
if (typeof name !== 'string') throw new TypeError('Expected first argument to be a string');
|
|
14265
|
-
if (!name) throw new TypeError('Virtual table module name cannot be an empty string');
|
|
14266
|
-
|
|
14267
|
-
// Determine whether the module is eponymous-only or not
|
|
14268
|
-
let eponymous = false;
|
|
14269
|
-
if (typeof factory === 'object' && factory !== null) {
|
|
14270
|
-
eponymous = true;
|
|
14271
|
-
factory = defer(parseTableDefinition(factory, 'used', name));
|
|
14272
|
-
} else {
|
|
14273
|
-
if (typeof factory !== 'function') throw new TypeError('Expected second argument to be a function or a table definition object');
|
|
14274
|
-
factory = wrapFactory(factory);
|
|
14275
|
-
}
|
|
14276
|
-
this[cppdb].table(factory, name, eponymous);
|
|
14277
|
-
return this;
|
|
14278
|
-
};
|
|
14279
|
-
function wrapFactory(factory) {
|
|
14280
|
-
return function virtualTableFactory(moduleName, databaseName, tableName, ...args) {
|
|
14281
|
-
const thisObject = {
|
|
14282
|
-
module: moduleName,
|
|
14283
|
-
database: databaseName,
|
|
14284
|
-
table: tableName
|
|
14285
|
-
};
|
|
14286
|
-
|
|
14287
|
-
// Generate a new table definition by invoking the factory
|
|
14288
|
-
const def = apply.call(factory, thisObject, args);
|
|
14289
|
-
if (typeof def !== 'object' || def === null) {
|
|
14290
|
-
throw new TypeError(`Virtual table module "${moduleName}" did not return a table definition object`);
|
|
14291
|
-
}
|
|
14292
|
-
return parseTableDefinition(def, 'returned', moduleName);
|
|
14293
|
-
};
|
|
14294
|
-
}
|
|
14295
|
-
function parseTableDefinition(def, verb, moduleName) {
|
|
14296
|
-
// Validate required properties
|
|
14297
|
-
if (!hasOwnProperty.call(def, 'rows')) {
|
|
14298
|
-
throw new TypeError(`Virtual table module "${moduleName}" ${verb} a table definition without a "rows" property`);
|
|
14299
|
-
}
|
|
14300
|
-
if (!hasOwnProperty.call(def, 'columns')) {
|
|
14301
|
-
throw new TypeError(`Virtual table module "${moduleName}" ${verb} a table definition without a "columns" property`);
|
|
14302
|
-
}
|
|
14303
|
-
|
|
14304
|
-
// Validate "rows" property
|
|
14305
|
-
const rows = def.rows;
|
|
14306
|
-
if (typeof rows !== 'function' || Object.getPrototypeOf(rows) !== GeneratorFunctionPrototype) {
|
|
14307
|
-
throw new TypeError(`Virtual table module "${moduleName}" ${verb} a table definition with an invalid "rows" property (should be a generator function)`);
|
|
14308
|
-
}
|
|
14309
|
-
|
|
14310
|
-
// Validate "columns" property
|
|
14311
|
-
let columns = def.columns;
|
|
14312
|
-
if (!Array.isArray(columns) || !isStringArray(columns = [...columns])) {
|
|
14313
|
-
throw new TypeError(`Virtual table module "${moduleName}" ${verb} a table definition with an invalid "columns" property (should be an array of strings)`);
|
|
14314
|
-
}
|
|
14315
|
-
if (columns.length !== new Set(columns).size) {
|
|
14316
|
-
throw new TypeError(`Virtual table module "${moduleName}" ${verb} a table definition with duplicate column names`);
|
|
14317
|
-
}
|
|
14318
|
-
if (!columns.length) {
|
|
14319
|
-
throw new RangeError(`Virtual table module "${moduleName}" ${verb} a table definition with zero columns`);
|
|
14320
|
-
}
|
|
14321
|
-
|
|
14322
|
-
// Validate "parameters" property
|
|
14323
|
-
let parameters;
|
|
14324
|
-
if (hasOwnProperty.call(def, 'parameters')) {
|
|
14325
|
-
parameters = def.parameters;
|
|
14326
|
-
if (!Array.isArray(parameters) || !isStringArray(parameters = [...parameters])) {
|
|
14327
|
-
throw new TypeError(`Virtual table module "${moduleName}" ${verb} a table definition with an invalid "parameters" property (should be an array of strings)`);
|
|
14328
|
-
}
|
|
14329
|
-
} else {
|
|
14330
|
-
parameters = inferParameters(rows);
|
|
14331
|
-
}
|
|
14332
|
-
if (parameters.length !== new Set(parameters).size) {
|
|
14333
|
-
throw new TypeError(`Virtual table module "${moduleName}" ${verb} a table definition with duplicate parameter names`);
|
|
14334
|
-
}
|
|
14335
|
-
if (parameters.length > 32) {
|
|
14336
|
-
throw new RangeError(`Virtual table module "${moduleName}" ${verb} a table definition with more than the maximum number of 32 parameters`);
|
|
14337
|
-
}
|
|
14338
|
-
for (const parameter of parameters) {
|
|
14339
|
-
if (columns.includes(parameter)) {
|
|
14340
|
-
throw new TypeError(`Virtual table module "${moduleName}" ${verb} a table definition with column "${parameter}" which was ambiguously defined as both a column and parameter`);
|
|
14341
|
-
}
|
|
14342
|
-
}
|
|
14343
|
-
|
|
14344
|
-
// Validate "safeIntegers" option
|
|
14345
|
-
let safeIntegers = 2;
|
|
14346
|
-
if (hasOwnProperty.call(def, 'safeIntegers')) {
|
|
14347
|
-
const bool = def.safeIntegers;
|
|
14348
|
-
if (typeof bool !== 'boolean') {
|
|
14349
|
-
throw new TypeError(`Virtual table module "${moduleName}" ${verb} a table definition with an invalid "safeIntegers" property (should be a boolean)`);
|
|
14350
|
-
}
|
|
14351
|
-
safeIntegers = +bool;
|
|
14352
|
-
}
|
|
14353
|
-
|
|
14354
|
-
// Validate "directOnly" option
|
|
14355
|
-
let directOnly = false;
|
|
14356
|
-
if (hasOwnProperty.call(def, 'directOnly')) {
|
|
14357
|
-
directOnly = def.directOnly;
|
|
14358
|
-
if (typeof directOnly !== 'boolean') {
|
|
14359
|
-
throw new TypeError(`Virtual table module "${moduleName}" ${verb} a table definition with an invalid "directOnly" property (should be a boolean)`);
|
|
14360
|
-
}
|
|
14361
|
-
}
|
|
14362
|
-
|
|
14363
|
-
// Generate SQL for the virtual table definition
|
|
14364
|
-
const columnDefinitions = [...parameters.map(identifier).map(str => `${str} HIDDEN`), ...columns.map(identifier)];
|
|
14365
|
-
return [`CREATE TABLE x(${columnDefinitions.join(', ')});`, wrapGenerator(rows, new Map(columns.map((x, i) => [x, parameters.length + i])), moduleName), parameters, safeIntegers, directOnly];
|
|
14366
|
-
}
|
|
14367
|
-
function wrapGenerator(generator, columnMap, moduleName) {
|
|
14368
|
-
return function* virtualTable(...args) {
|
|
14369
|
-
/*
|
|
14370
|
-
We must defensively clone any buffers in the arguments, because
|
|
14371
|
-
otherwise the generator could mutate one of them, which would cause
|
|
14372
|
-
us to return incorrect values for hidden columns, potentially
|
|
14373
|
-
corrupting the database.
|
|
14374
|
-
*/
|
|
14375
|
-
const output = args.map(x => Buffer.isBuffer(x) ? Buffer.from(x) : x);
|
|
14376
|
-
for (let i = 0; i < columnMap.size; ++i) {
|
|
14377
|
-
output.push(null); // Fill with nulls to prevent gaps in array (v8 optimization)
|
|
14378
|
-
}
|
|
14379
|
-
for (const row of generator(...args)) {
|
|
14380
|
-
if (Array.isArray(row)) {
|
|
14381
|
-
extractRowArray(row, output, columnMap.size, moduleName);
|
|
14382
|
-
yield output;
|
|
14383
|
-
} else if (typeof row === 'object' && row !== null) {
|
|
14384
|
-
extractRowObject(row, output, columnMap, moduleName);
|
|
14385
|
-
yield output;
|
|
14386
|
-
} else {
|
|
14387
|
-
throw new TypeError(`Virtual table module "${moduleName}" yielded something that isn't a valid row object`);
|
|
14388
|
-
}
|
|
14389
|
-
}
|
|
14390
|
-
};
|
|
14391
|
-
}
|
|
14392
|
-
function extractRowArray(row, output, columnCount, moduleName) {
|
|
14393
|
-
if (row.length !== columnCount) {
|
|
14394
|
-
throw new TypeError(`Virtual table module "${moduleName}" yielded a row with an incorrect number of columns`);
|
|
14395
|
-
}
|
|
14396
|
-
const offset = output.length - columnCount;
|
|
14397
|
-
for (let i = 0; i < columnCount; ++i) {
|
|
14398
|
-
output[i + offset] = row[i];
|
|
14399
|
-
}
|
|
14400
|
-
}
|
|
14401
|
-
function extractRowObject(row, output, columnMap, moduleName) {
|
|
14402
|
-
let count = 0;
|
|
14403
|
-
for (const key of Object.keys(row)) {
|
|
14404
|
-
const index = columnMap.get(key);
|
|
14405
|
-
if (index === undefined) {
|
|
14406
|
-
throw new TypeError(`Virtual table module "${moduleName}" yielded a row with an undeclared column "${key}"`);
|
|
14407
|
-
}
|
|
14408
|
-
output[index] = row[key];
|
|
14409
|
-
count += 1;
|
|
14410
|
-
}
|
|
14411
|
-
if (count !== columnMap.size) {
|
|
14412
|
-
throw new TypeError(`Virtual table module "${moduleName}" yielded a row with missing columns`);
|
|
14413
|
-
}
|
|
14414
|
-
}
|
|
14415
|
-
function inferParameters({
|
|
14416
|
-
length
|
|
14417
|
-
}) {
|
|
14418
|
-
if (!Number.isInteger(length) || length < 0) {
|
|
14419
|
-
throw new TypeError('Expected function.length to be a positive integer');
|
|
14420
|
-
}
|
|
14421
|
-
const params = [];
|
|
14422
|
-
for (let i = 0; i < length; ++i) {
|
|
14423
|
-
params.push(`$${i + 1}`);
|
|
14424
|
-
}
|
|
14425
|
-
return params;
|
|
14426
|
-
}
|
|
14427
|
-
const {
|
|
14428
|
-
hasOwnProperty
|
|
14429
|
-
} = Object.prototype;
|
|
14430
|
-
const {
|
|
14431
|
-
apply
|
|
14432
|
-
} = Function.prototype;
|
|
14433
|
-
const GeneratorFunctionPrototype = Object.getPrototypeOf(function* () {});
|
|
14434
|
-
const identifier = str => `"${str.replace(/"/g, '""')}"`;
|
|
14435
|
-
const defer = x => () => x;
|
|
14436
|
-
const isStringArray = arr => {
|
|
14437
|
-
for (let i = 0; i < arr.length; ++i) {
|
|
14438
|
-
if (typeof arr[i] !== 'string') return false;
|
|
14439
|
-
}
|
|
14440
|
-
return true;
|
|
14441
|
-
};
|
|
14442
|
-
return table;
|
|
14443
|
-
}
|
|
14444
|
-
|
|
14445
|
-
var inspect;
|
|
14446
|
-
var hasRequiredInspect;
|
|
14447
|
-
function requireInspect() {
|
|
14448
|
-
if (hasRequiredInspect) return inspect;
|
|
14449
|
-
hasRequiredInspect = 1;
|
|
14450
|
-
const DatabaseInspection = function Database() {};
|
|
14451
|
-
inspect = function inspect(depth, opts) {
|
|
14452
|
-
return Object.assign(new DatabaseInspection(), this);
|
|
14453
|
-
};
|
|
14454
|
-
return inspect;
|
|
14455
|
-
}
|
|
14456
|
-
|
|
14457
|
-
var database;
|
|
14458
|
-
var hasRequiredDatabase;
|
|
14459
|
-
function requireDatabase() {
|
|
14460
|
-
if (hasRequiredDatabase) return database;
|
|
14461
|
-
hasRequiredDatabase = 1;
|
|
14462
|
-
const fs = require$$0;
|
|
14463
|
-
const path = require$$1;
|
|
14464
|
-
const util = requireUtil();
|
|
14465
|
-
const SqliteError = requireSqliteError();
|
|
14466
|
-
database = function createDatabase(getAddon, allowNativeBinding) {
|
|
14467
|
-
function Database(filenameGiven, options) {
|
|
14468
|
-
if (new.target == null) {
|
|
14469
|
-
return new Database(filenameGiven, options);
|
|
14470
|
-
}
|
|
14471
|
-
|
|
14472
|
-
// Apply defaults
|
|
14473
|
-
let buffer;
|
|
14474
|
-
if (Buffer.isBuffer(filenameGiven)) {
|
|
14475
|
-
buffer = filenameGiven;
|
|
14476
|
-
filenameGiven = ':memory:';
|
|
14477
|
-
}
|
|
14478
|
-
if (filenameGiven == null) filenameGiven = '';
|
|
14479
|
-
if (options == null) options = {};
|
|
14480
|
-
|
|
14481
|
-
// Validate arguments
|
|
14482
|
-
if (typeof filenameGiven !== 'string') throw new TypeError('Expected first argument to be a string');
|
|
14483
|
-
if (typeof options !== 'object') throw new TypeError('Expected second argument to be an options object');
|
|
14484
|
-
if ('readOnly' in options) throw new TypeError('Misspelled option "readOnly" should be "readonly"');
|
|
14485
|
-
if ('memory' in options) throw new TypeError('Option "memory" was removed in v7.0.0 (use ":memory:" filename instead)');
|
|
14486
|
-
|
|
14487
|
-
// Interpret options
|
|
14488
|
-
const filename = filenameGiven.trim();
|
|
14489
|
-
const anonymous = filename === '' || filename === ':memory:';
|
|
14490
|
-
const readonly = util.getBooleanOption(options, 'readonly');
|
|
14491
|
-
const fileMustExist = util.getBooleanOption(options, 'fileMustExist');
|
|
14492
|
-
const timeout = 'timeout' in options ? options.timeout : 5000;
|
|
14493
|
-
const verbose = 'verbose' in options ? options.verbose : null;
|
|
14494
|
-
const nativeBinding = 'nativeBinding' in options ? options.nativeBinding : null;
|
|
14495
|
-
|
|
14496
|
-
// Validate interpreted options
|
|
14497
|
-
if (readonly && anonymous && !buffer) throw new TypeError('In-memory/temporary databases cannot be readonly');
|
|
14498
|
-
if (!Number.isInteger(timeout) || timeout < 0) throw new TypeError('Expected the "timeout" option to be a positive integer');
|
|
14499
|
-
if (timeout > 0x7fffffff) throw new RangeError('Option "timeout" cannot be greater than 2147483647');
|
|
14500
|
-
if (verbose != null && typeof verbose !== 'function') throw new TypeError('Expected the "verbose" option to be a function');
|
|
14501
|
-
if (!allowNativeBinding && 'nativeBinding' in options) throw new TypeError('The "nativeBinding" option is only supported by the default better-sqlite3 entrypoint');
|
|
14502
|
-
if (allowNativeBinding && nativeBinding != null && typeof nativeBinding !== 'string' && typeof nativeBinding !== 'object') throw new TypeError('Expected the "nativeBinding" option to be a string or addon object');
|
|
14503
|
-
|
|
14504
|
-
// Load the native addon
|
|
14505
|
-
const addon = getAddon(nativeBinding);
|
|
14506
|
-
if (!addon.isInitialized) {
|
|
14507
|
-
addon.initialize(SqliteError, arrayFactory, arrayAppender, rowFactory, recordFactory);
|
|
14508
|
-
addon.isInitialized = true;
|
|
14509
|
-
}
|
|
14510
|
-
|
|
14511
|
-
// Make sure the specified directory exists
|
|
14512
|
-
if (!anonymous && !filename.startsWith('file:') && !fs.existsSync(path.dirname(filename))) {
|
|
14513
|
-
throw new TypeError('Cannot open database because the directory does not exist');
|
|
14514
|
-
}
|
|
14515
|
-
Object.defineProperties(this, {
|
|
14516
|
-
[util.cppdb]: {
|
|
14517
|
-
value: new addon.Database(filename, filenameGiven, anonymous, readonly, fileMustExist, timeout, verbose || null, buffer || null)
|
|
14518
|
-
},
|
|
14519
|
-
...wrappers.getters
|
|
14520
|
-
});
|
|
14521
|
-
}
|
|
14522
|
-
const wrappers = requireWrappers();
|
|
14523
|
-
Database.prototype.prepare = wrappers.prepare;
|
|
14524
|
-
Database.prototype.transaction = requireTransaction();
|
|
14525
|
-
Database.prototype.pragma = requirePragma();
|
|
14526
|
-
Database.prototype.explain = requireExplain();
|
|
14527
|
-
Database.prototype.backup = requireBackup();
|
|
14528
|
-
Database.prototype.serialize = requireSerialize();
|
|
14529
|
-
Database.prototype.function = require_function();
|
|
14530
|
-
Database.prototype.aggregate = requireAggregate();
|
|
14531
|
-
Database.prototype.table = requireTable();
|
|
14532
|
-
Database.prototype.loadExtension = wrappers.loadExtension;
|
|
14533
|
-
Database.prototype.exec = wrappers.exec;
|
|
14534
|
-
Database.prototype.close = wrappers.close;
|
|
14535
|
-
Database.prototype.defaultSafeIntegers = wrappers.defaultSafeIntegers;
|
|
14536
|
-
Database.prototype.unsafeMode = wrappers.unsafeMode;
|
|
14537
|
-
Database.prototype[util.inspect] = requireInspect();
|
|
14538
|
-
return Database;
|
|
14539
|
-
};
|
|
14540
|
-
function arrayFactory(...values) {
|
|
14541
|
-
return values;
|
|
14542
|
-
}
|
|
14543
|
-
function arrayAppender(array, ...values) {
|
|
14544
|
-
const offset = array.length;
|
|
14545
|
-
for (let i = 0; i < values.length; ++i) {
|
|
14546
|
-
array[offset + i] = values[i];
|
|
14547
|
-
}
|
|
14548
|
-
}
|
|
14549
|
-
function rowFactory(...keys) {
|
|
14550
|
-
if (!keys.includes('__proto__')) {
|
|
14551
|
-
const parameters = keys.map((_, index) => `v${index}`).join(',');
|
|
14552
|
-
const properties = keys.map((key, index) => `${JSON.stringify(key)}:v${index}`).join(',');
|
|
14553
|
-
return Function(`return (${parameters}) => ({${properties}})`)();
|
|
14554
|
-
}
|
|
14555
|
-
return (...values) => {
|
|
14556
|
-
const row = {};
|
|
14557
|
-
for (let i = 0; i < keys.length; ++i) row[keys[i]] = values[i];
|
|
14558
|
-
return row;
|
|
14559
|
-
};
|
|
14560
|
-
}
|
|
14561
|
-
function recordFactory(value) {
|
|
14562
|
-
return {
|
|
14563
|
-
value,
|
|
14564
|
-
done: false
|
|
14565
|
-
};
|
|
14566
|
-
}
|
|
14567
|
-
return database;
|
|
14568
|
-
}
|
|
14569
|
-
|
|
14570
|
-
function commonjsRequire(path) {
|
|
14571
|
-
throw new Error('Could not dynamically require "' + path + '". Please configure the dynamicRequireTargets or/and ignoreDynamicRequires option of @rollup/plugin-commonjs appropriately for this require call to work.');
|
|
14572
|
-
}
|
|
14573
|
-
|
|
14574
|
-
var binding = {exports: {}};
|
|
14575
|
-
|
|
14576
|
-
var hasRequiredBinding;
|
|
14577
|
-
function requireBinding() {
|
|
14578
|
-
if (hasRequiredBinding) return binding.exports;
|
|
14579
|
-
hasRequiredBinding = 1;
|
|
14580
|
-
(function (module, exports) {
|
|
14581
|
-
|
|
14582
|
-
const fs = require$$0;
|
|
14583
|
-
const path = require$$1;
|
|
14584
|
-
const PREBUILD_PLATFORMS = ['linux', 'darwin', 'win32'];
|
|
14585
|
-
const PREBUILD_ARCHS = ['x64', 'arm64'];
|
|
14586
|
-
let DEFAULT_ADDON;
|
|
14587
|
-
function getBinding(nativeBinding) {
|
|
14588
|
-
// If a path was provided, load the binding from the filesystem.
|
|
14589
|
-
if (typeof nativeBinding === 'string') {
|
|
14590
|
-
// See <https://webpack.js.org/api/module-variables/#__non_webpack_require__-webpack-specific>
|
|
14591
|
-
const requireFunc = typeof __non_webpack_require__ === 'function' ? __non_webpack_require__ : commonjsRequire;
|
|
14592
|
-
return requireFunc(path.resolve(nativeBinding).replace(/(\.node)?$/, '.node'));
|
|
14593
|
-
}
|
|
14594
|
-
|
|
14595
|
-
// If an object was provided, use it as the binding directly.
|
|
14596
|
-
if (typeof nativeBinding === 'object' && nativeBinding !== null) {
|
|
14597
|
-
return nativeBinding;
|
|
14598
|
-
}
|
|
14599
|
-
|
|
14600
|
-
// If we're using the default binding and it already exists, just return it.
|
|
14601
|
-
if (DEFAULT_ADDON) {
|
|
14602
|
-
return DEFAULT_ADDON;
|
|
14603
|
-
}
|
|
14604
|
-
|
|
14605
|
-
// Otherwise, try to find the binding as a prebuilt binary.
|
|
14606
|
-
let filename = getPrebuildPath();
|
|
14607
|
-
if (filename) {
|
|
14608
|
-
return DEFAULT_ADDON = commonjsRequire(filename);
|
|
14609
|
-
}
|
|
14610
|
-
|
|
14611
|
-
// If no prebuilt binary was found, try the default node-gyp locations.
|
|
14612
|
-
filename = path.join(__dirname, '..', 'build', 'Debug', 'better_sqlite3.node');
|
|
14613
|
-
if (!fs.existsSync(filename)) {
|
|
14614
|
-
filename = path.join(__dirname, '..', 'build', 'Release', 'better_sqlite3.node');
|
|
14615
|
-
}
|
|
14616
|
-
return DEFAULT_ADDON = commonjsRequire(filename);
|
|
14617
|
-
}
|
|
14618
|
-
function getPrebuildPath() {
|
|
14619
|
-
if (PREBUILD_PLATFORMS.includes(process.platform) && PREBUILD_ARCHS.includes(process.arch)) {
|
|
14620
|
-
const target = `${isLinuxMusl() ? 'linuxmusl' : process.platform}-${process.arch}`;
|
|
14621
|
-
const filename = path.join(__dirname, '..', 'prebuilds', `${target}.node`);
|
|
14622
|
-
if (fs.existsSync(filename)) {
|
|
14623
|
-
return filename;
|
|
14624
|
-
}
|
|
14625
|
-
}
|
|
14626
|
-
return null;
|
|
14627
|
-
}
|
|
14628
|
-
function isLinuxMusl() {
|
|
14629
|
-
return process.platform === 'linux' && !process.report.getReport().header.glibcVersionRuntime;
|
|
14630
|
-
}
|
|
14631
|
-
exports.getBinding = getBinding;
|
|
14632
|
-
exports.getPrebuildPath = getPrebuildPath;
|
|
14633
|
-
|
|
14634
|
-
// This script is executed directly by binding.gyp to detect prebuilt binaries.
|
|
14635
|
-
if (require.main === module) {
|
|
14636
|
-
process.stdout.write(getPrebuildPath() ? '1' : '0');
|
|
14637
|
-
}
|
|
14638
|
-
})(binding, binding.exports);
|
|
14639
|
-
return binding.exports;
|
|
14640
|
-
}
|
|
14641
|
-
|
|
14642
|
-
var hasRequiredLib;
|
|
14643
|
-
function requireLib() {
|
|
14644
|
-
if (hasRequiredLib) return lib.exports;
|
|
14645
|
-
hasRequiredLib = 1;
|
|
14646
|
-
lib.exports = requireDatabase()(requireBinding().getBinding, true);
|
|
14647
|
-
lib.exports.SqliteError = requireSqliteError();
|
|
14648
|
-
return lib.exports;
|
|
14649
|
-
}
|
|
14650
|
-
|
|
14651
|
-
var libExports = requireLib();
|
|
14652
|
-
var Database = /*@__PURE__*/getDefaultExportFromCjs(libExports);
|
|
14653
|
-
|
|
14654
|
-
/**
|
|
14655
|
-
*
|
|
14656
|
-
*/
|
|
14657
|
-
class SQLiteResult {
|
|
14658
|
-
/**
|
|
14659
|
-
* @param {Error|null|undefined} error
|
|
14660
|
-
* @param {number|undefined} [insertId]
|
|
14661
|
-
* @param {number} [rowsAffected]
|
|
14662
|
-
* @param {object[]} [rows]
|
|
14663
|
-
*/
|
|
14664
|
-
constructor(error, insertId, rowsAffected, rows) {
|
|
14665
|
-
this.error = error;
|
|
14666
|
-
this.insertId = insertId;
|
|
14667
|
-
this.rowsAffected = rowsAffected;
|
|
14668
|
-
this.rows = rows;
|
|
14669
|
-
}
|
|
14670
|
-
}
|
|
14671
|
-
const READ_ONLY_ERROR = new Error('could not prepare statement (23 not authorized)');
|
|
14672
|
-
|
|
14673
|
-
/**
|
|
14674
|
-
* @typedef {(sql: string, duration: number) => void} SQLProfileCallback
|
|
14675
|
-
*/
|
|
14676
|
-
|
|
14677
|
-
/**
|
|
14678
|
-
* @typedef {((sql: string) => void)|undefined} SQLTraceCallback
|
|
14679
|
-
*/
|
|
14680
|
-
|
|
14681
|
-
// Two separate `better-sqlite3` connections (i.e., two separate
|
|
14682
|
-
// `SQLiteDatabase` instances) can legitimately point at the same
|
|
14683
|
-
// underlying file at once -- e.g. an old, about-to-close IndexedDB
|
|
14684
|
-
// connection and a newly-opened one during an upgrade. `PRAGMA
|
|
14685
|
-
// busy_timeout` can't safely arbitrate between them here: it blocks the
|
|
14686
|
-
// single JS thread synchronously while it retries, but the lock holder's
|
|
14687
|
-
// own release is itself scheduled via `setImmediate` below, which can
|
|
14688
|
-
// never fire while that retry loop is blocking the same thread -- so
|
|
14689
|
-
// instead of waiting, a second connection's write just fails with
|
|
14690
|
-
// "database is locked".
|
|
14691
|
-
//
|
|
14692
|
-
// `fileReaders`/`fileWriter` implement a simple (not starvation-proof --
|
|
14693
|
-
// see the release loop below) reader/writer lock per file path instead:
|
|
14694
|
-
// any number of `readonly` transactions may hold the file concurrently,
|
|
14695
|
-
// matching what SQLite itself already natively supports (multiple
|
|
14696
|
-
// readers never need to exclude each other, only a writer needs
|
|
14697
|
-
// exclusivity), while a non-`readonly` transaction still waits for
|
|
14698
|
-
// exclusive access -- no concurrent readers, no concurrent writer. A
|
|
14699
|
-
// simple single-owner mutex (this file's prior implementation) would
|
|
14700
|
-
// otherwise serialize even purely-concurrent-reader scenarios that
|
|
14701
|
-
// never touch a writer at all, for no reason `better-sqlite3`/SQLite
|
|
14702
|
-
// itself requires.
|
|
14703
|
-
/** @type {Map<string, Set<{_db: any, _qFilePath: string}>>} */
|
|
14704
|
-
const fileReaders = new Map();
|
|
14705
|
-
/** @type {Map<string, {_db: any, _qFilePath: string}>} */
|
|
14706
|
-
const fileWriter = new Map();
|
|
14707
|
-
/** @type {Map<string, {isReader: boolean, resume: () => void}[]>} */
|
|
14708
|
-
const fileWaiters = new Map();
|
|
14709
|
-
const beginRe = /^\s*BEGIN\b/iu;
|
|
14710
|
-
const endRe = /^\s*(END|COMMIT|ROLLBACK)\b/iu;
|
|
14711
|
-
|
|
14712
|
-
/**
|
|
14713
|
-
* @class
|
|
14714
|
-
* @param {string} name
|
|
14715
|
-
* @param {{busyTimeout?: number, trace?: (sql: string) => void, profile?: SQLProfileCallback}} [opts]
|
|
14716
|
-
* @this {{_db: any, _qFilePath: string}}
|
|
14717
|
-
* @returns {void}
|
|
14718
|
-
*/
|
|
14719
|
-
function SQLiteDatabase(name, opts = {}) {
|
|
14720
|
-
this._qFilePath = name;
|
|
14721
|
-
/** @type {import('better-sqlite3').Database} */
|
|
14722
|
-
const db = new Database(name);
|
|
14723
|
-
|
|
14724
|
-
/** @type {SQLTraceCallback} */
|
|
14725
|
-
// eslint-disable-next-line prefer-destructuring -- TS
|
|
14726
|
-
let trace = opts.trace;
|
|
14727
|
-
/** @type {SQLProfileCallback|undefined} */
|
|
14728
|
-
// eslint-disable-next-line prefer-destructuring -- TS
|
|
14729
|
-
let profile = opts.profile;
|
|
14730
|
-
if (opts.busyTimeout) {
|
|
14731
|
-
db.pragma('busy_timeout = ' + Number(opts.busyTimeout));
|
|
14732
|
-
}
|
|
14733
|
-
|
|
14734
|
-
// Kept untyped (rather than the better-sqlite3 `Database` type) since that
|
|
14735
|
-
// type is internal to `@types/better-sqlite3` and can't be named in this
|
|
14736
|
-
// file's emitted declaration.
|
|
14737
|
-
this._db = /** @type {any} */{
|
|
14738
|
-
_db: db,
|
|
14739
|
-
/**
|
|
14740
|
-
* Compatibility with node-sqlite3's configure API.
|
|
14741
|
-
* @param {'busyTimeout'|'trace'|'profile'|'memoryQuota'} option
|
|
14742
|
-
* @param {number|((sql: string, duration?: number) => void)} value
|
|
14743
|
-
* @returns {void}
|
|
14744
|
-
*/
|
|
14745
|
-
configure(option, value) {
|
|
14746
|
-
if (option === 'busyTimeout') {
|
|
14747
|
-
db.pragma('busy_timeout = ' + Number(/** @type {number} */value));
|
|
14748
|
-
return;
|
|
14749
|
-
}
|
|
14750
|
-
if (option === 'trace') {
|
|
14751
|
-
trace = /** @type {(sql: string) => void} */value;
|
|
14752
|
-
return;
|
|
14753
|
-
}
|
|
14754
|
-
if (option === 'profile') {
|
|
14755
|
-
profile = /** @type {SQLProfileCallback} */value;
|
|
14756
|
-
return;
|
|
14757
|
-
}
|
|
14758
|
-
if (option === 'memoryQuota') {
|
|
14759
|
-
const bytes = Number(value);
|
|
14760
|
-
// `better-sqlite3` doesn't have a direct `sqlite3_quota_set` binding,
|
|
14761
|
-
// but we can limit the max pages:
|
|
14762
|
-
const pageSizeObj = db.pragma('page_size', {
|
|
14763
|
-
simple: true
|
|
14764
|
-
});
|
|
14765
|
-
const pageSize = Number(pageSizeObj);
|
|
14766
|
-
db.pragma('max_page_count = ' + Math.ceil(bytes / pageSize));
|
|
14767
|
-
}
|
|
14768
|
-
},
|
|
14769
|
-
/**
|
|
14770
|
-
* Compatibility with callback-oriented close semantics.
|
|
14771
|
-
* @param {(err?: Error|null) => void} [cb]
|
|
14772
|
-
* @returns {void}
|
|
14773
|
-
*/
|
|
14774
|
-
close(cb) {
|
|
14775
|
-
try {
|
|
14776
|
-
db.close();
|
|
14777
|
-
if (cb) {
|
|
14778
|
-
return cb(null);
|
|
14779
|
-
}
|
|
14780
|
-
} catch (err) {
|
|
14781
|
-
if (cb) {
|
|
14782
|
-
return cb(/** @type {Error} */err);
|
|
14783
|
-
}
|
|
14784
|
-
}
|
|
14785
|
-
return undefined;
|
|
14786
|
-
},
|
|
14787
|
-
getTrace() {
|
|
14788
|
-
return trace;
|
|
14789
|
-
},
|
|
14790
|
-
getProfile() {
|
|
14791
|
-
return profile;
|
|
14792
|
-
}
|
|
14793
|
-
};
|
|
14794
|
-
}
|
|
14795
|
-
|
|
14796
|
-
/**
|
|
14797
|
-
* @param {import('better-sqlite3').Database} db
|
|
14798
|
-
* @param {string} sql
|
|
14799
|
-
* @param {unknown[]} args
|
|
14800
|
-
* @returns {object[]}
|
|
14801
|
-
*/
|
|
14802
|
-
function runSelect(db, sql, args) {
|
|
14803
|
-
const stmt = db.prepare(sql);
|
|
14804
|
-
return stmt.reader ? (/** @type {object[]} */stmt.all(...args)) : [];
|
|
14805
|
-
}
|
|
14806
|
-
|
|
14807
|
-
/**
|
|
14808
|
-
* @param {import('better-sqlite3').Database} db
|
|
14809
|
-
* @param {string} sql
|
|
14810
|
-
* @param {unknown[]} args
|
|
14811
|
-
* @returns {import('better-sqlite3').RunResult}
|
|
14812
|
-
*/
|
|
14813
|
-
function runNonSelect(db, sql, args) {
|
|
14814
|
-
const stmt = db.prepare(sql);
|
|
14815
|
-
return stmt.run(...args);
|
|
14816
|
-
}
|
|
14817
|
-
|
|
14818
|
-
/**
|
|
14819
|
-
* @param {{sql: string, args: unknown[]}[]} queries
|
|
14820
|
-
* @param {boolean} readOnly
|
|
14821
|
-
* @param {(err: Error|null, results?: SQLiteResult[]) => void} callback
|
|
14822
|
-
* @returns {void}
|
|
14823
|
-
*/
|
|
14824
|
-
SQLiteDatabase.prototype.exec = function exec(queries, readOnly, callback) {
|
|
14825
|
-
// `:memory:` (SQLite/`better-sqlite3`'s own sentinel for an isolated,
|
|
14826
|
-
// non-shared in-memory database) can never actually collide with a
|
|
14827
|
-
// different connection -- each `new Database(':memory:')` call is
|
|
14828
|
-
// already fully independent -- so there is nothing to serialize.
|
|
14829
|
-
const filePath = this._qFilePath === ':memory:' ? null : this._qFilePath;
|
|
14830
|
-
if (filePath && queries[0] && beginRe.test(queries[0].sql)) {
|
|
14831
|
-
const activeReaders = fileReaders.get(filePath);
|
|
14832
|
-
const hasActiveReaders = Boolean(activeReaders && activeReaders.size);
|
|
14833
|
-
const activeWriter = fileWriter.get(filePath);
|
|
14834
|
-
const blockedByWriter = Boolean(activeWriter && activeWriter !== this);
|
|
14835
|
-
const blocked = blockedByWriter || !readOnly && hasActiveReaders;
|
|
14836
|
-
if (blocked) {
|
|
14837
|
-
const waiters = fileWaiters.get(filePath) || [];
|
|
14838
|
-
waiters.push({
|
|
14839
|
-
isReader: readOnly,
|
|
14840
|
-
resume: () => this.exec(queries, readOnly, callback)
|
|
14841
|
-
});
|
|
14842
|
-
fileWaiters.set(filePath, waiters);
|
|
14843
|
-
return;
|
|
14844
|
-
}
|
|
14845
|
-
if (readOnly) {
|
|
14846
|
-
if (activeReaders) {
|
|
14847
|
-
activeReaders.add(this);
|
|
14848
|
-
} else {
|
|
14849
|
-
fileReaders.set(filePath, new Set([this]));
|
|
14850
|
-
}
|
|
14851
|
-
} else {
|
|
14852
|
-
fileWriter.set(filePath, this);
|
|
14853
|
-
}
|
|
14854
|
-
}
|
|
14855
|
-
const db = this._db._db;
|
|
14856
|
-
const len = queries.length;
|
|
14857
|
-
const results = Array.from({
|
|
14858
|
-
length: len
|
|
14859
|
-
});
|
|
14860
|
-
for (let i = 0; i < len; i++) {
|
|
14861
|
-
const query = queries[i];
|
|
14862
|
-
const {
|
|
14863
|
-
sql,
|
|
14864
|
-
args
|
|
14865
|
-
} = query;
|
|
14866
|
-
const isSelect = /^\s*SELECT\b/iu.test(sql);
|
|
14867
|
-
if (readOnly && !isSelect) {
|
|
14868
|
-
results[i] = new SQLiteResult(READ_ONLY_ERROR);
|
|
14869
|
-
continue;
|
|
14870
|
-
}
|
|
14871
|
-
const trace = this._db.getTrace();
|
|
14872
|
-
const profile = this._db.getProfile();
|
|
14873
|
-
// eslint-disable-next-line unicorn/prefer-bigint-literals -- `0n` needs ES2020+ target for tsc
|
|
14874
|
-
const start = profile ? process.hrtime.bigint() : BigInt(0);
|
|
14875
|
-
try {
|
|
14876
|
-
if (trace) {
|
|
14877
|
-
trace(sql);
|
|
14878
|
-
}
|
|
14879
|
-
if (isSelect) {
|
|
14880
|
-
const rows = runSelect(db, sql, args);
|
|
14881
|
-
results[i] = new SQLiteResult(null, undefined, 0, rows);
|
|
14882
|
-
} else {
|
|
14883
|
-
const executionResult = runNonSelect(db, sql, args);
|
|
14884
|
-
const insertId = Number(executionResult.lastInsertRowid);
|
|
14885
|
-
results[i] = new SQLiteResult(null, insertId, executionResult.changes, []);
|
|
14886
|
-
}
|
|
14887
|
-
} catch (err) {
|
|
14888
|
-
results[i] = new SQLiteResult(/** @type {Error} */err);
|
|
14889
|
-
} finally {
|
|
14890
|
-
if (profile) {
|
|
14891
|
-
profile(sql, Number(process.hrtime.bigint() - start));
|
|
14892
|
-
}
|
|
14893
|
-
}
|
|
14894
|
-
}
|
|
14895
|
-
// A real macrotask (not `queueMicrotask`) so this yields properly:
|
|
14896
|
-
// code that synchronously issues a new request from within each
|
|
14897
|
-
// request's callback (e.g. to keep a transaction alive) would
|
|
14898
|
-
// otherwise chain microtask to microtask forever, starving out any
|
|
14899
|
-
// `setTimeout`-based code (including IndexedDB's own internal request
|
|
14900
|
-
// scheduling) that never gets a turn to run. `setImmediate` (Node's
|
|
14901
|
-
// "check" phase) still yields the same way `setTimeout(..., 0)` did,
|
|
14902
|
-
// but runs sooner in Node's event loop.
|
|
14903
|
-
setImmediate(() => {
|
|
14904
|
-
// Release the file lock (if held) and hand it to the next waiting
|
|
14905
|
-
// connection, if any, only once this transaction has genuinely
|
|
14906
|
-
// finished -- and only here, on its own turn, so a resumed
|
|
14907
|
-
// waiter's own `exec` call can't run reentrantly inside this one.
|
|
14908
|
-
// Checked across the whole batch, not just `queries[0]`: when a
|
|
14909
|
-
// transaction's `BEGIN` and its later `ROLLBACK`/`COMMIT` are both
|
|
14910
|
-
// queued synchronously before `websql-configurable`'s async flush
|
|
14911
|
-
// gets a turn to run (e.g. an immediate `transaction.abort()`
|
|
14912
|
-
// inside `onupgradeneeded`), they arrive coalesced into a single
|
|
14913
|
-
// batch/`exec()` call, with the terminal statement anywhere but
|
|
14914
|
-
// first -- so only checking `queries[0]` would acquire the lock
|
|
14915
|
-
// and never see the matching release, deadlocking every later
|
|
14916
|
-
// connection to the same file.
|
|
14917
|
-
if (filePath && queries.some(q => endRe.test(q.sql))) {
|
|
14918
|
-
const activeReaders = fileReaders.get(filePath);
|
|
14919
|
-
if (activeReaders) {
|
|
14920
|
-
activeReaders.delete(this);
|
|
14921
|
-
if (!activeReaders.size) {
|
|
14922
|
-
fileReaders.delete(filePath);
|
|
14923
|
-
}
|
|
14924
|
-
}
|
|
14925
|
-
if (fileWriter.get(filePath) === this) {
|
|
14926
|
-
fileWriter.delete(filePath);
|
|
14927
|
-
}
|
|
14928
|
-
// Resume as many waiters as the lock now genuinely allows:
|
|
14929
|
-
// any leading run of readers (concurrent reads are always
|
|
14930
|
-
// fine), then at most one writer, since a writer needs
|
|
14931
|
-
// exclusivity -- stop there rather than looking past it.
|
|
14932
|
-
// Not starvation-proof: a steady stream of arriving readers
|
|
14933
|
-
// could in principle keep a waiting writer waiting
|
|
14934
|
-
// indefinitely, but that's an acceptable tradeoff here over
|
|
14935
|
-
// the added complexity of tracking arrival order across
|
|
14936
|
-
// reader/writer kinds.
|
|
14937
|
-
const waiters = fileWaiters.get(filePath);
|
|
14938
|
-
if (waiters) {
|
|
14939
|
-
while (waiters.length) {
|
|
14940
|
-
if (fileWriter.has(filePath)) {
|
|
14941
|
-
break;
|
|
14942
|
-
}
|
|
14943
|
-
const next = waiters[0];
|
|
14944
|
-
const stillHasReaders = fileReaders.get(filePath);
|
|
14945
|
-
if (!next.isReader && stillHasReaders && stillHasReaders.size) {
|
|
14946
|
-
break;
|
|
14947
|
-
}
|
|
14948
|
-
waiters.shift();
|
|
14949
|
-
next.resume();
|
|
14950
|
-
if (!next.isReader) {
|
|
14951
|
-
// A writer just took exclusive ownership (inside
|
|
14952
|
-
// `resume()`, synchronously, via the acquire
|
|
14953
|
-
// logic above) -- nothing else may proceed now.
|
|
14954
|
-
break;
|
|
14955
|
-
}
|
|
14956
|
-
}
|
|
14957
|
-
if (!waiters.length) {
|
|
14958
|
-
fileWaiters.delete(filePath);
|
|
14959
|
-
}
|
|
14960
|
-
}
|
|
14961
|
-
}
|
|
14962
|
-
callback(null, results);
|
|
14963
|
-
});
|
|
14964
|
-
};
|
|
14965
|
-
|
|
14966
12985
|
/**
|
|
14967
12986
|
* @typedef {{
|
|
14968
12987
|
* _db: any,
|
|
@@ -14990,16 +13009,16 @@ function wrappedSQLiteDatabase(name) {
|
|
|
14990
13009
|
// @ts-ignore It's ok; needed under some TS versions
|
|
14991
13010
|
const db = new SQLiteDatabase(name, {});
|
|
14992
13011
|
if (CFG.sqlBusyTimeout) {
|
|
14993
|
-
db.
|
|
13012
|
+
db.configure('busyTimeout', /** @type {number} */CFG.sqlBusyTimeout); // Default is 1000
|
|
14994
13013
|
}
|
|
14995
13014
|
if (CFG.sqlTrace) {
|
|
14996
|
-
db.
|
|
13015
|
+
db.configure('trace', CFG.sqlTrace);
|
|
14997
13016
|
}
|
|
14998
13017
|
if (CFG.sqlProfile) {
|
|
14999
|
-
db.
|
|
13018
|
+
db.configure('profile', CFG.sqlProfile);
|
|
15000
13019
|
}
|
|
15001
13020
|
if (CFG.sqlMemoryQuota) {
|
|
15002
|
-
db.
|
|
13021
|
+
db.configure('memoryQuota', /** @type {number} */CFG.sqlMemoryQuota);
|
|
15003
13022
|
}
|
|
15004
13023
|
return db;
|
|
15005
13024
|
}
|