@cocreate/indexeddb 1.0.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/src/index.js ADDED
@@ -0,0 +1,697 @@
1
+ /********************************************************************************
2
+ * Copyright (C) 2020 CoCreate LLC and others.
3
+ *
4
+ *
5
+ * SPDX-License-Identifier: MIT
6
+ ********************************************************************************/
7
+ // import observer from "@cocreate/observer"
8
+ // import crud from '@cocreate/crud'
9
+ import {dotNotationToObject} from '@cocreate/utils'
10
+ import {searchData, sortData, queryData} from '@cocreate/filter'
11
+
12
+ const createDatabase = (data) => {
13
+ return new Promise((resolve, reject) => {
14
+
15
+ let openRequest = indexedDB.open(data.database);
16
+
17
+ openRequest.onsuccess = function() {
18
+ resolve(openRequest.result)
19
+ };
20
+
21
+ openRequest.onerror = function() {
22
+ reject(openRequest.error)
23
+ };
24
+
25
+ }, (err) => {
26
+ console.log(err);
27
+ });
28
+ }
29
+
30
+ const readDatabase = (data) => {
31
+ return new Promise((resolve, reject) => {
32
+
33
+ let openRequest = indexedDB.open(data.database);
34
+
35
+ openRequest.onsuccess = function() {
36
+ let db = openRequest.result;
37
+ if (data.upgrade == true) {
38
+ let version = openRequest.result.version
39
+ db.close()
40
+
41
+ let request = indexedDB.open(data.database, Number(version += 1));
42
+ request.onupgradeneeded = function() {
43
+ db = request.result
44
+ };
45
+
46
+ request.onsuccess = function() {
47
+ resolve(db)
48
+ };
49
+
50
+ request.onerror = function() {
51
+ reject(request.error)
52
+ };
53
+
54
+ } else {
55
+ resolve(db)
56
+ }
57
+ };
58
+
59
+ openRequest.onerror = function() {
60
+ reject(openRequest.error)
61
+ };
62
+
63
+ }, (err) => {
64
+ console.log(err);
65
+ });
66
+ }
67
+
68
+ const readDatabases = () => {
69
+ return new Promise((resolve, reject) => {
70
+ indexedDB.databases().then((databases) => {
71
+ resolve(databases)
72
+ })
73
+ }, (err) => {
74
+ console.log(err);
75
+ });
76
+ }
77
+
78
+ const updateDatabase = (data) => {
79
+ return new Promise((resolve, reject) => {
80
+
81
+ let openRequest = indexedDB.open(data.database);
82
+
83
+ openRequest.onsuccess = function() {
84
+ let db = openRequest.result;
85
+ if (data.newDatabase) {
86
+ // function to clone db with new name
87
+ } else {
88
+ resolve(db)
89
+ }
90
+ };
91
+
92
+ openRequest.onerror = function() {
93
+ reject(openRequest.error)
94
+ };
95
+
96
+ }, (err) => {
97
+ console.log(err);
98
+ });
99
+ }
100
+
101
+ const deleteDatabase = (data) => {
102
+ return new Promise((resolve, reject) => {
103
+ let openRequest = indexedDB.deleteDatabase(data.database);
104
+
105
+ openRequest.onsuccess = function() {
106
+ resolve(openRequest.result);
107
+ };
108
+
109
+ openRequest.onerror = function() {
110
+ reject(openRequest.error);
111
+ };
112
+
113
+ }, (err) => {
114
+ console.log(err);
115
+ });
116
+ }
117
+
118
+ const database = (data) => {
119
+ return new Promise((resolve, reject) => {
120
+ let openRequest = indexedDB.open(data.database);
121
+
122
+ openRequest.onsuccess = function() {
123
+ let db = openRequest.result;
124
+ let collectionExist = db.objectStoreNames.contains(data.collection)
125
+ if (!collectionExist || data.upgrade == true) {
126
+ let version = openRequest.result.version
127
+ db.close()
128
+
129
+ let request = indexedDB.open(data.database, Number(version += 1));
130
+ request.onupgradeneeded = function() {
131
+ if (!collectionExist) {
132
+ db = request.result;
133
+ db.createObjectStore(data.collection, {keyPath: '_id', autoIncrement: true});
134
+ }
135
+ };
136
+
137
+ request.onsuccess = function() {
138
+ resolve(db)
139
+ };
140
+
141
+ request.onerror = function() {
142
+ reject(request.error)
143
+ };
144
+
145
+ } else {
146
+ resolve(db)
147
+ }
148
+ };
149
+
150
+ openRequest.onerror = function() {
151
+ reject(openRequest.error)
152
+ };
153
+
154
+ }, (err) => {
155
+ console.log(err);
156
+ });
157
+ }
158
+
159
+
160
+ const createCollection = (data) => {
161
+ return new Promise((resolve, reject) => {
162
+ let openRequest = indexedDB.open(data.database);
163
+
164
+ openRequest.onsuccess = function() {
165
+ let db = openRequest.result;
166
+ if (!db.objectStoreNames.contains(data.collection)) {
167
+ let version = openRequest.result.version
168
+ db.close()
169
+
170
+ let request = indexedDB.open(data.database, Number(version += 1));
171
+ request.onupgradeneeded = function() {
172
+ db = request.result;
173
+ db.createObjectStore(data.collection, {keyPath: '_id', autoIncrement: true});
174
+ };
175
+
176
+ request.onsuccess = function() {
177
+ resolve(request.result)
178
+ };
179
+
180
+ request.onerror = function() {
181
+ console.log("Error", request.error);
182
+ reject(request.error)
183
+ };
184
+
185
+ } else {
186
+ resolve(db)
187
+ }
188
+ };
189
+
190
+ openRequest.onerror = function() {
191
+ reject(openRequest.error)
192
+ };
193
+
194
+ }, (err) => {
195
+ console.log(err);
196
+ });
197
+ }
198
+
199
+ const readCollections = (data) => {
200
+ return new Promise((resolve, reject) => {
201
+ let openRequest = indexedDB.open(data.database);
202
+
203
+ openRequest.onsuccess = function() {
204
+ let db = openRequest.result;
205
+ let collections = db.objectStoreNames
206
+ resolve(collections)
207
+ }
208
+
209
+ openRequest.onerror = function() {
210
+ reject(openRequest.error)
211
+ };
212
+
213
+ }, (err) => {
214
+ console.log(err);
215
+ });
216
+ }
217
+
218
+ const updateCollection = (data) => {
219
+ return new Promise((resolve, reject) => {
220
+ let openRequest = indexedDB.open(data.dastabase);
221
+
222
+ openRequest.onsuccess = function() {
223
+ let db = openRequest.result;
224
+ if (db.objectStoreNames.contains(data.collection)) {
225
+ let version = openRequest.result.version
226
+ db.close()
227
+
228
+ let request = indexedDB.open(data.dastabase, Number(version += 1));
229
+ request.onupgradeneeded = function() {
230
+ let db = request.result;
231
+ let transaction = db.transaction([data.collection], "readonly");
232
+ let collection = transaction.objectStore(data.collection);
233
+ collection.name = data.newCollection
234
+ }
235
+
236
+ request.onsuccess = function() {
237
+ db.close()
238
+ resolve(request.result)
239
+ };
240
+
241
+ request.onerror = function() {
242
+ reject(request.error)
243
+ };
244
+
245
+ } else {
246
+ db.createObjectStore(data.newCollection, {keyPath: '_id', autoIncrement: true})
247
+ resolve(data.newCollection)
248
+ }
249
+ };
250
+
251
+ openRequest.onerror = function() {
252
+ reject(openRequest.error)
253
+ };
254
+
255
+ }, (err) => {
256
+ console.log(err);
257
+ });
258
+ }
259
+
260
+ const deleteCollection = (data) => {
261
+ return new Promise((resolve, reject) => {
262
+ let openRequest = indexedDB.open(data.database);
263
+
264
+ openRequest.onsuccess = function() {
265
+ let db = openRequest.result;
266
+ if (db.objectStoreNames.contains(data.collection)) {
267
+ let version = openRequest.result.version
268
+ db.close()
269
+
270
+ let request = indexedDB.open(data.database, Number(version += 1));
271
+ request.onupgradeneeded = function() {
272
+ db = request.result;
273
+ db.deleteObjectStore(data.collection)
274
+ }
275
+
276
+ request.onsuccess = function() {
277
+ // let db = request.result;
278
+ db.close()
279
+ resolve(data.collection)
280
+ };
281
+
282
+ request.onerror = function() {
283
+ reject(request.error)
284
+ };
285
+
286
+ };
287
+ };
288
+
289
+ openRequest.onerror = function() {
290
+ reject(openRequest.error)
291
+ };
292
+
293
+ }, (err) => {
294
+ console.log(err);
295
+ });
296
+ }
297
+
298
+ const createIndex = (data) => {
299
+ return new Promise((resolve, reject) => {
300
+ let openRequest = indexedDB.open(data.database);
301
+
302
+ openRequest.onsuccess = function() {
303
+ let db = openRequest.result;
304
+ let transaction = db.transaction([data.collection], "readonly");
305
+ let collection = transaction.objectStore(data.collection);
306
+
307
+ if (!collection.indexNames.contains(data.name)){
308
+ let version = openRequest.result.version
309
+ db.close()
310
+
311
+ let request = indexedDB.open(data.database, Number(version += 1));
312
+ request.onupgradeneeded = function() {
313
+ db = request.result;
314
+ transaction = db.transaction([data.collection], "readonly");
315
+ collection = transaction.objectStore(data.collection);
316
+ collection.createIndex(data.name, data.name, {unique: false})
317
+ }
318
+
319
+ request.onsuccess = function() {
320
+ db.close()
321
+ resolve('index created')
322
+ };
323
+
324
+ request.onerror = function() {
325
+ reject(request.error)
326
+ };
327
+
328
+ } else {
329
+ resolve('index created')
330
+ }
331
+ };
332
+
333
+ openRequest.onerror = function() {
334
+ reject(openRequest.error)
335
+ };
336
+ })
337
+
338
+
339
+ }
340
+ const readIndex = (data) => {
341
+ return new Promise((resolve, reject) => {
342
+ let openRequest = indexedDB.open(data.database);
343
+
344
+ openRequest.onsuccess = function() {
345
+ let db = openRequest.result;
346
+ let transaction = db.transaction([data.collection], "readonly");
347
+ let collection = transaction.objectStore(data.collection);
348
+ let indexes = collection.indexNames
349
+ db.close()
350
+ resolve(indexes)
351
+ };
352
+
353
+ openRequest.onerror = function() {
354
+ reject(openRequest.error)
355
+ };
356
+ })
357
+
358
+ }
359
+
360
+ const updateIndex = (data) => {
361
+ return new Promise((resolve, reject) => {
362
+ let openRequest = indexedDB.open(data.database);
363
+
364
+ openRequest.onsuccess = function() {
365
+ let db = openRequest.result;
366
+ let transaction = db.transaction([data.collection], "readonly");
367
+ let collection = transaction.objectStore(data.collection);
368
+
369
+ if (collection.indexNames.contains(data.oldName)){
370
+ let version = openRequest.result.version
371
+ db.close()
372
+
373
+ let request = indexedDB.open(data.database, Number(version += 1));
374
+ request.onupgradeneeded = function() {
375
+ db = request.result;
376
+ transaction = db.transaction([data.collection], "readonly");
377
+ collection = transaction.objectStore(data.collection);
378
+ let index = store.index(data.oldName);
379
+ index.name = data.newName;
380
+ }
381
+
382
+ request.onsuccess = function() {
383
+ let db = request.result;
384
+ db.close()
385
+ resolve('index does not exist')
386
+ };
387
+
388
+ request.onerror = function() {
389
+ reject(request.error)
390
+ };
391
+
392
+ } else {
393
+ collection.createIndex(data.newName, data.newName, {unique: false})
394
+ db.close()
395
+ resolve('index does not exist')
396
+ }
397
+ };
398
+
399
+ openRequest.onerror = function() {
400
+ reject(openRequest.error)
401
+ };
402
+ })
403
+
404
+ }
405
+ const deleteIndex = (data) => {
406
+ return new Promise((resolve, reject) => {
407
+ let openRequest = indexedDB.open(data.database);
408
+
409
+ openRequest.onsuccess = function() {
410
+ let db = openRequest.result;
411
+ let transaction = db.transaction([data.collection], "readonly");
412
+ let collection = transaction.objectStore(data.collection);
413
+
414
+ if (collection.indexNames.contains(data.name)){
415
+ let version = openRequest.result.version
416
+ db.close()
417
+
418
+ let request = indexedDB.open(data.database, Number(version += 1));
419
+ request.onupgradeneeded = function() {
420
+ db = request.result;
421
+ transaction = db.transaction([data.collection], "readonly");
422
+ collection = transaction.objectStore(data.collection);
423
+ collection.deleteIndex(data.name)
424
+ }
425
+
426
+ request.onsuccess = function() {
427
+ let db = request.result;
428
+ db.close()
429
+ resolve('index does not exist')
430
+ };
431
+
432
+ request.onerror = function() {
433
+ reject(request.error)
434
+ };
435
+
436
+ } else {
437
+ db.close()
438
+ resolve('index does not exist')
439
+ }
440
+ };
441
+
442
+ openRequest.onerror = function() {
443
+ reject(openRequest.error)
444
+ };
445
+ })
446
+
447
+ }
448
+
449
+ const createDocument = (data) => {
450
+ return new Promise((resolve, reject) => {
451
+ database(data).then((db) => {
452
+ let transaction = db.transaction([data.collection], "readwrite");
453
+ let collection = transaction.objectStore(data.collection);
454
+ if (!data.data._id)
455
+ data.data['_id'] = ObjectId()
456
+ let request = collection.add(data.data);
457
+
458
+ request.onsuccess = function() {
459
+ db.close()
460
+ resolve(data)
461
+ };
462
+
463
+ request.onerror = function() {
464
+ db.close()
465
+ reject(request.error)
466
+ };
467
+
468
+ }, (err) => {
469
+ console.log(err);
470
+ })
471
+ })
472
+ }
473
+
474
+ const readDocument = (data) => {
475
+ return new Promise((resolve, reject) => {
476
+ let openRequest = indexedDB.open(data.database);
477
+
478
+ openRequest.onsuccess = function() {
479
+ let db = openRequest.result;
480
+ let transaction = db.transaction([data.collection], "readwrite");
481
+ let collection = transaction.objectStore(data.collection);
482
+ let request = collection.get(data.data._id);
483
+
484
+ request.onsuccess = function() {
485
+ db.close()
486
+ resolve(request.result)
487
+ };
488
+
489
+ request.onerror = function() {
490
+ db.close()
491
+ reject(request.error)
492
+ };
493
+ };
494
+
495
+ openRequest.onerror = function() {
496
+ reject(openRequest.error)
497
+ };
498
+ })
499
+ }
500
+
501
+ const updateDocument = (data) => {
502
+ return new Promise((resolve, reject) => {
503
+ database(data).then((db) => {
504
+ let transaction = db.transaction([data.collection], "readwrite");
505
+ let collection = transaction.objectStore(data.collection);
506
+
507
+ if (!data.data._id && data.upsert == true) {
508
+ data.data['_id'] = ObjectId()
509
+ document = false
510
+ }
511
+ if (!data.data._id) {
512
+ db.close()
513
+ resolve(data['error'] = 'requires _id')
514
+ } else {
515
+ let get = collection.get(data.data._id)
516
+ get.onsuccess = function() {;
517
+ // ToDo: merge objects and update using dot notation
518
+ if (get.result || data.upsert == true) {
519
+ data.data = dotNotationToObject(data.data, get.result)
520
+ let put = collection.put(data.data);
521
+
522
+ put.onsuccess = function() {
523
+ db.close()
524
+ resolve(data)
525
+ };
526
+
527
+ put.onerror = function() {
528
+ db.close()
529
+ reject(put.error)
530
+ };
531
+ } else {
532
+ db.close()
533
+ reject('document doest not exist and upsert is not true')
534
+ }
535
+ };
536
+
537
+ get.onerror = function() {
538
+ db.close()
539
+ reject(get.error)
540
+ };
541
+ }
542
+ })
543
+ })
544
+ }
545
+
546
+ const deleteDocument = (data) => {
547
+ return new Promise((resolve, reject) => {
548
+ let openRequest = indexedDB.open(data.database);
549
+
550
+ openRequest.onsuccess = function() {
551
+ let db = openRequest.result;
552
+ let transaction = db.transaction([data.collection], "readwrite");
553
+ let collection = transaction.objectStore(data.collection);
554
+
555
+ let request = collection.delete(data.data._id);
556
+
557
+ request.onsuccess = function() {
558
+ db.close()
559
+ resolve(data)
560
+ };
561
+
562
+ request.onerror = function() {
563
+ db.close()
564
+ reject(request.error)
565
+ };
566
+ }
567
+ openRequest.onerror = function() {
568
+ reject(openRequest.error)
569
+ };
570
+ })
571
+ }
572
+
573
+ const readDocuments = (data) => {
574
+ return new Promise((resolve, reject) => {
575
+ let openRequest = indexedDB.open(data.database);
576
+
577
+ openRequest.onsuccess = function() {
578
+ let db = openRequest.result;
579
+ let transaction = db.transaction([data.collection], "readonly");
580
+ let collection = transaction.objectStore(data.collection);
581
+ let results = [];
582
+ // for (let filter of data.filters) {
583
+ // if (!collection.indexNames.contains(filter.name)) {
584
+ // db.close()
585
+ // createIndex(data.database, data.collection, filter.name).then(() => {
586
+ // database(data).then((db) => {
587
+ // let transaction = db.transaction([data.collection], "readonly");
588
+ // transaction.oncomplete = resolve(results);
589
+
590
+ // let collection = transaction.objectStore(data.collection);
591
+ // collection = transaction.objectStore(data.collection);
592
+
593
+ // let index = collection.index(filter.name);
594
+ // let request = index.openCursor(IDBKeyRange.upperBound(filter.value));
595
+
596
+ // // called for each record
597
+ // request.onsuccess = function() {
598
+ // let isFilter;
599
+ // let cursor = request.result;
600
+ // if (cursor) {
601
+ // let value = cursor.value;
602
+ // if (data.filter)
603
+ // isFilter = filter.queryData(value, data.filter);
604
+ // if (isFilter)
605
+ // results.push(value)
606
+ // cursor.continue();
607
+ // } else {
608
+ // console.log("No more documents");
609
+ // }
610
+ // };
611
+
612
+ // request.onerror = function() {
613
+ // reject(request.error)
614
+ // };
615
+
616
+ // });
617
+ // });
618
+ // } else {
619
+ // let index = collection.index(filter.name);
620
+ // let request = index.openCursor(IDBKeyRange.upperBound(filter.value));
621
+ let request = collection.openCursor();
622
+ transaction.oncomplete = resolve(results);
623
+
624
+ request.onsuccess = function() {
625
+ let isFilter;
626
+ let cursor = request.result;
627
+ if (cursor) {
628
+ let value = cursor.value;
629
+ if (data.filter && data.filter.query)
630
+ isFilter = queryData(value, data.filter.query);
631
+ if (isFilter !== false)
632
+ results.push(value)
633
+ cursor.continue();
634
+ } else {
635
+ if (data.filter) {
636
+ if (data.filter.search)
637
+ data.data = searchData(results, data.filter)
638
+ if (data.filter.sort)
639
+ data.data = sortData(data.data, data.filter.sort)
640
+ }
641
+ resolve(data)
642
+ }
643
+ };
644
+
645
+ request.onerror = function() {
646
+ reject(request.error)
647
+ };
648
+ // }
649
+ // }
650
+ };
651
+
652
+ openRequest.onerror = function() {
653
+ reject(openRequest.error)
654
+ };
655
+ })
656
+ }
657
+
658
+
659
+ const ObjectId = (rnd = r16 => Math.floor(r16).toString(16)) =>
660
+ rnd(Date.now()/1000) + ' '.repeat(16).replace(/./g, () => rnd(Math.random()*16));
661
+
662
+ function init() {
663
+ // Check for support.
664
+ if (!('indexedDB' in window)) {
665
+ console.log("This browser doesn't support IndexedDB.");
666
+ return;
667
+ }
668
+ }
669
+
670
+ init();
671
+
672
+ export default {
673
+ database,
674
+ createDatabase,
675
+ readDatabase,
676
+ readDatabases,
677
+ updateDatabase,
678
+ deleteDatabase,
679
+
680
+ createCollection,
681
+ readCollections,
682
+ updateCollection,
683
+ deleteCollection,
684
+
685
+ createIndex,
686
+ readIndex,
687
+ updateIndex,
688
+ deleteIndex,
689
+
690
+ createDocument,
691
+ readDocument,
692
+ readDocuments,
693
+ updateDocument,
694
+ deleteDocument,
695
+
696
+ ObjectId
697
+ };