├── .devcontainer ├── Dockerfile ├── devcontainer.json └── postCreate.sh ├── .eslintignore ├── .eslintrc.json ├── .gitattributes ├── .github ├── .OwlBot.lock.yaml ├── .OwlBot.yaml ├── CODEOWNERS ├── ISSUE_TEMPLATE │ ├── bug_report.yml │ ├── config.yml │ ├── documentation_request.yml │ ├── feature_request.yml │ ├── processs_request.md │ └── questions.md ├── PULL_REQUEST_TEMPLATE.md ├── auto-approve.yml ├── auto-label.yaml ├── blunderbuss.yml ├── generated-files-bot.yml ├── release-please.yml ├── release-trigger.yml ├── scripts │ ├── close-invalid-link.cjs │ ├── close-unresponsive.cjs │ ├── fixtures │ │ ├── invalidIssueBody.txt │ │ ├── validIssueBody.txt │ │ └── validIssueBodyDifferentLinkLocation.txt │ ├── package.json │ ├── remove-response-label.cjs │ └── tests │ │ ├── close-invalid-link.test.cjs │ │ └── close-or-remove-response-label.test.cjs ├── sync-repo-settings.yaml └── workflows │ ├── ci.yaml │ ├── issues-no-repro.yaml │ ├── response.yaml │ └── system-tests-against-emulator.yaml ├── .gitignore ├── .jsdoc.js ├── .kokoro ├── .gitattributes ├── cleanup.sh ├── common.cfg ├── continuous │ └── node18 │ │ ├── common.cfg │ │ ├── lint.cfg │ │ ├── samples-test.cfg │ │ ├── system-test.cfg │ │ └── test.cfg ├── docs.sh ├── lint.sh ├── populate-secrets.sh ├── presubmit │ ├── node18 │ │ ├── common.cfg │ │ ├── samples-test.cfg │ │ ├── system-test-multiplexed-session.cfg │ │ ├── system-test.cfg │ │ └── test.cfg │ └── windows │ │ ├── common.cfg │ │ └── test.cfg ├── publish.sh ├── release │ ├── cleanup.cfg │ ├── common.cfg │ ├── docs-devsite.cfg │ ├── docs-devsite.sh │ ├── docs.cfg │ ├── docs.sh │ └── publish.cfg ├── samples-test.sh ├── system-test.sh ├── test.bat ├── test.sh ├── trampoline.sh └── trampoline_v2.sh ├── .mocharc.js ├── .nycrc ├── .prettierignore ├── .prettierrc.js ├── .readme-partials.yml ├── .repo-metadata.json ├── .trampolinerc ├── CHANGELOG.md ├── CODE_OF_CONDUCT.md ├── CONTRIBUTING.md ├── LICENSE ├── OBSERVABILITY.md ├── README.md ├── SECURITY.md ├── benchmark ├── .eslintrc.yml ├── README.md ├── benchmarking-multiplexed-session.js ├── bin │ └── ycsb ├── spanner.ts ├── workload.js ├── workloada ├── workloadb └── ycsb.js ├── bin ├── README.md ├── benchwrapper.js ├── benchwrapper_test_client.js └── spanner.proto ├── linkinator.config.json ├── observability-test ├── batch-transaction.ts ├── database.ts ├── helper.ts ├── observability.ts ├── session-pool.ts ├── spanner.ts ├── table.ts └── transaction.ts ├── owlbot.py ├── package.json ├── protos ├── google │ └── spanner │ │ ├── admin │ │ ├── database │ │ │ └── v1 │ │ │ │ ├── backup.proto │ │ │ │ ├── backup_schedule.proto │ │ │ │ ├── common.proto │ │ │ │ └── spanner_database_admin.proto │ │ └── instance │ │ │ └── v1 │ │ │ ├── common.proto │ │ │ └── spanner_instance_admin.proto │ │ ├── executor │ │ └── v1 │ │ │ └── cloud_executor.proto │ │ └── v1 │ │ ├── change_stream.proto │ │ ├── commit_response.proto │ │ ├── keys.proto │ │ ├── mutation.proto │ │ ├── query_plan.proto │ │ ├── result_set.proto │ │ ├── spanner.proto │ │ ├── transaction.proto │ │ └── type.proto ├── protos.d.ts ├── protos.js └── protos.json ├── renovate.json ├── samples ├── .eslintrc.yml ├── README.md ├── add-and-drop-new-database-role.js ├── archived │ ├── add-and-drop-new-database-role.js │ ├── backups-cancel.js │ ├── backups-copy.js │ ├── backups-create-with-encryption-key.js │ ├── backups-create.js │ ├── backups-delete.js │ ├── backups-get-database-operations.js │ ├── backups-get-operations.js │ ├── backups-get.js │ ├── backups-restore-with-encryption-key.js │ ├── backups-restore.js │ ├── backups-update.js │ ├── backups.js │ ├── database-create-with-default-leader.js │ ├── database-create-with-encryption-key.js │ ├── database-create-with-version-retention-period.js │ ├── database-get-ddl.js │ ├── database-update-default-leader.js │ ├── database-update.js │ ├── datatypes.js │ ├── enable-fine-grained-access.js │ ├── get-database-roles.js │ ├── get-instance-config.js │ ├── index-create-storing.js │ ├── index-create.js │ ├── indexing.js │ ├── instance-config-create.js │ ├── instance-config-delete.js │ ├── instance-config-get-operations.js │ ├── instance-config-update.js │ ├── instance-with-processing-units.js │ ├── instance.js │ ├── json-add-column.js │ ├── list-databases.js │ ├── list-instance-configs.js │ ├── numeric-add-column.js │ ├── pg-add-column.js │ ├── pg-database-create.js │ ├── pg-index-create-storing.js │ ├── pg-interleaving.js │ ├── pg-jsonb-add-column.js │ ├── pg-sequence-alter.js │ ├── pg-sequence-create.js │ ├── pg-sequence-drop.js │ ├── schema.js │ ├── sequence-alter.js │ ├── sequence-create.js │ ├── sequence-drop.js │ ├── table-alter-with-foreign-key-delete-cascade.js │ ├── table-create-with-foreign-key-delete-cascade.js │ ├── table-drop-foreign-key-constraint-delete-cascade.js │ └── timestamp.js ├── backups-cancel.js ├── backups-copy-with-multiple-kms-keys.js ├── backups-copy.js ├── backups-create-with-encryption-key.js ├── backups-create-with-multiple-kms-keys.js ├── backups-create.js ├── backups-delete.js ├── backups-get-database-operations.js ├── backups-get-operations.js ├── backups-get.js ├── backups-restore-with-encryption-key.js ├── backups-restore-with-multiple-kms-keys.js ├── backups-restore.js ├── backups-update.js ├── backups.js ├── batch-write.js ├── batch.js ├── create-full-backup-schedule.js ├── create-incremental-backup-schedule.js ├── create-instance-without-default-backup-schedules.js ├── crud.js ├── database-add-split-points.js ├── database-create-with-default-leader.js ├── database-create-with-encryption-key.js ├── database-create-with-multiple-kms-keys.js ├── database-create-with-version-retention-period.js ├── database-get-ddl.js ├── database-get-default-leader.js ├── database-update-default-leader.js ├── database-update.js ├── datatypes.js ├── delete-backup-schedule.js ├── directed-reads.js ├── dml-returning-delete.js ├── dml-returning-insert.js ├── dml-returning-update.js ├── dml.js ├── enable-fine-grained-access.js ├── get-backup-schedule.js ├── get-commit-stats.js ├── get-database-roles.js ├── get-instance-config.js ├── index-create-storing.js ├── index-create.js ├── index-query-data.js ├── index-read-data-with-storing.js ├── index-read-data.js ├── indexing.js ├── instance-config-create.js ├── instance-config-delete.js ├── instance-config-get-operations.js ├── instance-config-update.js ├── instance-partition-create.js ├── instance-update.js ├── instance-with-asymmetric-autoscaling-config.js ├── instance-with-autoscaling-config.js ├── instance-with-processing-units.js ├── instance.js ├── json-add-column.js ├── json-query-parameter.js ├── json-update-data.js ├── list-backup-schedules.js ├── list-databases.js ├── list-instance-configs.js ├── max-commit-delay.js ├── numeric-add-column.js ├── numeric-query-parameter.js ├── numeric-update-data.js ├── observability-traces-otlp.js ├── observability-traces.js ├── package.json ├── pg-add-column.js ├── pg-case-sensitivity.js ├── pg-database-create.js ├── pg-datatypes-casting.js ├── pg-dml-batch.js ├── pg-dml-getting-started-update.js ├── pg-dml-partitioned.js ├── pg-dml-returning-delete.js ├── pg-dml-returning-insert.js ├── pg-dml-returning-update.js ├── pg-dml-with-parameter.js ├── pg-functions.js ├── pg-index-create-storing.js ├── pg-interleaving.js ├── pg-jsonb-add-column.js ├── pg-jsonb-query-parameter.js ├── pg-jsonb-update-data.js ├── pg-numeric-data-type.js ├── pg-ordering-nulls.js ├── pg-query-parameter.js ├── pg-schema-information.js ├── pg-sequence-alter.js ├── pg-sequence-create.js ├── pg-sequence-drop.js ├── proto-query-data.js ├── proto-type-add-column.js ├── proto-update-data-dml.js ├── proto-update-data.js ├── queryoptions.js ├── quickstart.js ├── read-data-with-database-role.js ├── request-tag.js ├── resource │ ├── README.md │ ├── descriptors.pb │ ├── singer.d.ts │ ├── singer.js │ └── singer.proto ├── rpc-priority-batch-dml.js ├── rpc-priority-partitioned-dml.js ├── rpc-priority-query-partitions.js ├── rpc-priority-read.js ├── rpc-priority-run.js ├── rpc-priority-transaction.js ├── schema.js ├── sequence-alter.js ├── sequence-create.js ├── sequence-drop.js ├── struct.js ├── system-test │ ├── archived │ │ └── spanner.test.js │ └── spanner.test.js ├── table-alter-with-foreign-key-delete-cascade.js ├── table-create-with-foreign-key-delete-cascade.js ├── table-drop-foreign-key-constraint-delete-cascade.js ├── timestamp.js ├── transaction-tag.js ├── transaction-timeout.js ├── transaction.js ├── update-backup-schedule.js └── update-instance-default-backup-schedule-type.js ├── scripts └── cleanup.js ├── src ├── backup.ts ├── batch-transaction.ts ├── codec.ts ├── common-grpc │ ├── service-object.ts │ └── service.ts ├── common.ts ├── database.ts ├── extra_proto_list.json ├── helper.ts ├── index.ts ├── instance-config.ts ├── instance.ts ├── instrument.ts ├── metrics │ ├── README.md │ ├── constants.ts │ ├── external-types.ts │ ├── spanner-metrics-exporter.ts │ └── transform.ts ├── multiplexed-session.ts ├── partial-result-stream.ts ├── request_id_header.ts ├── session-factory.ts ├── session-pool.ts ├── session.ts ├── spanner_grpc_config.json ├── table.ts ├── transaction-runner.ts ├── transaction.ts └── v1 │ ├── database_admin_client.ts │ ├── database_admin_client_config.json │ ├── database_admin_proto_list.json │ ├── gapic_metadata.json │ ├── index.ts │ ├── instance_admin_client.ts │ ├── instance_admin_client_config.json │ ├── instance_admin_proto_list.json │ ├── spanner_client.ts │ ├── spanner_client_config.json │ ├── spanner_executor_proxy_client.ts │ ├── spanner_executor_proxy_client_config.json │ ├── spanner_executor_proxy_proto_list.json │ └── spanner_proto_list.json ├── system-test ├── fixtures │ └── sample │ │ ├── package.json │ │ ├── src │ │ └── index.ts │ │ └── tsconfig.json ├── install.ts └── spanner.ts ├── test ├── backup.ts ├── batch-transaction.ts ├── codec.ts ├── common │ ├── service-object.ts │ └── service.ts ├── data │ ├── README.md │ ├── descriptors.pb │ ├── singer.d.ts │ ├── singer.js │ ├── singer.proto │ └── streaming-read-acceptance-test.json ├── database.ts ├── gapic_database_admin_v1.ts ├── gapic_instance_admin_v1.ts ├── gapic_spanner_executor_proxy_v1.ts ├── gapic_spanner_v1.ts ├── index.ts ├── instance-config.ts ├── instance.ts ├── metrics │ ├── spanner-metrics-exporter.ts │ └── transform.ts ├── mockserver │ ├── mockdatabaseadmin.ts │ ├── mockinstanceadmin.ts │ └── mockspanner.ts ├── multiplexed-session.ts ├── partial-result-stream.ts ├── request_id_header.ts ├── session-factory.ts ├── session-pool.ts ├── session.ts ├── spanner.ts ├── table.ts ├── transaction-runner.ts └── transaction.ts ├── tsconfig.json └── webpack.config.js /.devcontainer/Dockerfile: -------------------------------------------------------------------------------- 1 | ARG VARIANT="18" 2 | FROM mcr.microsoft.com/devcontainers/typescript-node:${VARIANT} 3 | 4 | RUN apt-get update && export DEBIAN_FRONTEND=noninteractive 5 | 6 | RUN type -p curl >/dev/null || (apt-get install curl -y) 7 | 8 | # install gh 9 | RUN curl -fsSL https://cli.github.com/packages/githubcli-archive-keyring.gpg | dd of=/usr/share/keyrings/githubcli-archive-keyring.gpg \ 10 | && chmod go+r /usr/share/keyrings/githubcli-archive-keyring.gpg \ 11 | && echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/githubcli-archive-keyring.gpg] https://cli.github.com/packages stable main" | tee /etc/apt/sources.list.d/github-cli.list > /dev/null \ 12 | && apt-get update \ 13 | && apt-get install gh -y 14 | 15 | # install gloud sdk 16 | RUN echo "deb [signed-by=/usr/share/keyrings/cloud.google.gpg] http://packages.cloud.google.com/apt cloud-sdk main" | tee -a /etc/apt/sources.list.d/google-cloud-sdk.list && curl https://packages.cloud.google.com/apt/doc/apt-key.gpg | apt-key --keyring /usr/share/keyrings/cloud.google.gpg add - && apt-get update -y && apt-get install google-cloud-cli -y -------------------------------------------------------------------------------- /.devcontainer/devcontainer.json: -------------------------------------------------------------------------------- 1 | // For format details, see https://aka.ms/devcontainer.json. For config options, see the 2 | // README at: https://github.com/devcontainers/templates/tree/main/src/typescript-node 3 | { 4 | "name": "Node.js & TypeScript", 5 | "build": { 6 | // Sets the run context to one level up instead of the .devcontainer folder. 7 | "args": { "VARIANT": "18" }, 8 | // Update the 'dockerFile' property if you aren't using the standard 'Dockerfile' filename. 9 | "dockerfile": "Dockerfile" 10 | }, 11 | 12 | "postCreateCommand": "bash .devcontainer/postCreate.sh", 13 | 14 | "customizations": { 15 | "vscode": { 16 | "settings": { 17 | "debug.javascript.autoAttachFilter":"smart" 18 | }, 19 | "extensions": [ 20 | "ms-azuretools.vscode-docker" 21 | ] 22 | } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /.devcontainer/postCreate.sh: -------------------------------------------------------------------------------- 1 | echo "Post Create Starting" 2 | 3 | npm install 4 | npm test -------------------------------------------------------------------------------- /.eslintignore: -------------------------------------------------------------------------------- 1 | **/node_modules 2 | **/coverage 3 | test/fixtures 4 | build/ 5 | docs/ 6 | protos/ 7 | samples/generated/ 8 | system-test/**/fixtures 9 | -------------------------------------------------------------------------------- /.eslintrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./node_modules/gts" 3 | } 4 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | *.ts text eol=lf 2 | *.js text eol=lf 3 | protos/* linguist-generated 4 | **/api-extractor.json linguist-language=JSON-with-Comments 5 | -------------------------------------------------------------------------------- /.github/.OwlBot.lock.yaml: -------------------------------------------------------------------------------- 1 | # Copyright 2025 Google LLC 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | docker: 15 | image: gcr.io/cloud-devrel-public-resources/owlbot-nodejs:latest 16 | digest: sha256:c7e4968cfc97a204a4b2381f3ecb55cabc40c4cccf88b1ef8bef0d976be87fee 17 | # created: 2025-04-08T17:33:08.498793944Z 18 | -------------------------------------------------------------------------------- /.github/.OwlBot.yaml: -------------------------------------------------------------------------------- 1 | # Copyright 2021 Google LLC 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | docker: 15 | image: gcr.io/cloud-devrel-public-resources/owlbot-nodejs:latest 16 | 17 | 18 | deep-remove-regex: 19 | - /owl-bot-staging 20 | 21 | deep-copy-regex: 22 | - source: /google/spanner/(v.*)/.*-nodejs/(.*) 23 | dest: /owl-bot-staging/$1/$2 24 | - source: /google/spanner/(admin/database/v.*)/.*-nodejs/(.*) 25 | dest: /owl-bot-staging/$1/$2 26 | - source: /google/spanner/(admin/instance/v.*)/.*-nodejs/(.*) 27 | dest: /owl-bot-staging/$1/$2 28 | - source: /google/spanner/(executor/v.*)/.*-nodejs/(.*) 29 | dest: /owl-bot-staging/$1/$2 30 | 31 | begin-after-commit-hash: 46f25fb1121747b994ff5818963fda84b5e6bfd3 32 | 33 | -------------------------------------------------------------------------------- /.github/CODEOWNERS: -------------------------------------------------------------------------------- 1 | # Code owners file. 2 | # This file controls who is tagged for review for any given pull request. 3 | # 4 | # For syntax help see: 5 | # https://help.github.com/en/github/creating-cloning-and-archiving-repositories/about-code-owners#codeowners-syntax 6 | 7 | 8 | # Unless specified, the jsteam is the default owner for nodejs repositories. 9 | * @googleapis/spanner-client-libraries-nodejs @googleapis/jsteam -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/config.yml: -------------------------------------------------------------------------------- 1 | contact_links: 2 | - name: Google Cloud Support 3 | url: https://cloud.google.com/support/ 4 | about: If you have a support contract with Google, please use the Google Cloud Support portal. 5 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/documentation_request.yml: -------------------------------------------------------------------------------- 1 | name: Documentation Requests 2 | description: Requests for more information 3 | body: 4 | - type: markdown 5 | attributes: 6 | value: > 7 | Please use this issue type to log documentation requests against the library itself. 8 | These requests should involve documentation on Github (`.md` files), and should relate to the library 9 | itself. If you have questions or documentation requests for an API, please 10 | reach out to the API tracker itself. 11 | 12 | Please submit an issue to the API team, either by submitting an 13 | issue in its issue tracker https://cloud.google.com/support/docs/issue-trackers), or by 14 | submitting an issue in its linked tracker in the .repo-metadata.json 15 | file in the API under packages/* ([example](https://issuetracker.google.com/issues?q=componentid:190851%2B%20status:open)). 16 | You can also submit a request to documentation on cloud.google.com itself with the "Send Feedback" 17 | on the bottom of the page. 18 | 19 | 20 | Please note that documentation requests and questions for specific APIs 21 | will be closed. 22 | - type: checkboxes 23 | attributes: 24 | label: Please make sure you have searched for information in the following 25 | guides. 26 | options: 27 | - label: "Search the issues already opened: 28 | https://github.com/GoogleCloudPlatform/google-cloud-node/issues" 29 | required: true 30 | - label: "Check our Troubleshooting guide: 31 | https://googlecloudplatform.github.io/google-cloud-node/#/docs/guid\ 32 | es/troubleshooting" 33 | required: true 34 | - label: "Check our FAQ: 35 | https://googlecloudplatform.github.io/google-cloud-node/#/docs/guid\ 36 | es/faq" 37 | required: true 38 | - label: "Check our libraries HOW-TO: 39 | https://github.com/googleapis/gax-nodejs/blob/main/client-libraries\ 40 | .md" 41 | required: true 42 | - label: "Check out our authentication guide: 43 | https://github.com/googleapis/google-auth-library-nodejs" 44 | required: true 45 | - label: "Check out handwritten samples for many of our APIs: 46 | https://github.com/GoogleCloudPlatform/nodejs-docs-samples" 47 | required: true 48 | - type: textarea 49 | attributes: 50 | label: > 51 | Documentation Request 52 | validations: 53 | required: true 54 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature_request.yml: -------------------------------------------------------------------------------- 1 | name: Feature Request 2 | description: Suggest an idea for this library 3 | labels: 4 | - feature request 5 | body: 6 | - type: markdown 7 | attributes: 8 | value: > 9 | **PLEASE READ**: If you have a support contract with Google, please 10 | create an issue in the [support 11 | console](https://cloud.google.com/support/) instead of filing on GitHub. 12 | This will ensure a timely response. Otherwise, please make sure to 13 | follow the steps below. 14 | - type: textarea 15 | attributes: 16 | label: > 17 | A screenshot that you have tested with "Try this API". 18 | description: > 19 | As our client libraries are mostly autogenerated, we kindly request 20 | that you test whether your feature request is with the client library, or with the 21 | API itself. To do so, please search for your API 22 | here: https://developers.google.com/apis-explorer and attempt to 23 | reproduce the issue in the given method. Please include a screenshot of 24 | the response in "Try this API". This response should NOT match the current 25 | behavior you are experiencing. If the behavior is the same, it means 26 | that you are likely requesting a feature for the API itself. In that 27 | case, please submit an issue to the API team, either by submitting an 28 | issue in its issue tracker https://cloud.google.com/support/docs/issue-trackers, or by 29 | submitting an issue in its linked tracker in the .repo-metadata.json 30 | file in the API under packages/* ([example](https://issuetracker.google.com/issues?q=componentid:190851%2B%20status:open)) 31 | 32 | Example of library specific issues would be: retry strategies, authentication questions, or issues with typings. 33 | Examples of API issues would include: expanding method parameter types, adding functionality to an API. 34 | validations: 35 | required: true 36 | - type: textarea 37 | attributes: 38 | label: > 39 | What would you like to see in the library? 40 | description: > 41 | Screenshots can be provided in the issue body below. 42 | placeholder: | 43 | 1. Set up authentication like so 44 | 2. Run the program like so 45 | 3. X would be nice to happen 46 | 47 | - type: textarea 48 | attributes: 49 | label: Describe alternatives you've considered 50 | 51 | - type: textarea 52 | attributes: 53 | label: Additional context/notes -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/processs_request.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Process Request 3 | about: Submit a process request to the library. Process requests are any requests related to library infrastructure, for example CI/CD, publishing, releasing, broken links. 4 | --- 5 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/questions.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Question 3 | about: If you have a question, please use Discussions 4 | 5 | --- 6 | 7 | If you have a general question that goes beyond the library itself, we encourage you to use [Discussions](https://github.com//discussions) 8 | to engage with fellow community members! 9 | -------------------------------------------------------------------------------- /.github/PULL_REQUEST_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | > Thank you for opening a Pull Request! Before submitting your PR, there are a few things you can do to make sure it goes smoothly: 2 | 3 | ## Description 4 | 5 | > Please provide a detailed description for the change. 6 | > As much as possible, please try to keep changes separate by purpose. For example, try not to make a one-line bug fix in a feature request, or add an irrelevant README change to a bug fix. 7 | 8 | ## Impact 9 | 10 | > What's the impact of this change? 11 | 12 | ## Testing 13 | 14 | > Have you added unit and integration tests if necessary? 15 | > Were any tests changed? Are any breaking changes necessary? 16 | 17 | ## Additional Information 18 | 19 | > Any additional details that we should be aware of? 20 | 21 | ## Checklist 22 | 23 | - [ ] Make sure to open an issue as a [bug/issue](https://github.com/googleapis/nodejs-spanner/issues/new/choose) before writing your code! That way we can discuss the change, evaluate designs, and agree on the general idea 24 | - [ ] Ensure the tests and linter pass 25 | - [ ] Code coverage does not decrease 26 | - [ ] Appropriate docs were updated 27 | - [ ] Appropriate comments were added, particularly in complex areas or places that require background 28 | - [ ] No new warnings or issues will be generated from this change 29 | 30 | Fixes #issue_number_goes_here 🦕 31 | -------------------------------------------------------------------------------- /.github/auto-approve.yml: -------------------------------------------------------------------------------- 1 | processes: 2 | - "NodeDependency" -------------------------------------------------------------------------------- /.github/auto-label.yaml: -------------------------------------------------------------------------------- 1 | requestsize: 2 | enabled: true 3 | -------------------------------------------------------------------------------- /.github/blunderbuss.yml: -------------------------------------------------------------------------------- 1 | assign_issues: 2 | - gargsurbhi 3 | -------------------------------------------------------------------------------- /.github/generated-files-bot.yml: -------------------------------------------------------------------------------- 1 | generatedFiles: 2 | - path: '.kokoro/**' 3 | message: '`.kokoro` files are templated and should be updated in [`synthtool`](https://github.com/googleapis/synthtool)' 4 | - path: '.github/CODEOWNERS' 5 | message: 'CODEOWNERS should instead be modified via the `codeowner_team` property in .repo-metadata.json' 6 | - path: '.github/workflows/ci.yaml' 7 | message: '`.github/workflows/ci.yaml` (GitHub Actions) should be updated in [`synthtool`](https://github.com/googleapis/synthtool)' 8 | - path: '.github/generated-files-bot.+(yml|yaml)' 9 | message: '`.github/generated-files-bot.(yml|yaml)` should be updated in [`synthtool`](https://github.com/googleapis/synthtool)' 10 | - path: 'README.md' 11 | message: '`README.md` is managed by [`synthtool`](https://github.com/googleapis/synthtool). However, a partials file can be used to update the README, e.g.: https://github.com/googleapis/nodejs-storage/blob/main/.readme-partials.yaml' 12 | - path: 'samples/README.md' 13 | message: '`samples/README.md` is managed by [`synthtool`](https://github.com/googleapis/synthtool). However, a partials file can be used to update the README, e.g.: https://github.com/googleapis/nodejs-storage/blob/main/.readme-partials.yaml' 14 | ignoreAuthors: 15 | - 'gcf-owl-bot[bot]' 16 | - 'yoshi-automation' 17 | -------------------------------------------------------------------------------- /.github/release-please.yml: -------------------------------------------------------------------------------- 1 | handleGHRelease: true 2 | releaseType: node 3 | -------------------------------------------------------------------------------- /.github/release-trigger.yml: -------------------------------------------------------------------------------- 1 | enabled: true 2 | multiScmName: nodejs-spanner 3 | -------------------------------------------------------------------------------- /.github/scripts/close-unresponsive.cjs: -------------------------------------------------------------------------------- 1 | /// Copyright 2024 Google LLC 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | function labeledEvent(data) { 16 | return data.event === "labeled" && data.label.name === "needs more info"; 17 | } 18 | 19 | const numberOfDaysLimit = 15; 20 | const close_message = `This has been closed since a request for information has \ 21 | not been answered for ${numberOfDaysLimit} days. It can be reopened when the \ 22 | requested information is provided.`; 23 | 24 | module.exports = async ({ github, context }) => { 25 | const owner = context.repo.owner; 26 | const repo = context.repo.repo; 27 | 28 | const issues = await github.rest.issues.listForRepo({ 29 | owner: owner, 30 | repo: repo, 31 | labels: "needs more info", 32 | }); 33 | const numbers = issues.data.map((e) => e.number); 34 | 35 | for (const number of numbers) { 36 | const events = await github.paginate( 37 | github.rest.issues.listEventsForTimeline, 38 | { 39 | owner: owner, 40 | repo: repo, 41 | issue_number: number, 42 | }, 43 | (response) => response.data.filter(labeledEvent) 44 | ); 45 | 46 | const latest_response_label = events[events.length - 1]; 47 | 48 | const created_at = new Date(latest_response_label.created_at); 49 | const now = new Date(); 50 | const diff = now - created_at; 51 | const diffDays = diff / (1000 * 60 * 60 * 24); 52 | 53 | if (diffDays > numberOfDaysLimit) { 54 | await github.rest.issues.update({ 55 | owner: owner, 56 | repo: repo, 57 | issue_number: number, 58 | state: "closed", 59 | }); 60 | 61 | await github.rest.issues.createComment({ 62 | owner: owner, 63 | repo: repo, 64 | issue_number: number, 65 | body: close_message, 66 | }); 67 | } 68 | } 69 | }; -------------------------------------------------------------------------------- /.github/scripts/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "tests", 3 | "private": true, 4 | "description": "tests for script", 5 | "scripts": { 6 | "test": "mocha tests/close-invalid-link.test.cjs && mocha tests/close-or-remove-response-label.test.cjs" 7 | }, 8 | "author": "Google Inc.", 9 | "license": "Apache-2.0", 10 | "engines": { 11 | "node": ">=18" 12 | }, 13 | "dependencies": { 14 | "js-yaml": "^4.1.0" 15 | }, 16 | "devDependencies": { 17 | "@octokit/rest": "^19.0.0", 18 | "mocha": "^10.0.0", 19 | "sinon": "^18.0.0" 20 | } 21 | } -------------------------------------------------------------------------------- /.github/scripts/remove-response-label.cjs: -------------------------------------------------------------------------------- 1 | // Copyright 2024 Google LLC 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | module.exports = async ({ github, context }) => { 16 | const commenter = context.actor; 17 | const issue = await github.rest.issues.get({ 18 | owner: context.repo.owner, 19 | repo: context.repo.repo, 20 | issue_number: context.issue.number, 21 | }); 22 | const author = issue.data.user.login; 23 | const labels = issue.data.labels.map((e) => e.name); 24 | 25 | if (author === commenter && labels.includes("needs more info")) { 26 | await github.rest.issues.removeLabel({ 27 | owner: context.repo.owner, 28 | repo: context.repo.repo, 29 | issue_number: context.issue.number, 30 | name: "needs more info", 31 | }); 32 | } 33 | }; -------------------------------------------------------------------------------- /.github/sync-repo-settings.yaml: -------------------------------------------------------------------------------- 1 | branchProtectionRules: 2 | - pattern: main 3 | isAdminEnforced: true 4 | requiredApprovingReviewCount: 1 5 | requiresCodeOwnerReviews: true 6 | requiresStrictStatusChecks: true 7 | requiredStatusCheckContexts: 8 | - "ci/kokoro: Samples test" 9 | - "ci/kokoro: System test" 10 | - lint 11 | - test (18) 12 | - test (20) 13 | - test (22) 14 | - cla/google 15 | - windows 16 | - OwlBot Post Processor 17 | permissionRules: 18 | - team: yoshi-admins 19 | permission: admin 20 | - team: jsteam-admins 21 | permission: admin 22 | - team: jsteam 23 | permission: push 24 | -------------------------------------------------------------------------------- /.github/workflows/ci.yaml: -------------------------------------------------------------------------------- 1 | on: 2 | push: 3 | branches: 4 | - main 5 | pull_request: 6 | name: ci 7 | jobs: 8 | test: 9 | runs-on: ubuntu-latest 10 | strategy: 11 | matrix: 12 | node: [18, 20, 22] 13 | steps: 14 | - uses: actions/checkout@v4 15 | - uses: actions/setup-node@v4 16 | with: 17 | node-version: ${{ matrix.node }} 18 | - run: node --version 19 | # The first installation step ensures that all of our production 20 | # dependencies work on the given Node.js version, this helps us find 21 | # dependencies that don't match our engines field: 22 | - run: npm install --production --engine-strict --ignore-scripts --no-package-lock 23 | # Clean up the production install, before installing dev/production: 24 | - run: rm -rf node_modules 25 | - run: npm install --engine-strict 26 | - run: npm test 27 | env: 28 | MOCHA_THROW_DEPRECATION: false 29 | test-script: 30 | runs-on: ubuntu-latest 31 | steps: 32 | - uses: actions/checkout@v4 33 | - uses: actions/setup-node@v4 34 | with: 35 | node-version: 18 36 | - run: node --version 37 | - run: npm install --engine-strict 38 | working-directory: .github/scripts 39 | - run: npm test 40 | working-directory: .github/scripts 41 | env: 42 | MOCHA_THROW_DEPRECATION: false 43 | windows: 44 | runs-on: windows-latest 45 | steps: 46 | - uses: actions/checkout@v4 47 | - uses: actions/setup-node@v4 48 | with: 49 | node-version: 18 50 | - run: npm install --engine-strict 51 | - run: npm test 52 | env: 53 | MOCHA_THROW_DEPRECATION: false 54 | lint: 55 | runs-on: ubuntu-latest 56 | steps: 57 | - uses: actions/checkout@v4 58 | - uses: actions/setup-node@v4 59 | with: 60 | node-version: 18 61 | - run: npm install 62 | - run: npm run lint 63 | docs: 64 | runs-on: ubuntu-latest 65 | steps: 66 | - uses: actions/checkout@v4 67 | - uses: actions/setup-node@v4 68 | with: 69 | node-version: 18 70 | - run: npm install 71 | - run: npm run docs 72 | - uses: JustinBeckwith/linkinator-action@v1 73 | with: 74 | paths: docs/ 75 | -------------------------------------------------------------------------------- /.github/workflows/issues-no-repro.yaml: -------------------------------------------------------------------------------- 1 | name: invalid_link 2 | on: 3 | issues: 4 | types: [opened, reopened] 5 | 6 | jobs: 7 | close: 8 | runs-on: ubuntu-latest 9 | permissions: 10 | issues: write 11 | pull-requests: write 12 | steps: 13 | - uses: actions/checkout@v4 14 | - uses: actions/setup-node@v3 15 | with: 16 | node-version: 18 17 | - run: npm install 18 | working-directory: ./.github/scripts 19 | - uses: actions/github-script@v7 20 | with: 21 | script: | 22 | const script = require('./.github/scripts/close-invalid-link.cjs') 23 | await script({github, context}) 24 | -------------------------------------------------------------------------------- /.github/workflows/response.yaml: -------------------------------------------------------------------------------- 1 | name: no_response 2 | on: 3 | schedule: 4 | - cron: '30 1 * * *' # Run every day at 01:30 5 | workflow_dispatch: 6 | issue_comment: 7 | 8 | jobs: 9 | close: 10 | if: github.event_name == 'schedule' || github.event_name == 'workflow_dispatch' 11 | runs-on: ubuntu-latest 12 | permissions: 13 | issues: write 14 | pull-requests: write 15 | steps: 16 | - uses: actions/checkout@v4 17 | - uses: actions/github-script@v7 18 | with: 19 | script: | 20 | const script = require('./.github/scripts/close-unresponsive.cjs') 21 | await script({github, context}) 22 | 23 | remove_label: 24 | if: github.event_name == 'issue_comment' 25 | runs-on: ubuntu-latest 26 | permissions: 27 | issues: write 28 | pull-requests: write 29 | steps: 30 | - uses: actions/checkout@v4 31 | - uses: actions/github-script@v7 32 | with: 33 | script: | 34 | const script = require('./.github/scripts/remove-response-label.cjs') 35 | await script({github, context}) 36 | -------------------------------------------------------------------------------- /.github/workflows/system-tests-against-emulator.yaml: -------------------------------------------------------------------------------- 1 | on: 2 | push: 3 | branches: 4 | - main 5 | pull_request: 6 | name: system-tests-against-emulator 7 | jobs: 8 | test: 9 | runs-on: ubuntu-latest 10 | 11 | services: 12 | emulator: 13 | image: gcr.io/cloud-spanner-emulator/emulator:latest 14 | ports: 15 | - 9010:9010 16 | - 9020:9020 17 | 18 | steps: 19 | - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4 20 | - uses: actions/setup-node@v4 21 | with: 22 | node-version: 18 23 | - run: node --version 24 | - run: npm install 25 | - run: npm run system-test 26 | env: 27 | SPANNER_EMULATOR_HOST: localhost:9010 28 | GCLOUD_PROJECT: emulator-test-project 29 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | **/*.log 2 | **/node_modules 3 | /.coverage 4 | /coverage 5 | /.nyc_output 6 | /docs/ 7 | /out/ 8 | /build/ 9 | system-test/secrets.js 10 | system-test/*key.json 11 | *.lock 12 | .DS_Store 13 | package-lock.json 14 | __pycache__ 15 | -------------------------------------------------------------------------------- /.jsdoc.js: -------------------------------------------------------------------------------- 1 | // Copyright 2025 Google LLC 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // https://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | // 15 | // ** This file is automatically generated by gapic-generator-typescript. ** 16 | // ** https://github.com/googleapis/gapic-generator-typescript ** 17 | // ** All changes to this file may be overwritten. ** 18 | 19 | 'use strict'; 20 | 21 | module.exports = { 22 | opts: { 23 | readme: './README.md', 24 | package: './package.json', 25 | template: './node_modules/jsdoc-fresh', 26 | recurse: true, 27 | verbose: true, 28 | destination: './docs/' 29 | }, 30 | plugins: [ 31 | 'plugins/markdown', 32 | 'jsdoc-region-tag' 33 | ], 34 | source: { 35 | excludePattern: '(^|\\/|\\\\)[._]', 36 | include: [ 37 | 'build/src', 38 | 'protos' 39 | ], 40 | includePattern: '\\.js$' 41 | }, 42 | templates: { 43 | copyright: 'Copyright 2025 Google LLC', 44 | includeDate: false, 45 | sourceFiles: false, 46 | systemName: '@google-cloud/spanner', 47 | theme: 'lumen', 48 | default: { 49 | outputSourceFiles: false 50 | } 51 | }, 52 | markdown: { 53 | idInHeadings: true 54 | } 55 | }; 56 | -------------------------------------------------------------------------------- /.kokoro/.gitattributes: -------------------------------------------------------------------------------- 1 | * linguist-generated=true 2 | -------------------------------------------------------------------------------- /.kokoro/cleanup.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Copyright 2018 Google LLC 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # https://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | 17 | set -eo pipefail 18 | 19 | export NPM_CONFIG_PREFIX=/home/node/.npm-global 20 | 21 | # Setup service account credentials. 22 | export GOOGLE_APPLICATION_CREDENTIALS=${KOKORO_GFILE_DIR}/spanner-key.json 23 | export GCLOUD_PROJECT=long-door-651 24 | 25 | cd $(dirname $0)/.. 26 | 27 | npm install 28 | 29 | npm run cleanup 30 | -------------------------------------------------------------------------------- /.kokoro/common.cfg: -------------------------------------------------------------------------------- 1 | # Format: //devtools/kokoro/config/proto/build.proto 2 | 3 | # Build logs will be here 4 | action { 5 | define_artifacts { 6 | regex: "**/*sponge_log.xml" 7 | } 8 | } 9 | 10 | # Download trampoline resources. 11 | gfile_resources: "/bigstore/cloud-devrel-kokoro-resources/trampoline" 12 | 13 | # Use the trampoline script to run in docker. 14 | build_file: "nodejs-spanner/.kokoro/trampoline_v2.sh" 15 | 16 | # Configure the docker image for kokoro-trampoline. 17 | env_vars: { 18 | key: "TRAMPOLINE_IMAGE" 19 | value: "gcr.io/cloud-devrel-kokoro-resources/node:18-user" 20 | } 21 | env_vars: { 22 | key: "TRAMPOLINE_BUILD_FILE" 23 | value: "github/nodejs-spanner/.kokoro/test.sh" 24 | } 25 | -------------------------------------------------------------------------------- /.kokoro/continuous/node18/common.cfg: -------------------------------------------------------------------------------- 1 | # Format: //devtools/kokoro/config/proto/build.proto 2 | 3 | # Build logs will be here 4 | action { 5 | define_artifacts { 6 | regex: "**/*sponge_log.xml" 7 | } 8 | } 9 | 10 | # Download trampoline resources. 11 | gfile_resources: "/bigstore/cloud-devrel-kokoro-resources/trampoline" 12 | 13 | # Use the trampoline script to run in docker. 14 | build_file: "nodejs-spanner/.kokoro/trampoline_v2.sh" 15 | 16 | # Configure the docker image for kokoro-trampoline. 17 | env_vars: { 18 | key: "TRAMPOLINE_IMAGE" 19 | value: "gcr.io/cloud-devrel-kokoro-resources/node:18-user" 20 | } 21 | env_vars: { 22 | key: "TRAMPOLINE_BUILD_FILE" 23 | value: "github/nodejs-spanner/.kokoro/test.sh" 24 | } 25 | -------------------------------------------------------------------------------- /.kokoro/continuous/node18/lint.cfg: -------------------------------------------------------------------------------- 1 | env_vars: { 2 | key: "TRAMPOLINE_BUILD_FILE" 3 | value: "github/nodejs-spanner/.kokoro/lint.sh" 4 | } 5 | -------------------------------------------------------------------------------- /.kokoro/continuous/node18/samples-test.cfg: -------------------------------------------------------------------------------- 1 | # Download resources for system tests (service account key, etc.) 2 | gfile_resources: "/bigstore/cloud-devrel-kokoro-resources/google-cloud-nodejs" 3 | 4 | env_vars: { 5 | key: "TRAMPOLINE_BUILD_FILE" 6 | value: "github/nodejs-spanner/.kokoro/samples-test.sh" 7 | } 8 | 9 | env_vars: { 10 | key: "SECRET_MANAGER_KEYS" 11 | value: "long-door-651-kokoro-system-test-service-account" 12 | } -------------------------------------------------------------------------------- /.kokoro/continuous/node18/system-test.cfg: -------------------------------------------------------------------------------- 1 | # Download resources for system tests (service account key, etc.) 2 | gfile_resources: "/bigstore/cloud-devrel-kokoro-resources/google-cloud-nodejs" 3 | 4 | env_vars: { 5 | key: "TRAMPOLINE_BUILD_FILE" 6 | value: "github/nodejs-spanner/.kokoro/system-test.sh" 7 | } 8 | 9 | env_vars: { 10 | key: "SECRET_MANAGER_KEYS" 11 | value: "long-door-651-kokoro-system-test-service-account" 12 | } -------------------------------------------------------------------------------- /.kokoro/continuous/node18/test.cfg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/googleapis/nodejs-spanner/57d67be2e3b6d6ac2a8a903acf8613b27a049c3b/.kokoro/continuous/node18/test.cfg -------------------------------------------------------------------------------- /.kokoro/docs.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Copyright 2018 Google LLC 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # https://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | 17 | set -eo pipefail 18 | 19 | export NPM_CONFIG_PREFIX=${HOME}/.npm-global 20 | 21 | cd $(dirname $0)/.. 22 | 23 | npm install 24 | 25 | npm run docs-test 26 | -------------------------------------------------------------------------------- /.kokoro/lint.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Copyright 2018 Google LLC 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # https://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | 17 | set -eo pipefail 18 | 19 | export NPM_CONFIG_PREFIX=${HOME}/.npm-global 20 | 21 | cd $(dirname $0)/.. 22 | 23 | npm install 24 | 25 | # Install and link samples 26 | if [ -f samples/package.json ]; then 27 | cd samples/ 28 | npm link ../ 29 | npm install 30 | cd .. 31 | fi 32 | 33 | npm run lint 34 | -------------------------------------------------------------------------------- /.kokoro/presubmit/node18/common.cfg: -------------------------------------------------------------------------------- 1 | # Format: //devtools/kokoro/config/proto/build.proto 2 | 3 | # Build logs will be here 4 | action { 5 | define_artifacts { 6 | regex: "**/*sponge_log.xml" 7 | } 8 | } 9 | 10 | # Download trampoline resources. 11 | gfile_resources: "/bigstore/cloud-devrel-kokoro-resources/trampoline" 12 | 13 | # Use the trampoline script to run in docker. 14 | build_file: "nodejs-spanner/.kokoro/trampoline_v2.sh" 15 | 16 | # Configure the docker image for kokoro-trampoline. 17 | env_vars: { 18 | key: "TRAMPOLINE_IMAGE" 19 | value: "gcr.io/cloud-devrel-kokoro-resources/node:18-user" 20 | } 21 | env_vars: { 22 | key: "TRAMPOLINE_BUILD_FILE" 23 | value: "github/nodejs-spanner/.kokoro/test.sh" 24 | } 25 | -------------------------------------------------------------------------------- /.kokoro/presubmit/node18/samples-test.cfg: -------------------------------------------------------------------------------- 1 | # Download resources for system tests (service account key, etc.) 2 | gfile_resources: "/bigstore/cloud-devrel-kokoro-resources/google-cloud-nodejs" 3 | 4 | env_vars: { 5 | key: "TRAMPOLINE_BUILD_FILE" 6 | value: "github/nodejs-spanner/.kokoro/samples-test.sh" 7 | } 8 | 9 | env_vars: { 10 | key: "SECRET_MANAGER_KEYS" 11 | value: "long-door-651-kokoro-system-test-service-account" 12 | } -------------------------------------------------------------------------------- /.kokoro/presubmit/node18/system-test-multiplexed-session.cfg: -------------------------------------------------------------------------------- 1 | # Download resources(service account key, etc.) for system tests when multiplexed session is enabled 2 | gfile_resources: "/bigstore/cloud-devrel-kokoro-resources/google-cloud-nodejs" 3 | 4 | env_vars: { 5 | key: "TRAMPOLINE_BUILD_FILE" 6 | value: "github/nodejs-spanner/.kokoro/system-test.sh" 7 | } 8 | 9 | env_vars: { 10 | key: "SECRET_MANAGER_KEYS" 11 | value: "long-door-651-kokoro-system-test-service-account" 12 | } 13 | 14 | env_vars: { 15 | key: "GOOGLE_CLOUD_SPANNER_MULTIPLEXED_SESSIONS" 16 | value: "true" 17 | } 18 | 19 | env_vars: { 20 | key: "GOOGLE_CLOUD_SPANNER_MULTIPLEXED_SESSIONS_PARTITIONED_OPS" 21 | value: "true" 22 | } -------------------------------------------------------------------------------- /.kokoro/presubmit/node18/system-test.cfg: -------------------------------------------------------------------------------- 1 | # Download resources for system tests (service account key, etc.) 2 | gfile_resources: "/bigstore/cloud-devrel-kokoro-resources/google-cloud-nodejs" 3 | 4 | env_vars: { 5 | key: "TRAMPOLINE_BUILD_FILE" 6 | value: "github/nodejs-spanner/.kokoro/system-test.sh" 7 | } 8 | 9 | env_vars: { 10 | key: "SECRET_MANAGER_KEYS" 11 | value: "long-door-651-kokoro-system-test-service-account" 12 | } -------------------------------------------------------------------------------- /.kokoro/presubmit/node18/test.cfg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/googleapis/nodejs-spanner/57d67be2e3b6d6ac2a8a903acf8613b27a049c3b/.kokoro/presubmit/node18/test.cfg -------------------------------------------------------------------------------- /.kokoro/presubmit/windows/common.cfg: -------------------------------------------------------------------------------- 1 | # Format: //devtools/kokoro/config/proto/build.proto 2 | 3 | -------------------------------------------------------------------------------- /.kokoro/presubmit/windows/test.cfg: -------------------------------------------------------------------------------- 1 | # Use the test file directly 2 | build_file: "nodejs-spanner/.kokoro/test.bat" 3 | -------------------------------------------------------------------------------- /.kokoro/publish.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Copyright 2018 Google LLC 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # https://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | 17 | set -eo pipefail 18 | 19 | export NPM_CONFIG_PREFIX=${HOME}/.npm-global 20 | 21 | # Start the releasetool reporter 22 | python3 -m releasetool publish-reporter-script > /tmp/publisher-script; source /tmp/publisher-script 23 | 24 | cd $(dirname $0)/.. 25 | 26 | NPM_TOKEN=$(cat $KOKORO_KEYSTORE_DIR/73713_google-cloud-npm-token-1) 27 | echo "//wombat-dressing-room.appspot.com/:_authToken=${NPM_TOKEN}" > ~/.npmrc 28 | 29 | npm install 30 | npm pack . 31 | # npm provides no way to specify, observe, or predict the name of the tarball 32 | # file it generates. We have to look in the current directory for the freshest 33 | # .tgz file. 34 | TARBALL=$(ls -1 -t *.tgz | head -1) 35 | 36 | npm publish --access=public --registry=https://wombat-dressing-room.appspot.com "$TARBALL" 37 | 38 | # Kokoro collects *.tgz and package-lock.json files and stores them in Placer 39 | # so we can generate SBOMs and attestations. 40 | # However, we *don't* want Kokoro to collect package-lock.json and *.tgz files 41 | # that happened to be installed with dependencies. 42 | find node_modules -name package-lock.json -o -name "*.tgz" | xargs rm -f -------------------------------------------------------------------------------- /.kokoro/release/cleanup.cfg: -------------------------------------------------------------------------------- 1 | # Format: //devtools/kokoro/config/proto/build.proto 2 | 3 | # Build logs will be here 4 | action { 5 | define_artifacts { 6 | regex: "**/*sponge_log.xml" 7 | } 8 | } 9 | 10 | # Download trampoline resources. 11 | gfile_resources: "/bigstore/cloud-devrel-kokoro-resources/trampoline" 12 | 13 | # Download resources for system tests (service account key, etc.) 14 | gfile_resources: "/bigstore/cloud-devrel-kokoro-resources/google-cloud-nodejs" 15 | 16 | # Use the trampoline script to run in docker. 17 | build_file: "nodejs-spanner/.kokoro/trampoline.sh" 18 | 19 | # Configure the docker image for kokoro-trampoline. 20 | env_vars: { 21 | key: "TRAMPOLINE_IMAGE" 22 | value: "gcr.io/cloud-devrel-kokoro-resources/node:8-user" 23 | } 24 | env_vars: { 25 | key: "TRAMPOLINE_BUILD_FILE" 26 | value: "github/nodejs-spanner/.kokoro/cleanup.sh" 27 | } 28 | -------------------------------------------------------------------------------- /.kokoro/release/common.cfg: -------------------------------------------------------------------------------- 1 | before_action { 2 | fetch_keystore { 3 | keystore_resource { 4 | keystore_config_id: 73713 5 | keyname: "yoshi-automation-github-key" 6 | } 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /.kokoro/release/docs-devsite.cfg: -------------------------------------------------------------------------------- 1 | # service account used to publish up-to-date docs. 2 | before_action { 3 | fetch_keystore { 4 | keystore_resource { 5 | keystore_config_id: 73713 6 | keyname: "docuploader_service_account" 7 | } 8 | } 9 | } 10 | 11 | # doc publications use a Python image. 12 | env_vars: { 13 | key: "TRAMPOLINE_IMAGE" 14 | value: "gcr.io/cloud-devrel-kokoro-resources/node:18-user" 15 | } 16 | 17 | # Download trampoline resources. 18 | gfile_resources: "/bigstore/cloud-devrel-kokoro-resources/trampoline" 19 | 20 | # Use the trampoline script to run in docker. 21 | build_file: "nodejs-spanner/.kokoro/trampoline_v2.sh" 22 | 23 | env_vars: { 24 | key: "TRAMPOLINE_BUILD_FILE" 25 | value: "github/nodejs-spanner/.kokoro/release/docs-devsite.sh" 26 | } 27 | -------------------------------------------------------------------------------- /.kokoro/release/docs-devsite.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Copyright 2021 Google LLC 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # https://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | 17 | set -eo pipefail 18 | 19 | if [[ -z "$CREDENTIALS" ]]; then 20 | # if CREDENTIALS are explicitly set, assume we're testing locally 21 | # and don't set NPM_CONFIG_PREFIX. 22 | export NPM_CONFIG_PREFIX=${HOME}/.npm-global 23 | export PATH="$PATH:${NPM_CONFIG_PREFIX}/bin" 24 | cd $(dirname $0)/../.. 25 | fi 26 | 27 | npm install 28 | npm install --no-save @google-cloud/cloud-rad@^0.4.0 29 | # publish docs to devsite 30 | npx @google-cloud/cloud-rad . cloud-rad 31 | -------------------------------------------------------------------------------- /.kokoro/release/docs.cfg: -------------------------------------------------------------------------------- 1 | # service account used to publish up-to-date docs. 2 | before_action { 3 | fetch_keystore { 4 | keystore_resource { 5 | keystore_config_id: 73713 6 | keyname: "docuploader_service_account" 7 | } 8 | } 9 | } 10 | 11 | # doc publications use a Python image. 12 | env_vars: { 13 | key: "TRAMPOLINE_IMAGE" 14 | value: "gcr.io/cloud-devrel-kokoro-resources/node:18-user" 15 | } 16 | 17 | # Download trampoline resources. 18 | gfile_resources: "/bigstore/cloud-devrel-kokoro-resources/trampoline" 19 | 20 | # Use the trampoline script to run in docker. 21 | build_file: "nodejs-spanner/.kokoro/trampoline_v2.sh" 22 | 23 | env_vars: { 24 | key: "TRAMPOLINE_BUILD_FILE" 25 | value: "github/nodejs-spanner/.kokoro/release/docs.sh" 26 | } 27 | -------------------------------------------------------------------------------- /.kokoro/release/docs.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Copyright 2019 Google LLC 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # https://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | 17 | set -eo pipefail 18 | 19 | # build jsdocs (Python is installed on the Node 18 docker image). 20 | if [[ -z "$CREDENTIALS" ]]; then 21 | # if CREDENTIALS are explicitly set, assume we're testing locally 22 | # and don't set NPM_CONFIG_PREFIX. 23 | export NPM_CONFIG_PREFIX=${HOME}/.npm-global 24 | export PATH="$PATH:${NPM_CONFIG_PREFIX}/bin" 25 | cd $(dirname $0)/../.. 26 | fi 27 | npm install 28 | npm run docs 29 | 30 | # create docs.metadata, based on package.json and .repo-metadata.json. 31 | npm i json@9.0.6 -g 32 | python3 -m docuploader create-metadata \ 33 | --name=$(cat .repo-metadata.json | json name) \ 34 | --version=$(cat package.json | json version) \ 35 | --language=$(cat .repo-metadata.json | json language) \ 36 | --distribution-name=$(cat .repo-metadata.json | json distribution_name) \ 37 | --product-page=$(cat .repo-metadata.json | json product_documentation) \ 38 | --github-repository=$(cat .repo-metadata.json | json repo) \ 39 | --issue-tracker=$(cat .repo-metadata.json | json issue_tracker) 40 | cp docs.metadata ./docs/docs.metadata 41 | 42 | # deploy the docs. 43 | if [[ -z "$CREDENTIALS" ]]; then 44 | CREDENTIALS=${KOKORO_KEYSTORE_DIR}/73713_docuploader_service_account 45 | fi 46 | if [[ -z "$BUCKET" ]]; then 47 | BUCKET=docs-staging 48 | fi 49 | python3 -m docuploader upload ./docs --credentials $CREDENTIALS --staging-bucket $BUCKET 50 | -------------------------------------------------------------------------------- /.kokoro/release/publish.cfg: -------------------------------------------------------------------------------- 1 | before_action { 2 | fetch_keystore { 3 | keystore_resource { 4 | keystore_config_id: 73713 5 | keyname: "docuploader_service_account" 6 | } 7 | } 8 | } 9 | 10 | before_action { 11 | fetch_keystore { 12 | keystore_resource { 13 | keystore_config_id: 73713 14 | keyname: "google-cloud-npm-token-1" 15 | } 16 | } 17 | } 18 | 19 | env_vars: { 20 | key: "SECRET_MANAGER_KEYS" 21 | value: "releasetool-publish-reporter-app,releasetool-publish-reporter-googleapis-installation,releasetool-publish-reporter-pem" 22 | } 23 | 24 | # Download trampoline resources. 25 | gfile_resources: "/bigstore/cloud-devrel-kokoro-resources/trampoline" 26 | 27 | # Use the trampoline script to run in docker. 28 | build_file: "nodejs-spanner/.kokoro/trampoline_v2.sh" 29 | 30 | # Configure the docker image for kokoro-trampoline. 31 | env_vars: { 32 | key: "TRAMPOLINE_IMAGE" 33 | value: "gcr.io/cloud-devrel-kokoro-resources/node:18-user" 34 | } 35 | 36 | env_vars: { 37 | key: "TRAMPOLINE_BUILD_FILE" 38 | value: "github/nodejs-spanner/.kokoro/publish.sh" 39 | } 40 | 41 | # Store the packages we uploaded to npmjs.org and their corresponding 42 | # package-lock.jsons in Placer. That way, we have a record of exactly 43 | # what we published, and which version of which tools we used to publish 44 | # it, which we can use to generate SBOMs and attestations. 45 | action { 46 | define_artifacts { 47 | regex: "github/**/*.tgz" 48 | regex: "github/**/package-lock.json" 49 | strip_prefix: "github" 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /.kokoro/system-test.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Copyright 2018 Google LLC 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # https://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | 17 | set -eo pipefail 18 | 19 | export NPM_CONFIG_PREFIX=${HOME}/.npm-global 20 | 21 | # Setup service account credentials. 22 | export GOOGLE_APPLICATION_CREDENTIALS=${KOKORO_GFILE_DIR}/secret_manager/long-door-651-kokoro-system-test-service-account 23 | export GCLOUD_PROJECT=long-door-651 24 | 25 | cd $(dirname $0)/.. 26 | 27 | # Run a pre-test hook, if a pre-system-test.sh is in the project 28 | if [ -f .kokoro/pre-system-test.sh ]; then 29 | set +x 30 | . .kokoro/pre-system-test.sh 31 | set -x 32 | fi 33 | 34 | npm install 35 | 36 | # If tests are running against main branch, configure flakybot 37 | # to open issues on failures: 38 | if [[ $KOKORO_BUILD_ARTIFACTS_SUBDIR = *"continuous"* ]] || [[ $KOKORO_BUILD_ARTIFACTS_SUBDIR = *"nightly"* ]]; then 39 | export MOCHA_REPORTER_OUTPUT=test_output_sponge_log.xml 40 | export MOCHA_REPORTER=xunit 41 | cleanup() { 42 | chmod +x $KOKORO_GFILE_DIR/linux_amd64/flakybot 43 | $KOKORO_GFILE_DIR/linux_amd64/flakybot 44 | } 45 | trap cleanup EXIT HUP 46 | fi 47 | 48 | npm run system-test 49 | 50 | # codecov combines coverage across integration and unit tests. Include 51 | # the logic below for any environment you wish to collect coverage for: 52 | COVERAGE_NODE=18 53 | if npx check-node-version@3.3.0 --silent --node $COVERAGE_NODE; then 54 | NYC_BIN=./node_modules/nyc/bin/nyc.js 55 | if [ -f "$NYC_BIN" ]; then 56 | $NYC_BIN report || true 57 | fi 58 | bash $KOKORO_GFILE_DIR/codecov.sh 59 | else 60 | echo "coverage is only reported for Node $COVERAGE_NODE" 61 | fi 62 | -------------------------------------------------------------------------------- /.kokoro/test.bat: -------------------------------------------------------------------------------- 1 | @rem Copyright 2018 Google LLC. All rights reserved. 2 | @rem 3 | @rem Licensed under the Apache License, Version 2.0 (the "License"); 4 | @rem you may not use this file except in compliance with the License. 5 | @rem You may obtain a copy of the License at 6 | @rem 7 | @rem http://www.apache.org/licenses/LICENSE-2.0 8 | @rem 9 | @rem Unless required by applicable law or agreed to in writing, software 10 | @rem distributed under the License is distributed on an "AS IS" BASIS, 11 | @rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | @rem See the License for the specific language governing permissions and 13 | @rem limitations under the License. 14 | 15 | @echo "Starting Windows build" 16 | 17 | cd /d %~dp0 18 | cd .. 19 | 20 | @rem npm path is not currently set in our image, we should fix this next time 21 | @rem we upgrade Node.js in the image: 22 | SET PATH=%PATH%;/cygdrive/c/Program Files/nodejs/npm 23 | 24 | call nvm use 18 25 | call which node 26 | 27 | call npm install || goto :error 28 | call npm run test || goto :error 29 | 30 | goto :EOF 31 | 32 | :error 33 | exit /b 1 34 | -------------------------------------------------------------------------------- /.kokoro/test.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Copyright 2018 Google LLC 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # https://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | 17 | set -eo pipefail 18 | 19 | export NPM_CONFIG_PREFIX=${HOME}/.npm-global 20 | 21 | cd $(dirname $0)/.. 22 | 23 | npm install 24 | # If tests are running against main branch, configure flakybot 25 | # to open issues on failures: 26 | if [[ $KOKORO_BUILD_ARTIFACTS_SUBDIR = *"continuous"* ]] || [[ $KOKORO_BUILD_ARTIFACTS_SUBDIR = *"nightly"* ]]; then 27 | export MOCHA_REPORTER_OUTPUT=test_output_sponge_log.xml 28 | export MOCHA_REPORTER=xunit 29 | cleanup() { 30 | chmod +x $KOKORO_GFILE_DIR/linux_amd64/flakybot 31 | $KOKORO_GFILE_DIR/linux_amd64/flakybot 32 | } 33 | trap cleanup EXIT HUP 34 | fi 35 | # Unit tests exercise the entire API surface, which may include 36 | # deprecation warnings: 37 | export MOCHA_THROW_DEPRECATION=false 38 | npm test 39 | 40 | # codecov combines coverage across integration and unit tests. Include 41 | # the logic below for any environment you wish to collect coverage for: 42 | COVERAGE_NODE=18 43 | if npx check-node-version@3.3.0 --silent --node $COVERAGE_NODE; then 44 | NYC_BIN=./node_modules/nyc/bin/nyc.js 45 | if [ -f "$NYC_BIN" ]; then 46 | $NYC_BIN report || true 47 | fi 48 | bash $KOKORO_GFILE_DIR/codecov.sh 49 | else 50 | echo "coverage is only reported for Node $COVERAGE_NODE" 51 | fi 52 | -------------------------------------------------------------------------------- /.kokoro/trampoline.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # Copyright 2017 Google Inc. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | 16 | # This file is not used any more, but we keep this file for making it 17 | # easy to roll back. 18 | # TODO: Remove this file from the template. 19 | 20 | set -eo pipefail 21 | 22 | # Always run the cleanup script, regardless of the success of bouncing into 23 | # the container. 24 | function cleanup() { 25 | chmod +x ${KOKORO_GFILE_DIR}/trampoline_cleanup.sh 26 | ${KOKORO_GFILE_DIR}/trampoline_cleanup.sh 27 | echo "cleanup"; 28 | } 29 | trap cleanup EXIT 30 | 31 | $(dirname $0)/populate-secrets.sh # Secret Manager secrets. 32 | python3 "${KOKORO_GFILE_DIR}/trampoline_v1.py" 33 | -------------------------------------------------------------------------------- /.mocharc.js: -------------------------------------------------------------------------------- 1 | // Copyright 2020 Google LLC 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | const config = { 15 | "enable-source-maps": true, 16 | "throw-deprecation": true, 17 | "timeout": 10000, 18 | "recursive": true 19 | } 20 | if (process.env.MOCHA_THROW_DEPRECATION === 'false') { 21 | delete config['throw-deprecation']; 22 | } 23 | if (process.env.MOCHA_REPORTER) { 24 | config.reporter = process.env.MOCHA_REPORTER; 25 | } 26 | if (process.env.MOCHA_REPORTER_OUTPUT) { 27 | config['reporter-option'] = `output=${process.env.MOCHA_REPORTER_OUTPUT}`; 28 | } 29 | module.exports = config 30 | -------------------------------------------------------------------------------- /.nycrc: -------------------------------------------------------------------------------- 1 | { 2 | "report-dir": "./.coverage", 3 | "reporter": ["text", "lcov"], 4 | "exclude": [ 5 | "**/*-test", 6 | "**/.coverage", 7 | "**/apis", 8 | "**/benchmark", 9 | "**/conformance", 10 | "**/docs", 11 | "**/samples", 12 | "**/scripts", 13 | "**/protos", 14 | "**/test", 15 | "**/*.d.ts", 16 | ".jsdoc.js", 17 | "**/.jsdoc.js", 18 | "karma.conf.js", 19 | "webpack-tests.config.js", 20 | "webpack.config.js" 21 | ], 22 | "exclude-after-remap": false, 23 | "all": true 24 | } 25 | -------------------------------------------------------------------------------- /.prettierignore: -------------------------------------------------------------------------------- 1 | **/node_modules 2 | **/coverage 3 | test/fixtures 4 | build/ 5 | docs/ 6 | protos/ 7 | -------------------------------------------------------------------------------- /.prettierrc.js: -------------------------------------------------------------------------------- 1 | // Copyright 2020 Google LLC 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // https://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | module.exports = { 16 | ...require('gts/.prettierrc.json') 17 | } 18 | -------------------------------------------------------------------------------- /.readme-partials.yml: -------------------------------------------------------------------------------- 1 | introduction: |- 2 | [Cloud Spanner](https://cloud.google.com/spanner/docs/) is a fully managed, mission-critical, relational database service that 3 | offers transactional consistency at global scale, schemas, SQL (ANSI 2011 with extensions), 4 | and automatic, synchronous replication for high availability. 5 | -------------------------------------------------------------------------------- /.repo-metadata.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "spanner", 3 | "name_pretty": "Cloud Spanner", 4 | "product_documentation": "https://cloud.google.com/spanner/docs/", 5 | "client_documentation": "https://cloud.google.com/nodejs/docs/reference/spanner/latest", 6 | "issue_tracker": "https://issuetracker.google.com/issues?q=componentid:190851%2B%20status:open", 7 | "release_level": "stable", 8 | "language": "nodejs", 9 | "repo": "googleapis/nodejs-spanner", 10 | "distribution_name": "@google-cloud/spanner", 11 | "api_id": "spanner.googleapis.com", 12 | "requires_billing": true, 13 | "codeowner_team": "@googleapis/spanner-client-libraries-nodejs", 14 | "api_shortname": "spanner", 15 | "library_type": "GAPIC_COMBO" 16 | } 17 | -------------------------------------------------------------------------------- /.trampolinerc: -------------------------------------------------------------------------------- 1 | # Copyright 2020 Google LLC 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | # Template for .trampolinerc 16 | 17 | # Add required env vars here. 18 | required_envvars+=( 19 | ) 20 | 21 | # Add env vars which are passed down into the container here. 22 | pass_down_envvars+=( 23 | "AUTORELEASE_PR" 24 | "VERSION" 25 | ) 26 | 27 | # Prevent unintentional override on the default image. 28 | if [[ "${TRAMPOLINE_IMAGE_UPLOAD:-false}" == "true" ]] && \ 29 | [[ -z "${TRAMPOLINE_IMAGE:-}" ]]; then 30 | echo "Please set TRAMPOLINE_IMAGE if you want to upload the Docker image." 31 | exit 1 32 | fi 33 | 34 | # Define the default value if it makes sense. 35 | if [[ -z "${TRAMPOLINE_IMAGE_UPLOAD:-}" ]]; then 36 | TRAMPOLINE_IMAGE_UPLOAD="" 37 | fi 38 | 39 | if [[ -z "${TRAMPOLINE_IMAGE:-}" ]]; then 40 | TRAMPOLINE_IMAGE="" 41 | fi 42 | 43 | if [[ -z "${TRAMPOLINE_DOCKERFILE:-}" ]]; then 44 | TRAMPOLINE_DOCKERFILE="" 45 | fi 46 | 47 | if [[ -z "${TRAMPOLINE_BUILD_FILE:-}" ]]; then 48 | TRAMPOLINE_BUILD_FILE="" 49 | fi 50 | 51 | # Secret Manager secrets. 52 | source ${PROJECT_ROOT}/.kokoro/populate-secrets.sh 53 | -------------------------------------------------------------------------------- /SECURITY.md: -------------------------------------------------------------------------------- 1 | # Security Policy 2 | 3 | To report a security issue, please use [g.co/vulnz](https://g.co/vulnz). 4 | 5 | The Google Security Team will respond within 5 working days of your report on g.co/vulnz. 6 | 7 | We use g.co/vulnz for our intake, and do coordination and disclosure here using GitHub Security Advisory to privately discuss and fix the issue. 8 | -------------------------------------------------------------------------------- /benchmark/.eslintrc.yml: -------------------------------------------------------------------------------- 1 | --- 2 | rules: 3 | no-console: off 4 | -------------------------------------------------------------------------------- /benchmark/README.md: -------------------------------------------------------------------------------- 1 | # YCSB Benchmarks 2 | 3 | Implements [YCSB](https://github.com/brianfrankcooper/YCSB) clients for cloud 4 | Spanner in Node.js. 5 | 6 | Visit [YCSBClientCloudSpanner](https://github.com/haih-g/YCSBClientCloudSpanner) 7 | for more details. 8 | 9 | ## Setup 10 | 11 | First you need to setup a Cloud Spanner instance and database. Then you can use 12 | [YCSB](https://github.com/brianfrankcooper/YCSB) to load the database. Then you 13 | can run the client benchmarks. 14 | 15 | ### Set up the database 16 | 17 | ```sh 18 | $ gcloud spanner instances create ycsb-instance --nodes 1 \ 19 | --config regional-us-central1 --description YCSB 20 | $ gcloud spanner databases create ycsb --instance ycsb-instance 21 | $ gcloud spanner databases ddl update ycsb --instance ycsb-instance \ 22 | --ddl="CREATE TABLE usertable ( 23 | id STRING(MAX), 24 | field0 STRING(MAX), 25 | field1 STRING(MAX), 26 | field2 STRING(MAX), 27 | field3 STRING(MAX), 28 | field4 STRING(MAX), 29 | field5 STRING(MAX), 30 | field6 STRING(MAX), 31 | field7 STRING(MAX), 32 | field8 STRING(MAX), 33 | field9 STRING(MAX), 34 | ) PRIMARY KEY(id)" 35 | ``` 36 | 37 | ### Use YCSB to load data 38 | 39 | You need to set up some environment variables first. You should use your own 40 | gcloud credentials and project. 41 | 42 | ```sh 43 | $ export GOOGLE_APPLICATION_CREDENTIALS=/usr/local/google/home/haih/cloud-spanner-client-benchmark.json 44 | $ export GCLOUD_PROJECT=cloud-spanner-client-benchmark 45 | ``` 46 | 47 | Then download YCSB and load the database. 48 | 49 | ```sh 50 | $ curl https://storage.googleapis.com/cloud-spanner-ycsb-custom-release/ycsb-cloudspanner-binding-0.13.0.tar.gz | tar -xzv 51 | $ ycsb-cloudspanner-binding-0.13.0/bin/ycsb load cloudspanner \ 52 | -P ycsb-cloudspanner-binding-0.13.0/workloads/workloada \ 53 | -p table=usertable -p cloudspanner.instance=ycsb-instance \ 54 | -p recordcount=5000 -p operationcount=100 -p cloudspanner.database=ycsb \ 55 | -threads 32 56 | ``` 57 | 58 | ## Run benchmarks 59 | 60 | ```sh 61 | $ npm run ycsb 62 | ``` 63 | 64 | Or if you want complete control over the parameters. 65 | 66 | ```sh 67 | node benchmarks/ycsb.js run -P benchmarks/workloada -p table=usertable \ 68 | -p cloudspanner.instance=ycsb-542756a4 -p recordcount=5000 \ 69 | -p operationcount=100 -p cloudspanner.database=ycsb -p num_worker=1 70 | ``` 71 | -------------------------------------------------------------------------------- /benchmark/bin/ycsb: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Copyright 2018 Google LLC 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | 16 | # A YCSB-like executable that can be integrated into PerfKitBenchmarker. 17 | # 18 | # It is intended to be run in a VM that is brought up by PerfKitBenchmarker 19 | # with node.js, npm, and google-cloud for nodejs installed. The environment can 20 | # be configured as follows: 21 | # 22 | # curl -o- https://raw.githubusercontent.com/creationix/nvm/v0.33.8/install.sh \ 23 | # | bash 24 | # export NVM_DIR="$HOME/.nvm" 25 | # [ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh" 26 | # nvm install stable' 27 | # nvm alias default stable') 28 | # npm install --save express @google-cloud/storage @google-cloud/common-grpc \ 29 | # binary-search-bounds dedent fs path stats-lite yargs checkpoint-stream 30 | # lodash.chunk merge-stream google-gax lodash.flatten delay p-queue \ 31 | # stack-trace lodash.snakecase lodash.random time-span 32 | # sudo sudo apt-get -y install git 33 | # git clone https://github.com/googleapis/nodejs-spanner.git 34 | 35 | export NVM_DIR="$HOME/.nvm" 36 | [ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh" 37 | 38 | DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" 39 | 40 | ln -s ${HOME}/nodejs-spanner/src ${DIR}/../../src 41 | ln -s ${HOME}/node_modules ${DIR}/../node_modules 42 | 43 | node ${DIR}/../ycsb.js run "${@:4}" 44 | -------------------------------------------------------------------------------- /benchmark/workloada: -------------------------------------------------------------------------------- 1 | readproportion=0.95 2 | updateproportion=0.05 3 | scanproportion=0 4 | insertproportion=0 5 | -------------------------------------------------------------------------------- /benchmark/workloadb: -------------------------------------------------------------------------------- 1 | readproportion=0.5 2 | updateproportion=0.5 3 | scanproportion=0 4 | insertproportion=0 5 | -------------------------------------------------------------------------------- /bin/README.md: -------------------------------------------------------------------------------- 1 | # benchwrapper 2 | 3 | benchwrapper is a lightweight gRPC server that wraps the Spanner library for 4 | benchmarking purposes. 5 | 6 | ## Running 7 | 8 | ``` 9 | cd nodejs-spanner 10 | npm install 11 | export SPANNER_EMULATOR_HOST=localhost:8080 12 | npm run benchwrapper -- --port 8081 13 | ``` -------------------------------------------------------------------------------- /bin/benchwrapper_test_client.js: -------------------------------------------------------------------------------- 1 | // Copyright 2019 Google LLC 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | // This is a simple test client for the Spanner benchwrapper. 16 | 17 | const {grpc} = require('google-gax'); 18 | const protoLoader = require('@grpc/proto-loader'); 19 | 20 | const argv = require('yargs') 21 | .option('port', { 22 | description: 'The port that the benchwrapper client should connect to.', 23 | type: 'number', 24 | demand: true, 25 | }) 26 | .parse(); 27 | 28 | const PROTO_PATH = __dirname + '/spanner.proto'; 29 | const packageDefinition = protoLoader.loadSync(PROTO_PATH, { 30 | keepCase: true, 31 | longs: String, 32 | enums: String, 33 | defaults: true, 34 | oneofs: true, 35 | }); 36 | const protoDescriptor = grpc.loadPackageDefinition(packageDefinition); 37 | const spannerBenchWrapper = protoDescriptor.spanner_bench; 38 | 39 | console.log(`connecting to localhost:${argv.port}`); 40 | const client = new spannerBenchWrapper.SpannerBenchWrapper( 41 | `localhost:${argv.port}`, 42 | grpc.credentials.createInsecure(), 43 | ); 44 | const readReq = { 45 | Query: 'SELECT 1 AS COL1 UNION ALL SELECT 2 AS COL1', 46 | }; 47 | const insertReq = { 48 | singers: [ 49 | {id: '1', firstName: 'Lana', lastName: 'Del Rey'}, 50 | {id: '2', firstName: 'Taylor', lastName: 'Swift'}, 51 | ], 52 | }; 53 | const updateReq = { 54 | Queries: [ 55 | 'UPDATE sometable SET foo=1 WHERE bar=2', 56 | 'UPDATE sometable SET foo=2 WHERE bar=1', 57 | ], 58 | }; 59 | client.read(readReq, (err, result) => { 60 | callback('read', err, result); 61 | }); 62 | client.insert(insertReq, (err, result) => { 63 | callback('insert', err, result); 64 | }); 65 | client.update(updateReq, (err, result) => { 66 | callback('update', err, result); 67 | }); 68 | 69 | function callback(method, err, result) { 70 | if (err) { 71 | console.log(`${method} failed with error ${err}`); 72 | return; 73 | } 74 | console.log(`${method} executed with result ${result}`); 75 | } 76 | -------------------------------------------------------------------------------- /bin/spanner.proto: -------------------------------------------------------------------------------- 1 | // Copyright 2019 Google LLC 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | syntax = "proto3"; 16 | 17 | package spanner_bench; 18 | option java_multiple_files = true; 19 | option java_package = "com.google.cloud.benchwrapper"; 20 | 21 | message Singer { 22 | int64 id = 1; 23 | string first_name = 2; 24 | string last_name = 3; 25 | string singer_info = 4; 26 | } 27 | 28 | message Album { 29 | int64 id = 1; 30 | int64 singer_id = 2; 31 | string album_title = 3; 32 | } 33 | 34 | message ReadQuery { 35 | // The query to use in the read call. 36 | string query = 1; 37 | } 38 | 39 | message InsertQuery { 40 | // The query to use in the insert call. 41 | repeated Singer singers = 1; 42 | repeated Album albums = 2; 43 | } 44 | 45 | message UpdateQuery { 46 | // The queries to use in the update call. 47 | repeated string queries = 1; 48 | } 49 | 50 | message EmptyResponse {} 51 | 52 | service SpannerBenchWrapper { 53 | // Read represents operations like Go's ReadOnlyTransaction.Query, Java's 54 | // ReadOnlyTransaction.executeQuery, Python's snapshot.read, and Node's 55 | // Transaction.Read. 56 | // 57 | // It will typically be used to read many items. 58 | rpc Read(ReadQuery) returns (EmptyResponse) {} 59 | 60 | // Insert represents operations like Go's Client.Apply, Java's 61 | // DatabaseClient.writeAtLeastOnce, Python's transaction.commit, and Node's 62 | // Transaction.Commit. 63 | // 64 | // It will typically be used to insert many items. 65 | rpc Insert(InsertQuery) returns (EmptyResponse) {} 66 | 67 | // Update represents operations like Go's ReadWriteTransaction.BatchUpdate, 68 | // Java's TransactionRunner.run, Python's Batch.update, and Node's 69 | // Transaction.BatchUpdate. 70 | // 71 | // It will typically be used to update many items. 72 | rpc Update(UpdateQuery) returns (EmptyResponse) {} 73 | } -------------------------------------------------------------------------------- /linkinator.config.json: -------------------------------------------------------------------------------- 1 | { 2 | "recurse": true, 3 | "skip": [ 4 | "https://codecov.io/gh/googleapis/", 5 | "www.googleapis.com", 6 | "img.shields.io", 7 | "https://console.cloud.google.com/cloudshell", 8 | "https://support.google.com" 9 | ], 10 | "silent": true, 11 | "concurrency": 5, 12 | "retry": true, 13 | "retryErrors": true, 14 | "retryErrorsCount": 5, 15 | "retryErrorsJitter": 3000 16 | } 17 | -------------------------------------------------------------------------------- /protos/google/spanner/admin/instance/v1/common.proto: -------------------------------------------------------------------------------- 1 | // Copyright 2025 Google LLC 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | syntax = "proto3"; 16 | 17 | package google.spanner.admin.instance.v1; 18 | 19 | import "google/api/field_behavior.proto"; 20 | import "google/api/resource.proto"; 21 | import "google/protobuf/timestamp.proto"; 22 | 23 | option csharp_namespace = "Google.Cloud.Spanner.Admin.Instance.V1"; 24 | option go_package = "cloud.google.com/go/spanner/admin/instance/apiv1/instancepb;instancepb"; 25 | option java_multiple_files = true; 26 | option java_outer_classname = "CommonProto"; 27 | option java_package = "com.google.spanner.admin.instance.v1"; 28 | option php_namespace = "Google\\Cloud\\Spanner\\Admin\\Instance\\V1"; 29 | option ruby_package = "Google::Cloud::Spanner::Admin::Instance::V1"; 30 | 31 | // Encapsulates progress related information for a Cloud Spanner long 32 | // running instance operations. 33 | message OperationProgress { 34 | // Percent completion of the operation. 35 | // Values are between 0 and 100 inclusive. 36 | int32 progress_percent = 1; 37 | 38 | // Time the request was received. 39 | google.protobuf.Timestamp start_time = 2; 40 | 41 | // If set, the time at which this operation failed or was completed 42 | // successfully. 43 | google.protobuf.Timestamp end_time = 3; 44 | } 45 | 46 | // Indicates the expected fulfillment period of an operation. 47 | enum FulfillmentPeriod { 48 | // Not specified. 49 | FULFILLMENT_PERIOD_UNSPECIFIED = 0; 50 | 51 | // Normal fulfillment period. The operation is expected to complete within 52 | // minutes. 53 | FULFILLMENT_PERIOD_NORMAL = 1; 54 | 55 | // Extended fulfillment period. It can take up to an hour for the operation 56 | // to complete. 57 | FULFILLMENT_PERIOD_EXTENDED = 2; 58 | } 59 | 60 | // ReplicaSelection identifies replicas with common properties. 61 | message ReplicaSelection { 62 | // Required. Name of the location of the replicas (e.g., "us-central1"). 63 | string location = 1 [(google.api.field_behavior) = REQUIRED]; 64 | } 65 | -------------------------------------------------------------------------------- /renovate.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": [ 3 | "config:base", 4 | "docker:disable", 5 | ":disableDependencyDashboard" 6 | ], 7 | "constraintsFiltering": "strict", 8 | "pinVersions": false, 9 | "rebaseStalePrs": true, 10 | "schedule": [ 11 | "after 9am and before 3pm" 12 | ], 13 | "gitAuthor": null, 14 | "packageRules": [ 15 | { 16 | "extends": "packages:linters", 17 | "groupName": "linters" 18 | } 19 | ], 20 | "ignoreDeps": ["typescript"] 21 | } 22 | -------------------------------------------------------------------------------- /samples/.eslintrc.yml: -------------------------------------------------------------------------------- 1 | --- 2 | rules: 3 | no-console: off 4 | -------------------------------------------------------------------------------- /samples/archived/backups-cancel.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2020 Google LLC 3 | * Licensed under the Apache License, Version 2.0 (the "License"); 4 | * you may not use this file except in compliance with the License. 5 | * You may obtain a copy of the License at 6 | * 7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | * 9 | * Unless required by applicable law or agreed to in writing, software 10 | * distributed under the License is distributed on an "AS IS" BASIS, 11 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | * See the License for the specific language governing permissions and 13 | * limitations under the License. 14 | */ 15 | 16 | 'use strict'; 17 | 18 | async function cancelBackup(instanceId, databaseId, backupId, projectId) { 19 | // [START spanner_cancel_backup_create] 20 | // Imports the Google Cloud client library and precise date library 21 | const {Spanner} = require('@google-cloud/spanner'); 22 | 23 | /** 24 | * TODO(developer): Uncomment the following lines before running the sample. 25 | */ 26 | // const projectId = 'my-project-id'; 27 | // const instanceId = 'my-instance'; 28 | // const databaseId = 'my-database'; 29 | // const backupId = 'my-backup'; 30 | 31 | // Creates a client 32 | const spanner = new Spanner({ 33 | projectId: projectId, 34 | }); 35 | 36 | // Gets a reference to a Cloud Spanner instance and database 37 | const instance = spanner.instance(instanceId); 38 | const database = instance.database(databaseId); 39 | 40 | const backup = instance.backup(backupId); 41 | 42 | // Creates a new backup of the database 43 | try { 44 | console.log(`Creating backup of database ${database.formattedName_}.`); 45 | const databasePath = database.formattedName_; 46 | // Expire backup one day in the future 47 | const expireTime = Date.now() + 1000 * 60 * 60 * 24; 48 | const [, operation] = await backup.create({ 49 | databasePath: databasePath, 50 | expireTime: expireTime, 51 | }); 52 | 53 | // Cancel the backup 54 | await operation.cancel(); 55 | 56 | console.log('Backup cancelled.'); 57 | } catch (err) { 58 | console.error('ERROR:', err); 59 | } finally { 60 | // Delete backup in case it got created before the cancel operation 61 | await backup.delete(); 62 | 63 | // Close the database when finished. 64 | await database.close(); 65 | } 66 | // [END spanner_cancel_backup_create] 67 | } 68 | 69 | module.exports.cancelBackup = cancelBackup; 70 | -------------------------------------------------------------------------------- /samples/archived/backups-delete.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2020 Google LLC 3 | * Licensed under the Apache License, Version 2.0 (the "License"); 4 | * you may not use this file except in compliance with the License. 5 | * You may obtain a copy of the License at 6 | * 7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | * 9 | * Unless required by applicable law or agreed to in writing, software 10 | * distributed under the License is distributed on an "AS IS" BASIS, 11 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | * See the License for the specific language governing permissions and 13 | * limitations under the License. 14 | */ 15 | 16 | 'use strict'; 17 | 18 | async function deleteBackup(instanceId, databaseId, backupId, projectId) { 19 | // [START spanner_delete_backup] 20 | // Imports the Google Cloud client library 21 | const {Spanner} = require('@google-cloud/spanner'); 22 | 23 | /** 24 | * TODO(developer): Uncomment the following lines before running the sample. 25 | */ 26 | // const projectId = 'my-project-id'; 27 | // const instanceId = 'my-instance'; 28 | // const databaseId = 'my-database'; 29 | // const backupId = 'my-backup'; 30 | 31 | // Creates a client 32 | const spanner = new Spanner({ 33 | projectId: projectId, 34 | }); 35 | 36 | // Gets a reference to a Cloud Spanner instance and backup 37 | const instance = spanner.instance(instanceId); 38 | const backup = instance.backup(backupId); 39 | 40 | // Delete the backup 41 | console.log(`Deleting backup ${backupId}.`); 42 | await backup.delete(); 43 | 44 | // Verify backup no longer exists 45 | const exists = await backup.exists(); 46 | if (exists) { 47 | console.error('Error: backup still exists.'); 48 | } else { 49 | console.log('Backup deleted.'); 50 | } 51 | // [END spanner_delete_backup] 52 | } 53 | 54 | module.exports.deleteBackup = deleteBackup; 55 | -------------------------------------------------------------------------------- /samples/archived/backups-get-database-operations.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2020 Google LLC 3 | * Licensed under the Apache License, Version 2.0 (the "License"); 4 | * you may not use this file except in compliance with the License. 5 | * You may obtain a copy of the License at 6 | * 7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | * 9 | * Unless required by applicable law or agreed to in writing, software 10 | * distributed under the License is distributed on an "AS IS" BASIS, 11 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | * See the License for the specific language governing permissions and 13 | * limitations under the License. 14 | */ 15 | 16 | 'use strict'; 17 | 18 | async function getDatabaseOperations(instanceId, projectId) { 19 | // [START spanner_list_database_operations] 20 | // Imports the Google Cloud client library 21 | const {Spanner, protos} = require('@google-cloud/spanner'); 22 | 23 | /** 24 | * TODO(developer): Uncomment the following lines before running the sample. 25 | */ 26 | // const projectId = 'my-project-id'; 27 | // const instanceId = 'my-instance'; 28 | 29 | // Creates a client 30 | const spanner = new Spanner({ 31 | projectId: projectId, 32 | }); 33 | 34 | // Gets a reference to a Cloud Spanner instance 35 | const instance = spanner.instance(instanceId); 36 | 37 | // List database operations 38 | try { 39 | const [databaseOperations] = await instance.getDatabaseOperations({ 40 | filter: 41 | '(metadata.@type:type.googleapis.com/google.spanner.admin.database.v1.OptimizeRestoredDatabaseMetadata)', 42 | }); 43 | console.log('Optimize Database Operations:'); 44 | databaseOperations.forEach(databaseOperation => { 45 | const metadata = 46 | protos.google.spanner.admin.database.v1.OptimizeRestoredDatabaseMetadata.decode( 47 | databaseOperation.metadata.value, 48 | ); 49 | console.log( 50 | `Database ${metadata.name} restored from backup is ` + 51 | `${metadata.progress.progressPercent}% optimized.`, 52 | ); 53 | }); 54 | } catch (err) { 55 | console.error('ERROR:', err); 56 | } 57 | // [END spanner_list_database_operations] 58 | } 59 | 60 | module.exports.getDatabaseOperations = getDatabaseOperations; 61 | -------------------------------------------------------------------------------- /samples/archived/backups-restore.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2021 Google LLC 3 | * Licensed under the Apache License, Version 2.0 (the "License"); 4 | * you may not use this file except in compliance with the License. 5 | * You may obtain a copy of the License at 6 | * 7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | * 9 | * Unless required by applicable law or agreed to in writing, software 10 | * distributed under the License is distributed on an "AS IS" BASIS, 11 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | * See the License for the specific language governing permissions and 13 | * limitations under the License. 14 | */ 15 | 16 | 'use strict'; 17 | 18 | async function restoreBackup(instanceId, databaseId, backupId, projectId) { 19 | // [START spanner_restore_backup] 20 | // Imports the Google Cloud client library and precise date library 21 | const {Spanner} = require('@google-cloud/spanner'); 22 | const {PreciseDate} = require('@google-cloud/precise-date'); 23 | 24 | /** 25 | * TODO(developer): Uncomment the following lines before running the sample. 26 | */ 27 | // const projectId = 'my-project-id'; 28 | // const instanceId = 'my-instance'; 29 | // const databaseId = 'my-database'; 30 | // const backupId = 'my-backup'; 31 | 32 | // Creates a client 33 | const spanner = new Spanner({ 34 | projectId: projectId, 35 | }); 36 | 37 | // Gets a reference to a Cloud Spanner instance and database 38 | const instance = spanner.instance(instanceId); 39 | const database = instance.database(databaseId); 40 | 41 | // Restore the database 42 | console.log( 43 | `Restoring database ${database.formattedName_} from backup ${backupId}.`, 44 | ); 45 | const [, restoreOperation] = await database.restore( 46 | `projects/${projectId}/instances/${instanceId}/backups/${backupId}`, 47 | ); 48 | 49 | // Wait for restore to complete 50 | console.log('Waiting for database restore to complete...'); 51 | await restoreOperation.promise(); 52 | 53 | console.log('Database restored from backup.'); 54 | const restoreInfo = await database.getRestoreInfo(); 55 | console.log( 56 | `Database ${restoreInfo.backupInfo.sourceDatabase} was restored ` + 57 | `to ${databaseId} from backup ${restoreInfo.backupInfo.backup} ` + 58 | 'with version time ' + 59 | `${new PreciseDate(restoreInfo.backupInfo.versionTime).toISOString()}.`, 60 | ); 61 | // [END spanner_restore_backup] 62 | } 63 | 64 | module.exports.restoreBackup = restoreBackup; 65 | -------------------------------------------------------------------------------- /samples/archived/backups-update.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2020 Google LLC 3 | * Licensed under the Apache License, Version 2.0 (the "License"); 4 | * you may not use this file except in compliance with the License. 5 | * You may obtain a copy of the License at 6 | * 7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | * 9 | * Unless required by applicable law or agreed to in writing, software 10 | * distributed under the License is distributed on an "AS IS" BASIS, 11 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | * See the License for the specific language governing permissions and 13 | * limitations under the License. 14 | */ 15 | 16 | 'use strict'; 17 | 18 | async function updateBackup(instanceId, backupId, projectId) { 19 | // [START spanner_update_backup] 20 | // Imports the Google Cloud client library and precise date library 21 | const {Spanner} = require('@google-cloud/spanner'); 22 | const {PreciseDate} = require('@google-cloud/precise-date'); 23 | 24 | /** 25 | * TODO(developer): Uncomment the following lines before running the sample. 26 | */ 27 | // const projectId = 'my-project-id'; 28 | // const instanceId = 'my-instance'; 29 | // const backupId = 'my-backup'; 30 | 31 | // Creates a client 32 | const spanner = new Spanner({ 33 | projectId: projectId, 34 | }); 35 | 36 | // Gets a reference to a Cloud Spanner instance and backup 37 | const instance = spanner.instance(instanceId); 38 | const backup = instance.backup(backupId); 39 | 40 | // Read backup metadata and update expiry time 41 | try { 42 | const currentExpireTime = await backup.getExpireTime(); 43 | const maxExpireTime = backup.metadata.maxExpireTime; 44 | const wantExpireTime = new PreciseDate(currentExpireTime); 45 | wantExpireTime.setDate(wantExpireTime.getDate() + 1); 46 | // New expire time should be less than the max expire time 47 | const min = (currentExpireTime, maxExpireTime) => 48 | currentExpireTime < maxExpireTime ? currentExpireTime : maxExpireTime; 49 | const newExpireTime = new PreciseDate(min(wantExpireTime, maxExpireTime)); 50 | console.log( 51 | `Backup ${backupId} current expire time: ${currentExpireTime.toISOString()}`, 52 | ); 53 | console.log(`Updating expire time to ${newExpireTime.toISOString()}`); 54 | await backup.updateExpireTime(newExpireTime); 55 | console.log('Expire time updated.'); 56 | } catch (err) { 57 | console.error('ERROR:', err); 58 | } 59 | // [END spanner_update_backup] 60 | } 61 | 62 | module.exports.updateBackup = updateBackup; 63 | -------------------------------------------------------------------------------- /samples/archived/database-create-with-encryption-key.js: -------------------------------------------------------------------------------- 1 | // Copyright 2021 Google LLC 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | 'use strict'; 16 | 17 | async function createDatabaseWithEncryptionKey( 18 | instanceId, 19 | databaseId, 20 | projectId, 21 | keyName, 22 | ) { 23 | // [START spanner_create_database_with_encryption_key] 24 | // Imports the Google Cloud client library 25 | const {Spanner} = require('@google-cloud/spanner'); 26 | 27 | /** 28 | * TODO(developer): Uncomment the following lines before running the sample. 29 | */ 30 | // const projectId = 'my-project-id'; 31 | // const instanceId = 'my-instance'; 32 | // const databaseId = 'my-database'; 33 | // const keyName = 34 | // 'projects/my-project-id/my-region/keyRings/my-key-ring/cryptoKeys/my-key'; 35 | 36 | // Creates a client 37 | const spanner = new Spanner({ 38 | projectId: projectId, 39 | }); 40 | 41 | // Gets a reference to a Cloud Spanner instance 42 | const instance = spanner.instance(instanceId); 43 | 44 | const request = { 45 | encryptionConfig: { 46 | kmsKeyName: keyName, 47 | }, 48 | }; 49 | 50 | // Creates a database 51 | const [database, operation] = await instance.createDatabase( 52 | databaseId, 53 | request, 54 | ); 55 | 56 | console.log(`Waiting for operation on ${database.id} to complete...`); 57 | await operation.promise(); 58 | 59 | console.log(`Created database ${databaseId} on instance ${instanceId}.`); 60 | 61 | // Get encryption key 62 | const [data] = await database.get(); 63 | 64 | console.log( 65 | `Database encrypted with key ${data.metadata.encryptionConfig.kmsKeyName}.`, 66 | ); 67 | // [END spanner_create_database_with_encryption_key] 68 | } 69 | 70 | module.exports.createDatabaseWithEncryptionKey = 71 | createDatabaseWithEncryptionKey; 72 | -------------------------------------------------------------------------------- /samples/archived/database-get-ddl.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2021 Google LLC 3 | * Licensed under the Apache License, Version 2.0 (the "License"); 4 | * you may not use this file except in compliance with the License. 5 | * You may obtain a copy of the License at 6 | * 7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | * 9 | * Unless required by applicable law or agreed to in writing, software 10 | * distributed under the License is distributed on an "AS IS" BASIS, 11 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | * See the License for the specific language governing permissions and 13 | * limitations under the License. 14 | */ 15 | 16 | // sample-metadata: 17 | // title: Gets the schema definition of an existing database 18 | // usage: node database-get-ddl.js 19 | 20 | 'use strict'; 21 | 22 | function main(instanceId, databaseId, projectId) { 23 | // [START spanner_get_database_ddl] 24 | /** 25 | * TODO(developer): Uncomment the following lines before running the sample. 26 | */ 27 | // const projectId = 'my-project-id'; 28 | // const instanceId = 'my-instance-id'; 29 | // const databaseId = 'my-database-id'; 30 | 31 | // Imports the Google Cloud client library 32 | const {Spanner} = require('@google-cloud/spanner'); 33 | 34 | // Creates a client 35 | const spanner = new Spanner({ 36 | projectId: projectId, 37 | }); 38 | // Gets a reference to a Cloud Spanner instance and a database. 39 | const instance = spanner.instance(instanceId); 40 | const database = instance.database(databaseId); 41 | 42 | async function getDatabaseDdl() { 43 | // Get the schema definition of the database. 44 | const [ddlStatements] = await database.getSchema(); 45 | 46 | console.log(`Retrieved database DDL for ${database.formattedName_}:`); 47 | ddlStatements.forEach(statement => { 48 | console.log(`${statement};\n`); 49 | }); 50 | } 51 | getDatabaseDdl(); 52 | // [END spanner_get_database_ddl] 53 | } 54 | process.on('unhandledRejection', err => { 55 | console.error(err.message); 56 | process.exitCode = 1; 57 | }); 58 | main(...process.argv.slice(2)); 59 | -------------------------------------------------------------------------------- /samples/archived/database-update-default-leader.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2021 Google LLC 3 | * Licensed under the Apache License, Version 2.0 (the "License"); 4 | * you may not use this file except in compliance with the License. 5 | * You may obtain a copy of the License at 6 | * 7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | * 9 | * Unless required by applicable law or agreed to in writing, software 10 | * distributed under the License is distributed on an "AS IS" BASIS, 11 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | * See the License for the specific language governing permissions and 13 | * limitations under the License. 14 | */ 15 | 16 | // sample-metadata: 17 | // title: Updates the default leader of an existing database 18 | // usage: node database-update-default-leader.js 19 | 20 | 'use strict'; 21 | 22 | function main(instanceId, databaseId, defaultLeader, projectId) { 23 | // [START spanner_update_database_with_default_leader] 24 | /** 25 | * TODO(developer): Uncomment the following lines before running the sample. 26 | */ 27 | // const projectId = 'my-project-id'; 28 | // const instanceId = 'my-instance-id'; 29 | // const databaseId = 'my-database-id'; 30 | // const defaultLeader = 'my-default-leader'; 31 | 32 | // Imports the Google Cloud client library 33 | const {Spanner} = require('@google-cloud/spanner'); 34 | 35 | // Creates a client 36 | const spanner = new Spanner({ 37 | projectId: projectId, 38 | }); 39 | // Gets a reference to a Cloud Spanner instance and a database. 40 | const instance = spanner.instance(instanceId); 41 | const database = instance.database(databaseId); 42 | 43 | async function updateDatabaseWithDefaultLeader() { 44 | console.log(`Updating database ${database.formattedName_}.`); 45 | const setDefaultLeaderStatement = ` 46 | ALTER DATABASE \`${databaseId}\` 47 | SET OPTIONS (default_leader = '${defaultLeader}')`; 48 | const [operation] = await database.updateSchema(setDefaultLeaderStatement); 49 | 50 | console.log(`Waiting for updating of ${database.id} to complete...`); 51 | await operation.promise(); 52 | console.log( 53 | `Updated database ${databaseId} with default leader ${defaultLeader}.`, 54 | ); 55 | } 56 | updateDatabaseWithDefaultLeader(); 57 | // [END spanner_update_database_with_default_leader] 58 | } 59 | process.on('unhandledRejection', err => { 60 | console.error(err.message); 61 | process.exitCode = 1; 62 | }); 63 | main(...process.argv.slice(2)); 64 | -------------------------------------------------------------------------------- /samples/archived/database-update.js: -------------------------------------------------------------------------------- 1 | // Copyright 2023 Google LLC 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | // sample-metadata: 16 | // title: Updates a Cloud Spanner Database. 17 | // usage: node database-update.js 18 | 19 | 'use strict'; 20 | 21 | function main( 22 | instanceId = 'my-instance', 23 | databaseId = 'my-database', 24 | projectId = 'my-project-id', 25 | ) { 26 | // [START spanner_update_database] 27 | /** 28 | * TODO(developer): Uncomment these variables before running the sample. 29 | */ 30 | // const instanceId = 'my-instance'; 31 | // const databaseId = 'my-database'; 32 | // const projectId = 'my-project-id'; 33 | 34 | // Imports the Google Cloud Spanner client library 35 | const {Spanner} = require('@google-cloud/spanner'); 36 | 37 | // Instantiates a client 38 | const spanner = new Spanner({ 39 | projectId: projectId, 40 | }); 41 | 42 | async function updateDatabase() { 43 | // Gets a reference to a Cloud Spanner instance and database 44 | const instance = spanner.instance(instanceId); 45 | const database = instance.database(databaseId); 46 | 47 | try { 48 | console.log(`Updating database ${database.id}.`); 49 | const [operation] = await database.setMetadata({ 50 | enableDropProtection: true, 51 | }); 52 | console.log( 53 | `Waiting for update operation for ${database.id} to complete...`, 54 | ); 55 | await operation.promise(); 56 | console.log(`Updated database ${database.id}.`); 57 | } catch (err) { 58 | console.log('ERROR:', err); 59 | } finally { 60 | // Close the database when finished. 61 | database.close(); 62 | } 63 | } 64 | updateDatabase(); 65 | // [END spanner_update_database] 66 | } 67 | 68 | process.on('unhandledRejection', err => { 69 | console.error(err.message); 70 | process.exitCode = 1; 71 | }); 72 | main(...process.argv.slice(2)); 73 | -------------------------------------------------------------------------------- /samples/archived/get-database-roles.js: -------------------------------------------------------------------------------- 1 | // Copyright 2022 Google LLC 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | // sample-metadata: 16 | // title: List database roles 17 | // usage: node get-database-roles.js 18 | 19 | 'use strict'; 20 | 21 | function main( 22 | instanceId = 'my-instance', 23 | databaseId = 'my-database', 24 | projectId = 'my-project-id', 25 | ) { 26 | // [START spanner_list_database_roles] 27 | /** 28 | * TODO(developer): Uncomment these variables before running the sample. 29 | */ 30 | // const instanceId = 'my-instance'; 31 | // const databaseId = 'my-database'; 32 | // const projectId = 'my-project-id'; 33 | // Imports the Google Cloud Spanner client library 34 | const {Spanner} = require('@google-cloud/spanner'); 35 | 36 | // Instantiates a client 37 | const spanner = new Spanner({ 38 | projectId: projectId, 39 | }); 40 | 41 | async function getDatabaseRoles() { 42 | // Gets a reference to a Cloud Spanner instance and database. 43 | const instance = spanner.instance(instanceId); 44 | const database = instance.database(databaseId); 45 | 46 | // Fetching database roles 47 | const [databaseRoles] = await database.getDatabaseRoles(); 48 | console.log(`Roles for Database: ${database.formattedName_}`); 49 | databaseRoles.forEach(role => { 50 | console.log(`Role: ${role.name}`); 51 | }); 52 | } 53 | getDatabaseRoles(); 54 | // [END spanner_list_database_roles] 55 | } 56 | 57 | process.on('unhandledRejection', err => { 58 | console.error(err.message); 59 | process.exitCode = 1; 60 | }); 61 | main(...process.argv.slice(2)); 62 | -------------------------------------------------------------------------------- /samples/archived/get-instance-config.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2021 Google LLC 3 | * Licensed under the Apache License, Version 2.0 (the "License"); 4 | * you may not use this file except in compliance with the License. 5 | * You may obtain a copy of the License at 6 | * 7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | * 9 | * Unless required by applicable law or agreed to in writing, software 10 | * distributed under the License is distributed on an "AS IS" BASIS, 11 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | * See the License for the specific language governing permissions and 13 | * limitations under the License. 14 | */ 15 | 16 | // sample-metadata: 17 | // title: Gets the instance config metadata for the configuration nam6 18 | // usage: node get-instance-config.js 19 | 20 | 'use strict'; 21 | 22 | function main(projectId) { 23 | // [START spanner_get_instance_config] 24 | /** 25 | * TODO(developer): Uncomment the following line before running the sample. 26 | */ 27 | // const projectId = 'my-project-id'; 28 | 29 | // Imports the Google Cloud client library 30 | const {Spanner} = require('@google-cloud/spanner'); 31 | 32 | // Creates a client 33 | const spanner = new Spanner({ 34 | projectId: projectId, 35 | }); 36 | 37 | async function getInstanceConfig() { 38 | // Get the instance config for the multi-region North America 6 (NAM6). 39 | // See https://cloud.google.com/spanner/docs/instance-configurations#configuration for a list of all available 40 | // configurations. 41 | const [instanceConfig] = await spanner.getInstanceConfig('nam6'); 42 | console.log( 43 | `Available leader options for instance config ${instanceConfig.name} ('${ 44 | instanceConfig.displayName 45 | }'): 46 | ${instanceConfig.leaderOptions.join()}`, 47 | ); 48 | } 49 | getInstanceConfig(); 50 | // [END spanner_get_instance_config] 51 | } 52 | process.on('unhandledRejection', err => { 53 | console.error(err.message); 54 | process.exitCode = 1; 55 | }); 56 | main(...process.argv.slice(2)); 57 | -------------------------------------------------------------------------------- /samples/archived/index-create-storing.js: -------------------------------------------------------------------------------- 1 | // Copyright 2021 Google LLC 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | // sample-metadata: 16 | // title: Creates a new value-storing index 17 | // usage: node createStoringIndex 18 | 19 | 'use strict'; 20 | 21 | function main( 22 | instanceId = 'my-instance', 23 | databaseId = 'my-database', 24 | projectId = 'my-project-id', 25 | ) { 26 | // [START spanner_create_storing_index] 27 | /** 28 | * TODO(developer): Uncomment these variables before running the sample. 29 | */ 30 | // const instanceId = 'my-instance'; 31 | // const databaseId = 'my-database'; 32 | // const projectId = 'my-project-id'; 33 | 34 | // Imports the Google Cloud Spanner client library 35 | const {Spanner} = require('@google-cloud/spanner'); 36 | 37 | // Instantiates a client 38 | const spanner = new Spanner({ 39 | projectId: projectId, 40 | }); 41 | 42 | async function createStoringIndex() { 43 | // Gets a reference to a Cloud Spanner instance and database 44 | const instance = spanner.instance(instanceId); 45 | const database = instance.database(databaseId); 46 | 47 | const request = [ 48 | 'CREATE INDEX AlbumsByAlbumTitle2 ON Albums(AlbumTitle) STORING (MarketingBudget)', 49 | ]; 50 | 51 | // Creates a new index in the database 52 | try { 53 | const [operation] = await database.updateSchema(request); 54 | 55 | console.log('Waiting for operation to complete...'); 56 | await operation.promise(); 57 | 58 | console.log('Added the AlbumsByAlbumTitle2 index.'); 59 | } catch (err) { 60 | console.error('ERROR:', err); 61 | } finally { 62 | // Close the database when finished. 63 | database.close(); 64 | } 65 | } 66 | createStoringIndex(); 67 | // [END spanner_create_storing_index] 68 | } 69 | process.on('unhandledRejection', err => { 70 | console.error(err.message); 71 | process.exitCode = 1; 72 | }); 73 | main(...process.argv.slice(2)); 74 | -------------------------------------------------------------------------------- /samples/archived/index-create.js: -------------------------------------------------------------------------------- 1 | // Copyright 2021 Google LLC 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | // sample-metadata: 16 | // title: Creates a new index 17 | // usage: node createIndex 18 | 19 | 'use strict'; 20 | 21 | function main( 22 | instanceId = 'my-instance', 23 | databaseId = 'my-database', 24 | projectId = 'my-project-id', 25 | ) { 26 | // [START spanner_create_index] 27 | /** 28 | * TODO(developer): Uncomment these variables before running the sample. 29 | */ 30 | // const instanceId = 'my-instance'; 31 | // const databaseId = 'my-database'; 32 | // const projectId = 'my-project-id'; 33 | 34 | // Imports the Google Cloud Spanner client library 35 | const {Spanner} = require('@google-cloud/spanner'); 36 | 37 | // Instantiates a client 38 | const spanner = new Spanner({ 39 | projectId: projectId, 40 | }); 41 | 42 | async function createIndex() { 43 | // Gets a reference to a Cloud Spanner instance and database 44 | const instance = spanner.instance(instanceId); 45 | const database = instance.database(databaseId); 46 | 47 | const request = ['CREATE INDEX AlbumsByAlbumTitle ON Albums(AlbumTitle)']; 48 | 49 | // Creates a new index in the database 50 | try { 51 | const [operation] = await database.updateSchema(request); 52 | 53 | console.log('Waiting for operation to complete...'); 54 | await operation.promise(); 55 | 56 | console.log('Added the AlbumsByAlbumTitle index.'); 57 | } catch (err) { 58 | console.error('ERROR:', err); 59 | } finally { 60 | // Close the database when finished. 61 | database.close(); 62 | } 63 | } 64 | createIndex(); 65 | // [END spanner_create_index] 66 | } 67 | process.on('unhandledRejection', err => { 68 | console.error(err.message); 69 | process.exitCode = 1; 70 | }); 71 | main(...process.argv.slice(2)); 72 | -------------------------------------------------------------------------------- /samples/archived/instance-config-delete.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2022 Google LLC 3 | * Licensed under the Apache License, Version 2.0 (the "License"); 4 | * you may not use this file except in compliance with the License. 5 | * You may obtain a copy of the License at 6 | * 7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | * 9 | * Unless required by applicable law or agreed to in writing, software 10 | * distributed under the License is distributed on an "AS IS" BASIS, 11 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | * See the License for the specific language governing permissions and 13 | * limitations under the License. 14 | */ 15 | 16 | // sample-metadata: 17 | // title: Deletes a user-managed instance configuration. 18 | // usage: node instance-config-delete 19 | 20 | 'use strict'; 21 | 22 | function main( 23 | instanceConfigId = 'custom-my-instance-config', 24 | projectId = 'my-project-id', 25 | ) { 26 | // [START spanner_delete_instance_config] 27 | 28 | /** 29 | * TODO(developer): Uncomment the following lines before running the sample. 30 | */ 31 | // const instanceConfigId = 'custom-my-instance-config-id'; 32 | // const projectId = 'my-project-id'; 33 | 34 | // Imports the Google Cloud client library 35 | const {Spanner} = require('@google-cloud/spanner'); 36 | 37 | // Creates a client 38 | const spanner = new Spanner({ 39 | projectId: projectId, 40 | }); 41 | async function deleteInstanceConfig() { 42 | // Deletes an instance config. 43 | const instanceConfig = spanner.instanceConfig(instanceConfigId); 44 | try { 45 | // Delete the instance config. 46 | console.log(`Deleting ${instanceConfig.id}...\n`); 47 | await instanceConfig.delete(); 48 | // Verify that the instance config no longer exists 49 | const exists = await instanceConfig.exists(); 50 | if (exists) { 51 | console.error( 52 | 'Error: Instance config ', 53 | instanceConfigId, 54 | ' still exists', 55 | ); 56 | } else { 57 | console.log(`Deleted instance config ${instanceConfigId}.\n`); 58 | } 59 | } catch (err) { 60 | console.error( 61 | 'ERROR: Deleting instance config ', 62 | instanceConfigId, 63 | ' failed with error message ', 64 | err, 65 | ); 66 | } 67 | } 68 | deleteInstanceConfig(); 69 | // [END spanner_delete_instance_config] 70 | } 71 | 72 | process.on('unhandledRejection', err => { 73 | console.error(err.message); 74 | process.exitCode = 1; 75 | }); 76 | main(...process.argv.slice(2)); 77 | -------------------------------------------------------------------------------- /samples/archived/instance-with-processing-units.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2021 Google LLC 3 | * Licensed under the Apache License, Version 2.0 (the "License"); 4 | * you may not use this file except in compliance with the License. 5 | * You may obtain a copy of the License at 6 | * 7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | * 9 | * Unless required by applicable law or agreed to in writing, software 10 | * distributed under the License is distributed on an "AS IS" BASIS, 11 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | * See the License for the specific language governing permissions and 13 | * limitations under the License. 14 | */ 15 | 16 | 'use strict'; 17 | 18 | async function createInstanceWithProcessingUnits(instanceId, projectId) { 19 | // [START spanner_create_instance_with_processing_units] 20 | // Imports the Google Cloud client library 21 | const {Spanner} = require('@google-cloud/spanner'); 22 | 23 | /** 24 | * TODO(developer): Uncomment the following lines before running the sample. 25 | */ 26 | // const projectId = 'my-project-id'; 27 | // const instanceId = 'my-instance'; 28 | 29 | // Creates a client 30 | const spanner = new Spanner({ 31 | projectId: projectId, 32 | }); 33 | 34 | const instance = spanner.instance(instanceId); 35 | 36 | // Creates a new instance 37 | try { 38 | console.log(`Creating instance ${instance.formattedName_}.`); 39 | const [, operation] = await instance.create({ 40 | config: 'regional-us-central1', 41 | processingUnits: 500, 42 | displayName: 'This is a display name.', 43 | labels: { 44 | ['cloud_spanner_samples']: 'true', 45 | }, 46 | }); 47 | 48 | console.log(`Waiting for operation on ${instance.id} to complete...`); 49 | await operation.promise(); 50 | 51 | console.log(`Created instance ${instanceId}.`); 52 | 53 | const [metadata] = await instance.getMetadata({ 54 | fieldNames: ['processingUnits'], 55 | }); 56 | console.log( 57 | `Instance ${instanceId} has ${metadata.processingUnits} ` + 58 | 'processing units.', 59 | ); 60 | } catch (err) { 61 | console.error('ERROR:', err); 62 | } 63 | // [END spanner_create_instance_with_processing_units] 64 | } 65 | 66 | module.exports.createInstanceWithProcessingUnits = 67 | createInstanceWithProcessingUnits; 68 | -------------------------------------------------------------------------------- /samples/archived/json-add-column.js: -------------------------------------------------------------------------------- 1 | // Copyright 2021 Google LLC 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | 'use strict'; 16 | 17 | async function addJsonColumn(instanceId, databaseId, projectId) { 18 | // [START spanner_add_json_column] 19 | // Imports the Google Cloud client library. 20 | const {Spanner} = require('@google-cloud/spanner'); 21 | 22 | /** 23 | * TODO(developer): Uncomment the following lines before running the sample. 24 | */ 25 | // const projectId = 'my-project-id'; 26 | // const instanceId = 'my-instance'; 27 | // const databaseId = 'my-database'; 28 | 29 | // Creates a client 30 | const spanner = new Spanner({ 31 | projectId: projectId, 32 | }); 33 | 34 | // Gets a reference to a Cloud Spanner instance. 35 | const instance = spanner.instance(instanceId); 36 | const database = instance.database(databaseId); 37 | 38 | const request = ['ALTER TABLE Venues ADD COLUMN VenueDetails JSON']; 39 | 40 | // Alter existing table to add a column. 41 | const [operation] = await database.updateSchema(request); 42 | 43 | console.log(`Waiting for operation on ${databaseId} to complete...`); 44 | 45 | await operation.promise(); 46 | 47 | console.log( 48 | `Added VenueDetails column to Venues table in database ${databaseId}.`, 49 | ); 50 | // [END spanner_add_json_column] 51 | } 52 | 53 | module.exports.addJsonColumn = addJsonColumn; 54 | -------------------------------------------------------------------------------- /samples/archived/list-databases.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2021 Google LLC 3 | * Licensed under the Apache License, Version 2.0 (the "License"); 4 | * you may not use this file except in compliance with the License. 5 | * You may obtain a copy of the License at 6 | * 7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | * 9 | * Unless required by applicable law or agreed to in writing, software 10 | * distributed under the License is distributed on an "AS IS" BASIS, 11 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | * See the License for the specific language governing permissions and 13 | * limitations under the License. 14 | */ 15 | 16 | // sample-metadata: 17 | // title: Lists all databases on the selected instance 18 | // usage: node list-databases.js 19 | 20 | 'use strict'; 21 | 22 | function main(instanceId, projectId) { 23 | // [START spanner_list_databases] 24 | /** 25 | * TODO(developer): Uncomment the following lines before running the sample. 26 | */ 27 | // const projectId = 'my-project-id'; 28 | // const instanceId = 'my-instance-id'; 29 | 30 | // Imports the Google Cloud client library 31 | const {Spanner} = require('@google-cloud/spanner'); 32 | 33 | // Creates a client 34 | const spanner = new Spanner({ 35 | projectId: projectId, 36 | }); 37 | // Gets a reference to a Cloud Spanner instance 38 | const instance = spanner.instance(instanceId); 39 | 40 | async function listDatabases() { 41 | // Lists all databases on the instance. 42 | const [databases] = await instance.getDatabases(); 43 | console.log(`Databases for projects/${projectId}/instances/${instanceId}:`); 44 | databases.forEach(database => { 45 | const defaultLeader = database.metadata.defaultLeader 46 | ? `(default leader = ${database.metadata.defaultLeader})` 47 | : ''; 48 | console.log(`\t${database.id} ${defaultLeader}`); 49 | }); 50 | } 51 | listDatabases(); 52 | // [END spanner_list_databases] 53 | } 54 | process.on('unhandledRejection', err => { 55 | console.error(err.message); 56 | process.exitCode = 1; 57 | }); 58 | main(...process.argv.slice(2)); 59 | -------------------------------------------------------------------------------- /samples/archived/list-instance-configs.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2021 Google LLC 3 | * Licensed under the Apache License, Version 2.0 (the "License"); 4 | * you may not use this file except in compliance with the License. 5 | * You may obtain a copy of the License at 6 | * 7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | * 9 | * Unless required by applicable law or agreed to in writing, software 10 | * distributed under the License is distributed on an "AS IS" BASIS, 11 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | * See the License for the specific language governing permissions and 13 | * limitations under the License. 14 | */ 15 | 16 | // sample-metadata: 17 | // title: Lists all the available instance configs for the selected project. 18 | // usage: node list-instance-configs.js 19 | 20 | 'use strict'; 21 | 22 | function main(projectId) { 23 | // [START spanner_list_instance_configs] 24 | /** 25 | * TODO(developer): Uncomment the following line before running the sample. 26 | */ 27 | // const projectId = 'my-project-id'; 28 | 29 | // Imports the Google Cloud client library 30 | const {Spanner} = require('@google-cloud/spanner'); 31 | 32 | // Creates a client 33 | const spanner = new Spanner({ 34 | projectId: projectId, 35 | }); 36 | 37 | async function listInstanceConfigs() { 38 | // Lists all available instance configurations in the project. 39 | // See https://cloud.google.com/spanner/docs/instance-configurations#configuration for a list of all available 40 | // configurations. 41 | const [instanceConfigs] = await spanner.getInstanceConfigs(); 42 | console.log(`Available instance configs for project ${projectId}:`); 43 | instanceConfigs.forEach(instanceConfig => { 44 | console.log( 45 | `Available leader options for instance config ${ 46 | instanceConfig.name 47 | } ('${instanceConfig.displayName}'): 48 | ${instanceConfig.leaderOptions.join()}`, 49 | ); 50 | }); 51 | } 52 | listInstanceConfigs(); 53 | // [END spanner_list_instance_configs] 54 | } 55 | process.on('unhandledRejection', err => { 56 | console.error(err.message); 57 | process.exitCode = 1; 58 | }); 59 | main(...process.argv.slice(2)); 60 | -------------------------------------------------------------------------------- /samples/archived/numeric-add-column.js: -------------------------------------------------------------------------------- 1 | // Copyright 2020 Google LLC 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | 'use strict'; 16 | 17 | async function addNumericColumn(instanceId, databaseId, projectId) { 18 | // [START spanner_add_numeric_column] 19 | // Imports the Google Cloud client library. 20 | const {Spanner} = require('@google-cloud/spanner'); 21 | 22 | /** 23 | * TODO(developer): Uncomment the following lines before running the sample. 24 | */ 25 | // const projectId = 'my-project-id'; 26 | // const instanceId = 'my-instance'; 27 | // const databaseId = 'my-database'; 28 | 29 | // Creates a client 30 | const spanner = new Spanner({ 31 | projectId: projectId, 32 | }); 33 | 34 | // Gets a reference to a Cloud Spanner instance. 35 | const instance = spanner.instance(instanceId); 36 | const database = instance.database(databaseId); 37 | 38 | const request = ['ALTER TABLE Venues ADD COLUMN Revenue NUMERIC']; 39 | 40 | // Alter existing table to add a column. 41 | const [operation] = await database.updateSchema(request); 42 | 43 | console.log(`Waiting for operation on ${databaseId} to complete...`); 44 | 45 | await operation.promise(); 46 | 47 | console.log( 48 | `Added Revenue column to Venues table in database ${databaseId}.`, 49 | ); 50 | // [END spanner_add_numeric_column] 51 | } 52 | 53 | module.exports.addNumericColumn = addNumericColumn; 54 | -------------------------------------------------------------------------------- /samples/archived/pg-add-column.js: -------------------------------------------------------------------------------- 1 | // Copyright 2022 Google LLC 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | // sample-metadata: 16 | // title: Adds a column to an existing table in a Spanner PostgreSQL database. 17 | // usage: node pg-add-column.js 18 | 19 | 'use strict'; 20 | 21 | function main( 22 | instanceId = 'my-instance', 23 | databaseId = 'my-database', 24 | projectId = 'my-project-id', 25 | ) { 26 | // [START spanner_postgresql_add_column] 27 | /** 28 | * TODO(developer): Uncomment these variables before running the sample. 29 | */ 30 | // const instanceId = 'my-instance'; 31 | // const databaseId = 'my-database'; 32 | // const projectId = 'my-project-id'; 33 | 34 | // Imports the Google Cloud Spanner client library 35 | const {Spanner} = require('@google-cloud/spanner'); 36 | 37 | // Instantiates a client 38 | const spanner = new Spanner({ 39 | projectId: projectId, 40 | }); 41 | 42 | async function pgAddColumn() { 43 | const instance = spanner.instance(instanceId); 44 | const database = instance.database(databaseId); 45 | 46 | const request = ['ALTER TABLE Albums ADD COLUMN MarketingBudget BIGINT']; 47 | 48 | // Alter existing table to add a column. 49 | const [operation] = await database.updateSchema(request); 50 | 51 | console.log(`Waiting for operation on ${databaseId} to complete...`); 52 | 53 | await operation.promise(); 54 | 55 | console.log( 56 | `Added MarketingBudget column to Albums table in database ${databaseId}.`, 57 | ); 58 | } 59 | pgAddColumn(); 60 | // [END spanner_postgresql_add_column] 61 | } 62 | 63 | process.on('unhandledRejection', err => { 64 | console.error(err.message); 65 | process.exitCode = 1; 66 | }); 67 | main(...process.argv.slice(2)); 68 | -------------------------------------------------------------------------------- /samples/archived/pg-index-create-storing.js: -------------------------------------------------------------------------------- 1 | // Copyright 2022 Google LLC 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | // sample-metadata: 16 | // title: Creates a new storing index in a Spanner PostgreSQL database. 17 | // usage: node pg-index-create-storing.js 18 | 19 | 'use strict'; 20 | 21 | function main( 22 | instanceId = 'my-instance', 23 | databaseId = 'my-database', 24 | projectId = 'my-project-id', 25 | ) { 26 | // [START spanner_postgresql_create_storing_index] 27 | /** 28 | * TODO(developer): Uncomment these variables before running the sample. 29 | */ 30 | // const instanceId = 'my-instance'; 31 | // const databaseId = 'my-database'; 32 | // const projectId = 'my-project-id'; 33 | 34 | // Imports the Google Cloud Spanner client library 35 | const {Spanner} = require('@google-cloud/spanner'); 36 | 37 | // Instantiates a client 38 | const spanner = new Spanner({ 39 | projectId: projectId, 40 | }); 41 | 42 | async function pgCreateStoringIndex() { 43 | // Gets a reference to a Cloud Spanner instance and database 44 | const instance = spanner.instance(instanceId); 45 | const database = instance.database(databaseId); 46 | 47 | const request = [ 48 | 'CREATE INDEX AlbumsByAlbumTitle ON Albums(AlbumTitle) INCLUDE(MarketingBudget)', 49 | ]; 50 | 51 | // Creates a new index in the database 52 | try { 53 | const [operation] = await database.updateSchema(request); 54 | 55 | console.log('Waiting for operation to complete...'); 56 | await operation.promise(); 57 | 58 | console.log('Added the AlbumsByAlbumTitle index.'); 59 | } catch (err) { 60 | console.error('ERROR:', err); 61 | } finally { 62 | // Close the database when finished. 63 | database.close(); 64 | } 65 | } 66 | pgCreateStoringIndex(); 67 | // [END spanner_postgresql_create_storing_index] 68 | } 69 | 70 | process.on('unhandledRejection', err => { 71 | console.error(err.message); 72 | process.exitCode = 1; 73 | }); 74 | main(...process.argv.slice(2)); 75 | -------------------------------------------------------------------------------- /samples/archived/pg-jsonb-add-column.js: -------------------------------------------------------------------------------- 1 | // Copyright 2024 Google LLC 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | // sample-metadata: 16 | // title: Showcase how add a jsonb column in a PostgreSQL table. 17 | // usage: node pg-jsonb-add-column.js 18 | 19 | 'use strict'; 20 | 21 | function main( 22 | instanceId = 'my-instance', 23 | databaseId = 'my-database', 24 | projectId = 'my-project-id', 25 | ) { 26 | // [START spanner_postgresql_jsonb_add_column] 27 | /** 28 | * TODO(developer): Uncomment these variables before running the sample. 29 | */ 30 | // const instanceId = 'my-instance'; 31 | // const databaseId = 'my-database'; 32 | // const projectId = 'my-project-id'; 33 | 34 | // Imports the Google Cloud Spanner client library 35 | const {Spanner} = require('@google-cloud/spanner'); 36 | 37 | // Instantiates a client 38 | const spanner = new Spanner({ 39 | projectId: projectId, 40 | }); 41 | 42 | async function pgJsonbAddColumn() { 43 | // Gets a reference to a Cloud Spanner instance and database. 44 | const instance = spanner.instance(instanceId); 45 | const database = instance.database(databaseId); 46 | 47 | const request = ['ALTER TABLE Venues ADD COLUMN VenueDetails JSONB']; 48 | 49 | // Updates schema by adding a new table. 50 | const [operation] = await database.updateSchema(request); 51 | console.log(`Waiting for operation on ${databaseId} to complete...`); 52 | await operation.promise(); 53 | console.log( 54 | `Added jsonb column to table venues to database ${databaseId}.`, 55 | ); 56 | } 57 | pgJsonbAddColumn(); 58 | // [END spanner_postgresql_jsonb_add_column] 59 | } 60 | 61 | process.on('unhandledRejection', err => { 62 | console.error(err.message); 63 | process.exitCode = 1; 64 | }); 65 | main(...process.argv.slice(2)); 66 | -------------------------------------------------------------------------------- /samples/archived/pg-sequence-drop.js: -------------------------------------------------------------------------------- 1 | // Copyright 2024 Google LLC 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | // sample-metadata: 16 | // title: Drops a sequence in PostgreSQL database. 17 | // usage: node pg-sequence-drop.js 18 | 19 | 'use strict'; 20 | 21 | async function main(instanceId, databaseId, projectId) { 22 | // [START spanner_drop_sequence] 23 | // Imports the Google Cloud client library. 24 | const {Spanner} = require('@google-cloud/spanner'); 25 | 26 | /** 27 | * TODO(developer): Uncomment the following lines before running the sample. 28 | */ 29 | // const projectId = 'my-project-id'; 30 | // const instanceId = 'my-instance'; 31 | // const databaseId = 'my-database'; 32 | 33 | // Creates a client 34 | const spanner = new Spanner({ 35 | projectId: projectId, 36 | }); 37 | 38 | async function dropSequence(instanceId, databaseId) { 39 | // Gets a reference to a Cloud Spanner instance and database 40 | const instance = spanner.instance(instanceId); 41 | const database = instance.database(databaseId); 42 | 43 | const request = [ 44 | 'ALTER TABLE Customers ALTER COLUMN CustomerId DROP DEFAULT', 45 | 'DROP SEQUENCE Seq', 46 | ]; 47 | 48 | // Drop sequence from DDL 49 | try { 50 | const [operation] = await database.updateSchema(request); 51 | 52 | console.log('Waiting for operation to complete...'); 53 | await operation.promise(); 54 | 55 | console.log( 56 | 'Altered Customers table to drop DEFAULT from CustomerId column and dropped the Seq sequence.', 57 | ); 58 | } catch (err) { 59 | console.error('ERROR:', err); 60 | } finally { 61 | // Close the database when finished. 62 | await database.close(); 63 | } 64 | } 65 | await dropSequence(instanceId, databaseId); 66 | // [END spanner_drop_sequence] 67 | } 68 | 69 | process.on('unhandledRejection', err => { 70 | console.error(err.message); 71 | process.exitCode = 1; 72 | }); 73 | main(...process.argv.slice(2)); 74 | -------------------------------------------------------------------------------- /samples/archived/sequence-drop.js: -------------------------------------------------------------------------------- 1 | // Copyright 2024 Google LLC 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | // sample-metadata: 16 | // title: Drops a sequence in GoogleSQL database. 17 | // usage: node sequence-drop.js 18 | 19 | 'use strict'; 20 | 21 | async function main(instanceId, databaseId, projectId) { 22 | // [START spanner_drop_sequence] 23 | // Imports the Google Cloud client library. 24 | const {Spanner} = require('@google-cloud/spanner'); 25 | 26 | /** 27 | * TODO(developer): Uncomment the following lines before running the sample. 28 | */ 29 | // const projectId = 'my-project-id'; 30 | // const instanceId = 'my-instance'; 31 | // const databaseId = 'my-database'; 32 | 33 | // Creates a client 34 | const spanner = new Spanner({ 35 | projectId: projectId, 36 | }); 37 | 38 | async function dropSequence(instanceId, databaseId) { 39 | // Gets a reference to a Cloud Spanner instance and database 40 | const instance = spanner.instance(instanceId); 41 | const database = instance.database(databaseId); 42 | 43 | const request = [ 44 | 'ALTER TABLE Customers ALTER COLUMN CustomerId DROP DEFAULT', 45 | 'DROP SEQUENCE Seq', 46 | ]; 47 | 48 | // Drop sequence from DDL 49 | try { 50 | const [operation] = await database.updateSchema(request); 51 | 52 | console.log('Waiting for operation to complete...'); 53 | await operation.promise(); 54 | 55 | console.log( 56 | 'Altered Customers table to drop DEFAULT from CustomerId column and dropped the Seq sequence.', 57 | ); 58 | } catch (err) { 59 | console.error('ERROR:', err); 60 | } finally { 61 | // Close the database when finished. 62 | await database.close(); 63 | } 64 | } 65 | await dropSequence(instanceId, databaseId); 66 | // [END spanner_drop_sequence] 67 | } 68 | 69 | process.on('unhandledRejection', err => { 70 | console.error(err.message); 71 | process.exitCode = 1; 72 | }); 73 | main(...process.argv.slice(2)); 74 | -------------------------------------------------------------------------------- /samples/archived/table-alter-with-foreign-key-delete-cascade.js: -------------------------------------------------------------------------------- 1 | // Copyright 2023 Google LLC 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | // sample-metadata: 16 | // title: Alters a table with foreign key delete cascade action 17 | // usage: node table-alter-with-foreign-key-delete-cascade.js 18 | 19 | 'use strict'; 20 | 21 | function main(instanceId, databaseId, projectId) { 22 | // [START spanner_alter_table_with_foreign_key_delete_cascade] 23 | 24 | // Imports the Google Cloud client library 25 | const {Spanner} = require('@google-cloud/spanner'); 26 | 27 | /** 28 | * TODO(developer): Uncomment the following lines before running the sample. 29 | */ 30 | // const projectId = 'my-project-id'; 31 | // const instanceId = 'my-instance-id'; 32 | // const databaseId = 'my-database-id'; 33 | 34 | // Creates a client 35 | const spanner = new Spanner({ 36 | projectId: projectId, 37 | }); 38 | 39 | // Gets a reference to a Cloud Spanner instance and a database. The database does not need to exist. 40 | const instance = spanner.instance(instanceId); 41 | const database = instance.database(databaseId); 42 | 43 | async function alterTableWithForeignKeyDeleteCascade() { 44 | const [operation] = await database.updateSchema([ 45 | `ALTER TABLE ShoppingCarts 46 | ADD CONSTRAINT FKShoppingCartsCustomerName 47 | FOREIGN KEY (CustomerName) 48 | REFERENCES Customers(CustomerName) 49 | ON DELETE CASCADE`, 50 | ]); 51 | 52 | console.log(`Waiting for operation on ${databaseId} to complete...`); 53 | await operation.promise(); 54 | 55 | console.log('Altered ShoppingCarts table with FKShoppingCartsCustomerName'); 56 | } 57 | alterTableWithForeignKeyDeleteCascade(); 58 | // [END spanner_alter_table_with_foreign_key_delete_cascade] 59 | } 60 | process.on('unhandledRejection', err => { 61 | console.error(err.message); 62 | process.exitCode = 1; 63 | }); 64 | main(...process.argv.slice(2)); 65 | -------------------------------------------------------------------------------- /samples/archived/table-drop-foreign-key-constraint-delete-cascade.js: -------------------------------------------------------------------------------- 1 | // Copyright 2023 Google LLC 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | // sample-metadata: 16 | // title: Drops a foreign key constraint with delete cascade action 17 | // usage: node table-drop-foreign-key-constraint-delete-cascade.js 18 | 19 | 'use strict'; 20 | 21 | function main(instanceId, databaseId, projectId) { 22 | // [START spanner_drop_foreign_key_constraint_delete_cascade] 23 | 24 | // Imports the Google Cloud client library 25 | const {Spanner} = require('@google-cloud/spanner'); 26 | 27 | /** 28 | * TODO(developer): Uncomment the following lines before running the sample. 29 | */ 30 | // const projectId = 'my-project-id'; 31 | // const instanceId = 'my-instance-id'; 32 | // const databaseId = 'my-database-id'; 33 | 34 | // Creates a client 35 | const spanner = new Spanner({ 36 | projectId: projectId, 37 | }); 38 | 39 | // Gets a reference to a Cloud Spanner instance and a database. The database does not need to exist. 40 | const instance = spanner.instance(instanceId); 41 | const database = instance.database(databaseId); 42 | 43 | async function dropForeignKeyConstraintDeleteCascade() { 44 | const [operation] = await database.updateSchema([ 45 | `ALTER TABLE ShoppingCarts 46 | DROP CONSTRAINT FKShoppingCartsCustomerName`, 47 | ]); 48 | 49 | console.log(`Waiting for operation on ${databaseId} to complete...`); 50 | await operation.promise(); 51 | 52 | console.log( 53 | 'Altered ShoppingCarts table to drop FKShoppingCartsCustomerName', 54 | ); 55 | } 56 | dropForeignKeyConstraintDeleteCascade(); 57 | // [END spanner_drop_foreign_key_constraint_delete_cascade] 58 | } 59 | process.on('unhandledRejection', err => { 60 | console.error(err.message); 61 | process.exitCode = 1; 62 | }); 63 | main(...process.argv.slice(2)); 64 | -------------------------------------------------------------------------------- /samples/backups-delete.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2024 Google LLC 3 | * Licensed under the Apache License, Version 2.0 (the "License"); 4 | * you may not use this file except in compliance with the License. 5 | * You may obtain a copy of the License at 6 | * 7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | * 9 | * Unless required by applicable law or agreed to in writing, software 10 | * distributed under the License is distributed on an "AS IS" BASIS, 11 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | * See the License for the specific language governing permissions and 13 | * limitations under the License. 14 | */ 15 | 16 | 'use strict'; 17 | 18 | async function deleteBackup(instanceId, backupId, projectId) { 19 | // [START spanner_delete_backup] 20 | 21 | // Imports the Google Cloud client library 22 | const {Spanner} = require('@google-cloud/spanner'); 23 | 24 | /** 25 | * TODO(developer): Uncomment the following lines before running the sample. 26 | */ 27 | // const projectId = 'my-project-id'; 28 | // const instanceId = 'my-instance'; 29 | // const databaseId = 'my-database'; 30 | // const backupId = 'my-backup'; 31 | 32 | // Creates a client 33 | const spanner = new Spanner({ 34 | projectId: projectId, 35 | }); 36 | 37 | // Gets a reference to a Cloud Spanner Database Admin Client object 38 | const databaseAdminClient = spanner.getDatabaseAdminClient(); 39 | 40 | // Delete the backup 41 | console.log(`Deleting backup ${backupId}.`); 42 | await databaseAdminClient.deleteBackup({ 43 | name: databaseAdminClient.backupPath(projectId, instanceId, backupId), 44 | }); 45 | console.log('Backup deleted.'); 46 | 47 | // Verify backup no longer exists 48 | try { 49 | await databaseAdminClient.getBackup({ 50 | name: databaseAdminClient.backupPath(projectId, instanceId, backupId), 51 | }); 52 | console.error('Error: backup still exists.'); 53 | } catch (err) { 54 | console.log('Backup deleted.'); 55 | } 56 | // [END spanner_delete_backup] 57 | } 58 | 59 | module.exports.deleteBackup = deleteBackup; 60 | -------------------------------------------------------------------------------- /samples/backups-get-database-operations.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2024 Google LLC 3 | * Licensed under the Apache License, Version 2.0 (the "License"); 4 | * you may not use this file except in compliance with the License. 5 | * You may obtain a copy of the License at 6 | * 7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | * 9 | * Unless required by applicable law or agreed to in writing, software 10 | * distributed under the License is distributed on an "AS IS" BASIS, 11 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | * See the License for the specific language governing permissions and 13 | * limitations under the License. 14 | */ 15 | 16 | 'use strict'; 17 | 18 | async function getDatabaseOperations(instanceId, projectId) { 19 | // [START spanner_list_database_operations] 20 | 21 | // Imports the Google Cloud client library 22 | const {Spanner, protos} = require('@google-cloud/spanner'); 23 | 24 | /** 25 | * TODO(developer): Uncomment the following lines before running the sample. 26 | */ 27 | // const projectId = 'my-project-id'; 28 | // const instanceId = 'my-instance'; 29 | 30 | // Creates a client 31 | const spanner = new Spanner({ 32 | projectId: projectId, 33 | }); 34 | 35 | // Gets a reference to a Cloud Spanner Database Admin Client object 36 | const databaseAdminClient = spanner.getDatabaseAdminClient(); 37 | 38 | // List database operations 39 | try { 40 | const [databaseOperations] = 41 | await databaseAdminClient.listDatabaseOperations({ 42 | parent: databaseAdminClient.instancePath(projectId, instanceId), 43 | filter: 44 | '(metadata.@type:type.googleapis.com/google.spanner.admin.database.v1.OptimizeRestoredDatabaseMetadata)', 45 | }); 46 | console.log('Optimize Database Operations:'); 47 | databaseOperations.forEach(databaseOperation => { 48 | const metadata = 49 | protos.google.spanner.admin.database.v1.OptimizeRestoredDatabaseMetadata.decode( 50 | databaseOperation.metadata.value, 51 | ); 52 | console.log( 53 | `Database ${metadata.name} restored from backup is ` + 54 | `${metadata.progress.progressPercent}% optimized.`, 55 | ); 56 | }); 57 | } catch (err) { 58 | console.error('ERROR:', err); 59 | } 60 | // [END spanner_list_database_operations] 61 | } 62 | 63 | module.exports.getDatabaseOperations = getDatabaseOperations; 64 | -------------------------------------------------------------------------------- /samples/database-get-ddl.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2024 Google LLC 3 | * Licensed under the Apache License, Version 2.0 (the "License"); 4 | * you may not use this file except in compliance with the License. 5 | * You may obtain a copy of the License at 6 | * 7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | * 9 | * Unless required by applicable law or agreed to in writing, software 10 | * distributed under the License is distributed on an "AS IS" BASIS, 11 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | * See the License for the specific language governing permissions and 13 | * limitations under the License. 14 | */ 15 | 16 | // sample-metadata: 17 | // title: Gets the schema definition of an existing database 18 | // usage: node database-get-ddl.js 19 | 20 | 'use strict'; 21 | 22 | function main(instanceId, databaseId, projectId) { 23 | // [START spanner_get_database_ddl] 24 | /** 25 | * TODO(developer): Uncomment the following lines before running the sample. 26 | */ 27 | // const projectId = 'my-project-id'; 28 | // const instanceId = 'my-instance-id'; 29 | // const databaseId = 'my-database-id'; 30 | 31 | // Imports the Google Cloud client library 32 | const {Spanner} = require('@google-cloud/spanner'); 33 | 34 | // creates a client 35 | const spanner = new Spanner({ 36 | projectId: projectId, 37 | }); 38 | 39 | const databaseAdminClient = spanner.getDatabaseAdminClient(); 40 | 41 | async function getDatabaseDdl() { 42 | // Get the schema definition of the database. 43 | const [ddlStatements] = await databaseAdminClient.getDatabaseDdl({ 44 | database: databaseAdminClient.databasePath( 45 | projectId, 46 | instanceId, 47 | databaseId, 48 | ), 49 | }); 50 | 51 | console.log( 52 | `Retrieved database DDL for ${databaseAdminClient.databasePath( 53 | projectId, 54 | instanceId, 55 | databaseId, 56 | )}:`, 57 | ); 58 | ddlStatements.statements.forEach(element => { 59 | console.log(element); 60 | }); 61 | } 62 | getDatabaseDdl(); 63 | // [END spanner_get_database_ddl] 64 | } 65 | process.on('unhandledRejection', err => { 66 | console.error(err.message); 67 | process.exitCode = 1; 68 | }); 69 | main(...process.argv.slice(2)); 70 | -------------------------------------------------------------------------------- /samples/database-get-default-leader.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2021 Google LLC 3 | * Licensed under the Apache License, Version 2.0 (the "License"); 4 | * you may not use this file except in compliance with the License. 5 | * You may obtain a copy of the License at 6 | * 7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | * 9 | * Unless required by applicable law or agreed to in writing, software 10 | * distributed under the License is distributed on an "AS IS" BASIS, 11 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | * See the License for the specific language governing permissions and 13 | * limitations under the License. 14 | */ 15 | 16 | // sample-metadata: 17 | // title: Gets the default leader option of an existing database 18 | // usage: node database-get-default-leader.js 19 | 20 | 'use strict'; 21 | 22 | function main(instanceId, databaseId, projectId) { 23 | // [START spanner_query_information_schema_database_options] 24 | /** 25 | * TODO(developer): Uncomment the following lines before running the sample. 26 | */ 27 | // const projectId = 'my-project-id'; 28 | // const instanceId = 'my-instance-id'; 29 | // const databaseId = 'my-database-id'; 30 | 31 | // Imports the Google Cloud client library 32 | const {Spanner} = require('@google-cloud/spanner'); 33 | 34 | // Creates a client 35 | const spanner = new Spanner({ 36 | projectId: projectId, 37 | }); 38 | // Gets a reference to a Cloud Spanner instance and a database. 39 | const instance = spanner.instance(instanceId); 40 | const database = instance.database(databaseId); 41 | 42 | async function getDatabaseDdl() { 43 | // Get the default leader option for the database. 44 | const [rows] = await database.run({ 45 | sql: ` 46 | SELECT s.OPTION_NAME, s.OPTION_VALUE 47 | FROM INFORMATION_SCHEMA.DATABASE_OPTIONS s 48 | WHERE s.OPTION_NAME = 'default_leader'`, 49 | json: true, 50 | }); 51 | if (rows.length > 0) { 52 | const option = rows[0]; 53 | console.log( 54 | `The ${option.OPTION_NAME} for ${databaseId} is ${option.OPTION_VALUE}`, 55 | ); 56 | } else { 57 | console.log( 58 | `Database ${databaseId} does not have a value for option 'default_leader'`, 59 | ); 60 | } 61 | } 62 | getDatabaseDdl(); 63 | // [END spanner_query_information_schema_database_options] 64 | } 65 | process.on('unhandledRejection', err => { 66 | console.error(err.message); 67 | process.exitCode = 1; 68 | }); 69 | main(...process.argv.slice(2)); 70 | -------------------------------------------------------------------------------- /samples/delete-backup-schedule.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2024 Google LLC 3 | * Licensed under the Apache License, Version 2.0 (the "License"); 4 | * you may not use this file except in compliance with the License. 5 | * You may obtain a copy of the License at 6 | * 7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | * 9 | * Unless required by applicable law or agreed to in writing, software 10 | * distributed under the License is distributed on an "AS IS" BASIS, 11 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | * See the License for the specific language governing permissions and 13 | * limitations under the License. 14 | */ 15 | 16 | // sample-metadata: 17 | // title: Deletes a backup schedule 18 | // usage: node delete-backup-schedule.js 19 | 20 | 'use strict'; 21 | 22 | function main( 23 | projectId = 'my-project-id', 24 | instanceId = 'my-instance-id', 25 | databaseId = 'my-database-id', 26 | scheduleId = 'my-schedule-id', 27 | ) { 28 | async function deleteBackupSchedule() { 29 | // [START spanner_delete_backup_schedule] 30 | // Import the Google Cloud client library for Spanner. 31 | const {Spanner} = require('@google-cloud/spanner'); 32 | 33 | /** 34 | * TODO(developer): Uncomment these variables before running the sample. 35 | */ 36 | // const projectId = 'my-project-id'; 37 | // const instanceId = 'my-instance-id'; 38 | // const databaseId = 'my-database-id'; 39 | // const scheduleId = 'my-schedule-id'; 40 | 41 | // Create a Spanner database admin client. 42 | const spanner = new Spanner({projectId}); 43 | const client = spanner.getDatabaseAdminClient(); 44 | 45 | try { 46 | // Delete the backup schedule. 47 | await client.deleteBackupSchedule({ 48 | name: client.backupSchedulePath( 49 | projectId, 50 | instanceId, 51 | databaseId, 52 | scheduleId, 53 | ), 54 | }); 55 | console.log('Deleted backup schedule'); 56 | } catch (err) { 57 | console.error('ERROR:', err); 58 | } 59 | // [END spanner_delete_backup_schedule] 60 | } 61 | 62 | deleteBackupSchedule(); 63 | } 64 | 65 | process.on('unhandledRejection', err => { 66 | console.error(err.message); 67 | process.exitCode = 1; 68 | }); 69 | main(...process.argv.slice(2)); 70 | -------------------------------------------------------------------------------- /samples/get-backup-schedule.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2024 Google LLC 3 | * Licensed under the Apache License, Version 2.0 (the "License"); 4 | * you may not use this file except in compliance with the License. 5 | * You may obtain a copy of the License at 6 | * 7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | * 9 | * Unless required by applicable law or agreed to in writing, software 10 | * distributed under the License is distributed on an "AS IS" BASIS, 11 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | * See the License for the specific language governing permissions and 13 | * limitations under the License. 14 | */ 15 | 16 | // sample-metadata: 17 | // title: Gets a backup schedule 18 | // usage: node get-backup-schedule.js 19 | 20 | 'use strict'; 21 | 22 | function main( 23 | projectId = 'my-project-id', 24 | instanceId = 'my-instance-id', 25 | databaseId = 'my-database-id', 26 | scheduleId = 'my-schedule-id', 27 | ) { 28 | async function getBackupSchedule() { 29 | // [START spanner_get_backup_schedule] 30 | // Import the Google Cloud client library for Spanner. 31 | const {Spanner} = require('@google-cloud/spanner'); 32 | 33 | /** 34 | * TODO(developer): Uncomment these variables before running the sample. 35 | */ 36 | // const projectId = 'my-project-id'; 37 | // const instanceId = 'my-instance-id'; 38 | // const databaseId = 'my-database-id'; 39 | // const scheduleId = 'my-schedule-id'; 40 | 41 | // Create a Spanner database admin client. 42 | const spanner = new Spanner({projectId}); 43 | const client = spanner.getDatabaseAdminClient(); 44 | 45 | try { 46 | // Get the backup schedule. 47 | const [response] = await client.getBackupSchedule({ 48 | name: client.backupSchedulePath( 49 | projectId, 50 | instanceId, 51 | databaseId, 52 | scheduleId, 53 | ), 54 | }); 55 | console.log('Backup schedule:', response); 56 | } catch (err) { 57 | console.error('ERROR:', err); 58 | } 59 | // [END spanner_get_backup_schedule] 60 | } 61 | 62 | getBackupSchedule(); 63 | } 64 | 65 | process.on('unhandledRejection', err => { 66 | console.error(err.message); 67 | process.exitCode = 1; 68 | }); 69 | main(...process.argv.slice(2)); 70 | -------------------------------------------------------------------------------- /samples/get-commit-stats.js: -------------------------------------------------------------------------------- 1 | // Copyright 2021 Google LLC 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | 'use strict'; 16 | 17 | async function getCommitStats(instanceId, databaseId, projectId) { 18 | // [START spanner_get_commit_stats] 19 | // Imports the Google Cloud client library. 20 | const {Spanner} = require('@google-cloud/spanner'); 21 | 22 | /** 23 | * TODO(developer): Uncomment the following lines before running the sample. 24 | */ 25 | // const projectId = 'my-project-id'; 26 | // const instanceId = 'my-instance'; 27 | // const databaseId = 'my-database'; 28 | 29 | // Creates a client. 30 | const spanner = new Spanner({ 31 | projectId: projectId, 32 | }); 33 | 34 | // Gets a reference to a Cloud Spanner instance and database. 35 | const instance = spanner.instance(instanceId); 36 | const database = instance.database(databaseId); 37 | 38 | // Instantiate Spanner table objects. 39 | const albumsTable = database.table('Albums'); 40 | 41 | // Updates rows in the Venues table. 42 | try { 43 | const [response] = await albumsTable.upsert( 44 | [ 45 | {SingerId: '1', AlbumId: '1', MarketingBudget: '200000'}, 46 | {SingerId: '2', AlbumId: '2', MarketingBudget: '400000'}, 47 | ], 48 | {returnCommitStats: true}, 49 | ); 50 | console.log( 51 | `Updated data with ${response.commitStats.mutationCount} mutations.`, 52 | ); 53 | } catch (err) { 54 | console.error('ERROR:', err); 55 | } finally { 56 | // Close the database when finished. 57 | database.close(); 58 | } 59 | // [END spanner_get_commit_stats] 60 | } 61 | 62 | module.exports.getCommitStats = getCommitStats; 63 | -------------------------------------------------------------------------------- /samples/get-database-roles.js: -------------------------------------------------------------------------------- 1 | // Copyright 2024 Google LLC 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | // sample-metadata: 16 | // title: List database roles 17 | // usage: node get-database-roles.js 18 | 19 | 'use strict'; 20 | 21 | function main( 22 | instanceId = 'my-instance', 23 | databaseId = 'my-database', 24 | projectId = 'my-project-id', 25 | ) { 26 | // [START spanner_list_database_roles] 27 | /** 28 | * TODO(developer): Uncomment these variables before running the sample. 29 | */ 30 | // const instanceId = 'my-instance'; 31 | // const databaseId = 'my-database'; 32 | // const projectId = 'my-project-id'; 33 | 34 | // Imports the Google Cloud client library 35 | const {Spanner} = require('@google-cloud/spanner'); 36 | 37 | // creates a client 38 | const spanner = new Spanner({ 39 | projectId: projectId, 40 | }); 41 | 42 | const databaseAdminClient = spanner.getDatabaseAdminClient(); 43 | 44 | async function getDatabaseRoles() { 45 | // Fetching database roles 46 | const [databaseRoles] = await databaseAdminClient.listDatabaseRoles({ 47 | parent: databaseAdminClient.databasePath( 48 | projectId, 49 | instanceId, 50 | databaseId, 51 | ), 52 | }); 53 | console.log( 54 | `Roles for Database: ${databaseAdminClient.databasePath( 55 | projectId, 56 | instanceId, 57 | databaseId, 58 | )}`, 59 | ); 60 | databaseRoles.forEach(role => { 61 | console.log(`Role: ${role.name}`); 62 | }); 63 | } 64 | getDatabaseRoles(); 65 | // [END spanner_list_database_roles] 66 | } 67 | 68 | process.on('unhandledRejection', err => { 69 | console.error(err.message); 70 | process.exitCode = 1; 71 | }); 72 | main(...process.argv.slice(2)); 73 | -------------------------------------------------------------------------------- /samples/get-instance-config.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2024 Google LLC 3 | * Licensed under the Apache License, Version 2.0 (the "License"); 4 | * you may not use this file except in compliance with the License. 5 | * You may obtain a copy of the License at 6 | * 7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | * 9 | * Unless required by applicable law or agreed to in writing, software 10 | * distributed under the License is distributed on an "AS IS" BASIS, 11 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | * See the License for the specific language governing permissions and 13 | * limitations under the License. 14 | */ 15 | 16 | // sample-metadata: 17 | // title: Gets the instance config metadata for the configuration nam6 18 | // usage: node get-instance-config.js 19 | 20 | 'use strict'; 21 | 22 | function main(projectId) { 23 | // [START spanner_get_instance_config] 24 | 25 | /** 26 | * TODO(developer): Uncomment the following line before running the sample. 27 | */ 28 | // const projectId = 'my-project-id'; 29 | 30 | // Imports the Google Cloud client library 31 | const {Spanner} = require('@google-cloud/spanner'); 32 | 33 | // Creates a client 34 | const spanner = new Spanner({ 35 | projectId: projectId, 36 | }); 37 | 38 | const instanceAdminClient = spanner.getInstanceAdminClient(); 39 | 40 | async function getInstanceConfig() { 41 | // Get the instance config for the multi-region North America 6 (NAM6). 42 | // See https://cloud.google.com/spanner/docs/instance-configurations#configuration for a list of all available 43 | // configurations. 44 | const [instanceConfig] = await instanceAdminClient.getInstanceConfig({ 45 | name: instanceAdminClient.instanceConfigPath(projectId, 'nam6'), 46 | }); 47 | console.log( 48 | `Available leader options for instance config ${instanceConfig.name} ('${ 49 | instanceConfig.displayName 50 | }'): 51 | ${instanceConfig.leaderOptions.join()}`, 52 | ); 53 | } 54 | getInstanceConfig(); 55 | // [END spanner_get_instance_config] 56 | } 57 | process.on('unhandledRejection', err => { 58 | console.error(err.message); 59 | process.exitCode = 1; 60 | }); 61 | main(...process.argv.slice(2)); 62 | -------------------------------------------------------------------------------- /samples/index-read-data.js: -------------------------------------------------------------------------------- 1 | // Copyright 2021 Google LLC 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | // sample-metadata: 16 | // title: Read data using an existing index. 17 | // usage: node readDataWithIndex 18 | 19 | 'use strict'; 20 | 21 | function main( 22 | instanceId = 'my-instance', 23 | databaseId = 'my-database', 24 | projectId = 'my-project-id', 25 | ) { 26 | // [START spanner_read_data_with_index] 27 | /** 28 | * TODO(developer): Uncomment these variables before running the sample. 29 | */ 30 | // const instanceId = 'my-instance'; 31 | // const databaseId = 'my-database'; 32 | // const projectId = 'my-project-id'; 33 | 34 | // Imports the Google Cloud Spanner client library 35 | const {Spanner} = require('@google-cloud/spanner'); 36 | 37 | // Instantiates a client 38 | const spanner = new Spanner({ 39 | projectId: projectId, 40 | }); 41 | 42 | async function readDataWithIndex() { 43 | // Gets a reference to a Cloud Spanner instance and database 44 | const instance = spanner.instance(instanceId); 45 | const database = instance.database(databaseId); 46 | 47 | const albumsTable = database.table('Albums'); 48 | 49 | const query = { 50 | columns: ['AlbumId', 'AlbumTitle'], 51 | keySet: { 52 | all: true, 53 | }, 54 | index: 'AlbumsByAlbumTitle', 55 | }; 56 | 57 | // Reads the Albums table using an index 58 | try { 59 | const [rows] = await albumsTable.read(query); 60 | 61 | rows.forEach(row => { 62 | const json = row.toJSON(); 63 | console.log(`AlbumId: ${json.AlbumId}, AlbumTitle: ${json.AlbumTitle}`); 64 | }); 65 | } catch (err) { 66 | console.error('ERROR:', err); 67 | } finally { 68 | // Close the database when finished. 69 | database.close(); 70 | } 71 | } 72 | readDataWithIndex(); 73 | // [END spanner_read_data_with_index] 74 | } 75 | process.on('unhandledRejection', err => { 76 | console.error(err.message); 77 | process.exitCode = 1; 78 | }); 79 | main(...process.argv.slice(2)); 80 | -------------------------------------------------------------------------------- /samples/instance-config-delete.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2024 Google LLC 3 | * Licensed under the Apache License, Version 2.0 (the "License"); 4 | * you may not use this file except in compliance with the License. 5 | * You may obtain a copy of the License at 6 | * 7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | * 9 | * Unless required by applicable law or agreed to in writing, software 10 | * distributed under the License is distributed on an "AS IS" BASIS, 11 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | * See the License for the specific language governing permissions and 13 | * limitations under the License. 14 | */ 15 | 16 | // sample-metadata: 17 | // title: Deletes a user-managed instance configuration. 18 | // usage: node instance-config-delete 19 | 20 | 'use strict'; 21 | 22 | function main( 23 | instanceConfigId = 'custom-my-instance-config', 24 | projectId = 'my-project-id', 25 | ) { 26 | // [START spanner_delete_instance_config] 27 | /** 28 | * TODO(developer): Uncomment the following lines before running the sample. 29 | */ 30 | // const instanceConfigId = 'custom-my-instance-config-id'; 31 | // const projectId = 'my-project-id'; 32 | 33 | // Imports the Google Cloud client library 34 | const {Spanner} = require('@google-cloud/spanner'); 35 | 36 | // Creates a client 37 | const spanner = new Spanner({ 38 | projectId: projectId, 39 | }); 40 | 41 | const instanceAdminClient = spanner.getInstanceAdminClient(); 42 | 43 | async function deleteInstanceConfig() { 44 | // Deletes an instance config. 45 | 46 | try { 47 | // Delete the instance config. 48 | console.log(`Deleting ${instanceConfigId}...\n`); 49 | await instanceAdminClient.deleteInstanceConfig({ 50 | name: instanceAdminClient.instanceConfigPath( 51 | projectId, 52 | instanceConfigId, 53 | ), 54 | }); 55 | console.log(`Deleted instance config ${instanceConfigId}.\n`); 56 | } catch (err) { 57 | console.error( 58 | 'ERROR: Deleting instance config ', 59 | instanceConfigId, 60 | ' failed with error message ', 61 | err, 62 | ); 63 | } 64 | } 65 | deleteInstanceConfig(); 66 | // [END spanner_delete_instance_config] 67 | } 68 | 69 | process.on('unhandledRejection', err => { 70 | console.error(err.message); 71 | process.exitCode = 1; 72 | }); 73 | main(...process.argv.slice(2)); 74 | -------------------------------------------------------------------------------- /samples/json-add-column.js: -------------------------------------------------------------------------------- 1 | // Copyright 2024 Google LLC 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | 'use strict'; 16 | 17 | async function addJsonColumn(instanceId, databaseId, projectId) { 18 | // [START spanner_add_json_column] 19 | 20 | /** 21 | * TODO(developer): Uncomment the following lines before running the sample. 22 | */ 23 | // const projectId = 'my-project-id'; 24 | // const instanceId = 'my-instance'; 25 | // const databaseId = 'my-database'; 26 | 27 | // Imports the Google Cloud client library 28 | const {Spanner} = require('@google-cloud/spanner'); 29 | 30 | // creates a client 31 | const spanner = new Spanner({ 32 | projectId: projectId, 33 | }); 34 | 35 | const databaseAdminClient = spanner.getDatabaseAdminClient(); 36 | 37 | const request = ['ALTER TABLE Venues ADD COLUMN VenueDetails JSON']; 38 | 39 | // Alter existing table to add a column. 40 | const [operation] = await databaseAdminClient.updateDatabaseDdl({ 41 | database: databaseAdminClient.databasePath( 42 | projectId, 43 | instanceId, 44 | databaseId, 45 | ), 46 | statements: request, 47 | }); 48 | 49 | console.log(`Waiting for operation on ${databaseId} to complete...`); 50 | 51 | await operation.promise(); 52 | 53 | console.log( 54 | `Added VenueDetails column to Venues table in database ${databaseId}.`, 55 | ); 56 | // [END spanner_add_json_column] 57 | } 58 | 59 | module.exports.addJsonColumn = addJsonColumn; 60 | -------------------------------------------------------------------------------- /samples/json-query-parameter.js: -------------------------------------------------------------------------------- 1 | // Copyright 2021 Google LLC 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | 'use strict'; 16 | 17 | async function queryWithJsonParameter(instanceId, databaseId, projectId) { 18 | // [START spanner_query_with_json_parameter] 19 | // Imports the Google Cloud client library. 20 | const {Spanner} = require('@google-cloud/spanner'); 21 | 22 | /** 23 | * TODO(developer): Uncomment the following lines before running the sample. 24 | */ 25 | // const projectId = 'my-project-id'; 26 | // const instanceId = 'my-instance'; 27 | // const databaseId = 'my-database'; 28 | 29 | // Creates a client 30 | const spanner = new Spanner({ 31 | projectId: projectId, 32 | }); 33 | 34 | // Gets a reference to a Cloud Spanner instance and database. 35 | const instance = spanner.instance(instanceId); 36 | const database = instance.database(databaseId); 37 | 38 | const fieldType = { 39 | type: 'json', 40 | }; 41 | 42 | const jsonValue = {rating: 9}; 43 | 44 | const query = { 45 | sql: `SELECT VenueId, VenueDetails FROM Venues 46 | WHERE JSON_VALUE(VenueDetails, '$.rating') = JSON_VALUE(@details, '$.rating')`, 47 | params: { 48 | details: jsonValue, 49 | }, 50 | types: { 51 | details: fieldType, 52 | }, 53 | }; 54 | 55 | // Queries rows from the Venues table. 56 | try { 57 | const [rows] = await database.run(query); 58 | 59 | rows.forEach(row => { 60 | const json = row.toJSON(); 61 | console.log( 62 | `VenueId: ${json.VenueId}, Details: ${JSON.stringify( 63 | json.VenueDetails, 64 | )}`, 65 | ); 66 | }); 67 | } catch (err) { 68 | console.error('ERROR:', err); 69 | } finally { 70 | // Close the database when finished. 71 | database.close(); 72 | } 73 | // [END spanner_query_with_json_parameter] 74 | } 75 | 76 | module.exports.queryWithJsonParameter = queryWithJsonParameter; 77 | -------------------------------------------------------------------------------- /samples/list-backup-schedules.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2024 Google LLC 3 | * Licensed under the Apache License, Version 2.0 (the "License"); 4 | * you may not use this file except in compliance with the License. 5 | * You may obtain a copy of the License at 6 | * 7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | * 9 | * Unless required by applicable law or agreed to in writing, software 10 | * distributed under the License is distributed on an "AS IS" BASIS, 11 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | * See the License for the specific language governing permissions and 13 | * limitations under the License. 14 | */ 15 | 16 | // sample-metadata: 17 | // title: Lists backup schedules of a database 18 | // usage: node list-backup-schedules.js 19 | 20 | 'use strict'; 21 | 22 | function main( 23 | projectId = 'my-project-id', 24 | instanceId = 'my-instance-id', 25 | databaseId = 'my-database-id', 26 | ) { 27 | async function listBackupSchedules() { 28 | // [START spanner_list_backup_schedules] 29 | // Import the Google Cloud client library for Spanner. 30 | const {Spanner} = require('@google-cloud/spanner'); 31 | 32 | /** 33 | * TODO(developer): Uncomment these variables before running the sample. 34 | */ 35 | // const projectId = 'my-project-id'; 36 | // const instanceId = 'my-instance-id'; 37 | // const databaseId = 'my-database-id'; 38 | 39 | // Create a Spanner database admin client. 40 | const spanner = new Spanner({projectId}); 41 | const client = spanner.getDatabaseAdminClient(); 42 | 43 | try { 44 | // List backup schedules of a database. 45 | const [schedules] = await client.listBackupSchedules({ 46 | parent: client.databasePath(projectId, instanceId, databaseId), 47 | }); 48 | schedules.forEach(schedule => { 49 | console.log('Backup schedule:', schedule); 50 | }); 51 | } catch (err) { 52 | console.error('ERROR:', err); 53 | } 54 | // [END spanner_list_backup_schedules] 55 | } 56 | 57 | listBackupSchedules(); 58 | } 59 | 60 | process.on('unhandledRejection', err => { 61 | console.error(err.message); 62 | process.exitCode = 1; 63 | }); 64 | main(...process.argv.slice(2)); 65 | -------------------------------------------------------------------------------- /samples/list-databases.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2024 Google LLC 3 | * Licensed under the Apache License, Version 2.0 (the "License"); 4 | * you may not use this file except in compliance with the License. 5 | * You may obtain a copy of the License at 6 | * 7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | * 9 | * Unless required by applicable law or agreed to in writing, software 10 | * distributed under the License is distributed on an "AS IS" BASIS, 11 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | * See the License for the specific language governing permissions and 13 | * limitations under the License. 14 | */ 15 | 16 | // sample-metadata: 17 | // title: Lists all databases on the selected instance 18 | // usage: node list-databases.js 19 | 20 | 'use strict'; 21 | 22 | function main(instanceId, projectId) { 23 | // [START spanner_list_databases] 24 | /** 25 | * TODO(developer): Uncomment the following lines before running the sample. 26 | */ 27 | // const projectId = 'my-project-id'; 28 | // const instanceId = 'my-instance-id'; 29 | 30 | // Imports the Google Cloud client library 31 | const {Spanner} = require('@google-cloud/spanner'); 32 | 33 | // creates a client 34 | const spanner = new Spanner({ 35 | projectId: projectId, 36 | }); 37 | 38 | const databaseAdminClient = spanner.getDatabaseAdminClient(); 39 | 40 | async function listDatabases() { 41 | // Lists all databases on the instance. 42 | const [databases] = await databaseAdminClient.listDatabases({ 43 | parent: databaseAdminClient.instancePath(projectId, instanceId), 44 | }); 45 | console.log(`Databases for projects/${projectId}/instances/${instanceId}:`); 46 | databases.forEach(database => { 47 | const defaultLeader = database.defaultLeader 48 | ? `(default leader = ${database.defaultLeader})` 49 | : ''; 50 | console.log(`\t${database.name} ${defaultLeader}`); 51 | }); 52 | } 53 | listDatabases(); 54 | // [END spanner_list_databases] 55 | } 56 | process.on('unhandledRejection', err => { 57 | console.error(err.message); 58 | process.exitCode = 1; 59 | }); 60 | main(...process.argv.slice(2)); 61 | -------------------------------------------------------------------------------- /samples/list-instance-configs.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2024 Google LLC 3 | * Licensed under the Apache License, Version 2.0 (the "License"); 4 | * you may not use this file except in compliance with the License. 5 | * You may obtain a copy of the License at 6 | * 7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | * 9 | * Unless required by applicable law or agreed to in writing, software 10 | * distributed under the License is distributed on an "AS IS" BASIS, 11 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | * See the License for the specific language governing permissions and 13 | * limitations under the License. 14 | */ 15 | 16 | // sample-metadata: 17 | // title: Lists all the available instance configs for the selected project. 18 | // usage: node list-instance-configs.js 19 | 20 | 'use strict'; 21 | 22 | function main(projectId) { 23 | // [START spanner_list_instance_configs] 24 | /** 25 | * TODO(developer): Uncomment the following line before running the sample. 26 | */ 27 | // const projectId = 'my-project-id'; 28 | 29 | // Imports the Google Cloud client library 30 | const {Spanner} = require('@google-cloud/spanner'); 31 | 32 | // Creates a client 33 | const spanner = new Spanner({ 34 | projectId: projectId, 35 | }); 36 | 37 | const instanceAdminClient = spanner.getInstanceAdminClient(); 38 | 39 | async function listInstanceConfigs() { 40 | // Lists all available instance configurations in the project. 41 | // See https://cloud.google.com/spanner/docs/instance-configurations#configuration for a list of all available 42 | // configurations. 43 | const [instanceConfigs] = await instanceAdminClient.listInstanceConfigs({ 44 | parent: instanceAdminClient.projectPath(projectId), 45 | }); 46 | console.log(`Available instance configs for project ${projectId}:`); 47 | instanceConfigs.forEach(instanceConfig => { 48 | console.log( 49 | `Available leader options for instance config ${ 50 | instanceConfig.name 51 | } ('${instanceConfig.displayName}'): 52 | ${instanceConfig.leaderOptions.join()}`, 53 | ); 54 | }); 55 | } 56 | listInstanceConfigs(); 57 | // [END spanner_list_instance_configs] 58 | } 59 | process.on('unhandledRejection', err => { 60 | console.error(err.message); 61 | process.exitCode = 1; 62 | }); 63 | main(...process.argv.slice(2)); 64 | -------------------------------------------------------------------------------- /samples/numeric-add-column.js: -------------------------------------------------------------------------------- 1 | // Copyright 2024 Google LLC 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | 'use strict'; 16 | 17 | async function addNumericColumn(instanceId, databaseId, projectId) { 18 | // [START spanner_add_numeric_column] 19 | 20 | /** 21 | * TODO(developer): Uncomment the following lines before running the sample. 22 | */ 23 | // const projectId = 'my-project-id'; 24 | // const instanceId = 'my-instance'; 25 | // const databaseId = 'my-database'; 26 | 27 | // Imports the Google Cloud client library 28 | const {Spanner} = require('@google-cloud/spanner'); 29 | 30 | // creates a client 31 | const spanner = new Spanner({ 32 | projectId: projectId, 33 | }); 34 | 35 | const databaseAdminClient = spanner.getDatabaseAdminClient(); 36 | 37 | const request = ['ALTER TABLE Venues ADD COLUMN Revenue NUMERIC']; 38 | 39 | // Alter existing table to add a column. 40 | const [operation] = await databaseAdminClient.updateDatabaseDdl({ 41 | database: databaseAdminClient.databasePath( 42 | projectId, 43 | instanceId, 44 | databaseId, 45 | ), 46 | statements: request, 47 | }); 48 | 49 | console.log(`Waiting for operation on ${databaseId} to complete...`); 50 | 51 | await operation.promise(); 52 | 53 | console.log( 54 | `Added Revenue column to Venues table in database ${databaseId}.`, 55 | ); 56 | // [END spanner_add_numeric_column] 57 | } 58 | 59 | module.exports.addNumericColumn = addNumericColumn; 60 | -------------------------------------------------------------------------------- /samples/numeric-query-parameter.js: -------------------------------------------------------------------------------- 1 | // Copyright 2020 Google LLC 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | 'use strict'; 16 | 17 | async function queryWithNumericParameter(instanceId, databaseId, projectId) { 18 | // [START spanner_query_with_numeric_parameter] 19 | // Imports the Google Cloud client library. 20 | const {Spanner} = require('@google-cloud/spanner'); 21 | 22 | /** 23 | * TODO(developer): Uncomment the following lines before running the sample. 24 | */ 25 | // const projectId = 'my-project-id'; 26 | // const instanceId = 'my-instance'; 27 | // const databaseId = 'my-database'; 28 | 29 | // Creates a client 30 | const spanner = new Spanner({ 31 | projectId: projectId, 32 | }); 33 | 34 | // Gets a reference to a Cloud Spanner instance and database. 35 | const instance = spanner.instance(instanceId); 36 | const database = instance.database(databaseId); 37 | 38 | const fieldType = { 39 | type: 'numeric', 40 | }; 41 | 42 | const exampleNumeric = Spanner.numeric('100000'); 43 | 44 | const query = { 45 | sql: `SELECT VenueId, VenueName, Revenue FROM Venues 46 | WHERE Revenue < @revenue`, 47 | params: { 48 | revenue: exampleNumeric, 49 | }, 50 | types: { 51 | revenue: fieldType, 52 | }, 53 | }; 54 | 55 | // Queries rows from the Venues table. 56 | try { 57 | const [rows] = await database.run(query); 58 | 59 | rows.forEach(row => { 60 | const json = row.toJSON(); 61 | console.log(`VenueId: ${json.VenueId}, Revenue: ${json.Revenue.value}`); 62 | }); 63 | } catch (err) { 64 | console.error('ERROR:', err); 65 | } finally { 66 | // Close the database when finished. 67 | database.close(); 68 | } 69 | // [END spanner_query_with_numeric_parameter] 70 | } 71 | 72 | module.exports.queryWithNumericParameter = queryWithNumericParameter; 73 | -------------------------------------------------------------------------------- /samples/numeric-update-data.js: -------------------------------------------------------------------------------- 1 | // Copyright 2020 Google LLC 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | 'use strict'; 16 | 17 | async function updateWithNumericData(instanceId, databaseId, projectId) { 18 | // [START spanner_update_data_with_numeric_column] 19 | // Imports the Google Cloud client library. 20 | const {Spanner} = require('@google-cloud/spanner'); 21 | 22 | /** 23 | * TODO(developer): Uncomment the following lines before running the sample. 24 | */ 25 | // const projectId = 'my-project-id'; 26 | // const instanceId = 'my-instance'; 27 | // const databaseId = 'my-database'; 28 | 29 | // Creates a client. 30 | const spanner = new Spanner({ 31 | projectId: projectId, 32 | }); 33 | 34 | // Gets a reference to a Cloud Spanner instance and database. 35 | const instance = spanner.instance(instanceId); 36 | const database = instance.database(databaseId); 37 | 38 | // Instantiate Spanner table objects. 39 | const venuesTable = database.table('Venues'); 40 | 41 | const data = [ 42 | { 43 | VenueId: '4', 44 | Revenue: Spanner.numeric('35000'), 45 | LastUpdateTime: 'spanner.commit_timestamp()', 46 | }, 47 | { 48 | VenueId: '19', 49 | Revenue: Spanner.numeric('104500'), 50 | LastUpdateTime: 'spanner.commit_timestamp()', 51 | }, 52 | { 53 | VenueId: '42', 54 | Revenue: Spanner.numeric('99999999999999999999999999999.99'), 55 | LastUpdateTime: 'spanner.commit_timestamp()', 56 | }, 57 | ]; 58 | 59 | // Updates rows in the Venues table. 60 | try { 61 | await venuesTable.update(data); 62 | console.log('Updated data.'); 63 | } catch (err) { 64 | console.error('ERROR:', err); 65 | } finally { 66 | // Close the database when finished. 67 | database.close(); 68 | } 69 | // [END spanner_update_data_with_numeric_column] 70 | } 71 | 72 | module.exports.updateWithNumericData = updateWithNumericData; 73 | -------------------------------------------------------------------------------- /samples/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "nodejs-docs-samples-spanner", 3 | "private": true, 4 | "license": "Apache-2.0", 5 | "author": "Google Inc.", 6 | "repository": "googleapis/nodejs-spanner", 7 | "files": [ 8 | "*.js" 9 | ], 10 | "engines": { 11 | "node": ">=18" 12 | }, 13 | "scripts": { 14 | "test-with-archived": "mocha system-test --timeout 1600000", 15 | "test": "mocha system-test/spanner.test.js --timeout 1600000" 16 | }, 17 | "dependencies": { 18 | "@google-cloud/kms": "^5.0.0", 19 | "@google-cloud/precise-date": "^5.0.0", 20 | "@google-cloud/spanner": "^8.0.0", 21 | "protobufjs": "^7.0.0", 22 | "yargs": "^17.0.0" 23 | }, 24 | "devDependencies": { 25 | "@google-cloud/opentelemetry-cloud-trace-exporter": "^2.4.1", 26 | "@opentelemetry/exporter-trace-otlp-grpc": "^0.57.0", 27 | "@opentelemetry/instrumentation": "^0.57.0", 28 | "@opentelemetry/instrumentation-grpc": "^0.57.0", 29 | "@opentelemetry/resources": "1.30.1", 30 | "@opentelemetry/sdk-trace-base": "~1.30.1", 31 | "@opentelemetry/sdk-trace-node": "^1.30.1", 32 | "@opentelemetry/api": "^1.9.0", 33 | "@opentelemetry/core": "^1.30.1", 34 | "chai": "^4.2.0", 35 | "mocha": "^9.0.0", 36 | "p-limit": "^3.0.1" 37 | } 38 | } -------------------------------------------------------------------------------- /samples/pg-add-column.js: -------------------------------------------------------------------------------- 1 | // Copyright 2024 Google LLC 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | // sample-metadata: 16 | // title: Adds a column to an existing table in a Spanner PostgreSQL database. 17 | // usage: node pg-add-column.js 18 | 19 | 'use strict'; 20 | 21 | function main( 22 | instanceId = 'my-instance', 23 | databaseId = 'my-database', 24 | projectId = 'my-project-id', 25 | ) { 26 | // [START spanner_postgresql_add_column] 27 | /** 28 | * TODO(developer): Uncomment these variables before running the sample. 29 | */ 30 | // const instanceId = 'my-instance'; 31 | // const databaseId = 'my-database'; 32 | // const projectId = 'my-project-id'; 33 | 34 | // Imports the Google Cloud client library 35 | const {Spanner} = require('@google-cloud/spanner'); 36 | 37 | // creates a client 38 | const spanner = new Spanner({ 39 | projectId: projectId, 40 | }); 41 | 42 | const databaseAdminClient = spanner.getDatabaseAdminClient(); 43 | 44 | async function pgAddColumn() { 45 | const request = ['ALTER TABLE Albums ADD COLUMN MarketingBudget BIGINT']; 46 | 47 | // Alter existing table to add a column. 48 | const [operation] = await databaseAdminClient.updateDatabaseDdl({ 49 | database: databaseAdminClient.databasePath( 50 | projectId, 51 | instanceId, 52 | databaseId, 53 | ), 54 | statements: request, 55 | }); 56 | 57 | console.log(`Waiting for operation on ${databaseId} to complete...`); 58 | 59 | await operation.promise(); 60 | 61 | console.log( 62 | `Added MarketingBudget column to Albums table in database ${databaseId}.`, 63 | ); 64 | } 65 | pgAddColumn(); 66 | // [END spanner_postgresql_add_column] 67 | } 68 | 69 | process.on('unhandledRejection', err => { 70 | console.error(err.message); 71 | process.exitCode = 1; 72 | }); 73 | main(...process.argv.slice(2)); 74 | -------------------------------------------------------------------------------- /samples/pg-functions.js: -------------------------------------------------------------------------------- 1 | // Copyright 2022 Google LLC 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | // sample-metadata: 16 | // title: Calls a server side function on a Spanner PostgreSQL database. 17 | // usage: node pg-functions.js 18 | 19 | 'use strict'; 20 | 21 | function main( 22 | instanceId = 'my-instance', 23 | databaseId = 'my-database', 24 | projectId = 'my-project-id', 25 | ) { 26 | // [START spanner_postgresql_functions] 27 | /** 28 | * TODO(developer): Uncomment these variables before running the sample. 29 | */ 30 | // const instanceId = 'my-instance'; 31 | // const databaseId = 'my-database'; 32 | // const projectId = 'my-project-id'; 33 | 34 | // Imports the Google Cloud Spanner client library 35 | const {Spanner} = require('@google-cloud/spanner'); 36 | 37 | // Instantiates a client 38 | const spanner = new Spanner({ 39 | projectId: projectId, 40 | }); 41 | 42 | async function pgFunctions() { 43 | // Gets a reference to a Cloud Spanner instance and database 44 | const instance = spanner.instance(instanceId); 45 | const database = instance.database(databaseId); 46 | 47 | const query = { 48 | sql: 'SELECT to_timestamp(1284352323) AS time', 49 | }; 50 | 51 | // Use the PostgreSQL `to_timestamp` function to convert a number of seconds since epoch to a timestamp. 52 | try { 53 | const [rows] = await database.run(query); 54 | rows.forEach(row => { 55 | const json = row.toJSON(); 56 | console.log(`1284352323 seconds after epoch is ${json.time}`); 57 | }); 58 | } catch (err) { 59 | console.error('ERROR:', err); 60 | } finally { 61 | // Close the database when finished. 62 | await database.close(); 63 | } 64 | } 65 | pgFunctions(); 66 | // [END spanner_postgresql_functions] 67 | } 68 | 69 | process.on('unhandledRejection', err => { 70 | console.error(err.message); 71 | process.exitCode = 1; 72 | }); 73 | main(...process.argv.slice(2)); 74 | -------------------------------------------------------------------------------- /samples/pg-jsonb-add-column.js: -------------------------------------------------------------------------------- 1 | // Copyright 2024 Google LLC 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | // sample-metadata: 16 | // title: Showcase how add a jsonb column in a PostgreSQL table. 17 | // usage: node pg-jsonb-add-column.js 18 | 19 | 'use strict'; 20 | 21 | function main( 22 | instanceId = 'my-instance', 23 | databaseId = 'my-database', 24 | projectId = 'my-project-id', 25 | ) { 26 | // [START spanner_postgresql_jsonb_add_column] 27 | /** 28 | * TODO(developer): Uncomment these variables before running the sample. 29 | */ 30 | // const instanceId = 'my-instance'; 31 | // const databaseId = 'my-database'; 32 | // const projectId = 'my-project-id'; 33 | 34 | // Imports the Google Cloud Spanner client library 35 | const {Spanner} = require('@google-cloud/spanner'); 36 | 37 | // Instantiates a client 38 | const spanner = new Spanner({ 39 | projectId: projectId, 40 | }); 41 | 42 | async function pgJsonbAddColumn() { 43 | // Gets a reference to a Cloud Spanner Database Admin Client object 44 | const databaseAdminClient = spanner.getDatabaseAdminClient(); 45 | 46 | const request = ['ALTER TABLE Venues ADD COLUMN VenueDetails JSONB']; 47 | 48 | // Updates schema by adding a new table. 49 | const [operation] = await databaseAdminClient.updateDatabaseDdl({ 50 | database: databaseAdminClient.databasePath( 51 | projectId, 52 | instanceId, 53 | databaseId, 54 | ), 55 | statements: request, 56 | }); 57 | console.log(`Waiting for operation on ${databaseId} to complete...`); 58 | await operation.promise(); 59 | console.log( 60 | `Added jsonb column to table venues to database ${databaseId}.`, 61 | ); 62 | } 63 | pgJsonbAddColumn(); 64 | // [END spanner_postgresql_jsonb_add_column] 65 | } 66 | 67 | process.on('unhandledRejection', err => { 68 | console.error(err.message); 69 | process.exitCode = 1; 70 | }); 71 | main(...process.argv.slice(2)); 72 | -------------------------------------------------------------------------------- /samples/quickstart.js: -------------------------------------------------------------------------------- 1 | // Copyright 2016 Google LLC 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | 'use strict'; 16 | 17 | async function quickstart( 18 | projectId = 'YOUR-PROJECT-ID', // Your Google Cloud Platform project ID 19 | instanceId = 'my-instance', // Your Cloud Spanner instance ID 20 | databaseId = 'my-database', // Your Cloud Spanner database ID 21 | ) { 22 | // [START spanner_quickstart] 23 | // Imports the Google Cloud client library 24 | const {Spanner} = require('@google-cloud/spanner'); 25 | 26 | // Creates a client 27 | const spanner = new Spanner({projectId}); 28 | 29 | // Gets a reference to a Cloud Spanner instance and database 30 | const instance = spanner.instance(instanceId); 31 | const database = instance.database(databaseId); 32 | 33 | // The query to execute 34 | const query = { 35 | sql: 'SELECT 1', 36 | }; 37 | 38 | // Execute a simple SQL statement 39 | const [rows] = await database.run(query); 40 | console.log(`Query: ${rows.length} found.`); 41 | rows.forEach(row => console.log(row)); 42 | // [END spanner_quickstart] 43 | } 44 | 45 | const args = process.argv.slice(2); 46 | quickstart(...args).catch(console.error); 47 | -------------------------------------------------------------------------------- /samples/request-tag.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2021 Google LLC 3 | * Licensed under the Apache License, Version 2.0 (the "License"); 4 | * you may not use this file except in compliance with the License. 5 | * You may obtain a copy of the License at 6 | * 7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | * 9 | * Unless required by applicable law or agreed to in writing, software 10 | * distributed under the License is distributed on an "AS IS" BASIS, 11 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | * See the License for the specific language governing permissions and 13 | * limitations under the License. 14 | */ 15 | 16 | // sample-metadata: 17 | // title: Sets a request tag for a single query 18 | // usage: node request-tag.js 19 | 20 | 'use strict'; 21 | 22 | function main(instanceId, databaseId, projectId) { 23 | // [START spanner_set_request_tag] 24 | /** 25 | * TODO(developer): Uncomment the following lines before running the sample. 26 | */ 27 | // const projectId = 'my-project-id'; 28 | // const instanceId = 'my-instance'; 29 | // const databaseId = 'my-database'; 30 | 31 | // Imports the Google Cloud client library 32 | const {Spanner} = require('@google-cloud/spanner'); 33 | 34 | // Creates a client 35 | const spanner = new Spanner({ 36 | projectId: projectId, 37 | }); 38 | 39 | async function queryTags() { 40 | // Gets a reference to a Cloud Spanner instance and database. 41 | const instance = spanner.instance(instanceId); 42 | const database = instance.database(databaseId); 43 | 44 | // Execute a query with a request tag. 45 | const [albums] = await database.run({ 46 | sql: 'SELECT SingerId, AlbumId, AlbumTitle FROM Albums', 47 | requestOptions: {requestTag: 'app=concert,env=dev,action=select'}, 48 | json: true, 49 | }); 50 | albums.forEach(album => { 51 | console.log( 52 | `SingerId: ${album.SingerId}, AlbumId: ${album.AlbumId}, AlbumTitle: ${album.AlbumTitle}`, 53 | ); 54 | }); 55 | await database.close(); 56 | } 57 | queryTags(); 58 | // [END spanner_set_request_tag] 59 | } 60 | process.on('unhandledRejection', err => { 61 | console.error(err.message); 62 | process.exitCode = 1; 63 | }); 64 | main(...process.argv.slice(2)); 65 | -------------------------------------------------------------------------------- /samples/resource/README.md: -------------------------------------------------------------------------------- 1 | #### To generate singer.js and singer.d.ts file from singer.proto 2 | ```shell 3 | npm install -g protobufjs-cli 4 | cd samples/resource 5 | pbjs -t static-module -w commonjs -o singer.js singer.proto 6 | pbts -o singer.d.ts singer.js 7 | protoc --proto_path=. --include_imports --descriptor_set_out=descriptors.pb singer.proto 8 | ``` 9 | -------------------------------------------------------------------------------- /samples/resource/descriptors.pb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/googleapis/nodejs-spanner/57d67be2e3b6d6ac2a8a903acf8613b27a049c3b/samples/resource/descriptors.pb -------------------------------------------------------------------------------- /samples/resource/singer.proto: -------------------------------------------------------------------------------- 1 | // Copyright 2023 Google LLC 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | syntax = "proto3"; 16 | 17 | package examples.spanner.music; 18 | 19 | message SingerInfo { 20 | optional int64 singer_id = 1; 21 | optional string birth_date = 2; 22 | optional string nationality = 3; 23 | optional Genre genre = 4; 24 | } 25 | 26 | enum Genre { 27 | POP = 0; 28 | JAZZ = 1; 29 | FOLK = 2; 30 | ROCK = 3; 31 | } 32 | -------------------------------------------------------------------------------- /samples/table-alter-with-foreign-key-delete-cascade.js: -------------------------------------------------------------------------------- 1 | // Copyright 2024 Google LLC 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | // sample-metadata: 16 | // title: Alters a table with foreign key delete cascade action 17 | // usage: node table-alter-with-foreign-key-delete-cascade.js 18 | 19 | 'use strict'; 20 | 21 | function main(instanceId, databaseId, projectId) { 22 | // [START spanner_alter_table_with_foreign_key_delete_cascade] 23 | 24 | /** 25 | * TODO(developer): Uncomment the following lines before running the sample. 26 | */ 27 | // const projectId = 'my-project-id'; 28 | // const instanceId = 'my-instance-id'; 29 | // const databaseId = 'my-database-id'; 30 | 31 | // Imports the Google Cloud client library 32 | const {Spanner} = require('@google-cloud/spanner'); 33 | 34 | // creates a client 35 | const spanner = new Spanner({ 36 | projectId: projectId, 37 | }); 38 | 39 | const databaseAdminClient = spanner.getDatabaseAdminClient(); 40 | 41 | async function alterTableWithForeignKeyDeleteCascade() { 42 | const request = [ 43 | `ALTER TABLE ShoppingCarts 44 | ADD CONSTRAINT FKShoppingCartsCustomerName 45 | FOREIGN KEY (CustomerName) 46 | REFERENCES Customers(CustomerName) 47 | ON DELETE CASCADE`, 48 | ]; 49 | const [operation] = await databaseAdminClient.updateDatabaseDdl({ 50 | database: databaseAdminClient.databasePath( 51 | projectId, 52 | instanceId, 53 | databaseId, 54 | ), 55 | statements: request, 56 | }); 57 | 58 | console.log(`Waiting for operation on ${databaseId} to complete...`); 59 | await operation.promise(); 60 | 61 | console.log('Altered ShoppingCarts table with FKShoppingCartsCustomerName'); 62 | } 63 | alterTableWithForeignKeyDeleteCascade(); 64 | // [END spanner_alter_table_with_foreign_key_delete_cascade] 65 | } 66 | process.on('unhandledRejection', err => { 67 | console.error(err.message); 68 | process.exitCode = 1; 69 | }); 70 | main(...process.argv.slice(2)); 71 | -------------------------------------------------------------------------------- /samples/table-drop-foreign-key-constraint-delete-cascade.js: -------------------------------------------------------------------------------- 1 | // Copyright 2024 Google LLC 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | // sample-metadata: 16 | // title: Drops a foreign key constraint with delete cascade action 17 | // usage: node table-drop-foreign-key-constraint-delete-cascade.js 18 | 19 | 'use strict'; 20 | 21 | function main(instanceId, databaseId, projectId) { 22 | // [START spanner_drop_foreign_key_constraint_delete_cascade] 23 | 24 | /** 25 | * TODO(developer): Uncomment the following lines before running the sample. 26 | */ 27 | // const projectId = 'my-project-id'; 28 | // const instanceId = 'my-instance-id'; 29 | // const databaseId = 'my-database-id'; 30 | 31 | // Imports the Google Cloud client library 32 | const {Spanner} = require('@google-cloud/spanner'); 33 | 34 | // creates a client 35 | const spanner = new Spanner({ 36 | projectId: projectId, 37 | }); 38 | 39 | const databaseAdminClient = spanner.getDatabaseAdminClient(); 40 | 41 | async function dropForeignKeyConstraintDeleteCascade() { 42 | const request = [ 43 | `ALTER TABLE ShoppingCarts 44 | DROP CONSTRAINT FKShoppingCartsCustomerName`, 45 | ]; 46 | 47 | const [operation] = await databaseAdminClient.updateDatabaseDdl({ 48 | database: databaseAdminClient.databasePath( 49 | projectId, 50 | instanceId, 51 | databaseId, 52 | ), 53 | statements: request, 54 | }); 55 | 56 | console.log(`Waiting for operation on ${databaseId} to complete...`); 57 | await operation.promise(); 58 | 59 | console.log( 60 | 'Altered ShoppingCarts table to drop FKShoppingCartsCustomerName', 61 | ); 62 | } 63 | dropForeignKeyConstraintDeleteCascade(); 64 | // [END spanner_drop_foreign_key_constraint_delete_cascade] 65 | } 66 | process.on('unhandledRejection', err => { 67 | console.error(err.message); 68 | process.exitCode = 1; 69 | }); 70 | main(...process.argv.slice(2)); 71 | -------------------------------------------------------------------------------- /scripts/cleanup.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * Copyright 2018 Google LLC. All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | const {Spanner} = require('../'); 18 | const pLimit = require('p-limit'); 19 | const {describe, it} = require('mocha'); 20 | const spanner = new Spanner({projectId: process.env.GCLOUD_PROJECT}); 21 | 22 | // Delete instances that are 1 hour old. 23 | const STALE_THRESHOLD = 60 * 60; 24 | 25 | const CURRENT_DATE = new Date(); 26 | 27 | async function deleteStaleInstances(labelFilter) { 28 | const [instances] = await spanner.getInstances({}); 29 | 30 | const filtered = instances.filter(instance => { 31 | return labelFilter(instance.metadata.labels); 32 | }); 33 | 34 | const limit = pLimit(5); 35 | await Promise.all( 36 | filtered.map(instance => 37 | limit(() => 38 | setTimeout(() => { 39 | instance.delete(); 40 | }, 500), 41 | ), 42 | ), 43 | ); 44 | } 45 | 46 | describe('Clean up', () => { 47 | it('should clean up stale instances', async () => { 48 | // Remove instances with label { created: Date } that's older than STALE_THRESHOLD 49 | const labelFilter = labels => { 50 | if (labels.created) { 51 | const creationDate = new Date(labels.created * 1000); 52 | return ( 53 | CURRENT_DATE.valueOf() - creationDate.valueOf() > 54 | STALE_THRESHOLD * 1000 55 | ); 56 | } 57 | return false; 58 | }; 59 | 60 | await deleteStaleInstances(labelFilter); 61 | }); 62 | }); 63 | -------------------------------------------------------------------------------- /src/extra_proto_list.json: -------------------------------------------------------------------------------- 1 | ["../node_modules/google-gax/build/protos/google/rpc/error_details.proto"] 2 | -------------------------------------------------------------------------------- /src/metrics/README.md: -------------------------------------------------------------------------------- 1 | # Custom Metric Exporter 2 | The custom metric exporter, as defined in [spanner-metrics-exporter.ts](./spanner-metrics-exporter.ts), is designed to work in conjunction with OpenTelemetry and the Spanner client. It converts data into its protobuf equivalent and sends it to Google Cloud Monitoring. 3 | 4 | ## Filtering Criteria 5 | The exporter filters metrics based on the following conditions, utilizing values defined in [constants.ts](./constants.ts): 6 | 7 | * Metrics with a scope set to `spanner-nodejs`. 8 | * Metrics with one of the following predefined names: 9 | * `attempt_latencies` 10 | * `attempt_count` 11 | * `operation_latencies` 12 | * `operation_count` 13 | * `gfe_latencies` 14 | * `gfe_connectivity_error_count` 15 | 16 | ## Service Endpoint 17 | The exporter sends metrics to the Google Cloud Monitoring [service endpoint](https://cloud.google.com/python/docs/reference/monitoring/latest/google.cloud.monitoring_v3.services.metric_service.MetricServiceClient#google_cloud_monitoring_v3_services_metric_service_MetricServiceClient_create_service_time_series), distinct from the regular client endpoint. This service endpoint operates under a different quota limit than the user endpoint and features an additional server-side filter that only permits a predefined set of metrics to pass through. 18 | 19 | When introducing new service metrics, it is essential to ensure they are allowed through by the server-side filter as well. -------------------------------------------------------------------------------- /src/metrics/external-types.ts: -------------------------------------------------------------------------------- 1 | // Copyright 2025 Google LLC 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | import {GoogleAuth} from 'google-auth-library'; 16 | 17 | export interface ExporterOptions { 18 | /** 19 | * Optional authentication options for Google services. 20 | */ 21 | auth: GoogleAuth; 22 | } 23 | 24 | export enum MetricKind { 25 | UNSPECIFIED = 'METRIC_KIND_UNSPECIFIED', 26 | GAUGE = 'GAUGE', 27 | DELTA = 'DELTA', 28 | CUMULATIVE = 'CUMULATIVE', 29 | } 30 | 31 | /** The value type of a metric. */ 32 | export enum ValueType { 33 | VALUE_TYPE_UNSPECIFIED = 'VALUE_TYPE_UNSPECIFIED', 34 | INT64 = 'INT64', 35 | DOUBLE = 'DOUBLE', 36 | DISTRIBUTION = 'DISTRIBUTION', 37 | } 38 | -------------------------------------------------------------------------------- /src/spanner_grpc_config.json: -------------------------------------------------------------------------------- 1 | { 2 | "channelPool": { 3 | "maxSize": 10, 4 | "maxConcurrentStreamsLowWatermark": 100 5 | }, 6 | "method": [ 7 | { 8 | "name": ["/google.spanner.v1.Spanner/CreateSession"], 9 | "affinity": { 10 | "command": "BIND", 11 | "affinityKey": "name" 12 | } 13 | }, 14 | { 15 | "name": ["/google.spanner.v1.Spanner/GetSession"], 16 | "affinity": { 17 | "command": "BOUND", 18 | "affinityKey": "name" 19 | } 20 | }, 21 | { 22 | "name": ["/google.spanner.v1.Spanner/DeleteSession"], 23 | "affinity": { 24 | "command": "UNBIND", 25 | "affinityKey": "name" 26 | } 27 | }, 28 | { 29 | "name": ["/google.spanner.v1.Spanner/ExecuteSql"], 30 | "affinity": { 31 | "command": "BOUND", 32 | "affinityKey": "session" 33 | } 34 | }, 35 | { 36 | "name": ["/google.spanner.v1.Spanner/ExecuteStreamingSql"], 37 | "affinity": { 38 | "command": "BOUND", 39 | "affinityKey": "session" 40 | } 41 | }, 42 | { 43 | "name": ["/google.spanner.v1.Spanner/Read"], 44 | "affinity": { 45 | "command": "BOUND", 46 | "affinityKey": "session" 47 | } 48 | }, 49 | { 50 | "name": ["/google.spanner.v1.Spanner/StreamingRead"], 51 | "affinity": { 52 | "command": "BOUND", 53 | "affinityKey": "session" 54 | } 55 | }, 56 | { 57 | "name": ["/google.spanner.v1.Spanner/BeginTransaction"], 58 | "affinity": { 59 | "command": "BOUND", 60 | "affinityKey": "session" 61 | } 62 | }, 63 | { 64 | "name": ["/google.spanner.v1.Spanner/Commit"], 65 | "affinity": { 66 | "command": "BOUND", 67 | "affinityKey": "session" 68 | } 69 | }, 70 | { 71 | "name": ["/google.spanner.v1.Spanner/Rollback"], 72 | "affinity": { 73 | "command": "BOUND", 74 | "affinityKey": "session" 75 | } 76 | }, 77 | { 78 | "name": ["/google.spanner.v1.Spanner/PartitionQuery"], 79 | "affinity": { 80 | "command": "BOUND", 81 | "affinityKey": "session" 82 | } 83 | }, 84 | { 85 | "name": ["/google.spanner.v1.Spanner/PartitionRead"], 86 | "affinity": { 87 | "command": "BOUND", 88 | "affinityKey": "session" 89 | } 90 | } 91 | ] 92 | } 93 | -------------------------------------------------------------------------------- /src/v1/database_admin_proto_list.json: -------------------------------------------------------------------------------- 1 | [ 2 | "../../protos/google/spanner/admin/database/v1/backup.proto", 3 | "../../protos/google/spanner/admin/database/v1/backup_schedule.proto", 4 | "../../protos/google/spanner/admin/database/v1/common.proto", 5 | "../../protos/google/spanner/admin/database/v1/spanner_database_admin.proto" 6 | ] 7 | -------------------------------------------------------------------------------- /src/v1/gapic_metadata.json: -------------------------------------------------------------------------------- 1 | { 2 | "schema": "1.0", 3 | "comment": "This file maps proto services/RPCs to the corresponding library clients/methods", 4 | "language": "typescript", 5 | "protoPackage": "google.spanner.executor.v1", 6 | "libraryPackage": "@google-cloud/executor", 7 | "services": { 8 | "SpannerExecutorProxy": { 9 | "clients": { 10 | "grpc": { 11 | "libraryClient": "SpannerExecutorProxyClient", 12 | "rpcs": { 13 | "ExecuteActionAsync": { 14 | "methods": [ 15 | "executeActionAsync" 16 | ] 17 | } 18 | } 19 | }, 20 | "grpc-fallback": { 21 | "libraryClient": "SpannerExecutorProxyClient", 22 | "rpcs": {} 23 | } 24 | } 25 | } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/v1/index.ts: -------------------------------------------------------------------------------- 1 | // Copyright 2020 Google LLC 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // https://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | // 15 | // ** This file is automatically generated by gapic-generator-typescript. ** 16 | // ** https://github.com/googleapis/gapic-generator-typescript ** 17 | // ** All changes to this file may be overwritten. ** 18 | 19 | export {SpannerClient} from './spanner_client'; 20 | export {DatabaseAdminClient} from './database_admin_client'; 21 | export {InstanceAdminClient} from './instance_admin_client'; 22 | export {SpannerExecutorProxyClient} from './spanner_executor_proxy_client'; 23 | -------------------------------------------------------------------------------- /src/v1/instance_admin_proto_list.json: -------------------------------------------------------------------------------- 1 | [ 2 | "../../protos/google/spanner/admin/instance/v1/common.proto", 3 | "../../protos/google/spanner/admin/instance/v1/spanner_instance_admin.proto" 4 | ] 5 | -------------------------------------------------------------------------------- /src/v1/spanner_executor_proxy_client_config.json: -------------------------------------------------------------------------------- 1 | { 2 | "interfaces": { 3 | "google.spanner.executor.v1.SpannerExecutorProxy": { 4 | "retry_codes": { 5 | "non_idempotent": [], 6 | "idempotent": [ 7 | "DEADLINE_EXCEEDED", 8 | "UNAVAILABLE" 9 | ] 10 | }, 11 | "retry_params": { 12 | "default": { 13 | "initial_retry_delay_millis": 100, 14 | "retry_delay_multiplier": 1.3, 15 | "max_retry_delay_millis": 60000, 16 | "initial_rpc_timeout_millis": 60000, 17 | "rpc_timeout_multiplier": 1, 18 | "max_rpc_timeout_millis": 60000, 19 | "total_timeout_millis": 600000 20 | } 21 | }, 22 | "methods": { 23 | "ExecuteActionAsync": { 24 | "retry_codes_name": "non_idempotent", 25 | "retry_params_name": "default" 26 | } 27 | } 28 | } 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/v1/spanner_executor_proxy_proto_list.json: -------------------------------------------------------------------------------- 1 | [ 2 | "../../protos/google/spanner/admin/database/v1/backup.proto", 3 | "../../protos/google/spanner/admin/database/v1/backup_schedule.proto", 4 | "../../protos/google/spanner/admin/database/v1/common.proto", 5 | "../../protos/google/spanner/admin/instance/v1/common.proto", 6 | "../../protos/google/spanner/executor/v1/cloud_executor.proto", 7 | "../../protos/google/spanner/v1/commit_response.proto", 8 | "../../protos/google/spanner/v1/keys.proto", 9 | "../../protos/google/spanner/v1/mutation.proto", 10 | "../../protos/google/spanner/v1/query_plan.proto", 11 | "../../protos/google/spanner/v1/result_set.proto", 12 | "../../protos/google/spanner/v1/transaction.proto", 13 | "../../protos/google/spanner/v1/type.proto" 14 | ] 15 | -------------------------------------------------------------------------------- /src/v1/spanner_proto_list.json: -------------------------------------------------------------------------------- 1 | [ 2 | "../../protos/google/spanner/v1/change_stream.proto", 3 | "../../protos/google/spanner/v1/commit_response.proto", 4 | "../../protos/google/spanner/v1/keys.proto", 5 | "../../protos/google/spanner/v1/mutation.proto", 6 | "../../protos/google/spanner/v1/query_plan.proto", 7 | "../../protos/google/spanner/v1/result_set.proto", 8 | "../../protos/google/spanner/v1/spanner.proto", 9 | "../../protos/google/spanner/v1/transaction.proto", 10 | "../../protos/google/spanner/v1/type.proto" 11 | ] 12 | -------------------------------------------------------------------------------- /system-test/fixtures/sample/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "spanner-sample-fixture", 3 | "description": "An app we're using to test the library.", 4 | "scripts": { 5 | "check": "gts check", 6 | "clean": "gts clean", 7 | "compile": "tsc -p .", 8 | "fix": "gts fix", 9 | "prepare": "npm run compile", 10 | "pretest": "npm run compile", 11 | "posttest": "npm run check", 12 | "start": "node build/src/index.js" 13 | }, 14 | "license": "Apache-2.0", 15 | "dependencies": { 16 | "@google-cloud/spanner": "file:./spanner.tgz" 17 | }, 18 | "devDependencies": { 19 | "@types/node": "^22.0.0", 20 | "typescript": "^4.0.0", 21 | "gts": "^3.0.0" 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /system-test/fixtures/sample/src/index.ts: -------------------------------------------------------------------------------- 1 | import {Spanner} from '@google-cloud/spanner'; 2 | async function main() { 3 | const spanner = new Spanner(); 4 | console.log(spanner); 5 | } 6 | main(); 7 | -------------------------------------------------------------------------------- /system-test/fixtures/sample/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./node_modules/gts/tsconfig-google.json", 3 | "compilerOptions": { 4 | "rootDir": ".", 5 | "outDir": "build", 6 | "types": ["node"] 7 | }, 8 | "include": [ 9 | "src/*.ts" 10 | ] 11 | } 12 | -------------------------------------------------------------------------------- /system-test/install.ts: -------------------------------------------------------------------------------- 1 | // Copyright 2019 Google LLC 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | import * as execa from 'execa'; 16 | import * as mv from 'mv'; 17 | import {ncp} from 'ncp'; 18 | import * as tmp from 'tmp'; 19 | import {promisify} from 'util'; 20 | import {describe, it, after} from 'mocha'; 21 | 22 | const keep = false; 23 | const mvp = promisify(mv) as {} as (...args: string[]) => Promise; 24 | const ncpp = promisify(ncp); 25 | const stagingDir = tmp.dirSync({keep, unsafeCleanup: true}); 26 | const stagingPath = stagingDir.name; 27 | // eslint-disable-next-line @typescript-eslint/no-var-requires 28 | const pkg = require('../../package.json'); 29 | 30 | describe('📦 pack and install', () => { 31 | /** 32 | * Create a staging directory with temp fixtures used to test on a fresh 33 | * application. 34 | */ 35 | it('should be able to use the d.ts', async () => { 36 | await execa('npm', ['pack', '--unsafe-perm']); 37 | const tarball = `google-cloud-spanner-${pkg.version}.tgz`; 38 | await mvp(tarball, `${stagingPath}/spanner.tgz`); 39 | await ncpp('system-test/fixtures/sample', `${stagingPath}/`); 40 | await execa('npm', ['install', '--unsafe-perm'], { 41 | cwd: `${stagingPath}/`, 42 | stdio: 'inherit', 43 | }); 44 | await execa('node', ['--throw-deprecation', 'build/src/index.js'], { 45 | cwd: `${stagingPath}/`, 46 | stdio: 'inherit', 47 | }); 48 | }); 49 | 50 | /** 51 | * CLEAN UP - remove the staging directory when done. 52 | */ 53 | after('cleanup staging', () => { 54 | if (!keep) { 55 | stagingDir.removeCallback(); 56 | } 57 | }); 58 | }); 59 | -------------------------------------------------------------------------------- /test/data/README.md: -------------------------------------------------------------------------------- 1 | #### To generate singer.js and singer.d.ts file from singer.proto 2 | ```shell 3 | npm install -g protobufjs-cli 4 | cd test/data 5 | pbjs -t static-module -w commonjs -o singer.js singer.proto 6 | pbts -o singer.d.ts singer.js 7 | protoc --proto_path=. --include_imports --descriptor_set_out=descriptors.pb singer.proto 8 | ``` 9 | -------------------------------------------------------------------------------- /test/data/descriptors.pb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/googleapis/nodejs-spanner/57d67be2e3b6d6ac2a8a903acf8613b27a049c3b/test/data/descriptors.pb -------------------------------------------------------------------------------- /test/data/singer.proto: -------------------------------------------------------------------------------- 1 | // Copyright 2023 Google LLC 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | syntax = "proto3"; 16 | 17 | package examples.spanner.music; 18 | 19 | message SingerInfo { 20 | optional int64 singer_id = 1; 21 | optional string birth_date = 2; 22 | optional string nationality = 3; 23 | optional Genre genre = 4; 24 | } 25 | 26 | enum Genre { 27 | POP = 0; 28 | JAZZ = 1; 29 | FOLK = 2; 30 | ROCK = 3; 31 | } 32 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./node_modules/gts/tsconfig-google.json", 3 | "compilerOptions": { 4 | "rootDir": ".", 5 | "outDir": "build", 6 | "noImplicitAny": false, 7 | "resolveJsonModule": true, 8 | "lib": [ 9 | "es2018", 10 | "dom" 11 | ] 12 | }, 13 | "include": [ 14 | "src/*.ts", 15 | "src/**/*.ts", 16 | "src/v1/*.d.ts", 17 | "src/**/*.js", 18 | "src/**/*.json", 19 | "test/*.ts", 20 | "test/**/*.ts", 21 | "system-test/*.ts", 22 | "benchmark/*.ts", 23 | "observability-test/*.ts", 24 | "src/**/*.json", 25 | "system-test/*.ts", 26 | "protos/protos.json", 27 | "samples/**/*.d.ts" 28 | ] 29 | } 30 | -------------------------------------------------------------------------------- /webpack.config.js: -------------------------------------------------------------------------------- 1 | // Copyright 2021 Google LLC 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // https://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | const path = require('path'); 16 | 17 | module.exports = { 18 | entry: './src/index.ts', 19 | output: { 20 | library: 'spanner', 21 | filename: './spanner.js', 22 | }, 23 | node: { 24 | child_process: 'empty', 25 | fs: 'empty', 26 | crypto: 'empty', 27 | }, 28 | resolve: { 29 | alias: { 30 | '../../../package.json': path.resolve(__dirname, 'package.json'), 31 | }, 32 | extensions: ['.js', '.json', '.ts'], 33 | }, 34 | module: { 35 | rules: [ 36 | { 37 | test: /\.tsx?$/, 38 | use: 'ts-loader', 39 | exclude: /node_modules/, 40 | }, 41 | { 42 | test: /node_modules[\\/]@grpc[\\/]grpc-js/, 43 | use: 'null-loader', 44 | }, 45 | { 46 | test: /node_modules[\\/]grpc/, 47 | use: 'null-loader', 48 | }, 49 | { 50 | test: /node_modules[\\/]retry-request/, 51 | use: 'null-loader', 52 | }, 53 | { 54 | test: /node_modules[\\/]https?-proxy-agent/, 55 | use: 'null-loader', 56 | }, 57 | { 58 | test: /node_modules[\\/]gtoken/, 59 | use: 'null-loader', 60 | }, 61 | ], 62 | }, 63 | mode: 'production', 64 | }; 65 | --------------------------------------------------------------------------------