@naturalcycles/datastore-lib 3.31.0 → 3.31.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.
@@ -1,6 +1,6 @@
1
1
  import { Transaction } from '@google-cloud/datastore';
2
2
  import type { Datastore, Key, Query } from '@google-cloud/datastore';
3
- import { BaseCommonDB, CommonDB, CommonDBSupport, DBQuery, DBTransaction, RunQueryResult } from '@naturalcycles/db-lib';
3
+ import { BaseCommonDB, CommonDB, CommonDBOptions, CommonDBSaveOptions, CommonDBSupport, DBQuery, DBTransaction, DBTransactionFn, RunQueryResult } from '@naturalcycles/db-lib';
4
4
  import { ObjectWithId, JsonSchemaObject, JsonSchemaRootObject, CommonLogger } from '@naturalcycles/js-lib';
5
5
  import { ReadableTyped } from '@naturalcycles/nodejs-lib';
6
6
  import { DatastoreDBCfg, DatastoreDBOptions, DatastoreDBSaveOptions, DatastoreDBStreamOptions, DatastorePayload, DatastorePropertyStats, DatastoreStats } from './datastore.model';
@@ -22,7 +22,7 @@ export declare class DatastoreDB extends BaseCommonDB implements CommonDB {
22
22
  protected KEY: symbol;
23
23
  ds(): Datastore;
24
24
  ping(): Promise<void>;
25
- getByIds<ROW extends ObjectWithId>(table: string, ids: string[], _opt?: DatastoreDBOptions): Promise<ROW[]>;
25
+ getByIds<ROW extends ObjectWithId>(table: string, ids: string[], opt?: DatastoreDBOptions): Promise<ROW[]>;
26
26
  runQuery<ROW extends ObjectWithId>(dbQuery: DBQuery<ROW>, _opt?: DatastoreDBOptions): Promise<RunQueryResult<ROW>>;
27
27
  runQueryCount<ROW extends ObjectWithId>(dbQuery: DBQuery<ROW>, _opt?: DatastoreDBOptions): Promise<number>;
28
28
  runDatastoreQuery<ROW extends ObjectWithId>(q: Query): Promise<RunQueryResult<ROW>>;
@@ -38,7 +38,7 @@ export declare class DatastoreDB extends BaseCommonDB implements CommonDB {
38
38
  * regardless if they were actually deleted or not.
39
39
  */
40
40
  deleteByIds(table: string, ids: string[], opt?: DatastoreDBOptions): Promise<number>;
41
- createTransaction(): Promise<DatastoreDBTransaction>;
41
+ runInTransaction(fn: DBTransactionFn): Promise<void>;
42
42
  getAllStats(): Promise<DatastoreStats[]>;
43
43
  /**
44
44
  * Returns undefined e.g when Table is non-existing
@@ -66,6 +66,8 @@ export declare class DatastoreDBTransaction implements DBTransaction {
66
66
  tx: Transaction;
67
67
  private constructor();
68
68
  static create(db: DatastoreDB): Promise<DatastoreDBTransaction>;
69
- commit(): Promise<void>;
70
69
  rollback(): Promise<void>;
70
+ getByIds<ROW extends ObjectWithId>(table: string, ids: string[], opt?: CommonDBOptions | undefined): Promise<ROW[]>;
71
+ saveBatch<ROW extends Partial<ObjectWithId>>(table: string, rows: ROW[], opt?: CommonDBSaveOptions<ROW> | undefined): Promise<void>;
72
+ deleteByIds(table: string, ids: string[], opt?: CommonDBOptions | undefined): Promise<number>;
71
73
  }
@@ -69,7 +69,7 @@ class DatastoreDB extends db_lib_1.BaseCommonDB {
69
69
  async ping() {
70
70
  await this.getAllStats();
71
71
  }
72
- async getByIds(table, ids, _opt) {
72
+ async getByIds(table, ids, opt = {}) {
73
73
  if (!ids.length)
74
74
  return [];
75
75
  const keys = ids.map(id => this.key(table, id));
@@ -77,7 +77,7 @@ class DatastoreDB extends db_lib_1.BaseCommonDB {
77
77
  if (this.cfg.timeout) {
78
78
  // First try
79
79
  try {
80
- const r = await (0, js_lib_1.pTimeout)(() => this.ds().get(keys), {
80
+ const r = await (0, js_lib_1.pTimeout)(() => (opt.tx?.tx || this.ds()).get(keys), {
81
81
  timeout: this.cfg.timeout,
82
82
  name: `datastore.getByIds(${table})`,
83
83
  });
@@ -90,7 +90,7 @@ class DatastoreDB extends db_lib_1.BaseCommonDB {
90
90
  const DS = datastoreLib.Datastore;
91
91
  this.cachedDatastore = new DS(this.cfg);
92
92
  // Second try (will throw)
93
- const r = await (0, js_lib_1.pRetry)(() => this.ds().get(keys), {
93
+ const r = await (0, js_lib_1.pRetry)(() => (opt.tx?.tx || this.ds()).get(keys), {
94
94
  ...this.getPRetryOptions(`datastore.getByIds(${table}) second try`),
95
95
  maxAttempts: 3,
96
96
  timeout: this.cfg.timeout,
@@ -214,8 +214,16 @@ class DatastoreDB extends db_lib_1.BaseCommonDB {
214
214
  async (batch) => await (opt.tx?.tx || this.ds()).delete(batch));
215
215
  return ids.length;
216
216
  }
217
- async createTransaction() {
218
- return await DatastoreDBTransaction.create(this);
217
+ async runInTransaction(fn) {
218
+ const tx = await DatastoreDBTransaction.create(this);
219
+ try {
220
+ await fn(tx);
221
+ await tx.tx.commit();
222
+ }
223
+ catch (err) {
224
+ await tx.tx.rollback();
225
+ throw err;
226
+ }
219
227
  }
220
228
  async getAllStats() {
221
229
  const q = this.ds().createQuery('__Stat_Kind__');
@@ -384,11 +392,17 @@ class DatastoreDBTransaction {
384
392
  await tx.run();
385
393
  return new DatastoreDBTransaction(db, tx);
386
394
  }
387
- async commit() {
388
- await this.tx.commit();
389
- }
390
395
  async rollback() {
391
396
  await this.tx.rollback();
392
397
  }
398
+ async getByIds(table, ids, opt) {
399
+ return await this.db.getByIds(table, ids, { ...opt, tx: this });
400
+ }
401
+ async saveBatch(table, rows, opt) {
402
+ await this.db.saveBatch(table, rows, { ...opt, tx: this });
403
+ }
404
+ async deleteByIds(table, ids, opt) {
405
+ return await this.db.deleteByIds(table, ids, { ...opt, tx: this });
406
+ }
393
407
  }
394
408
  exports.DatastoreDBTransaction = DatastoreDBTransaction;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@naturalcycles/datastore-lib",
3
- "version": "3.31.0",
3
+ "version": "3.31.1",
4
4
  "description": "Opinionated library to work with Google Datastore",
5
5
  "scripts": {
6
6
  "prepare": "husky install"
@@ -5,10 +5,13 @@ import {
5
5
  BaseCommonDB,
6
6
  CommonDB,
7
7
  commonDBFullSupport,
8
+ CommonDBOptions,
8
9
  CommonDBSaveMethod,
10
+ CommonDBSaveOptions,
9
11
  CommonDBSupport,
10
12
  DBQuery,
11
13
  DBTransaction,
14
+ DBTransactionFn,
12
15
  RunQueryResult,
13
16
  } from '@naturalcycles/db-lib'
14
17
  import {
@@ -132,7 +135,7 @@ export class DatastoreDB extends BaseCommonDB implements CommonDB {
132
135
  override async getByIds<ROW extends ObjectWithId>(
133
136
  table: string,
134
137
  ids: string[],
135
- _opt?: DatastoreDBOptions,
138
+ opt: DatastoreDBOptions = {},
136
139
  ): Promise<ROW[]> {
137
140
  if (!ids.length) return []
138
141
  const keys = ids.map(id => this.key(table, id))
@@ -141,10 +144,13 @@ export class DatastoreDB extends BaseCommonDB implements CommonDB {
141
144
  if (this.cfg.timeout) {
142
145
  // First try
143
146
  try {
144
- const r = await pTimeout(() => this.ds().get(keys), {
145
- timeout: this.cfg.timeout,
146
- name: `datastore.getByIds(${table})`,
147
- })
147
+ const r = await pTimeout(
148
+ () => ((opt.tx as DatastoreDBTransaction)?.tx || this.ds()).get(keys),
149
+ {
150
+ timeout: this.cfg.timeout,
151
+ name: `datastore.getByIds(${table})`,
152
+ },
153
+ )
148
154
  rows = r[0]
149
155
  } catch {
150
156
  this.cfg.logger.log('datastore recreated on error')
@@ -155,15 +161,18 @@ export class DatastoreDB extends BaseCommonDB implements CommonDB {
155
161
  this.cachedDatastore = new DS(this.cfg)
156
162
 
157
163
  // Second try (will throw)
158
- const r = await pRetry(() => this.ds().get(keys), {
159
- ...this.getPRetryOptions(`datastore.getByIds(${table}) second try`),
160
- maxAttempts: 3,
161
- timeout: this.cfg.timeout,
162
- errorData: {
163
- // This error will be grouped ACROSS all endpoints and usages
164
- fingerprint: [DATASTORE_TIMEOUT],
164
+ const r = await pRetry(
165
+ () => ((opt.tx as DatastoreDBTransaction)?.tx || this.ds()).get(keys),
166
+ {
167
+ ...this.getPRetryOptions(`datastore.getByIds(${table}) second try`),
168
+ maxAttempts: 3,
169
+ timeout: this.cfg.timeout,
170
+ errorData: {
171
+ // This error will be grouped ACROSS all endpoints and usages
172
+ fingerprint: [DATASTORE_TIMEOUT],
173
+ },
165
174
  },
166
- })
175
+ )
167
176
  rows = r[0]
168
177
  }
169
178
  } else {
@@ -352,8 +361,16 @@ export class DatastoreDB extends BaseCommonDB implements CommonDB {
352
361
  return ids.length
353
362
  }
354
363
 
355
- override async createTransaction(): Promise<DatastoreDBTransaction> {
356
- return await DatastoreDBTransaction.create(this)
364
+ override async runInTransaction(fn: DBTransactionFn): Promise<void> {
365
+ const tx = await DatastoreDBTransaction.create(this)
366
+
367
+ try {
368
+ await fn(tx)
369
+ await tx.tx.commit()
370
+ } catch (err) {
371
+ await tx.tx.rollback()
372
+ throw err
373
+ }
357
374
  }
358
375
 
359
376
  async getAllStats(): Promise<DatastoreStats[]> {
@@ -543,10 +560,31 @@ export class DatastoreDBTransaction implements DBTransaction {
543
560
  return new DatastoreDBTransaction(db, tx)
544
561
  }
545
562
 
546
- async commit(): Promise<void> {
547
- await this.tx.commit()
548
- }
549
563
  async rollback(): Promise<void> {
550
564
  await this.tx.rollback()
551
565
  }
566
+
567
+ async getByIds<ROW extends ObjectWithId>(
568
+ table: string,
569
+ ids: string[],
570
+ opt?: CommonDBOptions | undefined,
571
+ ): Promise<ROW[]> {
572
+ return await this.db.getByIds(table, ids, { ...opt, tx: this })
573
+ }
574
+
575
+ async saveBatch<ROW extends Partial<ObjectWithId>>(
576
+ table: string,
577
+ rows: ROW[],
578
+ opt?: CommonDBSaveOptions<ROW> | undefined,
579
+ ): Promise<void> {
580
+ await this.db.saveBatch(table, rows, { ...opt, tx: this })
581
+ }
582
+
583
+ async deleteByIds(
584
+ table: string,
585
+ ids: string[],
586
+ opt?: CommonDBOptions | undefined,
587
+ ): Promise<number> {
588
+ return await this.db.deleteByIds(table, ids, { ...opt, tx: this })
589
+ }
552
590
  }