w-serv-orm 1.1.6 → 1.1.8
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 +1 -0
- package/dist/w-serv-orm.umd.js +2 -2
- package/dist/w-serv-orm.umd.js.map +1 -1
- package/docs/WServOrm.html +20 -6
- package/docs/WServOrm.mjs.html +22 -4
- package/docs/index.html +1 -1
- package/g-mOrm.mjs +1 -0
- package/package.json +3 -3
- package/schema/tables/tests.mjs +1 -1
- package/src/WServOrm.mjs +21 -3
- package/src/genTestData.mjs +11 -3
- package/src/getDb.mjs +27 -6
- package/src/getDbBackupAndRecover.mjs +27 -2
- package/src/getItemsFail.mjs +5 -0
- package/src/getMapOrm.mjs +189 -37
- package/src/getProc.mjs +79 -70
- package/src/getSettings.mjs +1 -1
- package/test/api-procOrm.test.mjs +93 -0
- package/test/unit-WServOrm.test.mjs +554 -0
- package/test/unit-getDb.test.mjs +188 -0
- package/test/unit-mapOrm.test.mjs +373 -0
package/docs/WServOrm.html
CHANGED
|
@@ -74,13 +74,27 @@
|
|
|
74
74
|
<dl class="details">
|
|
75
75
|
|
|
76
76
|
<dt class="tag-description">Description:</dt>
|
|
77
|
-
<dd class="tag-description"><ul class="dummy"><li><p>產生伺服器ORM的支援物件</p
|
|
77
|
+
<dd class="tag-description"><ul class="dummy"><li><p>產生伺服器ORM的支援物件</p>
|
|
78
|
+
<p>每次呼叫各自建立資料表ORM、設定與擴充函數,同一行程內之多個實例互不干擾;同一url與db之資料庫資源能否並存,依所用ORM而定。</p>
|
|
79
|
+
<p>procOrm之save、del與mix,於ORM回傳之逐筆結果有任一筆ok為0(單筆失敗)時reject,訊息列出失敗筆之主鍵,如'failed to save data: id[b]'(超過100字元者截斷顯示;無有效主鍵者以data[k]列其於輸入內之位置,k自0起;超過10筆者只列前10筆並附總筆數),錯誤原文另由console.log輸出。
|
|
80
|
+
單筆失敗不中斷整批,故reject時其餘筆數已寫入。
|
|
81
|
+
mix之各步驟遇單筆失敗不中斷後續步驟,待全部步驟完成後一併reject;遇整批性錯誤則立即reject,後續步驟不執行。</p>
|
|
82
|
+
<p>insert、save與mix之新增、修改,數據未帶有效主鍵(非空字串或數字)者,若資料表之主鍵欄為id且為字串型(或型別未知),由本套件產生主鍵(同各ORM之genIDSeq)並於resolve時回傳;無欄位之數據不補。
|
|
83
|
+
reject時不回傳補出之主鍵,故重送未帶主鍵之數據會再產生新主鍵而重複寫入,需冪等重送者請自帶主鍵;save帶主鍵者重送以主鍵覆寫,del重送時已刪除者為主鍵未命中。
|
|
84
|
+
insert(含mix之新增)為主鍵已存在即略過之冪等新增,回傳之id含被略過者;recover亦以insert還原,故資料表須先清空。
|
|
85
|
+
insert、save與mix之新增、修改,寫入前各欄位之字串皆經wsemi之clearXSS清除(白名單外之標籤轉義,白名單內之標籤刪除白名單外之屬性與危險網址,標籤外之文字只轉義會開始標籤之<,故'a < b'等數學式不改寫);select與del不經清除。
|
|
86
|
+
字串主鍵若會被清除改寫(含HTML標記,如<後緊接英文字母),整批reject且不寫入任何一筆(mix於任何步驟之前檢查新增與修改),訊息列其位置而不回顯主鍵,如'failed to save data, id contains HTML markup: data[1]';否則改寫後之主鍵與呼叫端所持者不同,以原主鍵查詢與刪除皆找不到。</p>
|
|
87
|
+
<p>擴充函數(addFunCheck、addFunPreProcessing、addFunPostProcessing)屬於各實例,重建實例後須重新註冊;註冊時須傳入函數,否則立即拋錯(addFunCheck另令該實例之procOrm一律reject);註冊後約1毫秒(以計時器)才生效,在此之前之procOrm呼叫不會套用。
|
|
88
|
+
呼叫契約:check以reject或拋錯阻擋,回傳值不影響結果,且早於前處理執行;前處理逐一呼叫,各收新建之參數物件{woName,userId,isAdmin,mode,input},input為前一個回傳之input,回傳須為含input之物件否則reject;後處理逐一呼叫,各收新建之參數物件且其output為前一個之回傳值,最後之回傳值即為procOrm之回傳值。
|
|
89
|
+
後處理只在使用者檢查、check、前處理與ORM操作皆成功後執行,逐筆失敗(含del)或mix部分寫入後reject者皆不執行;後處理自身亦可reject。後處理之input為呼叫端傳入之數據,不含本套件補出之主鍵,主鍵見output。
|
|
90
|
+
如需觀察ORM實際寫入,可另監聽woItems內各ORM之change與error事件;惟事件由ORM發出,不含userId與isAdmin,mix會依步驟分次發出,經woItems直接寫入者亦會發出,insert之結果為聚合計數而非逐筆。
|
|
91
|
+
錯誤型別:procOrm由本套件產生之reject一律為英文訊息字串(供前端顯示或對應多語系;ORM之錯誤原文另由console.log輸出而不轉出),呼叫端提供之函數(getUserById與擴充函數)自身之reject或拋錯則原樣轉出;建構(設定或ORM無效)、擴充函數註冊、backup與recover由本套件產生之錯誤一律為Error,ORM之錯誤則原樣轉出。</p></li></ul></dd>
|
|
78
92
|
|
|
79
93
|
|
|
80
94
|
|
|
81
95
|
<dt class="tag-source">Source:</dt>
|
|
82
96
|
<dd class="tag-source"><ul class="dummy"><li>
|
|
83
|
-
<a href="WServOrm.mjs.html">WServOrm.mjs</a>, <a href="WServOrm.mjs.html#
|
|
97
|
+
<a href="WServOrm.mjs.html">WServOrm.mjs</a>, <a href="WServOrm.mjs.html#line100">line 100</a>
|
|
84
98
|
</li></ul></dd>
|
|
85
99
|
|
|
86
100
|
|
|
@@ -441,7 +455,7 @@
|
|
|
441
455
|
</td>
|
|
442
456
|
|
|
443
457
|
|
|
444
|
-
<td class="description last"><p>輸入當useCheckUser=true時依照使用者ID取得使用者資訊物件函數,預設null</p></td>
|
|
458
|
+
<td class="description last"><p>輸入當useCheckUser=true時依照使用者ID取得使用者資訊物件函數,預設null;建構時不檢查,未給或非函數時useCheckUser為true之procOrm呼叫一律reject</p></td>
|
|
445
459
|
</tr>
|
|
446
460
|
|
|
447
461
|
|
|
@@ -481,7 +495,7 @@
|
|
|
481
495
|
</td>
|
|
482
496
|
|
|
483
497
|
|
|
484
|
-
<td class="description last"><p
|
|
498
|
+
<td class="description last"><p>輸入非管理者使用procOrm之select時是否濾除isActive為'n'之數據布林值,預設true</p></td>
|
|
485
499
|
</tr>
|
|
486
500
|
|
|
487
501
|
|
|
@@ -514,7 +528,7 @@
|
|
|
514
528
|
|
|
515
529
|
|
|
516
530
|
<div class="param-desc">
|
|
517
|
-
<p
|
|
531
|
+
<p>回傳伺服器ORM支援物件,含woItems(各資料表ORM實例)、procOrm(資料操作函數,輸入為userId、woName、mode、input)、addFunCheck、addFunPreProcessing、addFunPostProcessing、closeAll(逐一關閉各資料表ORM之連線),以及backup(woItems)與recover(fp, woItems, genModels, needCreateStorage);後兩者不綁定本實例,須自行傳入woItems(須為非空物件,否則reject),其參數順序與getDb之recover(woItems, fp, opt)不同;recover於寫入前驗證備份內容(須為非空陣列且各筆之name為woItems內之資料表),失敗時reject,逐表寫入時中途失敗則先前之表已寫入</p>
|
|
518
532
|
</div>
|
|
519
533
|
|
|
520
534
|
|
|
@@ -573,7 +587,7 @@
|
|
|
573
587
|
<br class="clear">
|
|
574
588
|
|
|
575
589
|
<footer>
|
|
576
|
-
Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 4.0.5</a> on
|
|
590
|
+
Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 4.0.5</a> on Mon Oct 12 2026 13:45:56 GMT+0800 (台北標準時間) using the <a href="https://github.com/clenemt/docdash">docdash</a> theme.
|
|
577
591
|
</footer>
|
|
578
592
|
|
|
579
593
|
<script>prettyPrint();</script>
|
package/docs/WServOrm.mjs.html
CHANGED
|
@@ -56,6 +56,24 @@ import getProc from './getProc.mjs'
|
|
|
56
56
|
/**
|
|
57
57
|
* 產生伺服器ORM的支援物件
|
|
58
58
|
*
|
|
59
|
+
* 每次呼叫各自建立資料表ORM、設定與擴充函數,同一行程內之多個實例互不干擾;同一url與db之資料庫資源能否並存,依所用ORM而定。
|
|
60
|
+
*
|
|
61
|
+
* procOrm之save、del與mix,於ORM回傳之逐筆結果有任一筆ok為0(單筆失敗)時reject,訊息列出失敗筆之主鍵,如'failed to save data: id[b]'(超過100字元者截斷顯示;無有效主鍵者以data[k]列其於輸入內之位置,k自0起;超過10筆者只列前10筆並附總筆數),錯誤原文另由console.log輸出。
|
|
62
|
+
* 單筆失敗不中斷整批,故reject時其餘筆數已寫入。
|
|
63
|
+
* mix之各步驟遇單筆失敗不中斷後續步驟,待全部步驟完成後一併reject;遇整批性錯誤則立即reject,後續步驟不執行。
|
|
64
|
+
*
|
|
65
|
+
* insert、save與mix之新增、修改,數據未帶有效主鍵(非空字串或數字)者,若資料表之主鍵欄為id且為字串型(或型別未知),由本套件產生主鍵(同各ORM之genIDSeq)並於resolve時回傳;無欄位之數據不補。
|
|
66
|
+
* reject時不回傳補出之主鍵,故重送未帶主鍵之數據會再產生新主鍵而重複寫入,需冪等重送者請自帶主鍵;save帶主鍵者重送以主鍵覆寫,del重送時已刪除者為主鍵未命中。
|
|
67
|
+
* insert(含mix之新增)為主鍵已存在即略過之冪等新增,回傳之id含被略過者;recover亦以insert還原,故資料表須先清空。
|
|
68
|
+
* insert、save與mix之新增、修改,寫入前各欄位之字串皆經wsemi之clearXSS清除(白名單外之標籤轉義,白名單內之標籤刪除白名單外之屬性與危險網址,標籤外之文字只轉義會開始標籤之<,故'a < b'等數學式不改寫);select與del不經清除。
|
|
69
|
+
* 字串主鍵若會被清除改寫(含HTML標記,如<後緊接英文字母),整批reject且不寫入任何一筆(mix於任何步驟之前檢查新增與修改),訊息列其位置而不回顯主鍵,如'failed to save data, id contains HTML markup: data[1]';否則改寫後之主鍵與呼叫端所持者不同,以原主鍵查詢與刪除皆找不到。
|
|
70
|
+
*
|
|
71
|
+
* 擴充函數(addFunCheck、addFunPreProcessing、addFunPostProcessing)屬於各實例,重建實例後須重新註冊;註冊時須傳入函數,否則立即拋錯(addFunCheck另令該實例之procOrm一律reject);註冊後約1毫秒(以計時器)才生效,在此之前之procOrm呼叫不會套用。
|
|
72
|
+
* 呼叫契約:check以reject或拋錯阻擋,回傳值不影響結果,且早於前處理執行;前處理逐一呼叫,各收新建之參數物件{woName,userId,isAdmin,mode,input},input為前一個回傳之input,回傳須為含input之物件否則reject;後處理逐一呼叫,各收新建之參數物件且其output為前一個之回傳值,最後之回傳值即為procOrm之回傳值。
|
|
73
|
+
* 後處理只在使用者檢查、check、前處理與ORM操作皆成功後執行,逐筆失敗(含del)或mix部分寫入後reject者皆不執行;後處理自身亦可reject。後處理之input為呼叫端傳入之數據,不含本套件補出之主鍵,主鍵見output。
|
|
74
|
+
* 如需觀察ORM實際寫入,可另監聽woItems內各ORM之change與error事件;惟事件由ORM發出,不含userId與isAdmin,mix會依步驟分次發出,經woItems直接寫入者亦會發出,insert之結果為聚合計數而非逐筆。
|
|
75
|
+
* 錯誤型別:procOrm由本套件產生之reject一律為英文訊息字串(供前端顯示或對應多語系;ORM之錯誤原文另由console.log輸出而不轉出),呼叫端提供之函數(getUserById與擴充函數)自身之reject或拋錯則原樣轉出;建構(設定或ORM無效)、擴充函數註冊、backup與recover由本套件產生之錯誤一律為Error,ORM之錯誤則原樣轉出。
|
|
76
|
+
*
|
|
59
77
|
* @class
|
|
60
78
|
* @param {Object} ds 輸入資料表設定物件
|
|
61
79
|
* @param {Object} WOrm 輸入資料庫ORM物件
|
|
@@ -63,9 +81,9 @@ import getProc from './getProc.mjs'
|
|
|
63
81
|
* @param {String} db 輸入資料庫名稱字串
|
|
64
82
|
* @param {Object} [opt={}] 輸入設定物件,預設{}
|
|
65
83
|
* @param {Boolean} [opt.useCheckUser=true] 輸入是否檢查使用者資訊布林值,預設true
|
|
66
|
-
* @param {Function} [opt.getUserById=null] 輸入當useCheckUser=true時依照使用者ID取得使用者資訊物件函數,預設null
|
|
67
|
-
* @param {Boolean} [opt.useExcludeWhenNotAdmin=true]
|
|
68
|
-
* @returns {Object}
|
|
84
|
+
* @param {Function} [opt.getUserById=null] 輸入當useCheckUser=true時依照使用者ID取得使用者資訊物件函數,預設null;建構時不檢查,未給或非函數時useCheckUser為true之procOrm呼叫一律reject
|
|
85
|
+
* @param {Boolean} [opt.useExcludeWhenNotAdmin=true] 輸入非管理者使用procOrm之select時是否濾除isActive為'n'之數據布林值,預設true
|
|
86
|
+
* @returns {Object} 回傳伺服器ORM支援物件,含woItems(各資料表ORM實例)、procOrm(資料操作函數,輸入為userId、woName、mode、input)、addFunCheck、addFunPreProcessing、addFunPostProcessing、closeAll(逐一關閉各資料表ORM之連線),以及backup(woItems)與recover(fp, woItems, genModels, needCreateStorage);後兩者不綁定本實例,須自行傳入woItems(須為非空物件,否則reject),其參數順序與getDb之recover(woItems, fp, opt)不同;recover於寫入前驗證備份內容(須為非空陣列且各筆之name為woItems內之資料表),失敗時reject,逐表寫入時中途失敗則先前之表已寫入
|
|
69
87
|
* @example
|
|
70
88
|
*
|
|
71
89
|
* // import WOrm from 'w-orm-mongodb/src/WOrmMongodb.mjs' //自行選擇引用ORM
|
|
@@ -174,7 +192,7 @@ export default WServOrm
|
|
|
174
192
|
<br class="clear">
|
|
175
193
|
|
|
176
194
|
<footer>
|
|
177
|
-
Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 4.0.5</a> on
|
|
195
|
+
Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 4.0.5</a> on Mon Oct 12 2026 13:45:56 GMT+0800 (台北標準時間) using the <a href="https://github.com/clenemt/docdash">docdash</a> theme.
|
|
178
196
|
</footer>
|
|
179
197
|
|
|
180
198
|
<script>prettyPrint();</script>
|
package/docs/index.html
CHANGED
|
@@ -71,7 +71,7 @@
|
|
|
71
71
|
<br class="clear">
|
|
72
72
|
|
|
73
73
|
<footer>
|
|
74
|
-
Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 4.0.5</a> on
|
|
74
|
+
Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 4.0.5</a> on Mon Oct 12 2026 13:45:56 GMT+0800 (台北標準時間) using the <a href="https://github.com/clenemt/docdash">docdash</a> theme.
|
|
75
75
|
</footer>
|
|
76
76
|
|
|
77
77
|
<script>prettyPrint();</script>
|
package/g-mOrm.mjs
CHANGED
|
@@ -47,6 +47,7 @@ console.log(r) //回傳server用orm相關函數
|
|
|
47
47
|
// [Symbol(kCapture)]: false
|
|
48
48
|
// }
|
|
49
49
|
// },
|
|
50
|
+
// closeAll: [AsyncFunction: closeAll],
|
|
50
51
|
// addFunCheck: [Function: addFunCheck],
|
|
51
52
|
// addFunPreProcessing: [Function: addFunPreProcessing],
|
|
52
53
|
// addFunPostProcessing: [Function: addFunPostProcessing],
|
package/package.json
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "w-serv-orm",
|
|
3
|
-
"version": "1.1.
|
|
3
|
+
"version": "1.1.8",
|
|
4
4
|
"main": "dist/w-serv-orm.umd.js",
|
|
5
5
|
"dependencies": {
|
|
6
6
|
"json5": "^2.2.3",
|
|
7
|
-
"
|
|
7
|
+
"w-data-collector": "^1.0.46",
|
|
8
|
+
"wsemi": "^1.9.13"
|
|
8
9
|
},
|
|
9
10
|
"devDependencies": {
|
|
10
|
-
"w-data-collector": "^1.0.43",
|
|
11
11
|
"w-orm-lowdb": "^1.0.31",
|
|
12
12
|
"w-package-tools": "^1.1.16"
|
|
13
13
|
},
|
package/schema/tables/tests.mjs
CHANGED
package/src/WServOrm.mjs
CHANGED
|
@@ -9,6 +9,24 @@ import getProc from './getProc.mjs'
|
|
|
9
9
|
/**
|
|
10
10
|
* 產生伺服器ORM的支援物件
|
|
11
11
|
*
|
|
12
|
+
* 每次呼叫各自建立資料表ORM、設定與擴充函數,同一行程內之多個實例互不干擾;同一url與db之資料庫資源能否並存,依所用ORM而定。
|
|
13
|
+
*
|
|
14
|
+
* procOrm之save、del與mix,於ORM回傳之逐筆結果有任一筆ok為0(單筆失敗)時reject,訊息列出失敗筆之主鍵,如'failed to save data: id[b]'(超過100字元者截斷顯示;無有效主鍵者以data[k]列其於輸入內之位置,k自0起;超過10筆者只列前10筆並附總筆數),錯誤原文另由console.log輸出。
|
|
15
|
+
* 單筆失敗不中斷整批,故reject時其餘筆數已寫入。
|
|
16
|
+
* mix之各步驟遇單筆失敗不中斷後續步驟,待全部步驟完成後一併reject;遇整批性錯誤則立即reject,後續步驟不執行。
|
|
17
|
+
*
|
|
18
|
+
* insert、save與mix之新增、修改,數據未帶有效主鍵(非空字串或數字)者,若資料表之主鍵欄為id且為字串型(或型別未知),由本套件產生主鍵(同各ORM之genIDSeq)並於resolve時回傳;無欄位之數據不補。
|
|
19
|
+
* reject時不回傳補出之主鍵,故重送未帶主鍵之數據會再產生新主鍵而重複寫入,需冪等重送者請自帶主鍵;save帶主鍵者重送以主鍵覆寫,del重送時已刪除者為主鍵未命中。
|
|
20
|
+
* insert(含mix之新增)為主鍵已存在即略過之冪等新增,回傳之id含被略過者;recover亦以insert還原,故資料表須先清空。
|
|
21
|
+
* insert、save與mix之新增、修改,寫入前各欄位之字串皆經wsemi之clearXSS清除(白名單外之標籤轉義,白名單內之標籤刪除白名單外之屬性與危險網址,標籤外之文字只轉義會開始標籤之<,故'a < b'等數學式不改寫);select與del不經清除。
|
|
22
|
+
* 字串主鍵若會被清除改寫(含HTML標記,如<後緊接英文字母),整批reject且不寫入任何一筆(mix於任何步驟之前檢查新增與修改),訊息列其位置而不回顯主鍵,如'failed to save data, id contains HTML markup: data[1]';否則改寫後之主鍵與呼叫端所持者不同,以原主鍵查詢與刪除皆找不到。
|
|
23
|
+
*
|
|
24
|
+
* 擴充函數(addFunCheck、addFunPreProcessing、addFunPostProcessing)屬於各實例,重建實例後須重新註冊;註冊時須傳入函數,否則立即拋錯(addFunCheck另令該實例之procOrm一律reject);註冊後約1毫秒(以計時器)才生效,在此之前之procOrm呼叫不會套用。
|
|
25
|
+
* 呼叫契約:check以reject或拋錯阻擋,回傳值不影響結果,且早於前處理執行;前處理逐一呼叫,各收新建之參數物件{woName,userId,isAdmin,mode,input},input為前一個回傳之input,回傳須為含input之物件否則reject;後處理逐一呼叫,各收新建之參數物件且其output為前一個之回傳值,最後之回傳值即為procOrm之回傳值。
|
|
26
|
+
* 後處理只在使用者檢查、check、前處理與ORM操作皆成功後執行,逐筆失敗(含del)或mix部分寫入後reject者皆不執行;後處理自身亦可reject。後處理之input為呼叫端傳入之數據,不含本套件補出之主鍵,主鍵見output。
|
|
27
|
+
* 如需觀察ORM實際寫入,可另監聽woItems內各ORM之change與error事件;惟事件由ORM發出,不含userId與isAdmin,mix會依步驟分次發出,經woItems直接寫入者亦會發出,insert之結果為聚合計數而非逐筆。
|
|
28
|
+
* 錯誤型別:procOrm由本套件產生之reject一律為英文訊息字串(供前端顯示或對應多語系;ORM之錯誤原文另由console.log輸出而不轉出),呼叫端提供之函數(getUserById與擴充函數)自身之reject或拋錯則原樣轉出;建構(設定或ORM無效)、擴充函數註冊、backup與recover由本套件產生之錯誤一律為Error,ORM之錯誤則原樣轉出。
|
|
29
|
+
*
|
|
12
30
|
* @class
|
|
13
31
|
* @param {Object} ds 輸入資料表設定物件
|
|
14
32
|
* @param {Object} WOrm 輸入資料庫ORM物件
|
|
@@ -16,9 +34,9 @@ import getProc from './getProc.mjs'
|
|
|
16
34
|
* @param {String} db 輸入資料庫名稱字串
|
|
17
35
|
* @param {Object} [opt={}] 輸入設定物件,預設{}
|
|
18
36
|
* @param {Boolean} [opt.useCheckUser=true] 輸入是否檢查使用者資訊布林值,預設true
|
|
19
|
-
* @param {Function} [opt.getUserById=null] 輸入當useCheckUser=true時依照使用者ID取得使用者資訊物件函數,預設null
|
|
20
|
-
* @param {Boolean} [opt.useExcludeWhenNotAdmin=true]
|
|
21
|
-
* @returns {Object}
|
|
37
|
+
* @param {Function} [opt.getUserById=null] 輸入當useCheckUser=true時依照使用者ID取得使用者資訊物件函數,預設null;建構時不檢查,未給或非函數時useCheckUser為true之procOrm呼叫一律reject
|
|
38
|
+
* @param {Boolean} [opt.useExcludeWhenNotAdmin=true] 輸入非管理者使用procOrm之select時是否濾除isActive為'n'之數據布林值,預設true
|
|
39
|
+
* @returns {Object} 回傳伺服器ORM支援物件,含woItems(各資料表ORM實例)、procOrm(資料操作函數,輸入為userId、woName、mode、input)、addFunCheck、addFunPreProcessing、addFunPostProcessing、closeAll(逐一關閉各資料表ORM之連線),以及backup(woItems)與recover(fp, woItems, genModels, needCreateStorage);後兩者不綁定本實例,須自行傳入woItems(須為非空物件,否則reject),其參數順序與getDb之recover(woItems, fp, opt)不同;recover於寫入前驗證備份內容(須為非空陣列且各筆之name為woItems內之資料表),失敗時reject,逐表寫入時中途失敗則先前之表已寫入
|
|
22
40
|
* @example
|
|
23
41
|
*
|
|
24
42
|
* // import WOrm from 'w-orm-mongodb/src/WOrmMongodb.mjs' //自行選擇引用ORM
|
package/src/genTestData.mjs
CHANGED
|
@@ -1,7 +1,9 @@
|
|
|
1
|
-
import get from 'lodash-es/get.js'
|
|
1
|
+
import get from 'lodash-es/get.js'
|
|
2
|
+
import size from 'lodash-es/size.js'
|
|
2
3
|
import isbol from 'wsemi/src/isbol.mjs'
|
|
3
|
-
import isfun from 'wsemi/src/isfun.mjs'
|
|
4
|
+
import isfun from 'wsemi/src/isfun.mjs'
|
|
4
5
|
import pmSeries from 'wsemi/src/pmSeries.mjs'
|
|
6
|
+
import getItemsFail from 'w-data-collector/src/getItemsFail.mjs'
|
|
5
7
|
|
|
6
8
|
|
|
7
9
|
async function genTestData(ds, woItems, opt = {}) {
|
|
@@ -44,7 +46,13 @@ async function genTestData(ds, woItems, opt = {}) {
|
|
|
44
46
|
}
|
|
45
47
|
|
|
46
48
|
//save
|
|
47
|
-
await woItems[k].save(rs)
|
|
49
|
+
let rss = await woItems[k].save(rs)
|
|
50
|
+
|
|
51
|
+
//check, 單筆失敗時整批仍resolve並以該筆ok為0回報, 須逐筆檢查
|
|
52
|
+
let fails = getItemsFail(rss, rs)
|
|
53
|
+
if (size(fails) > 0) {
|
|
54
|
+
throw new Error(`failed to write test data into table[${k}]: ${JSON.stringify(fails)}`)
|
|
55
|
+
}
|
|
48
56
|
|
|
49
57
|
if (bLog) {
|
|
50
58
|
console.log(`${k}.funTest and save`, rs)
|
package/src/getDb.mjs
CHANGED
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
import path from 'path'
|
|
2
2
|
import fs from 'fs'
|
|
3
|
-
import get from 'lodash-es/get.js'
|
|
4
|
-
import each from 'lodash-es/each.js'
|
|
5
|
-
import keys from 'lodash-es/keys.js'
|
|
3
|
+
import get from 'lodash-es/get.js'
|
|
4
|
+
import each from 'lodash-es/each.js'
|
|
5
|
+
import keys from 'lodash-es/keys.js'
|
|
6
6
|
import iseobj from 'wsemi/src/iseobj.mjs'
|
|
7
7
|
import isbol from 'wsemi/src/isbol.mjs'
|
|
8
8
|
import isestr from 'wsemi/src/isestr.mjs'
|
|
9
|
+
import isfun from 'wsemi/src/isfun.mjs'
|
|
9
10
|
import o2j from 'wsemi/src/o2j.mjs'
|
|
10
11
|
import now2strp from 'wsemi/src/now2strp.mjs'
|
|
11
12
|
import haskey from 'wsemi/src/haskey.mjs'
|
|
@@ -38,13 +39,13 @@ function genModels(ds, genModelsByTabs, opt = {}) {
|
|
|
38
39
|
|
|
39
40
|
//check
|
|
40
41
|
if (!haskey(ds[name], 'settings')) {
|
|
41
|
-
console.log(
|
|
42
|
+
console.log(`table[${name}] has no settings`)
|
|
42
43
|
return true //跳出換下一個
|
|
43
44
|
}
|
|
44
45
|
|
|
45
46
|
//check
|
|
46
47
|
if (!iseobj(ds[name].settings)) {
|
|
47
|
-
console.log(`ds[${name}].settings
|
|
48
|
+
console.log(`invalid ds[${name}].settings`)
|
|
48
49
|
return true //跳出換下一個
|
|
49
50
|
}
|
|
50
51
|
|
|
@@ -66,6 +67,7 @@ function genModels(ds, genModelsByTabs, opt = {}) {
|
|
|
66
67
|
|
|
67
68
|
|
|
68
69
|
async function backup(woItems, opt = {}) {
|
|
70
|
+
//備份各資料表至cwd(模組載入時之工作目錄)下之backup-時間.json; 失敗時印log後reject原錯誤, 令呼叫端(含未await之頂層腳本)可偵測
|
|
69
71
|
|
|
70
72
|
//bLog
|
|
71
73
|
let bLog = get(opt, 'bLog')
|
|
@@ -80,6 +82,11 @@ async function backup(woItems, opt = {}) {
|
|
|
80
82
|
//o2j
|
|
81
83
|
let j = o2j(res)
|
|
82
84
|
|
|
85
|
+
//check, o2j無法序列化時回空字串, 不得寫出空備份而回報成功
|
|
86
|
+
if (!isestr(j)) {
|
|
87
|
+
throw new Error('backup data can not be serialized')
|
|
88
|
+
}
|
|
89
|
+
|
|
83
90
|
//fn
|
|
84
91
|
let fn = `backup-${now2strp()}.json`
|
|
85
92
|
|
|
@@ -95,12 +102,15 @@ async function backup(woItems, opt = {}) {
|
|
|
95
102
|
})
|
|
96
103
|
.catch((err) => {
|
|
97
104
|
console.log(err)
|
|
105
|
+
throw err
|
|
98
106
|
})
|
|
99
107
|
|
|
100
108
|
}
|
|
101
109
|
|
|
102
110
|
|
|
103
111
|
async function recover(woItems, fp, opt = {}) {
|
|
112
|
+
//由備份檔以insert還原各資料表; 主鍵已存在者略過, 故資料表須先清空; 逐表寫入, 中途失敗時先前之表已寫入
|
|
113
|
+
//失敗時印log後reject原錯誤; bRela為true時須提供opt.ds與opt.genModelsByTabs以產生model
|
|
104
114
|
|
|
105
115
|
//bRela, 是否為關聯資料庫
|
|
106
116
|
let bRela = get(opt, 'bRela')
|
|
@@ -115,10 +125,20 @@ async function recover(woItems, fp, opt = {}) {
|
|
|
115
125
|
}
|
|
116
126
|
|
|
117
127
|
//funGenModels and bNeedCreateStorage, 若為關聯資料庫則需使用genModels與needCreateStorage=true
|
|
128
|
+
//genModels須以ds與genModelsByTabs產生model, 低階recover則以無參數呼叫, 故以閉包帶入; 缺則於任何寫入之前reject
|
|
118
129
|
let funGenModels = null
|
|
119
130
|
let bNeedCreateStorage = false
|
|
120
131
|
if (bRela) {
|
|
121
|
-
|
|
132
|
+
let ds = get(opt, 'ds')
|
|
133
|
+
let genModelsByTabs = get(opt, 'genModelsByTabs')
|
|
134
|
+
if (!iseobj(ds) || !isfun(genModelsByTabs)) {
|
|
135
|
+
let err = new Error('bRela needs opt.ds and opt.genModelsByTabs')
|
|
136
|
+
console.log(err)
|
|
137
|
+
return Promise.reject(err)
|
|
138
|
+
}
|
|
139
|
+
funGenModels = () => {
|
|
140
|
+
genModels(ds, genModelsByTabs, opt)
|
|
141
|
+
}
|
|
122
142
|
bNeedCreateStorage = true
|
|
123
143
|
}
|
|
124
144
|
|
|
@@ -131,6 +151,7 @@ async function recover(woItems, fp, opt = {}) {
|
|
|
131
151
|
})
|
|
132
152
|
.catch((err) => {
|
|
133
153
|
console.log(err)
|
|
154
|
+
throw err
|
|
134
155
|
})
|
|
135
156
|
|
|
136
157
|
}
|
|
@@ -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()
|