@naturalcycles/db-lib 8.60.1 → 9.1.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 +3 -4
- package/dist/adapter/cachedb/cache.db.js +5 -4
- package/dist/adapter/cachedb/cache.db.model.d.ts +2 -2
- package/dist/adapter/file/file.db.d.ts +4 -7
- package/dist/adapter/file/file.db.js +102 -56
- package/dist/adapter/inmemory/inMemory.db.d.ts +32 -3
- package/dist/adapter/inmemory/inMemory.db.js +76 -25
- package/dist/base.common.db.d.ts +7 -10
- package/dist/base.common.db.js +13 -7
- package/dist/common.db.d.ts +60 -4
- package/dist/common.db.js +23 -0
- package/dist/commondao/common.dao.d.ts +28 -9
- package/dist/commondao/common.dao.js +72 -71
- package/dist/commondao/common.dao.model.d.ts +0 -10
- package/dist/db.model.d.ts +29 -1
- package/dist/index.d.ts +0 -1
- package/dist/index.js +0 -1
- package/dist/testing/daoTest.d.ts +2 -2
- package/dist/testing/daoTest.js +29 -39
- package/dist/testing/dbTest.d.ts +1 -39
- package/dist/testing/dbTest.js +41 -50
- package/dist/testing/index.d.ts +2 -2
- package/dist/timeseries/commonTimeSeriesDao.js +9 -10
- package/dist/transaction/dbTransaction.util.d.ts +14 -4
- package/dist/transaction/dbTransaction.util.js +49 -22
- package/dist/validation/index.js +2 -2
- package/package.json +1 -1
- package/src/adapter/cachedb/cache.db.model.ts +7 -2
- package/src/adapter/cachedb/cache.db.ts +7 -8
- package/src/adapter/file/file.db.ts +120 -74
- package/src/adapter/inmemory/inMemory.db.ts +101 -24
- package/src/base.common.db.ts +22 -11
- package/src/common.db.ts +84 -3
- package/src/commondao/common.dao.model.ts +0 -11
- package/src/commondao/common.dao.ts +102 -91
- package/src/db.model.ts +34 -2
- package/src/index.ts +0 -1
- package/src/testing/daoTest.ts +32 -52
- package/src/testing/dbTest.ts +43 -120
- package/src/testing/index.ts +2 -12
- package/src/timeseries/commonTimeSeriesDao.ts +9 -12
- package/src/transaction/dbTransaction.util.ts +61 -23
- package/src/validation/index.ts +2 -2
- package/dist/transaction/dbTransaction.d.ts +0 -27
- package/dist/transaction/dbTransaction.js +0 -64
- package/src/transaction/dbTransaction.ts +0 -67
|
@@ -13,12 +13,12 @@ import {
|
|
|
13
13
|
AnyObject,
|
|
14
14
|
AppError,
|
|
15
15
|
AsyncMapper,
|
|
16
|
+
CommonLogger,
|
|
16
17
|
ErrorMode,
|
|
17
18
|
JsonSchemaObject,
|
|
18
19
|
JsonSchemaRootObject,
|
|
19
20
|
ObjectWithId,
|
|
20
21
|
pMap,
|
|
21
|
-
Promisable,
|
|
22
22
|
Saved,
|
|
23
23
|
SKIP,
|
|
24
24
|
UnixTimestampMillisNumber,
|
|
@@ -43,16 +43,8 @@ import {
|
|
|
43
43
|
writableVoid,
|
|
44
44
|
} from '@naturalcycles/nodejs-lib'
|
|
45
45
|
import { DBLibError } from '../cnst'
|
|
46
|
-
import {
|
|
47
|
-
DBDeleteByIdsOperation,
|
|
48
|
-
DBModelType,
|
|
49
|
-
DBOperation,
|
|
50
|
-
DBPatch,
|
|
51
|
-
DBSaveBatchOperation,
|
|
52
|
-
RunQueryResult,
|
|
53
|
-
} from '../db.model'
|
|
46
|
+
import { DBModelType, DBPatch, DBTransaction, RunQueryResult } from '../db.model'
|
|
54
47
|
import { DBQuery, RunnableDBQuery } from '../query/dbQuery'
|
|
55
|
-
import { DBTransaction } from '../transaction/dbTransaction'
|
|
56
48
|
import {
|
|
57
49
|
CommonDaoCfg,
|
|
58
50
|
CommonDaoCreateOptions,
|
|
@@ -210,7 +202,7 @@ export class CommonDao<
|
|
|
210
202
|
const op = `getByIds ${ids.length} id(s) (${_truncate(ids.slice(0, 10).join(', '), 50)})`
|
|
211
203
|
const table = opt.table || this.cfg.table
|
|
212
204
|
const started = this.logStarted(op, table)
|
|
213
|
-
let dbms = await this.cfg.db.getByIds<DBM>(table, ids)
|
|
205
|
+
let dbms = await (opt.tx || this.cfg.db).getByIds<DBM>(table, ids)
|
|
214
206
|
if (!opt.raw && this.cfg.hooks!.afterLoad && dbms.length) {
|
|
215
207
|
dbms = (await pMap(dbms, async dbm => await this.cfg.hooks!.afterLoad!(dbm))).filter(
|
|
216
208
|
_isTruthy,
|
|
@@ -698,68 +690,6 @@ export class CommonDao<
|
|
|
698
690
|
return obj as any
|
|
699
691
|
}
|
|
700
692
|
|
|
701
|
-
tx = {
|
|
702
|
-
save: async (
|
|
703
|
-
bm: Unsaved<BM>,
|
|
704
|
-
opt: CommonDaoSaveBatchOptions<DBM> = {},
|
|
705
|
-
): Promise<DBSaveBatchOperation | undefined> => {
|
|
706
|
-
// .save actually returns DBM (not BM) when it detects `opt.tx === true`
|
|
707
|
-
const row: DBM | null = (await this.save(bm, { ...opt, tx: true })) as any
|
|
708
|
-
if (row === null) return
|
|
709
|
-
|
|
710
|
-
return {
|
|
711
|
-
type: 'saveBatch',
|
|
712
|
-
table: this.cfg.table,
|
|
713
|
-
rows: [row],
|
|
714
|
-
opt: {
|
|
715
|
-
excludeFromIndexes: this.cfg.excludeFromIndexes,
|
|
716
|
-
...opt,
|
|
717
|
-
},
|
|
718
|
-
}
|
|
719
|
-
},
|
|
720
|
-
saveBatch: async (
|
|
721
|
-
bms: Unsaved<BM>[],
|
|
722
|
-
opt: CommonDaoSaveBatchOptions<DBM> = {},
|
|
723
|
-
): Promise<DBSaveBatchOperation | undefined> => {
|
|
724
|
-
const rows: DBM[] = (await this.saveBatch(bms, { ...opt, tx: true })) as any
|
|
725
|
-
if (!rows.length) return
|
|
726
|
-
|
|
727
|
-
return {
|
|
728
|
-
type: 'saveBatch',
|
|
729
|
-
table: this.cfg.table,
|
|
730
|
-
rows,
|
|
731
|
-
opt: {
|
|
732
|
-
excludeFromIndexes: this.cfg.excludeFromIndexes,
|
|
733
|
-
...opt,
|
|
734
|
-
},
|
|
735
|
-
}
|
|
736
|
-
},
|
|
737
|
-
deleteByIds: async (
|
|
738
|
-
ids: string[],
|
|
739
|
-
opt: CommonDaoOptions = {},
|
|
740
|
-
): Promise<DBDeleteByIdsOperation | undefined> => {
|
|
741
|
-
if (!ids.length) return
|
|
742
|
-
return {
|
|
743
|
-
type: 'deleteByIds',
|
|
744
|
-
table: this.cfg.table,
|
|
745
|
-
ids,
|
|
746
|
-
opt,
|
|
747
|
-
}
|
|
748
|
-
},
|
|
749
|
-
deleteById: async (
|
|
750
|
-
id: string | null | undefined,
|
|
751
|
-
opt: CommonDaoOptions = {},
|
|
752
|
-
): Promise<DBDeleteByIdsOperation | undefined> => {
|
|
753
|
-
if (!id) return
|
|
754
|
-
return {
|
|
755
|
-
type: 'deleteByIds',
|
|
756
|
-
table: this.cfg.table,
|
|
757
|
-
ids: [id],
|
|
758
|
-
opt,
|
|
759
|
-
}
|
|
760
|
-
},
|
|
761
|
-
}
|
|
762
|
-
|
|
763
693
|
// SAVE
|
|
764
694
|
/**
|
|
765
695
|
* Mutates with id, created, updated
|
|
@@ -778,12 +708,7 @@ export class CommonDao<
|
|
|
778
708
|
|
|
779
709
|
if (this.cfg.hooks!.beforeSave) {
|
|
780
710
|
dbm = (await this.cfg.hooks!.beforeSave(dbm))!
|
|
781
|
-
if (dbm === null
|
|
782
|
-
}
|
|
783
|
-
|
|
784
|
-
if (opt.tx) {
|
|
785
|
-
// May return `null`, in which case it'll be skipped
|
|
786
|
-
return dbm as any
|
|
711
|
+
if (dbm === null) return bm as any
|
|
787
712
|
}
|
|
788
713
|
|
|
789
714
|
const table = opt.table || this.cfg.table
|
|
@@ -960,10 +885,6 @@ export class CommonDao<
|
|
|
960
885
|
)
|
|
961
886
|
}
|
|
962
887
|
|
|
963
|
-
if (opt.tx) {
|
|
964
|
-
return dbms as any
|
|
965
|
-
}
|
|
966
|
-
|
|
967
888
|
if (opt.ensureUniqueId) throw new AppError('ensureUniqueId is not supported in saveBatch')
|
|
968
889
|
if (this.cfg.immutable && !opt.allowMutability && !opt.saveMethod) {
|
|
969
890
|
opt = { ...opt, saveMethod: 'insert' }
|
|
@@ -980,7 +901,7 @@ export class CommonDao<
|
|
|
980
901
|
const { excludeFromIndexes } = this.cfg
|
|
981
902
|
const assignGeneratedIds = opt.assignGeneratedIds || this.cfg.assignGeneratedIds
|
|
982
903
|
|
|
983
|
-
await this.cfg.db.saveBatch(table, dbms, {
|
|
904
|
+
await (opt.tx || this.cfg.db).saveBatch(table, dbms, {
|
|
984
905
|
excludeFromIndexes,
|
|
985
906
|
assignGeneratedIds,
|
|
986
907
|
...opt,
|
|
@@ -1071,7 +992,7 @@ export class CommonDao<
|
|
|
1071
992
|
|
|
1072
993
|
if (beforeSave) {
|
|
1073
994
|
dbm = (await beforeSave(dbm))!
|
|
1074
|
-
if (dbm === null
|
|
995
|
+
if (dbm === null) return SKIP
|
|
1075
996
|
}
|
|
1076
997
|
|
|
1077
998
|
return dbm
|
|
@@ -1118,7 +1039,7 @@ export class CommonDao<
|
|
|
1118
1039
|
const op = `deleteById(${id})`
|
|
1119
1040
|
const table = opt.table || this.cfg.table
|
|
1120
1041
|
const started = this.logStarted(op, table)
|
|
1121
|
-
const count = await this.cfg.db.
|
|
1042
|
+
const count = await this.cfg.db.deleteByIds(table, [id], opt)
|
|
1122
1043
|
this.logSaveResult(started, op, table)
|
|
1123
1044
|
return count
|
|
1124
1045
|
}
|
|
@@ -1130,7 +1051,7 @@ export class CommonDao<
|
|
|
1130
1051
|
const op = `deleteByIds(${ids.join(', ')})`
|
|
1131
1052
|
const table = opt.table || this.cfg.table
|
|
1132
1053
|
const started = this.logStarted(op, table)
|
|
1133
|
-
const count = await this.cfg.db.
|
|
1054
|
+
const count = await (opt.tx || this.cfg.db).deleteByIds(table, ids, opt)
|
|
1134
1055
|
this.logSaveResult(started, op, table)
|
|
1135
1056
|
return count
|
|
1136
1057
|
}
|
|
@@ -1410,11 +1331,17 @@ export class CommonDao<
|
|
|
1410
1331
|
await this.cfg.db.ping()
|
|
1411
1332
|
}
|
|
1412
1333
|
|
|
1413
|
-
async runInTransaction(
|
|
1414
|
-
|
|
1415
|
-
|
|
1334
|
+
async runInTransaction(fn: CommonDaoTransactionFn): Promise<void> {
|
|
1335
|
+
await this.cfg.db.runInTransaction(async tx => {
|
|
1336
|
+
const daoTx = new CommonDaoTransaction(tx, this.cfg.logger!)
|
|
1416
1337
|
|
|
1417
|
-
|
|
1338
|
+
try {
|
|
1339
|
+
await fn(daoTx)
|
|
1340
|
+
} catch (err) {
|
|
1341
|
+
await daoTx.rollback()
|
|
1342
|
+
throw err
|
|
1343
|
+
}
|
|
1344
|
+
})
|
|
1418
1345
|
}
|
|
1419
1346
|
|
|
1420
1347
|
protected logResult(started: number, op: string, res: any, table: string): void {
|
|
@@ -1473,3 +1400,87 @@ export class CommonDao<
|
|
|
1473
1400
|
return Date.now()
|
|
1474
1401
|
}
|
|
1475
1402
|
}
|
|
1403
|
+
|
|
1404
|
+
/**
|
|
1405
|
+
* Transaction is committed when the function returns resolved Promise (aka "returns normally").
|
|
1406
|
+
*
|
|
1407
|
+
* Transaction is rolled back when the function returns rejected Promise (aka "throws").
|
|
1408
|
+
*/
|
|
1409
|
+
export type CommonDaoTransactionFn = (tx: CommonDaoTransaction) => Promise<void>
|
|
1410
|
+
|
|
1411
|
+
/**
|
|
1412
|
+
* Transaction context.
|
|
1413
|
+
* Has similar API than CommonDao, but all operations are performed in the context of the transaction.
|
|
1414
|
+
*/
|
|
1415
|
+
export class CommonDaoTransaction {
|
|
1416
|
+
constructor(
|
|
1417
|
+
private tx: DBTransaction,
|
|
1418
|
+
private logger: CommonLogger,
|
|
1419
|
+
) {}
|
|
1420
|
+
|
|
1421
|
+
/**
|
|
1422
|
+
* Perform a graceful rollback without throwing/re-throwing any error.
|
|
1423
|
+
*/
|
|
1424
|
+
async rollback(): Promise<void> {
|
|
1425
|
+
try {
|
|
1426
|
+
await this.tx.rollback()
|
|
1427
|
+
} catch (err) {
|
|
1428
|
+
// graceful rollback without re-throw
|
|
1429
|
+
this.logger.error(err)
|
|
1430
|
+
}
|
|
1431
|
+
}
|
|
1432
|
+
|
|
1433
|
+
async getById<BM extends Partial<ObjectWithId>, DBM extends ObjectWithId>(
|
|
1434
|
+
dao: CommonDao<BM, DBM, any>,
|
|
1435
|
+
id: string,
|
|
1436
|
+
opt?: CommonDaoOptions,
|
|
1437
|
+
): Promise<Saved<BM> | null> {
|
|
1438
|
+
return (await this.getByIds(dao, [id], opt))[0] || null
|
|
1439
|
+
}
|
|
1440
|
+
|
|
1441
|
+
async getByIds<BM extends Partial<ObjectWithId>, DBM extends ObjectWithId>(
|
|
1442
|
+
dao: CommonDao<BM, DBM, any>,
|
|
1443
|
+
ids: string[],
|
|
1444
|
+
opt?: CommonDaoOptions,
|
|
1445
|
+
): Promise<Saved<BM>[]> {
|
|
1446
|
+
return await dao.getByIds(ids, { ...opt, tx: this.tx })
|
|
1447
|
+
}
|
|
1448
|
+
|
|
1449
|
+
// todo: Queries inside Transaction are not supported yet
|
|
1450
|
+
// async runQuery<BM extends Partial<ObjectWithId>, DBM extends ObjectWithId>(
|
|
1451
|
+
// dao: CommonDao<BM, DBM, any>,
|
|
1452
|
+
// q: DBQuery<DBM>,
|
|
1453
|
+
// opt?: CommonDaoOptions,
|
|
1454
|
+
// ): Promise<Saved<BM>[]> {
|
|
1455
|
+
// try {
|
|
1456
|
+
// return await dao.runQuery(q, { ...opt, tx: this.tx })
|
|
1457
|
+
// } catch (err) {
|
|
1458
|
+
// await this.rollback()
|
|
1459
|
+
// throw err
|
|
1460
|
+
// }
|
|
1461
|
+
// }
|
|
1462
|
+
|
|
1463
|
+
async save<BM extends Partial<ObjectWithId>, DBM extends ObjectWithId>(
|
|
1464
|
+
dao: CommonDao<BM, DBM, any>,
|
|
1465
|
+
bm: Unsaved<BM>,
|
|
1466
|
+
opt?: CommonDaoSaveBatchOptions<DBM>,
|
|
1467
|
+
): Promise<Saved<BM>> {
|
|
1468
|
+
return (await this.saveBatch(dao, [bm], opt))[0]!
|
|
1469
|
+
}
|
|
1470
|
+
|
|
1471
|
+
async saveBatch<BM extends Partial<ObjectWithId>, DBM extends ObjectWithId>(
|
|
1472
|
+
dao: CommonDao<BM, DBM, any>,
|
|
1473
|
+
bms: Unsaved<BM>[],
|
|
1474
|
+
opt?: CommonDaoSaveBatchOptions<DBM>,
|
|
1475
|
+
): Promise<Saved<BM>[]> {
|
|
1476
|
+
return await dao.saveBatch(bms, { ...opt, tx: this.tx })
|
|
1477
|
+
}
|
|
1478
|
+
|
|
1479
|
+
async deleteById(dao: CommonDao<any>, id: string, opt?: CommonDaoOptions): Promise<number> {
|
|
1480
|
+
return await this.deleteByIds(dao, [id], opt)
|
|
1481
|
+
}
|
|
1482
|
+
|
|
1483
|
+
async deleteByIds(dao: CommonDao<any>, ids: string[], opt?: CommonDaoOptions): Promise<number> {
|
|
1484
|
+
return await dao.deleteByIds(ids, { ...opt, tx: this.tx })
|
|
1485
|
+
}
|
|
1486
|
+
}
|
package/src/db.model.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import { ObjectWithId } from '@naturalcycles/js-lib'
|
|
1
|
+
import type { ObjectWithId } from '@naturalcycles/js-lib'
|
|
2
|
+
import { CommonDB } from './common.db'
|
|
2
3
|
|
|
3
4
|
/**
|
|
4
5
|
* Similar to SQL INSERT, UPDATE.
|
|
@@ -10,7 +11,38 @@ import { ObjectWithId } from '@naturalcycles/js-lib'
|
|
|
10
11
|
*/
|
|
11
12
|
export type CommonDBSaveMethod = 'upsert' | 'insert' | 'update'
|
|
12
13
|
|
|
13
|
-
|
|
14
|
+
/**
|
|
15
|
+
* Transaction is committed when the function returns resolved Promise (aka "returns normally").
|
|
16
|
+
*
|
|
17
|
+
* Transaction is rolled back when the function returns rejected Promise (aka "throws").
|
|
18
|
+
*/
|
|
19
|
+
export type DBTransactionFn = (tx: DBTransaction) => Promise<void>
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* Transaction context.
|
|
23
|
+
* Has similar API than CommonDB, but all operations are performed in the context of the transaction.
|
|
24
|
+
*/
|
|
25
|
+
export interface DBTransaction {
|
|
26
|
+
getByIds: CommonDB['getByIds']
|
|
27
|
+
saveBatch: CommonDB['saveBatch']
|
|
28
|
+
deleteByIds: CommonDB['deleteByIds']
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Perform a graceful rollback.
|
|
32
|
+
* It'll rollback the transaction and won't throw/re-throw any errors.
|
|
33
|
+
*/
|
|
34
|
+
rollback: () => Promise<void>
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
export interface CommonDBOptions {
|
|
38
|
+
/**
|
|
39
|
+
* If passed - the operation will be performed in the context of that DBTransaction.
|
|
40
|
+
* Note that not every type of operation supports Transaction
|
|
41
|
+
* (e.g in Datastore queries cannot be executed inside a Transaction).
|
|
42
|
+
* Also, not every CommonDB implementation supports Transactions.
|
|
43
|
+
*/
|
|
44
|
+
tx?: DBTransaction
|
|
45
|
+
}
|
|
14
46
|
|
|
15
47
|
/**
|
|
16
48
|
* All properties default to undefined.
|
package/src/index.ts
CHANGED
|
@@ -13,6 +13,5 @@ export * from './pipeline/dbPipelineBackup'
|
|
|
13
13
|
export * from './pipeline/dbPipelineCopy'
|
|
14
14
|
export * from './pipeline/dbPipelineRestore'
|
|
15
15
|
export * from './query/dbQuery'
|
|
16
|
-
export * from './transaction/dbTransaction'
|
|
17
16
|
export * from './transaction/dbTransaction.util'
|
|
18
17
|
export * from './kv/commonKeyValueDaoMemoCache'
|
package/src/testing/daoTest.ts
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import { Readable } from 'node:stream'
|
|
2
|
-
import {
|
|
2
|
+
import { _deepCopy, _pick, _sortBy, _omit, localTimeNow } from '@naturalcycles/js-lib'
|
|
3
3
|
import { _pipeline, readableToArray, transformNoOp } from '@naturalcycles/nodejs-lib'
|
|
4
4
|
import { CommonDaoLogLevel, DBQuery } from '..'
|
|
5
5
|
import { CommonDB } from '../common.db'
|
|
6
6
|
import { CommonDao } from '../commondao/common.dao'
|
|
7
|
-
import {
|
|
7
|
+
import { CommonDBImplementationQuirks, expectMatch } from './dbTest'
|
|
8
8
|
import {
|
|
9
9
|
createTestItemsBM,
|
|
10
10
|
testItemBMSchema,
|
|
@@ -16,11 +16,8 @@ import {
|
|
|
16
16
|
} from './test.model'
|
|
17
17
|
import { TestItemBM } from '.'
|
|
18
18
|
|
|
19
|
-
export function runCommonDaoTest(
|
|
20
|
-
db
|
|
21
|
-
features: CommonDBImplementationFeatures = {},
|
|
22
|
-
quirks: CommonDBImplementationQuirks = {},
|
|
23
|
-
): void {
|
|
19
|
+
export function runCommonDaoTest(db: CommonDB, quirks: CommonDBImplementationQuirks = {}): void {
|
|
20
|
+
const { support } = db
|
|
24
21
|
const dao = new CommonDao({
|
|
25
22
|
table: TEST_TABLE,
|
|
26
23
|
db,
|
|
@@ -31,26 +28,6 @@ export function runCommonDaoTest(
|
|
|
31
28
|
logLevel: CommonDaoLogLevel.DATA_FULL,
|
|
32
29
|
})
|
|
33
30
|
|
|
34
|
-
const {
|
|
35
|
-
querying = true,
|
|
36
|
-
// tableSchemas = true,
|
|
37
|
-
createTable = true,
|
|
38
|
-
dbQueryFilter = true,
|
|
39
|
-
// dbQueryFilterIn = true,
|
|
40
|
-
dbQueryOrder = true,
|
|
41
|
-
dbQuerySelectFields = true,
|
|
42
|
-
streaming = true,
|
|
43
|
-
strongConsistency = true,
|
|
44
|
-
nullValues = true,
|
|
45
|
-
transactions = true,
|
|
46
|
-
} = features
|
|
47
|
-
|
|
48
|
-
// const {
|
|
49
|
-
// allowExtraPropertiesInResponse,
|
|
50
|
-
// allowBooleansAsUndefined,
|
|
51
|
-
// } = quirks
|
|
52
|
-
const eventualConsistencyDelay = !strongConsistency && quirks.eventualConsistencyDelay
|
|
53
|
-
|
|
54
31
|
const items = createTestItemsBM(3)
|
|
55
32
|
const itemsClone = _deepCopy(items)
|
|
56
33
|
// deepFreeze(items) // mutation of id/created/updated is allowed now! (even expected)
|
|
@@ -66,13 +43,13 @@ export function runCommonDaoTest(
|
|
|
66
43
|
})
|
|
67
44
|
|
|
68
45
|
// CREATE TABLE, DROP
|
|
69
|
-
if (createTable) {
|
|
46
|
+
if (support.createTable) {
|
|
70
47
|
test('createTable, dropIfExists=true', async () => {
|
|
71
48
|
await dao.createTable(testItemDBMJsonSchema, { dropIfExists: true })
|
|
72
49
|
})
|
|
73
50
|
}
|
|
74
51
|
|
|
75
|
-
if (
|
|
52
|
+
if (support.queries) {
|
|
76
53
|
// DELETE ALL initially
|
|
77
54
|
test('deleteByIds test items', async () => {
|
|
78
55
|
const rows = await dao.query().select(['id']).runQuery()
|
|
@@ -87,7 +64,6 @@ export function runCommonDaoTest(
|
|
|
87
64
|
|
|
88
65
|
// QUERY empty
|
|
89
66
|
test('runQuery(all), runQueryCount should return empty', async () => {
|
|
90
|
-
if (eventualConsistencyDelay) await pDelay(eventualConsistencyDelay)
|
|
91
67
|
expect(await dao.query().runQuery()).toEqual([])
|
|
92
68
|
expect(await dao.query().runQueryCount()).toBe(0)
|
|
93
69
|
})
|
|
@@ -109,7 +85,7 @@ export function runCommonDaoTest(
|
|
|
109
85
|
})
|
|
110
86
|
|
|
111
87
|
// SAVE
|
|
112
|
-
if (nullValues) {
|
|
88
|
+
if (support.nullValues) {
|
|
113
89
|
test('should allow to save and load null values', async () => {
|
|
114
90
|
const item3 = {
|
|
115
91
|
...createTestItemBM(3),
|
|
@@ -168,15 +144,14 @@ export function runCommonDaoTest(
|
|
|
168
144
|
})
|
|
169
145
|
|
|
170
146
|
// QUERY
|
|
171
|
-
if (
|
|
147
|
+
if (support.queries) {
|
|
172
148
|
test('runQuery(all) should return all items', async () => {
|
|
173
|
-
if (eventualConsistencyDelay) await pDelay(eventualConsistencyDelay)
|
|
174
149
|
let rows = await dao.query().runQuery()
|
|
175
150
|
rows = _sortBy(rows, r => r.id)
|
|
176
151
|
expectMatch(expectedItems, rows, quirks)
|
|
177
152
|
})
|
|
178
153
|
|
|
179
|
-
if (dbQueryFilter) {
|
|
154
|
+
if (support.dbQueryFilter) {
|
|
180
155
|
test('query even=true', async () => {
|
|
181
156
|
let rows = await dao.query().filter('even', '==', true).runQuery()
|
|
182
157
|
rows = _sortBy(rows, r => r.id)
|
|
@@ -188,14 +163,14 @@ export function runCommonDaoTest(
|
|
|
188
163
|
})
|
|
189
164
|
}
|
|
190
165
|
|
|
191
|
-
if (dbQueryOrder) {
|
|
166
|
+
if (support.dbQueryOrder) {
|
|
192
167
|
test('query order by k1 desc', async () => {
|
|
193
168
|
const rows = await dao.query().order('k1', true).runQuery()
|
|
194
169
|
expectMatch([...expectedItems].reverse(), rows, quirks)
|
|
195
170
|
})
|
|
196
171
|
}
|
|
197
172
|
|
|
198
|
-
if (dbQuerySelectFields) {
|
|
173
|
+
if (support.dbQuerySelectFields) {
|
|
199
174
|
test('projection query with only ids', async () => {
|
|
200
175
|
let rows = await dao.query().select(['id']).runQuery()
|
|
201
176
|
rows = _sortBy(rows, r => r.id)
|
|
@@ -213,7 +188,7 @@ export function runCommonDaoTest(
|
|
|
213
188
|
}
|
|
214
189
|
|
|
215
190
|
// STREAM
|
|
216
|
-
if (streaming) {
|
|
191
|
+
if (support.streaming) {
|
|
217
192
|
test('streamQueryForEach all', async () => {
|
|
218
193
|
let rows: TestItemBM[] = []
|
|
219
194
|
await dao.query().streamQueryForEach(bm => void rows.push(bm))
|
|
@@ -269,11 +244,10 @@ export function runCommonDaoTest(
|
|
|
269
244
|
}
|
|
270
245
|
|
|
271
246
|
// DELETE BY
|
|
272
|
-
if (
|
|
247
|
+
if (support.queries) {
|
|
273
248
|
test('deleteByQuery even=false', async () => {
|
|
274
249
|
const deleted = await dao.query().filter('even', '==', false).deleteByQuery()
|
|
275
250
|
expect(deleted).toBe(items.filter(item => !item.even).length)
|
|
276
|
-
if (eventualConsistencyDelay) await pDelay(eventualConsistencyDelay)
|
|
277
251
|
expect(await dao.query().runQueryCount()).toBe(1)
|
|
278
252
|
})
|
|
279
253
|
|
|
@@ -283,14 +257,18 @@ export function runCommonDaoTest(
|
|
|
283
257
|
})
|
|
284
258
|
}
|
|
285
259
|
|
|
286
|
-
if (transactions) {
|
|
260
|
+
if (support.transactions) {
|
|
287
261
|
test('transaction happy path', async () => {
|
|
288
262
|
// cleanup
|
|
289
263
|
await dao.query().deleteByQuery()
|
|
290
264
|
|
|
291
265
|
// Test that id, created, updated are created
|
|
292
266
|
const now = localTimeNow().unix()
|
|
293
|
-
|
|
267
|
+
|
|
268
|
+
await dao.runInTransaction(async tx => {
|
|
269
|
+
const row = _omit(item1, ['id', 'created', 'updated'])
|
|
270
|
+
await tx.save(dao, row)
|
|
271
|
+
})
|
|
294
272
|
|
|
295
273
|
const loaded = await dao.query().runQuery()
|
|
296
274
|
expect(loaded.length).toBe(1)
|
|
@@ -298,17 +276,19 @@ export function runCommonDaoTest(
|
|
|
298
276
|
expect(loaded[0]!.created).toBeGreaterThanOrEqual(now)
|
|
299
277
|
expect(loaded[0]!.updated).toBe(loaded[0]!.created)
|
|
300
278
|
|
|
301
|
-
await dao.runInTransaction(
|
|
279
|
+
await dao.runInTransaction(async tx => {
|
|
280
|
+
await tx.deleteById(dao, loaded[0]!.id)
|
|
281
|
+
})
|
|
302
282
|
|
|
303
283
|
// saveBatch [item1, 2, 3]
|
|
304
284
|
// save item3 with k1: k1_mod
|
|
305
285
|
// delete item2
|
|
306
286
|
// remaining: item1, item3_with_k1_mod
|
|
307
|
-
await dao.runInTransaction(
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
287
|
+
await dao.runInTransaction(async tx => {
|
|
288
|
+
await tx.saveBatch(dao, items)
|
|
289
|
+
await tx.save(dao, { ...items[2]!, k1: 'k1_mod' })
|
|
290
|
+
await tx.deleteById(dao, items[1]!.id)
|
|
291
|
+
})
|
|
312
292
|
|
|
313
293
|
const rows = await dao.query().runQuery()
|
|
314
294
|
const expected = [items[0], { ...items[2]!, k1: 'k1_mod' }]
|
|
@@ -317,10 +297,10 @@ export function runCommonDaoTest(
|
|
|
317
297
|
|
|
318
298
|
test('transaction rollback', async () => {
|
|
319
299
|
await expect(
|
|
320
|
-
dao.runInTransaction(
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
300
|
+
dao.runInTransaction(async tx => {
|
|
301
|
+
await tx.deleteById(dao, items[2]!.id)
|
|
302
|
+
await tx.save(dao, { ...items[0]!, k1: 5 as any }) // it should fail here
|
|
303
|
+
}),
|
|
324
304
|
).rejects.toThrow()
|
|
325
305
|
|
|
326
306
|
const rows = await dao.query().runQuery()
|
|
@@ -328,7 +308,7 @@ export function runCommonDaoTest(
|
|
|
328
308
|
expectMatch(expected, rows, quirks)
|
|
329
309
|
})
|
|
330
310
|
|
|
331
|
-
if (
|
|
311
|
+
if (support.queries) {
|
|
332
312
|
test('transaction cleanup', async () => {
|
|
333
313
|
await dao.query().deleteByQuery()
|
|
334
314
|
})
|