1 11
/*!
2 11
 * Copyright 2016 Google Inc. All Rights Reserved.
3 11
 *
4 11
 * Licensed under the Apache License, Version 2.0 (the "License");
5 11
 * you may not use this file except in compliance with the License.
6 11
 * You may obtain a copy of the License at
7 11
 *
8 11
 *      http://www.apache.org/licenses/LICENSE-2.0
9 11
 *
10 11
 * Unless required by applicable law or agreed to in writing, software
11 11
 * distributed under the License is distributed on an "AS IS" BASIS,
12 11
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 11
 * See the License for the specific language governing permissions and
14 11
 * limitations under the License.
15 11
 */
16 11

17 11
import arrify = require('arrify');
18 11
import {ServiceObjectConfig, GetConfig} from '@google-cloud/common';
19 11
// eslint-disable-next-line @typescript-eslint/no-var-requires
20 11
const common = require('./common-grpc/service-object');
21 11
import {paginator} from '@google-cloud/paginator';
22 11
import {promisifyAll} from '@google-cloud/promisify';
23 11
import * as extend from 'extend';
24 11
import snakeCase = require('lodash.snakecase');
25 11
import {Database, SessionPoolConstructor} from './database';
26 11
import {Spanner, RequestConfig} from '.';
27 11
import {CallOptions, ServiceError} from 'grpc';
28 11
import {
29 11
  RequestCallback,
30 11
  PagedRequest,
31 11
  PagedResponse,
32 11
  LongRunningCallback,
33 11
  NormalCallback,
34 11
  ResourceCallback,
35 11
} from './common';
36 11
import {Duplex} from 'stream';
37 11
import {SessionPoolOptions, SessionPool} from './session-pool';
38 11
import {Operation as GaxOperation} from 'google-gax';
39 11
import {Backup} from './backup';
40 11
import {google as instanceAdmin} from '../protos/protos';
41 11
import {google as databaseAdmin} from '../protos/protos';
42 11
import {google as spannerClient} from '../protos/protos';
43 11
import {CreateInstanceRequest} from './index';
44 11

45 11
export type IBackup = databaseAdmin.spanner.admin.database.v1.IBackup;
46 11
export type IDatabase = databaseAdmin.spanner.admin.database.v1.IDatabase;
47 11
export type IInstance = instanceAdmin.spanner.admin.instance.v1.IInstance;
48 11
export type IOperation = instanceAdmin.longrunning.IOperation;
49 11
export type CreateInstanceResponse = [Instance, GaxOperation, IOperation];
50 11
export type CreateDatabaseResponse = [Database, GaxOperation, IOperation];
51 11
export type DeleteInstanceResponse = [instanceAdmin.protobuf.IEmpty];
52 11
export type ExistsInstanceResponse = [boolean];
53 11
export type GetInstanceResponse = [Instance, IInstance];
54 11
export type GetInstanceMetadataResponse = [IInstance];
55 11
export interface GetInstanceMetadataOptions {
56 11
  fieldNames?: string | string[];
57 11
}
58 11
export type GetDatabasesResponse = PagedResponse<
59 11
  Database,
60 11
  databaseAdmin.spanner.admin.database.v1.IListDatabasesResponse
61 11
>;
62 11
export type SetInstanceMetadataResponse = [GaxOperation, IOperation];
63 11
export type GetBackupsResponse = PagedResponse<
64 11
  Backup,
65 11
  databaseAdmin.spanner.admin.database.v1.IListBackupsResponse
66 11
>;
67 11
export type GetBackupOperationsResponse = PagedResponse<
68 11
  IOperation,
69 11
  databaseAdmin.spanner.admin.database.v1.IListBackupOperationsResponse
70 11
>;
71 11
export type GetDatabaseOperationsResponse = PagedResponse<
72 11
  IOperation,
73 11
  databaseAdmin.spanner.admin.database.v1.IListDatabaseOperationsResponse
74 11
>;
75 11

76 11
export interface CreateDatabaseOptions
77 11
  extends databaseAdmin.spanner.admin.database.v1.ICreateDatabaseRequest {
78 11
  poolOptions?: SessionPoolOptions;
79 11
  poolCtor?: SessionPool;
80 11
  schema?: string;
81 11
}
82 11
export interface GetDatabasesRequest
83 11
  extends databaseAdmin.spanner.admin.database.v1.IListDatabasesRequest {
84 11
  autoPaginate?: boolean;
85 11
  maxApiCalls?: number;
86 11
  maxResults?: number;
87 11
}
88 11
export type CreateInstanceCallback = LongRunningCallback<Instance>;
89 11
export type CreateDatabaseCallback = LongRunningCallback<Database>;
90 11
export type DeleteInstanceCallback = NormalCallback<
91 11
  instanceAdmin.protobuf.IEmpty
92 11
>;
93 11

94 11
export type ExistsInstanceCallback = NormalCallback<boolean>;
95 11
export type GetDatabasesCallback = RequestCallback<
96 11
  Database,
97 11
  databaseAdmin.spanner.admin.database.v1.IListDatabasesResponse
98 11
>;
99 11
export type GetInstanceCallback = ResourceCallback<Instance, IInstance>;
100 11
export type GetInstanceMetadataCallback = NormalCallback<IInstance>;
101 11
export type SetInstanceMetadataCallback = ResourceCallback<
102 11
  GaxOperation,
103 11
  IOperation
104 11
>;
105 11
export type GetBackupsOptions = PagedRequest<
106 11
  databaseAdmin.spanner.admin.database.v1.IListBackupsRequest
107 11
>;
108 11
export type GetBackupsCallback = RequestCallback<
109 11
  Backup,
110 11
  databaseAdmin.spanner.admin.database.v1.IListBackupsResponse
111 11
>;
112 11
export type GetBackupOperationsOptions = PagedRequest<
113 11
  databaseAdmin.spanner.admin.database.v1.IListBackupOperationsRequest
114 11
>;
115 11
export type GetBackupOperationsCallback = RequestCallback<
116 11
  IOperation,
117 11
  databaseAdmin.spanner.admin.database.v1.IListBackupOperationsResponse
118 11
>;
119 11
export type GetDatabaseOperationsOptions = PagedRequest<
120 11
  databaseAdmin.spanner.admin.database.v1.IListDatabaseOperationsRequest
121 11
>;
122 11
export type GetDatabaseOperationsCallback = RequestCallback<
123 11
  IOperation,
124 11
  databaseAdmin.spanner.admin.database.v1.IListDatabaseOperationsResponse
125 11
>;
126 11
export interface GetInstanceConfig
127 11
  extends GetConfig,
128 11
    GetInstanceMetadataOptions {}
129 11

