@naturalcycles/db-lib 8.46.1 → 8.48.0
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/adapter/cachedb/cache.db.d.ts +2 -3
- package/dist/adapter/cachedb/cache.db.js +12 -51
- package/dist/adapter/file/file.db.d.ts +0 -2
- package/dist/adapter/file/file.db.js +0 -20
- package/dist/adapter/inmemory/inMemory.db.d.ts +2 -3
- package/dist/adapter/inmemory/inMemory.db.js +32 -25
- package/dist/base.common.db.d.ts +8 -9
- package/dist/base.common.db.js +22 -26
- package/dist/common.db.d.ts +20 -7
- package/dist/commondao/common.dao.d.ts +4 -1
- package/dist/commondao/common.dao.js +32 -13
- package/dist/db.model.d.ts +13 -0
- package/dist/db.model.js +17 -1
- package/dist/query/dbQuery.d.ts +3 -1
- package/dist/query/dbQuery.js +8 -1
- package/dist/testing/daoTest.js +3 -4
- package/dist/testing/dbTest.d.ts +2 -0
- package/dist/testing/dbTest.js +52 -12
- package/dist/transaction/dbTransaction.util.js +5 -1
- package/package.json +1 -1
- package/src/adapter/cachedb/cache.db.ts +21 -82
- package/src/adapter/file/file.db.ts +0 -32
- package/src/adapter/inmemory/inMemory.db.ts +34 -34
- package/src/base.common.db.ts +33 -33
- package/src/common.db.ts +24 -16
- package/src/commondao/common.dao.ts +46 -15
- package/src/db.model.ts +19 -0
- package/src/query/dbQuery.ts +17 -2
- package/src/testing/daoTest.ts +13 -10
- package/src/testing/dbTest.ts +80 -17
- package/src/transaction/dbTransaction.util.ts +5 -1
package/src/common.db.ts
CHANGED
|
@@ -5,6 +5,7 @@ import {
|
|
|
5
5
|
CommonDBOptions,
|
|
6
6
|
CommonDBSaveOptions,
|
|
7
7
|
CommonDBStreamOptions,
|
|
8
|
+
DBPatch,
|
|
8
9
|
RunQueryResult,
|
|
9
10
|
} from './db.model'
|
|
10
11
|
import { DBQuery } from './query/dbQuery'
|
|
@@ -42,17 +43,6 @@ export interface CommonDB {
|
|
|
42
43
|
opt?: CommonDBCreateOptions,
|
|
43
44
|
): Promise<void>
|
|
44
45
|
|
|
45
|
-
// GET
|
|
46
|
-
/**
|
|
47
|
-
* Order of items returned is not guaranteed to match order of ids.
|
|
48
|
-
* (Such limitation exists because Datastore doesn't support it).
|
|
49
|
-
*/
|
|
50
|
-
getByIds<ROW extends ObjectWithId>(
|
|
51
|
-
table: string,
|
|
52
|
-
ids: ROW['id'][],
|
|
53
|
-
opt?: CommonDBOptions,
|
|
54
|
-
): Promise<ROW[]>
|
|
55
|
-
|
|
56
46
|
// QUERY
|
|
57
47
|
/**
|
|
58
48
|
* Order by 'id' is not supported by all implementations (for example, Datastore doesn't support it).
|
|
@@ -84,14 +74,32 @@ export interface CommonDB {
|
|
|
84
74
|
* Returns number of deleted items.
|
|
85
75
|
* Not supported by all implementations (e.g Datastore will always return same number as number of ids).
|
|
86
76
|
*/
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
77
|
+
deleteByQuery<ROW extends ObjectWithId>(q: DBQuery<ROW>, opt?: CommonDBOptions): Promise<number>
|
|
78
|
+
|
|
79
|
+
/**
|
|
80
|
+
* Applies patch to the rows returned by the query.
|
|
81
|
+
*
|
|
82
|
+
* Example:
|
|
83
|
+
*
|
|
84
|
+
* UPDATE table SET A = B where $QUERY_CONDITION
|
|
85
|
+
*
|
|
86
|
+
* patch would be { A: 'B' } for that query.
|
|
87
|
+
*
|
|
88
|
+
* Supports "increment query", example:
|
|
89
|
+
*
|
|
90
|
+
* UPDATE table SET A = A + 1
|
|
91
|
+
*
|
|
92
|
+
* In that case patch would look like:
|
|
93
|
+
* { A: DBIncrement(1) }
|
|
94
|
+
*
|
|
95
|
+
* Returns number of rows affected.
|
|
96
|
+
*/
|
|
97
|
+
updateByQuery<ROW extends ObjectWithId>(
|
|
98
|
+
q: DBQuery<ROW>,
|
|
99
|
+
patch: DBPatch<ROW>,
|
|
90
100
|
opt?: CommonDBOptions,
|
|
91
101
|
): Promise<number>
|
|
92
102
|
|
|
93
|
-
deleteByQuery<ROW extends ObjectWithId>(q: DBQuery<ROW>, opt?: CommonDBOptions): Promise<number>
|
|
94
|
-
|
|
95
103
|
// TRANSACTION
|
|
96
104
|
/**
|
|
97
105
|
* Should be implemented as a Transaction (best effort), which means that
|
|
@@ -40,6 +40,7 @@ import {
|
|
|
40
40
|
DBDeleteByIdsOperation,
|
|
41
41
|
DBModelType,
|
|
42
42
|
DBOperation,
|
|
43
|
+
DBPatch,
|
|
43
44
|
DBSaveBatchOperation,
|
|
44
45
|
RunQueryResult,
|
|
45
46
|
} from '../db.model'
|
|
@@ -133,14 +134,17 @@ export class CommonDao<
|
|
|
133
134
|
|
|
134
135
|
if (opt.timeout) {
|
|
135
136
|
// todo: possibly remove it after debugging is done
|
|
136
|
-
dbm = (
|
|
137
|
-
|
|
137
|
+
dbm = await pTimeout(
|
|
138
|
+
async () => {
|
|
139
|
+
return (await this.cfg.db.runQuery(DBQuery.create<DBM>(table).filterEq('id', id))).rows[0]
|
|
140
|
+
},
|
|
141
|
+
{
|
|
138
142
|
timeout: opt.timeout,
|
|
139
143
|
name: `getById(${table})`,
|
|
140
|
-
}
|
|
141
|
-
)
|
|
144
|
+
},
|
|
145
|
+
)
|
|
142
146
|
} else {
|
|
143
|
-
dbm = (await this.cfg.db.
|
|
147
|
+
dbm = (await this.cfg.db.runQuery(DBQuery.create<DBM>(table).filterEq('id', id))).rows[0]
|
|
144
148
|
}
|
|
145
149
|
|
|
146
150
|
const bm = opt.raw ? (dbm as any) : await this.dbmToBM(dbm, opt)
|
|
@@ -170,7 +174,7 @@ export class CommonDao<
|
|
|
170
174
|
const op = `getByIdAsDBM(${id})`
|
|
171
175
|
const table = opt.table || this.cfg.table
|
|
172
176
|
const started = this.logStarted(op, table)
|
|
173
|
-
let [dbm] = await this.cfg.db.
|
|
177
|
+
let [dbm] = (await this.cfg.db.runQuery(DBQuery.create<DBM>(table).filterEq('id', id))).rows
|
|
174
178
|
if (!opt.raw) {
|
|
175
179
|
dbm = this.anyToDBM(dbm!, opt)
|
|
176
180
|
}
|
|
@@ -185,7 +189,7 @@ export class CommonDao<
|
|
|
185
189
|
const op = `getByIdAsTM(${id})`
|
|
186
190
|
const table = opt.table || this.cfg.table
|
|
187
191
|
const started = this.logStarted(op, table)
|
|
188
|
-
const [dbm] = await this.cfg.db.
|
|
192
|
+
const [dbm] = (await this.cfg.db.runQuery(DBQuery.create<DBM>(table).filterEq('id', id))).rows
|
|
189
193
|
if (opt.raw) {
|
|
190
194
|
this.logResult(started, op, dbm, table)
|
|
191
195
|
return (dbm as any) || null
|
|
@@ -200,7 +204,7 @@ export class CommonDao<
|
|
|
200
204
|
const op = `getByIds ${ids.length} id(s) (${_truncate(ids.slice(0, 10).join(', '), 50)})`
|
|
201
205
|
const table = opt.table || this.cfg.table
|
|
202
206
|
const started = this.logStarted(op, table)
|
|
203
|
-
const dbms = await this.cfg.db.
|
|
207
|
+
const dbms = (await this.cfg.db.runQuery(DBQuery.create<DBM>(table).filterIn('id', ids))).rows
|
|
204
208
|
const bms = opt.raw ? (dbms as any) : await this.dbmsToBM(dbms, opt)
|
|
205
209
|
this.logResult(started, op, bms, table)
|
|
206
210
|
return bms
|
|
@@ -210,7 +214,7 @@ export class CommonDao<
|
|
|
210
214
|
const op = `getByIdsAsDBM ${ids.length} id(s) (${_truncate(ids.slice(0, 10).join(', '), 50)})`
|
|
211
215
|
const table = opt.table || this.cfg.table
|
|
212
216
|
const started = this.logStarted(op, table)
|
|
213
|
-
const dbms = await this.cfg.db.
|
|
217
|
+
const dbms = (await this.cfg.db.runQuery(DBQuery.create<DBM>(table).filterIn('id', ids))).rows
|
|
214
218
|
this.logResult(started, op, dbms, table)
|
|
215
219
|
return dbms
|
|
216
220
|
}
|
|
@@ -266,7 +270,8 @@ export class CommonDao<
|
|
|
266
270
|
|
|
267
271
|
private async ensureUniqueId(table: string, dbm: DBM): Promise<void> {
|
|
268
272
|
// todo: retry N times
|
|
269
|
-
const existing = await this.cfg.db.
|
|
273
|
+
const existing = (await this.cfg.db.runQuery(DBQuery.create<DBM>(table).filterEq('id', dbm.id)))
|
|
274
|
+
.rows
|
|
270
275
|
if (existing.length) {
|
|
271
276
|
throw new AppError(DBLibError.NON_UNIQUE_ID, {
|
|
272
277
|
table,
|
|
@@ -868,9 +873,9 @@ export class CommonDao<
|
|
|
868
873
|
const op = `deleteById(${id})`
|
|
869
874
|
const table = opt.table || this.cfg.table
|
|
870
875
|
const started = this.logStarted(op, table)
|
|
871
|
-
const
|
|
876
|
+
const count = await this.cfg.db.deleteByQuery(DBQuery.create(table).filterEq('id', id))
|
|
872
877
|
this.logSaveResult(started, op, table)
|
|
873
|
-
return
|
|
878
|
+
return count
|
|
874
879
|
}
|
|
875
880
|
|
|
876
881
|
async deleteByIds(ids: ID[], opt: CommonDaoOptions = {}): Promise<number> {
|
|
@@ -879,9 +884,9 @@ export class CommonDao<
|
|
|
879
884
|
const op = `deleteByIds(${ids.join(', ')})`
|
|
880
885
|
const table = opt.table || this.cfg.table
|
|
881
886
|
const started = this.logStarted(op, table)
|
|
882
|
-
const
|
|
887
|
+
const count = await this.cfg.db.deleteByQuery(DBQuery.create(table).filterIn('id', ids))
|
|
883
888
|
this.logSaveResult(started, op, table)
|
|
884
|
-
return
|
|
889
|
+
return count
|
|
885
890
|
}
|
|
886
891
|
|
|
887
892
|
/**
|
|
@@ -911,7 +916,10 @@ export class CommonDao<
|
|
|
911
916
|
transformBuffer<string>({ batchSize }),
|
|
912
917
|
transformMap<string[], void>(
|
|
913
918
|
async ids => {
|
|
914
|
-
deleted += await this.cfg.db.
|
|
919
|
+
deleted += await this.cfg.db.deleteByQuery(
|
|
920
|
+
DBQuery.create(q.table).filterIn('id', ids),
|
|
921
|
+
opt,
|
|
922
|
+
)
|
|
915
923
|
},
|
|
916
924
|
{
|
|
917
925
|
predicate: _passthroughPredicate,
|
|
@@ -934,6 +942,29 @@ export class CommonDao<
|
|
|
934
942
|
return deleted
|
|
935
943
|
}
|
|
936
944
|
|
|
945
|
+
async updateById(id: ID, patch: DBPatch<DBM>, opt: CommonDaoOptions = {}): Promise<number> {
|
|
946
|
+
return await this.updateByQuery(this.query().filterEq('id', id), patch, opt)
|
|
947
|
+
}
|
|
948
|
+
|
|
949
|
+
async updateByIds(ids: ID[], patch: DBPatch<DBM>, opt: CommonDaoOptions = {}): Promise<number> {
|
|
950
|
+
return await this.updateByQuery(this.query().filterIn('id', ids), patch, opt)
|
|
951
|
+
}
|
|
952
|
+
|
|
953
|
+
async updateByQuery(
|
|
954
|
+
q: DBQuery<DBM>,
|
|
955
|
+
patch: DBPatch<DBM>,
|
|
956
|
+
opt: CommonDaoOptions = {},
|
|
957
|
+
): Promise<number> {
|
|
958
|
+
this.requireWriteAccess()
|
|
959
|
+
this.requireObjectMutability(opt)
|
|
960
|
+
q.table = opt.table || q.table
|
|
961
|
+
const op = `updateByQuery(${q.pretty()})`
|
|
962
|
+
const started = this.logStarted(op, q.table)
|
|
963
|
+
const updated = await this.cfg.db.updateByQuery(q, patch, opt)
|
|
964
|
+
this.logSaveResult(started, op, q.table)
|
|
965
|
+
return updated
|
|
966
|
+
}
|
|
967
|
+
|
|
937
968
|
// CONVERSIONS
|
|
938
969
|
|
|
939
970
|
async dbmToBM(_dbm: undefined, opt?: CommonDaoOptions): Promise<undefined>
|
package/src/db.model.ts
CHANGED
|
@@ -76,3 +76,22 @@ export enum DBModelType {
|
|
|
76
76
|
BM = 'BM',
|
|
77
77
|
TM = 'TM',
|
|
78
78
|
}
|
|
79
|
+
|
|
80
|
+
/**
|
|
81
|
+
* Allows to construct a query similar to:
|
|
82
|
+
*
|
|
83
|
+
* UPDATE table SET A = A + 1
|
|
84
|
+
*
|
|
85
|
+
* In this case DBIncement.of(1) will be needed.
|
|
86
|
+
*/
|
|
87
|
+
export class DBIncrement {
|
|
88
|
+
private constructor(public amount: number) {}
|
|
89
|
+
|
|
90
|
+
static of(amount: number): DBIncrement {
|
|
91
|
+
return new DBIncrement(amount)
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
export type DBPatch<ROW extends Partial<ObjectWithId>> = Partial<
|
|
96
|
+
Record<keyof ROW, ROW[keyof ROW] | DBIncrement>
|
|
97
|
+
>
|
package/src/query/dbQuery.ts
CHANGED
|
@@ -5,9 +5,15 @@ import {
|
|
|
5
5
|
_truncate,
|
|
6
6
|
Saved,
|
|
7
7
|
AnyObject,
|
|
8
|
+
_objectAssign,
|
|
8
9
|
} from '@naturalcycles/js-lib'
|
|
9
10
|
import { ReadableTyped } from '@naturalcycles/nodejs-lib'
|
|
10
|
-
import {
|
|
11
|
+
import {
|
|
12
|
+
CommonDaoOptions,
|
|
13
|
+
CommonDaoStreamForEachOptions,
|
|
14
|
+
CommonDaoStreamOptions,
|
|
15
|
+
DBPatch,
|
|
16
|
+
} from '..'
|
|
11
17
|
import { CommonDao } from '../commondao/common.dao'
|
|
12
18
|
import { RunQueryResult } from '../db.model'
|
|
13
19
|
|
|
@@ -118,6 +124,11 @@ export class DBQuery<ROW extends ObjectWithId = AnyObjectWithId> {
|
|
|
118
124
|
return this
|
|
119
125
|
}
|
|
120
126
|
|
|
127
|
+
filterIn(name: keyof ROW, val: any[]): this {
|
|
128
|
+
this._filters.push({ name, op: 'in', val })
|
|
129
|
+
return this
|
|
130
|
+
}
|
|
131
|
+
|
|
121
132
|
limit(limit: number): this {
|
|
122
133
|
this._limitValue = limit
|
|
123
134
|
return this
|
|
@@ -162,7 +173,7 @@ export class DBQuery<ROW extends ObjectWithId = AnyObjectWithId> {
|
|
|
162
173
|
}
|
|
163
174
|
|
|
164
175
|
clone(): DBQuery<ROW> {
|
|
165
|
-
return
|
|
176
|
+
return _objectAssign(new DBQuery<ROW>(this.table), {
|
|
166
177
|
_filters: [...this._filters],
|
|
167
178
|
_limitValue: this._limitValue,
|
|
168
179
|
_offsetValue: this._offsetValue,
|
|
@@ -269,6 +280,10 @@ export class RunnableDBQuery<
|
|
|
269
280
|
return await this.dao.runQueryCount(this, opt)
|
|
270
281
|
}
|
|
271
282
|
|
|
283
|
+
async updateByQuery(patch: DBPatch<DBM>, opt?: CommonDaoOptions): Promise<number> {
|
|
284
|
+
return await this.dao.updateByQuery(this, patch, opt)
|
|
285
|
+
}
|
|
286
|
+
|
|
272
287
|
async streamQueryForEach(
|
|
273
288
|
mapper: AsyncMapper<Saved<BM>, void>,
|
|
274
289
|
opt?: CommonDaoStreamForEachOptions<Saved<BM>>,
|
package/src/testing/daoTest.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { pDelay, _deepCopy, _pick, _sortBy, _omit, localTime } from '@naturalcycles/js-lib'
|
|
2
2
|
import { readableToArray, transformNoOp } from '@naturalcycles/nodejs-lib'
|
|
3
|
-
import { CommonDaoLogLevel } from '..'
|
|
3
|
+
import { CommonDaoLogLevel, DBQuery } from '..'
|
|
4
4
|
import { CommonDB } from '../common.db'
|
|
5
5
|
import { CommonDao } from '../commondao/common.dao'
|
|
6
6
|
import { CommonDBImplementationFeatures, CommonDBImplementationQuirks, expectMatch } from './dbTest'
|
|
@@ -75,9 +75,12 @@ export function runCommonDaoTest(
|
|
|
75
75
|
// DELETE ALL initially
|
|
76
76
|
test('deleteByIds test items', async () => {
|
|
77
77
|
const rows = await dao.query().select(['id']).runQuery()
|
|
78
|
-
await db.
|
|
79
|
-
TEST_TABLE
|
|
80
|
-
|
|
78
|
+
await db.deleteByQuery(
|
|
79
|
+
DBQuery.create(TEST_TABLE).filter(
|
|
80
|
+
'id',
|
|
81
|
+
'in',
|
|
82
|
+
rows.map(r => r.id),
|
|
83
|
+
),
|
|
81
84
|
)
|
|
82
85
|
})
|
|
83
86
|
|
|
@@ -156,7 +159,11 @@ export function runCommonDaoTest(
|
|
|
156
159
|
// GET not empty
|
|
157
160
|
test('getByIds all items', async () => {
|
|
158
161
|
const rows = await dao.getByIds(items.map(i => i.id).concat('abcd'))
|
|
159
|
-
expectMatch(
|
|
162
|
+
expectMatch(
|
|
163
|
+
expectedItems,
|
|
164
|
+
_sortBy(rows, r => r.id),
|
|
165
|
+
quirks,
|
|
166
|
+
)
|
|
160
167
|
})
|
|
161
168
|
|
|
162
169
|
// QUERY
|
|
@@ -258,11 +265,7 @@ export function runCommonDaoTest(
|
|
|
258
265
|
|
|
259
266
|
test('cleanup', async () => {
|
|
260
267
|
// CLEAN UP
|
|
261
|
-
|
|
262
|
-
await db.deleteByIds(
|
|
263
|
-
TEST_TABLE,
|
|
264
|
-
rows.map(i => i.id),
|
|
265
|
-
)
|
|
268
|
+
await dao.query().deleteByQuery()
|
|
266
269
|
})
|
|
267
270
|
}
|
|
268
271
|
|
package/src/testing/dbTest.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { pDelay, pMap, _filterObject, _pick, _sortBy } from '@naturalcycles/js-lib'
|
|
2
2
|
import { readableToArray } from '@naturalcycles/nodejs-lib'
|
|
3
3
|
import { CommonDB } from '../common.db'
|
|
4
|
+
import { DBIncrement, DBPatch } from '../db.model'
|
|
4
5
|
import { DBQuery } from '../query/dbQuery'
|
|
5
6
|
import { DBTransaction } from '../transaction/dbTransaction'
|
|
6
7
|
import {
|
|
@@ -25,6 +26,10 @@ export interface CommonDBImplementationFeatures {
|
|
|
25
26
|
insert?: boolean
|
|
26
27
|
update?: boolean
|
|
27
28
|
|
|
29
|
+
updateByQuery?: boolean
|
|
30
|
+
|
|
31
|
+
dbIncrement?: boolean
|
|
32
|
+
|
|
28
33
|
createTable?: boolean
|
|
29
34
|
tableSchemas?: boolean
|
|
30
35
|
|
|
@@ -87,6 +92,8 @@ export function runCommonDBTest(
|
|
|
87
92
|
dbQuerySelectFields = true,
|
|
88
93
|
insert = true,
|
|
89
94
|
update = true,
|
|
95
|
+
updateByQuery = true,
|
|
96
|
+
dbIncrement = true,
|
|
90
97
|
streaming = true,
|
|
91
98
|
strongConsistency = true,
|
|
92
99
|
bufferSupport = true,
|
|
@@ -122,9 +129,12 @@ export function runCommonDBTest(
|
|
|
122
129
|
// DELETE ALL initially
|
|
123
130
|
test('deleteByIds test items', async () => {
|
|
124
131
|
const { rows } = await db.runQuery(queryAll().select(['id']))
|
|
125
|
-
await db.
|
|
126
|
-
|
|
127
|
-
|
|
132
|
+
await db.runQuery(
|
|
133
|
+
queryAll().filter(
|
|
134
|
+
'id',
|
|
135
|
+
'in',
|
|
136
|
+
rows.map(i => i.id),
|
|
137
|
+
),
|
|
128
138
|
)
|
|
129
139
|
})
|
|
130
140
|
|
|
@@ -138,17 +148,17 @@ export function runCommonDBTest(
|
|
|
138
148
|
|
|
139
149
|
// GET empty
|
|
140
150
|
test('getByIds(item1.id) should return empty', async () => {
|
|
141
|
-
const [item1Loaded] = await db.
|
|
151
|
+
const [item1Loaded] = (await db.runQuery(queryAll().filterEq('id', item1.id))).rows
|
|
142
152
|
// console.log(a)
|
|
143
153
|
expect(item1Loaded).toBeUndefined()
|
|
144
154
|
})
|
|
145
155
|
|
|
146
156
|
test('getByIds([]) should return []', async () => {
|
|
147
|
-
expect(await db.
|
|
157
|
+
expect((await db.runQuery(queryAll().filter('id', 'in', []))).rows).toEqual([])
|
|
148
158
|
})
|
|
149
159
|
|
|
150
160
|
test('getByIds(...) should return empty', async () => {
|
|
151
|
-
expect(await db.
|
|
161
|
+
expect((await db.runQuery(queryAll().filter('id', 'in', ['abc', 'abcd']))).rows).toEqual([])
|
|
152
162
|
})
|
|
153
163
|
|
|
154
164
|
// SAVE
|
|
@@ -160,7 +170,7 @@ export function runCommonDBTest(
|
|
|
160
170
|
}
|
|
161
171
|
deepFreeze(item3)
|
|
162
172
|
await db.saveBatch(TEST_TABLE, [item3])
|
|
163
|
-
const item3Loaded = (await db.
|
|
173
|
+
const item3Loaded = (await db.runQuery(queryAll().filterEq('id', item3.id))).rows[0]!
|
|
164
174
|
expectMatch([item3], [item3Loaded], quirks)
|
|
165
175
|
expect(item3Loaded.k2).toBeNull()
|
|
166
176
|
})
|
|
@@ -177,7 +187,7 @@ export function runCommonDBTest(
|
|
|
177
187
|
delete expected.k2
|
|
178
188
|
|
|
179
189
|
await db.saveBatch(TEST_TABLE, [item3])
|
|
180
|
-
const item3Loaded = (await db.
|
|
190
|
+
const item3Loaded = (await db.runQuery(queryAll().filterEq('id', item3.id))).rows[0]!
|
|
181
191
|
expectMatch([expected], [item3Loaded], quirks)
|
|
182
192
|
expect(item3Loaded.k2).toBeUndefined()
|
|
183
193
|
expect(Object.keys(item3Loaded)).not.toContain('k2')
|
|
@@ -212,8 +222,14 @@ export function runCommonDBTest(
|
|
|
212
222
|
|
|
213
223
|
// GET not empty
|
|
214
224
|
test('getByIds all items', async () => {
|
|
215
|
-
const rows =
|
|
216
|
-
|
|
225
|
+
const rows = (
|
|
226
|
+
await db.runQuery(queryAll().filter('id', 'in', items.map(i => i.id).concat('abcd')))
|
|
227
|
+
).rows
|
|
228
|
+
expectMatch(
|
|
229
|
+
items,
|
|
230
|
+
_sortBy(rows, r => r.id),
|
|
231
|
+
quirks,
|
|
232
|
+
)
|
|
217
233
|
})
|
|
218
234
|
|
|
219
235
|
// QUERY
|
|
@@ -333,8 +349,8 @@ export function runCommonDBTest(
|
|
|
333
349
|
b1,
|
|
334
350
|
}
|
|
335
351
|
await db.saveBatch(TEST_TABLE, [item])
|
|
336
|
-
const
|
|
337
|
-
const b1Loaded = loaded
|
|
352
|
+
const loaded = (await db.runQuery(queryAll().filterEq('id', item.id))).rows[0]!
|
|
353
|
+
const b1Loaded = loaded.b1!
|
|
338
354
|
// console.log({
|
|
339
355
|
// b11: typeof b1,
|
|
340
356
|
// b12: typeof b1Loaded,
|
|
@@ -383,14 +399,61 @@ export function runCommonDBTest(
|
|
|
383
399
|
})
|
|
384
400
|
}
|
|
385
401
|
|
|
402
|
+
if (updateByQuery) {
|
|
403
|
+
test('updateByQuery simple', async () => {
|
|
404
|
+
// cleanup, reset initial data
|
|
405
|
+
await db.deleteByQuery(queryAll())
|
|
406
|
+
await db.saveBatch(TEST_TABLE, items)
|
|
407
|
+
|
|
408
|
+
const patch: DBPatch<TestItemDBM> = {
|
|
409
|
+
k3: 5,
|
|
410
|
+
k2: 'abc',
|
|
411
|
+
}
|
|
412
|
+
|
|
413
|
+
await db.updateByQuery(DBQuery.create<TestItemDBM>(TEST_TABLE).filterEq('even', true), patch)
|
|
414
|
+
|
|
415
|
+
const { rows } = await db.runQuery(queryAll())
|
|
416
|
+
const expected = items.map(r => {
|
|
417
|
+
if (r.even) {
|
|
418
|
+
return { ...r, ...patch }
|
|
419
|
+
}
|
|
420
|
+
return r
|
|
421
|
+
})
|
|
422
|
+
expectMatch(expected, rows, quirks)
|
|
423
|
+
})
|
|
424
|
+
|
|
425
|
+
if (dbIncrement) {
|
|
426
|
+
test('updateByQuery DBIncrement', async () => {
|
|
427
|
+
// cleanup, reset initial data
|
|
428
|
+
await db.deleteByQuery(queryAll())
|
|
429
|
+
await db.saveBatch(TEST_TABLE, items)
|
|
430
|
+
|
|
431
|
+
const patch: DBPatch<TestItemDBM> = {
|
|
432
|
+
k3: DBIncrement.of(1),
|
|
433
|
+
k2: 'abcd',
|
|
434
|
+
}
|
|
435
|
+
|
|
436
|
+
await db.updateByQuery(
|
|
437
|
+
DBQuery.create<TestItemDBM>(TEST_TABLE).filterEq('even', true),
|
|
438
|
+
patch,
|
|
439
|
+
)
|
|
440
|
+
|
|
441
|
+
const { rows } = await db.runQuery(queryAll())
|
|
442
|
+
const expected = items.map(r => {
|
|
443
|
+
if (r.even) {
|
|
444
|
+
return { ...r, ...patch, k3: (r.k3 || 0) + 1 }
|
|
445
|
+
}
|
|
446
|
+
return r
|
|
447
|
+
})
|
|
448
|
+
expectMatch(expected, rows, quirks)
|
|
449
|
+
})
|
|
450
|
+
}
|
|
451
|
+
}
|
|
452
|
+
|
|
386
453
|
if (querying) {
|
|
387
454
|
test('cleanup', async () => {
|
|
388
455
|
// CLEAN UP
|
|
389
|
-
|
|
390
|
-
await db.deleteByIds(
|
|
391
|
-
TEST_TABLE,
|
|
392
|
-
rows.map(i => i.id),
|
|
393
|
-
)
|
|
456
|
+
await db.deleteByQuery(queryAll())
|
|
394
457
|
})
|
|
395
458
|
}
|
|
396
459
|
}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { CommonDB } from '../common.db'
|
|
2
2
|
import { CommonDBSaveOptions, DBOperation } from '../db.model'
|
|
3
|
+
import { DBQuery } from '../query/dbQuery'
|
|
3
4
|
import { DBTransaction } from './dbTransaction'
|
|
4
5
|
|
|
5
6
|
/**
|
|
@@ -80,7 +81,10 @@ export async function commitDBTransactionSimple(
|
|
|
80
81
|
if (op.type === 'saveBatch') {
|
|
81
82
|
await db.saveBatch(op.table, op.rows, { ...op.opt, ...opt })
|
|
82
83
|
} else if (op.type === 'deleteByIds') {
|
|
83
|
-
await db.
|
|
84
|
+
await db.deleteByQuery(DBQuery.create(op.table).filter('id', 'in', op.ids), {
|
|
85
|
+
...op.opt,
|
|
86
|
+
...opt,
|
|
87
|
+
})
|
|
84
88
|
} else {
|
|
85
89
|
throw new Error(`DBOperation not supported: ${(op as any).type}`)
|
|
86
90
|
}
|