@naturalcycles/db-lib 8.21.3 → 8.24.1

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 (49) hide show
  1. package/dist/adapter/cachedb/cache.db.d.ts +3 -5
  2. package/dist/adapter/cachedb/cache.db.js +16 -14
  3. package/dist/adapter/cachedb/cache.db.model.d.ts +9 -1
  4. package/dist/adapter/file/file.db.d.ts +2 -2
  5. package/dist/adapter/file/file.db.js +4 -3
  6. package/dist/adapter/file/file.db.model.d.ts +7 -1
  7. package/dist/adapter/file/inMemory.persistence.plugin.d.ts +2 -2
  8. package/dist/adapter/file/localFile.persistence.plugin.d.ts +2 -1
  9. package/dist/adapter/file/noop.persistence.plugin.d.ts +2 -1
  10. package/dist/adapter/inmemory/inMemory.db.d.ts +7 -2
  11. package/dist/adapter/inmemory/inMemory.db.js +8 -7
  12. package/dist/adapter/inmemory/queryInMemory.d.ts +1 -1
  13. package/dist/base.common.db.d.ts +2 -2
  14. package/dist/common.db.d.ts +2 -2
  15. package/dist/commondao/common.dao.d.ts +10 -3
  16. package/dist/commondao/common.dao.js +49 -12
  17. package/dist/commondao/common.dao.model.d.ts +19 -2
  18. package/dist/db.model.d.ts +1 -13
  19. package/dist/index.d.ts +4 -4
  20. package/dist/index.js +1 -2
  21. package/dist/model.util.d.ts +1 -1
  22. package/dist/pipeline/dbPipelineBackup.js +0 -1
  23. package/dist/query/dbQuery.d.ts +5 -3
  24. package/dist/transaction/dbTransaction.d.ts +2 -1
  25. package/dist/validation/index.d.ts +3 -3
  26. package/package.json +2 -2
  27. package/readme.md +1 -6
  28. package/src/adapter/cachedb/cache.db.model.ts +10 -6
  29. package/src/adapter/cachedb/cache.db.ts +29 -18
  30. package/src/adapter/file/file.db.model.ts +8 -1
  31. package/src/adapter/file/file.db.ts +8 -11
  32. package/src/adapter/file/inMemory.persistence.plugin.ts +2 -2
  33. package/src/adapter/file/localFile.persistence.plugin.ts +2 -2
  34. package/src/adapter/file/noop.persistence.plugin.ts +2 -1
  35. package/src/adapter/inmemory/inMemory.db.ts +22 -9
  36. package/src/adapter/inmemory/queryInMemory.ts +1 -2
  37. package/src/base.common.db.ts +2 -2
  38. package/src/common.db.ts +1 -2
  39. package/src/commondao/common.dao.model.ts +21 -7
  40. package/src/commondao/common.dao.ts +62 -16
  41. package/src/db.model.ts +1 -16
  42. package/src/index.ts +0 -10
  43. package/src/model.util.ts +1 -1
  44. package/src/pipeline/dbPipelineBackup.ts +0 -2
  45. package/src/query/dbQuery.ts +5 -3
  46. package/src/timeseries/commonTimeSeriesDao.ts +1 -1
  47. package/src/transaction/dbTransaction.ts +2 -1
  48. package/src/transaction/dbTransaction.util.ts +2 -2
  49. package/CHANGELOG.md +0 -1327
@@ -1,10 +1,9 @@
1
1
  /// <reference types="node" />
2
2
  import { Readable } from 'stream';
3
- import { JsonSchemaObject, JsonSchemaRootObject } from '@naturalcycles/js-lib';
4
- import { IDebugger } from '@naturalcycles/nodejs-lib';
3
+ import { JsonSchemaObject, JsonSchemaRootObject, ObjectWithId } from '@naturalcycles/js-lib';
5
4
  import { BaseCommonDB } from '../../base.common.db';
6
5
  import { CommonDB } from '../../common.db';
7
- import { ObjectWithId, RunQueryResult } from '../../db.model';
6
+ import { RunQueryResult } from '../../db.model';
8
7
  import { DBQuery } from '../../query/dbQuery';
9
8
  import { CacheDBCfg, CacheDBCreateOptions, CacheDBOptions, CacheDBStreamOptions } from './cache.db.model';
10
9
  /**
@@ -14,9 +13,8 @@ import { CacheDBCfg, CacheDBCreateOptions, CacheDBOptions, CacheDBStreamOptions
14
13
  * Queries always hit downstream (unless `onlyCache` is passed)
15
14
  */
