@naturalcycles/db-lib 8.60.0 → 9.0.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.
Files changed (52) hide show
  1. package/dist/adapter/cachedb/cache.db.d.ts +3 -4
  2. package/dist/adapter/cachedb/cache.db.js +5 -4
  3. package/dist/adapter/cachedb/cache.db.model.d.ts +2 -2
  4. package/dist/adapter/file/file.db.d.ts +15 -7
  5. package/dist/adapter/file/file.db.js +93 -57
  6. package/dist/adapter/file/localFile.persistence.plugin.js +3 -3
  7. package/dist/adapter/inmemory/inMemory.db.d.ts +30 -4
  8. package/dist/adapter/inmemory/inMemory.db.js +89 -33
  9. package/dist/base.common.db.d.ts +7 -10
  10. package/dist/base.common.db.js +11 -7
  11. package/dist/common.db.d.ts +56 -4
  12. package/dist/common.db.js +23 -0
  13. package/dist/commondao/common.dao.d.ts +17 -9
  14. package/dist/commondao/common.dao.js +82 -69
  15. package/dist/commondao/common.dao.model.d.ts +0 -10
  16. package/dist/db.model.d.ts +12 -1
  17. package/dist/index.d.ts +0 -1
  18. package/dist/index.js +0 -1
  19. package/dist/pipeline/dbPipelineBackup.js +4 -4
  20. package/dist/pipeline/dbPipelineRestore.js +2 -2
  21. package/dist/testing/daoTest.d.ts +2 -2
  22. package/dist/testing/daoTest.js +29 -39
  23. package/dist/testing/dbTest.d.ts +1 -39
  24. package/dist/testing/dbTest.js +40 -49
  25. package/dist/testing/index.d.ts +2 -2
  26. package/dist/timeseries/commonTimeSeriesDao.js +5 -6
  27. package/dist/transaction/dbTransaction.util.d.ts +17 -4
  28. package/dist/transaction/dbTransaction.util.js +46 -22
  29. package/dist/validation/index.js +2 -2
  30. package/package.json +1 -1
  31. package/src/adapter/cachedb/cache.db.model.ts +7 -2
  32. package/src/adapter/cachedb/cache.db.ts +7 -8
  33. package/src/adapter/file/file.db.ts +121 -69
  34. package/src/adapter/file/localFile.persistence.plugin.ts +4 -5
  35. package/src/adapter/inmemory/inMemory.db.ts +106 -33
  36. package/src/base.common.db.ts +20 -11
  37. package/src/common.db.ts +80 -3
  38. package/src/commondao/common.dao.model.ts +0 -11
  39. package/src/commondao/common.dao.ts +103 -89
  40. package/src/db.model.ts +15 -2
  41. package/src/index.ts +0 -1
  42. package/src/pipeline/dbPipelineBackup.ts +5 -8
  43. package/src/pipeline/dbPipelineRestore.ts +3 -4
  44. package/src/testing/daoTest.ts +32 -52
  45. package/src/testing/dbTest.ts +42 -119
  46. package/src/testing/index.ts +2 -12
  47. package/src/timeseries/commonTimeSeriesDao.ts +5 -6
  48. package/src/transaction/dbTransaction.util.ts +61 -22
  49. package/src/validation/index.ts +2 -2
  50. package/dist/transaction/dbTransaction.d.ts +0 -27
  51. package/dist/transaction/dbTransaction.js +0 -64
  52. package/src/transaction/dbTransaction.ts +0 -67
@@ -1,9 +1,35 @@
1
1
  import { JsonSchemaObject, JsonSchemaRootObject, ObjectWithId } from '@naturalcycles/js-lib';
2
2
  import { ReadableTyped } from '@naturalcycles/nodejs-lib';
3
- import { CommonDBCreateOptions, CommonDBOptions, CommonDBSaveOptions, CommonDBStreamOptions, DBPatch, RunQueryResult } from './db.model';
3
+ import { CommonDBCreateOptions, CommonDBOptions, CommonDBSaveOptions, CommonDBStreamOptions, DBPatch, DBTransaction, RunQueryResult } from './db.model';
4
4
  import { DBQuery } from './query/dbQuery';
