@pi-r/gcp 0.11.2 → 0.12.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.
- package/client/index.js +489 -254
- package/download/index.js +21 -19
- package/package.json +5 -5
- package/types/index.d.ts +4 -3
- package/upload/index.js +29 -27
package/client/index.js
CHANGED
|
@@ -1,31 +1,12 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
exports.setBucketPolicy = setBucketPolicy;
|
|
11
|
-
exports.setBucketTagging = setBucketTagging;
|
|
12
|
-
exports.setBucketWebsite = setBucketWebsite;
|
|
13
|
-
exports.deleteObjects = deleteObjects;
|
|
14
|
-
exports.deleteObjectsV2 = deleteObjectsV2;
|
|
15
|
-
exports.deleteObjectsV3 = deleteObjectsV3;
|
|
16
|
-
exports.copyObject = copyObject;
|
|
17
|
-
exports.executeQuery = executeQuery;
|
|
18
|
-
exports.executeBatchQuery = executeBatchQuery;
|
|
19
|
-
exports.setPublicRead = setPublicRead;
|
|
20
|
-
exports.setPredefinedAcl = setPredefinedAcl;
|
|
21
|
-
exports.createBucketRequest = createBucketRequest;
|
|
22
|
-
exports.getProjectId = getProjectId;
|
|
23
|
-
const path = require("node:path");
|
|
24
|
-
const firestore_1 = require("@google-cloud/firestore");
|
|
25
|
-
const storage_1 = require("@google-cloud/storage");
|
|
26
|
-
const Cloud = require("@e-mc/cloud");
|
|
27
|
-
const types_1 = require("@e-mc/types");
|
|
28
|
-
const util_1 = require("@e-mc/cloud/util");
|
|
2
|
+
|
|
3
|
+
const path = require('node:path');
|
|
4
|
+
const { FieldPath, FieldValue, Filter, Firestore } = require('@google-cloud/firestore');
|
|
5
|
+
const { countAll, countIf, field, and: whereAnd, or: whereOr } = require('@google-cloud/firestore/pipelines');
|
|
6
|
+
const { Storage } = require('@google-cloud/storage');
|
|
7
|
+
const Cloud = require('@e-mc/cloud');
|
|
8
|
+
const { errorMessage, errorValue, isArray, isErrorCode, isObject, isPlainObject, isString } = require('@e-mc/types');
|
|
9
|
+
const { formatError } = require('@e-mc/cloud/util');
|
|
29
10
|
const FIREBASE_DB = {};
|
|
30
11
|
const FIREBASE_STORAGE = {};
|
|
31
12
|
const ADMIN_DB = {};
|
|
@@ -56,7 +37,7 @@ function getApp(credential, isDB) {
|
|
|
56
37
|
return getStorage(app);
|
|
57
38
|
}
|
|
58
39
|
const adminApp = require('firebase-admin/app');
|
|
59
|
-
const clientApp =
|
|
40
|
+
const clientApp = isString(credential.admin) || isPlainObject(credential.admin);
|
|
60
41
|
let app;
|
|
61
42
|
if (!clientApp) {
|
|
62
43
|
for (const item of adminApp.getApps()) {
|
|
@@ -100,7 +81,7 @@ async function hasBucket(client) {
|
|
|
100
81
|
async function updatePredefinedAcl(acl, values, metadata = {}) {
|
|
101
82
|
const items = [];
|
|
102
83
|
let { projectNumber, defaultObjectAcl } = metadata;
|
|
103
|
-
if (projectNumber === undefined &&
|
|
84
|
+
if (projectNumber === undefined && isArray(defaultObjectAcl)) {
|
|
104
85
|
const target = defaultObjectAcl.find(item => item.projectTeam?.projectNumber);
|
|
105
86
|
if (target !== undefined) {
|
|
106
87
|
projectNumber = target.projectTeam.projectNumber;
|
|
@@ -110,9 +91,9 @@ async function updatePredefinedAcl(acl, values, metadata = {}) {
|
|
|
110
91
|
items.push(...values.map(async (value) => {
|
|
111
92
|
const entity = await target.get({ entity: value.entity }).catch(() => null);
|
|
112
93
|
if (entity) {
|
|
113
|
-
return
|
|
94
|
+
return isString(value.role) ? target.update(value) : target.delete(value);
|
|
114
95
|
}
|
|
115
|
-
if (
|
|
96
|
+
if (isString(value.role)) {
|
|
116
97
|
if (projectNumber !== undefined) {
|
|
117
98
|
value.userProject ||= projectNumber.toString();
|
|
118
99
|
}
|
|
@@ -135,14 +116,67 @@ async function updatePredefinedAcl(acl, values, metadata = {}) {
|
|
|
135
116
|
async function setUniformBucketLevel(bucket, enabled) {
|
|
136
117
|
return bucket.setMetadata({ iamConfiguration: { uniformBucketLevelAccess: { enabled } } });
|
|
137
118
|
}
|
|
119
|
+
function createPipelineExpression(method, params, items) {
|
|
120
|
+
const [name, cond] = items;
|
|
121
|
+
let fld = field(name);
|
|
122
|
+
if (isArray(cond)) {
|
|
123
|
+
if (cond.every(pm => isExpression(pm))) {
|
|
124
|
+
for (const args of cond) {
|
|
125
|
+
fld = buildPipelineExpression(method, params, fld, args);
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
else {
|
|
129
|
+
fld = buildPipelineExpression(method, params, fld, cond);
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
else {
|
|
133
|
+
fld = buildPipelineExpression(method, params, fld, items.slice(1));
|
|
134
|
+
}
|
|
135
|
+
return fld;
|
|
136
|
+
}
|
|
137
|
+
function buildPipelineExpression(method, params, fld, items) {
|
|
138
|
+
for (const cond of items) {
|
|
139
|
+
if (isString(cond)) {
|
|
140
|
+
try {
|
|
141
|
+
fld = fld[cond]();
|
|
142
|
+
}
|
|
143
|
+
catch (err) {
|
|
144
|
+
throw errorConditional(method, cond, err);
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
else if (isArray(cond)) {
|
|
148
|
+
const pm1 = cond[0];
|
|
149
|
+
if (isExpression(pm1)) {
|
|
150
|
+
fld = buildPipelineExpression(method, params, fld, pm1);
|
|
151
|
+
}
|
|
152
|
+
else if (isString(pm1)) {
|
|
153
|
+
try {
|
|
154
|
+
fld = fld[pm1](...cond.slice(1));
|
|
155
|
+
}
|
|
156
|
+
catch (err) {
|
|
157
|
+
throw errorConditional(method, pm1, err);
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
else {
|
|
161
|
+
throw errorConditional(method, params);
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
else {
|
|
165
|
+
throw errorConditional(method, params);
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
return fld;
|
|
169
|
+
}
|
|
138
170
|
const keyLimit = (limit) => limit > 0 ? `_${limit}` : '_0';
|
|
139
|
-
const asFieldPath = (params) => Array.isArray(params) && params.every(item => typeof item === 'string') ? new
|
|
171
|
+
const asFieldPath = (params) => Array.isArray(params) && params.every(item => typeof item === 'string') ? new FieldPath(...params) : params;
|
|
172
|
+
const errorConditional = (method, hint, cause) => errorMessage(method, cause ? 'Method usage not supported' : 'Parameters were not recognized', Cloud.asString(hint), cause);
|
|
140
173
|
const getFirebasePackageName = (credential) => credential.apiKey && credential.authDomain && credential ? 'firebase' : 'firebase-admin';
|
|
141
|
-
const isErrorConflict = (err) =>
|
|
142
|
-
const hasGoogleAuth = (credential) =>
|
|
174
|
+
const isErrorConflict = (err) => isErrorCode(err, 409);
|
|
175
|
+
const hasGoogleAuth = (credential) => isString(credential.keyFilename || credential.keyFile || process.env.GOOGLE_APPLICATION_CREDENTIALS) || isObject(credential.credentials) || !!credential.authClient;
|
|
176
|
+
const isExpression = (params) => isArray(params) && params.every(pm => isArray(pm) || isString(pm));
|
|
143
177
|
const isSpanner = (data) => data.product === "spanner" || !data.product && !!(data.name && data.database && (data.query || data.table));
|
|
144
178
|
const isBigtable = (data) => data.product === "bigtable" || !data.product && !!(data.name && data.table && !data.database);
|
|
145
|
-
const isBigQuery = (data) => data.product === "bigquery" || !data.product && !!(!data.name && data.table && data.database ||
|
|
179
|
+
const isBigQuery = (data) => data.product === "bigquery" || !data.product && !!(!data.name && data.table && data.database || isString(data.query) || isString(data.options?.query));
|
|
146
180
|
const isDatastore = (data) => data.product === "datastore" || !data.product && !!(data.keys || data.kind || data.query && !data.table && !data.id);
|
|
147
181
|
function isFirebaseApp(credential, store, admin) {
|
|
148
182
|
return !!(credential.apiKey && credential.authDomain && (store || credential.databaseURL) || credential.product === "firebase" && process.env.GOOGLE_APPLICATION_CREDENTIALS) && (!admin || !credential.admin);
|
|
@@ -168,7 +202,7 @@ function createStorageClient(credential, bucket) {
|
|
|
168
202
|
}
|
|
169
203
|
}
|
|
170
204
|
getProjectId(credential, false);
|
|
171
|
-
return new
|
|
205
|
+
return new Storage(credential);
|
|
172
206
|
}
|
|
173
207
|
function createDatabaseClient(credential, data) {
|
|
174
208
|
let packageName;
|
|
@@ -201,10 +235,10 @@ function createDatabaseClient(credential, data) {
|
|
|
201
235
|
this.checkPackage(err, packageName, { passThrough: true });
|
|
202
236
|
throw err;
|
|
203
237
|
}
|
|
204
|
-
return new
|
|
238
|
+
return new Firestore(credential);
|
|
205
239
|
}
|
|
206
240
|
async function createBucket(credential, bucket, publicRead, service = "gcp") {
|
|
207
|
-
return createBucketV2.call(this, credential, bucket, publicRead ? 'publicRead' : undefined,
|
|
241
|
+
return createBucketV2.call(this, credential, bucket, publicRead ? 'publicRead' : undefined, {}, service);
|
|
208
242
|
}
|
|
209
243
|
async function createBucketV2(credential, bucket, acl, options, service = "gcp") {
|
|
210
244
|
if (isFirebaseApp(credential, true, true)) {
|
|
@@ -239,7 +273,7 @@ async function setBucketPolicy(credential, bucket, options, service = "gcp") {
|
|
|
239
273
|
}
|
|
240
274
|
const client = createStorageClient.call(this, credential, bucket).bucket(bucket);
|
|
241
275
|
if (!await hasBucket(client)) {
|
|
242
|
-
this.formatFail(64, service, ["Bucket does not exist", bucket],
|
|
276
|
+
this.formatFail(64, service, ["Bucket does not exist", bucket], errorMessage(service, "Bucket does not exist"), Cloud.optionsLogMessage('FAIL', { fatal: false }));
|
|
243
277
|
return false;
|
|
244
278
|
}
|
|
245
279
|
const errors = [];
|
|
@@ -272,29 +306,29 @@ async function setBucketPolicy(credential, bucket, options, service = "gcp") {
|
|
|
272
306
|
await setUniformBucketLevel(client, false).catch((err) => errors.push(err));
|
|
273
307
|
break;
|
|
274
308
|
default:
|
|
275
|
-
errors.push(
|
|
309
|
+
errors.push(errorValue('Invalid ACL', Cloud.asString(acl) || 'empty'));
|
|
276
310
|
break;
|
|
277
311
|
}
|
|
278
312
|
}
|
|
279
|
-
if (options.acl && (options.acl = options.acl.filter(user =>
|
|
313
|
+
if (options.acl && (options.acl = options.acl.filter(user => isString(user.entity))).length > 0) {
|
|
280
314
|
errors.push(...await updatePredefinedAcl(client.acl, options.acl, options.metadata));
|
|
281
315
|
}
|
|
282
316
|
if (errors.length > 0) {
|
|
283
317
|
this.formatFail(64, service, ["Unable to update bucket policy", bucket], errors[0], Cloud.optionsLogMessage('FAIL', { fatal: false }));
|
|
284
318
|
return false;
|
|
285
319
|
}
|
|
286
|
-
this.formatMessage(64, service, ["Bucket ACL configured", bucket],
|
|
320
|
+
this.formatMessage(64, service, ["Bucket ACL configured", bucket], isString(acl) ? acl : '', Cloud.optionsLogMessage('COMMAND'));
|
|
287
321
|
return true;
|
|
288
322
|
}
|
|
289
323
|
async function setBucketTagging(credential, bucket, labels, service = "gcp") {
|
|
290
|
-
if (isFirebaseApp(credential, true, true) || !
|
|
324
|
+
if (isFirebaseApp(credential, true, true) || !isPlainObject(labels)) {
|
|
291
325
|
return false;
|
|
292
326
|
}
|
|
293
327
|
const client = createStorageClient.call(this, credential, bucket).bucket(bucket);
|
|
294
328
|
const deleting = Object.keys(labels).length === 0;
|
|
295
329
|
if (deleting) {
|
|
296
330
|
const [metadata] = await client.getMetadata();
|
|
297
|
-
if (!
|
|
331
|
+
if (!isPlainObject(metadata.labels)) {
|
|
298
332
|
return true;
|
|
299
333
|
}
|
|
300
334
|
labels = {};
|
|
@@ -304,7 +338,7 @@ async function setBucketTagging(credential, bucket, labels, service = "gcp") {
|
|
|
304
338
|
}
|
|
305
339
|
return client.setMetadata({ labels })
|
|
306
340
|
.then(([metadata]) => {
|
|
307
|
-
this.formatMessage(64, service, [deleting ? "Tags deleted" : "Tags created", bucket], (
|
|
341
|
+
this.formatMessage(64, service, [deleting ? "Tags deleted" : "Tags created", bucket], (isPlainObject(metadata.labels) ? Object.keys(metadata.labels).length : 0) + ' labels (current)', Cloud.optionsLogMessage('COMMAND'));
|
|
308
342
|
return true;
|
|
309
343
|
})
|
|
310
344
|
.catch((err) => {
|
|
@@ -318,10 +352,10 @@ async function setBucketWebsite(credential, bucket, options, service = "gcp") {
|
|
|
318
352
|
}
|
|
319
353
|
const website = {};
|
|
320
354
|
const { indexPage, errorPage } = options;
|
|
321
|
-
if (
|
|
355
|
+
if (isString(indexPage)) {
|
|
322
356
|
website.mainPageSuffix = indexPage;
|
|
323
357
|
}
|
|
324
|
-
if (
|
|
358
|
+
if (isString(errorPage)) {
|
|
325
359
|
website.notFoundPage = errorPage;
|
|
326
360
|
}
|
|
327
361
|
const client = createStorageClient.call(this, credential, bucket).bucket(bucket);
|
|
@@ -335,8 +369,8 @@ async function setBucketWebsite(credential, bucket, options, service = "gcp") {
|
|
|
335
369
|
return false;
|
|
336
370
|
});
|
|
337
371
|
}
|
|
338
|
-
async function deleteObjects(credential, bucket,
|
|
339
|
-
return
|
|
372
|
+
async function deleteObjects(credential, bucket, options, service) {
|
|
373
|
+
return deleteObjectsV3.call(this, credential, bucket, options, service);
|
|
340
374
|
}
|
|
341
375
|
async function deleteObjectsV2(credential, bucket, recursive = true, service) {
|
|
342
376
|
return deleteObjectsV3.call(this, credential, bucket, { recursive }, service);
|
|
@@ -424,11 +458,11 @@ async function deleteObjectsV3(credential, bucket, options = {}, service = "gcp"
|
|
|
424
458
|
}
|
|
425
459
|
async function copyObject(credential, bucketSource, keySource, bucket, key, options = {}, service = "gcp") {
|
|
426
460
|
if (isFirebaseApp(credential, true, true)) {
|
|
427
|
-
throw
|
|
461
|
+
throw errorValue("Copy object not supported", 'firebase');
|
|
428
462
|
}
|
|
429
463
|
const instance = createStorageClient.call(this, credential);
|
|
430
|
-
const source =
|
|
431
|
-
const destination =
|
|
464
|
+
const source = isString(keySource) ? instance.bucket(bucketSource).file(keySource) : keySource;
|
|
465
|
+
const destination = isString(key) ? instance.bucket(bucket).file(key) : key;
|
|
432
466
|
return source.copy(destination, options)
|
|
433
467
|
.then(() => {
|
|
434
468
|
this.formatMessage(64, service, ["Copy success", bucket], source.bucket.name + '/' + source.name, Cloud.optionsLogMessage('COMMAND'));
|
|
@@ -490,9 +524,9 @@ async function executeBatchQuery(credential, batch, sessionKey) {
|
|
|
490
524
|
cacheValue.exclusiveOf = Array.isArray(ignoreCache) ? ignoreCache : undefined;
|
|
491
525
|
let rows, queryString = '';
|
|
492
526
|
if (product === "firebase" || isFirebaseApp(credential)) {
|
|
493
|
-
if (!
|
|
527
|
+
if (!isString(query)) {
|
|
494
528
|
closeClient();
|
|
495
|
-
throw
|
|
529
|
+
throw formatError(item, "Missing database query");
|
|
496
530
|
}
|
|
497
531
|
const orderBy = item.orderBy;
|
|
498
532
|
if (useCache) {
|
|
@@ -505,10 +539,10 @@ async function executeBatchQuery(credential, batch, sessionKey) {
|
|
|
505
539
|
const { ref, get, child, query: queryDB, update: updateDB } = require('@firebase/database');
|
|
506
540
|
const constraints = [];
|
|
507
541
|
let limiter = 0;
|
|
508
|
-
if (
|
|
542
|
+
if (isArray(orderBy)) {
|
|
509
543
|
const sort = require('@firebase/database');
|
|
510
544
|
for (const items of orderBy) {
|
|
511
|
-
if (
|
|
545
|
+
if (isArray(items)) {
|
|
512
546
|
const method = items[0];
|
|
513
547
|
switch (method) {
|
|
514
548
|
case 'orderByChild':
|
|
@@ -535,25 +569,25 @@ async function executeBatchQuery(credential, batch, sessionKey) {
|
|
|
535
569
|
}
|
|
536
570
|
}
|
|
537
571
|
const db = createClient(item, 0);
|
|
538
|
-
if (
|
|
572
|
+
if (isPlainObject(update)) {
|
|
539
573
|
await updateDB(ref(db, query), update);
|
|
540
574
|
}
|
|
541
575
|
const snapshot = await (constraints.length > 0 ? get(queryDB(ref(db, query), ...constraints)) : get(child(ref(db), query)));
|
|
542
576
|
if (snapshot.exists()) {
|
|
543
577
|
const val = snapshot.val();
|
|
544
578
|
const group = limiter === 1 && Object.keys(val);
|
|
545
|
-
rows = [group &&
|
|
579
|
+
rows = [group && isObject(val) && isObject(val[group[0]]) ? val[group[0]] : val];
|
|
546
580
|
}
|
|
547
581
|
}
|
|
548
582
|
else if (isSpanner(item)) {
|
|
549
|
-
const columns =
|
|
583
|
+
const columns = isPlainObject(query) && query.columns || item.columns;
|
|
550
584
|
if (!(query || table && columns)) {
|
|
551
585
|
closeClient();
|
|
552
|
-
throw
|
|
586
|
+
throw formatError(item, "Missing database query");
|
|
553
587
|
}
|
|
554
588
|
if (!name || !database) {
|
|
555
589
|
closeClient();
|
|
556
|
-
throw
|
|
590
|
+
throw formatError(item, !name ? "Missing instance name" : "Missing database name");
|
|
557
591
|
}
|
|
558
592
|
const { updateType, options = {} } = item;
|
|
559
593
|
if (useCache) {
|
|
@@ -565,10 +599,10 @@ async function executeBatchQuery(credential, batch, sessionKey) {
|
|
|
565
599
|
}
|
|
566
600
|
const db = createClient(item, 5).instance(name).database(database, options.databasePool, options.databaseQuery);
|
|
567
601
|
if (table) {
|
|
568
|
-
if (
|
|
602
|
+
if (isPlainObject(update)) {
|
|
569
603
|
await db.table(table)[updateType === 1 ? 'insert' : updateType === 2 ? 'replace' : 'update'](update, options.tableUpdate);
|
|
570
604
|
}
|
|
571
|
-
const request =
|
|
605
|
+
const request = isPlainObject(query) ? query : {};
|
|
572
606
|
request.json = true;
|
|
573
607
|
if (columns) {
|
|
574
608
|
request.columns = columns;
|
|
@@ -580,7 +614,7 @@ async function executeBatchQuery(credential, batch, sessionKey) {
|
|
|
580
614
|
[rows] = await db.table(table).read(request, options.tableRead);
|
|
581
615
|
}
|
|
582
616
|
else {
|
|
583
|
-
if (
|
|
617
|
+
if (isString(update) || isPlainObject(update) && isString(update.sql)) {
|
|
584
618
|
await new Promise((resolve, reject) => {
|
|
585
619
|
db.runTransaction((err, transaction) => {
|
|
586
620
|
if (err || !transaction) {
|
|
@@ -597,67 +631,65 @@ async function executeBatchQuery(credential, batch, sessionKey) {
|
|
|
597
631
|
});
|
|
598
632
|
});
|
|
599
633
|
}
|
|
600
|
-
const request =
|
|
634
|
+
const request = isPlainObject(query) ? query : { sql: query };
|
|
601
635
|
request.json = true;
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
636
|
+
const { params, types } = request;
|
|
637
|
+
if (params && isPlainObject(types)) {
|
|
638
|
+
const { Spanner } = require('@google-cloud/spanner');
|
|
639
|
+
for (const attr in types) {
|
|
640
|
+
let value = params[attr];
|
|
641
|
+
if (value === undefined) {
|
|
642
|
+
continue;
|
|
643
|
+
}
|
|
644
|
+
const method = types[attr];
|
|
645
|
+
switch (method) {
|
|
646
|
+
case 'date':
|
|
647
|
+
if (isString(value)) {
|
|
648
|
+
value = Spanner.date(value);
|
|
649
|
+
}
|
|
650
|
+
else if (Array.isArray(value) && value.length === 3) {
|
|
651
|
+
value = Spanner.date(...value);
|
|
652
|
+
}
|
|
653
|
+
break;
|
|
654
|
+
case 'interval':
|
|
655
|
+
if (Array.isArray(value) && value.length === 3) {
|
|
656
|
+
value = Spanner.interval(value[0], value[1], BigInt(value[2]));
|
|
657
|
+
}
|
|
658
|
+
break;
|
|
659
|
+
case 'float':
|
|
660
|
+
case 'float32':
|
|
661
|
+
case 'int':
|
|
662
|
+
case 'numeric':
|
|
663
|
+
value = Spanner[method](value);
|
|
664
|
+
break;
|
|
665
|
+
case 'protoEnum':
|
|
666
|
+
case 'protoMessage':
|
|
667
|
+
case 'struct':
|
|
668
|
+
if (isPlainObject(value)) {
|
|
630
669
|
value = Spanner[method](value);
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
value = Spanner.pgNumeric(value);
|
|
647
|
-
}
|
|
648
|
-
break;
|
|
649
|
-
case 'timestamp':
|
|
650
|
-
value = Spanner.timestamp(value);
|
|
651
|
-
break;
|
|
652
|
-
}
|
|
653
|
-
request.params[attr] = value;
|
|
670
|
+
}
|
|
671
|
+
break;
|
|
672
|
+
case 'pgJsonb':
|
|
673
|
+
if (isString(value) || isPlainObject(value)) {
|
|
674
|
+
value = Spanner.pgJsonb(value);
|
|
675
|
+
}
|
|
676
|
+
break;
|
|
677
|
+
case 'pgNumeric':
|
|
678
|
+
if (isString(value)) {
|
|
679
|
+
value = Spanner.pgNumeric(value);
|
|
680
|
+
}
|
|
681
|
+
break;
|
|
682
|
+
case 'timestamp':
|
|
683
|
+
value = Spanner.timestamp(value);
|
|
684
|
+
break;
|
|
654
685
|
}
|
|
686
|
+
params[attr] = value;
|
|
655
687
|
}
|
|
656
688
|
}
|
|
657
689
|
if (limit > 0) {
|
|
658
690
|
(request.gaxOptions ||= {}).maxResults = limit;
|
|
659
691
|
}
|
|
660
|
-
if (
|
|
692
|
+
if (flags & 2) {
|
|
661
693
|
rows = [];
|
|
662
694
|
await new Promise((resolve, reject) => {
|
|
663
695
|
db.runStream(request)
|
|
@@ -676,24 +708,24 @@ async function executeBatchQuery(credential, batch, sessionKey) {
|
|
|
676
708
|
else if (isBigtable(item)) {
|
|
677
709
|
if (!name || !table) {
|
|
678
710
|
closeClient();
|
|
679
|
-
throw
|
|
711
|
+
throw formatError(item, !name ? "Missing database name" : "Missing database table");
|
|
680
712
|
}
|
|
681
713
|
const { columns, options = {} } = item;
|
|
682
|
-
if (
|
|
714
|
+
if (isObject(query)) {
|
|
683
715
|
options.filter = query;
|
|
684
716
|
}
|
|
685
717
|
if (!id && limit > 0) {
|
|
686
718
|
(options.gaxOptions ||= {}).maxResults = limit;
|
|
687
719
|
}
|
|
688
720
|
if (useCache) {
|
|
689
|
-
queryString = name + '_' + table + (
|
|
721
|
+
queryString = name + '_' + table + (isString(id) ? '_' + id + (isArray(columns) ? '_' + Cloud.asString(columns, true) : '') : '') + Cloud.asString(options, true);
|
|
690
722
|
if (!(update && id) && (rows = this.getCacheResult(service, credential, queryString, cacheValue, ignoreCache))) {
|
|
691
723
|
result[i] = rows;
|
|
692
724
|
continue;
|
|
693
725
|
}
|
|
694
726
|
}
|
|
695
727
|
const db = createClient(item, 4).instance(name).table(table);
|
|
696
|
-
if (
|
|
728
|
+
if (isString(id)) {
|
|
697
729
|
const row = db.row(id);
|
|
698
730
|
if (update) {
|
|
699
731
|
await row.save(update);
|
|
@@ -721,14 +753,14 @@ async function executeBatchQuery(credential, batch, sessionKey) {
|
|
|
721
753
|
}
|
|
722
754
|
else if (isBigQuery(item)) {
|
|
723
755
|
const { params, options = {} } = item;
|
|
724
|
-
if (
|
|
756
|
+
if (isString(query)) {
|
|
725
757
|
options.query = query;
|
|
726
758
|
}
|
|
727
759
|
else if (!options.query) {
|
|
728
760
|
closeClient();
|
|
729
|
-
throw
|
|
761
|
+
throw formatError(item, "Missing database query");
|
|
730
762
|
}
|
|
731
|
-
if (
|
|
763
|
+
if (isObject(params)) {
|
|
732
764
|
options.params = params;
|
|
733
765
|
}
|
|
734
766
|
if (limit > 0) {
|
|
@@ -749,7 +781,7 @@ async function executeBatchQuery(credential, batch, sessionKey) {
|
|
|
749
781
|
target = target.table(table);
|
|
750
782
|
options.destination = target;
|
|
751
783
|
}
|
|
752
|
-
if (
|
|
784
|
+
if (isString(update)) {
|
|
753
785
|
const [metadata] = await target.getMetadata();
|
|
754
786
|
metadata.view = update;
|
|
755
787
|
await target.setMetadata(metadata);
|
|
@@ -765,10 +797,10 @@ async function executeBatchQuery(credential, batch, sessionKey) {
|
|
|
765
797
|
const { keys, kind, options } = item;
|
|
766
798
|
if (!keys && !kind && !Array.isArray(query)) {
|
|
767
799
|
closeClient();
|
|
768
|
-
throw
|
|
800
|
+
throw formatError(item, "Missing database query");
|
|
769
801
|
}
|
|
770
802
|
if (useCache) {
|
|
771
|
-
queryString = (keys ? Cloud.asString(keys, true) : (kind ? (name ? '_' + name : '') + '_' + Cloud.asString(kind, true) : '') + '_' + Cloud.asString(query, true) + keyLimit(limit)) + (options ? Cloud.asString(options, true) : '');
|
|
803
|
+
queryString = (keys ? Cloud.asString(keys, true) : (kind ? (name ? '_' + name : '') + '_' + Cloud.asString(kind, true) : '') + '_' + Cloud.asString(query, true) + '_' + keyLimit(limit)) + (options ? Cloud.asString(options, true) : '');
|
|
772
804
|
if (!update && (rows = this.getCacheResult(service, credential, queryString, cacheValue, ignoreCache))) {
|
|
773
805
|
result[i] = rows;
|
|
774
806
|
continue;
|
|
@@ -776,34 +808,51 @@ async function executeBatchQuery(credential, batch, sessionKey) {
|
|
|
776
808
|
}
|
|
777
809
|
const db = createClient(item, 2);
|
|
778
810
|
if (keys) {
|
|
779
|
-
const
|
|
780
|
-
if (
|
|
781
|
-
await db.save({ key
|
|
811
|
+
const key = !Array.isArray(keys) || !Array.isArray(keys[0]) ? db.key(keys) : keys.map(value => db.key(value));
|
|
812
|
+
if (isPlainObject(update)) {
|
|
813
|
+
await db.save({ key, data: update });
|
|
814
|
+
}
|
|
815
|
+
else if (isArray(update)) {
|
|
816
|
+
await db.save(update.map(pm => isPlainObject(pm) && !pm.key ? { ...pm, key } : pm));
|
|
782
817
|
}
|
|
783
|
-
rows = await db.get(
|
|
818
|
+
rows = await db.get(key, options);
|
|
784
819
|
if (limit > 0 && rows.length > limit) {
|
|
785
820
|
rows = rows.slice(0, limit);
|
|
786
821
|
}
|
|
787
822
|
}
|
|
788
823
|
else {
|
|
789
824
|
const task = name && kind ? db.createQuery(name, kind) : db.createQuery(kind);
|
|
790
|
-
if (
|
|
825
|
+
if (isArray(query)) {
|
|
791
826
|
for (const args of query) {
|
|
792
|
-
if (
|
|
827
|
+
if (isArray(args)) {
|
|
793
828
|
const method = args[0];
|
|
829
|
+
const arg1 = args[1];
|
|
794
830
|
switch (method) {
|
|
795
|
-
case 'end':
|
|
796
831
|
case 'filter':
|
|
797
|
-
|
|
798
|
-
|
|
799
|
-
case '
|
|
832
|
+
task.filter(...args.slice(1));
|
|
833
|
+
break;
|
|
834
|
+
case 'hasAncestor':
|
|
835
|
+
task.hasAncestor(db.key(arg1));
|
|
836
|
+
break;
|
|
800
837
|
case 'order':
|
|
801
|
-
|
|
838
|
+
if (isPlainObject(args[2])) {
|
|
839
|
+
task.order(arg1, args[2]);
|
|
840
|
+
}
|
|
841
|
+
else {
|
|
842
|
+
task.order(arg1);
|
|
843
|
+
}
|
|
844
|
+
break;
|
|
802
845
|
case 'start':
|
|
803
|
-
|
|
846
|
+
case 'end':
|
|
847
|
+
task[method](arg1);
|
|
804
848
|
break;
|
|
805
|
-
case '
|
|
806
|
-
|
|
849
|
+
case 'select':
|
|
850
|
+
case 'groupBy':
|
|
851
|
+
task[method](arg1);
|
|
852
|
+
break;
|
|
853
|
+
case 'limit':
|
|
854
|
+
case 'offset':
|
|
855
|
+
task[method](arg1);
|
|
807
856
|
break;
|
|
808
857
|
}
|
|
809
858
|
}
|
|
@@ -812,11 +861,11 @@ async function executeBatchQuery(credential, batch, sessionKey) {
|
|
|
812
861
|
if (limit > 0) {
|
|
813
862
|
task.limit(limit);
|
|
814
863
|
}
|
|
815
|
-
if (
|
|
864
|
+
if (isPlainObject(update)) {
|
|
816
865
|
await new Promise((resolve, reject) => {
|
|
817
866
|
db.runQuery(task.select('__key__'), options).then(entities => {
|
|
818
867
|
const response = entities[0];
|
|
819
|
-
if (
|
|
868
|
+
if (isArray(response)) {
|
|
820
869
|
const items = response.map(entity => db.key(entity[db.KEY]));
|
|
821
870
|
db.save({ key: items, data: update })
|
|
822
871
|
.then(() => {
|
|
@@ -837,7 +886,7 @@ async function executeBatchQuery(credential, batch, sessionKey) {
|
|
|
837
886
|
else if (product === "firestore" || !product && table) {
|
|
838
887
|
if (!table) {
|
|
839
888
|
closeClient();
|
|
840
|
-
throw
|
|
889
|
+
throw formatError(item, "Missing database table");
|
|
841
890
|
}
|
|
842
891
|
const db = createClient(item, 3);
|
|
843
892
|
const group = !table.includes('/') && (flags & 1) === 1;
|
|
@@ -848,7 +897,7 @@ async function executeBatchQuery(credential, batch, sessionKey) {
|
|
|
848
897
|
rows = [data];
|
|
849
898
|
}
|
|
850
899
|
}
|
|
851
|
-
else if (
|
|
900
|
+
else if (isString(id) || Array.isArray(id)) {
|
|
852
901
|
const options = Array.isArray(id) ? item.options : null;
|
|
853
902
|
if (useCache) {
|
|
854
903
|
queryString = table + '_' + id + (options ? Cloud.asString(options, true) : '');
|
|
@@ -866,7 +915,7 @@ async function executeBatchQuery(credential, batch, sessionKey) {
|
|
|
866
915
|
}
|
|
867
916
|
else {
|
|
868
917
|
const doc = db.collection(table).doc(id);
|
|
869
|
-
if (
|
|
918
|
+
if (isPlainObject(update)) {
|
|
870
919
|
const pattern = /^__(delete|serverTimestamp|increment|vector|array(?:Union|Remove))(?:<(.+)>)?__$/s;
|
|
871
920
|
for (const attr in update) {
|
|
872
921
|
const match = pattern.exec(attr);
|
|
@@ -875,20 +924,20 @@ async function executeBatchQuery(credential, batch, sessionKey) {
|
|
|
875
924
|
switch (method) {
|
|
876
925
|
case 'delete':
|
|
877
926
|
case 'serverTimestamp':
|
|
878
|
-
update[attr] =
|
|
927
|
+
update[attr] = FieldValue[method]();
|
|
879
928
|
break;
|
|
880
929
|
case 'increment':
|
|
881
|
-
update[attr] =
|
|
930
|
+
update[attr] = FieldValue.increment(match[2] ? +match[2] : 1);
|
|
882
931
|
break;
|
|
883
932
|
case 'vector':
|
|
884
933
|
if (match[2]) {
|
|
885
|
-
update[attr] =
|
|
934
|
+
update[attr] = FieldValue.vector(match[2].split(',').map(unit => parseFloat(unit)));
|
|
886
935
|
}
|
|
887
936
|
break;
|
|
888
937
|
case 'arrayUnion':
|
|
889
938
|
case 'arrayRemove':
|
|
890
939
|
if (match[2]) {
|
|
891
|
-
update[attr] =
|
|
940
|
+
update[attr] = FieldValue[method](...match[2].trim().split(/(?<!\\)\s*,\s*/).map(unit => {
|
|
892
941
|
switch (unit) {
|
|
893
942
|
case 'true':
|
|
894
943
|
return true;
|
|
@@ -941,7 +990,7 @@ async function executeBatchQuery(credential, batch, sessionKey) {
|
|
|
941
990
|
const options = item.options || {};
|
|
942
991
|
if (options.vectorField) {
|
|
943
992
|
if (Array.isArray(query)) {
|
|
944
|
-
options.queryVector ||=
|
|
993
|
+
options.queryVector ||= FieldValue.vector(query);
|
|
945
994
|
}
|
|
946
995
|
if (limit > 0) {
|
|
947
996
|
options.limit = limit;
|
|
@@ -950,11 +999,11 @@ async function executeBatchQuery(credential, batch, sessionKey) {
|
|
|
950
999
|
}
|
|
951
1000
|
else if (item.params && (options.queryVector || Array.isArray(query) && query.every(value => typeof value === 'number'))) {
|
|
952
1001
|
if (!options.queryVector) {
|
|
953
|
-
if (useCache && (rows = this.getCacheResult(service, credential, queryString = table + '_' + Cloud.asString(item.params, true) + '_' + Cloud.asString(query, true) + (options ? Cloud.asString(options, true) : '')
|
|
1002
|
+
if (useCache && (rows = this.getCacheResult(service, credential, queryString = table + '_' + Cloud.asString(item.params, true) + '_' + Cloud.asString(query, true) + '_' + keyLimit(limit) + (options ? Cloud.asString(options, true) : ''), cacheValue, ignoreCache))) {
|
|
954
1003
|
result[i] = rows;
|
|
955
1004
|
continue;
|
|
956
1005
|
}
|
|
957
|
-
options.queryVector =
|
|
1006
|
+
options.queryVector = FieldValue.vector(query);
|
|
958
1007
|
}
|
|
959
1008
|
options.vectorField = asFieldPath(item.params);
|
|
960
1009
|
if (limit > 0) {
|
|
@@ -962,93 +1011,308 @@ async function executeBatchQuery(credential, batch, sessionKey) {
|
|
|
962
1011
|
}
|
|
963
1012
|
rows = (await db.collection(table).findNearest(options).get()).docs.map(doc => doc.data());
|
|
964
1013
|
}
|
|
965
|
-
else if (
|
|
966
|
-
|
|
967
|
-
if (useCache && (rows = this.getCacheResult(service, credential, queryString = table + '_' + Cloud.asString(query, true) + '_' + Cloud.asString(orderBy, true) + `_${group ? `1${typeof id === 'number' ? `:${id}` : ''}` : '0'}` + keyLimit(limit), cacheValue, ignoreCache))) {
|
|
1014
|
+
else if (isArray(query)) {
|
|
1015
|
+
if (useCache && (rows = this.getCacheResult(service, credential, queryString = table + '_' + Cloud.asString(query, true) + '_' + keyLimit(limit) + '_' + (item.pipeline ? (group ? '1' : '0') + (options ? Cloud.asString(options, true) : '') : (group ? typeof id === 'number' ? `part:${id}` : ':1' : ':0') + (item.orderBy ? Cloud.asString(item.orderBy, true) : '')), cacheValue, ignoreCache))) {
|
|
968
1016
|
result[i] = rows;
|
|
969
1017
|
continue;
|
|
970
1018
|
}
|
|
971
|
-
|
|
972
|
-
|
|
973
|
-
const
|
|
974
|
-
|
|
975
|
-
|
|
976
|
-
|
|
1019
|
+
if (item.pipeline) {
|
|
1020
|
+
const target = group ? db.pipeline().collectionGroup(table) : db.pipeline().collection(table);
|
|
1021
|
+
for (const args of query) {
|
|
1022
|
+
const method = args[0];
|
|
1023
|
+
const params = args.slice(1);
|
|
1024
|
+
const values = params.every(p => isArray(p)) ? params : null;
|
|
1025
|
+
switch (method) {
|
|
1026
|
+
case 'aggregate':
|
|
1027
|
+
if (values && values.length > 1) {
|
|
1028
|
+
const filter = values.map(([col, cond]) => {
|
|
1029
|
+
if (isString(col) && isArray(cond)) {
|
|
1030
|
+
const items = cond.slice(0);
|
|
1031
|
+
const output = items.pop();
|
|
1032
|
+
let alias = null;
|
|
1033
|
+
if (items.length > 0) {
|
|
1034
|
+
let fld = field(col);
|
|
1035
|
+
found: {
|
|
1036
|
+
for (const agg of items) {
|
|
1037
|
+
switch (agg) {
|
|
1038
|
+
case 'count':
|
|
1039
|
+
case 'countDistinct':
|
|
1040
|
+
case 'sum':
|
|
1041
|
+
case 'average':
|
|
1042
|
+
case 'minimum':
|
|
1043
|
+
case 'maximum':
|
|
1044
|
+
alias = fld[agg]();
|
|
1045
|
+
break found;
|
|
1046
|
+
case 'countIf':
|
|
1047
|
+
alias = countIf(fld.asBoolean());
|
|
1048
|
+
break found;
|
|
1049
|
+
default:
|
|
1050
|
+
if (isArray(agg)) {
|
|
1051
|
+
fld = buildPipelineExpression(method, params, fld, agg);
|
|
1052
|
+
}
|
|
1053
|
+
else if (isString(agg)) {
|
|
1054
|
+
fld = fld[agg]();
|
|
1055
|
+
}
|
|
1056
|
+
else {
|
|
1057
|
+
break found;
|
|
1058
|
+
}
|
|
1059
|
+
break;
|
|
1060
|
+
}
|
|
1061
|
+
}
|
|
1062
|
+
}
|
|
1063
|
+
}
|
|
1064
|
+
else if (col === 'countAll') {
|
|
1065
|
+
alias = countAll();
|
|
1066
|
+
}
|
|
1067
|
+
if (alias && output) {
|
|
1068
|
+
return alias.as((isArray(output) ? output[0] : output));
|
|
1069
|
+
}
|
|
1070
|
+
}
|
|
1071
|
+
throw errorConditional(method, params);
|
|
1072
|
+
});
|
|
1073
|
+
target.aggregate(...filter);
|
|
1074
|
+
}
|
|
1075
|
+
else {
|
|
1076
|
+
target.aggregate(...params);
|
|
1077
|
+
}
|
|
1078
|
+
break;
|
|
1079
|
+
case 'findNearest':
|
|
1080
|
+
target.findNearest(...params);
|
|
1081
|
+
break;
|
|
1082
|
+
case 'limit':
|
|
1083
|
+
target.limit(...params);
|
|
1084
|
+
break;
|
|
1085
|
+
case 'offset':
|
|
1086
|
+
target.offset(...params);
|
|
1087
|
+
break;
|
|
1088
|
+
case 'rawStage':
|
|
1089
|
+
target.rawStage(...params);
|
|
1090
|
+
break;
|
|
1091
|
+
case 'removeFields':
|
|
1092
|
+
target.removeFields(...params);
|
|
1093
|
+
break;
|
|
1094
|
+
case 'replaceWith':
|
|
1095
|
+
target.replaceWith(...params);
|
|
1096
|
+
break;
|
|
1097
|
+
case 'sample':
|
|
1098
|
+
target.sample(...params);
|
|
1099
|
+
break;
|
|
1100
|
+
case 'search':
|
|
1101
|
+
target.search(...params);
|
|
1102
|
+
break;
|
|
1103
|
+
case 'select':
|
|
1104
|
+
case 'distinct':
|
|
1105
|
+
if (values) {
|
|
1106
|
+
const commit = (fld) => target[method](fld);
|
|
1107
|
+
for (const cond of values) {
|
|
1108
|
+
if (isString(cond)) {
|
|
1109
|
+
target[method](cond);
|
|
1110
|
+
}
|
|
1111
|
+
else if (isArray(cond)) {
|
|
1112
|
+
const [pm1, pm2] = cond;
|
|
1113
|
+
if (isString(pm2)) {
|
|
1114
|
+
commit(pm1 === 'field' ? field(pm2) : field(pm1).as(pm2));
|
|
1115
|
+
}
|
|
1116
|
+
else {
|
|
1117
|
+
found: {
|
|
1118
|
+
if (isArray(pm2)) {
|
|
1119
|
+
let fld = field(pm1);
|
|
1120
|
+
for (const pm3 of pm2) {
|
|
1121
|
+
if (isString(pm3)) {
|
|
1122
|
+
fld = fld[pm3]();
|
|
1123
|
+
}
|
|
1124
|
+
else if (isArray(pm3)) {
|
|
1125
|
+
if (pm3[0] === 'as') {
|
|
1126
|
+
commit(fld.as(pm3[1]));
|
|
1127
|
+
break found;
|
|
1128
|
+
}
|
|
1129
|
+
fld = buildPipelineExpression(method, params, fld, pm3);
|
|
1130
|
+
}
|
|
1131
|
+
else {
|
|
1132
|
+
break;
|
|
1133
|
+
}
|
|
1134
|
+
}
|
|
1135
|
+
}
|
|
1136
|
+
throw errorConditional(method, params);
|
|
1137
|
+
}
|
|
1138
|
+
}
|
|
1139
|
+
}
|
|
1140
|
+
else {
|
|
1141
|
+
throw errorConditional(method, params);
|
|
1142
|
+
}
|
|
1143
|
+
}
|
|
1144
|
+
}
|
|
1145
|
+
else if (method === 'distinct') {
|
|
1146
|
+
target.distinct(...params);
|
|
1147
|
+
}
|
|
1148
|
+
else {
|
|
1149
|
+
target.select(...params);
|
|
1150
|
+
}
|
|
1151
|
+
break;
|
|
1152
|
+
case 'sort':
|
|
1153
|
+
if (isPlainObject(params[0])) {
|
|
1154
|
+
target.sort(params[0]);
|
|
1155
|
+
}
|
|
1156
|
+
else {
|
|
1157
|
+
for (const cond of params) {
|
|
1158
|
+
if (isString(cond)) {
|
|
1159
|
+
target.sort(field(cond).ascending());
|
|
1160
|
+
}
|
|
1161
|
+
else if (isArray(cond)) {
|
|
1162
|
+
const [pm1, pm2] = cond;
|
|
1163
|
+
const fld = pm2 ? field(pm1).descending() : field(pm1).ascending();
|
|
1164
|
+
target.sort(fld);
|
|
1165
|
+
}
|
|
1166
|
+
else {
|
|
1167
|
+
throw errorConditional(method, params);
|
|
1168
|
+
}
|
|
1169
|
+
}
|
|
1170
|
+
}
|
|
1171
|
+
break;
|
|
1172
|
+
case 'union':
|
|
1173
|
+
target.union(...params);
|
|
1174
|
+
break;
|
|
1175
|
+
case 'unnest':
|
|
1176
|
+
if (values) {
|
|
1177
|
+
for (const [col, alias, indexField] of values) {
|
|
1178
|
+
const fld = alias ? field(col).as(alias) : field(col);
|
|
1179
|
+
target.unnest(fld, indexField);
|
|
1180
|
+
}
|
|
1181
|
+
}
|
|
1182
|
+
else {
|
|
1183
|
+
target.unnest(...params);
|
|
1184
|
+
}
|
|
1185
|
+
break;
|
|
1186
|
+
case 'whereAnd':
|
|
1187
|
+
case 'whereOr':
|
|
1188
|
+
if (values) {
|
|
1189
|
+
const filter = values.map(cond => createPipelineExpression(method, params, cond).asBoolean());
|
|
1190
|
+
target.where(method === 'whereAnd' ? whereAnd(...filter) : whereOr(...filter));
|
|
1191
|
+
}
|
|
1192
|
+
else {
|
|
1193
|
+
throw errorConditional(method, params);
|
|
1194
|
+
}
|
|
1195
|
+
break;
|
|
1196
|
+
case 'where':
|
|
1197
|
+
if (values) {
|
|
1198
|
+
for (const cond of values) {
|
|
1199
|
+
const fld = createPipelineExpression(method, params, cond);
|
|
1200
|
+
target.where(fld.asBoolean());
|
|
1201
|
+
}
|
|
1202
|
+
}
|
|
1203
|
+
else {
|
|
1204
|
+
target.where(...params);
|
|
1205
|
+
}
|
|
1206
|
+
break;
|
|
977
1207
|
}
|
|
978
1208
|
}
|
|
1209
|
+
if (limit > 0) {
|
|
1210
|
+
target.limit(limit);
|
|
1211
|
+
}
|
|
1212
|
+
const results = (await target.execute(item.options)).results;
|
|
1213
|
+
if (id === true) {
|
|
1214
|
+
rows = results.map(doc => {
|
|
1215
|
+
const data = doc.data();
|
|
1216
|
+
data.__id__ = doc.id;
|
|
1217
|
+
return data;
|
|
1218
|
+
});
|
|
1219
|
+
}
|
|
979
1220
|
else {
|
|
980
|
-
|
|
1221
|
+
rows = results.map(doc => doc.data());
|
|
981
1222
|
}
|
|
982
1223
|
}
|
|
983
1224
|
else {
|
|
984
|
-
targets
|
|
985
|
-
|
|
986
|
-
|
|
987
|
-
|
|
988
|
-
|
|
989
|
-
|
|
1225
|
+
const targets = [];
|
|
1226
|
+
if (group) {
|
|
1227
|
+
const col = db.collectionGroup(table);
|
|
1228
|
+
if (typeof id === 'number') {
|
|
1229
|
+
for await (const partition of col.getPartitions(id)) {
|
|
1230
|
+
targets.push(partition.toQuery());
|
|
1231
|
+
}
|
|
1232
|
+
}
|
|
1233
|
+
else {
|
|
1234
|
+
targets.push(col);
|
|
1235
|
+
}
|
|
1236
|
+
}
|
|
1237
|
+
else {
|
|
1238
|
+
targets.push(db.collection(table));
|
|
1239
|
+
}
|
|
1240
|
+
rows = [];
|
|
1241
|
+
const orderBy = item.orderBy;
|
|
1242
|
+
for (let target of targets) {
|
|
1243
|
+
for (const args of query) {
|
|
990
1244
|
const method = args[0];
|
|
991
1245
|
const params = args.slice(1);
|
|
992
1246
|
switch (method) {
|
|
993
1247
|
case 'whereAnd':
|
|
994
1248
|
case 'whereOr':
|
|
995
|
-
if (
|
|
996
|
-
|
|
1249
|
+
if (params.every(pm => isArray(pm))) {
|
|
1250
|
+
target = target.where(Filter[method === 'whereAnd' ? 'and' : 'or'](...params.map(p => Filter.where(...p))));
|
|
1251
|
+
}
|
|
1252
|
+
else {
|
|
1253
|
+
throw errorConditional(method, params);
|
|
997
1254
|
}
|
|
998
|
-
target = target.where(firestore_1.Filter[method === 'whereAnd' ? 'and' : 'or'](...params.map((p) => firestore_1.Filter.where(p[0], p[1], p[2]))));
|
|
999
1255
|
break;
|
|
1000
|
-
case '
|
|
1256
|
+
case 'where':
|
|
1001
1257
|
params[0] = asFieldPath(params[0]);
|
|
1002
|
-
target = target.
|
|
1258
|
+
target = target.where(...params);
|
|
1003
1259
|
break;
|
|
1004
|
-
case 'where':
|
|
1005
1260
|
case 'orderBy':
|
|
1006
1261
|
params[0] = asFieldPath(params[0]);
|
|
1007
|
-
target = target
|
|
1262
|
+
target = target.orderBy(...params);
|
|
1263
|
+
break;
|
|
1264
|
+
case 'findNearest':
|
|
1265
|
+
params[0] = asFieldPath(params[0]);
|
|
1266
|
+
target = target.findNearest(...params).query;
|
|
1267
|
+
break;
|
|
1008
1268
|
case 'select':
|
|
1009
|
-
params.forEach((
|
|
1010
|
-
params[index] = asFieldPath(
|
|
1269
|
+
params.forEach((pm, index) => {
|
|
1270
|
+
params[index] = asFieldPath(pm);
|
|
1011
1271
|
});
|
|
1012
|
-
target = target.select
|
|
1272
|
+
target = target.select(...params);
|
|
1013
1273
|
break;
|
|
1014
1274
|
case 'endAt':
|
|
1015
1275
|
case 'endBefore':
|
|
1276
|
+
target = target[method](...params);
|
|
1277
|
+
break;
|
|
1016
1278
|
case 'limit':
|
|
1017
1279
|
case 'limitToLast':
|
|
1018
1280
|
case 'offset':
|
|
1281
|
+
target = target[method](...params);
|
|
1282
|
+
break;
|
|
1019
1283
|
case 'startAfter':
|
|
1020
1284
|
case 'startAt':
|
|
1285
|
+
target = target[method](...params);
|
|
1286
|
+
break;
|
|
1021
1287
|
case 'withConverter':
|
|
1022
|
-
target = target
|
|
1288
|
+
target = target.withConverter(...params);
|
|
1023
1289
|
break;
|
|
1024
1290
|
}
|
|
1025
1291
|
}
|
|
1026
|
-
|
|
1027
|
-
|
|
1028
|
-
|
|
1029
|
-
if ((0, types_1.isArray)(order)) {
|
|
1030
|
-
target = target.orderBy(asFieldPath(order[0]), order[1]);
|
|
1031
|
-
}
|
|
1032
|
-
else if ((0, types_1.isString)(order)) {
|
|
1033
|
-
target = target.orderBy(order);
|
|
1292
|
+
if (Array.isArray(orderBy)) {
|
|
1293
|
+
for (const order of orderBy) {
|
|
1294
|
+
target = isArray(order) ? target.orderBy(asFieldPath(order[0]), order[1]) : target.orderBy(order);
|
|
1034
1295
|
}
|
|
1035
1296
|
}
|
|
1297
|
+
else if (orderBy) {
|
|
1298
|
+
target = target.orderBy(orderBy);
|
|
1299
|
+
}
|
|
1300
|
+
if (limit > 0) {
|
|
1301
|
+
target = target.limit(limit);
|
|
1302
|
+
}
|
|
1303
|
+
rows = rows.concat((await target.get()).docs.map(doc => doc.data()));
|
|
1036
1304
|
}
|
|
1037
|
-
if (limit > 0) {
|
|
1038
|
-
target = target.limit(limit);
|
|
1039
|
-
}
|
|
1040
|
-
rows = rows.concat((await target.get()).docs.map(doc => doc.data()));
|
|
1041
1305
|
}
|
|
1042
1306
|
}
|
|
1043
1307
|
else {
|
|
1044
1308
|
closeClient();
|
|
1045
|
-
throw
|
|
1309
|
+
throw formatError(item, "Missing database query");
|
|
1046
1310
|
}
|
|
1047
1311
|
}
|
|
1048
1312
|
}
|
|
1049
1313
|
else {
|
|
1050
1314
|
closeClient();
|
|
1051
|
-
throw
|
|
1315
|
+
throw formatError(item, "Missing database product");
|
|
1052
1316
|
}
|
|
1053
1317
|
result[i] = this.setQueryResult(service, credential, queryString, rows, cacheValue);
|
|
1054
1318
|
}
|
|
@@ -1066,6 +1330,9 @@ function setPublicRead(acl, pathname, requested, service = "gcp") {
|
|
|
1066
1330
|
if (requested) {
|
|
1067
1331
|
this.formatMessage(64, service, ["Unable to grant public-read", pathname], err, Cloud.optionsLogMessage('WARN'));
|
|
1068
1332
|
}
|
|
1333
|
+
else {
|
|
1334
|
+
this.addLog(3, err, service, 'acl:allUsers');
|
|
1335
|
+
}
|
|
1069
1336
|
});
|
|
1070
1337
|
}
|
|
1071
1338
|
async function setPredefinedAcl(target, value, bucket, pathname = '', metadata = {}, requested = true, service = "gcp") {
|
|
@@ -1085,7 +1352,7 @@ async function setPredefinedAcl(target, value, bucket, pathname = '', metadata =
|
|
|
1085
1352
|
default: {
|
|
1086
1353
|
const owner = metadata.owner?.entity;
|
|
1087
1354
|
let acl = metadata.acl;
|
|
1088
|
-
if (
|
|
1355
|
+
if (isArray(acl)) {
|
|
1089
1356
|
items = [];
|
|
1090
1357
|
}
|
|
1091
1358
|
else {
|
|
@@ -1145,61 +1412,6 @@ async function setPredefinedAcl(target, value, bucket, pathname = '', metadata =
|
|
|
1145
1412
|
}
|
|
1146
1413
|
});
|
|
1147
1414
|
}
|
|
1148
|
-
function createBucketRequest(credential) {
|
|
1149
|
-
const options = {};
|
|
1150
|
-
for (const attr in credential) {
|
|
1151
|
-
switch (attr) {
|
|
1152
|
-
case 'archive':
|
|
1153
|
-
case 'coldline':
|
|
1154
|
-
case 'dataLocations':
|
|
1155
|
-
case 'dra':
|
|
1156
|
-
case 'enableObjectRetention':
|
|
1157
|
-
case 'multiRegional':
|
|
1158
|
-
case 'nearline':
|
|
1159
|
-
case 'predefinedAcl':
|
|
1160
|
-
case 'predefinedDefaultObjectAcl':
|
|
1161
|
-
case 'projection':
|
|
1162
|
-
case 'regional':
|
|
1163
|
-
case 'requesterPays':
|
|
1164
|
-
case 'standard':
|
|
1165
|
-
case 'userProject':
|
|
1166
|
-
case 'acl':
|
|
1167
|
-
case 'autoclass':
|
|
1168
|
-
case 'billing':
|
|
1169
|
-
case 'cors':
|
|
1170
|
-
case 'customPlacementConfig':
|
|
1171
|
-
case 'defaultEventBasedHold':
|
|
1172
|
-
case 'defaultObjectAcl':
|
|
1173
|
-
case 'encryption':
|
|
1174
|
-
case 'hierarchicalNamespace':
|
|
1175
|
-
case 'iamConfiguration':
|
|
1176
|
-
case 'labels':
|
|
1177
|
-
case 'lifecycle':
|
|
1178
|
-
case 'location':
|
|
1179
|
-
case 'locationType':
|
|
1180
|
-
case 'logging':
|
|
1181
|
-
case 'generation':
|
|
1182
|
-
case 'metageneration':
|
|
1183
|
-
case 'name':
|
|
1184
|
-
case 'objectRetention':
|
|
1185
|
-
case 'owner':
|
|
1186
|
-
case 'projectNumber':
|
|
1187
|
-
case 'retentionPolicy':
|
|
1188
|
-
case 'rpo':
|
|
1189
|
-
case 'softDeleteTime':
|
|
1190
|
-
case 'hardDeleteTime':
|
|
1191
|
-
case 'softDeletePolicy':
|
|
1192
|
-
case 'storageClass':
|
|
1193
|
-
case 'timeCreated':
|
|
1194
|
-
case 'updated':
|
|
1195
|
-
case 'versioning':
|
|
1196
|
-
case 'website':
|
|
1197
|
-
options[attr] = credential[attr];
|
|
1198
|
-
break;
|
|
1199
|
-
}
|
|
1200
|
-
}
|
|
1201
|
-
return options;
|
|
1202
|
-
}
|
|
1203
1415
|
function getProjectId(credential, cache) {
|
|
1204
1416
|
let projectId = credential.projectId;
|
|
1205
1417
|
if (!cache && projectId) {
|
|
@@ -1216,7 +1428,7 @@ function getProjectId(credential, cache) {
|
|
|
1216
1428
|
if (!projectId) {
|
|
1217
1429
|
try {
|
|
1218
1430
|
const id = require(pathname).project_id;
|
|
1219
|
-
if (
|
|
1431
|
+
if (isString(id)) {
|
|
1220
1432
|
projectId = id;
|
|
1221
1433
|
}
|
|
1222
1434
|
}
|
|
@@ -1227,6 +1439,29 @@ function getProjectId(credential, cache) {
|
|
|
1227
1439
|
}
|
|
1228
1440
|
return projectId;
|
|
1229
1441
|
}
|
|
1230
|
-
|
|
1231
|
-
|
|
1232
|
-
|
|
1442
|
+
const CLOUD_UPLOAD_STREAM = true;
|
|
1443
|
+
const CLOUD_UPLOAD_CHUNK = true;
|
|
1444
|
+
const CLOUD_DOWNLOAD_CHUNK = true;
|
|
1445
|
+
|
|
1446
|
+
exports.CLOUD_DOWNLOAD_CHUNK = CLOUD_DOWNLOAD_CHUNK;
|
|
1447
|
+
exports.CLOUD_UPLOAD_CHUNK = CLOUD_UPLOAD_CHUNK;
|
|
1448
|
+
exports.CLOUD_UPLOAD_STREAM = CLOUD_UPLOAD_STREAM;
|
|
1449
|
+
exports.copyObject = copyObject;
|
|
1450
|
+
exports.createBucket = createBucket;
|
|
1451
|
+
exports.createBucketV2 = createBucketV2;
|
|
1452
|
+
exports.createDatabaseClient = createDatabaseClient;
|
|
1453
|
+
exports.createStorageClient = createStorageClient;
|
|
1454
|
+
exports.deleteObjects = deleteObjects;
|
|
1455
|
+
exports.deleteObjectsV2 = deleteObjectsV2;
|
|
1456
|
+
exports.deleteObjectsV3 = deleteObjectsV3;
|
|
1457
|
+
exports.executeBatchQuery = executeBatchQuery;
|
|
1458
|
+
exports.executeQuery = executeQuery;
|
|
1459
|
+
exports.getProjectId = getProjectId;
|
|
1460
|
+
exports.isFirebaseApp = isFirebaseApp;
|
|
1461
|
+
exports.setBucketPolicy = setBucketPolicy;
|
|
1462
|
+
exports.setBucketTagging = setBucketTagging;
|
|
1463
|
+
exports.setBucketWebsite = setBucketWebsite;
|
|
1464
|
+
exports.setPredefinedAcl = setPredefinedAcl;
|
|
1465
|
+
exports.setPublicRead = setPublicRead;
|
|
1466
|
+
exports.validateDatabase = validateDatabase;
|
|
1467
|
+
exports.validateStorage = validateStorage;
|