w-orm-mongodb 1.1.37 → 1.1.39
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 +447 -288
- package/dist/w-orm-mongodb.umd.js +2 -2
- package/dist/w-orm-mongodb.umd.js.map +1 -1
- package/docs/WOrmMongodb.html +221 -37
- package/docs/WOrmMongodb.mjs.html +1265 -829
- package/docs/index.html +2 -2
- package/g-basic.mjs +16 -6
- package/g-gfs.mjs +102 -102
- package/g-unique.mjs +66 -0
- package/package.json +2 -3
- package/script.txt +0 -1
- package/src/WOrmMongodb.mjs +1263 -827
- package/test/api-basic.test.mjs +1200 -0
- package/test/api-gfs.test.mjs +574 -0
- package/test/lib/api-setup.mjs +142 -0
- package/test/basic.test.mjs +0 -348
- package/test/gfs.test.mjs +0 -172
package/docs/index.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="WOrmMongodb.html">WOrmMongodb</a><ul class='methods'><li data-type='method'><a href="WOrmMongodb.html#.del">del</a></li><li data-type='method'><a href="WOrmMongodb.html#.delAll">delAll</a></li><li data-type='method'><a href="WOrmMongodb.html#.delAllGfs">delAllGfs</a></li><li data-type='method'><a href="WOrmMongodb.html#.delGfs">delGfs</a></li><li data-type='method'><a href="WOrmMongodb.html#.insert">insert</a></li><li data-type='method'><a href="WOrmMongodb.html#.insertGfs">insertGfs</a></li><li data-type='method'><a href="WOrmMongodb.html#.save">save</a></li><li data-type='method'><a href="WOrmMongodb.html#.select">select</a></li><li data-type='method'><a href="WOrmMongodb.html#.
|
|
32
|
+
<h2><a href="index.html">Home</a></h2><h3>Classes</h3><ul><li><a href="WOrmMongodb.html">WOrmMongodb</a><ul class='methods'><li data-type='method'><a href="WOrmMongodb.html#.del">del</a></li><li data-type='method'><a href="WOrmMongodb.html#.delAll">delAll</a></li><li data-type='method'><a href="WOrmMongodb.html#.delAllGfs">delAllGfs</a></li><li data-type='method'><a href="WOrmMongodb.html#.delGfs">delGfs</a></li><li data-type='method'><a href="WOrmMongodb.html#.insert">insert</a></li><li data-type='method'><a href="WOrmMongodb.html#.insertGfs">insertGfs</a></li><li data-type='method'><a href="WOrmMongodb.html#.save">save</a></li><li data-type='method'><a href="WOrmMongodb.html#.select">select</a></li><li data-type='method'><a href="WOrmMongodb.html#.selectByPk">selectByPk</a></li><li data-type='method'><a href="WOrmMongodb.html#.selectByPkGfs">selectByPkGfs</a></li></ul></li></ul>
|
|
33
33
|
|
|
34
34
|
</nav>
|
|
35
35
|
|
|
@@ -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 Sun Aug 16 2026 23:36:47 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-basic.mjs
CHANGED
|
@@ -98,10 +98,18 @@ async function test() {
|
|
|
98
98
|
let spc = await wo.select({ '$or': [{ '$and': [{ value: { '$ne': 123 } }, { value: { '$in': [123, 321, 123.456, 456] } }, { value: { '$nin': [456, 654] } }] }, { '$or': [{ value: { '$lte': -1 } }, { value: { '$gte': 400 } }] }] })
|
|
99
99
|
console.log('select by $or, $and, $ne, $in, $nin', spc)
|
|
100
100
|
|
|
101
|
-
//select by regex
|
|
102
|
-
let sr = await wo.select({ name: { $regex: 'PeT', $options: '
|
|
101
|
+
//select by regex, $options之合法flag僅有i、m、x、s
|
|
102
|
+
let sr = await wo.select({ name: { $regex: 'PeT', $options: 'i' } })
|
|
103
103
|
console.log('selectReg', sr)
|
|
104
104
|
|
|
105
|
+
//selectByPk, 由id直接查找單筆, 不需如select提取全部符合數據再處理
|
|
106
|
+
let sbi = await wo.selectByPk('id-rosemary')
|
|
107
|
+
console.log('selectByPk', sbi)
|
|
108
|
+
|
|
109
|
+
//selectByPk by id not existed
|
|
110
|
+
let sbn = await wo.selectByPk('id-not-existed')
|
|
111
|
+
console.log('selectByPk by id not existed', sbn)
|
|
112
|
+
|
|
105
113
|
//del
|
|
106
114
|
let d = ss.filter(function(v) {
|
|
107
115
|
return v.name === 'kettle'
|
|
@@ -117,14 +125,14 @@ async function test() {
|
|
|
117
125
|
}
|
|
118
126
|
test()
|
|
119
127
|
// change delAll
|
|
120
|
-
// delAll then { n:
|
|
128
|
+
// delAll then { n: 0, nDeleted: 0, ok: 1 }
|
|
121
129
|
// change insert
|
|
122
130
|
// insert then { n: 3, nInserted: 3, ok: 1 }
|
|
123
131
|
// change save
|
|
124
132
|
// save then [
|
|
125
|
-
// { n: 1, nModified: 1, ok: 1 },
|
|
126
|
-
// { n: 1, nModified: 1, ok: 1 },
|
|
127
|
-
// { n: 0, nModified: 0, ok: 1 }
|
|
133
|
+
// { n: 1, nInserted: 0, nModified: 1, ok: 1 },
|
|
134
|
+
// { n: 1, nInserted: 0, nModified: 1, ok: 1 },
|
|
135
|
+
// { n: 0, nInserted: 0, nModified: 0, ok: 1 }
|
|
128
136
|
// ]
|
|
129
137
|
// select all [
|
|
130
138
|
// { id: 'id-peter', name: 'peter(modify)', value: 123 },
|
|
@@ -157,6 +165,8 @@ test()
|
|
|
157
165
|
// }
|
|
158
166
|
// ]
|
|
159
167
|
// selectReg [ { id: 'id-peter', name: 'peter(modify)', value: 123 } ]
|
|
168
|
+
// selectByPk { id: 'id-rosemary', name: 'rosemary(modify)', value: 123.456 }
|
|
169
|
+
// selectByPk by id not existed null
|
|
160
170
|
// change del
|
|
161
171
|
// del then [ { n: 1, nDeleted: 1, ok: 1 } ]
|
|
162
172
|
|
package/g-gfs.mjs
CHANGED
|
@@ -1,102 +1,102 @@
|
|
|
1
|
-
import
|
|
2
|
-
import
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
let opt = {
|
|
8
|
-
url: 'mongodb://username:password@127.0.0.1:27017',
|
|
9
|
-
db: 'worm',
|
|
10
|
-
cl: 'usersGfs',
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
let
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
let
|
|
26
|
-
|
|
27
|
-
//
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
//
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
console.log('
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
console.log('
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
console.log('
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
//
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
//
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
// change delAllGfs
|
|
84
|
-
// delAllGfs then { n: 0, ok: 1 }
|
|
85
|
-
// change insertGfs
|
|
86
|
-
// insertGfs { n: 1,
|
|
87
|
-
//
|
|
88
|
-
//
|
|
89
|
-
//
|
|
90
|
-
//
|
|
91
|
-
//
|
|
92
|
-
//
|
|
93
|
-
//
|
|
94
|
-
//
|
|
95
|
-
//
|
|
96
|
-
//
|
|
97
|
-
//
|
|
98
|
-
// ]
|
|
99
|
-
// change
|
|
100
|
-
//
|
|
101
|
-
|
|
102
|
-
//node g-gfs.mjs
|
|
1
|
+
import WOrm from './src/WOrmMongodb.mjs'
|
|
2
|
+
//import WOrm from './dist/w-orm-mongodb.umd.js'
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
//GridFS函數之參數與回傳形狀比照一般操作:
|
|
6
|
+
//數據物件為{ id, u8a }, insertGfs收物件或陣列, delGfs收物件或陣列並回傳等長陣列
|
|
7
|
+
let opt = {
|
|
8
|
+
url: 'mongodb://username:password@127.0.0.1:27017',
|
|
9
|
+
db: 'worm',
|
|
10
|
+
cl: 'usersGfs',
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
//genU8a, 產生內容可複現之測試數據
|
|
14
|
+
function genU8a(n) {
|
|
15
|
+
let u8a = new Uint8Array(n)
|
|
16
|
+
for (let i = 0; i < n; i++) {
|
|
17
|
+
u8a[i] = i % 256
|
|
18
|
+
}
|
|
19
|
+
return u8a
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
async function test() {
|
|
23
|
+
|
|
24
|
+
//wo
|
|
25
|
+
let wo = WOrm(opt)
|
|
26
|
+
|
|
27
|
+
//on
|
|
28
|
+
wo.on('change', function(mode, data, res) {
|
|
29
|
+
console.log('change', mode)
|
|
30
|
+
})
|
|
31
|
+
|
|
32
|
+
//u8a, 亦可為瀏覽器或nodejs取得之任何Uint8Array
|
|
33
|
+
let u8a = genU8a(1000)
|
|
34
|
+
|
|
35
|
+
//delAllGfs
|
|
36
|
+
await wo.delAllGfs()
|
|
37
|
+
.then(function(msg) {
|
|
38
|
+
console.log('delAllGfs then', msg)
|
|
39
|
+
})
|
|
40
|
+
.catch(function(msg) {
|
|
41
|
+
console.log('delAllGfs catch', msg)
|
|
42
|
+
})
|
|
43
|
+
|
|
44
|
+
//insertGfs
|
|
45
|
+
let gi = await wo.insertGfs({ id: 'id-file', u8a })
|
|
46
|
+
console.log('insertGfs', gi)
|
|
47
|
+
|
|
48
|
+
//insertGfs, 已存在id者跳過且不覆寫
|
|
49
|
+
let gr = await wo.insertGfs({ id: 'id-file', u8a: genU8a(50) })
|
|
50
|
+
console.log('insertGfs existed id', gr)
|
|
51
|
+
|
|
52
|
+
//selectByPkGfs
|
|
53
|
+
let gs = await wo.selectByPkGfs('id-file')
|
|
54
|
+
console.log('selectByPkGfs id', gs.id)
|
|
55
|
+
console.log('selectByPkGfs u8a.length', gs.u8a.length)
|
|
56
|
+
console.log('selectByPkGfs u8a[0..3]', gs.u8a[0], gs.u8a[1], gs.u8a[2], gs.u8a[3])
|
|
57
|
+
|
|
58
|
+
//selectByPkGfs by id not existed
|
|
59
|
+
let gn = await wo.selectByPkGfs('id-not-existed')
|
|
60
|
+
console.log('selectByPkGfs by id not existed', gn)
|
|
61
|
+
|
|
62
|
+
//insertGfs, 一次插入多筆
|
|
63
|
+
let gm = await wo.insertGfs([
|
|
64
|
+
{ id: 'id-a', u8a: genU8a(10) },
|
|
65
|
+
{ id: 'id-b', u8a: genU8a(20) },
|
|
66
|
+
])
|
|
67
|
+
console.log('insertGfs multi', gm)
|
|
68
|
+
|
|
69
|
+
//delGfs
|
|
70
|
+
let gd = await wo.delGfs({ id: 'id-file' })
|
|
71
|
+
console.log('delGfs', gd)
|
|
72
|
+
|
|
73
|
+
//delGfs by id not existed
|
|
74
|
+
let gdn = await wo.delGfs({ id: 'id-not-existed' })
|
|
75
|
+
console.log('delGfs by id not existed', gdn)
|
|
76
|
+
|
|
77
|
+
//delAllGfs
|
|
78
|
+
let gda = await wo.delAllGfs()
|
|
79
|
+
console.log('delAllGfs', gda)
|
|
80
|
+
|
|
81
|
+
}
|
|
82
|
+
test()
|
|
83
|
+
// change delAllGfs
|
|
84
|
+
// delAllGfs then { n: 0, nDeleted: 0, ok: 1 }
|
|
85
|
+
// change insertGfs
|
|
86
|
+
// insertGfs { n: 1, nInserted: 1, ok: 1 }
|
|
87
|
+
// change insertGfs
|
|
88
|
+
// insertGfs existed id { n: 1, nInserted: 0, ok: 1 }
|
|
89
|
+
// selectByPkGfs id id-file
|
|
90
|
+
// selectByPkGfs u8a.length 1000
|
|
91
|
+
// selectByPkGfs u8a[0..3] 0 1 2 3
|
|
92
|
+
// selectByPkGfs by id not existed null
|
|
93
|
+
// change insertGfs
|
|
94
|
+
// insertGfs multi { n: 2, nInserted: 2, ok: 1 }
|
|
95
|
+
// change delGfs
|
|
96
|
+
// delGfs [ { n: 1, nDeleted: 1, ok: 1 } ]
|
|
97
|
+
// change delGfs
|
|
98
|
+
// delGfs by id not existed [ { n: 0, nDeleted: 0, ok: 1 } ]
|
|
99
|
+
// change delAllGfs
|
|
100
|
+
// delAllGfs { n: 2, nDeleted: 2, ok: 1 }
|
|
101
|
+
|
|
102
|
+
//node g-gfs.mjs
|
package/g-unique.mjs
ADDED
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import WOrm from './src/WOrmMongodb.mjs'
|
|
2
|
+
//import WOrm from './dist/w-orm-mongodb.umd.js'
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
//本套件會於id欄位建立唯一索引,
|
|
6
|
+
//令insert與save之[檢查id]與[寫入]由MongoDB於單一操作內原子完成,
|
|
7
|
+
//故併發時同一id僅會有一筆數據, 且不須開啟transaction
|
|
8
|
+
//註: 若既有資料表內已存在重複id, 建立索引會失敗, 須先自行清除重複數據
|
|
9
|
+
let opt = {
|
|
10
|
+
url: 'mongodb://username:password@127.0.0.1:27017',
|
|
11
|
+
db: 'worm',
|
|
12
|
+
cl: 'usersUnique',
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
async function test() {
|
|
17
|
+
|
|
18
|
+
//wo
|
|
19
|
+
let wo = WOrm(opt)
|
|
20
|
+
|
|
21
|
+
//delAll
|
|
22
|
+
await wo.delAll()
|
|
23
|
+
|
|
24
|
+
//insert, 同批含重複id時僅首筆成功
|
|
25
|
+
let ri = await wo.insert([
|
|
26
|
+
{ id: 'id-dup', name: 'dup-1' },
|
|
27
|
+
{ id: 'id-dup', name: 'dup-2' },
|
|
28
|
+
{ id: 'id-uniq', name: 'uniq' },
|
|
29
|
+
])
|
|
30
|
+
console.log('insert with duplicated id', ri)
|
|
31
|
+
console.log('selectByPk(id-dup)', await wo.selectByPk('id-dup'))
|
|
32
|
+
|
|
33
|
+
//insert, 對已存在id再插入則跳過而不覆寫
|
|
34
|
+
let re = await wo.insert({ id: 'id-dup', name: 'dup-3' })
|
|
35
|
+
console.log('insert existed id', re)
|
|
36
|
+
console.log('selectByPk(id-dup)', await wo.selectByPk('id-dup'))
|
|
37
|
+
|
|
38
|
+
//insert, 併發對同一id插入10次, nInserted總和為1
|
|
39
|
+
let rc = await Promise.all(Array.from({ length: 10 }, (v, k) => {
|
|
40
|
+
return wo.insert({ id: 'id-race', k })
|
|
41
|
+
}))
|
|
42
|
+
console.log('sum of nInserted by 10 concurrent insert', rc.reduce((sum, v) => sum + v.nInserted, 0))
|
|
43
|
+
console.log('records of id-race', (await wo.select({ id: 'id-race' })).length)
|
|
44
|
+
|
|
45
|
+
//save, 併發對同一全新id儲存不同欄位, 僅一次為插入, 各欄位皆保留
|
|
46
|
+
let rs = await Promise.all(Array.from({ length: 5 }, (v, k) => {
|
|
47
|
+
return wo.save({ id: 'id-new', [`f${k}`]: k })
|
|
48
|
+
}))
|
|
49
|
+
console.log('count of nInserted===1 by 5 concurrent save', rs.filter((v) => v[0].nInserted === 1).length)
|
|
50
|
+
console.log('records of id-new', (await wo.select({ id: 'id-new' })).length)
|
|
51
|
+
console.log('selectByPk(id-new)', await wo.selectByPk('id-new'))
|
|
52
|
+
|
|
53
|
+
}
|
|
54
|
+
test()
|
|
55
|
+
// insert with duplicated id { n: 3, nInserted: 2, ok: 1 }
|
|
56
|
+
// selectByPk(id-dup) { id: 'id-dup', name: 'dup-1' }
|
|
57
|
+
// insert existed id { n: 1, nInserted: 0, ok: 1 }
|
|
58
|
+
// selectByPk(id-dup) { id: 'id-dup', name: 'dup-1' }
|
|
59
|
+
// sum of nInserted by 10 concurrent insert 1
|
|
60
|
+
// records of id-race 1
|
|
61
|
+
// count of nInserted===1 by 5 concurrent save 1
|
|
62
|
+
// records of id-new 1
|
|
63
|
+
// selectByPk(id-new) { id: 'id-new', f0: 0, f1: 1, f2: 2, f4: 4, f3: 3 }
|
|
64
|
+
// 註: 併發儲存之各欄位皆會保留, 惟欄位順序取決於各次儲存之完成順序, 故每次執行不盡相同
|
|
65
|
+
|
|
66
|
+
//node g-unique.mjs
|
package/package.json
CHANGED
package/script.txt
CHANGED