w-serv-orm 1.1.7 → 1.1.9
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 +2 -6
- package/dist/w-serv-orm.umd.js +2 -2
- package/dist/w-serv-orm.umd.js.map +1 -1
- package/docs/WServOrm.html +21 -158
- package/docs/WServOrm.mjs.html +48 -16
- package/docs/index.html +1 -1
- package/g-mOrm.mjs +2 -6
- package/package.json +3 -3
- package/schema/tables/tests.mjs +1 -1
- package/src/WServOrm.mjs +46 -14
- package/src/genTestData.mjs +2 -2
- package/src/getDb.mjs +27 -6
- package/src/getDbBackupAndRecover.mjs +27 -2
- package/src/getItemsFail.mjs +2 -34
- package/src/getMapOrm.mjs +128 -46
- package/src/getProc.mjs +104 -180
- package/src/getSettings.mjs +1 -1
- package/test/api-procOrm.test.mjs +27 -2
- package/test/unit-WServOrm.test.mjs +567 -0
- package/test/unit-getDb.test.mjs +188 -0
- package/test/unit-mapOrm.test.mjs +119 -14
|
@@ -1,10 +1,15 @@
|
|
|
1
1
|
// import path from 'path'
|
|
2
2
|
import fs from 'fs'
|
|
3
|
-
import trim from 'lodash-es/trim.js'
|
|
4
|
-
import size from 'lodash-es/size.js'
|
|
3
|
+
import trim from 'lodash-es/trim.js'
|
|
4
|
+
import size from 'lodash-es/size.js'
|
|
5
|
+
import get from 'lodash-es/get.js'
|
|
6
|
+
import each from 'lodash-es/each.js'
|
|
5
7
|
import pmSeries from 'wsemi/src/pmSeries.mjs'
|
|
6
8
|
import fsIsFile from 'wsemi/src/fsIsFile.mjs'
|
|
7
9
|
import iseobj from 'wsemi/src/iseobj.mjs'
|
|
10
|
+
import isearr from 'wsemi/src/isearr.mjs'
|
|
11
|
+
import isestr from 'wsemi/src/isestr.mjs'
|
|
12
|
+
import haskey from 'wsemi/src/haskey.mjs'
|
|
8
13
|
import isfun from 'wsemi/src/isfun.mjs'
|
|
9
14
|
import isbol from 'wsemi/src/isbol.mjs'
|
|
10
15
|
import j2o from 'wsemi/src/j2o.mjs'
|
|
@@ -12,6 +17,12 @@ import j2o from 'wsemi/src/j2o.mjs'
|
|
|
12
17
|
|
|
13
18
|
async function backup(woItems) {
|
|
14
19
|
|
|
20
|
+
//check, 同recover; 否則無效值由pmSeries以字串reject, 而空物件或空陣列會產出recover拒收之空備份
|
|
21
|
+
if (!iseobj(woItems)) {
|
|
22
|
+
console.log('woItems', woItems)
|
|
23
|
+
throw new Error('invalid woItems')
|
|
24
|
+
}
|
|
25
|
+
|
|
15
26
|
//rs
|
|
16
27
|
let rs = await pmSeries(woItems, async (v, k) => {
|
|
17
28
|
console.log('backup...', k)
|
|
@@ -58,6 +69,20 @@ async function recover(fp, woItems, genModels, needCreateStorage = false) {
|
|
|
58
69
|
let rs = j2o(j)
|
|
59
70
|
// console.log('recover rs', rs)
|
|
60
71
|
|
|
72
|
+
//check, 備份內容須為非空陣列, 且各筆之name為woItems內之資料表; 於任何寫入之前驗證, 避免空檔或壞檔(j2o解析失敗回{})假成功, 亦避免部分還原
|
|
73
|
+
if (!isearr(rs)) {
|
|
74
|
+
throw new Error('invalid backup data, need a non-empty array')
|
|
75
|
+
}
|
|
76
|
+
each(rs, (v, k) => {
|
|
77
|
+
let name = get(v, 'name')
|
|
78
|
+
if (!isestr(name)) {
|
|
79
|
+
throw new Error(`invalid backup data, rs[${k}].name is not a string`)
|
|
80
|
+
}
|
|
81
|
+
if (!haskey(woItems, name)) {
|
|
82
|
+
throw new Error(`invalid backup data, table[${name}] is not in woItems`)
|
|
83
|
+
}
|
|
84
|
+
})
|
|
85
|
+
|
|
61
86
|
//genModels
|
|
62
87
|
if (isfun(genModels)) {
|
|
63
88
|
genModels()
|
package/src/getItemsFail.mjs
CHANGED
|
@@ -1,37 +1,5 @@
|
|
|
1
|
-
import
|
|
2
|
-
import each from 'lodash-es/each.js'
|
|
3
|
-
import isarr from 'wsemi/src/isarr.mjs'
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
function getItemsFail(rs, data) {
|
|
7
|
-
//由ORM逐筆函數(save、del)之回傳結果取出失敗者, 回傳[{k,id,err}], k為該筆於輸入內之位置
|
|
8
|
-
//w-orm系列規格: 逐筆函數回傳與輸入等長保序之陣列, 單筆失敗時整批仍resolve, 該筆以ok為0並附err回報, 須由呼叫端逐筆檢查
|
|
9
|
-
//逐筆結果不含主鍵, 故主鍵取自輸入之同位置數據
|
|
10
|
-
|
|
11
|
-
//check, 未依規格之ORM可能回傳非陣列, 無從逐筆檢查
|
|
12
|
-
if (!isarr(rs)) {
|
|
13
|
-
return []
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
//check, 輸入為單一物件時ORM回傳長度為1之陣列
|
|
17
|
-
if (!isarr(data)) {
|
|
18
|
-
data = [data]
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
//fails, 僅ok為0者視為失敗
|
|
22
|
-
let fails = []
|
|
23
|
-
each(rs, (v, k) => {
|
|
24
|
-
if (get(v, 'ok') === 0) {
|
|
25
|
-
fails.push({
|
|
26
|
-
k,
|
|
27
|
-
id: get(data, [k, 'id']),
|
|
28
|
-
err: get(v, 'err', ''),
|
|
29
|
-
})
|
|
30
|
-
}
|
|
31
|
-
})
|
|
32
|
-
|
|
33
|
-
return fails
|
|
34
|
-
}
|
|
1
|
+
import getItemsFail from 'w-data-collector/src/getItemsFail.mjs'
|
|
35
2
|
|
|
36
3
|
|
|
4
|
+
//相容檔: 本套件1.1.7曾以此路徑提供getItemsFail, 使用端有以深層路徑引用者(如w-web-sso之server/ormWrite.mjs), 故保留並轉出w-data-collector之實作
|
|
37
5
|
export default getItemsFail
|
package/src/getMapOrm.mjs
CHANGED
|
@@ -4,54 +4,98 @@ import map from 'lodash-es/map.js'
|
|
|
4
4
|
import size from 'lodash-es/size.js'
|
|
5
5
|
import take from 'lodash-es/take.js'
|
|
6
6
|
import join from 'lodash-es/join.js'
|
|
7
|
+
import truncate from 'lodash-es/truncate.js'
|
|
7
8
|
import nowms2str from 'wsemi/src/nowms2str.mjs'
|
|
9
|
+
import genIDSeq from 'wsemi/src/genIDSeq.mjs'
|
|
8
10
|
import isarr from 'wsemi/src/isarr.mjs'
|
|
9
11
|
import iseobj from 'wsemi/src/iseobj.mjs'
|
|
10
12
|
import isestr from 'wsemi/src/isestr.mjs'
|
|
11
13
|
import isnum from 'wsemi/src/isnum.mjs'
|
|
12
14
|
import clearXSS from 'wsemi/src/clearXSS.mjs'
|
|
13
|
-
import getItemsFail from '
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
let _ds = null
|
|
17
|
-
let _woItems = null
|
|
15
|
+
import getItemsFail from 'w-data-collector/src/getItemsFail.mjs'
|
|
18
16
|
|
|
19
17
|
|
|
20
18
|
function getMsgFail(msg, fails) {
|
|
21
19
|
//前端訊息僅列出失敗筆, 錯誤原文另由console.log輸出, 與既有整批錯誤之處理一致
|
|
22
20
|
//有效主鍵(非空字串或數字)列為id[...], 否則列其於輸入內之位置, 失敗筆數過多時僅列前nShow筆並附總筆數
|
|
21
|
+
//主鍵超過nIdMax字元者截斷顯示(LMDB逐筆失敗常因主鍵超長, 故兩者常同時出現), log仍保留全文
|
|
23
22
|
|
|
24
|
-
//nShow
|
|
23
|
+
//nShow, nIdMax
|
|
25
24
|
let nShow = 10
|
|
25
|
+
let nIdMax = 100
|
|
26
26
|
|
|
27
27
|
//ss
|
|
28
28
|
let ss = map(take(fails, nShow), (v) => {
|
|
29
29
|
if (isestr(v.id) || isnum(v.id)) {
|
|
30
|
-
return `id[${v.id}]`
|
|
30
|
+
return `id[${truncate(String(v.id), { length: nIdMax, omission: '…' })}]`
|
|
31
31
|
}
|
|
32
|
-
return
|
|
32
|
+
return `data[${v.k}]`
|
|
33
33
|
})
|
|
34
34
|
|
|
35
35
|
//c
|
|
36
36
|
let c = `${msg}: ${join(ss, ', ')}`
|
|
37
37
|
if (size(fails) > nShow) {
|
|
38
|
-
c +=
|
|
38
|
+
c += `, ... (${size(fails)} in total)`
|
|
39
39
|
}
|
|
40
40
|
|
|
41
41
|
return c
|
|
42
42
|
}
|
|
43
43
|
|
|
44
44
|
|
|
45
|
-
function
|
|
45
|
+
function isPkIdString(dsTab, keys) {
|
|
46
|
+
//資料表之主鍵欄是否為id且可容納字串型之補值, 供adjustData判斷是否補主鍵
|
|
47
|
+
|
|
48
|
+
//check, 須有id欄; 有settings者另須標為pk
|
|
49
|
+
if (keys.indexOf('id') < 0) {
|
|
50
|
+
return false
|
|
51
|
+
}
|
|
52
|
+
let settings = get(dsTab, 'settings', null)
|
|
53
|
+
if (iseobj(settings) && get(settings, 'id.pk') !== true) {
|
|
54
|
+
return false
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
//check, 型別已知者須為字串型, 與w-orm-reladb可自動補值之主鍵欄型別一致
|
|
58
|
+
let type = get(settings, 'id.type', '') || get(dsTab, 'kpType.id', '')
|
|
59
|
+
if (isestr(type) && ['STRING', 'TEXT', 'CHAR', 'UUID', 'CITEXT'].indexOf(type.toUpperCase()) < 0) {
|
|
60
|
+
return false
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
return true
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
|
|
67
|
+
function getItemsIdXSS(data) {
|
|
68
|
+
//輸入數據之主鍵(非空字串)會被clearXSS改寫者, 回傳[{k,id}], k為其於輸入內之位置
|
|
69
|
+
//寫入路徑之欄位皆經clearXSS而select與del不經過, 主鍵被改寫後以原主鍵查詢與刪除皆找不到, 故呼叫端須於寫入前整批拒絕
|
|
70
|
+
let rs = []
|
|
71
|
+
each(isarr(data) ? data : [data], (v, k) => {
|
|
72
|
+
let id = get(v, 'id')
|
|
73
|
+
if (isestr(id) && clearXSS(id) !== id) {
|
|
74
|
+
rs.push({ k, id })
|
|
75
|
+
}
|
|
76
|
+
})
|
|
77
|
+
return rs
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
|
|
81
|
+
function getMsgIdXSS(msg, fails) {
|
|
82
|
+
//主鍵含HTML標記, 訊息只列位置不回顯主鍵, 主鍵原文另由console.log輸出
|
|
83
|
+
return getMsgFail(`${msg}, id contains HTML markup`, map(fails, (v) => {
|
|
84
|
+
return { k: v.k }
|
|
85
|
+
}))
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
|
|
89
|
+
function adjustData(ds, woName, userId, data, mode = 'save') { //mode: 'insert', 'save', 'insert+save'
|
|
46
90
|
|
|
47
91
|
//check
|
|
48
|
-
if (!iseobj(
|
|
49
|
-
console.log('ds',
|
|
92
|
+
if (!iseobj(ds)) {
|
|
93
|
+
console.log('ds', ds)
|
|
50
94
|
throw new Error('invalid ds')
|
|
51
95
|
}
|
|
52
96
|
|
|
53
97
|
//keys
|
|
54
|
-
let keys =
|
|
98
|
+
let keys = ds[woName].keys
|
|
55
99
|
|
|
56
100
|
//one
|
|
57
101
|
let one = false
|
|
@@ -128,6 +172,17 @@ function adjustData(woName, userId, data, mode = 'save') { //mode: 'insert', 'sa
|
|
|
128
172
|
})
|
|
129
173
|
}
|
|
130
174
|
|
|
175
|
+
//id, 未提供有效主鍵者由本套件補值, 令回傳之主鍵與實際寫入者一致, 補值器同各ORM之genIDSeq
|
|
176
|
+
//有效主鍵之判定同w-orm系列: 非空字串或數字(reladb、mdb視數字為有效)
|
|
177
|
+
//補值寫在上方之複本, 不改呼叫端原物件; 無欄位之列不補, 保留ORM視空物件為無效輸入之行為
|
|
178
|
+
if (isPkIdString(ds[woName], keys)) {
|
|
179
|
+
each(data, (v) => {
|
|
180
|
+
if (size(v) > 0 && !isestr(v.id) && !isnum(v.id)) {
|
|
181
|
+
v.id = genIDSeq()
|
|
182
|
+
}
|
|
183
|
+
})
|
|
184
|
+
}
|
|
185
|
+
|
|
131
186
|
//復原data型態, 若原本data為物件則取第0個回傳
|
|
132
187
|
data = one ? data[0] : data
|
|
133
188
|
|
|
@@ -135,22 +190,22 @@ function adjustData(woName, userId, data, mode = 'save') { //mode: 'insert', 'sa
|
|
|
135
190
|
}
|
|
136
191
|
|
|
137
192
|
|
|
138
|
-
async function mapOrm(userId, woName, mode, input) {
|
|
193
|
+
async function mapOrm(ds, woItems, userId, woName, mode, input) {
|
|
139
194
|
//由woName自動綁定至woItems內的ORM物件
|
|
140
195
|
let err = null
|
|
141
196
|
let r
|
|
142
197
|
|
|
143
198
|
//check
|
|
144
|
-
if (!iseobj(
|
|
145
|
-
return Promise.reject(
|
|
199
|
+
if (!iseobj(woItems)) {
|
|
200
|
+
return Promise.reject(`invalid woItems`)
|
|
146
201
|
}
|
|
147
202
|
|
|
148
203
|
//wo
|
|
149
|
-
let wo = get(
|
|
204
|
+
let wo = get(woItems, woName, null)
|
|
150
205
|
|
|
151
206
|
//check
|
|
152
207
|
if (wo === null) {
|
|
153
|
-
return Promise.reject(`
|
|
208
|
+
return Promise.reject(`can not find table[${woName}] in ORM`)
|
|
154
209
|
}
|
|
155
210
|
|
|
156
211
|
if (mode === 'select') {
|
|
@@ -159,7 +214,7 @@ async function mapOrm(userId, woName, mode, input) {
|
|
|
159
214
|
r = await wo.select(input)
|
|
160
215
|
.catch((msg) => {
|
|
161
216
|
console.log(`${woName}.select catch`, msg)
|
|
162
|
-
err = '
|
|
217
|
+
err = 'failed to select data'
|
|
163
218
|
})
|
|
164
219
|
|
|
165
220
|
//check
|
|
@@ -170,13 +225,23 @@ async function mapOrm(userId, woName, mode, input) {
|
|
|
170
225
|
}
|
|
171
226
|
else if (mode === 'insert' || mode === 'save') {
|
|
172
227
|
|
|
228
|
+
//inputOrig, 呼叫端原輸入, 逐筆失敗之訊息以呼叫端視角列出(本套件補出之主鍵只寫於複本, reject時呼叫端未曾取得)
|
|
229
|
+
let inputOrig = input
|
|
230
|
+
|
|
231
|
+
//check, 主鍵會被clearXSS改寫者整批拒絕, 不寫入任何一筆
|
|
232
|
+
let failsIdXSS = getItemsIdXSS(input)
|
|
233
|
+
if (size(failsIdXSS) > 0) {
|
|
234
|
+
console.log(`${woName}.${mode} id changed by clearXSS`, failsIdXSS)
|
|
235
|
+
return Promise.reject(getMsgIdXSS(mode === 'insert' ? 'failed to insert data' : 'failed to save data', failsIdXSS))
|
|
236
|
+
}
|
|
237
|
+
|
|
173
238
|
//adjustData
|
|
174
239
|
try {
|
|
175
|
-
input = adjustData(woName, userId, input, mode)
|
|
240
|
+
input = adjustData(ds, woName, userId, input, mode)
|
|
176
241
|
}
|
|
177
242
|
catch (e) {
|
|
178
|
-
console.log(
|
|
179
|
-
err = '
|
|
243
|
+
console.log(`${woName}.adjustData catch`, e.toString())
|
|
244
|
+
err = 'failed to adjust data'
|
|
180
245
|
return Promise.reject(err)
|
|
181
246
|
}
|
|
182
247
|
|
|
@@ -184,15 +249,15 @@ async function mapOrm(userId, woName, mode, input) {
|
|
|
184
249
|
if (mode === 'insert') {
|
|
185
250
|
r = await wo.insert(input)
|
|
186
251
|
.catch((msg) => {
|
|
187
|
-
console.log(`${woName}.
|
|
188
|
-
err = '
|
|
252
|
+
console.log(`${woName}.insert catch`, msg)
|
|
253
|
+
err = 'failed to insert data'
|
|
189
254
|
})
|
|
190
255
|
}
|
|
191
256
|
else if (mode === 'save') {
|
|
192
257
|
r = await wo.save(input)
|
|
193
258
|
.catch((msg) => {
|
|
194
259
|
console.log(`${woName}.save catch`, msg)
|
|
195
|
-
err = '
|
|
260
|
+
err = 'failed to save data'
|
|
196
261
|
})
|
|
197
262
|
}
|
|
198
263
|
|
|
@@ -207,7 +272,7 @@ async function mapOrm(userId, woName, mode, input) {
|
|
|
207
272
|
let fails = getItemsFail(r, input)
|
|
208
273
|
if (size(fails) > 0) {
|
|
209
274
|
console.log(`${woName}.save fail`, fails)
|
|
210
|
-
return Promise.reject(getMsgFail('
|
|
275
|
+
return Promise.reject(getMsgFail('failed to save data', getItemsFail(r, inputOrig)))
|
|
211
276
|
}
|
|
212
277
|
}
|
|
213
278
|
|
|
@@ -229,7 +294,7 @@ async function mapOrm(userId, woName, mode, input) {
|
|
|
229
294
|
r = await wo.del(input)
|
|
230
295
|
.catch((msg) => {
|
|
231
296
|
console.log(`${woName}.del catch`, msg)
|
|
232
|
-
err = '
|
|
297
|
+
err = 'failed to delete data'
|
|
233
298
|
})
|
|
234
299
|
|
|
235
300
|
//check, 單筆失敗時整批仍resolve並以該筆ok為0回報, 須逐筆檢查
|
|
@@ -237,7 +302,7 @@ async function mapOrm(userId, woName, mode, input) {
|
|
|
237
302
|
let fails = getItemsFail(r, input)
|
|
238
303
|
if (size(fails) > 0) {
|
|
239
304
|
console.log(`${woName}.del fail`, fails)
|
|
240
|
-
err = getMsgFail('
|
|
305
|
+
err = getMsgFail('failed to delete data', fails)
|
|
241
306
|
}
|
|
242
307
|
}
|
|
243
308
|
|
|
@@ -248,7 +313,7 @@ async function mapOrm(userId, woName, mode, input) {
|
|
|
248
313
|
r = await wo.delAll(input)
|
|
249
314
|
.catch((msg) => {
|
|
250
315
|
console.log(`${woName}.delAll catch`, msg)
|
|
251
|
-
err = '
|
|
316
|
+
err = 'failed to delete data'
|
|
252
317
|
})
|
|
253
318
|
|
|
254
319
|
}
|
|
@@ -256,7 +321,20 @@ async function mapOrm(userId, woName, mode, input) {
|
|
|
256
321
|
|
|
257
322
|
//check
|
|
258
323
|
if (!iseobj(input)) {
|
|
259
|
-
return Promise.reject('mix
|
|
324
|
+
return Promise.reject('invalid input of mix, need the result object of ltdtDiffByKey')
|
|
325
|
+
}
|
|
326
|
+
|
|
327
|
+
//check, 新增與修改之主鍵會被clearXSS改寫者, 於任何步驟寫入之前整批拒絕
|
|
328
|
+
let msgsIdXSS = []
|
|
329
|
+
for (let [key, msg] of [['add', 'failed to insert data'], ['diff', 'failed to update data']]) {
|
|
330
|
+
let fails = getItemsIdXSS(get(input, key, []))
|
|
331
|
+
if (size(fails) > 0) {
|
|
332
|
+
console.log(`${woName}.mix ${key} id changed by clearXSS`, fails)
|
|
333
|
+
msgsIdXSS.push(getMsgIdXSS(msg, fails))
|
|
334
|
+
}
|
|
335
|
+
}
|
|
336
|
+
if (size(msgsIdXSS) > 0) {
|
|
337
|
+
return Promise.reject(join(msgsIdXSS, '; '))
|
|
260
338
|
}
|
|
261
339
|
|
|
262
340
|
//rt,r
|
|
@@ -271,19 +349,19 @@ async function mapOrm(userId, woName, mode, input) {
|
|
|
271
349
|
|
|
272
350
|
//adjustData
|
|
273
351
|
try {
|
|
274
|
-
add = adjustData(woName, userId, add, 'insert+save')
|
|
352
|
+
add = adjustData(ds, woName, userId, add, 'insert+save')
|
|
275
353
|
}
|
|
276
354
|
catch (e) {
|
|
277
|
-
console.log(
|
|
278
|
-
err = '
|
|
355
|
+
console.log(`${woName}.adjustData catch`, e.toString())
|
|
356
|
+
err = 'failed to adjust data'
|
|
279
357
|
return Promise.reject(err)
|
|
280
358
|
}
|
|
281
359
|
|
|
282
360
|
//insert
|
|
283
361
|
await wo.insert(add)
|
|
284
362
|
.catch((msg) => {
|
|
285
|
-
console.log(`${woName}.
|
|
286
|
-
err = '
|
|
363
|
+
console.log(`${woName}.insert catch`, msg)
|
|
364
|
+
err = 'failed to insert data'
|
|
287
365
|
})
|
|
288
366
|
|
|
289
367
|
//check
|
|
@@ -304,8 +382,8 @@ async function mapOrm(userId, woName, mode, input) {
|
|
|
304
382
|
//del
|
|
305
383
|
let rs = await wo.del(del)
|
|
306
384
|
.catch((msg) => {
|
|
307
|
-
console.log(`${woName}.
|
|
308
|
-
err = '
|
|
385
|
+
console.log(`${woName}.del catch`, msg)
|
|
386
|
+
err = 'failed to delete data'
|
|
309
387
|
})
|
|
310
388
|
|
|
311
389
|
//check
|
|
@@ -317,7 +395,7 @@ async function mapOrm(userId, woName, mode, input) {
|
|
|
317
395
|
let fails = getItemsFail(rs, del)
|
|
318
396
|
if (size(fails) > 0) {
|
|
319
397
|
console.log(`${woName}.del fail`, fails)
|
|
320
|
-
msgsFail.push(getMsgFail('
|
|
398
|
+
msgsFail.push(getMsgFail('failed to delete data', fails))
|
|
321
399
|
}
|
|
322
400
|
|
|
323
401
|
//r
|
|
@@ -330,13 +408,16 @@ async function mapOrm(userId, woName, mode, input) {
|
|
|
330
408
|
let diff = get(input, 'diff', [])
|
|
331
409
|
if (size(diff) > 0) {
|
|
332
410
|
|
|
411
|
+
//diffOrig, 呼叫端原輸入, 逐筆失敗之訊息以呼叫端視角列出
|
|
412
|
+
let diffOrig = diff
|
|
413
|
+
|
|
333
414
|
//adjustData
|
|
334
415
|
try {
|
|
335
|
-
diff = adjustData(woName, userId, diff)
|
|
416
|
+
diff = adjustData(ds, woName, userId, diff)
|
|
336
417
|
}
|
|
337
418
|
catch (e) {
|
|
338
|
-
console.log(
|
|
339
|
-
err = '
|
|
419
|
+
console.log(`${woName}.adjustData catch`, e.toString())
|
|
420
|
+
err = 'failed to adjust data'
|
|
340
421
|
return Promise.reject(err)
|
|
341
422
|
}
|
|
342
423
|
|
|
@@ -344,7 +425,7 @@ async function mapOrm(userId, woName, mode, input) {
|
|
|
344
425
|
let rs = await wo.save(diff)
|
|
345
426
|
.catch((msg) => {
|
|
346
427
|
console.log(`${woName}.save catch`, msg)
|
|
347
|
-
err = '
|
|
428
|
+
err = 'failed to update data'
|
|
348
429
|
})
|
|
349
430
|
|
|
350
431
|
//check
|
|
@@ -356,7 +437,7 @@ async function mapOrm(userId, woName, mode, input) {
|
|
|
356
437
|
let fails = getItemsFail(rs, diff)
|
|
357
438
|
if (size(fails) > 0) {
|
|
358
439
|
console.log(`${woName}.save fail`, fails)
|
|
359
|
-
msgsFail.push(getMsgFail('
|
|
440
|
+
msgsFail.push(getMsgFail('failed to update data', getItemsFail(rs, diffOrig)))
|
|
360
441
|
}
|
|
361
442
|
|
|
362
443
|
//r
|
|
@@ -387,9 +468,10 @@ async function mapOrm(userId, woName, mode, input) {
|
|
|
387
468
|
|
|
388
469
|
|
|
389
470
|
function getMapOrm(ds, woItems) {
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
471
|
+
//每次呼叫各自綁定ds與woItems並回傳新函數, 令同一行程內之多個實例互不干擾; 回傳函數之參數形狀維持(userId, woName, mode, input)
|
|
472
|
+
return async (userId, woName, mode, input) => {
|
|
473
|
+
return mapOrm(ds, woItems, userId, woName, mode, input)
|
|
474
|
+
}
|
|
393
475
|
}
|
|
394
476
|
|
|
395
477
|
|