@naturalcycles/db-lib 8.48.1 → 8.49.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.
@@ -23,6 +23,7 @@ export declare class CacheDB extends BaseCommonDB implements CommonDB {
23
23
  getTables(): Promise<string[]>;
24
24
  getTableSchema<ROW extends ObjectWithId>(table: string): Promise<JsonSchemaRootObject<ROW>>;
25
25
  createTable<ROW extends ObjectWithId>(table: string, schema: JsonSchemaObject<ROW>, opt?: CacheDBCreateOptions): Promise<void>;
26
+ getByIds<ROW extends ObjectWithId>(table: string, ids: ROW['id'][], opt?: CacheDBSaveOptions<ROW>): Promise<ROW[]>;
26
27
  saveBatch<ROW extends Partial<ObjectWithId>>(table: string, rows: ROW[], opt?: CacheDBSaveOptions<ROW>): Promise<void>;
27
28
  runQuery<ROW extends ObjectWithId>(q: DBQuery<ROW>, opt?: CacheDBSaveOptions<ROW>): Promise<RunQueryResult<ROW>>;
28
29
  runQueryCount<ROW extends ObjectWithId>(q: DBQuery<ROW>, opt?: CacheDBOptions): Promise<number>;
@@ -42,6 +42,36 @@ class CacheDB extends base_common_db_1.BaseCommonDB {
42
42
  await this.cfg.cacheDB.createTable(table, schema, opt);
43
43
  }
44
44
  }
