Compare fe003c0 ... +116 ... 8ae1f6e

Showing 20 of 113 files from the diff.
Newly tracked file
.mocharc.js changed.
Other files ignored by Codecov
test/instance.ts has changed.
test/database.ts has changed.
synth.metadata has changed.
test/backup.ts has changed.
CHANGELOG.md has changed.
.kokoro/test.sh has changed.
test/spanner.ts has changed.
protos/protos.js has changed.
test/table.ts has changed.
README.md has changed.
src/.eslintrc.yml was deleted.
tsconfig.json has changed.
test/index.ts has changed.
test/codec.ts has changed.
package.json has changed.
.kokoro/docs.sh has changed.
synth.py has changed.
test/session.ts has changed.
samples/crud.js has changed.
samples/README.md has changed.
samples/dml.js has changed.
.kokoro/lint.sh has changed.

@@ -18,7 +18,8 @@
Loading
18 18
 * @module spanner/session
19 19
 */
20 20
21 -
import {GrpcServiceObject} from './common-grpc/service-object';
21 +
// eslint-disable-next-line @typescript-eslint/no-var-requires
22 +
const common = require('./common-grpc/service-object');
22 23
import {promisifyAll} from '@google-cloud/promisify';
23 24
import * as extend from 'extend';
24 25
import * as r from 'teeny-request';
@@ -34,9 +35,9 @@
Loading
34 35
  CreateSessionCallback,
35 36
  CreateSessionOptions,
36 37
} from './database';
37 -
import {ServiceObjectConfig, DeleteCallback} from '@google-cloud/common';
38 -
import {NormalCallback} from './common';
39 -
import {ServiceError} from 'grpc';
38 +
import {ServiceObjectConfig} from '@google-cloud/common';
39 +
import {NormalCallback, CLOUD_RESOURCE_HEADER} from './common';
40 +
import {grpc, CallOptions} from 'google-gax';
40 41
41 42
export type GetSessionResponse = [Session, r.Response];
42 43
@@ -55,7 +56,9 @@
Loading
55 56
56 57
export type KeepAliveCallback = NormalCallback<google.spanner.v1.IResultSet>;
57 58
export type KeepAliveResponse = [google.spanner.v1.IResultSet];
58 -
export type DeleteResponse = [r.Response];
59 +
export type DeleteSessionResponse = [google.protobuf.IEmpty];
60 +
export type DeleteSessionCallback = NormalCallback<google.protobuf.IEmpty>;
61 +
59 62
/**
60 63
 * Create a Session object to interact with a Cloud Spanner session.
61 64
 *
@@ -94,13 +97,14 @@
Loading
94 97
 * //-
95 98
 * const session = database.session('session-name');
96 99
 */
