indexeddbshim 11.0.0 → 12.0.0-pre.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/badges/licenses-badge.svg +1 -1
- package/dist/CFG.d.ts +80 -0
- package/dist/CFG.d.ts.map +1 -0
- package/dist/DOMException.d.ts +71 -0
- package/dist/DOMException.d.ts.map +1 -0
- package/dist/DOMStringList.d.ts +20 -0
- package/dist/DOMStringList.d.ts.map +1 -0
- package/dist/Event.d.ts +21 -0
- package/dist/Event.d.ts.map +1 -0
- package/dist/IDBCursor.d.ts +289 -0
- package/dist/IDBCursor.d.ts.map +1 -0
- package/dist/IDBDatabase.d.ts +144 -0
- package/dist/IDBDatabase.d.ts.map +1 -0
- package/dist/IDBFactory.d.ts +96 -0
- package/dist/IDBFactory.d.ts.map +1 -0
- package/dist/IDBIndex.d.ts +243 -0
- package/dist/IDBIndex.d.ts.map +1 -0
- package/dist/IDBKeyRange.d.ts +79 -0
- package/dist/IDBKeyRange.d.ts.map +1 -0
- package/dist/IDBObjectStore.d.ts +273 -0
- package/dist/IDBObjectStore.d.ts.map +1 -0
- package/dist/IDBRequest.d.ts +90 -0
- package/dist/IDBRequest.d.ts.map +1 -0
- package/dist/IDBTransaction.d.ts +271 -0
- package/dist/IDBTransaction.d.ts.map +1 -0
- package/dist/IDBVersionChangeEvent.d.ts +23 -0
- package/dist/IDBVersionChangeEvent.d.ts.map +1 -0
- package/dist/Key.d.ts +214 -0
- package/dist/Key.d.ts.map +1 -0
- package/dist/Sca.d.ts +31 -0
- package/dist/Sca.d.ts.map +1 -0
- package/dist/UnicodeIdentifiers.d.ts +3 -0
- package/dist/UnicodeIdentifiers.d.ts.map +1 -0
- package/dist/browser-UnicodeIdentifiers.d.ts +2 -0
- package/dist/browser-UnicodeIdentifiers.d.ts.map +1 -0
- package/dist/browser-noninvasive.d.ts +3 -0
- package/dist/browser-noninvasive.d.ts.map +1 -0
- package/dist/browser.d.ts +2 -0
- package/dist/browser.d.ts.map +1 -0
- package/dist/cmp.d.ts +9 -0
- package/dist/cmp.d.ts.map +1 -0
- package/dist/indexeddbshim-Key.js +491 -189
- package/dist/indexeddbshim-Key.js.map +1 -1
- package/dist/indexeddbshim-Key.min.js +2 -2
- package/dist/indexeddbshim-Key.min.js.map +1 -1
- package/dist/indexeddbshim-UnicodeIdentifiers-node.cjs +17263 -1396
- package/dist/indexeddbshim-UnicodeIdentifiers-node.cjs.map +1 -1
- package/dist/indexeddbshim-UnicodeIdentifiers.js +3892 -1271
- package/dist/indexeddbshim-UnicodeIdentifiers.js.map +1 -1
- package/dist/indexeddbshim-UnicodeIdentifiers.min.js +2 -2
- package/dist/indexeddbshim-UnicodeIdentifiers.min.js.map +1 -1
- package/dist/indexeddbshim-node.cjs +17259 -1396
- package/dist/indexeddbshim-node.cjs.map +1 -1
- package/dist/indexeddbshim-noninvasive.js +3887 -1271
- package/dist/indexeddbshim-noninvasive.js.map +1 -1
- package/dist/indexeddbshim-noninvasive.min.js +2 -2
- package/dist/indexeddbshim-noninvasive.min.js.map +1 -1
- package/dist/indexeddbshim.js +3887 -1271
- package/dist/indexeddbshim.js.map +1 -1
- package/dist/indexeddbshim.min.js +2 -2
- package/dist/indexeddbshim.min.js.map +1 -1
- package/dist/node-UnicodeIdentifiers.d.ts +8 -0
- package/dist/node-UnicodeIdentifiers.d.ts.map +1 -0
- package/dist/node.d.ts +8 -0
- package/dist/node.d.ts.map +1 -0
- package/dist/nodeWebSQL.d.ts +3 -0
- package/dist/nodeWebSQL.d.ts.map +1 -0
- package/dist/setGlobalVars.d.ts +79 -0
- package/dist/setGlobalVars.d.ts.map +1 -0
- package/dist/unicode-regex.d.ts +3 -0
- package/dist/unicode-regex.d.ts.map +1 -0
- package/dist/util.d.ts +174 -0
- package/dist/util.d.ts.map +1 -0
- package/package.json +40 -27
- package/src/CFG.js +89 -11
- package/src/DOMException.js +116 -29
- package/src/DOMStringList.js +92 -2
- package/src/Event.js +19 -4
- package/src/IDBCursor.js +339 -67
- package/src/IDBDatabase.js +87 -10
- package/src/IDBFactory.js +319 -56
- package/src/IDBIndex.js +385 -96
- package/src/IDBKeyRange.js +86 -13
- package/src/IDBObjectStore.js +326 -68
- package/src/IDBRequest.js +59 -1
- package/src/IDBTransaction.js +247 -38
- package/src/IDBVersionChangeEvent.js +28 -3
- package/src/Key.js +273 -156
- package/src/Sca.js +29 -4
- package/src/browser-UnicodeIdentifiers.js +5 -1
- package/src/cmp.js +5 -5
- package/src/node-UnicodeIdentifiers.js +9 -0
- package/src/node.js +5 -0
- package/src/nodeWebSQL.js +11 -5
- package/src/setGlobalVars.js +156 -21
- package/src/unicode-regex.js +9 -1
- package/src/util.js +228 -40
- package/typings/shimIndexedDB.d.ts +9 -0
package/src/IDBIndex.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import SyncPromise from 'sync-promise';
|
|
1
|
+
import SyncPromise from 'sync-promise-expanded';
|
|
2
2
|
import {createDOMException} from './DOMException.js';
|
|
3
3
|
import {IDBCursor, IDBCursorWithValue} from './IDBCursor.js';
|
|
4
4
|
import * as util from './util.js';
|
|
@@ -11,22 +11,70 @@ import IDBObjectStore from './IDBObjectStore.js';
|
|
|
11
11
|
|
|
12
12
|
const readonlyProperties = ['objectStore', 'keyPath', 'multiEntry', 'unique'];
|
|
13
13
|
|
|
14
|
-
|
|
14
|
+
/**
|
|
15
|
+
* @typedef {number} Integer
|
|
16
|
+
*/
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* @typedef {{
|
|
20
|
+
* columnName: string,
|
|
21
|
+
* keyPath: import('./Key.js').KeyPath,
|
|
22
|
+
* optionalParams: {
|
|
23
|
+
* unique: boolean,
|
|
24
|
+
* multiEntry: boolean
|
|
25
|
+
* }
|
|
26
|
+
* deleted?: boolean,
|
|
27
|
+
* __deleted?: boolean,
|
|
28
|
+
* cursors?: import('./IDBCursor.js').IDBCursorWithValueFull[],
|
|
29
|
+
* }} IDBIndexProperties
|
|
30
|
+
*/
|
|
31
|
+
|
|
15
32
|
/**
|
|
16
33
|
* IDB Index.
|
|
17
34
|
* @see http://www.w3.org/TR/IndexedDB/#idl-def-IDBIndex
|
|
18
|
-
* @param {IDBObjectStore} store
|
|
19
|
-
* @param {IDBIndexProperties} indexProperties
|
|
20
35
|
* @class
|
|
21
36
|
*/
|
|
22
37
|
function IDBIndex () {
|
|
23
|
-
/* eslint-enable jsdoc/check-param-names */
|
|
24
38
|
throw new TypeError('Illegal constructor');
|
|
25
39
|
}
|
|
26
40
|
const IDBIndexAlias = IDBIndex;
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* @typedef {IDBIndex & {
|
|
44
|
+
* name: string,
|
|
45
|
+
* keyPath: import('./Key.js').KeyPath,
|
|
46
|
+
* multiEntry: boolean,
|
|
47
|
+
* unique: boolean,
|
|
48
|
+
* objectStore: import('./IDBObjectStore.js').IDBObjectStoreFull,
|
|
49
|
+
* __pendingCreate?: boolean,
|
|
50
|
+
* __deleted?: boolean,
|
|
51
|
+
* __originalName: string,
|
|
52
|
+
* __currentName: string,
|
|
53
|
+
* __pendingName?: string,
|
|
54
|
+
* __pendingDelete?: boolean,
|
|
55
|
+
* __name: string,
|
|
56
|
+
* __multiEntry: boolean,
|
|
57
|
+
* __unique: boolean,
|
|
58
|
+
* __objectStore: import('./IDBObjectStore.js').IDBObjectStoreFull,
|
|
59
|
+
* __keyPath: import('./Key.js').KeyPath,
|
|
60
|
+
* __recreated?: boolean
|
|
61
|
+
* }} IDBIndexFull
|
|
62
|
+
*/
|
|
63
|
+
|
|
64
|
+
/**
|
|
65
|
+
*
|
|
66
|
+
* @param {import('./IDBObjectStore.js').IDBObjectStoreFull} store
|
|
67
|
+
* @param {IDBIndexProperties} indexProperties
|
|
68
|
+
* @returns {IDBIndexFull}
|
|
69
|
+
*/
|
|
27
70
|
IDBIndex.__createInstance = function (store, indexProperties) {
|
|
71
|
+
/**
|
|
72
|
+
* @class
|
|
73
|
+
* @this {IDBIndexFull}
|
|
74
|
+
*/
|
|
28
75
|
function IDBIndex () {
|
|
29
76
|
const me = this;
|
|
77
|
+
// @ts-expect-error It's ok
|
|
30
78
|
me[Symbol.toStringTag] = 'IDBIndex';
|
|
31
79
|
util.defineReadonlyProperties(me, readonlyProperties);
|
|
32
80
|
me.__objectStore = store;
|
|
@@ -38,16 +86,31 @@ IDBIndex.__createInstance = function (store, indexProperties) {
|
|
|
38
86
|
me.__deleted = Boolean(indexProperties.__deleted);
|
|
39
87
|
me.__objectStore.__cursors = indexProperties.cursors || [];
|
|
40
88
|
Object.defineProperty(me, '__currentName', {
|
|
89
|
+
/**
|
|
90
|
+
* @this {IDBIndexFull}
|
|
91
|
+
* @returns {string}
|
|
92
|
+
*/
|
|
41
93
|
get () {
|
|
42
|
-
return '__pendingName' in me
|
|
94
|
+
return '__pendingName' in me
|
|
95
|
+
? /** @type {string} */ (me.__pendingName)
|
|
96
|
+
: me.name;
|
|
43
97
|
}
|
|
44
98
|
});
|
|
45
99
|
Object.defineProperty(me, 'name', {
|
|
46
100
|
enumerable: false,
|
|
47
101
|
configurable: false,
|
|
102
|
+
/**
|
|
103
|
+
* @this {IDBIndexFull}
|
|
104
|
+
* @returns {string}
|
|
105
|
+
*/
|
|
48
106
|
get () {
|
|
49
107
|
return this.__name;
|
|
50
108
|
},
|
|
109
|
+
/**
|
|
110
|
+
* @param {string} newName
|
|
111
|
+
* @this {IDBIndexFull}
|
|
112
|
+
* @returns {void}
|
|
113
|
+
*/
|
|
51
114
|
set (newName) {
|
|
52
115
|
const me = this;
|
|
53
116
|
newName = util.convertToDOMString(newName);
|
|
@@ -72,7 +135,9 @@ IDBIndex.__createInstance = function (store, indexProperties) {
|
|
|
72
135
|
objectStore.__indexes[newName] = me;
|
|
73
136
|
objectStore.indexNames.splice(objectStore.indexNames.indexOf(oldName), 1, newName);
|
|
74
137
|
|
|
75
|
-
const storeHandle =
|
|
138
|
+
const storeHandle = /** @type {import('./IDBTransaction.js').IDBTransactionFull} */ (
|
|
139
|
+
objectStore.transaction
|
|
140
|
+
).__storeHandles[objectStore.name];
|
|
76
141
|
const oldIndexHandle = storeHandle.__indexHandles[oldName];
|
|
77
142
|
oldIndexHandle.__name = newName; // Fix old references
|
|
78
143
|
storeHandle.__indexHandles[newName] = oldIndexHandle; // Ensure new reference accessible
|
|
@@ -82,24 +147,37 @@ IDBIndex.__createInstance = function (store, indexProperties) {
|
|
|
82
147
|
['key', 'BLOB ' + (objectStore.autoIncrement ? 'UNIQUE, inc INTEGER PRIMARY KEY AUTOINCREMENT' : 'PRIMARY KEY')],
|
|
83
148
|
['value', 'BLOB']
|
|
84
149
|
].concat(
|
|
150
|
+
// @ts-expect-error Has numeric indexes instead of iterator
|
|
85
151
|
[...objectStore.indexNames]
|
|
86
152
|
.filter((indexName) => indexName !== newName)
|
|
87
153
|
.map((indexName) => [util.escapeIndexNameForSQL(indexName), 'BLOB'])
|
|
88
154
|
);
|
|
89
155
|
|
|
90
|
-
me.__renameIndex(
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
156
|
+
me.__renameIndex(
|
|
157
|
+
objectStore, oldName, newName, colInfoToPreserveArr,
|
|
158
|
+
function (tx, success) {
|
|
159
|
+
IDBIndexAlias.__updateIndexList(store, tx, function (store) {
|
|
160
|
+
delete storeHandle.__pendingName;
|
|
161
|
+
success(store);
|
|
162
|
+
});
|
|
163
|
+
}
|
|
164
|
+
);
|
|
96
165
|
}
|
|
97
166
|
});
|
|
98
167
|
}
|
|
99
168
|
IDBIndex.prototype = IDBIndexAlias.prototype;
|
|
169
|
+
|
|
170
|
+
// @ts-expect-error It's ok
|
|
100
171
|
return new IDBIndex();
|
|
101
172
|
};
|
|
102
173
|
|
|
174
|
+
/**
|
|
175
|
+
*
|
|
176
|
+
* @param {IDBIndexFull} index
|
|
177
|
+
* @param {string} [msg]
|
|
178
|
+
* @throws {DOMException}
|
|
179
|
+
* @returns {void}
|
|
180
|
+
*/
|
|
103
181
|
IDBIndex.__invalidStateIfDeleted = function (index, msg) {
|
|
104
182
|
if (index.__deleted || index.__pendingDelete || (
|
|
105
183
|
index.__pendingCreate && index.objectStore.transaction && index.objectStore.transaction.__errored
|
|
@@ -110,10 +188,9 @@ IDBIndex.__invalidStateIfDeleted = function (index, msg) {
|
|
|
110
188
|
|
|
111
189
|
/**
|
|
112
190
|
* Clones an IDBIndex instance for a different IDBObjectStore instance.
|
|
113
|
-
* @param {
|
|
114
|
-
* @param {IDBObjectStore} store
|
|
115
|
-
* @
|
|
116
|
-
* @returns {IDBIndex}
|
|
191
|
+
* @param {IDBIndexFull} index
|
|
192
|
+
* @param {import('./IDBObjectStore.js').IDBObjectStoreFull} store
|
|
193
|
+
* @returns {IDBIndexFull}
|
|
117
194
|
*/
|
|
118
195
|
IDBIndex.__clone = function (index, store) {
|
|
119
196
|
const idx = IDBIndex.__createInstance(store, {
|
|
@@ -124,7 +201,11 @@ IDBIndex.__clone = function (index, store) {
|
|
|
124
201
|
unique: index.unique
|
|
125
202
|
}
|
|
126
203
|
});
|
|
127
|
-
|
|
204
|
+
/** @type {const} */ ([
|
|
205
|
+
'__pendingCreate', '__pendingDelete', '__deleted',
|
|
206
|
+
'__originalName', '__recreated'
|
|
207
|
+
]).forEach((p) => {
|
|
208
|
+
// @ts-expect-error Why is this type "never"?
|
|
128
209
|
idx[p] = index[p];
|
|
129
210
|
});
|
|
130
211
|
return idx;
|
|
@@ -132,10 +213,9 @@ IDBIndex.__clone = function (index, store) {
|
|
|
132
213
|
|
|
133
214
|
/**
|
|
134
215
|
* Creates a new index on an object store.
|
|
135
|
-
* @param {IDBObjectStore} store
|
|
136
|
-
* @param {
|
|
216
|
+
* @param {import('./IDBObjectStore.js').IDBObjectStoreFull} store
|
|
217
|
+
* @param {IDBIndexFull} index
|
|
137
218
|
* @returns {void}
|
|
138
|
-
* @protected
|
|
139
219
|
*/
|
|
140
220
|
IDBIndex.__createIndex = function (store, index) {
|
|
141
221
|
const indexName = index.name;
|
|
@@ -160,14 +240,27 @@ IDBIndex.__createIndex = function (store, index) {
|
|
|
160
240
|
|
|
161
241
|
// Create the index in WebSQL
|
|
162
242
|
const {transaction} = store;
|
|
163
|
-
|
|
243
|
+
/** @type {import('./IDBTransaction.js').IDBTransactionFull} */ (
|
|
244
|
+
transaction
|
|
245
|
+
).__addNonRequestToTransactionQueue(function createIndex (tx, args, success, failure) {
|
|
164
246
|
const columnExists = idx && (idx.__deleted || idx.__recreated); // This check must occur here rather than earlier as properties may not have been set yet otherwise
|
|
247
|
+
|
|
248
|
+
/** @type {{[key: string]: boolean}} */
|
|
165
249
|
let indexValues = {};
|
|
166
250
|
|
|
251
|
+
/**
|
|
252
|
+
* @param {SQLTransaction} tx
|
|
253
|
+
* @param {SQLError} err
|
|
254
|
+
* @returns {void}
|
|
255
|
+
*/
|
|
167
256
|
function error (tx, err) {
|
|
168
257
|
failure(createDOMException('UnknownError', 'Could not create index "' + indexName + '"' + err.code + '::' + err.message, err));
|
|
169
258
|
}
|
|
170
259
|
|
|
260
|
+
/**
|
|
261
|
+
* @param {SQLTransaction} tx
|
|
262
|
+
* @returns {void}
|
|
263
|
+
*/
|
|
171
264
|
function applyIndex (tx) {
|
|
172
265
|
// Update the object store's index list
|
|
173
266
|
IDBIndex.__updateIndexList(store, tx, function () {
|
|
@@ -176,17 +269,26 @@ IDBIndex.__createIndex = function (store, index) {
|
|
|
176
269
|
CFG.DEBUG && console.log('Adding existing ' + storeName + ' records to the ' + indexName + ' index');
|
|
177
270
|
addIndexEntry(0);
|
|
178
271
|
|
|
272
|
+
/**
|
|
273
|
+
* @param {Integer} i
|
|
274
|
+
* @returns {void}
|
|
275
|
+
*/
|
|
179
276
|
function addIndexEntry (i) {
|
|
180
277
|
if (i < data.rows.length) {
|
|
181
278
|
try {
|
|
182
279
|
const value = Sca.decode(util.unescapeSQLiteResponse(data.rows.item(i).value));
|
|
183
|
-
|
|
184
|
-
if (
|
|
280
|
+
const indexKey = Key.extractKeyValueDecodedFromValueUsingKeyPath(value, index.keyPath, index.multiEntry); // Todo: Do we need this stricter error checking?
|
|
281
|
+
if (
|
|
282
|
+
('invalid' in indexKey && indexKey.invalid) ||
|
|
283
|
+
('failure' in indexKey && indexKey.failure)
|
|
284
|
+
) { // Todo: Do we need invalid checks and should we instead treat these as being duplicates?
|
|
185
285
|
throw new Error('Go to catch; ignore bad indexKey');
|
|
186
286
|
}
|
|
187
|
-
|
|
287
|
+
const indexKeyStr = /** @type {string} */ (
|
|
288
|
+
Key.encode(indexKey.value, index.multiEntry)
|
|
289
|
+
);
|
|
188
290
|
if (index.unique) {
|
|
189
|
-
if (indexValues[
|
|
291
|
+
if (indexValues[indexKeyStr]) {
|
|
190
292
|
indexValues = {};
|
|
191
293
|
failure(createDOMException(
|
|
192
294
|
'ConstraintError',
|
|
@@ -194,16 +296,17 @@ IDBIndex.__createIndex = function (store, index) {
|
|
|
194
296
|
));
|
|
195
297
|
return;
|
|
196
298
|
}
|
|
197
|
-
indexValues[
|
|
299
|
+
indexValues[indexKeyStr] = true;
|
|
198
300
|
}
|
|
199
301
|
|
|
200
302
|
tx.executeSql(
|
|
201
303
|
'UPDATE ' + util.escapeStoreNameForSQL(storeName) + ' SET ' +
|
|
202
304
|
util.escapeIndexNameForSQL(indexName) + ' = ? WHERE "key" = ?',
|
|
203
|
-
[util.escapeSQLiteStatement(
|
|
305
|
+
[util.escapeSQLiteStatement(indexKeyStr), data.rows.item(i).key],
|
|
204
306
|
function (tx, data) {
|
|
205
307
|
addIndexEntry(i + 1);
|
|
206
|
-
},
|
|
308
|
+
},
|
|
309
|
+
/** @type {SQLStatementErrorCallback} */ (error)
|
|
207
310
|
);
|
|
208
311
|
} catch (e) {
|
|
209
312
|
// Not a valid value to insert into index, so just continue
|
|
@@ -222,13 +325,17 @@ IDBIndex.__createIndex = function (store, index) {
|
|
|
222
325
|
success(store);
|
|
223
326
|
}
|
|
224
327
|
}
|
|
225
|
-
}, error);
|
|
226
|
-
}, error);
|
|
328
|
+
}, /** @type {SQLStatementErrorCallback} */ (error));
|
|
329
|
+
}, /** @type {SQLStatementErrorCallback} */ (error));
|
|
227
330
|
}
|
|
228
331
|
|
|
229
332
|
const escapedStoreNameSQL = util.escapeStoreNameForSQL(storeName);
|
|
230
333
|
const escapedIndexNameSQL = util.escapeIndexNameForSQL(index.name);
|
|
231
334
|
|
|
335
|
+
/**
|
|
336
|
+
* @param {SQLTransaction} tx
|
|
337
|
+
* @returns {void}
|
|
338
|
+
*/
|
|
232
339
|
function addIndexSQL (tx) {
|
|
233
340
|
if (!CFG.useSQLiteIndexes) {
|
|
234
341
|
applyIndex(tx);
|
|
@@ -244,7 +351,7 @@ IDBIndex.__createIndex = function (store, index) {
|
|
|
244
351
|
'" ON ' + escapedStoreNameSQL + '(' + escapedIndexNameSQL + ')',
|
|
245
352
|
[],
|
|
246
353
|
applyIndex,
|
|
247
|
-
error
|
|
354
|
+
/** @type {SQLStatementErrorCallback} */ (error)
|
|
248
355
|
);
|
|
249
356
|
}
|
|
250
357
|
|
|
@@ -256,16 +363,17 @@ IDBIndex.__createIndex = function (store, index) {
|
|
|
256
363
|
// For a new index, add a new column to the object store, then apply the index
|
|
257
364
|
const sql = ['ALTER TABLE', escapedStoreNameSQL, 'ADD', escapedIndexNameSQL, 'BLOB'].join(' ');
|
|
258
365
|
CFG.DEBUG && console.log(sql);
|
|
259
|
-
tx.executeSql(
|
|
366
|
+
tx.executeSql(
|
|
367
|
+
sql, [], addIndexSQL, /** @type {SQLStatementErrorCallback} */ (error)
|
|
368
|
+
);
|
|
260
369
|
}
|
|
261
|
-
}
|
|
370
|
+
});
|
|
262
371
|
};
|
|
263
372
|
|
|
264
373
|
/**
|
|
265
374
|
* Deletes an index from an object store.
|
|
266
|
-
* @param {IDBObjectStore} store
|
|
267
|
-
* @param {
|
|
268
|
-
* @protected
|
|
375
|
+
* @param {import('./IDBObjectStore.js').IDBObjectStoreFull} store
|
|
376
|
+
* @param {IDBIndexFull} index
|
|
269
377
|
* @returns {void}
|
|
270
378
|
*/
|
|
271
379
|
IDBIndex.__deleteIndex = function (store, index) {
|
|
@@ -280,11 +388,21 @@ IDBIndex.__deleteIndex = function (store, index) {
|
|
|
280
388
|
|
|
281
389
|
// Remove the index in WebSQL
|
|
282
390
|
const {transaction} = store;
|
|
283
|
-
|
|
391
|
+
/** @type {import('./IDBTransaction.js').IDBTransactionFull} */ (
|
|
392
|
+
transaction
|
|
393
|
+
).__addNonRequestToTransactionQueue(function deleteIndex (tx, args, success, failure) {
|
|
394
|
+
/**
|
|
395
|
+
* @param {SQLTransaction} tx
|
|
396
|
+
* @param {SQLError} err
|
|
397
|
+
* @returns {void}
|
|
398
|
+
*/
|
|
284
399
|
function error (tx, err) {
|
|
285
400
|
failure(createDOMException('UnknownError', 'Could not delete index "' + index.name + '"', err));
|
|
286
401
|
}
|
|
287
402
|
|
|
403
|
+
/**
|
|
404
|
+
* @returns {void}
|
|
405
|
+
*/
|
|
288
406
|
function finishDeleteIndex () {
|
|
289
407
|
// Update the object store's index list
|
|
290
408
|
IDBIndex.__updateIndexList(store, tx, function (store) {
|
|
@@ -296,7 +414,7 @@ IDBIndex.__deleteIndex = function (store, index) {
|
|
|
296
414
|
delete indexHandle.__pendingDelete;
|
|
297
415
|
}
|
|
298
416
|
success(store);
|
|
299
|
-
}, error);
|
|
417
|
+
}, /** @type {SQLStatementErrorCallback} */ (error));
|
|
300
418
|
}
|
|
301
419
|
|
|
302
420
|
if (!CFG.useSQLiteIndexes) {
|
|
@@ -311,24 +429,31 @@ IDBIndex.__deleteIndex = function (store, index) {
|
|
|
311
429
|
),
|
|
312
430
|
[],
|
|
313
431
|
finishDeleteIndex,
|
|
314
|
-
error
|
|
432
|
+
/** @type {SQLStatementErrorCallback} */ (error)
|
|
315
433
|
);
|
|
316
|
-
}
|
|
434
|
+
});
|
|
317
435
|
};
|
|
318
436
|
|
|
437
|
+
/**
|
|
438
|
+
* @typedef {{[key: string]: IDBIndexProperties}} IndexList
|
|
439
|
+
*/
|
|
440
|
+
|
|
319
441
|
/**
|
|
320
442
|
* Updates index list for the given object store.
|
|
321
|
-
* @param {IDBObjectStore} store
|
|
322
|
-
* @param {
|
|
323
|
-
* @param {
|
|
324
|
-
* @param {
|
|
443
|
+
* @param {import('./IDBObjectStore.js').IDBObjectStoreFull} store
|
|
444
|
+
* @param {SQLTransaction} tx
|
|
445
|
+
* @param {(store: IDBObjectStore) => void} success
|
|
446
|
+
* @param {(
|
|
447
|
+
* tx: SQLTransaction,
|
|
448
|
+
* err: SQLError
|
|
449
|
+
* ) => boolean} [failure]
|
|
325
450
|
* @returns {void}
|
|
326
451
|
*/
|
|
327
452
|
IDBIndex.__updateIndexList = function (store, tx, success, failure) {
|
|
453
|
+
/** @type {IndexList} **/
|
|
328
454
|
const indexList = {};
|
|
329
455
|
for (let i = 0; i < store.indexNames.length; i++) {
|
|
330
456
|
const idx = store.__indexes[store.indexNames[i]];
|
|
331
|
-
/** @type {IDBIndexProperties} **/
|
|
332
457
|
indexList[idx.name] = {
|
|
333
458
|
columnName: idx.name,
|
|
334
459
|
keyPath: idx.keyPath,
|
|
@@ -336,24 +461,28 @@ IDBIndex.__updateIndexList = function (store, tx, success, failure) {
|
|
|
336
461
|
unique: idx.unique,
|
|
337
462
|
multiEntry: idx.multiEntry
|
|
338
463
|
},
|
|
339
|
-
deleted: Boolean(idx.
|
|
464
|
+
deleted: Boolean(idx.__deleted)
|
|
340
465
|
};
|
|
341
466
|
}
|
|
342
467
|
|
|
343
468
|
CFG.DEBUG && console.log('Updating the index list for ' + store.__currentName, indexList);
|
|
344
469
|
tx.executeSql('UPDATE __sys__ SET "indexList" = ? WHERE "name" = ?', [JSON.stringify(indexList), util.escapeSQLiteStatement(store.__currentName)], function () {
|
|
345
470
|
success(store);
|
|
346
|
-
}, failure);
|
|
471
|
+
}, /** @type {SQLStatementErrorCallback} */ (failure));
|
|
347
472
|
};
|
|
348
473
|
|
|
474
|
+
/**
|
|
475
|
+
* @typedef {any|IDBKeyRange} Query
|
|
476
|
+
*/
|
|
477
|
+
|
|
349
478
|
/**
|
|
350
479
|
* Retrieves index data for the given key.
|
|
351
|
-
* @param {
|
|
352
|
-
* @param {
|
|
480
|
+
* @param {Query} range
|
|
481
|
+
* @param {"value"|"key"|"count"} opType
|
|
353
482
|
* @param {boolean} nullDisallowed
|
|
354
|
-
* @param {number} count
|
|
355
|
-
* @
|
|
356
|
-
* @
|
|
483
|
+
* @param {number} [count]
|
|
484
|
+
* @this {IDBIndexFull}
|
|
485
|
+
* @returns {import('./IDBRequest.js').IDBRequestFull}
|
|
357
486
|
*/
|
|
358
487
|
IDBIndex.prototype.__fetchIndexData = function (range, opType, nullDisallowed, count) {
|
|
359
488
|
const me = this;
|
|
@@ -373,20 +502,24 @@ IDBIndex.prototype.__fetchIndexData = function (range, opType, nullDisallowed, c
|
|
|
373
502
|
}
|
|
374
503
|
|
|
375
504
|
const fetchArgs = buildFetchIndexDataSQL(nullDisallowed, me, range, opType, false);
|
|
376
|
-
return
|
|
377
|
-
|
|
505
|
+
return /** @type {import('./IDBTransaction.js').IDBTransactionFull} */ (
|
|
506
|
+
me.objectStore.transaction
|
|
507
|
+
).__addToTransactionQueue(function (...args) {
|
|
508
|
+
executeFetchIndexData(
|
|
509
|
+
count,
|
|
510
|
+
...fetchArgs,
|
|
511
|
+
// @ts-expect-error It's ok
|
|
512
|
+
...args
|
|
513
|
+
);
|
|
378
514
|
}, undefined, me);
|
|
379
515
|
};
|
|
380
516
|
|
|
381
|
-
/* eslint-disable jsdoc/check-param-names */
|
|
382
517
|
/**
|
|
383
518
|
* Opens a cursor over the given key range.
|
|
384
|
-
* @
|
|
385
|
-
* @
|
|
386
|
-
* @returns {IDBRequest}
|
|
519
|
+
* @this {IDBIndexFull}
|
|
520
|
+
* @returns {import('./IDBRequest.js').IDBRequestFull}
|
|
387
521
|
*/
|
|
388
522
|
IDBIndex.prototype.openCursor = function (/* query, direction */) {
|
|
389
|
-
/* eslint-enable jsdoc/check-param-names */
|
|
390
523
|
const me = this;
|
|
391
524
|
// eslint-disable-next-line prefer-rest-params
|
|
392
525
|
const [query, direction] = arguments;
|
|
@@ -395,15 +528,12 @@ IDBIndex.prototype.openCursor = function (/* query, direction */) {
|
|
|
395
528
|
return cursor.__request;
|
|
396
529
|
};
|
|
397
530
|
|
|
398
|
-
/* eslint-disable jsdoc/check-param-names */
|
|
399
531
|
/**
|
|
400
532
|
* Opens a cursor over the given key range. The cursor only includes key values, not data.
|
|
401
|
-
* @
|
|
402
|
-
* @
|
|
403
|
-
* @returns {IDBRequest}
|
|
533
|
+
* @this {IDBIndexFull}
|
|
534
|
+
* @returns {import('./IDBRequest.js').IDBRequestFull}
|
|
404
535
|
*/
|
|
405
536
|
IDBIndex.prototype.openKeyCursor = function (/* query, direction */) {
|
|
406
|
-
/* eslint-enable jsdoc/check-param-names */
|
|
407
537
|
const me = this;
|
|
408
538
|
// eslint-disable-next-line prefer-rest-params
|
|
409
539
|
const [query, direction] = arguments;
|
|
@@ -412,6 +542,13 @@ IDBIndex.prototype.openKeyCursor = function (/* query, direction */) {
|
|
|
412
542
|
return cursor.__request;
|
|
413
543
|
};
|
|
414
544
|
|
|
545
|
+
/**
|
|
546
|
+
*
|
|
547
|
+
* @param {Query} query
|
|
548
|
+
* @throws {TypeError}
|
|
549
|
+
* @this {IDBIndexFull}
|
|
550
|
+
* @returns {import('./IDBRequest.js').IDBRequestFull}
|
|
551
|
+
*/
|
|
415
552
|
IDBIndex.prototype.get = function (query) {
|
|
416
553
|
if (!arguments.length) { // Per https://heycam.github.io/webidl/
|
|
417
554
|
throw new TypeError('A parameter was missing for `IDBIndex.get`.');
|
|
@@ -419,6 +556,13 @@ IDBIndex.prototype.get = function (query) {
|
|
|
419
556
|
return this.__fetchIndexData(query, 'value', true);
|
|
420
557
|
};
|
|
421
558
|
|
|
559
|
+
/**
|
|
560
|
+
*
|
|
561
|
+
* @param {Query} query
|
|
562
|
+
* @throws {TypeError}
|
|
563
|
+
* @this {IDBIndexFull}
|
|
564
|
+
* @returns {import('./IDBRequest.js').IDBRequestFull}
|
|
565
|
+
*/
|
|
422
566
|
IDBIndex.prototype.getKey = function (query) {
|
|
423
567
|
if (!arguments.length) { // Per https://heycam.github.io/webidl/
|
|
424
568
|
throw new TypeError('A parameter was missing for `IDBIndex.getKey`.');
|
|
@@ -426,18 +570,30 @@ IDBIndex.prototype.getKey = function (query) {
|
|
|
426
570
|
return this.__fetchIndexData(query, 'key', true);
|
|
427
571
|
};
|
|
428
572
|
|
|
573
|
+
/**
|
|
574
|
+
* @this {IDBIndexFull}
|
|
575
|
+
* @returns {import('./IDBRequest.js').IDBRequestFull}
|
|
576
|
+
*/
|
|
429
577
|
IDBIndex.prototype.getAll = function (/* query, count */) {
|
|
430
578
|
// eslint-disable-next-line prefer-rest-params
|
|
431
579
|
const [query, count] = arguments;
|
|
432
580
|
return this.__fetchIndexData(query, 'value', false, count);
|
|
433
581
|
};
|
|
434
582
|
|
|
583
|
+
/**
|
|
584
|
+
* @this {IDBIndexFull}
|
|
585
|
+
* @returns {import('./IDBRequest.js').IDBRequestFull}
|
|
586
|
+
*/
|
|
435
587
|
IDBIndex.prototype.getAllKeys = function (/* query, count */) {
|
|
436
588
|
// eslint-disable-next-line prefer-rest-params
|
|
437
589
|
const [query, count] = arguments;
|
|
438
590
|
return this.__fetchIndexData(query, 'key', false, count);
|
|
439
591
|
};
|
|
440
592
|
|
|
593
|
+
/**
|
|
594
|
+
* @this {IDBIndexFull}
|
|
595
|
+
* @returns {import('./IDBRequest.js').IDBRequestFull}
|
|
596
|
+
*/
|
|
441
597
|
IDBIndex.prototype.count = function (/* query */) {
|
|
442
598
|
const me = this;
|
|
443
599
|
// eslint-disable-next-line prefer-rest-params
|
|
@@ -454,6 +610,19 @@ IDBIndex.prototype.count = function (/* query */) {
|
|
|
454
610
|
return me.__fetchIndexData(query, 'count', false);
|
|
455
611
|
};
|
|
456
612
|
|
|
613
|
+
/**
|
|
614
|
+
*
|
|
615
|
+
* @param {import('./IDBObjectStore.js').IDBObjectStoreFull} store
|
|
616
|
+
* @param {string} oldName
|
|
617
|
+
* @param {string} newName
|
|
618
|
+
* @param {string[][]} colInfoToPreserveArr
|
|
619
|
+
* @param {null|((
|
|
620
|
+
* tx: SQLTransaction,
|
|
621
|
+
* success: ((store: IDBObjectStore) => void)
|
|
622
|
+
* ) => void)} cb
|
|
623
|
+
* @this {IDBIndexFull}
|
|
624
|
+
* @returns {void}
|
|
625
|
+
*/
|
|
457
626
|
IDBIndex.prototype.__renameIndex = function (store, oldName, newName, colInfoToPreserveArr = [], cb = null) {
|
|
458
627
|
const newNameType = 'BLOB';
|
|
459
628
|
const storeName = store.__currentName;
|
|
@@ -467,10 +636,20 @@ IDBIndex.prototype.__renameIndex = function (store, oldName, newName, colInfoToP
|
|
|
467
636
|
|
|
468
637
|
// We could adapt the approach at http://stackoverflow.com/a/8430746/271577
|
|
469
638
|
// to make the approach reusable without passing column names, but it is a bit fragile
|
|
470
|
-
|
|
639
|
+
/** @type {import('./IDBTransaction.js').IDBTransactionFull} */ (
|
|
640
|
+
store.transaction
|
|
641
|
+
).__addNonRequestToTransactionQueue(function renameIndex (tx, args, success, error) {
|
|
642
|
+
/**
|
|
643
|
+
* @param {SQLTransaction} tx
|
|
644
|
+
* @param {SQLError} err
|
|
645
|
+
* @returns {void}
|
|
646
|
+
*/
|
|
471
647
|
function sqlError (tx, err) {
|
|
472
648
|
error(err);
|
|
473
649
|
}
|
|
650
|
+
/**
|
|
651
|
+
* @returns {void}
|
|
652
|
+
*/
|
|
474
653
|
function finish () {
|
|
475
654
|
if (cb) {
|
|
476
655
|
cb(tx, success);
|
|
@@ -512,9 +691,17 @@ IDBIndex.prototype.__renameIndex = function (store, oldName, newName, colInfoToP
|
|
|
512
691
|
const sql = 'CREATE INDEX ' +
|
|
513
692
|
escapedIndexToRecreate + ' ON ' + escapedStoreNameSQL + '(' + escapedIndexNameSQL + ')';
|
|
514
693
|
CFG.DEBUG && console.log(sql);
|
|
515
|
-
tx.executeSql(
|
|
516
|
-
|
|
517
|
-
|
|
694
|
+
tx.executeSql(
|
|
695
|
+
sql,
|
|
696
|
+
[],
|
|
697
|
+
resolve,
|
|
698
|
+
/* eslint-disable no-extra-parens -- TS */
|
|
699
|
+
/** @type {SQLStatementErrorCallback} */
|
|
700
|
+
(function (tx, err) {
|
|
701
|
+
reject(err);
|
|
702
|
+
})
|
|
703
|
+
/* eslint-enable no-extra-parens -- TS */
|
|
704
|
+
);
|
|
518
705
|
// }, function (tx, err) {
|
|
519
706
|
// reject(err);
|
|
520
707
|
// });
|
|
@@ -525,31 +712,59 @@ IDBIndex.prototype.__renameIndex = function (store, oldName, newName, colInfoToP
|
|
|
525
712
|
// Chrome erring here if not dropped first; Node does not
|
|
526
713
|
const sql = 'DROP INDEX IF EXISTS ' + escapedIndexToRecreate;
|
|
527
714
|
CFG.DEBUG && console.log(sql);
|
|
528
|
-
tx.executeSql(
|
|
529
|
-
|
|
530
|
-
'
|
|
531
|
-
|
|
532
|
-
|
|
715
|
+
tx.executeSql(
|
|
716
|
+
sql, [], function () {
|
|
717
|
+
const sql = 'CREATE INDEX ' + escapedIndexToRecreate +
|
|
718
|
+
' ON ' + escapedStoreNameSQL + '("key")';
|
|
719
|
+
CFG.DEBUG && console.log(sql);
|
|
720
|
+
tx.executeSql(
|
|
721
|
+
sql, [], resolve,
|
|
722
|
+
/* eslint-disable no-extra-parens -- TS */
|
|
723
|
+
/** @type {SQLStatementErrorCallback} */
|
|
724
|
+
(function (tx, err) {
|
|
725
|
+
/* eslint-enable no-extra-parens -- TS */
|
|
726
|
+
reject(err);
|
|
727
|
+
})
|
|
728
|
+
);
|
|
729
|
+
},
|
|
730
|
+
/* eslint-disable no-extra-parens -- TS */
|
|
731
|
+
/** @type {SQLStatementErrorCallback} */
|
|
732
|
+
(function (tx, err) {
|
|
733
|
+
/* eslint-enable no-extra-parens -- TS */
|
|
533
734
|
reject(err);
|
|
534
|
-
})
|
|
535
|
-
|
|
536
|
-
reject(err);
|
|
537
|
-
});
|
|
735
|
+
})
|
|
736
|
+
);
|
|
538
737
|
})
|
|
539
738
|
);
|
|
540
|
-
SyncPromise.all(indexCreations).then(
|
|
739
|
+
SyncPromise.all(indexCreations).then(
|
|
740
|
+
finish,
|
|
741
|
+
/** @type {(reason: any) => PromiseLike<never>} */
|
|
742
|
+
(error)
|
|
743
|
+
).catch((err) => {
|
|
541
744
|
console.log('Index rename error');
|
|
542
745
|
throw err;
|
|
543
746
|
});
|
|
544
|
-
}, sqlError);
|
|
545
|
-
}, sqlError);
|
|
546
|
-
}, sqlError);
|
|
547
|
-
}, sqlError);
|
|
747
|
+
}, /** @type {SQLStatementErrorCallback} */ (sqlError));
|
|
748
|
+
}, /** @type {SQLStatementErrorCallback} */ (sqlError));
|
|
749
|
+
}, /** @type {SQLStatementErrorCallback} */ (sqlError));
|
|
750
|
+
}, /** @type {SQLStatementErrorCallback} */ (sqlError));
|
|
548
751
|
});
|
|
549
752
|
};
|
|
550
753
|
|
|
754
|
+
/**
|
|
755
|
+
* @typedef {any} AnyValue
|
|
756
|
+
*/
|
|
757
|
+
|
|
551
758
|
Object.defineProperty(IDBIndex, Symbol.hasInstance, {
|
|
552
|
-
|
|
759
|
+
/**
|
|
760
|
+
* @param {AnyValue} obj
|
|
761
|
+
* @returns {boolean}
|
|
762
|
+
*/
|
|
763
|
+
value: (obj) => util.isObj(obj) &&
|
|
764
|
+
'openCursor' in obj &&
|
|
765
|
+
typeof obj.openCursor === 'function' &&
|
|
766
|
+
'multiEntry' in obj &&
|
|
767
|
+
typeof obj.multiEntry === 'boolean'
|
|
553
768
|
});
|
|
554
769
|
|
|
555
770
|
util.defineReadonlyOuterInterface(IDBIndex.prototype, readonlyProperties);
|
|
@@ -561,12 +776,31 @@ Object.defineProperty(IDBIndex, 'prototype', {
|
|
|
561
776
|
writable: false
|
|
562
777
|
});
|
|
563
778
|
|
|
564
|
-
|
|
779
|
+
/**
|
|
780
|
+
* @param {number|null} count
|
|
781
|
+
* @param {boolean} unboundedDisallowed
|
|
782
|
+
* @param {IDBIndexFull} index
|
|
783
|
+
* @param {boolean} hasKey
|
|
784
|
+
* @param {import('./Key.js').Value|import('./Key.js').Key} range
|
|
785
|
+
* @param {"value"|"key"|"count"} opType
|
|
786
|
+
* @param {boolean} multiChecks
|
|
787
|
+
* @param {string[]} sql
|
|
788
|
+
* @param {string[]} sqlValues
|
|
789
|
+
* @param {SQLTransaction} tx
|
|
790
|
+
* @param {null|undefined} args
|
|
791
|
+
* @param {(result: number|undefined|[]|AnyValue|AnyValue[]) => void} success
|
|
792
|
+
* @param {(tx: SQLTransaction, err: SQLError) => void} error
|
|
793
|
+
* @returns {void}
|
|
794
|
+
*/
|
|
795
|
+
function executeFetchIndexData (
|
|
796
|
+
count, unboundedDisallowed, index, hasKey, range, opType,
|
|
797
|
+
multiChecks, sql, sqlValues, tx, args, success, error
|
|
798
|
+
) {
|
|
565
799
|
if (unboundedDisallowed) {
|
|
566
800
|
count = 1;
|
|
567
801
|
}
|
|
568
802
|
if (count) {
|
|
569
|
-
sql.push('LIMIT', count);
|
|
803
|
+
sql.push('LIMIT', String(count));
|
|
570
804
|
}
|
|
571
805
|
const isCount = opType === 'count';
|
|
572
806
|
CFG.DEBUG && console.log('Trying to fetch data for Index', sql.join(' '), sqlValues);
|
|
@@ -576,11 +810,27 @@ function executeFetchIndexData (count, unboundedDisallowed, index, hasKey, range
|
|
|
576
810
|
const decode = isCount
|
|
577
811
|
? () => { /* */ }
|
|
578
812
|
: (opType === 'key'
|
|
579
|
-
|
|
813
|
+
// eslint-disable-next-line operator-linebreak -- JSDoc
|
|
814
|
+
?
|
|
815
|
+
/**
|
|
816
|
+
* @param {{
|
|
817
|
+
* key: string
|
|
818
|
+
* }} record
|
|
819
|
+
* @returns {import('./Key.js').ValueType|undefined}
|
|
820
|
+
*/
|
|
821
|
+
(record) => {
|
|
580
822
|
// Key.convertValueToKey(record.key); // Already validated before storage
|
|
581
823
|
return Key.decode(util.unescapeSQLiteResponse(record.key));
|
|
582
824
|
}
|
|
583
|
-
|
|
825
|
+
// eslint-disable-next-line operator-linebreak -- JSDoc
|
|
826
|
+
:
|
|
827
|
+
/**
|
|
828
|
+
* @param {{
|
|
829
|
+
* value: string
|
|
830
|
+
* }} record
|
|
831
|
+
* @returns {AnyValue}
|
|
832
|
+
*/
|
|
833
|
+
(record) => { // when opType is value
|
|
584
834
|
return Sca.decode(util.unescapeSQLiteResponse(record.value));
|
|
585
835
|
});
|
|
586
836
|
if (index.multiEntry) {
|
|
@@ -588,11 +838,23 @@ function executeFetchIndexData (count, unboundedDisallowed, index, hasKey, range
|
|
|
588
838
|
const encodedKey = Key.encode(range, index.multiEntry);
|
|
589
839
|
for (let i = 0; i < data.rows.length; i++) {
|
|
590
840
|
const row = data.rows.item(i);
|
|
591
|
-
const rowKey = Key.
|
|
841
|
+
const rowKey = /** @type {import('./Key.js').ValueTypeArray} */ (
|
|
842
|
+
Key.decode(row[escapedIndexNameForKeyCol])
|
|
843
|
+
);
|
|
592
844
|
let record;
|
|
593
845
|
if (hasKey && (
|
|
594
|
-
(multiChecks && range.some(
|
|
595
|
-
|
|
846
|
+
(multiChecks && range.some(
|
|
847
|
+
/**
|
|
848
|
+
* @param {string} check
|
|
849
|
+
* @returns {boolean}
|
|
850
|
+
*/
|
|
851
|
+
(check) => rowKey.includes(check)
|
|
852
|
+
)) || // More precise than our SQL
|
|
853
|
+
Key.isMultiEntryMatch(
|
|
854
|
+
/** @type {string} */
|
|
855
|
+
(encodedKey),
|
|
856
|
+
row[escapedIndexNameForKeyCol]
|
|
857
|
+
)
|
|
596
858
|
)) {
|
|
597
859
|
recordCount++;
|
|
598
860
|
record = row;
|
|
@@ -625,10 +887,29 @@ function executeFetchIndexData (count, unboundedDisallowed, index, hasKey, range
|
|
|
625
887
|
} else {
|
|
626
888
|
success(unboundedDisallowed ? records[0] : records);
|
|
627
889
|
}
|
|
628
|
-
}, error);
|
|
890
|
+
}, /** @type {SQLStatementErrorCallback} */ (error));
|
|
629
891
|
}
|
|
630
892
|
|
|
631
|
-
|
|
893
|
+
/**
|
|
894
|
+
* @param {boolean} nullDisallowed
|
|
895
|
+
* @param {IDBIndexFull} index
|
|
896
|
+
* @param {import('./Key.js').Value|import('./Key.js').Key} range
|
|
897
|
+
* @param {"value"|"key"|"count"} opType
|
|
898
|
+
* @param {boolean} multiChecks
|
|
899
|
+
* @returns {[
|
|
900
|
+
* nullDisallowed: boolean,
|
|
901
|
+
* index: IDBIndexFull,
|
|
902
|
+
* hasRange: boolean,
|
|
903
|
+
* range: import('./Key.js').Value|import('./Key.js').Key,
|
|
904
|
+
* opType: "value"|"key"|"count",
|
|
905
|
+
* multiChecks: boolean,
|
|
906
|
+
* sql: string[],
|
|
907
|
+
* sqlValues: string[]
|
|
908
|
+
* ]}
|
|
909
|
+
*/
|
|
910
|
+
function buildFetchIndexDataSQL (
|
|
911
|
+
nullDisallowed, index, range, opType, multiChecks
|
|
912
|
+
) {
|
|
632
913
|
const hasRange = nullDisallowed || !util.isNullish(range);
|
|
633
914
|
const col = opType === 'count' ? 'key' : opType; // It doesn't matter which column we use for 'count' as long as it is valid
|
|
634
915
|
const sql = [
|
|
@@ -638,19 +919,27 @@ function buildFetchIndexDataSQL (nullDisallowed, index, range, opType, multiChec
|
|
|
638
919
|
'FROM', util.escapeStoreNameForSQL(index.objectStore.__currentName),
|
|
639
920
|
'WHERE', util.escapeIndexNameForSQL(index.name), 'NOT NULL'
|
|
640
921
|
];
|
|
922
|
+
|
|
923
|
+
/** @type {string[]} */
|
|
641
924
|
const sqlValues = [];
|
|
642
925
|
if (hasRange) {
|
|
643
926
|
if (multiChecks) {
|
|
644
927
|
sql.push('AND (');
|
|
645
|
-
|
|
928
|
+
/** @type {import('./Key.js').KeyPathArray} */ (
|
|
929
|
+
range
|
|
930
|
+
).forEach((innerKey, i) => {
|
|
646
931
|
if (i > 0) sql.push('OR');
|
|
647
932
|
sql.push(util.escapeIndexNameForSQL(index.name), "LIKE ? ESCAPE '^' ");
|
|
648
|
-
sqlValues.push('%' + util.sqlLIKEEscape(
|
|
933
|
+
sqlValues.push('%' + util.sqlLIKEEscape(
|
|
934
|
+
/** @type {string} */ (Key.encode(innerKey, index.multiEntry))
|
|
935
|
+
) + '%');
|
|
649
936
|
});
|
|
650
937
|
sql.push(')');
|
|
651
938
|
} else if (index.multiEntry) {
|
|
652
939
|
sql.push('AND', util.escapeIndexNameForSQL(index.name), "LIKE ? ESCAPE '^'");
|
|
653
|
-
sqlValues.push('%' + util.sqlLIKEEscape(
|
|
940
|
+
sqlValues.push('%' + util.sqlLIKEEscape(
|
|
941
|
+
/** @type {string} */ (Key.encode(range, index.multiEntry))
|
|
942
|
+
) + '%');
|
|
654
943
|
} else {
|
|
655
944
|
const convertedRange = convertValueToKeyRange(range, nullDisallowed);
|
|
656
945
|
setSQLForKeyRange(convertedRange, util.escapeIndexNameForSQL(index.name), sql, sqlValues, true, false);
|