@google-cloud/spanner
Version:
Cloud Spanner Client Library for Node.js
1,347 lines • 63 kB
TypeScript
/*!
* Copyright 2016 Google Inc. All Rights Reserved.
*
* 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 { PreciseDate } from '@google-cloud/precise-date';
import Long = require('long');
import { EventEmitter } from 'events';
import { grpc, CallOptions } from 'google-gax';
import { common as p } from 'protobufjs';
import { Readable } from 'stream';
import { Json, JSONOptions, Type, Value } from './codec';
import { PartialResultStream, ResumeToken, Row } from './partial-result-stream';
import { Session } from './session';
import { Key } from './table';
import { google as spannerClient } from '../protos/protos';
import { NormalCallback } from './common';
import { google } from '../protos/protos';
import IQueryOptions = google.spanner.v1.ExecuteSqlRequest.IQueryOptions;
import IRequestOptions = google.spanner.v1.IRequestOptions;
import { Spanner } from '.';
import { ObservabilityOptions, traceConfig } from './instrument';
import { RunTransactionOptions } from './transaction-runner';
export type Rows = Array<Row | Json>;
export interface TimestampBounds {
strong?: boolean;
minReadTimestamp?: PreciseDate | spannerClient.protobuf.ITimestamp;
maxStaleness?: number | spannerClient.protobuf.IDuration;
readTimestamp?: PreciseDate | spannerClient.protobuf.ITimestamp;
exactStaleness?: number | spannerClient.protobuf.IDuration;
returnReadTimestamp?: boolean;
}
export interface BatchWriteOptions {
requestOptions?: Pick<IRequestOptions, 'priority' | 'transactionTag'>;
gaxOptions?: CallOptions;
excludeTxnFromChangeStreams?: boolean;
}
export interface RequestOptions {
json?: boolean;
jsonOptions?: JSONOptions;
gaxOptions?: CallOptions;
maxResumeRetries?: number;
/**
* An object where column names as keys and custom objects as corresponding
* values for deserialization. This is only needed for proto columns
* where deserialization logic is on user-specific code. When provided,
* the custom object enables deserialization of backend-received column data.
* If not provided, data remains serialized as buffer for Proto Messages and
* integer for Proto Enums.
*
* @example
* To obtain Proto Messages and Proto Enums as JSON objects, you must supply
* additional metadata. This metadata should include the protobufjs-cli
* generated proto message function and enum object. It encompasses the essential
* logic for proper data deserialization.
*
* Eg: To read data from Proto Columns in json format using DQL, you should pass
* columnsMetadata where key is the name of the column and value is the protobufjs-cli
* generated proto message function and enum object.
*
* const query = {
* sql: `SELECT SingerId,
* FirstName,
* LastName,
* SingerInfo,
* SingerGenre,
* SingerInfoArray,
* SingerGenreArray
* FROM Singers
* WHERE SingerId = 6`,
* columnsMetadata: {
* SingerInfo: music.SingerInfo,
* SingerInfoArray: music.SingerInfo,
* SingerGenre: music.Genre,
* SingerGenreArray: music.Genre,
* },
* };
*/
columnsMetadata?: object;
}
export interface CommitOptions {
requestOptions?: Pick<IRequestOptions, 'priority'>;
returnCommitStats?: boolean;
maxCommitDelay?: spannerClient.protobuf.IDuration;
gaxOptions?: CallOptions;
}
export interface Statement {
sql: string;
params?: {
[param: string]: Value;
};
types?: Type | {
[param: string]: Value;
};
paramTypes?: {
[k: string]: google.spanner.v1.Type;
} | null;
}
export interface ExecuteSqlRequest extends Statement, RequestOptions {
resumeToken?: ResumeToken;
queryMode?: spannerClient.spanner.v1.ExecuteSqlRequest.QueryMode;
partitionToken?: Uint8Array | string;
seqno?: number;
queryOptions?: IQueryOptions;
requestOptions?: Omit<IRequestOptions, 'transactionTag'>;
dataBoostEnabled?: boolean | null;
directedReadOptions?: google.spanner.v1.IDirectedReadOptions;
}
export interface KeyRange {
startClosed?: Value[];
startOpen?: Value[];
endClosed?: Value[];
endOpen?: Value[];
}
export interface ReadRequest extends RequestOptions {
table?: string;
index?: string;
columns?: string[] | null;
keys?: string[] | string[][];
ranges?: KeyRange[];
keySet?: spannerClient.spanner.v1.IKeySet | null;
limit?: number | Long | string | null;
resumeToken?: Uint8Array | null;
partitionToken?: Uint8Array | null;
requestOptions?: Omit<IRequestOptions, 'transactionTag'>;
dataBoostEnabled?: boolean | null;
directedReadOptions?: google.spanner.v1.IDirectedReadOptions;
}
export interface BatchUpdateError extends grpc.ServiceError {
rowCounts: number[];
}
export type CommitRequest = spannerClient.spanner.v1.ICommitRequest;
export type BatchUpdateResponse = [
number[],
spannerClient.spanner.v1.ExecuteBatchDmlResponse
];
export type BeginResponse = [spannerClient.spanner.v1.ITransaction];
export type BeginTransactionCallback = NormalCallback<spannerClient.spanner.v1.ITransaction>;
export type CommitResponse = [spannerClient.spanner.v1.ICommitResponse];
export type ReadResponse = [Rows];
export type RunResponse = [
Rows,
spannerClient.spanner.v1.ResultSetStats,
spannerClient.spanner.v1.ResultSetMetadata
];
export type RunUpdateResponse = [number];
export interface BatchUpdateOptions {
requestOptions?: Omit<IRequestOptions, 'transactionTag'>;
gaxOptions?: CallOptions;
}
export interface BatchUpdateCallback {
(err: null | BatchUpdateError, rowCounts: number[], response?: spannerClient.spanner.v1.ExecuteBatchDmlResponse): void;
}
export interface BatchUpdateOptions {
requestOptions?: Omit<IRequestOptions, 'transactionTag'>;
gaxOptions?: CallOptions;
}
export type ReadCallback = NormalCallback<Rows>;
export interface RunCallback {
(err: null | grpc.ServiceError, rows: Rows, stats: spannerClient.spanner.v1.ResultSetStats, metadata?: spannerClient.spanner.v1.ResultSetMetadata): void;
}
export interface RunUpdateCallback {
(err: null | grpc.ServiceError, rowCount: number): void;
}
export type CommitCallback = NormalCallback<spannerClient.spanner.v1.ICommitResponse>;
/**
* @typedef {object} TimestampBounds
* @property {boolean} [strong=true] Read at a timestamp where all previously
* committed transactions are visible.
* @property {external:PreciseDate|google.protobuf.Timestamp} [minReadTimestamp]
* Executes all reads at a `timestamp >= minReadTimestamp`.
* @property {number|google.protobuf.Timestamp} [maxStaleness] Read data at a
* `timestamp >= NOW - maxStaleness` (milliseconds).
* @property {external:PreciseDate|google.protobuf.Timestamp} [readTimestamp]
* Executes all reads at the given timestamp.
* @property {number|google.protobuf.Timestamp} [exactStaleness] Executes all
* reads at a timestamp that is `exactStaleness` (milliseconds) old.
* @property {boolean} [returnReadTimestamp=true] When true,
* {@link Snapshot#readTimestamp} will be populated after
* {@link Snapshot#begin} is called.
*/
/**
* This transaction type provides guaranteed consistency across several reads,
* but does not allow writes. Snapshot read-only transactions can be configured
* to read at timestamps in the past.
*
* When finished with the Snapshot, call {@link Snapshot#end} to
* release the underlying {@link Session}. Failure to do so can result in a
* Session leak.
*
* **This object is created and returned from {@link Database#getSnapshot}.**
*
* @class
* @hideconstructor
*
* @see [Timestamp Bounds API Documentation](https://cloud.google.com/spanner/docs/timestamp-bounds)
*
* @example
* ```
* const {Spanner} = require('@google-cloud/spanner');
* const spanner = new Spanner();
*
* const instance = spanner.instance('my-instance');
* const database = instance.database('my-database');
*
* const timestampBounds = {
* strong: true
* };
*
* database.getSnapshot(timestampBounds, (err, transaction) => {
* if (err) {
* // Error handling omitted.
* }
*
* // It should be called when the snapshot finishes.
* transaction.end();
* });
* ```
*/
export declare class Snapshot extends EventEmitter {
protected _options: spannerClient.spanner.v1.ITransactionOptions;
protected _seqno: number;
protected _waitingRequests: Array<() => void>;
protected _inlineBeginStarted: any;
protected _useInRunner: boolean;
id?: Uint8Array | string;
ended: boolean;
metadata?: spannerClient.spanner.v1.ITransaction;
readTimestamp?: PreciseDate;
readTimestampProto?: spannerClient.protobuf.ITimestamp;
request: (config: {}, callback: Function) => void;
requestStream: (config: {}) => Readable;
session: Session;
queryOptions?: IQueryOptions;
commonHeaders_: {
[k: string]: string;
};
requestOptions?: Pick<IRequestOptions, 'transactionTag'>;
_observabilityOptions?: ObservabilityOptions;
_traceConfig: traceConfig;
protected _dbName?: string;
/**
* The transaction ID.
*
* @name Snapshot#id
* @type {?(string|Buffer)}
*/
/**
* Whether or not the transaction has ended. If true, make no further
* requests, and discard the transaction.
*
* @name Snapshot#ended
* @type {boolean}
*/
/**
* The raw transaction response object. It is populated after
* {@link Snapshot#begin} is called.
*
* @name Snapshot#metadata
* @type {?TransactionResponse}
*/
/**
* **Snapshot only**
* The timestamp at which all reads are performed.
*
* @name Snapshot#readTimestamp
* @type {?external:PreciseDate}
*/
/**
* **Snapshot only**
* The protobuf version of {@link Snapshot#readTimestamp}. This is useful if
* you require microsecond precision.
*
* @name Snapshot#readTimestampProto
* @type {?google.protobuf.Timestamp}
*/
/**
* @constructor
*
* @param {Session} session The parent Session object.
* @param {TimestampBounds} [options] Snapshot timestamp bounds.
* @param {QueryOptions} [queryOptions] Default query options to use when none
* are specified for a query.
*/
constructor(session: Session, options?: TimestampBounds, queryOptions?: IQueryOptions);
/**
* @typedef {object} TransactionResponse
* @property {string|Buffer} id The transaction ID.
* @property {?google.protobuf.Timestamp} readTimestamp For snapshot read-only
* transactions, the read timestamp chosen for the transaction.
*/
/**
* @typedef {array} TransactionBeginResponse
* @property {TransactionResponse} 0 The raw transaction object.
*/
/**
* @callback TransactionBeginCallback
* @param {?Error} err Request error, if any.
* @param {TransactionResponse} apiResponse The raw transaction object.
*/
/**
* Begin a new transaction. Typically, you need not call this unless
* manually creating transactions via {@link Session} objects.
*
* @see [BeginTransaction API Documentation](https://cloud.google.com/spanner/docs/reference/rpc/google.spanner.v1#google.spanner.v1.Spanner.BeginTransaction)
*
* @param {object} [gaxOptions] Request configuration options,
* See {@link https://googleapis.dev/nodejs/google-gax/latest/interfaces/CallOptions.html|CallOptions}
* for more details.
* @param {TransactionBeginCallback} [callback] Callback function.
* @returns {Promise<TransactionBeginResponse>}
*
* @example
* ```
* transaction.begin(function(err) {
* if (!err) {
* // transaction began successfully.
* }
* });
*
* ```
* @example If the callback is omitted, the function returns a Promise
* ```
* transaction.begin()
* .then(function(data) {
* const apiResponse = data[0];
* });
* ```
*/
begin(gaxOptions?: CallOptions): Promise<BeginResponse>;
begin(callback: BeginTransactionCallback): void;
begin(gaxOptions: CallOptions, callback: BeginTransactionCallback): void;
/**
* A KeyRange represents a range of rows in a table or index.
*
* A range has a start key and an end key. These keys can be open or closed,
* indicating if the range includes rows with that key.
*
* Keys are represented by an array of strings where the nth value in the list
* corresponds to the nth component of the table or index primary key.
*
* @typedef {object} KeyRange
* @property {string[]} [startClosed] If the start is closed, then the range
* includes all rows whose first key columns exactly match.
* @property {string[]} [startOpen] If the start is open, then the range
* excludes rows whose first key columns exactly match.
* @property {string[]} [endClosed] If the end is closed, then the range
* includes all rows whose first key columns exactly match.
* @property {string[]} [endOpen] If the end is open, then the range excludes
* rows whose first key columns exactly match.
*/
/**
* Read request options. This includes all standard ReadRequest options as
* well as several convenience properties.
*
* @see [StreamingRead API Documentation](https://cloud.google.com/spanner/docs/reference/rpc/google.spanner.v1#google.spanner.v1.Spanner.StreamingRead)
* @see [ReadRequest API Documentation](https://cloud.google.com/spanner/docs/reference/rpc/google.spanner.v1#google.spanner.v1.ReadRequest)
*
* @typedef {object} ReadRequest
* @property {string} table The name of the table in the database to be read.
* @property {string[]} columns The columns of the table to be returned for each
* row matching this query.
* @property {string[]|string[][]} keys The primary or index keys of the rows in this table to be
* yielded. If using a composite key, provide an array within this array.
* See the example below.
* @property {KeyRange[]} [ranges] An alternative to the keys property; this can
* be used to define a range of keys to be yielded.
* @property {string} [index] The name of an index on the table if a
* different index than the primary key should be used to determine which rows to return.
* @property {boolean} [json=false] Receive the rows as serialized objects. This
* is the equivalent of calling `toJSON()` on each row.
* @property {JSONOptions} [jsonOptions] Configuration options for the serialized
* objects.
* @property {object} [keySet] Defines a collection of keys and/or key ranges to
* read.
* @property {number} [limit] The number of rows to yield.
* @property {Buffer} [partitionToken]
* If present, results will be restricted to the specified partition
* previously created using PartitionRead(). There must be an exact
* match for the values of fields common to this message and the
* PartitionReadRequest message used to create this partition_token.
* @property {google.spanner.v1.RequestOptions} [requestOptions]
* Common options for this request.
* @property {google.spanner.v1.IDirectedReadOptions} [directedReadOptions]
* Indicates which replicas or regions should be used for non-transactional reads or queries.
* @property {object} [gaxOptions]
* Call options. See {@link https://googleapis.dev/nodejs/google-gax/latest/interfaces/CallOptions.html|CallOptions}
* for more details.
*/
/**
* Create a readable object stream to receive rows from the database using key
* lookups and scans.
*
* Wrapper around {@link v1.SpannerClient#streamingRead}.
*
* @see {@link v1.SpannerClient#streamingRead}
* @see [StreamingRead API Documentation](https://cloud.google.com/spanner/docs/reference/rpc/google.spanner.v1#google.spanner.v1.Spanner.StreamingRead)
* @see [ReadRequest API Documentation](https://cloud.google.com/spanner/docs/reference/rpc/google.spanner.v1#google.spanner.v1.ReadRequest)
*
* @fires PartialResultStream#response
* @fires PartialResultStream#stats
*
* @param {string} table The table to read from.
* @param {ReadRequest} query Configuration object. See official
* [`ReadRequest`](https://cloud.google.com/spanner/docs/reference/rpc/google.spanner.v1#google.spanner.v1.ReadRequest).
* API documentation.
* @returns {ReadableStream} A readable stream that emits rows.
*
* @example
* ```
* transaction.createReadStream('Singers', {
* keys: ['1'],
* columns: ['SingerId', 'name']
* })
* .on('error', function(err) {})
* .on('data', function(row) {
* // row = [
* // {
* // name: 'SingerId',
* // value: '1'
* // },
* // {
* // name: 'Name',
* // value: 'Eddie Wilson'
* // }
* // ]
* })
* .on('end', function() {
* // All results retrieved.
* });
*
* ```
* @example Provide an array for `query.keys` to read with a
* composite key.
* ```
* const query = {
* keys: [
* [
* 'Id1',
* 'Name1'
* ],
* [
* 'Id2',
* 'Name2'
* ]
* ],
* // ...
* };
* ```
*
* @example Rows are returned as an array of object arrays. Each
* object has a `name` and `value` property. To get a serialized object, call
* `toJSON()`.
* ```
* transaction.createReadStream('Singers', {
* keys: ['1'],
* columns: ['SingerId', 'name']
* })
* .on('error', function(err) {})
* .on('data', function(row) {
* // row.toJSON() = {
* // SingerId: '1',
* // Name: 'Eddie Wilson'
* // }
* })
* .on('end', function() {
* // All results retrieved.
* });
* ```
*
* @example Alternatively, set `query.json` to `true`, and this step
* will perform automatically.
* ```
* transaction.createReadStream('Singers', {
* keys: ['1'],
* columns: ['SingerId', 'name'],
* json: true,
* })
* .on('error', function(err) {})
* .on('data', function(row) {
* // row = {
* // SingerId: '1',
* // Name: 'Eddie Wilson'
* // }
* })
* .on('end', function() {
* // All results retrieved.
* });
* ```
*
* @example If you anticipate many results, you can end a stream
* early to prevent unnecessary processing and API requests.
* ```
* transaction.createReadStream('Singers', {
* keys: ['1'],
* columns: ['SingerId', 'name']
* })
* .on('data', function(row) {
* this.end();
* });
* ```
*/
createReadStream(table: string, request?: ReadRequest): PartialResultStream;
/**
* Let the client know you're done with a particular transaction. This should
* mainly be called for {@link Snapshot} objects, however in certain cases
* you may want to call them for {@link Transaction} objects as well.
*
* @example Calling `end` on a read only snapshot
* ```
* database.getSnapshot((err, transaction) => {
* if (err) {
* // Error handling omitted.
* }
*
* transaction.run('SELECT * FROM Singers', (err, rows) => {
* if (err) {
* // Error handling omitted.
* }
*
* // End the snapshot.
* transaction.end();
* });
* });
* ```
*
* @example Calling `end` on a read/write transaction
* ```
* database.runTransaction((err, transaction) => {
* if (err) {
* // Error handling omitted.
* }
*
* const query = 'UPDATE Account SET Balance = 1000 WHERE Key = 1';
*
* transaction.runUpdate(query, err => {
* if (err) {
* // In the event of an error, there would be nothing to rollback,
* so
* // instead of continuing, discard the
* transaction. transaction.end(); return;
* }
*
* transaction.commit(err => {});
* });
* });
* ```
*/
end(): void;
/**
* @typedef {array} ReadResponse
* @property {array[]} 0 Rows are returned as an array of object arrays. Each
* object has a `name` and `value` property. To get a serialized object,
* call `toJSON()`. Optionally, provide an options object to `toJSON()`
* specifying `wrapNumbers: true` to protect large integer values outside
* of the range of JavaScript Number. If set, FLOAT64 values are returned
* as {@link Spanner.Float} objects and INT64 values as {@link
* Spanner.Int}.
*/
/**
* @callback ReadCallback
* @param {?Error} err Request error, if any.
* @param {array[]} rows Rows are returned as an array of object arrays. Each
* object has a `name` and `value` property. To get a serialized object,
* call `toJSON()`. Optionally, provide an options object to `toJSON()`
* specifying `wrapNumbers: true` to protect large integer values outside
* of the range of JavaScript Number. If set, FLOAT64 values are returned
* as {@link Spanner.Float} objects and INT64 values as {@link
* Spanner.Int}.
*/
/**
* Performs a read request against the specified Table.
*
* Wrapper around {@link v1.SpannerClient#read}.
*
* @see {@link v1.SpannerClient#read}
*
* @param {string} table The table to read from.
* @param {ReadRequest} query Configuration object. See official
* [`ReadRequest`](https://cloud.google.com/spanner/docs/reference/rpc/google.spanner.v1#google.spanner.v1.ReadRequest).
* API documentation.
* @param {ReadCallback} [callback] Callback function.
* @returns {Promise<ReadResponse>}
*
* @example
* ```
* const query = {
* keys: ['1'],
* columns: ['SingerId', 'name']
* };
*
* transaction.read('Singers', query, function(err, rows) {
* if (err) {
* // Error handling omitted.
* }
*
* const firstRow = rows[0];
*
* // firstRow = [
* // {
* // name: 'SingerId',
* // value: '1'
* // },
* // {
* // name: 'Name',
* // value: 'Eddie Wilson'
* // }
* // ]
* });
*
* ```
* @example Provide an array for `query.keys` to read with a
* composite key.
* ```
* const query = {
* keys: [
* [
* 'Id1',
* 'Name1'
* ],
* [
* 'Id2',
* 'Name2'
* ]
* ],
* // ...
* };
* ```
*
* @example Rows are returned as an array of object arrays. Each
* object has a `name` and `value` property. To get a serialized object, call
* `toJSON()`.
* ```
* transaction.read('Singers', query, function(err, rows) {
* if (err) {
* // Error handling omitted.
* }
*
* const firstRow = rows[0];
*
* // firstRow.toJSON() = {
* // SingerId: '1',
* // Name: 'Eddie Wilson'
* // }
* });
* ```
*
* @example Alternatively, set `query.json` to `true`, and this step
* will perform automatically.
* ```
* query.json = true;
*
* transaction.read('Singers', query, function(err, rows) {
* if (err) {
* // Error handling omitted.
* }
*
* const firstRow = rows[0];
*
* // firstRow = {
* // SingerId: '1',
* // Name: 'Eddie Wilson'
* // }
* });
* ```
*/
read(table: string, request: ReadRequest): Promise<ReadResponse>;
read(table: string, callback: ReadCallback): void;
read(table: string, request: ReadRequest, callback: ReadCallback): void;
/**
* Execute a SQL statement on this database inside of a transaction.
*
* **Performance Considerations:**
*
* This method wraps the streaming method,
* {@link Snapshot#run} for your convenience. All rows are stored in memory
* before releasing to your callback. If you intend to receive a lot of
* results from your query, consider using the streaming method,
* so you can free each result from memory after consuming it.
*
* Wrapper around {@link v1.SpannerClient#executeStreamingSql}.
*
* @see {@link v1.SpannerClient#executeStreamingSql}
* @see [ExecuteStreamingSql API Documentation](https://cloud.google.com/spanner/docs/reference/rpc/google.spanner.v1#google.spanner.v1.Spanner.ExecuteStreamingSql)
* @see [ExecuteSqlRequest API Documentation](https://cloud.google.com/spanner/docs/reference/rpc/google.spanner.v1#google.spanner.v1.ExecuteSqlRequest)
*
* @param {string|ExecuteSqlRequest} query A SQL query or
* {@link ExecuteSqlRequest} object.
* @param {RunCallback} [callback] Callback function.
* @returns {Promise<RunResponse>}
*
* @example
* ```
* transaction.run(query, function(err, rows) {
* if (err) {
* // Error handling omitted.
* }
*
* // rows = [
* // {
* // SingerId: '1',
* // Name: 'Eddie Wilson'
* // }
* // ]
* });
*
* ```
* @example The SQL query string can contain parameter placeholders.
* A parameter placeholder consists of '@' followed by the parameter name.
* ```
* const query = {
* sql: 'SELECT * FROM Singers WHERE name = @name',
* params: {
* name: 'Eddie Wilson'
* }
* };
*
* transaction.run(query, function(err, rows) {
* if (err) {
* // Error handling omitted.
* }
* });
* ```
*
* @example If you need to enforce a specific param type, a types map
* can be provided. This is typically useful if your param value can be null.
* ```
* const query = {
* sql: 'SELECT * FROM Singers WHERE name = @name AND id = @id',
* params: {
* id: spanner.int(8),
* name: null
* },
* types: {
* id: 'int64',
* name: 'string'
* }
* };
*
* transaction.run(query, function(err, rows) {
* if (err) {
* // Error handling omitted.
* }
* });
* ```
*/
run(query: string | ExecuteSqlRequest): Promise<RunResponse>;
run(query: string | ExecuteSqlRequest, callback: RunCallback): void;
/**
* ExecuteSql request options. This includes all standard ExecuteSqlRequest
* options as well as several convenience properties.
*
* @see [Query Syntax](https://cloud.google.com/spanner/docs/query-syntax)
* @see [ExecuteSql API Documentation](https://cloud.google.com/spanner/docs/reference/rpc/google.spanner.v1#google.spanner.v1.Spanner.ExecuteSql)
*
* @typedef {object} ExecuteSqlRequest
* @property {string} resumeToken The token used to resume getting results.
* @property {google.spanner.v1.ExecuteSqlRequest.QueryMode} queryMode Query plan and
* execution statistics for the SQL statement that
* produced this result set.
* @property {string} partitionToken The partition token.
* @property {number} seqno The Sequence number. This option is used internally and will be overridden.
* @property {string} sql The SQL string.
* @property {google.spanner.v1.ExecuteSqlRequest.IQueryOptions} [queryOptions]
* Default query options to use with the database. These options will be
* overridden by any query options set in environment variables or that
* are specified on a per-query basis.
* @property {google.spanner.v1.IRequestOptions} requestOptions The request options to include
* with the commit request.
* @property {Object.<string, *>} [params] A map of parameter names to values.
* @property {Object.<string, (string|ParamType)>} [types] A map of parameter
* names to types. If omitted the client will attempt to guess for all
* non-null values.
* @property {boolean} [json=false] Receive the rows as serialized objects. This
* is the equivalent of calling `toJSON()` on each row.
* @property {JSONOptions} [jsonOptions] Configuration options for the
* serialized objects.
* @property {object} [gaxOptions] Request configuration options,
* See {@link https://googleapis.dev/nodejs/google-gax/latest/interfaces/CallOptions.html|CallOptions}
* for more details.
* @property {number} [maxResumeRetries] The maximum number of times that the
* stream will retry to push data downstream, when the downstream indicates
* that it is not ready for any more data. Increase this value if you
* experience 'Stream is still not ready to receive data' errors as a
* result of a slow writer in your receiving stream.
* @property {object} [directedReadOptions]
* Indicates which replicas or regions should be used for non-transactional reads or queries.
*/
/**
* Create a readable object stream to receive resulting rows from a SQL
* statement.
*
* Wrapper around {@link v1.SpannerClient#executeStreamingSql}.
*
* @see {@link v1.SpannerClient#executeStreamingSql}
* @see [ExecuteStreamingSql API Documentation](https://cloud.google.com/spanner/docs/reference/rpc/google.spanner.v1#google.spanner.v1.Spanner.ExecuteStreamingSql)
* @see [ExecuteSqlRequest API Documentation](https://cloud.google.com/spanner/docs/reference/rpc/google.spanner.v1#google.spanner.v1.ExecuteSqlRequest)
*
* @fires PartialResultStream#response
* @fires PartialResultStream#stats
*
* @param {string|ExecuteSqlRequest} query A SQL query or
* {@link ExecuteSqlRequest} object.
* @returns {ReadableStream}
*
* @example
* ```
* const query = 'SELECT * FROM Singers';
*
* transaction.runStream(query)
* .on('error', function(err) {})
* .on('data', function(row) {
* // row = {
* // SingerId: '1',
* // Name: 'Eddie Wilson'
* // }
* })
* .on('end', function() {
* // All results retrieved.
* });
*
* ```
* @example The SQL query string can contain parameter placeholders.
* A parameter placeholder consists of '@' followed by the parameter name.
* ```
* const query = {
* sql: 'SELECT * FROM Singers WHERE name = @name',
* params: {
* name: 'Eddie Wilson'
* }
* };
*
* transaction.runStream(query)
* .on('error', function(err) {})
* .on('data', function(row) {})
* .on('end', function() {});
* ```
*
* @example If you anticipate many results, you can end a stream
* early to prevent unnecessary processing and API requests.
* ```
* transaction.runStream(query)
* .on('data', function(row) {
* this.end();
* });
* ```
*/
runStream(query: string | ExecuteSqlRequest): PartialResultStream;
/**
*
* @private
*/
configureTagOptions(singleUse?: boolean, transactionTag?: string, requestOptions?: {}): IRequestOptions | null;
/**
* Transforms convenience options `keys` and `ranges` into a KeySet object.
*
* @private
* @static
*
* @param {ReadRequest} request The read request.
* @returns {object}
*/
static encodeKeySet(request: ReadRequest): spannerClient.spanner.v1.IKeySet;
/**
* Formats timestamp options into proto format.
*
* @private
* @static
*
* @param {TimestampBounds} options The user supplied options.
* @returns {object}
*/
static encodeTimestampBounds(options: TimestampBounds): spannerClient.spanner.v1.TransactionOptions.IReadOnly;
/**
* Encodes convenience options `param` and `types` into the proto formatted.
*
* @private
* @static
*
* @param {ExecuteSqlRequest} request The SQL request.
* @returns {object}
*/
static encodeParams(request: ExecuteSqlRequest): {
params: p.IStruct;
paramTypes: {
[field: string]: spannerClient.spanner.v1.Type;
};
};
/**
* Get directed read options
* @private
* @param {google.spanner.v1.IDirectedReadOptions} directedReadOptions Request directedReadOptions object.
*/
protected _getDirectedReadOptions(directedReadOptions: google.spanner.v1.IDirectedReadOptions | null | undefined): spannerClient.spanner.v1.IDirectedReadOptions | null | undefined;
/**
* Update transaction properties from the response.
*
* @private
*
* @param {spannerClient.spanner.v1.ITransaction} resp Response object.
*/
protected _update(resp: spannerClient.spanner.v1.ITransaction): void;
/**
* Wrap `makeRequest` function with the lock to make sure the inline begin
* transaction can happen only once.
*
* @param makeRequest
* @private
*/
private _wrapWithIdWaiter;
_releaseWaitingRequests(): void;
/**
* Gets the Spanner object
*
* @private
*
* @returns {Spanner}
*/
protected _getSpanner(): Spanner;
}
/**
* Never use DML class directly. Instead, it should be extended upon
* if a class requires DML capabilities.
*
* @private
* @class
*/
export declare class Dml extends Snapshot {
/**
* @typedef {array} RunUpdateResponse
* @property {number} 0 Affected row count.
*/
/**
* @callback RunUpdateCallback
* @param {?Error} err Request error, if any.
* @param {number} rowCount Affected row count.
*/
/**
* Execute a DML statement and get the affected row count.
*
* @private
*
* @see {@link Transaction#run}
*
* @param {string|object} query A DML statement or
* [`ExecuteSqlRequest`](https://cloud.google.com/spanner/docs/reference/rpc/google.spanner.v1#google.spanner.v1.ExecuteSqlRequest)
* object.
* @param {object} [query.params] A map of parameter name to values.
* @param {object} [query.types] A map of parameter types.
* @param {RunUpdateCallback} [callback] Callback function.
* @returns {Promise<RunUpdateResponse>}
*/
runUpdate(query: string | ExecuteSqlRequest): Promise<RunUpdateResponse>;
runUpdate(query: string | ExecuteSqlRequest, callback: RunUpdateCallback): void;
}
/**
* This type of transaction is the only way to write data into Cloud Spanner.
* These transactions rely on pessimistic locking and, if necessary, two-phase
* commit. Locking read-write transactions may abort, requiring the application
* to retry.
*
* Calling either {@link Transaction#commit} or {@link Transaction#rollback}
* signals that the transaction is finished and no further requests will be
* made. If for some reason you decide not to call one of the aformentioned
* methods, call {@link Transaction#end} to release the underlying
* {@link Session}.
*
* Running a transaction via {@link Database#runTransaction} or
* {@link Database#runTransactionAsync} automatically re-runs the
* transaction on `ABORTED` errors.
*
* {@link Database#getTransaction} returns a plain {@link Transaction}
* object, requiring the user to retry manually.
*
* @class
* @extends Snapshot
*
* @param {Session} session The parent Session object.
*
* @example
* ```
* const {Spanner} = require('@google-cloud/spanner');
* const spanner = new Spanner();
*
* const instance = spanner.instance('my-instance');
* const database = instance.database('my-database');
*
* database.runTransaction(function(err, transaction) {
* // The `transaction` object is ready for use.
* });
*
* ```
* @example To manually control retrying the transaction, use the
* `getTransaction` method.
* ```
* database.getTransaction(function(err, transaction) {
* // The `transaction` object is ready for use.
* });
* ```
*/
export declare class Transaction extends Dml {
commitTimestamp?: PreciseDate;
commitTimestampProto?: spannerClient.protobuf.ITimestamp;
private _queuedMutations;
/**
* Timestamp at which the transaction was committed. Will be populated once
* {@link Transaction#commit} is called.
*
* @name Transaction#commitTimestamp
* @type {?external:PreciseDate}
*/
/**
* The protobuf version of {@link Transaction#commitTimestamp}. This is useful
* if you require microsecond precision.
*
* @name Transaction#commitTimestampProto
* @type {?google.protobuf.Timestamp}
*/
/**
* Execute a DML statement and get the affected row count.
*
* @name Transaction#runUpdate
*
* @see {@link Transaction#run}
*
* @param {string|object} query A DML statement or
* [`ExecuteSqlRequest`](https://cloud.google.com/spanner/docs/reference/rpc/google.spanner.v1#google.spanner.v1.ExecuteSqlRequest)
* object.
* @param {object} [query.params] A map of parameter name to values.
* @param {object} [query.types] A map of parameter types.
* @param {RunUpdateCallback} [callback] Callback function.
* @returns {Promise<RunUpdateResponse>}
*
* @example
* ```
* const query = 'UPDATE Account SET Balance = 1000 WHERE Key = 1';
*
* transaction.runUpdate(query, (err, rowCount) => {
* if (err) {
* // Error handling omitted.
* }
* });
* ```
*/
constructor(session: Session, options?: spannerClient.spanner.v1.TransactionOptions.ReadWrite, queryOptions?: IQueryOptions, requestOptions?: Pick<IRequestOptions, 'transactionTag'>);
/**
* @typedef {error} BatchUpdateError
* @property {number} code gRPC status code.
* @property {?object} metadata gRPC metadata.
* @property {number[]} rowCounts The affected row counts for any DML
* statements that were executed successfully before this error occurred.
*/
/**
* @typedef {object} BatchUpdateOptions
* @property {object} [gaxOptions] Request configuration options,
* See {@link https://googleapis.dev/nodejs/google-gax/latest/interfaces/CallOptions.html|CallOptions}
* for more details.
* @property {google.spanner.v1.IRequestOptions} [requestOptions] The request options to include
* with the commit request.
*/
/**
* @typedef {array} BatchUpdateResponse
* @property {number[]} 0 Affected row counts.
* @property {object} 1 The full API response.
*/
/**
* @callback BatchUpdateCallback
* @param {?BatchUpdateError} err Request error, if any.
* @param {number[]} rowCounts Affected row counts.
* @param {object} apiResponse The full API response.
*/
/**
* Execute a series of DML statements and get the affected row counts.
*
* If any of the DML statements fail, the returned error will contain a list
* of results for all successfully executed statements.
*
* @param {string[]|object[]} query A DML statement or
* [`ExecuteSqlRequest`](https://cloud.google.com/spanner/docs/reference/rpc/google.spanner.v1#google.spanner.v1.ExecuteSqlRequest)
* object.
* @param {object} [query.params] A map of parameter name to values.
* @param {object} [query.types] A map of parameter types.
* @param {object} [gaxOptions] Request configuration options,
* See {@link https://googleapis.dev/nodejs/google-gax/latest/interfaces/CallOptions.html|CallOptions}
* for more details.
* @param {BatchUpdateOptions} [options] Options for configuring the request.
* @param {RunUpdateCallback} [callback] Callback function.
* @returns {Promise<RunUpdateResponse>}
*
* @example
* ```
* const queries = [
* {
* sql: 'INSERT INTO MyTable (Key, Value) VALUES (@key, @value)',
* params: {key: 'my-key', value: 'my-value'},
* },
* {
* sql: 'UPDATE MyTable t SET t.Value = @value WHERE t.KEY = @key',
* params: {key: 'my-other-key', value: 'my-other-value'}
* }
* ];
*
* transaction.batchUpdate(queries, (err, rowCounts, apiResponse) => {
* if (err) {
* // Error handling omitted.
* }
* });
*
* ```
* @example If the callback is omitted, we'll return a Promise.
* ```
* const [rowCounts, apiResponse] = await transaction.batchUpdate(queries);
* ```
*/
batchUpdate(queries: Array<string | Statement>, options?: BatchUpdateOptions | CallOptions): Promise<BatchUpdateResponse>;
batchUpdate(queries: Array<string | Statement>, callback: BatchUpdateCallback): void;
batchUpdate(queries: Array<string | Statement>, options: BatchUpdateOptions | CallOptions, callback: BatchUpdateCallback): void;
private static extractKnownMetadata;
/**
* This method updates the _queuedMutations property of the transaction.
*
* @public
*
* @param {spannerClient.spanner.v1.Mutation[]} [mutation]
*/
setQueuedMutations(mutation: spannerClient.spanner.v1.Mutation[]): void;
/**
* @typedef {object} CommitOptions
* @property {google.spanner.v1.IRequestOptions} requestOptions The request options to include
* with the commit request.
* @property {boolean} returnCommitStats Include statistics related to the
* transaction in the {@link CommitResponse}.
* @property {spannerClient.proto.IDuration} maxCommitDelay Maximum amount
* of delay the commit is willing to incur in order to improve
* throughput. Value should be between 0ms and 500ms.
* @property {object} [gaxOptions] The request configuration options,
* See {@link https://googleapis.dev/nodejs/google-gax/latest/interfaces/CallOptions.html|CallOptions}
* for more details.
*/
/**
* @typedef {object} CommitResponse
* @property {google.protobuf.Timestamp} commitTimestamp The transaction
* commit timestamp.
* @property {google.spanner.v1.CommitResponse.ICommitStats|null} commitStats
* The statistics about this commit. Only populated if requested in
* {@link CommitOptions}.
*/
/**
* @typedef {array} CommitPromiseResponse
* @property {CommitResponse} 0 The commit response.
*/
/**
* @callback CommitCallback
* @param {?Error} error Request error, if any.
* @param {CommitResponse} apiResponse The full API response.
*/
/**
* Commit the transaction.
*
* Wrapper around {@link v1.SpannerClient#commit}.
*
* @see {@link v1.SpannerClient#commit}
* @see [Commit API Documentation](https://cloud.google.com/spanner/docs/reference/rpc/google.spanner.v1#google.spanner.v1.Spanner.Commit)
*
* @param {CommitOptions} [options] Options for configuring the request.
* @param {CommitCallback} [callback] Callback function.
* @returns {Promise<CommitPromiseResponse>}
*
* @example
* ```
* database.runTransaction(function(err, transaction) {
* if (err) {
* // Error handling omitted.
* }
*
* // Queue a mutation (note that there is no callback passed to `insert`).
* transaction.insert('Singers', {
* SingerId: 'Id3b',
* Name: 'Joe West'
* });
*
* // Commit the transaction.
* transaction.commit(function(err, apiResponse) {
* if (!err) {
* // Get the commit timestamp on successful commits.
* const {commitTimestamp} = apiResponse;
* }
* });
* });
* ```
*/
commit(options?: CommitOptions | CallOptions): Promise<CommitResponse>;
commit(callback: CommitCallback): void;
commit(options: CommitOptions | CallOptions, callback: CommitCallback): void;
/**
* Decorates an error returned by a commit with additional information for
* specific known errors.
* @param err the error to check and decorate with additional information if possible
* @param mutations the mutations included in the commit request
* @private
*/
private static decorateCommitError;
/**
* Decorates an error returned by a commit with additional information if the
* error was returned because the application tried to insert an array of
* objects into a JSON column. An array of objects will by default be encoded
* as ARRAY<JSON>, but can also be interpreted as JSON. An application must
* specify a top-level array of objects that should be inserted into a JSON
* column as a string instead of as an array of objects.
* @param err the error returned by the commit RPC
* @param mutations the mutations included in the commit request
* @private
*/
private static decoratePossibleJsonMismatchError;
/**
* Delete rows from a table.
*
* @see [Commit API Documentation](https://cloud.google.com/spanner/docs/reference/rpc/google.spanner.v1#google.spanner.v1.Spanner.Commit)
*
* @param {string} table The name of the table.
* @param {array} keys The keys for the rows to delete. If using a
* composite key, provide an array within this array. See the example
* below.
*
* @example
* ```
* const keys = ['Id1', 'Id2', 'Id3'];
*
* database.runTransaction(function(err, transaction) {
* if (err) {
* // Error handling omitted.
* }
*
* // Queue this mutation until later calling `commit`.
* // Note that a callback is not passed to `deleteRows`.
* transaction.deleteRows('Singers', keys);
*
* // Commit the transaction.
* transaction.commit(function(err) {
* if (!err) {
* // The rows were deleted successfully.
* }
* });
* });
*
* ```
* @example Provide an array for `keys` to delete rows with a
* composite key.
* ```
* const keys = [
* [
* 'Id1',
* 'Name1'
* ],
* [
* 'Id2',
* 'Name2'
* ]
* ];
* ```
*/
deleteRows(table: string, keys: Key[]): void;
/**
* Insert rows of data into this table.
*
* @see [Commit API Documentation](https://cloud.google.com/spanner/docs/reference/rpc/google.spanner.v1#google.spanner.v1.Spanner.Commit)
*
* @param {string} table The name of the table.
* @param {object|object[]} rows A map of names to values of data to insert
* into this table.
*
* @example
* ```
* const row = {
* SingerId: 'Id3',
* Name: 'Eddie Wilson'
* };
*
* database.runTransaction(function(err, transaction) {
* if (err) {
* // Error handling omitted.
* }
*
* // Queue this mutation until later calling `commit`.
* // Note that a callback is not passed to `insert`.
* transaction.insert('Singers', row);
*
* // Commit the transaction.
* transaction.commit(function(err) {
* if (!err) {
* // The row was inserted successfully.
* }
* });
* });
*
* ```
* @example Multiple rows can be inserted at once.
* ```
* const row2 = {
* SingerId: 'Id3b',
* Name: 'Joe West'
* };
*
* database.runTransaction(function(err, transaction) {
* if (err) {
* // Error handling omitted.
* }
*
* // Queue multiple mutations until later calling `commit`.
* // Note that a callback is not passed to `insert`.
* transaction.insert('Singers', [
* row,
* row2
* ]);
*
* // Commit the transaction.
* transaction.commit(function(err) {
* if (!err) {
* // The rows were inserted successfully.
* }
* });
* });
* ```
*/
insert(table: string, rows: object | object[]): void;
/**
* Replace rows of data within a table.
*
* @see [Commit API Documentation](https://cloud.google.com/spanner/docs/reference/rpc/google.spanner.v1#google.spanner.v1.Spanner.Commit)
*
* @param {string} table The table to read from.
* @param {object|object[]} rows A map of names to values of data to insert
* into this table.
*
* @example
* ```
* const row