97 -
export class Session extends GrpcServiceObject {
100 +
export class Session extends common.GrpcServiceObject {
98 101
  id!: string;
99 102
  formattedName_?: string;
100 103
  type?: types;
101 104
  txn?: Transaction;
102 105
  lastUsed?: number;
103 -
  lastError?: ServiceError;
106 +
  lastError?: grpc.ServiceError;
107 +
  resourceHeader_: {[k: string]: string};
104 108
  constructor(database: Database, name?: string) {
105 109
    const methods = {
106 110
      /**
@@ -231,15 +235,19 @@
Loading
231 235
      },
232 236
    } as {}) as ServiceObjectConfig);
233 237
238 +
    this.resourceHeader_ = {
239 +
      [CLOUD_RESOURCE_HEADER]: (this.parent as Database).formattedName_,
240 +
    };
234 241
    this.request = database.request;
235 242
    this.requestStream = database.requestStream;
236 243
237 244
    if (name) {
238 245
      this.formattedName_ = Session.formatName_(database.formattedName_, name);
239 246
    }
240 247
  }
241 -
  delete(): Promise<DeleteResponse>;
242 -
  delete(callback: DeleteCallback): void;
248 +
  delete(gaxOptions?: CallOptions): Promise<DeleteSessionResponse>;
249 +
  delete(callback: DeleteSessionCallback): void;
250 +
  delete(gaxOptions: CallOptions, callback: DeleteSessionCallback): void;
243 251
  /**
244 252
   * Delete a session.
245 253
   *
@@ -248,8 +256,10 @@
Loading
248 256
   * @see {@link v1.SpannerClient#deleteSession}
249 257
   * @see [DeleteSession API Documentation](https://cloud.google.com/spanner/docs/reference/rpc/google.spanner.v1#google.spanner.v1.Spanner.DeleteSession)
250 258
   *
251 -
   * @param {BasicCallback} [callback] Callback function.
252 -
   * @returns {Promise<BasicResponse>}
259 +
   * @param {object} [gaxOptions] Request configuration options, outlined here:
260 +
   *     https://googleapis.github.io/gax-nodejs/classes/CallSettings.html.
261 +
   * @param {DeleteSessionCallback} [callback] Callback function.
262 +
   * @returns {Promise<DeleteSessionResponse>}
253 263
   *
254 264
   * @example
255 265
   * session.delete(function(err, apiResponse) {
@@ -267,7 +277,15 @@
Loading
267 277
   *   const apiResponse = data[0];
268 278
   * });
269 279
   */
270 -
  delete(callback?: DeleteCallback): void | Promise<DeleteResponse> {
280 +
  delete(
281 +
    optionsOrCallback?: CallOptions | DeleteSessionCallback,
282 +
    cb?: DeleteSessionCallback
283 +
  ): void | Promise<DeleteSessionResponse> {
284 +
    const gaxOpts =
285 +
      typeof optionsOrCallback === 'object' ? optionsOrCallback : {};
286 +
    const callback =
287 +
      typeof optionsOrCallback === 'function' ? optionsOrCallback : cb!;
288 +
271 289
    const reqOpts = {
272 290
      name: this.formattedName_,
273 291
    };
@@ -276,12 +294,18 @@
Loading
276 294
        client: 'SpannerClient',
277 295
        method: 'deleteSession',
278 296
        reqOpts,
297 +
        gaxOpts,
298 +
        headers: this.resourceHeader_,
279 299
      },
280 300
      callback!
281 301
    );
282 302
  }
283 -
  getMetadata(): Promise<GetSessionMetadataResponse>;
303 +
  getMetadata(gaxOptions?: CallOptions): Promise<GetSessionMetadataResponse>;
284 304
  getMetadata(callback: GetSessionMetadataCallback): void;
305 +
  getMetadata(
306 +
    gaxOptions: CallOptions,
307 +
    callback: GetSessionMetadataCallback
308 +
  ): void;
285 309
  /**
286 310
   * @typedef {array} GetSessionMetadataResponse
287 311
   * @property {object} 0 The session's metadata.
@@ -301,6 +325,8 @@
Loading
301 325
   * @see {@link v1.SpannerClient#getSession}
302 326
   * @see [GetSession API Documentation](https://cloud.google.com/spanner/docs/reference/rpc/google.spanner.v1#google.spanner.v1.Spanner.GetSession)
303 327
   *
328 +
   * @param {object} [gaxOptions] Request configuration options, outlined here:
329 +
   *     https://googleapis.github.io/gax-nodejs/classes/CallSettings.html.
304 330
   * @param {GetSessionMetadataCallback} [callback] Callback function.
305 331
   * @returns {Promise<GetSessionMetadataResponse>}
306 332
   *
@@ -316,8 +342,14 @@
Loading
316 342
   * });
317 343
   */
318 344
  getMetadata(
319 -
    callback?: GetSessionMetadataCallback
345 +
    optionsOrCallback?: CallOptions | GetSessionMetadataCallback,
346 +
    cb?: GetSessionMetadataCallback
320 347
  ): void | Promise<GetSessionMetadataResponse> {
348 +
    const gaxOpts =
349 +
      typeof optionsOrCallback === 'object' ? optionsOrCallback : {};
350 +
    const callback =
351 +
      typeof optionsOrCallback === 'function' ? optionsOrCallback : cb!;
352 +
321 353
    const reqOpts = {
322 354
      name: this.formattedName_,
323 355
    };
@@ -326,15 +358,25 @@
Loading
326 358
        client: 'SpannerClient',
327 359
        method: 'getSession',
328 360
        reqOpts,
361 +
        gaxOpts,
362 +
        headers: this.resourceHeader_,
329 363
      },
330 -
      callback!
364 +
      (err, resp) => {
365 +
        if (resp) {
366 +
          this.metadata = resp;
367 +
        }
368 +
        callback!(err, resp);
369 +
      }
331 370
    );
332 371
  }
333 -
  keepAlive(): Promise<KeepAliveResponse>;
372 +
  keepAlive(gaxOptions?: CallOptions): Promise<KeepAliveResponse>;
334 373
  keepAlive(callback: KeepAliveCallback): void;
374 +
  keepAlive(gaxOptions: CallOptions, callback: KeepAliveCallback): void;
335 375
  /**
336 376
   * Ping the session with `SELECT 1` to prevent it from expiring.
337 377
   *
378 +
   * @param {object} [gaxOptions] Request configuration options, outlined here:
379 +
   *     https://googleapis.github.io/gax-nodejs/classes/CallSettings.html.
338 380
   * @param {BasicCallback} [callback] Callback function.
339 381
   * @returns {Promise<BasicResponse>}
340 382
   *
@@ -345,7 +387,15 @@
Loading
345 387
   *   }
346 388
   * });
347 389
   */
348 -
  keepAlive(callback?: KeepAliveCallback): void | Promise<KeepAliveResponse> {
390 +
  keepAlive(
391 +
    optionsOrCallback?: CallOptions | KeepAliveCallback,
392 +
    cb?: KeepAliveCallback
393 +
  ): void | Promise<KeepAliveResponse> {
394 +
    const gaxOpts =
395 +
      typeof optionsOrCallback === 'object' ? optionsOrCallback : {};
396 +
    const callback =
397 +
      typeof optionsOrCallback === 'function' ? optionsOrCallback : cb!;
398 +
349 399
    const reqOpts = {
350 400
      session: this.formattedName_,
351 401
      sql: 'SELECT 1',
@@ -355,6 +405,8 @@
Loading
355 405
        client: 'SpannerClient',
356 406
        method: 'executeSql',
357 407
        reqOpts,
408 +
        gaxOpts,
409 +
        headers: this.resourceHeader_,
358 410
      },
359 411
      callback!
360 412
    );

@@ -15,51 +15,49 @@
Loading
15 15
 */
16 16
17 17
import {GrpcService, GrpcServiceConfig} from './common-grpc/service';
18 -
import {paginator} from '@google-cloud/paginator';
19 18
import {PreciseDate} from '@google-cloud/precise-date';
20 19
import {replaceProjectIdToken} from '@google-cloud/projectify';
21 20
import {promisifyAll} from '@google-cloud/promisify';
22 21
import * as extend from 'extend';
23 22
import {GoogleAuth, GoogleAuthOptions} from 'google-auth-library';
24 -
import * as is from 'is';
25 23
import * as path from 'path';
26 24
import {common as p} from 'protobufjs';
27 25
import * as streamEvents from 'stream-events';
28 26
import * as through from 'through2';
29 -
import {codec, Float, Int, SpannerDate, Struct} from './codec';
27 +
import {codec, Float, Int, Numeric, SpannerDate, Struct} from './codec';
30 28
import {Backup} from './backup';
31 29
import {Database} from './database';
32 30
import {
33 31
  Instance,
34 32
  CreateInstanceCallback,
35 33
  CreateInstanceResponse,
36 34
} from './instance';
35 +
import {grpc, GrpcClientOptions, CallOptions} from 'google-gax';
37 36
import {google as instanceAdmin} from '../protos/protos';
38 -
import {PagedRequest, PagedResponse, PagedCallback} from './common';
37 +
import {
38 +
  PagedOptions,
39 +
  PagedResponse,
40 +
  PagedCallback,
41 +
  PagedOptionsWithFilter,
42 +
  CLOUD_RESOURCE_HEADER,
43 +
} from './common';
39 44
import {Session} from './session';
40 45
import {SessionPool} from './session-pool';
41 46
import {Table} from './table';
42 47
import {PartitionedDml, Snapshot, Transaction} from './transaction';
43 -
import {GrpcClientOptions} from 'google-gax';
44 -
import {ChannelCredentials} from 'grpc';
45 -
import {
46 -
  createGcpApiConfig,
47 -
  gcpCallInvocationTransformer,
48 -
  gcpChannelFactoryOverride,
49 -
} from 'grpc-gcp';
48 +
import grpcGcpModule = require('grpc-gcp');
49 +
const grpcGcp = grpcGcpModule(grpc);
50 50
import * as v1 from './v1';
51 -
import * as grpc from 'grpc';
51 +
import * as pumpify from 'pumpify';
52 +
import {Transform} from 'stream';
52 53
53 54
// eslint-disable-next-line @typescript-eslint/no-var-requires
54 55
const gcpApiConfig = require('./spanner_grpc_config.json');
55 56
56 57
export type IOperation = instanceAdmin.longrunning.IOperation;
57 58
58 -
export type GetInstancesRequest = PagedRequest<
59 -
  instanceAdmin.spanner.admin.instance.v1.IListInstancesRequest & {
60 -
    maxResults?: number;
61 -
  }
62 -
>;
59 +
export type GetInstancesOptions = PagedOptionsWithFilter;
60 +
63 61
export type GetInstancesResponse = PagedResponse<
64 62
  Instance,
65 63
  instanceAdmin.spanner.admin.instance.v1.IListInstancesResponse
@@ -69,37 +67,36 @@
Loading
69 67
  instanceAdmin.spanner.admin.instance.v1.IListInstancesResponse
70 68
>;
71 69
72 -
export type GetInstanceConfigsRequest = PagedRequest<
73 -
  instanceAdmin.spanner.admin.instance.v1.IListInstanceConfigsRequest & {
74 -
    maxResults?: number;
75 -
  }
76 -
>;
70 +
export type GetInstanceConfigsOptions = PagedOptions;
77 71
export type GetInstanceConfigsResponse = PagedResponse<
78 -
  instanceAdmin.spanner.admin.instance.v1.InstanceConfig,
72 +
  instanceAdmin.spanner.admin.instance.v1.IInstanceConfig,
79 73
  instanceAdmin.spanner.admin.instance.v1.IListInstanceConfigsResponse
80 74
>;
81 75
export type GetInstanceConfigsCallback = PagedCallback<
82 -
  instanceAdmin.spanner.admin.instance.v1.InstanceConfig,
76 +
  instanceAdmin.spanner.admin.instance.v1.IInstanceConfig,
83 77
  instanceAdmin.spanner.admin.instance.v1.IListInstanceConfigsResponse
84 78
>;
85 79
86 80
export interface SpannerOptions extends GrpcClientOptions {
87 81
  apiEndpoint?: string;
88 82
  servicePath?: string;
89 83
  port?: number;
90 -
  sslCreds?: ChannelCredentials;
84 +
  sslCreds?: grpc.ChannelCredentials;
91 85
}
92 86
export interface RequestConfig {
93 87
  client: string;
94 88
  method: string;
95 89
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
96 90
  reqOpts: any;
97 -
  gaxOpts?: {};
91 +
  gaxOpts?: CallOptions;
92 +
  headers: {[k: string]: string};
98 93
}
99 94
export interface CreateInstanceRequest {
100 -
  config: string;
95 +
  config?: string;
101 96
  nodes?: number;
97 +
  displayName?: string;
102 98
  labels?: {[k: string]: string} | null;
99 +
  gaxOptions?: CallOptions;
103 100
}
104 101
/**
105 102
 * Translates enum values to string keys.
@@ -161,7 +158,8 @@
Loading
161 158
  auth: GoogleAuth;
162 159
  clients_: Map<string, {}>;
163 160
  instances_: Map<string, Instance>;
164 -
  getInstancesStream: Function;
161 +
  projectFormattedName_: string;
162 +
  resourceHeader_: {[k: string]: string};
165 163
166 164
  /**
167 165
   * Placeholder used to auto populate a column with the commit timestamp.
@@ -225,9 +223,9 @@
Loading
225 223
        libVersion: require('../../package.json').version,
226 224
        scopes,
227 225
        // Enable grpc-gcp support
228 -
        'grpc.callInvocationTransformer': gcpCallInvocationTransformer,
229 -
        'grpc.channelFactoryOverride': gcpChannelFactoryOverride,
230 -
        'grpc.gcpApiConfig': createGcpApiConfig(gcpApiConfig),
226 +
        'grpc.callInvocationTransformer': grpcGcp.gcpCallInvocationTransformer,
227 +
        'grpc.channelFactoryOverride': grpcGcp.gcpChannelFactoryOverride,
228 +
        'grpc.gcpApiConfig': grpcGcp.createGcpApiConfig(gcpApiConfig),
231 229
        grpc,
232 230
      },
233 231
      options || {}
@@ -262,43 +260,10 @@
Loading
262 260
    this.auth = new GoogleAuth(this.options);
263 261
    this.clients_ = new Map();
264 262
    this.instances_ = new Map();
265 -
266 -
    /**
267 -
     * Get a list of {@link Instance} objects as a readable object stream.
268 -
     *
269 -
     * Wrapper around {@link v1.InstanceAdminClient#listInstances}.
270 -
     *
271 -
     * @see {@link v1.InstanceAdminClient#listInstances}
272 -
     * @see [ListInstances API Documentation](https://cloud.google.com/spanner/docs/reference/rpc/google.spanner.admin.instance.v1#google.spanner.admin.instance.v1.InstanceAdmin.ListInstances)
273 -
     *
274 -
     * @method Spanner#getInstancesStream
275 -
     * @param {GetInstancesRequest} [query] Query object for listing instances.
276 -
     * @returns {ReadableStream} A readable stream that emits {@link Instance}
277 -
     *     instances.
278 -
     *
279 -
     * @example
280 -
     * const {Spanner} = require('@google-cloud/spanner');
281 -
     * const spanner = new Spanner();
282 -
     *
283 -
     * spanner.getInstancesStream()
284 -
     *   .on('error', console.error)
285 -
     *   .on('data', function(instance) {
286 -
     *     // `instance` is an `Instance` object.
287 -
     *   })
288 -
     *   .on('end', function() {
289 -
     *     // All instances retrieved.
290 -
     *   });
291 -
     *
292 -
     * //-
293 -
     * // If you anticipate many results, you can end a stream early to prevent
294 -
     * // unnecessary processing and API requests.
295 -
     * //-
296 -
     * spanner.getInstancesStream()
297 -
     *   .on('data', function(instance) {
298 -
     *     this.end();
299 -
     *   });
300 -
     */
301 -
    this.getInstancesStream = paginator.streamify('getInstances');
263 +
    this.projectFormattedName_ = 'projects/' + this.projectId;
264 +
    this.resourceHeader_ = {
265 +
      [CLOUD_RESOURCE_HEADER]: this.projectFormattedName_,
266 +
    };
302 267
  }
303 268
304 269
  createInstance(
@@ -324,6 +289,11 @@
Loading
324 289
   *     be used to control how resource metrics are aggregated. And they can
325 290
   *     be used as arguments to policy management rules (e.g. route,
326 291
   *     firewall, load balancing, etc.).
292 +
   * @property {string} [displayName] The descriptive name for this instance
293 +
   *     as it appears in UIs. Must be unique per project and between 4 and 30
294 +
   *     characters in length.
295 +
   *     Defaults to the instance unique identifier '<instance>' of the full
296 +
   *     instance name of the form 'projects/<project>/instances/<instance>'.
327 297
   */
328 298
  /**
329 299
   * @typedef {array} CreateInstanceResponse
@@ -406,30 +376,33 @@
Loading
406 376
      );
407 377
    }
408 378
    const formattedName = Instance.formatName_(this.projectId, name);
409 -
    const shortName = formattedName.split('/').pop();
379 +
    const displayName = config.displayName || formattedName.split('/').pop();
410 380
    const reqOpts = {
411 -
      parent: 'projects/' + this.projectId,
412 -
      instanceId: shortName,
381 +
      parent: this.projectFormattedName_,
382 +
      instanceId: formattedName.split('/').pop(),
413 383
      instance: extend(
414 384
        {
415 385
          name: formattedName,
416 -
          displayName: shortName,
386 +
          displayName,
417 387
          nodeCount: config.nodes || 1,
418 388
        },
419 389
        config
420 390
      ),
421 391
    };
422 392
423 393
    delete reqOpts.instance.nodes;
394 +
    delete reqOpts.instance.gaxOptions;
424 395
425 -
    if (config.config.indexOf('/') === -1) {
396 +
    if (config.config!.indexOf('/') === -1) {
426 397
      reqOpts.instance.config = `projects/${this.projectId}/instanceConfigs/${config.config}`;
427 398
    }
428 399
    this.request(
429 400
      {
430 401
        client: 'InstanceAdminClient',
431 402
        method: 'createInstance',
432 403
        reqOpts,
404 +
        gaxOpts: config.gaxOptions,
405 +
        headers: this.resourceHeader_,
433 406
      },
434 407
      (err, operation, resp) => {
435 408
        if (err) {
@@ -442,18 +415,18 @@
Loading
442 415
    );
443 416
  }
444 417
445 -
  getInstances(query?: GetInstancesRequest): Promise<GetInstancesResponse>;
418 +
  getInstances(options?: GetInstancesOptions): Promise<GetInstancesResponse>;
446 419
  getInstances(callback: GetInstancesCallback): void;
447 420
  getInstances(
448 -
    query: GetInstancesRequest,
421 +
    query: GetInstancesOptions,
449 422
    callback: GetInstancesCallback
450 423
  ): void;
451 424
  /**
452 425
   * Query object for listing instances.
453 426
   *
454 -
   * @typedef {object} GetInstancesRequest
455 -
   * @property {boolean} [autoPaginate=true] Have pagination handled
456 -
   *     automatically.
427 +
   * @typedef {object} GetInstancesOptions
428 +
   * @property {object} [gaxOptions] Request configuration options, outlined
429 +
   *     here: https://googleapis.github.io/gax-nodejs/global.html#CallOptions.
457 430
   * @property {string} [filter] An expression for filtering the results of the
458 431
   *     request. Filter rules are case insensitive. The fields eligible for
459 432
   *     filtering are:
@@ -468,21 +441,21 @@
Loading
468 441
   *     - **`labels.env:dev`** The instance's label env has the value dev.
469 442
   *     - **`name:howl labels.env:dev`** The instance's name is howl and it has
470 443
   *       the label env with value dev.
471 -
   * @property {number} [maxApiCalls] Maximum number of API calls to make.
472 -
   * @property {number} [maxResults] Maximum number of items to return.
473 444
   * @property {number} [pageSize] Maximum number of results per page.
474 445
   * @property {string} [pageToken] A previously-returned page token
475 446
   *     representing part of the larger set of results to view.
476 447
   */
477 448
  /**
478 449
   * @typedef {array} GetInstancesResponse
479 450
   * @property {Instance[]} 0 Array of {@link Instance} instances.
480 -
   * @property {object} 1 The full API response.
451 +
   * @property {object} 1 A query object to receive more results.
452 +
   * @property {object} 2 The full API response.
481 453
   */
482 454
  /**
483 455
   * @callback GetInstancesCallback
484 456
   * @param {?Error} err Request error, if any.
485 457
   * @param {Instance[]} instances Array of {@link Instance} instances.
458 +
   * @param {string} nextQuery A query object to receive more results.
486 459
   * @param {object} apiResponse The full API response.
487 460
   */
488 461
  /**
@@ -493,7 +466,7 @@
Loading
493 466
   * @see {@link v1.InstanceAdminClient#listInstances}
494 467
   * @see [ListInstances API Documentation](https://cloud.google.com/spanner/docs/reference/rpc/google.spanner.admin.instance.v1#google.spanner.admin.instance.v1.InstanceAdmin.ListInstances)
495 468
   *
496 -
   * @param {GetInstancesRequest} [query] Query object for listing instances.
469 +
   * @param {GetInstancesOptions} [options] Query object for listing instances.
497 470
   * @param {GetInstancesCallback} [callback] Callback function.
498 471
   * @returns {Promise<GetInstancesResponse>}
499 472
   *
@@ -517,7 +490,9 @@
Loading
517 490
   * }
518 491
   *
519 492
   * spanner.getInstances({
520 -
   *   autoPaginate: false
493 +
   *   gaxOptions: {
494 +
   *     autoPaginate: false,
495 +
   *   }
521 496
   * }, callback);
522 497
   *
523 498
   * //-
@@ -528,26 +503,50 @@
Loading
528 503
   * });
529 504
   */
530 505
  getInstances(
531 -
    query?: GetInstancesRequest | GetInstancesCallback,
532 -
    callback?: GetInstancesCallback
506 +
    optionsOrCallback?: GetInstancesOptions | GetInstancesCallback,
507 +
    cb?: GetInstancesCallback
533 508
  ): Promise<GetInstancesResponse> | void {
534 509
    // eslint-disable-next-line @typescript-eslint/no-this-alias
535 510
    const self = this;
536 -
    if (is.fn(query)) {
537 -
      callback = query as GetInstancesCallback;
538 -
      query = {};
539 -
    }
540 -
    const reqOpts = extend({}, query, {
511 +
    const options =
512 +
      typeof optionsOrCallback === 'object'
513 +
        ? optionsOrCallback
514 +
        : ({} as GetInstancesOptions);
515 +
    const callback =
516 +
      typeof optionsOrCallback === 'function' ? optionsOrCallback : cb!;
517 +
518 +
    const gaxOpts = extend(true, {}, options.gaxOptions);
519 +
520 +
    let reqOpts = extend({}, options, {
541 521
      parent: 'projects/' + this.projectId,
542 522
    });
523 +
524 +
    delete reqOpts.gaxOptions;
525 +
526 +
    // Copy over pageSize and pageToken values from gaxOptions.
527 +
    // However values set on options take precedence.
528 +
    if (gaxOpts) {
529 +
      reqOpts = extend(
530 +
        {},
531 +
        {
532 +
          pageSize: gaxOpts.pageSize,
533 +
          pageToken: gaxOpts.pageToken,
534 +
        },
535 +
        reqOpts
536 +
      );
537 +
      delete gaxOpts.pageToken;
538 +
      delete gaxOpts.pageSize;
539 +
    }
540 +
543 541
    this.request(
544 542
      {
545 543
        client: 'InstanceAdminClient',
546 544
        method: 'listInstances',
547 545
        reqOpts,
548 -
        gaxOpts: query,
546 +
        gaxOpts,
547 +
        headers: this.resourceHeader_,
549 548
      },
550 -
      (err, instances, ...args) => {
549 +
      (err, instances, nextPageRequest, ...args) => {
551 550
        let instanceInstances: Instance[] | null = null;
552 551
        if (instances) {
553 552
          instanceInstances = instances.map(instance => {
@@ -556,38 +555,122 @@
Loading
556 555
            return instanceInstance;
557 556
          });
558 557
        }
559 -
        callback!(err, instanceInstances, ...args);
558 +
        const nextQuery = nextPageRequest!
559 +
          ? extend({}, options, nextPageRequest!)
560 +
          : null;
561 +
        callback!(err, instanceInstances, nextQuery, ...args);
560 562
      }
561 563
    );
562 564
  }
563 565
566 +
  /**
567 +
   * Get a list of {@link Instance} objects as a readable object stream.
568 +
   *
569 +
   * Wrapper around {@link v1.InstanceAdminClient#listInstances}.
570 +
   *
571 +
   * @see {@link v1.InstanceAdminClient#listInstances}
572 +
   * @see [ListInstances API Documentation](https://cloud.google.com/spanner/docs/reference/rpc/google.spanner.admin.instance.v1#google.spanner.admin.instance.v1.InstanceAdmin.ListInstances)
573 +
   *
574 +
   * @method Spanner#getInstancesStream
575 +
   * @param {GetInstancesOptions} [options] Query object for listing instances.
576 +
   * @returns {ReadableStream} A readable stream that emits {@link Instance}
577 +
   *     instances.
578 +
   *
579 +
   * @example
580 +
   * const {Spanner} = require('@google-cloud/spanner');
581 +
   * const spanner = new Spanner();
582 +
   *
583 +
   * spanner.getInstancesStream()
584 +
   *   .on('error', console.error)
585 +
   *   .on('data', function(instance) {
586 +
   *     // `instance` is an `Instance` object.
587 +
   *   })
588 +
   *   .on('end', function() {
589 +
   *     // All instances retrieved.
590 +
   *   });
591 +
   *
592 +
   * //-
593 +
   * // If you anticipate many results, you can end a stream early to prevent
594 +
   * // unnecessary processing and API requests.
595 +
   * //-
596 +
   * spanner.getInstancesStream()
597 +
   *   .on('data', function(instance) {
598 +
   *     this.end();
599 +
   *   });
600 +
   */
601 +
  getInstancesStream(options: GetInstancesOptions = {}): NodeJS.ReadableStream {
602 +
    const gaxOpts = extend(true, {}, options.gaxOptions);
603 +
604 +
    let reqOpts = extend({}, options, {
605 +
      parent: 'projects/' + this.projectId,
606 +
    });
607 +
    delete reqOpts.gaxOptions;
608 +
609 +
    // Copy over pageSize and pageToken values from gaxOptions.
610 +
    // However values set on options take precedence.
611 +
    if (gaxOpts) {
612 +
      reqOpts = extend(
613 +
        {},
614 +
        {
615 +
          pageSize: gaxOpts.pageSize,
616 +
          pageToken: gaxOpts.pageToken,
617 +
        },
618 +
        reqOpts
619 +
      );
620 +
      delete gaxOpts.pageSize;
621 +
      delete gaxOpts.pageToken;
622 +
    }
623 +
624 +
    return new pumpify.obj([
625 +
      this.requestStream({
626 +
        client: 'InstanceAdminClient',
627 +
        method: 'listInstancesStream',
628 +
        reqOpts,
629 +
        gaxOpts,
630 +
        headers: this.resourceHeader_,
631 +
      }),
632 +
      new Transform({
633 +
        objectMode: true,
634 +
        transform: (
635 +
          chunk: instanceAdmin.spanner.admin.instance.v1.IInstance,
636 +
          enc: string,
637 +
          cb: Function
638 +
        ) => {
639 +
          const instance = this.instance(chunk.name!);
640 +
          instance.metadata = chunk;
641 +
          cb(null, instance);
642 +
        },
643 +
      }),
644 +
    ]);
645 +
  }
646 +
564 647
  getInstanceConfigs(
565 -
    query?: GetInstanceConfigsRequest
648 +
    query?: GetInstanceConfigsOptions
566 649
  ): Promise<GetInstanceConfigsResponse>;
567 650
  getInstanceConfigs(callback: GetInstanceConfigsCallback): void;
568 651
  getInstanceConfigs(
569 -
    query: GetInstanceConfigsRequest,
652 +
    query: GetInstanceConfigsOptions,
570 653
    callback: GetInstanceConfigsCallback
571 654
  ): void;
572 655
  /**
573 -
   * Query object for listing instance configs.
656 +
   * Lists the supported instance configurations for a given project.
574 657
   *
575 -
   * @typedef {object} GetInstanceConfigsRequest
576 -
   * @property {boolean} [autoPaginate=true] Have pagination handled
577 -
   *     automatically.
578 -
   * @property {number} [maxApiCalls] Maximum number of API calls to make.
579 -
   * @property {number} [maxResults] Maximum number of items to return.
658 +
   * @typedef {object} GetInstanceConfigsOptions
580 659
   * @property {number} [pageSize] Maximum number of results per page.
581 660
   * @property {string} [pageToken] A previously-returned page token
582 661
   *     representing part of the larger set of results to view.
662 +
   * @property {object} [gaxOptions] Request configuration options, outlined
663 +
   *     here: https://googleapis.github.io/gax-nodejs/global.html#CallOptions.
664 +
583 665
   */
584 666
  /**
585 667
   * @typedef {array} GetInstanceConfigsResponse
586 668
   * @property {object[]} 0 List of all available instance configs.
587 669
   * @property {string} 0.name The unique identifier for the instance config.
588 670
   * @property {string} 0.displayName The name of the instance config as it
589 671
   *     appears in UIs.
590 -
   * @property {object} 1 The full API response.
672 +
   * @property {object} 1 A query object to receive more results.
673 +
   * @property {object} 2 The full API response.
591 674
   */
592 675
  /**
593 676
   * @callback GetInstanceConfigsCallback
@@ -597,6 +680,7 @@
Loading
597 680
   *     config.
598 681
   * @param {string} instanceConfigs.displayName The name of the instance config
599 682
   *     as it appears in UIs.
683 +
   * @param {object} nextQuery A query object to receive more results.
600 684
   * @param {object} apiResponse The full API response.
601 685
   */
602 686
  /**
@@ -607,7 +691,7 @@
Loading
607 691
   * @see {@link v1.InstanceAdminClient#listInstanceConfigs}
608 692
   * @see [ListInstanceConfigs API Documentation](https://cloud.google.com/spanner/docs/reference/rpc/google.spanner.admin.instance.v1#google.spanner.admin.instance.v1.InstanceAdmin.ListInstanceConfigs)
609 693
   *
610 -
   * @param {GetInstanceConfigsRequest} [query] Query object for listing instance
694 +
   * @param {GetInstanceConfigsOptions} [options] Query object for listing instance
611 695
   *     configs.
612 696
   * @param {GetInstanceConfigsCallback} [callback] Callback function.
613 697
   * @returns {Promise<GetInstanceConfigsResponse>}
@@ -632,7 +716,9 @@
Loading
632 716
   * }
633 717
   *
634 718
   * spanner.getInstanceConfigs({
635 -
   *   autoPaginate: false
719 +
   *   gaxOptions: {
720 +
   *     autoPaginate: false,
721 +
   *   }
636 722
   * }, callback);
637 723
   *
638 724
   * //-
@@ -643,28 +729,51 @@
Loading
643 729
   * });
644 730
   */
645 731
  getInstanceConfigs(
646 -
    queryOrCallback?: GetInstanceConfigsRequest | GetInstanceConfigsCallback,
732 +
    optionsOrCallback?: GetInstanceConfigsOptions | GetInstanceConfigsCallback,
647 733
    cb?: GetInstanceConfigsCallback
648 734
  ): Promise<GetInstanceConfigsResponse> | void {
649 735
    const callback =
650 -
      typeof queryOrCallback === 'function'
651 -
        ? (queryOrCallback as GetInstanceConfigsCallback)
652 -
        : cb;
653 -
    const query =
654 -
      typeof queryOrCallback === 'object'
655 -
        ? (queryOrCallback as GetInstanceConfigsRequest)
656 -
        : {};
657 -
    const reqOpts = extend({}, query, {
736 +
      typeof optionsOrCallback === 'function' ? optionsOrCallback : cb;
737 +
    const options =
738 +
      typeof optionsOrCallback === 'object'
739 +
        ? optionsOrCallback
740 +
        : ({} as GetInstanceConfigsOptions);
741 +
742 +
    const gaxOpts = extend(true, {}, options.gaxOptions);
743 +
    let reqOpts = extend({}, options, {
658 744
      parent: 'projects/' + this.projectId,
659 745
    });
746 +
    delete reqOpts.gaxOptions;
747 +
748 +
    // Copy over pageSize and pageToken values from gaxOptions.
749 +
    // However values set on options take precedence.
750 +
    if (gaxOpts) {
751 +
      reqOpts = extend(
752 +
        {},
753 +
        {
754 +
          pageSize: gaxOpts.pageSize,
755 +
          pageToken: gaxOpts.pageToken,
756 +
        },
757 +
        reqOpts
758 +
      );
759 +
      delete gaxOpts.pageSize;
760 +
      delete gaxOpts.pageToken;
761 +
    }
762 +
660 763
    return this.request(
661 764
      {
662 765
        client: 'InstanceAdminClient',
663 766
        method: 'listInstanceConfigs',
664 767
        reqOpts,
665 -
        gaxOpts: query,
768 +
        gaxOpts,
769 +
        headers: this.resourceHeader_,
666 770
      },
667 -
      callback
771 +
      (err, instanceConfigs, nextPageRequest, ...args) => {
772 +
        const nextQuery = nextPageRequest!
773 +
          ? extend({}, options, nextPageRequest!)
774 +
          : null;
775 +
        callback!(err, instanceConfigs, nextQuery, ...args);
776 +
      }
668 777
    );
669 778
  }
670 779
@@ -677,7 +786,7 @@
Loading
677 786
   * @see [ListInstanceConfigs API Documentation](https://cloud.google.com/spanner/docs/reference/rpc/google.spanner.admin.instance.v1#google.spanner.admin.instance.v1.InstanceAdmin.ListInstanceConfigs)
678 787
   *
679 788
   * @method Spanner#getInstanceConfigsStream
680 -
   * @param {GetInstanceConfigsRequest} [query] Query object for listing instance
789 +
   * @param {GetInstanceConfigsOptions} [options] Query object for listing instance
681 790
   *     configs.
682 791
   * @returns {ReadableStream} A readable stream that emits instance configs.
683 792
   *
@@ -702,16 +811,36 @@
Loading
702 811
   *   });
703 812
   */
704 813
  getInstanceConfigsStream(
705 -
    query?: GetInstanceConfigsRequest
814 +
    options: GetInstanceConfigsOptions = {}
706 815
  ): NodeJS.ReadableStream {
707 -
    const reqOpts = extend({}, query, {
816 +
    const gaxOpts = extend(true, {}, options.gaxOptions);
817 +
818 +
    let reqOpts = extend({}, options, {
708 819
      parent: 'projects/' + this.projectId,
709 820
    });
821 +
822 +
    // Copy over pageSize and pageToken values from gaxOptions.
823 +
    // However values set on options take precedence.
824 +
    if (gaxOpts) {
825 +
      reqOpts = extend(
826 +
        {},
827 +
        {
828 +
          pageSize: gaxOpts.pageSize,
829 +
          pageToken: gaxOpts.pageToken,
830 +
        },
831 +
        reqOpts
832 +
      );
833 +
      delete gaxOpts.pageSize;
834 +
      delete gaxOpts.pageToken;
835 +
    }
836 +
837 +
    delete reqOpts.gaxOptions;
710 838
    return this.requestStream({
711 839
      client: 'InstanceAdminClient',
712 840
      method: 'listInstanceConfigsStream',
713 841
      reqOpts,
714 -
      gaxOpts: query,
842 +
      gaxOpts,
843 +
      headers: this.resourceHeader_,
715 844
    });
716 845
  }
717 846
@@ -764,7 +893,12 @@
Loading
764 893
      const requestFn = gaxClient[config.method].bind(
765 894
        gaxClient,
766 895
        reqOpts,
767 -
        config.gaxOpts
896 +
        // Add headers to `gaxOpts`
897 +
        extend(true, {}, config.gaxOpts, {
898 +
          otherArgs: {
899 +
            headers: config.headers,
900 +
          },
901 +
        })
768 902
      );
769 903
      callback(null, requestFn);
770 904
    });
@@ -783,7 +917,7 @@
Loading
783 917
   */
784 918
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
785 919
  request(config: any, callback?: any): any {
786 -
    if (is.fn(callback)) {
920 +
    if (typeof callback === 'function') {
787 921
      this.prepareGapicRequest_(config, (err, requestFn) => {
788 922
        if (err) {
789 923
          callback(err);
@@ -939,6 +1073,20 @@
Loading
939 1073
    return new codec.Int(value);
940 1074
  }
941 1075
1076 +
  /**
1077 +
   * Helper function to get a Cloud Spanner Numeric object.
1078 +
   *
1079 +
   * @param {string} value The numeric value as a string.
1080 +
   * @returns {Numeric}
1081 +
   *
1082 +
   * @example
1083 +
   * const {Spanner} = require('@google-cloud/spanner');
1084 +
   * const numeric = Spanner.numeric("3.141592653");
1085 +
   */
1086 +
  static numeric(value): Numeric {
1087 +
    return new codec.Numeric(value);
1088 +
  }
1089 +
942 1090
  /**
943 1091
   * Helper function to get a Cloud Spanner Struct object.
944 1092
   *
@@ -969,9 +1117,9 @@
Loading
969 1117
  exclude: [
970 1118
    'date',
971 1119
    'float',
972 -
    'getInstanceConfigs',
973 1120
    'instance',
974 1121
    'int',
1122 +
    'numeric',
975 1123
    'operation',
976 1124
    'timestamp',
977 1125
  ],

@@ -32,7 +32,7 @@
Loading
32 32
import {RequestType} from 'google-gax/build/src/apitypes';
33 33
import * as protos from '../../protos/protos';
34 34
import * as gapicConfig from './instance_admin_client_config.json';
35 -
35 +
import {operationsProtos} from 'google-gax';
36 36
const version = require('../../../package.json').version;
37 37
38 38
/**
@@ -82,8 +82,10 @@
Loading
82 82
  /**
83 83
   * Construct an instance of InstanceAdminClient.
84 84
   *
85 -
   * @param {object} [options] - The configuration object. See the subsequent
86 -
   *   parameters for more details.
85 +
   * @param {object} [options] - The configuration object.
86 +
   * The options accepted by the constructor are described in detail
87 +
   * in [this document](https://github.com/googleapis/gax-nodejs/blob/master/client-libraries.md#creating-the-client-instance).
88 +
   * The common options are:
87 89
   * @param {object} [options.credentials] - Credentials object.
88 90
   * @param {string} [options.credentials.client_email]
89 91
   * @param {string} [options.credentials.private_key]
@@ -103,38 +105,33 @@
Loading
103 105
   *     your project ID will be detected automatically.
104 106
   * @param {string} [options.apiEndpoint] - The domain name of the
105 107
   *     API remote host.
108 +
   * @param {gax.ClientConfig} [options.clientConfig] - client configuration override.
109 +
   *     TODO(@alexander-fenster): link to gax documentation.
110 +
   * @param {boolean} fallback - Use HTTP fallback mode.
111 +
   *     In fallback mode, a special browser-compatible transport implementation is used
112 +
   *     instead of gRPC transport. In browser context (if the `window` object is defined)
113 +
   *     the fallback mode is enabled automatically; set `options.fallback` to `false`
114 +
   *     if you need to override this behavior.
106 115
   */
107 -
108 116
  constructor(opts?: ClientOptions) {
109 -
    // Ensure that options include the service address and port.
117 +
    // Ensure that options include all the required fields.
110 118
    const staticMembers = this.constructor as typeof InstanceAdminClient;
111 119
    const servicePath =
112 -
      opts && opts.servicePath
113 -
        ? opts.servicePath
114 -
        : opts && opts.apiEndpoint
115 -
        ? opts.apiEndpoint
116 -
        : staticMembers.servicePath;
117 -
    const port = opts && opts.port ? opts.port : staticMembers.port;
120 +
      opts?.servicePath || opts?.apiEndpoint || staticMembers.servicePath;
121 +
    const port = opts?.port || staticMembers.port;
122 +
    const clientConfig = opts?.clientConfig ?? {};
123 +
    const fallback = opts?.fallback ?? typeof window !== 'undefined';
124 +
    opts = Object.assign({servicePath, port, clientConfig, fallback}, opts);
118 125
119 -
    if (!opts) {
120 -
      opts = {servicePath, port};
126 +
    // If scopes are unset in options and we're connecting to a non-default endpoint, set scopes just in case.
127 +
    if (servicePath !== staticMembers.servicePath && !('scopes' in opts)) {
128 +
      opts['scopes'] = staticMembers.scopes;
121 129
    }
122 -
    opts.servicePath = opts.servicePath || servicePath;
123 -
    opts.port = opts.port || port;
124 -
    opts.clientConfig = opts.clientConfig || {};
125 130
126 -
    const isBrowser = typeof window !== 'undefined';
127 -
    if (isBrowser) {
128 -
      opts.fallback = true;
129 -
    }
130 -
    // If we are in browser, we are already using fallback because of the
131 -
    // "browser" field in package.json.
132 -
    // But if we were explicitly requested to use fallback, let's do it now.
133 -
    this._gaxModule = !isBrowser && opts.fallback ? gax.fallback : gax;
131 +
    // Choose either gRPC or proto-over-HTTP implementation of google-gax.
132 +
    this._gaxModule = opts.fallback ? gax.fallback : gax;
134 133
135 -
    // Create a `gaxGrpc` object, with any grpc-specific options
136 -
    // sent to the client.
137 -
    opts.scopes = (this.constructor as typeof InstanceAdminClient).scopes;
134 +
    // Create a `gaxGrpc` object, with any grpc-specific options sent to the client.
138 135
    this._gaxGrpc = new this._gaxModule.GrpcClient(opts);
139 136
140 137
    // Save options to use in initialize() method.
@@ -143,6 +140,11 @@
Loading
143 140
    // Save the auth object to the client, for use by other methods.
144 141
    this.auth = this._gaxGrpc.auth as gax.GoogleAuth;
145 142
143 +
    // Set the default scopes in auth client if needed.
144 +
    if (servicePath === staticMembers.servicePath) {
145 +
      this.auth.defaultScopes = staticMembers.scopes;
146 +
    }
147 +
146 148
    // Determine the client header string.
147 149
    const clientHeader = [`gax/${this._gaxModule.version}`, `gapic/${version}`];
148 150
    if (typeof process !== 'undefined' && 'versions' in process) {
@@ -184,6 +186,9 @@
Loading
184 186
      instanceConfigPathTemplate: new this._gaxModule.PathTemplate(
185 187
        'projects/{project}/instanceConfigs/{instance_config}'
186 188
      ),
189 +
      projectPathTemplate: new this._gaxModule.PathTemplate(
190 +
        'projects/{project}'
191 +
      ),
187 192
    };
188 193
189 194
    // Some of the methods on this service return "paged" results,
@@ -315,12 +320,14 @@
Loading
315 320
        }
316 321
      );
317 322
323 +
      const descriptor =
324 +
        this.descriptors.page[methodName] ||
325 +
        this.descriptors.longrunning[methodName] ||
326 +
        undefined;
318 327
      const apiCall = this._gaxModule.createApiCall(
319 328
        callPromise,
320 329
        this._defaults[methodName],
321 -
        this.descriptors.page[methodName] ||
322 -
          this.descriptors.stream[methodName] ||
323 -
          this.descriptors.longrunning[methodName]
330 +
        descriptor
324 331
      );
325 332
326 333
      this.innerApiCalls[methodName] = apiCall;
@@ -331,6 +338,7 @@
Loading
331 338
332 339
  /**
333 340
   * The DNS address for this API service.
341 +
   * @returns {string} The DNS address for this service.
334 342
   */
335 343
  static get servicePath() {
336 344
    return 'spanner.googleapis.com';
@@ -339,13 +347,15 @@
Loading
339 347
  /**
340 348
   * The DNS address for this API service - same as servicePath(),
341 349
   * exists for compatibility reasons.
350 +
   * @returns {string} The DNS address for this service.
342 351
   */
343 352
  static get apiEndpoint() {
344 353
    return 'spanner.googleapis.com';
345 354
  }
346 355
347 356
  /**
348 357
   * The port for this API service.
358 +
   * @returns {number} The default port for this service.
349 359
   */
350 360
  static get port() {
351 361
    return 443;
@@ -354,6 +364,7 @@
Loading
354 364
  /**
355 365
   * The scopes needed to make gRPC calls for every method defined
356 366
   * in this service.
367 +
   * @returns {string[]} List of default scopes.
357 368
   */
358 369
  static get scopes() {
359 370
    return [
@@ -366,8 +377,7 @@
Loading
366 377
  getProjectId(callback: Callback<string, undefined, undefined>): void;
367 378
  /**
368 379
   * Return the project ID used by this class.
369 -
   * @param {function(Error, string)} callback - the callback to
370 -
   *   be called with the current project Id.
380 +
   * @returns {Promise} A promise that resolves to string containing the project ID.
371 381
   */
372 382
  getProjectId(
373 383
    callback?: Callback<string, undefined, undefined>
@@ -428,7 +438,11 @@
Loading
428 438
   *   Call options. See {@link https://googleapis.dev/nodejs/google-gax/latest/interfaces/CallOptions.html|CallOptions} for more details.
429 439
   * @returns {Promise} - The promise which resolves to an array.
430 440
   *   The first element of the array is an object representing [InstanceConfig]{@link google.spanner.admin.instance.v1.InstanceConfig}.
431 -
   *   The promise has a method named "cancel" which cancels the ongoing API call.
441 +
   *   Please see the
442 +
   *   [documentation](https://github.com/googleapis/gax-nodejs/blob/master/client-libraries.md#regular-methods)
443 +
   *   for more details and examples.
444 +
   * @example
445 +
   * const [response] = await client.getInstanceConfig(request);
432 446
   */
433 447
  getInstanceConfig(
434 448
    request: protos.google.spanner.admin.instance.v1.IGetInstanceConfigRequest,
@@ -524,7 +538,11 @@
Loading
524 538
   *   Call options. See {@link https://googleapis.dev/nodejs/google-gax/latest/interfaces/CallOptions.html|CallOptions} for more details.
525 539
   * @returns {Promise} - The promise which resolves to an array.
526 540
   *   The first element of the array is an object representing [Instance]{@link google.spanner.admin.instance.v1.Instance}.
527 -
   *   The promise has a method named "cancel" which cancels the ongoing API call.
541 +
   *   Please see the
542 +
   *   [documentation](https://github.com/googleapis/gax-nodejs/blob/master/client-libraries.md#regular-methods)
543 +
   *   for more details and examples.
544 +
   * @example
545 +
   * const [response] = await client.getInstance(request);
528 546
   */
529 547
  getInstance(
530 548
    request: protos.google.spanner.admin.instance.v1.IGetInstanceRequest,
@@ -626,7 +644,11 @@
Loading
626 644
   *   Call options. See {@link https://googleapis.dev/nodejs/google-gax/latest/interfaces/CallOptions.html|CallOptions} for more details.
627 645
   * @returns {Promise} - The promise which resolves to an array.
628 646
   *   The first element of the array is an object representing [Empty]{@link google.protobuf.Empty}.
629 -
   *   The promise has a method named "cancel" which cancels the ongoing API call.
647 +
   *   Please see the
648 +
   *   [documentation](https://github.com/googleapis/gax-nodejs/blob/master/client-libraries.md#regular-methods)
649 +
   *   for more details and examples.
650 +
   * @example
651 +
   * const [response] = await client.deleteInstance(request);
630 652
   */
631 653
  deleteInstance(
632 654
    request: protos.google.spanner.admin.instance.v1.IDeleteInstanceRequest,
@@ -723,7 +745,11 @@
Loading
723 745
   *   Call options. See {@link https://googleapis.dev/nodejs/google-gax/latest/interfaces/CallOptions.html|CallOptions} for more details.
724 746
   * @returns {Promise} - The promise which resolves to an array.
725 747
   *   The first element of the array is an object representing [Policy]{@link google.iam.v1.Policy}.
726 -
   *   The promise has a method named "cancel" which cancels the ongoing API call.
748 +
   *   Please see the
749 +
   *   [documentation](https://github.com/googleapis/gax-nodejs/blob/master/client-libraries.md#regular-methods)
750 +
   *   for more details and examples.
751 +
   * @example
752 +
   * const [response] = await client.setIamPolicy(request);
727 753
   */
728 754
  setIamPolicy(
729 755
    request: protos.google.iam.v1.ISetIamPolicyRequest,
@@ -811,7 +837,11 @@
Loading
811 837
   *   Call options. See {@link https://googleapis.dev/nodejs/google-gax/latest/interfaces/CallOptions.html|CallOptions} for more details.
812 838
   * @returns {Promise} - The promise which resolves to an array.
813 839
   *   The first element of the array is an object representing [Policy]{@link google.iam.v1.Policy}.
814 -
   *   The promise has a method named "cancel" which cancels the ongoing API call.
840 +
   *   Please see the
841 +
   *   [documentation](https://github.com/googleapis/gax-nodejs/blob/master/client-libraries.md#regular-methods)
842 +
   *   for more details and examples.
843 +
   * @example
844 +
   * const [response] = await client.getIamPolicy(request);
815 845
   */
816 846
  getIamPolicy(
817 847
    request: protos.google.iam.v1.IGetIamPolicyRequest,
@@ -902,7 +932,11 @@
Loading
902 932
   *   Call options. See {@link https://googleapis.dev/nodejs/google-gax/latest/interfaces/CallOptions.html|CallOptions} for more details.
903 933
   * @returns {Promise} - The promise which resolves to an array.
904 934
   *   The first element of the array is an object representing [TestIamPermissionsResponse]{@link google.iam.v1.TestIamPermissionsResponse}.
905 -
   *   The promise has a method named "cancel" which cancels the ongoing API call.
935 +
   *   Please see the
936 +
   *   [documentation](https://github.com/googleapis/gax-nodejs/blob/master/client-libraries.md#regular-methods)
937 +
   *   for more details and examples.
938 +
   * @example
939 +
   * const [response] = await client.testIamPermissions(request);
906 940
   */
907 941
  testIamPermissions(
908 942
    request: protos.google.iam.v1.ITestIamPermissionsRequest,
@@ -1032,8 +1066,15 @@
Loading
1032 1066
   * @param {object} [options]
1033 1067
   *   Call options. See {@link https://googleapis.dev/nodejs/google-gax/latest/interfaces/CallOptions.html|CallOptions} for more details.
1034 1068
   * @returns {Promise} - The promise which resolves to an array.
1035 -
   *   The first element of the array is an object representing [Operation]{@link google.longrunning.Operation}.
1036 -
   *   The promise has a method named "cancel" which cancels the ongoing API call.
1069 +
   *   The first element of the array is an object representing
1070 +
   *   a long running operation. Its `promise()` method returns a promise
1071 +
   *   you can `await` for.
1072 +
   *   Please see the
1073 +
   *   [documentation](https://github.com/googleapis/gax-nodejs/blob/master/client-libraries.md#long-running-operations)
1074 +
   *   for more details and examples.
1075 +
   * @example
1076 +
   * const [operation] = await client.createInstance(request);
1077 +
   * const [response] = await operation.promise();
1037 1078
   */
1038 1079
  createInstance(
1039 1080
    request: protos.google.spanner.admin.instance.v1.ICreateInstanceRequest,
@@ -1084,6 +1125,43 @@
Loading
1084 1125
    this.initialize();
1085 1126
    return this.innerApiCalls.createInstance(request, options, callback);
1086 1127
  }
1128 +
  /**
1129 +
   * Check the status of the long running operation returned by `createInstance()`.
1130 +
   * @param {String} name
1131 +
   *   The operation name that will be passed.
1132 +
   * @returns {Promise} - The promise which resolves to an object.
1133 +
   *   The decoded operation object has result and metadata field to get information from.
1134 +
   *   Please see the
1135 +
   *   [documentation](https://github.com/googleapis/gax-nodejs/blob/master/client-libraries.md#long-running-operations)
1136 +
   *   for more details and examples.
1137 +
   * @example
1138 +
   * const decodedOperation = await checkCreateInstanceProgress(name);
1139 +
   * console.log(decodedOperation.result);
1140 +
   * console.log(decodedOperation.done);
1141 +
   * console.log(decodedOperation.metadata);
1142 +
   */
1143 +
  async checkCreateInstanceProgress(
1144 +
    name: string
1145 +
  ): Promise<
1146 +
    LROperation<
1147 +
      protos.google.spanner.admin.instance.v1.Instance,
1148 +
      protos.google.spanner.admin.instance.v1.CreateInstanceMetadata
1149 +
    >
1150 +
  > {
1151 +
    const request = new operationsProtos.google.longrunning.GetOperationRequest(
1152 +
      {name}
1153 +
    );
1154 +
    const [operation] = await this.operationsClient.getOperation(request);
1155 +
    const decodeOperation = new gax.Operation(
1156 +
      operation,
1157 +
      this.descriptors.longrunning.createInstance,
1158 +
      gax.createDefaultBackoffSettings()
1159 +
    );
1160 +
    return decodeOperation as LROperation<
1161 +
      protos.google.spanner.admin.instance.v1.Instance,
1162 +
      protos.google.spanner.admin.instance.v1.CreateInstanceMetadata
1163 +
    >;
1164 +
  }
1087 1165
  updateInstance(
1088 1166
    request: protos.google.spanner.admin.instance.v1.IUpdateInstanceRequest,
1089 1167
    options?: gax.CallOptions
@@ -1175,8 +1253,15 @@
Loading
1175 1253
   * @param {object} [options]
1176 1254
   *   Call options. See {@link https://googleapis.dev/nodejs/google-gax/latest/interfaces/CallOptions.html|CallOptions} for more details.
1177 1255
   * @returns {Promise} - The promise which resolves to an array.
1178 -
   *   The first element of the array is an object representing [Operation]{@link google.longrunning.Operation}.
1179 -
   *   The promise has a method named "cancel" which cancels the ongoing API call.
1256 +
   *   The first element of the array is an object representing
1257 +
   *   a long running operation. Its `promise()` method returns a promise
1258 +
   *   you can `await` for.
1259 +
   *   Please see the
1260 +
   *   [documentation](https://github.com/googleapis/gax-nodejs/blob/master/client-libraries.md#long-running-operations)
1261 +
   *   for more details and examples.
1262 +
   * @example
1263 +
   * const [operation] = await client.updateInstance(request);
1264 +
   * const [response] = await operation.promise();
1180 1265
   */
1181 1266
  updateInstance(
1182 1267
    request: protos.google.spanner.admin.instance.v1.IUpdateInstanceRequest,
@@ -1227,6 +1312,43 @@
Loading
1227 1312
    this.initialize();
1228 1313
    return this.innerApiCalls.updateInstance(request, options, callback);
1229 1314
  }
1315 +
  /**
1316 +
   * Check the status of the long running operation returned by `updateInstance()`.
1317 +
   * @param {String} name
1318 +
   *   The operation name that will be passed.
1319 +
   * @returns {Promise} - The promise which resolves to an object.
1320 +
   *   The decoded operation object has result and metadata field to get information from.
1321 +
   *   Please see the
1322 +
   *   [documentation](https://github.com/googleapis/gax-nodejs/blob/master/client-libraries.md#long-running-operations)
1323 +
   *   for more details and examples.
1324 +
   * @example
1325 +
   * const decodedOperation = await checkUpdateInstanceProgress(name);
1326 +
   * console.log(decodedOperation.result);
1327 +
   * console.log(decodedOperation.done);
1328 +
   * console.log(decodedOperation.metadata);
1329 +
   */
1330 +
  async checkUpdateInstanceProgress(
1331 +
    name: string
1332 +
  ): Promise<
1333 +
    LROperation<
1334 +
      protos.google.spanner.admin.instance.v1.Instance,
1335 +
      protos.google.spanner.admin.instance.v1.UpdateInstanceMetadata
1336 +
    >
1337 +
  > {
1338 +
    const request = new operationsProtos.google.longrunning.GetOperationRequest(
1339 +
      {name}
1340 +
    );
1341 +
    const [operation] = await this.operationsClient.getOperation(request);
1342 +
    const decodeOperation = new gax.Operation(
1343 +
      operation,
1344 +
      this.descriptors.longrunning.updateInstance,
1345 +
      gax.createDefaultBackoffSettings()
1346 +
    );
1347 +
    return decodeOperation as LROperation<
1348 +
      protos.google.spanner.admin.instance.v1.Instance,
1349 +
      protos.google.spanner.admin.instance.v1.UpdateInstanceMetadata
1350 +
    >;
1351 +
  }
1230 1352
  listInstanceConfigs(
1231 1353
    request: protos.google.spanner.admin.instance.v1.IListInstanceConfigsRequest,
1232 1354
    options?: gax.CallOptions
@@ -1278,19 +1400,14 @@
Loading
1278 1400
   *   Call options. See {@link https://googleapis.dev/nodejs/google-gax/latest/interfaces/CallOptions.html|CallOptions} for more details.
1279 1401
   * @returns {Promise} - The promise which resolves to an array.
1280 1402
   *   The first element of the array is Array of [InstanceConfig]{@link google.spanner.admin.instance.v1.InstanceConfig}.
1281 -
   *   The client library support auto-pagination by default: it will call the API as many
1403 +
   *   The client library will perform auto-pagination by default: it will call the API as many
1282 1404
   *   times as needed and will merge results from all the pages into this array.
1283 -
   *
1284 -
   *   When autoPaginate: false is specified through options, the array has three elements.
1285 -
   *   The first element is Array of [InstanceConfig]{@link google.spanner.admin.instance.v1.InstanceConfig} that corresponds to
1286 -
   *   the one page received from the API server.
1287 -
   *   If the second element is not null it contains the request object of type [ListInstanceConfigsRequest]{@link google.spanner.admin.instance.v1.ListInstanceConfigsRequest}
1288 -
   *   that can be used to obtain the next page of the results.
1289 -
   *   If it is null, the next page does not exist.
1290 -
   *   The third element contains the raw response received from the API server. Its type is
1291 -
   *   [ListInstanceConfigsResponse]{@link google.spanner.admin.instance.v1.ListInstanceConfigsResponse}.
1292 -
   *
1293 -
   *   The promise has a method named "cancel" which cancels the ongoing API call.
1405 +
   *   Note that it can affect your quota.
1406 +
   *   We recommend using `listInstanceConfigsAsync()`
1407 +
   *   method described below for async iteration which you can stop as needed.
1408 +
   *   Please see the
1409 +
   *   [documentation](https://github.com/googleapis/gax-nodejs/blob/master/client-libraries.md#auto-pagination)
1410 +
   *   for more details and examples.
1294 1411
   */
1295 1412
  listInstanceConfigs(
1296 1413
    request: protos.google.spanner.admin.instance.v1.IListInstanceConfigsRequest,
@@ -1338,18 +1455,7 @@
Loading
1338 1455
  }
1339 1456
1340 1457
  /**
1341 -
   * Equivalent to {@link listInstanceConfigs}, but returns a NodeJS Stream object.
1342 -
   *
1343 -
   * This fetches the paged responses for {@link listInstanceConfigs} continuously
1344 -
   * and invokes the callback registered for 'data' event for each element in the
1345 -
   * responses.
1346 -
   *
1347 -
   * The returned object has 'end' method when no more elements are required.
1348 -
   *
1349 -
   * autoPaginate option will be ignored.
1350 -
   *
1351 -
   * @see {@link https://nodejs.org/api/stream.html}
1352 -
   *
1458 +
   * Equivalent to `method.name.toCamelCase()`, but returns a NodeJS Stream object.
1353 1459
   * @param {Object} request
1354 1460
   *   The request object that will be sent.
1355 1461
   * @param {string} request.parent
@@ -1367,6 +1473,13 @@
Loading
1367 1473
   *   Call options. See {@link https://googleapis.dev/nodejs/google-gax/latest/interfaces/CallOptions.html|CallOptions} for more details.
1368 1474
   * @returns {Stream}
1369 1475
   *   An object stream which emits an object representing [InstanceConfig]{@link google.spanner.admin.instance.v1.InstanceConfig} on 'data' event.
1476 +
   *   The client library will perform auto-pagination by default: it will call the API as many
1477 +
   *   times as needed. Note that it can affect your quota.
1478 +
   *   We recommend using `listInstanceConfigsAsync()`
1479 +
   *   method described below for async iteration which you can stop as needed.
1480 +
   *   Please see the
1481 +
   *   [documentation](https://github.com/googleapis/gax-nodejs/blob/master/client-libraries.md#auto-pagination)
1482 +
   *   for more details and examples.
1370 1483
   */
1371 1484
  listInstanceConfigsStream(
1372 1485
    request?: protos.google.spanner.admin.instance.v1.IListInstanceConfigsRequest,
@@ -1391,10 +1504,9 @@
Loading
1391 1504
  }
1392 1505
1393 1506
  /**
1394 -
   * Equivalent to {@link listInstanceConfigs}, but returns an iterable object.
1395 -
   *
1396 -
   * for-await-of syntax is used with the iterable to recursively get response element on-demand.
1507 +
   * Equivalent to `listInstanceConfigs`, but returns an iterable object.
1397 1508
   *
1509 +
   * `for`-`await`-`of` syntax is used with the iterable to get response elements on-demand.
1398 1510
   * @param {Object} request
1399 1511
   *   The request object that will be sent.
1400 1512
   * @param {string} request.parent
@@ -1411,7 +1523,18 @@
Loading
1411 1523
   * @param {object} [options]
1412 1524
   *   Call options. See {@link https://googleapis.dev/nodejs/google-gax/latest/interfaces/CallOptions.html|CallOptions} for more details.
1413 1525
   * @returns {Object}
1414 -
   *   An iterable Object that conforms to @link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Iteration_protocols.
1526 +
   *   An iterable Object that allows [async iteration](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Iteration_protocols).
1527 +
   *   When you iterate the returned iterable, each element will be an object representing
1528 +
   *   [InstanceConfig]{@link google.spanner.admin.instance.v1.InstanceConfig}. The API will be called under the hood as needed, once per the page,
1529 +
   *   so you can stop the iteration when you don't need more results.
1530 +
   *   Please see the
1531 +
   *   [documentation](https://github.com/googleapis/gax-nodejs/blob/master/client-libraries.md#auto-pagination)
1532 +
   *   for more details and examples.
1533 +
   * @example
1534 +
   * const iterable = client.listInstanceConfigsAsync(request);
1535 +
   * for await (const response of iterable) {
1536 +
   *   // process response
1537 +
   * }
1415 1538
   */
1416 1539
  listInstanceConfigsAsync(
1417 1540
    request?: protos.google.spanner.admin.instance.v1.IListInstanceConfigsRequest,
@@ -1505,19 +1628,14 @@
Loading
1505 1628
   *   Call options. See {@link https://googleapis.dev/nodejs/google-gax/latest/interfaces/CallOptions.html|CallOptions} for more details.
1506 1629
   * @returns {Promise} - The promise which resolves to an array.
1507 1630
   *   The first element of the array is Array of [Instance]{@link google.spanner.admin.instance.v1.Instance}.
1508 -
   *   The client library support auto-pagination by default: it will call the API as many
1631 +
   *   The client library will perform auto-pagination by default: it will call the API as many
1509 1632
   *   times as needed and will merge results from all the pages into this array.
1510 -
   *
1511 -
   *   When autoPaginate: false is specified through options, the array has three elements.
1512 -
   *   The first element is Array of [Instance]{@link google.spanner.admin.instance.v1.Instance} that corresponds to
1513 -
   *   the one page received from the API server.
1514 -
   *   If the second element is not null it contains the request object of type [ListInstancesRequest]{@link google.spanner.admin.instance.v1.ListInstancesRequest}
1515 -
   *   that can be used to obtain the next page of the results.
1516 -
   *   If it is null, the next page does not exist.
1517 -
   *   The third element contains the raw response received from the API server. Its type is
1518 -
   *   [ListInstancesResponse]{@link google.spanner.admin.instance.v1.ListInstancesResponse}.
1519 -
   *
1520 -
   *   The promise has a method named "cancel" which cancels the ongoing API call.
1633 +
   *   Note that it can affect your quota.
1634 +
   *   We recommend using `listInstancesAsync()`
1635 +
   *   method described below for async iteration which you can stop as needed.
1636 +
   *   Please see the
1637 +
   *   [documentation](https://github.com/googleapis/gax-nodejs/blob/master/client-libraries.md#auto-pagination)
1638 +
   *   for more details and examples.
1521 1639
   */
1522 1640
  listInstances(
1523 1641
    request: protos.google.spanner.admin.instance.v1.IListInstancesRequest,
@@ -1565,18 +1683,7 @@
Loading
1565 1683
  }
1566 1684
1567 1685
  /**
1568 -
   * Equivalent to {@link listInstances}, but returns a NodeJS Stream object.
1569 -
   *
1570 -
   * This fetches the paged responses for {@link listInstances} continuously
1571 -
   * and invokes the callback registered for 'data' event for each element in the
1572 -
   * responses.
1573 -
   *
1574 -
   * The returned object has 'end' method when no more elements are required.
1575 -
   *
1576 -
   * autoPaginate option will be ignored.
1577 -
   *
1578 -
   * @see {@link https://nodejs.org/api/stream.html}
1579 -
   *
1686 +
   * Equivalent to `method.name.toCamelCase()`, but returns a NodeJS Stream object.
1580 1687
   * @param {Object} request
1581 1688
   *   The request object that will be sent.
1582 1689
   * @param {string} request.parent
@@ -1613,6 +1720,13 @@
Loading
1613 1720
   *   Call options. See {@link https://googleapis.dev/nodejs/google-gax/latest/interfaces/CallOptions.html|CallOptions} for more details.
1614 1721
   * @returns {Stream}
1615 1722
   *   An object stream which emits an object representing [Instance]{@link google.spanner.admin.instance.v1.Instance} on 'data' event.
1723 +
   *   The client library will perform auto-pagination by default: it will call the API as many
1724 +
   *   times as needed. Note that it can affect your quota.
1725 +
   *   We recommend using `listInstancesAsync()`
1726 +
   *   method described below for async iteration which you can stop as needed.
1727 +
   *   Please see the
1728 +
   *   [documentation](https://github.com/googleapis/gax-nodejs/blob/master/client-libraries.md#auto-pagination)
1729 +
   *   for more details and examples.
1616 1730
   */
1617 1731
  listInstancesStream(
1618 1732
    request?: protos.google.spanner.admin.instance.v1.IListInstancesRequest,
@@ -1637,10 +1751,9 @@
Loading
1637 1751
  }
1638 1752
1639 1753
  /**
1640 -
   * Equivalent to {@link listInstances}, but returns an iterable object.
1641 -
   *
1642 -
   * for-await-of syntax is used with the iterable to recursively get response element on-demand.
1754 +
   * Equivalent to `listInstances`, but returns an iterable object.
1643 1755
   *
1756 +
   * `for`-`await`-`of` syntax is used with the iterable to get response elements on-demand.
1644 1757
   * @param {Object} request
1645 1758
   *   The request object that will be sent.
1646 1759
   * @param {string} request.parent
@@ -1676,7 +1789,18 @@
Loading
1676 1789
   * @param {object} [options]
1677 1790
   *   Call options. See {@link https://googleapis.dev/nodejs/google-gax/latest/interfaces/CallOptions.html|CallOptions} for more details.
1678 1791
   * @returns {Object}
1679 -
   *   An iterable Object that conforms to @link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Iteration_protocols.
1792 +
   *   An iterable Object that allows [async iteration](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Iteration_protocols).
1793 +
   *   When you iterate the returned iterable, each element will be an object representing
1794 +
   *   [Instance]{@link google.spanner.admin.instance.v1.Instance}. The API will be called under the hood as needed, once per the page,
1795 +
   *   so you can stop the iteration when you don't need more results.
1796 +
   *   Please see the
1797 +
   *   [documentation](https://github.com/googleapis/gax-nodejs/blob/master/client-libraries.md#auto-pagination)
1798 +
   *   for more details and examples.
1799 +
   * @example
1800 +
   * const iterable = client.listInstancesAsync(request);
1801 +
   * for await (const response of iterable) {
1802 +
   *   // process response
1803 +
   * }
1680 1804
   */
1681 1805
  listInstancesAsync(
1682 1806
    request?: protos.google.spanner.admin.instance.v1.IListInstancesRequest,
@@ -1781,9 +1905,33 @@
Loading
1781 1905
  }
1782 1906
1783 1907
  /**
1784 -
   * Terminate the GRPC channel and close the client.
1908 +
   * Return a fully-qualified project resource name string.
1909 +
   *
1910 +
   * @param {string} project
1911 +
   * @returns {string} Resource name string.
1912 +
   */
1913 +
  projectPath(project: string) {
1914 +
    return this.pathTemplates.projectPathTemplate.render({
1915 +
      project: project,
1916 +
    });
1917 +
  }
1918 +
1919 +
  /**
1920 +
   * Parse the project from Project resource.
1921 +
   *
1922 +
   * @param {string} projectName
1923 +
   *   A fully-qualified path representing Project resource.
1924 +
   * @returns {string} A string representing the project.
1925 +
   */
1926 +
  matchProjectFromProjectName(projectName: string) {
1927 +
    return this.pathTemplates.projectPathTemplate.match(projectName).project;
1928 +
  }
1929 +
1930 +
  /**
1931 +
   * Terminate the gRPC channel and close the client.
1785 1932
   *
1786 1933
   * The client will no longer be usable and all future behavior is undefined.
1934 +
   * @returns {Promise} A promise that resolves when the client is closed.
1787 1935
   */
1788 1936
  close(): Promise<void> {
1789 1937
    this.initialize();

@@ -17,46 +17,52 @@
Loading
17 17
import {
18 18
  ApiError,
19 19
  ExistsCallback,
20 +
  GetConfig,
20 21
  Metadata,
21 22
  ServiceObjectConfig,
22 -
  GetConfig,
23 23
} from '@google-cloud/common';
24 -
import {GrpcServiceObject} from './common-grpc/service-object';
25 -
import {promisify, promisifyAll} from '@google-cloud/promisify';
26 -
import arrify = require('arrify');
24 +
// eslint-disable-next-line @typescript-eslint/no-var-requires
25 +
const common = require('./common-grpc/service-object');
26 +
import {promisify, promisifyAll, callbackifyAll} from '@google-cloud/promisify';
27 27
import * as extend from 'extend';
28 28
import * as r from 'teeny-request';
29 29
import * as streamEvents from 'stream-events';
30 30
import * as through from 'through2';
31 -
import {Operation as GaxOperation} from 'google-gax';
31 +
import {CallOptions, grpc, Operation as GaxOperation} from 'google-gax';
32 32
import {Backup} from './backup';
33 33
import {BatchTransaction, TransactionIdentifier} from './batch-transaction';
34 -
import {google as databaseAdmin} from '../protos/protos';
34 +
import * as pumpify from 'pumpify';
35 +
import {
36 +
  google as databaseAdmin,
37 +
  google,
38 +
  google as spannerClient,
39 +
} from '../protos/protos';
35 40
import {
36 -
  Instance,
37 -
  CreateDatabaseOptions,
38 41
  CreateDatabaseCallback,
42 +
  CreateDatabaseOptions,
39 43
  GetDatabaseOperationsOptions,
40 44
  GetDatabaseOperationsResponse,
45 +
  Instance,
46 +
  GetDatabaseOperationsCallback,
41 47
} from './instance';
42 48
import {PartialResultStream, Row} from './partial-result-stream';
43 49
import {Session} from './session';
44 50
import {
51 +
  isSessionNotFoundError,
45 52
  SessionPool,
46 -
  SessionPoolOptions,
47 53
  SessionPoolCloseCallback,
48 54
  SessionPoolInterface,
49 -
  isSessionNotFoundError,
55 +
  SessionPoolOptions,
50 56
} from './session-pool';
51 -
import {Table, CreateTableCallback, CreateTableResponse} from './table';
57 +
import {CreateTableCallback, CreateTableResponse, Table} from './table';
52 58
import {
59 +
  ExecuteSqlRequest,
60 +
  RunCallback,
61 +
  RunResponse,
62 +
  RunUpdateCallback,
53 63
  Snapshot,
54 64
  TimestampBounds,
55 65
  Transaction,
56 -
  ExecuteSqlRequest,
57 -
  RunUpdateCallback,
58 -
  RunResponse,
59 -
  RunCallback,
60 66
} from './transaction';
61 67
import {
62 68
  AsyncRunTransactionCallback,
@@ -65,23 +71,21 @@
Loading
65 71
  RunTransactionOptions,
66 72
  TransactionRunner,
67 73
} from './transaction-runner';
68 -
69 -
import {google} from '../protos/protos';
70 74
import {
71 75
  IOperation,
72 -
  Schema,
76 +
  LongRunningCallback,
77 +
  NormalCallback,
78 +
  PagedOptionsWithFilter,
79 +
  CLOUD_RESOURCE_HEADER,
80 +
  PagedResponse,
73 81
  RequestCallback,
74 -
  PagedRequest,
75 82
  ResourceCallback,
76 -
  PagedResponse,
77 -
  NormalCallback,
78 -
  LongRunningCallback,
83 +
  Schema,
79 84
} from './common';
80 -
import {ServiceError, CallOptions} from 'grpc';
81 -
import {Readable, Transform, Duplex} from 'stream';
85 +
import {Duplex, Readable, Transform} from 'stream';
82 86
import {PreciseDate} from '@google-cloud/precise-date';
83 -
import {google as spannerClient} from '../protos/protos';
84 87
import {EnumKey, RequestConfig, TranslateEnumKeys} from '.';
88 +
import arrify = require('arrify');
85 89
86 90
type CreateBatchTransactionCallback = ResourceCallback<
87 91
  BatchTransaction,
@@ -120,7 +124,7 @@
Loading
120 124
121 125
type ResultSetStats = spannerClient.spanner.v1.ResultSetStats;
122 126
123 -
type GetSessionsOptions = PagedRequest<google.spanner.v1.IListSessionsRequest>;
127 +
export type GetSessionsOptions = PagedOptionsWithFilter;
124 128
125 129
/**
126 130
 * IDatabase structure with database state enum translated to string form.
@@ -166,7 +170,9 @@
Loading
166 170
>;
167 171
168 172
export type GetDatabaseConfig = GetConfig &
169 -
  databaseAdmin.spanner.admin.database.v1.GetDatabaseRequest;
173 +
  databaseAdmin.spanner.admin.database.v1.GetDatabaseRequest & {
174 +
    gaxOptions?: CallOptions;
175 +
  };
170 176
type DatabaseCloseResponse = [google.protobuf.IEmpty];
171 177
172 178
export type CreateSessionResponse = [
@@ -175,8 +181,8 @@
Loading
175 181
];
176 182
177 183
export interface CreateSessionOptions {
178 -
  name?: string | null;
179 184
  labels?: {[k: string]: string} | null;
185 +
  gaxOptions?: CallOptions;
180 186
}
181 187
182 188
export type CreateSessionCallback = ResourceCallback<
@@ -198,7 +204,10 @@
Loading
198 204
  spannerClient.spanner.v1.IBatchCreateSessionsResponse
199 205
>;
200 206
201 -
export type DatabaseDeleteCallback = NormalCallback<r.Response>;
207 +
export type DatabaseDeleteResponse = [databaseAdmin.protobuf.IEmpty];
208 +
export type DatabaseDeleteCallback = NormalCallback<
209 +
  databaseAdmin.protobuf.IEmpty
210 +
>;
202 211
203 212
export interface CancelableDuplex extends Duplex {
204 213
  cancel(): void;
@@ -212,6 +221,11 @@
Loading
212 221
  databaseAdmin.longrunning.IOperation
213 222
];
214 223
224 +
export type GetRestoreInfoCallback = NormalCallback<IRestoreInfoTranslatedEnum>;
225 +
export type GetStateCallback = NormalCallback<
226 +
  EnumKey<typeof databaseAdmin.spanner.admin.database.v1.Database.State>
227 +
>;
228 +
215 229
interface DatabaseRequest {
216 230
  (
217 231
    config: RequestConfig,
@@ -237,11 +251,12 @@
Loading
237 251
 * const instance = spanner.instance('my-instance');
238 252
 * const database = instance.database('my-database');
239 253
 */
240 -
class Database extends GrpcServiceObject {
254 +
class Database extends common.GrpcServiceObject {
241 255
  private instance: Instance;
242 256
  formattedName_: string;
243 257
  pool_: SessionPoolInterface;
244 258
  queryOptions_?: spannerClient.spanner.v1.ExecuteSqlRequest.IQueryOptions;
259 +
  resourceHeader_: {[k: string]: string};
245 260
  request: DatabaseRequest;
246 261
  constructor(
247 262
    instance: Instance,
@@ -304,7 +319,41 @@
Loading
304 319
        options: CreateDatabaseOptions,
305 320
        callback: CreateDatabaseCallback
306 321
      ) => {
307 -
        return instance.createDatabase(formattedName_, options, callback);
322 +
        const pool = this.pool_ as SessionPool;
323 +
        if (pool._pending > 0) {
324 +
          // If there are BatchCreateSessions requests pending, then we should
325 +
          // wait until these have finished before we try to create the database.
326 +
          // Otherwise the results of these requests might be propagated to
327 +
          // client requests that are submitted after the database has been
328 +
          // created. If the pending requests have not finished within 10 seconds,
329 +
          // they will be ignored and the database creation will proceed.
330 +
          let timeout;
331 +
          const promises = [
332 +
            new Promise<void>(
333 +
              resolve => (timeout = setTimeout(resolve, 10000))
334 +
            ),
335 +
            new Promise<void>(resolve => {
336 +
              pool
337 +
                .on('available', () => {
338 +
                  if (pool._pending === 0) {
339 +
                    clearTimeout(timeout);
340 +
                    resolve();
341 +
                  }
342 +
                })
343 +
                .on('createError', () => {
344 +
                  if (pool._pending === 0) {
345 +
                    clearTimeout(timeout);
346 +
                    resolve();
347 +
                  }
348 +
                });
349 +
            }),
350 +
          ];
351 +
          Promise.race(promises).then(() =>
352 +
            instance.createDatabase(formattedName_, options, callback)
353 +
          );
354 +
        } else {
355 +
          return instance.createDatabase(formattedName_, options, callback);
356 +
        }
308 357
      },
309 358
    } as {}) as ServiceObjectConfig);
310 359
@@ -314,9 +363,11 @@
Loading
314 363
        : new SessionPool(this, poolOptions);
315 364
    this.formattedName_ = formattedName_;
316 365
    this.instance = instance;
366 +
    this.resourceHeader_ = {
367 +
      [CLOUD_RESOURCE_HEADER]: this.formattedName_,
368 +
    };
317 369
    this.request = instance.request;
318 -
    // eslint-disable-next-line @typescript-eslint/no-explicit-any
319 -
    this.requestStream = instance.requestStream as any;
370 +
    this.requestStream = instance.requestStream;
320 371
    this.pool_.on('error', this.emit.bind(this, 'error'));
321 372
    this.pool_.open();
322 373
    this.queryOptions_ = Object.assign(
@@ -417,6 +468,8 @@
Loading
417 468
        client: 'SpannerClient',
418 469
        method: 'batchCreateSessions',
419 470
        reqOpts,
471 +
        gaxOpts: options.gaxOptions,
472 +
        headers: this.resourceHeader_,
420 473
      },
421 474
      (err, resp) => {
422 475
        if (err) {
@@ -555,12 +608,13 @@
Loading
555 608
        ? (optionsOrCallback as TimestampBounds)
556 609
        : {};
557 610
558 -
    this.createSession((err, session, resp) => {
611 +
    this.pool_.getReadSession((err, session) => {
559 612
      if (err) {
560 -
        callback!(err, null, resp);
613 +
        callback!(err, null, undefined);
561 614
        return;
562 615
      }
563 616
      const transaction = this.batchTransaction({session: session!}, options);
617 +
      this._releaseOnEnd(session!, transaction);
564 618
      transaction.begin((err, resp) => {
565 619
        if (err) {
566 620
          callback!(err, null, resp!);
@@ -576,6 +630,20 @@
Loading
576 630
    options: CreateSessionOptions,
577 631
    callback: CreateSessionCallback
578 632
  ): void;
633 +
  /**
634 +
   * Create a new session.
635 +
   *
636 +
   * @typedef {object} CreateSessionOptions
637 +
   * @property {Object.<string, string>} [labels] The labels for the session.
638 +
   *
639 +
   *   * Label keys must be between 1 and 63 characters long and must conform to
640 +
   *     the following regular expression: `[a-z]([-a-z0-9]*[a-z0-9])?`.
641 +
   *   * Label values must be between 0 and 63 characters long and must conform
642 +
   *     to the regular expression `([a-z]([-a-z0-9]*[a-z0-9])?)?`.
643 +
   *   * No more than 64 labels can be associated with a given session.
644 +
   * @property {object} [gaxOptions] Request configuration options, outlined
645 +
   *     here: https://googleapis.github.io/gax-nodejs/global.html#CallOptions.
646 +
   */
579 647
  /**
580 648
   * @typedef {array} CreateSessionResponse
581 649
   * @property {Session} 0 The newly created session.
@@ -637,10 +705,8 @@
Loading
637 705
    cb?: CreateSessionCallback
638 706
  ): void | Promise<CreateSessionResponse> {
639 707
    const callback =
640 -
      typeof optionsOrCallback === 'function'
641 -
        ? (optionsOrCallback as CreateSessionCallback)
642 -
        : cb!;
643 -
    const gaxOpts =
708 +
      typeof optionsOrCallback === 'function' ? optionsOrCallback : cb!;
709 +
    const options =
644 710
      typeof optionsOrCallback === 'object' && optionsOrCallback
645 711
        ? extend({}, optionsOrCallback)
646 712
        : ({} as CreateSessionOptions);
@@ -649,17 +715,17 @@
Loading
649 715
      database: this.formattedName_,
650 716
    };
651 717
652 -
    if (gaxOpts.labels) {
653 -
      reqOpts.session = {labels: gaxOpts.labels};
654 -
      delete gaxOpts.labels;
718 +
    if (options.labels) {
719 +
      reqOpts.session = {labels: options.labels};
655 720
    }
656 721
657 722
    this.request<google.spanner.v1.ISession>(
658 723
      {
659 724
        client: 'SpannerClient',
660 725
        method: 'createSession',
661 726
        reqOpts,
662 -
        gaxOpts,
727 +
        gaxOpts: options.gaxOptions,
728 +
        headers: this.resourceHeader_,
663 729
      },
664 730
      (err, resp) => {
665 731
        if (err) {
@@ -672,8 +738,16 @@
Loading
672 738
      }
673 739
    );
674 740
  }
675 -
  createTable(schema: Schema): Promise<CreateTableResponse>;
676 -
  createTable(schema: Schema, callback?: CreateTableCallback): void;
741 +
  createTable(
742 +
    schema: Schema,
743 +
    gaxOptions?: CallOptions
744 +
  ): Promise<CreateTableResponse>;
745 +
  createTable(schema: Schema, callback: CreateTableCallback): void;
746 +
  createTable(
747 +
    schema: Schema,
748 +
    gaxOptions: CallOptions,
749 +
    callback: CreateTableCallback
750 +
  ): void;
677 751
  /**
678 752
   * @typedef {array} CreateTableResponse
679 753
   * @property {Table} 0 The new {@link Table}.
@@ -697,6 +771,8 @@
Loading
697 771
   * @see {@link Database#updateSchema}
698 772
   *
699 773
   * @param {string} schema A DDL CREATE statement describing the table.
774 +
   * @param {object} [gaxOptions] Request configuration options, outlined here:
775 +
   *     https://googleapis.github.io/gax-nodejs/classes/CallSettings.html.
700 776
   * @param {CreateTableCallback} [callback] Callback function.
701 777
   * @returns {Promise<CreateTableResponse>}
702 778
   *
@@ -743,9 +819,15 @@
Loading
743 819
   */
744 820
  createTable(
745 821
    schema: Schema,
746 -
    callback?: CreateTableCallback
822 +
    gaxOptionsOrCallback?: CallOptions | CreateTableCallback,
823 +
    cb?: CreateTableCallback
747 824
  ): void | Promise<CreateTableResponse> {
748 -
    this.updateSchema(schema, (err, operation, resp) => {
825 +
    const gaxOptions =
826 +
      typeof gaxOptionsOrCallback === 'object' ? gaxOptionsOrCallback : {};
827 +
    const callback =
828 +
      typeof gaxOptionsOrCallback === 'function' ? gaxOptionsOrCallback : cb!;
829 +
830 +
    this.updateSchema(schema, gaxOptions, (err, operation, resp) => {
749 831
      if (err) {
750 832
        callback!(err, null, null, resp!);
751 833
        return;
@@ -776,17 +858,21 @@
Loading
776 858
      }
777 859
    });
778 860
  }
779 -
  delete(): Promise<[r.Response]>;
861 +
  delete(gaxOptions?: CallOptions): Promise<DatabaseDeleteResponse>;
780 862
  delete(callback: DatabaseDeleteCallback): void;
863 +
  delete(gaxOptions: CallOptions, callback: DatabaseDeleteCallback): void;
781 864
  /**
782 865
   * Delete the database.
783 866
   *
784 867
   * Wrapper around {@link v1.DatabaseAdminClient#dropDatabase}.
785 868
   *
786 869
   * @see {@link v1.DatabaseAdminClient#dropDatabase}
787 870
   * @see [DropDatabase API Documentation](https://cloud.google.com/spanner/docs/reference/rpc/google.spanner.admin.database.v1#google.spanner.admin.database.v1.DatabaseAdmin.DropDatabase)
788 -
   * @param {BasicCallback} [callback] Callback function.
789 -
   * @returns {Promise<BasicResponse>}
871 +
   *
872 +
   * @param {object} [gaxOptions] Request configuration options, outlined here:
873 +
   *     https://googleapis.github.io/gax-nodejs/classes/CallSettings.html.
874 +
   * @param {DatabaseDeleteCallback} [callback] Callback function.
875 +
   * @returns {Promise<DatabaseDeleteResponse>}
790 876
   *
791 877
   * @example
792 878
   * const {Spanner} = require('@google-cloud/spanner');
@@ -810,7 +896,15 @@
Loading
810 896
   *   const apiResponse = data[0];
811 897
   * });
812 898
   */
813 -
  delete(callback?: DatabaseDeleteCallback): void | Promise<[r.Response]> {
899 +
  delete(
900 +
    optionsOrCallback?: CallOptions | DatabaseDeleteCallback,
901 +
    cb?: DatabaseDeleteCallback
902 +
  ): void | Promise<DatabaseDeleteResponse> {
903 +
    const gaxOpts =
904 +
      typeof optionsOrCallback === 'object' ? optionsOrCallback : {};
905 +
    const callback =
906 +
      typeof optionsOrCallback === 'function' ? optionsOrCallback : cb!;
907 +
814 908
    const reqOpts: databaseAdmin.spanner.admin.database.v1.IDropDatabaseRequest = {
815 909
      database: this.formattedName_,
816 910
    };
@@ -820,13 +914,16 @@
Loading
820 914
          client: 'DatabaseAdminClient',
821 915
          method: 'dropDatabase',
822 916
          reqOpts,
917 +
          gaxOpts,
918 +
          headers: this.resourceHeader_,
823 919
        },
824 920
        callback!
825 921
      );
826 922
    });
827 923
  }
828 -
  exists(): Promise<[boolean]>;
924 +
  exists(gaxOptions?: CallOptions): Promise<[boolean]>;
829 925
  exists(callback: ExistsCallback): void;
926 +
  exists(gaxOptions: CallOptions, callback: ExistsCallback): void;
830 927
  /**
831 928
   * @typedef {array} DatabaseExistsResponse
832 929
   * @property {boolean} 0 Whether the {@link Database} exists.
@@ -840,6 +937,8 @@
Loading
840 937
   * Check if a database exists.
841 938
   *
842 939
   * @method Database#exists
940 +
   * @param {object} [gaxOptions] Request configuration options, outlined here:
941 +
   *     https://googleapis.github.io/gax-nodejs/classes/CallSettings.html.
843 942
   * @param {DatabaseExistsCallback} [callback] Callback function.
844 943
   * @returns {Promise<DatabaseExistsResponse>}
845 944
   *
@@ -859,10 +958,18 @@
Loading
859 958
   *   const exists = data[0];
860 959
   * });
861 960
   */
862 -
  exists(callback?: ExistsCallback): void | Promise<[boolean]> {
961 +
  exists(
962 +
    gaxOptionsOrCallback?: CallOptions | ExistsCallback,
963 +
    cb?: ExistsCallback
964 +
  ): void | Promise<[boolean]> {
965 +
    const gaxOptions =
966 +
      typeof gaxOptionsOrCallback === 'object' ? gaxOptionsOrCallback : {};
967 +
    const callback =
968 +
      typeof gaxOptionsOrCallback === 'function' ? gaxOptionsOrCallback : cb!;
969 +
863 970
    const NOT_FOUND = 5;
864 971
865 -
    this.getMetadata(err => {
972 +
    this.getMetadata(gaxOptions, err => {
866 973
      if (err && (err as ApiError).code !== NOT_FOUND) {
867 974
        callback!(err);
868 975
        return;
@@ -928,14 +1035,14 @@
Loading
928 1035
        : ({} as GetDatabaseConfig);
929 1036
    const callback =
930 1037
      typeof optionsOrCallback === 'function' ? optionsOrCallback : cb;
931 -
    this.getMetadata((err, metadata) => {
1038 +
    this.getMetadata(options.gaxOptions!, (err, metadata) => {
932 1039
      if (err) {
933 1040
        if (options.autoCreate && (err as ApiError).code === 5) {
934 1041
          this.create(
935 1042
            options,
936 1043
            (err, database: Database, operation: GaxOperation) => {
937 1044
              if (err) {
938 -
                callback!(err);
1045 +
                callback!(err as grpc.ServiceError);
939 1046
                return;
940 1047
              }
941 1048
              operation
@@ -954,8 +1061,9 @@
Loading
954 1061
      callback!(null, this, metadata as r.Response);
955 1062
    });
956 1063
  }
957 -
  getMetadata(): Promise<GetMetadataResponse>;
1064 +
  getMetadata(gaxOptions?: CallOptions): Promise<GetMetadataResponse>;
958 1065
  getMetadata(callback: GetMetadataCallback): void;
1066 +
  getMetadata(gaxOptions: CallOptions, callback: GetMetadataCallback): void;
959 1067
  /**
960 1068
   * @typedef {array} GetDatabaseMetadataResponse
961 1069
   * @property {object} 0 The {@link Database} metadata.
@@ -974,7 +1082,8 @@
Loading
974 1082
   *
975 1083
   * @see {@link v1.DatabaseAdminClient#getDatabase}
976 1084
   * @see [GetDatabase API Documentation](https://cloud.google.com/spanner/docs/reference/rpc/google.spanner.admin.database.v1#google.spanner.admin.database.v1.DatabaseAdmin.GetDatabase)
977 -
   *
1085 +
   * @param {object} [gaxOptions] Request configuration options, outlined here:
1086 +
   *     https://googleapis.github.io/gax-nodejs/classes/CallSettings.html.
978 1087
   * @param {GetMetadataCallback} [callback] Callback function.
979 1088
   * @returns {Promise<GetMetadataResponse>}
980 1089
   *
@@ -1002,8 +1111,18 @@
Loading
1002 1111
   * });
1003 1112
   */
1004 1113
  getMetadata(
1005 -
    callback?: GetMetadataCallback
1114 +
    gaxOptionsOrCallback?: CallOptions | GetMetadataCallback,
1115 +
    cb?: GetMetadataCallback
1006 1116
  ): void | Promise<GetMetadataResponse> {
1117 +
    const callback =
1118 +
      typeof gaxOptionsOrCallback === 'function'
1119 +
        ? (gaxOptionsOrCallback as GetMetadataCallback)
1120 +
        : cb;
1121 +
    const gaxOpts =
1122 +
      typeof gaxOptionsOrCallback === 'object'
1123 +
        ? (gaxOptionsOrCallback as CallOptions)
1124 +
        : {};
1125 +
1007 1126
    const reqOpts: databaseAdmin.spanner.admin.database.v1.IGetDatabaseRequest = {
1008 1127
      name: this.formattedName_,
1009 1128
    };
@@ -1012,11 +1131,23 @@
Loading
1012 1131
        client: 'DatabaseAdminClient',
1013 1132
        method: 'getDatabase',
1014 1133
        reqOpts,
1134 +
        gaxOpts,
1135 +
        headers: this.resourceHeader_,
1015 1136
      },
1016 -
      callback!
1137 +
      (err, resp) => {
1138 +
        if (resp) {
1139 +
          this.metadata = resp;
1140 +
        }
1141 +
        callback!(err, resp);
1142 +
      }
1017 1143
    );
1018 1144
  }
1019 1145
1146 +
  getRestoreInfo(
1147 +
    options?: CallOptions
1148 +
  ): Promise<IRestoreInfoTranslatedEnum | undefined>;
1149 +
  getRestoreInfo(callback: GetRestoreInfoCallback): void;
1150 +
  getRestoreInfo(options: CallOptions, callback: GetRestoreInfoCallback): void;
1020 1151
  /**
1021 1152
   * {@link google.spanner.admin.database.v1#RestoreInfo} structure with restore
1022 1153
   * source type enum translated to string form.
@@ -1029,6 +1160,9 @@
Loading
1029 1160
   * @see {@link #getMetadata}
1030 1161
   *
1031 1162
   * @method Database#getRestoreInfo
1163 +
   * @param {object} [gaxOptions] Request configuration options, outlined here:
1164 +
   *     https://googleapis.github.io/gax-nodejs/classes/CallSettings.html.
1165 +
   * @param {GetRestoreInfoCallback} [callback] Callback function.
1032 1166
   * @returns {Promise<IRestoreInfoTranslatedEnum | undefined>} When resolved,
1033 1167
   *     contains the restore information for the database if it was restored
1034 1168
   *     from a backup.
@@ -1041,11 +1175,24 @@
Loading
1041 1175
   * const restoreInfo = await database.getRestoreInfo();
1042 1176
   * console.log(`Database restored from ${restoreInfo.backupInfo.backup}`);
1043 1177
   */
1044 -
  async getRestoreInfo(): Promise<IRestoreInfoTranslatedEnum | undefined> {
1045 -
    const [metadata] = await this.getMetadata();
1178 +
  async getRestoreInfo(
1179 +
    optionsOrCallback?: CallOptions | GetRestoreInfoCallback
1180 +
  ): Promise<IRestoreInfoTranslatedEnum | undefined> {
1181 +
    const gaxOptions =
1182 +
      typeof optionsOrCallback === 'object' ? optionsOrCallback : {};
1183 +
1184 +
    const [metadata] = await this.getMetadata(gaxOptions);
1046 1185
    return metadata.restoreInfo ? metadata.restoreInfo : undefined;
1047 1186
  }
1048 1187
1188 +
  getState(
1189 +
    options?: CallOptions
1190 +
  ): Promise<
1191 +
    | EnumKey<typeof databaseAdmin.spanner.admin.database.v1.Database.State>
1192 +
    | undefined
1193 +
  >;
1194 +
  getState(callback: GetStateCallback): void;
1195 +
  getState(options: CallOptions, callback: GetStateCallback): void;
1049 1196
  /**
1050 1197
   * Retrieves the state of the database.
1051 1198
   *
@@ -1055,6 +1202,9 @@
Loading
1055 1202
   * @see {@link #getMetadata}
1056 1203
   *
1057 1204
   * @method Database#getState
1205 +
   * @param {object} [gaxOptions] Request configuration options, outlined here:
1206 +
   *     https://googleapis.github.io/gax-nodejs/classes/CallSettings.html.
1207 +
   * @param {GetStateCallback} [callback] Callback function.
1058 1208
   * @returns {Promise<EnumKey<typeof, databaseAdmin.spanner.admin.database.v1.Database.State> | undefined>}
1059 1209
   *     When resolved, contains the current state of the database if the state
1060 1210
   *     is defined.
@@ -1067,16 +1217,22 @@
Loading
1067 1217
   * const state = await database.getState();
1068 1218
   * const isReady = (state === 'READY');
1069 1219
   */
1070 -
  async getState(): Promise<
1220 +
  async getState(
1221 +
    optionsOrCallback?: CallOptions | GetStateCallback
1222 +
  ): Promise<
1071 1223
    | EnumKey<typeof databaseAdmin.spanner.admin.database.v1.Database.State>
1072 1224
    | undefined
1073 1225
  > {
1074 -
    const [metadata] = await this.getMetadata();
1226 +
    const gaxOptions =
1227 +
      typeof optionsOrCallback === 'object' ? optionsOrCallback : {};
1228 +
1229 +
    const [metadata] = await this.getMetadata(gaxOptions);
1075 1230
    return metadata.state || undefined;
1076 1231
  }
1077 1232
1078 -
  getSchema(): Promise<GetSchemaResponse>;
1233 +
  getSchema(options?: CallOptions): Promise<GetSchemaResponse>;
1079 1234
  getSchema(callback: GetSchemaCallback): void;
1235 +
  getSchema(options: CallOptions, callback: GetSchemaCallback): void;
1080 1236
  /**
1081 1237
   * @typedef {array} GetSchemaResponse
1082 1238
   * @property {string[]} 0 An array of database DDL statements.
@@ -1097,6 +1253,8 @@
Loading
1097 1253
   * @see [Data Definition Language (DDL)](https://cloud.google.com/spanner/docs/data-definition-language)
1098 1254
   * @see [GetDatabaseDdl API Documentation](https://cloud.google.com/spanner/docs/reference/rpc/google.spanner.admin.database.v1#google.spanner.admin.database.v1.DatabaseAdmin.GetDatabaseDdl)
1099 1255
   *
1256 +
   * @param {object} [gaxOptions] Request configuration options, outlined here:
1257 +
   *     https://googleapis.github.io/gax-nodejs/classes/CallSettings.html.
1100 1258
   * @param {GetSchemaCallback} [callback] Callback function.
1101 1259
   * @returns {Promise<GetSchemaResponse>}
1102 1260
   *
@@ -1117,7 +1275,15 @@
Loading
1117 1275
   *   const apiResponse = data[1];
1118 1276
   * });
1119 1277
   */
1120 -
  getSchema(callback?: GetSchemaCallback): void | Promise<GetSchemaResponse> {
1278 +
  getSchema(
1279 +
    optionsOrCallback?: CallOptions | GetSchemaCallback,
1280 +
    cb?: GetSchemaCallback
1281 +
  ): void | Promise<GetSchemaResponse> {
1282 +
    const gaxOpts =
1283 +
      typeof optionsOrCallback === 'object' ? optionsOrCallback : {};
1284 +
    const callback =
1285 +
      typeof optionsOrCallback === 'function' ? optionsOrCallback : cb!;
1286 +
1121 1287
    const reqOpts: databaseAdmin.spanner.admin.database.v1.IGetDatabaseDdlRequest = {
1122 1288
      database: this.formattedName_,
1123 1289
    };
@@ -1128,6 +1294,8 @@
Loading
1128 1294
        client: 'DatabaseAdminClient',
1129 1295
        method: 'getDatabaseDdl',
1130 1296
        reqOpts,
1297 +
        gaxOpts,
1298 +
        headers: this.resourceHeader_,
1131 1299
      },
1132 1300
      // eslint-disable-next-line @typescript-eslint/no-explicit-any
1133 1301
      (err, statements, ...args: any[]) => {
@@ -1141,9 +1309,7 @@
Loading
1141 1309
  /**
1142 1310
   * Options object for listing sessions.
1143 1311
   *
1144 -
   * @typedef {object} GetSessionsRequest
1145 -
   * @property {boolean} [autoPaginate=true] Have pagination handled
1146 -
   *     automatically.
1312 +
   * @typedef {object} GetSessionsOptions
1147 1313
   * @property {string} [filter] An expression for filtering the results of the
1148 1314
   *     request. Filter rules are case insensitive. The fields eligible for
1149 1315
   *     filtering are:
@@ -1158,21 +1324,23 @@
Loading
1158 1324
   *     - **`labels.env:dev`** The instance's label env has the value dev.
1159 1325
   *     - **`name:howl labels.env:dev`** The instance's name is howl and it has
1160 1326
   *       the label env with value dev.
1161 -
   * @property {number} [maxApiCalls] Maximum number of API calls to make.
1162 -
   * @property {number} [maxResults] Maximum number of items to return.
1163 1327
   * @property {number} [pageSize] Maximum number of results per page.
1164 1328
   * @property {string} [pageToken] A previously-returned page token
1165 1329
   *     representing part of the larger set of results to view.
1330 +
   * @property {object} [gaxOptions] Request configuration options, outlined
1331 +
   *     here: https://googleapis.github.io/gax-nodejs/global.html#CallOptions.
1166 1332
   */
1167 1333
  /**
1168 1334
   * @typedef {array} GetSessionsResponse
1169 1335
   * @property {Session[]} 0 Array of {@link Session} instances.
1170 -
   * @property {object} 1 The full API response.
1336 +
   * @property {object} 1 A query object to receive more results.
1337 +
   * @property {object} 2 The full API response.
1171 1338
   */
1172 1339
  /**
1173 1340
   * @callback GetSessionsCallback
1174 1341
   * @param {?Error} err Request error, if any.
1175 1342
   * @param {Session[]} instances Array of {@link Session} instances.
1343 +
   * @param {object} nextQuery A query object to receive more results.
1176 1344
   * @param {object} apiResponse The full API response.
1177 1345
   */
1178 1346
  /**
@@ -1210,7 +1378,7 @@
Loading
1210 1378
   * }
1211 1379
   *
1212 1380
   * database.getInstances({
1213 -
   *   autoPaginate: false
1381 +
   *   gaxOptions: {autoPaginate: false}
1214 1382
   * }, callback);
1215 1383
   *
1216 1384
   * //-
@@ -1227,19 +1395,32 @@
Loading
1227 1395
    // eslint-disable-next-line @typescript-eslint/no-this-alias
1228 1396
    const self = this;
1229 1397
    const callback =
1230 -
      typeof optionsOrCallback === 'function'
1231 -
        ? (optionsOrCallback as GetSessionsCallback)
1232 -
        : cb;
1398 +
      typeof optionsOrCallback === 'function' ? optionsOrCallback : cb;
1233 1399
    const options =
1234 1400
      typeof optionsOrCallback === 'object'
1235 -
        ? (optionsOrCallback as GetSessionsOptions)
1236 -
        : {gaxOptions: {}};
1237 -
    const gaxOpts: CallOptions = options.gaxOptions as CallOptions;
1238 -
    const reqOpts = extend({}, options, {
1401 +
        ? optionsOrCallback
1402 +
        : ({} as GetSessionsOptions);
1403 +
    const gaxOpts = extend(true, {}, options.gaxOptions);
1404 +
    let reqOpts = extend({}, options, {
1239 1405
      database: this.formattedName_,
1240 1406
    });
1241 -
1242 1407
    delete reqOpts.gaxOptions;
1408 +
1409 +
    // Copy over pageSize and pageToken values from gaxOptions.
1410 +
    // However values set on options take precedence.
1411 +
    if (gaxOpts) {
1412 +
      reqOpts = extend(
1413 +
        {},
1414 +
        {
1415 +
          pageSize: gaxOpts.pageSize,
1416 +
          pageToken: gaxOpts.pageToken,
1417 +
        },
1418 +
        reqOpts
1419 +
      );
1420 +
      delete gaxOpts.pageSize;
1421 +
      delete gaxOpts.pageToken;
1422 +
    }
1423 +
1243 1424
    this.request<
1244 1425
      google.spanner.v1.ISession,
1245 1426
      google.spanner.v1.IListSessionsResponse
@@ -1249,8 +1430,9 @@
Loading
1249 1430
        method: 'listSessions',
1250 1431
        reqOpts,
1251 1432
        gaxOpts,
1433 +
        headers: this.resourceHeader_,
1252 1434
      },
1253 -
      (err, sessions, ...args) => {
1435 +
      (err, sessions, nextPageRequest, ...args) => {
1254 1436
        let sessionInstances: Session[] | null = null;
1255 1437
        if (sessions) {
1256 1438
          sessionInstances = sessions.map(metadata => {
@@ -1259,10 +1441,98 @@
Loading
1259 1441
            return session;
1260 1442
          });
1261 1443
        }
1262 -
        callback!(err, sessionInstances!, ...args);
1444 +
        const nextQuery = nextPageRequest!
1445 +
          ? extend({}, options, nextPageRequest!)
1446 +
          : null;
1447 +
        callback!(err, sessionInstances!, nextQuery, ...args);
1263 1448
      }
1264 1449
    );
1265 1450
  }
1451 +
1452 +
  /**
1453 +
   * Get a list of sessions as a readable object stream.
1454 +
   *
1455 +
   * Wrapper around {@link v1.SpannerClient#listSessions}
1456 +
   *
1457 +
   * @see {@link v1.SpannerClient#listSessions}
1458 +
   * @see [ListSessions API Documentation](https://cloud.google.com/spanner/docs/reference/rpc/google.spanner.v1#google.spanner.v1.Spanner.ListSessions)
1459 +
   *
1460 +
   * @method Spanner#getSessionsStream
1461 +
   * @param {GetSessionsOptions} [options] Options object for listing sessions.
1462 +
   * @returns {ReadableStream} A readable stream that emits {@link Session}
1463 +
   *     instances.
1464 +
   *
1465 +
   * @example
1466 +
   * const {Spanner} = require('@google-cloud/spanner');
1467 +
   * const spanner = new Spanner();
1468 +
   *
1469 +
   * const instance = spanner.instance('my-instance');
1470 +
   * const database = instance.database('my-database');
1471 +
   *
1472 +
   * database.getSessionsStream()
1473 +
   *   .on('error', console.error)
1474 +
   *   .on('data', function(database) {
1475 +
   *     // `sessions` is a `Session` object.
1476 +
   *   })
1477 +
   *   .on('end', function() {
1478 +
   *     // All sessions retrieved.
1479 +
   *   });
1480 +
   *
1481 +
   * //-
1482 +
   * // If you anticipate many results, you can end a stream early to prevent
1483 +
   * // unnecessary processing and API requests.
1484 +
   * //-
1485 +
   * database.getSessionsStream()
1486 +
   *   .on('data', function(session) {
1487 +
   *     this.end();
1488 +
   *   });
1489 +
   */
1490 +
  getSessionsStream(options: GetSessionsOptions = {}): NodeJS.ReadableStream {
1491 +
    const gaxOpts = extend(true, {}, options.gaxOptions);
1492 +
1493 +
    let reqOpts = extend({}, options, {
1494 +
      database: this.formattedName_,
1495 +
    });
1496 +
    delete reqOpts.gaxOptions;
1497 +
1498 +
    // Copy over pageSize and pageToken values from gaxOptions.
1499 +
    // However values set on options take precedence.
1500 +
    if (gaxOpts) {
1501 +
      reqOpts = extend(
1502 +
        {},
1503 +
        {
1504 +
          pageSize: gaxOpts.pageSize,
1505 +
          pageToken: gaxOpts.pageToken,
1506 +
        },
1507 +
        reqOpts
1508 +
      );
1509 +
      delete gaxOpts.pageSize;
1510 +
      delete gaxOpts.pageToken;
1511 +
    }
1512 +
1513 +
    return new pumpify.obj([
1514 +
      this.requestStream({
1515 +
        client: 'SpannerClient',
1516 +
        method: 'listSessionsStream',
1517 +
        reqOpts,
1518 +
        gaxOpts,
1519 +
        headers: this.resourceHeader_,
1520 +
      }),
1521 +
      new Transform({
1522 +
        objectMode: true,
1523 +
        transform: (
1524 +
          chunk: databaseAdmin.spanner.v1.ISession,
1525 +
          enc: string,
1526 +
          cb: Function
1527 +
        ) => {
1528 +
          const session = this.session(chunk.name!);
1529 +
          session.metadata = chunk;
1530 +
          cb(null, session);
1531 +
        },
1532 +
      }),
1533 +
    ]);
1534 +
  }
1535 +
1266 1536
  getSnapshot(options?: TimestampBounds): Promise<[Snapshot]>;
1267 1537
  getSnapshot(callback: GetSnapshotCallback): void;
1268 1538
  getSnapshot(options: TimestampBounds, callback: GetSnapshotCallback): void;
@@ -1284,6 +1554,12 @@
Loading
1284 1554
   * called to release the underlying {@link Session}. **Failure to do could
1285 1555
   * result in a Session leak.**
1286 1556
   *
1557 +
   * **NOTE:** Since the returned {@link Snapshot} transaction is not a
1558 +
   * single-use transaction, it is invalid to set the `minReadTimestamp` and
1559 +
   * `maxStaleness` parameters in {@link TimestampBounds} as those parameters
1560 +
   * can only be set for single-use transactions.
1561 +
   * https://cloud.google.com/spanner/docs/reference/rest/v1/TransactionOptions#bounded-staleness
1562 +
   *
1287 1563
   * @see {@link v1.SpannerClient#beginTransaction}
1288 1564
   *
1289 1565
   * @param {TimestampBounds} [options] Timestamp bounds.
@@ -1404,10 +1680,18 @@
Loading
1404 1680
      if (!err) {
1405 1681
        this._releaseOnEnd(session!, transaction!);
1406 1682
      }
1407 -
      callback!(err, transaction);
1683 +
      callback!(err as grpc.ServiceError | null, transaction);
1408 1684
    });
1409 1685
  }
1410 1686
1687 +
  getOperations(
1688 +
    options?: GetDatabaseOperationsOptions
1689 +
  ): Promise<GetDatabaseOperationsResponse>;
1690 +
  getOperations(callback: GetDatabaseOperationsCallback): void;
1691 +
  getOperations(
1692 +
    options: GetDatabaseOperationsOptions,
1693 +
    callback: GetDatabaseOperationsCallback
1694 +
  ): void;
1411 1695
  /**
1412 1696
   * Query object for listing database operations.
1413 1697
   *
@@ -1418,6 +1702,9 @@
Loading
1418 1702
   * @property {number} [pageSize] Maximum number of results per page.
1419 1703
   * @property {string} [pageToken] A previously-returned page token
1420 1704
   *     representing part of the larger set of results to view.
1705 +
   * @property {object} [gaxOptions] Request configuration options, outlined
1706 +
   *     here: https://googleapis.github.io/gax-nodejs/global.html#CallOptions.
1707 +
   * @param {GetDatabaseOperationsCallback} [callback] Callback function.
1421 1708
   */
1422 1709
  /**
1423 1710
   * @typedef {array} GetDatabaseOperationsResponse
@@ -1459,8 +1746,12 @@
Loading
1459 1746
   * } while (pageToken);
1460 1747
   */
1461 1748
  async getOperations(
1462 -
    options?: GetDatabaseOperationsOptions
1749 +
    optionsOrCallback?:
1750 +
      | GetDatabaseOperationsOptions
1751 +
      | GetDatabaseOperationsCallback
1463 1752
  ): Promise<GetDatabaseOperationsResponse> {
1753 +
    const options =
1754 +
      typeof optionsOrCallback === 'object' ? optionsOrCallback : {};
1464 1755
    // Create a query that lists database operations only on this database from
1465 1756
    // the instance. Operation name will be prefixed with the database path for
1466 1757
    // all operations on this database
@@ -1529,7 +1820,7 @@
Loading
1529 1820
        requestStream.cancel();
1530 1821
      }
1531 1822
    };
1532 -
    function destroyStream(err: ServiceError) {
1823 +
    function destroyStream(err: grpc.ServiceError) {
1533 1824
      waitForSessionStream.destroy(err);
1534 1825
    }
1535 1826
    function releaseSession() {
@@ -1628,6 +1919,7 @@
Loading
1628 1919
        method: 'restoreDatabase',
1629 1920
        reqOpts,
1630 1921
        gaxOpts,
1922 +
        headers: this.resourceHeader_,
1631 1923
      },
1632 1924
      (err, operation, resp) => {
1633 1925
        if (err) {
@@ -1859,20 +2151,41 @@
Loading
1859 2151
        return;
1860 2152
      }
1861 2153
1862 -
      const transaction = session!.partitionedDml();
2154 +
      this._runPartitionedUpdate(session!, query, callback);
2155 +
    });
2156 +
  }
2157 +
2158 +
  _runPartitionedUpdate(
2159 +
    session: Session,
2160 +
    query: string | ExecuteSqlRequest,
2161 +
    callback?: RunUpdateCallback
2162 +
  ): void | Promise<number> {
2163 +
    const transaction = session.partitionedDml();
1863 2164
1864 -
      transaction.begin(err => {
2165 +
    transaction.begin(err => {
2166 +
      if (err) {
2167 +
        this.pool_.release(session!);
2168 +
        callback!(err, 0);
2169 +
        return;
2170 +
      }
2171 +
2172 +
      transaction.runUpdate(query, (err, updateCount) => {
1865 2173
        if (err) {
2174 +
          if (err.code !== grpc.status.ABORTED) {
2175 +
            this.pool_.release(session!);
2176 +
            callback!(err, 0);
2177 +
            return;
2178 +
          }
2179 +
          this._runPartitionedUpdate(session, query, callback);
2180 +
        } else {
1866 2181
          this.pool_.release(session!);
1867 -
          callback!(err, 0);
2182 +
          callback!(null, updateCount);
1868 2183
          return;
1869 2184
        }
1870 -
1871 -
        this._releaseOnEnd(session!, transaction);
1872 -
        transaction.runUpdate(query, callback!);
1873 2185
      });
1874 2186
    });
1875 2187
  }
2188 +
1876 2189
  /**
1877 2190
   * Create a readable object stream to receive resulting rows from a SQL
1878 2191
   * statement.
@@ -2018,12 +2331,15 @@
Loading
2018 2331
      dataStream
2019 2332
        .once('data', () => (dataReceived = true))
2020 2333
        .once('error', err => {
2021 -
          if (!dataReceived && isSessionNotFoundError(err)) {
2334 +
          if (
2335 +
            !dataReceived &&
2336 +
            isSessionNotFoundError(err as grpc.ServiceError)
2337 +
          ) {
2022 2338
            // If it is a 'Session not found' error and we have not yet received
2023 2339
            // any data, we can safely retry the query on a new session.
2024 2340
            // Register the error on the session so the pool can discard it.
2025 2341
            if (session) {
2026 -
              session.lastError = err;
2342 +
              session.lastError = err as grpc.ServiceError;
2027 2343
            }
2028 2344
            // Remove the current data stream from the end user stream.
2029 2345
            dataStream.unpipe(proxyStream);
@@ -2141,12 +2457,12 @@
Loading
2141 2457
        : {};
2142 2458
2143 2459
    this.pool_.getWriteSession((err, session?, transaction?) => {
2144 -
      if (err && isSessionNotFoundError(err)) {
2460 +
      if (err && isSessionNotFoundError(err as grpc.ServiceError)) {
2145 2461
        this.runTransaction(options, runFn!);
2146 2462
        return;
2147 2463
      }
2148 2464
      if (err) {
2149 -
        runFn!(err);
2465 +
        runFn!(err as grpc.ServiceError);
2150 2466
        return;
2151 2467
      }
2152 2468
@@ -2307,8 +2623,16 @@
Loading
2307 2623
    }
2308 2624
    return new Table(this, name);
2309 2625
  }
2310 -
  updateSchema(statements: Schema): Promise<UpdateSchemaResponse>;
2626 +
  updateSchema(
2627 +
    statements: Schema,
2628 +
    gaxOptions?: CallOptions
2629 +
  ): Promise<UpdateSchemaResponse>;
2311 2630
  updateSchema(statements: Schema, callback: UpdateSchemaCallback): void;
2631 +
  updateSchema(
2632 +
    statements: Schema,
2633 +
    gaxOptions: CallOptions,
2634 +
    callback: UpdateSchemaCallback
2635 +
  ): void;
2312 2636
  /**
2313 2637
   * Update the schema of the database by creating/altering/dropping tables,
2314 2638
   * columns, indexes, etc.
@@ -2327,6 +2651,8 @@
Loading
2327 2651
   * @param {string|string[]|object} statements An array of database DDL
2328 2652
   *     statements, or an
2329 2653
   *     [`UpdateDatabaseDdlRequest` object](https://cloud.google.com/spanner/docs/reference/rpc/google.spanner.admin.database.v1#google.spanner.admin.database.v1.UpdateDatabaseDdlRequest).
2654 +
   * @param {object} [gaxOptions] Request configuration options, outlined here:
2655 +
   *     https://googleapis.github.io/gax-nodejs/classes/CallSettings.html.
2330 2656
   * @param {LongRunningOperationCallback} [callback] Callback function.
2331 2657
   * @returns {Promise<LongRunningOperationResponse>}
2332 2658
   *
@@ -2384,8 +2710,14 @@
Loading
2384 2710
   */
2385 2711
  updateSchema(
2386 2712
    statements: Schema,
2387 -
    callback?: UpdateSchemaCallback
2713 +
    optionsOrCallback?: CallOptions | UpdateSchemaCallback,
2714 +
    cb?: UpdateSchemaCallback
2388 2715
  ): Promise<UpdateSchemaResponse> | void {
2716 +
    const gaxOpts =
2717 +
      typeof optionsOrCallback === 'object' ? optionsOrCallback : {};
2718 +
    const callback =
2719 +
      typeof optionsOrCallback === 'function' ? optionsOrCallback : cb!;
2720 +
2389 2721
    if (typeof statements === 'string' || Array.isArray(statements)) {
2390 2722
      statements = {
2391 2723
        statements: arrify(statements) as string[],
@@ -2402,6 +2734,8 @@
Loading
2402 2734
        client: 'DatabaseAdminClient',
2403 2735
        method: 'updateDatabaseDdl',
2404 2736
        reqOpts,
2737 +
        gaxOpts,
2738 +
        headers: this.resourceHeader_,
2405 2739
      },
2406 2740
      callback!
2407 2741
    );
@@ -2439,17 +2773,49 @@
Loading
2439 2773
promisifyAll(Database, {
2440 2774
  exclude: [
2441 2775
    'batchTransaction',
2442 -
    'getMetadata',
2443 2776
    'getRestoreInfo',
2444 2777
    'getState',
2445 2778
    'getOperations',
2446 2779
    'runTransaction',
2780 +
    'runTransactionAsync',
2447 2781
    'table',
2448 -
    'updateSchema',
2449 2782
    'session',
2450 2783
  ],
2451 2784
});
2452 2785
2786 +
/*! Developer Documentation
2787 +
 *
2788 +
 * All async methods (except for streams) will return a Promise in the event
2789 +
 * that a callback is omitted.
2790 +
 */
2791 +
callbackifyAll(Database, {
2792 +
  exclude: [
2793 +
    'create',
2794 +
    'batchCreateSessions',
2795 +
    'batchTransaction',
2796 +
    'close',
2797 +
    'createBatchTransaction',
2798 +
    'createSession',
2799 +
    'createTable',
2800 +
    'delete',
2801 +
    'exists',
2802 +
    'get',
2803 +
    'getMetadata',
2804 +
    'getSchema',
2805 +
    'getSessions',
2806 +
    'getSnapshot',
2807 +
    'getTransaction',
2808 +
    'restore',
2809 +
    'run',
2810 +
    'runPartitionedUpdate',
2811 +
    'runTransaction',
2812 +
    'runTransactionAsync',
2813 +
    'session',
2814 +
    'table',
2815 +
    'updateSchema',
2816 +
  ],
2817 +
});
2818 +
2453 2819
/**
2454 2820
 * Reference to the {@link Database} class.
2455 2821
 * @name module:@google-cloud/spanner.Database

@@ -13,18 +13,24 @@
Loading
13 13
 * limitations under the License.
14 14
 */
15 15
16 -
import {promisifyAll} from '@google-cloud/promisify';
16 +
import {promisifyAll, callbackifyAll} from '@google-cloud/promisify';
17 17
import {Instance} from './instance';
18 18
import {
19 19
  IOperation,
20 20
  LongRunningCallback,
21 21
  RequestCallback,
22 22
  ResourceCallback,
23 +
  NormalCallback,
24 +
  CLOUD_RESOURCE_HEADER,
23 25
} from './common';
24 26
import {EnumKey, Spanner, RequestConfig, TranslateEnumKeys} from '.';
25 -
import {Metadata, Operation as GaxOperation} from 'google-gax';
27 +
import {
28 +
  grpc,
29 +
  CallOptions,
30 +
  Metadata,
31 +
  Operation as GaxOperation,
32 +
} from 'google-gax';
26 33
import {DateStruct, PreciseDate} from '@google-cloud/precise-date';
27 -
import {CallOptions, status} from 'grpc';
28 34
import {google as databaseAdmin} from '../protos/protos';
29 35
import {common as p} from 'protobufjs';
30 36
@@ -64,7 +70,7 @@
Loading
64 70
  databaseAdmin.spanner.admin.database.v1.IBackup
65 71
>;
66 72
67 -
type DeleteCallback = RequestCallback<void>;
73 +
type DeleteCallback = RequestCallback<databaseAdmin.protobuf.IEmpty>;
68 74
69 75
interface BackupRequest {
70 76
  (
@@ -73,6 +79,11 @@
Loading
73 79
  ): void;
74 80
  <T>(config: RequestConfig, callback: RequestCallback<T>): void;
75 81
}
82 +
export type GetStateCallback = NormalCallback<
83 +
  EnumKey<typeof databaseAdmin.spanner.admin.database.v1.Backup.State>
84 +
>;
85 +
export type GetExpireTimeCallback = NormalCallback<PreciseDate>;
86 +
export type ExistsCallback = NormalCallback<boolean>;
76 87
/**
77 88
 * The {@link Backup} class represents a Cloud Spanner backup.
78 89
 *
@@ -90,12 +101,17 @@
Loading
90 101
  id: string;
91 102
  formattedName_: string;
92 103
  instanceFormattedName_: string;
104 +
  resourceHeader_: {[k: string]: string};
93 105
  request: BackupRequest;
106 +
  metadata?: databaseAdmin.spanner.admin.database.v1.IBackup;
94 107
  constructor(instance: Instance, name: string) {
95 108
    this.request = instance.request;
96 109
    this.instanceFormattedName_ = instance.formattedName_;
97 110
    this.formattedName_ = Backup.formatName_(instance.formattedName_, name);
98 111
    this.id = this.formattedName_.split('/').pop() || '';
112 +
    this.resourceHeader_ = {
113 +
      [CLOUD_RESOURCE_HEADER]: this.instanceFormattedName_,
114 +
    };
99 115
  }
100 116
101 117
  create(options: CreateBackupOptions): Promise<CreateBackupResponse>;
@@ -154,7 +170,7 @@
Loading
154 170
    options: CreateBackupOptions,
155 171
    callback?: CreateBackupCallback
156 172
  ): Promise<CreateBackupResponse> | void {
157 -
    const gaxOpts: CallOptions = options.gaxOptions as CallOptions;
173 +
    const gaxOpts = options.gaxOptions;
158 174
    const reqOpts: databaseAdmin.spanner.admin.database.v1.ICreateBackupRequest = {
159 175
      parent: this.instanceFormattedName_,
160 176
      backupId: this.id,
@@ -164,12 +180,13 @@
Loading
164 180
        name: this.formattedName_,
165 181
      },
166 182
    };
167 -
    return this.request(
183 +
    this.request(
168 184
      {
169 185
        client: 'DatabaseAdminClient',
170 186
        method: 'createBackup',
171 187
        reqOpts,
172 188
        gaxOpts,
189 +
        headers: this.resourceHeader_,
173 190
      },
174 191
      (err, operation, resp) => {
175 192
        if (err) {
@@ -181,7 +198,6 @@
Loading
181 198
    );
182 199
  }
183 200
184 -
  getMetadata(): Promise<GetMetadataResponse>;
185 201
  getMetadata(gaxOptions?: CallOptions): Promise<GetMetadataResponse>;
186 202
  getMetadata(callback: GetMetadataCallback): void;
187 203
  getMetadata(gaxOptions: CallOptions, callback: GetMetadataCallback): void;
@@ -231,19 +247,29 @@
Loading
231 247
    const reqOpts: databaseAdmin.spanner.admin.database.v1.IGetBackupRequest = {
232 248
      name: this.formattedName_,
233 249
    };
234 -
    return this.request<IBackupTranslatedEnum>(
250 +
    this.request<IBackupTranslatedEnum>(
235 251
      {
236 252
        client: 'DatabaseAdminClient',
237 253
        method: 'getBackup',
238 254
        reqOpts,
239 255
        gaxOpts,
256 +
        headers: this.resourceHeader_,
240 257
      },
241 258
      (err, response) => {
259 +
        if (response) {
260 +
          this.metadata = response;
261 +
        }
242 262
        callback!(err, response);
243 263
      }
244 264
    );
245 265
  }
246 266
267 +
  getState(): Promise<
268 +
    | EnumKey<typeof databaseAdmin.spanner.admin.database.v1.Backup.State>
269 +
    | undefined
270 +
    | null
271 +
  >;
272 +
  getState(callback: GetStateCallback): void;
247 273
  /**
248 274
   * Retrieves the state of the backup.
249 275
   *
@@ -252,6 +278,7 @@
Loading
252 278
   * @see {@link #getMetadata}
253 279
   *
254 280
   * @method Backup#getState
281 +
   * @param {GetStateCallback} [callback] Callback function.
255 282
   * @returns {Promise<EnumKey<typeof, databaseAdmin.spanner.admin.database.v1.Backup.State> | undefined>}
256 283
   *     When resolved, contains the current state of the backup if it exists.
257 284
   *
@@ -266,11 +293,14 @@
Loading
266 293
  async getState(): Promise<
267 294
    | EnumKey<typeof databaseAdmin.spanner.admin.database.v1.Backup.State>
268 295
    | undefined
296 +
    | null
269 297
  > {
270 298
    const [backupInfo] = await this.getMetadata();
271 -
    return backupInfo.state || undefined;
299 +
    return backupInfo.state;
272 300
  }
273 301
302 +
  getExpireTime(): Promise<PreciseDate | undefined>;
303 +
  getExpireTime(callback: GetExpireTimeCallback): void;
274 304
  /**
275 305
   * Retrieves the expiry time of the backup.
276 306
   *
@@ -294,6 +324,8 @@
Loading
294 324
    return new PreciseDate(backupInfo.expireTime as DateStruct);
295 325
  }
296 326
327 +
  exists(): Promise<boolean>;
328 +
  exists(callback: ExistsCallback): void;
297 329
  /**
298 330
   * Checks whether the backup exists.
299 331
   *
@@ -318,7 +350,7 @@
Loading
318 350
      // Found therefore it exists
319 351
      return true;
320 352
    } catch (err) {
321 -
      if (err.code === status.NOT_FOUND) {
353 +
      if (err.code === grpc.status.NOT_FOUND) {
322 354
        return false;
323 355
      }
324 356
      // Some other error occurred, rethrow
@@ -393,21 +425,21 @@
Loading
393 425
        paths: ['expire_time'],
394 426
      },
395 427
    };
396 -
    return this.request<databaseAdmin.spanner.admin.database.v1.IBackup>(
428 +
    this.request<databaseAdmin.spanner.admin.database.v1.IBackup>(
397 429
      {
398 430
        client: 'DatabaseAdminClient',
399 431
        method: 'updateBackup',
400 432
        reqOpts,
401 433
        gaxOpts,
434 +
        headers: this.resourceHeader_,
402 435
      },
403 436
      (err, response) => {
404 437
        callback!(err, response);
405 438
      }
406 439
    );
407 440
  }
408 441
409 -
  delete(): Promise<void>;
410 -
  delete(gaxOptions?: CallOptions): Promise<void>;
442 +
  delete(gaxOptions?: CallOptions): Promise<databaseAdmin.protobuf.IEmpty>;
411 443
  delete(callback: DeleteCallback): void;
412 444
  delete(gaxOptions: CallOptions, callback: DeleteCallback): void;
413 445
  /**
@@ -429,7 +461,7 @@
Loading
429 461
  delete(
430 462
    gaxOptionsOrCallback?: CallOptions | DeleteCallback,
431 463
    cb?: DeleteCallback
432 -
  ): void | Promise<void> {
464 +
  ): void | Promise<databaseAdmin.protobuf.IEmpty> {
433 465
    const callback =
434 466
      typeof gaxOptionsOrCallback === 'function'
435 467
        ? (gaxOptionsOrCallback as DeleteCallback)
@@ -441,12 +473,13 @@
Loading
441 473
    const reqOpts: databaseAdmin.spanner.admin.database.v1.IDeleteBackupRequest = {
442 474
      name: this.formattedName_,
443 475
    };
444 -
    return this.request<databaseAdmin.spanner.admin.database.v1.IBackup>(
476 +
    this.request<databaseAdmin.spanner.admin.database.v1.IBackup>(
445 477
      {
446 478
        client: 'DatabaseAdminClient',
447 479
        method: 'deleteBackup',
448 480
        reqOpts,
449 481
        gaxOpts,
482 +
        headers: this.resourceHeader_,
450 483
      },
451 484
      err => {
452 485
        callback!(err);
@@ -488,6 +521,15 @@
Loading
488 521
  exclude: ['getState', 'getExpireTime', 'exists'],
489 522
});
490 523
524 +
/*! Developer Documentation
525 +
 *
526 +
 * All async methods (except for streams) will return a Promise in the event
527 +
 * that a callback is omitted.
528 +
 */
529 +
callbackifyAll(Backup, {
530 +
  exclude: ['create', 'getMetadata', 'updateExpireTime', 'delete'],
531 +
});
532 +
491 533
/**
492 534
 * Reference to the {@link Backup} class.
493 535
 * @name module:@google-cloud/spanner.Backup

Click to load this diff.
Loading diff...

Click to load this diff.
Loading diff...

Click to load this diff.
Loading diff...

Click to load this diff.
Loading diff...

Click to load this diff.
Loading diff...

Click to load this diff.
Loading diff...

Click to load this diff.
Loading diff...

Click to load this diff.
Loading diff...

Click to load this diff.
Loading diff...

Click to load this diff.
Loading diff...

Click to load this diff.
Loading diff...

Click to load this diff.
Loading diff...

Click to load this diff.
Loading diff...

Click to load this diff.
Loading diff...

Click to load this diff.
Loading diff...

Learn more Showing 9 files with coverage changes found.

Changes in src/transaction-runner.ts
New
Loading file...
New file .prettierrc.js
New
Loading file...
New file .mocharc.js
New
Loading file...
Changes in src/v1/database_admin_client.ts
-1
+1
Loading file...
Changes in src/database.ts
-1
+1
Loading file...
Changes in src/v1/spanner_client.ts
-1
+1
Loading file...
Changes in src/v1/instance_admin_client.ts
-1
+1
Loading file...
Changes in src/backup.ts
-1
+1
Loading file...
Changes in src/common.ts
-21
+21
Loading file...

118 Commits

+51
+51
+183
+174
+6
+3
Hiding 2 contexual commits
+6
-6
-20 Files
-20143
-19755
-10
-378
Hiding 1 contexual commits
+20 Files
+20143
+19755
+10
+378
Hiding 1 contexual commits Hiding 2 contexual commits
-50
-50
Hiding 1 contexual commits
+75
+75