@cocreate/indexeddb 1.23.0 → 1.23.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +8 -0
- package/package.json +1 -1
- package/src/index.js +913 -793
package/src/index.js
CHANGED
|
@@ -23,856 +23,976 @@
|
|
|
23
23
|
*/
|
|
24
24
|
|
|
25
25
|
import {
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
26
|
+
ObjectId,
|
|
27
|
+
dotNotationToObject,
|
|
28
|
+
searchData,
|
|
29
|
+
sortData,
|
|
30
|
+
queryData,
|
|
31
|
+
createUpdate,
|
|
32
|
+
isEqualArray,
|
|
33
|
+
isEqualObject
|
|
34
34
|
} from "@cocreate/utils";
|
|
35
35
|
|
|
36
36
|
let indexedDbFunction;
|
|
37
37
|
|
|
38
38
|
function init() {
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
39
|
+
// Check for support.
|
|
40
|
+
if (!("indexedDB" in window)) {
|
|
41
|
+
console.log("This browser doesn't support IndexedDB.");
|
|
42
|
+
setStatus(false);
|
|
43
|
+
return;
|
|
44
|
+
} else {
|
|
45
|
+
try {
|
|
46
|
+
indexedDB.databases();
|
|
47
|
+
if (
|
|
48
|
+
window.CoCreateConfig &&
|
|
49
|
+
window.CoCreateConfig.indexeddb !== false
|
|
50
|
+
)
|
|
51
|
+
setStatus(true);
|
|
52
|
+
} catch (e) {
|
|
53
|
+
setStatus(false);
|
|
54
|
+
}
|
|
55
|
+
}
|
|
53
56
|
}
|
|
54
57
|
|
|
55
58
|
function setStatus(value) {
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
59
|
+
if (window.CoCreateConfig) window.CoCreateConfig.indexeddb = value;
|
|
60
|
+
else window.CoCreateConfig = { indexeddb: value };
|
|
61
|
+
|
|
62
|
+
if (!value) {
|
|
63
|
+
indexedDbFunction = indexedDb;
|
|
64
|
+
send = value;
|
|
65
|
+
} else if (!send) {
|
|
66
|
+
send = indexedDbFunction;
|
|
67
|
+
indexedDbFunction = true;
|
|
68
|
+
}
|
|
66
69
|
}
|
|
67
70
|
|
|
68
71
|
async function send(data) {
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
72
|
+
try {
|
|
73
|
+
let newData = [];
|
|
74
|
+
|
|
75
|
+
let type = data.method.split(".")[0];
|
|
76
|
+
if (type === "database") {
|
|
77
|
+
if (data.method === "database.get") {
|
|
78
|
+
return await processDatabase(data);
|
|
79
|
+
} else await processDatabase(data, newData, type);
|
|
80
|
+
} else {
|
|
81
|
+
if (!data["timeStamp"])
|
|
82
|
+
data["timeStamp"] = new Date().toISOString();
|
|
83
|
+
|
|
84
|
+
let databases = data.database;
|
|
85
|
+
if (!databases && data.organization_id)
|
|
86
|
+
databases = [data.organization_id];
|
|
87
|
+
if (!Array.isArray(databases)) databases = [databases];
|
|
88
|
+
|
|
89
|
+
let arrays = data.array || [];
|
|
90
|
+
if (!Array.isArray(arrays)) arrays = [arrays];
|
|
91
|
+
|
|
92
|
+
for (let i = 0; i < databases.length; i++) {
|
|
93
|
+
let database = databases[i];
|
|
94
|
+
if (type === "array") {
|
|
95
|
+
await processArray(data, newData, database, type);
|
|
96
|
+
} else {
|
|
97
|
+
for (let j = 0; j < arrays.length; j++) {
|
|
98
|
+
if (type === "index")
|
|
99
|
+
await processIndex(data, newData, database, type);
|
|
100
|
+
else if (type === "object")
|
|
101
|
+
await processObject(
|
|
102
|
+
data,
|
|
103
|
+
newData,
|
|
104
|
+
database,
|
|
105
|
+
arrays[j],
|
|
106
|
+
type
|
|
107
|
+
);
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
return createData(data, newData, type);
|
|
114
|
+
} catch (error) {
|
|
115
|
+
errorHandler(data, error);
|
|
116
|
+
}
|
|
107
117
|
}
|
|
108
118
|
|
|
109
119
|
const dbVersion = new Map();
|
|
110
120
|
const processDatabase = (data, newData, type) => {
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
121
|
+
return new Promise(
|
|
122
|
+
(resolve, reject) => {
|
|
123
|
+
if (!data) data = {};
|
|
124
|
+
if (!data[type]) data[type] = [];
|
|
125
|
+
|
|
126
|
+
if (data.method == "database.read") {
|
|
127
|
+
indexedDB.databases().then((databases) => {
|
|
128
|
+
for (let database of databases) {
|
|
129
|
+
if (data.$filter && data.$filter.query) {
|
|
130
|
+
let isFilter = queryData(
|
|
131
|
+
database,
|
|
132
|
+
data.$filter.query
|
|
133
|
+
);
|
|
134
|
+
if (isFilter)
|
|
135
|
+
newData.push({
|
|
136
|
+
$storage: ["indexeddb"],
|
|
137
|
+
...database
|
|
138
|
+
});
|
|
139
|
+
} else
|
|
140
|
+
newData.push({
|
|
141
|
+
$storage: ["indexeddb"],
|
|
142
|
+
...database
|
|
143
|
+
});
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
resolve();
|
|
147
|
+
});
|
|
148
|
+
} else {
|
|
149
|
+
let databases;
|
|
150
|
+
if (data.method == "database.update")
|
|
151
|
+
databases = Object.keys(data.database);
|
|
152
|
+
else databases = data.database;
|
|
153
|
+
|
|
154
|
+
if (!Array.isArray(databases)) databases = [databases];
|
|
155
|
+
|
|
156
|
+
for (let i = 0; i < databases.length; i++) {
|
|
157
|
+
let openRequest,
|
|
158
|
+
database = databases[i];
|
|
159
|
+
switch (data.method) {
|
|
160
|
+
case "database.get":
|
|
161
|
+
case "database.create":
|
|
162
|
+
case "database.update":
|
|
163
|
+
openRequest = indexedDB.open(database);
|
|
164
|
+
break;
|
|
165
|
+
case "database.delete":
|
|
166
|
+
openRequest =
|
|
167
|
+
indexedDB.deleteprocessDatabase(database);
|
|
168
|
+
break;
|
|
169
|
+
default:
|
|
170
|
+
errorHandler(data, "unknown method", database);
|
|
171
|
+
resolve(data);
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
openRequest.onsuccess = function () {
|
|
175
|
+
let db = openRequest.result;
|
|
176
|
+
|
|
177
|
+
if (data.method == "database.update") {
|
|
178
|
+
let objectStoreNames = Array.from(
|
|
179
|
+
db.objectStoreNames
|
|
180
|
+
);
|
|
181
|
+
for (let array of objectStoreNames) {
|
|
182
|
+
let request = array.openCursor();
|
|
183
|
+
|
|
184
|
+
request.onsuccess = function () {
|
|
185
|
+
let cursor = request.result;
|
|
186
|
+
if (cursor) {
|
|
187
|
+
let value = cursor.value;
|
|
188
|
+
|
|
189
|
+
cursor.continue();
|
|
190
|
+
} else {
|
|
191
|
+
// -1
|
|
192
|
+
}
|
|
193
|
+
};
|
|
194
|
+
|
|
195
|
+
request.onerror = function () {
|
|
196
|
+
errorHandler(
|
|
197
|
+
data,
|
|
198
|
+
request.error,
|
|
199
|
+
database,
|
|
200
|
+
array
|
|
201
|
+
);
|
|
202
|
+
};
|
|
203
|
+
}
|
|
204
|
+
} else if (data.upgrade === true) {
|
|
205
|
+
db.close();
|
|
206
|
+
|
|
207
|
+
let version =
|
|
208
|
+
dbVersion.get(database) ||
|
|
209
|
+
openRequest.result.version;
|
|
210
|
+
resolve(
|
|
211
|
+
indexedDB.open(database, Number((version += 1)))
|
|
212
|
+
);
|
|
213
|
+
dbVersion.set(database, version);
|
|
214
|
+
} else if (data.array) {
|
|
215
|
+
db.close();
|
|
216
|
+
|
|
217
|
+
let version =
|
|
218
|
+
dbVersion.get(database) ||
|
|
219
|
+
openRequest.result.version;
|
|
220
|
+
let request = indexedDB.open(
|
|
221
|
+
database,
|
|
222
|
+
Number((version += 1))
|
|
223
|
+
);
|
|
224
|
+
dbVersion.set(database, version);
|
|
225
|
+
|
|
226
|
+
request.onupgradeneeded = function (event) {
|
|
227
|
+
const db = event.target.result;
|
|
228
|
+
|
|
229
|
+
let arrays = data.array;
|
|
230
|
+
if (!Array.isArray(arrays)) arrays = [arrays];
|
|
231
|
+
|
|
232
|
+
for (let j = 0; j < arrays.length; j++) {
|
|
233
|
+
if (
|
|
234
|
+
!db.objectStoreNames.contains(arrays[j])
|
|
235
|
+
) {
|
|
236
|
+
try {
|
|
237
|
+
db.createObjectStore(arrays[j], {
|
|
238
|
+
keyPath: "_id",
|
|
239
|
+
autoIncrement: true
|
|
240
|
+
});
|
|
241
|
+
} catch (error) {
|
|
242
|
+
errorHandler(
|
|
243
|
+
data,
|
|
244
|
+
error,
|
|
245
|
+
database,
|
|
246
|
+
arrays[j]
|
|
247
|
+
);
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
if (data.indexName) {
|
|
252
|
+
const transaction =
|
|
253
|
+
event.target.transaction;
|
|
254
|
+
const objectStore =
|
|
255
|
+
transaction.objectStore(arrays[j]);
|
|
256
|
+
if (
|
|
257
|
+
!objectStore.indexNames.contains(
|
|
258
|
+
data.indexName
|
|
259
|
+
)
|
|
260
|
+
)
|
|
261
|
+
objectStore.createIndex(
|
|
262
|
+
data.indexName,
|
|
263
|
+
data.indexFields,
|
|
264
|
+
{ unique: data.unique || false }
|
|
265
|
+
);
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
};
|
|
269
|
+
|
|
270
|
+
request.onsuccess = function (event) {
|
|
271
|
+
if (databases.length - 1 === i) {
|
|
272
|
+
if (data.method == "database.get")
|
|
273
|
+
resolve(event.target.result);
|
|
274
|
+
else resolve(data);
|
|
275
|
+
}
|
|
276
|
+
};
|
|
277
|
+
|
|
278
|
+
request.onerror = function (event) {
|
|
279
|
+
errorHandler(
|
|
280
|
+
data,
|
|
281
|
+
event.target.error,
|
|
282
|
+
database,
|
|
283
|
+
array
|
|
284
|
+
);
|
|
285
|
+
if (databases.length - 1 === i) {
|
|
286
|
+
if (data.method == "database.get")
|
|
287
|
+
resolve(event.target.result);
|
|
288
|
+
else resolve(data);
|
|
289
|
+
}
|
|
290
|
+
};
|
|
291
|
+
} else if (databases.length - 1 === i) {
|
|
292
|
+
if (data.method == "database.get") resolve(db);
|
|
293
|
+
else resolve(data);
|
|
294
|
+
}
|
|
295
|
+
};
|
|
296
|
+
|
|
297
|
+
openRequest.onerror = function () {
|
|
298
|
+
errorHandler(data, openRequest.error, database);
|
|
299
|
+
resolve(data);
|
|
300
|
+
};
|
|
301
|
+
}
|
|
302
|
+
}
|
|
303
|
+
},
|
|
304
|
+
(error) => {
|
|
305
|
+
errorHandler(data, error);
|
|
306
|
+
}
|
|
307
|
+
);
|
|
255
308
|
};
|
|
256
309
|
|
|
257
310
|
async function processArray(data, newData, database, type) {
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
311
|
+
let db = await processDatabase({ method: "database.get", database });
|
|
312
|
+
|
|
313
|
+
let objectStoreNames = Array.from(db.objectStoreNames);
|
|
314
|
+
if (data.method == "array.read") {
|
|
315
|
+
if (!data[type]) data[type] = [];
|
|
316
|
+
|
|
317
|
+
for (let i = 0; i < objectStoreNames.length; i++) {
|
|
318
|
+
if (data.$filter && data.$filter.query) {
|
|
319
|
+
let isFilter = queryData(
|
|
320
|
+
{ name: objectStoreNames[i] },
|
|
321
|
+
data.$filter.query
|
|
322
|
+
);
|
|
323
|
+
if (isFilter)
|
|
324
|
+
newData.push({
|
|
325
|
+
name: objectStoreNames,
|
|
326
|
+
$storage: ["indexeddb"],
|
|
327
|
+
$database: [database]
|
|
328
|
+
});
|
|
329
|
+
} else
|
|
330
|
+
newData.push({
|
|
331
|
+
name: objectStoreNames[i],
|
|
332
|
+
$storage: ["indexeddb"],
|
|
333
|
+
$database: [database]
|
|
334
|
+
});
|
|
335
|
+
}
|
|
336
|
+
} else {
|
|
337
|
+
db.close();
|
|
338
|
+
|
|
339
|
+
let request = await processDatabase({
|
|
340
|
+
method: "database.get",
|
|
341
|
+
database,
|
|
342
|
+
upgrade: true
|
|
343
|
+
});
|
|
344
|
+
await new Promise((resolve) => {
|
|
345
|
+
request.onupgradeneeded = function (event) {
|
|
346
|
+
let db = event.target.result;
|
|
347
|
+
let arrays;
|
|
348
|
+
if (data.method == "array.update")
|
|
349
|
+
arrays = Object.keys(data[type]);
|
|
350
|
+
else arrays = data[type];
|
|
351
|
+
if (!Array.isArray(arrays)) arrays = [arrays];
|
|
352
|
+
|
|
353
|
+
for (let i = 0; i < arrays.length; i++) {
|
|
354
|
+
let error,
|
|
355
|
+
array = arrays[i];
|
|
356
|
+
|
|
357
|
+
let arrayExist = db.objectStoreNames.contains(array);
|
|
358
|
+
if (arrayExist && data.method == "array.create") {
|
|
359
|
+
error = "array already exists";
|
|
360
|
+
} else if (data.method == "array.delete") {
|
|
361
|
+
if (objectStoreNames.includes(array)) {
|
|
362
|
+
db.deleteObjectStore(array);
|
|
363
|
+
} else {
|
|
364
|
+
error = "the array does not exist";
|
|
365
|
+
}
|
|
366
|
+
} else {
|
|
367
|
+
if (!arrayExist && data.method == "array.update")
|
|
368
|
+
array = data[type][arrays[i]];
|
|
369
|
+
|
|
370
|
+
if (arrayExist) {
|
|
371
|
+
if (data.method == "array.update") {
|
|
372
|
+
let transaction = event.target.transaction;
|
|
373
|
+
let objectStore =
|
|
374
|
+
transaction.objectStore(array);
|
|
375
|
+
|
|
376
|
+
if (
|
|
377
|
+
!objectStoreNames.includes(
|
|
378
|
+
data[type][arrays[i]]
|
|
379
|
+
)
|
|
380
|
+
)
|
|
381
|
+
array = objectStore.name =
|
|
382
|
+
data[type][arrays[i]];
|
|
383
|
+
else
|
|
384
|
+
error =
|
|
385
|
+
"An array with the new name already exist";
|
|
386
|
+
}
|
|
387
|
+
} else if (data.method == "array.update")
|
|
388
|
+
error = "array does not exists";
|
|
389
|
+
}
|
|
390
|
+
|
|
391
|
+
if (!error)
|
|
392
|
+
newData.push({
|
|
393
|
+
name: array,
|
|
394
|
+
$storage: ["indexeddb"],
|
|
395
|
+
$database: [database]
|
|
396
|
+
});
|
|
397
|
+
else errorHandler(data, error, database);
|
|
398
|
+
}
|
|
399
|
+
};
|
|
400
|
+
|
|
401
|
+
request.onsuccess = function (event) {
|
|
402
|
+
event.target.result.close();
|
|
403
|
+
resolve();
|
|
404
|
+
};
|
|
405
|
+
|
|
406
|
+
request.onerror = function (event) {
|
|
407
|
+
errorHandler(data, event.target.error, database);
|
|
408
|
+
resolve();
|
|
409
|
+
};
|
|
410
|
+
});
|
|
411
|
+
}
|
|
350
412
|
}
|
|
351
413
|
|
|
352
414
|
async function processIndex(data, newData, database, array, type) {
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
415
|
+
let db = await processDatabase({ method: "database.get", database });
|
|
416
|
+
let arrayExist = db.objectStoreNames.contains(array);
|
|
417
|
+
if (arrayExist) {
|
|
418
|
+
// ToDO: switch here to types
|
|
419
|
+
let transaction = db.transaction(array, "readonly");
|
|
420
|
+
let objectStore = transaction.objectStore(array);
|
|
421
|
+
let indexNames = Array.from(objectStore.indexNames);
|
|
422
|
+
|
|
423
|
+
if (data.method == "index.read") {
|
|
424
|
+
for (let i = 0; i < indexNames.length; i++) {
|
|
425
|
+
let name = indexNames[i];
|
|
426
|
+
if (data.$filter && data.$filter.query)
|
|
427
|
+
if (!queryData({ name }, data.$filter.query)) continue;
|
|
428
|
+
|
|
429
|
+
newData.push({
|
|
430
|
+
name,
|
|
431
|
+
$storage: ["indexeddb"],
|
|
432
|
+
$database: [database],
|
|
433
|
+
$array: [array]
|
|
434
|
+
});
|
|
435
|
+
}
|
|
436
|
+
db.close();
|
|
437
|
+
} else {
|
|
438
|
+
db.close();
|
|
439
|
+
let indexes;
|
|
440
|
+
if (data.method == "index.update")
|
|
441
|
+
indexes = Object.keys(data[type]);
|
|
442
|
+
else indexes = data[type];
|
|
443
|
+
|
|
444
|
+
if (!Array.isArray(indexes)) indexes = [indexes];
|
|
445
|
+
|
|
446
|
+
for (let i = 0; i < indexes.length; i++) {
|
|
447
|
+
let error,
|
|
448
|
+
index = indexes[i];
|
|
449
|
+
db = await processDatabase({
|
|
450
|
+
method: "database.get",
|
|
451
|
+
database,
|
|
452
|
+
upgrade: true
|
|
453
|
+
});
|
|
454
|
+
let transaction = db.transaction;
|
|
455
|
+
let objectStore = transaction.objectStore(array);
|
|
456
|
+
let indexExist = indexNames.includes(index);
|
|
457
|
+
|
|
458
|
+
if (data.method == "index.create") {
|
|
459
|
+
if (!indexExist)
|
|
460
|
+
objectStore.createIndex(index, index, {
|
|
461
|
+
unique: false
|
|
462
|
+
});
|
|
463
|
+
else error = "index already exist";
|
|
464
|
+
} else if (indexExist) {
|
|
465
|
+
if (data.method == "index.delete")
|
|
466
|
+
objectStore.deleteIndex(index);
|
|
467
|
+
else if (
|
|
468
|
+
data.method == "index.update" &&
|
|
469
|
+
!indexNames.includes(data[type][indexes[i]])
|
|
470
|
+
) {
|
|
471
|
+
if (!indexNames.includes(data[type][indexes[i]])) {
|
|
472
|
+
let indexObj = objectStore.index(index);
|
|
473
|
+
index = indexObj.name = data[type][indexes[i]];
|
|
474
|
+
} else error = "new index name already exist";
|
|
475
|
+
}
|
|
476
|
+
} else error = "index does not exist";
|
|
477
|
+
|
|
478
|
+
if (!error)
|
|
479
|
+
newData.push({
|
|
480
|
+
name: index,
|
|
481
|
+
$storage: ["indexeddb"],
|
|
482
|
+
$database: [database],
|
|
483
|
+
$array: [array]
|
|
484
|
+
});
|
|
485
|
+
else errorHandler(data, error, database, array);
|
|
486
|
+
|
|
487
|
+
db.result.close();
|
|
488
|
+
}
|
|
489
|
+
}
|
|
490
|
+
}
|
|
425
491
|
}
|
|
426
492
|
|
|
427
493
|
async function processObject(data, newData, database, array, type) {
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
494
|
+
let db = await processDatabase({ method: "database.get", database });
|
|
495
|
+
|
|
496
|
+
try {
|
|
497
|
+
if (!data[type]) data[type] = [];
|
|
498
|
+
else if (typeof data[type] === "string")
|
|
499
|
+
data[type] = [{ _id: data[type] }];
|
|
500
|
+
else if (!Array.isArray(data[type])) data[type] = [data[type]];
|
|
501
|
+
|
|
502
|
+
let isFilter;
|
|
503
|
+
if (data.$filter) isFilter = true;
|
|
504
|
+
|
|
505
|
+
let arrayExist = db.objectStoreNames.contains(array);
|
|
506
|
+
if (!arrayExist) {
|
|
507
|
+
db.close();
|
|
508
|
+
if (
|
|
509
|
+
data.method == "object.create" ||
|
|
510
|
+
data.method == "object.update"
|
|
511
|
+
) {
|
|
512
|
+
db = await processDatabase({
|
|
513
|
+
method: "database.get",
|
|
514
|
+
database,
|
|
515
|
+
array
|
|
516
|
+
});
|
|
517
|
+
} else {
|
|
518
|
+
return errorHandler(
|
|
519
|
+
data,
|
|
520
|
+
"array does not exist",
|
|
521
|
+
database,
|
|
522
|
+
array
|
|
523
|
+
);
|
|
524
|
+
}
|
|
525
|
+
}
|
|
526
|
+
|
|
527
|
+
if (!array || !db)
|
|
528
|
+
throw new Error({ error: "This is an error message.", db, array });
|
|
529
|
+
|
|
530
|
+
let lastItem;
|
|
531
|
+
if ((isFilter && !data[type].length) || data.isFilter) {
|
|
532
|
+
if (data[type].length) lastItem = data[type][data[type].length - 1];
|
|
533
|
+
data[type] = [{ isFilter: "isEmptyObjectFilter" }];
|
|
534
|
+
|
|
535
|
+
// data[type].splice(0, 0, { isFilter: 'isEmptyObjectFilter' });
|
|
536
|
+
}
|
|
537
|
+
|
|
538
|
+
let transactionType = "readwrite";
|
|
539
|
+
if (data.method == "object.read") transactionType = "readonly";
|
|
540
|
+
|
|
541
|
+
let transaction = db.transaction([array], transactionType);
|
|
542
|
+
let objectStore = transaction.objectStore(array);
|
|
543
|
+
|
|
544
|
+
let globalOperators = getGlobalOperators(data);
|
|
545
|
+
let upsert = data.upsert;
|
|
546
|
+
|
|
547
|
+
for (let i = 0; i < data[type].length; i++) {
|
|
548
|
+
const reference = {
|
|
549
|
+
$storage: ["indexeddb"],
|
|
550
|
+
$database: [database],
|
|
551
|
+
$array: [array]
|
|
552
|
+
};
|
|
553
|
+
|
|
554
|
+
delete data[type][i].$storage;
|
|
555
|
+
delete data[type][i].$database;
|
|
556
|
+
delete data[type][i].$array;
|
|
557
|
+
|
|
558
|
+
if (data.method == "object.create") {
|
|
559
|
+
if (data.organization_id)
|
|
560
|
+
data[type][i]["organization_id"] = data.organization_id;
|
|
561
|
+
|
|
562
|
+
if (!data[type][i]._id)
|
|
563
|
+
data[type][i]["_id"] = ObjectId().toString();
|
|
564
|
+
data[type][i] = dotNotationToObject(data[type][i]);
|
|
565
|
+
|
|
566
|
+
// TODO: user_id || clientId shohould be retrieved from CoCreate
|
|
567
|
+
data[type][i]["created"] = {
|
|
568
|
+
on: data.timeStamp,
|
|
569
|
+
by: data.user_id || data.clientId
|
|
570
|
+
};
|
|
571
|
+
data[type][i] = await add(objectStore, data[type][i]);
|
|
572
|
+
data[type][i] = { ...reference, ...data[type][i] };
|
|
573
|
+
} else {
|
|
574
|
+
if (data[type][i].$filter) isFilter = true;
|
|
575
|
+
|
|
576
|
+
if (data.method == "object.update") {
|
|
577
|
+
if (data.organization_id)
|
|
578
|
+
data[type][i]["organization_id"] = data.organization_id;
|
|
579
|
+
|
|
580
|
+
if (data[type][i].$upsert) upsert = data[type][i].$upsert;
|
|
581
|
+
// TODO: user_id || clientId shohould be retrieved from CoCreate
|
|
582
|
+
if (!data[type][i].modified)
|
|
583
|
+
data[type][i].modified = {
|
|
584
|
+
on: data.timeStamp,
|
|
585
|
+
by: data.user_id || data.clientId
|
|
586
|
+
};
|
|
587
|
+
}
|
|
588
|
+
|
|
589
|
+
let index = 0,
|
|
590
|
+
limit,
|
|
591
|
+
range,
|
|
592
|
+
direction;
|
|
593
|
+
if (data[type][i]._id) {
|
|
594
|
+
range = IDBKeyRange.only(data[type][i]._id);
|
|
595
|
+
} else if (isFilter) {
|
|
596
|
+
let indexName;
|
|
597
|
+
let indexFields;
|
|
598
|
+
|
|
599
|
+
if (data.$filter) {
|
|
600
|
+
// TODO: requires a more robust sorting thats suports various directions
|
|
601
|
+
// Build compound index name from sort keys
|
|
602
|
+
if (data.$filter.sort && data.$filter.sort.length > 0) {
|
|
603
|
+
// Create a standard index name without _id
|
|
604
|
+
let sortKeys = data.$filter.sort
|
|
605
|
+
.map((sort) => sort.key)
|
|
606
|
+
.filter((key) => key !== "_id");
|
|
607
|
+
indexName = sortKeys.join("_"); // e.g., "createdAt_category"
|
|
608
|
+
|
|
609
|
+
// Define compound index fields
|
|
610
|
+
indexFields = [...sortKeys];
|
|
611
|
+
|
|
612
|
+
// Set cursor direction based on the first sort key direction
|
|
613
|
+
direction =
|
|
614
|
+
data.$filter.sort[0].direction === "desc"
|
|
615
|
+
? "prev"
|
|
616
|
+
: "next";
|
|
617
|
+
|
|
618
|
+
// Use last item's values, including _id, to set up the range for pagination
|
|
619
|
+
if (indexName && lastItem && lastItem._id) {
|
|
620
|
+
indexName += "_id";
|
|
621
|
+
indexFields.push("_id");
|
|
622
|
+
let lastKeyValues = [
|
|
623
|
+
...sortKeys.map((key) => lastItem[key]),
|
|
624
|
+
lastItem._id
|
|
625
|
+
]; // Compound key array with _id
|
|
626
|
+
|
|
627
|
+
// Create IDBKeyRange based on direction and lastKeyValues
|
|
628
|
+
if (direction === "next") {
|
|
629
|
+
range = IDBKeyRange.lowerBound(
|
|
630
|
+
lastKeyValues,
|
|
631
|
+
true
|
|
632
|
+
);
|
|
633
|
+
} else {
|
|
634
|
+
range = IDBKeyRange.upperBound(
|
|
635
|
+
lastKeyValues,
|
|
636
|
+
true
|
|
637
|
+
);
|
|
638
|
+
}
|
|
639
|
+
}
|
|
640
|
+
} else if (
|
|
641
|
+
data.$filter.query &&
|
|
642
|
+
data.$filter.query[0] &&
|
|
643
|
+
data.$filter.query[0].key
|
|
644
|
+
) {
|
|
645
|
+
if (data.$filter.query[0].operator === "$eq") {
|
|
646
|
+
range = IDBKeyRange.only(
|
|
647
|
+
data.$filter.query[0].value
|
|
648
|
+
);
|
|
649
|
+
} else if (
|
|
650
|
+
data.$filter.query[0].operator === "$gt"
|
|
651
|
+
) {
|
|
652
|
+
range = IDBKeyRange.lowerBound(
|
|
653
|
+
data.$filter.query[0].value,
|
|
654
|
+
true
|
|
655
|
+
);
|
|
656
|
+
} else if (
|
|
657
|
+
data.$filter.query[0].operator === "$lt"
|
|
658
|
+
) {
|
|
659
|
+
range = IDBKeyRange.upperBound(
|
|
660
|
+
data.$filter.query[0].value,
|
|
661
|
+
true
|
|
662
|
+
);
|
|
663
|
+
} else if (
|
|
664
|
+
data.$filter.query[0].operator === "$gte"
|
|
665
|
+
) {
|
|
666
|
+
range = IDBKeyRange.lowerBound(
|
|
667
|
+
data.$filter.query[0].value
|
|
668
|
+
);
|
|
669
|
+
} else if (
|
|
670
|
+
data.$filter.query[0].operator === "$lte"
|
|
671
|
+
) {
|
|
672
|
+
range = IDBKeyRange.upperBound(
|
|
673
|
+
data.$filter.query[0].value
|
|
674
|
+
);
|
|
675
|
+
}
|
|
676
|
+
|
|
677
|
+
indexName = data.$filter.query[0].key;
|
|
678
|
+
}
|
|
679
|
+
}
|
|
680
|
+
|
|
681
|
+
if (indexName && !indexName.includes("-")) {
|
|
682
|
+
// Check if the compound index exists; create it if not
|
|
683
|
+
let indexNames = Array.from(objectStore.indexNames);
|
|
684
|
+
if (!indexNames.includes(indexName)) {
|
|
685
|
+
db.close();
|
|
686
|
+
db = await processDatabase({
|
|
687
|
+
method: "database.get",
|
|
688
|
+
database,
|
|
689
|
+
array,
|
|
690
|
+
indexName,
|
|
691
|
+
indexFields
|
|
692
|
+
});
|
|
693
|
+
transaction = db.transaction(array, "readwrite");
|
|
694
|
+
objectStore = transaction.objectStore(array);
|
|
695
|
+
}
|
|
696
|
+
objectStore = objectStore.index(indexName);
|
|
697
|
+
}
|
|
698
|
+
|
|
699
|
+
let count = objectStore.count();
|
|
700
|
+
count.onsuccess = function () {
|
|
701
|
+
if (data.$filter) data.$filter.count = count.result;
|
|
702
|
+
else if (data.object.$filter)
|
|
703
|
+
data.object.$filter.count = count.result;
|
|
704
|
+
};
|
|
705
|
+
|
|
706
|
+
if (data.$filter) {
|
|
707
|
+
if (data.$filter.index) index = data.$filter.index;
|
|
708
|
+
if (data.$filter.limit) limit = data.$filter.limit;
|
|
709
|
+
}
|
|
710
|
+
|
|
711
|
+
if (data[type][i].$filter) {
|
|
712
|
+
if (data[type][i].$filter.index)
|
|
713
|
+
index = data[type][i].$filter.index;
|
|
714
|
+
if (data[type][i].$filter.limit)
|
|
715
|
+
limit = data[type][i].$filter.limit;
|
|
716
|
+
}
|
|
717
|
+
} else if (
|
|
718
|
+
data.method == "object.delete" ||
|
|
719
|
+
(data.method == "object.update" &&
|
|
720
|
+
!range &&
|
|
721
|
+
!upsert &&
|
|
722
|
+
!isFilter)
|
|
723
|
+
) {
|
|
724
|
+
continue;
|
|
725
|
+
}
|
|
726
|
+
|
|
727
|
+
await openCursor(
|
|
728
|
+
objectStore,
|
|
729
|
+
range,
|
|
730
|
+
direction,
|
|
731
|
+
data,
|
|
732
|
+
newData,
|
|
733
|
+
isFilter,
|
|
734
|
+
index,
|
|
735
|
+
limit,
|
|
736
|
+
database,
|
|
737
|
+
array,
|
|
738
|
+
upsert,
|
|
739
|
+
type,
|
|
740
|
+
i,
|
|
741
|
+
globalOperators,
|
|
742
|
+
reference
|
|
743
|
+
);
|
|
744
|
+
|
|
745
|
+
if (index) newData = newData.slice(index);
|
|
746
|
+
}
|
|
747
|
+
}
|
|
748
|
+
|
|
749
|
+
if (db.close) db.close();
|
|
750
|
+
} catch (error) {
|
|
751
|
+
errorHandler(data, error, database, array);
|
|
752
|
+
if (db.close) db.close();
|
|
753
|
+
}
|
|
649
754
|
}
|
|
650
755
|
|
|
651
756
|
function openCursor(
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
757
|
+
objectStore,
|
|
758
|
+
range,
|
|
759
|
+
direction,
|
|
760
|
+
data,
|
|
761
|
+
newData,
|
|
762
|
+
isFilter,
|
|
763
|
+
index,
|
|
764
|
+
limit,
|
|
765
|
+
database,
|
|
766
|
+
array,
|
|
767
|
+
upsert,
|
|
768
|
+
type,
|
|
769
|
+
i,
|
|
770
|
+
globalOperators,
|
|
771
|
+
reference
|
|
667
772
|
) {
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
|
|
722
|
-
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
|
|
773
|
+
return new Promise(async (resolve, reject) => {
|
|
774
|
+
const request = objectStore.openCursor(range || null, direction); // next, prev
|
|
775
|
+
|
|
776
|
+
let hasUpdated,
|
|
777
|
+
matchedLength = 0,
|
|
778
|
+
hasSkipped;
|
|
779
|
+
request.onsuccess = async () => {
|
|
780
|
+
let cursor = request.result;
|
|
781
|
+
|
|
782
|
+
if (
|
|
783
|
+
data.method === "object.create" ||
|
|
784
|
+
(data.method === "object.update" &&
|
|
785
|
+
((!range && !isFilter && upsert) ||
|
|
786
|
+
(!cursor && upsert && !hasUpdated)))
|
|
787
|
+
) {
|
|
788
|
+
let isMatch = true;
|
|
789
|
+
if (isFilter) {
|
|
790
|
+
if (cursor)
|
|
791
|
+
isMatch = filter(
|
|
792
|
+
objectStore,
|
|
793
|
+
data[type][i],
|
|
794
|
+
data[type][i],
|
|
795
|
+
cursor.value
|
|
796
|
+
);
|
|
797
|
+
else if (data.method === "object.update" && !upsert)
|
|
798
|
+
isMatch = false;
|
|
799
|
+
}
|
|
800
|
+
|
|
801
|
+
if (isMatch !== false) {
|
|
802
|
+
try {
|
|
803
|
+
data[type][i]._id = ObjectId(
|
|
804
|
+
data[type][i]._id
|
|
805
|
+
).toString();
|
|
806
|
+
} catch (error) {
|
|
807
|
+
data[type][i]._id = ObjectId().toString();
|
|
808
|
+
}
|
|
809
|
+
|
|
810
|
+
let result;
|
|
811
|
+
if (data.method == "object.create") {
|
|
812
|
+
data[type][i] = await add(objectStore, data[type][i]);
|
|
813
|
+
} else if (data.method == "object.update") {
|
|
814
|
+
let update = createUpdate(
|
|
815
|
+
cursor && cursor.value ? cursor.value : {},
|
|
816
|
+
data[type][i],
|
|
817
|
+
globalOperators
|
|
818
|
+
);
|
|
819
|
+
if (update) {
|
|
820
|
+
await put(objectStore, update);
|
|
821
|
+
data[type][i].$update = update;
|
|
822
|
+
}
|
|
823
|
+
}
|
|
824
|
+
data[type][i] = { ...reference, ...data[type][i] };
|
|
825
|
+
|
|
826
|
+
matchedLength++;
|
|
827
|
+
}
|
|
828
|
+
resolve();
|
|
829
|
+
} else if (cursor) {
|
|
830
|
+
if (index && !hasSkipped) {
|
|
831
|
+
cursor.advance(index);
|
|
832
|
+
hasSkipped = true;
|
|
833
|
+
} else {
|
|
834
|
+
let isMatch = true;
|
|
835
|
+
if (isFilter)
|
|
836
|
+
isMatch = filter(
|
|
837
|
+
objectStore,
|
|
838
|
+
data,
|
|
839
|
+
data[type][i],
|
|
840
|
+
cursor.value
|
|
841
|
+
);
|
|
842
|
+
|
|
843
|
+
if (isMatch !== false) {
|
|
844
|
+
let result = cursor.value;
|
|
845
|
+
|
|
846
|
+
if (data.method == "object.update") {
|
|
847
|
+
let update = createUpdate(
|
|
848
|
+
cursor.value,
|
|
849
|
+
data[type][i],
|
|
850
|
+
globalOperators
|
|
851
|
+
);
|
|
852
|
+
if (update) await cursorUpdate(cursor, update);
|
|
853
|
+
result = data[type][i];
|
|
854
|
+
result.$update = update;
|
|
855
|
+
// result = cursor.update(update)
|
|
856
|
+
hasUpdated = true;
|
|
857
|
+
// set dotnotation for keys with $operators for items that end in [] to be used by socket.id
|
|
858
|
+
// TODO: if update.$<operator>.someKey[] requires the index of inerted item added to the field name. update.$<operator>.someKey[<index>]
|
|
859
|
+
// TODO: if $addToSet get field name and item if it does not exist.
|
|
860
|
+
// TODO: if $pull get field name and find if item exist and delete.
|
|
861
|
+
} else if (data.method == "object.delete") {
|
|
862
|
+
result = cursor.value;
|
|
863
|
+
cursor.delete();
|
|
864
|
+
}
|
|
865
|
+
|
|
866
|
+
if (data[type][i]._id)
|
|
867
|
+
data[type][i] = { ...reference, ...result };
|
|
868
|
+
else {
|
|
869
|
+
let object = data[type].find(
|
|
870
|
+
(obj) => obj._id && obj._id === result._id
|
|
871
|
+
);
|
|
872
|
+
if (object)
|
|
873
|
+
object = { ...reference, ...object, ...result };
|
|
874
|
+
else newData.push({ ...reference, ...result });
|
|
875
|
+
}
|
|
876
|
+
}
|
|
877
|
+
|
|
878
|
+
if (
|
|
879
|
+
!limit ||
|
|
880
|
+
(limit && limit > newData.length + matchedLength)
|
|
881
|
+
) {
|
|
882
|
+
cursor.continue();
|
|
883
|
+
} else {
|
|
884
|
+
resolve();
|
|
885
|
+
}
|
|
886
|
+
}
|
|
887
|
+
} else {
|
|
888
|
+
resolve();
|
|
889
|
+
}
|
|
890
|
+
};
|
|
891
|
+
|
|
892
|
+
request.onerror = () => {
|
|
893
|
+
reject(request.error);
|
|
894
|
+
};
|
|
895
|
+
});
|
|
778
896
|
}
|
|
779
897
|
|
|
780
898
|
function add(objectStore, object) {
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
|
|
784
|
-
|
|
785
|
-
|
|
786
|
-
|
|
899
|
+
return new Promise((resolve, reject) => {
|
|
900
|
+
const store = objectStore.objectStore || objectStore;
|
|
901
|
+
let request = store.add(object);
|
|
902
|
+
request.onsuccess = () => resolve(object);
|
|
903
|
+
request.onerror = () => reject(request.error);
|
|
904
|
+
});
|
|
787
905
|
}
|
|
788
906
|
|
|
789
907
|
function get(objectStore, object) {
|
|
790
|
-
|
|
791
|
-
|
|
792
|
-
|
|
793
|
-
|
|
794
|
-
|
|
908
|
+
return new Promise((resolve, reject) => {
|
|
909
|
+
const request = objectStore.get(object._id);
|
|
910
|
+
request.onsuccess = () => resolve(request.result);
|
|
911
|
+
request.onerror = () => reject(request.error);
|
|
912
|
+
});
|
|
795
913
|
}
|
|
796
914
|
|
|
797
915
|
function put(objectStore, object) {
|
|
798
|
-
|
|
799
|
-
|
|
800
|
-
|
|
916
|
+
return new Promise((resolve, reject) => {
|
|
917
|
+
const store = objectStore.objectStore || objectStore;
|
|
918
|
+
let request = store.put(object);
|
|
801
919
|
|
|
802
|
-
|
|
803
|
-
|
|
804
|
-
|
|
920
|
+
request.onsuccess = () => resolve(object);
|
|
921
|
+
request.onerror = () => reject(request.error);
|
|
922
|
+
});
|
|
805
923
|
}
|
|
806
924
|
|
|
807
925
|
function deleteObject(objectStore, object) {
|
|
808
|
-
|
|
809
|
-
|
|
810
|
-
|
|
811
|
-
|
|
812
|
-
|
|
926
|
+
return new Promise((resolve, reject) => {
|
|
927
|
+
const request = objectStore.delete(object._id);
|
|
928
|
+
request.onsuccess = () => resolve(object);
|
|
929
|
+
request.onerror = () => reject(request.error);
|
|
930
|
+
});
|
|
813
931
|
}
|
|
814
932
|
|
|
815
933
|
function cursorUpdate(cursor, update) {
|
|
816
|
-
|
|
817
|
-
|
|
818
|
-
|
|
819
|
-
|
|
820
|
-
|
|
934
|
+
return new Promise((resolve, reject) => {
|
|
935
|
+
const request = cursor.update(update);
|
|
936
|
+
request.onsuccess = () => resolve(request.source.value);
|
|
937
|
+
request.onerror = () => reject(request.error);
|
|
938
|
+
});
|
|
821
939
|
}
|
|
822
940
|
|
|
823
941
|
function filter(objectStore, data, object, result) {
|
|
824
|
-
|
|
825
|
-
|
|
826
|
-
|
|
827
|
-
|
|
828
|
-
|
|
829
|
-
|
|
830
|
-
|
|
831
|
-
|
|
942
|
+
let isMatch = true;
|
|
943
|
+
let filter = data.$filter || object.$filter;
|
|
944
|
+
if (filter) {
|
|
945
|
+
if (filter.query) isMatch = queryData(result, filter.query);
|
|
946
|
+
if (isMatch && filter.search)
|
|
947
|
+
isMatch = searchData(result, filter.search);
|
|
948
|
+
}
|
|
949
|
+
|
|
950
|
+
return isMatch;
|
|
832
951
|
}
|
|
833
952
|
|
|
834
953
|
function getGlobalOperators(data, object = {}) {
|
|
835
|
-
|
|
836
|
-
|
|
837
|
-
|
|
838
|
-
|
|
839
|
-
|
|
954
|
+
for (let operator of Object.keys(data)) {
|
|
955
|
+
if (!operator.startsWith("$")) return;
|
|
956
|
+
for (let key of Object.keys(data[operator]))
|
|
957
|
+
object[operator + "." + key] = data[operator][key];
|
|
958
|
+
}
|
|
840
959
|
|
|
841
|
-
|
|
960
|
+
return object;
|
|
842
961
|
}
|
|
843
962
|
|
|
844
963
|
function createData(data, newData, type) {
|
|
845
|
-
|
|
846
|
-
|
|
847
|
-
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
|
|
853
|
-
|
|
854
|
-
|
|
855
|
-
|
|
856
|
-
|
|
857
|
-
|
|
858
|
-
|
|
859
|
-
|
|
860
|
-
|
|
861
|
-
|
|
862
|
-
|
|
863
|
-
|
|
864
|
-
|
|
964
|
+
// data.request = data[type] || {}
|
|
965
|
+
if (
|
|
966
|
+
data[type] &&
|
|
967
|
+
data[type][0] &&
|
|
968
|
+
data[type][0].isFilter === "isEmptyObjectFilter"
|
|
969
|
+
) {
|
|
970
|
+
data[type].shift();
|
|
971
|
+
data.isFilter = true;
|
|
972
|
+
}
|
|
973
|
+
|
|
974
|
+
data[type].push(...newData);
|
|
975
|
+
|
|
976
|
+
if (data.$filter) {
|
|
977
|
+
if (data.$filter.sort)
|
|
978
|
+
data[type] = sortData(data[type], data.$filter.sort);
|
|
979
|
+
|
|
980
|
+
data.$filter.startingIndex = data.$filter.index;
|
|
981
|
+
data.$filter.index += data[type].length;
|
|
982
|
+
}
|
|
983
|
+
|
|
984
|
+
return data;
|
|
865
985
|
}
|
|
866
986
|
|
|
867
987
|
function errorHandler(data, error, database, array) {
|
|
868
|
-
|
|
869
|
-
|
|
870
|
-
|
|
871
|
-
|
|
872
|
-
|
|
873
|
-
|
|
874
|
-
|
|
875
|
-
|
|
988
|
+
console.error(error, data);
|
|
989
|
+
// if (typeof error == "object") error["storage"] = "indexeddb";
|
|
990
|
+
// else error = { storage: "indexeddb", message: error };
|
|
991
|
+
|
|
992
|
+
// if (database) error["database"] = database;
|
|
993
|
+
// if (array) error["array"] = array;
|
|
994
|
+
// if (data.error) data.error.push(error);
|
|
995
|
+
// else data.error = [error];
|
|
876
996
|
}
|
|
877
997
|
|
|
878
998
|
init();
|