From 14ae01cd82e455a0dc22d7e3bb8c362e541ede12 Mon Sep 17 00:00:00 2001 From: Arpan Mishra Date: Thu, 15 Feb 2024 13:52:16 +0530 Subject: [PATCH] docs: samples and tests for database Admin APIs. (#2775) Adds samples and tests for auto-generated Database Admin APIs. --- README.md | 23 ++- samples/pom.xml | 1 + .../generated/AddAndDropDatabaseRole.java | 75 +++++++++ .../admin/generated/AddJsonColumnSample.java | 49 ++++++ .../admin/generated/AddJsonbColumnSample.java | 50 ++++++ .../generated/AddNumericColumnSample.java | 50 ++++++ .../admin/generated/AlterSequenceSample.java | 98 +++++++++++ ...ableWithForeignKeyDeleteCascadeSample.java | 56 +++++++ ...CreateDatabaseWithDefaultLeaderSample.java | 76 --------- ...abaseWithVersionRetentionPeriodSample.java | 71 ++++++++ .../generated/CreateInstanceExample.java | 56 +++---- .../admin/generated/CreateSequenceSample.java | 102 ++++++++++++ ...ableWithForeignKeyDeleteCascadeSample.java | 63 ++++++++ ...reignKeyConstraintDeleteCascadeSample.java | 53 ++++++ .../admin/generated/DropSequenceSample.java | 66 ++++++++ .../generated/EnableFineGrainedAccess.java | 106 ++++++++++++ .../admin/generated/GetDatabaseDdlSample.java | 49 ++++++ .../admin/generated/ListDatabaseRoles.java | 52 ++++++ .../admin/generated/ListDatabasesSample.java | 54 +++++++ .../generated/PgAlterSequenceSample.java | 92 +++++++++++ .../generated/PgCaseSensitivitySample.java | 153 ++++++++++++++++++ .../generated/PgCreateSequenceSample.java | 99 ++++++++++++ .../admin/generated/PgDropSequenceSample.java | 71 ++++++++ .../generated/PgInterleavedTableSample.java | 72 +++++++++ .../admin/generated/UpdateDatabaseSample.java | 76 +++++++++ ...UpdateDatabaseWithDefaultLeaderSample.java | 69 ++++++++ ...leWithForeignKeyDeleteCascadeSampleIT.java | 70 ++++++++ ...eateDatabaseWithDefaultLeaderSampleIT.java | 61 ------- ...aseWithVersionRetentionPeriodSampleIT.java | 47 ++++++ ...leWithForeignKeyDeleteCascadeSampleIT.java | 57 +++++++ .../admin/generated/DatabaseRolesIT.java | 126 +++++++++++++++ ...ignKeyConstraintDeleteCascadeSampleIT.java | 68 ++++++++ .../generated/GetDatabaseDdlSampleIT.java | 82 ++++++++++ ...anceSampleIT.java => ListDatabasesIT.java} | 24 ++- .../generated/PgCaseSensitivitySampleIT.java | 45 ++++++ .../generated/PgInterleavedTableSampleIT.java | 44 +++++ .../admin/generated/SampleTestBaseV2.java | 15 +- .../admin/generated/SequenceSampleIT.java | 142 ++++++++++++++++ .../generated/UpdateDatabaseSampleIT.java | 71 ++++++++ ...dateDatabaseWithDefaultLeaderSampleIT.java | 63 ++++++++ 40 files changed, 2515 insertions(+), 182 deletions(-) create mode 100644 samples/snippets/src/main/java/com/example/spanner/admin/generated/AddAndDropDatabaseRole.java create mode 100644 samples/snippets/src/main/java/com/example/spanner/admin/generated/AddJsonColumnSample.java create mode 100644 samples/snippets/src/main/java/com/example/spanner/admin/generated/AddJsonbColumnSample.java create mode 100644 samples/snippets/src/main/java/com/example/spanner/admin/generated/AddNumericColumnSample.java create mode 100644 samples/snippets/src/main/java/com/example/spanner/admin/generated/AlterSequenceSample.java create mode 100644 samples/snippets/src/main/java/com/example/spanner/admin/generated/AlterTableWithForeignKeyDeleteCascadeSample.java delete mode 100644 samples/snippets/src/main/java/com/example/spanner/admin/generated/CreateDatabaseWithDefaultLeaderSample.java create mode 100644 samples/snippets/src/main/java/com/example/spanner/admin/generated/CreateDatabaseWithVersionRetentionPeriodSample.java create mode 100644 samples/snippets/src/main/java/com/example/spanner/admin/generated/CreateSequenceSample.java create mode 100644 samples/snippets/src/main/java/com/example/spanner/admin/generated/CreateTableWithForeignKeyDeleteCascadeSample.java create mode 100644 samples/snippets/src/main/java/com/example/spanner/admin/generated/DropForeignKeyConstraintDeleteCascadeSample.java create mode 100644 samples/snippets/src/main/java/com/example/spanner/admin/generated/DropSequenceSample.java create mode 100644 samples/snippets/src/main/java/com/example/spanner/admin/generated/EnableFineGrainedAccess.java create mode 100644 samples/snippets/src/main/java/com/example/spanner/admin/generated/GetDatabaseDdlSample.java create mode 100644 samples/snippets/src/main/java/com/example/spanner/admin/generated/ListDatabaseRoles.java create mode 100644 samples/snippets/src/main/java/com/example/spanner/admin/generated/ListDatabasesSample.java create mode 100644 samples/snippets/src/main/java/com/example/spanner/admin/generated/PgAlterSequenceSample.java create mode 100644 samples/snippets/src/main/java/com/example/spanner/admin/generated/PgCaseSensitivitySample.java create mode 100644 samples/snippets/src/main/java/com/example/spanner/admin/generated/PgCreateSequenceSample.java create mode 100644 samples/snippets/src/main/java/com/example/spanner/admin/generated/PgDropSequenceSample.java create mode 100644 samples/snippets/src/main/java/com/example/spanner/admin/generated/PgInterleavedTableSample.java create mode 100644 samples/snippets/src/main/java/com/example/spanner/admin/generated/UpdateDatabaseSample.java create mode 100644 samples/snippets/src/main/java/com/example/spanner/admin/generated/UpdateDatabaseWithDefaultLeaderSample.java create mode 100644 samples/snippets/src/test/java/com/example/spanner/admin/generated/AlterTableWithForeignKeyDeleteCascadeSampleIT.java delete mode 100644 samples/snippets/src/test/java/com/example/spanner/admin/generated/CreateDatabaseWithDefaultLeaderSampleIT.java create mode 100644 samples/snippets/src/test/java/com/example/spanner/admin/generated/CreateDatabaseWithVersionRetentionPeriodSampleIT.java create mode 100644 samples/snippets/src/test/java/com/example/spanner/admin/generated/CreateTableWithForeignKeyDeleteCascadeSampleIT.java create mode 100644 samples/snippets/src/test/java/com/example/spanner/admin/generated/DatabaseRolesIT.java create mode 100644 samples/snippets/src/test/java/com/example/spanner/admin/generated/DropForeignKeyConstraintDeleteCascadeSampleIT.java create mode 100644 samples/snippets/src/test/java/com/example/spanner/admin/generated/GetDatabaseDdlSampleIT.java rename samples/snippets/src/test/java/com/example/spanner/admin/generated/{CreateInstanceSampleIT.java => ListDatabasesIT.java} (57%) create mode 100644 samples/snippets/src/test/java/com/example/spanner/admin/generated/PgCaseSensitivitySampleIT.java create mode 100644 samples/snippets/src/test/java/com/example/spanner/admin/generated/PgInterleavedTableSampleIT.java create mode 100644 samples/snippets/src/test/java/com/example/spanner/admin/generated/SequenceSampleIT.java create mode 100644 samples/snippets/src/test/java/com/example/spanner/admin/generated/UpdateDatabaseSampleIT.java create mode 100644 samples/snippets/src/test/java/com/example/spanner/admin/generated/UpdateDatabaseWithDefaultLeaderSampleIT.java diff --git a/README.md b/README.md index 82dca0538c2..bced4b3972e 100644 --- a/README.md +++ b/README.md @@ -509,15 +509,36 @@ Samples are in the [`samples/`](https://github.com/googleapis/java-spanner/tree/ | Update Jsonb Data Sample | [source code](https://github.com/googleapis/java-spanner/blob/main/samples/snippets/src/main/java/com/example/spanner/UpdateJsonbDataSample.java) | [![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/java-spanner&page=editor&open_in_editor=samples/snippets/src/main/java/com/example/spanner/UpdateJsonbDataSample.java) | | Update Numeric Data Sample | [source code](https://github.com/googleapis/java-spanner/blob/main/samples/snippets/src/main/java/com/example/spanner/UpdateNumericDataSample.java) | [![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/java-spanner&page=editor&open_in_editor=samples/snippets/src/main/java/com/example/spanner/UpdateNumericDataSample.java) | | Update Using Dml Returning Sample | [source code](https://github.com/googleapis/java-spanner/blob/main/samples/snippets/src/main/java/com/example/spanner/UpdateUsingDmlReturningSample.java) | [![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/java-spanner&page=editor&open_in_editor=samples/snippets/src/main/java/com/example/spanner/UpdateUsingDmlReturningSample.java) | -| Create Database With Default Leader Sample | [source code](https://github.com/googleapis/java-spanner/blob/main/samples/snippets/src/main/java/com/example/spanner/admin/generated/CreateDatabaseWithDefaultLeaderSample.java) | [![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/java-spanner&page=editor&open_in_editor=samples/snippets/src/main/java/com/example/spanner/admin/generated/CreateDatabaseWithDefaultLeaderSample.java) | +| Add And Drop Database Role | [source code](https://github.com/googleapis/java-spanner/blob/main/samples/snippets/src/main/java/com/example/spanner/admin/generated/AddAndDropDatabaseRole.java) | [![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/java-spanner&page=editor&open_in_editor=samples/snippets/src/main/java/com/example/spanner/admin/generated/AddAndDropDatabaseRole.java) | +| Add Json Column Sample | [source code](https://github.com/googleapis/java-spanner/blob/main/samples/snippets/src/main/java/com/example/spanner/admin/generated/AddJsonColumnSample.java) | [![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/java-spanner&page=editor&open_in_editor=samples/snippets/src/main/java/com/example/spanner/admin/generated/AddJsonColumnSample.java) | +| Add Jsonb Column Sample | [source code](https://github.com/googleapis/java-spanner/blob/main/samples/snippets/src/main/java/com/example/spanner/admin/generated/AddJsonbColumnSample.java) | [![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/java-spanner&page=editor&open_in_editor=samples/snippets/src/main/java/com/example/spanner/admin/generated/AddJsonbColumnSample.java) | +| Add Numeric Column Sample | [source code](https://github.com/googleapis/java-spanner/blob/main/samples/snippets/src/main/java/com/example/spanner/admin/generated/AddNumericColumnSample.java) | [![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/java-spanner&page=editor&open_in_editor=samples/snippets/src/main/java/com/example/spanner/admin/generated/AddNumericColumnSample.java) | +| Alter Sequence Sample | [source code](https://github.com/googleapis/java-spanner/blob/main/samples/snippets/src/main/java/com/example/spanner/admin/generated/AlterSequenceSample.java) | [![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/java-spanner&page=editor&open_in_editor=samples/snippets/src/main/java/com/example/spanner/admin/generated/AlterSequenceSample.java) | +| Alter Table With Foreign Key Delete Cascade Sample | [source code](https://github.com/googleapis/java-spanner/blob/main/samples/snippets/src/main/java/com/example/spanner/admin/generated/AlterTableWithForeignKeyDeleteCascadeSample.java) | [![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/java-spanner&page=editor&open_in_editor=samples/snippets/src/main/java/com/example/spanner/admin/generated/AlterTableWithForeignKeyDeleteCascadeSample.java) | +| Create Database With Version Retention Period Sample | [source code](https://github.com/googleapis/java-spanner/blob/main/samples/snippets/src/main/java/com/example/spanner/admin/generated/CreateDatabaseWithVersionRetentionPeriodSample.java) | [![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/java-spanner&page=editor&open_in_editor=samples/snippets/src/main/java/com/example/spanner/admin/generated/CreateDatabaseWithVersionRetentionPeriodSample.java) | | Create Instance Config Sample | [source code](https://github.com/googleapis/java-spanner/blob/main/samples/snippets/src/main/java/com/example/spanner/admin/generated/CreateInstanceConfigSample.java) | [![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/java-spanner&page=editor&open_in_editor=samples/snippets/src/main/java/com/example/spanner/admin/generated/CreateInstanceConfigSample.java) | | Create Instance Example | [source code](https://github.com/googleapis/java-spanner/blob/main/samples/snippets/src/main/java/com/example/spanner/admin/generated/CreateInstanceExample.java) | [![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/java-spanner&page=editor&open_in_editor=samples/snippets/src/main/java/com/example/spanner/admin/generated/CreateInstanceExample.java) | | Create Instance With Autoscaling Config Example | [source code](https://github.com/googleapis/java-spanner/blob/main/samples/snippets/src/main/java/com/example/spanner/admin/generated/CreateInstanceWithAutoscalingConfigExample.java) | [![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/java-spanner&page=editor&open_in_editor=samples/snippets/src/main/java/com/example/spanner/admin/generated/CreateInstanceWithAutoscalingConfigExample.java) | | Create Instance With Processing Units Example | [source code](https://github.com/googleapis/java-spanner/blob/main/samples/snippets/src/main/java/com/example/spanner/admin/generated/CreateInstanceWithProcessingUnitsExample.java) | [![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/java-spanner&page=editor&open_in_editor=samples/snippets/src/main/java/com/example/spanner/admin/generated/CreateInstanceWithProcessingUnitsExample.java) | +| Create Sequence Sample | [source code](https://github.com/googleapis/java-spanner/blob/main/samples/snippets/src/main/java/com/example/spanner/admin/generated/CreateSequenceSample.java) | [![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/java-spanner&page=editor&open_in_editor=samples/snippets/src/main/java/com/example/spanner/admin/generated/CreateSequenceSample.java) | +| Create Table With Foreign Key Delete Cascade Sample | [source code](https://github.com/googleapis/java-spanner/blob/main/samples/snippets/src/main/java/com/example/spanner/admin/generated/CreateTableWithForeignKeyDeleteCascadeSample.java) | [![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/java-spanner&page=editor&open_in_editor=samples/snippets/src/main/java/com/example/spanner/admin/generated/CreateTableWithForeignKeyDeleteCascadeSample.java) | | Delete Instance Config Sample | [source code](https://github.com/googleapis/java-spanner/blob/main/samples/snippets/src/main/java/com/example/spanner/admin/generated/DeleteInstanceConfigSample.java) | [![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/java-spanner&page=editor&open_in_editor=samples/snippets/src/main/java/com/example/spanner/admin/generated/DeleteInstanceConfigSample.java) | +| Drop Foreign Key Constraint Delete Cascade Sample | [source code](https://github.com/googleapis/java-spanner/blob/main/samples/snippets/src/main/java/com/example/spanner/admin/generated/DropForeignKeyConstraintDeleteCascadeSample.java) | [![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/java-spanner&page=editor&open_in_editor=samples/snippets/src/main/java/com/example/spanner/admin/generated/DropForeignKeyConstraintDeleteCascadeSample.java) | +| Drop Sequence Sample | [source code](https://github.com/googleapis/java-spanner/blob/main/samples/snippets/src/main/java/com/example/spanner/admin/generated/DropSequenceSample.java) | [![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/java-spanner&page=editor&open_in_editor=samples/snippets/src/main/java/com/example/spanner/admin/generated/DropSequenceSample.java) | +| Enable Fine Grained Access | [source code](https://github.com/googleapis/java-spanner/blob/main/samples/snippets/src/main/java/com/example/spanner/admin/generated/EnableFineGrainedAccess.java) | [![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/java-spanner&page=editor&open_in_editor=samples/snippets/src/main/java/com/example/spanner/admin/generated/EnableFineGrainedAccess.java) | +| Get Database Ddl Sample | [source code](https://github.com/googleapis/java-spanner/blob/main/samples/snippets/src/main/java/com/example/spanner/admin/generated/GetDatabaseDdlSample.java) | [![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/java-spanner&page=editor&open_in_editor=samples/snippets/src/main/java/com/example/spanner/admin/generated/GetDatabaseDdlSample.java) | | Get Instance Config Sample | [source code](https://github.com/googleapis/java-spanner/blob/main/samples/snippets/src/main/java/com/example/spanner/admin/generated/GetInstanceConfigSample.java) | [![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/java-spanner&page=editor&open_in_editor=samples/snippets/src/main/java/com/example/spanner/admin/generated/GetInstanceConfigSample.java) | +| List Database Roles | [source code](https://github.com/googleapis/java-spanner/blob/main/samples/snippets/src/main/java/com/example/spanner/admin/generated/ListDatabaseRoles.java) | [![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/java-spanner&page=editor&open_in_editor=samples/snippets/src/main/java/com/example/spanner/admin/generated/ListDatabaseRoles.java) | +| List Databases Sample | [source code](https://github.com/googleapis/java-spanner/blob/main/samples/snippets/src/main/java/com/example/spanner/admin/generated/ListDatabasesSample.java) | [![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/java-spanner&page=editor&open_in_editor=samples/snippets/src/main/java/com/example/spanner/admin/generated/ListDatabasesSample.java) | | List Instance Config Operations Sample | [source code](https://github.com/googleapis/java-spanner/blob/main/samples/snippets/src/main/java/com/example/spanner/admin/generated/ListInstanceConfigOperationsSample.java) | [![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/java-spanner&page=editor&open_in_editor=samples/snippets/src/main/java/com/example/spanner/admin/generated/ListInstanceConfigOperationsSample.java) | | List Instance Configs Sample | [source code](https://github.com/googleapis/java-spanner/blob/main/samples/snippets/src/main/java/com/example/spanner/admin/generated/ListInstanceConfigsSample.java) | [![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/java-spanner&page=editor&open_in_editor=samples/snippets/src/main/java/com/example/spanner/admin/generated/ListInstanceConfigsSample.java) | +| Pg Alter Sequence Sample | [source code](https://github.com/googleapis/java-spanner/blob/main/samples/snippets/src/main/java/com/example/spanner/admin/generated/PgAlterSequenceSample.java) | [![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/java-spanner&page=editor&open_in_editor=samples/snippets/src/main/java/com/example/spanner/admin/generated/PgAlterSequenceSample.java) | +| Pg Case Sensitivity Sample | [source code](https://github.com/googleapis/java-spanner/blob/main/samples/snippets/src/main/java/com/example/spanner/admin/generated/PgCaseSensitivitySample.java) | [![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/java-spanner&page=editor&open_in_editor=samples/snippets/src/main/java/com/example/spanner/admin/generated/PgCaseSensitivitySample.java) | +| Pg Create Sequence Sample | [source code](https://github.com/googleapis/java-spanner/blob/main/samples/snippets/src/main/java/com/example/spanner/admin/generated/PgCreateSequenceSample.java) | [![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/java-spanner&page=editor&open_in_editor=samples/snippets/src/main/java/com/example/spanner/admin/generated/PgCreateSequenceSample.java) | +| Pg Drop Sequence Sample | [source code](https://github.com/googleapis/java-spanner/blob/main/samples/snippets/src/main/java/com/example/spanner/admin/generated/PgDropSequenceSample.java) | [![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/java-spanner&page=editor&open_in_editor=samples/snippets/src/main/java/com/example/spanner/admin/generated/PgDropSequenceSample.java) | +| Pg Interleaved Table Sample | [source code](https://github.com/googleapis/java-spanner/blob/main/samples/snippets/src/main/java/com/example/spanner/admin/generated/PgInterleavedTableSample.java) | [![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/java-spanner&page=editor&open_in_editor=samples/snippets/src/main/java/com/example/spanner/admin/generated/PgInterleavedTableSample.java) | +| Update Database Sample | [source code](https://github.com/googleapis/java-spanner/blob/main/samples/snippets/src/main/java/com/example/spanner/admin/generated/UpdateDatabaseSample.java) | [![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/java-spanner&page=editor&open_in_editor=samples/snippets/src/main/java/com/example/spanner/admin/generated/UpdateDatabaseSample.java) | +| Update Database With Default Leader Sample | [source code](https://github.com/googleapis/java-spanner/blob/main/samples/snippets/src/main/java/com/example/spanner/admin/generated/UpdateDatabaseWithDefaultLeaderSample.java) | [![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/java-spanner&page=editor&open_in_editor=samples/snippets/src/main/java/com/example/spanner/admin/generated/UpdateDatabaseWithDefaultLeaderSample.java) | | Update Instance Config Sample | [source code](https://github.com/googleapis/java-spanner/blob/main/samples/snippets/src/main/java/com/example/spanner/admin/generated/UpdateInstanceConfigSample.java) | [![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/java-spanner&page=editor&open_in_editor=samples/snippets/src/main/java/com/example/spanner/admin/generated/UpdateInstanceConfigSample.java) | diff --git a/samples/pom.xml b/samples/pom.xml index be994d055bd..07b17a608cd 100644 --- a/samples/pom.xml +++ b/samples/pom.xml @@ -19,6 +19,7 @@ com.google.cloud.samples shared-configuration 1.2.0 + diff --git a/samples/snippets/src/main/java/com/example/spanner/admin/generated/AddAndDropDatabaseRole.java b/samples/snippets/src/main/java/com/example/spanner/admin/generated/AddAndDropDatabaseRole.java new file mode 100644 index 00000000000..d88fe72dc8f --- /dev/null +++ b/samples/snippets/src/main/java/com/example/spanner/admin/generated/AddAndDropDatabaseRole.java @@ -0,0 +1,75 @@ +/* + * Copyright 2022 Google Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.example.spanner.admin.generated; + +// [START spanner_add_and_drop_database_role] + +import com.google.cloud.spanner.admin.database.v1.DatabaseAdminClient; +import com.google.common.collect.ImmutableList; +import com.google.spanner.admin.database.v1.DatabaseName; +import java.io.IOException; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.TimeoutException; + +public class AddAndDropDatabaseRole { + + static void addAndDropDatabaseRole() throws IOException { + // TODO(developer): Replace these variables before running the sample. + String projectId = "my-project"; + String instanceId = "my-instance"; + String databaseId = "my-database"; + String parentRole = "parent_role"; + String childRole = "child_role"; + addAndDropDatabaseRole(projectId, instanceId, databaseId, parentRole, childRole); + } + + static void addAndDropDatabaseRole( + String projectId, String instanceId, String databaseId, String parentRole, String childRole) + throws IOException { + final DatabaseAdminClient databaseAdminClient = DatabaseAdminClient.create(); + try { + System.out.println("Waiting for role create operation to complete..."); + databaseAdminClient.updateDatabaseDdlAsync( + DatabaseName.of(projectId, instanceId, databaseId), + ImmutableList.of( + String.format("CREATE ROLE %s", parentRole), + String.format("GRANT SELECT ON TABLE Albums TO ROLE %s", parentRole), + String.format("CREATE ROLE %s", childRole), + String.format("GRANT ROLE %s TO ROLE %s", parentRole, childRole))) + .get(5, TimeUnit.MINUTES); + System.out.printf( + "Created roles %s and %s and granted privileges%n", parentRole, childRole); + // Delete role and membership. + System.out.println("Waiting for role revoke & drop operation to complete..."); + databaseAdminClient.updateDatabaseDdlAsync( + DatabaseName.of(projectId, instanceId, databaseId), + ImmutableList.of( + String.format("REVOKE ROLE %s FROM ROLE %s", parentRole, childRole), + String.format("DROP ROLE %s", childRole))).get(5, TimeUnit.MINUTES); + System.out.printf("Revoked privileges and dropped role %s%n", childRole); + } catch (ExecutionException | TimeoutException e) { + System.out.printf( + "Error: AddAndDropDatabaseRole failed with error message %s\n", e.getMessage()); + e.printStackTrace(); + } catch (InterruptedException e) { + System.out.println( + "Error: Waiting for AddAndDropDatabaseRole operation to finish was interrupted"); + } + } +} +// [END spanner_add_and_drop_database_role] diff --git a/samples/snippets/src/main/java/com/example/spanner/admin/generated/AddJsonColumnSample.java b/samples/snippets/src/main/java/com/example/spanner/admin/generated/AddJsonColumnSample.java new file mode 100644 index 00000000000..32d1daea2d1 --- /dev/null +++ b/samples/snippets/src/main/java/com/example/spanner/admin/generated/AddJsonColumnSample.java @@ -0,0 +1,49 @@ +/* + * Copyright 2021 Google Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.example.spanner.admin.generated; + +// [START spanner_add_json_column] +import com.google.cloud.spanner.admin.database.v1.DatabaseAdminClient; +import com.google.common.collect.ImmutableList; +import com.google.spanner.admin.database.v1.DatabaseName; +import java.io.IOException; +import java.util.concurrent.ExecutionException; + +class AddJsonColumnSample { + + static void addJsonColumn() throws InterruptedException, ExecutionException, IOException { + // TODO(developer): Replace these variables before running the sample. + String projectId = "my-project"; + String instanceId = "my-instance"; + String databaseId = "my-database"; + + addJsonColumn(projectId, instanceId, databaseId); + } + + static void addJsonColumn(String projectId, String instanceId, String databaseId) + throws InterruptedException, ExecutionException, IOException { + final DatabaseAdminClient databaseAdminClient = DatabaseAdminClient.create(); + + // Wait for the operation to finish. + // This will throw an ExecutionException if the operation fails. + databaseAdminClient.updateDatabaseDdlAsync( + DatabaseName.of(projectId, instanceId, databaseId), + ImmutableList.of("ALTER TABLE Venues ADD COLUMN VenueDetails JSON")).get(); + System.out.printf("Successfully added column `VenueDetails`%n"); + } +} +// [END spanner_add_json_column] diff --git a/samples/snippets/src/main/java/com/example/spanner/admin/generated/AddJsonbColumnSample.java b/samples/snippets/src/main/java/com/example/spanner/admin/generated/AddJsonbColumnSample.java new file mode 100644 index 00000000000..800c2d3d655 --- /dev/null +++ b/samples/snippets/src/main/java/com/example/spanner/admin/generated/AddJsonbColumnSample.java @@ -0,0 +1,50 @@ +/* + * Copyright 2022 Google Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.example.spanner.admin.generated; + +// [START spanner_postgresql_jsonb_add_column] +import com.google.cloud.spanner.admin.database.v1.DatabaseAdminClient; +import com.google.common.collect.ImmutableList; +import com.google.spanner.admin.database.v1.DatabaseName; +import java.io.IOException; +import java.util.concurrent.ExecutionException; + +class AddJsonbColumnSample { + + static void addJsonbColumn() throws InterruptedException, ExecutionException, IOException { + // TODO(developer): Replace these variables before running the sample. + String projectId = "my-project"; + String instanceId = "my-instance"; + String databaseId = "my-database"; + + addJsonbColumn(projectId, instanceId, databaseId); + } + + static void addJsonbColumn(String projectId, String instanceId, String databaseId) + throws InterruptedException, ExecutionException, IOException { + final DatabaseAdminClient databaseAdminClient = DatabaseAdminClient.create(); + + // JSONB datatype is only supported with PostgreSQL-dialect databases. + // Wait for the operation to finish. + // This will throw an ExecutionException if the operation fails. + databaseAdminClient.updateDatabaseDdlAsync( + DatabaseName.of(projectId, instanceId, databaseId), + ImmutableList.of("ALTER TABLE Venues ADD COLUMN VenueDetails JSONB")).get(); + System.out.printf("Successfully added column `VenueDetails`%n"); + } +} +// [END spanner_postgresql_jsonb_add_column] diff --git a/samples/snippets/src/main/java/com/example/spanner/admin/generated/AddNumericColumnSample.java b/samples/snippets/src/main/java/com/example/spanner/admin/generated/AddNumericColumnSample.java new file mode 100644 index 00000000000..191e0377b66 --- /dev/null +++ b/samples/snippets/src/main/java/com/example/spanner/admin/generated/AddNumericColumnSample.java @@ -0,0 +1,50 @@ +/* + * Copyright 2020 Google Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.example.spanner.admin.generated; + +// [START spanner_add_numeric_column] + +import com.google.cloud.spanner.admin.database.v1.DatabaseAdminClient; +import com.google.common.collect.ImmutableList; +import com.google.spanner.admin.database.v1.DatabaseName; +import java.io.IOException; +import java.util.concurrent.ExecutionException; + +class AddNumericColumnSample { + + static void addNumericColumn() throws InterruptedException, ExecutionException, IOException { + // TODO(developer): Replace these variables before running the sample. + String projectId = "my-project"; + String instanceId = "my-instance"; + String databaseId = "my-database"; + + addNumericColumn(projectId, instanceId, databaseId); + } + + static void addNumericColumn(String projectId, String instanceId, String databaseId) + throws InterruptedException, ExecutionException, IOException { + final DatabaseAdminClient databaseAdminClient = DatabaseAdminClient.create(); + + // Wait for the operation to finish. + // This will throw an ExecutionException if the operation fails. + databaseAdminClient.updateDatabaseDdlAsync( + DatabaseName.of(projectId, instanceId, databaseId), + ImmutableList.of("ALTER TABLE Venues ADD COLUMN Revenue NUMERIC")).get(); + System.out.printf("Successfully added column `Revenue`%n"); + } +} +// [END spanner_add_numeric_column] diff --git a/samples/snippets/src/main/java/com/example/spanner/admin/generated/AlterSequenceSample.java b/samples/snippets/src/main/java/com/example/spanner/admin/generated/AlterSequenceSample.java new file mode 100644 index 00000000000..05ae63a7a53 --- /dev/null +++ b/samples/snippets/src/main/java/com/example/spanner/admin/generated/AlterSequenceSample.java @@ -0,0 +1,98 @@ +/* + * Copyright 2023 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.example.spanner.admin.generated; + +// [START spanner_alter_sequence] + +import com.google.cloud.spanner.DatabaseClient; +import com.google.cloud.spanner.DatabaseId; +import com.google.cloud.spanner.ResultSet; +import com.google.cloud.spanner.Spanner; +import com.google.cloud.spanner.SpannerExceptionFactory; +import com.google.cloud.spanner.SpannerOptions; +import com.google.cloud.spanner.Statement; +import com.google.cloud.spanner.admin.database.v1.DatabaseAdminClient; +import com.google.common.collect.ImmutableList; +import com.google.spanner.admin.database.v1.DatabaseName; +import java.io.IOException; +import java.util.Objects; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.TimeoutException; + +public class AlterSequenceSample { + + static void alterSequence() throws IOException { + // TODO(developer): Replace these variables before running the sample. + final String projectId = "my-project"; + final String instanceId = "my-instance"; + final String databaseId = "my-database"; + alterSequence(projectId, instanceId, databaseId); + } + + static void alterSequence(String projectId, String instanceId, String databaseId) + throws IOException { + DatabaseAdminClient databaseAdminClient = DatabaseAdminClient.create(); + try (Spanner spanner = + SpannerOptions.newBuilder().setProjectId(projectId).build().getService()) { + + databaseAdminClient + .updateDatabaseDdlAsync(DatabaseName.of(projectId, instanceId, databaseId), + ImmutableList.of( + "ALTER SEQUENCE Seq SET OPTIONS " + + "(skip_range_min = 1000, skip_range_max = 5000000)")) + .get(5, TimeUnit.MINUTES); + + System.out.println( + "Altered Seq sequence to skip an inclusive range between 1000 and 5000000"); + + final DatabaseClient dbClient = + spanner.getDatabaseClient(DatabaseId.of(projectId, instanceId, databaseId)); + + Long insertCount = + dbClient + .readWriteTransaction() + .run( + transaction -> { + try (ResultSet rs = + transaction.executeQuery( + Statement.of( + "INSERT INTO Customers (CustomerName) VALUES " + + "('Lea'), ('Catalina'), ('Smith') " + + "THEN RETURN CustomerId"))) { + while (rs.next()) { + System.out.printf( + "Inserted customer record with CustomerId: %d\n", rs.getLong(0)); + } + return Objects.requireNonNull(rs.getStats()).getRowCountExact(); + } + }); + System.out.printf("Number of customer records inserted is: %d\n", insertCount); + } catch (ExecutionException e) { + // If the operation failed during execution, expose the cause. + throw SpannerExceptionFactory.asSpannerException(e.getCause()); + } catch (InterruptedException e) { + // Throw when a thread is waiting, sleeping, or otherwise occupied, + // and the thread is interrupted, either before or during the activity. + throw SpannerExceptionFactory.propagateInterrupt(e); + } catch (TimeoutException e) { + // If the operation timed out propagate the timeout + throw SpannerExceptionFactory.propagateTimeout(e); + } + } +} +// [END spanner_alter_sequence] diff --git a/samples/snippets/src/main/java/com/example/spanner/admin/generated/AlterTableWithForeignKeyDeleteCascadeSample.java b/samples/snippets/src/main/java/com/example/spanner/admin/generated/AlterTableWithForeignKeyDeleteCascadeSample.java new file mode 100644 index 00000000000..5784bfab0c7 --- /dev/null +++ b/samples/snippets/src/main/java/com/example/spanner/admin/generated/AlterTableWithForeignKeyDeleteCascadeSample.java @@ -0,0 +1,56 @@ +/* + * Copyright 2023 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.example.spanner.admin.generated; + +// [START spanner_alter_table_with_foreign_key_delete_cascade] + +import com.google.cloud.spanner.admin.database.v1.DatabaseAdminClient; +import com.google.common.collect.ImmutableList; +import com.google.spanner.admin.database.v1.DatabaseName; +import java.io.IOException; + +class AlterTableWithForeignKeyDeleteCascadeSample { + + static void alterForeignKeyDeleteCascadeConstraint() throws IOException { + // TODO(developer): Replace these variables before running the sample. + String projectId = "my-project"; + String instanceId = "my-instance"; + String databaseId = "my-database"; + + alterForeignKeyDeleteCascadeConstraint(projectId, instanceId, databaseId); + } + + static void alterForeignKeyDeleteCascadeConstraint( + String projectId, String instanceId, String databaseId) throws IOException { + DatabaseAdminClient databaseAdminClient = DatabaseAdminClient.create(); + + databaseAdminClient.updateDatabaseDdlAsync(DatabaseName.of(projectId, instanceId, + databaseId), + ImmutableList.of( + "ALTER TABLE ShoppingCarts\n" + + " ADD CONSTRAINT FKShoppingCartsCustomerName\n" + + " FOREIGN KEY (CustomerName)\n" + + " REFERENCES Customers(CustomerName)\n" + + " ON DELETE CASCADE\n")); + System.out.printf( + String.format( + "Altered ShoppingCarts table with FKShoppingCartsCustomerName\n" + + "foreign key constraint on database %s on instance %s", + databaseId, instanceId)); + } +} +// [END spanner_alter_table_with_foreign_key_delete_cascade] diff --git a/samples/snippets/src/main/java/com/example/spanner/admin/generated/CreateDatabaseWithDefaultLeaderSample.java b/samples/snippets/src/main/java/com/example/spanner/admin/generated/CreateDatabaseWithDefaultLeaderSample.java deleted file mode 100644 index 853ec557b94..00000000000 --- a/samples/snippets/src/main/java/com/example/spanner/admin/generated/CreateDatabaseWithDefaultLeaderSample.java +++ /dev/null @@ -1,76 +0,0 @@ -/* - * Copyright 2023 Google LLC - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.example.spanner.admin.generated; - -//[START spanner_create_database_with_default_leader] - -import com.google.cloud.spanner.SpannerException; -import com.google.cloud.spanner.SpannerExceptionFactory; -import com.google.cloud.spanner.admin.database.v1.DatabaseAdminClient; -import com.google.common.collect.ImmutableList; -import com.google.spanner.admin.database.v1.CreateDatabaseRequest; -import com.google.spanner.admin.database.v1.Database; -import java.io.IOException; -import java.util.concurrent.ExecutionException; - -public class CreateDatabaseWithDefaultLeaderSample { - - static void createDatabaseWithDefaultLeader() throws IOException { - // TODO(developer): Replace these variables before running the sample. - final String instanceName = "projects/my-project/instances/my-instance-id"; - final String databaseId = "my-database-name"; - final String defaultLeader = "my-default-leader"; - createDatabaseWithDefaultLeader(instanceName, databaseId, defaultLeader); - } - - static void createDatabaseWithDefaultLeader(String instanceName, String databaseId, - String defaultLeader) throws IOException { - try (DatabaseAdminClient databaseAdminClient = DatabaseAdminClient.create()) { - Database createdDatabase = - databaseAdminClient.createDatabaseAsync( - CreateDatabaseRequest.newBuilder() - .setParent(instanceName) - .setCreateStatement("CREATE DATABASE `" + databaseId + "`") - .addAllExtraStatements( - ImmutableList.of("CREATE TABLE Singers (" - + " SingerId INT64 NOT NULL," - + " FirstName STRING(1024)," - + " LastName STRING(1024)," - + " SingerInfo BYTES(MAX)" - + ") PRIMARY KEY (SingerId)", - "CREATE TABLE Albums (" - + " SingerId INT64 NOT NULL," - + " AlbumId INT64 NOT NULL," - + " AlbumTitle STRING(MAX)" - + ") PRIMARY KEY (SingerId, AlbumId)," - + " INTERLEAVE IN PARENT Singers ON DELETE CASCADE", - "ALTER DATABASE " + "`" + databaseId + "`" - + " SET OPTIONS ( default_leader = '" + defaultLeader + "' )")) - .build()).get(); - System.out.println("Created database [" + createdDatabase.getName() + "]"); - System.out.println("\tDefault leader: " + createdDatabase.getDefaultLeader()); - } catch (ExecutionException e) { - // If the operation failed during execution, expose the cause. - throw (SpannerException) e.getCause(); - } catch (InterruptedException e) { - // Throw when a thread is waiting, sleeping, or otherwise occupied, - // and the thread is interrupted, either before or during the activity. - throw SpannerExceptionFactory.propagateInterrupt(e); - } - } -} -//[END spanner_create_database_with_default_leader] diff --git a/samples/snippets/src/main/java/com/example/spanner/admin/generated/CreateDatabaseWithVersionRetentionPeriodSample.java b/samples/snippets/src/main/java/com/example/spanner/admin/generated/CreateDatabaseWithVersionRetentionPeriodSample.java new file mode 100644 index 00000000000..8d26f1ced56 --- /dev/null +++ b/samples/snippets/src/main/java/com/example/spanner/admin/generated/CreateDatabaseWithVersionRetentionPeriodSample.java @@ -0,0 +1,71 @@ +/* + * Copyright 2021 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.example.spanner.admin.generated; + +// [START spanner_create_database_with_version_retention_period] + +import com.google.cloud.spanner.SpannerException; +import com.google.cloud.spanner.SpannerExceptionFactory; +import com.google.cloud.spanner.admin.database.v1.DatabaseAdminClient; +import com.google.common.collect.Lists; +import com.google.spanner.admin.database.v1.CreateDatabaseRequest; +import com.google.spanner.admin.database.v1.Database; +import com.google.spanner.admin.database.v1.InstanceName; +import java.io.IOException; +import java.util.concurrent.ExecutionException; + +public class CreateDatabaseWithVersionRetentionPeriodSample { + + static void createDatabaseWithVersionRetentionPeriod() throws IOException { + // TODO(developer): Replace these variables before running the sample. + String projectId = "my-project"; + String instanceId = "my-instance"; + String databaseId = "my-database"; + String versionRetentionPeriod = "7d"; + + createDatabaseWithVersionRetentionPeriod(projectId, instanceId, databaseId, + versionRetentionPeriod); + } + + static void createDatabaseWithVersionRetentionPeriod(String projectId, + String instanceId, String databaseId, String versionRetentionPeriod) throws IOException { + DatabaseAdminClient databaseAdminClient = DatabaseAdminClient.create(); + + try { + CreateDatabaseRequest request = + CreateDatabaseRequest.newBuilder() + .setParent(InstanceName.of(projectId, instanceId).toString()) + .setCreateStatement("CREATE DATABASE `" + databaseId + "`") + .addAllExtraStatements(Lists.newArrayList("ALTER DATABASE " + "`" + databaseId + "`" + + " SET OPTIONS ( version_retention_period = '" + versionRetentionPeriod + "' )")) + .build(); + Database database = + databaseAdminClient.createDatabaseAsync(request).get(); + System.out.println("Created database [" + database.getName() + "]"); + System.out.println("\tVersion retention period: " + database.getVersionRetentionPeriod()); + System.out.println("\tEarliest version time: " + database.getEarliestVersionTime()); + } catch (ExecutionException e) { + // If the operation failed during execution, expose the cause. + throw (SpannerException) e.getCause(); + } catch (InterruptedException e) { + // Throw when a thread is waiting, sleeping, or otherwise occupied, + // and the thread is interrupted, either before or during the activity. + throw SpannerExceptionFactory.propagateInterrupt(e); + } + } +} +// [END spanner_create_database_with_version_retention_period] diff --git a/samples/snippets/src/main/java/com/example/spanner/admin/generated/CreateInstanceExample.java b/samples/snippets/src/main/java/com/example/spanner/admin/generated/CreateInstanceExample.java index 8664c85b444..925b0984992 100644 --- a/samples/snippets/src/main/java/com/example/spanner/admin/generated/CreateInstanceExample.java +++ b/samples/snippets/src/main/java/com/example/spanner/admin/generated/CreateInstanceExample.java @@ -36,35 +36,35 @@ static void createInstance() throws IOException { } static void createInstance(String projectId, String instanceId) throws IOException { - try (InstanceAdminClient instanceAdminClient = InstanceAdminClient.create()) { - // Set Instance configuration. - int nodeCount = 2; - String displayName = "Descriptive name"; + InstanceAdminClient instanceAdminClient = InstanceAdminClient.create(); - // Create an Instance object that will be used to create the instance. - Instance instance = - Instance.newBuilder() - .setDisplayName(displayName) - .setNodeCount(nodeCount) - .setConfig( - InstanceConfigName.of(projectId, "regional-us-central1").toString()) - .build(); - try { - // Wait for the createInstance operation to finish. - Instance createdInstance = instanceAdminClient.createInstanceAsync( - CreateInstanceRequest.newBuilder() - .setParent(ProjectName.of(projectId).toString()) - .setInstanceId(instanceId) - .setInstance(instance) - .build()).get(); - System.out.printf("Instance %s was successfully created%n", createdInstance.getName()); - } catch (ExecutionException e) { - System.out.printf( - "Error: Creating instance %s failed with error message %s%n", - instance.getName(), e.getMessage()); - } catch (InterruptedException e) { - System.out.println("Error: Waiting for createInstance operation to finish was interrupted"); - } + // Set Instance configuration. + int nodeCount = 2; + String displayName = "Descriptive name"; + + // Create an Instance object that will be used to create the instance. + Instance instance = + Instance.newBuilder() + .setDisplayName(displayName) + .setNodeCount(nodeCount) + .setConfig( + InstanceConfigName.of(projectId, "regional-us-central1").toString()) + .build(); + try { + // Wait for the createInstance operation to finish. + Instance createdInstance = instanceAdminClient.createInstanceAsync( + CreateInstanceRequest.newBuilder() + .setParent(ProjectName.of(projectId).toString()) + .setInstanceId(instanceId) + .setInstance(instance) + .build()).get(); + System.out.printf("Instance %s was successfully created%n", createdInstance.getName()); + } catch (ExecutionException e) { + System.out.printf( + "Error: Creating instance %s failed with error message %s%n", + instance.getName(), e.getMessage()); + } catch (InterruptedException e) { + System.out.println("Error: Waiting for createInstance operation to finish was interrupted"); } } } diff --git a/samples/snippets/src/main/java/com/example/spanner/admin/generated/CreateSequenceSample.java b/samples/snippets/src/main/java/com/example/spanner/admin/generated/CreateSequenceSample.java new file mode 100644 index 00000000000..6614d988b78 --- /dev/null +++ b/samples/snippets/src/main/java/com/example/spanner/admin/generated/CreateSequenceSample.java @@ -0,0 +1,102 @@ +/* + * Copyright 2023 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.example.spanner.admin.generated; + +// [START spanner_create_sequence] + +import com.google.cloud.spanner.DatabaseClient; +import com.google.cloud.spanner.DatabaseId; +import com.google.cloud.spanner.ResultSet; +import com.google.cloud.spanner.Spanner; +import com.google.cloud.spanner.SpannerExceptionFactory; +import com.google.cloud.spanner.SpannerOptions; +import com.google.cloud.spanner.Statement; +import com.google.cloud.spanner.admin.database.v1.DatabaseAdminClient; +import com.google.common.collect.ImmutableList; +import com.google.spanner.admin.database.v1.DatabaseName; +import java.io.IOException; +import java.util.Objects; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.TimeoutException; + +public class CreateSequenceSample { + + static void createSequence() throws IOException { + // TODO(developer): Replace these variables before running the sample. + final String projectId = "my-project"; + final String instanceId = "my-instance"; + final String databaseId = "my-database"; + createSequence(projectId, instanceId, databaseId); + } + + static void createSequence(String projectId, String instanceId, String databaseId) + throws IOException { + DatabaseAdminClient databaseAdminClient = DatabaseAdminClient.create(); + + try (Spanner spanner = + SpannerOptions.newBuilder().setProjectId(projectId).build().getService()) { + + databaseAdminClient + .updateDatabaseDdlAsync( + DatabaseName.of(projectId, instanceId, databaseId), + ImmutableList.of( + "CREATE SEQUENCE Seq OPTIONS (sequence_kind = 'bit_reversed_positive')", + "CREATE TABLE Customers (CustomerId INT64 DEFAULT " + + "(GET_NEXT_SEQUENCE_VALUE(SEQUENCE Seq)), CustomerName STRING(1024)) " + + "PRIMARY KEY (CustomerId)")) + .get(5, TimeUnit.MINUTES); + + System.out.println( + "Created Seq sequence and Customers table, where the key column CustomerId " + + "uses the sequence as a default value"); + + final DatabaseClient dbClient = + spanner.getDatabaseClient(DatabaseId.of(projectId, instanceId, databaseId)); + + Long insertCount = + dbClient + .readWriteTransaction() + .run( + transaction -> { + try (ResultSet rs = + transaction.executeQuery( + Statement.of( + "INSERT INTO Customers (CustomerName) VALUES " + + "('Alice'), ('David'), ('Marc') THEN RETURN CustomerId"))) { + while (rs.next()) { + System.out.printf( + "Inserted customer record with CustomerId: %d\n", rs.getLong(0)); + } + return Objects.requireNonNull(rs.getStats()).getRowCountExact(); + } + }); + System.out.printf("Number of customer records inserted is: %d\n", insertCount); + } catch (ExecutionException e) { + // If the operation failed during execution, expose the cause. + throw SpannerExceptionFactory.asSpannerException(e.getCause()); + } catch (InterruptedException e) { + // Throw when a thread is waiting, sleeping, or otherwise occupied, + // and the thread is interrupted, either before or during the activity. + throw SpannerExceptionFactory.propagateInterrupt(e); + } catch (TimeoutException e) { + // If the operation timed out propagate the timeout + throw SpannerExceptionFactory.propagateTimeout(e); + } + } +} +// [END spanner_create_sequence] diff --git a/samples/snippets/src/main/java/com/example/spanner/admin/generated/CreateTableWithForeignKeyDeleteCascadeSample.java b/samples/snippets/src/main/java/com/example/spanner/admin/generated/CreateTableWithForeignKeyDeleteCascadeSample.java new file mode 100644 index 00000000000..cc46f1e214e --- /dev/null +++ b/samples/snippets/src/main/java/com/example/spanner/admin/generated/CreateTableWithForeignKeyDeleteCascadeSample.java @@ -0,0 +1,63 @@ +/* + * Copyright 2023 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.example.spanner.admin.generated; + +// [START spanner_create_table_with_foreign_key_delete_cascade] + +import com.google.cloud.spanner.admin.database.v1.DatabaseAdminClient; +import com.google.common.collect.ImmutableList; +import com.google.spanner.admin.database.v1.CreateDatabaseRequest; +import com.google.spanner.admin.database.v1.DatabaseName; +import java.io.IOException; + +class CreateTableWithForeignKeyDeleteCascadeSample { + + static void createForeignKeyDeleteCascadeConstraint() throws IOException { + // TODO(developer): Replace these variables before running the sample. + String projectId = "my-project"; + String instanceId = "my-instance"; + String databaseId = "my-database"; + + createForeignKeyDeleteCascadeConstraint(projectId, instanceId, databaseId); + } + + static void createForeignKeyDeleteCascadeConstraint( + String projectId, String instanceId, String databaseId) throws IOException { + DatabaseAdminClient databaseAdminClient = DatabaseAdminClient.create(); + databaseAdminClient.updateDatabaseDdlAsync( + DatabaseName.of(projectId, instanceId, databaseId), + ImmutableList.of( + "CREATE TABLE Customers (\n" + + " CustomerId INT64 NOT NULL,\n" + + " CustomerName STRING(62) NOT NULL,\n" + + " ) PRIMARY KEY (CustomerId)", + "CREATE TABLE ShoppingCarts (\n" + + " CartId INT64 NOT NULL,\n" + + " CustomerId INT64 NOT NULL,\n" + + " CustomerName STRING(62) NOT NULL,\n" + + " CONSTRAINT FKShoppingCartsCustomerId FOREIGN KEY (CustomerId)\n" + + " REFERENCES Customers (CustomerId) ON DELETE CASCADE\n" + + " ) PRIMARY KEY (CartId)\n")); + + System.out.printf( + String.format( + "Created Customers and ShoppingCarts table with FKShoppingCartsCustomerId\n" + + "foreign key constraint on database %s on instance %s\n", + databaseId, instanceId)); + } +} +// [END spanner_create_table_with_foreign_key_delete_cascade] diff --git a/samples/snippets/src/main/java/com/example/spanner/admin/generated/DropForeignKeyConstraintDeleteCascadeSample.java b/samples/snippets/src/main/java/com/example/spanner/admin/generated/DropForeignKeyConstraintDeleteCascadeSample.java new file mode 100644 index 00000000000..7d569acea8d --- /dev/null +++ b/samples/snippets/src/main/java/com/example/spanner/admin/generated/DropForeignKeyConstraintDeleteCascadeSample.java @@ -0,0 +1,53 @@ +/* + * Copyright 2023 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.example.spanner.admin.generated; + +// [START spanner_drop_foreign_key_constraint_delete_cascade] + +import com.google.cloud.spanner.admin.database.v1.DatabaseAdminClient; +import com.google.common.collect.ImmutableList; +import com.google.spanner.admin.database.v1.DatabaseName; +import java.io.IOException; + +class DropForeignKeyConstraintDeleteCascadeSample { + + static void deleteForeignKeyDeleteCascadeConstraint() throws IOException { + // TODO(developer): Replace these variables before running the sample. + String projectId = "my-project"; + String instanceId = "my-instance"; + String databaseId = "my-database"; + + deleteForeignKeyDeleteCascadeConstraint(projectId, instanceId, databaseId); + } + + static void deleteForeignKeyDeleteCascadeConstraint( + String projectId, String instanceId, String databaseId) throws IOException { + DatabaseAdminClient databaseAdminClient = DatabaseAdminClient.create(); + databaseAdminClient.updateDatabaseDdlAsync( + DatabaseName.of(projectId, instanceId, databaseId), + ImmutableList.of( + "ALTER TABLE ShoppingCarts\n" + + " DROP CONSTRAINT FKShoppingCartsCustomerName\n")); + + System.out.printf( + String.format( + "Altered ShoppingCarts table to drop FKShoppingCartsCustomerName\n" + + "foreign key constraint on database %s on instance %s\n", + databaseId, instanceId)); + } +} +// [END spanner_drop_foreign_key_constraint_delete_cascade] diff --git a/samples/snippets/src/main/java/com/example/spanner/admin/generated/DropSequenceSample.java b/samples/snippets/src/main/java/com/example/spanner/admin/generated/DropSequenceSample.java new file mode 100644 index 00000000000..f9917677de1 --- /dev/null +++ b/samples/snippets/src/main/java/com/example/spanner/admin/generated/DropSequenceSample.java @@ -0,0 +1,66 @@ +/* + * Copyright 2023 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.example.spanner.admin.generated; + +// [START spanner_drop_sequence] + +import com.google.cloud.spanner.SpannerExceptionFactory; +import com.google.cloud.spanner.admin.database.v1.DatabaseAdminClient; +import com.google.common.collect.ImmutableList; +import com.google.spanner.admin.database.v1.DatabaseName; +import java.io.IOException; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.TimeoutException; + +public class DropSequenceSample { + + static void dropSequence() throws IOException { + // TODO(developer): Replace these variables before running the sample. + final String projectId = "my-project"; + final String instanceId = "my-instance"; + final String databaseId = "my-database"; + dropSequence(projectId, instanceId, databaseId); + } + + static void dropSequence(String projectId, String instanceId, String databaseId) + throws IOException { + DatabaseAdminClient databaseAdminClient = DatabaseAdminClient.create(); + try { + databaseAdminClient + .updateDatabaseDdlAsync(DatabaseName.of(projectId, instanceId, databaseId), + ImmutableList.of( + "ALTER TABLE Customers ALTER COLUMN CustomerId DROP DEFAULT", + "DROP SEQUENCE Seq")) + .get(5, TimeUnit.MINUTES); + System.out.println( + "Altered Customers table to drop DEFAULT from CustomerId column " + + "and dropped the Seq sequence"); + } catch (ExecutionException e) { + // If the operation failed during execution, expose the cause. + throw SpannerExceptionFactory.asSpannerException(e.getCause()); + } catch (InterruptedException e) { + // Throw when a thread is waiting, sleeping, or otherwise occupied, + // and the thread is interrupted, either before or during the activity. + throw SpannerExceptionFactory.propagateInterrupt(e); + } catch (TimeoutException e) { + // If the operation timed out propagate the timeout + throw SpannerExceptionFactory.propagateTimeout(e); + } + } +} +// [END spanner_drop_sequence] diff --git a/samples/snippets/src/main/java/com/example/spanner/admin/generated/EnableFineGrainedAccess.java b/samples/snippets/src/main/java/com/example/spanner/admin/generated/EnableFineGrainedAccess.java new file mode 100644 index 00000000000..7f66992cad1 --- /dev/null +++ b/samples/snippets/src/main/java/com/example/spanner/admin/generated/EnableFineGrainedAccess.java @@ -0,0 +1,106 @@ +/* + * Copyright 2022 Google Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.example.spanner.admin.generated; + +// [START spanner_enable_fine_grained_access] + +import com.google.cloud.spanner.admin.database.v1.DatabaseAdminClient; +import com.google.common.collect.ImmutableList; +import com.google.iam.v1.Binding; +import com.google.iam.v1.GetIamPolicyRequest; +import com.google.iam.v1.GetPolicyOptions; +import com.google.iam.v1.Policy; +import com.google.iam.v1.SetIamPolicyRequest; +import com.google.spanner.admin.database.v1.DatabaseName; +import com.google.type.Expr; +import java.io.IOException; + +public class EnableFineGrainedAccess { + + static void enableFineGrainedAccess() throws IOException { + // TODO(developer): Replace these variables before running the sample. + String projectId = "my-project"; + String instanceId = "my-instance"; + String databaseId = "my-database"; + String iamMember = "user:alice@example.com"; + String role = "my-role"; + String title = "my-condition-title"; + enableFineGrainedAccess(projectId, instanceId, databaseId, iamMember, title, role); + } + + static void enableFineGrainedAccess( + String projectId, + String instanceId, + String databaseId, + String iamMember, + String title, + String role) throws IOException { + final DatabaseAdminClient databaseAdminClient = DatabaseAdminClient.create(); + final GetPolicyOptions options = + GetPolicyOptions.newBuilder().setRequestedPolicyVersion(3).build(); + final GetIamPolicyRequest getRequest = + GetIamPolicyRequest.newBuilder() + .setResource(DatabaseName.of(projectId, instanceId, databaseId).toString()) + .setOptions(options).build(); + final Policy policy = databaseAdminClient.getIamPolicy(getRequest); + int policyVersion = policy.getVersion(); + // The policy in the response from getDatabaseIAMPolicy might use the policy version + // that you specified, or it might use a lower policy version. For example, if you + // specify version 3, but the policy has no conditional role bindings, the response + // uses version 1. Valid values are 0, 1, and 3. + if (policy.getVersion() < 3) { + // conditional role bindings work with policy version 3 + policyVersion = 3; + } + + Binding binding1 = + Binding.newBuilder() + .setRole("roles/spanner.fineGrainedAccessUser") + .addAllMembers(ImmutableList.of(iamMember)) + .build(); + + Binding binding2 = + Binding.newBuilder() + .setRole("roles/spanner.databaseRoleUser") + .setCondition( + Expr.newBuilder().setDescription(title).setExpression( + String.format("resource.name.endsWith(\"/databaseRoles/%s\")", role) + ).setTitle(title).build()) + .addAllMembers(ImmutableList.of(iamMember)) + .build(); + ImmutableList bindings = + ImmutableList.builder() + .addAll(policy.getBindingsList()) + .add(binding1) + .add(binding2) + .build(); + Policy policyWithConditions = + Policy.newBuilder() + .setVersion(policyVersion) + .setEtag(policy.getEtag()) + .addAllBindings(bindings) + .build(); + final SetIamPolicyRequest setRequest = + SetIamPolicyRequest.newBuilder() + .setResource(DatabaseName.of(projectId, instanceId, databaseId).toString()) + .setPolicy(policyWithConditions).build(); + final Policy response = databaseAdminClient.setIamPolicy(setRequest); + System.out.printf( + "Enabled fine-grained access in IAM with version %d%n", response.getVersion()); + } +} +// [END spanner_enable_fine_grained_access] diff --git a/samples/snippets/src/main/java/com/example/spanner/admin/generated/GetDatabaseDdlSample.java b/samples/snippets/src/main/java/com/example/spanner/admin/generated/GetDatabaseDdlSample.java new file mode 100644 index 00000000000..250136c1fb6 --- /dev/null +++ b/samples/snippets/src/main/java/com/example/spanner/admin/generated/GetDatabaseDdlSample.java @@ -0,0 +1,49 @@ +/* + * Copyright 2021 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.example.spanner.admin.generated; + +//[START spanner_get_database_ddl] + +import com.google.cloud.spanner.admin.database.v1.DatabaseAdminClient; +import com.google.spanner.admin.database.v1.DatabaseName; +import com.google.spanner.admin.database.v1.GetDatabaseDdlResponse; +import java.io.IOException; + +public class GetDatabaseDdlSample { + + static void getDatabaseDdl() throws IOException { + // TODO(developer): Replace these variables before running the sample. + final String projectId = "my-project"; + final String instanceId = "my-instance"; + final String databaseId = "my-database"; + getDatabaseDdl(projectId, instanceId, databaseId); + } + + static void getDatabaseDdl( + String projectId, String instanceId, String databaseId) throws IOException { + + final DatabaseAdminClient databaseAdminClient = DatabaseAdminClient.create(); + + final GetDatabaseDdlResponse response = + databaseAdminClient.getDatabaseDdl(DatabaseName.of(projectId, instanceId, databaseId)); + System.out.println("Retrieved database DDL for " + databaseId); + for (String ddl : response.getStatementsList()) { + System.out.println(ddl); + } + } +} +//[END spanner_get_database_ddl] diff --git a/samples/snippets/src/main/java/com/example/spanner/admin/generated/ListDatabaseRoles.java b/samples/snippets/src/main/java/com/example/spanner/admin/generated/ListDatabaseRoles.java new file mode 100644 index 00000000000..d5d8859673d --- /dev/null +++ b/samples/snippets/src/main/java/com/example/spanner/admin/generated/ListDatabaseRoles.java @@ -0,0 +1,52 @@ +/* + * Copyright 2022 Google Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.example.spanner.admin.generated; + +// [START spanner_list_database_roles] + +import com.google.cloud.spanner.admin.database.v1.DatabaseAdminClient; +import com.google.cloud.spanner.admin.database.v1.DatabaseAdminClient.ListDatabaseRolesPage; +import com.google.cloud.spanner.admin.database.v1.DatabaseAdminClient.ListDatabaseRolesPagedResponse; +import com.google.spanner.admin.database.v1.DatabaseName; +import com.google.spanner.admin.database.v1.DatabaseRole; +import java.io.IOException; + +public class ListDatabaseRoles { + + static void listDatabaseRoles() throws IOException { + // TODO(developer): Replace these variables before running the sample. + String projectId = "my-project"; + String instanceId = "my-instance"; + String databaseId = "my-database"; + listDatabaseRoles(projectId, instanceId, databaseId); + } + + static void listDatabaseRoles(String projectId, String instanceId, String databaseId) + throws IOException { + final DatabaseAdminClient databaseAdminClient = DatabaseAdminClient.create(); + DatabaseName databaseName = DatabaseName.of(projectId, instanceId, databaseId); + ListDatabaseRolesPagedResponse response + = databaseAdminClient.listDatabaseRoles(databaseName); + System.out.println("List of Database roles"); + for (ListDatabaseRolesPage page : response.iteratePages()) { + for (DatabaseRole role : page.iterateAll()) { + System.out.printf("Obtained role %s%n", role.getName()); + } + } + } +} +// [END spanner_list_database_roles] diff --git a/samples/snippets/src/main/java/com/example/spanner/admin/generated/ListDatabasesSample.java b/samples/snippets/src/main/java/com/example/spanner/admin/generated/ListDatabasesSample.java new file mode 100644 index 00000000000..7518064f2cd --- /dev/null +++ b/samples/snippets/src/main/java/com/example/spanner/admin/generated/ListDatabasesSample.java @@ -0,0 +1,54 @@ +/* + * Copyright 2021 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.example.spanner.admin.generated; + +//[START spanner_list_databases] + +import com.google.cloud.spanner.admin.database.v1.DatabaseAdminClient; +import com.google.cloud.spanner.admin.database.v1.DatabaseAdminClient.ListDatabasesPage; +import com.google.cloud.spanner.admin.database.v1.DatabaseAdminClient.ListDatabasesPagedResponse; +import com.google.spanner.admin.database.v1.Database; +import com.google.spanner.admin.database.v1.InstanceName; +import java.io.IOException; + +public class ListDatabasesSample { + + static void listDatabases() throws IOException { + // TODO(developer): Replace these variables before running the sample. + final String projectId = "my-project"; + final String instanceId = "my-instance"; + listDatabases(projectId, instanceId); + } + + static void listDatabases(String projectId, String instanceId) throws IOException { + final DatabaseAdminClient databaseAdminClient = DatabaseAdminClient.create(); + + ListDatabasesPagedResponse response = + databaseAdminClient.listDatabases(InstanceName.of(projectId, instanceId)); + + System.out.println("Databases for projects/" + projectId + "/instances/" + instanceId); + + for (ListDatabasesPage page : response.iteratePages()) { + for (Database database : page.iterateAll()) { + final String defaultLeader = database.getDefaultLeader().equals("") + ? "" : "(default leader = " + database.getDefaultLeader() + ")"; + System.out.println("\t" + database.getName() + " " + defaultLeader); + } + } + } +} +//[END spanner_list_databases] diff --git a/samples/snippets/src/main/java/com/example/spanner/admin/generated/PgAlterSequenceSample.java b/samples/snippets/src/main/java/com/example/spanner/admin/generated/PgAlterSequenceSample.java new file mode 100644 index 00000000000..39a4cd543a6 --- /dev/null +++ b/samples/snippets/src/main/java/com/example/spanner/admin/generated/PgAlterSequenceSample.java @@ -0,0 +1,92 @@ +/* + * Copyright 2023 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.example.spanner.admin.generated; + +// [START spanner_postgresql_alter_sequence] + +import com.google.cloud.spanner.DatabaseClient; +import com.google.cloud.spanner.DatabaseId; +import com.google.cloud.spanner.ResultSet; +import com.google.cloud.spanner.Spanner; +import com.google.cloud.spanner.SpannerExceptionFactory; +import com.google.cloud.spanner.SpannerOptions; +import com.google.cloud.spanner.Statement; +import com.google.cloud.spanner.admin.database.v1.DatabaseAdminClient; +import com.google.common.collect.ImmutableList; +import com.google.spanner.admin.database.v1.DatabaseName; +import java.io.IOException; +import java.util.Objects; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.TimeoutException; + +public class PgAlterSequenceSample { + + static void pgAlterSequence() throws IOException { + // TODO(developer): Replace these variables before running the sample. + final String projectId = "my-project"; + final String instanceId = "my-instance"; + final String databaseId = "my-database"; + pgAlterSequence(projectId, instanceId, databaseId); + } + + static void pgAlterSequence(String projectId, String instanceId, String databaseId) + throws IOException { + try (Spanner spanner = + SpannerOptions.newBuilder().setProjectId(projectId).build().getService()) { + final DatabaseAdminClient databaseAdminClient = DatabaseAdminClient.create(); + databaseAdminClient + .updateDatabaseDdlAsync( + DatabaseName.of(projectId, instanceId, databaseId), + ImmutableList.of("ALTER SEQUENCE Seq SKIP RANGE 1000 5000000")) + .get(5, TimeUnit.MINUTES); + System.out.println( + "Altered Seq sequence to skip an inclusive range between 1000 and 5000000"); + final DatabaseClient dbClient = + spanner.getDatabaseClient(DatabaseId.of(projectId, instanceId, databaseId)); + Long insertCount = + dbClient + .readWriteTransaction() + .run( + transaction -> { + try (ResultSet rs = + transaction.executeQuery( + Statement.of( + "INSERT INTO Customers (CustomerName) VALUES " + + "('Lea'), ('Catalina'), ('Smith') RETURNING CustomerId"))) { + while (rs.next()) { + System.out.printf( + "Inserted customer record with CustomerId: %d\n", rs.getLong(0)); + } + return Objects.requireNonNull(rs.getStats()).getRowCountExact(); + } + }); + System.out.printf("Number of customer records inserted is: %d\n", insertCount); + } catch (ExecutionException e) { + // If the operation failed during execution, expose the cause. + throw SpannerExceptionFactory.asSpannerException(e.getCause()); + } catch (InterruptedException e) { + // Throw when a thread is waiting, sleeping, or otherwise occupied, + // and the thread is interrupted, either before or during the activity. + throw SpannerExceptionFactory.propagateInterrupt(e); + } catch (TimeoutException e) { + // If the operation timed out propagate the timeout + throw SpannerExceptionFactory.propagateTimeout(e); + } + } +} +// [END spanner_postgresql_alter_sequence] diff --git a/samples/snippets/src/main/java/com/example/spanner/admin/generated/PgCaseSensitivitySample.java b/samples/snippets/src/main/java/com/example/spanner/admin/generated/PgCaseSensitivitySample.java new file mode 100644 index 00000000000..951b46446f1 --- /dev/null +++ b/samples/snippets/src/main/java/com/example/spanner/admin/generated/PgCaseSensitivitySample.java @@ -0,0 +1,153 @@ +/* + * Copyright 2022 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.example.spanner.admin.generated; + +// [START spanner_postgresql_identifier_case_sensitivity] + +import com.google.cloud.spanner.DatabaseClient; +import com.google.cloud.spanner.DatabaseId; +import com.google.cloud.spanner.Mutation; +import com.google.cloud.spanner.ResultSet; +import com.google.cloud.spanner.Spanner; +import com.google.cloud.spanner.SpannerExceptionFactory; +import com.google.cloud.spanner.SpannerOptions; +import com.google.cloud.spanner.Statement; +import com.google.cloud.spanner.admin.database.v1.DatabaseAdminClient; +import com.google.common.collect.Lists; +import com.google.spanner.admin.database.v1.DatabaseName; +import java.io.IOException; +import java.util.Collections; +import java.util.concurrent.ExecutionException; + +public class PgCaseSensitivitySample { + + static void pgCaseSensitivity() throws IOException { + // TODO(developer): Replace these variables before running the sample. + final String projectId = "my-project"; + final String instanceId = "my-instance"; + final String databaseId = "my-database"; + pgCaseSensitivity(projectId, instanceId, databaseId); + } + + static void pgCaseSensitivity(String projectId, String instanceId, String databaseId) + throws IOException { + DatabaseAdminClient databaseAdminClient = DatabaseAdminClient.create(); + + try (Spanner spanner = + SpannerOptions.newBuilder() + .setProjectId(projectId) + .build() + .getService()) { + + // Spanner PostgreSQL follows the case sensitivity rules of PostgreSQL. This means that: + // 1. Identifiers that are not double-quoted are folded to lower case. + // 2. Identifiers that are double-quoted retain their case and are case-sensitive. + // See https://www.postgresql.org/docs/current/sql-syntax-lexical.html#SQL-SYNTAX-IDENTIFIERS + // for more information. + databaseAdminClient.updateDatabaseDdlAsync( + DatabaseName.of(projectId, instanceId, databaseId), + Lists.newArrayList( + "CREATE TABLE Singers (" + // SingerId will be folded to `singerid`. + + " SingerId bigint NOT NULL PRIMARY KEY," + // FirstName and LastName are double-quoted and will therefore retain their + // mixed case and are case-sensitive. This means that any statement that + // references any of these columns must use double quotes. + + " \"FirstName\" varchar(1024) NOT NULL," + + " \"LastName\" varchar(1024) NOT NULL" + + ")")).get(); + + DatabaseClient client = + spanner.getDatabaseClient(DatabaseId.of(projectId, instanceId, databaseId)); + + client.write( + Collections.singleton( + Mutation.newInsertBuilder("Singers") + .set("singerid") + .to(1L) + // Column names in mutations are always case-insensitive, regardless whether the + // columns were double-quoted or not during creation. + .set("firstname") + .to("Bruce") + .set("lastname") + .to("Allison") + .build())); + + try (ResultSet singers = + client + .singleUse() + .executeQuery( + Statement.of("SELECT SingerId, \"FirstName\", \"LastName\" FROM Singers"))) { + while (singers.next()) { + System.out.printf( + "SingerId: %d, FirstName: %s, LastName: %s\n", + // SingerId is automatically folded to lower case. Accessing the column by its name in + // a result set must therefore use all lower-case letters. + singers.getLong("singerid"), + // FirstName and LastName were double-quoted during creation, and retain their mixed + // case when returned in a result set. + singers.getString("FirstName"), + singers.getString("LastName")); + } + } + + // Aliases are also identifiers, and specifying an alias in double quotes will make the alias + // retain its case. + try (ResultSet singers = + client + .singleUse() + .executeQuery( + Statement.of( + "SELECT " + + "singerid AS \"SingerId\", " + + "concat(\"FirstName\", ' '::varchar, \"LastName\") AS \"FullName\" " + + "FROM Singers"))) { + while (singers.next()) { + System.out.printf( + "SingerId: %d, FullName: %s\n", + // The aliases are double-quoted and therefore retains their mixed case. + singers.getLong("SingerId"), singers.getString("FullName")); + } + } + + // DML statements must also follow the PostgreSQL case rules. + client + .readWriteTransaction() + .run( + transaction -> + transaction.executeUpdate( + Statement.newBuilder( + "INSERT INTO Singers (SingerId, \"FirstName\", \"LastName\") " + + "VALUES ($1, $2, $3)") + .bind("p1") + .to(2L) + .bind("p2") + .to("Alice") + .bind("p3") + .to("Bruxelles") + .build())); + } catch (ExecutionException e) { + // If the operation failed during execution, expose the cause. + throw SpannerExceptionFactory.asSpannerException(e.getCause()); + } catch (InterruptedException e) { + // Throw when a thread is waiting, sleeping, or otherwise occupied, + // and the thread is interrupted, either before or during the activity. + throw SpannerExceptionFactory.propagateInterrupt(e); + } + } +} +// [END spanner_postgresql_identifier_case_sensitivity] \ No newline at end of file diff --git a/samples/snippets/src/main/java/com/example/spanner/admin/generated/PgCreateSequenceSample.java b/samples/snippets/src/main/java/com/example/spanner/admin/generated/PgCreateSequenceSample.java new file mode 100644 index 00000000000..6e7d9c34c57 --- /dev/null +++ b/samples/snippets/src/main/java/com/example/spanner/admin/generated/PgCreateSequenceSample.java @@ -0,0 +1,99 @@ +/* + * Copyright 2023 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.example.spanner.admin.generated; + +// [START spanner_postgresql_create_sequence] + +import com.google.cloud.spanner.DatabaseClient; +import com.google.cloud.spanner.DatabaseId; +import com.google.cloud.spanner.ResultSet; +import com.google.cloud.spanner.Spanner; +import com.google.cloud.spanner.SpannerExceptionFactory; +import com.google.cloud.spanner.SpannerOptions; +import com.google.cloud.spanner.Statement; +import com.google.cloud.spanner.admin.database.v1.DatabaseAdminClient; +import com.google.common.collect.ImmutableList; +import com.google.spanner.admin.database.v1.DatabaseName; +import java.io.IOException; +import java.util.Objects; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.TimeoutException; + +public class PgCreateSequenceSample { + + static void pgCreateSequence() throws IOException { + // TODO(developer): Replace these variables before running the sample. + final String projectId = "my-project"; + final String instanceId = "my-instance"; + final String databaseId = "my-database"; + pgCreateSequence(projectId, instanceId, databaseId); + } + + static void pgCreateSequence(String projectId, String instanceId, String databaseId) + throws IOException { + DatabaseAdminClient databaseAdminClient = DatabaseAdminClient.create(); + + try (Spanner spanner = + SpannerOptions.newBuilder().setProjectId(projectId).build().getService()) { + databaseAdminClient + .updateDatabaseDdlAsync(DatabaseName.of(projectId, instanceId, databaseId).toString(), + ImmutableList.of( + "CREATE SEQUENCE Seq BIT_REVERSED_POSITIVE;", + "CREATE TABLE Customers (CustomerId BIGINT DEFAULT nextval('Seq'), " + + "CustomerName character varying(1024), PRIMARY KEY (CustomerId))")) + .get(5, TimeUnit.MINUTES); + + System.out.println( + "Created Seq sequence and Customers table, where the key column " + + "CustomerId uses the sequence as a default value"); + + final DatabaseClient dbClient = + spanner.getDatabaseClient(DatabaseId.of(projectId, instanceId, databaseId)); + + Long insertCount = + dbClient + .readWriteTransaction() + .run( + transaction -> { + try (ResultSet rs = + transaction.executeQuery( + Statement.of( + "INSERT INTO Customers (CustomerName) VALUES " + + "('Alice'), ('David'), ('Marc') RETURNING CustomerId"))) { + while (rs.next()) { + System.out.printf( + "Inserted customer record with CustomerId: %d\n", rs.getLong(0)); + } + return Objects.requireNonNull(rs.getStats()).getRowCountExact(); + } + }); + System.out.printf("Number of customer records inserted is: %d\n", insertCount); + } catch (ExecutionException e) { + // If the operation failed during execution, expose the cause. + throw SpannerExceptionFactory.asSpannerException(e.getCause()); + } catch (InterruptedException e) { + // Throw when a thread is waiting, sleeping, or otherwise occupied, + // and the thread is interrupted, either before or during the activity. + throw SpannerExceptionFactory.propagateInterrupt(e); + } catch (TimeoutException e) { + // If the operation timed out propagate the timeout + throw SpannerExceptionFactory.propagateTimeout(e); + } + } +} +// [END spanner_postgresql_create_sequence] diff --git a/samples/snippets/src/main/java/com/example/spanner/admin/generated/PgDropSequenceSample.java b/samples/snippets/src/main/java/com/example/spanner/admin/generated/PgDropSequenceSample.java new file mode 100644 index 00000000000..dec927d20ac --- /dev/null +++ b/samples/snippets/src/main/java/com/example/spanner/admin/generated/PgDropSequenceSample.java @@ -0,0 +1,71 @@ +/* + * Copyright 2023 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.example.spanner.admin.generated; + +// [START spanner_postgresql_drop_sequence] + +import com.google.cloud.spanner.Spanner; +import com.google.cloud.spanner.SpannerExceptionFactory; +import com.google.cloud.spanner.SpannerOptions; +import com.google.cloud.spanner.admin.database.v1.DatabaseAdminClient; +import com.google.common.collect.ImmutableList; +import com.google.spanner.admin.database.v1.DatabaseName; +import java.io.IOException; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.TimeoutException; + +public class PgDropSequenceSample { + + static void pgDropSequence() throws IOException { + // TODO(developer): Replace these variables before running the sample. + final String projectId = "my-project"; + final String instanceId = "my-instance"; + final String databaseId = "my-database"; + pgDropSequence(projectId, instanceId, databaseId); + } + + static void pgDropSequence(String projectId, String instanceId, String databaseId) + throws IOException { + DatabaseAdminClient databaseAdminClient = DatabaseAdminClient.create(); + + try (Spanner spanner = + SpannerOptions.newBuilder().setProjectId(projectId).build().getService()) { + databaseAdminClient + .updateDatabaseDdlAsync( + DatabaseName.of(projectId, instanceId, databaseId), + ImmutableList.of( + "ALTER TABLE Customers ALTER COLUMN CustomerId DROP DEFAULT", + "DROP SEQUENCE Seq")) + .get(5, TimeUnit.MINUTES); + System.out.println( + "Altered Customers table to drop DEFAULT from " + + "CustomerId column and dropped the Seq sequence"); + } catch (ExecutionException e) { + // If the operation failed during execution, expose the cause. + throw SpannerExceptionFactory.asSpannerException(e.getCause()); + } catch (InterruptedException e) { + // Throw when a thread is waiting, sleeping, or otherwise occupied, + // and the thread is interrupted, either before or during the activity. + throw SpannerExceptionFactory.propagateInterrupt(e); + } catch (TimeoutException e) { + // If the operation timed out propagate the timeout + throw SpannerExceptionFactory.propagateTimeout(e); + } + } +} +// [END spanner_postgresql_drop_sequence] diff --git a/samples/snippets/src/main/java/com/example/spanner/admin/generated/PgInterleavedTableSample.java b/samples/snippets/src/main/java/com/example/spanner/admin/generated/PgInterleavedTableSample.java new file mode 100644 index 00000000000..14af53dc5a8 --- /dev/null +++ b/samples/snippets/src/main/java/com/example/spanner/admin/generated/PgInterleavedTableSample.java @@ -0,0 +1,72 @@ +/* + * Copyright 2022 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.example.spanner.admin.generated; + +// [START spanner_postgresql_interleaved_table] + +import com.google.cloud.spanner.SpannerExceptionFactory; +import com.google.cloud.spanner.admin.database.v1.DatabaseAdminClient; +import com.google.spanner.admin.database.v1.DatabaseName; +import java.io.IOException; +import java.util.Arrays; +import java.util.concurrent.ExecutionException; + +public class PgInterleavedTableSample { + + static void pgInterleavedTable() throws IOException { + // TODO(developer): Replace these variables before running the sample. + final String projectId = "my-project"; + final String instanceId = "my-instance"; + final String databaseId = "my-database"; + pgInterleavedTable(projectId, instanceId, databaseId); + } + + static void pgInterleavedTable(String projectId, String instanceId, String databaseId) + throws IOException { + DatabaseAdminClient databaseAdminClient = DatabaseAdminClient.create(); + try { + // The Spanner PostgreSQL dialect extends the PostgreSQL dialect with certain Spanner + // specific features, such as interleaved tables. + // See https://cloud.google.com/spanner/docs/postgresql/data-definition-language#create_table + // for the full CREATE TABLE syntax. + databaseAdminClient.updateDatabaseDdlAsync(DatabaseName.of(projectId, + instanceId, + databaseId), + Arrays.asList( + "CREATE TABLE Singers (" + + " SingerId bigint NOT NULL PRIMARY KEY," + + " FirstName varchar(1024) NOT NULL," + + " LastName varchar(1024) NOT NULL" + + ")", + "CREATE TABLE Albums (" + + " SingerId bigint NOT NULL," + + " AlbumId bigint NOT NULL," + + " Title varchar(1024) NOT NULL," + + " PRIMARY KEY (SingerId, AlbumId)" + + ") INTERLEAVE IN PARENT Singers ON DELETE CASCADE")).get(); + System.out.println("Created interleaved table hierarchy using PostgreSQL dialect"); + } catch (ExecutionException e) { + // If the operation failed during execution, expose the cause. + throw SpannerExceptionFactory.asSpannerException(e.getCause()); + } catch (InterruptedException e) { + // Throw when a thread is waiting, sleeping, or otherwise occupied, + // and the thread is interrupted, either before or during the activity. + throw SpannerExceptionFactory.propagateInterrupt(e); + } + } +} +// [END spanner_postgresql_interleaved_table] \ No newline at end of file diff --git a/samples/snippets/src/main/java/com/example/spanner/admin/generated/UpdateDatabaseSample.java b/samples/snippets/src/main/java/com/example/spanner/admin/generated/UpdateDatabaseSample.java new file mode 100644 index 00000000000..958be6e20a4 --- /dev/null +++ b/samples/snippets/src/main/java/com/example/spanner/admin/generated/UpdateDatabaseSample.java @@ -0,0 +1,76 @@ +/* + * Copyright 2023 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.example.spanner.admin.generated; + +// [START spanner_update_database] + +import com.google.api.gax.longrunning.OperationFuture; +import com.google.cloud.spanner.SpannerExceptionFactory; +import com.google.cloud.spanner.admin.database.v1.DatabaseAdminClient; +import com.google.common.collect.Lists; +import com.google.protobuf.FieldMask; +import com.google.spanner.admin.database.v1.Database; +import com.google.spanner.admin.database.v1.DatabaseName; +import com.google.spanner.admin.database.v1.UpdateDatabaseMetadata; +import com.google.spanner.admin.database.v1.UpdateDatabaseRequest; +import java.io.IOException; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.TimeoutException; + +public class UpdateDatabaseSample { + + static void updateDatabase() throws IOException { + // TODO(developer): Replace these variables before running the sample. + final String projectId = "my-project"; + final String instanceId = "my-instance"; + final String databaseId = "my-database"; + + updateDatabase(projectId, instanceId, databaseId); + } + + static void updateDatabase( + String projectId, String instanceId, String databaseId) throws IOException { + DatabaseAdminClient databaseAdminClient = DatabaseAdminClient.create(); + try { + final Database database = + Database.newBuilder() + .setName(DatabaseName.of(projectId, instanceId, databaseId).toString()) + .setEnableDropProtection(true).build(); + final UpdateDatabaseRequest updateDatabaseRequest = + UpdateDatabaseRequest.newBuilder() + .setDatabase(database) + .setUpdateMask( + FieldMask.newBuilder().addAllPaths( + Lists.newArrayList("enable_drop_protection")).build()) + .build(); + OperationFuture operation = + databaseAdminClient.updateDatabaseAsync(updateDatabaseRequest); + System.out.printf("Waiting for update operation for %s to complete...\n", databaseId); + Database updatedDb = operation.get(5, TimeUnit.MINUTES); + System.out.printf("Updated database %s.\n", updatedDb.getName()); + } catch (ExecutionException | TimeoutException e) { + // If the operation failed during execution, expose the cause. + throw SpannerExceptionFactory.asSpannerException(e.getCause()); + } catch (InterruptedException e) { + // Throw when a thread is waiting, sleeping, or otherwise occupied, + // and the thread is interrupted, either before or during the activity. + throw SpannerExceptionFactory.propagateInterrupt(e); + } + } +} +// [END spanner_update_database] diff --git a/samples/snippets/src/main/java/com/example/spanner/admin/generated/UpdateDatabaseWithDefaultLeaderSample.java b/samples/snippets/src/main/java/com/example/spanner/admin/generated/UpdateDatabaseWithDefaultLeaderSample.java new file mode 100644 index 00000000000..5306358714e --- /dev/null +++ b/samples/snippets/src/main/java/com/example/spanner/admin/generated/UpdateDatabaseWithDefaultLeaderSample.java @@ -0,0 +1,69 @@ +/* + * Copyright 2021 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.example.spanner.admin.generated; + +//[START spanner_update_database_with_default_leader] + +import com.google.api.gax.longrunning.OperationFuture; +import com.google.cloud.spanner.SpannerException; +import com.google.cloud.spanner.SpannerExceptionFactory; +import com.google.cloud.spanner.admin.database.v1.DatabaseAdminClient; +import com.google.spanner.admin.database.v1.DatabaseName; +import java.io.IOException; +import java.util.Collections; +import java.util.concurrent.ExecutionException; + +public class UpdateDatabaseWithDefaultLeaderSample { + + static void updateDatabaseWithDefaultLeader() throws IOException { + // TODO(developer): Replace these variables before running the sample. + final String projectId = "my-project"; + final String instanceId = "my-instance"; + final String databaseId = "my-database"; + final String defaultLeader = "my-default-leader"; + updateDatabaseWithDefaultLeader(projectId, instanceId, databaseId, defaultLeader); + } + + static void updateDatabaseWithDefaultLeader( + String projectId, String instanceId, String databaseId, String defaultLeader) + throws IOException { + DatabaseAdminClient databaseAdminClient = DatabaseAdminClient.create(); + + try { + databaseAdminClient + .updateDatabaseDdlAsync( + DatabaseName.of(projectId, instanceId, databaseId), + Collections.singletonList( + String.format( + "ALTER DATABASE `%s` SET OPTIONS (default_leader = '%s')", + databaseId, + defaultLeader + ) + ) + ).get(); + System.out.println("Updated default leader to " + defaultLeader); + } catch (ExecutionException e) { + // If the operation failed during execution, expose the cause. + throw (SpannerException) e.getCause(); + } catch (InterruptedException e) { + // Throw when a thread is waiting, sleeping, or otherwise occupied, + // and the thread is interrupted, either before or during the activity. + throw SpannerExceptionFactory.propagateInterrupt(e); + } + } +} +//[END spanner_update_database_with_default_leader] diff --git a/samples/snippets/src/test/java/com/example/spanner/admin/generated/AlterTableWithForeignKeyDeleteCascadeSampleIT.java b/samples/snippets/src/test/java/com/example/spanner/admin/generated/AlterTableWithForeignKeyDeleteCascadeSampleIT.java new file mode 100644 index 00000000000..2295119b69c --- /dev/null +++ b/samples/snippets/src/test/java/com/example/spanner/admin/generated/AlterTableWithForeignKeyDeleteCascadeSampleIT.java @@ -0,0 +1,70 @@ +/* + * Copyright 2023 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.example.spanner.admin.generated; + +import static org.junit.Assert.assertTrue; + +import com.example.spanner.SampleRunner; +import com.example.spanner.SampleTestBase; +import com.google.spanner.admin.database.v1.CreateDatabaseRequest; +import com.google.spanner.admin.database.v1.DatabaseDialect; +import com.google.spanner.admin.database.v1.InstanceName; +import java.util.Arrays; +import java.util.concurrent.TimeUnit; +import org.junit.Test; + +public class AlterTableWithForeignKeyDeleteCascadeSampleIT extends SampleTestBaseV2 { + + @Test + public void testAlterTableWithForeignKeyDeleteCascade() throws Exception { + + // Creates database + final String databaseId = idGenerator.generateDatabaseId(); + final CreateDatabaseRequest request = + CreateDatabaseRequest.newBuilder() + .setCreateStatement("CREATE DATABASE `" + databaseId + "`") + .setParent(InstanceName.of(projectId, instanceId).toString()) + .addAllExtraStatements(Arrays.asList( + "CREATE TABLE Customers (\n" + + " CustomerId INT64 NOT NULL,\n" + + " CustomerName STRING(62) NOT NULL,\n" + + " ) PRIMARY KEY (CustomerId)", + "CREATE TABLE ShoppingCarts (\n" + + " CartId INT64 NOT NULL,\n" + + " CustomerId INT64 NOT NULL,\n" + + " CustomerName STRING(62) NOT NULL,\n" + + " CONSTRAINT FKShoppingCartsCustomerId" + + " FOREIGN KEY (CustomerId)\n" + + " REFERENCES Customers (CustomerId)\n" + + " ) PRIMARY KEY (CartId)\n")).build(); + databaseAdminClient.createDatabaseAsync(request).get(5, TimeUnit.MINUTES); + + // Runs sample + final String out = + SampleRunner.runSample( + () -> + AlterTableWithForeignKeyDeleteCascadeSample.alterForeignKeyDeleteCascadeConstraint( + projectId, instanceId, databaseId)); + + assertTrue( + "Expected to have created database " + + databaseId + + " with tables containing " + + "foreign key constraints.", + out.contains("Altered ShoppingCarts table " + "with FKShoppingCartsCustomerName")); + } +} diff --git a/samples/snippets/src/test/java/com/example/spanner/admin/generated/CreateDatabaseWithDefaultLeaderSampleIT.java b/samples/snippets/src/test/java/com/example/spanner/admin/generated/CreateDatabaseWithDefaultLeaderSampleIT.java deleted file mode 100644 index 39d02e1ed5c..00000000000 --- a/samples/snippets/src/test/java/com/example/spanner/admin/generated/CreateDatabaseWithDefaultLeaderSampleIT.java +++ /dev/null @@ -1,61 +0,0 @@ -/* - * Copyright 2023 Google LLC - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.example.spanner.admin.generated; - -import static org.junit.Assert.assertTrue; - -import com.example.spanner.SampleRunner; -import com.google.spanner.admin.instance.v1.InstanceConfig; -import com.google.spanner.admin.instance.v1.InstanceName; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.junit.runners.JUnit4; - -@RunWith(JUnit4.class) -public class CreateDatabaseWithDefaultLeaderSampleIT extends SampleTestBaseV2 { - - @Test - public void testCreateDatabaseWithDefaultLeader() throws Exception { - final String databaseId = idGenerator.generateDatabaseId(); - - // Finds possible default leader - - final String instanceConfigId = instanceAdminClient.getInstance( - InstanceName.of(projectId, multiRegionalInstanceId)).getConfig(); - final InstanceConfig config = instanceAdminClient.getInstanceConfig(instanceConfigId); - assertTrue( - "Expected instance config " + instanceConfigId + " to have at least one leader option", - config.getLeaderOptionsCount() > 0 - ); - final String defaultLeader = config.getLeaderOptions(0); - - // Runs sample - final String out = SampleRunner.runSample(() -> - CreateDatabaseWithDefaultLeaderSample.createDatabaseWithDefaultLeader( - getInstanceName(projectId, multiRegionalInstanceId), - databaseId, - defaultLeader - ) - ); - - assertTrue( - "Expected created database to have default leader " + defaultLeader + "." - + " Output received was " + out, - out.contains("Default leader: " + defaultLeader) - ); - } -} diff --git a/samples/snippets/src/test/java/com/example/spanner/admin/generated/CreateDatabaseWithVersionRetentionPeriodSampleIT.java b/samples/snippets/src/test/java/com/example/spanner/admin/generated/CreateDatabaseWithVersionRetentionPeriodSampleIT.java new file mode 100644 index 00000000000..64400fbf210 --- /dev/null +++ b/samples/snippets/src/test/java/com/example/spanner/admin/generated/CreateDatabaseWithVersionRetentionPeriodSampleIT.java @@ -0,0 +1,47 @@ +/* + * Copyright 2021 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.example.spanner.admin.generated; + +import static com.google.common.truth.Truth.assertThat; + +import com.example.spanner.SampleRunner; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.JUnit4; + +/** + * Integration tests for {@link com.example.spanner.CreateDatabaseWithVersionRetentionPeriodSample} + */ +@RunWith(JUnit4.class) +public class CreateDatabaseWithVersionRetentionPeriodSampleIT extends SampleTestBaseV2 { + + @Test + public void createsDatabaseWithVersionRetentionPeriod() throws Exception { + final String databaseId = idGenerator.generateDatabaseId(); + final String versionRetentionPeriod = "7d"; + + final String out = SampleRunner.runSample(() -> CreateDatabaseWithVersionRetentionPeriodSample + .createDatabaseWithVersionRetentionPeriod( + projectId, instanceId, databaseId, versionRetentionPeriod + )); + + assertThat(out).contains( + "Created database [projects/" + projectId + "/instances/" + instanceId + "/databases/" + + databaseId + "]"); + assertThat(out).contains("Version retention period: " + versionRetentionPeriod); + } +} diff --git a/samples/snippets/src/test/java/com/example/spanner/admin/generated/CreateTableWithForeignKeyDeleteCascadeSampleIT.java b/samples/snippets/src/test/java/com/example/spanner/admin/generated/CreateTableWithForeignKeyDeleteCascadeSampleIT.java new file mode 100644 index 00000000000..6fd9aeddb16 --- /dev/null +++ b/samples/snippets/src/test/java/com/example/spanner/admin/generated/CreateTableWithForeignKeyDeleteCascadeSampleIT.java @@ -0,0 +1,57 @@ +/* + * Copyright 2023 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.example.spanner.admin.generated; + +import static org.junit.Assert.assertTrue; + +import com.example.spanner.SampleRunner; +import com.example.spanner.SampleTestBase; +import com.google.spanner.admin.database.v1.CreateDatabaseRequest; +import com.google.spanner.admin.database.v1.InstanceName; +import java.util.Arrays; +import java.util.concurrent.TimeUnit; +import org.junit.Test; + +public class CreateTableWithForeignKeyDeleteCascadeSampleIT extends SampleTestBaseV2 { + + @Test + public void testCreateTableWithForeignKeyDeleteCascade() throws Exception { + + // Creates database + final String databaseId = idGenerator.generateDatabaseId(); + final CreateDatabaseRequest request = + CreateDatabaseRequest.newBuilder() + .setCreateStatement("CREATE DATABASE `" + databaseId + "`") + .setParent(InstanceName.of(projectId, instanceId).toString()).build(); + databaseAdminClient.createDatabaseAsync(request).get(5, TimeUnit.MINUTES); + + // Runs sample + final String out = + SampleRunner.runSample( + () -> + CreateTableWithForeignKeyDeleteCascadeSample + .createForeignKeyDeleteCascadeConstraint(projectId, instanceId, databaseId)); + + assertTrue( + "Expected to have created database " + + databaseId + + " with tables containing " + + "foreign key constraints.", + out.contains( + "Created Customers and ShoppingCarts table " + "with FKShoppingCartsCustomerId")); + } +} diff --git a/samples/snippets/src/test/java/com/example/spanner/admin/generated/DatabaseRolesIT.java b/samples/snippets/src/test/java/com/example/spanner/admin/generated/DatabaseRolesIT.java new file mode 100644 index 00000000000..93b19a2b330 --- /dev/null +++ b/samples/snippets/src/test/java/com/example/spanner/admin/generated/DatabaseRolesIT.java @@ -0,0 +1,126 @@ +/* + * Copyright 2022 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.example.spanner.admin.generated; + +import static org.junit.Assert.assertTrue; + +import com.example.spanner.SampleRunner; +import com.google.cloud.spanner.DatabaseClient; +import com.google.cloud.spanner.DatabaseId; +import com.google.cloud.spanner.KeySet; +import com.google.cloud.spanner.Mutation; +import com.google.common.collect.Lists; +import com.google.spanner.admin.database.v1.CreateDatabaseRequest; +import java.util.Arrays; +import java.util.Collections; +import java.util.concurrent.TimeUnit; +import org.junit.After; +import org.junit.Before; +import org.junit.BeforeClass; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.JUnit4; + +/** + * Integration tests for FGAC samples for GoogleStandardSql dialect. + */ +@RunWith(JUnit4.class) +public class DatabaseRolesIT extends SampleTestBaseV2 { + + private static DatabaseId databaseId; + + @BeforeClass + public static void createTestDatabase() throws Exception { + final String database = idGenerator.generateDatabaseId(); + final CreateDatabaseRequest request = + CreateDatabaseRequest.newBuilder() + .setParent( + com.google.spanner.admin.database.v1.InstanceName.of(projectId, instanceId) + .toString()) + .setCreateStatement("CREATE DATABASE `" + database + "`") + .addAllExtraStatements(Lists.newArrayList( + "CREATE TABLE Singers (" + + " SingerId INT64 NOT NULL," + + " FirstName STRING(1024)," + + " LastName STRING(1024)," + + " SingerInfo BYTES(MAX)," + + " FullName STRING(2048) AS " + + " (ARRAY_TO_STRING([FirstName, LastName], \" \")) STORED" + + ") PRIMARY KEY (SingerId)", + "CREATE TABLE Albums (" + + " SingerId INT64 NOT NULL," + + " AlbumId INT64 NOT NULL," + + " AlbumTitle STRING(MAX)," + + " MarketingBudget INT64" + + ") PRIMARY KEY (SingerId, AlbumId)," + + " INTERLEAVE IN PARENT Singers ON DELETE CASCADE")).build(); + databaseAdminClient.createDatabaseAsync(request).get(5, TimeUnit.MINUTES); + databaseId = DatabaseId.of(projectId, instanceId, database); + } + + @Before + public void insertTestData() { + final DatabaseClient client = spanner.getDatabaseClient(databaseId); + client.write( + Arrays.asList( + Mutation.newInsertOrUpdateBuilder("Singers") + .set("SingerId") + .to(1L) + .set("FirstName") + .to("Melissa") + .set("LastName") + .to("Garcia") + .build(), + Mutation.newInsertOrUpdateBuilder("Albums") + .set("SingerId") + .to(1L) + .set("AlbumId") + .to(1L) + .set("AlbumTitle") + .to("title 1") + .set("MarketingBudget") + .to(20000L) + .build())); + } + + @After + public void removeTestData() { + final DatabaseClient client = spanner.getDatabaseClient(databaseId); + client.write(Collections.singletonList(Mutation.delete("Singers", KeySet.all()))); + } + + @Test + public void testAddAndDropDatabaseRole() throws Exception { + final String out = + SampleRunner.runSample( + () -> + AddAndDropDatabaseRole.addAndDropDatabaseRole( + projectId, instanceId, databaseId.getDatabase(), "new_parent", "new_child")); + assertTrue(out.contains("Created roles new_parent and new_child and granted privileges")); + assertTrue(out.contains("Revoked privileges and dropped role new_child")); + } + + @Test + public void testListDatabaseRoles() throws Exception { + final String out = + SampleRunner.runSample( + () -> + ListDatabaseRoles.listDatabaseRoles( + projectId, instanceId, databaseId.getDatabase())); + assertTrue(out.contains("Obtained role ")); + } +} diff --git a/samples/snippets/src/test/java/com/example/spanner/admin/generated/DropForeignKeyConstraintDeleteCascadeSampleIT.java b/samples/snippets/src/test/java/com/example/spanner/admin/generated/DropForeignKeyConstraintDeleteCascadeSampleIT.java new file mode 100644 index 00000000000..f2dae05237a --- /dev/null +++ b/samples/snippets/src/test/java/com/example/spanner/admin/generated/DropForeignKeyConstraintDeleteCascadeSampleIT.java @@ -0,0 +1,68 @@ +/* + * Copyright 2023 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.example.spanner.admin.generated; + +import static org.junit.Assert.assertTrue; + +import com.example.spanner.SampleRunner; +import com.example.spanner.SampleTestBase; +import com.google.common.collect.Lists; +import com.google.spanner.admin.database.v1.CreateDatabaseRequest; +import com.google.spanner.admin.database.v1.InstanceName; +import java.util.Arrays; +import java.util.concurrent.TimeUnit; +import org.junit.Test; + +public class DropForeignKeyConstraintDeleteCascadeSampleIT extends SampleTestBaseV2 { + + @Test + public void testDropForeignKeyConstraintDeleteCascade() throws Exception { + + // Creates database + final String databaseId = idGenerator.generateDatabaseId(); + final CreateDatabaseRequest request = + CreateDatabaseRequest.newBuilder() + .setCreateStatement("CREATE DATABASE `" + databaseId + "`") + .setParent(InstanceName.of(projectId, instanceId).toString()) + .addAllExtraStatements(Lists.newArrayList( + "CREATE TABLE Customers (\n" + + " CustomerId INT64 NOT NULL,\n" + + " CustomerName STRING(62) NOT NULL,\n" + + " ) PRIMARY KEY (CustomerId)", + "CREATE TABLE ShoppingCarts (\n" + + " CartId INT64 NOT NULL,\n" + + " CustomerId INT64 NOT NULL,\n" + + " CustomerName STRING(62) NOT NULL,\n" + + " CONSTRAINT FKShoppingCartsCustomerName" + + " FOREIGN KEY (CustomerName)\n" + + " REFERENCES Customers (CustomerName) ON DELETE CASCADE\n" + + " ) PRIMARY KEY (CartId)\n")).build(); + databaseAdminClient.createDatabaseAsync(request).get(5, TimeUnit.MINUTES); + + // Runs sample + final String out = + SampleRunner.runSample( + () -> + DropForeignKeyConstraintDeleteCascadeSample.deleteForeignKeyDeleteCascadeConstraint( + projectId, instanceId, databaseId)); + + assertTrue( + "Expected to have dropped foreign-key constraints from tables in created database " + + databaseId, + out.contains("Altered ShoppingCarts table to drop FKShoppingCartsCustomerName")); + } +} diff --git a/samples/snippets/src/test/java/com/example/spanner/admin/generated/GetDatabaseDdlSampleIT.java b/samples/snippets/src/test/java/com/example/spanner/admin/generated/GetDatabaseDdlSampleIT.java new file mode 100644 index 00000000000..8769a125983 --- /dev/null +++ b/samples/snippets/src/test/java/com/example/spanner/admin/generated/GetDatabaseDdlSampleIT.java @@ -0,0 +1,82 @@ +/* + * Copyright 2021 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.example.spanner.admin.generated; + +import static org.junit.Assert.assertTrue; + +import com.example.spanner.SampleRunner; +import com.google.common.collect.Lists; +import com.google.spanner.admin.database.v1.CreateDatabaseRequest; +import com.google.spanner.admin.instance.v1.InstanceConfig; +import com.google.spanner.admin.instance.v1.InstanceName; +import java.util.concurrent.TimeUnit; +import org.junit.Test; + +public class GetDatabaseDdlSampleIT extends SampleTestBaseV2 { + + @Test + public void testGetDatabaseDdl() throws Exception { + // Finds a possible new leader option + final String instanceConfigId = instanceAdminClient.getInstance( + InstanceName.of(projectId, multiRegionalInstanceId)).getConfig(); + final InstanceConfig config = instanceAdminClient.getInstanceConfig(instanceConfigId); + assertTrue( + "Expected instance config " + instanceConfigId + " to have at least one leader option", + config.getLeaderOptionsList().size() > 0 + ); + final String defaultLeader = config.getLeaderOptions(0); + + // Creates database + final String databaseId = idGenerator.generateDatabaseId(); + final CreateDatabaseRequest request = + CreateDatabaseRequest.newBuilder() + .setParent( + com.google.spanner.admin.database.v1.InstanceName.of(projectId, + multiRegionalInstanceId).toString()) + .setCreateStatement("CREATE DATABASE `" + databaseId + "`") + .addAllExtraStatements(Lists.newArrayList( + "CREATE TABLE Singers (Id INT64 NOT NULL) PRIMARY KEY (Id)", + "ALTER DATABASE `" + + databaseId + + "` SET OPTIONS ( default_leader = '" + + defaultLeader + + "')" + )).build(); + databaseAdminClient.createDatabaseAsync(request).get(5, TimeUnit.MINUTES); + + // Runs sample + final String out = SampleRunner.runSample(() -> GetDatabaseDdlSample + .getDatabaseDdl(projectId, multiRegionalInstanceId, databaseId) + ); + + assertTrue( + "Expected to have retrieved database DDL for " + databaseId + "." + + " Output received was " + out, + out.contains("Retrieved database DDL for " + databaseId) + ); + assertTrue( + "Expected leader to be set to " + defaultLeader + "." + + " Output received was " + out, + out.contains("default_leader = '" + defaultLeader + "'") + ); + assertTrue( + "Expected table to have been created in " + databaseId + "." + + " Output received was " + out, + out.contains("CREATE TABLE Singers") + ); + } +} diff --git a/samples/snippets/src/test/java/com/example/spanner/admin/generated/CreateInstanceSampleIT.java b/samples/snippets/src/test/java/com/example/spanner/admin/generated/ListDatabasesIT.java similarity index 57% rename from samples/snippets/src/test/java/com/example/spanner/admin/generated/CreateInstanceSampleIT.java rename to samples/snippets/src/test/java/com/example/spanner/admin/generated/ListDatabasesIT.java index 7743b24f132..730205b8b48 100644 --- a/samples/snippets/src/test/java/com/example/spanner/admin/generated/CreateInstanceSampleIT.java +++ b/samples/snippets/src/test/java/com/example/spanner/admin/generated/ListDatabasesIT.java @@ -1,11 +1,11 @@ /* - * Copyright 2023 Google LLC + * Copyright 2022 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, @@ -24,20 +24,14 @@ import org.junit.runners.JUnit4; @RunWith(JUnit4.class) -public class CreateInstanceSampleIT extends SampleTestBaseV2 { +public class ListDatabasesIT extends SampleTestBaseV2 { @Test - public void testCreateInstance() throws Exception { - final String instanceId = idGenerator.generateInstanceId(); - - // Runs sample - final String out = SampleRunner.runSample(() -> - CreateInstanceExample.createInstance(projectId, instanceId) - ); - - assertTrue( - "Expected created instance " + instanceId + "." - + " Output received was " + out, out.contains("was successfully created") - ); + public void testListDatabaseRoles() throws Exception { + final String out = + SampleRunner.runSample( + () -> + ListDatabasesSample.listDatabases(projectId, instanceId)); + assertTrue(out.contains("Databases for projects")); } } diff --git a/samples/snippets/src/test/java/com/example/spanner/admin/generated/PgCaseSensitivitySampleIT.java b/samples/snippets/src/test/java/com/example/spanner/admin/generated/PgCaseSensitivitySampleIT.java new file mode 100644 index 00000000000..88337ba8c6a --- /dev/null +++ b/samples/snippets/src/test/java/com/example/spanner/admin/generated/PgCaseSensitivitySampleIT.java @@ -0,0 +1,45 @@ +/* + * Copyright 2022 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.example.spanner.admin.generated; + +import static org.junit.Assert.assertTrue; + +import com.example.spanner.SampleRunner; +import com.google.spanner.admin.database.v1.CreateDatabaseRequest; +import com.google.spanner.admin.database.v1.DatabaseDialect; +import com.google.spanner.admin.database.v1.InstanceName; +import org.junit.Test; + +public class PgCaseSensitivitySampleIT extends SampleTestBaseV2 { + + @Test + public void testPgCaseSensitivitySample() throws Exception { + final String databaseId = idGenerator.generateDatabaseId(); + final CreateDatabaseRequest request = + CreateDatabaseRequest.newBuilder() + .setCreateStatement(getCreateDatabaseStatement(databaseId, DatabaseDialect.POSTGRESQL)) + .setParent(InstanceName.of(projectId, instanceId).toString()) + .setDatabaseDialect(DatabaseDialect.POSTGRESQL).build(); + databaseAdminClient.createDatabaseAsync(request).get(); + + final String out = + SampleRunner.runSample( + () -> PgCaseSensitivitySample.pgCaseSensitivity(projectId, instanceId, databaseId)); + assertTrue(out, out.contains("SingerId: 1, FirstName: Bruce, LastName: Allison")); + assertTrue(out, out.contains("SingerId: 1, FullName: Bruce Allison")); + } +} \ No newline at end of file diff --git a/samples/snippets/src/test/java/com/example/spanner/admin/generated/PgInterleavedTableSampleIT.java b/samples/snippets/src/test/java/com/example/spanner/admin/generated/PgInterleavedTableSampleIT.java new file mode 100644 index 00000000000..59a0f4a524f --- /dev/null +++ b/samples/snippets/src/test/java/com/example/spanner/admin/generated/PgInterleavedTableSampleIT.java @@ -0,0 +1,44 @@ +/* + * Copyright 2022 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.example.spanner.admin.generated; + +import static org.junit.Assert.assertTrue; + +import com.example.spanner.SampleRunner; +import com.google.spanner.admin.database.v1.CreateDatabaseRequest; +import com.google.spanner.admin.database.v1.DatabaseDialect; +import com.google.spanner.admin.database.v1.InstanceName; +import org.junit.Test; + +public class PgInterleavedTableSampleIT extends SampleTestBaseV2 { + + @Test + public void testPgInterleavedTableSample() throws Exception { + final String databaseId = idGenerator.generateDatabaseId(); + final CreateDatabaseRequest request = + CreateDatabaseRequest.newBuilder() + .setCreateStatement(getCreateDatabaseStatement(databaseId, DatabaseDialect.POSTGRESQL)) + .setParent(InstanceName.of(projectId, instanceId).toString()) + .setDatabaseDialect(DatabaseDialect.POSTGRESQL).build(); + databaseAdminClient.createDatabaseAsync(request).get(); + + final String out = + SampleRunner.runSample( + () -> PgInterleavedTableSample.pgInterleavedTable(projectId, instanceId, databaseId)); + assertTrue(out.contains("Created interleaved table hierarchy using PostgreSQL dialect")); + } +} \ No newline at end of file diff --git a/samples/snippets/src/test/java/com/example/spanner/admin/generated/SampleTestBaseV2.java b/samples/snippets/src/test/java/com/example/spanner/admin/generated/SampleTestBaseV2.java index 941f97fe859..e5ff002110c 100644 --- a/samples/snippets/src/test/java/com/example/spanner/admin/generated/SampleTestBaseV2.java +++ b/samples/snippets/src/test/java/com/example/spanner/admin/generated/SampleTestBaseV2.java @@ -17,11 +17,13 @@ package com.example.spanner.admin.generated; import com.example.spanner.SampleIdGenerator; +import com.google.cloud.spanner.Spanner; import com.google.cloud.spanner.SpannerOptions; import com.google.cloud.spanner.admin.database.v1.DatabaseAdminClient; import com.google.cloud.spanner.admin.database.v1.DatabaseAdminSettings; import com.google.cloud.spanner.admin.instance.v1.InstanceAdminClient; import com.google.cloud.spanner.admin.instance.v1.InstanceAdminSettings; +import com.google.spanner.admin.database.v1.DatabaseDialect; import java.io.IOException; import java.util.concurrent.TimeUnit; import org.junit.AfterClass; @@ -45,7 +47,7 @@ public class SampleTestBaseV2 { protected static final String instanceId = System.getProperty("spanner.test.instance"); protected static DatabaseAdminClient databaseAdminClient; protected static InstanceAdminClient instanceAdminClient; - + protected static Spanner spanner; protected static final String multiRegionalInstanceId = System.getProperty("spanner.test.instance.mr"); protected static final String instanceConfigName = System @@ -69,6 +71,7 @@ public static void beforeClass() throws IOException { } projectId = options.getProjectId(); + spanner = options.getService(); databaseAdminClient = DatabaseAdminClient.create(databaseAdminSettingsBuilder.build()); instanceAdminClient = InstanceAdminClient.create(instanceAdminSettingBuilder.build()); idGenerator = new SampleIdGenerator( @@ -134,6 +137,7 @@ public static void afterClass() throws InterruptedException { + ", skipping..."); } } + databaseAdminClient.close(); instanceAdminClient.close(); @@ -164,4 +168,13 @@ static String getInstanceConfigName(final String projectId, final String instanc static String getProjectName(final String projectId) { return String.format("projects/%s", projectId); } + + static String getCreateDatabaseStatement( + final String databaseName, final DatabaseDialect dialect) { + if (dialect == DatabaseDialect.GOOGLE_STANDARD_SQL) { + return "CREATE DATABASE `" + databaseName + "`"; + } else { + return "CREATE DATABASE \"" + databaseName + "\""; + } + } } diff --git a/samples/snippets/src/test/java/com/example/spanner/admin/generated/SequenceSampleIT.java b/samples/snippets/src/test/java/com/example/spanner/admin/generated/SequenceSampleIT.java new file mode 100644 index 00000000000..b3f4df004d7 --- /dev/null +++ b/samples/snippets/src/test/java/com/example/spanner/admin/generated/SequenceSampleIT.java @@ -0,0 +1,142 @@ +/* + * Copyright 2022 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.example.spanner.admin.generated; + +import static com.example.spanner.SampleRunner.runSample; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + +import com.google.common.collect.ImmutableList; +import com.google.spanner.admin.database.v1.CreateDatabaseRequest; +import com.google.spanner.admin.database.v1.DatabaseDialect; +import java.util.HashSet; +import java.util.concurrent.TimeUnit; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.Parameterized; +import org.junit.runners.Parameterized.Parameter; +import org.junit.runners.Parameterized.Parameters; + +/** + * Integration tests for Bit reversed sequence samples for GoogleStandardSql and PostgreSql + * dialects. + */ +@RunWith(Parameterized.class) +public class SequenceSampleIT extends SampleTestBaseV2 { + + private static String databaseId; + + /** + * Set of dialects for which database has already been created in this test suite. This helps in + * limiting the number of databases created per dialect to one. + */ + private static final HashSet dbInitializedDialects = new HashSet<>(); + + @Parameters(name = "dialect = {0}") + public static Iterable data() { + return ImmutableList.of(DatabaseDialect.GOOGLE_STANDARD_SQL, DatabaseDialect.POSTGRESQL); + } + + @Parameter(0) + public static DatabaseDialect dialect; + + @Before + public void createTestDatabase() throws Exception { + // Limits number of created databases to one per dialect. + if (dbInitializedDialects.contains(dialect)) { + return; + } + dbInitializedDialects.add(dialect); + databaseId = idGenerator.generateDatabaseId(); + CreateDatabaseRequest createDatabaseRequest = + CreateDatabaseRequest.newBuilder() + .setParent(getInstanceName(projectId, instanceId)) + .setCreateStatement(getCreateDatabaseStatement(databaseId, dialect)) + .setDatabaseDialect(dialect).build(); + databaseAdminClient + .createDatabaseAsync(createDatabaseRequest) + .get(10, TimeUnit.MINUTES); + } + + @Test + public void createSequence() throws Exception { + String out; + if (dialect == DatabaseDialect.GOOGLE_STANDARD_SQL) { + out = + runSample( + () -> + CreateSequenceSample.createSequence( + projectId, instanceId, databaseId)); + } else { + out = + runSample( + () -> + PgCreateSequenceSample.pgCreateSequence( + projectId, instanceId, databaseId)); + } + assertTrue( + out.contains( + "Created Seq sequence and Customers table, where the key column " + + "CustomerId uses the sequence as a default value")); + assertEquals(out.split("Inserted customer record with CustomerId", -1).length - 1, 3); + assertTrue(out.contains("Number of customer records inserted is: 3")); + } + + @Test + public void alterSequence() throws Exception { + String out; + if (dialect == DatabaseDialect.GOOGLE_STANDARD_SQL) { + out = + runSample( + () -> + AlterSequenceSample.alterSequence( + projectId, instanceId, databaseId)); + } else { + out = + runSample( + () -> + PgAlterSequenceSample.pgAlterSequence( + projectId, instanceId, databaseId)); + } + assertTrue( + out.contains("Altered Seq sequence to skip an inclusive range between 1000 and 5000000")); + assertEquals(out.split("Inserted customer record with CustomerId", -1).length - 1, 3); + assertTrue(out.contains("Number of customer records inserted is: 3")); + } + + @Test + public void dropSequence() throws Exception { + String out; + if (dialect == DatabaseDialect.GOOGLE_STANDARD_SQL) { + out = + runSample( + () -> + DropSequenceSample.dropSequence(projectId, instanceId, databaseId)); + } else { + out = + runSample( + () -> + PgDropSequenceSample.pgDropSequence( + projectId, instanceId, databaseId)); + } + assertTrue( + out.contains( + "Altered Customers table to drop DEFAULT from " + + "CustomerId column and dropped the Seq sequence")); + } +} diff --git a/samples/snippets/src/test/java/com/example/spanner/admin/generated/UpdateDatabaseSampleIT.java b/samples/snippets/src/test/java/com/example/spanner/admin/generated/UpdateDatabaseSampleIT.java new file mode 100644 index 00000000000..acac98cde42 --- /dev/null +++ b/samples/snippets/src/test/java/com/example/spanner/admin/generated/UpdateDatabaseSampleIT.java @@ -0,0 +1,71 @@ +/* + * Copyright 2023 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.example.spanner.admin.generated; + +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; + +import com.example.spanner.SampleRunner; +import com.google.api.gax.longrunning.OperationFuture; +import com.google.common.collect.Lists; +import com.google.protobuf.FieldMask; +import com.google.spanner.admin.database.v1.Database; +import com.google.spanner.admin.database.v1.DatabaseName; +import com.google.spanner.admin.database.v1.UpdateDatabaseMetadata; +import com.google.spanner.admin.database.v1.UpdateDatabaseRequest; +import java.util.concurrent.TimeUnit; +import org.junit.Test; + +public class UpdateDatabaseSampleIT extends SampleTestBaseV2 { + + @Test + public void testUpdateDatabase() throws Exception { + // Create database + final String databaseId = idGenerator.generateDatabaseId(); + databaseAdminClient + .createDatabaseAsync(getInstanceName(projectId, instanceId), + "CREATE DATABASE `" + databaseId + "`") + .get(5, TimeUnit.MINUTES); + + // Runs sample + final String out = + SampleRunner.runSample( + () -> UpdateDatabaseSample.updateDatabase(projectId, instanceId, databaseId)); + assertTrue( + "Expected that database would have been updated. Output received was " + out, + out.contains(String.format( + "Updated database %s", DatabaseName.of(projectId, instanceId, databaseId)))); + + // Cleanup + final com.google.spanner.admin.database.v1.Database database = + com.google.spanner.admin.database.v1.Database.newBuilder() + .setName(DatabaseName.of(projectId, instanceId, databaseId).toString()) + .setEnableDropProtection(false).build(); + final UpdateDatabaseRequest updateDatabaseRequest = + UpdateDatabaseRequest.newBuilder() + .setDatabase(database) + .setUpdateMask( + FieldMask.newBuilder().addAllPaths( + Lists.newArrayList("enable_drop_protection")).build()) + .build(); + + OperationFuture operation = + databaseAdminClient.updateDatabaseAsync(updateDatabaseRequest); + Database updatedDb = operation.get(5, TimeUnit.MINUTES); + assertFalse(updatedDb.getEnableDropProtection()); + } +} diff --git a/samples/snippets/src/test/java/com/example/spanner/admin/generated/UpdateDatabaseWithDefaultLeaderSampleIT.java b/samples/snippets/src/test/java/com/example/spanner/admin/generated/UpdateDatabaseWithDefaultLeaderSampleIT.java new file mode 100644 index 00000000000..3ec35872880 --- /dev/null +++ b/samples/snippets/src/test/java/com/example/spanner/admin/generated/UpdateDatabaseWithDefaultLeaderSampleIT.java @@ -0,0 +1,63 @@ +/* + * Copyright 2021 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.example.spanner.admin.generated; + +import static org.junit.Assert.assertTrue; + +import com.example.spanner.SampleRunner; +import com.google.spanner.admin.database.v1.Database; +import com.google.spanner.admin.instance.v1.InstanceConfig; +import java.util.concurrent.TimeUnit; +import org.junit.Test; + +public class UpdateDatabaseWithDefaultLeaderSampleIT extends SampleTestBaseV2 { + + @Test + public void testUpdateDatabaseWithDefaultLeader() throws Exception { + // Create database + final String databaseId = idGenerator.generateDatabaseId(); + final Database createdDatabase = databaseAdminClient + .createDatabaseAsync(getInstanceName(projectId, multiRegionalInstanceId), + "CREATE DATABASE `" + databaseId + "`") + .get(5, TimeUnit.MINUTES); + final String defaultLeader = createdDatabase.getDefaultLeader(); + + // Finds a possible new leader option + final String instanceConfigId = + instanceAdminClient.getInstance(getInstanceName(projectId, multiRegionalInstanceId)) + .getConfig(); + final InstanceConfig config = instanceAdminClient.getInstanceConfig(instanceConfigId); + final String newLeader = + config.getLeaderOptionsList().stream() + .filter(leader -> !leader.equals(defaultLeader)) + .findFirst().orElseThrow(() -> + new RuntimeException("Expected to find a leader option different than " + + defaultLeader) + ); + + // Runs sample + final String out = SampleRunner.runSample(() -> UpdateDatabaseWithDefaultLeaderSample + .updateDatabaseWithDefaultLeader(projectId, multiRegionalInstanceId, databaseId, newLeader) + ); + + assertTrue( + "Expected that database new leader would had been updated to " + newLeader + "." + + " Output received was " + out, + out.contains("Updated default leader to " + newLeader) + ); + } +}