16
15
  export declare class CacheDB extends BaseCommonDB implements CommonDB {
17
- cfg: CacheDBCfg;
18
16
  constructor(cfg: CacheDBCfg);
19
- log: IDebugger;
17
+ cfg: CacheDBCfg;
20
18
  ping(): Promise<void>;
21
19
  /**
22
20
  * Resets InMemory DB data
@@ -2,8 +2,8 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.CacheDB = void 0;
4
4
  const stream_1 = require("stream");
5
- const nodejs_lib_1 = require("@naturalcycles/nodejs-lib");
6
5
  const base_common_db_1 = require("../../base.common.db");
6
+ const isGAE = !!process.env['GAE_INSTANCE'];
7
7
  /**
8
8
  * CommonDB implementation that proxies requests to downstream CommonDB
9
9
  * and does in-memory caching.
@@ -13,8 +13,10 @@ const base_common_db_1 = require("../../base.common.db");
13
13
  class CacheDB extends base_common_db_1.BaseCommonDB {
14
14
  constructor(cfg) {
15
15
  super();
16
- this.cfg = cfg;
17
- this.log = (0, nodejs_lib_1.Debug)(`nc:db-lib:${cfg.name}`);
16
+ this.cfg = {
17
+ logger: isGAE ? undefined : console,
18
+ ...cfg,
19
+ };
18
20
  }
19
21
  async ping() {
20
22
  await Promise.all([this.cfg.cacheDB.ping(), this.cfg.downstreamDB.ping()]);
@@ -49,7 +51,7 @@ class CacheDB extends base_common_db_1.BaseCommonDB {
49
51
  results.forEach(r => (resultMap[r.id] = r));
50
52
  missingIds.push(...ids.filter(id => !resultMap[id]));
51
53
  if (this.cfg.logCached) {
52
- this.log(`${table}.getByIds ${results.length} rows from cache: [${results
54
+ this.cfg.logger?.log(`${table}.getByIds ${results.length} rows from cache: [${results
53
55
  .map(r => r.id)
54
56
  .join(', ')}]`);
55
57
  }
@@ -58,7 +60,7 @@ class CacheDB extends base_common_db_1.BaseCommonDB {
58
60
  const results = await this.cfg.downstreamDB.getByIds(table, missingIds, opt);
59
61
  results.forEach(r => (resultMap[r.id] = r));
60
62
  if (this.cfg.logDownstream) {
61
- this.log(`${table}.getByIds ${results.length} rows from downstream: [${results
63
+ this.cfg.logger?.log(`${table}.getByIds ${results.length} rows from downstream: [${results
62
64
  .map(r => r.id)
63
65
  .join(', ')}]`);
64
66
  }
@@ -76,13 +78,13 @@ class CacheDB extends base_common_db_1.BaseCommonDB {
76
78
  if (!opt.onlyCache && !this.cfg.onlyCache) {
77
79
  deletedIds = await this.cfg.downstreamDB.deleteByIds(table, ids, opt);
78
80
  if (this.cfg.logDownstream) {
79
- this.log(`${table}.deleteByIds ${deletedIds} rows from downstream`);
81
+ this.cfg.logger?.log(`${table}.deleteByIds ${deletedIds} rows from downstream`);
80
82
  }
81
83
  }
82
84
  if (!opt.skipCache && !this.cfg.skipCache) {
83
85
  const cacheResult = this.cfg.cacheDB.deleteByIds(table, ids, opt).then(deletedFromCache => {
84
86
  if (this.cfg.logCached) {
85
- this.log(`${table}.deleteByIds ${deletedFromCache} rows from cache`);
87
+ this.cfg.logger?.log(`${table}.deleteByIds ${deletedFromCache} rows from cache`);
86
88
  }
87
89
  });
88
90
  if (this.cfg.awaitCache)
@@ -94,7 +96,7 @@ class CacheDB extends base_common_db_1.BaseCommonDB {
94
96
  if (!opt.onlyCache && !this.cfg.onlyCache) {
95
97
  await this.cfg.downstreamDB.saveBatch(table, rows, opt);
96
98
  if (this.cfg.logDownstream) {
97
- this.log(`${table}.saveBatch ${rows.length} rows to downstream: [${rows
99
+ this.cfg.logger?.log(`${table}.saveBatch ${rows.length} rows to downstream: [${rows
98
100
  .map(r => r.id)
99
101
  .join(', ')}]`);
100
102
  }
@@ -102,7 +104,7 @@ class CacheDB extends base_common_db_1.BaseCommonDB {
102
104
  if (!opt.skipCache && !this.cfg.skipCache) {
103
105
  const cacheResult = this.cfg.cacheDB.saveBatch(table, rows, opt).then(() => {
104
106
  if (this.cfg.logCached) {
105
- this.log(`${table}.saveBatch ${rows.length} rows to cache: [${rows.map(r => r.id).join(', ')}]`);
107
+ this.cfg.logger?.log(`${table}.saveBatch ${rows.length} rows to cache: [${rows.map(r => r.id).join(', ')}]`);
106
108
  }
107
109
  });
108
110
  if (this.cfg.awaitCache)
@@ -113,7 +115,7 @@ class CacheDB extends base_common_db_1.BaseCommonDB {
113
115
  if (!opt.onlyCache && !this.cfg.onlyCache) {
114
116
  const { rows, ...queryResult } = await this.cfg.downstreamDB.runQuery(q, opt);
115
117
  if (this.cfg.logDownstream) {
116
- this.log(`${q.table}.runQuery ${rows.length} rows from downstream`);
118
+ this.cfg.logger?.log(`${q.table}.runQuery ${rows.length} rows from downstream`);
117
119
  }
118
120
  // Don't save to cache if it was a projection query
119
121
  if (!opt.skipCache && !opt.skipCache && !q._selectedFieldNames) {
@@ -127,7 +129,7 @@ class CacheDB extends base_common_db_1.BaseCommonDB {
127
129
  return { rows: [] };
128
130
  const { rows, ...queryResult } = await this.cfg.cacheDB.runQuery(q, opt);
129
131
  if (this.cfg.logCached) {
130
- this.log(`${q.table}.runQuery ${rows.length} rows from cache`);
132
+ this.cfg.logger?.log(`${q.table}.runQuery ${rows.length} rows from cache`);
131
133
  }
132
134
  return { rows, ...queryResult };
133
135
  }
@@ -137,7 +139,7 @@ class CacheDB extends base_common_db_1.BaseCommonDB {
137
139
  }
138
140
  const count = await this.cfg.cacheDB.runQueryCount(q, opt);
139
141
  if (this.cfg.logCached) {
140
- this.log(`${q.table}.runQueryCount ${count} rows from cache`);
142
+ this.cfg.logger?.log(`${q.table}.runQueryCount ${count} rows from cache`);
141
143
  }
142
144
  return count;
143
145
  }
@@ -175,7 +177,7 @@ class CacheDB extends base_common_db_1.BaseCommonDB {
175
177
  if (!opt.onlyCache && !this.cfg.onlyCache) {
176
178
  const deletedIds = await this.cfg.downstreamDB.deleteByQuery(q, opt);
177
179
  if (this.cfg.logDownstream) {
178
- this.log(`${q.table}.deleteByQuery ${deletedIds} rows from downstream and cache`);
180
+ this.cfg.logger?.log(`${q.table}.deleteByQuery ${deletedIds} rows from downstream and cache`);
179
181
  }
180
182
  if (!opt.skipCache && !this.cfg.skipCache) {
181
183
  const cacheResult = this.cfg.cacheDB.deleteByQuery(q, opt);
@@ -188,7 +190,7 @@ class CacheDB extends base_common_db_1.BaseCommonDB {
188
190
  return 0;
189
191
  const deletedIds = await this.cfg.cacheDB.deleteByQuery(q, opt);
190
192
  if (this.cfg.logCached) {
191
- this.log(`${q.table}.deleteByQuery ${deletedIds} rows from cache`);
193
+ this.cfg.logger?.log(`${q.table}.deleteByQuery ${deletedIds} rows from cache`);
192
194
  }
193
195
  return deletedIds;
194
196
  }
@@ -1,5 +1,6 @@
1
+ import { CommonLogger, ObjectWithId } from '@naturalcycles/js-lib';
1
2
  import { CommonDB } from '../../common.db';
2
- import { CommonDBCreateOptions, CommonDBSaveOptions, CommonDBStreamOptions, ObjectWithId } from '../../db.model';
3
+ import { CommonDBCreateOptions, CommonDBSaveOptions, CommonDBStreamOptions } from '../../db.model';
3
4
  export interface CacheDBCfg {
4
5
  name: string;
5
6
  cacheDB: CommonDB;
@@ -31,6 +32,13 @@ export interface CacheDBCfg {
31
32
  * @default false
32
33
  */
33
34
  logDownstream?: boolean;
35
+ /**
36
+ * Pass noopLogger (or undefined) to skip logging completely.
37
+ *
38
+ * Defaults to `console` in dev.
39
+ * Default to noop in AppEngine.
40
+ */
41
+ logger?: CommonLogger;
34
42
  }