5
- import { DBTransaction } from './transaction/dbTransaction';
5
+ export declare enum CommonDBType {
6
+ 'document' = "document",
7
+ 'relational' = "relational"
8
+ }
6
9
  export interface CommonDB {
10
+ /**
11
+ * Relational databases are expected to return `null` for all missing properties.
12
+ */
13
+ dbType: CommonDBType;
14
+ /**
15
+ * Manifest of supported features.
16
+ */
17
+ support: CommonDBSupport;
18
+ supportsQueries?: boolean;
19
+ supportsDBQueryFilter?: boolean;
20
+ supportsDBQueryFilterIn?: boolean;
21
+ supportsDBQueryOrder?: boolean;
22
+ supportsDBQuerySelectFields?: boolean;
23
+ supportsInsertSaveMethod?: boolean;
24
+ supportsUpdateSaveMethod?: boolean;
25
+ supportsUpdateByQuery?: boolean;
26
+ supportsDBIncrement?: boolean;
27
+ supportsCreateTable?: boolean;
28
+ supportsTableSchemas?: boolean;
29
+ supportsStreaming?: boolean;
30
+ supportsBufferValues?: boolean;
31
+ supportsNullValues?: boolean;
32
+ supportsTransactions?: boolean;
7
33
  /**
8
34
  * Checks that connection/credentials/etc is ok.
9
35
  * Also acts as a "warmup request" for a DB.
@@ -31,7 +57,7 @@ export interface CommonDB {
31
57
  * Order of items returned is not guaranteed to match order of ids.
32
58
  * (Such limitation exists because Datastore doesn't support it).
33
59
  */
34
- getByIds: <ROW extends ObjectWithId>(table: string, ids: ROW['id'][], opt?: CommonDBOptions) => Promise<ROW[]>;
60
+ getByIds: <ROW extends ObjectWithId>(table: string, ids: string[], opt?: CommonDBOptions) => Promise<ROW[]>;
35
61
  /**
36
62
  * Order by 'id' is not supported by all implementations (for example, Datastore doesn't support it).
37
63
  */
@@ -42,6 +68,11 @@ export interface CommonDB {
42
68
  * rows can have missing ids only if DB supports auto-generating them (like mysql auto_increment).
43
69
  */
44
70
  saveBatch: <ROW extends Partial<ObjectWithId>>(table: string, rows: ROW[], opt?: CommonDBSaveOptions<ROW>) => Promise<void>;
71
+ /**
72
+ * Returns number of deleted items.
73
+ * Not supported by all implementations (e.g Datastore will always return same number as number of ids).
74
+ */
75
+ deleteByIds: (table: string, ids: string[], opt?: CommonDBOptions) => Promise<number>;
45
76
  /**
46
77
  * Returns number of deleted items.
47
78
  * Not supported by all implementations (e.g Datastore will always return same number as number of ids).
@@ -70,5 +101,26 @@ export interface CommonDB {
70
101
  * Should be implemented as a Transaction (best effort), which means that
71
102
  * either ALL or NONE of the operations should be applied.
72
103
  */
73
- commitTransaction: (tx: DBTransaction, opt?: CommonDBOptions) => Promise<void>;
104
+ createTransaction: () => Promise<DBTransaction>;
105
+ }
106
+ /**
107
+ * Manifest of supported features.
108
+ */
109
+ export interface CommonDBSupport {
110
+ queries?: boolean;
111
+ dbQueryFilter?: boolean;
112
+ dbQueryFilterIn?: boolean;
113
+ dbQueryOrder?: boolean;
114
+ dbQuerySelectFields?: boolean;
115
+ insertSaveMethod?: boolean;
116
+ updateSaveMethod?: boolean;
117
+ updateByQuery?: boolean;
118
+ dbIncrement?: boolean;
119
+ createTable?: boolean;
120
+ tableSchemas?: boolean;
121
+ streaming?: boolean;
122
+ bufferValues?: boolean;
123
+ nullValues?: boolean;
124
+ transactions?: boolean;
74
125
  }
126
+ export declare const commonDBFullSupport: CommonDBSupport;
package/dist/common.db.js CHANGED
@@ -1,2 +1,25 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.commonDBFullSupport = exports.CommonDBType = void 0;
4
+ var CommonDBType;
5
+ (function (CommonDBType) {
6
+ CommonDBType["document"] = "document";
7
+ CommonDBType["relational"] = "relational";
8
+ })(CommonDBType || (exports.CommonDBType = CommonDBType = {}));
9
+ exports.commonDBFullSupport = {
10
+ queries: true,
11
+ dbQueryFilter: true,
12
+ dbQueryFilterIn: true,
13
+ dbQueryOrder: true,
14
+ dbQuerySelectFields: true,
15
+ insertSaveMethod: true,
16
+ updateSaveMethod: true,
17
+ updateByQuery: true,
18
+ dbIncrement: true,
19
+ createTable: true,
20
+ tableSchemas: true,
21
+ streaming: true,
22
+ bufferValues: true,
23
+ nullValues: true,
24
+ transactions: true,
25
+ };
@@ -1,8 +1,8 @@
1
1
  /// <reference types="node" />
2
2
  import { Transform } from 'node:stream';
3
- import { AnyObject, AsyncMapper, JsonSchemaObject, JsonSchemaRootObject, ObjectWithId, Promisable, Saved, UnixTimestampMillisNumber, Unsaved, ZodSchema } from '@naturalcycles/js-lib';
3
+ import { AnyObject, AsyncMapper, JsonSchemaObject, JsonSchemaRootObject, ObjectWithId, Saved, UnixTimestampMillisNumber, Unsaved, ZodSchema } from '@naturalcycles/js-lib';
4
4
  import { AjvSchema, ObjectSchema, ReadableTyped } from '@naturalcycles/nodejs-lib';
5
- import { DBDeleteByIdsOperation, DBModelType, DBOperation, DBPatch, DBSaveBatchOperation, RunQueryResult } from '../db.model';
5
+ import { DBModelType, DBPatch, DBTransaction, RunQueryResult } from '../db.model';
6
6
  import { DBQuery, RunnableDBQuery } from '../query/dbQuery';
7
7
  import { CommonDaoCfg, CommonDaoCreateOptions, CommonDaoOptions, CommonDaoSaveBatchOptions, CommonDaoSaveOptions, CommonDaoStreamDeleteOptions, CommonDaoStreamForEachOptions, CommonDaoStreamOptions, CommonDaoStreamSaveOptions } from './common.dao.model';
8
8
  /**
@@ -85,12 +85,6 @@ export declare class CommonDao<BM extends Partial<ObjectWithId>, DBM extends Obj
85
85
  assignIdCreatedUpdated(obj: DBM, opt?: CommonDaoOptions): DBM;
86
86
  assignIdCreatedUpdated(obj: BM, opt?: CommonDaoOptions): Saved<BM>;
87
87
  assignIdCreatedUpdated(obj: Unsaved<BM>, opt?: CommonDaoOptions): Saved<BM>;
88
- tx: {
89
- save: (bm: Unsaved<BM>, opt?: CommonDaoSaveBatchOptions<DBM>) => Promise<DBSaveBatchOperation | undefined>;
90
- saveBatch: (bms: Unsaved<BM>[], opt?: CommonDaoSaveBatchOptions<DBM>) => Promise<DBSaveBatchOperation | undefined>;
91
- deleteByIds: (ids: string[], opt?: CommonDaoOptions) => Promise<DBDeleteByIdsOperation | undefined>;
92
- deleteById: (id: string | null | undefined, opt?: CommonDaoOptions) => Promise<DBDeleteByIdsOperation | undefined>;
93
- };
94
88
  /**
95
89
  * Mutates with id, created, updated
96
90
  */
@@ -175,9 +169,23 @@ export declare class CommonDao<BM extends Partial<ObjectWithId>, DBM extends Obj
175
169
  * Proxy to this.cfg.db.ping
176
170
  */
177
171
  ping(): Promise<void>;
178
- runInTransaction(ops: Promisable<DBOperation | undefined>[]): Promise<void>;
172
+ useTransaction(fn: (tx: CommonDaoTransaction) => Promise<void>): Promise<void>;
173
+ createTransaction(): Promise<CommonDaoTransaction>;
179
174
  protected logResult(started: number, op: string, res: any, table: string): void;
180
175
  protected logSaveResult(started: number, op: string, table: string): void;
181
176
  protected logStarted(op: string, table: string, force?: boolean): UnixTimestampMillisNumber;
182
177
  protected logSaveStarted(op: string, items: any, table: string): UnixTimestampMillisNumber;
183
178
  }
