w-orm-lowdb 1.0.12 → 1.0.14
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/README.md +121 -15
- package/dist/w-orm-lowdb.umd.js +2 -2
- package/dist/w-orm-lowdb.umd.js.map +1 -1
- package/docs/WOrmLowdb.html +628 -27
- package/docs/WOrmLowdb.mjs.html +1068 -779
- package/docs/index.html +2 -2
- package/g-basic.mjs +203 -185
- package/package.json +3 -3
- package/src/WOrmLowdb.mjs +1066 -777
- package/test/lib/procConcurrency.mjs +53 -0
- package/test/unit-autogenpk.test.mjs +205 -0
- package/test/{basic.test.mjs → unit-basic.test.mjs} +51 -54
- package/test/{cache.test.mjs → unit-cache.test.mjs} +2 -2
- package/test/unit-concurrency.test.mjs +140 -0
- package/test/unit-del.test.mjs +140 -0
- package/test/unit-delall.test.mjs +153 -0
- package/test/unit-event.test.mjs +252 -0
- package/test/unit-insert.test.mjs +120 -0
- package/test/unit-insertbulk.test.mjs +188 -0
- package/test/unit-returnlist.test.mjs +159 -0
- package/test/unit-save.test.mjs +199 -0
- package/test/unit-selectbypk.test.mjs +121 -0
- package/toolg/gDistRollup.mjs +3 -3
package/docs/WOrmLowdb.mjs.html
CHANGED
|
@@ -29,7 +29,7 @@
|
|
|
29
29
|
<nav >
|
|
30
30
|
|
|
31
31
|
|
|
32
|
-
<h2><a href="index.html">Home</a></h2><h3>Classes</h3><ul><li><a href="WOrmLowdb.html">WOrmLowdb</a><ul class='methods'><li data-type='method'><a href="WOrmLowdb.html#.delAllCore">delAllCore</a></li><li data-type='method'><a href="WOrmLowdb.html#.delCore">delCore</a></li><li data-type='method'><a href="WOrmLowdb.html#.insertCore">insertCore</a></li><li data-type='method'><a href="WOrmLowdb.html#.saveCore">saveCore</a></li><li data-type='method'><a href="WOrmLowdb.html#.selectCore">selectCore</a></li></ul></li></ul>
|
|
32
|
+
<h2><a href="index.html">Home</a></h2><h3>Classes</h3><ul><li><a href="WOrmLowdb.html">WOrmLowdb</a><ul class='methods'><li data-type='method'><a href="WOrmLowdb.html#.delAllCore">delAllCore</a></li><li data-type='method'><a href="WOrmLowdb.html#.delCore">delCore</a></li><li data-type='method'><a href="WOrmLowdb.html#.insertBulkCore">insertBulkCore</a></li><li data-type='method'><a href="WOrmLowdb.html#.insertCore">insertCore</a></li><li data-type='method'><a href="WOrmLowdb.html#.saveCore">saveCore</a></li><li data-type='method'><a href="WOrmLowdb.html#.selectByPkCore">selectByPkCore</a></li><li data-type='method'><a href="WOrmLowdb.html#.selectCore">selectCore</a></li><li data-type='method'><a href="WOrmLowdb.html#~serialize">serialize</a></li></ul></li></ul>
|
|
33
33
|
|
|
34
34
|
</nav>
|
|
35
35
|
|
|
@@ -45,783 +45,1072 @@
|
|
|
45
45
|
|
|
46
46
|
<section>
|
|
47
47
|
<article>
|
|
48
|
-
<pre class="prettyprint source linenums"><code>import path from 'path'
|
|
49
|
-
import
|
|
50
|
-
import {
|
|
51
|
-
import {
|
|
52
|
-
import
|
|
53
|
-
import
|
|
54
|
-
import
|
|
55
|
-
import
|
|
56
|
-
import merge from 'lodash-es/merge.js'
|
|
57
|
-
import isEqual from 'lodash-es/isEqual.js'
|
|
58
|
-
import size from 'lodash-es/size.js'
|
|
59
|
-
import cloneDeep from 'lodash-es/cloneDeep.js'
|
|
60
|
-
import
|
|
61
|
-
import
|
|
62
|
-
import
|
|
63
|
-
import
|
|
64
|
-
import
|
|
65
|
-
import
|
|
66
|
-
import
|
|
67
|
-
import
|
|
68
|
-
import
|
|
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
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
//
|
|
111
|
-
let
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
//
|
|
120
|
-
let
|
|
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
|
-
let
|
|
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
|
-
return
|
|
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
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
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
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
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
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
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
|
-
if (!
|
|
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
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
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
|
-
let b = false
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
//
|
|
704
|
-
let
|
|
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
|
-
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
|
|
784
|
-
|
|
785
|
-
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
|
|
790
|
-
|
|
791
|
-
|
|
792
|
-
|
|
793
|
-
|
|
794
|
-
|
|
795
|
-
|
|
796
|
-
|
|
797
|
-
|
|
798
|
-
|
|
799
|
-
|
|
800
|
-
|
|
801
|
-
|
|
802
|
-
|
|
803
|
-
|
|
804
|
-
|
|
805
|
-
}
|
|
806
|
-
|
|
807
|
-
|
|
808
|
-
|
|
809
|
-
|
|
810
|
-
|
|
811
|
-
|
|
812
|
-
|
|
813
|
-
|
|
814
|
-
|
|
815
|
-
|
|
816
|
-
|
|
817
|
-
|
|
818
|
-
|
|
819
|
-
|
|
820
|
-
|
|
821
|
-
|
|
822
|
-
|
|
823
|
-
|
|
824
|
-
|
|
48
|
+
<pre class="prettyprint source linenums"><code>import path from 'path'
|
|
49
|
+
import { Low } from 'lowdb'
|
|
50
|
+
import { JSONFile } from 'lowdb/node'
|
|
51
|
+
import { Query } from 'mingo'
|
|
52
|
+
import get from 'lodash-es/get.js'
|
|
53
|
+
import each from 'lodash-es/each.js'
|
|
54
|
+
import map from 'lodash-es/map.js'
|
|
55
|
+
import filter from 'lodash-es/filter.js'
|
|
56
|
+
import merge from 'lodash-es/merge.js'
|
|
57
|
+
import isEqual from 'lodash-es/isEqual.js'
|
|
58
|
+
import size from 'lodash-es/size.js'
|
|
59
|
+
import cloneDeep from 'lodash-es/cloneDeep.js'
|
|
60
|
+
import evem from 'wsemi/src/evem.mjs'
|
|
61
|
+
import genIDSeq from 'wsemi/src/genIDSeq.mjs'
|
|
62
|
+
import pmSeries from 'wsemi/src/pmSeries.mjs'
|
|
63
|
+
import isarr from 'wsemi/src/isarr.mjs'
|
|
64
|
+
import isbol from 'wsemi/src/isbol.mjs'
|
|
65
|
+
import isestr from 'wsemi/src/isestr.mjs'
|
|
66
|
+
import iseobj from 'wsemi/src/iseobj.mjs'
|
|
67
|
+
import isearr from 'wsemi/src/isearr.mjs'
|
|
68
|
+
import haskey from 'wsemi/src/haskey.mjs'
|
|
69
|
+
|
|
70
|
+
|
|
71
|
+
//kpGqueue, 以資料庫檔案路徑為鍵之全域序列化佇列, 詳見下方serialize說明
|
|
72
|
+
let kpGqueue = {}
|
|
73
|
+
|
|
74
|
+
|
|
75
|
+
/**
|
|
76
|
+
* 操作資料庫(lowdb)
|
|
77
|
+
*
|
|
78
|
+
* 回傳物件為EventEmitter,除各操作函數外另發出change與error兩事件,供呼叫端於單一處集中觀察資料異動與失敗。
|
|
79
|
+
* 事件僅為附加通知,其所送出之資訊皆另有正規管道(操作結果經resolve、整批性錯誤經reject、逐筆失敗經該筆之err欄位),
|
|
80
|
+
* 故不監聽亦能取得完整資訊,且監聽與否不改變任何操作之回傳值。
|
|
81
|
+
*
|
|
82
|
+
* change事件,參數為(mode, data, res),於資料實際異動成功後發出:
|
|
83
|
+
* mode為操作別字串,可為'insert'、'insertBulk'、'save'、'del'、'delAll';save內若逐筆走自動插入則該筆另發出mode為'insert'之事件。
|
|
84
|
+
* data為本次操作之輸入數據,delAll固定為null。
|
|
85
|
+
* res為本次操作之回傳結果。
|
|
86
|
+
* 逐筆函數以整批為單位發出一次而不逐筆發出,select與selectByPk不發出本事件。
|
|
87
|
+
*
|
|
88
|
+
* error事件,參數為(mode, data, err),於操作發生錯誤時發出:
|
|
89
|
+
* mode為操作別字串,可為'select'、'selectByPk'、'insert'、'insertBulk'、'save'、'del'、'delAll'。
|
|
90
|
+
* data為本次操作之輸入數據,無輸入數據者為null。
|
|
91
|
+
* err為錯誤訊息字串,內容與正規管道所送出者一致。
|
|
92
|
+
* 整批性錯誤於reject之前發出;逐筆失敗於該筆結果定案後發出,每筆一次。
|
|
93
|
+
* 註: 逐筆失敗時整批仍resolve,故收到本事件不表示該次呼叫失敗;正常結果(如查無數據、主鍵未命中、全數已存在)不發出本事件。
|
|
94
|
+
*
|
|
95
|
+
* 註: 本套件之主鍵欄位固定為id,尚未支援指定其他欄位為主鍵。
|
|
96
|
+
* 註: 本套件之寫入為[整檔讀出、記憶體修改、整檔寫回],其原子性由行程內之序列化佇列提供,
|
|
97
|
+
* 故僅單一行程內併發成立,跨行程併發不成立,詳見README之併發保證宣告。
|
|
98
|
+
*
|
|
99
|
+
* @class
|
|
100
|
+
* @param {Object} [opt={}] 輸入設定物件,預設{}
|
|
101
|
+
* @param {String} [opt.url='./db.json'] 輸入資料庫位置字串,預設'./db.json'
|
|
102
|
+
* @param {String} [opt.db='worm'] 輸入使用資料庫名稱字串,預設'worm'
|
|
103
|
+
* @param {String} [opt.cl='test'] 輸入使用資料表名稱字串,預設'test'
|
|
104
|
+
* @param {Boolean} [opt.useCache=false] 輸入是否使用select快取,適用於單程序操作,預設false
|
|
105
|
+
* @param {Boolean} [opt.autoGenPk=true] 輸入insert、insertBulk與save於數據未帶有效主鍵(本套件為id欄位)時是否自動產生主鍵值,預設true;給false代表主鍵改由呼叫端自備,套件不產生亦不檢查其唯一性與格式,未帶有效主鍵者將reject
|
|
106
|
+
* @returns {Object} 回傳操作資料庫物件,各事件功能詳見說明
|
|
107
|
+
*/
|
|
108
|
+
function WOrmLowdb(opt = {}) {
|
|
109
|
+
|
|
110
|
+
//_cache
|
|
111
|
+
let _cache = null
|
|
112
|
+
|
|
113
|
+
//url
|
|
114
|
+
let url = get(opt, 'url')
|
|
115
|
+
if (!isestr(url)) {
|
|
116
|
+
url = './db.json'
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
//db
|
|
120
|
+
let db = get(opt, 'db')
|
|
121
|
+
if (!isestr(db)) {
|
|
122
|
+
db = 'worm'
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
//cl
|
|
126
|
+
let cl = get(opt, 'cl')
|
|
127
|
+
if (!isestr(cl)) {
|
|
128
|
+
cl = 'test'
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
//useCache
|
|
132
|
+
let useCache = get(opt, 'useCache')
|
|
133
|
+
if (!isbol(useCache)) {
|
|
134
|
+
useCache = false
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
//autoGenPk, 主鍵由誰產生為整個資料表之政策, 故為建構層設定, 不可於各寫入函數之option逐次覆寫,
|
|
138
|
+
//否則同一資料表將混入兩種來源之主鍵而難以追溯
|
|
139
|
+
let autoGenPk = get(opt, 'autoGenPk')
|
|
140
|
+
if (!isbol(autoGenPk)) {
|
|
141
|
+
autoGenPk = true
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
//key
|
|
145
|
+
let key = `${db}:${cl}`
|
|
146
|
+
|
|
147
|
+
//adapter
|
|
148
|
+
let adapter = new JSONFile(url)
|
|
149
|
+
|
|
150
|
+
//lowdb
|
|
151
|
+
let lowdb = new Low(adapter, {})
|
|
152
|
+
|
|
153
|
+
//ee
|
|
154
|
+
let ee = evem() //採eventemitter3, 其於'error'無監聽者時僅回傳false而不拋出, 故操作行為不因監聽者之有無而改變
|
|
155
|
+
|
|
156
|
+
//gkey, 基於url也就是以檔案路徑為準, 同檔案路徑須使用同一佇列
|
|
157
|
+
let gkey = path.resolve(url)
|
|
158
|
+
|
|
159
|
+
//佇列初始化, 同一資料庫檔案之全部操作一律序列化
|
|
160
|
+
if (!haskey(kpGqueue, gkey)) {
|
|
161
|
+
kpGqueue[gkey] = Promise.resolve()
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
/**
|
|
165
|
+
* 序列化同一資料庫檔案之操作
|
|
166
|
+
*
|
|
167
|
+
* 本套件之寫入為[整檔讀出、記憶體修改、整檔寫回],lowdb無條件寫入亦無比較並交換,
|
|
168
|
+
* 故insert之[檢查主鍵不存在與寫入]與save之[查找主鍵與更新或插入],其原子性只能由行程內之序列化達成。
|
|
169
|
+
* 採Promise鏈而非[布林旗標配合輪詢等待],係因後者之[檢查旗標]與[設定旗標]之間隔有await,
|
|
170
|
+
* 並非原子之test-and-set,多個等候者之輪詢若落在同一批timer觸發即會同時進入臨界區;
|
|
171
|
+
* 且輪詢函數逾時後為resolve而非reject,等滿即照樣放行。Promise鏈為嚴格FIFO且無逾時放行,由結構保證互斥。
|
|
172
|
+
* select亦納入序列化,令其不致與寫入之整檔替換交錯。
|
|
173
|
+
*
|
|
174
|
+
* 註: 佇列為module層之變數,僅同一行程內共享,故跨行程併發不受此保護。
|
|
175
|
+
*/
|
|
176
|
+
let serialize = (fn) => {
|
|
177
|
+
|
|
178
|
+
//pmPrev, 恆為已攔截錯誤之Promise, 故前一次操作失敗不會中斷佇列
|
|
179
|
+
let pmPrev = kpGqueue[gkey]
|
|
180
|
+
|
|
181
|
+
//pm
|
|
182
|
+
let pm = pmPrev.then(() => {
|
|
183
|
+
return fn()
|
|
184
|
+
})
|
|
185
|
+
|
|
186
|
+
//update, 存入已攔截錯誤者, 避免本次reject成為unhandled
|
|
187
|
+
kpGqueue[gkey] = pm.catch(() => {})
|
|
188
|
+
|
|
189
|
+
return pm
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
//emitChange, 資料實際異動成功後發出, 事件僅為附加通知不承擔回傳義務
|
|
193
|
+
//一律包try/catch, 令訂閱函數自身拋錯不影響本次操作之結果
|
|
194
|
+
let emitChange = (mode, data, res) => {
|
|
195
|
+
try {
|
|
196
|
+
ee.emit('change', mode, data, res)
|
|
197
|
+
}
|
|
198
|
+
catch (err) {
|
|
199
|
+
console.log(err)
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
//emitError, 操作發生錯誤時發出, 錯誤訊息一律轉為字串
|
|
204
|
+
let emitError = (mode, data, err) => {
|
|
205
|
+
try {
|
|
206
|
+
ee.emit('error', mode, data, getErrMsg(err))
|
|
207
|
+
}
|
|
208
|
+
catch (errEmit) {
|
|
209
|
+
console.log(errEmit)
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
//getErrMsg, 取錯誤訊息字串, 供逐筆結果之err欄位與error事件使用
|
|
214
|
+
let getErrMsg = (err) => {
|
|
215
|
+
let m = get(err, 'message')
|
|
216
|
+
if (isestr(m)) {
|
|
217
|
+
return m
|
|
218
|
+
}
|
|
219
|
+
return String(err)
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
//procPk, 依autoGenPk處理各數據之主鍵, 供insert、insertBulk與save共用
|
|
223
|
+
//autoGenPk為true時補值; 為false時不補值, 未帶有效主鍵者屬呼叫端未履行契約, 拋出為整批性錯誤,
|
|
224
|
+
//且檢查於任何寫入之前完成, 故不會有部份筆數已寫入而整批失敗之情形
|
|
225
|
+
let procPk = (data, fnName) => {
|
|
226
|
+
if (autoGenPk) {
|
|
227
|
+
return map(data, function(v) {
|
|
228
|
+
if (!isestr(v.id)) {
|
|
229
|
+
v.id = genIDSeq()
|
|
230
|
+
}
|
|
231
|
+
return v
|
|
232
|
+
})
|
|
233
|
+
}
|
|
234
|
+
each(data, function(v, k) {
|
|
235
|
+
if (!isestr(get(v, 'id'))) {
|
|
236
|
+
throw new Error(`can not ${fnName} by data[${k}] without valid id when autoGenPk is false`)
|
|
237
|
+
}
|
|
238
|
+
})
|
|
239
|
+
return data
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
//readData, 讀取資料庫檔案並取得本資料表之陣列
|
|
243
|
+
//註: 使用lowdb.read()初始化後須馬上檢測, 若無key則須先創建空陣列
|
|
244
|
+
let readData = async() => {
|
|
245
|
+
await lowdb.read()
|
|
246
|
+
if (!haskey(lowdb.data, key)) {
|
|
247
|
+
lowdb.data[key] = []
|
|
248
|
+
}
|
|
249
|
+
return lowdb.data[key]
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
//writeData, 以新陣列取代本資料表後寫檔
|
|
253
|
+
//寫檔失敗時還原記憶體狀態, 令reject之後之記憶體與檔案一致,
|
|
254
|
+
//否則殘留之修改會於下次寫入時被一併帶出, 使本應未生效之數據落盤
|
|
255
|
+
let writeData = async(arrOld, arrNew) => {
|
|
256
|
+
lowdb.data[key] = arrNew
|
|
257
|
+
try {
|
|
258
|
+
await lowdb.write()
|
|
259
|
+
}
|
|
260
|
+
catch (err) {
|
|
261
|
+
lowdb.data[key] = arrOld
|
|
262
|
+
throw err
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
//getKpPk, 由數據陣列建立[主鍵值 => {k, v}]之對照表, k為所在索引
|
|
267
|
+
//僅收錄具有效主鍵值者, 令資料表內若有主鍵值無效之殘留數據不致被誤配為命中
|
|
268
|
+
let getKpPk = (ltdt) => {
|
|
269
|
+
let kp = {}
|
|
270
|
+
each(ltdt, (v, k) => {
|
|
271
|
+
let id = get(v, 'id')
|
|
272
|
+
if (isestr(id)) {
|
|
273
|
+
kp[id] = { k, v }
|
|
274
|
+
}
|
|
275
|
+
})
|
|
276
|
+
return kp
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
//getData
|
|
280
|
+
let getData = async() => {
|
|
281
|
+
|
|
282
|
+
//check
|
|
283
|
+
if (useCache && isarr(_cache)) {
|
|
284
|
+
return cloneDeep(_cache) //與外部使用數據脫勾
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
//read
|
|
288
|
+
let ltdt = await readData()
|
|
289
|
+
|
|
290
|
+
//cloneDeep, 數據為lowdb內部的記憶體狀態本體, 須cloneDeep與外部使用數據脫勾
|
|
291
|
+
ltdt = cloneDeep(ltdt)
|
|
292
|
+
|
|
293
|
+
if (useCache) {
|
|
294
|
+
_cache = ltdt
|
|
295
|
+
return cloneDeep(ltdt) //與外部使用數據脫勾
|
|
296
|
+
}
|
|
297
|
+
return ltdt
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
/**
|
|
301
|
+
* 查詢數據
|
|
302
|
+
*
|
|
303
|
+
* @memberOf WOrmLowdb
|
|
304
|
+
* @param {Object} [find={}] 輸入查詢條件物件
|
|
305
|
+
* @returns {Promise} 回傳Promise,resolve回傳數據陣列,無符合數據回傳空陣列,reject回傳錯誤訊息
|
|
306
|
+
*/
|
|
307
|
+
async function selectCore(find = {}) {
|
|
308
|
+
let isErr = false
|
|
309
|
+
|
|
310
|
+
//res
|
|
311
|
+
let res = null
|
|
312
|
+
try {
|
|
313
|
+
|
|
314
|
+
//ltdt
|
|
315
|
+
let ltdt = await getData()
|
|
316
|
+
|
|
317
|
+
//filter
|
|
318
|
+
if (iseobj(find)) {
|
|
319
|
+
|
|
320
|
+
//q
|
|
321
|
+
let q = new Query(find)
|
|
322
|
+
// console.log('q', q)
|
|
323
|
+
|
|
324
|
+
//find
|
|
325
|
+
res = q.find(ltdt).all()
|
|
326
|
+
// console.log('res', res)
|
|
327
|
+
|
|
328
|
+
}
|
|
329
|
+
else {
|
|
330
|
+
res = ltdt
|
|
331
|
+
}
|
|
332
|
+
|
|
333
|
+
//check
|
|
334
|
+
if (!isarr(res)) {
|
|
335
|
+
isErr = true
|
|
336
|
+
res = new Error(`can not select by find[${JSON.stringify(find)}]`)
|
|
337
|
+
}
|
|
338
|
+
|
|
339
|
+
}
|
|
340
|
+
catch (err) {
|
|
341
|
+
isErr = true
|
|
342
|
+
res = err
|
|
343
|
+
}
|
|
344
|
+
|
|
345
|
+
//check
|
|
346
|
+
if (isErr) {
|
|
347
|
+
|
|
348
|
+
//emit, 整批性錯誤須於reject之前發出
|
|
349
|
+
emitError('select', null, res)
|
|
350
|
+
|
|
351
|
+
return Promise.reject(res)
|
|
352
|
+
}
|
|
353
|
+
|
|
354
|
+
return res
|
|
355
|
+
}
|
|
356
|
+
async function select(find = {}) {
|
|
357
|
+
return serialize(() => selectCore(find))
|
|
358
|
+
}
|
|
359
|
+
|
|
360
|
+
/**
|
|
361
|
+
* 由主鍵查詢單筆數據
|
|
362
|
+
* 註: 本套件之主鍵欄位固定為id,尚未支援指定其他欄位為主鍵
|
|
363
|
+
* 註: lowdb無索引,本函數仍須讀取全表,故較select僅省去查詢條件之過濾而無數量級之效能差異,
|
|
364
|
+
* 提供本函數係為與其他w-orm系列套件維持同一組函數
|
|
365
|
+
*
|
|
366
|
+
* @memberOf WOrmLowdb
|
|
367
|
+
* @param {String} pk 輸入主鍵值字串,本套件之主鍵欄位為id
|
|
368
|
+
* @returns {Promise} 回傳Promise,resolve回傳數據物件,若無此主鍵或主鍵值無效則回傳null,reject回傳錯誤訊息
|
|
369
|
+
*/
|
|
370
|
+
async function selectByPkCore(pk) {
|
|
371
|
+
let isErr = false
|
|
372
|
+
|
|
373
|
+
//res
|
|
374
|
+
let res = null
|
|
375
|
+
try {
|
|
376
|
+
|
|
377
|
+
//check
|
|
378
|
+
if (!isestr(pk)) {
|
|
379
|
+
//未給有效主鍵值視為查無數據
|
|
380
|
+
return null
|
|
381
|
+
}
|
|
382
|
+
|
|
383
|
+
//ltdt
|
|
384
|
+
let ltdt = await getData()
|
|
385
|
+
|
|
386
|
+
//查找資料表內pk, 判定基準與insert、insertBulk、save、del內對既有數據之認定一致(皆以id之字串值比對)
|
|
387
|
+
let kp = getKpPk(ltdt)
|
|
388
|
+
let r = get(kp, pk, null)
|
|
389
|
+
|
|
390
|
+
//check
|
|
391
|
+
if (iseobj(r)) {
|
|
392
|
+
res = r.v
|
|
393
|
+
}
|
|
394
|
+
else {
|
|
395
|
+
//不存在此主鍵, 回傳null
|
|
396
|
+
res = null
|
|
397
|
+
}
|
|
398
|
+
|
|
399
|
+
}
|
|
400
|
+
catch (err) {
|
|
401
|
+
isErr = true
|
|
402
|
+
res = err
|
|
403
|
+
}
|
|
404
|
+
|
|
405
|
+
//check
|
|
406
|
+
if (isErr) {
|
|
407
|
+
|
|
408
|
+
//emit, 整批性錯誤須於reject之前發出
|
|
409
|
+
emitError('selectByPk', null, res)
|
|
410
|
+
|
|
411
|
+
return Promise.reject(res)
|
|
412
|
+
}
|
|
413
|
+
|
|
414
|
+
return res
|
|
415
|
+
}
|
|
416
|
+
async function selectByPk(pk) {
|
|
417
|
+
return serialize(() => selectByPkCore(pk))
|
|
418
|
+
}
|
|
419
|
+
|
|
420
|
+
/**
|
|
421
|
+
* 插入數據,僅於主鍵不存在時寫入,已存在者跳過且不覆寫
|
|
422
|
+
*
|
|
423
|
+
* @memberOf WOrmLowdb
|
|
424
|
+
* @param {Object|Array} data 輸入數據物件或陣列
|
|
425
|
+
* @param {Object} [option={}] 輸入設定物件,預設為{}
|
|
426
|
+
* @param {Boolean} [option.returnList=false] 輸入是否改回傳逐筆結果布林值,預設false。給true時回傳與輸入等長保序之陣列,各筆為{n,nInserted,ok},nInserted為1即該筆為新增;聚合計數只回答有幾筆是新的,逐筆結果方能回答是哪幾筆,供下游僅對新資料執行昂貴動作。回傳形式由呼叫點靜態決定,共用之結果處理程式碼不可跨不同取值之呼叫點混用
|
|
427
|
+
* @returns {Promise} 回傳Promise,resolve依returnList回傳插入結果:預設回傳聚合物件{n,nInserted,ok},n為輸入筆數、nInserted為實際插入筆數;returnList為true時回傳逐筆陣列,各筆n恆為1(主鍵命中或經插入)、ok恆為1(insert之錯誤皆屬整批性而reject,不進逐筆);reject回傳錯誤訊息
|
|
428
|
+
*/
|
|
429
|
+
async function insertCore(data, option = {}) {
|
|
430
|
+
let isErr = false
|
|
431
|
+
|
|
432
|
+
//returnList
|
|
433
|
+
let returnList = get(option, 'returnList')
|
|
434
|
+
if (!isbol(returnList)) {
|
|
435
|
+
returnList = false
|
|
436
|
+
}
|
|
437
|
+
|
|
438
|
+
//check
|
|
439
|
+
if (!iseobj(data) && !isearr(data)) {
|
|
440
|
+
if (returnList) {
|
|
441
|
+
//輸入無效, 對齊save與del之空陣列規定
|
|
442
|
+
return []
|
|
443
|
+
}
|
|
444
|
+
return {
|
|
445
|
+
n: 0,
|
|
446
|
+
nInserted: 0,
|
|
447
|
+
ok: 1,
|
|
448
|
+
}
|
|
449
|
+
}
|
|
450
|
+
|
|
451
|
+
//cloneDeep, 與外部數據脫勾
|
|
452
|
+
data = cloneDeep(data)
|
|
453
|
+
|
|
454
|
+
//res
|
|
455
|
+
let res = null
|
|
456
|
+
try {
|
|
457
|
+
|
|
458
|
+
//check
|
|
459
|
+
if (!isarr(data)) {
|
|
460
|
+
data = [data]
|
|
461
|
+
}
|
|
462
|
+
|
|
463
|
+
//check id
|
|
464
|
+
data = procPk(data, 'insert')
|
|
465
|
+
|
|
466
|
+
//read
|
|
467
|
+
let arrOld = await readData()
|
|
468
|
+
|
|
469
|
+
//kp
|
|
470
|
+
let kp = getKpPk(arrOld)
|
|
471
|
+
|
|
472
|
+
//each
|
|
473
|
+
let nAll = size(data)
|
|
474
|
+
let ltdone = []
|
|
475
|
+
let ltpush = []
|
|
476
|
+
each(data, (v) => {
|
|
477
|
+
|
|
478
|
+
//check
|
|
479
|
+
if (!haskey(kp, v.id)) {
|
|
480
|
+
//未存在v.id
|
|
481
|
+
|
|
482
|
+
//push
|
|
483
|
+
ltpush.push(v)
|
|
484
|
+
|
|
485
|
+
//update, 須同步更新kp, 否則同批含重複主鍵者會全數寫入而出現重複主鍵
|
|
486
|
+
kp[v.id] = { k: -1, v }
|
|
487
|
+
|
|
488
|
+
ltdone.push(true)
|
|
489
|
+
}
|
|
490
|
+
else {
|
|
491
|
+
//已存在v.id(含同批重複之非首筆)則不push
|
|
492
|
+
ltdone.push(false)
|
|
493
|
+
}
|
|
494
|
+
|
|
495
|
+
})
|
|
496
|
+
|
|
497
|
+
//write, 未有須插入者即不寫檔, 全數已存在屬正常結果
|
|
498
|
+
if (size(ltpush) > 0) {
|
|
499
|
+
await writeData(arrOld, [...arrOld, ...ltpush])
|
|
500
|
+
}
|
|
501
|
+
|
|
502
|
+
//res
|
|
503
|
+
if (returnList) {
|
|
504
|
+
//逐筆結果, 與輸入等長保序, 元素沿用逐筆結果之家族形狀(同save與del之元素)
|
|
505
|
+
//n恆為1(主鍵命中既有或經插入而產生), ok恆為1(insert之錯誤皆屬整批性而reject, 不進逐筆),
|
|
506
|
+
//資訊由nInserted承載, filter(v=>v.nInserted===1)之長度必等於聚合模式之nInserted
|
|
507
|
+
res = map(ltdone, function(done) {
|
|
508
|
+
return {
|
|
509
|
+
n: 1,
|
|
510
|
+
nInserted: done ? 1 : 0,
|
|
511
|
+
ok: 1,
|
|
512
|
+
}
|
|
513
|
+
})
|
|
514
|
+
}
|
|
515
|
+
else {
|
|
516
|
+
res = {
|
|
517
|
+
n: nAll,
|
|
518
|
+
nInserted: size(ltpush),
|
|
519
|
+
ok: 1,
|
|
520
|
+
}
|
|
521
|
+
}
|
|
522
|
+
|
|
523
|
+
}
|
|
524
|
+
catch (err) {
|
|
525
|
+
isErr = true
|
|
526
|
+
res = err
|
|
527
|
+
}
|
|
528
|
+
|
|
529
|
+
//update, 不能保證插入多少, 一律重設快取
|
|
530
|
+
_cache = null
|
|
531
|
+
|
|
532
|
+
//emit, 於change可能須使用select, 故須放在重設快取之後
|
|
533
|
+
if (!isErr) {
|
|
534
|
+
emitChange('insert', data, res)
|
|
535
|
+
}
|
|
536
|
+
|
|
537
|
+
//check
|
|
538
|
+
if (isErr) {
|
|
539
|
+
|
|
540
|
+
//emit, 整批性錯誤須於reject之前發出
|
|
541
|
+
emitError('insert', data, res)
|
|
542
|
+
|
|
543
|
+
return Promise.reject(res)
|
|
544
|
+
}
|
|
545
|
+
|
|
546
|
+
return res
|
|
547
|
+
}
|
|
548
|
+
async function insert(data, option = {}) {
|
|
549
|
+
return serialize(() => insertCore(data, option))
|
|
550
|
+
}
|
|
551
|
+
|
|
552
|
+
/**
|
|
553
|
+
* 批次插入數據,全批視為一個單位,全部插入成功或一筆都不寫入
|
|
554
|
+
* 註: 本函數非insert之加速版,兩者衝突政策不同。insert於主鍵已存在時跳過該筆而整批ok為1,
|
|
555
|
+
* 本函數則整批reject且不寫入任何一筆;同批含重複主鍵者亦視為衝突。確無衝突時兩者結果相同
|
|
556
|
+
* 註: 於本套件不會較insert快,因兩者皆為一次讀檔與一次寫檔,
|
|
557
|
+
* 提供本函數係為與其他w-orm系列套件維持同一組函數,令呼叫端得於各套件間替換而不須改寫呼叫
|
|
558
|
+
*
|
|
559
|
+
* @memberOf WOrmLowdb
|
|
560
|
+
* @param {Object|Array} data 輸入數據物件或陣列
|
|
561
|
+
* @returns {Promise} 回傳Promise,resolve回傳插入結果物件{n,nInserted,ok},n為輸入筆數、nInserted成功時恆等於n,任一筆主鍵已存在則reject回傳錯誤訊息
|
|
562
|
+
*/
|
|
563
|
+
async function insertBulkCore(data) {
|
|
564
|
+
let isErr = false
|
|
565
|
+
|
|
566
|
+
//check
|
|
567
|
+
if (!iseobj(data) && !isearr(data)) {
|
|
568
|
+
return {
|
|
569
|
+
n: 0,
|
|
570
|
+
nInserted: 0,
|
|
571
|
+
ok: 1,
|
|
572
|
+
}
|
|
573
|
+
}
|
|
574
|
+
|
|
575
|
+
//cloneDeep, 與外部數據脫勾
|
|
576
|
+
data = cloneDeep(data)
|
|
577
|
+
|
|
578
|
+
//res
|
|
579
|
+
let res = null
|
|
580
|
+
try {
|
|
581
|
+
|
|
582
|
+
//check
|
|
583
|
+
if (!isarr(data)) {
|
|
584
|
+
data = [data]
|
|
585
|
+
}
|
|
586
|
+
|
|
587
|
+
//check id
|
|
588
|
+
data = procPk(data, 'insertBulk')
|
|
589
|
+
|
|
590
|
+
//read
|
|
591
|
+
let arrOld = await readData()
|
|
592
|
+
|
|
593
|
+
//kp
|
|
594
|
+
let kp = getKpPk(arrOld)
|
|
595
|
+
|
|
596
|
+
//nAll
|
|
597
|
+
let nAll = size(data)
|
|
598
|
+
|
|
599
|
+
//check, 主鍵檢查於任何寫入之前一次完成, 任一筆衝突即整批中止,
|
|
600
|
+
//同批含重複主鍵者亦於此被偵測為衝突(kp隨檢查同步更新)
|
|
601
|
+
let pkConflict = null
|
|
602
|
+
each(data, (v) => {
|
|
603
|
+
if (haskey(kp, v.id)) {
|
|
604
|
+
pkConflict = v.id
|
|
605
|
+
return false //中止each
|
|
606
|
+
}
|
|
607
|
+
kp[v.id] = { k: -1, v }
|
|
608
|
+
})
|
|
609
|
+
|
|
610
|
+
//check
|
|
611
|
+
if (pkConflict !== null) {
|
|
612
|
+
throw new Error(`can not insertBulk by existed id[${pkConflict}]`)
|
|
613
|
+
}
|
|
614
|
+
|
|
615
|
+
//write, 全部通過檢查方寫入, 且寫檔為單次[寫暫存檔後更名]之原子替換,
|
|
616
|
+
//故全有全無成立: 檢查失敗時尚未修改任何狀態, 寫檔失敗時writeData會還原記憶體
|
|
617
|
+
await writeData(arrOld, [...arrOld, ...data])
|
|
618
|
+
|
|
619
|
+
//res, 未衝突則全數插入, 故nInserted恆等於n
|
|
620
|
+
res = {
|
|
621
|
+
n: nAll,
|
|
622
|
+
nInserted: nAll,
|
|
623
|
+
ok: 1,
|
|
624
|
+
}
|
|
625
|
+
|
|
626
|
+
}
|
|
627
|
+
catch (err) {
|
|
628
|
+
isErr = true
|
|
629
|
+
res = err
|
|
630
|
+
}
|
|
631
|
+
|
|
632
|
+
//update, 不能保證插入多少, 一律重設快取
|
|
633
|
+
_cache = null
|
|
634
|
+
|
|
635
|
+
//emit, 於change可能須使用select, 故須放在重設快取之後
|
|
636
|
+
if (!isErr) {
|
|
637
|
+
emitChange('insertBulk', data, res)
|
|
638
|
+
}
|
|
639
|
+
|
|
640
|
+
//check
|
|
641
|
+
if (isErr) {
|
|
642
|
+
|
|
643
|
+
//emit, 整批性錯誤須於reject之前發出
|
|
644
|
+
emitError('insertBulk', data, res)
|
|
645
|
+
|
|
646
|
+
return Promise.reject(res)
|
|
647
|
+
}
|
|
648
|
+
|
|
649
|
+
return res
|
|
650
|
+
}
|
|
651
|
+
async function insertBulk(data) {
|
|
652
|
+
return serialize(() => insertBulkCore(data))
|
|
653
|
+
}
|
|
654
|
+
|
|
655
|
+
/**
|
|
656
|
+
* 儲存數據,以主鍵為準更新既有數據,未給之欄位保留;主鍵不存在且autoInsert為true時改為插入
|
|
657
|
+
*
|
|
658
|
+
* @memberOf WOrmLowdb
|
|
659
|
+
* @param {Object|Array} data 輸入數據物件或陣列
|
|
660
|
+
* @param {Object} [option={}] 輸入設定物件,預設為{}
|
|
661
|
+
* @param {boolean} [option.autoInsert=true] 輸入是否於儲存時發現原本無數據,則自動改以插入處理,預設為true
|
|
662
|
+
* @returns {Promise} 回傳Promise,resolve回傳與輸入等長之儲存結果陣列,各筆為{n,nInserted,nModified,ok},n為主鍵命中筆數,單筆失敗者ok為0並附err,reject回傳錯誤訊息
|
|
663
|
+
*/
|
|
664
|
+
async function saveCore(data, option = {}) {
|
|
665
|
+
let isErr = false
|
|
666
|
+
|
|
667
|
+
//check
|
|
668
|
+
if (!iseobj(data) && !isearr(data)) {
|
|
669
|
+
return []
|
|
670
|
+
}
|
|
671
|
+
|
|
672
|
+
//cloneDeep, 與外部數據脫勾
|
|
673
|
+
data = cloneDeep(data)
|
|
674
|
+
|
|
675
|
+
//autoInsert
|
|
676
|
+
let autoInsert = get(option, 'autoInsert', true)
|
|
677
|
+
|
|
678
|
+
//res
|
|
679
|
+
let res = null
|
|
680
|
+
try {
|
|
681
|
+
|
|
682
|
+
//check
|
|
683
|
+
if (!isarr(data)) {
|
|
684
|
+
data = [data]
|
|
685
|
+
}
|
|
686
|
+
|
|
687
|
+
//check id
|
|
688
|
+
data = procPk(data, 'save')
|
|
689
|
+
|
|
690
|
+
//read
|
|
691
|
+
let arrOld = await readData()
|
|
692
|
+
|
|
693
|
+
//arrNew, 逐筆修改於複本上進行, 全部完成後方取代與寫檔
|
|
694
|
+
let arrNew = [...arrOld]
|
|
695
|
+
|
|
696
|
+
//kp
|
|
697
|
+
let kp = getKpPk(arrNew)
|
|
698
|
+
|
|
699
|
+
//pmSeries
|
|
700
|
+
let b = false
|
|
701
|
+
res = await pmSeries(data, async(v) => {
|
|
702
|
+
|
|
703
|
+
//rest
|
|
704
|
+
let rest = null
|
|
705
|
+
|
|
706
|
+
try {
|
|
707
|
+
|
|
708
|
+
//查找資料表內v.id
|
|
709
|
+
let r = get(kp, v.id, null)
|
|
710
|
+
|
|
711
|
+
//existed
|
|
712
|
+
let existed = iseobj(r)
|
|
713
|
+
|
|
714
|
+
//check
|
|
715
|
+
if (existed) {
|
|
716
|
+
//已存在v.id
|
|
717
|
+
|
|
718
|
+
//vv, 現值
|
|
719
|
+
let vv = r.v
|
|
720
|
+
|
|
721
|
+
//vm, 合併後之結果, 另建新物件以免污染原數據
|
|
722
|
+
let vm = merge({}, vv, v)
|
|
723
|
+
|
|
724
|
+
//判定基準為[合併後結果與現值相同], 而非[待寫入物件與現值全等],
|
|
725
|
+
//令nModified忠實反映是否真的寫入, 僅給部份欄位且值皆相同者不應回報已修改
|
|
726
|
+
if (isEqual(vm, vv)) {
|
|
727
|
+
//合併後與現值相同不須寫入, 惟已命中v.id故n為1
|
|
728
|
+
rest = {
|
|
729
|
+
n: 1,
|
|
730
|
+
nInserted: 0,
|
|
731
|
+
nModified: 0,
|
|
732
|
+
ok: 1,
|
|
733
|
+
}
|
|
734
|
+
}
|
|
735
|
+
else {
|
|
736
|
+
//合併後與現值不同須更新
|
|
737
|
+
|
|
738
|
+
//update
|
|
739
|
+
arrNew[r.k] = vm
|
|
740
|
+
kp[v.id] = { k: r.k, v: vm }
|
|
741
|
+
|
|
742
|
+
b = true
|
|
743
|
+
|
|
744
|
+
rest = {
|
|
745
|
+
n: 1,
|
|
746
|
+
nInserted: 0,
|
|
747
|
+
nModified: 1,
|
|
748
|
+
ok: 1,
|
|
749
|
+
}
|
|
750
|
+
}
|
|
751
|
+
|
|
752
|
+
}
|
|
753
|
+
else {
|
|
754
|
+
//不存在v.id, 若autoInsert則須插入
|
|
755
|
+
if (autoInsert) {
|
|
756
|
+
|
|
757
|
+
//push
|
|
758
|
+
let k = size(arrNew)
|
|
759
|
+
arrNew.push(v)
|
|
760
|
+
kp[v.id] = { k, v }
|
|
761
|
+
|
|
762
|
+
b = true
|
|
763
|
+
|
|
764
|
+
rest = {
|
|
765
|
+
n: 1,
|
|
766
|
+
nInserted: 1,
|
|
767
|
+
nModified: 0,
|
|
768
|
+
ok: 1,
|
|
769
|
+
}
|
|
770
|
+
|
|
771
|
+
}
|
|
772
|
+
else {
|
|
773
|
+
//未命中且未開啟autoInsert, 未命中故n為0
|
|
774
|
+
rest = {
|
|
775
|
+
n: 0,
|
|
776
|
+
nInserted: 0,
|
|
777
|
+
nModified: 0,
|
|
778
|
+
ok: 1,
|
|
779
|
+
}
|
|
780
|
+
}
|
|
781
|
+
}
|
|
782
|
+
|
|
783
|
+
}
|
|
784
|
+
catch (err) {
|
|
785
|
+
|
|
786
|
+
//本筆失敗不中斷整批, 以ok為0並附err回報, 由呼叫端逐筆檢查
|
|
787
|
+
rest = {
|
|
788
|
+
n: 1,
|
|
789
|
+
nInserted: 0,
|
|
790
|
+
nModified: 0,
|
|
791
|
+
ok: 0,
|
|
792
|
+
err: getErrMsg(err),
|
|
793
|
+
}
|
|
794
|
+
|
|
795
|
+
}
|
|
796
|
+
|
|
797
|
+
return rest
|
|
798
|
+
})
|
|
799
|
+
|
|
800
|
+
//write
|
|
801
|
+
if (b) {
|
|
802
|
+
await writeData(arrOld, arrNew)
|
|
803
|
+
}
|
|
804
|
+
|
|
805
|
+
}
|
|
806
|
+
catch (err) {
|
|
807
|
+
isErr = true
|
|
808
|
+
res = err
|
|
809
|
+
}
|
|
810
|
+
|
|
811
|
+
//update, 不能保證變更多少, 一律重設快取
|
|
812
|
+
_cache = null
|
|
813
|
+
|
|
814
|
+
//emit, 於change可能須使用select, 故須放在重設快取之後
|
|
815
|
+
if (!isErr) {
|
|
816
|
+
|
|
817
|
+
//emit, 逐筆失敗於該筆結果定案後發出, 每筆一次
|
|
818
|
+
//此事件之發出不表示整批失敗, 整批仍resolve, 該筆以ok為0回報
|
|
819
|
+
each(res, (rest, k) => {
|
|
820
|
+
if (get(rest, 'ok') === 0) {
|
|
821
|
+
emitError('save', [get(data, k)], get(rest, 'err'))
|
|
822
|
+
}
|
|
823
|
+
})
|
|
824
|
+
|
|
825
|
+
//emit, 逐筆插入另發出mode為insert之事件, 供呼叫端區辨新增與更新
|
|
826
|
+
//逐筆結果與輸入等長保序, 故由nInserted即可定位係哪幾筆走插入, 不須另行記錄
|
|
827
|
+
each(res, (rest, k) => {
|
|
828
|
+
if (get(rest, 'nInserted') === 1) {
|
|
829
|
+
emitChange('insert', [get(data, k)], rest)
|
|
830
|
+
}
|
|
831
|
+
})
|
|
832
|
+
|
|
833
|
+
//emit, 逐筆失敗之error事件已於上方發出, 故必早於本整批change
|
|
834
|
+
emitChange('save', data, res)
|
|
835
|
+
|
|
836
|
+
}
|
|
837
|
+
|
|
838
|
+
//check
|
|
839
|
+
if (isErr) {
|
|
840
|
+
|
|
841
|
+
//emit, 整批性錯誤須於reject之前發出
|
|
842
|
+
emitError('save', data, res)
|
|
843
|
+
|
|
844
|
+
return Promise.reject(res)
|
|
845
|
+
}
|
|
846
|
+
|
|
847
|
+
return res
|
|
848
|
+
}
|
|
849
|
+
async function save(data, option = {}) {
|
|
850
|
+
return serialize(() => saveCore(data, option))
|
|
851
|
+
}
|
|
852
|
+
|
|
853
|
+
/**
|
|
854
|
+
* 刪除數據,依主鍵刪除
|
|
855
|
+
*
|
|
856
|
+
* @memberOf WOrmLowdb
|
|
857
|
+
* @param {Object|Array} data 輸入數據物件或陣列
|
|
858
|
+
* @returns {Promise} 回傳Promise,resolve回傳與輸入等長之刪除結果陣列,各筆為{n,nDeleted,ok},n為主鍵命中筆數,單筆失敗或未給有效id者ok為0並附err,reject回傳錯誤訊息
|
|
859
|
+
*/
|
|
860
|
+
async function delCore(data) {
|
|
861
|
+
let isErr = false
|
|
862
|
+
|
|
863
|
+
//check
|
|
864
|
+
if (!iseobj(data) && !isearr(data)) {
|
|
865
|
+
return []
|
|
866
|
+
}
|
|
867
|
+
|
|
868
|
+
//cloneDeep, 與外部數據脫勾
|
|
869
|
+
data = cloneDeep(data)
|
|
870
|
+
|
|
871
|
+
//res
|
|
872
|
+
let res = null
|
|
873
|
+
try {
|
|
874
|
+
|
|
875
|
+
//check
|
|
876
|
+
if (!isarr(data)) {
|
|
877
|
+
data = [data]
|
|
878
|
+
}
|
|
879
|
+
|
|
880
|
+
//read
|
|
881
|
+
let arrOld = await readData()
|
|
882
|
+
|
|
883
|
+
//kp
|
|
884
|
+
let kp = getKpPk(arrOld)
|
|
885
|
+
|
|
886
|
+
//pmSeries
|
|
887
|
+
let kpDel = {}
|
|
888
|
+
let b = false
|
|
889
|
+
res = await pmSeries(data, async(v) => {
|
|
890
|
+
|
|
891
|
+
//rest
|
|
892
|
+
let rest = null
|
|
893
|
+
|
|
894
|
+
try {
|
|
895
|
+
|
|
896
|
+
//id
|
|
897
|
+
let id = get(v, 'id', '')
|
|
898
|
+
|
|
899
|
+
//check
|
|
900
|
+
if (!isestr(id)) {
|
|
901
|
+
//未給有效v.id視為該筆數據有問題而無法處理, 以ok為0並附err回報,
|
|
902
|
+
//與[已給v.id但查無數據]之ok為1有別, 二者須可由ok分辨
|
|
903
|
+
//註: 亦不可將無效主鍵送進查詢條件, 故於此直接定案
|
|
904
|
+
rest = {
|
|
905
|
+
n: 0,
|
|
906
|
+
nDeleted: 0,
|
|
907
|
+
ok: 0,
|
|
908
|
+
err: `can not delete by invalid id[${id}]`,
|
|
909
|
+
}
|
|
910
|
+
}
|
|
911
|
+
else {
|
|
912
|
+
|
|
913
|
+
//查找資料表內v.id
|
|
914
|
+
let r = get(kp, id, null)
|
|
915
|
+
|
|
916
|
+
//check
|
|
917
|
+
if (iseobj(r)) {
|
|
918
|
+
//已存在v.id則須刪除
|
|
919
|
+
|
|
920
|
+
//push
|
|
921
|
+
kpDel[r.k] = true
|
|
922
|
+
|
|
923
|
+
//update, 須同步移除, 否則同批重複主鍵者會重複計入nDeleted
|
|
924
|
+
delete kp[id]
|
|
925
|
+
|
|
926
|
+
b = true
|
|
927
|
+
|
|
928
|
+
rest = {
|
|
929
|
+
n: 1,
|
|
930
|
+
nDeleted: 1,
|
|
931
|
+
ok: 1,
|
|
932
|
+
}
|
|
933
|
+
|
|
934
|
+
}
|
|
935
|
+
else {
|
|
936
|
+
//不存在v.id則不刪除, 未命中故n為0
|
|
937
|
+
rest = {
|
|
938
|
+
n: 0,
|
|
939
|
+
nDeleted: 0,
|
|
940
|
+
ok: 1,
|
|
941
|
+
}
|
|
942
|
+
|
|
943
|
+
}
|
|
944
|
+
|
|
945
|
+
}
|
|
946
|
+
|
|
947
|
+
}
|
|
948
|
+
catch (err) {
|
|
949
|
+
|
|
950
|
+
//本筆失敗不中斷整批, 以ok為0並附err回報, 由呼叫端逐筆檢查
|
|
951
|
+
rest = {
|
|
952
|
+
n: 1,
|
|
953
|
+
nDeleted: 0,
|
|
954
|
+
ok: 0,
|
|
955
|
+
err: getErrMsg(err),
|
|
956
|
+
}
|
|
957
|
+
|
|
958
|
+
}
|
|
959
|
+
|
|
960
|
+
return rest
|
|
961
|
+
})
|
|
962
|
+
|
|
963
|
+
//write
|
|
964
|
+
if (b) {
|
|
965
|
+
let arrNew = filter(arrOld, (v, k) => {
|
|
966
|
+
return !haskey(kpDel, k)
|
|
967
|
+
})
|
|
968
|
+
await writeData(arrOld, arrNew)
|
|
969
|
+
}
|
|
970
|
+
|
|
971
|
+
}
|
|
972
|
+
catch (err) {
|
|
973
|
+
isErr = true
|
|
974
|
+
res = err
|
|
975
|
+
}
|
|
976
|
+
|
|
977
|
+
//update, 不能保證刪除多少, 一律重設快取
|
|
978
|
+
_cache = null
|
|
979
|
+
|
|
980
|
+
//emit, 於change可能須使用select, 故須放在重設快取之後
|
|
981
|
+
if (!isErr) {
|
|
982
|
+
|
|
983
|
+
//emit, 逐筆失敗於該筆結果定案後發出, 每筆一次
|
|
984
|
+
//此事件之發出不表示整批失敗, 整批仍resolve, 該筆以ok為0回報
|
|
985
|
+
each(res, (rest, k) => {
|
|
986
|
+
if (get(rest, 'ok') === 0) {
|
|
987
|
+
emitError('del', [get(data, k)], get(rest, 'err'))
|
|
988
|
+
}
|
|
989
|
+
})
|
|
990
|
+
|
|
991
|
+
//emit, 逐筆失敗之error事件已於上方發出, 故必早於本整批change
|
|
992
|
+
emitChange('del', data, res)
|
|
993
|
+
|
|
994
|
+
}
|
|
995
|
+
|
|
996
|
+
//check
|
|
997
|
+
if (isErr) {
|
|
998
|
+
|
|
999
|
+
//emit, 整批性錯誤須於reject之前發出
|
|
1000
|
+
emitError('del', data, res)
|
|
1001
|
+
|
|
1002
|
+
return Promise.reject(res)
|
|
1003
|
+
}
|
|
1004
|
+
|
|
1005
|
+
return res
|
|
1006
|
+
}
|
|
1007
|
+
async function del(data) {
|
|
1008
|
+
return serialize(() => delCore(data))
|
|
1009
|
+
}
|
|
1010
|
+
|
|
1011
|
+
/**
|
|
1012
|
+
* 刪除全部數據,需與del分開,避免未傳數據導致直接刪除全表
|
|
1013
|
+
*
|
|
1014
|
+
* @memberOf WOrmLowdb
|
|
1015
|
+
* @param {Object} [find={}] 輸入刪除條件物件
|
|
1016
|
+
* @returns {Promise} 回傳Promise,resolve回傳刪除結果物件{n,nDeleted,ok},n與nDeleted同為實際刪除筆數,reject回傳錯誤訊息
|
|
1017
|
+
*/
|
|
1018
|
+
async function delAllCore(find = {}) {
|
|
1019
|
+
let isErr = false
|
|
1020
|
+
|
|
1021
|
+
//res
|
|
1022
|
+
let res = null
|
|
1023
|
+
try {
|
|
1024
|
+
|
|
1025
|
+
//read
|
|
1026
|
+
let arrOld = await readData()
|
|
1027
|
+
|
|
1028
|
+
//filter
|
|
1029
|
+
let nAll = size(arrOld)
|
|
1030
|
+
let nDel = 0
|
|
1031
|
+
let arrNew = null
|
|
1032
|
+
if (iseobj(find)) {
|
|
1033
|
+
|
|
1034
|
+
//q
|
|
1035
|
+
let q = new Query(find)
|
|
1036
|
+
// console.log('q', q)
|
|
1037
|
+
|
|
1038
|
+
//filter, 以與select同一條件逐筆判定, 保留未命中者
|
|
1039
|
+
arrNew = filter(arrOld, (v) => {
|
|
1040
|
+
return !q.test(v)
|
|
1041
|
+
})
|
|
1042
|
+
|
|
1043
|
+
//nDel
|
|
1044
|
+
nDel = nAll - size(arrNew)
|
|
1045
|
+
// console.log('nDel', nDel)
|
|
1046
|
+
|
|
1047
|
+
}
|
|
1048
|
+
else {
|
|
1049
|
+
//find未給或為空物件時刪除全部數據
|
|
1050
|
+
|
|
1051
|
+
//nDel
|
|
1052
|
+
nDel = nAll
|
|
1053
|
+
|
|
1054
|
+
//empty
|
|
1055
|
+
arrNew = []
|
|
1056
|
+
|
|
1057
|
+
}
|
|
1058
|
+
|
|
1059
|
+
//write, 無命中即不寫檔, 屬正常結果
|
|
1060
|
+
if (nDel > 0) {
|
|
1061
|
+
await writeData(arrOld, arrNew)
|
|
1062
|
+
}
|
|
1063
|
+
|
|
1064
|
+
//res, n為實際刪除筆數而非全表筆數, 故與nDeleted同值
|
|
1065
|
+
res = {
|
|
1066
|
+
n: nDel,
|
|
1067
|
+
nDeleted: nDel,
|
|
1068
|
+
ok: 1,
|
|
1069
|
+
}
|
|
1070
|
+
|
|
1071
|
+
}
|
|
1072
|
+
catch (err) {
|
|
1073
|
+
isErr = true
|
|
1074
|
+
res = err
|
|
1075
|
+
}
|
|
1076
|
+
|
|
1077
|
+
//update, 不能保證刪除多少, 一律重設快取
|
|
1078
|
+
_cache = null
|
|
1079
|
+
|
|
1080
|
+
//emit, 於change可能須使用select, 故須放在重設快取之後
|
|
1081
|
+
if (!isErr) {
|
|
1082
|
+
emitChange('delAll', null, res)
|
|
1083
|
+
}
|
|
1084
|
+
|
|
1085
|
+
//check
|
|
1086
|
+
if (isErr) {
|
|
1087
|
+
|
|
1088
|
+
//emit, 整批性錯誤須於reject之前發出
|
|
1089
|
+
emitError('delAll', null, res)
|
|
1090
|
+
|
|
1091
|
+
return Promise.reject(res)
|
|
1092
|
+
}
|
|
1093
|
+
|
|
1094
|
+
return res
|
|
1095
|
+
}
|
|
1096
|
+
async function delAll(find = {}) {
|
|
1097
|
+
return serialize(() => delAllCore(find))
|
|
1098
|
+
}
|
|
1099
|
+
|
|
1100
|
+
//bind
|
|
1101
|
+
ee.select = select
|
|
1102
|
+
ee.selectByPk = selectByPk
|
|
1103
|
+
ee.insert = insert
|
|
1104
|
+
ee.insertBulk = insertBulk
|
|
1105
|
+
ee.save = save
|
|
1106
|
+
ee.del = del
|
|
1107
|
+
ee.delAll = delAll
|
|
1108
|
+
|
|
1109
|
+
return ee
|
|
1110
|
+
}
|
|
1111
|
+
|
|
1112
|
+
|
|
1113
|
+
export default WOrmLowdb
|
|
825
1114
|
</code></pre>
|
|
826
1115
|
</article>
|
|
827
1116
|
</section>
|
|
@@ -836,7 +1125,7 @@ export default WOrmLowdb
|
|
|
836
1125
|
<br class="clear">
|
|
837
1126
|
|
|
838
1127
|
<footer>
|
|
839
|
-
Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 4.0.5</a> on
|
|
1128
|
+
Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 4.0.5</a> on Mon Aug 17 2026 20:57:08 GMT+0800 (台北標準時間) using the <a href="https://github.com/clenemt/docdash">docdash</a> theme.
|
|
840
1129
|
</footer>
|
|
841
1130
|
|
|
842
1131
|
<script>prettyPrint();</script>
|