130 11
interface InstanceRequest {
131 11
  (
132 11
    config: RequestConfig,
133 11
    callback: ResourceCallback<GaxOperation, IOperation>
134 11
  ): void;
135 11
  <T>(config: RequestConfig, callback: RequestCallback<T>): void;
136 11
  <T, R>(config: RequestConfig, callback: RequestCallback<T, R>): void;
137 11
}
138 11
/**
139 11
 * The {@link Instance} class represents a [Cloud Spanner
140 11
 * instance](https://cloud.google.com/spanner/docs/instances).
141 11
 *
142 11
 * Create an `Instance` object to interact with a Cloud Spanner instance.
143 11
 *
144 11
 * @class
145 11
 *
146 11
 * @param {Spanner} spanner {@link Spanner} instance.
147 11
 * @param {string} name Name of the instance.
148 11
 *
149 11
 * @example
150 11
 * const {Spanner} = require('@google-cloud/spanner');
151 11
 * const spanner = new Spanner();
152 11
 * const instance = spanner.instance('my-instance');
153 11
 */
154 11
class Instance extends common.GrpcServiceObject {
155 11
  formattedName_: string;
156 11
  request: InstanceRequest;
157 11
  requestStream: (config?: RequestConfig) => Duplex;
158 11
  databases_: Map<string, Database>;
159 11
  metadata?: IInstance;
160 11
  constructor(spanner: Spanner, name: string) {
161 11
    const formattedName_ = Instance.formatName_(spanner.projectId, name);
162 11
    const methods = {
163 11
      /**
164 11
       * Create an instance.
165 11
       *
166 11
       * Wrapper around {@link v1.InstanceAdminClient#createInstance}.
167 11
       *
168 11
       * @see {@link v1.InstanceAdminClient#createInstance}
169 11
       * @see [CreateInstance API Documentation](https://cloud.google.com/spanner/docs/reference/rpc/google.spanner.admin.instance.v1#google.spanner.admin.instance.v1.InstanceAdmin.CreateInstance)
170 11
       *
171 11
       * @method Instance#create
172 11
       * @param {CreateInstanceRequest} config Configuration object.
173 11
       * @param {CreateInstanceCallback} [callback] Callback function.
174 11
       * @returns {Promise<CreateInstanceResponse>}
175 11
       *
176 11
       * @example
177 11
       * const {Spanner} = require('@google-cloud/spanner');
178 11
       * const spanner = new Spanner();
179 11
       *
180 11
       * const instance = spanner.instance('my-instance');
181 11
       *
182 11
       * instance.create(function(err, instance, operation, apiResponse) {
183 11
       *   if (err) {
184 11
       *     // Error handling omitted.
185 11
       *   }
186 11
       *
187 11
       *   operation
188 11
       *     .on('error', function(err) {})
189 11
       *     .on('complete', function() {
190 11
       *       // Instance created successfully.
191 11
       *     });
192 11
       * });
193 11
       *
194 11
       * //-
195 11
       * // If the callback is omitted, we'll return a Promise.
196 11
       * //-
197 11
       * instance.create()
198 11
       *   .then(function(data) {
199 11
       *     const operation = data[0];
200 11
       *     const apiResponse = data[1];
201 11
       *
202 11
       *     return operation.promise();
203 11
       *   })
204 11
       *   .then(function() {
205 11
       *     // Instance created successfully.
206 11
       *   });
207 11
       */
208 11
      create: true,
209 11
    };
210 11
    super(({
211 11
      parent: spanner,
212 11
      /**
213 11
       * @name Instance#id
214 11
       * @type {string}
215 11
       */
216 11
      id: name,
217 11
      methods,
218 11
      createMethod(
219 11
        _: {},
220 11
        options: CreateInstanceRequest,
221 11
        callback: CreateInstanceCallback
222 11
      ): void {
223 11
        spanner.createInstance(formattedName_, options, callback);
224 11
      },
225 11
    } as {}) as ServiceObjectConfig);
226 11
    this.formattedName_ = formattedName_;
227 11
    this.request = spanner.request.bind(spanner);
228 11
    this.requestStream = spanner.requestStream.bind(spanner);
229 11
    this.databases_ = new Map<string, Database>();
230 11
  }
231 11

232 11
  /**
233 11
   * Get a reference to a Backup object.
234 11
   *
235 11
   * @throws {Error} If any parameter is not provided.
236 11
   *
237 11
   * @param {string} backupId The name of the backup.
238 11
   * @return {Backup} A Backup object.
239 11
   *
240 11
   * @example
241 11
   * const {Spanner} = require('@google-cloud/spanner');
242 11
   * const spanner = new Spanner();
243 11
   * const instance = spanner.instance('my-instance');
244 11
   * const backup = instance.backup('my-backup');
245 11
   */
246 11
  backup(backupId: string): Backup {
247 11
    if (!backupId) {
248 11
      throw new Error('A backup ID is required to create a Backup.');
249 11
    }
250 11

251 11
    return new Backup(this, backupId);
252 11
  }
253 11

254 11
  getBackups(options?: GetBackupsOptions): Promise<GetBackupsResponse>;
255 11
  getBackups(callback: GetBackupsCallback): void;
256 11
  getBackups(query: GetBackupsOptions, callback: GetBackupsCallback): void;
257 11
  /**
258 11
   * Query object for listing backups.
259 11
   *
260 11
   * @typedef {object} GetBackupsOptions
261 11
   * @property {string} [filter] An expression for filtering the results of the
262 11
   *     request. Filter can be configured as outlined in
263 11
   *     {@link v1.DatabaseAdminClient#listBackups}.
264 11
   * @property {number} [pageSize] Maximum number of results per page.
265 11
   * @property {string} [pageToken] A previously-returned page token
266 11
   *     representing part of the larger set of results to view.
267 11
   */
268 11
  /**
269 11
   * @typedef {array} GetBackupsResponse
270 11
   * @property {Backup[]} 0 Array of {@link Backup} instances.
271 11
   * @property {object} 1 The full API response.
272 11
   */
273 11
  /**
274 11
   * List backups on the instance.
275 11
   *
276 11
   * Both completed and in-progress backups are listed if no filter is supplied.
277 11
   *
278 11
   * @see {@link #backup}
279 11
   *
280 11
   * @param {GetBackupsOptions} [options] The query object for listing backups.
281 11
   * @param {CallOptions} [options.gaxOptions] The request configuration
282 11
   *     options, outlined here:
283 11
   *     https://googleapis.github.io/gax-nodejs/classes/CallSettings.html.
284 11
   * @returns {Promise<GetBackupsResponse>} When resolved, contains a paged list
285 11
   *     of backups.
286 11
   *
287 11
   * @example
288 11
   * const {Spanner} = require('@google-cloud/spanner');
289 11
   * const spanner = new Spanner();
290 11
   * const instance = spanner.instance('my-instance');
291 11
   * const [backups] = await instance.getBackups();
292 11
   *
293 11
   * //-
294 11
   * // To manually handle pagination, set autoPaginate:false in gaxOptions.
295 11
   * //-
296 11
   * let pageToken = undefined;
297 11
   * do {
298 11
   *   const [backups, , response] = await instance.getBackups({
299 11
   *     pageSize: 3,
300 11
   *     pageToken,
301 11
   *     gaxOptions: {autoPaginate: false},
302 11
   *   });
303 11
   *   backups.forEach(backup => {
304 11
   *     // Do something with backup
305 11
   *   });
306 11
   *   pageToken = response.nextPageToken;
307 11
   * } while (pageToken);
308 11
   */
309 11
  getBackups(
310 11
    optionsOrCallback?: GetBackupsOptions | GetBackupsCallback,
311 11
    cb?: GetBackupsCallback
312 11
  ): void | Promise<GetBackupsResponse> {
313 11
    const callback =
314 11
      typeof optionsOrCallback === 'function'
315 11
        ? (optionsOrCallback as GetBackupsCallback)
316 11
        : cb!;
317 11
    const options =
318 11
      typeof optionsOrCallback === 'object'
319 11
        ? (optionsOrCallback as GetBackupsOptions)
320 11
        : {gaxOptions: {}};
321 11
    const gaxOpts: CallOptions = options.gaxOptions as CallOptions;
322 11
    const reqOpts = extend({}, options, {
323 11
      parent: this.formattedName_,
324 11
    });
325 11
    delete reqOpts.gaxOptions;
326 11

327 11
    this.request<
328 11
      IBackup,
329 11
      databaseAdmin.spanner.admin.database.v1.IListBackupsResponse
330 11
    >(
331 11
      {
332 11
        client: 'DatabaseAdminClient',
333 11
        method: 'listBackups',
334 11
        reqOpts,
335 11
        gaxOpts,
336 11
      },
337 11
      (err, backups, ...args) => {
338 11
        let backupInstances: Backup[] | null = null;
339 11
        if (backups) {
340 11
          backupInstances = backups.map(backup => {
341 11
            return this.backup(backup.name!);
342 11
          });
343 11
        }
344 11

345 11
        callback(err, backupInstances, ...args);
346 11
      }
347 11
    );
348 11
  }
349 11

350 11
  getBackupOperations(
351 11
    options?: GetBackupOperationsOptions
352 11
  ): Promise<GetBackupOperationsResponse>;
353 11
  getBackupOperations(callback: GetBackupOperationsCallback): void;
354 11
  getBackupOperations(
355 11
    options: GetBackupOperationsOptions,
356 11
    callback: GetBackupOperationsCallback
357 11
  ): void;
358 11
  /**
359 11
   * Query object for listing backup operations.
360 11
   *
361 11
   * @typedef {object} GetBackupOperationsOptions
362 11
   * @property {string} [filter] An expression for filtering the results of the
363 11
   *     request. Filter can be configured as outlined in
364 11
   *     {@link v1.DatabaseAdminClient#listBackupOperations}.
365 11
   * @property {number} [pageSize] Maximum number of results per page.
366 11
   * @property {string} [pageToken] A previously-returned page token
367 11
   *     representing part of the larger set of results to view.
368 11
   */
369 11
  /**
370 11
   * @typedef {array} GetBackupOperationsResponse
371 11
   * @property {IOperation[]} 0 Array of {@link IOperation} instances.
372 11
   * @property {object} 1 The full API response.
373 11
   */
374 11
  /**
375 11
   * List pending and completed backup operations for all databases in the instance.
376 11
   *
377 11
   * @see {@link #listOperations}
378 11
   *
379 11
   * @param {GetBackupOperationsOptions} [options] The query object for listing
380 11
   *     backup operations.
381 11
   * @param {CallOptions} [options.gaxOptions] The request configuration
382 11
   *     options, outlined here:
383 11
   *     https://googleapis.github.io/gax-nodejs/classes/CallSettings.html.
384 11
   * @returns {Promise<GetBackupOperationsResponse>} When resolved, contains a
385 11
   *     paged list of backup operations.
386 11
   *
387 11
   * @example
388 11
   * const {Spanner} = require('@google-cloud/spanner');
389 11
   * const spanner = new Spanner();
390 11
   * const instance = spanner.instance('my-instance');
391 11
   * const [operations] = await instance.getBackupOperations();
392 11
   *
393 11
   * //-
394 11
   * // To manually handle pagination, set autoPaginate:false in gaxOptions.
395 11
   * //-
396 11
   * let pageToken = undefined;
397 11
   * do {
398 11
   *   const [operations, , response] = await instance.getBackupOperations({
399 11
   *     pageSize: 3,
400 11
   *     pageToken,
401 11
   *     gaxOptions: {autoPaginate: false},
402 11
   *   });
403 11
   *   operations.forEach(operation => {
404 11
   *     // Do something with operation
405 11
   *   });
406 11
   *   pageToken = response.nextPageToken;
407 11
   * } while (pageToken);
408 11
   */
409 11
  getBackupOperations(
410 11
    optionsOrCallback?:
411 11
      | GetBackupOperationsOptions
412 11
      | GetBackupOperationsCallback,
413 11
    cb?: GetBackupOperationsCallback
414 11
  ): void | Promise<GetBackupOperationsResponse> {
415 11
    const callback =
416 11
      typeof optionsOrCallback === 'function'
417 11
        ? (optionsOrCallback as GetBackupOperationsCallback)
418 11
        : cb!;
419 11
    const options =
420 11
      typeof optionsOrCallback === 'object'
421 11
        ? (optionsOrCallback as GetBackupOperationsOptions)
422 11
        : {gaxOptions: {}};
423 11
    const gaxOpts: CallOptions = options.gaxOptions as CallOptions;
424 11
    const reqOpts = extend({}, options, {
425 11
      parent: this.formattedName_,
426 11
    });
427 11
    delete reqOpts.gaxOptions;
428 11

429 11
    this.request<
430 11
      IOperation,
431 11
      databaseAdmin.spanner.admin.database.v1.IListBackupOperationsResponse
432 11
    >(
433 11
      {
434 11
        client: 'DatabaseAdminClient',
435 11
        method: 'listBackupOperations',
436 11
        reqOpts,
437 11
        gaxOpts,
438 11
      },
439 11
      (err, operations, ...args) => {
440 0
        callback!(err, operations, ...args);
441 0
      }
442 11
    );
443 11
  }
444 11

445 11
  getDatabaseOperations(
446 11
    options?: GetDatabaseOperationsOptions
447 11
  ): Promise<GetDatabaseOperationsResponse>;
448 11
  getDatabaseOperations(callback: GetDatabaseOperationsCallback): void;
449 11
  getDatabaseOperations(
450 11
    options: GetDatabaseOperationsOptions,
451 11
    callback: GetDatabaseOperationsCallback
452 11
  ): void;
453 11
  /**
454 11
   * Query object for listing database operations.
455 11
   *
456 11
   * @typedef {object} GetDatabaseOperationsOptions
457 11
   * @property {string} [filter] An expression for filtering the results of the
458 11
   *     request. Filter can be configured as outlined in
459 11
   *     {@link v1.DatabaseAdminClient#listDatabaseOperations}.
460 11
   * @property {number} [pageSize] Maximum number of results per page.
461 11
   * @property {string} [pageToken] A previously-returned page token
462 11
   *     representing part of the larger set of results to view.
463 11
   */
464 11
  /**
465 11
   * @typedef {array} GetDatabaseOperationsResponse
466 11
   * @property {IOperation[]} 0 Array of {@link IOperation} instances.
467 11
   * @property {object} 1 The full API response.
468 11
   */
469 11
  /**
470 11
   * List pending and completed operations for all databases in the instance.
471 11
   *
472 11
   * @see {@link Database.getDatabaseOperations}
473 11
   *
474 11
   * @param {GetDatabaseOperationsOptions} [options] The query object for
475 11
   *     listing database operations.
476 11
   * @param {CallOptions} [options.gaxOptions] The request configuration
477 11
   *     options, outlined here:
478 11
   *     https://googleapis.github.io/gax-nodejs/classes/CallSettings.html.
479 11
   * @returns {Promise<GetDatabaseOperationsResponse>} When resolved, contains a
480 11
   *     paged list of database operations.
481 11
   *
482 11
   * @example
483 11
   * const {Spanner} = require('@google-cloud/spanner');
484 11
   * const spanner = new Spanner();
485 11
   * const instance = spanner.instance('my-instance');
486 11
   * const [operations] = await instance.getDatabaseOperations();
487 11
   * // ... then do something with the operations
488 11
   *
489 11
   * //-
490 11
   * // To manually handle pagination, set autoPaginate:false in gaxOptions.
491 11
   * //-
492 11
   * let pageToken = undefined;
493 11
   * do {
494 11
   *   const [operations, , response] = await instance.getDatabaseOperations({
495 11
   *     pageSize: 3,
496 11
   *     pageToken,
497 11
   *     gaxOptions: {autoPaginate: false},
498 11
   *   });
499 11
   *   operations.forEach(operation => {
500 11
   *     // Do something with operation
501 11
   *   });
502 11
   *   pageToken = response.nextPageToken;
503 11
   * } while (pageToken);
504 11
   */
505 11
  getDatabaseOperations(
506 11
    optionsOrCallback?:
507 11
      | GetDatabaseOperationsOptions
508 11
      | GetDatabaseOperationsCallback,
509 11
    cb?: GetDatabaseOperationsCallback
510 11
  ): void | Promise<GetDatabaseOperationsResponse> {
511 11
    const callback =
512 11
      typeof optionsOrCallback === 'function'
513 11
        ? (optionsOrCallback as GetDatabaseOperationsCallback)
514 11
        : cb!;
515 11
    const options =
516 11
      typeof optionsOrCallback === 'object'
517 11
        ? (optionsOrCallback as GetDatabaseOperationsOptions)
518 11
        : {gaxOptions: {}};
519 11
    const gaxOpts: CallOptions = options.gaxOptions as CallOptions;
520 11
    const reqOpts = extend({}, options, {
521 11
      parent: this.formattedName_,
522 11
    });
523 11
    delete reqOpts.gaxOptions;
524 11

525 11
    this.request<
526 11
      IOperation,
527 11
      databaseAdmin.spanner.admin.database.v1.IListDatabaseOperationsResponse
528 11
    >(
529 11
      {
530 11
        client: 'DatabaseAdminClient',
531 11
        method: 'listDatabaseOperations',
532 11
        reqOpts,
533 11
        gaxOpts,
534 11
      },
535 11
      (err, operations, ...args) => {
536 11
        callback!(err, operations, ...args);
537 11
      }
538 11
    );
539 11
  }
540 11

541 11
  createDatabase(
542 11
    name: string,
543 11
    options?: CreateDatabaseOptions
544 11
  ): Promise<CreateDatabaseResponse>;
545 11
  createDatabase(name: string, callback: CreateDatabaseCallback): void;
546 11
  createDatabase(
547 11
    name: string,
548 11
    options: CreateDatabaseOptions,
549 11
    callback: CreateDatabaseCallback
550 11
  ): void;
551 11
  /**
552 11
   * Config for the new database.
553 11
   *
554 11
   * @typedef {object} CreateDatabaseRequest
555 11
   * @property {SessionPoolOptions} [poolOptions]
556 11
   * @property {SessionPoolCtor} [poolCtor]
557 11
   */
558 11
  /**
559 11
   * @typedef {array} CreateDatabaseResponse
560 11
   * @property {Database} 0 The new {@link Database}.
561 11
   * @property {Operation} 1 An {@link Operation} object that can be used to check
562 11
   *     the status of the request.
563 11
   * @property {object} 2 The full API response.
564 11
   */
565 11
  /**
566 11
   * @callback CreateDatabaseCallback
567 11
   * @param {?Error} err Request error, if any.
568 11
   * @param {Database} database The new {@link Database}.
569 11
   * @param {Operation} operation An {@link Operation} object that can be used to
570 11
   *     check the status of the request.
571 11
   * @param {object} apiResponse The full API response.
572 11
   */
573 11
  /**
574 11
   * Create a database in this instance.
575 11
   *
576 11
   * Wrapper around {@link v1.DatabaseAdminClient#createDatabase}.
577 11
   *
578 11
   * @see {@link v1.DatabaseAdminClient#createDatabase}
579 11
   * @see [CreateDatabase API Documentation](https://cloud.google.com/spanner/docs/reference/rpc/google.spanner.admin.database.v1#google.spanner.admin.database.v1.DatabaseAdmin.CreateDatabase)
580 11
   *
581 11
   * @throws {Error} If a name is not provided.
582 11
   *
583 11
   * @param {name} name The name of the database to create.
584 11
   * @param {CreateDatabaseRequest} [options] Configuration object.
585 11
   * @param {CreateDatabaseCallback} [callback] Callback function.
586 11
   * @returns {Promise<CreateDatabaseResponse>}
587 11
   *
588 11
   * @example
589 11
   * const {Spanner} = require('@google-cloud/spanner');
590 11
   * const spanner = new Spanner();
591 11
   *
592 11
   * const instance = spanner.instance('my-instance');
593 11
   *
594 11
   * function callback(err, database, operation, apiResponse) {
595 11
   *   if (err) {
596 11
   *     // Error handling omitted.
597 11
   *   }
598 11
   *
599 11
   *   operation
600 11
   *     .on('error', function(err) {})
601 11
   *     .on('complete', function() {
602 11
   *       // Database created successfully.
603 11
   *     });
604 11
   * }
605 11
   *
606 11
   * instance.createDatabase('new-database-name', callback);
607 11
   *
608 11
   * //-
609 11
   * // Set the schema for the database.
610 11
   * //-
611 11
   * instance.createDatabase('new-database-name', {
612 11
   *   schema:
613 11
   *     'CREATE TABLE Singers (' +
614 11
   *     '  SingerId STRING(1024) NOT NULL,' +
615 11
   *     '  Name STRING(1024),' +
616 11
   *     ') PRIMARY KEY(SingerId)'
617 11
   * }, callback);
618 11
   * //-
619 11
   * // If the callback is omitted, we'll return a Promise.
620 11
   * //-
621 11
   * instance.createDatabase('new-database-name')
622 11
   *   .then(function(data) {
623 11
   *     const database = data[0];
624 11
   *     const operation = data[1];
625 11
   *     return operation.promise();
626 11
   *   })
627 11
   *   .then(function() {
628 11
   *     // Database created successfully.
629 11
   *   });
630 11
   *
631 11
   * @example <caption>include:samples/schema.js</caption>
632 11
   * region_tag:spanner_create_database
633 11
   * Full example:
634 11
   */
635 11
  createDatabase(
636 11
    name: string,
637 11
    optionsOrCallback?: CreateDatabaseOptions | CreateDatabaseCallback,
638 11
    cb?: CreateDatabaseCallback
639 11
  ): void | Promise<CreateDatabaseResponse> {
640 11
    if (!name) {
641 11
      throw new Error('A name is required to create a database.');
642 11
    }
643 11
    const callback =
644 11
      typeof optionsOrCallback === 'function' ? optionsOrCallback : cb!;
645 11
    const options =
646 11
      typeof optionsOrCallback === 'object'
647 11
        ? optionsOrCallback
648 11
        : ({} as CreateDatabaseOptions);
649 11

650 11
    const poolOptions = options.poolOptions;
651 11
    delete options.poolOptions;
652 11
    const poolCtor = options.poolCtor;
653 11
    delete options.poolCtor;
654 11
    const reqOpts = extend(
655 11
      {
656 11
        parent: this.formattedName_,
657 11
        createStatement: 'CREATE DATABASE `' + name.split('/').pop() + '`',
658 11
      },
659 11
      options
660 11
    );
661 11
    if (reqOpts.schema) {
662 11
      reqOpts.extraStatements = arrify(reqOpts.schema);
663 11
      delete reqOpts.schema;
664 11
    }
665 11
    this.request(
666 11
      {
667 11
        client: 'DatabaseAdminClient',
668 11
        method: 'createDatabase',
669 11
        reqOpts,
670 11
      },
671 11
      (err, operation, resp) => {
672 11
        if (err) {
673 11
          callback(err, null, null, resp);
674 11
          return;
675 11
        }
676 11
        const database = this.database(name, poolOptions || poolCtor);
677 11
        callback(null, database, operation, resp);
678 11
      }
679 11
    );
680 11
  }
681 11

682 11
  /**
683 11
   * Get a reference to a Database object.
684 11
   *
685 11
   * @throws {Error} If a name is not provided.
686 11
   *
687 11
   * @param {string} name The name of the instance.
688 11
   * @param {SessionPoolOptions|SessionPoolCtor} [poolOptions] Session pool
689 11
   *     configuration options.
690 11
   * @param {spannerClient.spanner.v1.ExecuteSqlRequest.IQueryOptions} [queryOptions]
691 11
   *     Default query options to use with the database. These options will be
692 11
   *     overridden by any query options set in environment variables or that
693 11
   *     are specified on a per-query basis.
694 11
   * @return {Database} A Database object.
695 11
   *
696 11
   * @example
697 11
   * const {Spanner} = require('@google-cloud/spanner');
698 11
   * const spanner = new Spanner();
699 11
   *
700 11
   * const instance = spanner.instance('my-instance');
701 11
   * const database = instance.database('my-database');
702 11
   */
703 11
  database(
704 11
    name: string,
705 11
    poolOptions?: SessionPoolOptions | SessionPoolConstructor,
706 11
    queryOptions?: spannerClient.spanner.v1.ExecuteSqlRequest.IQueryOptions
707 11
  ): Database {
708 11
    if (!name) {
709 11
      throw new Error('A name is required to access a Database object.');
710 11
    }
711 11
    // Only add an additional key for SessionPoolOptions and QueryOptions if an
712 11
    // options object with at least one value was passed in.
713 11
    let optionsKey =
714 11
      poolOptions && Object.keys(poolOptions).length > 0
715 11
        ? '/' + JSON.stringify(Object.entries(poolOptions).sort())
716 11
        : '';
717 11
    if (queryOptions && Object.keys(queryOptions).length > 0) {
718 11
      optionsKey =
719 11
        optionsKey + '/' + JSON.stringify(Object.entries(queryOptions!).sort());
720 11
    }
721 11
    const key = name.split('/').pop() + optionsKey;
722 11
    if (!this.databases_.has(key!)) {
723 11
      this.databases_.set(
724 11
        key!,
725 11
        new Database(this, name, poolOptions, queryOptions)
726 11
      );
727 11
    }
728 11
    return this.databases_.get(key!)!;
729 11
  }
730 11

731 11
  delete(): Promise<DeleteInstanceResponse>;
732 11
  delete(callback: DeleteInstanceCallback): void;
733 11
  /**
734 11
   * @typedef {array} DeleteInstanceResponse
735 11
   * @property {object} 0 The full API response.
736 11
   */
737 11
  /**
738 11
   * @callback DeleteInstanceCallback
739 11
   * @param {?Error} err Request error, if any.
740 11
   * @param {object} apiResponse The full API response.
741 11
   */
742 11
  /**
743 11
   * Delete the instance.
744 11
   *
745 11
   * Wrapper around {@link v1.InstanceAdminClient#deleteInstance}.
746 11
   *
747 11
   * @see {@link v1.InstanceAdminClient#deleteInstance}
748 11
   * @see [DeleteInstance API Documentation](https://cloud.google.com/spanner/docs/reference/rpc/google.spanner.admin.instance.v1#google.spanner.admin.instance.v1.InstanceAdmin.DeleteInstance)
749 11
   *
750 11
   * @param {DeleteInstanceCallback} [callback] Callback function.
751 11
   * @returns {Promise<DeleteInstanceResponse>}
752 11
   *
753 11
   * @example
754 11
   * const {Spanner} = require('@google-cloud/spanner');
755 11
   * const spanner = new Spanner();
756 11
   *
757 11
   * const instance = spanner.instance('my-instance');
758 11
   *
759 11
   * instance.delete(function(err, apiResponse) {
760 11
   *   if (err) {
761 11
   *     // Error handling omitted.
762 11
   *   }
763 11
   *
764 11
   *   // Instance was deleted successfully.
765 11
   * });
766 11
   *
767 11
   * //-
768 11
   * // If the callback is omitted, we'll return a Promise.
769 11
   * //-
770 11
   * instance.delete().then(function(data) {
771 11
   *   const apiResponse = data[0];
772 11
   * });
773 11
   */
774 11
  delete(
775 11
    callback?: DeleteInstanceCallback
776 11
  ): void | Promise<DeleteInstanceResponse> {
777 11
    const reqOpts = {
778 11
      name: this.formattedName_,
779 11
    };
780 11
    Promise.all(
781 11
      Array.from(this.databases_.values()).map(database => {
782 11
        return database.close();
783 11
      })
784 11
    )
785 11
      .catch(() => {})
786 11
      .then(() => {
787 11
        this.databases_.clear();
788 11
        this.request<instanceAdmin.protobuf.IEmpty>(
789 11
          {
790 11
            client: 'InstanceAdminClient',
791 11
            method: 'deleteInstance',
792 11
            reqOpts,
793 11
          },
794 11
          (err, resp) => {
795 11
            if (!err) {
796 11
              this.parent.instances_.delete(this.id);
797 11
            }
798 11
            callback!(err, resp!);
799 11
          }
800 11
        );
801 11
      });
802 11
  }
803 11

804 11
  exists(): Promise<ExistsInstanceResponse>;
805 11
  exists(callback: ExistsInstanceCallback): void;
806 11
  /**
807 11
   * @typedef {array} InstanceExistsResponse
808 11
   * @property {boolean} 0 Whether the {@link Instance} exists.
809 11
   */
810 11
  /**
811 11
   * @callback InstanceExistsCallback
812 11
   * @param {?Error} err Request error, if any.
813 11
   * @param {boolean} exists Whether the {@link Instance} exists.
814 11
   */
815 11
  /**
816 11
   * Check if an instance exists.
817 11
   *
818 11
   * @method Instance#exists
819 11
   * @param {InstanceExistsCallback} [callback] Callback function.
820 11
   * @returns {Promise<InstanceExistsResponse>}
821 11
   *
822 11
   * @example
823 11
   * const {Spanner} = require('@google-cloud/spanner');
824 11
   * const spanner = new Spanner();
825 11
   *
826 11
   * const instance = spanner.instance('my-instance');
827 11
   *
828 11
   * instance.exists(function(err, exists) {});
829 11
   *
830 11
   * //-
831 11
   * // If the callback is omitted, we'll return a Promise.
832 11
   * //-
833 11
   * instance.exists().then(function(data) {
834 11
   *   const exists = data[0];
835 11
   * });
836 11
   */
837 11
  exists(
838 11
    callback?: ExistsInstanceCallback
839 11
  ): void | Promise<ExistsInstanceResponse> {
840 11
    const NOT_FOUND = 5;
841 11

842 11
    this.getMetadata(err => {
843 11
      if (err && err.code !== NOT_FOUND) {
844 11
        callback!(err, null);
845 11
        return;
846 11
      }
847 11

848 11
      const exists = !err || err.code !== NOT_FOUND;
849 11
      callback!(null, exists);
850 11
    });
851 11
  }
852 11

853 11
  get(options?: GetInstanceConfig): Promise<GetInstanceResponse>;
854 11
  get(callback: GetInstanceCallback): void;
855 11
  get(options: GetInstanceConfig, callback: GetInstanceCallback): void;
856 11
  /**
857 11
   * @typedef {array} GetInstanceResponse
858 11
   * @property {Instance} 0 The {@link Instance}.
859 11
   * @property {object} 1 The full API response.
860 11
   */
861 11
  /**
862 11
   * @callback GetInstanceCallback
863 11
   * @param {?Error} err Request error, if any.
864 11
   * @param {Instance} instance The {@link Instance}.
865 11
   * @param {object} apiResponse The full API response.
866 11
   */
867 11
  /**
868 11
   * Get an instance if it exists.
869 11
   *
870 11
   * You may optionally use this to "get or create" an object by providing an
871 11
   * object with `autoCreate` set to `true`. Any extra configuration that is
872 11
   * normally required for the `create` method must be contained within this
873 11
   * object as well.
874 11
   *
875 11
   * @param {options} [options] Configuration object.
876 11
   * @param {boolean} [options.autoCreate=false] Automatically create the
877 11
   *     object if it does not exist.
878 11
   * @param {string | string[]} [options.fieldNames] A list of `Instance` field
879 11
   *     names to be requested. Eligible values are: `name`, `displayName`,
880 11
   *     `endpointUris`, `labels`, `config`, `nodeCount`, `state`.
881 11
   * @param {GetInstanceCallback} [callback] Callback function.
882 11
   * @returns {Promise<GetInstanceResponse>}
883 11
   *
884 11
   * @example
885 11
   * const {Spanner} = require('@google-cloud/spanner');
886 11
   * const spanner = new Spanner();
887 11
   *
888 11
   * const instance = spanner.instance('my-instance');
889 11
   *
890 11
   * instance.get(function(err, instance, apiResponse) {
891 11
   *   // `instance.metadata` has been populated.
892 11
   * });
893 11
   *
894 11
   * //-
895 11
   * // If the callback is omitted, we'll return a Promise.
896 11
   * //-
897 11
   * instance.get().then(function(data) {
898 11
   *   const instance = data[0];
899 11
   *   const apiResponse = data[0];
900 11
   * });
901 11
   */
902 11
  get(
903 11
    optionsOrCallback?: GetInstanceConfig | GetInstanceCallback,
904 11
    cb?: GetInstanceCallback
905 11
  ): void | Promise<GetInstanceResponse> {
906 11
    const callback =
907 11
      typeof optionsOrCallback === 'function' ? optionsOrCallback : cb!;
908 11
    const options =
909 11
      typeof optionsOrCallback === 'object'
910 11
        ? optionsOrCallback
911 11
        : ({} as GetInstanceConfig);
912 11

913 11
    const getMetadataOptions: GetInstanceMetadataOptions = new Object(null);
914 11
    if (options.fieldNames) {
915 11
      getMetadataOptions.fieldNames = options['fieldNames'];
916 11
      delete options.fieldNames;
917 11
    }
918 11

919 11
    this.getMetadata(getMetadataOptions, (err, metadata) => {
920 11
      if (err) {
921 11
        if (err.code === 5 && options.autoCreate) {
922 11
          this.create(
923 11
            options,
924 11
            (
925 11
              err: ServiceError | null,
926 11
              instance?: Instance,
927 11
              operation?: GaxOperation | null
928 11
            ) => {
929 11
              if (err) {
930 11
                callback(err);
931 11
                return;
932 11
              }
933 11
              operation!
934 11
                .on('error', callback)
935 11
                .on('complete', (metadata: IInstance) => {
936 11
                  this.metadata = metadata;
937 11
                  callback(null, this, metadata);
938 11
                });
939 11
            }
940 11
          );
941 11
          return;
942 11
        }
943 11
        callback(err);
944 11
        return;
945 11
      }
946 11
      callback(null, this, metadata!);
947 11
    });
948 11
  }
949 11

950 11
  getDatabases(query?: GetDatabasesRequest): Promise<GetDatabasesResponse>;
951 11
  getDatabases(callback: GetDatabasesCallback): void;
952 11
  getDatabases(
953 11
    query: GetDatabasesRequest,
954 11
    callback: GetDatabasesCallback
955 11
  ): void;
956 11
  /**
957 11
   * Query object for listing databases.
958 11
   *
959 11
   * @typedef {object} GetDatabasesRequest
960 11
   * @property {boolean} [autoPaginate=true] Have pagination handled
961 11
   *     automatically.
962 11
   * @property {number} [maxApiCalls] Maximum number of API calls to make.
963 11
   * @property {number} [maxResults] Maximum number of items to return.
964 11
   * @property {number} [pageSize] Maximum number of results per page.
965 11
   * @property {string} [pageToken] A previously-returned page token
966 11
   *     representing part of the larger set of results to view.
967 11
   */
968 11
  /**
969 11
   * @typedef {array} GetDatabasesResponse
970 11
   * @property {Database[]} 0 Array of {@link Database} instances.
971 11
   * @property {object} 1 The full API response.
972 11
   */
973 11
  /**
974 11
   * @callback GetDatabasesCallback
975 11
   * @param {?Error} err Request error, if any.
976 11
   * @param {Database[]} databases Array of {@link Database} instances.
977 11
   * @param {object} apiResponse The full API response.
978 11
   */
979 11
  /**
980 11
   * Get a list of databases.
981 11
   *
982 11
   * Wrapper around {@link v1.DatabaseAdminClient#listDatabases}.
983 11
   *
984 11
   * @see {@link v1.DatabaseAdminClient#listDatabases}
985 11
   * @see [ListDatabases API Documentation](https://cloud.google.com/spanner/docs/reference/rpc/google.spanner.admin.database.v1#google.spanner.admin.database.v1.DatabaseAdmin.ListDatabases)
986 11
   *
987 11
   * @param {GetDatabasesRequest} [query] Query object for listing databases.
988 11
   * @param {GetDatabasesCallback} [callback] Callback function.
989 11
   * @returns {Promise<GetDatabasesResponse>}
990 11
   *
991 11
   * @example
992 11
   * const {Spanner} = require('@google-cloud/spanner');
993 11
   * const spanner = new Spanner();
994 11
   *
995 11
   * const instance = spanner.instance('my-instance');
996 11
   *
997 11
   * instance.getDatabases(function(err, databases) {
998 11
   *   // `databases` is an array of `Database` objects.
999 11
   * });
1000 11
   *
1001 11
   * //-
1002 11
   * // To control how many API requests are made and page through the results
1003 11
   * // manually, set `autoPaginate` to `false`.
1004 11
   * //-
1005 11
   * function callback(err, databases, nextQuery, apiResponse) {
1006 11
   *   if (nextQuery) {
1007 11
   *     // More results exist.
1008 11
   *     instance.getDatabases(nextQuery, callback);
1009 11
   *   }
1010 11
   * }
1011 11
   *
1012 11
   * instance.getDatabases({
1013 11
   *   autoPaginate: false
1014 11
   * }, callback);
1015 11
   *
1016 11
   * //-
1017 11
   * // If the callback is omitted, we'll return a Promise.
1018 11
   * //-
1019 11
   * instance.getDatabases().then(function(data) {
1020 11
   *   const databases = data[0];
1021 11
   * });
1022 11
   */
1023 11
  getDatabases(
1024 11
    queryOrCallback?: GetDatabasesRequest | GetDatabasesCallback,
1025 11
    cb?: GetDatabasesCallback
1026 11
  ): void | Promise<GetDatabasesResponse> {
1027 11
    // eslint-disable-next-line @typescript-eslint/no-this-alias
1028 11
    const self = this;
1029 11
    const callback =
1030 11
      typeof queryOrCallback === 'function' ? queryOrCallback : cb!;
1031 11
    const query =
1032 11
      typeof queryOrCallback === 'object'
1033 11
        ? queryOrCallback
1034 11
        : ({} as GetDatabasesRequest);
1035 11

1036 11
    const reqOpts = extend({}, query, {
1037 11
      parent: this.formattedName_,
1038 11
    });
1039 11
    this.request<IDatabase[]>(
1040 11
      {
1041 11
        client: 'DatabaseAdminClient',
1042 11
        method: 'listDatabases',
1043 11
        reqOpts,
1044 11
        gaxOpts: query,
1045 11
      },
1046 11
      (err, rowDatabases, ...args) => {
1047 11
        let databases: Database[] | null = null;
1048 11
        if (rowDatabases) {
1049 11
          databases = rowDatabases.map(database => {
1050 11
            const databaseInstance = self.database(database.name!);
1051 11
            databaseInstance.metadata = database;
1052 11
            return databaseInstance;
1053 11
          });
1054 11
        }
1055 11
        callback(err, databases, ...args);
1056 11
      }
1057 11
    );
1058 11
  }
1059 11
  getMetadata(
1060 11
    options?: GetInstanceMetadataOptions
1061 11
  ): Promise<GetInstanceMetadataResponse>;
1062 11
  getMetadata(callback: GetInstanceMetadataCallback): void;
1063 11
  getMetadata(
1064 11
    options: GetInstanceMetadataOptions,
1065 11
    callback: GetInstanceMetadataCallback
1066 11
  ): void;
1067 11
  /**
1068 11
   * @typedef {array} GetInstanceMetadataResponse
1069 11
   * @property {object} 0 The {@link Instance} metadata.
1070 11
   * @property {object} 1 The full API response.
1071 11
   */
1072 11
  /**
1073 11
   * @callback GetInstanceMetadataCallback
1074 11
   * @param {?Error} err Request error, if any.
1075 11
   * @param {object} metadata The {@link Instance} metadata.
1076 11
   * @param {object} apiResponse The full API response.
1077 11
   */
1078 11
  /**
1079 11
   * Get the instance's metadata.
1080 11
   *
1081 11
   * Wrapper around {@link v1.InstanceAdminClient#getInstance}.
1082 11
   *
1083 11
   * @see {@link v1.InstanceAdminClient#getInstance}
1084 11
   * @see [GetInstance API Documentation](https://cloud.google.com/spanner/docs/reference/rpc/google.spanner.admin.instance.v1#google.spanner.admin.instance.v1.InstanceAdmin.GetInstance)
1085 11
   *
1086 11
   * @param {GetInstanceMetadataOptions} [options] Configuration object
1087 11
   * @param {string | string[]} [options.fieldNames] A list of `Instance` field
1088 11
   *     names to be requested. Eligible values are: `name`, `displayName`,
1089 11
   *     `endpointUris`, `labels`, `config`, `nodeCount`, `state`.
1090 11
   * @param {GetInstanceMetadataCallback} [callback] Callback function.
1091 11
   * @returns {Promise<GetInstanceMetadataResponse>}
1092 11
   *
1093 11
   * @example
1094 11
   * const {Spanner} = require('@google-cloud/spanner');
1095 11
   * const spanner = new Spanner();
1096 11
   *
1097 11
   * const instance = spanner.instance('my-instance');
1098 11
   *
1099 11
   * instance.getMetadata(function(err, metadata, apiResponse) {});
1100 11
   *
1101 11
   * //-
1102 11
   * // Request only `displayName`.
1103 11
   * //-
1104 11
   * instance.getMetadata({fieldNames: 'displayName'}, (err, metadata, apiResponse) => {
1105 11
   *   // metadata will only contain value for `displayName`
1106 11
   *   const displayName = metadata['displayName'];
1107 11
   * })
1108 11
   *
1109 11
   * //-
1110 11
   * // Request multiple specific field names.
1111 11
   * //-
1112 11
   * instance.getMetadata({fieldNames: ['displayName', 'nodeCount']}, (err, metadata, apiResponse) => {
1113 11
   *   // metadata will only contain value for `displayName` and 'nodeCount'
1114 11
   *   const displayName = metadata['displayName'];
1115 11
   *   const nodeCount = metadata['nodeCount'];
1116 11
   * });
1117 11
   *
1118 11
   * //-
1119 11
   * // If the callback is omitted, we'll return a Promise.
1120 11
   * //-
1121 11
   * instance.getMetadata().then(function(data) {
1122 11
   *   const metadata = data[0];
1123 11
   *   const apiResponse = data[1];
1124 11
   * });
1125 11
   */
1126 11
  getMetadata(
1127 11
    optionsOrCallback?:
1128 11
      | GetInstanceMetadataOptions
1129 11
      | GetInstanceMetadataCallback,
1130 11
    cb?: GetInstanceMetadataCallback
1131 11
  ): Promise<GetInstanceMetadataResponse> | void {
1132 11
    const callback =
1133 11
      typeof optionsOrCallback === 'function' ? optionsOrCallback : cb!;
1134 11
    const options =
1135 11
      typeof optionsOrCallback === 'object' ? optionsOrCallback : {};
1136 11
    const reqOpts = {
1137 11
      name: this.formattedName_,
1138 11
    };
1139 11
    if (options.fieldNames) {
1140 11
      reqOpts['fieldMask'] = {
1141 11
        paths: arrify(options['fieldNames']!).map(snakeCase),
1142 11
      };
1143 11
    }
1144 11
    return this.request<IInstance>(
1145 11
      {
1146 11
        client: 'InstanceAdminClient',
1147 11
        method: 'getInstance',
1148 11
        reqOpts,
1149 11
      },
1150 11
      callback!
1151 11
    );
1152 11
  }
1153 11

1154 11
  setMetadata(metadata: IInstance): Promise<SetInstanceMetadataResponse>;
1155 11
  setMetadata(metadata: IInstance, callback: SetInstanceMetadataCallback): void;
1156 11
  /**
1157 11
   * Update the metadata for this instance. Note that this method follows PATCH
1158 11
   * semantics, so previously-configured settings will persist.
1159 11
   *
1160 11
   * Wrapper around {@link v1.InstanceAdminClient#updateInstance}.
1161 11
   *
1162 11
   * @see {@link v1.InstanceAdminClient#updateInstance}
1163 11
   * @see [UpdateInstance API Documentation](https://cloud.google.com/spanner/docs/reference/rpc/google.spanner.admin.instance.v1#google.spanner.admin.instance.v1.InstanceAdmin.UpdateInstance)
1164 11
   *
1165 11
   * @param {object} metadata The metadata you wish to set.
1166 11
   * @param {SetInstanceMetadataCallback} [callback] Callback function.
1167 11
   * @returns {Promise<LongRunningOperationResponse>}
1168 11
   *
1169 11
   * @example
1170 11
   * const {Spanner} = require('@google-cloud/spanner');
1171 11
   * const spanner = new Spanner();
1172 11
   *
1173 11
   * const instance = spanner.instance('my-instance');
1174 11
   *
1175 11
   * const metadata = {
1176 11
   *   displayName: 'My Instance'
1177 11
   * };
1178 11
   *
1179 11
   * instance.setMetadata(metadata, function(err, operation, apiResponse) {
1180 11
   *   if (err) {
1181 11
   *     // Error handling omitted.
1182 11
   *   }
1183 11
   *
1184 11
   *   operation
1185 11
   *     .on('error', function(err) {})
1186 11
   *     .on('complete', function() {
1187 11
   *       // Metadata updated successfully.
1188 11
   *     });
1189 11
   * });
1190 11
   *
1191 11
   * //-
1192 11
   * // If the callback is omitted, we'll return a Promise.
1193 11
   * //-
1194 11
   * instance.setMetadata(metadata).then(function(data) {
1195 11
   *   const operation = data[0];
1196 11
   *   const apiResponse = data[1];
1197 11
   * });
1198 11
   */
1199 11
  setMetadata(
1200 11
    metadata: IInstance,
1201 11
    callback?: SetInstanceMetadataCallback
1202 11
  ): void | Promise<SetInstanceMetadataResponse> {
1203 11
    const reqOpts = {
1204 11
      instance: extend(
1205 11
        {
1206 11
          name: this.formattedName_,
1207 11
        },
1208 11
        metadata
1209 11
      ),
1210 11
      fieldMask: {
1211 11
        paths: Object.keys(metadata).map(snakeCase),
1212 11
      },
1213 11
    };
1214 11
    return this.request(
1215 11
      {
1216 11
        client: 'InstanceAdminClient',
1217 11
        method: 'updateInstance',
1218 11
        reqOpts,
1219 11
      },
1220 11
      callback!
1221 11
    );
1222 11
  }
1223 11
  /**
1224 11
   * Format the instance name to include the project ID.
1225 11
   *
1226 11
   * @private
1227 11
   *
1228 11
   * @param {string} projectId The project ID.
1229 11
   * @param {string} name The instance name.
1230 11
   * @returns {string}
1231 11
   *
1232 11
   * @example
1233 11
   * Instance.formatName_('grape-spaceship-123', 'my-instance');
1234 11
   * // 'projects/grape-spaceship-123/instances/my-instance'
1235 11
   */
1236 11
  static formatName_(projectId: string, name: string) {
1237 11
    if (name.indexOf('/') > -1) {
1238 11
      return name;
1239 11
    }
1240 11
    const instanceName = name.split('/').pop();
1241 11
    return 'projects/' + projectId + '/instances/' + instanceName;
1242 11
  }
1243 11
}
1244 11