179
+ export declare class CommonDaoTransaction {
180
+ private tx;
181
+ constructor(tx: DBTransaction);
182
+ commit(): Promise<void>;
183
+ rollback(): Promise<void>;
184
+ getById<BM extends Partial<ObjectWithId>, DBM extends ObjectWithId>(dao: CommonDao<BM, DBM, any>, id: string, opt?: CommonDaoOptions): Promise<Saved<BM> | null>;
185
+ getByIds<BM extends Partial<ObjectWithId>, DBM extends ObjectWithId>(dao: CommonDao<BM, DBM, any>, ids: string[], opt?: CommonDaoOptions): Promise<Saved<BM>[]>;
186
+ runQuery<BM extends Partial<ObjectWithId>, DBM extends ObjectWithId>(dao: CommonDao<BM, DBM, any>, q: DBQuery<DBM>, opt?: CommonDaoOptions): Promise<Saved<BM>[]>;
187
+ save<BM extends Partial<ObjectWithId>, DBM extends ObjectWithId>(dao: CommonDao<BM, DBM, any>, bm: Unsaved<BM>, opt?: CommonDaoSaveBatchOptions<DBM>): Promise<Saved<BM>>;
188
+ saveBatch<BM extends Partial<ObjectWithId>, DBM extends ObjectWithId>(dao: CommonDao<BM, DBM, any>, bms: Unsaved<BM>[], opt?: CommonDaoSaveBatchOptions<DBM>): Promise<Saved<BM>[]>;
189
+ deleteById(dao: CommonDao<any>, id: string, opt?: CommonDaoOptions): Promise<number>;
190
+ deleteByIds(dao: CommonDao<any>, ids: string[], opt?: CommonDaoOptions): Promise<number>;
191
+ }
@@ -1,12 +1,11 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.CommonDao = void 0;
3
+ exports.CommonDaoTransaction = exports.CommonDao = void 0;
4
4
  const js_lib_1 = require("@naturalcycles/js-lib");
5
5
  const nodejs_lib_1 = require("@naturalcycles/nodejs-lib");
6
6
  const cnst_1 = require("../cnst");
