@google-cloud/datastore
Version:
Cloud Datastore Client Library for Node.js
556 lines (555 loc) • 20.5 kB
TypeScript
/*!
* Copyright 2014 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.
*/
import { CallOptions } from 'google-gax';
import { google } from '../protos/protos';
import { Datastore, TransactionOptions } from '.';
import { Entities, Entity, entity } from './entity';
import { Query, RunQueryCallback, RunQueryOptions, RunQueryResponse } from './query';
import { CommitCallback, CommitResponse, CreateReadStreamOptions, DatastoreRequest, GetCallback, GetResponse, RequestCallback } from './request';
import { AggregateQuery } from './aggregate';
/**
* A transaction is a set of Datastore operations on one or more entities. Each
* transaction is guaranteed to be atomic, which means that transactions are
* never partially applied. Either all of the operations in the transaction are
* applied, or none of them are applied.
*
* @see {@link https://cloud.google.com/datastore/docs/concepts/transactions| Transactions Reference}
*
* @class
* @extends {Request}
* @param {Datastore} datastore A Datastore instance.
* @mixes module:datastore/request
*
* @example
* ```
* const {Datastore} = require('@google-cloud/datastore');
* const datastore = new Datastore();
* const transaction = datastore.transaction();
* ```
*/
declare class Transaction extends DatastoreRequest {
#private;
namespace?: string;
readOnly: boolean;
request: Function;
modifiedEntities_: ModifiedEntities;
skipCommit?: boolean;
constructor(datastore: Datastore, options?: TransactionOptions);
/*! Developer Documentation
*
* Below, we override two methods that we inherit from DatastoreRequest:
* `delete` and `save`. This is done because:
*
* A) the documentation needs to be different for a transactional save, and
* B) we build up a "modifiedEntities_" array on this object, used to build
* the final commit request with.
*/
/**
* Commit the remote transaction and finalize the current transaction
* instance.
*
* If the commit request fails, we will automatically rollback the
* transaction.
*
* @param {CallOptions | https://googleapis.github.io/gax-nodejs/global.html#CallOptions} [gaxOptions] Request configuration options.
* @param {function} callback The callback function.
* @param {?error} callback.err An error returned while making this request.
* If the commit fails, we automatically try to rollback the transaction
* (see {module:datastore/transaction#rollback}).
* @param {object} callback.apiResponse The full API response.
*
* @example
* ```
* const {Datastore} = require('@google-cloud/datastore');
* const datastore = new Datastore();
* const transaction = datastore.transaction();
*
* transaction.commit((err, apiResponse) => {
* if (err) {
* // Transaction could not be committed.
* }
* });
*
* //-
* // If the callback is omitted, we'll return a Promise.
* //-
* transaction.commit().then((data) => {
* const apiResponse = data[0];
* });
* ```
*/
commit(gaxOptions?: CallOptions): Promise<CommitResponse>;
/**
* @param {object} [gaxOptions] Request configuration options, outlined here:
* https://googleapis.github.io/gax-nodejs/global.html#CallOptions.
* @param {function} callback The callback function.
* @param {?error} callback.err An error returned while making this request.
* If the commit fails, we automatically try to rollback the transaction
* (see {module:datastore/transaction#rollback}).
* @param {object} callback.apiResponse The full API response.
*/
commit(callback: CommitCallback): void;
commit(gaxOptions: CallOptions, callback: CommitCallback): void;
/**
* Create a query for the specified kind. See {module:datastore/query} for all
* of the available methods.
*
* @see {@link https://cloud.google.com/datastore/docs/concepts/queries| Datastore Queries}
*
* @see {@link Query}
*
* @param {string} [namespace] Namespace.
* @param {string} kind The kind to query.
* @returns {Query}
*
* @example
* ```
* const {Datastore} = require('@google-cloud/datastore');
* const datastore = new Datastore();
* const transaction = datastore.transaction();
*
* // Run the query inside the transaction.
* transaction.run((err) => {
* if (err) {
* // Error handling omitted.
* }
* const ancestorKey = datastore.key(['ParentCompany', 'Alphabet']);
*
* const query = transaction.createQuery('Company')
* .hasAncestor(ancestorKey);
*
* query.run((err, entities) => {
* if (err) {
* // Error handling omitted.
* }
*
* transaction.commit((err) => {
* if (!err) {
* // Transaction committed successfully.
* }
* });
* });
* });
*
* // Run the query inside the transaction.with namespace
* transaction.run((err) => {
* if (err) {
* // Error handling omitted.
* }
* const ancestorKey = datastore.key(['ParentCompany', 'Alphabet']);
*
* const query = transaction.createQuery('CompanyNamespace', 'Company')
* .hasAncestor(ancestorKey);
*
* query.run((err, entities) => {
* if (err) {
* // Error handling omitted.
* }
*
* transaction.commit((err) => {
* if (!err) {
* // Transaction committed successfully.
* }
* });
* });
* });
* ```
*/
createQuery(kind?: string): Query;
createQuery(kind?: string[]): Query;
createQuery(namespace: string, kind: string): Query;
createQuery(namespace: string, kind: string[]): Query;
/**
* Create an aggregation query from the query specified. See {module:datastore/query} for all
* of the available methods.
*
* @param {Query} query A Query object
*/
createAggregationQuery(query: Query): AggregateQuery;
/**
* Delete all entities identified with the specified key(s) in the current
* transaction.
*
* @param {Key|Key[]} key Datastore key object(s).
*
* @example
* ```
* const {Datastore} = require('@google-cloud/datastore');
* const datastore = new Datastore();
* const transaction = datastore.transaction();
*
* transaction.run((err) => {
* if (err) {
* // Error handling omitted.
* }
*
* // Delete a single entity.
* transaction.delete(datastore.key(['Company', 123]));
*
* // Delete multiple entities at once.
* transaction.delete([
* datastore.key(['Company', 123]),
* datastore.key(['Product', 'Computer'])
* ]);
*
* transaction.commit((err) => {
* if (!err) {
* // Transaction committed successfully.
* }
* });
* });
* ```
*/
delete(entities?: Entities): any;
/**
* This function calls get on the super class. If the transaction
* has not been started yet then the transaction is started before the
* get call is made.
*
* @param {Key|Key[]} keys Datastore key object(s).
* @param {object} [options] Optional configuration.
* @param {function} callback The callback function.
*
*/
get(keys: entity.Key | entity.Key[], options?: CreateReadStreamOptions): Promise<GetResponse>;
get(keys: entity.Key | entity.Key[], callback: GetCallback): void;
get(keys: entity.Key | entity.Key[], options: CreateReadStreamOptions, callback: GetCallback): void;
/**
* Maps to {@link https://cloud.google.com/nodejs/docs/reference/datastore/latest/datastore/transaction#_google_cloud_datastore_Transaction_save_member_1_|Datastore#save}, forcing the method to be `insert`.
*
* @param {object|object[]} entities Datastore key object(s).
* @param {Key} entities.key Datastore key object.
* @param {string[]} [entities.excludeFromIndexes] Exclude properties from
* indexing using a simple JSON path notation. See the examples in
* {@link Datastore#save} to see how to target properties at different
* levels of nesting within your entity.
* @param {object} entities.data Data to save with the provided key.
*/
insert(entities: Entities): void;
/**
* Reverse a transaction remotely and finalize the current transaction
* instance.
*
* @param {object} [gaxOptions] Request configuration options, outlined here:
* https://googleapis.github.io/gax-nodejs/global.html#CallOptions.
* @param {function} callback The callback function.
* @param {?error} callback.err An error returned while making this request.
* @param {object} callback.apiResponse The full API response.
*
* @example
* ```
* const {Datastore} = require('@google-cloud/datastore');
* const datastore = new Datastore();
* const transaction = datastore.transaction();
*
* transaction.run((err) => {
* if (err) {
* // Error handling omitted.
* }
*
* transaction.rollback((err) => {
* if (!err) {
* // Transaction rolled back successfully.
* }
* });
* });
*
* //-
* // If the callback is omitted, we'll return a Promise.
* //-
* transaction.rollback().then((data) => {
* const apiResponse = data[0];
* });
* ```
*/
rollback(callback: RollbackCallback): void;
rollback(gaxOptions?: CallOptions): Promise<RollbackResponse>;
rollback(gaxOptions: CallOptions, callback: RollbackCallback): void;
/**
* Begin a remote transaction. In the callback provided, run your
* transactional commands.
*
* @param {object} [options] Configuration object.
* @param {object} [options.gaxOptions] Request configuration options, outlined
* here: https://googleapis.github.io/gax-nodejs/global.html#CallOptions.
* @param {boolean} [options.readOnly=false] A read-only transaction cannot
* modify entities.
* @param {string} [options.transactionId] The ID of a previous transaction.
* @param {function} callback The function to execute within the context of
* a transaction.
* @param {?error} callback.err An error returned while making this request.
* @param {Transaction} callback.transaction This transaction
* instance.
* @param {object} callback.apiResponse The full API response.
*
* @example
* ```
* const {Datastore} = require('@google-cloud/datastore');
* const datastore = new Datastore();
* const transaction = datastore.transaction();
*
* transaction.run((err, transaction) => {
* // Perform Datastore transactional operations.
* const key = datastore.key(['Company', 123]);
*
* transaction.get(key, (err, entity) => {
* entity.name = 'Google';
*
* transaction.save({
* key: key,
* data: entity
* });
*
* transaction.commit((err) => {
* if (!err) {
* // Data saved successfully.
* }
* });
* });
* });
*
* //-
* // If the callback is omitted, we'll return a Promise.
* //-
* transaction.run().then((data) => {
* const transaction = data[0];
* const apiResponse = data[1];
* });
* ```
*/
run(options?: RunOptions): Promise<RunResponse>;
run(callback: RunCallback): void;
run(options: RunOptions, callback: RunCallback): void;
/**
*
* This function calls runAggregationQuery on the super class. If the transaction
* has not been started yet then the transaction is started before the
* runAggregationQuery call is made.
*
* @param {AggregateQuery} [query] AggregateQuery object.
* @param {RunQueryOptions} [options] Optional configuration
* @param {function} [callback] The callback function. If omitted, a promise is
* returned.
*
**/
runAggregationQuery(query: AggregateQuery, options?: RunQueryOptions): Promise<RunQueryResponse>;
runAggregationQuery(query: AggregateQuery, options: RunQueryOptions, callback: RequestCallback): void;
runAggregationQuery(query: AggregateQuery, callback: RequestCallback): void;
/**
* This function calls runQuery on the super class. If the transaction
* has not been started yet then the transaction is started before the
* runQuery call is made.
*
* @param {Query} query A Query object
* @param {object} [options] Optional configuration.
* @param {function} [callback] The callback function. If omitted, a readable
* stream instance is returned.
*
*/
runQuery(query: Query, options?: RunQueryOptions): Promise<RunQueryResponse>;
runQuery(query: Query, options: RunQueryOptions, callback: RunQueryCallback): void;
runQuery(query: Query, callback: RunQueryCallback): void;
/**
* Insert or update the specified object(s) in the current transaction. If a
* key is incomplete, its associated object is inserted and the original Key
* object is updated to contain the generated ID.
*
* This method will determine the correct Datastore method to execute
* (`upsert`, `insert`, or `update`) by using the key(s) provided. For
* example, if you provide an incomplete key (one without an ID), the request
* will create a new entity and have its ID automatically assigned. If you
* provide a complete key, the entity will be updated with the data specified.
*
* By default, all properties are indexed. To prevent a property from being
* included in *all* indexes, you must supply an `excludeFromIndexes` array.
* See below for an example.
*
* @param {object|object[]} entities Datastore key object(s).
* @param {Key} entities.key Datastore key object.
* @param {string[]} [entities.excludeFromIndexes] Exclude properties from
* indexing using a simple JSON path notation. See the example below to
* see how to target properties at different levels of nesting within your
* entity.
* @param {object} entities.data Data to save with the provided key.
*
* @example
* ```
* <caption>Save a single entity.</caption>
* const {Datastore} = require('@google-cloud/datastore');
* const datastore = new Datastore();
* const transaction = datastore.transaction();
*
* // Notice that we are providing an incomplete key. After the transaction is
* // committed, the Key object held by the `key` variable will be populated
* // with a path containing its generated ID.
* //-
* const key = datastore.key('Company');
*
* transaction.run((err) => {
* if (err) {
* // Error handling omitted.
* }
*
* transaction.save({
* key: key,
* data: {
* rating: '10'
* }
* });
*
* transaction.commit((err) => {
* if (!err) {
* // Data saved successfully.
* }
* });
* });
*
* ```
* @example
* ```
* const {Datastore} = require('@google-cloud/datastore');
* const datastore = new Datastore();
* const transaction = datastore.transaction();
*
* // Use an array, `excludeFromIndexes`, to exclude properties from indexing.
* // This will allow storing string values larger than 1500 bytes.
*
* transaction.run((err) => {
* if (err) {
* // Error handling omitted.
* }
*
* transaction.save({
* key: key,
* excludeFromIndexes: [
* 'description',
* 'embeddedEntity.description',
* 'arrayValue[].description'
* ],
* data: {
* description: 'Long string (...)',
* embeddedEntity: {
* description: 'Long string (...)'
* },
* arrayValue: [
* {
* description: 'Long string (...)'
* }
* ]
* }
* });
*
* transaction.commit((err) => {
* if (!err) {
* // Data saved successfully.
* }
* });
* });
*
* ```
* @example
* ```
* <caption>Save multiple entities at once.</caption>
* const {Datastore} = require('@google-cloud/datastore');
* const datastore = new Datastore();
* const transaction = datastore.transaction();
* const companyKey = datastore.key(['Company', 123]);
* const productKey = datastore.key(['Product', 'Computer']);
*
* transaction.run((err) => {
* if (err) {
* // Error handling omitted.
* }
*
* transaction.save([
* {
* key: companyKey,
* data: {
* HQ: 'Dallas, TX'
* }
* },
* {
* key: productKey,
* data: {
* vendor: 'Dell'
* }
* }
* ]);
*
* transaction.commit((err) => {
* if (!err) {
* // Data saved successfully.
* }
* });
* });
* ```
*/
save(entities: Entities): void;
/**
* Maps to {@link https://cloud.google.com/nodejs/docs/reference/datastore/latest/datastore/transaction#_google_cloud_datastore_Transaction_save_member_1_|Datastore#save}, forcing the method to be `update`.
*
* @param {object|object[]} entities Datastore key object(s).
* @param {Key} entities.key Datastore key object.
* @param {string[]} [entities.excludeFromIndexes] Exclude properties from
* indexing using a simple JSON path notation. See the examples in
* {@link Datastore#save} to see how to target properties at different
* levels of nesting within your entity.
* @param {object} entities.data Data to save with the provided key.
*/
update(entities: Entities): void;
/**
* Maps to {@link https://cloud.google.com/nodejs/docs/reference/datastore/latest/datastore/transaction#_google_cloud_datastore_Transaction_save_member_1_|Datastore#save}, forcing the method to be `upsert`.
*
* @param {object|object[]} entities Datastore key object(s).
* @param {Key} entities.key Datastore key object.
* @param {string[]} [entities.excludeFromIndexes] Exclude properties from
* indexing using a simple JSON path notation. See the examples in
* {@link Datastore#save} to see how to target properties at different
* levels of nesting within your entity.
* @param {object} entities.data Data to save with the provided key.
*/
upsert(entities: Entities): void;
}
export type ModifiedEntities = Array<{
entity: {
key: Entity;
};
method: string;
args: Entity[];
}>;
export type RunResponse = [
Transaction,
google.datastore.v1.IBeginTransactionResponse
];
export interface RunCallback {
(error: Error | null, transaction: Transaction | null, response?: google.datastore.v1.IBeginTransactionResponse): void;
}
export interface RollbackCallback {
(error: Error | null, response?: google.datastore.v1.IRollbackResponse): void;
}
export type RollbackResponse = [google.datastore.v1.IRollbackResponse];
export interface RunOptions {
readOnly?: boolean;
transactionId?: string;
transactionOptions?: TransactionOptions;
gaxOptions?: CallOptions;
}
/**
* Reference to the {@link Transaction} class.
* @name module:@google-cloud/datastore.Transaction
* @see Transaction
*/
export { Transaction };