35
43
  export interface CacheDBOptions<ROW extends ObjectWithId> extends CommonDBSaveOptions<ROW> {
36
44
  /**
@@ -1,6 +1,6 @@
1
- import { JsonSchemaRootObject } from '@naturalcycles/js-lib';
1
+ import { JsonSchemaRootObject, ObjectWithId } from '@naturalcycles/js-lib';
2
2
  import { ReadableTyped } from '@naturalcycles/nodejs-lib';
3
- import { BaseCommonDB, DBSaveBatchOperation, ObjectWithId } from '../..';
3
+ import { BaseCommonDB, DBSaveBatchOperation } from '../..';
4
4
  import { CommonDB } from '../../common.db';
5
5
  import { CommonDBOptions, CommonDBSaveOptions, CommonDBStreamOptions, RunQueryResult } from '../../db.model';
6
6
  import { DBQuery } from '../../query/dbQuery';
@@ -5,7 +5,7 @@ const js_lib_1 = require("@naturalcycles/js-lib");
5
5
  const nodejs_lib_1 = require("@naturalcycles/nodejs-lib");
6
6
  const colors_1 = require("@naturalcycles/nodejs-lib/dist/colors");
7
7
  const __1 = require("../..");
8
- const log = (0, nodejs_lib_1.Debug)('nc:db-lib:filedb');
8
+ const isGAE = !!process.env['GAE_INSTANCE'];
9
9
  /**
10
10
  * Provides barebone implementation for "whole file" based CommonDB.
11
11
  * "whole file" means that the persistence layer doesn't allow any querying,
@@ -22,6 +22,7 @@ class FileDB extends __1.BaseCommonDB {
22
22
  this.cfg = {
23
23
  sortObjects: true,
24
24
  logFinished: true,
25
+ logger: isGAE ? undefined : console,
25
26
  ...cfg,
26
27
  };
27
28
  }
@@ -183,14 +184,14 @@ class FileDB extends __1.BaseCommonDB {
183
184
  }
184
185
  logStarted(op) {
185
186
  if (this.cfg.logStarted) {
186
- log(`>> ${op}`);
187
+ this.cfg.logger?.log(`>> ${op}`);
187
188
  }
188
189
  return Date.now();
189
190
  }
190
191
  logFinished(started, op) {
191
192
  if (!this.cfg.logFinished)
192
193
  return;
193
- log(`<< ${op} ${(0, colors_1.dimGrey)(`in ${(0, js_lib_1._since)(started)}`)}`);
194
+ this.cfg.logger?.log(`<< ${op} ${(0, colors_1.dimGrey)(`in ${(0, js_lib_1._since)(started)}`)}`);
194
195
  }
195
196
  }
196
197
  exports.FileDB = FileDB;
@@ -1,4 +1,5 @@
1
- import { DBSaveBatchOperation, ObjectWithId } from '../../db.model';
1
+ import { CommonLogger, ObjectWithId } from '@naturalcycles/js-lib';
2
+ import { DBSaveBatchOperation } from '../../db.model';
2
3
  import type { DBQueryOrder } from '../../query/dbQuery';
3
4
  export interface FileDBPersistencePlugin {
4
5
  ping(): Promise<void>;
@@ -17,6 +18,11 @@ export interface FileDBCfg {
17
18
  * If true - will run `sortObjectDeep()` on each object to achieve deterministic sort
18
19
  */
19
20
  sortObjects?: boolean;
21
+ /**
22
+ * Defaults to `console` in dev.
23
+ * Default to noop in AppEngine.
24
+ */
25
+ logger?: CommonLogger;
20
26
  /**
21
27
  * @default false
22
28
  */
@@ -1,5 +1,5 @@
1
- import { StringMap } from '@naturalcycles/js-lib';
2
- import { DBSaveBatchOperation, ObjectWithId } from '../../db.model';
1
+ import { StringMap, ObjectWithId } from '@naturalcycles/js-lib';
2
+ import { DBSaveBatchOperation } from '../../db.model';
3
3
  import { FileDBPersistencePlugin } from './file.db.model';
4
4
  /**
5
5
  * Mostly useful for testing.
@@ -1,4 +1,5 @@
1
- import { DBSaveBatchOperation, ObjectWithId } from '../../db.model';
1
+ import { ObjectWithId } from '@naturalcycles/js-lib';
2
+ import { DBSaveBatchOperation } from '../../db.model';
2
3
  import { FileDBPersistencePlugin } from './file.db.model';
3
4
  export interface LocalFilePersistencePluginCfg {
4
5
  /**
@@ -1,4 +1,5 @@
1
- import { DBSaveBatchOperation, ObjectWithId } from '../../db.model';
1
+ import { ObjectWithId } from '@naturalcycles/js-lib';
2
+ import { DBSaveBatchOperation } from '../../db.model';
2
3
  import { FileDBPersistencePlugin } from './file.db.model';
3
4
  export declare class NoopPersistencePlugin implements FileDBPersistencePlugin {
4
5
  ping(): Promise<void>;
@@ -1,6 +1,6 @@
1
- import { JsonSchemaObject, StringMap, JsonSchemaRootObject } from '@naturalcycles/js-lib';
1
+ import { JsonSchemaObject, StringMap, JsonSchemaRootObject, ObjectWithId, CommonLogger } from '@naturalcycles/js-lib';
2
2
  import { ReadableTyped } from '@naturalcycles/nodejs-lib';
3
- import { CommonDB, DBTransaction, ObjectWithId } from '../..';
3
+ import { CommonDB, DBTransaction } from '../..';
4
4
  import { CommonDBCreateOptions, CommonDBOptions, CommonDBSaveOptions, RunQueryResult } from '../../db.model';
5
5
  import { DBQuery } from '../../query/dbQuery';
6
6
  export interface InMemoryDBCfg {
@@ -30,6 +30,11 @@ export interface InMemoryDBCfg {
30
30
  * @default true
31
31
  */
32
32
  persistZip: boolean;
33
+ /**
34
+ * Defaults to `console` in dev.
35
+ * Default to noop in AppEngine.
36
+ */
37
+ logger?: CommonLogger;
33
38
  }