7
7
  const db_model_1 = require("../db.model");
8
8
  const dbQuery_1 = require("../query/dbQuery");
9
- const dbTransaction_1 = require("../transaction/dbTransaction");
10
9
  const common_dao_model_1 = require("./common.dao.model");
11
10
  const isGAE = !!process.env['GAE_INSTANCE'];
12
11
  const isCI = !!process.env['CI'];
@@ -20,57 +19,6 @@ const isCI = !!process.env['CI'];
20
19
  class CommonDao {
21
20
  constructor(cfg) {
22
21
  this.cfg = cfg;
23
- this.tx = {
24
- save: async (bm, opt = {}) => {
25
- // .save actually returns DBM (not BM) when it detects `opt.tx === true`
26
- const row = (await this.save(bm, { ...opt, tx: true }));
27
- if (row === null)
28
- return;
29
- return {
30
- type: 'saveBatch',
31
- table: this.cfg.table,
32
- rows: [row],
33
- opt: {
34
- excludeFromIndexes: this.cfg.excludeFromIndexes,
35
- ...opt,
36
- },
37
- };
38
- },
39
- saveBatch: async (bms, opt = {}) => {
40
- const rows = (await this.saveBatch(bms, { ...opt, tx: true }));
41
- if (!rows.length)
42
- return;
43
- return {
44
- type: 'saveBatch',
45
- table: this.cfg.table,
46
- rows,
47
- opt: {
48
- excludeFromIndexes: this.cfg.excludeFromIndexes,
49
- ...opt,
50
- },
51
- };
52
- },
53
- deleteByIds: async (ids, opt = {}) => {
54
- if (!ids.length)
55
- return;
56
- return {
57
- type: 'deleteByIds',
58
- table: this.cfg.table,
59
- ids,
60
- opt,
61
- };
62
- },
63
- deleteById: async (id, opt = {}) => {
64
- if (!id)
65
- return;
66
- return {
67
- type: 'deleteByIds',
68
- table: this.cfg.table,
69
- ids: [id],
70
- opt,
71
- };
72
- },
73
- };
74
22
  this.cfg = {
75
23
  // Default is to NOT log in AppEngine and in CI,
76
24
  // otherwise to log Operations
@@ -562,13 +510,9 @@ class CommonDao {
562
510
  let dbm = await this.bmToDBM(bm, opt);
563
511
  if (this.cfg.hooks.beforeSave) {
564
512
  dbm = (await this.cfg.hooks.beforeSave(dbm));
565
- if (dbm === null && !opt.tx)
513
+ if (dbm === null)
566
514
  return bm;
567
515
  }
568
- if (opt.tx) {
569
- // May return `null`, in which case it'll be skipped
570
- return dbm;
571
- }
572
516
  const table = opt.table || this.cfg.table;
573
517
  if (opt.ensureUniqueId && idWasGenerated)
574
518
  await this.ensureUniqueId(table, dbm);
@@ -706,9 +650,6 @@ class CommonDao {
706
650
  if (this.cfg.hooks.beforeSave && dbms.length) {
707
651
  dbms = (await (0, js_lib_1.pMap)(dbms, async (dbm) => await this.cfg.hooks.beforeSave(dbm))).filter(js_lib_1._isTruthy);
708
652
  }
709
- if (opt.tx) {
710
- return dbms;
711
- }
712
653
  if (opt.ensureUniqueId)
713
654
  throw new js_lib_1.AppError('ensureUniqueId is not supported in saveBatch');
714
655
  if (this.cfg.immutable && !opt.allowMutability && !opt.saveMethod) {
@@ -792,7 +733,7 @@ class CommonDao {
792
733
  let dbm = await this.bmToDBM(bm, opt);
793
734
  if (beforeSave) {
794
735
  dbm = (await beforeSave(dbm));
795
- if (dbm === null && !opt.tx)
736
+ if (dbm === null)
796
737
  return js_lib_1.SKIP;
797
738
  }
798
739
  return dbm;
@@ -828,7 +769,7 @@ class CommonDao {
828
769
  const op = `deleteById(${id})`;
829
770
  const table = opt.table || this.cfg.table;
830
771
  const started = this.logStarted(op, table);
831
- const count = await this.cfg.db.deleteByQuery(dbQuery_1.DBQuery.create(table).filterEq('id', id));
772
+ const count = await this.cfg.db.deleteByIds(table, [id], opt);
832
773
  this.logSaveResult(started, op, table);
833
774
  return count;
834
775
  }
@@ -840,7 +781,7 @@ class CommonDao {
840
781
  const op = `deleteByIds(${ids.join(', ')})`;
841
782
  const table = opt.table || this.cfg.table;
842
783
  const started = this.logStarted(op, table);
843
- const count = await this.cfg.db.deleteByQuery(dbQuery_1.DBQuery.create(table).filterIn('id', ids));
784
+ const count = await this.cfg.db.deleteByIds(table, ids, opt);
844
785
  this.logSaveResult(started, op, table);
845
786
  return count;
846
787
  }
@@ -1050,11 +991,21 @@ class CommonDao {
1050
991
  async ping() {
1051
992
  await this.cfg.db.ping();
1052
993
  }
1053
- async runInTransaction(ops) {
1054
- const resolvedOps = (await Promise.all(ops)).filter(js_lib_1._isTruthy);
1055
- if (!resolvedOps.length)
1056
- return;
1057
- await this.cfg.db.commitTransaction(dbTransaction_1.DBTransaction.create(resolvedOps));
994
+ async useTransaction(fn) {
995
+ const tx = await this.cfg.db.createTransaction();
996
+ const daoTx = new CommonDaoTransaction(tx);
997
+ try {
998
+ await fn(daoTx);
999
+ await daoTx.commit();
1000
+ }
1001
+ catch (err) {
1002
+ await daoTx.rollback();
1003
+ throw err;
1004
+ }
1005
+ }
1006
+ async createTransaction() {
1007
+ const tx = await this.cfg.db.createTransaction();
1008
+ return new CommonDaoTransaction(tx);
1058
1009
  }
1059
1010
  logResult(started, op, res, table) {
1060
1011
  if (!this.cfg.logLevel)
@@ -1111,3 +1062,65 @@ class CommonDao {
1111
1062
  }
1112
1063
  }
1113
1064
  exports.CommonDao = CommonDao;
1065
+ class CommonDaoTransaction {
1066
+ constructor(tx) {
1067
+ this.tx = tx;
1068
+ }
1069
+ async commit() {
1070
+ await this.tx.commit();
1071
+ }
1072
+ async rollback() {
1073
+ try {
1074
+ await this.tx.rollback();
1075
+ }
1076
+ catch (err) {
1077
+ console.log(err);
1078
+ }
1079
+ }
1080
+ async getById(dao, id, opt) {
1081
+ return (await this.getByIds(dao, [id], opt))[0] || null;
1082
+ }
1083
+ async getByIds(dao, ids, opt) {
1084
+ try {
1085
+ return await dao.getByIds(ids, { ...opt, tx: this.tx });
1086
+ }
1087
+ catch (err) {
1088
+ await this.rollback();
1089
+ throw err;
1090
+ }
1091
+ }
1092
+ async runQuery(dao, q, opt) {
1093
+ try {
1094
+ return await dao.runQuery(q, { ...opt, tx: this.tx });
1095
+ }
1096
+ catch (err) {
1097
+ await this.rollback();
1098
+ throw err;
1099
+ }
1100
+ }
1101
+ async save(dao, bm, opt) {
1102
+ return (await this.saveBatch(dao, [bm], opt))[0];
1103
+ }
1104
+ async saveBatch(dao, bms, opt) {
1105
+ try {
1106
+ return await dao.saveBatch(bms, { ...opt, tx: this.tx });
1107
+ }
1108
+ catch (err) {
1109
+ await this.rollback();
1110
+ throw err;
1111
+ }
1112
+ }
1113
+ async deleteById(dao, id, opt) {
1114
+ return await this.deleteByIds(dao, [id], opt);
1115
+ }
1116
+ async deleteByIds(dao, ids, opt) {
1117
+ try {
1118
+ return await dao.deleteByIds(ids, { ...opt, tx: this.tx });
1119
+ }
1120
+ catch (err) {
1121
+ await this.rollback();
1122
+ throw err;
1123
+ }
1124
+ }
1125
+ }
1126
+ exports.CommonDaoTransaction = CommonDaoTransaction;
@@ -222,16 +222,6 @@ export interface CommonDaoOptions extends CommonDBOptions {
222
222
  * Useful e.g in AirtableDB where you can have one Dao to control multiple tables.
223
223
  */
224
224
  table?: string;
225
- /**
226
- * If passed - operation will not be performed immediately, but instead "added" to the transaction.
227
- * In the end - transaction needs to be committed (by calling `commit`).
228
- * This API is inspired by Datastore API.
229
- *
230
- * Only applicable to save* and delete* operations
231
- *
232
- * @experimental
233
- */
234
- tx?: boolean;
235
225
  }
236
226
  export interface CommonDaoSaveOptions<BM extends Partial<ObjectWithId>, DBM extends ObjectWithId> extends CommonDaoSaveBatchOptions<DBM> {
237
227
  /**
@@ -1,4 +1,4 @@
1
- import { ObjectWithId } from '@naturalcycles/js-lib';
1
+ import type { ObjectWithId } from '@naturalcycles/js-lib';
2
2
  /**
3
3
  * Similar to SQL INSERT, UPDATE.
4
4
  * Insert will fail if row already exists.
@@ -8,7 +8,18 @@ import { ObjectWithId } from '@naturalcycles/js-lib';
8
8
  * Default is Upsert.
9
9
  */
10
10
  export type CommonDBSaveMethod = 'upsert' | 'insert' | 'update';
11
+ export interface DBTransaction {
12
+ commit: () => Promise<void>;
13
+ rollback: () => Promise<void>;
14
+ }
11
15
  export interface CommonDBOptions {
16
+ /**
17
+ * If passed - the operation will be performed in the context of that DBTransaction.
18
+ * Note that not every type of operation supports Transaction
19
+ * (e.g in Datastore queries cannot be executed inside a Transaction).
20
+ * Also, not every CommonDB implementation supports Transactions.
21
+ */
22
+ tx?: DBTransaction;
12
23
  }
13
24
  /**
14
25
  * All properties default to undefined.
package/dist/index.d.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/dist/index.js CHANGED
@@ -16,6 +16,5 @@ tslib_1.__exportStar(require("./pipeline/dbPipelineBackup"), exports);
16
16
  tslib_1.__exportStar(require("./pipeline/dbPipelineCopy"), exports);
17
17
  tslib_1.__exportStar(require("./pipeline/dbPipelineRestore"), exports);
18
18
  tslib_1.__exportStar(require("./query/dbQuery"), exports);
19
- tslib_1.__exportStar(require("./transaction/dbTransaction"), exports);
20
19
  tslib_1.__exportStar(require("./transaction/dbTransaction.util"), exports);
21
20
  tslib_1.__exportStar(require("./kv/commonKeyValueDaoMemoCache"), exports);
@@ -23,7 +23,7 @@ async function dbPipelineBackup(opt) {
23
23
  const gzip = opt.gzip !== false; // default to true
24
24
  let { tables } = opt;
25
25
  console.log(`>> ${(0, nodejs_lib_1.dimWhite)('dbPipelineBackup')} started in ${(0, nodejs_lib_1.grey)(outputDirPath)}...`);
26
- (0, nodejs_lib_1._ensureDirSync)(outputDirPath);
26
+ nodejs_lib_1.fs2.ensureDir(outputDirPath);
27
27
  tables ||= await db.getTables();
28
28
  console.log(`${(0, nodejs_lib_1.yellow)(tables.length)} ${(0, nodejs_lib_1.boldWhite)('table(s)')}:\n` + tables.join('\n'));
29
29
  const statsPerTable = {};
@@ -46,16 +46,16 @@ async function dbPipelineBackup(opt) {
46
46
  }
47
47
  const filePath = `${outputDirPath}/${table}.ndjson` + (gzip ? '.gz' : '');
48
48
  const schemaFilePath = `${outputDirPath}/${table}.schema.json`;
49
- if (protectFromOverwrite && (0, nodejs_lib_1._pathExistsSync)(filePath)) {
49
+ if (protectFromOverwrite && nodejs_lib_1.fs2.pathExists(filePath)) {
50
50
  throw new js_lib_1.AppError(`dbPipelineBackup: output file exists: ${filePath}`);
51
51
  }
52
52
  const started = Date.now();
53
53
  let rows = 0;
54
- (0, nodejs_lib_1._ensureFileSync)(filePath);
54
+ nodejs_lib_1.fs2.ensureFile(filePath);
55
55
  // console.log(`>> ${grey(filePath)} started...`)
56
56
  if (emitSchemaFromDB) {
57
57
  const schema = await db.getTableSchema(table);
58
- await (0, nodejs_lib_1._writeJson)(schemaFilePath, schema, { spaces: 2 });
58
+ await nodejs_lib_1.fs2.writeJsonAsync(schemaFilePath, schema, { spaces: 2 });
59
59
  console.log(`>> ${(0, nodejs_lib_1.grey)(schemaFilePath)} saved (generated from DB)`);
60
60
  }
61
61
  await (0, nodejs_lib_1._pipeline)([
@@ -19,7 +19,7 @@ async function dbPipelineRestore(opt) {
19
19
  const onlyTables = opt.tables && new Set(opt.tables);
20
20
  const sinceUpdatedStr = sinceUpdated ? ' since ' + (0, nodejs_lib_1.grey)((0, js_lib_1.localTime)(sinceUpdated).toPretty()) : '';
21
21
  console.log(`>> ${(0, nodejs_lib_1.dimWhite)('dbPipelineRestore')} started in ${(0, nodejs_lib_1.grey)(inputDirPath)}...${sinceUpdatedStr}`);
22
- (0, nodejs_lib_1._ensureDirSync)(inputDirPath);
22
+ nodejs_lib_1.fs2.ensureDir(inputDirPath);
23
23
  const tablesToGzip = new Set();
24
24
  const sizeByTable = {};
25
25
  const statsPerTable = {};
@@ -54,7 +54,7 @@ async function dbPipelineRestore(opt) {
54
54
  console.warn(`${schemaFilePath} does not exist!`);
55
55
  return;
56
56
  }
57
- const schema = await (0, nodejs_lib_1._readJson)(schemaFilePath);
57
+ const schema = await nodejs_lib_1.fs2.readJsonAsync(schemaFilePath);
58
58
  await db.createTable(table, schema, { dropIfExists: true });
59
59
  });
60
60
  }
@@ -1,3 +1,3 @@
1
1
  import { CommonDB } from '../common.db';
2
- import { CommonDBImplementationFeatures, CommonDBImplementationQuirks } from './dbTest';
3
- export declare function runCommonDaoTest(db: CommonDB, features?: CommonDBImplementationFeatures, quirks?: CommonDBImplementationQuirks): void;
2
+ import { CommonDBImplementationQuirks } from './dbTest';
3
+ export declare function runCommonDaoTest(db: CommonDB, quirks?: CommonDBImplementationQuirks): void;
@@ -8,7 +8,8 @@ const __1 = require("..");
8
8
  const common_dao_1 = require("../commondao/common.dao");
9
9
  const dbTest_1 = require("./dbTest");
10
10
  const test_model_1 = require("./test.model");
11
- function runCommonDaoTest(db, features = {}, quirks = {}) {
11
+ function runCommonDaoTest(db, quirks = {}) {
12
+ const { support } = db;
12
13
  const dao = new common_dao_1.CommonDao({
13
14
  table: test_model_1.TEST_TABLE,
14
15
  db,
@@ -18,16 +19,6 @@ function runCommonDaoTest(db, features = {}, quirks = {}) {
18
19
  logStarted: true,
19
20
  logLevel: __1.CommonDaoLogLevel.DATA_FULL,
20
21
  });
21
- const { querying = true,
22
- // tableSchemas = true,
23
- createTable = true, dbQueryFilter = true,
24
- // dbQueryFilterIn = true,
25
- dbQueryOrder = true, dbQuerySelectFields = true, streaming = true, strongConsistency = true, nullValues = true, transactions = true, } = features;
26
- // const {
27
- // allowExtraPropertiesInResponse,
28
- // allowBooleansAsUndefined,
29
- // } = quirks
30
- const eventualConsistencyDelay = !strongConsistency && quirks.eventualConsistencyDelay;
31
22
  const items = (0, test_model_1.createTestItemsBM)(3);
32
23
  const itemsClone = (0, js_lib_1._deepCopy)(items);
33
24
  // deepFreeze(items) // mutation of id/created/updated is allowed now! (even expected)
@@ -40,12 +31,12 @@ function runCommonDaoTest(db, features = {}, quirks = {}) {
40
31
  await dao.ping();
41
32
  });
42
33
  // CREATE TABLE, DROP
43
- if (createTable) {
34
+ if (support.createTable) {
44
35
  test('createTable, dropIfExists=true', async () => {
45
36
  await dao.createTable(test_model_1.testItemDBMJsonSchema, { dropIfExists: true });
46
37
  });
47
38
  }
48
- if (querying) {
39
+ if (support.queries) {
49
40
  // DELETE ALL initially
50
41
  test('deleteByIds test items', async () => {
51
42
  const rows = await dao.query().select(['id']).runQuery();
@@ -53,8 +44,6 @@ function runCommonDaoTest(db, features = {}, quirks = {}) {
53
44
  });
54
45
  // QUERY empty
55
46
  test('runQuery(all), runQueryCount should return empty', async () => {
56
- if (eventualConsistencyDelay)
57
- await (0, js_lib_1.pDelay)(eventualConsistencyDelay);
58
47
  expect(await dao.query().runQuery()).toEqual([]);
59
48
  expect(await dao.query().runQueryCount()).toBe(0);
60
49
  });
@@ -72,7 +61,7 @@ function runCommonDaoTest(db, features = {}, quirks = {}) {
72
61
  expect(await dao.getByIds(['abc', 'abcd'])).toEqual([]);
73
62
  });
74
63
  // SAVE
75
- if (nullValues) {
64
+ if (support.nullValues) {
76
65
  test('should allow to save and load null values', async () => {
77
66
  const item3 = {
78
67
  ...(0, test_model_1.createTestItemBM)(3),
@@ -118,28 +107,26 @@ function runCommonDaoTest(db, features = {}, quirks = {}) {
118
107
  (0, dbTest_1.expectMatch)(expectedItems, (0, js_lib_1._sortBy)(rows, r => r.id), quirks);
119
108
  });
120
109
  // QUERY
121
- if (querying) {
110
+ if (support.queries) {
122
111
  test('runQuery(all) should return all items', async () => {
123
- if (eventualConsistencyDelay)
124
- await (0, js_lib_1.pDelay)(eventualConsistencyDelay);
125
112
  let rows = await dao.query().runQuery();
126
113
  rows = (0, js_lib_1._sortBy)(rows, r => r.id);
127
114
  (0, dbTest_1.expectMatch)(expectedItems, rows, quirks);
128
115
  });
129
- if (dbQueryFilter) {
116
+ if (support.dbQueryFilter) {
130
117
  test('query even=true', async () => {
131
118
  let rows = await dao.query().filter('even', '==', true).runQuery();
132
119
  rows = (0, js_lib_1._sortBy)(rows, r => r.id);
133
120
  (0, dbTest_1.expectMatch)(expectedItems.filter(i => i.even), rows, quirks);
134
121
  });
135
122
  }
136
- if (dbQueryOrder) {
123
+ if (support.dbQueryOrder) {
137
124
  test('query order by k1 desc', async () => {
138
125
  const rows = await dao.query().order('k1', true).runQuery();
139
126
  (0, dbTest_1.expectMatch)([...expectedItems].reverse(), rows, quirks);
140
127
  });
141
128
  }
142
- if (dbQuerySelectFields) {
129
+ if (support.dbQuerySelectFields) {
143
130
  test('projection query with only ids', async () => {
144
131
  let rows = await dao.query().select(['id']).runQuery();
145
132
  rows = (0, js_lib_1._sortBy)(rows, r => r.id);
@@ -151,7 +138,7 @@ function runCommonDaoTest(db, features = {}, quirks = {}) {
151
138
  });
152
139
  }
153
140
  // STREAM
154
- if (streaming) {
141
+ if (support.streaming) {
155
142
  test('streamQueryForEach all', async () => {
156
143
  let rows = [];
157
144
  await dao.query().streamQueryForEach(bm => void rows.push(bm));
@@ -187,12 +174,10 @@ function runCommonDaoTest(db, features = {}, quirks = {}) {
187
174
  });
188
175
  }
189
176
  // DELETE BY
190
- if (querying) {
177
+ if (support.queries) {
191
178
  test('deleteByQuery even=false', async () => {
192
179
  const deleted = await dao.query().filter('even', '==', false).deleteByQuery();
193
180
  expect(deleted).toBe(items.filter(item => !item.even).length);
194
- if (eventualConsistencyDelay)
195
- await (0, js_lib_1.pDelay)(eventualConsistencyDelay);
196
181
  expect(await dao.query().runQueryCount()).toBe(1);
197
182
  });
198
183
  test('cleanup', async () => {
@@ -200,42 +185,47 @@ function runCommonDaoTest(db, features = {}, quirks = {}) {
200
185
  await dao.query().deleteByQuery();
201
186
  });
202
187
  }
203
- if (transactions) {
188
+ if (support.transactions) {
204
189
  test('transaction happy path', async () => {
205
190
  // cleanup
206
191
  await dao.query().deleteByQuery();
207
192
  // Test that id, created, updated are created
208
193
  const now = (0, js_lib_1.localTimeNow)().unix();
209
- await dao.runInTransaction([dao.tx.save((0, js_lib_1._omit)(item1, ['id', 'created', 'updated']))]);
194
+ await dao.useTransaction(async (tx) => {
195
+ const row = (0, js_lib_1._omit)(item1, ['id', 'created', 'updated']);
196
+ await tx.save(dao, row);
197
+ });
210
198
  const loaded = await dao.query().runQuery();
211
199
  expect(loaded.length).toBe(1);
212
200
  expect(loaded[0].id).toBeDefined();
213
201
  expect(loaded[0].created).toBeGreaterThanOrEqual(now);
214
202
  expect(loaded[0].updated).toBe(loaded[0].created);
215
- await dao.runInTransaction([dao.tx.deleteById(loaded[0].id)]);
203
+ await dao.useTransaction(async (tx) => {
204
+ await tx.deleteById(dao, loaded[0].id);
205
+ });
216
206
  // saveBatch [item1, 2, 3]
217
207
  // save item3 with k1: k1_mod
218
208
  // delete item2
219
209
  // remaining: item1, item3_with_k1_mod
220
- await dao.runInTransaction([
221
- dao.tx.saveBatch(items),
222
- dao.tx.save({ ...items[2], k1: 'k1_mod' }),
223
- dao.tx.deleteById(items[1].id),
224
- ]);
210
+ await dao.useTransaction(async (tx) => {
211
+ await tx.saveBatch(dao, items);
212
+ await tx.save(dao, { ...items[2], k1: 'k1_mod' });
213
+ await tx.deleteById(dao, items[1].id);
214
+ });
225
215
  const rows = await dao.query().runQuery();
226
216
  const expected = [items[0], { ...items[2], k1: 'k1_mod' }];
227
217
  (0, dbTest_1.expectMatch)(expected, rows, quirks);
228
218
  });
229
219
  test('transaction rollback', async () => {
230
- await expect(dao.runInTransaction([
231
- dao.tx.deleteById(items[2].id),
232
- dao.tx.save({ ...items[0], k1: 5 }), // it should fail here
233
- ])).rejects.toThrow();
220
+ await expect(dao.useTransaction(async (tx) => {
221
+ await tx.deleteById(dao, items[2].id);
222
+ await tx.save(dao, { ...items[0], k1: 5 }); // it should fail here
223
+ })).rejects.toThrow();
234
224
  const rows = await dao.query().runQuery();
235
225
  const expected = [items[0], { ...items[2], k1: 'k1_mod' }];
236
226
  (0, dbTest_1.expectMatch)(expected, rows, quirks);
237
227
  });
238
- if (querying) {
228
+ if (support.queries) {
239
229
  test('transaction cleanup', async () => {
240
230
  await dao.query().deleteByQuery();
241
231
  });