45
+ async getByIds(table, ids, opt = {}) {
46
+ const resultMap = {};
47
+ const missingIds = [];
48
+ if (!opt.skipCache && !this.cfg.skipCache) {
49
+ const results = await this.cfg.cacheDB.getByIds(table, ids, opt);
50
+ results.forEach(r => (resultMap[r.id] = r));
51
+ missingIds.push(...ids.filter(id => !resultMap[id]));
52
+ if (this.cfg.logCached) {
53
+ this.cfg.logger?.log(`${table}.getByIds ${results.length} rows from cache: [${results
54
+ .map(r => r.id)
55
+ .join(', ')}]`);
56
+ }
57
+ }
58
+ if (missingIds.length && !opt.onlyCache && !this.cfg.onlyCache) {
59
+ const results = await this.cfg.downstreamDB.getByIds(table, missingIds, opt);
60
+ results.forEach(r => (resultMap[r.id] = r));
61
+ if (this.cfg.logDownstream) {
62
+ this.cfg.logger?.log(`${table}.getByIds ${results.length} rows from downstream: [${results
63
+ .map(r => r.id)
64
+ .join(', ')}]`);
65
+ }
66
+ if (!opt.skipCache) {
67
+ const cacheResult = this.cfg.cacheDB.saveBatch(table, results, opt);
68
+ if (this.cfg.awaitCache)
69
+ await cacheResult;
70
+ }
71
+ }
72
+ // return in right order
73
+ return ids.map(id => resultMap[id]).filter(Boolean);
74
+ }
45
75
  async saveBatch(table, rows, opt = {}) {
46
76
  if (!opt.onlyCache && !this.cfg.onlyCache) {
47
77
  await this.cfg.downstreamDB.saveBatch(table, rows, opt);
@@ -21,6 +21,7 @@ export declare class FileDB extends BaseCommonDB implements CommonDB {
21
21
  cfg: FileDBCfg;
22
22
  ping(): Promise<void>;
23
23
  getTables(): Promise<string[]>;
24
+ getByIds<ROW extends ObjectWithId>(table: string, ids: ROW['id'][], _opt?: CommonDBOptions): Promise<ROW[]>;
24
25
  saveBatch<ROW extends Partial<ObjectWithId>>(table: string, rows: ROW[], _opt?: CommonDBSaveOptions<ROW>): Promise<void>;
25
26
  /**
26
27
  * Implementation is optimized for loading/saving _whole files_.
@@ -34,6 +34,10 @@ class FileDB extends __1.BaseCommonDB {
34
34
  this.logFinished(started, `getTables() ${tables.length} tables`);
35
35
  return tables;
36
36
  }
37
+ async getByIds(table, ids, _opt) {
38
+ const byId = (0, js_lib_1._by)(await this.loadFile(table), r => r.id);
39
+ return ids.map(id => byId[id]).filter(Boolean);
40
+ }
37
41
  async saveBatch(table, rows, _opt) {
38
42
  if (!rows.length)
39
43
  return; // save some api calls
@@ -52,6 +52,7 @@ export declare class InMemoryDB implements CommonDB {
52
52
  getTables(): Promise<string[]>;
53
53
  getTableSchema<ROW extends ObjectWithId>(_table: string): Promise<JsonSchemaRootObject<ROW>>;
54
54
  createTable<ROW extends ObjectWithId>(_table: string, _schema: JsonSchemaObject<ROW>, opt?: CommonDBCreateOptions): Promise<void>;
55
+ getByIds<ROW extends ObjectWithId>(_table: string, ids: ROW['id'][], _opt?: CommonDBOptions): Promise<ROW[]>;
55
56
  saveBatch<ROW extends Partial<ObjectWithId>>(_table: string, rows: ROW[], opt?: CommonDBSaveOptions<ROW>): Promise<void>;
56
57
  deleteByQuery<ROW extends ObjectWithId>(q: DBQuery<ROW>, _opt?: CommonDBOptions): Promise<number>;
57
58
  updateByQuery<ROW extends ObjectWithId>(q: DBQuery<ROW>, patch: DBPatch<ROW>): Promise<number>;
@@ -67,6 +67,11 @@ class InMemoryDB {
67
67
  this.data[table] ||= {};
68
68
  }
69
69
  }
70
+ async getByIds(_table, ids, _opt) {
71
+ const table = this.cfg.tablesPrefix + _table;
72
+ this.data[table] ||= {};
73
+ return ids.map(id => this.data[table][id]).filter(Boolean);
74
+ }
70
75
  async saveBatch(_table, rows, opt = {}) {
71
76
  const table = this.cfg.tablesPrefix + _table;
72
77
  this.data[table] ||= {};
@@ -13,6 +13,7 @@ export declare class BaseCommonDB implements CommonDB {
13
13
  getTables(): Promise<string[]>;
14
14
  getTableSchema<ROW extends ObjectWithId>(table: string): Promise<JsonSchemaRootObject<ROW>>;
15
15
  createTable<ROW extends ObjectWithId>(table: string, schema: JsonSchemaObject<ROW>): Promise<void>;
16
+ getByIds<ROW extends ObjectWithId>(table: string, ids: ROW['id'][]): Promise<ROW[]>;
16
17
  deleteByQuery<ROW extends ObjectWithId>(q: DBQuery<ROW>): Promise<number>;
17
18
  updateByQuery<ROW extends ObjectWithId>(q: DBQuery<ROW>, patch: DBPatch<ROW>, opt?: CommonDBOptions): Promise<number>;
18
19
  runQuery<ROW extends ObjectWithId>(q: DBQuery<ROW>): Promise<RunQueryResult<ROW>>;
@@ -19,6 +19,9 @@ class BaseCommonDB {
19
19
  async createTable(table, schema) {
20
20
  // no-op
21
21
  }
22
+ async getByIds(table, ids) {
23
+ throw new Error('getByIds is not implemented');
24
+ }
22
25
  async deleteByQuery(q) {
23
26
  throw new Error('deleteByQuery is not implemented');
24
27
  }
@@ -27,6 +27,11 @@ export interface CommonDB {
27
27
  * Caution! dropIfExists defaults to false. If set to true - will actually DROP the table!
28
28
  */
29
29
  createTable<ROW extends ObjectWithId>(table: string, schema: JsonSchemaObject<ROW>, opt?: CommonDBCreateOptions): Promise<void>;
30
+ /**
31
+ * Order of items returned is not guaranteed to match order of ids.
32
+ * (Such limitation exists because Datastore doesn't support it).
33
+ */
34
+ getByIds<ROW extends ObjectWithId>(table: string, ids: ROW['id'][], opt?: CommonDBOptions): Promise<ROW[]>;
30
35
  /**
31
36
  * Order by 'id' is not supported by all implementations (for example, Datastore doesn't support it).
32
37
  */
@@ -8,7 +8,6 @@ const db_model_1 = require("../db.model");
8
8
  const dbQuery_1 = require("../query/dbQuery");
9
9
  const dbTransaction_1 = require("../transaction/dbTransaction");
10
10
  const common_dao_model_1 = require("./common.dao.model");
11
- /* eslint-disable no-dupe-class-members */
12
11
  const isGAE = !!process.env['GAE_INSTANCE'];
13
12
  const isCI = !!process.env['CI'];
14
13
  /**
@@ -113,14 +112,14 @@ class CommonDao {
113
112
  if (opt.timeout) {
114
113
  // todo: possibly remove it after debugging is done
115
114
  dbm = await (0, js_lib_1.pTimeout)(async () => {
116
- return (await this.cfg.db.runQuery(dbQuery_1.DBQuery.create(table).filterEq('id', id))).rows[0];
115
+ return (await this.cfg.db.getByIds(table, [id]))[0];
117
116
  }, {
118
117
  timeout: opt.timeout,
119
118
  name: `getById(${table})`,
120
119
  });
121
120
  }
122
121
  else {
123
- dbm = (await this.cfg.db.runQuery(dbQuery_1.DBQuery.create(table).filterEq('id', id))).rows[0];
122
+ dbm = (await this.cfg.db.getByIds(table, [id]))[0];
124
123
  }
125
124
  const bm = opt.raw ? dbm : await this.dbmToBM(dbm, opt);
126
125
  this.logResult(started, op, bm, table);
@@ -145,7 +144,7 @@ class CommonDao {
145
144
  const op = `getByIdAsDBM(${id})`;
146
145
  const table = opt.table || this.cfg.table;
147
146
  const started = this.logStarted(op, table);
148
- let [dbm] = (await this.cfg.db.runQuery(dbQuery_1.DBQuery.create(table).filterEq('id', id))).rows;
147
+ let [dbm] = await this.cfg.db.getByIds(table, [id]);
149
148
  if (!opt.raw) {
150
149
  dbm = this.anyToDBM(dbm, opt);
151
150
  }
@@ -158,7 +157,7 @@ class CommonDao {
158
157
  const op = `getByIdAsTM(${id})`;
159
158
  const table = opt.table || this.cfg.table;
160
159
  const started = this.logStarted(op, table);
161
- const [dbm] = (await this.cfg.db.runQuery(dbQuery_1.DBQuery.create(table).filterEq('id', id))).rows;
160
+ const [dbm] = await this.cfg.db.getByIds(table, [id]);
162
161
  if (opt.raw) {
163
162
  this.logResult(started, op, dbm, table);
164
163
  return dbm || null;
@@ -172,7 +171,7 @@ class CommonDao {
172
171
  const op = `getByIds ${ids.length} id(s) (${(0, js_lib_1._truncate)(ids.slice(0, 10).join(', '), 50)})`;
173
172
  const table = opt.table || this.cfg.table;
174
173
  const started = this.logStarted(op, table);
175
- const dbms = (await this.cfg.db.runQuery(dbQuery_1.DBQuery.create(table).filterIn('id', ids))).rows;
174
+ const dbms = await this.cfg.db.getByIds(table, ids);
176
175
  const bms = opt.raw ? dbms : await this.dbmsToBM(dbms, opt);
177
176
  this.logResult(started, op, bms, table);
178
177
  return bms;
@@ -181,7 +180,7 @@ class CommonDao {
181
180
  const op = `getByIdsAsDBM ${ids.length} id(s) (${(0, js_lib_1._truncate)(ids.slice(0, 10).join(', '), 50)})`;
182
181
  const table = opt.table || this.cfg.table;
183
182
  const started = this.logStarted(op, table);
184
- const dbms = (await this.cfg.db.runQuery(dbQuery_1.DBQuery.create(table).filterIn('id', ids))).rows;
183
+ const dbms = await this.cfg.db.getByIds(table, ids);
185
184
  this.logResult(started, op, dbms, table);
186
185
  return dbms;
187
186
  }
@@ -231,8 +230,7 @@ class CommonDao {
231
230
  }
232
231
  async ensureUniqueId(table, dbm) {
233
232
  // todo: retry N times
234
- const existing = (await this.cfg.db.runQuery(dbQuery_1.DBQuery.create(table).filterEq('id', dbm.id)))
235
- .rows;
233
+ const existing = await this.cfg.db.getByIds(table, [dbm.id]);
236
234
  if (existing.length) {
237
235
  throw new js_lib_1.AppError(cnst_1.DBLibError.NON_UNIQUE_ID, {
238
236
  table,
@@ -49,15 +49,15 @@ function runCommonDBTest(db, features = {}, quirks = {}) {
49
49
  }
50
50
  // GET empty
51
51
  test('getByIds(item1.id) should return empty', async () => {
52
- const [item1Loaded] = (await db.runQuery(queryAll().filterEq('id', item1.id))).rows;
52
+ const [item1Loaded] = await db.getByIds(test_model_1.TEST_TABLE, [item1.id]);
53
53
  // console.log(a)
54
54
  expect(item1Loaded).toBeUndefined();
55
55
  });
56
56
  test('getByIds([]) should return []', async () => {
57
- expect((await db.runQuery(queryAll().filterIn('id', []))).rows).toEqual([]);
57
+ expect(await db.getByIds(test_model_1.TEST_TABLE, [])).toEqual([]);
58
58
  });
59
59
  test('getByIds(...) should return empty', async () => {
60
- expect((await db.runQuery(queryAll().filterIn('id', ['abc', 'abcd']))).rows).toEqual([]);
60
+ expect(await db.getByIds(test_model_1.TEST_TABLE, ['abc', 'abcd'])).toEqual([]);
61
61
  });
62
62
  // SAVE
63
63
  if (nullValues) {
@@ -68,7 +68,7 @@ function runCommonDBTest(db, features = {}, quirks = {}) {
68
68
  };
69
69
  (0, test_util_1.deepFreeze)(item3);
70
70
  await db.saveBatch(test_model_1.TEST_TABLE, [item3]);
71
- const item3Loaded = (await db.runQuery(queryAll().filterEq('id', item3.id))).rows[0];
71
+ const item3Loaded = (await db.getByIds(test_model_1.TEST_TABLE, [item3.id]))[0];
72
72
  expectMatch([item3], [item3Loaded], quirks);
73
73
  expect(item3Loaded.k2).toBeNull();
74
74
  });
@@ -83,7 +83,7 @@ function runCommonDBTest(db, features = {}, quirks = {}) {
83
83
  const expected = { ...item3 };
84
84
  delete expected.k2;
85
85
  await db.saveBatch(test_model_1.TEST_TABLE, [item3]);
86
- const item3Loaded = (await db.runQuery(queryAll().filterEq('id', item3.id))).rows[0];
86
+ const item3Loaded = (await db.getByIds(test_model_1.TEST_TABLE, [item3.id]))[0];
87
87
  expectMatch([expected], [item3Loaded], quirks);
88
88
  expect(item3Loaded.k2).toBeUndefined();
89
89
  expect(Object.keys(item3Loaded)).not.toContain('k2');
@@ -112,8 +112,7 @@ function runCommonDBTest(db, features = {}, quirks = {}) {
112
112
  }
113
113
  // GET not empty
114
114
  test('getByIds all items', async () => {
115
- const rows = (await db.runQuery(queryAll().filterIn('id', items.map(i => i.id).concat('abcd'))))
116
- .rows;
115
+ const rows = await db.getByIds(test_model_1.TEST_TABLE, items.map(i => i.id).concat('abcd'));
117
116
  expectMatch(items, (0, js_lib_1._sortBy)(rows, r => r.id), quirks);
118
117
  });
119
118
  // QUERY
@@ -205,7 +204,7 @@ function runCommonDBTest(db, features = {}, quirks = {}) {
205
204
  b1,
206
205
  };
207
206
  await db.saveBatch(test_model_1.TEST_TABLE, [item]);
208
- const loaded = (await db.runQuery(queryAll().filterEq('id', item.id))).rows[0];
207
+ const loaded = (await db.getByIds(test_model_1.TEST_TABLE, [item.id]))[0];
209
208
  const b1Loaded = loaded.b1;
210
209
  // console.log({
211
210
  // b11: typeof b1,
package/package.json CHANGED
@@ -41,7 +41,7 @@
41
41
  "engines": {
42
42
  "node": ">=14.15"
43
43
  },
44
- "version": "8.48.1",
44
+ "version": "8.49.0",
45
45
  "description": "Lowest Common Denominator API to supported Databases",
46
46
  "keywords": [
47
47
  "db",
@@ -1,5 +1,10 @@
1
1
  import { Readable } from 'node:stream'
2
- import { JsonSchemaObject, JsonSchemaRootObject, ObjectWithId } from '@naturalcycles/js-lib'
2
+ import {
3
+ JsonSchemaObject,
4
+ JsonSchemaRootObject,
5
+ ObjectWithId,
6
+ StringMap,
7
+ } from '@naturalcycles/js-lib'
3
8
  import { BaseCommonDB } from '../../base.common.db'
4
9
  import { CommonDB } from '../../common.db'
5
10
  import { CommonDBOptions, DBPatch, RunQueryResult } from '../../db.model'
@@ -67,6 +72,52 @@ export class CacheDB extends BaseCommonDB implements CommonDB {
67
72
  }
68
73
  }
69
74
 
75
+ override async getByIds<ROW extends ObjectWithId>(
76
+ table: string,
77
+ ids: ROW['id'][],
78
+ opt: CacheDBSaveOptions<ROW> = {},
79
+ ): Promise<ROW[]> {
80
+ const resultMap: StringMap<ROW> = {}
81
+ const missingIds: ROW['id'][] = []
82
+
83
+ if (!opt.skipCache && !this.cfg.skipCache) {
84
+ const results = await this.cfg.cacheDB.getByIds<ROW>(table, ids, opt)
85
+
86
+ results.forEach(r => (resultMap[r.id] = r))
87
+
88
+ missingIds.push(...ids.filter(id => !resultMap[id]))
89
+
90
+ if (this.cfg.logCached) {
91
+ this.cfg.logger?.log(
92
+ `${table}.getByIds ${results.length} rows from cache: [${results
93
+ .map(r => r.id)
94
+ .join(', ')}]`,
95
+ )
96
+ }
97
+ }
98
+
99
+ if (missingIds.length && !opt.onlyCache && !this.cfg.onlyCache) {
100
+ const results = await this.cfg.downstreamDB.getByIds<ROW>(table, missingIds, opt)
101
+ results.forEach(r => (resultMap[r.id] = r))
102
+
103
+ if (this.cfg.logDownstream) {
104
+ this.cfg.logger?.log(
105
+ `${table}.getByIds ${results.length} rows from downstream: [${results
106
+ .map(r => r.id)
107
+ .join(', ')}]`,
108
+ )
109
+ }
110
+
111
+ if (!opt.skipCache) {
112
+ const cacheResult = this.cfg.cacheDB.saveBatch(table, results, opt)
113
+ if (this.cfg.awaitCache) await cacheResult
114
+ }
115
+ }
116
+
117
+ // return in right order
118
+ return ids.map(id => resultMap[id]!).filter(Boolean)
119
+ }
120
+
70
121
  override async saveBatch<ROW extends Partial<ObjectWithId>>(
71
122
  table: string,
72
123
  rows: ROW[],
@@ -65,6 +65,15 @@ export class FileDB extends BaseCommonDB implements CommonDB {
65
65
  return tables
66
66
  }
67
67
 
68
+ override async getByIds<ROW extends ObjectWithId>(
69
+ table: string,
70
+ ids: ROW['id'][],
71
+ _opt?: CommonDBOptions,
72
+ ): Promise<ROW[]> {
73
+ const byId = _by(await this.loadFile<ROW>(table), r => r.id)
74
+ return ids.map(id => byId[id]!).filter(Boolean)
75
+ }
76
+
68
77
  override async saveBatch<ROW extends Partial<ObjectWithId>>(
69
78
  table: string,
70
79
  rows: ROW[],
@@ -143,6 +143,16 @@ export class InMemoryDB implements CommonDB {
143
143
  }
144
144
  }
145
145
 
146
+ async getByIds<ROW extends ObjectWithId>(
147
+ _table: string,
148
+ ids: ROW['id'][],
149
+ _opt?: CommonDBOptions,
150
+ ): Promise<ROW[]> {
151
+ const table = this.cfg.tablesPrefix + _table
152
+ this.data[table] ||= {}
153
+ return ids.map(id => this.data[table]![id] as ROW).filter(Boolean)
154
+ }
155
+
146
156
  async saveBatch<ROW extends Partial<ObjectWithId>>(
147
157
  _table: string,
148
158
  rows: ROW[],
@@ -33,6 +33,10 @@ export class BaseCommonDB implements CommonDB {
33
33
  // no-op
34
34
  }
35
35
 
36
+ async getByIds<ROW extends ObjectWithId>(table: string, ids: ROW['id'][]): Promise<ROW[]> {
37
+ throw new Error('getByIds is not implemented')
38
+ }
39
+
36
40
  async deleteByQuery<ROW extends ObjectWithId>(q: DBQuery<ROW>): Promise<number> {
37
41
  throw new Error('deleteByQuery is not implemented')
38
42
  }
package/src/common.db.ts CHANGED
@@ -43,6 +43,17 @@ export interface CommonDB {
43
43
  opt?: CommonDBCreateOptions,
44
44
  ): Promise<void>
45
45
 
46
+ // GET
47
+ /**
48
+ * Order of items returned is not guaranteed to match order of ids.
49
+ * (Such limitation exists because Datastore doesn't support it).
50
+ */
51
+ getByIds<ROW extends ObjectWithId>(
52
+ table: string,
53
+ ids: ROW['id'][],
54
+ opt?: CommonDBOptions,
55
+ ): Promise<ROW[]>
56
+
46
57
  // QUERY
47
58
  /**
48
59
  * Order by 'id' is not supported by all implementations (for example, Datastore doesn't support it).
@@ -56,8 +56,6 @@ import {
56
56
  CommonDaoStreamOptions,
57
57
  } from './common.dao.model'
58
58
 
59
- /* eslint-disable no-dupe-class-members */
60
-
61
59
  const isGAE = !!process.env['GAE_INSTANCE']
62
60
  const isCI = !!process.env['CI']
63
61
 
@@ -136,7 +134,7 @@ export class CommonDao<
136
134
  // todo: possibly remove it after debugging is done
137
135
  dbm = await pTimeout(
138
136
  async () => {
139
- return (await this.cfg.db.runQuery(DBQuery.create<DBM>(table).filterEq('id', id))).rows[0]
137
+ return (await this.cfg.db.getByIds<DBM>(table, [id]))[0]
140
138
  },
141
139
  {
142
140
  timeout: opt.timeout,
@@ -144,7 +142,7 @@ export class CommonDao<
144
142
  },
145
143
  )
146
144
  } else {
147
- dbm = (await this.cfg.db.runQuery(DBQuery.create<DBM>(table).filterEq('id', id))).rows[0]
145
+ dbm = (await this.cfg.db.getByIds<DBM>(table, [id]))[0]
148
146
  }
149
147
 
150
148
  const bm = opt.raw ? (dbm as any) : await this.dbmToBM(dbm, opt)
@@ -174,7 +172,7 @@ export class CommonDao<
174
172
  const op = `getByIdAsDBM(${id})`
175
173
  const table = opt.table || this.cfg.table
176
174
  const started = this.logStarted(op, table)
177
- let [dbm] = (await this.cfg.db.runQuery(DBQuery.create<DBM>(table).filterEq('id', id))).rows
175
+ let [dbm] = await this.cfg.db.getByIds<DBM>(table, [id])
178
176
  if (!opt.raw) {
179
177
  dbm = this.anyToDBM(dbm!, opt)
180
178
  }
@@ -189,7 +187,7 @@ export class CommonDao<
189
187
  const op = `getByIdAsTM(${id})`
190
188
  const table = opt.table || this.cfg.table
191
189
  const started = this.logStarted(op, table)
192
- const [dbm] = (await this.cfg.db.runQuery(DBQuery.create<DBM>(table).filterEq('id', id))).rows
190
+ const [dbm] = await this.cfg.db.getByIds<DBM>(table, [id])
193
191
  if (opt.raw) {
194
192
  this.logResult(started, op, dbm, table)
195
193
  return (dbm as any) || null
@@ -204,7 +202,7 @@ export class CommonDao<
204
202
  const op = `getByIds ${ids.length} id(s) (${_truncate(ids.slice(0, 10).join(', '), 50)})`
205
203
  const table = opt.table || this.cfg.table
206
204
  const started = this.logStarted(op, table)
207
- const dbms = (await this.cfg.db.runQuery(DBQuery.create<DBM>(table).filterIn('id', ids))).rows
205
+ const dbms = await this.cfg.db.getByIds<DBM>(table, ids)
208
206
  const bms = opt.raw ? (dbms as any) : await this.dbmsToBM(dbms, opt)
209
207
  this.logResult(started, op, bms, table)
210
208
  return bms
@@ -214,7 +212,7 @@ export class CommonDao<
214
212
  const op = `getByIdsAsDBM ${ids.length} id(s) (${_truncate(ids.slice(0, 10).join(', '), 50)})`
215
213
  const table = opt.table || this.cfg.table
216
214
  const started = this.logStarted(op, table)
217
- const dbms = (await this.cfg.db.runQuery(DBQuery.create<DBM>(table).filterIn('id', ids))).rows
215
+ const dbms = await this.cfg.db.getByIds<DBM>(table, ids)
218
216
  this.logResult(started, op, dbms, table)
219
217
  return dbms
220
218
  }
@@ -270,8 +268,7 @@ export class CommonDao<
270
268
 
271
269
  private async ensureUniqueId(table: string, dbm: DBM): Promise<void> {
272
270
  // todo: retry N times
273
- const existing = (await this.cfg.db.runQuery(DBQuery.create<DBM>(table).filterEq('id', dbm.id)))
274
- .rows
271
+ const existing = await this.cfg.db.getByIds<DBM>(table, [dbm.id])
275
272
  if (existing.length) {
276
273
  throw new AppError(DBLibError.NON_UNIQUE_ID, {
277
274
  table,
@@ -147,17 +147,17 @@ export function runCommonDBTest(
147
147
 
148
148
  // GET empty
149
149
  test('getByIds(item1.id) should return empty', async () => {
150
- const [item1Loaded] = (await db.runQuery(queryAll().filterEq('id', item1.id))).rows
150
+ const [item1Loaded] = await db.getByIds(TEST_TABLE, [item1.id])
151
151
  // console.log(a)
152
152
  expect(item1Loaded).toBeUndefined()
153
153
  })
154
154
 
155
155
  test('getByIds([]) should return []', async () => {
156
- expect((await db.runQuery(queryAll().filterIn('id', []))).rows).toEqual([])
156
+ expect(await db.getByIds(TEST_TABLE, [])).toEqual([])
157
157
  })
158
158
 
159
159
  test('getByIds(...) should return empty', async () => {
160
- expect((await db.runQuery(queryAll().filterIn('id', ['abc', 'abcd']))).rows).toEqual([])
160
+ expect(await db.getByIds(TEST_TABLE, ['abc', 'abcd'])).toEqual([])
161
161
  })
162
162
 
163
163
  // SAVE
@@ -169,7 +169,7 @@ export function runCommonDBTest(
169
169
  }
170
170
  deepFreeze(item3)
171
171
  await db.saveBatch(TEST_TABLE, [item3])
172
- const item3Loaded = (await db.runQuery(queryAll().filterEq('id', item3.id))).rows[0]!
172
+ const item3Loaded = (await db.getByIds<TestItemDBM>(TEST_TABLE, [item3.id]))[0]!
173
173
  expectMatch([item3], [item3Loaded], quirks)
174
174
  expect(item3Loaded.k2).toBeNull()
175
175
  })
@@ -186,7 +186,7 @@ export function runCommonDBTest(
186
186
  delete expected.k2
187
187
 
188
188
  await db.saveBatch(TEST_TABLE, [item3])
189
- const item3Loaded = (await db.runQuery(queryAll().filterEq('id', item3.id))).rows[0]!
189
+ const item3Loaded = (await db.getByIds<TestItemDBM>(TEST_TABLE, [item3.id]))[0]!
190
190
  expectMatch([expected], [item3Loaded], quirks)
191
191
  expect(item3Loaded.k2).toBeUndefined()
192
192
  expect(Object.keys(item3Loaded)).not.toContain('k2')
@@ -221,8 +221,7 @@ export function runCommonDBTest(
221
221
 
222
222
  // GET not empty
223
223
  test('getByIds all items', async () => {
224
- const rows = (await db.runQuery(queryAll().filterIn('id', items.map(i => i.id).concat('abcd'))))
225
- .rows
224
+ const rows = await db.getByIds<TestItemDBM>(TEST_TABLE, items.map(i => i.id).concat('abcd'))
226
225
  expectMatch(
227
226
  items,
228
227
  _sortBy(rows, r => r.id),
@@ -347,7 +346,7 @@ export function runCommonDBTest(
347
346
  b1,
348
347
  }
349
348
  await db.saveBatch(TEST_TABLE, [item])
350
- const loaded = (await db.runQuery(queryAll().filterEq('id', item.id))).rows[0]!
349
+ const loaded = (await db.getByIds<TestItemDBM>(TEST_TABLE, [item.id]))[0]!
351
350
  const b1Loaded = loaded.b1!
352
351
  // console.log({
353
352
  // b11: typeof b1,