@google-cloud/datastore
Version:
Cloud Datastore Client Library for Node.js
1,193 lines • 38.3 kB
JavaScript
/*!
* Copyright 2018 Google LLC.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
Object.defineProperty(exports, "__esModule", { value: true });
exports.DatastoreAdminClient = exports.DatastoreClient = exports.v1 = exports.Transaction = exports.Query = exports.DatastoreRequest = exports.Index = exports.Datastore = exports.or = exports.and = exports.PropertyFilter = exports.AggregateField = exports.Key = void 0;
/**
* @namespace google
*/
/**
* @namespace google.datastore.v1
*/
/**
* @namespace google.protobuf
*/
const arrify = require("arrify");
const extend = require("extend");
const google_gax_1 = require("google-gax");
const is = require("is");
const stream_1 = require("stream");
const entity_1 = require("./entity");
const aggregate_1 = require("./aggregate");
Object.defineProperty(exports, "AggregateField", { enumerable: true, get: function () { return aggregate_1.AggregateField; } });
var Key = entity_1.entity.Key;
exports.Key = Key;
const filter_1 = require("./filter");
Object.defineProperty(exports, "PropertyFilter", { enumerable: true, get: function () { return filter_1.PropertyFilter; } });
Object.defineProperty(exports, "and", { enumerable: true, get: function () { return filter_1.and; } });
Object.defineProperty(exports, "or", { enumerable: true, get: function () { return filter_1.or; } });
const index_class_1 = require("./index-class");
Object.defineProperty(exports, "Index", { enumerable: true, get: function () { return index_class_1.Index; } });
const query_1 = require("./query");
Object.defineProperty(exports, "Query", { enumerable: true, get: function () { return query_1.Query; } });
const request_1 = require("./request");
Object.defineProperty(exports, "DatastoreRequest", { enumerable: true, get: function () { return request_1.DatastoreRequest; } });
const transaction_1 = require("./transaction");
Object.defineProperty(exports, "Transaction", { enumerable: true, get: function () { return transaction_1.Transaction; } });
const promisify_1 = require("@google-cloud/promisify");
const aggregate_2 = require("./aggregate");
const extendExcludeFromIndexes_1 = require("./utils/entity/extendExcludeFromIndexes");
const buildEntityProto_1 = require("./utils/entity/buildEntityProto");
const { grpc } = new google_gax_1.GrpcClient();
// Import the clients for each version supported by this package.
const gapic = Object.freeze({
v1: require('./v1'),
});
const urlSafeKey = new entity_1.entity.URLSafeKey();
/**
* Idiomatic class for interacting with Cloud Datastore. Uses the lower-level
* {@link DatastoreClient} class under the hood.
*
* In addition to the constructor options shown here, the {@link Datastore}
* class constructor accepts the same options accepted by
* {@link DatastoreClient}.
*
* <h4>The Datastore Emulator</h4>
*
* Make sure you have the <a href="https://cloud.google.com/sdk/docs/install">
* gcloud SDK installed</a>, then run:
*
* <pre>
* $ gcloud beta emulators datastore start --no-legacy
* </pre>
*
* You will see the following printed:
*
* <pre>
* [datastore] API endpoint: http://localhost:8005
* [datastore] If you are using a library that supports the
* DATASTORE_EMULATOR_HOST environment variable, run:
* [datastore]
* [datastore] export DATASTORE_EMULATOR_HOST=localhost:8005
* [datastore]
* [datastore] Dev App Server is now running.
* </pre>
*
* Set that environment variable and your localhost Datastore will
* automatically be used. You can also pass this address in manually with
* `apiEndpoint`.
*
* Additionally, `DATASTORE_PROJECT_ID` is recognized. If you have this set,
* you don't need to provide a `projectId`.
*
*
* See {@link https://cloud.google.com/datastore/docs/concepts/overview| Cloud Datastore Concepts Overview}
*
* @param {object} [options] Configuration options.
* @param {string} [options.apiEndpoint] Override the default API endpoint used
* to reach Datastore. This is useful for connecting to your local Datastore
* server (usually "http://localhost:8080").
* @param {string} [options.namespace] Namespace to isolate transactions to.
*
* @example Import the client library
* ```
* const {Datastore} = require('@google-cloud/datastore');
*
* ```
* @example Create a client that uses <a href="https://cloud.google.com/docs/authentication/production#providing_credentials_to_your_application">Application Default Credentials (ADC)</a>:
* ```
* const datastore = new Datastore();
*
* ```
* @example Create a client with <a href="https://cloud.google.com/docs/authentication/production#obtaining_and_providing_service_account_credentials_manually">explicit credentials</a>:
* ```
* const datastore = new Datastore({
* projectId: 'your-project-id',
* keyFilename: '/path/to/keyfile.json'
* });
*
* ```
* @example Retrieving Records
* ```
* const {Datastore} = require('@google-cloud/datastore');
* const datastore = new Datastore();
*
* // Records, called "entities" in Datastore, are retrieved by using a key. The
* // key is more than a numeric identifier, it is a complex data structure that
* // can be used to model relationships. The simplest key has a string `kind`
* // value, and either a numeric `id` value, or a string `name` value.
* //
* // A single record can be retrieved with {@link Datastore#key} and
* // {@link Datastore#get}.
* //-
* const key = datastore.key(['Company', 'Google']);
*
* datastore.get(key, function(err, entity) {
* // entity = The record.
* // entity[datastore.KEY] = The key for this entity.
* });
*
* //-
* // <h3>Querying Records</h3>
* //
* // Create a query with {@link Datastore#createQuery}.
* //-
* const query = datastore.createQuery('Company');
*
* //-
* // Multiple records can be found that match criteria with
* // {@link Query#filter}.
* //-
* query.filter('location', 'CA');
*
* //-
* // Records can also be ordered with {@link Query#order}.
* //-
* query.order('name');
*
* //-
* // The number of records returned can be specified with
* // {@link Query#limit}.
* //-
* query.limit(5);
*
* //-
* // Records' key structures can also be queried with
* // {@link Query#hasAncestor}.
* //-
* const ancestorKey = datastore.key(['ParentCompany', 'Alphabet']);
*
* query.hasAncestor(ancestorKey);
*
* //-
* // Run the query with {@link Datastore#runQuery}.
* //-
* datastore.runQuery(query, (err, entities) => {
* // entities = An array of records.
*
* // Access the Key object for an entity.
* const firstEntityKey = entities[0][datastore.KEY];
* });
*
* ```
* @example Paginating Records
* ```
* // Imagine building a website that allows a user to sift through hundreds of
* // their contacts. You'll likely want to only display a subset of these at
* // once, so you set a limit.
* //-
* const express = require('express');
* const app = express();
*
* const NUM_RESULTS_PER_PAGE = 15;
*
* app.get('/contacts', (req, res) => {
* const query = datastore.createQuery('Contacts')
* .limit(NUM_RESULTS_PER_PAGE);
*
* if (req.query.nextPageCursor) {
* query.start(req.query.nextPageCursor);
* }
*
* datastore.runQuery(query, (err, entities, info) => {
* if (err) {
* // Error handling omitted.
* return;
* }
*
* // Respond to the front end with the contacts and the cursoring token
* // from the query we just ran.
* const frontEndResponse = {
* contacts: entities
* };
*
* // Check if more results may exist.
* if (info.moreResults !== datastore.NO_MORE_RESULTS) {
* frontEndResponse.nextPageCursor = info.endCursor;
* }
*
* res.render('contacts', frontEndResponse);
* });
* });
*
* ```
* @example Creating Records
* ```
* // New entities can be created and persisted with {@link Datastore#save}.
* // The entity must have a key to be saved. If you don't specify an
* // identifier for the key, one is generated for you.
* //
* // We will create a key with a `name` identifier, "Google".
* //-
* const key = datastore.key(['Company', 'Google']);
*
* const data = {
* name: 'Google',
* location: 'CA'
* };
*
* datastore.save({
* key: key,
* data: data
* }, (err) => {
* if (!err) {
* // Record saved successfully.
* }
* });
*
* //-
* // We can verify the data was saved by using {@link Datastore#get}.
* //-
* datastore.get(key, (err, entity) => {
* // entity = {
* // name: 'Google',
* // location: 'CA'
* // }
* });
*
* //-
* // If we want to update this record, we can modify the data object and re-
* // save it.
* //-
* data.symbol = 'GOOG';
*
* datastore.save({
* key: key, // defined above (datastore.key(['Company', 'Google']))
* data: data
* }, (err, entity) => {
* if (!err) {
* // Record updated successfully.
* }
* });
*
* ```
* @example Deleting Records
* ```
* // Entities can be removed from Datastore by passing the entity's key object
* // to {@link Datastore#delete}.
* //-
* const key = datastore.key(['Company', 'Google']);
*
* datastore.delete(key, (err) => {
* if (!err) {
* // Record deleted successfully.
* }
* });
*
* ```
* @example Transactions
* ```
* // Complex logic can be wrapped in a transaction with
* // {@link Datastore#transaction}. All queries and updates run within
* // the transaction will be applied when the `done` function is called.
* //-
* const transaction = datastore.transaction();
*
* transaction.run((err) => {
* if (err) {
* // Error handling omitted.
* }
*
* const key = datastore.key(['Company', 'Google']);
*
* transaction.get(key, (err, entity) => {
* if (err) {
* // Error handling omitted.
* }
*
* entity.symbol = 'GOOG';
*
* transaction.save(entity);
*
* transaction.commit((err) => {
* if (!err) {
* // Transaction committed successfully.
* }
* });
* });
* });
*
* ```
* @example Queries with Ancestors
* ```
* const {Datastore} = require('@google-cloud/datastore');
* const datastore = new Datastore();
*
* const customerId1 = 2993844;
* const customerId2 = 4993882;
* const customerKey1 = datastore.key(['Customer', customerId1]);
* const customerKey2 = datastore.key(['Customer', customerId2]);
* const cookieKey1 = datastore.key(['Customer', customerId1, 'Cookie',
* 'cookie28839']); // child entity const cookieKey2 =
* datastore.key(['Customer', customerId1, 'Cookie', 'cookie78984']); // child
* entity const cookieKey3 = datastore.key(['Customer', customerId2, 'Cookie',
* 'cookie93911']); // child entity
*
* const entities = [];
*
* entities.push({
* key: customerKey1,
* data: {
* name: 'Jane Doe',
* address: '4848 Liller'
* }
* });
*
* entities.push({
* key: customerKey2,
* data: {
* name: 'John Smith',
* address: '4848 Pine'
* }
* });
*
* entities.push({
* key: cookieKey1,
* data: {
* cookieVal: 'dj83kks88rkld'
* }
* });
*
* entities.push({
* key: cookieKey2,
* data: {
* cookieVal: 'sj843ka99s'
* }
* });
*
* entities.push({
* key: cookieKey3,
* data: {
* cookieVal: 'otk82k2kw'
* }
* });
*
* datastore.upsert(entities);
*
* const query = datastore.createQuery().hasAncestor(customerKey1);
*
* datastore.runQuery(query, (err, entities) => {
* for (let entity of entities) {
* console.log(entity[datastore.KEY]);
* }
* });
*
* const query2 = datastore.createQuery().hasAncestor(customerKey2);
*
* datastore.runQuery(query2, (err, entities) => {
* for (let entity of entities) {
* console.log(entity[datastore.KEY]);
* }
* });
*
* datastore.runQuery(query2, (entities) => {
* console.log(entities);
* });
* ```
*/
class Datastore extends request_1.DatastoreRequest {
clients_;
namespace;
defaultBaseUrl_;
options;
baseUrl_;
port_;
customEndpoint_;
auth;
constructor(options) {
super();
options = options || {};
this.clients_ = new Map();
this.datastore = this;
/**
* @name Datastore#namespace
* @type {string}
*/
this.namespace = options.namespace;
options.projectId = options.projectId || process.env.DATASTORE_PROJECT_ID;
this.defaultBaseUrl_ = 'datastore.googleapis.com';
this.determineBaseUrl_(options.apiEndpoint);
const scopes = Array.from(new Set([
...gapic.v1.DatastoreClient.scopes,
...gapic.v1.DatastoreAdminClient.scopes,
]));
this.options = Object.assign({
libName: 'gccl',
libVersion: require('../../package.json').version,
scopes,
servicePath: this.baseUrl_,
port: typeof this.port_ === 'number' ? this.port_ : 443,
}, options);
const isUsingLocalhost = this.baseUrl_ &&
(this.baseUrl_.includes('localhost') ||
this.baseUrl_.includes('127.0.0.1') ||
this.baseUrl_.includes('::1'));
const isEmulatorVariableSet = process.env.DATASTORE_EMULATOR_HOST;
const isUsingEmulator = isUsingLocalhost || isEmulatorVariableSet;
if (this.customEndpoint_ && isUsingEmulator) {
this.options.sslCreds ??= grpc.credentials.createInsecure();
}
this.auth = new google_gax_1.GoogleAuth(this.options);
}
/**
* Create an aggregation query from a Query.
*
* @param {Query} query A Query object.
*/
createAggregationQuery(query) {
return new aggregate_2.AggregateQuery(query);
}
export(config, callback) {
const reqOpts = {
entityFilter: {},
...config,
};
if (reqOpts.bucket && reqOpts.outputUrlPrefix) {
throw new Error('Both `bucket` and `outputUrlPrefix` were provided.');
}
if (!reqOpts.outputUrlPrefix) {
if (typeof config.bucket === 'string') {
reqOpts.outputUrlPrefix = `gs://${config.bucket.replace('gs://', '')}`;
}
else if (typeof config.bucket === 'object') {
reqOpts.outputUrlPrefix = `gs://${config.bucket.name}`;
}
else {
throw new Error('A Bucket object or URL must be provided.');
}
}
if (reqOpts.kinds) {
if (typeof config.entityFilter === 'object') {
throw new Error('Both `entityFilter` and `kinds` were provided.');
}
reqOpts.entityFilter.kinds = reqOpts.kinds;
}
if (reqOpts.namespaces) {
if (typeof config.entityFilter === 'object') {
throw new Error('Both `entityFilter` and `namespaces` were provided.');
}
reqOpts.entityFilter.namespaceIds = reqOpts.namespaces;
}
delete reqOpts.bucket;
delete reqOpts.gaxOptions;
delete reqOpts.kinds;
delete reqOpts.namespaces;
this.request_({
client: 'DatastoreAdminClient',
method: 'exportEntities',
reqOpts: reqOpts,
gaxOpts: config.gaxOptions,
},
// eslint-disable-next-line @typescript-eslint/no-explicit-any
callback);
}
getIndexes(optionsOrCallback, cb) {
let options = typeof optionsOrCallback === 'object' ? optionsOrCallback : {};
const callback = typeof optionsOrCallback === 'function' ? optionsOrCallback : cb;
options = extend(true, {}, options);
const gaxOpts = options.gaxOptions || {};
const reqOpts = {
pageSize: gaxOpts.pageSize,
pageToken: gaxOpts.pageToken,
...options,
};
delete gaxOpts.pageSize;
delete gaxOpts.pageToken;
delete reqOpts.autoPaginate;
delete reqOpts.gaxOptions;
if (typeof options.autoPaginate === 'boolean' &&
typeof gaxOpts.autoPaginate === 'undefined') {
gaxOpts.autoPaginate = options.autoPaginate;
}
this.request_({
client: 'DatastoreAdminClient',
method: 'listIndexes',
reqOpts,
gaxOpts,
},
// eslint-disable-next-line @typescript-eslint/no-explicit-any
(err, ...resp) => {
let indexes = [];
if (resp[0]) {
indexes = resp[0].map((index) => {
const indexInstance = this.index(index.indexId);
indexInstance.metadata = index;
return indexInstance;
});
}
const nextQuery = resp[1] ? Object.assign(options, resp[1]) : null;
const apiResp = resp[2];
callback(err, indexes, nextQuery, apiResp);
});
}
/**
* Get all of the indexes in this project as a readable object stream.
*
* @param {GetIndexesOptions} [options] Configuration object. See
* {@link Datastore#getIndexes} for a complete list of options.
* @returns {ReadableStream<Index>}
*/
getIndexesStream(options) {
const { gaxOptions, ...reqOpts } = options || {};
return (0, stream_1.pipeline)(this.requestStream_({
client: 'DatastoreAdminClient',
method: 'listIndexesStream',
reqOpts,
gaxOpts: gaxOptions,
}), new stream_1.Transform({
objectMode: true,
transform: (index, enc, next) => {
const indexInstance = this.index(index.indexId);
indexInstance.metadata = index;
next(null, indexInstance);
},
}), () => { });
}
/**
* Gets the database id that all requests will be run against.
*
* @returns {string} The database id that the current client is set to that
* requests will run against.
*/
getDatabaseId() {
return this.options.databaseId;
}
getProjectId() {
return this.auth.getProjectId();
}
import(config, callback) {
const reqOpts = {
entityFilter: {},
...config,
};
if (config.file && config.inputUrl) {
throw new Error('Both `file` and `inputUrl` were provided.');
}
if (!reqOpts.inputUrl) {
if (typeof config.file === 'string') {
reqOpts.inputUrl = `gs://${config.file.replace('gs://', '')}`;
}
else if (typeof config.file === 'object') {
reqOpts.inputUrl = `gs://${config.file.bucket.name}/${config.file.name}`;
}
else {
throw new Error('An input URL must be provided.');
}
}
if (reqOpts.kinds) {
if (typeof config.entityFilter === 'object') {
throw new Error('Both `entityFilter` and `kinds` were provided.');
}
reqOpts.entityFilter.kinds = reqOpts.kinds;
}
if (reqOpts.namespaces) {
if (typeof config.entityFilter === 'object') {
throw new Error('Both `entityFilter` and `namespaces` were provided.');
}
reqOpts.entityFilter.namespaceIds = reqOpts.namespaces;
}
delete reqOpts.file;
delete reqOpts.gaxOptions;
delete reqOpts.kinds;
delete reqOpts.namespaces;
this.request_({
client: 'DatastoreAdminClient',
method: 'importEntities',
reqOpts: reqOpts,
gaxOpts: config.gaxOptions,
},
// eslint-disable-next-line @typescript-eslint/no-explicit-any
callback);
}
/**
* Get a reference to an Index.
*
* @param {string} id The index name or id.
* @returns {Index}
*/
index(id) {
return new index_class_1.Index(this, id);
}
insert(entities, callback) {
entities = arrify(entities)
.map(request_1.DatastoreRequest.prepareEntityObject_)
.map((x) => {
x.method = 'insert';
return x;
});
this.save(entities, callback);
}
save(entities, gaxOptionsOrCallback, cb) {
entities = arrify(entities);
const gaxOptions = typeof gaxOptionsOrCallback === 'object' ? gaxOptionsOrCallback : {};
const callback = typeof gaxOptionsOrCallback === 'function' ? gaxOptionsOrCallback : cb;
const insertIndexes = {};
const mutations = [];
const methods = {
insert: true,
update: true,
upsert: true,
};
// Iterate over the entity objects, build a proto from all keys and values,
// then place in the correct mutation array (insert, update, etc).
entities
.map(request_1.DatastoreRequest.prepareEntityObject_)
.forEach((entityObject, index) => {
const mutation = {};
let method = 'upsert';
if (entityObject.method) {
if (methods[entityObject.method]) {
method = entityObject.method;
}
else {
throw new Error('Method ' + entityObject.method + ' not recognized.');
}
}
if (!entity_1.entity.isKeyComplete(entityObject.key)) {
insertIndexes[index] = true;
}
(0, extendExcludeFromIndexes_1.extendExcludeFromIndexes)(entityObject);
const entityProto = (0, buildEntityProto_1.buildEntityProto)(entityObject);
entityProto.key = entity_1.entity.keyToKeyProto(entityObject.key);
mutation[method] = entityProto;
mutations.push(mutation);
});
const reqOpts = {
mutations,
};
function onCommit(err, resp) {
if (err || !resp) {
callback(err, resp);
return;
}
arrify(resp.mutationResults).forEach((result, index) => {
if (!result.key) {
return;
}
if (insertIndexes[index]) {
const id = entity_1.entity.keyFromKeyProto(result.key).id;
entities[index].key.id = id;
}
});
callback(null, resp);
}
if (this.id) {
this.requests_.push(reqOpts);
this.requestCallbacks_.push(onCommit);
return;
}
this.request_({
client: 'DatastoreClient',
method: 'commit',
reqOpts,
gaxOpts: gaxOptions,
}, onCommit);
}
update(entities, callback) {
entities = arrify(entities)
.map(request_1.DatastoreRequest.prepareEntityObject_)
.map((x) => {
x.method = 'update';
return x;
});
this.save(entities, callback);
}
upsert(entities, callback) {
entities = arrify(entities)
.map(request_1.DatastoreRequest.prepareEntityObject_)
.map((x) => {
x.method = 'upsert';
return x;
});
this.save(entities, callback);
}
/**
* Helper function to get a Datastore Double object.
*
* @param {number} value The double value.
* @returns {object}
*
* @example
* ```
* const {Datastore} = require('@google-cloud/datastore');
* const datastore = new Datastore();
* const threeDouble = datastore.double(3.0);
* ```
*/
static double(value) {
return new entity_1.entity.Double(value);
}
/**
* Helper function to get a Datastore Double object.
*
* @param {number} value The double value.
* @returns {object}
*/
double(value) {
return Datastore.double(value);
}
/**
* Helper function to check if something is a Datastore Double object.
*
* @param {*} value The double value.
* @returns {boolean}
*
* @example
* ```
* const {Datastore} = require('@google-cloud/datastore');
* const datastore = new Datastore();
* datastore.isDouble(0.42); // false
* datastore.isDouble(datastore.double(0.42)); // true
* ```
*/
static isDouble(value) {
return entity_1.entity.isDsDouble(value);
}
/**
* Helper function to check if something is a Datastore Double object.
*
* @param {*} value The double value.
* @returns {boolean}
*
*/
isDouble(value) {
return Datastore.isDouble(value);
}
/**
* Helper function to get a Datastore Geo Point object.
*
* @param {object} coordinates The coordinates value.
* @param {number} coordinates.latitude Latitudinal value.
* @param {number} coordinates.longitude Longitudinal value.
* @returns {object}
*
* @example
* ```
* const {Datastore} = require('@google-cloud/datastore');
* const datastore = new Datastore();
* const coordinates = {
* latitude: 40.6894,
* longitude: -74.0447
* };
*
* const geoPoint = datastore.geoPoint(coordinates);
*
* //-
* // List all companies that are located at 40.123 latitude
* // and -74.0447 longitude.
* //-
* const query = datastore.createQuery('Company');
* const companyQuery = query
* .filter('geoPoint.latitude', datastore.double(40.123))
* .filter('geoPoint.longitude', datastore.double(-74.0447));
* ```
*/
static geoPoint(coordinates) {
return new entity_1.entity.GeoPoint(coordinates);
}
/**
* Helper function to get a Datastore Geo Point object.
*
* @param {object} coordinates The coordinates value.
* @param {number} coordinates.latitude Latitudinal value.
* @param {number} coordinates.longitude Longitudinal value.
* @returns {object}
*
*/
geoPoint(coordinates) {
return Datastore.geoPoint(coordinates);
}
/**
* Helper function to check if something is a Datastore Geo Point object.
*
* @param {*} value The coordinates value.
* @returns {boolean}
*
* @example
* ```
* const {Datastore} = require('@google-cloud/datastore');
* const datastore = new Datastore();
* const coordinates = {
* latitude: 0,
* longitude: 0
* };
*
* datastore.isGeoPoint(coordinates); // false
* datastore.isGeoPoint(datastore.geoPoint(coordinates)); // true
* ```
*/
static isGeoPoint(value) {
return entity_1.entity.isDsGeoPoint(value);
}
/**
* Helper function to check if something is a Datastore Geo Point object.
*
* @param {*} value The coordinates value.
* @returns {boolean}
*
*/
isGeoPoint(value) {
return Datastore.isGeoPoint(value);
}
/**
* Helper function to get a Datastore Integer object.
*
* This is also useful when using an ID outside the bounds of a JavaScript
* Number object.
*
* @param {number} value The integer value.
* @returns {object}
*
* @example
* ```
* const {Datastore} = require('@google-cloud/datastore');
* const datastore = new Datastore();
* const sevenInteger = datastore.int(7);
*
* //-
* // Create an Int to support long Key IDs.
* //-
* const key = datastore.key([
* 'Kind',
* datastore.int('100000000000001234')
* ]);
* ```
*/
static int(value) {
return new entity_1.entity.Int(value);
}
/**
* Helper function to get a Datastore Integer object.
*
* This is also useful when using an ID outside the bounds of a JavaScript
* Number object.
*
* @param {number | int} value The integer value.
* @returns {object}
*
*/
int(value) {
return Datastore.int(value);
}
/**
* Helper function to check if something is a Datastore Integer object.
*
* @param {*} value The value to check
* @returns {boolean}
*
* @example
* ```
* const {Datastore} = require('@google-cloud/datastore');
* const datastore = new Datastore();
* datastore.isInt(42); // false
* datastore.isInt(datastore.int(42)); // true
* ```
*/
static isInt(value) {
return entity_1.entity.isDsInt(value);
}
/**
* Helper function to check if something is a Datastore Integer object.
*
* @param {*} value The value to check
* @returns {boolean}
*
*/
isInt(value) {
return Datastore.isInt(value);
}
/**
* Access the Key from an Entity object.
*
* @name Datastore.KEY
* @type {symbol}
*/
/**
* Access the Key from an Entity object.
*
* @name Datastore#KEY
* @type {symbol}
*/
static KEY = entity_1.entity.KEY_SYMBOL;
KEY = Datastore.KEY;
/**
* This is one of three values which may be returned from
* {@link Datastore#runQuery}, {@link Transaction#runQuery}, and
* {@link Query#run} as `info.moreResults`.
*
* There *may* be more results after the specified end cursor.
*
* @type {string}
*/
static MORE_RESULTS_AFTER_CURSOR = 'MORE_RESULTS_AFTER_CURSOR';
MORE_RESULTS_AFTER_CURSOR = Datastore.MORE_RESULTS_AFTER_CURSOR;
/**
* This is one of three values which may be returned from
* {@link Datastore#runQuery}, {@link Transaction#runQuery}, and
* {@link Query#run} as `info.moreResults`.
*
* There *may* be more results after the specified limit.
*
* @type {string}
*/
static MORE_RESULTS_AFTER_LIMIT = 'MORE_RESULTS_AFTER_LIMIT';
MORE_RESULTS_AFTER_LIMIT = Datastore.MORE_RESULTS_AFTER_LIMIT;
/**
* This is one of three values which may be returned from
* {@link Datastore#runQuery}, {@link Transaction#runQuery}, and
* {@link Query#run} as `info.moreResults`.
*
* There are no more results left to query for.
*
* @type {string}
*/
static NO_MORE_RESULTS = 'NO_MORE_RESULTS';
NO_MORE_RESULTS = Datastore.NO_MORE_RESULTS;
createQuery(namespaceOrKind, kind) {
let namespace = namespaceOrKind;
if (!kind) {
kind = namespaceOrKind;
namespace = this.namespace;
}
return new query_1.Query(this, namespace, arrify(kind));
}
key(options) {
const keyOptions = is.object(options)
? options
: {
namespace: this.namespace,
path: arrify(options),
};
return new entity_1.entity.Key(keyOptions);
}
/**
* Helper function to check if something is a Datastore Key object.
*
* @param {*} value Value to compare property to.
* @returns {boolean}
*
* @example
* ```
* const {Datastore} = require('@google-cloud/datastore');
* const datastore = new Datastore();
* datastore.isKey({path: ['Company', 123]}); // false
* datastore.isKey(datastore.key(['Company', 123])); // true
* ```
*/
static isKey(value) {
return entity_1.entity.isDsKey(value);
}
isKey(value) {
return Datastore.isKey(value);
}
keyToLegacyUrlSafe(key, locationPrefixOrCallback, callback) {
const locationPrefix = typeof locationPrefixOrCallback === 'string'
? locationPrefixOrCallback
: '';
callback =
typeof locationPrefixOrCallback === 'function'
? locationPrefixOrCallback
: callback;
this.auth.getProjectId((err, projectId) => {
if (err) {
callback(err);
return;
}
callback(null, urlSafeKey.legacyEncode(projectId, key, locationPrefix));
});
}
/**
* Helper to convert URL safe key string to entity key object
*
* This is intended to work with the "legacy" representation of a
* datastore "Key" used within Google App Engine (a so-called "Reference").
*
* @param {entity.Key} key Entity key object.
* @param {string} locationPrefix Optional .
* The location prefix of an App Engine project ID.
* Often this value is 's~', but may also be 'e~', or other location prefixes
* currently unknown.
* @returns {string} Created urlsafe key.
*
* @example
* ```
* const {Datastore} = require('@google-cloud/datastore');
* const datastore = new Datastore();
* const urlSafeKey = 'ag9ncmFzcy1jbHVtcC00NzlyEwsSB0NvbXBhbnkiBkdvb2dsZQw';
*
* datastore.keyFromLegacyUrlsafe(key);
*
* ```
*/
keyFromLegacyUrlsafe(key) {
return urlSafeKey.legacyDecode(key);
}
/**
* Create a new Transaction object.
*
* @param {object} [options] Configuration object.
* @param {string} [options.id] The ID of a previously run transaction.
* @param {boolean} [options.readOnly=false] A read-only transaction cannot
* modify entities.
* @returns {Transaction}
*
* @example
* ```
* const {Datastore} = require('@google-cloud/datastore');
* const datastore = new Datastore();
* const transaction = datastore.transaction();
* ```
*/
transaction(options) {
return new transaction_1.Transaction(this, options);
}
/**
* Determine the appropriate endpoint to use for API requests. If not
* explicitly defined, check for the "DATASTORE_EMULATOR_HOST" environment
* variable, used to connect to a local Datastore server.
*
* @private
*
* @param {string} customApiEndpoint Custom API endpoint.
*/
determineBaseUrl_(customApiEndpoint) {
let baseUrl = this.defaultBaseUrl_;
const leadingProtocol = new RegExp('^https*://');
const trailingSlashes = new RegExp('/*$');
const port = new RegExp(':(\\d+)');
if (customApiEndpoint) {
baseUrl = customApiEndpoint;
this.customEndpoint_ = true;
}
else if (process.env.DATASTORE_EMULATOR_HOST) {
baseUrl = process.env.DATASTORE_EMULATOR_HOST;
this.customEndpoint_ = true;
}
if (port.test(baseUrl)) {
this.port_ = Number(baseUrl.match(port)[1]);
}
this.baseUrl_ = baseUrl
.replace(leadingProtocol, '')
.replace(port, '')
.replace(trailingSlashes, '');
}
/**
* {@link DatastoreRequest} class.
*
* @name Datastore.DatastoreRequest
* @see DatastoreRequest
* @type {constructor}
*/
DatastoreRequest = request_1.DatastoreRequest;
/**
* {@link Query} class.
*
* @name Datastore.Query
* @see Query
* @type {constructor}
*/
Query = query_1.Query;
/**
* {@link Transaction} class.
*
* @name Datastore.Transaction
* @see Transaction
* @type {constructor}
*/
Transaction = transaction_1.Transaction;
}
exports.Datastore = Datastore;
/*! Developer Documentation
*
* All async methods (except for streams) will return a Promise in the event
* that a callback is omitted.
*/
(0, promisify_1.promisifyAll)(Datastore, {
exclude: [
'createAggregationQuery',
'double',
'isDouble',
'geoPoint',
'getDatabaseId',
'getProjectId',
'isGeoPoint',
'index',
'int',
'isInt',
'createQuery',
'key',
'isKey',
'keyFromLegacyUrlsafe',
'transaction',
],
});
/**
* The default export of the `@google-cloud/datastore` package is the
* {@link Datastore} class.
*
* See the {@link Datastore} class for client methods and configuration options.
*
* @module {Datastore} @google-cloud/datastore
* @alias nodejs-datastore
*
* @example Install the client library with <a href="https://www.npmjs.com/">npm</a>:
* ```
* npm install --save
* ```
* @google-cloud/datastore
*
* @example Import the client library
* ```
* const {Datastore} = require('@google-cloud/datastore');
*
* ```
* @example Create a client that uses <a href="https://cloud.google.com/docs/authentication/production#providing_credentials_to_your_application">Application Default Credentials (ADC)</a>:
* ```
* const datastore = new Datastore();
*
* ```
* @example Create a client with <a href="https://cloud.google.com/docs/authentication/production#obtaining_and_providing_service_account_credentials_manually">explicit credentials</a>:
* ```
* const datastore = new Datastore({ projectId:
* 'your-project-id', keyFilename: '/path/to/keyfile.json'
* });
*
* ```
* @example <caption>include:samples/quickstart.js</caption>
* region_tag:datastore_quickstart
* Full quickstart example:
*/
/**
* @name Datastore.v1
* @see v1.DatastoreClient
* @type {object}
* @property {constructor} DatastoreClient
* Reference to {@link v1.DatastoreClient}.
*/
/**
* @name module:@google-cloud/datastore.v1
* @see v1.DatastoreClient
* @type {object}
* @property {constructor} DatastoreClient
* Reference to {@link v1.DatastoreClient}.
*/
module.exports.v1 = gapic.v1;
const v1 = gapic.v1;
exports.v1 = v1;
var v1_1 = require("./v1");
Object.defineProperty(exports, "DatastoreClient", { enumerable: true, get: function () { return v1_1.DatastoreClient; } });
Object.defineProperty(exports, "DatastoreAdminClient", { enumerable: true, get: function () { return v1_1.DatastoreAdminClient; } });
//# sourceMappingURL=index.js.map
;