@cocreate/indexeddb 1.10.20 → 1.11.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/CHANGELOG.md +20 -0
- package/CoCreate.config.js +2 -2
- package/LICENSE +683 -21
- package/docs/index.html +9 -15
- package/package.json +4 -5
- package/src/index.js +449 -892
- package/test/collections.js +13 -9
- package/test/databases.js +9 -6
- package/test/documents.js +26 -22
- package/test/index.html +1 -1
- package/test/indexes.js +7 -7
- package/webpack.config.js +79 -73
package/src/index.js
CHANGED
|
@@ -1,98 +1,164 @@
|
|
|
1
1
|
/********************************************************************************
|
|
2
|
-
* Copyright (C)
|
|
2
|
+
* Copyright (C) 2023 CoCreate and Contributors.
|
|
3
3
|
*
|
|
4
|
+
* This program is free software: you can redistribute it and/or modify
|
|
5
|
+
* it under the terms of the GNU Affero General Public License as published
|
|
6
|
+
* by the Free Software Foundation, either version 3 of the License, or
|
|
7
|
+
* (at your option) any later version.
|
|
4
8
|
*
|
|
5
|
-
*
|
|
9
|
+
* This program is distributed in the hope that it will be useful,
|
|
10
|
+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
11
|
+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
12
|
+
* GNU Affero General Public License for more details.
|
|
13
|
+
*
|
|
14
|
+
* You should have received a copy of the GNU Affero General Public License
|
|
15
|
+
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
6
16
|
********************************************************************************/
|
|
7
|
-
import { ObjectId, dotNotationToObject, searchData, sortData, queryData } from '@cocreate/utils'
|
|
8
|
-
import uuid from '@cocreate/uuid'
|
|
9
17
|
|
|
10
|
-
|
|
18
|
+
// Commercial Licensing Information:
|
|
19
|
+
// For commercial use of this software without the copyleft provisions of the AGPLv3,
|
|
20
|
+
// you must obtain a commercial license from CoCreate LLC.
|
|
21
|
+
// For details, visit <https://cocreate.app/licenses/> or contact us at sales@cocreate.app.
|
|
11
22
|
|
|
12
|
-
|
|
13
|
-
return Database('createDatabase', data)
|
|
14
|
-
}
|
|
23
|
+
import { ObjectId, dotNotationToObject, searchData, sortData, queryData } from '@cocreate/utils'
|
|
15
24
|
|
|
16
|
-
|
|
17
|
-
|
|
25
|
+
// let status = true;
|
|
26
|
+
let indexedDbFunction
|
|
27
|
+
function init() {
|
|
28
|
+
// Check for support.
|
|
29
|
+
if (!('indexedDB' in window)) {
|
|
30
|
+
console.log("This browser doesn't support IndexedDB.");
|
|
31
|
+
setStatus(false);
|
|
32
|
+
return;
|
|
33
|
+
} else {
|
|
34
|
+
try {
|
|
35
|
+
indexedDB.databases()
|
|
36
|
+
if (window.CoCreateConfig && window.CoCreateConfig.indexeddb !== false)
|
|
37
|
+
setStatus(true)
|
|
38
|
+
} catch (e) {
|
|
39
|
+
setStatus(false);
|
|
40
|
+
}
|
|
41
|
+
}
|
|
18
42
|
}
|
|
19
43
|
|
|
20
|
-
|
|
21
|
-
|
|
44
|
+
function setStatus(value) {
|
|
45
|
+
if (window.CoCreateConfig)
|
|
46
|
+
window.CoCreateConfig.indexeddb = value;
|
|
47
|
+
else
|
|
48
|
+
window.CoCreateConfig = { indexeddb: value };
|
|
49
|
+
if (!value) {
|
|
50
|
+
indexedDbFunction = indexedDb
|
|
51
|
+
indexedDb = value;
|
|
52
|
+
} else {
|
|
53
|
+
indexedDb = indexedDbFunction
|
|
54
|
+
indexedDbFunction = true
|
|
55
|
+
}
|
|
22
56
|
}
|
|
23
57
|
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
58
|
+
async function indexedDb(data) {
|
|
59
|
+
try {
|
|
60
|
+
let newData = [];
|
|
61
|
+
|
|
62
|
+
let type = data.method.split('.');
|
|
63
|
+
type = type[type.length - 1];
|
|
64
|
+
|
|
65
|
+
if (type === 'database')
|
|
66
|
+
await processDatabase(data, newData, type)
|
|
67
|
+
else {
|
|
68
|
+
if (data.request)
|
|
69
|
+
data[type] = data.request
|
|
70
|
+
|
|
71
|
+
if (!data['timeStamp'])
|
|
72
|
+
data['timeStamp'] = new Date().toISOString()
|
|
73
|
+
|
|
74
|
+
let databases = data.database;
|
|
75
|
+
if (!Array.isArray(databases))
|
|
76
|
+
databases = [databases]
|
|
77
|
+
|
|
78
|
+
let arrays = data.array;
|
|
79
|
+
if (!Array.isArray(arrays))
|
|
80
|
+
arrays = [arrays]
|
|
27
81
|
|
|
28
|
-
|
|
29
|
-
|
|
82
|
+
for (let i = 0; i < databases.length; i++) {
|
|
83
|
+
let database = databases[i]
|
|
84
|
+
if (type === 'array') {
|
|
85
|
+
await processArray(data, newData, database, '', type)
|
|
86
|
+
} else {
|
|
87
|
+
for (let j = 0; j < arrays.length; j++) {
|
|
88
|
+
if (type === 'index')
|
|
89
|
+
await processIndex(data, newData, database, type)
|
|
90
|
+
else if (type === 'object')
|
|
91
|
+
await processObject(data, newData, database, arrays[j], type)
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
return createData(data, newData, type)
|
|
97
|
+
|
|
98
|
+
} catch (error) {
|
|
99
|
+
errorHandler(data, error)
|
|
100
|
+
}
|
|
30
101
|
}
|
|
31
102
|
|
|
32
103
|
const dbVersion = new Map()
|
|
33
|
-
const
|
|
104
|
+
const processDatabase = (data, newData, type) => {
|
|
34
105
|
return new Promise((resolve, reject) => {
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
if (!data) data = {}
|
|
106
|
+
if (!data)
|
|
107
|
+
data = {}
|
|
38
108
|
if (data.request)
|
|
39
109
|
data[type] = data.request
|
|
40
110
|
|
|
41
111
|
if (!data['timeStamp'])
|
|
42
112
|
data['timeStamp'] = new Date().toISOString()
|
|
43
113
|
|
|
44
|
-
if (
|
|
114
|
+
if (data.method == 'read.database') {
|
|
45
115
|
indexedDB.databases().then((databases) => {
|
|
46
116
|
for (let database of databases) {
|
|
47
117
|
if (data.filter && data.filter.query) {
|
|
48
118
|
let isFilter = queryData(database, data.filter.query)
|
|
49
119
|
if (isFilter)
|
|
50
|
-
|
|
120
|
+
newData.push({ storage: 'indexeddb', database })
|
|
51
121
|
} else
|
|
52
|
-
|
|
122
|
+
newData.push({ storage: 'indexeddb', database })
|
|
53
123
|
}
|
|
54
124
|
|
|
55
|
-
resolve(
|
|
125
|
+
resolve()
|
|
56
126
|
})
|
|
57
127
|
} else {
|
|
58
128
|
let databases
|
|
59
|
-
if (
|
|
60
|
-
databases = Object.keys(data.database)
|
|
129
|
+
if (data.method == 'update.database')
|
|
130
|
+
databases = Object.keys(data.database)
|
|
61
131
|
else
|
|
62
132
|
databases = data.database;
|
|
63
133
|
|
|
64
134
|
if (!Array.isArray(databases))
|
|
65
135
|
databases = [databases]
|
|
66
136
|
|
|
67
|
-
let
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
switch (action) {
|
|
74
|
-
case 'getDatabase':
|
|
75
|
-
case 'createDatabase':
|
|
76
|
-
case 'updateDatabase':
|
|
137
|
+
for (let i = 0; i < databases.length; i++) {
|
|
138
|
+
let openRequest, database = databases[i];
|
|
139
|
+
switch (data.method) {
|
|
140
|
+
case 'get.database':
|
|
141
|
+
case 'create.database':
|
|
142
|
+
case 'update.database':
|
|
77
143
|
openRequest = indexedDB.open(database);
|
|
78
144
|
break;
|
|
79
|
-
case '
|
|
80
|
-
openRequest = indexedDB.
|
|
145
|
+
case 'delete.database':
|
|
146
|
+
openRequest = indexedDB.deleteprocessDatabase(database);
|
|
81
147
|
break;
|
|
82
148
|
default:
|
|
83
|
-
errorHandler(data, 'unknown
|
|
149
|
+
errorHandler(data, 'unknown method', database)
|
|
84
150
|
resolve(data)
|
|
85
151
|
}
|
|
86
152
|
|
|
87
153
|
openRequest.onsuccess = function () {
|
|
88
154
|
let db = openRequest.result;
|
|
89
155
|
let dbs = [] // TODO: return an array of dbinstance??
|
|
90
|
-
if (
|
|
91
|
-
// TODO: open a cursor at database
|
|
156
|
+
if (data.method == 'update.database') {
|
|
157
|
+
// TODO: open a cursor at database array and save each array and object at value
|
|
92
158
|
|
|
93
159
|
let objectStoreNames = Array.from(db.objectStoreNames)
|
|
94
|
-
for (let
|
|
95
|
-
let request =
|
|
160
|
+
for (let array of objectStoreNames) {
|
|
161
|
+
let request = array.openCursor();
|
|
96
162
|
|
|
97
163
|
request.onsuccess = function () {
|
|
98
164
|
let cursor = request.result;
|
|
@@ -106,21 +172,20 @@ const Database = (action, data) => {
|
|
|
106
172
|
};
|
|
107
173
|
|
|
108
174
|
request.onerror = function () {
|
|
109
|
-
errorHandler(data, request.error, database,
|
|
175
|
+
errorHandler(data, request.error, database, array)
|
|
110
176
|
};
|
|
111
177
|
|
|
112
178
|
}
|
|
113
179
|
|
|
114
|
-
} else if (data.
|
|
115
|
-
let
|
|
116
|
-
if (!Array.isArray(
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
let collectionsLength = collections.length
|
|
120
|
-
for (let collection of collections) {
|
|
180
|
+
} else if (data.array && data.array.length) {
|
|
181
|
+
let arrays = data.array;
|
|
182
|
+
if (!Array.isArray(arrays))
|
|
183
|
+
arrays = [arrays]
|
|
121
184
|
|
|
122
|
-
|
|
123
|
-
|
|
185
|
+
for (let j = 0; j < arrays.length; j++) {
|
|
186
|
+
let array = arrays[j]
|
|
187
|
+
let arrayExist = db.objectStoreNames.contains(array)
|
|
188
|
+
if (!arrayExist || arrays.length == 1 && data.upgrade == true) {
|
|
124
189
|
db.close()
|
|
125
190
|
|
|
126
191
|
let version = dbVersion.get(database) || openRequest.result.version
|
|
@@ -130,24 +195,19 @@ const Database = (action, data) => {
|
|
|
130
195
|
request.onupgradeneeded = function () {
|
|
131
196
|
db = request.result;
|
|
132
197
|
|
|
133
|
-
if (!
|
|
198
|
+
if (!arrayExist) {
|
|
134
199
|
db = request.result;
|
|
135
200
|
try {
|
|
136
|
-
db.createObjectStore(
|
|
201
|
+
db.createObjectStore(array, { keyPath: '_id', autoIncrement: true });
|
|
137
202
|
} catch (error) {
|
|
138
|
-
errorHandler(data, error, database,
|
|
203
|
+
errorHandler(data, error, database, array)
|
|
139
204
|
}
|
|
140
205
|
}
|
|
141
206
|
};
|
|
142
207
|
|
|
143
208
|
request.onsuccess = function () {
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
if (!collectionsLength)
|
|
147
|
-
databasesLength -= 1
|
|
148
|
-
|
|
149
|
-
if (!databasesLength && !collectionsLength) {
|
|
150
|
-
if (action == 'getDatabase') {
|
|
209
|
+
if (databases.length - 1 === i && arrays.length - 1 === j) {
|
|
210
|
+
if (data.method == 'get.database') {
|
|
151
211
|
let transaction = request.transaction
|
|
152
212
|
|
|
153
213
|
if (data.upgrade == true && !transaction) {
|
|
@@ -171,25 +231,17 @@ const Database = (action, data) => {
|
|
|
171
231
|
};
|
|
172
232
|
|
|
173
233
|
request.onerror = function () {
|
|
174
|
-
errorHandler(data, request.error, database,
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
if (!collectionsLength)
|
|
178
|
-
databasesLength -= 1
|
|
179
|
-
if (!databasesLength && !collectionsLength) {
|
|
180
|
-
if (action == 'getDatabase')
|
|
234
|
+
errorHandler(data, request.error, database, array)
|
|
235
|
+
if (databases.length - 1 === i && arrays.length - 1 === j) {
|
|
236
|
+
if (data.method == 'get.database')
|
|
181
237
|
resolve(request)
|
|
182
238
|
else
|
|
183
239
|
resolve(data)
|
|
184
240
|
}
|
|
185
241
|
};
|
|
186
242
|
} else {
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
if (!collectionsLength)
|
|
190
|
-
databasesLength -= 1
|
|
191
|
-
if (!databasesLength && !collectionsLength) {
|
|
192
|
-
if (action == 'getDatabase')
|
|
243
|
+
if (databases.length - 1 === i && arrays.length - 1 === j) {
|
|
244
|
+
if (data.method == 'get.database')
|
|
193
245
|
resolve(db)
|
|
194
246
|
else
|
|
195
247
|
resolve(data)
|
|
@@ -197,9 +249,8 @@ const Database = (action, data) => {
|
|
|
197
249
|
}
|
|
198
250
|
}
|
|
199
251
|
} else {
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
if (action == 'getDatabase') {
|
|
252
|
+
if (databases.length - 1 === i) {
|
|
253
|
+
if (data.method == 'get.database') {
|
|
203
254
|
let transaction = openRequest.transaction
|
|
204
255
|
|
|
205
256
|
if (data.upgrade == true && !transaction) {
|
|
@@ -212,12 +263,9 @@ const Database = (action, data) => {
|
|
|
212
263
|
upgrade.onupgradeneeded = function () {
|
|
213
264
|
resolve(upgrade)
|
|
214
265
|
};
|
|
215
|
-
|
|
216
|
-
} else {
|
|
266
|
+
} else
|
|
217
267
|
resolve(db)
|
|
218
|
-
|
|
219
|
-
}
|
|
220
|
-
else
|
|
268
|
+
} else
|
|
221
269
|
resolve(data)
|
|
222
270
|
}
|
|
223
271
|
}
|
|
@@ -237,585 +285,261 @@ const Database = (action, data) => {
|
|
|
237
285
|
});
|
|
238
286
|
}
|
|
239
287
|
|
|
288
|
+
async function processArray(data, newData, database, type) {
|
|
289
|
+
let db = await processDatabase({ method: 'get.database', database })
|
|
290
|
+
db.close()
|
|
291
|
+
|
|
292
|
+
let objectStoreNames = Array.from(db.objectStoreNames)
|
|
293
|
+
if (data.method == 'read.array') {
|
|
294
|
+
if (!data[type])
|
|
295
|
+
data[type] = []
|
|
296
|
+
|
|
297
|
+
for (let i = 0; i < objectStoreNames.length; i++) {
|
|
298
|
+
if (data.filter && data.filter.query) {
|
|
299
|
+
let isFilter = queryData({ name: objectStoreNames[i] }, data.filter.query)
|
|
300
|
+
if (isFilter)
|
|
301
|
+
newData.push({ name: objectStoreNames, storage: 'indexeddb', database })
|
|
302
|
+
} else
|
|
303
|
+
newData.push({ name: objectStoreNames[i], storage: 'indexeddb', database })
|
|
304
|
+
}
|
|
305
|
+
} else {
|
|
306
|
+
let arrays
|
|
307
|
+
if (data.method == 'update.array')
|
|
308
|
+
arrays = Object.keys(data[type])
|
|
309
|
+
else
|
|
310
|
+
arrays = data[type];
|
|
311
|
+
if (!Array.isArray(arrays))
|
|
312
|
+
arrays = [arrays]
|
|
313
|
+
|
|
314
|
+
for (let i = 0; i < arrays.length; i++) {
|
|
315
|
+
let error, array = arrays[i]
|
|
316
|
+
|
|
317
|
+
let arrayExist = db.objectStoreNames.contains(array)
|
|
318
|
+
if (arrayExist && data.method == 'create.array') {
|
|
319
|
+
error = 'array already exists'
|
|
320
|
+
} else {
|
|
321
|
+
if (!arrayExist && data.method == 'update.array')
|
|
322
|
+
array = data[type][arrays[i]]
|
|
323
|
+
|
|
324
|
+
let db = await processDatabase({ method: 'get.database', database, array, upgrade: true })
|
|
325
|
+
if (arrayExist) {
|
|
326
|
+
if (data.method == 'delete.array')
|
|
327
|
+
db.result.deleteObjectStore(array)
|
|
328
|
+
else if (data.method == 'update.array') {
|
|
329
|
+
let transaction = db.transaction;
|
|
330
|
+
let objectStore = transaction.objectStore(array);
|
|
331
|
+
|
|
332
|
+
if (!objectStoreNames.includes(data[type][arrays[i]]))
|
|
333
|
+
array = objectStore.name = data[type][arrays[i]];
|
|
334
|
+
else
|
|
335
|
+
error = 'An array with the new name already exist'
|
|
336
|
+
}
|
|
337
|
+
} else if (data.method == 'update.array')
|
|
338
|
+
error = 'array does not exists'
|
|
339
|
+
}
|
|
240
340
|
|
|
241
|
-
|
|
242
|
-
return collection('createCollection', data)
|
|
243
|
-
}
|
|
244
|
-
|
|
245
|
-
function readCollection(data) {
|
|
246
|
-
return collection('readCollection', data)
|
|
247
|
-
}
|
|
248
|
-
|
|
249
|
-
function updateCollection(data) {
|
|
250
|
-
return collection('updateCollection', data)
|
|
251
|
-
}
|
|
341
|
+
db.result.close()
|
|
252
342
|
|
|
253
|
-
|
|
254
|
-
|
|
343
|
+
if (!error)
|
|
344
|
+
newData.push({ name: array, storage: 'indexeddb', database })
|
|
345
|
+
else
|
|
346
|
+
errorHandler(data, error, database)
|
|
347
|
+
}
|
|
348
|
+
}
|
|
255
349
|
}
|
|
256
350
|
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
351
|
+
async function processIndex(data, newData, database, array, type) {
|
|
352
|
+
let db = await processDatabase({ method: 'get.database', database })
|
|
353
|
+
let arrayExist = db.objectStoreNames.contains(array)
|
|
354
|
+
if (arrayExist) {
|
|
355
|
+
// ToDO: switch here to types
|
|
356
|
+
let transaction = db.transaction(array, "readonly");
|
|
357
|
+
let objectStore = transaction.objectStore(array);
|
|
358
|
+
let indexNames = Array.from(objectStore.indexNames)
|
|
359
|
+
|
|
360
|
+
if (data.method == 'read.index') {
|
|
361
|
+
for (let i = 0; i < indexNames.length; i++) {
|
|
362
|
+
let name = indexNames[i]
|
|
363
|
+
if (data.filter && data.filter.query)
|
|
364
|
+
if (!(queryData({ name }, data.filter.query))) continue
|
|
365
|
+
|
|
366
|
+
newData.push({ name, storage: 'indexeddb', database, array })
|
|
367
|
+
}
|
|
368
|
+
db.close()
|
|
369
|
+
} else {
|
|
370
|
+
db.close()
|
|
371
|
+
let indexes
|
|
372
|
+
if (data.method == 'update.index')
|
|
373
|
+
indexes = Object.keys(data[type])
|
|
374
|
+
else
|
|
375
|
+
indexes = data[type];
|
|
269
376
|
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
let databasesLength = databases.length
|
|
273
|
-
for (let database of databases) {
|
|
274
|
-
let openRequest = indexedDB.open(database)
|
|
377
|
+
if (!Array.isArray(indexes))
|
|
378
|
+
indexes = [indexes]
|
|
275
379
|
|
|
276
|
-
|
|
277
|
-
let
|
|
278
|
-
db.
|
|
279
|
-
let
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
data[type] = []
|
|
283
|
-
|
|
284
|
-
for (let collection of objectStoreNames) {
|
|
285
|
-
if (data.filter && data.filter.query) {
|
|
286
|
-
let isFilter = queryData({ name: collection }, data.filter.query)
|
|
287
|
-
if (isFilter)
|
|
288
|
-
collectionArray.push({ name: collection, db: 'indexeddb', database })
|
|
289
|
-
} else
|
|
290
|
-
collectionArray.push({ name: collection, db: 'indexeddb', database })
|
|
291
|
-
}
|
|
380
|
+
for (let i = 0; i < indexes.length; i++) {
|
|
381
|
+
let error, index = indexes[i]
|
|
382
|
+
db = await processDatabase({ method: 'get.database', database, upgrade: true })
|
|
383
|
+
let transaction = db.transaction;
|
|
384
|
+
let objectStore = transaction.objectStore(array);
|
|
385
|
+
let indexExist = indexNames.includes(index)
|
|
292
386
|
|
|
293
|
-
|
|
294
|
-
if (!
|
|
295
|
-
|
|
296
|
-
}
|
|
297
|
-
|
|
298
|
-
} else {
|
|
299
|
-
let collections
|
|
300
|
-
if (action == 'updateCollection')
|
|
301
|
-
collections = Object.keys(data[type]).map((key) => [key, data[type][key]])
|
|
387
|
+
if (data.method == 'create.index') {
|
|
388
|
+
if (!indexExist)
|
|
389
|
+
objectStore.createIndex(index, index, { unique: false })
|
|
302
390
|
else
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
collectionExist && ['updateCollection', 'deleteCollection'].includes(action) ||
|
|
314
|
-
!collectionExist && ['createCollection', 'updateCollection'].includes(action)
|
|
315
|
-
) {
|
|
316
|
-
getDatabase({ database, collection, upgrade: true }).then((db) => {
|
|
317
|
-
if (collectionExist && action == 'updateCollection') {
|
|
318
|
-
let transaction = db.transaction;
|
|
319
|
-
let objectStore = transaction.objectStore(collection);
|
|
320
|
-
|
|
321
|
-
let valueExist = objectStoreNames.includes(value)
|
|
322
|
-
if (!valueExist) {
|
|
323
|
-
objectStore.name = value;
|
|
324
|
-
}
|
|
325
|
-
else
|
|
326
|
-
errorHandler(data, 'collection does not exist', database)
|
|
327
|
-
|
|
328
|
-
db.result.close()
|
|
329
|
-
|
|
330
|
-
collectionArray.push({ name: value, db: 'indexeddb', database })
|
|
331
|
-
collectionsLength -= 1
|
|
332
|
-
|
|
333
|
-
if (!collectionsLength)
|
|
334
|
-
databasesLength -= 1
|
|
335
|
-
|
|
336
|
-
if (!databasesLength && !collectionsLength) {
|
|
337
|
-
resolve(createData(data, collectionArray, type))
|
|
338
|
-
}
|
|
339
|
-
|
|
340
|
-
} else {
|
|
341
|
-
db = db.result
|
|
342
|
-
|
|
343
|
-
if (action == 'deleteCollection') {
|
|
344
|
-
db.deleteObjectStore(collection)
|
|
345
|
-
}
|
|
346
|
-
|
|
347
|
-
db.close()
|
|
348
|
-
|
|
349
|
-
collectionArray.push({ name: collection, db: 'indexeddb', database })
|
|
350
|
-
collectionsLength -= 1
|
|
351
|
-
|
|
352
|
-
if (!collectionsLength)
|
|
353
|
-
databasesLength -= 1
|
|
354
|
-
|
|
355
|
-
if (!databasesLength && !collectionsLength) {
|
|
356
|
-
resolve(createData(data, collectionArray, type))
|
|
357
|
-
}
|
|
358
|
-
|
|
359
|
-
}
|
|
360
|
-
}, (error) => {
|
|
361
|
-
errorHandler(data, error, database)
|
|
362
|
-
})
|
|
363
|
-
|
|
364
|
-
} else {
|
|
365
|
-
collectionArray.push({ name: collection, db: 'indexeddb', database })
|
|
366
|
-
collectionsLength -= 1
|
|
367
|
-
|
|
368
|
-
if (!collectionsLength)
|
|
369
|
-
databasesLength -= 1
|
|
370
|
-
|
|
371
|
-
if (!databasesLength && !collectionsLength) {
|
|
372
|
-
resolve(createData(data, collectionArray, type))
|
|
373
|
-
}
|
|
374
|
-
}
|
|
375
|
-
|
|
391
|
+
error = 'index already exist'
|
|
392
|
+
} else if (indexExist) {
|
|
393
|
+
if (data.method == 'delete.index')
|
|
394
|
+
objectStore.deleteIndex(index)
|
|
395
|
+
else if (data.method == 'update.index' && !indexNames.includes(data[type][indexes[i]])) {
|
|
396
|
+
if (!indexNames.includes(data[type][indexes[i]])) {
|
|
397
|
+
let indexObj = objectStore.index(index);
|
|
398
|
+
index = indexObj.name = data[type][indexes[i]];
|
|
399
|
+
} else
|
|
400
|
+
error = 'new index name already exist'
|
|
376
401
|
}
|
|
402
|
+
} else
|
|
403
|
+
error = 'index does not exist'
|
|
377
404
|
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
openRequest.onerror = function () {
|
|
383
|
-
errorHandler(data, openRequest.error, database)
|
|
384
|
-
databasesLength -= 1
|
|
405
|
+
if (!error)
|
|
406
|
+
newData.push({ name: index, storage: 'indexeddb', database, array })
|
|
407
|
+
else
|
|
408
|
+
errorHandler(data, error, database, array)
|
|
385
409
|
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
}
|
|
389
|
-
};
|
|
410
|
+
db.result.close()
|
|
411
|
+
}
|
|
390
412
|
}
|
|
391
|
-
}
|
|
392
|
-
errorHandler(data, error)
|
|
393
|
-
});
|
|
394
|
-
}
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
function createIndex(data) {
|
|
398
|
-
return index('createIndex', data)
|
|
399
|
-
}
|
|
400
|
-
|
|
401
|
-
function readIndex(data) {
|
|
402
|
-
return index('readIndex', data)
|
|
403
|
-
}
|
|
404
|
-
|
|
405
|
-
function updateIndex(data) {
|
|
406
|
-
return index('updateIndex', data)
|
|
407
|
-
}
|
|
408
|
-
|
|
409
|
-
function deleteIndex(data) {
|
|
410
|
-
return index('deleteIndex', data)
|
|
413
|
+
}
|
|
411
414
|
}
|
|
412
415
|
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
if (data.
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
let databasesLength = databases.length
|
|
433
|
-
for (let database of databases) {
|
|
434
|
-
let collectionsLength = collections.length
|
|
435
|
-
for (let collection of collections) {
|
|
436
|
-
getDatabase({ database }).then((db) => {
|
|
437
|
-
let objectStoreNames = Array.from(db.objectStoreNames)
|
|
438
|
-
if (objectStoreNames.includes(collection)) {
|
|
439
|
-
let transaction = db.transaction(collection, "readonly");
|
|
440
|
-
let objectStore = transaction.objectStore(collection);
|
|
441
|
-
let indexNames = Array.from(objectStore.indexNames)
|
|
442
|
-
|
|
443
|
-
if (action == 'readIndex') {
|
|
444
|
-
for (let index of indexNames) {
|
|
445
|
-
if (data.filter && data.filter.query) {
|
|
446
|
-
let isFilter = queryData({ name: index }, data.filter.query)
|
|
447
|
-
if (isFilter)
|
|
448
|
-
indexArray.push({ name: index, db: 'indexeddb', database, collection })
|
|
449
|
-
} else
|
|
450
|
-
indexArray.push({ name: index, db: 'indexeddb', database, collection })
|
|
451
|
-
}
|
|
452
|
-
collectionsLength -= 1
|
|
453
|
-
db.close()
|
|
454
|
-
|
|
455
|
-
if (!collectionsLength)
|
|
456
|
-
databasesLength -= 1
|
|
457
|
-
|
|
458
|
-
if (!databasesLength && !collectionsLength)
|
|
459
|
-
resolve(createData(data, indexArray, type))
|
|
460
|
-
|
|
461
|
-
} else {
|
|
462
|
-
db.close()
|
|
463
|
-
let indexes
|
|
464
|
-
if (action == 'updateIndex')
|
|
465
|
-
indexes = Object.keys(data[type]).map((key) => [key, data[type][key]])
|
|
466
|
-
else
|
|
467
|
-
indexes = data[type];
|
|
468
|
-
if (!Array.isArray(indexes))
|
|
469
|
-
indexes = [indexes]
|
|
470
|
-
|
|
471
|
-
let indexesLength = indexes.length
|
|
472
|
-
for (let index of indexes) {
|
|
473
|
-
|
|
474
|
-
getDatabase({ database, upgrade: true }).then((db2) => {
|
|
475
|
-
let transaction = db2.transaction;
|
|
476
|
-
let objectStore = transaction.objectStore(collection);
|
|
477
|
-
|
|
478
|
-
let value
|
|
479
|
-
if (action == 'updateIndex')
|
|
480
|
-
[index, value] = index
|
|
481
|
-
|
|
482
|
-
let indexExist = indexNames.includes(index)
|
|
483
|
-
|
|
484
|
-
if (action == 'createIndex') {
|
|
485
|
-
if (!indexExist) {
|
|
486
|
-
objectStore.createIndex(index, index, { unique: false })
|
|
487
|
-
indexArray.push({ name: index, db: 'indexeddb', database, collection })
|
|
488
|
-
}
|
|
489
|
-
else
|
|
490
|
-
errorHandler(data, 'index exist', database, collection)
|
|
491
|
-
}
|
|
492
|
-
if (action == 'updateIndex') {
|
|
493
|
-
let valueExist = indexNames.includes(value)
|
|
494
|
-
let indexObj = objectStore.index(index);
|
|
495
|
-
if (indexExist && !valueExist) {
|
|
496
|
-
indexObj.name = value;
|
|
497
|
-
indexArray.push({ name: value, db: 'indexeddb', database, collection })
|
|
498
|
-
}
|
|
499
|
-
else
|
|
500
|
-
errorHandler(data, 'index does not exist', database, collection)
|
|
501
|
-
|
|
502
|
-
}
|
|
503
|
-
if (action == 'deleteIndex') {
|
|
504
|
-
if (indexExist) {
|
|
505
|
-
objectStore.deleteIndex(index)
|
|
506
|
-
indexArray.push({ name: index, db: 'indexeddb', database, collection })
|
|
507
|
-
}
|
|
508
|
-
else
|
|
509
|
-
errorHandler(data, 'index does not exist', database, collection)
|
|
510
|
-
}
|
|
511
|
-
db2.result.close()
|
|
416
|
+
async function processObject(data, newData, database, array, type) {
|
|
417
|
+
let db = await processDatabase({ method: 'get.database', database })
|
|
418
|
+
let filteredObjects
|
|
419
|
+
let arrayExist = db.objectStoreNames.contains(array)
|
|
420
|
+
if (arrayExist) {
|
|
421
|
+
if (data.filter || data.method == 'read.object' && !data.object && !data.object.length) {
|
|
422
|
+
db.close()
|
|
423
|
+
filteredObjects = await readObject(data, database, array)
|
|
424
|
+
db = await processDatabase({ method: 'get.database', database })
|
|
425
|
+
}
|
|
426
|
+
} else {
|
|
427
|
+
db.close()
|
|
428
|
+
db = processDatabase({ method: 'get.database', database, array })
|
|
429
|
+
if (data.filter || data.method == 'read.object' && (!data.object || !data.object.length)) {
|
|
430
|
+
db.close()
|
|
431
|
+
filteredObjects = await readObject(data, database, array)
|
|
432
|
+
db = processDatabase({ method: 'get.database', database })
|
|
433
|
+
}
|
|
434
|
+
}
|
|
512
435
|
|
|
513
|
-
|
|
436
|
+
let transaction, objectStore
|
|
437
|
+
if (array && db) {
|
|
438
|
+
transaction = db.transaction([array], "readwrite");
|
|
439
|
+
objectStore = transaction.objectStore(array);
|
|
440
|
+
}
|
|
514
441
|
|
|
515
|
-
|
|
516
|
-
collectionsLength -= 1
|
|
442
|
+
let objects = []
|
|
517
443
|
|
|
518
|
-
|
|
519
|
-
|
|
444
|
+
if (Array.isArray(data[type]))
|
|
445
|
+
objects.push(...data[type]);
|
|
446
|
+
else if (data[type] != undefined)
|
|
447
|
+
objects.push(data[type])
|
|
448
|
+
// else if (data[type] != undefined && data.method == 'create.object')
|
|
449
|
+
// objects.push(data[type])
|
|
450
|
+
// else if (data[type] != undefined)
|
|
451
|
+
// objects.push({...data[type]})
|
|
520
452
|
|
|
521
|
-
if (!databasesLength && !collectionsLength && !indexesLength) {
|
|
522
|
-
resolve(createData(data, indexArray, type))
|
|
523
|
-
}
|
|
524
|
-
});
|
|
525
|
-
}
|
|
526
453
|
|
|
527
|
-
|
|
454
|
+
if (filteredObjects && filteredObjects.length) {
|
|
455
|
+
if (data.method == 'read.object') {
|
|
456
|
+
for (let i = 0; i < filteredObjects.length; i++)
|
|
457
|
+
newData.push({ storage: 'indexeddb', database, array, ...filteredObjects[i] })
|
|
528
458
|
|
|
529
|
-
|
|
530
|
-
db.close()
|
|
531
|
-
errorHandler(data, `collection: ${collection} does not exist`, database, collection)
|
|
532
|
-
resolve(data)
|
|
533
|
-
}
|
|
534
|
-
});
|
|
459
|
+
}
|
|
535
460
|
|
|
461
|
+
if (data.method == 'update.object') {
|
|
462
|
+
let updateData = objects[0];
|
|
463
|
+
if (updateData)
|
|
464
|
+
objects.shift();
|
|
465
|
+
for (let filterDoc of filteredObjects) {
|
|
466
|
+
filterDoc = dotNotationToObject(updateData, filterDoc)
|
|
467
|
+
objects.push(filterDoc)
|
|
536
468
|
}
|
|
537
469
|
}
|
|
538
470
|
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
}
|
|
542
|
-
}
|
|
543
|
-
|
|
544
|
-
function createDocument(data) {
|
|
545
|
-
return document('createDocument', data)
|
|
546
|
-
}
|
|
547
|
-
|
|
548
|
-
function readDocument(data) {
|
|
549
|
-
return document('readDocument', data)
|
|
550
|
-
}
|
|
551
|
-
|
|
552
|
-
function updateDocument(data) {
|
|
553
|
-
return document('updateDocument', data)
|
|
554
|
-
}
|
|
555
|
-
|
|
556
|
-
function deleteDocument(data) {
|
|
557
|
-
return document('deleteDocument', data)
|
|
558
|
-
}
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
const document = (action, data) => {
|
|
562
|
-
return new Promise((resolve, reject) => {
|
|
563
|
-
let type = 'document'
|
|
564
|
-
let documents = []
|
|
565
|
-
|
|
566
|
-
if (data.request)
|
|
567
|
-
data[type] = data.request
|
|
568
|
-
|
|
569
|
-
if (data.document && !Array.isArray(data.document))
|
|
570
|
-
data.document = [data.document]
|
|
571
|
-
|
|
572
|
-
if (!data['timeStamp'])
|
|
573
|
-
data['timeStamp'] = new Date().toISOString()
|
|
574
|
-
|
|
575
|
-
let databases = data.database;
|
|
576
|
-
if (!Array.isArray(databases))
|
|
577
|
-
databases = [databases]
|
|
578
|
-
|
|
579
|
-
let collections = data.collection;
|
|
580
|
-
if (!Array.isArray(collections))
|
|
581
|
-
collections = [collections]
|
|
582
|
-
|
|
583
|
-
let databasesLength = databases.length
|
|
584
|
-
for (let database of databases) {
|
|
585
|
-
getDatabase({ database }).then((db) => {
|
|
586
|
-
let collectionsLength = collections.length
|
|
587
|
-
for (let collection of collections) {
|
|
588
|
-
let collectionExist = db.objectStoreNames.contains(collection)
|
|
589
|
-
if (!collectionExist) {
|
|
590
|
-
db.close()
|
|
591
|
-
getDatabase({ database, collection }).then((db) => {
|
|
592
|
-
if (data.filter || action == 'readDocument' && (!data.document || !data.document.length)) {
|
|
593
|
-
db.close()
|
|
594
|
-
readDocuments(data, database, collection).then((filterDocs) => {
|
|
595
|
-
getDatabase({ database }).then((db) => {
|
|
596
|
-
let transaction = db.transaction([collection], "readwrite");
|
|
597
|
-
let objectStore = transaction.objectStore(collection);
|
|
598
|
-
|
|
599
|
-
runDocs({ action, data, objectStore, documents, filterDocs, database, collection, type }).then(() => {
|
|
600
|
-
db.close()
|
|
601
|
-
collectionsLength -= 1
|
|
602
|
-
|
|
603
|
-
if (!collectionsLength)
|
|
604
|
-
databasesLength -= 1
|
|
605
|
-
|
|
606
|
-
if (!databasesLength && !collectionsLength) {
|
|
607
|
-
resolve(createData(data, documents, type))
|
|
608
|
-
}
|
|
609
|
-
})
|
|
610
|
-
})
|
|
611
|
-
|
|
612
|
-
})
|
|
613
|
-
} else {
|
|
614
|
-
let transaction = db.transaction([collection], "readwrite");
|
|
615
|
-
let objectStore = transaction.objectStore(collection);
|
|
616
|
-
|
|
617
|
-
runDocs({ action, data, objectStore, documents, database, collection, type }).then(() => {
|
|
618
|
-
db.close()
|
|
619
|
-
collectionsLength -= 1
|
|
620
|
-
|
|
621
|
-
if (!collectionsLength)
|
|
622
|
-
databasesLength -= 1
|
|
623
|
-
|
|
624
|
-
if (!databasesLength && !collectionsLength) {
|
|
625
|
-
resolve(createData(data, documents, type))
|
|
626
|
-
}
|
|
627
|
-
})
|
|
628
|
-
}
|
|
629
|
-
|
|
630
|
-
}).catch((error) => {
|
|
631
|
-
errorHandler(data, { message: error, data }, database)
|
|
632
|
-
collectionsLength -= 1
|
|
633
|
-
|
|
634
|
-
if (!collectionsLength)
|
|
635
|
-
databasesLength -= 1
|
|
636
|
-
|
|
637
|
-
if (!databasesLength && !collectionsLength)
|
|
638
|
-
resolve(createData(data, documents, type))
|
|
639
|
-
|
|
640
|
-
})
|
|
641
|
-
|
|
642
|
-
} else {
|
|
643
|
-
if (data.filter || action == 'readDocument' && (!data.document || !data.document.length)) {
|
|
644
|
-
|
|
645
|
-
db.close()
|
|
646
|
-
readDocuments(data, database, collection).then((filterDocs) => {
|
|
647
|
-
getDatabase({ database }).then((db) => {
|
|
648
|
-
let transaction = db.transaction([collection], "readwrite");
|
|
649
|
-
let objectStore = transaction.objectStore(collection);
|
|
650
|
-
|
|
651
|
-
runDocs({ action, data, objectStore, documents, filterDocs, database, collection, type }).then(() => {
|
|
652
|
-
db.close()
|
|
653
|
-
collectionsLength -= 1
|
|
654
|
-
|
|
655
|
-
if (!collectionsLength)
|
|
656
|
-
databasesLength -= 1
|
|
657
|
-
|
|
658
|
-
if (!databasesLength && !collectionsLength) {
|
|
659
|
-
resolve(createData(data, documents, type))
|
|
660
|
-
}
|
|
661
|
-
})
|
|
662
|
-
})
|
|
663
|
-
})
|
|
664
|
-
} else {
|
|
665
|
-
let transaction = db.transaction([collection], "readwrite");
|
|
666
|
-
let objectStore = transaction.objectStore(collection);
|
|
667
|
-
|
|
668
|
-
runDocs({ action, data, objectStore, documents, database, collection, type }).then(() => {
|
|
669
|
-
db.close()
|
|
670
|
-
collectionsLength -= 1
|
|
671
|
-
|
|
672
|
-
if (!collectionsLength)
|
|
673
|
-
databasesLength -= 1
|
|
674
|
-
if (!databasesLength && !collectionsLength) {
|
|
675
|
-
resolve(createData(data, documents, type))
|
|
676
|
-
}
|
|
677
|
-
})
|
|
678
|
-
}
|
|
679
|
-
}
|
|
680
|
-
}
|
|
681
|
-
|
|
682
|
-
}).catch((error) => {
|
|
683
|
-
errorHandler(data, { message: error, data }, database)
|
|
471
|
+
if (data.method == 'delete.object')
|
|
472
|
+
objects.push(...filteredObjects)
|
|
473
|
+
}
|
|
684
474
|
|
|
685
|
-
|
|
475
|
+
for (let i = 0; i < objects.length; i++) {
|
|
476
|
+
// TODO deDuplcate object per array
|
|
477
|
+
delete objects[i].storage
|
|
478
|
+
delete objects[i].database
|
|
479
|
+
delete objects[i].array
|
|
480
|
+
|
|
481
|
+
if (data.method == 'update.object' || data.method == 'delete.object') {
|
|
482
|
+
if (objects[i]._id) {
|
|
483
|
+
if (data.organization_id)
|
|
484
|
+
objects[i]['organization_id'] = data.organization_id
|
|
485
|
+
objects[i]['modified'] = { on: data.timeStamp, by: data.user_id || data.clientId }
|
|
486
|
+
|
|
487
|
+
await updateObject(data, objects[i], objectStore, database, array)
|
|
488
|
+
objects[i].storage = 'indexeddb'
|
|
489
|
+
objects[i].database = database
|
|
490
|
+
objects[i].array = array
|
|
491
|
+
newData.push(objects[i])
|
|
492
|
+
}
|
|
493
|
+
} else if (data.method == 'create.object') {
|
|
494
|
+
if (!objects[i]._id)
|
|
495
|
+
objects[i]['_id'] = ObjectId()
|
|
496
|
+
objects[i] = dotNotationToObject(objects[i])
|
|
497
|
+
|
|
498
|
+
if (data.organization_id)
|
|
499
|
+
objects[i]['organization_id'] = data.organization_id
|
|
500
|
+
objects[i]['created'] = { on: data.timeStamp, by: data.user_id || data.clientId }
|
|
501
|
+
await addGet(data, newData, database, array, objects[i], objectStore, 'add')
|
|
502
|
+
} else if (data.method == 'read.object') {
|
|
503
|
+
if (objects[i]._id)
|
|
504
|
+
await addGet(data, newData, database, array, objects[i]._id, objectStore, 'get')
|
|
505
|
+
else
|
|
506
|
+
errorHandler(data, { message: 'requires _id', object: objects[i] }, database, objectStore.name)
|
|
507
|
+
}
|
|
686
508
|
|
|
687
|
-
|
|
688
|
-
resolve(createData(data, documents, type))
|
|
689
|
-
})
|
|
509
|
+
}
|
|
690
510
|
|
|
691
|
-
|
|
692
|
-
})
|
|
511
|
+
db.close()
|
|
693
512
|
}
|
|
694
513
|
|
|
695
|
-
function
|
|
514
|
+
function addGet(data, newData, database, array, object, objectStore, operator) {
|
|
696
515
|
return new Promise((resolve, reject) => {
|
|
697
|
-
let
|
|
698
|
-
|
|
699
|
-
if (Array.isArray(data[type]))
|
|
700
|
-
docs.push(...data[type]);
|
|
701
|
-
// else if (data[type] != undefined && action == 'createDocument')
|
|
702
|
-
// docs.push(data[type])
|
|
703
|
-
// else if (data[type] != undefined)
|
|
704
|
-
// docs.push({...data[type]})
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
if (filterDocs && filterDocs.length) {
|
|
708
|
-
if (action == 'readDocument') {
|
|
709
|
-
for (let i = 0; i < filterDocs.length; i++)
|
|
710
|
-
documents.push({ db: 'indexeddb', database, collection, ...filterDocs[i] })
|
|
711
|
-
|
|
712
|
-
}
|
|
516
|
+
let request = objectStore[operator](object)
|
|
713
517
|
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
if (
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
|
|
518
|
+
request.onsuccess = function () {
|
|
519
|
+
if (request.result) {
|
|
520
|
+
if (data.method == 'read.object')
|
|
521
|
+
object = request.result
|
|
522
|
+
object.storage = 'indexeddb'
|
|
523
|
+
object.database = database
|
|
524
|
+
object.array = array
|
|
525
|
+
|
|
526
|
+
newData.push(object)
|
|
722
527
|
}
|
|
528
|
+
resolve()
|
|
529
|
+
};
|
|
723
530
|
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
}
|
|
727
|
-
|
|
728
|
-
let docsLength = docs.length
|
|
729
|
-
|
|
730
|
-
if (docsLength > 0) {
|
|
731
|
-
for (let doc of docs) {
|
|
732
|
-
// TODO deDuplcate document_id per collection
|
|
733
|
-
delete doc.storage
|
|
734
|
-
delete doc.database
|
|
735
|
-
delete doc.collection
|
|
736
|
-
|
|
737
|
-
if (action == 'updateDocument' || action == 'deleteDocument') {
|
|
738
|
-
if (doc._id) {
|
|
739
|
-
if (data.organization_id)
|
|
740
|
-
doc['organization_id'] = data.organization_id
|
|
741
|
-
doc['modified'] = { on: data.timeStamp, by: data.user_id || data.clientId }
|
|
742
|
-
|
|
743
|
-
updateDoc(action, data, doc, objectStore, database, collection).then((doc) => {
|
|
744
|
-
doc.storage = 'indexeddb'
|
|
745
|
-
doc.database = database
|
|
746
|
-
doc.collection = collection
|
|
747
|
-
documents.push(doc)
|
|
748
|
-
docsLength -= 1
|
|
749
|
-
if (!docsLength) {
|
|
750
|
-
resolve()
|
|
751
|
-
}
|
|
752
|
-
})
|
|
753
|
-
} else {
|
|
754
|
-
docsLength -= 1
|
|
755
|
-
if (!docsLength)
|
|
756
|
-
resolve()
|
|
757
|
-
}
|
|
758
|
-
} else {
|
|
759
|
-
let request;
|
|
760
|
-
if (action == 'createDocument') {
|
|
761
|
-
if (!doc._id)
|
|
762
|
-
doc['_id'] = ObjectId()
|
|
763
|
-
doc = dotNotationToObject(doc)
|
|
764
|
-
|
|
765
|
-
if (data.organization_id)
|
|
766
|
-
doc['organization_id'] = data.organization_id
|
|
767
|
-
doc['created'] = { on: data.timeStamp, by: data.user_id || data.clientId }
|
|
768
|
-
request = objectStore.add(doc);
|
|
769
|
-
}
|
|
770
|
-
|
|
771
|
-
if (action == 'readDocument') {
|
|
772
|
-
if (action == 'readDocument' && doc._id)
|
|
773
|
-
request = objectStore.get(doc._id);
|
|
774
|
-
else {
|
|
775
|
-
docsLength -= 1
|
|
776
|
-
errorHandler(data, { message: 'requires _id', document: doc }, database, objectStore.name)
|
|
777
|
-
if (!docsLength) {
|
|
778
|
-
resolve()
|
|
779
|
-
}
|
|
780
|
-
}
|
|
781
|
-
}
|
|
782
|
-
|
|
783
|
-
request.onsuccess = function () {
|
|
784
|
-
if (request.result) {
|
|
785
|
-
if (action == 'readDocument')
|
|
786
|
-
doc = request.result
|
|
787
|
-
doc.storage = 'indexeddb'
|
|
788
|
-
doc.database = database
|
|
789
|
-
doc.collection = collection
|
|
790
|
-
|
|
791
|
-
documents.push(doc)
|
|
792
|
-
}
|
|
793
|
-
docsLength -= 1
|
|
794
|
-
if (!docsLength) {
|
|
795
|
-
resolve()
|
|
796
|
-
}
|
|
797
|
-
};
|
|
798
|
-
|
|
799
|
-
request.onerror = function () {
|
|
800
|
-
errorHandler(data, { message: request.error, document: doc }, database, objectStore.name)
|
|
801
|
-
resolve()
|
|
802
|
-
};
|
|
803
|
-
}
|
|
804
|
-
}
|
|
805
|
-
} else {
|
|
531
|
+
request.onerror = function () {
|
|
532
|
+
errorHandler(data, { message: request.error, object }, database, objectStore.name)
|
|
806
533
|
resolve()
|
|
807
|
-
}
|
|
808
|
-
|
|
809
|
-
|
|
810
|
-
})
|
|
534
|
+
};
|
|
535
|
+
|
|
536
|
+
});
|
|
811
537
|
}
|
|
812
538
|
|
|
813
|
-
function
|
|
539
|
+
function updateObject(data, doc, objectStore, database, array) {
|
|
814
540
|
return new Promise((resolve, reject) => {
|
|
815
541
|
let get = objectStore.get(doc._id)
|
|
816
542
|
get.onsuccess = function () {
|
|
817
|
-
;
|
|
818
|
-
|
|
819
543
|
let result = get.result
|
|
820
544
|
if (result || data.upsert == true) {
|
|
821
545
|
let modify = true
|
|
@@ -824,7 +548,7 @@ function updateDoc(action, data, doc, objectStore, database, collection) {
|
|
|
824
548
|
modify = false
|
|
825
549
|
|
|
826
550
|
if (modify) {
|
|
827
|
-
if (
|
|
551
|
+
if (data.method == 'update.object') {
|
|
828
552
|
doc = dotNotationToObject(doc, get.result)
|
|
829
553
|
|
|
830
554
|
if (data.updateName) {
|
|
@@ -849,13 +573,13 @@ function updateDoc(action, data, doc, objectStore, database, collection) {
|
|
|
849
573
|
};
|
|
850
574
|
|
|
851
575
|
put.onerror = function () {
|
|
852
|
-
errorHandler(data, put.error, database,
|
|
576
|
+
errorHandler(data, put.error, database, array, doc)
|
|
853
577
|
resolve(doc)
|
|
854
578
|
};
|
|
855
579
|
|
|
856
580
|
}
|
|
857
581
|
|
|
858
|
-
if (
|
|
582
|
+
if (data.method == 'delete.object') {
|
|
859
583
|
let deleteDoc = objectStore.delete(doc._id);
|
|
860
584
|
|
|
861
585
|
deleteDoc.onsuccess = function () {
|
|
@@ -863,270 +587,156 @@ function updateDoc(action, data, doc, objectStore, database, collection) {
|
|
|
863
587
|
};
|
|
864
588
|
|
|
865
589
|
deleteDoc.onerror = function () {
|
|
866
|
-
errorHandler(data, deleteDoc.error, database,
|
|
590
|
+
errorHandler(data, deleteDoc.error, database, array, doc)
|
|
867
591
|
resolve(doc)
|
|
868
592
|
};
|
|
869
593
|
}
|
|
870
594
|
|
|
871
595
|
} else {
|
|
872
596
|
// TODO: handle if _id not found upsert
|
|
873
|
-
errorHandler(data, 'doc in db is newer', database,
|
|
597
|
+
errorHandler(data, 'doc in db is newer', database, array, doc)
|
|
874
598
|
resolve(doc)
|
|
875
599
|
}
|
|
876
600
|
} else {
|
|
877
|
-
errorHandler(data, '
|
|
601
|
+
errorHandler(data, 'object doest not exist and upsert is not true', database, array, doc)
|
|
878
602
|
resolve(doc)
|
|
879
603
|
}
|
|
880
604
|
|
|
881
605
|
};
|
|
882
606
|
|
|
883
607
|
get.onerror = function () {
|
|
884
|
-
errorHandler(data, get.error, database,
|
|
608
|
+
errorHandler(data, get.error, database, array, doc)
|
|
885
609
|
resolve(doc)
|
|
886
610
|
};
|
|
887
611
|
|
|
888
612
|
})
|
|
889
613
|
}
|
|
890
614
|
|
|
891
|
-
|
|
892
|
-
return new Promise((resolve, reject) => {
|
|
893
|
-
let openRequest = indexedDB.open(database);
|
|
894
|
-
|
|
895
|
-
openRequest.onsuccess = function () {
|
|
896
|
-
let db = openRequest.result;
|
|
897
|
-
try {
|
|
898
|
-
let transaction = db.transaction([collection], "readonly");
|
|
899
|
-
let objectStore = transaction.objectStore(collection);
|
|
900
|
-
|
|
901
|
-
if (data.filter) {
|
|
902
|
-
let count = objectStore.count();
|
|
903
|
-
count.onsuccess = function () {
|
|
904
|
-
data.filter.count = count.result
|
|
905
|
-
}
|
|
906
|
-
}
|
|
615
|
+
function readObject(data, database, array) {
|
|
616
|
+
return new Promise(async (resolve, reject) => {
|
|
907
617
|
|
|
908
|
-
|
|
909
|
-
|
|
910
|
-
|
|
911
|
-
|
|
912
|
-
|
|
913
|
-
|
|
914
|
-
|
|
915
|
-
|
|
618
|
+
try {
|
|
619
|
+
let db = await processDatabase({ method: 'get.database', database })
|
|
620
|
+
let transaction = db.transaction([array], "readonly");
|
|
621
|
+
let objectStore = transaction.objectStore(array);
|
|
622
|
+
|
|
623
|
+
if (data.filter) {
|
|
624
|
+
let count = objectStore.count();
|
|
625
|
+
count.onsuccess = function () {
|
|
626
|
+
data.filter.count = count.result
|
|
916
627
|
}
|
|
628
|
+
}
|
|
917
629
|
|
|
918
|
-
|
|
919
|
-
|
|
920
|
-
|
|
921
|
-
|
|
922
|
-
|
|
923
|
-
|
|
924
|
-
|
|
925
|
-
|
|
926
|
-
|
|
927
|
-
|
|
928
|
-
|
|
929
|
-
|
|
930
|
-
|
|
931
|
-
|
|
932
|
-
|
|
933
|
-
|
|
934
|
-
|
|
935
|
-
|
|
936
|
-
|
|
937
|
-
|
|
938
|
-
|
|
939
|
-
|
|
940
|
-
|
|
941
|
-
|
|
942
|
-
|
|
943
|
-
|
|
944
|
-
|
|
945
|
-
|
|
946
|
-
const indexStore = objectStore.index(indexName);
|
|
947
|
-
readDocs(data, database, collection, indexStore, direction).then((results) => {
|
|
948
|
-
db.close()
|
|
949
|
-
resolve(results)
|
|
950
|
-
})
|
|
630
|
+
let isIndex = false
|
|
631
|
+
let indexName, direction;
|
|
632
|
+
if (data.filter && data.filter.sort && data.filter.sort[0] && data.filter.sort[0].name) {
|
|
633
|
+
indexName = data.filter.sort[0].name
|
|
634
|
+
// if (indexName.includes('-'))
|
|
635
|
+
// isIndex = false
|
|
636
|
+
// else
|
|
637
|
+
// isIndex = true
|
|
638
|
+
}
|
|
639
|
+
|
|
640
|
+
if (isIndex) {
|
|
641
|
+
direction = data.filter.sort[0].direction
|
|
642
|
+
if (direction == 'desc')
|
|
643
|
+
direction = 'prev'
|
|
644
|
+
else
|
|
645
|
+
direction = 'next'
|
|
646
|
+
|
|
647
|
+
let indexNames = Array.from(objectStore.indexNames)
|
|
648
|
+
let indexExist = indexNames.includes(indexName)
|
|
649
|
+
if (!indexExist) {
|
|
650
|
+
db.close()
|
|
651
|
+
db = await processDatabase({ method: 'get.database', database, upgrade: true })
|
|
652
|
+
transaction = db.transaction;
|
|
653
|
+
objectStore = transaction.objectStore(array);
|
|
654
|
+
try {
|
|
655
|
+
objectStore.createIndex(indexName, indexName, { unique: false })
|
|
656
|
+
} catch (error) {
|
|
657
|
+
// console.log(error)
|
|
951
658
|
}
|
|
952
|
-
} else {
|
|
953
|
-
readDocs(data, database, collection, objectStore).then((results) => {
|
|
954
|
-
db.close()
|
|
955
|
-
resolve(results)
|
|
956
|
-
})
|
|
957
659
|
}
|
|
958
|
-
|
|
959
|
-
errorHandler(data, error, database)
|
|
960
|
-
db.close()
|
|
961
|
-
resolve([])
|
|
962
|
-
return
|
|
660
|
+
objectStore = objectStore.index(indexName);
|
|
963
661
|
}
|
|
964
662
|
|
|
965
|
-
|
|
966
|
-
|
|
967
|
-
|
|
968
|
-
|
|
969
|
-
|
|
970
|
-
|
|
971
|
-
|
|
972
|
-
|
|
973
|
-
|
|
974
|
-
async function readDocs(data, database, collection, objectStore, direction) {
|
|
975
|
-
return new Promise((resolve, reject) => {
|
|
976
|
-
|
|
977
|
-
let results = [], index = 0, limit
|
|
978
|
-
if (data.filter) {
|
|
979
|
-
if (data.filter.startIndex)
|
|
980
|
-
index = data.filter.startIndex
|
|
981
|
-
if (data.filter.limit)
|
|
982
|
-
limit = data.filter.limit
|
|
983
|
-
if (limit)
|
|
984
|
-
limit = index + limit;
|
|
985
|
-
}
|
|
663
|
+
let results = [], index = 0, limit
|
|
664
|
+
if (data.filter) {
|
|
665
|
+
if (data.filter.index)
|
|
666
|
+
index = data.filter.index
|
|
667
|
+
if (data.filter.limit)
|
|
668
|
+
limit = data.filter.limit
|
|
669
|
+
if (limit)
|
|
670
|
+
limit = index + limit;
|
|
671
|
+
}
|
|
986
672
|
|
|
987
|
-
|
|
988
|
-
|
|
989
|
-
|
|
990
|
-
|
|
991
|
-
|
|
992
|
-
|
|
993
|
-
|
|
994
|
-
|
|
995
|
-
|
|
996
|
-
|
|
997
|
-
|
|
998
|
-
|
|
999
|
-
|
|
1000
|
-
|
|
1001
|
-
|
|
1002
|
-
|
|
673
|
+
const request = objectStore.openCursor(null, direction);
|
|
674
|
+
request.onsuccess = function () {
|
|
675
|
+
let cursor = request.result;
|
|
676
|
+
if (cursor) {
|
|
677
|
+
let isFilter = true;
|
|
678
|
+
let value = cursor.value;
|
|
679
|
+
if (data.filter) {
|
|
680
|
+
if (data.filter.query)
|
|
681
|
+
isFilter = queryData(value, data.filter.query);
|
|
682
|
+
if (isFilter && data.filter.search)
|
|
683
|
+
isFilter = searchData(value, data.filter.search);
|
|
684
|
+
}
|
|
685
|
+
if (isFilter !== false)
|
|
686
|
+
results.push(value)
|
|
687
|
+
if (limit && limit == results.length) {
|
|
688
|
+
results = results.slice(index, limit)
|
|
689
|
+
resolve(results)
|
|
690
|
+
} else
|
|
691
|
+
cursor.continue();
|
|
692
|
+
} else {
|
|
693
|
+
if (index)
|
|
694
|
+
results = results.slice(index)
|
|
1003
695
|
resolve(results)
|
|
1004
|
-
}
|
|
1005
|
-
cursor.continue();
|
|
1006
|
-
} else {
|
|
1007
|
-
if (index)
|
|
1008
|
-
results = results.slice(index)
|
|
1009
|
-
resolve(results)
|
|
696
|
+
}
|
|
1010
697
|
}
|
|
1011
|
-
}
|
|
1012
|
-
|
|
1013
|
-
request.onerror = function () {
|
|
1014
|
-
errorHandler(data, request.error, database, collection)
|
|
1015
|
-
db.close()
|
|
1016
|
-
resolve([])
|
|
1017
|
-
};
|
|
1018
698
|
|
|
1019
|
-
|
|
1020
|
-
|
|
699
|
+
request.onerror = function () {
|
|
700
|
+
errorHandler(data, request.error, database, array)
|
|
701
|
+
db.close()
|
|
702
|
+
resolve([])
|
|
703
|
+
};
|
|
1021
704
|
|
|
1022
|
-
async function generateDB(organization = { document: {} }, user = { document: {} }) {
|
|
1023
|
-
const organization_id = organization.document._id || ObjectId();
|
|
1024
|
-
const defaultKey = organization.document.key || uuid.generate();
|
|
1025
|
-
const user_id = user.document._id || ObjectId();
|
|
1026
705
|
|
|
1027
|
-
|
|
1028
|
-
|
|
1029
|
-
|
|
706
|
+
if (db && db.close)
|
|
707
|
+
db.close()
|
|
708
|
+
// return results
|
|
1030
709
|
|
|
1031
|
-
|
|
1032
|
-
|
|
1033
|
-
|
|
1034
|
-
organization.collection = 'organizations'
|
|
1035
|
-
organization.document._id = organization_id
|
|
1036
|
-
organization.document.name = organization.document.name || 'untitiled'
|
|
1037
|
-
organization.organization_id = organization_id
|
|
1038
|
-
createDocument(organization);
|
|
1039
|
-
|
|
1040
|
-
// Create user
|
|
1041
|
-
user.database = organization_id
|
|
1042
|
-
user.collection = 'users'
|
|
1043
|
-
user.document._id = user_id
|
|
1044
|
-
user.document.firstname = user.document.firstname || 'untitiled'
|
|
1045
|
-
user.document.lastname = user.document.lastname || 'untitiled'
|
|
1046
|
-
user.organization_id = organization_id
|
|
1047
|
-
createDocument(user);
|
|
1048
|
-
|
|
1049
|
-
// Create default key
|
|
1050
|
-
let key = {
|
|
1051
|
-
database: organization_id,
|
|
1052
|
-
collection: 'keys',
|
|
1053
|
-
document: {
|
|
1054
|
-
_id: ObjectId(),
|
|
1055
|
-
type: "key",
|
|
1056
|
-
key: defaultKey,
|
|
1057
|
-
actions: {
|
|
1058
|
-
signIn: true,
|
|
1059
|
-
signUp: true
|
|
1060
|
-
},
|
|
1061
|
-
default: true
|
|
1062
|
-
},
|
|
1063
|
-
organization_id
|
|
710
|
+
} catch (error) {
|
|
711
|
+
errorHandler(data, error, database, array)
|
|
712
|
+
resolve([])
|
|
1064
713
|
}
|
|
1065
|
-
|
|
1066
|
-
|
|
1067
|
-
// Create role
|
|
1068
|
-
let role_id = ObjectId();
|
|
1069
|
-
let role = {
|
|
1070
|
-
database: organization_id,
|
|
1071
|
-
collection: 'keys',
|
|
1072
|
-
document: {
|
|
1073
|
-
_id: role_id,
|
|
1074
|
-
type: "role",
|
|
1075
|
-
name: "admin",
|
|
1076
|
-
admin: "true"
|
|
1077
|
-
},
|
|
1078
|
-
organization_id
|
|
1079
|
-
};
|
|
1080
|
-
createDocument(role);
|
|
1081
|
-
|
|
1082
|
-
// Create user key
|
|
1083
|
-
let userKey = {
|
|
1084
|
-
database: organization_id,
|
|
1085
|
-
collection: 'keys',
|
|
1086
|
-
document: {
|
|
1087
|
-
_id: ObjectId(),
|
|
1088
|
-
type: "user",
|
|
1089
|
-
key: user_id,
|
|
1090
|
-
collection: 'users', // could be any collection
|
|
1091
|
-
roles: [role_id],
|
|
1092
|
-
email: user.document.email,
|
|
1093
|
-
password: user.document.password || btoa('0000')
|
|
1094
|
-
},
|
|
1095
|
-
organization_id
|
|
1096
|
-
};
|
|
1097
|
-
createDocument(userKey);
|
|
1098
|
-
|
|
1099
|
-
return [organization, key, user, role, userKey]
|
|
1100
|
-
|
|
1101
|
-
} catch (error) {
|
|
1102
|
-
return false
|
|
1103
|
-
}
|
|
714
|
+
});
|
|
1104
715
|
}
|
|
1105
716
|
|
|
1106
|
-
function errorHandler(data, error, database,
|
|
717
|
+
function errorHandler(data, error, database, array) {
|
|
1107
718
|
if (typeof error == 'object')
|
|
1108
719
|
error['storage'] = 'indexeddb'
|
|
1109
720
|
else
|
|
1110
|
-
error = {
|
|
721
|
+
error = { storage: 'indexeddb', message: error }
|
|
1111
722
|
|
|
1112
723
|
if (database)
|
|
1113
724
|
error['database'] = database
|
|
1114
|
-
if (
|
|
1115
|
-
error['
|
|
725
|
+
if (array)
|
|
726
|
+
error['array'] = array
|
|
1116
727
|
if (data.error)
|
|
1117
728
|
data.error.push(error)
|
|
1118
729
|
else
|
|
1119
730
|
data.error = [error]
|
|
1120
|
-
|
|
1121
731
|
}
|
|
1122
732
|
|
|
1123
|
-
function createData(data,
|
|
733
|
+
function createData(data, newData, type) {
|
|
1124
734
|
data.request = data[type] || {}
|
|
1125
735
|
|
|
1126
736
|
if (data.filter && data.filter.sort)
|
|
1127
|
-
data[type] = sortData(
|
|
737
|
+
data[type] = sortData(newData, data.filter.sort)
|
|
1128
738
|
else
|
|
1129
|
-
data[type] =
|
|
739
|
+
data[type] = newData
|
|
1130
740
|
|
|
1131
741
|
if (data.returnLog) {
|
|
1132
742
|
if (!data.log)
|
|
@@ -1137,59 +747,6 @@ function createData(data, array, type) {
|
|
|
1137
747
|
return data
|
|
1138
748
|
}
|
|
1139
749
|
|
|
1140
|
-
|
|
1141
|
-
function init() {
|
|
1142
|
-
// Check for support.
|
|
1143
|
-
if (!('indexedDB' in window)) {
|
|
1144
|
-
console.log("This browser doesn't support IndexedDB.");
|
|
1145
|
-
setStatus(false);
|
|
1146
|
-
return;
|
|
1147
|
-
} else {
|
|
1148
|
-
try {
|
|
1149
|
-
indexedDB.databases()
|
|
1150
|
-
if (window.CoCreateConfig && window.CoCreateConfig.indexeddb !== false)
|
|
1151
|
-
setStatus(true)
|
|
1152
|
-
} catch (e) {
|
|
1153
|
-
setStatus(false);
|
|
1154
|
-
}
|
|
1155
|
-
}
|
|
1156
|
-
}
|
|
1157
|
-
|
|
1158
|
-
function setStatus(value) {
|
|
1159
|
-
if (window.CoCreateConfig)
|
|
1160
|
-
window.CoCreateConfig.indexeddb = value;
|
|
1161
|
-
else
|
|
1162
|
-
window.CoCreateConfig = { indexeddb: value };
|
|
1163
|
-
|
|
1164
|
-
status = value;
|
|
1165
|
-
}
|
|
1166
|
-
|
|
1167
|
-
|
|
1168
750
|
init();
|
|
1169
751
|
|
|
1170
|
-
export default
|
|
1171
|
-
status,
|
|
1172
|
-
ObjectId,
|
|
1173
|
-
getDatabase,
|
|
1174
|
-
createDatabase,
|
|
1175
|
-
readDatabase,
|
|
1176
|
-
updateDatabase,
|
|
1177
|
-
deleteDatabase,
|
|
1178
|
-
|
|
1179
|
-
createCollection,
|
|
1180
|
-
readCollection,
|
|
1181
|
-
updateCollection,
|
|
1182
|
-
deleteCollection,
|
|
1183
|
-
|
|
1184
|
-
createIndex,
|
|
1185
|
-
readIndex,
|
|
1186
|
-
updateIndex,
|
|
1187
|
-
deleteIndex,
|
|
1188
|
-
|
|
1189
|
-
createDocument,
|
|
1190
|
-
readDocument,
|
|
1191
|
-
updateDocument,
|
|
1192
|
-
deleteDocument,
|
|
1193
|
-
|
|
1194
|
-
generateDB
|
|
1195
|
-
};
|
|
752
|
+
export default indexedDb
|