UNPKG

@google-cloud/spanner

Version:
362 lines 12.7 kB
"use strict"; /*! * 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. */ Object.defineProperty(exports, "__esModule", { value: true }); exports.Session = void 0; /*! * @module spanner/session */ // eslint-disable-next-line @typescript-eslint/no-var-requires const common = require('./common-grpc/service-object'); const promisify_1 = require("@google-cloud/promisify"); const extend = require("extend"); const transaction_1 = require("./transaction"); const common_1 = require("./common"); const request_id_header_1 = require("./request_id_header"); /** * Create a Session object to interact with a Cloud Spanner session. * * **It is unlikely you will need to interact with sessions directly. By * default, sessions are created and utilized for maximum performance * automatically.** * * @class * @param {Database} database Parent {@link Database} instance. * @param {string} [name] The name of the session. If not provided, it is * assumed you are going to create it. * * @example * ``` * const {Spanner} = require('@google-cloud/spanner'); * const spanner = new Spanner(); * * const instance = spanner.instance('my-instance'); * const database = instance.database('my-database'); * * //- * // To create a session manually, don't provide a name. * //- * const session = database.session(); * * session.create(function(err) { * if (err) { * // Error handling omitted. * } * * // Session created successfully. * // `session.id` = The name of the session. * }); * * //- * // To access a previously-created session, provide a name. * //- * const session = database.session('session-name'); * ``` */ class Session extends common.GrpcServiceObject { formattedName_; txn; lastUsed; lastError; commonHeaders_; _observabilityOptions; constructor(database, name) { const methods = { /** * Create a session. * * @method Session#create * @param {object} [options] See {@link Database#createSession}. * @param {CreateSessionCallback} [callback] Callback function. * @returns {Promise<CreateSessionResponse>} * * @example * ``` * session.create(function(err, session, apiResponse) { * if (err) { * // Error handling omitted. * } * * // Session created successfully. * }); * * //- * //Returns a Promise if the callback is omitted. * //- * session.create() * .then(function(data) { * const session = data[0]; * const apiResponse = data[1]; * * // Session created successfully. * }); * ``` */ create: true, /** * @typedef {array} SessionExistsResponse * @property {boolean} 0 Whether the {@link Session} exists. */ /** * @callback SessionExistsCallback * @param {?Error} err Request error, if any. * @param {boolean} exists Whether the {@link Session} exists. */ /** * Check if a session exists. * * @method Session#exists * @param {SessionExistsCallback} [callback] Callback function. * @returns {Promise<SessionExistsResponse>} * * @example * ``` * session.exists(function(err, exists) {}); * * //- * //Returns a Promise if the callback is omitted. * //- * session.exists().then(function(data) { * const exists = data[0]; * }); * ``` */ exists: true, /** * @typedef {array} GetSessionResponse * @property {Session} 0 The {@link Session}. * @property {object} 1 The full API response. */ /** * @callback CreateSessionCallback * @param {?Error} err Request error, if any. * @param {Session} session The {@link Session}. * @param {object} apiResponse The full API response. */ /** * Get a session if it exists. * * You may optionally use this to "get or create" an object by providing * an object with `autoCreate` set to `true`. Any extra configuration that * is normally required for the `create` method must be contained within * this object as well. * * @method Session#get * @param {options} [options] Configuration object. * @param {boolean} [options.autoCreate=false] Automatically create the * object if it does not exist. * @param {CreateSessionCallback} [callback] Callback function. * @returns {Promise<GetSessionResponse>} * * @example * ``` * session.get(function(err, session, apiResponse) { * // `session.metadata` has been populated. * }); * * //- * //Returns a Promise if the callback is omitted. * //- * session.get().then(function(data) { * const session = data[0]; * const apiResponse = data[0]; * }); * ``` */ get: true, }; super({ parent: database, /** * @name Session#id * @type {string} */ id: name, methods, createMethod: (_, optionsOrCallback, callback) => { const options = typeof optionsOrCallback === 'object' ? optionsOrCallback : {}; callback = typeof optionsOrCallback === 'function' ? optionsOrCallback : callback; this.labels = options.labels || null; this.databaseRole = options.databaseRole || database.databaseRole || null; return database.createSession(options, (err, session, apiResponse) => { if (err) { callback(err, null, apiResponse); return; } extend(this, session); callback(null, this, apiResponse); }); }, }); this._observabilityOptions = database._observabilityOptions; this.commonHeaders_ = (0, common_1.getCommonHeaders)(this.parent.formattedName_, this._observabilityOptions?.enableEndToEndTracing); this.request = database.request; this.requestStream = database.requestStream; if (name) { this.formattedName_ = Session.formatName_(database.formattedName_, name); } } delete(optionsOrCallback, cb) { const gaxOpts = typeof optionsOrCallback === 'object' ? optionsOrCallback : {}; const callback = typeof optionsOrCallback === 'function' ? optionsOrCallback : cb; const reqOpts = { name: this.formattedName_, }; const database = this.parent; return this.request({ client: 'SpannerClient', method: 'deleteSession', reqOpts, gaxOpts, headers: (0, request_id_header_1.injectRequestIDIntoHeaders)(this.commonHeaders_, this, (0, request_id_header_1.nextNthRequest)(database), 1), }, callback); } getMetadata(optionsOrCallback, cb) { const gaxOpts = typeof optionsOrCallback === 'object' ? optionsOrCallback : {}; const callback = typeof optionsOrCallback === 'function' ? optionsOrCallback : cb; const reqOpts = { name: this.formattedName_, }; const headers = this.commonHeaders_; if (this._getSpanner().routeToLeaderEnabled) { (0, common_1.addLeaderAwareRoutingHeader)(headers); } const database = this.parent; return this.request({ client: 'SpannerClient', method: 'getSession', reqOpts, gaxOpts, headers: (0, request_id_header_1.injectRequestIDIntoHeaders)(headers, this.session, (0, request_id_header_1.nextNthRequest)(database), 1), }, (err, resp) => { if (resp) { resp.databaseRole = resp.creatorRole; delete resp.creatorRole; this.metadata = resp; } callback(err, resp); }); } keepAlive(optionsOrCallback, cb) { const gaxOpts = typeof optionsOrCallback === 'object' ? optionsOrCallback : {}; const callback = typeof optionsOrCallback === 'function' ? optionsOrCallback : cb; const reqOpts = { session: this.formattedName_, sql: 'SELECT 1', }; const database = this.parent; return this.request({ client: 'SpannerClient', method: 'executeSql', reqOpts, gaxOpts, headers: (0, request_id_header_1.injectRequestIDIntoHeaders)(this.commonHeaders_, this, (0, request_id_header_1.nextNthRequest)(database), 1), }, callback); } /** * Create a PartitionedDml transaction. * * @returns {PartitionedDml} * * @example * ``` * const transaction = session.partitionedDml(); * ``` */ partitionedDml() { return new transaction_1.PartitionedDml(this); } /** * Create a Snapshot transaction. * * @param {TimestampBounds} [options] The timestamp bounds. * @param {google.spanner.v1.ExecuteSqlRequest.IQueryOptions} [queryOptions] The default query options to use. * @returns {Snapshot} * * @example * ``` * const snapshot = session.snapshot({strong: false}); * ``` */ snapshot(options, queryOptions) { return new transaction_1.Snapshot(this, options, queryOptions); } /** * Create a read write Transaction. * * @param {google.spanner.v1.ExecuteSqlRequest.IQueryOptions} [queryOptions] The default query options to use. * @return {Transaction} * * @example * ``` * const transaction = session.transaction(); * ``` */ transaction(queryOptions, requestOptions) { return new transaction_1.Transaction(this, undefined, queryOptions, requestOptions); } /** * Format the session name to include the parent database's name. * * @private * * @param {string} databaseName The parent database's name. * @param {string} name The instance name. * @returns {string} * * @example * ``` * Session.formatName_('my-database', 'my-session'); * // 'projects/grape-spaceship-123/instances/my-instance/' + * // 'databases/my-database/sessions/my-session' * ``` */ static formatName_(databaseName, name) { if (name.indexOf('/') > -1) { return name; } const sessionName = name.split('/').pop(); return databaseName + '/sessions/' + sessionName; } /** * Gets the Spanner object * * @private * * @returns {Spanner} */ _getSpanner() { return this.parent.parent.parent; } channelId() { // The Node.js client does not use a gRPC channel pool, so this always returns 1. return 1; } } exports.Session = Session; /*! Developer Documentation * * All async methods (except for streams) will return a Promise in the event * that a callback is omitted. */ (0, promisify_1.promisifyAll)(Session, { exclude: ['delete', 'partitionedDml', 'snapshot', 'transaction'], }); //# sourceMappingURL=session.js.map