w-orm-lowdb 1.0.1 → 1.0.2

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.
@@ -48,7 +48,8 @@
48
48
  <pre class="prettyprint source linenums"><code>import events from 'events'
49
49
  import { Low } from 'lowdb'
50
50
  import { JSONFile } from 'lowdb/node'
51
- import { Query } from 'mingo'
51
+ import { Query } from 'mingo' //須指定安裝6.5.6, 若6.6.0無法匯入Query
52
+ import { Mutex } from 'async-mutex'
52
53
  import get from 'lodash-es/get.js'
53
54
  import each from 'lodash-es/each.js'
54
55
  import map from 'lodash-es/map.js'
@@ -105,6 +106,9 @@ function WOrmLowdb(opt = {}) {
105
106
  //lowdb
106
107
  let lowdb = new Low(adapter, {})
107
108
 
109
+ //mutex
110
+ let mutex = new Mutex()
111
+
108
112
  // //default, 此處偵測會失效, 因操作函數內會通過lowdb.read()初始化, 預設創建空陣列會被取代
109
113
  // if (!haskey(lowdb.data, key)) {
110
114
  // lowdb.data[key] = []
@@ -171,94 +175,96 @@ function WOrmLowdb(opt = {}) {
171
175
  * @returns {Promise} 回傳Promise,resolve回傳插入結果,reject回傳錯誤訊息
172
176
  */
173
177
  async function insert(data) {
174
- let isErr = false
178
+ return await mutex.runExclusive(async () => {
179
+ let isErr = false
175
180
 
176
- //check
177
- if (!iseobj(data) &amp;&amp; !isearr(data)) {
178
- return Promise.reject(`data is not an effective object or array`)
179
- }
181
+ //check
182
+ if (!iseobj(data) &amp;&amp; !isearr(data)) {
183
+ return Promise.reject(`data is not an effective object or array`)
184
+ }
180
185
 
181
- //cloneDeep, 與外部數據脫勾
182
- data = cloneDeep(data)
186
+ //cloneDeep, 與外部數據脫勾
187
+ data = cloneDeep(data)
183
188
 
184
- //res
185
- let res = null
186
- try {
189
+ //res
190
+ let res = null
191
+ try {
187
192
 
188
- //check
189
- if (!isarr(data)) {
190
- data = [data]
191
- }
193
+ //check
194
+ if (!isarr(data)) {
195
+ data = [data]
196
+ }
192
197
 
193
- //check id
194
- data = map(data, function(v) {
195
- if (!isestr(v.id)) {
196
- v.id = genID()
198
+ //check id
199
+ data = map(data, function(v) {
200
+ if (!isestr(v.id)) {
201
+ v.id = genID()
202
+ }
203
+ return v
204
+ })
205
+
206
+ //read
207
+ await lowdb.read()
208
+
209
+ //default, 使用lowdb.read()初始化後須馬上檢測, 若無key則須先創建空陣列
210
+ if (!haskey(lowdb.data, key)) {
211
+ lowdb.data[key] = []
197
212
  }
198
- return v
199
- })
200
213
 
201
- //read
202
- await lowdb.read()
214
+ //kp
215
+ let kp = {}
216
+ each(lowdb.data[key], (v, k) => {
217
+ kp[v.id] = { k, v }
218
+ })
203
219
 
204
- //default, 使用lowdb.read()初始化後須馬上檢測, 若無key則須先創建空陣列
205
- if (!haskey(lowdb.data, key)) {
206
- lowdb.data[key] = []
207
- }
220
+ //each
221
+ let nAll = size(data)
222
+ let nPush = 0
223
+ let b = false
224
+ each(data, (v) => {
208
225
 
209
- //kp
210
- let kp = {}
211
- each(lowdb.data[key], (v, k) => {
212
- kp[v.id] = { k, v }
213
- })
226
+ //check
227
+ if (!haskey(kp, v.id)) {
228
+ //未存在v.id
214
229
 
215
- //each
216
- let nAll = size(data)
217
- let nPush = 0
218
- let b = false
219
- each(data, (v) => {
230
+ //push
231
+ lowdb.data[key].push(v)
220
232
 
221
- //check
222
- if (!haskey(kp, v.id)) {
223
- //未存在v.id
233
+ nPush++
234
+ b = true
235
+ }
236
+ else {
237
+ //已存在v.id則不push
238
+ }
224
239
 
225
- //push
226
- lowdb.data[key].push(v)
240
+ })
227
241
 
228
- nPush++
229
- b = true
242
+ //write
243
+ if (b) {
244
+ await lowdb.write()
230
245
  }
231
- else {
232
- //已存在v.id則不push
246
+
247
+ //res
248
+ res = {
249
+ n: nAll,
250
+ nInserted: nPush,
251
+ ok: 1,
233
252
  }
234
253
 
235
- })
254
+ //emit
255
+ ee.emit('change', 'insert', data, res)
236
256
 
237
- //write
238
- if (b) {
239
- await lowdb.write()
240
257
  }
241
-
242
- //res
243
- res = {
244
- n: nAll,
245
- nInserted: nPush,
246
- ok: 1,
258
+ catch (err) {
259
+ isErr = true
260
+ res = err
247
261
  }
248
262
 
249
- //emit
250
- ee.emit('change', 'insert', data, res)
251
-
252
- }
253
- catch (err) {
254
- isErr = true
255
- res = err
256
- }
257
-
258
- if (isErr) {
259
- return Promise.reject(res)
260
- }
261
- return res
263
+ if (isErr) {
264
+ return Promise.reject(res)
265
+ }
266
+ return res
267
+ })
262
268
  }
263
269
 
264
270
  /**
@@ -271,122 +277,121 @@ function WOrmLowdb(opt = {}) {
271
277
  * @returns {Promise} 回傳Promise,resolve回傳儲存結果,reject回傳錯誤訊息
272
278
  */
273
279
  async function save(data, option = {}) {
274
- let isErr = false
275
-
276
- //check
277
- if (!iseobj(data) &amp;&amp; !isearr(data)) {
278
- return Promise.reject(`data is not an effective object or array`)
279
- }
280
+ return await mutex.runExclusive(async () => {
281
+ let isErr = false
280
282
 
281
- //cloneDeep, 與外部數據脫勾
282
- data = cloneDeep(data)
283
+ //check
284
+ if (!iseobj(data) &amp;&amp; !isearr(data)) {
285
+ return Promise.reject(`data is not an effective object or array`)
286
+ }
283
287
 
284
- //autoInsert
285
- let autoInsert = get(option, 'autoInsert', true)
288
+ //cloneDeep, 與外部數據脫勾
289
+ data = cloneDeep(data)
286
290
 
287
- //res
288
- let res = null
289
- try {
291
+ //autoInsert
292
+ let autoInsert = get(option, 'autoInsert', true)
290
293
 
291
- //check
292
- if (!isarr(data)) {
293
- data = [data]
294
- }
294
+ //res
295
+ let res = null
296
+ try {
295
297
 
296
- //check id
297
- data = map(data, function(v) {
298
- if (!isestr(v.id)) {
299
- v.id = genID()
298
+ //check
299
+ if (!isarr(data)) {
300
+ data = [data]
300
301
  }
301
- return v
302
- })
303
302
 
304
- //read
305
- await lowdb.read()
303
+ //check id
304
+ data = map(data, function(v) {
305
+ if (!isestr(v.id)) {
306
+ v.id = genID()
307
+ }
308
+ return v
309
+ })
306
310
 
307
- //default, 使用lowdb.read()初始化後須馬上檢測, 若無key則須先創建空陣列
308
- if (!haskey(lowdb.data, key)) {
309
- lowdb.data[key] = []
310
- }
311
+ //read
312
+ await lowdb.read()
311
313
 
312
- //kp
313
- let kp = {}
314
- each(lowdb.data[key], (v, k) => {
315
- kp[v.id] = { k, v }
316
- })
314
+ //default, 使用lowdb.read()初始化後須馬上檢測, 若無key則須先創建空陣列
315
+ if (!haskey(lowdb.data, key)) {
316
+ lowdb.data[key] = []
317
+ }
317
318
 
318
- //pmSeries
319
- let b = false
320
- res = await pmSeries(data, async(v) => {
319
+ //kp
320
+ let kp = {}
321
+ each(lowdb.data[key], (v, k) => {
322
+ kp[v.id] = { k, v }
323
+ })
321
324
 
322
- //rest
323
- let rest = null
325
+ //pmSeries
326
+ let b = false
327
+ res = await pmSeries(data, async(v) => {
324
328
 
325
- //id
326
- let id = get(v, 'id', '')
329
+ //rest
330
+ let rest = null
327
331
 
328
- //查找資料表內v.id為_v
329
- let r = get(kp, id, null)
332
+ //查找資料表內v.id
333
+ let r = get(kp, v.id, null)
330
334
 
331
- //check
332
- if (iseobj(r)) {
333
- //已存在v.id
334
- if (isEqual(v, r.v)) {
335
- //內容相同不更新
336
- }
337
- else {
338
- //內容不同須更新
335
+ //check
336
+ if (iseobj(r)) {
337
+ //已存在v.id
338
+ if (isEqual(v, r.v)) {
339
+ //內容相同不更新
340
+ }
341
+ else {
342
+ //內容不同須更新
339
343
 
340
- //merge
341
- lowdb.data[key][r.k] = merge(lowdb.data[key][r.k], v)
344
+ //merge
345
+ lowdb.data[key][r.k] = merge(lowdb.data[key][r.k], v)
342
346
 
343
- rest = { update: true }
344
- b = true
347
+ rest = { update: true }
348
+ b = true
349
+ }
345
350
  }
346
- }
347
351
 
348
- //rest
349
- if (iseobj(rest)) {
350
- rest = {
351
- n: 1,
352
- nModified: 1,
353
- ok: 1,
352
+ //rest
353
+ if (iseobj(rest)) {
354
+ rest = {
355
+ n: 1,
356
+ nModified: 1,
357
+ ok: 1,
358
+ }
354
359
  }
355
- }
356
- else {
357
- rest = {
358
- n: 0,
359
- nModified: 0,
360
- ok: 1,
360
+ else {
361
+ rest = {
362
+ n: 0,
363
+ nModified: 0,
364
+ ok: 1,
365
+ }
361
366
  }
362
- }
363
367
 
364
- //autoInsert
365
- if (autoInsert &amp;&amp; rest.n === 0) {
366
- rest = await insert(v)
367
- }
368
+ //autoInsert
369
+ if (autoInsert &amp;&amp; rest.n === 0) {
370
+ rest = await insert(v)
371
+ }
368
372
 
369
- return rest
370
- })
373
+ return rest
374
+ })
371
375
 
372
- //write
373
- if (b) {
374
- await lowdb.write()
375
- }
376
+ //write
377
+ if (b) {
378
+ await lowdb.write()
379
+ }
376
380
 
377
- //emit
378
- ee.emit('change', 'save', data, res)
381
+ //emit
382
+ ee.emit('change', 'save', data, res)
379
383
 
380
- }
381
- catch (err) {
382
- isErr = true
383
- res = err
384
- }
384
+ }
385
+ catch (err) {
386
+ isErr = true
387
+ res = err
388
+ }
385
389
 
386
- if (isErr) {
387
- return Promise.reject(res)
388
- }
389
- return res
390
+ if (isErr) {
391
+ return Promise.reject(res)
392
+ }
393
+ return res
394
+ })
390
395
  }
391
396
 
392
397
  /**
@@ -397,124 +402,126 @@ function WOrmLowdb(opt = {}) {
397
402
  * @returns {Promise} 回傳Promise,resolve回傳刪除結果,reject回傳錯誤訊息
398
403
  */
399
404
  async function del(data) {
400
- let isErr = false
401
-
402
- //check
403
- if (!iseobj(data) &amp;&amp; !isearr(data)) {
404
- return Promise.reject(`data is not an effective object or array`)
405
- }
406
-
407
- //cloneDeep, 與外部數據脫勾
408
- data = cloneDeep(data)
409
-
410
- //res
411
- let res = null
412
- try {
405
+ return await mutex.runExclusive(async () => {
406
+ let isErr = false
413
407
 
414
408
  //check
415
- if (!isarr(data)) {
416
- data = [data]
409
+ if (!iseobj(data) &amp;&amp; !isearr(data)) {
410
+ return Promise.reject(`data is not an effective object or array`)
417
411
  }
418
412
 
419
- //read
420
- await lowdb.read()
413
+ //cloneDeep, 與外部數據脫勾
414
+ data = cloneDeep(data)
421
415
 
422
- //default, 使用lowdb.read()初始化後須馬上檢測, 若無key則須先創建空陣列
423
- if (!haskey(lowdb.data, key)) {
424
- lowdb.data[key] = []
425
- }
416
+ //res
417
+ let res = null
418
+ try {
426
419
 
427
- //kp
428
- let kp = {}
429
- each(lowdb.data[key], (v, k) => {
430
- kp[v.id] = { k, v }
431
- })
420
+ //check
421
+ if (!isarr(data)) {
422
+ data = [data]
423
+ }
432
424
 
433
- //pmSeries
434
- let ks = []
435
- let b = false
436
- res = await pmSeries(data, async(v) => {
425
+ //read
426
+ await lowdb.read()
437
427
 
438
- //rest
439
- let rest = null
428
+ //default, 使用lowdb.read()初始化後須馬上檢測, 若無key則須先創建空陣列
429
+ if (!haskey(lowdb.data, key)) {
430
+ lowdb.data[key] = []
431
+ }
440
432
 
441
- //id
442
- let id = get(v, 'id', '')
433
+ //kp
434
+ let kp = {}
435
+ each(lowdb.data[key], (v, k) => {
436
+ kp[v.id] = { k, v }
437
+ })
443
438
 
444
- //check
445
- if (isestr(id)) {
439
+ //pmSeries
440
+ let ks = []
441
+ let b = false
442
+ res = await pmSeries(data, async(v) => {
446
443
 
447
- //查找資料表內v.id為_v
448
- let r = get(kp, id, null)
444
+ //rest
445
+ let rest = null
446
+
447
+ //id
448
+ let id = get(v, 'id', '')
449
449
 
450
450
  //check
451
- if (iseobj(r)) {
452
- //已存在v.id則須刪除
451
+ if (isestr(id)) {
453
452
 
454
- //push
455
- ks.push(r.k)
453
+ //查找資料表內v.id為_v
454
+ let r = get(kp, id, null)
456
455
 
457
- b = true
456
+ //check
457
+ if (iseobj(r)) {
458
+ //已存在v.id則須刪除
459
+
460
+ //push
461
+ ks.push(r.k)
462
+
463
+ b = true
464
+
465
+ //rest
466
+ rest = {
467
+ n: 1,
468
+ nDeleted: 1,
469
+ ok: 1,
470
+ }
471
+
472
+ }
473
+ else {
474
+ //不存在v.id則不刪除
475
+
476
+ //rest
477
+ rest = {
478
+ n: 1,
479
+ nDeleted: 0,
480
+ ok: 1,
481
+ }
458
482
 
459
- //rest
460
- rest = {
461
- n: 1,
462
- nDeleted: 1,
463
- ok: 1,
464
483
  }
465
484
 
466
485
  }
467
486
  else {
468
- //不存在v.id則不刪除
487
+ //未給v.id則不刪除
469
488
 
470
489
  //rest
471
490
  rest = {
472
491
  n: 1,
473
492
  nDeleted: 0,
474
- ok: 1,
493
+ ok: 0, //未給v.id視為有問題數據, 故ok給0
475
494
  }
476
495
 
477
496
  }
478
497
 
479
- }
480
- else {
481
- //未給v.id則不刪除
498
+ return rest
499
+ })
482
500
 
483
- //rest
484
- rest = {
485
- n: 1,
486
- nDeleted: 0,
487
- ok: 0, //未給v.id視為有問題數據, 故ok給0
488
- }
501
+ //update
502
+ if (b) {
503
+ lowdb.data[key] = arrPullAt(lowdb.data[key], ks)
504
+ }
489
505
 
506
+ //write
507
+ if (b) {
508
+ await lowdb.write()
490
509
  }
491
510
 
492
- return rest
493
- })
511
+ //emit
512
+ ee.emit('change', 'del', data, res)
494
513
 
495
- //update
496
- if (b) {
497
- lowdb.data[key] = arrPullAt(lowdb.data[key], ks)
498
514
  }
499
-
500
- //write
501
- if (b) {
502
- await lowdb.write()
515
+ catch (err) {
516
+ isErr = true
517
+ res = err
503
518
  }
504
519
 
505
- //emit
506
- ee.emit('change', 'del', data, res)
507
-
508
- }
509
- catch (err) {
510
- isErr = true
511
- res = err
512
- }
513
-
514
- if (isErr) {
515
- return Promise.reject(res)
516
- }
517
- return res
520
+ if (isErr) {
521
+ return Promise.reject(res)
522
+ }
523
+ return res
524
+ })
518
525
  }
519
526
 
520
527
  /**
@@ -525,109 +532,111 @@ function WOrmLowdb(opt = {}) {
525
532
  * @returns {Promise} 回傳Promise,resolve回傳刪除結果,reject回傳錯誤訊息
526
533
  */
527
534
  async function delAll(find = {}) {
528
- let isErr = false
535
+ return await mutex.runExclusive(async () => {
536
+ let isErr = false
529
537
 
530
- //res
531
- let res = null
532
- try {
538
+ //res
539
+ let res = null
540
+ try {
533
541
 
534
- //read
535
- await lowdb.read()
542
+ //read
543
+ await lowdb.read()
536
544
 
537
- //default, 使用lowdb.read()初始化後須馬上檢測, 若無key則須先創建空陣列
538
- if (!haskey(lowdb.data, key)) {
539
- lowdb.data[key] = []
540
- }
545
+ //default, 使用lowdb.read()初始化後須馬上檢測, 若無key則須先創建空陣列
546
+ if (!haskey(lowdb.data, key)) {
547
+ lowdb.data[key] = []
548
+ }
541
549
 
542
- //filter
543
- let nAll = size(lowdb.data[key])
544
- let nDel = 0
545
- let b = false
546
- if (iseobj(find)) {
550
+ //filter
551
+ let nAll = size(lowdb.data[key])
552
+ let nDel = 0
553
+ let b = false
554
+ if (iseobj(find)) {
547
555
 
548
- //q
549
- let q = new Query(find)
550
- // console.log('q', q)
556
+ //q
557
+ let q = new Query(find)
558
+ // console.log('q', q)
551
559
 
552
- //find
553
- let _res = q.find(lowdb.data[key]).all()
554
- // console.log('_res', _res)
560
+ //find
561
+ let _res = q.find(lowdb.data[key]).all()
562
+ // console.log('_res', _res)
563
+
564
+ //nDel
565
+ nDel = size(_res)
566
+ // console.log('nDel', nDel)
555
567
 
556
- //nDel
557
- nDel = size(_res)
558
- // console.log('nDel', nDel)
568
+ if (nDel === 0) {
569
+ //未有find結果等於不刪除
570
+ }
571
+ else if (nAll === nDel) {
572
+ //全在find結果內等於全部刪除
573
+
574
+ //empty
575
+ lowdb.data[key] = []
576
+
577
+ b = true
578
+ }
579
+ else {
580
+ //部份在find結果內
581
+
582
+ //_kp
583
+ let _kp = {}
584
+ each(_res, (v, k) => {
585
+ _kp[v.id] = { k, v }
586
+ })
587
+
588
+ //arr
589
+ let arr = []
590
+ each(lowdb.data[key], (v, k) => {
591
+ if (!haskey(_kp, v.id)) {
592
+ //未在find結果內代表須保留
593
+ arr.push(v)
594
+ }
595
+ })
596
+
597
+ //update
598
+ lowdb.data[key] = arr
559
599
 
560
- if (nDel === 0) {
561
- //未有find結果等於不刪除
600
+ b = true
601
+ }
562
602
  }
563
- else if (nAll === nDel) {
564
- //全在find結果內等於全部刪除
603
+ else {
604
+
605
+ //nDel
606
+ nDel = nAll
565
607
 
566
608
  //empty
567
609
  lowdb.data[key] = []
568
610
 
569
611
  b = true
570
612
  }
571
- else {
572
- //部份在find結果內
573
-
574
- //_kp
575
- let _kp = {}
576
- each(_res, (v, k) => {
577
- _kp[v.id] = { k, v }
578
- })
579
-
580
- //arr
581
- let arr = []
582
- each(lowdb.data[key], (v, k) => {
583
- if (!haskey(_kp, v.id)) {
584
- //未在find結果內代表須保留
585
- arr.push(v)
586
- }
587
- })
588
-
589
- //update
590
- lowdb.data[key] = arr
591
613
 
592
- b = true
614
+ //write
615
+ if (b) {
616
+ await lowdb.write()
593
617
  }
594
- }
595
- else {
596
618
 
597
- //nDel
598
- nDel = nAll
619
+ //res
620
+ res = {
621
+ n: nAll,
622
+ nDeleted: nDel,
623
+ ok: 1,
624
+ }
599
625
 
600
- //empty
601
- lowdb.data[key] = []
626
+ //emit
627
+ ee.emit('change', 'delAll', null, res)
602
628
 
603
- b = true
604
629
  }
605
-
606
- //write
607
- if (b) {
608
- await lowdb.write()
630
+ catch (err) {
631
+ isErr = true
632
+ res = err
609
633
  }
610
634
 
611
- //res
612
- res = {
613
- n: nAll,
614
- nDeleted: nDel,
615
- ok: 1,
635
+ if (isErr) {
636
+ return Promise.reject(res)
616
637
  }
617
-
618
- //emit
619
- ee.emit('change', 'delAll', null, res)
620
-
621
- }
622
- catch (err) {
623
- isErr = true
624
- res = err
625
- }
626
-
627
- if (isErr) {
628
- return Promise.reject(res)
629
- }
630
- return res
638
+ return res
639
+ })
631
640
  }
632
641
 
633
642
  //bind
@@ -656,7 +665,7 @@ export default WOrmLowdb
656
665
  <br class="clear">
657
666
 
658
667
  <footer>
659
- Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 4.0.4</a> on Wed Apr 02 2025 11:25:26 GMT+0800 (台北標準時間) using the <a href="https://github.com/clenemt/docdash">docdash</a> theme.
668
+ Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 4.0.4</a> on Fri May 09 2025 11:30:47 GMT+0800 (台北標準時間) using the <a href="https://github.com/clenemt/docdash">docdash</a> theme.
660
669
  </footer>
661
670
 
662
671
  <script>prettyPrint();</script>