1245 11
/**
1246 11
 * Get a list of databases as a readable object stream.
1247 11
 *
1248 11
 * Wrapper around {@link v1.DatabaseAdminClient#listDatabases}.
1249 11
 *
1250 11
 * @see {@link v1.DatabaseAdminClient#listDatabases}
1251 11
 * @see [ListDatabases API Documentation](https://cloud.google.com/spanner/docs/reference/rpc/google.spanner.admin.database.v1#google.spanner.admin.database.v1.DatabaseAdmin.ListDatabases)
1252 11
 *
1253 11
 * @method Spanner#getDatabasesStream
1254 11
 * @param {GetDatabasesRequest} [query] Query object for listing databases.
1255 11
 * @returns {ReadableStream} A readable stream that emits {@link Database}
1256 11
 *     instances.
1257 11
 *
1258 11
 * @example
1259 11
 * const {Spanner} = require('@google-cloud/spanner');
1260 11
 * const spanner = new Spanner();
1261 11
 *
1262 11
 * const instance = spanner.instance('my-instance');
1263 11
 *
1264 11
 * instance.getDatabasesStream()
1265 11
 *   .on('error', console.error)
1266 11
 *   .on('data', function(database) {
1267 11
 *     // `database` is a `Database` object.
1268 11
 *   })
1269 11
 *   .on('end', function() {
1270 11
 *     // All databases retrieved.
1271 11
 *   });
1272 11
 *
1273 11
 * //-
1274 11
 * // If you anticipate many results, you can end a stream early to prevent
1275 11
 * // unnecessary processing and API requests.
1276 11
 * //-
1277 11
 * instance.getDatabasesStream()
1278 11
 *   .on('data', function(database) {
1279 11
 *     this.end();
1280 11
 *   });
1281 11
 */
1282 11
Instance.prototype.getDatabasesStream = paginator.streamify('getDatabases');
1283 11

1284 11
/*! Developer Documentation
1285 11
 *
1286 11
 * All async methods (except for streams) will return a Promise in the event
1287 11
 * that a callback is omitted.
1288 11
 */
1289 11
promisifyAll(Instance, {
1290 11
  exclude: ['database', 'backup'],
1291 11
});
1292 11

1293 11
/**
1294 11
 * Reference to the {@link Instance} class.
1295 11
 * @name module:@google-cloud/spanner.Instance
1296 11
 * @see Instance
1297 11
 */
1298 11
export {Instance};

Read our documentation on viewing source code .

Loading