@naturalcycles/datastore-lib 4.18.3 → 4.18.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/datastore.db.d.ts +0 -1
- package/dist/datastore.db.js +7 -20
- package/dist/datastoreStreamReadable.js +2 -5
- package/dist/query.util.d.ts +3 -0
- package/dist/query.util.js +13 -0
- package/package.json +1 -1
- package/src/datastore.db.ts +7 -22
- package/src/datastoreStreamReadable.ts +2 -6
- package/src/query.util.ts +17 -0
package/dist/datastore.db.d.ts
CHANGED
|
@@ -66,7 +66,6 @@ export declare class DatastoreDB extends BaseCommonDB implements CommonDB {
|
|
|
66
66
|
* It may happen that transaction is already committed/rolled back, so we don't want to throw an error here.
|
|
67
67
|
*/
|
|
68
68
|
private rollback;
|
|
69
|
-
private getRunQueryOptions;
|
|
70
69
|
}
|
|
71
70
|
/**
|
|
72
71
|
* https://cloud.google.com/datastore/docs/concepts/transactions#datastore-datastore-transactional-update-nodejs
|
package/dist/datastore.db.js
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import { Datastore, PropertyFilter } from '@google-cloud/datastore';
|
|
2
2
|
import { BaseCommonDB, commonDBFullSupport } from '@naturalcycles/db-lib';
|
|
3
|
-
import { _round } from '@naturalcycles/js-lib';
|
|
4
3
|
import { _chunk } from '@naturalcycles/js-lib/array/array.util.js';
|
|
5
4
|
import { _ms } from '@naturalcycles/js-lib/datetime/time.util.js';
|
|
6
5
|
import { _assert } from '@naturalcycles/js-lib/error/assert.js';
|
|
@@ -14,7 +13,7 @@ import { boldWhite } from '@naturalcycles/nodejs-lib/colors';
|
|
|
14
13
|
import { Pipeline } from '@naturalcycles/nodejs-lib/stream';
|
|
15
14
|
import { DatastoreType } from './datastore.model.js';
|
|
16
15
|
import { DatastoreStreamReadable } from './datastoreStreamReadable.js';
|
|
17
|
-
import { dbQueryToDatastoreQuery } from './query.util.js';
|
|
16
|
+
import { dbQueryToDatastoreQuery, getRunQueryOptions } from './query.util.js';
|
|
18
17
|
// Datastore (also Firestore and other Google APIs) supports max 500 of items when saving/deleting, etc.
|
|
19
18
|
const MAX_ITEMS = 500;
|
|
20
19
|
// It's an empyrical value, but anything less than infinity is better than infinity
|
|
@@ -90,7 +89,7 @@ export class DatastoreDB extends BaseCommonDB {
|
|
|
90
89
|
let ds = this.ds();
|
|
91
90
|
const keys = ids.map(id => this.key(ds, table, id));
|
|
92
91
|
let rows;
|
|
93
|
-
const dsOpt =
|
|
92
|
+
const dsOpt = getRunQueryOptions(opt);
|
|
94
93
|
if (this.cfg.timeout) {
|
|
95
94
|
// First try
|
|
96
95
|
try {
|
|
@@ -141,7 +140,7 @@ export class DatastoreDB extends BaseCommonDB {
|
|
|
141
140
|
async multiGet(map, opt = {}) {
|
|
142
141
|
const result = {};
|
|
143
142
|
const ds = this.ds();
|
|
144
|
-
const dsOpt =
|
|
143
|
+
const dsOpt = getRunQueryOptions(opt);
|
|
145
144
|
const keys = [];
|
|
146
145
|
for (const [table, ids] of _stringMapEntries(map)) {
|
|
147
146
|
result[table] = [];
|
|
@@ -174,7 +173,7 @@ export class DatastoreDB extends BaseCommonDB {
|
|
|
174
173
|
}
|
|
175
174
|
const ds = this.ds();
|
|
176
175
|
const q = dbQueryToDatastoreQuery(dbQuery, ds.createQuery(dbQuery.table));
|
|
177
|
-
const dsOpt =
|
|
176
|
+
const dsOpt = getRunQueryOptions(opt);
|
|
178
177
|
const qr = await this.runDatastoreQuery(q, dsOpt);
|
|
179
178
|
// Special case when projection query didn't specify 'id'
|
|
180
179
|
if (dbQuery._selectedFieldNames && !dbQuery._selectedFieldNames.includes('id')) {
|
|
@@ -186,7 +185,7 @@ export class DatastoreDB extends BaseCommonDB {
|
|
|
186
185
|
const ds = this.ds();
|
|
187
186
|
const q = dbQueryToDatastoreQuery(dbQuery, ds.createQuery(dbQuery.table));
|
|
188
187
|
const aq = ds.createAggregationQuery(q).count('count');
|
|
189
|
-
const dsOpt =
|
|
188
|
+
const dsOpt = getRunQueryOptions(opt);
|
|
190
189
|
const [entities] = await ds.runAggregationQuery(aq, dsOpt);
|
|
191
190
|
return entities[0]?.count;
|
|
192
191
|
}
|
|
@@ -209,7 +208,7 @@ export class DatastoreDB extends BaseCommonDB {
|
|
|
209
208
|
};
|
|
210
209
|
const readable = opt.experimentalCursorStream
|
|
211
210
|
? new DatastoreStreamReadable(q, opt)
|
|
212
|
-
: ds.runQueryStream(q,
|
|
211
|
+
: ds.runQueryStream(q, getRunQueryOptions(opt));
|
|
213
212
|
return Pipeline.from(readable).mapSync(r => this.mapId(r));
|
|
214
213
|
}
|
|
215
214
|
// https://github.com/GoogleCloudPlatform/nodejs-getting-started/blob/master/2-structured-data/books/model-datastore.js
|
|
@@ -255,7 +254,7 @@ export class DatastoreDB extends BaseCommonDB {
|
|
|
255
254
|
}
|
|
256
255
|
const ds = this.ds();
|
|
257
256
|
const datastoreQuery = dbQueryToDatastoreQuery(q.select([]), ds.createQuery(q.table));
|
|
258
|
-
const dsOpt =
|
|
257
|
+
const dsOpt = getRunQueryOptions(opt);
|
|
259
258
|
const { rows } = await this.runDatastoreQuery(datastoreQuery, dsOpt);
|
|
260
259
|
return await this.deleteByIds(q.table, rows.map(obj => obj.id), opt);
|
|
261
260
|
}
|
|
@@ -500,18 +499,6 @@ export class DatastoreDB extends BaseCommonDB {
|
|
|
500
499
|
this.cfg.logger.error(err);
|
|
501
500
|
}
|
|
502
501
|
}
|
|
503
|
-
getRunQueryOptions(opt) {
|
|
504
|
-
if (!opt.readAt)
|
|
505
|
-
return {};
|
|
506
|
-
// Datastore expects UnixTimestamp in milliseconds
|
|
507
|
-
// Datastore requires the timestamp to be rounded to the whole minutes
|
|
508
|
-
const readTime = _round(opt.readAt, 60) * 1000;
|
|
509
|
-
if (readTime >= Date.now() - 1000) {
|
|
510
|
-
// To avoid the error of: The requested 'read_time' cannot be in the future
|
|
511
|
-
return {};
|
|
512
|
-
}
|
|
513
|
-
return { readTime };
|
|
514
|
-
}
|
|
515
502
|
}
|
|
516
503
|
/**
|
|
517
504
|
* https://cloud.google.com/datastore/docs/concepts/transactions#datastore-datastore-transactional-update-nodejs
|
|
@@ -3,6 +3,7 @@ import { localTime } from '@naturalcycles/js-lib/datetime/localTime.js';
|
|
|
3
3
|
import { _ms } from '@naturalcycles/js-lib/datetime/time.util.js';
|
|
4
4
|
import { createCommonLoggerAtLevel } from '@naturalcycles/js-lib/log';
|
|
5
5
|
import { pRetry } from '@naturalcycles/js-lib/promise/pRetry.js';
|
|
6
|
+
import { getRunQueryOptions } from './query.util.js';
|
|
6
7
|
export class DatastoreStreamReadable extends Readable {
|
|
7
8
|
q;
|
|
8
9
|
table;
|
|
@@ -39,11 +40,7 @@ export class DatastoreStreamReadable extends Readable {
|
|
|
39
40
|
batchSize,
|
|
40
41
|
highWaterMark,
|
|
41
42
|
};
|
|
42
|
-
this.dsOpt =
|
|
43
|
-
if (opt.readAt) {
|
|
44
|
-
// Datastore expects UnixTimestamp in milliseconds
|
|
45
|
-
this.dsOpt.readTime = opt.readAt * 1000;
|
|
46
|
-
}
|
|
43
|
+
this.dsOpt = getRunQueryOptions(opt);
|
|
47
44
|
const logger = createCommonLoggerAtLevel(opt.logger, opt.logLevel);
|
|
48
45
|
this.logger = logger;
|
|
49
46
|
this.originalLimit = q.limitVal;
|
package/dist/query.util.d.ts
CHANGED
|
@@ -1,4 +1,7 @@
|
|
|
1
1
|
import { type Query } from '@google-cloud/datastore';
|
|
2
|
+
import type { RunQueryOptions } from '@google-cloud/datastore/build/src/query.js';
|
|
2
3
|
import type { DBQuery } from '@naturalcycles/db-lib';
|
|
3
4
|
import type { ObjectWithId } from '@naturalcycles/js-lib/types';
|
|
5
|
+
import type { DatastoreDBReadOptions } from './datastore.model.js';
|
|
4
6
|
export declare function dbQueryToDatastoreQuery<ROW extends ObjectWithId>(dbQuery: Readonly<DBQuery<ROW>>, emptyQuery: Query): Query;
|
|
7
|
+
export declare function getRunQueryOptions(opt: DatastoreDBReadOptions): RunQueryOptions;
|
package/dist/query.util.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { PropertyFilter } from '@google-cloud/datastore';
|
|
2
|
+
import { _round } from '@naturalcycles/js-lib';
|
|
2
3
|
const FNAME_MAP = {
|
|
3
4
|
id: '__key__',
|
|
4
5
|
};
|
|
@@ -47,3 +48,15 @@ export function dbQueryToDatastoreQuery(dbQuery, emptyQuery) {
|
|
|
47
48
|
}
|
|
48
49
|
return q;
|
|
49
50
|
}
|
|
51
|
+
export function getRunQueryOptions(opt) {
|
|
52
|
+
if (!opt.readAt)
|
|
53
|
+
return {};
|
|
54
|
+
// Datastore expects UnixTimestamp in milliseconds
|
|
55
|
+
// Datastore requires the timestamp to be rounded to the whole minutes
|
|
56
|
+
let readTime = _round(opt.readAt, 60) * 1000;
|
|
57
|
+
if (readTime >= Date.now() - 1000) {
|
|
58
|
+
// To avoid the error of: The requested 'read_time' cannot be in the future
|
|
59
|
+
readTime -= 60_000;
|
|
60
|
+
}
|
|
61
|
+
return { readTime };
|
|
62
|
+
}
|
package/package.json
CHANGED
package/src/datastore.db.ts
CHANGED
|
@@ -15,7 +15,6 @@ import type {
|
|
|
15
15
|
RunQueryResult,
|
|
16
16
|
} from '@naturalcycles/db-lib'
|
|
17
17
|
import { BaseCommonDB, commonDBFullSupport } from '@naturalcycles/db-lib'
|
|
18
|
-
import { _round } from '@naturalcycles/js-lib'
|
|
19
18
|
import { _chunk } from '@naturalcycles/js-lib/array/array.util.js'
|
|
20
19
|
import { _ms } from '@naturalcycles/js-lib/datetime/time.util.js'
|
|
21
20
|
import { _assert } from '@naturalcycles/js-lib/error/assert.js'
|
|
@@ -47,7 +46,7 @@ import type {
|
|
|
47
46
|
} from './datastore.model.js'
|
|
48
47
|
import { DatastoreType } from './datastore.model.js'
|
|
49
48
|
import { DatastoreStreamReadable } from './datastoreStreamReadable.js'
|
|
50
|
-
import { dbQueryToDatastoreQuery } from './query.util.js'
|
|
49
|
+
import { dbQueryToDatastoreQuery, getRunQueryOptions } from './query.util.js'
|
|
51
50
|
|
|
52
51
|
// Datastore (also Firestore and other Google APIs) supports max 500 of items when saving/deleting, etc.
|
|
53
52
|
const MAX_ITEMS = 500
|
|
@@ -146,7 +145,7 @@ export class DatastoreDB extends BaseCommonDB implements CommonDB {
|
|
|
146
145
|
const keys = ids.map(id => this.key(ds, table, id))
|
|
147
146
|
let rows: any[]
|
|
148
147
|
|
|
149
|
-
const dsOpt =
|
|
148
|
+
const dsOpt = getRunQueryOptions(opt)
|
|
150
149
|
|
|
151
150
|
if (this.cfg.timeout) {
|
|
152
151
|
// First try
|
|
@@ -216,7 +215,7 @@ export class DatastoreDB extends BaseCommonDB implements CommonDB {
|
|
|
216
215
|
): Promise<StringMap<ROW[]>> {
|
|
217
216
|
const result: StringMap<ROW[]> = {}
|
|
218
217
|
const ds = this.ds()
|
|
219
|
-
const dsOpt =
|
|
218
|
+
const dsOpt = getRunQueryOptions(opt)
|
|
220
219
|
const keys: Key[] = []
|
|
221
220
|
for (const [table, ids] of _stringMapEntries(map)) {
|
|
222
221
|
result[table] = []
|
|
@@ -260,7 +259,7 @@ export class DatastoreDB extends BaseCommonDB implements CommonDB {
|
|
|
260
259
|
|
|
261
260
|
const ds = this.ds()
|
|
262
261
|
const q = dbQueryToDatastoreQuery(dbQuery, ds.createQuery(dbQuery.table))
|
|
263
|
-
const dsOpt =
|
|
262
|
+
const dsOpt = getRunQueryOptions(opt)
|
|
264
263
|
const qr = await this.runDatastoreQuery<ROW>(q, dsOpt)
|
|
265
264
|
|
|
266
265
|
// Special case when projection query didn't specify 'id'
|
|
@@ -278,7 +277,7 @@ export class DatastoreDB extends BaseCommonDB implements CommonDB {
|
|
|
278
277
|
const ds = this.ds()
|
|
279
278
|
const q = dbQueryToDatastoreQuery(dbQuery, ds.createQuery(dbQuery.table))
|
|
280
279
|
const aq = ds.createAggregationQuery(q).count('count')
|
|
281
|
-
const dsOpt =
|
|
280
|
+
const dsOpt = getRunQueryOptions(opt)
|
|
282
281
|
const [entities] = await ds.runAggregationQuery(aq, dsOpt)
|
|
283
282
|
return entities[0]?.count
|
|
284
283
|
}
|
|
@@ -313,7 +312,7 @@ export class DatastoreDB extends BaseCommonDB implements CommonDB {
|
|
|
313
312
|
|
|
314
313
|
const readable = opt.experimentalCursorStream
|
|
315
314
|
? new DatastoreStreamReadable<ROW>(q, opt)
|
|
316
|
-
: ds.runQueryStream(q,
|
|
315
|
+
: ds.runQueryStream(q, getRunQueryOptions(opt))
|
|
317
316
|
|
|
318
317
|
return Pipeline.from<ROW>(readable).mapSync(r => this.mapId<ROW>(r))
|
|
319
318
|
}
|
|
@@ -383,7 +382,7 @@ export class DatastoreDB extends BaseCommonDB implements CommonDB {
|
|
|
383
382
|
|
|
384
383
|
const ds = this.ds()
|
|
385
384
|
const datastoreQuery = dbQueryToDatastoreQuery(q.select([]), ds.createQuery(q.table))
|
|
386
|
-
const dsOpt =
|
|
385
|
+
const dsOpt = getRunQueryOptions(opt)
|
|
387
386
|
const { rows } = await this.runDatastoreQuery<ObjectWithId>(datastoreQuery, dsOpt)
|
|
388
387
|
return await this.deleteByIds(
|
|
389
388
|
q.table,
|
|
@@ -680,20 +679,6 @@ export class DatastoreDB extends BaseCommonDB implements CommonDB {
|
|
|
680
679
|
this.cfg.logger.error(err)
|
|
681
680
|
}
|
|
682
681
|
}
|
|
683
|
-
|
|
684
|
-
private getRunQueryOptions(opt: DatastoreDBReadOptions): RunQueryOptions {
|
|
685
|
-
if (!opt.readAt) return {}
|
|
686
|
-
|
|
687
|
-
// Datastore expects UnixTimestamp in milliseconds
|
|
688
|
-
// Datastore requires the timestamp to be rounded to the whole minutes
|
|
689
|
-
const readTime = _round(opt.readAt, 60) * 1000
|
|
690
|
-
if (readTime >= Date.now() - 1000) {
|
|
691
|
-
// To avoid the error of: The requested 'read_time' cannot be in the future
|
|
692
|
-
return {}
|
|
693
|
-
}
|
|
694
|
-
|
|
695
|
-
return { readTime }
|
|
696
|
-
}
|
|
697
682
|
}
|
|
698
683
|
|
|
699
684
|
/**
|
|
@@ -12,6 +12,7 @@ import { pRetry } from '@naturalcycles/js-lib/promise/pRetry.js'
|
|
|
12
12
|
import type { UnixTimestampMillis } from '@naturalcycles/js-lib/types'
|
|
13
13
|
import type { ReadableTyped } from '@naturalcycles/nodejs-lib/stream'
|
|
14
14
|
import type { DatastoreDBStreamOptions } from './datastore.model.js'
|
|
15
|
+
import { getRunQueryOptions } from './query.util.js'
|
|
15
16
|
|
|
16
17
|
export class DatastoreStreamReadable<T = any> extends Readable implements ReadableTyped<T> {
|
|
17
18
|
private readonly table: string
|
|
@@ -53,12 +54,7 @@ export class DatastoreStreamReadable<T = any> extends Readable implements Readab
|
|
|
53
54
|
batchSize,
|
|
54
55
|
highWaterMark,
|
|
55
56
|
}
|
|
56
|
-
this.dsOpt =
|
|
57
|
-
if (opt.readAt) {
|
|
58
|
-
// Datastore expects UnixTimestamp in milliseconds
|
|
59
|
-
this.dsOpt.readTime = opt.readAt * 1000
|
|
60
|
-
}
|
|
61
|
-
|
|
57
|
+
this.dsOpt = getRunQueryOptions(opt)
|
|
62
58
|
const logger = createCommonLoggerAtLevel(opt.logger, opt.logLevel)
|
|
63
59
|
this.logger = logger
|
|
64
60
|
this.originalLimit = q.limitVal
|
package/src/query.util.ts
CHANGED
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
import { PropertyFilter, type Query } from '@google-cloud/datastore'
|
|
2
|
+
import type { RunQueryOptions } from '@google-cloud/datastore/build/src/query.js'
|
|
2
3
|
import type { DBQuery, DBQueryFilterOperator } from '@naturalcycles/db-lib'
|
|
4
|
+
import { _round } from '@naturalcycles/js-lib'
|
|
3
5
|
import type { ObjectWithId, StringMap } from '@naturalcycles/js-lib/types'
|
|
6
|
+
import type { DatastoreDBReadOptions } from './datastore.model.js'
|
|
4
7
|
|
|
5
8
|
const FNAME_MAP: StringMap = {
|
|
6
9
|
id: '__key__',
|
|
@@ -64,3 +67,17 @@ export function dbQueryToDatastoreQuery<ROW extends ObjectWithId>(
|
|
|
64
67
|
|
|
65
68
|
return q
|
|
66
69
|
}
|
|
70
|
+
|
|
71
|
+
export function getRunQueryOptions(opt: DatastoreDBReadOptions): RunQueryOptions {
|
|
72
|
+
if (!opt.readAt) return {}
|
|
73
|
+
|
|
74
|
+
// Datastore expects UnixTimestamp in milliseconds
|
|
75
|
+
// Datastore requires the timestamp to be rounded to the whole minutes
|
|
76
|
+
let readTime = _round(opt.readAt, 60) * 1000
|
|
77
|
+
if (readTime >= Date.now() - 1000) {
|
|
78
|
+
// To avoid the error of: The requested 'read_time' cannot be in the future
|
|
79
|
+
readTime -= 60_000
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
return { readTime }
|
|
83
|
+
}
|