w-orm-reladb 1.0.42 → 1.0.44

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.
@@ -0,0 +1,212 @@
1
+ import assert from 'assert'
2
+ import wo from '../src/WOrmReladb.mjs'
3
+ import { genRs, genRsm, sortByName } from './api-fixtures.mjs'
4
+
5
+
6
+ //測試前需先啟動本機MSSQL服務(如docker容器: docker start mssql-worm), 並具有資料庫worm與帳號username/password(db_owner)
7
+
8
+
9
+ let genOpt = () => {
10
+ return {
11
+ url: 'mssql://username:password@localhost:1433',
12
+ db: 'worm',
13
+ cl: 'users',
14
+ fdModels: './models',
15
+ }
16
+ }
17
+
18
+
19
+ describe('mssql crud', function() {
20
+
21
+ let w = wo(genOpt())
22
+
23
+ before(async function() {
24
+ await w.createStorage()
25
+ await w.delAll().catch(() => {})
26
+ })
27
+
28
+ it('insert 3筆, 空id自動產生主鍵', async function() {
29
+ let msg = await w.insert(genRs())
30
+ assert.deepStrictEqual(msg, { n: 3, nInserted: 3, ok: 1 })
31
+ })
32
+
33
+ it('save({autoInsert:true}) 修改2筆並插入1筆', async function() {
34
+ let msg = await w.save(genRsm(), { autoInsert: true })
35
+ assert.deepStrictEqual(msg, [
36
+ { n: 1, nModified: 1, ok: 1 },
37
+ { n: 1, nModified: 1, ok: 1 },
38
+ { n: 1, nInserted: 1, ok: 1 },
39
+ ])
40
+ })
41
+
42
+ it('select() 查全部得4筆', async function() {
43
+ let ss = sortByName(await w.select())
44
+ assert.strictEqual(ss.length, 4)
45
+ let [kettle, kettleM, peter, rosemary] = ss
46
+ assert.ok(typeof kettle.id === 'string' && kettle.id.length > 0)
47
+ assert.strictEqual(kettle.name, 'kettle')
48
+ assert.strictEqual(kettle.value, 456)
49
+ assert.ok(typeof kettleM.id === 'string' && kettleM.id.length > 0)
50
+ assert.strictEqual(kettleM.name, 'kettle(modify)')
51
+ assert.strictEqual(kettleM.value, null)
52
+ assert.deepStrictEqual(peter, { id: 'id-peter', name: 'peter(modify)', value: 123 })
53
+ assert.deepStrictEqual(rosemary, { id: 'id-rosemary', name: 'rosemary(modify)', value: 123.456 })
54
+ })
55
+
56
+ it('select({id}) 依主鍵查詢', async function() {
57
+ let so = await w.select({ id: 'id-rosemary' })
58
+ assert.deepStrictEqual(so, [{ id: 'id-rosemary', name: 'rosemary(modify)', value: 123.456 }])
59
+ })
60
+
61
+ it('select $and+$gt+$lt', async function() {
62
+ let sp = await w.select({ '$and': [{ value: { '$gt': 123 } }, { value: { '$lt': 200 } }] })
63
+ assert.deepStrictEqual(sp, [{ id: 'id-rosemary', name: 'rosemary(modify)', value: 123.456 }])
64
+ })
65
+
66
+ it('select $or+$gte+$lte', async function() {
67
+ let sp = await w.select({ '$or': [{ value: { '$lte': -1 } }, { value: { '$gte': 200 } }] })
68
+ assert.strictEqual(sp.length, 1)
69
+ assert.strictEqual(sp[0].name, 'kettle')
70
+ assert.strictEqual(sp[0].value, 456)
71
+ })
72
+
73
+ it('select 巢狀$or+$and+$ne+$in+$nin', async function() {
74
+ let sp = sortByName(await w.select({ '$or': [{ '$and': [{ value: { '$ne': 123 } }, { value: { '$in': [123, 321, 123.456, 456] } }, { value: { '$nin': [456, 654] } }] }, { '$or': [{ value: { '$lte': -1 } }, { value: { '$gte': 400 } }] }] }))
75
+ assert.strictEqual(sp.length, 2)
76
+ assert.strictEqual(sp[0].name, 'kettle')
77
+ assert.strictEqual(sp[0].value, 456)
78
+ assert.deepStrictEqual(sp[1], { id: 'id-rosemary', name: 'rosemary(modify)', value: 123.456 })
79
+ })
80
+
81
+ it('select $regex不分大小寫', async function() {
82
+ let sr = await w.select({ name: { $regex: 'PeT', $options: '$i' } })
83
+ assert.deepStrictEqual(sr, [{ id: 'id-peter', name: 'peter(modify)', value: 123 }])
84
+ })
85
+
86
+ it('del 刪除3筆並保留kettle', async function() {
87
+ let ss = await w.select()
88
+ let d = ss.filter((v) => v.name !== 'kettle')
89
+ let msg = await w.del(d)
90
+ assert.deepStrictEqual(msg, [
91
+ { n: 1, nDeleted: 1, ok: 1 },
92
+ { n: 1, nDeleted: 1, ok: 1 },
93
+ { n: 1, nDeleted: 1, ok: 1 },
94
+ ])
95
+ let left = await w.select()
96
+ assert.strictEqual(left.length, 1)
97
+ assert.strictEqual(left[0].name, 'kettle')
98
+ })
99
+
100
+ it('delAll 清空後select回傳空陣列', async function() {
101
+ let msg = await w.delAll()
102
+ assert.deepStrictEqual(msg, { n: 1, nDeleted: 1, ok: 1 })
103
+ let ss = await w.select()
104
+ assert.deepStrictEqual(ss, [])
105
+ })
106
+
107
+ })
108
+
109
+
110
+ describe('mssql transaction commit', function() {
111
+
112
+ let w = wo(genOpt())
113
+ let instance = null
114
+
115
+ before(async function() {
116
+ await w.createStorage()
117
+ await w.delAll().catch(() => {})
118
+ })
119
+
120
+ after(async function() {
121
+ if (instance) {
122
+ await instance.close().catch(() => {})
123
+ }
124
+ })
125
+
126
+ it('交易內insert+save+del, commit後數據持久化', async function() {
127
+ instance = await w.init()
128
+ let transaction = await w.genTransaction()
129
+ let connState = { instance, transaction }
130
+
131
+ let mi = await w.insert(genRs(), connState)
132
+ assert.deepStrictEqual(mi, { n: 3, nInserted: 3, ok: 1 })
133
+
134
+ let msv = await w.save(genRsm(), { ...connState, autoInsert: false })
135
+ assert.deepStrictEqual(msv, [
136
+ { n: 1, nModified: 1, ok: 1 },
137
+ { n: 1, nModified: 1, ok: 1 },
138
+ { n: 0, nModified: 0, ok: 1 },
139
+ ])
140
+
141
+ let md = await w.del({ id: 'id-rosemary' }, connState)
142
+ assert.deepStrictEqual(md, [{ n: 1, nDeleted: 1, ok: 1 }])
143
+
144
+ //交易內select可查到暫時有效的數據
145
+ let ssIn = sortByName(await w.select(null, connState))
146
+ assert.strictEqual(ssIn.length, 2)
147
+ assert.strictEqual(ssIn[0].name, 'kettle')
148
+ assert.strictEqual(ssIn[1].name, 'peter(modify)')
149
+
150
+ await transaction.commit()
151
+ await instance.close()
152
+ instance = null
153
+
154
+ let ssFinal = sortByName(await w.select())
155
+ assert.strictEqual(ssFinal.length, 2)
156
+ assert.strictEqual(ssFinal[0].name, 'kettle')
157
+ assert.strictEqual(ssFinal[0].value, 456)
158
+ assert.deepStrictEqual(ssFinal[1], { id: 'id-peter', name: 'peter(modify)', value: 123 })
159
+ })
160
+
161
+ })
162
+
163
+
164
+ describe('mssql transaction rollback', function() {
165
+
166
+ let w = wo(genOpt())
167
+ let instance = null
168
+
169
+ before(async function() {
170
+ await w.createStorage()
171
+ await w.delAll().catch(() => {})
172
+ })
173
+
174
+ after(async function() {
175
+ if (instance) {
176
+ await instance.close().catch(() => {})
177
+ }
178
+ })
179
+
180
+ it('交易內insert+save+del, rollback後數據全數還原', async function() {
181
+ instance = await w.init()
182
+ let transaction = await w.genTransaction()
183
+ let connState = { instance, transaction }
184
+
185
+ let mi = await w.insert(genRs(), connState)
186
+ assert.deepStrictEqual(mi, { n: 3, nInserted: 3, ok: 1 })
187
+
188
+ let msv = await w.save(genRsm(), { ...connState, autoInsert: false })
189
+ assert.deepStrictEqual(msv, [
190
+ { n: 1, nModified: 1, ok: 1 },
191
+ { n: 1, nModified: 1, ok: 1 },
192
+ { n: 0, nModified: 0, ok: 1 },
193
+ ])
194
+
195
+ let md = await w.del({ id: 'id-rosemary' }, connState)
196
+ assert.deepStrictEqual(md, [{ n: 1, nDeleted: 1, ok: 1 }])
197
+
198
+ //交易內select可查到暫時有效的數據
199
+ let ssIn = sortByName(await w.select(null, connState))
200
+ assert.strictEqual(ssIn.length, 2)
201
+ assert.strictEqual(ssIn[0].name, 'kettle')
202
+ assert.strictEqual(ssIn[1].name, 'peter(modify)')
203
+
204
+ await transaction.rollback()
205
+ await instance.close()
206
+ instance = null
207
+
208
+ let ssFinal = await w.select()
209
+ assert.deepStrictEqual(ssFinal, [])
210
+ })
211
+
212
+ })
@@ -0,0 +1,236 @@
1
+ import fs from 'fs'
2
+ import assert from 'assert'
3
+ import wo from '../src/WOrmReladb.mjs'
4
+ import { genRs, genRsm, sortByName } from './api-fixtures.mjs'
5
+
6
+
7
+ //sqlite使用獨立暫存storage檔測試, 不使用專案根目錄之worm.sqlite
8
+
9
+
10
+ let genOpt = (storage) => {
11
+ return {
12
+ url: 'sqlite://:',
13
+ db: 'worm',
14
+ cl: 'users',
15
+ fdModels: './models',
16
+ storage,
17
+ }
18
+ }
19
+
20
+ let prepStorage = (storage) => {
21
+ fs.mkdirSync('./tmp', { recursive: true })
22
+ if (fs.existsSync(storage)) {
23
+ fs.unlinkSync(storage)
24
+ }
25
+ }
26
+
27
+ let cleanStorage = (storage) => {
28
+ if (fs.existsSync(storage)) {
29
+ fs.unlinkSync(storage)
30
+ }
31
+ try {
32
+ fs.rmdirSync('./tmp') //僅在空資料夾時移除
33
+ }
34
+ catch (err) {}
35
+ }
36
+
37
+
38
+ describe('sqlite crud', function() {
39
+
40
+ let storage = './tmp/api-sqlite-crud.sqlite'
41
+ let w = wo(genOpt(storage))
42
+
43
+ before(async function() {
44
+ prepStorage(storage)
45
+ await w.createStorage()
46
+ })
47
+
48
+ after(function() {
49
+ cleanStorage(storage)
50
+ })
51
+
52
+ it('insert 3筆, 空id自動產生主鍵', async function() {
53
+ let msg = await w.insert(genRs())
54
+ assert.deepStrictEqual(msg, { n: 3, nInserted: 3, ok: 1 })
55
+ })
56
+
57
+ it('save({autoInsert:false}) 修改2筆且不插入空id項', async function() {
58
+ let msg = await w.save(genRsm(), { autoInsert: false })
59
+ assert.deepStrictEqual(msg, [
60
+ { n: 1, nModified: 1, ok: 1 },
61
+ { n: 1, nModified: 1, ok: 1 },
62
+ { n: 0, nModified: 0, ok: 1 },
63
+ ])
64
+ })
65
+
66
+ it('select() 查全部得3筆', async function() {
67
+ let ss = sortByName(await w.select())
68
+ assert.strictEqual(ss.length, 3)
69
+ let [kettle, peter, rosemary] = ss
70
+ assert.ok(typeof kettle.id === 'string' && kettle.id.length > 0)
71
+ assert.strictEqual(kettle.name, 'kettle')
72
+ assert.strictEqual(kettle.value, 456)
73
+ assert.deepStrictEqual(peter, { id: 'id-peter', name: 'peter(modify)', value: 123 })
74
+ assert.deepStrictEqual(rosemary, { id: 'id-rosemary', name: 'rosemary(modify)', value: 123.456 })
75
+ })
76
+
77
+ it('select({id}) 依主鍵查詢', async function() {
78
+ let so = await w.select({ id: 'id-rosemary' })
79
+ assert.deepStrictEqual(so, [{ id: 'id-rosemary', name: 'rosemary(modify)', value: 123.456 }])
80
+ })
81
+
82
+ it('select $and+$gt+$lt', async function() {
83
+ let sp = await w.select({ '$and': [{ value: { '$gt': 123 } }, { value: { '$lt': 200 } }] })
84
+ assert.deepStrictEqual(sp, [{ id: 'id-rosemary', name: 'rosemary(modify)', value: 123.456 }])
85
+ })
86
+
87
+ it('select $or+$gte+$lte', async function() {
88
+ let sp = await w.select({ '$or': [{ value: { '$lte': -1 } }, { value: { '$gte': 200 } }] })
89
+ assert.strictEqual(sp.length, 1)
90
+ assert.strictEqual(sp[0].name, 'kettle')
91
+ assert.strictEqual(sp[0].value, 456)
92
+ })
93
+
94
+ it('select 巢狀$or+$and+$ne+$in+$nin', async function() {
95
+ let sp = sortByName(await w.select({ '$or': [{ '$and': [{ value: { '$ne': 123 } }, { value: { '$in': [123, 321, 123.456, 456] } }, { value: { '$nin': [456, 654] } }] }, { '$or': [{ value: { '$lte': -1 } }, { value: { '$gte': 400 } }] }] }))
96
+ assert.strictEqual(sp.length, 2)
97
+ assert.strictEqual(sp[0].name, 'kettle')
98
+ assert.strictEqual(sp[0].value, 456)
99
+ assert.deepStrictEqual(sp[1], { id: 'id-rosemary', name: 'rosemary(modify)', value: 123.456 })
100
+ })
101
+
102
+ it('select $regex不分大小寫', async function() {
103
+ let sr = await w.select({ name: { $regex: 'PeT', $options: '$i' } })
104
+ assert.deepStrictEqual(sr, [{ id: 'id-peter', name: 'peter(modify)', value: 123 }])
105
+ })
106
+
107
+ it('del 刪除2筆並保留kettle', async function() {
108
+ let ss = await w.select()
109
+ let d = ss.filter((v) => v.name !== 'kettle')
110
+ let msg = await w.del(d)
111
+ assert.deepStrictEqual(msg, [
112
+ { n: 1, nDeleted: 1, ok: 1 },
113
+ { n: 1, nDeleted: 1, ok: 1 },
114
+ ])
115
+ let left = await w.select()
116
+ assert.strictEqual(left.length, 1)
117
+ assert.strictEqual(left[0].name, 'kettle')
118
+ })
119
+
120
+ it('delAll 清空後select回傳空陣列', async function() {
121
+ let msg = await w.delAll()
122
+ assert.deepStrictEqual(msg, { n: 1, nDeleted: 1, ok: 1 })
123
+ let ss = await w.select()
124
+ assert.deepStrictEqual(ss, [])
125
+ })
126
+
127
+ })
128
+
129
+
130
+ describe('sqlite transaction commit', function() {
131
+
132
+ let storage = './tmp/api-sqlite-commit.sqlite'
133
+ let w = wo(genOpt(storage))
134
+ let instance = null
135
+
136
+ before(async function() {
137
+ prepStorage(storage)
138
+ await w.createStorage()
139
+ })
140
+
141
+ after(async function() {
142
+ if (instance) {
143
+ await instance.close().catch(() => {})
144
+ }
145
+ cleanStorage(storage)
146
+ })
147
+
148
+ it('交易內insert+save+del, commit後數據持久化', async function() {
149
+ instance = await w.init()
150
+ let transaction = await w.genTransaction()
151
+ let connState = { instance, transaction }
152
+
153
+ let mi = await w.insert(genRs(), connState)
154
+ assert.deepStrictEqual(mi, { n: 3, nInserted: 3, ok: 1 })
155
+
156
+ let msv = await w.save(genRsm(), { ...connState, autoInsert: false })
157
+ assert.deepStrictEqual(msv, [
158
+ { n: 1, nModified: 1, ok: 1 },
159
+ { n: 1, nModified: 1, ok: 1 },
160
+ { n: 0, nModified: 0, ok: 1 },
161
+ ])
162
+
163
+ let md = await w.del({ id: 'id-rosemary' }, connState)
164
+ assert.deepStrictEqual(md, [{ n: 1, nDeleted: 1, ok: 1 }])
165
+
166
+ //交易內select可查到暫時有效的數據
167
+ let ssIn = sortByName(await w.select(null, connState))
168
+ assert.strictEqual(ssIn.length, 2)
169
+ assert.strictEqual(ssIn[0].name, 'kettle')
170
+ assert.strictEqual(ssIn[1].name, 'peter(modify)')
171
+
172
+ await transaction.commit()
173
+ await instance.close()
174
+ instance = null
175
+
176
+ let ssFinal = sortByName(await w.select())
177
+ assert.strictEqual(ssFinal.length, 2)
178
+ assert.strictEqual(ssFinal[0].name, 'kettle')
179
+ assert.strictEqual(ssFinal[0].value, 456)
180
+ assert.deepStrictEqual(ssFinal[1], { id: 'id-peter', name: 'peter(modify)', value: 123 })
181
+ })
182
+
183
+ })
184
+
185
+
186
+ describe('sqlite transaction rollback', function() {
187
+
188
+ let storage = './tmp/api-sqlite-rollback.sqlite'
189
+ let w = wo(genOpt(storage))
190
+ let instance = null
191
+
192
+ before(async function() {
193
+ prepStorage(storage)
194
+ await w.createStorage()
195
+ })
196
+
197
+ after(async function() {
198
+ if (instance) {
199
+ await instance.close().catch(() => {})
200
+ }
201
+ cleanStorage(storage)
202
+ })
203
+
204
+ it('交易內insert+save+del, rollback後數據全數還原', async function() {
205
+ instance = await w.init()
206
+ let transaction = await w.genTransaction()
207
+ let connState = { instance, transaction }
208
+
209
+ let mi = await w.insert(genRs(), connState)
210
+ assert.deepStrictEqual(mi, { n: 3, nInserted: 3, ok: 1 })
211
+
212
+ let msv = await w.save(genRsm(), { ...connState, autoInsert: false })
213
+ assert.deepStrictEqual(msv, [
214
+ { n: 1, nModified: 1, ok: 1 },
215
+ { n: 1, nModified: 1, ok: 1 },
216
+ { n: 0, nModified: 0, ok: 1 },
217
+ ])
218
+
219
+ let md = await w.del({ id: 'id-rosemary' }, connState)
220
+ assert.deepStrictEqual(md, [{ n: 1, nDeleted: 1, ok: 1 }])
221
+
222
+ //交易內select可查到暫時有效的數據
223
+ let ssIn = sortByName(await w.select(null, connState))
224
+ assert.strictEqual(ssIn.length, 2)
225
+ assert.strictEqual(ssIn[0].name, 'kettle')
226
+ assert.strictEqual(ssIn[1].name, 'peter(modify)')
227
+
228
+ await transaction.rollback()
229
+ await instance.close()
230
+ instance = null
231
+
232
+ let ssFinal = await w.select()
233
+ assert.deepStrictEqual(ssFinal, [])
234
+ })
235
+
236
+ })
package/worm.sqlite CHANGED
Binary file
package/test/all.test.mjs DELETED
@@ -1,10 +0,0 @@
1
- import assert from 'assert'
2
-
3
-
4
- describe('all', function() {
5
-
6
- it('test in localhost', function() {
7
- assert.strict.deepEqual(1, 1)
8
- })
9
-
10
- })