w-orm-lowdb 1.0.2 → 1.0.3
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/dist/w-orm-lowdb.umd.js +2 -2
- package/dist/w-orm-lowdb.umd.js.map +1 -1
- package/docs/WOrmLowdb.html +42 -42
- package/docs/WOrmLowdb.mjs.html +389 -335
- package/docs/index.html +2 -2
- package/package.json +1 -2
- package/src/WOrmLowdb.mjs +387 -333
package/src/WOrmLowdb.mjs
CHANGED
|
@@ -2,7 +2,6 @@ import events from 'events'
|
|
|
2
2
|
import { Low } from 'lowdb'
|
|
3
3
|
import { JSONFile } from 'lowdb/node'
|
|
4
4
|
import { Query } from 'mingo' //須指定安裝6.5.6, 若6.6.0無法匯入Query
|
|
5
|
-
import { Mutex } from 'async-mutex'
|
|
6
5
|
import get from 'lodash-es/get.js'
|
|
7
6
|
import each from 'lodash-es/each.js'
|
|
8
7
|
import map from 'lodash-es/map.js'
|
|
@@ -18,6 +17,12 @@ import iseobj from 'wsemi/src/iseobj.mjs'
|
|
|
18
17
|
import isearr from 'wsemi/src/isearr.mjs'
|
|
19
18
|
import haskey from 'wsemi/src/haskey.mjs'
|
|
20
19
|
import arrPullAt from 'wsemi/src/arrPullAt.mjs'
|
|
20
|
+
import waitFun from 'wsemi/src/waitFun.mjs'
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
//全域鎖, 一次僅能執行一種操作函數
|
|
24
|
+
//select理論上是不用鎖, 但因為操作上db.jon.tmp更名回db.json時似乎非rename而是串流寫入, 導致有機會撈到不完整json數據進而出錯, 故還是得要上鎖以策安全
|
|
25
|
+
let glock = false
|
|
21
26
|
|
|
22
27
|
|
|
23
28
|
/**
|
|
@@ -59,9 +64,6 @@ function WOrmLowdb(opt = {}) {
|
|
|
59
64
|
//lowdb
|
|
60
65
|
let lowdb = new Low(adapter, {})
|
|
61
66
|
|
|
62
|
-
//mutex
|
|
63
|
-
let mutex = new Mutex()
|
|
64
|
-
|
|
65
67
|
// //default, 此處偵測會失效, 因操作函數內會通過lowdb.read()初始化, 預設創建空陣列會被取代
|
|
66
68
|
// if (!haskey(lowdb.data, key)) {
|
|
67
69
|
// lowdb.data[key] = []
|
|
@@ -77,7 +79,7 @@ function WOrmLowdb(opt = {}) {
|
|
|
77
79
|
* @param {Object} [find={}] 輸入查詢條件物件
|
|
78
80
|
* @returns {Promise} 回傳Promise,resolve回傳數據,reject回傳錯誤訊息
|
|
79
81
|
*/
|
|
80
|
-
async function
|
|
82
|
+
async function selectCore(find = {}) {
|
|
81
83
|
let isErr = false
|
|
82
84
|
|
|
83
85
|
//res
|
|
@@ -119,6 +121,18 @@ function WOrmLowdb(opt = {}) {
|
|
|
119
121
|
}
|
|
120
122
|
return res
|
|
121
123
|
}
|
|
124
|
+
async function select(find = {}) {
|
|
125
|
+
if (glock) {
|
|
126
|
+
await waitFun(() => {
|
|
127
|
+
return !glock
|
|
128
|
+
})
|
|
129
|
+
}
|
|
130
|
+
glock = true
|
|
131
|
+
return await selectCore(find)
|
|
132
|
+
.finally(() => {
|
|
133
|
+
glock = false
|
|
134
|
+
})
|
|
135
|
+
}
|
|
122
136
|
|
|
123
137
|
/**
|
|
124
138
|
* 插入數據,插入同樣數據會自動產生不同_id,故insert前需自行判斷有無重複
|
|
@@ -127,97 +141,107 @@ function WOrmLowdb(opt = {}) {
|
|
|
127
141
|
* @param {Object|Array} data 輸入數據物件或陣列
|
|
128
142
|
* @returns {Promise} 回傳Promise,resolve回傳插入結果,reject回傳錯誤訊息
|
|
129
143
|
*/
|
|
130
|
-
async function
|
|
131
|
-
|
|
132
|
-
let isErr = false
|
|
133
|
-
|
|
134
|
-
//check
|
|
135
|
-
if (!iseobj(data) && !isearr(data)) {
|
|
136
|
-
return Promise.reject(`data is not an effective object or array`)
|
|
137
|
-
}
|
|
138
|
-
|
|
139
|
-
//cloneDeep, 與外部數據脫勾
|
|
140
|
-
data = cloneDeep(data)
|
|
144
|
+
async function insertCore(data) {
|
|
145
|
+
let isErr = false
|
|
141
146
|
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
147
|
+
//check
|
|
148
|
+
if (!iseobj(data) && !isearr(data)) {
|
|
149
|
+
return Promise.reject(`data is not an effective object or array`)
|
|
150
|
+
}
|
|
145
151
|
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
data = [data]
|
|
149
|
-
}
|
|
152
|
+
//cloneDeep, 與外部數據脫勾
|
|
153
|
+
data = cloneDeep(data)
|
|
150
154
|
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
v.id = genID()
|
|
155
|
-
}
|
|
156
|
-
return v
|
|
157
|
-
})
|
|
155
|
+
//res
|
|
156
|
+
let res = null
|
|
157
|
+
try {
|
|
158
158
|
|
|
159
|
-
|
|
160
|
-
|
|
159
|
+
//check
|
|
160
|
+
if (!isarr(data)) {
|
|
161
|
+
data = [data]
|
|
162
|
+
}
|
|
161
163
|
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
164
|
+
//check id
|
|
165
|
+
data = map(data, function(v) {
|
|
166
|
+
if (!isestr(v.id)) {
|
|
167
|
+
v.id = genID()
|
|
165
168
|
}
|
|
169
|
+
return v
|
|
170
|
+
})
|
|
166
171
|
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
each(lowdb.data[key], (v, k) => {
|
|
170
|
-
kp[v.id] = { k, v }
|
|
171
|
-
})
|
|
172
|
+
//read
|
|
173
|
+
await lowdb.read()
|
|
172
174
|
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
each(data, (v) => {
|
|
175
|
+
//default, 使用lowdb.read()初始化後須馬上檢測, 若無key則須先創建空陣列
|
|
176
|
+
if (!haskey(lowdb.data, key)) {
|
|
177
|
+
lowdb.data[key] = []
|
|
178
|
+
}
|
|
178
179
|
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
180
|
+
//kp
|
|
181
|
+
let kp = {}
|
|
182
|
+
each(lowdb.data[key], (v, k) => {
|
|
183
|
+
kp[v.id] = { k, v }
|
|
184
|
+
})
|
|
182
185
|
|
|
183
|
-
|
|
184
|
-
|
|
186
|
+
//each
|
|
187
|
+
let nAll = size(data)
|
|
188
|
+
let nPush = 0
|
|
189
|
+
let b = false
|
|
190
|
+
each(data, (v) => {
|
|
185
191
|
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
else {
|
|
190
|
-
//已存在v.id則不push
|
|
191
|
-
}
|
|
192
|
+
//check
|
|
193
|
+
if (!haskey(kp, v.id)) {
|
|
194
|
+
//未存在v.id
|
|
192
195
|
|
|
193
|
-
|
|
196
|
+
//push
|
|
197
|
+
lowdb.data[key].push(v)
|
|
194
198
|
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
await lowdb.write()
|
|
199
|
+
nPush++
|
|
200
|
+
b = true
|
|
198
201
|
}
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
res = {
|
|
202
|
-
n: nAll,
|
|
203
|
-
nInserted: nPush,
|
|
204
|
-
ok: 1,
|
|
202
|
+
else {
|
|
203
|
+
//已存在v.id則不push
|
|
205
204
|
}
|
|
206
205
|
|
|
207
|
-
|
|
208
|
-
ee.emit('change', 'insert', data, res)
|
|
206
|
+
})
|
|
209
207
|
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
res = err
|
|
208
|
+
//write
|
|
209
|
+
if (b) {
|
|
210
|
+
await lowdb.write()
|
|
214
211
|
}
|
|
215
212
|
|
|
216
|
-
|
|
217
|
-
|
|
213
|
+
//res
|
|
214
|
+
res = {
|
|
215
|
+
n: nAll,
|
|
216
|
+
nInserted: nPush,
|
|
217
|
+
ok: 1,
|
|
218
218
|
}
|
|
219
|
-
|
|
220
|
-
|
|
219
|
+
|
|
220
|
+
//emit
|
|
221
|
+
ee.emit('change', 'insert', data, res)
|
|
222
|
+
|
|
223
|
+
}
|
|
224
|
+
catch (err) {
|
|
225
|
+
isErr = true
|
|
226
|
+
res = err
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
if (isErr) {
|
|
230
|
+
return Promise.reject(res)
|
|
231
|
+
}
|
|
232
|
+
return res
|
|
233
|
+
}
|
|
234
|
+
async function insert(data) {
|
|
235
|
+
if (glock) {
|
|
236
|
+
await waitFun(() => {
|
|
237
|
+
return !glock
|
|
238
|
+
})
|
|
239
|
+
}
|
|
240
|
+
glock = true
|
|
241
|
+
return await insertCore(data)
|
|
242
|
+
.finally(() => {
|
|
243
|
+
glock = false
|
|
244
|
+
})
|
|
221
245
|
}
|
|
222
246
|
|
|
223
247
|
/**
|
|
@@ -229,122 +253,132 @@ function WOrmLowdb(opt = {}) {
|
|
|
229
253
|
* @param {boolean} [option.autoInsert=true] 輸入是否於儲存時發現原本無數據,則自動改以插入處理,預設為true
|
|
230
254
|
* @returns {Promise} 回傳Promise,resolve回傳儲存結果,reject回傳錯誤訊息
|
|
231
255
|
*/
|
|
232
|
-
async function
|
|
233
|
-
|
|
234
|
-
let isErr = false
|
|
235
|
-
|
|
236
|
-
//check
|
|
237
|
-
if (!iseobj(data) && !isearr(data)) {
|
|
238
|
-
return Promise.reject(`data is not an effective object or array`)
|
|
239
|
-
}
|
|
240
|
-
|
|
241
|
-
//cloneDeep, 與外部數據脫勾
|
|
242
|
-
data = cloneDeep(data)
|
|
256
|
+
async function saveCore(data, option = {}) {
|
|
257
|
+
let isErr = false
|
|
243
258
|
|
|
244
|
-
|
|
245
|
-
|
|
259
|
+
//check
|
|
260
|
+
if (!iseobj(data) && !isearr(data)) {
|
|
261
|
+
return Promise.reject(`data is not an effective object or array`)
|
|
262
|
+
}
|
|
246
263
|
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
try {
|
|
264
|
+
//cloneDeep, 與外部數據脫勾
|
|
265
|
+
data = cloneDeep(data)
|
|
250
266
|
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
data = [data]
|
|
254
|
-
}
|
|
267
|
+
//autoInsert
|
|
268
|
+
let autoInsert = get(option, 'autoInsert', true)
|
|
255
269
|
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
v.id = genID()
|
|
260
|
-
}
|
|
261
|
-
return v
|
|
262
|
-
})
|
|
270
|
+
//res
|
|
271
|
+
let res = null
|
|
272
|
+
try {
|
|
263
273
|
|
|
264
|
-
|
|
265
|
-
|
|
274
|
+
//check
|
|
275
|
+
if (!isarr(data)) {
|
|
276
|
+
data = [data]
|
|
277
|
+
}
|
|
266
278
|
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
279
|
+
//check id
|
|
280
|
+
data = map(data, function(v) {
|
|
281
|
+
if (!isestr(v.id)) {
|
|
282
|
+
v.id = genID()
|
|
270
283
|
}
|
|
284
|
+
return v
|
|
285
|
+
})
|
|
271
286
|
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
each(lowdb.data[key], (v, k) => {
|
|
275
|
-
kp[v.id] = { k, v }
|
|
276
|
-
})
|
|
287
|
+
//read
|
|
288
|
+
await lowdb.read()
|
|
277
289
|
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
290
|
+
//default, 使用lowdb.read()初始化後須馬上檢測, 若無key則須先創建空陣列
|
|
291
|
+
if (!haskey(lowdb.data, key)) {
|
|
292
|
+
lowdb.data[key] = []
|
|
293
|
+
}
|
|
281
294
|
|
|
282
|
-
|
|
283
|
-
|
|
295
|
+
//kp
|
|
296
|
+
let kp = {}
|
|
297
|
+
each(lowdb.data[key], (v, k) => {
|
|
298
|
+
kp[v.id] = { k, v }
|
|
299
|
+
})
|
|
284
300
|
|
|
285
|
-
|
|
286
|
-
|
|
301
|
+
//pmSeries
|
|
302
|
+
let b = false
|
|
303
|
+
res = await pmSeries(data, async(v) => {
|
|
287
304
|
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
//已存在v.id
|
|
291
|
-
if (isEqual(v, r.v)) {
|
|
292
|
-
//內容相同不更新
|
|
293
|
-
}
|
|
294
|
-
else {
|
|
295
|
-
//內容不同須更新
|
|
305
|
+
//rest
|
|
306
|
+
let rest = null
|
|
296
307
|
|
|
297
|
-
|
|
298
|
-
|
|
308
|
+
//查找資料表內v.id
|
|
309
|
+
let r = get(kp, v.id, null)
|
|
299
310
|
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
//rest
|
|
306
|
-
if (iseobj(rest)) {
|
|
307
|
-
rest = {
|
|
308
|
-
n: 1,
|
|
309
|
-
nModified: 1,
|
|
310
|
-
ok: 1,
|
|
311
|
-
}
|
|
311
|
+
//check
|
|
312
|
+
if (iseobj(r)) {
|
|
313
|
+
//已存在v.id
|
|
314
|
+
if (isEqual(v, r.v)) {
|
|
315
|
+
//內容相同不更新
|
|
312
316
|
}
|
|
313
317
|
else {
|
|
314
|
-
|
|
315
|
-
n: 0,
|
|
316
|
-
nModified: 0,
|
|
317
|
-
ok: 1,
|
|
318
|
-
}
|
|
319
|
-
}
|
|
318
|
+
//內容不同須更新
|
|
320
319
|
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
320
|
+
//merge
|
|
321
|
+
lowdb.data[key][r.k] = merge(lowdb.data[key][r.k], v)
|
|
322
|
+
|
|
323
|
+
rest = { update: true }
|
|
324
|
+
b = true
|
|
324
325
|
}
|
|
326
|
+
}
|
|
325
327
|
|
|
326
|
-
|
|
327
|
-
|
|
328
|
+
//rest
|
|
329
|
+
if (iseobj(rest)) {
|
|
330
|
+
rest = {
|
|
331
|
+
n: 1,
|
|
332
|
+
nModified: 1,
|
|
333
|
+
ok: 1,
|
|
334
|
+
}
|
|
335
|
+
}
|
|
336
|
+
else {
|
|
337
|
+
rest = {
|
|
338
|
+
n: 0,
|
|
339
|
+
nModified: 0,
|
|
340
|
+
ok: 1,
|
|
341
|
+
}
|
|
342
|
+
}
|
|
328
343
|
|
|
329
|
-
//
|
|
330
|
-
if (
|
|
331
|
-
await
|
|
344
|
+
//autoInsert
|
|
345
|
+
if (autoInsert && rest.n === 0) {
|
|
346
|
+
rest = await insertCore(v)
|
|
332
347
|
}
|
|
333
348
|
|
|
334
|
-
|
|
335
|
-
|
|
349
|
+
return rest
|
|
350
|
+
})
|
|
336
351
|
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
res = err
|
|
352
|
+
//write
|
|
353
|
+
if (b) {
|
|
354
|
+
await lowdb.write()
|
|
341
355
|
}
|
|
342
356
|
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
357
|
+
//emit
|
|
358
|
+
ee.emit('change', 'save', data, res)
|
|
359
|
+
|
|
360
|
+
}
|
|
361
|
+
catch (err) {
|
|
362
|
+
isErr = true
|
|
363
|
+
res = err
|
|
364
|
+
}
|
|
365
|
+
|
|
366
|
+
if (isErr) {
|
|
367
|
+
return Promise.reject(res)
|
|
368
|
+
}
|
|
369
|
+
return res
|
|
370
|
+
}
|
|
371
|
+
async function save(data, option = {}) {
|
|
372
|
+
if (glock) {
|
|
373
|
+
await waitFun(() => {
|
|
374
|
+
return !glock
|
|
375
|
+
})
|
|
376
|
+
}
|
|
377
|
+
glock = true
|
|
378
|
+
return await saveCore(data, option)
|
|
379
|
+
.finally(() => {
|
|
380
|
+
glock = false
|
|
381
|
+
})
|
|
348
382
|
}
|
|
349
383
|
|
|
350
384
|
/**
|
|
@@ -354,127 +388,137 @@ function WOrmLowdb(opt = {}) {
|
|
|
354
388
|
* @param {Object|Array} data 輸入數據物件或陣列
|
|
355
389
|
* @returns {Promise} 回傳Promise,resolve回傳刪除結果,reject回傳錯誤訊息
|
|
356
390
|
*/
|
|
357
|
-
async function
|
|
358
|
-
|
|
359
|
-
let isErr = false
|
|
360
|
-
|
|
361
|
-
//check
|
|
362
|
-
if (!iseobj(data) && !isearr(data)) {
|
|
363
|
-
return Promise.reject(`data is not an effective object or array`)
|
|
364
|
-
}
|
|
365
|
-
|
|
366
|
-
//cloneDeep, 與外部數據脫勾
|
|
367
|
-
data = cloneDeep(data)
|
|
368
|
-
|
|
369
|
-
//res
|
|
370
|
-
let res = null
|
|
371
|
-
try {
|
|
391
|
+
async function delCore(data) {
|
|
392
|
+
let isErr = false
|
|
372
393
|
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
394
|
+
//check
|
|
395
|
+
if (!iseobj(data) && !isearr(data)) {
|
|
396
|
+
return Promise.reject(`data is not an effective object or array`)
|
|
397
|
+
}
|
|
377
398
|
|
|
378
|
-
|
|
379
|
-
|
|
399
|
+
//cloneDeep, 與外部數據脫勾
|
|
400
|
+
data = cloneDeep(data)
|
|
380
401
|
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
}
|
|
402
|
+
//res
|
|
403
|
+
let res = null
|
|
404
|
+
try {
|
|
385
405
|
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
})
|
|
406
|
+
//check
|
|
407
|
+
if (!isarr(data)) {
|
|
408
|
+
data = [data]
|
|
409
|
+
}
|
|
391
410
|
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
let b = false
|
|
395
|
-
res = await pmSeries(data, async(v) => {
|
|
411
|
+
//read
|
|
412
|
+
await lowdb.read()
|
|
396
413
|
|
|
397
|
-
|
|
398
|
-
|
|
414
|
+
//default, 使用lowdb.read()初始化後須馬上檢測, 若無key則須先創建空陣列
|
|
415
|
+
if (!haskey(lowdb.data, key)) {
|
|
416
|
+
lowdb.data[key] = []
|
|
417
|
+
}
|
|
399
418
|
|
|
400
|
-
|
|
401
|
-
|
|
419
|
+
//kp
|
|
420
|
+
let kp = {}
|
|
421
|
+
each(lowdb.data[key], (v, k) => {
|
|
422
|
+
kp[v.id] = { k, v }
|
|
423
|
+
})
|
|
402
424
|
|
|
403
|
-
|
|
404
|
-
|
|
425
|
+
//pmSeries
|
|
426
|
+
let ks = []
|
|
427
|
+
let b = false
|
|
428
|
+
res = await pmSeries(data, async(v) => {
|
|
405
429
|
|
|
406
|
-
|
|
407
|
-
|
|
430
|
+
//rest
|
|
431
|
+
let rest = null
|
|
408
432
|
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
//已存在v.id則須刪除
|
|
433
|
+
//id
|
|
434
|
+
let id = get(v, 'id', '')
|
|
412
435
|
|
|
413
|
-
|
|
414
|
-
|
|
436
|
+
//check
|
|
437
|
+
if (isestr(id)) {
|
|
415
438
|
|
|
416
|
-
|
|
439
|
+
//查找資料表內v.id為_v
|
|
440
|
+
let r = get(kp, id, null)
|
|
417
441
|
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
nDeleted: 1,
|
|
422
|
-
ok: 1,
|
|
423
|
-
}
|
|
442
|
+
//check
|
|
443
|
+
if (iseobj(r)) {
|
|
444
|
+
//已存在v.id則須刪除
|
|
424
445
|
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
//不存在v.id則不刪除
|
|
446
|
+
//push
|
|
447
|
+
ks.push(r.k)
|
|
428
448
|
|
|
429
|
-
|
|
430
|
-
rest = {
|
|
431
|
-
n: 1,
|
|
432
|
-
nDeleted: 0,
|
|
433
|
-
ok: 1,
|
|
434
|
-
}
|
|
449
|
+
b = true
|
|
435
450
|
|
|
451
|
+
//rest
|
|
452
|
+
rest = {
|
|
453
|
+
n: 1,
|
|
454
|
+
nDeleted: 1,
|
|
455
|
+
ok: 1,
|
|
436
456
|
}
|
|
437
457
|
|
|
438
458
|
}
|
|
439
459
|
else {
|
|
440
|
-
|
|
460
|
+
//不存在v.id則不刪除
|
|
441
461
|
|
|
442
462
|
//rest
|
|
443
463
|
rest = {
|
|
444
464
|
n: 1,
|
|
445
465
|
nDeleted: 0,
|
|
446
|
-
ok:
|
|
466
|
+
ok: 1,
|
|
447
467
|
}
|
|
448
468
|
|
|
449
469
|
}
|
|
450
470
|
|
|
451
|
-
return rest
|
|
452
|
-
})
|
|
453
|
-
|
|
454
|
-
//update
|
|
455
|
-
if (b) {
|
|
456
|
-
lowdb.data[key] = arrPullAt(lowdb.data[key], ks)
|
|
457
471
|
}
|
|
472
|
+
else {
|
|
473
|
+
//未給v.id則不刪除
|
|
474
|
+
|
|
475
|
+
//rest
|
|
476
|
+
rest = {
|
|
477
|
+
n: 1,
|
|
478
|
+
nDeleted: 0,
|
|
479
|
+
ok: 0, //未給v.id視為有問題數據, 故ok給0
|
|
480
|
+
}
|
|
458
481
|
|
|
459
|
-
//write
|
|
460
|
-
if (b) {
|
|
461
|
-
await lowdb.write()
|
|
462
482
|
}
|
|
463
483
|
|
|
464
|
-
|
|
465
|
-
|
|
484
|
+
return rest
|
|
485
|
+
})
|
|
466
486
|
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
res = err
|
|
487
|
+
//update
|
|
488
|
+
if (b) {
|
|
489
|
+
lowdb.data[key] = arrPullAt(lowdb.data[key], ks)
|
|
471
490
|
}
|
|
472
491
|
|
|
473
|
-
|
|
474
|
-
|
|
492
|
+
//write
|
|
493
|
+
if (b) {
|
|
494
|
+
await lowdb.write()
|
|
475
495
|
}
|
|
476
|
-
|
|
477
|
-
|
|
496
|
+
|
|
497
|
+
//emit
|
|
498
|
+
ee.emit('change', 'del', data, res)
|
|
499
|
+
|
|
500
|
+
}
|
|
501
|
+
catch (err) {
|
|
502
|
+
isErr = true
|
|
503
|
+
res = err
|
|
504
|
+
}
|
|
505
|
+
|
|
506
|
+
if (isErr) {
|
|
507
|
+
return Promise.reject(res)
|
|
508
|
+
}
|
|
509
|
+
return res
|
|
510
|
+
}
|
|
511
|
+
async function del(data) {
|
|
512
|
+
if (glock) {
|
|
513
|
+
await waitFun(() => {
|
|
514
|
+
return !glock
|
|
515
|
+
})
|
|
516
|
+
}
|
|
517
|
+
glock = true
|
|
518
|
+
return await delCore(data)
|
|
519
|
+
.finally(() => {
|
|
520
|
+
glock = false
|
|
521
|
+
})
|
|
478
522
|
}
|
|
479
523
|
|
|
480
524
|
/**
|
|
@@ -484,112 +528,122 @@ function WOrmLowdb(opt = {}) {
|
|
|
484
528
|
* @param {Object} [find={}] 輸入刪除條件物件
|
|
485
529
|
* @returns {Promise} 回傳Promise,resolve回傳刪除結果,reject回傳錯誤訊息
|
|
486
530
|
*/
|
|
487
|
-
async function
|
|
488
|
-
|
|
489
|
-
let isErr = false
|
|
490
|
-
|
|
491
|
-
//res
|
|
492
|
-
let res = null
|
|
493
|
-
try {
|
|
494
|
-
|
|
495
|
-
//read
|
|
496
|
-
await lowdb.read()
|
|
497
|
-
|
|
498
|
-
//default, 使用lowdb.read()初始化後須馬上檢測, 若無key則須先創建空陣列
|
|
499
|
-
if (!haskey(lowdb.data, key)) {
|
|
500
|
-
lowdb.data[key] = []
|
|
501
|
-
}
|
|
531
|
+
async function delAllCore(find = {}) {
|
|
532
|
+
let isErr = false
|
|
502
533
|
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
let b = false
|
|
507
|
-
if (iseobj(find)) {
|
|
534
|
+
//res
|
|
535
|
+
let res = null
|
|
536
|
+
try {
|
|
508
537
|
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
// console.log('q', q)
|
|
538
|
+
//read
|
|
539
|
+
await lowdb.read()
|
|
512
540
|
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
541
|
+
//default, 使用lowdb.read()初始化後須馬上檢測, 若無key則須先創建空陣列
|
|
542
|
+
if (!haskey(lowdb.data, key)) {
|
|
543
|
+
lowdb.data[key] = []
|
|
544
|
+
}
|
|
516
545
|
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
546
|
+
//filter
|
|
547
|
+
let nAll = size(lowdb.data[key])
|
|
548
|
+
let nDel = 0
|
|
549
|
+
let b = false
|
|
550
|
+
if (iseobj(find)) {
|
|
520
551
|
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
else if (nAll === nDel) {
|
|
525
|
-
//全在find結果內等於全部刪除
|
|
552
|
+
//q
|
|
553
|
+
let q = new Query(find)
|
|
554
|
+
// console.log('q', q)
|
|
526
555
|
|
|
527
|
-
|
|
528
|
-
|
|
556
|
+
//find
|
|
557
|
+
let _res = q.find(lowdb.data[key]).all()
|
|
558
|
+
// console.log('_res', _res)
|
|
529
559
|
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
//部份在find結果內
|
|
534
|
-
|
|
535
|
-
//_kp
|
|
536
|
-
let _kp = {}
|
|
537
|
-
each(_res, (v, k) => {
|
|
538
|
-
_kp[v.id] = { k, v }
|
|
539
|
-
})
|
|
540
|
-
|
|
541
|
-
//arr
|
|
542
|
-
let arr = []
|
|
543
|
-
each(lowdb.data[key], (v, k) => {
|
|
544
|
-
if (!haskey(_kp, v.id)) {
|
|
545
|
-
//未在find結果內代表須保留
|
|
546
|
-
arr.push(v)
|
|
547
|
-
}
|
|
548
|
-
})
|
|
549
|
-
|
|
550
|
-
//update
|
|
551
|
-
lowdb.data[key] = arr
|
|
560
|
+
//nDel
|
|
561
|
+
nDel = size(_res)
|
|
562
|
+
// console.log('nDel', nDel)
|
|
552
563
|
|
|
553
|
-
|
|
554
|
-
|
|
564
|
+
if (nDel === 0) {
|
|
565
|
+
//未有find結果等於不刪除
|
|
555
566
|
}
|
|
556
|
-
else {
|
|
557
|
-
|
|
558
|
-
//nDel
|
|
559
|
-
nDel = nAll
|
|
567
|
+
else if (nAll === nDel) {
|
|
568
|
+
//全在find結果內等於全部刪除
|
|
560
569
|
|
|
561
570
|
//empty
|
|
562
571
|
lowdb.data[key] = []
|
|
563
572
|
|
|
564
573
|
b = true
|
|
565
574
|
}
|
|
575
|
+
else {
|
|
576
|
+
//部份在find結果內
|
|
577
|
+
|
|
578
|
+
//_kp
|
|
579
|
+
let _kp = {}
|
|
580
|
+
each(_res, (v, k) => {
|
|
581
|
+
_kp[v.id] = { k, v }
|
|
582
|
+
})
|
|
583
|
+
|
|
584
|
+
//arr
|
|
585
|
+
let arr = []
|
|
586
|
+
each(lowdb.data[key], (v, k) => {
|
|
587
|
+
if (!haskey(_kp, v.id)) {
|
|
588
|
+
//未在find結果內代表須保留
|
|
589
|
+
arr.push(v)
|
|
590
|
+
}
|
|
591
|
+
})
|
|
566
592
|
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
await lowdb.write()
|
|
570
|
-
}
|
|
593
|
+
//update
|
|
594
|
+
lowdb.data[key] = arr
|
|
571
595
|
|
|
572
|
-
|
|
573
|
-
res = {
|
|
574
|
-
n: nAll,
|
|
575
|
-
nDeleted: nDel,
|
|
576
|
-
ok: 1,
|
|
596
|
+
b = true
|
|
577
597
|
}
|
|
598
|
+
}
|
|
599
|
+
else {
|
|
578
600
|
|
|
579
|
-
//
|
|
580
|
-
|
|
601
|
+
//nDel
|
|
602
|
+
nDel = nAll
|
|
603
|
+
|
|
604
|
+
//empty
|
|
605
|
+
lowdb.data[key] = []
|
|
581
606
|
|
|
607
|
+
b = true
|
|
582
608
|
}
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
609
|
+
|
|
610
|
+
//write
|
|
611
|
+
if (b) {
|
|
612
|
+
await lowdb.write()
|
|
586
613
|
}
|
|
587
614
|
|
|
588
|
-
|
|
589
|
-
|
|
615
|
+
//res
|
|
616
|
+
res = {
|
|
617
|
+
n: nAll,
|
|
618
|
+
nDeleted: nDel,
|
|
619
|
+
ok: 1,
|
|
590
620
|
}
|
|
591
|
-
|
|
592
|
-
|
|
621
|
+
|
|
622
|
+
//emit
|
|
623
|
+
ee.emit('change', 'delAll', null, res)
|
|
624
|
+
|
|
625
|
+
}
|
|
626
|
+
catch (err) {
|
|
627
|
+
isErr = true
|
|
628
|
+
res = err
|
|
629
|
+
}
|
|
630
|
+
|
|
631
|
+
if (isErr) {
|
|
632
|
+
return Promise.reject(res)
|
|
633
|
+
}
|
|
634
|
+
return res
|
|
635
|
+
}
|
|
636
|
+
async function delAll(find = {}) {
|
|
637
|
+
if (glock) {
|
|
638
|
+
await waitFun(() => {
|
|
639
|
+
return !glock
|
|
640
|
+
})
|
|
641
|
+
}
|
|
642
|
+
glock = true
|
|
643
|
+
return await delAllCore(find)
|
|
644
|
+
.finally(() => {
|
|
645
|
+
glock = false
|
|
646
|
+
})
|
|
593
647
|
}
|
|
594
648
|
|
|
595
649
|
//bind
|