34
39
  export declare class InMemoryDB implements CommonDB {
35
40
  constructor(cfg?: Partial<InMemoryDBCfg>);
@@ -8,7 +8,7 @@ const nodejs_lib_1 = require("@naturalcycles/nodejs-lib");
8
8
  const colors_1 = require("@naturalcycles/nodejs-lib/dist/colors");
9
9
  const fs = require("fs-extra");
10
10
  const __1 = require("../..");
11
- const log = (0, nodejs_lib_1.Debug)('nc:db-lib:inmemorydb');
11
+ const isGAE = !!process.env['GAE_INSTANCE'];
12
12
  class InMemoryDB {
13
13
  constructor(cfg) {
14
14
  // data[table][id] > {id: 'a', created: ... }
@@ -19,6 +19,7 @@ class InMemoryDB {
19
19
  persistenceEnabled: false,
20
20
  persistZip: true,
21
21
  persistentStoragePath: './tmp/inmemorydb',
22
+ logger: isGAE ? undefined : console,
22
23
  ...cfg,
23
24
  };
24
25
  }
@@ -36,7 +37,7 @@ class InMemoryDB {
36
37
  async resetCache(_table) {
37
38
  if (_table) {
38
39
  const table = this.cfg.tablesPrefix + _table;
39
- log(`reset ${table}`);
40
+ this.cfg.logger?.log(`reset ${table}`);
40
41
  this.data[table] = {};
41
42
  }
42
43
  else {
@@ -44,7 +45,7 @@ class InMemoryDB {
44
45
  (await this.getTables()).forEach(table => {
45
46
  this.data[table] = {};
46
47
  });
47
- log('reset');
48
+ this.cfg.logger?.log('reset');
48
49
  }
49
50
  }
50
51
  async getTables() {
@@ -53,7 +54,7 @@ class InMemoryDB {
53
54
  async getTableSchema(_table) {
54
55
  const table = this.cfg.tablesPrefix + _table;
55
56
  return {
56
- ...(0, js_lib_1.generateJsonSchemaFromData)(Object.values(this.data[table] || {})),
57
+ ...(0, js_lib_1.generateJsonSchemaFromData)((0, js_lib_1._stringMapValues)(this.data[table] || {})),
57
58
  $id: `${table}.schema.json`,
58
59
  };
59
60
  }
@@ -76,7 +77,7 @@ class InMemoryDB {
76
77
  this.data[table] = this.data[table] || {};
77
78
  rows.forEach(r => {
78
79
  if (!r.id) {
79
- log.warn({ rows });
80
+ this.cfg.logger?.warn({ rows });
80
81
  throw new Error(`InMemoryDB: id doesn't exist for row`);
81
82
  }
82
83
  // JSON parse/stringify (deep clone) is to:
@@ -160,7 +161,7 @@ class InMemoryDB {
160
161
  fs.createWriteStream(fname),
161
162
  ]);
162
163
  });
163
- log(`flushToDisk took ${(0, colors_1.dimGrey)((0, js_lib_1._since)(started))} to save ${(0, colors_1.yellow)(tables)} tables`);
164
+ this.cfg.logger?.log(`flushToDisk took ${(0, colors_1.dimGrey)((0, js_lib_1._since)(started))} to save ${(0, colors_1.yellow)(tables)} tables`);
164
165
  }
165
166
  /**
166
167
  * Restores all tables (all namespaces) at once.
@@ -189,7 +190,7 @@ class InMemoryDB {
189
190
  ]);
190
191
  this.data[table] = (0, js_lib_1._by)(rows, r => r.id);
191
192
  });
192
- log(`restoreFromDisk took ${(0, colors_1.dimGrey)((0, js_lib_1._since)(started))} to read ${(0, colors_1.yellow)(files.length)} tables`);
193
+ this.cfg.logger?.log(`restoreFromDisk took ${(0, colors_1.dimGrey)((0, js_lib_1._since)(started))} to read ${(0, colors_1.yellow)(files.length)} tables`);
193
194
  }
194
195
  }
195
196
  exports.InMemoryDB = InMemoryDB;
@@ -1,3 +1,3 @@
1
- import { ObjectWithId } from '../../db.model';
1
+ import { ObjectWithId } from '@naturalcycles/js-lib';
2
2
  import { DBQuery } from '../../query/dbQuery';
3
3
  export declare function queryInMemory<ROW extends ObjectWithId>(q: DBQuery<ROW>, rows?: ROW[]): ROW[];
@@ -1,7 +1,7 @@
1
- import { JsonSchemaObject, JsonSchemaRootObject } from '@naturalcycles/js-lib';
1
+ import { JsonSchemaObject, JsonSchemaRootObject, ObjectWithId } from '@naturalcycles/js-lib';
2
2
  import { ReadableTyped } from '@naturalcycles/nodejs-lib';
3
3
  import { CommonDB } from './common.db';
4
- import { CommonDBOptions, CommonDBSaveOptions, ObjectWithId, RunQueryResult } from './db.model';
4
+ import { CommonDBOptions, CommonDBSaveOptions, RunQueryResult } from './db.model';
5
5
  import { DBQuery } from './query/dbQuery';
6
6
  import { DBTransaction } from './transaction/dbTransaction';
7
7
  /**
@@ -1,6 +1,6 @@
1
- import { JsonSchemaObject, JsonSchemaRootObject } from '@naturalcycles/js-lib';
1
+ import { JsonSchemaObject, JsonSchemaRootObject, ObjectWithId } from '@naturalcycles/js-lib';
2
2
  import { ReadableTyped } from '@naturalcycles/nodejs-lib';
3
- import { CommonDBCreateOptions, CommonDBOptions, CommonDBSaveOptions, CommonDBStreamOptions, ObjectWithId, RunQueryResult } from './db.model';
3
+ import { CommonDBCreateOptions, CommonDBOptions, CommonDBSaveOptions, CommonDBStreamOptions, RunQueryResult } from './db.model';
4
4
  import { DBQuery } from './query/dbQuery';
5
5
  import { DBTransaction } from './transaction/dbTransaction';
6
6
  export interface CommonDB {
@@ -1,6 +1,6 @@
1
- import { AsyncMapper, JsonSchemaObject, JsonSchemaRootObject, Saved } from '@naturalcycles/js-lib';
1
+ import { AsyncMapper, JsonSchemaObject, JsonSchemaRootObject, Saved, ObjectWithId } from '@naturalcycles/js-lib';
2
2
  import { AjvSchema, ObjectSchemaTyped, ReadableTyped } from '@naturalcycles/nodejs-lib';
3
- import { DBModelType, ObjectWithId, RunQueryResult } from '../db.model';
3
+ import { DBModelType, RunQueryResult } from '../db.model';
4
4
  import { DBQuery, RunnableDBQuery } from '../query/dbQuery';
5
5
  import { CommonDaoCfg, CommonDaoCreateOptions, CommonDaoOptions, CommonDaoSaveOptions, CommonDaoStreamForEachOptions, CommonDaoStreamOptions } from './common.dao.model';
6
6
  /**
@@ -104,7 +104,14 @@ export declare class CommonDao<BM extends Partial<ObjectWithId>, DBM extends Obj
104
104
  deleteById(id: undefined, opt?: CommonDaoOptions): Promise<0>;
105
105
  deleteById(id?: string, opt?: CommonDaoOptions): Promise<number>;
106
106
  deleteByIds(ids: string[], opt?: CommonDaoOptions): Promise<number>;
107
- deleteByQuery(q: DBQuery<DBM>, opt?: CommonDaoOptions): Promise<number>;
107
+ /**
108
+ * Pass `stream: true` option to use Streaming: it will Stream the query, batch by 500, and execute
109
+ * `deleteByIds` for each batch concurrently (infinite concurrency).
110
+ * This is expected to be more memory-efficient way of deleting big numbers of rows.
111
+ */
112
+ deleteByQuery(q: DBQuery<DBM>, opt?: CommonDaoStreamForEachOptions<DBM> & {
113
+ stream?: boolean;
114
+ }): Promise<number>;
108
115
  dbmToBM(_dbm: undefined, opt?: CommonDaoOptions): Promise<undefined>;
109
116
  dbmToBM(_dbm?: DBM, opt?: CommonDaoOptions): Promise<Saved<BM>>;
110
117
  dbmsToBM(dbms: DBM[], opt?: CommonDaoOptions): Promise<Saved<BM>[]>;
@@ -7,8 +7,8 @@ const cnst_1 = require("../cnst");
7
7
  const db_model_1 = require("../db.model");
8
8
  const dbQuery_1 = require("../query/dbQuery");
9
9
  const common_dao_model_1 = require("./common.dao.model");
10
- const log = (0, nodejs_lib_1.Debug)('nc:db-lib:commondao');
11
10
  /* eslint-disable no-dupe-class-members */
11
+ const isGAE = !!process.env['GAE_INSTANCE'];
12
12
  /**
13
13
  * Lowest common denominator API between supported Databases.
14
14
  *
@@ -22,6 +22,7 @@ class CommonDao {
22
22
  this.cfg = {
23
23
  logLevel: common_dao_model_1.CommonDaoLogLevel.OPERATIONS,
24
24
  createdUpdated: true,
25
+ logger: isGAE ? undefined : console,
25
26
  ...cfg,
26
27
  hooks: {
27
28
  createId: () => (0, nodejs_lib_1.stringId)(),
@@ -234,7 +235,7 @@ class CommonDao {
234
235
  const started = this.logStarted(op, q.table);
235
236
  const count = await this.cfg.db.runQueryCount(q, opt);
236
237
  if (this.cfg.logLevel >= common_dao_model_1.CommonDaoLogLevel.OPERATIONS) {
237
- log(`<< ${q.table}.${op}: ${count} row(s) in ${(0, js_lib_1._since)(started)}`);
238
+ this.cfg.logger?.log(`<< ${q.table}.${op}: ${count} row(s) in ${(0, js_lib_1._since)(started)}`);
238
239
  }
239
240
  return count;
240
241
  }
@@ -269,7 +270,7 @@ class CommonDao {
269
270
  (0, nodejs_lib_1.writableVoid)(),
270
271
  ]);
271
272
  if (this.cfg.logLevel >= common_dao_model_1.CommonDaoLogLevel.OPERATIONS) {
272
- log(`<< ${q.table}.${op}: ${count} row(s) in ${(0, js_lib_1._since)(started)}`);
273
+ this.cfg.logger?.log(`<< ${q.table}.${op}: ${count} row(s) in ${(0, js_lib_1._since)(started)}`);
273
274
  }
274
275
  }
275
276
  async streamQueryAsDBMForEach(q, mapper, opt = {}) {
@@ -301,7 +302,7 @@ class CommonDao {
301
302
  (0, nodejs_lib_1.writableVoid)(),
302
303
  ]);
303
304
  if (this.cfg.logLevel >= common_dao_model_1.CommonDaoLogLevel.OPERATIONS) {
304
- log(`<< ${q.table}.${op}: ${count} row(s) in ${(0, js_lib_1._since)(started)}`);
305
+ this.cfg.logger?.log(`<< ${q.table}.${op}: ${count} row(s) in ${(0, js_lib_1._since)(started)}`);
305
306
  }
306
307
  }
307
308
  /**
@@ -384,7 +385,7 @@ class CommonDao {
384
385
  (0, nodejs_lib_1.writableVoid)(),
385
386
  ]);
386
387
  if (this.cfg.logLevel >= common_dao_model_1.CommonDaoLogLevel.OPERATIONS) {
387
- log(`<< ${q.table}.${op}: ${count} id(s) in ${(0, js_lib_1._since)(started)}`);
388
+ this.cfg.logger?.log(`<< ${q.table}.${op}: ${count} id(s) in ${(0, js_lib_1._since)(started)}`);
388
389
  }
389
390
  }
390
391
  assignIdCreatedUpdated(obj, opt = {}) {
@@ -536,14 +537,45 @@ class CommonDao {
536
537
  this.logSaveResult(started, op, table);
537
538
  return deletedIds;
538
539
  }
540
+ /**
541
+ * Pass `stream: true` option to use Streaming: it will Stream the query, batch by 500, and execute
542
+ * `deleteByIds` for each batch concurrently (infinite concurrency).
543
+ * This is expected to be more memory-efficient way of deleting big numbers of rows.
544
+ */
539
545
  async deleteByQuery(q, opt = {}) {
540
546
  this.requireWriteAccess();
541
547
  q.table = opt.table || q.table;
542
548
  const op = `deleteByQuery(${q.pretty()})`;
543
549
  const started = this.logStarted(op, q.table);
544
- const ids = await this.cfg.db.deleteByQuery(q, opt);
550
+ let deleted = 0;
551
+ if (opt.stream) {
552
+ const batchSize = 500;
553
+ await (0, nodejs_lib_1._pipeline)([
554
+ this.cfg.db.streamQuery(q.select(['id']), opt),
555
+ (0, nodejs_lib_1.transformMapSimple)(objectWithId => objectWithId.id, {
556
+ errorMode: js_lib_1.ErrorMode.SUPPRESS,
557
+ }),
558
+ (0, nodejs_lib_1.transformBuffer)({ batchSize }),
559
+ (0, nodejs_lib_1.transformMap)(async (ids) => {
560
+ deleted += await this.cfg.db.deleteByIds(q.table, ids, opt);
561
+ }, {
562
+ predicate: js_lib_1._passthroughPredicate,
563
+ }),
564
+ // LogProgress should be AFTER the mapper, to be able to report correct stats
565
+ (0, nodejs_lib_1.transformLogProgress)({
566
+ metric: q.table,
567
+ logEvery: 2,
568
+ batchSize,
569
+ ...opt,
570
+ }),
571
+ (0, nodejs_lib_1.writableVoid)(),
572
+ ]);
573
+ }
574
+ else {
575
+ deleted = await this.cfg.db.deleteByQuery(q, opt);
576
+ }
545
577
  this.logSaveResult(started, op, q.table);
546
- return ids;
578
+ return deleted;
547
579
  }
548
580
  async dbmToBM(_dbm, opt = {}) {
549
581
  if (!_dbm)
@@ -648,7 +680,12 @@ class CommonDao {
648
680
  // obj = _filterNullishValues(obj as any)
649
681
  // We still filter `undefined` values here, because `beforeDBMToBM` can return undefined values
650
682
  // and they can be annoying with snapshot tests
651
- obj = (0, js_lib_1._filterUndefinedValues)(obj);
683
+ if (this.cfg.filterNullishValues) {
684
+ obj = (0, js_lib_1._filterNullishValues)(obj);
685
+ }
686
+ else {
687
+ obj = (0, js_lib_1._filterUndefinedValues)(obj);
688
+ }
652
689
  // Pre-validation hooks
653
690
  if (modelType === db_model_1.DBModelType.DBM) {
654
691
  obj = this.cfg.hooks.beforeDBMValidate(obj);
@@ -721,16 +758,16 @@ class CommonDao {
721
758
  else {
722
759
  logRes = `undefined`;
723
760
  }
724
- log(...[`<< ${table}.${op}: ${logRes} in ${(0, js_lib_1._since)(started)}`].concat(args));
761
+ this.cfg.logger?.log(...[`<< ${table}.${op}: ${logRes} in ${(0, js_lib_1._since)(started)}`].concat(args));
725
762
  }
726
763
  logSaveResult(started, op, table) {
727
764
  if (!this.cfg.logLevel)
728
765
  return;
729
- log(`<< ${table}.${op} in ${(0, js_lib_1._since)(started)}`);
766
+ this.cfg.logger?.log(`<< ${table}.${op} in ${(0, js_lib_1._since)(started)}`);
730
767
  }
731
768
  logStarted(op, table, force = false) {
732
769
  if (this.cfg.logStarted || force) {
733
- log(`>> ${table}.${op}`);
770
+ this.cfg.logger?.log(`>> ${table}.${op}`);
734
771
  }
735
772
  return Date.now();
736
773
  }
@@ -750,7 +787,7 @@ class CommonDao {
750
787
  args.push(items);
751
788
  }
752
789
  }
753
- log(...args);
790
+ this.cfg.logger?.log(...args);
754
791
  }
755
792
  return Date.now();
756
793
  }
@@ -1,7 +1,7 @@
1
- import { ErrorMode } from '@naturalcycles/js-lib';
1
+ import { CommonLogger, ErrorMode, ObjectWithId } from '@naturalcycles/js-lib';
2
2
  import { AjvSchema, AjvValidationError, JoiValidationError, ObjectSchemaTyped, TransformLogProgressOptions, TransformMapOptions } from '@naturalcycles/nodejs-lib';
3
3
  import { CommonDB } from '../common.db';
4
- import { CommonDBCreateOptions, CommonDBOptions, CommonDBSaveOptions, ObjectWithId } from '../db.model';
4
+ import { CommonDBCreateOptions, CommonDBOptions, CommonDBSaveOptions } from '../db.model';
5
5
  export declare type CommonDaoCreateIdHook<BM, DBM> = (obj: DBM | BM) => string;
6
6
  export declare type CommonDaoParseNaturalIdHook<DBM> = (id: string) => Partial<DBM>;
7
7
  export declare type CommonDaoBeforeCreateHook<BM> = (bm: Partial<BM>) => BM;
@@ -53,6 +53,13 @@ export interface CommonDaoCfg<BM extends Partial<ObjectWithId>, DBM extends Obje
53
53
  * Set to true to limit DB writing (will throw an error is such case).
54
54
  */
55
55
  readOnly?: boolean;
56
+ /**
57
+ * Pass undefined (or noopLogger) to disable logging completely.
58
+ *
59
+ * Defaults to `console` in dev.
60
+ * Default to noop in AppEngine.
61
+ */
62
+ logger?: CommonLogger;
56
63
  /**
57
64
  * @default OPERATIONS
58
65
  */
@@ -67,6 +74,16 @@ export interface CommonDaoCfg<BM extends Partial<ObjectWithId>, DBM extends Obje
67
74
  * Set to false to disable created/updated fields management.
68
75
  */
69
76
  createdUpdated?: boolean;
77
+ /**
78
+ * Default is false.
79
+ * If true - will run `_filterNullishValues` inside `validateAndConvert` function
80
+ * (instead of `_filterUndefinedValues`).
81
+ * This was the old db-lib behavior.
82
+ * This option allows to keep backwards-compatible behavior.
83
+ *
84
+ * @deprecated
85
+ */
86
+ filterNullishValues?: boolean;
70
87
  }
71
88
  /**
72
89
  * All properties default to undefined.
@@ -1,4 +1,4 @@
1
- import { AnyObject } from '@naturalcycles/js-lib';
1
+ import { AnyObjectWithId, ObjectWithId } from '@naturalcycles/js-lib';
2
2
  import { CommonDB } from './common.db';
3
3
  export interface CommonDBOptions {
4
4
  }
@@ -40,18 +40,6 @@ export declare enum DBModelType {
40
40
  BM = "BM",
41
41
  TM = "TM"
42
42
  }
43
- export interface CreatedUpdated {
44
- created: number;
45
- updated: number;
46
- }
47
- export interface CreatedUpdatedId extends CreatedUpdated {
48
- id: string;
49
- }
50
- export interface ObjectWithId {
51
- id: string;
52
- }
53
- export interface AnyObjectWithId extends AnyObject, ObjectWithId {
54
- }
55
43
  /**
56
44
  * Interface for a module (lib) that implements CommonDB.
57
45
  *
package/dist/index.d.ts CHANGED
@@ -6,16 +6,16 @@ import { DBLibError } from './cnst';
6
6
  import { CommonDB } from './common.db';
7
7
  import { CommonDao } from './commondao/common.dao';
8
8
  import { CommonDaoAnonymizeHook, CommonDaoBeforeBMToDBMHook, CommonDaoBeforeBMToTMHook, CommonDaoBeforeCreateHook, CommonDaoBeforeDBMToBMHook, CommonDaoBeforeDBMValidateHook, CommonDaoBeforeTMToBMHook, CommonDaoCfg, CommonDaoCreateIdHook, CommonDaoCreateOptions, CommonDaoLogLevel, CommonDaoOptions, CommonDaoParseNaturalIdHook, CommonDaoSaveOptions, CommonDaoStreamForEachOptions, CommonDaoStreamOptions } from './commondao/common.dao.model';
9
- import { AnyObjectWithId, CommonDBAdapter, CommonDBCreateOptions, CommonDBOptions, CommonDBSaveOptions, CommonDBStreamOptions, CreatedUpdated, CreatedUpdatedId, DBDeleteByIdsOperation, DBModelType, DBOperation, DBRelation, DBSaveBatchOperation, ObjectWithId, RunQueryResult } from './db.model';
9
+ import { CommonDBAdapter, CommonDBCreateOptions, CommonDBOptions, CommonDBSaveOptions, CommonDBStreamOptions, DBDeleteByIdsOperation, DBModelType, DBOperation, DBRelation, DBSaveBatchOperation, RunQueryResult } from './db.model';
10
10
  import { getDB } from './getDB';
11
11
  import { CommonKeyValueDao, CommonKeyValueDaoCfg } from './kv/commonKeyValueDao';
12
12
  import { CommonKeyValueDB, KeyValueDBTuple } from './kv/commonKeyValueDB';
13
- import { createdUpdatedFields, createdUpdatedIdFields, deserializeJsonField, idField, serializeJsonField } from './model.util';
13
+ import { createdUpdatedFields, createdUpdatedIdFields, deserializeJsonField, serializeJsonField } from './model.util';
14
14
  import { dbPipelineBackup, DBPipelineBackupOptions } from './pipeline/dbPipelineBackup';
15
15
  import { dbPipelineCopy, DBPipelineCopyOptions } from './pipeline/dbPipelineCopy';
16
16
  import { dbPipelineRestore, DBPipelineRestoreOptions } from './pipeline/dbPipelineRestore';
17
17
  import { DBQuery, DBQueryFilter, DBQueryFilterOperator, dbQueryFilterOperatorValues, DBQueryOrder, RunnableDBQuery } from './query/dbQuery';
18
18
  import { DBTransaction, RunnableDBTransaction } from './transaction/dbTransaction';
19
19
  import { commitDBTransactionSimple, mergeDBOperations } from './transaction/dbTransaction.util';
20
- export type { DBQueryFilterOperator, DBQueryFilter, DBQueryOrder, CommonDaoCreateOptions, CommonDaoOptions, CommonDaoSaveOptions, CommonDaoStreamForEachOptions, CommonDaoStreamOptions, CommonDBOptions, CommonDBSaveOptions, CommonDBStreamOptions, CommonDBCreateOptions, CommonDB, RunQueryResult, CreatedUpdated, CreatedUpdatedId, AnyObjectWithId, ObjectWithId, CommonDaoCfg, CommonDaoCreateIdHook, CommonDaoParseNaturalIdHook, CommonDaoBeforeCreateHook, CommonDaoBeforeDBMValidateHook, CommonDaoBeforeDBMToBMHook, CommonDaoBeforeBMToDBMHook, CommonDaoBeforeTMToBMHook, CommonDaoBeforeBMToTMHook, CommonDaoAnonymizeHook, InMemoryDBCfg, InMemoryKeyValueDBCfg, DBPipelineBackupOptions, DBPipelineRestoreOptions, DBPipelineCopyOptions, CommonDBAdapter, DBOperation, DBSaveBatchOperation, DBDeleteByIdsOperation, CommonKeyValueDB, CommonKeyValueDaoCfg, KeyValueDBTuple, };
21
- export { DBQuery, dbQueryFilterOperatorValues, RunnableDBQuery, CommonDaoLogLevel, DBRelation, DBModelType, CommonDao, createdUpdatedFields, createdUpdatedIdFields, idField, InMemoryDB, InMemoryKeyValueDB, queryInMemory, serializeJsonField, deserializeJsonField, dbPipelineBackup, dbPipelineRestore, dbPipelineCopy, getDB, DBLibError, BaseCommonDB, DBTransaction, RunnableDBTransaction, mergeDBOperations, commitDBTransactionSimple, CommonKeyValueDao, };
20
+ export type { DBQueryFilterOperator, DBQueryFilter, DBQueryOrder, CommonDaoCreateOptions, CommonDaoOptions, CommonDaoSaveOptions, CommonDaoStreamForEachOptions, CommonDaoStreamOptions, CommonDBOptions, CommonDBSaveOptions, CommonDBStreamOptions, CommonDBCreateOptions, CommonDB, RunQueryResult, CommonDaoCfg, CommonDaoCreateIdHook, CommonDaoParseNaturalIdHook, CommonDaoBeforeCreateHook, CommonDaoBeforeDBMValidateHook, CommonDaoBeforeDBMToBMHook, CommonDaoBeforeBMToDBMHook, CommonDaoBeforeTMToBMHook, CommonDaoBeforeBMToTMHook, CommonDaoAnonymizeHook, InMemoryDBCfg, InMemoryKeyValueDBCfg, DBPipelineBackupOptions, DBPipelineRestoreOptions, DBPipelineCopyOptions, CommonDBAdapter, DBOperation, DBSaveBatchOperation, DBDeleteByIdsOperation, CommonKeyValueDB, CommonKeyValueDaoCfg, KeyValueDBTuple, };
21
+ export { DBQuery, dbQueryFilterOperatorValues, RunnableDBQuery, CommonDaoLogLevel, DBRelation, DBModelType, CommonDao, createdUpdatedFields, createdUpdatedIdFields, InMemoryDB, InMemoryKeyValueDB, queryInMemory, serializeJsonField, deserializeJsonField, dbPipelineBackup, dbPipelineRestore, dbPipelineCopy, getDB, DBLibError, BaseCommonDB, DBTransaction, RunnableDBTransaction, mergeDBOperations, commitDBTransactionSimple, CommonKeyValueDao, };