From 88e24c7a7d046056605a2a824450e0153b339c86 Mon Sep 17 00:00:00 2001 From: Arpan Mishra Date: Fri, 12 Jan 2024 20:50:41 +0530 Subject: [PATCH 01/21] docs: samples and tests for instance APIs. (#2768) Adds samples and tests for auto-generated Instance Admin APIs. --- README.md | 14 ++- samples/install-without-bom/pom.xml | 3 +- samples/native-image/pom.xml | 1 + samples/snapshot/pom.xml | 3 +- samples/snippets/pom.xml | 2 +- ...CreateDatabaseWithDefaultLeaderSample.java | 4 +- .../generated/CreateInstanceConfigSample.java | 88 +++++++++++++++++++ .../generated/CreateInstanceExample.java | 57 ++++++------ ...eInstanceWithAutoscalingConfigExample.java | 87 ++++++++++++++++++ ...ateInstanceWithProcessingUnitsExample.java | 73 +++++++++++++++ .../generated/DeleteInstanceConfigSample.java | 55 ++++++++++++ .../generated/GetInstanceConfigSample.java | 51 +++++++++++ .../ListInstanceConfigOperationsSample.java | 67 ++++++++++++++ .../generated/ListInstanceConfigsSample.java | 48 ++++++++++ .../generated/UpdateInstanceConfigSample.java | 82 +++++++++++++++++ ...InstanceWithAutoscalingConfigSampleIT.java | 37 ++++++++ ...teInstanceWithProcessingUnitsSampleIT.java | 37 ++++++++ .../CustomInstanceConfigSampleIT.java | 74 ++++++++++++++++ .../admin/generated/SampleTestBaseV2.java | 11 ++- 19 files changed, 755 insertions(+), 39 deletions(-) create mode 100644 samples/snippets/src/main/java/com/example/spanner/admin/generated/CreateInstanceConfigSample.java create mode 100644 samples/snippets/src/main/java/com/example/spanner/admin/generated/CreateInstanceWithAutoscalingConfigExample.java create mode 100644 samples/snippets/src/main/java/com/example/spanner/admin/generated/CreateInstanceWithProcessingUnitsExample.java create mode 100644 samples/snippets/src/main/java/com/example/spanner/admin/generated/DeleteInstanceConfigSample.java create mode 100644 samples/snippets/src/main/java/com/example/spanner/admin/generated/GetInstanceConfigSample.java create mode 100644 samples/snippets/src/main/java/com/example/spanner/admin/generated/ListInstanceConfigOperationsSample.java create mode 100644 samples/snippets/src/main/java/com/example/spanner/admin/generated/ListInstanceConfigsSample.java create mode 100644 samples/snippets/src/main/java/com/example/spanner/admin/generated/UpdateInstanceConfigSample.java create mode 100644 samples/snippets/src/test/java/com/example/spanner/admin/generated/CreateInstanceWithAutoscalingConfigSampleIT.java create mode 100644 samples/snippets/src/test/java/com/example/spanner/admin/generated/CreateInstanceWithProcessingUnitsSampleIT.java create mode 100644 samples/snippets/src/test/java/com/example/spanner/admin/generated/CustomInstanceConfigSampleIT.java diff --git a/README.md b/README.md index 417e48553d8..5b94cdadb35 100644 --- a/README.md +++ b/README.md @@ -57,13 +57,13 @@ implementation 'com.google.cloud:google-cloud-spanner' If you are using Gradle without BOM, add this to your dependencies: ```Groovy -implementation 'com.google.cloud:google-cloud-spanner:6.55.0' +implementation 'com.google.cloud:google-cloud-spanner:6.56.0' ``` If you are using SBT, add this to your dependencies: ```Scala -libraryDependencies += "com.google.cloud" % "google-cloud-spanner" % "6.55.0" +libraryDependencies += "com.google.cloud" % "google-cloud-spanner" % "6.56.0" ``` @@ -331,7 +331,15 @@ Samples are in the [`samples/`](https://github.com/googleapis/java-spanner/tree/ | 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) | +| 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) | +| 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) | +| 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 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) | +| 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) | @@ -435,7 +443,7 @@ Java is a registered trademark of Oracle and/or its affiliates. [kokoro-badge-link-5]: http://storage.googleapis.com/cloud-devrel-public/java/badges/java-spanner/java11.html [stability-image]: https://img.shields.io/badge/stability-stable-green [maven-version-image]: https://img.shields.io/maven-central/v/com.google.cloud/google-cloud-spanner.svg -[maven-version-link]: https://central.sonatype.com/artifact/com.google.cloud/google-cloud-spanner/6.55.0 +[maven-version-link]: https://central.sonatype.com/artifact/com.google.cloud/google-cloud-spanner/6.56.0 [authentication]: https://github.com/googleapis/google-cloud-java#authentication [auth-scopes]: https://developers.google.com/identity/protocols/oauth2/scopes [predefined-iam-roles]: https://cloud.google.com/iam/docs/understanding-roles#predefined_roles diff --git a/samples/install-without-bom/pom.xml b/samples/install-without-bom/pom.xml index c30d1f02fd8..5db018897a9 100644 --- a/samples/install-without-bom/pom.xml +++ b/samples/install-without-bom/pom.xml @@ -15,6 +15,7 @@ com.google.cloud.samples shared-configuration 1.2.0 + @@ -144,7 +145,7 @@ java-client-integration-test java-client-mr-integration-test - nam15 + nam11 us-east1 cmek-test-key-ring cmek-test-key diff --git a/samples/native-image/pom.xml b/samples/native-image/pom.xml index 7beb606063b..d4a8d10d74c 100644 --- a/samples/native-image/pom.xml +++ b/samples/native-image/pom.xml @@ -14,6 +14,7 @@ com.google.cloud.samples shared-configuration 1.2.0 + diff --git a/samples/snapshot/pom.xml b/samples/snapshot/pom.xml index e58390df897..5e343b36dcc 100644 --- a/samples/snapshot/pom.xml +++ b/samples/snapshot/pom.xml @@ -15,6 +15,7 @@ com.google.cloud.samples shared-configuration 1.2.0 + @@ -143,7 +144,7 @@ java-client-integration-test java-client-mr-integration-test - nam15 + nam11 us-east1 cmek-test-key-ring cmek-test-key diff --git a/samples/snippets/pom.xml b/samples/snippets/pom.xml index 0c55fa59f4a..406225e85f0 100644 --- a/samples/snippets/pom.xml +++ b/samples/snippets/pom.xml @@ -180,7 +180,7 @@ java-client-integration-test java-client-mr-integration-test - nam15 + nam11 us-east1 cmek-test-key-ring cmek-test-key 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 index eedbca8095a..853ec557b94 100644 --- 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 @@ -39,9 +39,7 @@ static void createDatabaseWithDefaultLeader() throws IOException { static void createDatabaseWithDefaultLeader(String instanceName, String databaseId, String defaultLeader) throws IOException { - DatabaseAdminClient databaseAdminClient = DatabaseAdminClient.create(); - - try { + try (DatabaseAdminClient databaseAdminClient = DatabaseAdminClient.create()) { Database createdDatabase = databaseAdminClient.createDatabaseAsync( CreateDatabaseRequest.newBuilder() diff --git a/samples/snippets/src/main/java/com/example/spanner/admin/generated/CreateInstanceConfigSample.java b/samples/snippets/src/main/java/com/example/spanner/admin/generated/CreateInstanceConfigSample.java new file mode 100644 index 00000000000..49ce023b24a --- /dev/null +++ b/samples/snippets/src/main/java/com/example/spanner/admin/generated/CreateInstanceConfigSample.java @@ -0,0 +1,88 @@ +/* + * Copyright 2024 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_instance_config] + +import com.google.cloud.spanner.admin.instance.v1.InstanceAdminClient; +import com.google.spanner.admin.instance.v1.CreateInstanceConfigRequest; +import com.google.spanner.admin.instance.v1.InstanceConfig; +import com.google.spanner.admin.instance.v1.InstanceConfigName; +import com.google.spanner.admin.instance.v1.ProjectName; +import com.google.spanner.admin.instance.v1.ReplicaInfo; +import java.io.IOException; +import java.util.List; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.TimeoutException; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +class CreateInstanceConfigSample { + + static void createInstanceConfig() throws IOException { + // TODO(developer): Replace these variables before running the sample. + String projectId = "my-project"; + String baseInstanceConfigId = "nam11"; + String instanceConfigId = "custom-instance-config4"; + + createInstanceConfig(projectId, baseInstanceConfigId, instanceConfigId); + } + + static void createInstanceConfig( + String projectId, String baseInstanceConfigId, String instanceConfigId) throws IOException { + try (InstanceAdminClient instanceAdminClient = InstanceAdminClient.create()) { + final InstanceConfigName baseInstanceConfigName = InstanceConfigName.of(projectId, + baseInstanceConfigId); + final InstanceConfig baseConfig = + instanceAdminClient.getInstanceConfig(baseInstanceConfigName.toString()); + final InstanceConfigName instanceConfigName = InstanceConfigName.of(projectId, + instanceConfigId); + /** + * The replicas for the custom instance configuration must include all the replicas of the + * base configuration, in addition to at least one from the list of optional replicas of the + * base configuration. + */ + final List replicas = + Stream.concat(baseConfig.getReplicasList().stream(), + baseConfig.getOptionalReplicasList().stream().limit(1)).collect(Collectors.toList()); + final InstanceConfig instanceConfig = + InstanceConfig.newBuilder().setName(instanceConfigName.toString()) + .setBaseConfig(baseInstanceConfigName.toString()) + .setDisplayName("Instance Configuration").addAllReplicas(replicas).build(); + final CreateInstanceConfigRequest createInstanceConfigRequest = + CreateInstanceConfigRequest.newBuilder().setParent(ProjectName.of(projectId).toString()) + .setInstanceConfigId(instanceConfigId).setInstanceConfig(instanceConfig).build(); + try { + System.out.printf("Waiting for create operation for %s to complete...\n", + instanceConfigName); + InstanceConfig instanceConfigResult = + instanceAdminClient.createInstanceConfigAsync( + createInstanceConfigRequest).get(5, TimeUnit.MINUTES); + System.out.printf("Created instance configuration %s\n", instanceConfigResult.getName()); + } catch (ExecutionException | TimeoutException e) { + System.out.printf( + "Error: Creating instance configuration %s failed with error message %s\n", + instanceConfig.getName(), e.getMessage()); + } catch (InterruptedException e) { + System.out.println( + "Error: Waiting for createInstanceConfig operation to finish was interrupted"); + } + } + } +} +// [END spanner_create_instance_config] 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 88675c414cf..8664c85b444 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 @@ -17,6 +17,7 @@ package com.example.spanner.admin.generated; //[START spanner_create_instance] + import com.google.cloud.spanner.admin.instance.v1.InstanceAdminClient; import com.google.spanner.admin.instance.v1.CreateInstanceRequest; import com.google.spanner.admin.instance.v1.Instance; @@ -35,35 +36,35 @@ static void createInstance() throws IOException { } static void createInstance(String projectId, String instanceId) throws IOException { - InstanceAdminClient instanceAdminClient = InstanceAdminClient.create(); - - // Set Instance configuration. - int nodeCount = 2; - String displayName = "Descriptive name"; + try (InstanceAdminClient instanceAdminClient = InstanceAdminClient.create()) { + // 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"); + // 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/CreateInstanceWithAutoscalingConfigExample.java b/samples/snippets/src/main/java/com/example/spanner/admin/generated/CreateInstanceWithAutoscalingConfigExample.java new file mode 100644 index 00000000000..aa785fe57d0 --- /dev/null +++ b/samples/snippets/src/main/java/com/example/spanner/admin/generated/CreateInstanceWithAutoscalingConfigExample.java @@ -0,0 +1,87 @@ +/* + * Copyright 2024 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_instance_with_autoscaling_config] + +import com.google.cloud.spanner.admin.instance.v1.InstanceAdminClient; +import com.google.spanner.admin.instance.v1.AutoscalingConfig; +import com.google.spanner.admin.instance.v1.CreateInstanceRequest; +import com.google.spanner.admin.instance.v1.Instance; +import com.google.spanner.admin.instance.v1.InstanceConfigName; +import com.google.spanner.admin.instance.v1.ProjectName; +import java.io.IOException; +import java.util.concurrent.ExecutionException; + +class CreateInstanceWithAutoscalingConfigExample { + + static void createInstance() throws IOException { + // TODO(developer): Replace these variables before running the sample. + String projectId = "my-project"; + String instanceId = "my-instance"; + createInstance(projectId, instanceId); + } + + static void createInstance(String projectId, String instanceId) throws IOException { + try (InstanceAdminClient instanceAdminClient = InstanceAdminClient.create()) { + // Set Instance configuration. + String configId = "regional-us-central1"; + String displayName = "Descriptive name"; + + // Create an autoscaling config. + // When autoscaling_config is enabled, node_count and processing_units fields + // need not be specified. + AutoscalingConfig autoscalingConfig = + AutoscalingConfig.newBuilder() + .setAutoscalingLimits( + AutoscalingConfig.AutoscalingLimits.newBuilder().setMinNodes(1).setMaxNodes(2)) + .setAutoscalingTargets( + AutoscalingConfig.AutoscalingTargets.newBuilder() + .setHighPriorityCpuUtilizationPercent(65) + .setStorageUtilizationPercent(95)) + .build(); + Instance instance = + Instance.newBuilder() + .setAutoscalingConfig(autoscalingConfig) + .setDisplayName(displayName) + .setConfig( + InstanceConfigName.of(projectId, configId).toString()) + .build(); + + // Creates a new instance + System.out.printf("Creating instance %s.%n", instanceId); + try { + // Wait for the createInstance operation to finish. + Instance instanceResult = instanceAdminClient.createInstanceAsync( + CreateInstanceRequest.newBuilder() + .setParent(ProjectName.of(projectId).toString()) + .setInstanceId(instanceId) + .setInstance(instance) + .build()).get(); + System.out.printf("Autoscaler instance %s was successfully created%n", + instanceResult.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"); + } + } + } +} +// [END spanner_create_instance_with_autoscaling_config] diff --git a/samples/snippets/src/main/java/com/example/spanner/admin/generated/CreateInstanceWithProcessingUnitsExample.java b/samples/snippets/src/main/java/com/example/spanner/admin/generated/CreateInstanceWithProcessingUnitsExample.java new file mode 100644 index 00000000000..9aa0487098b --- /dev/null +++ b/samples/snippets/src/main/java/com/example/spanner/admin/generated/CreateInstanceWithProcessingUnitsExample.java @@ -0,0 +1,73 @@ +/* + * Copyright 2024 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_instance_with_processing_units] + +import com.google.cloud.spanner.admin.instance.v1.InstanceAdminClient; +import com.google.spanner.admin.instance.v1.CreateInstanceRequest; +import com.google.spanner.admin.instance.v1.Instance; +import com.google.spanner.admin.instance.v1.InstanceConfigName; +import com.google.spanner.admin.instance.v1.ProjectName; +import java.io.IOException; + +class CreateInstanceWithProcessingUnitsExample { + + static void createInstance() throws IOException { + // TODO(developer): Replace these variables before running the sample. + String projectId = "my-project"; + String instanceId = "my-instance"; + createInstance(projectId, instanceId); + } + + static void createInstance(String projectId, String instanceId) throws IOException { + try (InstanceAdminClient instanceAdminClient = InstanceAdminClient.create()) { + // Set Instance configuration. + String configId = "regional-us-central1"; + // This will create an instance with the processing power of 0.2 nodes. + int processingUnits = 500; + String displayName = "Descriptive name"; + + try { + // Creates a new instance + System.out.printf("Creating instance %s.%n", instanceId); + Instance instance = + Instance.newBuilder() + .setDisplayName(displayName) + .setProcessingUnits(processingUnits) + .setConfig( + InstanceConfigName.of(projectId, configId).toString()) + .build(); + // Wait for the createInstance operation to finish. + System.out.printf("Waiting for operation on %s to complete...%n", instanceId); + Instance createdInstance = instanceAdminClient.createInstanceAsync( + CreateInstanceRequest.newBuilder() + .setParent(ProjectName.of(projectId).toString()) + .setInstanceId(instanceId) + .setInstance(instance) + .build()).get(); + + System.out.printf("Created instance %s.%n", createdInstance.getName()); + System.out.printf("Instance %s has %d processing units.%n", createdInstance.getName(), + createdInstance.getProcessingUnits()); + } catch (Exception e) { + System.out.printf("Error: %s.%n", e.getMessage()); + } + } + } +} +//[END spanner_create_instance_with_processing_units] diff --git a/samples/snippets/src/main/java/com/example/spanner/admin/generated/DeleteInstanceConfigSample.java b/samples/snippets/src/main/java/com/example/spanner/admin/generated/DeleteInstanceConfigSample.java new file mode 100644 index 00000000000..1fa9aee586c --- /dev/null +++ b/samples/snippets/src/main/java/com/example/spanner/admin/generated/DeleteInstanceConfigSample.java @@ -0,0 +1,55 @@ +/* + * Copyright 2024 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_delete_instance_config] + +import com.google.cloud.spanner.SpannerException; +import com.google.cloud.spanner.admin.instance.v1.InstanceAdminClient; +import com.google.spanner.admin.instance.v1.DeleteInstanceConfigRequest; +import com.google.spanner.admin.instance.v1.InstanceConfigName; +import java.io.IOException; + +class DeleteInstanceConfigSample { + + static void deleteInstanceConfig() throws IOException { + // TODO(developer): Replace these variables before running the sample. + String projectId = "my-project"; + String instanceConfigId = "custom-user-config"; + deleteInstanceConfig(projectId, instanceConfigId); + } + + static void deleteInstanceConfig(String projectId, String instanceConfigId) throws IOException { + try (final InstanceAdminClient instanceAdminClient = InstanceAdminClient.create()) { + final InstanceConfigName instanceConfigName = InstanceConfigName.of(projectId, + instanceConfigId); + final DeleteInstanceConfigRequest request = + DeleteInstanceConfigRequest.newBuilder().setName(instanceConfigName.toString()).build(); + + try { + System.out.printf("Deleting %s...\n", instanceConfigName); + instanceAdminClient.deleteInstanceConfig(request); + System.out.printf("Deleted instance configuration %s\n", instanceConfigName); + } catch (SpannerException e) { + System.out.printf( + "Error: Deleting instance configuration %s failed with error message: %s\n", + instanceConfigName, e.getMessage()); + } + } + } +} +// [END spanner_delete_instance_config] diff --git a/samples/snippets/src/main/java/com/example/spanner/admin/generated/GetInstanceConfigSample.java b/samples/snippets/src/main/java/com/example/spanner/admin/generated/GetInstanceConfigSample.java new file mode 100644 index 00000000000..5fc1b907479 --- /dev/null +++ b/samples/snippets/src/main/java/com/example/spanner/admin/generated/GetInstanceConfigSample.java @@ -0,0 +1,51 @@ +/* + * Copyright 2024 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_instance_config] + +import com.google.cloud.spanner.admin.instance.v1.InstanceAdminClient; +import com.google.spanner.admin.instance.v1.InstanceConfig; +import com.google.spanner.admin.instance.v1.InstanceConfigName; +import java.io.IOException; + +public class GetInstanceConfigSample { + + static void getInstanceConfig() throws IOException { + // TODO(developer): Replace these variables before running the sample. + final String projectId = "my-project"; + final String instanceConfigId = "nam6"; + getInstanceConfig(projectId, instanceConfigId); + } + + static void getInstanceConfig(String projectId, String instanceConfigId) throws IOException { + try (final InstanceAdminClient instanceAdminClient = InstanceAdminClient.create()) { + final InstanceConfigName instanceConfigName = InstanceConfigName.of(projectId, + instanceConfigId); + + final InstanceConfig instanceConfig = + instanceAdminClient.getInstanceConfig(instanceConfigName.toString()); + + System.out.printf( + "Available leader options for instance config %s: %s%n", + instanceConfig.getName(), + instanceConfig.getLeaderOptionsList() + ); + } + } +} +//[END spanner_get_instance_config] diff --git a/samples/snippets/src/main/java/com/example/spanner/admin/generated/ListInstanceConfigOperationsSample.java b/samples/snippets/src/main/java/com/example/spanner/admin/generated/ListInstanceConfigOperationsSample.java new file mode 100644 index 00000000000..6970c500694 --- /dev/null +++ b/samples/snippets/src/main/java/com/example/spanner/admin/generated/ListInstanceConfigOperationsSample.java @@ -0,0 +1,67 @@ +/* + * Copyright 2024 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_instance_config_operations] + +import com.google.cloud.spanner.admin.instance.v1.InstanceAdminClient; +import com.google.longrunning.Operation; +import com.google.protobuf.InvalidProtocolBufferException; +import com.google.spanner.admin.instance.v1.CreateInstanceConfigMetadata; +import com.google.spanner.admin.instance.v1.ListInstanceConfigOperationsRequest; +import com.google.spanner.admin.instance.v1.ProjectName; +import java.io.IOException; + +public class ListInstanceConfigOperationsSample { + + static void listInstanceConfigOperations() throws IOException { + // TODO(developer): Replace these variables before running the sample. + String projectId = "my-project"; + listInstanceConfigOperations(projectId); + } + + static void listInstanceConfigOperations(String projectId) throws IOException { + try (final InstanceAdminClient instanceAdminClient = InstanceAdminClient.create()) { + final ProjectName projectName = ProjectName.of(projectId); + System.out.printf( + "Getting list of instance config operations for project %s...\n", + projectId); + final ListInstanceConfigOperationsRequest request = + ListInstanceConfigOperationsRequest.newBuilder() + .setParent(projectName.toString()) + .setFilter("(metadata.@type=type.googleapis.com/" + + "google.spanner.admin.instance.v1.CreateInstanceConfigMetadata)").build(); + final Iterable instanceConfigOperations = + instanceAdminClient.listInstanceConfigOperations(request).iterateAll(); + for (Operation operation : instanceConfigOperations) { + CreateInstanceConfigMetadata metadata = + operation.getMetadata().unpack(CreateInstanceConfigMetadata.class); + System.out.printf( + "Create instance config operation for %s is %d%% completed.\n", + metadata.getInstanceConfig().getName(), metadata.getProgress().getProgressPercent()); + } + System.out.printf( + "Obtained list of instance config operations for project %s...\n", + projectName); + } catch (InvalidProtocolBufferException e) { + System.out.printf( + "Error: Listing instance config operations failed with error message %s\n", + e.getMessage()); + } + } +} +// [END spanner_list_instance_config_operations] diff --git a/samples/snippets/src/main/java/com/example/spanner/admin/generated/ListInstanceConfigsSample.java b/samples/snippets/src/main/java/com/example/spanner/admin/generated/ListInstanceConfigsSample.java new file mode 100644 index 00000000000..92a0c7014e9 --- /dev/null +++ b/samples/snippets/src/main/java/com/example/spanner/admin/generated/ListInstanceConfigsSample.java @@ -0,0 +1,48 @@ +/* + * Copyright 2024 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_instance_configs] + +import com.google.cloud.spanner.admin.instance.v1.InstanceAdminClient; +import com.google.spanner.admin.instance.v1.InstanceConfig; +import com.google.spanner.admin.instance.v1.ProjectName; +import java.io.IOException; + +public class ListInstanceConfigsSample { + + static void listInstanceConfigs() throws IOException { + // TODO(developer): Replace these variables before running the sample. + String projectId = "my-project"; + listInstanceConfigs(projectId); + } + + static void listInstanceConfigs(String projectId) throws IOException { + try (final InstanceAdminClient instanceAdminClient = InstanceAdminClient.create()) { + final ProjectName projectName = ProjectName.of(projectId); + for (InstanceConfig instanceConfig : + instanceAdminClient.listInstanceConfigs(projectName).iterateAll()) { + System.out.printf( + "Available leader options for instance config %s: %s%n", + instanceConfig.getName(), + instanceConfig.getLeaderOptionsList() + ); + } + } + } +} +//[END spanner_list_instance_configs] diff --git a/samples/snippets/src/main/java/com/example/spanner/admin/generated/UpdateInstanceConfigSample.java b/samples/snippets/src/main/java/com/example/spanner/admin/generated/UpdateInstanceConfigSample.java new file mode 100644 index 00000000000..1fb5cd0e6fb --- /dev/null +++ b/samples/snippets/src/main/java/com/example/spanner/admin/generated/UpdateInstanceConfigSample.java @@ -0,0 +1,82 @@ +/* + * Copyright 2024 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_instance_config] + +import com.google.cloud.spanner.admin.instance.v1.InstanceAdminClient; +import com.google.common.collect.ImmutableList; +import com.google.protobuf.FieldMask; +import com.google.spanner.admin.instance.v1.InstanceConfig; +import com.google.spanner.admin.instance.v1.InstanceConfigName; +import com.google.spanner.admin.instance.v1.UpdateInstanceConfigRequest; +import java.io.IOException; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.TimeoutException; + +class UpdateInstanceConfigSample { + + static void updateInstanceConfig() throws IOException { + // TODO(developer): Replace these variables before running the sample. + String projectId = "my-project"; + String instanceConfigId = "custom-instance-config"; + updateInstanceConfig(projectId, instanceConfigId); + } + + static void updateInstanceConfig(String projectId, String instanceConfigId) throws IOException { + try (final InstanceAdminClient instanceAdminClient = InstanceAdminClient.create()) { + final InstanceConfigName instanceConfigName = + InstanceConfigName.of(projectId, instanceConfigId); + final InstanceConfig instanceConfig = + InstanceConfig.newBuilder() + .setName(instanceConfigName.toString()) + .setDisplayName("updated custom instance config") + .putLabels("updated", "true").build(); + /** + * The field mask must always be specified; this prevents any future + * fields in [InstanceConfig][google.spanner.admin.instance.v1.InstanceConfig] + * from being erased accidentally by clients that do not know about them. + */ + final UpdateInstanceConfigRequest updateInstanceConfigRequest = + UpdateInstanceConfigRequest.newBuilder() + .setInstanceConfig(instanceConfig) + .setUpdateMask( + FieldMask.newBuilder().addAllPaths(ImmutableList.of("display_name", "labels")) + .build()).build(); + try { + System.out.printf("Waiting for update operation on %s to complete...\n", + instanceConfigName); + InstanceConfig instanceConfigResult = + instanceAdminClient.updateInstanceConfigAsync( + updateInstanceConfigRequest).get(5, TimeUnit.MINUTES); + System.out.printf( + "Updated instance configuration %s with new display name %s\n", + instanceConfigResult.getName(), instanceConfig.getDisplayName()); + } catch (ExecutionException | TimeoutException e) { + System.out.printf( + "Error: Updating instance config %s failed with error message %s\n", + instanceConfig.getName(), e.getMessage()); + e.printStackTrace(); + } catch (InterruptedException e) { + System.out.println( + "Error: Waiting for updateInstanceConfig operation to finish was interrupted"); + } + } + } +} +// [END spanner_update_instance_config] diff --git a/samples/snippets/src/test/java/com/example/spanner/admin/generated/CreateInstanceWithAutoscalingConfigSampleIT.java b/samples/snippets/src/test/java/com/example/spanner/admin/generated/CreateInstanceWithAutoscalingConfigSampleIT.java new file mode 100644 index 00000000000..86224cfd305 --- /dev/null +++ b/samples/snippets/src/test/java/com/example/spanner/admin/generated/CreateInstanceWithAutoscalingConfigSampleIT.java @@ -0,0 +1,37 @@ +/* + * Copyright 2024 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 com.google.spanner.admin.database.v1.InstanceName; +import org.junit.Test; + +public class CreateInstanceWithAutoscalingConfigSampleIT extends SampleTestBaseV2 { + + @Test + public void testCreateInstanceWithAutoscalingConfig() throws Exception { + String instanceId = idGenerator.generateInstanceId(); + String out = + SampleRunner.runSample( + () -> CreateInstanceWithAutoscalingConfigExample.createInstance(projectId, instanceId)); + assertThat(out) + .contains(String.format("Autoscaler instance %s", + InstanceName.of(projectId, instanceId).toString())); + } +} diff --git a/samples/snippets/src/test/java/com/example/spanner/admin/generated/CreateInstanceWithProcessingUnitsSampleIT.java b/samples/snippets/src/test/java/com/example/spanner/admin/generated/CreateInstanceWithProcessingUnitsSampleIT.java new file mode 100644 index 00000000000..13778dff825 --- /dev/null +++ b/samples/snippets/src/test/java/com/example/spanner/admin/generated/CreateInstanceWithProcessingUnitsSampleIT.java @@ -0,0 +1,37 @@ +/* + * Copyright 2024 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 com.google.spanner.admin.database.v1.InstanceName; +import org.junit.Test; + +public class CreateInstanceWithProcessingUnitsSampleIT extends SampleTestBaseV2 { + + @Test + public void testCreateInstanceWithProcessingUnits() throws Exception { + String instanceId = idGenerator.generateInstanceId(); + String out = + SampleRunner.runSample( + () -> CreateInstanceWithProcessingUnitsExample.createInstance(projectId, instanceId)); + assertThat(out) + .contains(String.format("Instance %s has %d processing units", + InstanceName.of(projectId, instanceId).toString(), 500)); + } +} diff --git a/samples/snippets/src/test/java/com/example/spanner/admin/generated/CustomInstanceConfigSampleIT.java b/samples/snippets/src/test/java/com/example/spanner/admin/generated/CustomInstanceConfigSampleIT.java new file mode 100644 index 00000000000..8a01d2a7a6b --- /dev/null +++ b/samples/snippets/src/test/java/com/example/spanner/admin/generated/CustomInstanceConfigSampleIT.java @@ -0,0 +1,74 @@ +/* + * Copyright 2024 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 org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.JUnit4; + +@RunWith(JUnit4.class) +public class CustomInstanceConfigSampleIT extends SampleTestBaseV2 { + + @Test + public void testCustomInstanceConfigOperations() throws Exception { + String customInstanceConfigId = idGenerator.generateInstanceConfigId(); + + // Create a random instance config. Display name is set to the instance config id in sample. + final String out1 = + SampleRunner.runSample( + () -> + CreateInstanceConfigSample.createInstanceConfig( + projectId, instanceConfigName, customInstanceConfigId)); + assertTrue(out1.contains("Created instance configuration")); + + // Fetch the instance config that was created above. + final String out2 = + SampleRunner.runSample( + () -> GetInstanceConfigSample.getInstanceConfig(projectId, instanceConfigName)); + assertTrue(out2.contains("Available leader options for instance config")); + + // Fetch the instance config that was created above. + final String out3 = + SampleRunner.runSample( + () -> ListInstanceConfigsSample.listInstanceConfigs(projectId)); + assertTrue(out3.contains("Available leader options for instance config")); + + // List the instance config operations. + final String out4 = + SampleRunner.runSample( + () -> + ListInstanceConfigOperationsSample.listInstanceConfigOperations(projectId)); + assertTrue(out4.contains("Obtained list of instance config operations")); + + // Update display name to a randomly generated instance config id. + final String out5 = + SampleRunner.runSample( + () -> + UpdateInstanceConfigSample.updateInstanceConfig(projectId, customInstanceConfigId)); + assertTrue(out5.contains("Updated instance configuration")); + + // Delete the created instance config. + final String out6 = + SampleRunner.runSample( + () -> + DeleteInstanceConfigSample.deleteInstanceConfig(projectId, customInstanceConfigId)); + assertTrue(out6.contains("Deleted instance configuration")); + } +} 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 30989214fa3..941f97fe859 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 @@ -124,7 +124,7 @@ public static void afterClass() throws InterruptedException { for (String configId : idGenerator.getInstanceConfigIds()) { try { // If the config is not found, it is ignored (no exception is thrown) - instanceAdminClient.deleteInstanceConfig(configId); + instanceAdminClient.deleteInstanceConfig(getInstanceConfigName(projectId, configId)); } catch (Exception e) { System.out.println( "Failed to delete instance config " @@ -134,7 +134,6 @@ public static void afterClass() throws InterruptedException { + ", skipping..."); } } - databaseAdminClient.close(); instanceAdminClient.close(); @@ -157,4 +156,12 @@ static String getBackupName(final String projectId, static String getInstanceName(final String projectId, final String instanceId) { return String.format("projects/%s/instances/%s", projectId, instanceId); } + + static String getInstanceConfigName(final String projectId, final String instanceConfigId) { + return String.format("projects/%s/instanceConfigs/%s", projectId, instanceConfigId); + } + + static String getProjectName(final String projectId) { + return String.format("projects/%s", projectId); + } } From 19f75d88832c9e33c8482dc67acf0876e9c73552 Mon Sep 17 00:00:00 2001 From: "release-please[bot]" <55107282+release-please[bot]@users.noreply.github.com> Date: Fri, 12 Jan 2024 16:04:16 +0000 Subject: [PATCH 02/21] chore(main): release 6.56.1-SNAPSHOT (#2773) :robot: I have created a release *beep* *boop* --- ### Updating meta-information for bleeding-edge SNAPSHOT release. --- This PR was generated with [Release Please](https://togithub.com/googleapis/release-please). See [documentation](https://togithub.com/googleapis/release-please#release-please). --- google-cloud-spanner-bom/pom.xml | 20 +++++++++---------- google-cloud-spanner-executor/pom.xml | 4 ++-- google-cloud-spanner/pom.xml | 4 ++-- .../pom.xml | 4 ++-- .../pom.xml | 4 ++-- grpc-google-cloud-spanner-executor-v1/pom.xml | 4 ++-- grpc-google-cloud-spanner-v1/pom.xml | 4 ++-- pom.xml | 20 +++++++++---------- .../pom.xml | 4 ++-- .../pom.xml | 4 ++-- .../pom.xml | 4 ++-- proto-google-cloud-spanner-v1/pom.xml | 4 ++-- samples/snapshot/pom.xml | 2 +- versions.txt | 20 +++++++++---------- 14 files changed, 51 insertions(+), 51 deletions(-) diff --git a/google-cloud-spanner-bom/pom.xml b/google-cloud-spanner-bom/pom.xml index 232ebb3bc3a..257c3bb24b5 100644 --- a/google-cloud-spanner-bom/pom.xml +++ b/google-cloud-spanner-bom/pom.xml @@ -3,7 +3,7 @@ 4.0.0 com.google.cloud google-cloud-spanner-bom - 6.56.0 + 6.56.1-SNAPSHOT pom com.google.cloud @@ -53,48 +53,48 @@ com.google.cloud google-cloud-spanner - 6.56.0 + 6.56.1-SNAPSHOT com.google.cloud google-cloud-spanner-executor - 6.56.0 + 6.56.1-SNAPSHOT com.google.cloud google-cloud-spanner test-jar - 6.56.0 + 6.56.1-SNAPSHOT com.google.api.grpc grpc-google-cloud-spanner-v1 - 6.56.0 + 6.56.1-SNAPSHOT com.google.api.grpc grpc-google-cloud-spanner-admin-instance-v1 - 6.56.0 + 6.56.1-SNAPSHOT com.google.api.grpc grpc-google-cloud-spanner-admin-database-v1 - 6.56.0 + 6.56.1-SNAPSHOT com.google.api.grpc proto-google-cloud-spanner-admin-instance-v1 - 6.56.0 + 6.56.1-SNAPSHOT com.google.api.grpc proto-google-cloud-spanner-v1 - 6.56.0 + 6.56.1-SNAPSHOT com.google.api.grpc proto-google-cloud-spanner-admin-database-v1 - 6.56.0 + 6.56.1-SNAPSHOT diff --git a/google-cloud-spanner-executor/pom.xml b/google-cloud-spanner-executor/pom.xml index 38c1b618f49..094a0933e5b 100644 --- a/google-cloud-spanner-executor/pom.xml +++ b/google-cloud-spanner-executor/pom.xml @@ -5,14 +5,14 @@ 4.0.0 com.google.cloud google-cloud-spanner-executor - 6.56.0 + 6.56.1-SNAPSHOT jar Google Cloud Spanner Executor com.google.cloud google-cloud-spanner-parent - 6.56.0 + 6.56.1-SNAPSHOT diff --git a/google-cloud-spanner/pom.xml b/google-cloud-spanner/pom.xml index b843a62c4a3..24abc0d2195 100644 --- a/google-cloud-spanner/pom.xml +++ b/google-cloud-spanner/pom.xml @@ -3,7 +3,7 @@ 4.0.0 com.google.cloud google-cloud-spanner - 6.56.0 + 6.56.1-SNAPSHOT jar Google Cloud Spanner https://github.com/googleapis/java-spanner @@ -11,7 +11,7 @@ com.google.cloud google-cloud-spanner-parent - 6.56.0 + 6.56.1-SNAPSHOT google-cloud-spanner diff --git a/grpc-google-cloud-spanner-admin-database-v1/pom.xml b/grpc-google-cloud-spanner-admin-database-v1/pom.xml index c93e5a6dd95..5878efe3231 100644 --- a/grpc-google-cloud-spanner-admin-database-v1/pom.xml +++ b/grpc-google-cloud-spanner-admin-database-v1/pom.xml @@ -4,13 +4,13 @@ 4.0.0 com.google.api.grpc grpc-google-cloud-spanner-admin-database-v1 - 6.56.0 + 6.56.1-SNAPSHOT grpc-google-cloud-spanner-admin-database-v1 GRPC library for grpc-google-cloud-spanner-admin-database-v1 com.google.cloud google-cloud-spanner-parent - 6.56.0 + 6.56.1-SNAPSHOT diff --git a/grpc-google-cloud-spanner-admin-instance-v1/pom.xml b/grpc-google-cloud-spanner-admin-instance-v1/pom.xml index db2c09e364a..a24a3a237f2 100644 --- a/grpc-google-cloud-spanner-admin-instance-v1/pom.xml +++ b/grpc-google-cloud-spanner-admin-instance-v1/pom.xml @@ -4,13 +4,13 @@ 4.0.0 com.google.api.grpc grpc-google-cloud-spanner-admin-instance-v1 - 6.56.0 + 6.56.1-SNAPSHOT grpc-google-cloud-spanner-admin-instance-v1 GRPC library for grpc-google-cloud-spanner-admin-instance-v1 com.google.cloud google-cloud-spanner-parent - 6.56.0 + 6.56.1-SNAPSHOT diff --git a/grpc-google-cloud-spanner-executor-v1/pom.xml b/grpc-google-cloud-spanner-executor-v1/pom.xml index 58b71b249da..905f35a2c95 100644 --- a/grpc-google-cloud-spanner-executor-v1/pom.xml +++ b/grpc-google-cloud-spanner-executor-v1/pom.xml @@ -4,13 +4,13 @@ 4.0.0 com.google.api.grpc grpc-google-cloud-spanner-executor-v1 - 6.56.0 + 6.56.1-SNAPSHOT grpc-google-cloud-spanner-executor-v1 GRPC library for google-cloud-spanner com.google.cloud google-cloud-spanner-parent - 6.56.0 + 6.56.1-SNAPSHOT diff --git a/grpc-google-cloud-spanner-v1/pom.xml b/grpc-google-cloud-spanner-v1/pom.xml index 2b18db8530f..b76dad98579 100644 --- a/grpc-google-cloud-spanner-v1/pom.xml +++ b/grpc-google-cloud-spanner-v1/pom.xml @@ -4,13 +4,13 @@ 4.0.0 com.google.api.grpc grpc-google-cloud-spanner-v1 - 6.56.0 + 6.56.1-SNAPSHOT grpc-google-cloud-spanner-v1 GRPC library for grpc-google-cloud-spanner-v1 com.google.cloud google-cloud-spanner-parent - 6.56.0 + 6.56.1-SNAPSHOT diff --git a/pom.xml b/pom.xml index b94c5bb9702..de0017f9cb1 100644 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ com.google.cloud google-cloud-spanner-parent pom - 6.56.0 + 6.56.1-SNAPSHOT Google Cloud Spanner Parent https://github.com/googleapis/java-spanner @@ -62,47 +62,47 @@ com.google.api.grpc proto-google-cloud-spanner-admin-instance-v1 - 6.56.0 + 6.56.1-SNAPSHOT com.google.api.grpc proto-google-cloud-spanner-executor-v1 - 6.56.0 + 6.56.1-SNAPSHOT com.google.api.grpc grpc-google-cloud-spanner-executor-v1 - 6.56.0 + 6.56.1-SNAPSHOT com.google.api.grpc proto-google-cloud-spanner-v1 - 6.56.0 + 6.56.1-SNAPSHOT com.google.api.grpc proto-google-cloud-spanner-admin-database-v1 - 6.56.0 + 6.56.1-SNAPSHOT com.google.api.grpc grpc-google-cloud-spanner-v1 - 6.56.0 + 6.56.1-SNAPSHOT com.google.api.grpc grpc-google-cloud-spanner-admin-instance-v1 - 6.56.0 + 6.56.1-SNAPSHOT com.google.api.grpc grpc-google-cloud-spanner-admin-database-v1 - 6.56.0 + 6.56.1-SNAPSHOT com.google.cloud google-cloud-spanner - 6.56.0 + 6.56.1-SNAPSHOT diff --git a/proto-google-cloud-spanner-admin-database-v1/pom.xml b/proto-google-cloud-spanner-admin-database-v1/pom.xml index ce545f304ae..58aaca468f9 100644 --- a/proto-google-cloud-spanner-admin-database-v1/pom.xml +++ b/proto-google-cloud-spanner-admin-database-v1/pom.xml @@ -4,13 +4,13 @@ 4.0.0 com.google.api.grpc proto-google-cloud-spanner-admin-database-v1 - 6.56.0 + 6.56.1-SNAPSHOT proto-google-cloud-spanner-admin-database-v1 PROTO library for proto-google-cloud-spanner-admin-database-v1 com.google.cloud google-cloud-spanner-parent - 6.56.0 + 6.56.1-SNAPSHOT diff --git a/proto-google-cloud-spanner-admin-instance-v1/pom.xml b/proto-google-cloud-spanner-admin-instance-v1/pom.xml index d9d6234d8ad..3cceb9e3471 100644 --- a/proto-google-cloud-spanner-admin-instance-v1/pom.xml +++ b/proto-google-cloud-spanner-admin-instance-v1/pom.xml @@ -4,13 +4,13 @@ 4.0.0 com.google.api.grpc proto-google-cloud-spanner-admin-instance-v1 - 6.56.0 + 6.56.1-SNAPSHOT proto-google-cloud-spanner-admin-instance-v1 PROTO library for proto-google-cloud-spanner-admin-instance-v1 com.google.cloud google-cloud-spanner-parent - 6.56.0 + 6.56.1-SNAPSHOT diff --git a/proto-google-cloud-spanner-executor-v1/pom.xml b/proto-google-cloud-spanner-executor-v1/pom.xml index 11441c6c33f..f75db302663 100644 --- a/proto-google-cloud-spanner-executor-v1/pom.xml +++ b/proto-google-cloud-spanner-executor-v1/pom.xml @@ -4,13 +4,13 @@ 4.0.0 com.google.api.grpc proto-google-cloud-spanner-executor-v1 - 6.56.0 + 6.56.1-SNAPSHOT proto-google-cloud-spanner-executor-v1 Proto library for google-cloud-spanner com.google.cloud google-cloud-spanner-parent - 6.56.0 + 6.56.1-SNAPSHOT diff --git a/proto-google-cloud-spanner-v1/pom.xml b/proto-google-cloud-spanner-v1/pom.xml index 1e853188341..94c2ea3bba0 100644 --- a/proto-google-cloud-spanner-v1/pom.xml +++ b/proto-google-cloud-spanner-v1/pom.xml @@ -4,13 +4,13 @@ 4.0.0 com.google.api.grpc proto-google-cloud-spanner-v1 - 6.56.0 + 6.56.1-SNAPSHOT proto-google-cloud-spanner-v1 PROTO library for proto-google-cloud-spanner-v1 com.google.cloud google-cloud-spanner-parent - 6.56.0 + 6.56.1-SNAPSHOT diff --git a/samples/snapshot/pom.xml b/samples/snapshot/pom.xml index 5e343b36dcc..1bd0971d430 100644 --- a/samples/snapshot/pom.xml +++ b/samples/snapshot/pom.xml @@ -32,7 +32,7 @@ com.google.cloud google-cloud-spanner - 6.56.0 + 6.56.1-SNAPSHOT diff --git a/versions.txt b/versions.txt index 5911a718a06..264eb030ceb 100644 --- a/versions.txt +++ b/versions.txt @@ -1,13 +1,13 @@ # Format: # module:released-version:current-version -proto-google-cloud-spanner-admin-instance-v1:6.56.0:6.56.0 -proto-google-cloud-spanner-v1:6.56.0:6.56.0 -proto-google-cloud-spanner-admin-database-v1:6.56.0:6.56.0 -grpc-google-cloud-spanner-v1:6.56.0:6.56.0 -grpc-google-cloud-spanner-admin-instance-v1:6.56.0:6.56.0 -grpc-google-cloud-spanner-admin-database-v1:6.56.0:6.56.0 -google-cloud-spanner:6.56.0:6.56.0 -google-cloud-spanner-executor:6.56.0:6.56.0 -proto-google-cloud-spanner-executor-v1:6.56.0:6.56.0 -grpc-google-cloud-spanner-executor-v1:6.56.0:6.56.0 +proto-google-cloud-spanner-admin-instance-v1:6.56.0:6.56.1-SNAPSHOT +proto-google-cloud-spanner-v1:6.56.0:6.56.1-SNAPSHOT +proto-google-cloud-spanner-admin-database-v1:6.56.0:6.56.1-SNAPSHOT +grpc-google-cloud-spanner-v1:6.56.0:6.56.1-SNAPSHOT +grpc-google-cloud-spanner-admin-instance-v1:6.56.0:6.56.1-SNAPSHOT +grpc-google-cloud-spanner-admin-database-v1:6.56.0:6.56.1-SNAPSHOT +google-cloud-spanner:6.56.0:6.56.1-SNAPSHOT +google-cloud-spanner-executor:6.56.0:6.56.1-SNAPSHOT +proto-google-cloud-spanner-executor-v1:6.56.0:6.56.1-SNAPSHOT +grpc-google-cloud-spanner-executor-v1:6.56.0:6.56.1-SNAPSHOT From 1c41e9d067c26ddc1b38f4235eb0fd4d640e2281 Mon Sep 17 00:00:00 2001 From: Mend Renovate Date: Thu, 18 Jan 2024 15:59:29 +0100 Subject: [PATCH 03/21] chore(deps): update dependency com.google.cloud:libraries-bom to v26.30.0 (#2729) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * chore(deps): update dependency com.google.cloud:libraries-bom to v26.30.0 * 🦉 Updates from OwlBot post-processor See https://github.com/googleapis/repo-automation-bots/blob/main/packages/owl-bot/README.md --------- Co-authored-by: Owl Bot --- README.md | 4 ++-- samples/native-image/pom.xml | 2 +- samples/snippets/pom.xml | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 5b94cdadb35..bb85fae99ef 100644 --- a/README.md +++ b/README.md @@ -19,7 +19,7 @@ If you are using Maven with [BOM][libraries-bom], add this to your pom.xml file: com.google.cloud libraries-bom - 26.26.0 + 26.30.0 pom import @@ -50,7 +50,7 @@ If you are using Maven without the BOM, add this to your dependencies: If you are using Gradle 5.x or later, add this to your dependencies: ```Groovy -implementation platform('com.google.cloud:libraries-bom:26.29.0') +implementation platform('com.google.cloud:libraries-bom:26.30.0') implementation 'com.google.cloud:google-cloud-spanner' ``` diff --git a/samples/native-image/pom.xml b/samples/native-image/pom.xml index d4a8d10d74c..137f5596148 100644 --- a/samples/native-image/pom.xml +++ b/samples/native-image/pom.xml @@ -29,7 +29,7 @@ com.google.cloud libraries-bom - 26.26.0 + 26.30.0 pom import diff --git a/samples/snippets/pom.xml b/samples/snippets/pom.xml index 406225e85f0..b6dd7ab693c 100644 --- a/samples/snippets/pom.xml +++ b/samples/snippets/pom.xml @@ -34,7 +34,7 @@ com.google.cloud libraries-bom - 26.26.0 + 26.30.0 pom import From 38792f4bf2e5267f09fa22ac4d3c045e54ab2544 Mon Sep 17 00:00:00 2001 From: Mend Renovate Date: Fri, 19 Jan 2024 05:19:35 +0100 Subject: [PATCH 04/21] chore(deps): update dependency com.google.cloud:google-cloud-spanner to v6.56.0 (#2735) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * chore(deps): update dependency com.google.cloud:google-cloud-spanner to v6.56.0 * 🦉 Updates from OwlBot post-processor See https://github.com/googleapis/repo-automation-bots/blob/main/packages/owl-bot/README.md --------- Co-authored-by: Owl Bot --- README.md | 2 +- samples/install-without-bom/pom.xml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index bb85fae99ef..503eb3677d5 100644 --- a/README.md +++ b/README.md @@ -42,7 +42,7 @@ If you are using Maven without the BOM, add this to your dependencies: com.google.cloud google-cloud-spanner - 6.53.0 + 6.56.0 ``` diff --git a/samples/install-without-bom/pom.xml b/samples/install-without-bom/pom.xml index 5db018897a9..592328de2d9 100644 --- a/samples/install-without-bom/pom.xml +++ b/samples/install-without-bom/pom.xml @@ -33,7 +33,7 @@ com.google.cloud google-cloud-spanner - 6.53.0 + 6.56.0 From 6b9513f95d261b09f0aa003c08ecb65e09ed79c7 Mon Sep 17 00:00:00 2001 From: Rajat Bhatta <93644539+rajatbhatta@users.noreply.github.com> Date: Fri, 19 Jan 2024 19:13:20 +0800 Subject: [PATCH 05/21] sample: add support for Directed Read options (#2394) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * sample: add support for Directed Read options * add additional assertion on output from sample * fix nit Co-authored-by: Knut Olav Løite * 🦉 Updates from OwlBot post-processor See https://github.com/googleapis/repo-automation-bots/blob/main/packages/owl-bot/README.md * feat: update setter * 🦉 Updates from OwlBot post-processor See https://github.com/googleapis/repo-automation-bots/blob/main/packages/owl-bot/README.md * feat: update comment * feat: update comment * feat: add additional comments * feat: lint fix --------- Co-authored-by: Knut Olav Løite Co-authored-by: Owl Bot Co-authored-by: Sri Harsha CH <57220027+harshachinta@users.noreply.github.com> Co-authored-by: Sri Harsha CH --- README.md | 1 + .../example/spanner/DirectedReadSample.java | 114 ++++++++++++++++++ .../example/spanner/DirectedReadSampleIT.java | 105 ++++++++++++++++ 3 files changed, 220 insertions(+) create mode 100644 samples/snippets/src/main/java/com/example/spanner/DirectedReadSample.java create mode 100644 samples/snippets/src/test/java/com/example/spanner/DirectedReadSampleIT.java diff --git a/README.md b/README.md index 503eb3677d5..4784fc5caeb 100644 --- a/README.md +++ b/README.md @@ -285,6 +285,7 @@ Samples are in the [`samples/`](https://github.com/googleapis/java-spanner/tree/ | Custom Timeout And Retry Settings Example | [source code](https://github.com/googleapis/java-spanner/blob/main/samples/snippets/src/main/java/com/example/spanner/CustomTimeoutAndRetrySettingsExample.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/CustomTimeoutAndRetrySettingsExample.java) | | Delete Instance Config Sample | [source code](https://github.com/googleapis/java-spanner/blob/main/samples/snippets/src/main/java/com/example/spanner/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/DeleteInstanceConfigSample.java) | | Delete Using Dml Returning Sample | [source code](https://github.com/googleapis/java-spanner/blob/main/samples/snippets/src/main/java/com/example/spanner/DeleteUsingDmlReturningSample.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/DeleteUsingDmlReturningSample.java) | +| Directed Read Sample | [source code](https://github.com/googleapis/java-spanner/blob/main/samples/snippets/src/main/java/com/example/spanner/DirectedReadSample.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/DirectedReadSample.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/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/DropForeignKeyConstraintDeleteCascadeSample.java) | | Drop Sequence Sample | [source code](https://github.com/googleapis/java-spanner/blob/main/samples/snippets/src/main/java/com/example/spanner/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/DropSequenceSample.java) | | Enable Fine Grained Access | [source code](https://github.com/googleapis/java-spanner/blob/main/samples/snippets/src/main/java/com/example/spanner/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/EnableFineGrainedAccess.java) | diff --git a/samples/snippets/src/main/java/com/example/spanner/DirectedReadSample.java b/samples/snippets/src/main/java/com/example/spanner/DirectedReadSample.java new file mode 100644 index 00000000000..141d9e28244 --- /dev/null +++ b/samples/snippets/src/main/java/com/example/spanner/DirectedReadSample.java @@ -0,0 +1,114 @@ +/* + * Copyright 2023 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; + +// [START spanner_directed_read] +import com.google.cloud.spanner.DatabaseClient; +import com.google.cloud.spanner.DatabaseId; +import com.google.cloud.spanner.Options; +import com.google.cloud.spanner.ResultSet; +import com.google.cloud.spanner.Spanner; +import com.google.cloud.spanner.SpannerOptions; +import com.google.cloud.spanner.Statement; +import com.google.spanner.v1.DirectedReadOptions; +import com.google.spanner.v1.DirectedReadOptions.ExcludeReplicas; +import com.google.spanner.v1.DirectedReadOptions.IncludeReplicas; +import com.google.spanner.v1.DirectedReadOptions.ReplicaSelection; + +public class DirectedReadSample { + static void directedRead() { + // TODO(developer): Replace these variables before running the sample. + final String projectId = "my-project"; + final String instanceId = "my-instance"; + final String databaseId = "my-database"; + directedRead(projectId, instanceId, databaseId); + } + + static void directedRead(String projectId, String instanceId, String databaseId) { + // Only one of excludeReplicas or includeReplicas can be set + // Each accepts a list of replicaSelections which contains location and type + // * `location` - The location must be one of the regions within the + // multi-region configuration of your database. + // * `type` - The type of the replica + // Some examples of using replicaSelectors are: + // * `location:us-east1` --> The "us-east1" replica(s) of any available type + // will be used to process the request. + // * `type:READ_ONLY` --> The "READ_ONLY" type replica(s) in nearest + // . available location will be used to process the + // request. + // * `location:us-east1 type:READ_ONLY` --> The "READ_ONLY" type replica(s) + // in location "us-east1" will be used to process + // the request. + // includeReplicas also contains an option called autoFailoverDisabled, which when set to true + // will instruct Spanner to not route requests to a replica outside the + // includeReplicas list when all the specified replicas are unavailable + // or unhealthy. Default value is `false`. + final DirectedReadOptions directedReadOptionsForClient = + DirectedReadOptions.newBuilder() + .setExcludeReplicas( + ExcludeReplicas.newBuilder() + .addReplicaSelections( + ReplicaSelection.newBuilder().setLocation("us-east4").build()) + .build()) + .build(); + + // You can set default `DirectedReadOptions` for a Spanner client. These options will be applied + // to all read-only transactions that are executed by this client, unless specific + // DirectedReadOptions are set for a query. + // Directed read can only be used for read-only transactions. The default options will be + // ignored for any read/write transaction that the client executes. + try (Spanner spanner = + SpannerOptions.newBuilder() + .setProjectId(projectId) + .setDirectedReadOptions(directedReadOptionsForClient) + .build() + .getService()) { + final DatabaseClient dbClient = + spanner.getDatabaseClient(DatabaseId.of(projectId, instanceId, databaseId)); + + // DirectedReadOptions at request level will override the options set at + // client level (through SpannerOptions). + final DirectedReadOptions directedReadOptionsForRequest = + DirectedReadOptions.newBuilder() + .setIncludeReplicas( + IncludeReplicas.newBuilder() + .addReplicaSelections( + ReplicaSelection.newBuilder() + .setType(ReplicaSelection.Type.READ_WRITE) + .build()) + .setAutoFailoverDisabled(true) + .build()) + .build(); + + // Read rows while passing DirectedReadOptions directly to the query. + try (ResultSet rs = + dbClient + .singleUse() + .executeQuery( + Statement.of("SELECT SingerId, AlbumId, AlbumTitle FROM Albums"), + Options.directedRead(directedReadOptionsForRequest))) { + while (rs.next()) { + System.out.printf( + "SingerId: %d, AlbumId: %d, AlbumTitle: %s\n", + rs.getLong(0), rs.getLong(1), rs.getString(2)); + } + System.out.println("Successfully executed read-only transaction with directedReadOptions"); + } + } + } +} +// [END spanner_directed_read] diff --git a/samples/snippets/src/test/java/com/example/spanner/DirectedReadSampleIT.java b/samples/snippets/src/test/java/com/example/spanner/DirectedReadSampleIT.java new file mode 100644 index 00000000000..771e157a3df --- /dev/null +++ b/samples/snippets/src/test/java/com/example/spanner/DirectedReadSampleIT.java @@ -0,0 +1,105 @@ +/* + * 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; + +import static com.example.spanner.SampleRunner.runSample; +import static org.junit.Assert.assertTrue; + +import com.google.cloud.spanner.DatabaseAdminClient; +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.cloud.spanner.Spanner; +import com.google.cloud.spanner.SpannerOptions; +import com.google.common.collect.ImmutableList; +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 {@link DirectedReadSample} */ +@RunWith(JUnit4.class) +public class DirectedReadSampleIT extends SampleTestBase { + + private static DatabaseId databaseId; + private static Spanner spanner; + + @BeforeClass + public static void createTestDatabase() throws Exception { + spanner = SpannerOptions.newBuilder().setProjectId(projectId).build().getService(); + DatabaseAdminClient databaseAdminClient = spanner.getDatabaseAdminClient(); + final String database = idGenerator.generateDatabaseId(); + databaseAdminClient + .createDatabase( + instanceId, + database, + ImmutableList.of( + "CREATE TABLE Albums (" + + " SingerId INT64 NOT NULL," + + " AlbumId INT64," + + " AlbumTitle STRING(1024)" + + ") PRIMARY KEY (SingerId, AlbumId)")) + .get(10, TimeUnit.MINUTES); + databaseId = DatabaseId.of(projectId, instanceId, database); + } + + @Before + public void insertTestData() { + final DatabaseClient client = spanner.getDatabaseClient(databaseId); + client.write( + Arrays.asList( + Mutation.newInsertOrUpdateBuilder("Albums") + .set("SingerId") + .to(1L) + .set("AlbumId") + .to(1L) + .set("AlbumTitle") + .to("title 1") + .build(), + Mutation.newInsertOrUpdateBuilder("Albums") + .set("SingerId") + .to(2L) + .set("AlbumId") + .to(2L) + .set("AlbumTitle") + .to("title 2") + .build())); + } + + @After + public void removeTestData() { + final DatabaseClient client = spanner.getDatabaseClient(databaseId); + client.write(Collections.singletonList(Mutation.delete("Albums", KeySet.all()))); + } + + @Test + public void testDirectedRead() throws Exception { + final String out = + runSample( + () -> DirectedReadSample.directedRead(projectId, instanceId, databaseId.getDatabase())); + assertTrue(out.contains("SingerId: 1, AlbumId: 1, AlbumTitle: title 1")); + assertTrue(out.contains("SingerId: 2, AlbumId: 2, AlbumTitle: title 2")); + assertTrue( + out.contains("Successfully executed read-only transaction with directedReadOptions")); + } +} From 8bf2a7333bf208e01cb5e237bed9d9293f119f2d Mon Sep 17 00:00:00 2001 From: "gcf-owl-bot[bot]" <78513119+gcf-owl-bot[bot]@users.noreply.github.com> Date: Mon, 22 Jan 2024 11:19:09 -0500 Subject: [PATCH 06/21] chore: Create renovate_config_check.yaml (#1920) (#2795) * chore: Create renovate_config_check.yaml Source-Link: https://github.com/googleapis/synthtool/commit/6612ab8f3afcd5e292aecd647f0fa68812c9f5b5 Post-Processor: gcr.io/cloud-devrel-public-resources/owlbot-java:latest@sha256:a6aa751984f1e905c3ae5a3aac78fc7b68210626ce91487dc7ff4f0a06f010cc Co-authored-by: Owl Bot --- .github/.OwlBot.lock.yaml | 6 ++--- .github/workflows/renovate_config_check.yaml | 25 ++++++++++++++++++++ 2 files changed, 28 insertions(+), 3 deletions(-) create mode 100644 .github/workflows/renovate_config_check.yaml diff --git a/.github/.OwlBot.lock.yaml b/.github/.OwlBot.lock.yaml index 30e52f32306..dc05a72762f 100644 --- a/.github/.OwlBot.lock.yaml +++ b/.github/.OwlBot.lock.yaml @@ -1,4 +1,4 @@ -# Copyright 2023 Google LLC +# Copyright 2024 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -13,5 +13,5 @@ # limitations under the License. docker: image: gcr.io/cloud-devrel-public-resources/owlbot-java:latest - digest: sha256:81f75d962cd28b7ad10740a643b8069b8fa0357cb495b782eef8560bb7a8fd65 -# created: 2023-12-05T19:16:19.735195992Z \ No newline at end of file + digest: sha256:a6aa751984f1e905c3ae5a3aac78fc7b68210626ce91487dc7ff4f0a06f010cc +# created: 2024-01-22T14:14:20.913785597Z diff --git a/.github/workflows/renovate_config_check.yaml b/.github/workflows/renovate_config_check.yaml new file mode 100644 index 00000000000..87d8eb2be8c --- /dev/null +++ b/.github/workflows/renovate_config_check.yaml @@ -0,0 +1,25 @@ +name: Renovate Bot Config Validation + +on: + pull_request: + paths: + - 'renovate.json' + +jobs: + renovate_bot_config_validation: + runs-on: ubuntu-22.04 + + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Set up Node.js + uses: actions/setup-node@v3 + with: + node-version: '20' + + - name: Install Renovate and Config Validator + run: | + npm install -g npm@latest + npm install --global renovate + renovate-config-validator From 8b642e5970bdafe85684c3fcc7f3b1787fe17574 Mon Sep 17 00:00:00 2001 From: Deepankar Dixit <90280028+ddixit14@users.noreply.github.com> Date: Mon, 22 Jan 2024 18:21:31 +0000 Subject: [PATCH 07/21] chore: remove dependency list completeness check (#2797) Reference for removal of this check in split-repositories - https://github.com/googleapis/synthtool/pull/1663 --- .kokoro/dependencies.sh | 51 ----------------------------------------- 1 file changed, 51 deletions(-) diff --git a/.kokoro/dependencies.sh b/.kokoro/dependencies.sh index 6a9f719a5e6..3c613d6b56d 100755 --- a/.kokoro/dependencies.sh +++ b/.kokoro/dependencies.sh @@ -65,54 +65,3 @@ if [ ! -z "${JAVA8_HOME}" ]; then fi mvn -B dependency:analyze -DfailOnWarning=true - -echo "****************** DEPENDENCY LIST COMPLETENESS CHECK *******************" -## Run dependency list completeness check -function completenessCheck() { - # Output dep list with compile scope generated using the original pom - # Running mvn dependency:list on Java versions that support modules will also include the module of the dependency. - # This is stripped from the output as it is not present in the flattened pom. - # Only dependencies with 'compile' or 'runtime' scope are included from original dependency list. - msg "Generating dependency list using original pom..." - mvn dependency:list -f pom.xml -DincludeScope=runtime -Dsort=true | grep '\[INFO] .*:.*:.*:.*:.*' | sed -e 's/ --.*//' >.org-list.txt - - # Output dep list generated using the flattened pom (only 'compile' and 'runtime' scopes) - msg "Generating dependency list using flattened pom..." - mvn dependency:list -f .flattened-pom.xml -DincludeScope=runtime -Dsort=true | grep '\[INFO] .*:.*:.*:.*:.*' >.new-list.txt - - # Compare two dependency lists - msg "Comparing dependency lists..." - diff .org-list.txt .new-list.txt >.diff.txt - if [[ $? == 0 ]] - then - msg "Success. No diff!" - else - msg "Diff found. See below: " - msg "You can also check .diff.txt file located in $1." - cat .diff.txt - return 1 - fi -} - -# Allow failures to continue running the script -set +e - -error_count=0 -for path in **/.flattened-pom.xml -do - # Check flattened pom in each dir that contains it for completeness - dir=$(dirname "$path") - pushd "$dir" - completenessCheck "$dir" - error_count=$(($error_count + $?)) - popd -done - -if [[ $error_count == 0 ]] -then - msg "All checks passed." - exit 0 -else - msg "Errors found. See log statements above." - exit 1 -fi From f689f742d8754134523ed0394b9c1b8256adcae2 Mon Sep 17 00:00:00 2001 From: Mend Renovate Date: Tue, 23 Jan 2024 04:02:29 +0100 Subject: [PATCH 08/21] deps: update dependency com.google.cloud:google-cloud-shared-dependencies to v3.22.0 (#2785) --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index de0017f9cb1..31fc8561520 100644 --- a/pom.xml +++ b/pom.xml @@ -54,7 +54,7 @@ UTF-8 github google-cloud-spanner-parent - 3.21.0 + 3.22.0 From 4a906bf2719c30dcd7371f497a8a28c250db77be Mon Sep 17 00:00:00 2001 From: "gcf-owl-bot[bot]" <78513119+gcf-owl-bot[bot]@users.noreply.github.com> Date: Wed, 24 Jan 2024 17:13:54 +0530 Subject: [PATCH 09/21] feat(spanner): add proto descriptors for proto and enum types in create/update/get database ddl requests (#2774) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * feat(spanner): add proto descriptors for proto and enum types in create/update/get database ddl requests PiperOrigin-RevId: 601013501 Source-Link: https://github.com/googleapis/googleapis/commit/81b24a52c7d820e43a18417fa4ee2b7494b64fa3 Source-Link: https://github.com/googleapis/googleapis-gen/commit/46f0446037906f0d905365835f02a652241f3de3 Copy-Tag: eyJwIjoiLmdpdGh1Yi8uT3dsQm90LnlhbWwiLCJoIjoiNDZmMDQ0NjAzNzkwNmYwZDkwNTM2NTgzNWYwMmE2NTIyNDFmM2RlMyJ9 fix(deps): Update the Java code generator (gapic-generator-java) to 2.32.0 PiperOrigin-RevId: 599914188 Source-Link: https://github.com/googleapis/googleapis/commit/17e6661f8bf43374633adf950454ed8e69bdcee1 Source-Link: https://github.com/googleapis/googleapis-gen/commit/d86ba5be537e489435105ca85566cc4103301aba Copy-Tag: eyJwIjoiLmdpdGh1Yi8uT3dsQm90LnlhbWwiLCJoIjoiZDg2YmE1YmU1MzdlNDg5NDM1MTA1Y2E4NTU2NmNjNDEwMzMwMWFiYSJ9 feat: add max_commit_delay API PiperOrigin-RevId: 599315735 Source-Link: https://github.com/googleapis/googleapis/commit/465a103d01ad515f7bdb48185ffcca9e20aa7e73 Source-Link: https://github.com/googleapis/googleapis-gen/commit/930e2318acbd10fb54d8668d2f2cf19fe413d5a9 Copy-Tag: eyJwIjoiLmdpdGh1Yi8uT3dsQm90LnlhbWwiLCJoIjoiOTMwZTIzMThhY2JkMTBmYjU0ZDg2NjhkMmYyY2YxOWZlNDEzZDVhOSJ9 feat(spanner): add proto and enum types PiperOrigin-RevId: 599046867 Source-Link: https://github.com/googleapis/googleapis/commit/64a5bfe1fef67ccad62e49ab398c5c8baa57080c Source-Link: https://github.com/googleapis/googleapis-gen/commit/6e96ab8bb1ec4536c5a0c4d095f53ce0578cb8a4 Copy-Tag: eyJwIjoiLmdpdGh1Yi8uT3dsQm90LnlhbWwiLCJoIjoiNmU5NmFiOGJiMWVjNDUzNmM1YTBjNGQwOTVmNTNjZTA1NzhjYjhhNCJ9 fix(deps): Update the Java code generator (gapic-generator-java) to 2.31.0 PiperOrigin-RevId: 596645164 Source-Link: https://github.com/googleapis/googleapis/commit/4a0e62ecde2a6459bea8722a33173cfce1e9fb50 Source-Link: https://github.com/googleapis/googleapis-gen/commit/a10ed6a77676c37e60799098d48d0afb16008613 Copy-Tag: eyJwIjoiLmdpdGh1Yi8uT3dsQm90LnlhbWwiLCJoIjoiYTEwZWQ2YTc3Njc2YzM3ZTYwNzk5MDk4ZDQ4ZDBhZmIxNjAwODYxMyJ9 * 🦉 Updates from OwlBot post-processor See https://github.com/googleapis/repo-automation-bots/blob/main/packages/owl-bot/README.md --------- Co-authored-by: Owl Bot --- .../v1/SpannerExecutorProxyClient.java | 33 +- .../SpannerExecutorProxyStubSettings.java | 25 +- .../database/v1/DatabaseAdminClient.java | 428 ++++++++++++++- .../v1/stub/DatabaseAdminStubSettings.java | 26 +- .../instance/v1/InstanceAdminClient.java | 333 +++++++++++- .../v1/stub/InstanceAdminStubSettings.java | 26 +- .../cloud/spanner/v1/SpannerClient.java | 294 ++++++++++- .../spanner/v1/stub/SpannerStubSettings.java | 26 +- .../v1/DatabaseAdminClientHttpJsonTest.java | 10 +- .../database/v1/DatabaseAdminClientTest.java | 10 +- .../admin/database/v1/DatabaseAdminGrpc.java | 2 +- .../admin/instance/v1/InstanceAdminGrpc.java | 2 +- .../executor/v1/SpannerExecutorProxyGrpc.java | 2 +- .../com/google/spanner/v1/SpannerGrpc.java | 2 +- .../spanner/admin/database/v1/Backup.java | 2 +- .../spanner/admin/database/v1/BackupInfo.java | 2 +- .../database/v1/BackupInfoOrBuilder.java | 2 +- .../admin/database/v1/BackupOrBuilder.java | 2 +- .../admin/database/v1/BackupProto.java | 2 +- .../admin/database/v1/CommonProto.java | 2 +- .../v1/CopyBackupEncryptionConfig.java | 2 +- .../CopyBackupEncryptionConfigOrBuilder.java | 2 +- .../admin/database/v1/CopyBackupMetadata.java | 2 +- .../v1/CopyBackupMetadataOrBuilder.java | 2 +- .../admin/database/v1/CopyBackupRequest.java | 2 +- .../v1/CopyBackupRequestOrBuilder.java | 2 +- .../v1/CreateBackupEncryptionConfig.java | 2 +- ...CreateBackupEncryptionConfigOrBuilder.java | 2 +- .../database/v1/CreateBackupMetadata.java | 2 +- .../v1/CreateBackupMetadataOrBuilder.java | 2 +- .../database/v1/CreateBackupRequest.java | 2 +- .../v1/CreateBackupRequestOrBuilder.java | 2 +- .../database/v1/CreateDatabaseMetadata.java | 2 +- .../v1/CreateDatabaseMetadataOrBuilder.java | 2 +- .../database/v1/CreateDatabaseRequest.java | 154 +++++- .../v1/CreateDatabaseRequestOrBuilder.java | 29 +- .../spanner/admin/database/v1/Database.java | 2 +- .../admin/database/v1/DatabaseDialect.java | 2 +- .../admin/database/v1/DatabaseOrBuilder.java | 2 +- .../admin/database/v1/DatabaseRole.java | 2 +- .../database/v1/DatabaseRoleOrBuilder.java | 2 +- .../database/v1/DdlStatementActionInfo.java | 2 +- .../v1/DdlStatementActionInfoOrBuilder.java | 2 +- .../database/v1/DeleteBackupRequest.java | 2 +- .../v1/DeleteBackupRequestOrBuilder.java | 2 +- .../database/v1/DropDatabaseRequest.java | 2 +- .../v1/DropDatabaseRequestOrBuilder.java | 2 +- .../admin/database/v1/EncryptionConfig.java | 2 +- .../v1/EncryptionConfigOrBuilder.java | 2 +- .../admin/database/v1/EncryptionInfo.java | 2 +- .../database/v1/EncryptionInfoOrBuilder.java | 2 +- .../admin/database/v1/GetBackupRequest.java | 2 +- .../v1/GetBackupRequestOrBuilder.java | 2 +- .../database/v1/GetDatabaseDdlRequest.java | 2 +- .../v1/GetDatabaseDdlRequestOrBuilder.java | 2 +- .../database/v1/GetDatabaseDdlResponse.java | 114 +++- .../v1/GetDatabaseDdlResponseOrBuilder.java | 19 +- .../admin/database/v1/GetDatabaseRequest.java | 2 +- .../v1/GetDatabaseRequestOrBuilder.java | 2 +- .../v1/ListBackupOperationsRequest.java | 2 +- .../ListBackupOperationsRequestOrBuilder.java | 2 +- .../v1/ListBackupOperationsResponse.java | 2 +- ...ListBackupOperationsResponseOrBuilder.java | 2 +- .../admin/database/v1/ListBackupsRequest.java | 2 +- .../v1/ListBackupsRequestOrBuilder.java | 2 +- .../database/v1/ListBackupsResponse.java | 2 +- .../v1/ListBackupsResponseOrBuilder.java | 2 +- .../v1/ListDatabaseOperationsRequest.java | 2 +- ...istDatabaseOperationsRequestOrBuilder.java | 2 +- .../v1/ListDatabaseOperationsResponse.java | 2 +- ...stDatabaseOperationsResponseOrBuilder.java | 2 +- .../database/v1/ListDatabaseRolesRequest.java | 2 +- .../v1/ListDatabaseRolesRequestOrBuilder.java | 2 +- .../v1/ListDatabaseRolesResponse.java | 2 +- .../ListDatabaseRolesResponseOrBuilder.java | 2 +- .../database/v1/ListDatabasesRequest.java | 2 +- .../v1/ListDatabasesRequestOrBuilder.java | 2 +- .../database/v1/ListDatabasesResponse.java | 2 +- .../v1/ListDatabasesResponseOrBuilder.java | 2 +- .../admin/database/v1/OperationProgress.java | 2 +- .../v1/OperationProgressOrBuilder.java | 2 +- .../v1/OptimizeRestoredDatabaseMetadata.java | 2 +- ...mizeRestoredDatabaseMetadataOrBuilder.java | 2 +- .../v1/RestoreDatabaseEncryptionConfig.java | 2 +- ...toreDatabaseEncryptionConfigOrBuilder.java | 2 +- .../database/v1/RestoreDatabaseMetadata.java | 2 +- .../v1/RestoreDatabaseMetadataOrBuilder.java | 2 +- .../database/v1/RestoreDatabaseRequest.java | 2 +- .../v1/RestoreDatabaseRequestOrBuilder.java | 2 +- .../admin/database/v1/RestoreInfo.java | 2 +- .../database/v1/RestoreInfoOrBuilder.java | 2 +- .../admin/database/v1/RestoreSourceType.java | 2 +- .../v1/SpannerDatabaseAdminProto.java | 440 ++++++++-------- .../database/v1/UpdateBackupRequest.java | 2 +- .../v1/UpdateBackupRequestOrBuilder.java | 2 +- .../v1/UpdateDatabaseDdlMetadata.java | 2 +- .../UpdateDatabaseDdlMetadataOrBuilder.java | 2 +- .../database/v1/UpdateDatabaseDdlRequest.java | 150 +++++- .../v1/UpdateDatabaseDdlRequestOrBuilder.java | 28 +- .../database/v1/UpdateDatabaseMetadata.java | 2 +- .../v1/UpdateDatabaseMetadataOrBuilder.java | 2 +- .../database/v1/UpdateDatabaseRequest.java | 2 +- .../v1/UpdateDatabaseRequestOrBuilder.java | 2 +- .../database/v1/spanner_database_admin.proto | 40 ++ .../admin/instance/v1/AutoscalingConfig.java | 2 +- .../v1/AutoscalingConfigOrBuilder.java | 2 +- .../admin/instance/v1/CommonProto.java | 2 +- .../v1/CreateInstanceConfigMetadata.java | 2 +- ...CreateInstanceConfigMetadataOrBuilder.java | 2 +- .../v1/CreateInstanceConfigRequest.java | 2 +- .../CreateInstanceConfigRequestOrBuilder.java | 2 +- .../instance/v1/CreateInstanceMetadata.java | 2 +- .../v1/CreateInstanceMetadataOrBuilder.java | 2 +- .../instance/v1/CreateInstanceRequest.java | 2 +- .../v1/CreateInstanceRequestOrBuilder.java | 2 +- .../v1/DeleteInstanceConfigRequest.java | 2 +- .../DeleteInstanceConfigRequestOrBuilder.java | 2 +- .../instance/v1/DeleteInstanceRequest.java | 2 +- .../v1/DeleteInstanceRequestOrBuilder.java | 2 +- .../instance/v1/GetInstanceConfigRequest.java | 2 +- .../v1/GetInstanceConfigRequestOrBuilder.java | 2 +- .../admin/instance/v1/GetInstanceRequest.java | 2 +- .../v1/GetInstanceRequestOrBuilder.java | 2 +- .../spanner/admin/instance/v1/Instance.java | 2 +- .../admin/instance/v1/InstanceConfig.java | 2 +- .../instance/v1/InstanceConfigOrBuilder.java | 2 +- .../admin/instance/v1/InstanceOrBuilder.java | 2 +- .../ListInstanceConfigOperationsRequest.java | 2 +- ...tanceConfigOperationsRequestOrBuilder.java | 2 +- .../ListInstanceConfigOperationsResponse.java | 2 +- ...anceConfigOperationsResponseOrBuilder.java | 2 +- .../v1/ListInstanceConfigsRequest.java | 2 +- .../ListInstanceConfigsRequestOrBuilder.java | 2 +- .../v1/ListInstanceConfigsResponse.java | 2 +- .../ListInstanceConfigsResponseOrBuilder.java | 2 +- .../instance/v1/ListInstancesRequest.java | 2 +- .../v1/ListInstancesRequestOrBuilder.java | 2 +- .../instance/v1/ListInstancesResponse.java | 2 +- .../v1/ListInstancesResponseOrBuilder.java | 2 +- .../admin/instance/v1/OperationProgress.java | 2 +- .../v1/OperationProgressOrBuilder.java | 2 +- .../admin/instance/v1/ReplicaInfo.java | 2 +- .../instance/v1/ReplicaInfoOrBuilder.java | 2 +- .../v1/SpannerInstanceAdminProto.java | 2 +- .../v1/UpdateInstanceConfigMetadata.java | 2 +- ...UpdateInstanceConfigMetadataOrBuilder.java | 2 +- .../v1/UpdateInstanceConfigRequest.java | 2 +- .../UpdateInstanceConfigRequestOrBuilder.java | 2 +- .../instance/v1/UpdateInstanceMetadata.java | 2 +- .../v1/UpdateInstanceMetadataOrBuilder.java | 2 +- .../instance/v1/UpdateInstanceRequest.java | 2 +- .../v1/UpdateInstanceRequestOrBuilder.java | 2 +- .../spanner/executor/v1/AdminAction.java | 2 +- .../executor/v1/AdminActionOrBuilder.java | 2 +- .../spanner/executor/v1/AdminResult.java | 2 +- .../executor/v1/AdminResultOrBuilder.java | 2 +- .../spanner/executor/v1/BatchDmlAction.java | 2 +- .../executor/v1/BatchDmlActionOrBuilder.java | 2 +- .../spanner/executor/v1/BatchPartition.java | 2 +- .../executor/v1/BatchPartitionOrBuilder.java | 2 +- .../executor/v1/CancelOperationAction.java | 2 +- .../v1/CancelOperationActionOrBuilder.java | 2 +- .../executor/v1/ChangeStreamRecord.java | 2 +- .../v1/ChangeStreamRecordOrBuilder.java | 2 +- .../executor/v1/ChildPartitionsRecord.java | 2 +- .../v1/ChildPartitionsRecordOrBuilder.java | 2 +- .../v1/CloseBatchTransactionAction.java | 2 +- .../CloseBatchTransactionActionOrBuilder.java | 2 +- .../executor/v1/CloudBackupResponse.java | 2 +- .../v1/CloudBackupResponseOrBuilder.java | 2 +- .../executor/v1/CloudDatabaseResponse.java | 2 +- .../v1/CloudDatabaseResponseOrBuilder.java | 2 +- .../executor/v1/CloudExecutorProto.java | 2 +- .../v1/CloudInstanceConfigResponse.java | 2 +- .../CloudInstanceConfigResponseOrBuilder.java | 2 +- .../executor/v1/CloudInstanceResponse.java | 2 +- .../v1/CloudInstanceResponseOrBuilder.java | 2 +- .../spanner/executor/v1/ColumnMetadata.java | 2 +- .../executor/v1/ColumnMetadataOrBuilder.java | 2 +- .../spanner/executor/v1/Concurrency.java | 2 +- .../executor/v1/ConcurrencyOrBuilder.java | 2 +- .../executor/v1/CopyCloudBackupAction.java | 2 +- .../v1/CopyCloudBackupActionOrBuilder.java | 2 +- .../executor/v1/CreateCloudBackupAction.java | 2 +- .../v1/CreateCloudBackupActionOrBuilder.java | 2 +- .../v1/CreateCloudDatabaseAction.java | 2 +- .../CreateCloudDatabaseActionOrBuilder.java | 2 +- .../v1/CreateCloudInstanceAction.java | 2 +- .../CreateCloudInstanceActionOrBuilder.java | 2 +- .../v1/CreateUserInstanceConfigAction.java | 2 +- ...eateUserInstanceConfigActionOrBuilder.java | 2 +- .../spanner/executor/v1/DataChangeRecord.java | 2 +- .../v1/DataChangeRecordOrBuilder.java | 2 +- .../executor/v1/DeleteCloudBackupAction.java | 2 +- .../v1/DeleteCloudBackupActionOrBuilder.java | 2 +- .../v1/DeleteCloudInstanceAction.java | 2 +- .../DeleteCloudInstanceActionOrBuilder.java | 2 +- .../v1/DeleteUserInstanceConfigAction.java | 2 +- ...leteUserInstanceConfigActionOrBuilder.java | 2 +- .../google/spanner/executor/v1/DmlAction.java | 2 +- .../executor/v1/DmlActionOrBuilder.java | 2 +- .../executor/v1/DropCloudDatabaseAction.java | 2 +- .../v1/DropCloudDatabaseActionOrBuilder.java | 2 +- .../executor/v1/ExecuteChangeStreamQuery.java | 2 +- .../v1/ExecuteChangeStreamQueryOrBuilder.java | 2 +- .../executor/v1/ExecutePartitionAction.java | 2 +- .../v1/ExecutePartitionActionOrBuilder.java | 2 +- .../executor/v1/FinishTransactionAction.java | 2 +- .../v1/FinishTransactionActionOrBuilder.java | 2 +- .../GenerateDbPartitionsForQueryAction.java | 2 +- ...teDbPartitionsForQueryActionOrBuilder.java | 2 +- .../v1/GenerateDbPartitionsForReadAction.java | 2 +- ...ateDbPartitionsForReadActionOrBuilder.java | 2 +- .../executor/v1/GetCloudBackupAction.java | 2 +- .../v1/GetCloudBackupActionOrBuilder.java | 2 +- .../executor/v1/GetCloudDatabaseAction.java | 2 +- .../v1/GetCloudDatabaseActionOrBuilder.java | 2 +- .../executor/v1/GetCloudInstanceAction.java | 2 +- .../v1/GetCloudInstanceActionOrBuilder.java | 2 +- .../v1/GetCloudInstanceConfigAction.java | 2 +- ...GetCloudInstanceConfigActionOrBuilder.java | 2 +- .../executor/v1/GetOperationAction.java | 2 +- .../v1/GetOperationActionOrBuilder.java | 2 +- .../spanner/executor/v1/HeartbeatRecord.java | 2 +- .../executor/v1/HeartbeatRecordOrBuilder.java | 2 +- .../google/spanner/executor/v1/KeyRange.java | 2 +- .../executor/v1/KeyRangeOrBuilder.java | 2 +- .../google/spanner/executor/v1/KeySet.java | 2 +- .../spanner/executor/v1/KeySetOrBuilder.java | 2 +- .../v1/ListCloudBackupOperationsAction.java | 2 +- ...tCloudBackupOperationsActionOrBuilder.java | 2 +- .../executor/v1/ListCloudBackupsAction.java | 2 +- .../v1/ListCloudBackupsActionOrBuilder.java | 2 +- .../v1/ListCloudDatabaseOperationsAction.java | 2 +- ...loudDatabaseOperationsActionOrBuilder.java | 2 +- .../executor/v1/ListCloudDatabasesAction.java | 2 +- .../v1/ListCloudDatabasesActionOrBuilder.java | 2 +- .../v1/ListCloudInstanceConfigsAction.java | 2 +- ...stCloudInstanceConfigsActionOrBuilder.java | 2 +- .../executor/v1/ListCloudInstancesAction.java | 2 +- .../v1/ListCloudInstancesActionOrBuilder.java | 2 +- .../spanner/executor/v1/MutationAction.java | 2 +- .../executor/v1/MutationActionOrBuilder.java | 2 +- .../executor/v1/OperationResponse.java | 2 +- .../v1/OperationResponseOrBuilder.java | 2 +- .../executor/v1/PartitionedUpdateAction.java | 2 +- .../v1/PartitionedUpdateActionOrBuilder.java | 2 +- .../spanner/executor/v1/QueryAction.java | 2 +- .../executor/v1/QueryActionOrBuilder.java | 2 +- .../spanner/executor/v1/QueryResult.java | 2 +- .../executor/v1/QueryResultOrBuilder.java | 2 +- .../spanner/executor/v1/ReadAction.java | 2 +- .../executor/v1/ReadActionOrBuilder.java | 2 +- .../spanner/executor/v1/ReadResult.java | 2 +- .../executor/v1/ReadResultOrBuilder.java | 2 +- .../v1/ReconfigureCloudDatabaseAction.java | 2 +- ...configureCloudDatabaseActionOrBuilder.java | 2 +- .../v1/RestoreCloudDatabaseAction.java | 2 +- .../RestoreCloudDatabaseActionOrBuilder.java | 2 +- .../spanner/executor/v1/SpannerAction.java | 2 +- .../executor/v1/SpannerActionOrBuilder.java | 2 +- .../executor/v1/SpannerActionOutcome.java | 2 +- .../v1/SpannerActionOutcomeOrBuilder.java | 2 +- .../v1/SpannerAsyncActionRequest.java | 2 +- .../SpannerAsyncActionRequestOrBuilder.java | 2 +- .../v1/SpannerAsyncActionResponse.java | 2 +- .../SpannerAsyncActionResponseOrBuilder.java | 2 +- .../v1/StartBatchTransactionAction.java | 2 +- .../StartBatchTransactionActionOrBuilder.java | 2 +- .../executor/v1/StartTransactionAction.java | 2 +- .../v1/StartTransactionActionOrBuilder.java | 2 +- .../spanner/executor/v1/TableMetadata.java | 2 +- .../executor/v1/TableMetadataOrBuilder.java | 2 +- .../v1/TransactionExecutionOptions.java | 2 +- .../TransactionExecutionOptionsOrBuilder.java | 2 +- .../executor/v1/UpdateCloudBackupAction.java | 2 +- .../v1/UpdateCloudBackupActionOrBuilder.java | 2 +- .../v1/UpdateCloudDatabaseAction.java | 2 +- .../UpdateCloudDatabaseActionOrBuilder.java | 2 +- .../v1/UpdateCloudDatabaseDdlAction.java | 2 +- ...UpdateCloudDatabaseDdlActionOrBuilder.java | 2 +- .../v1/UpdateCloudInstanceAction.java | 2 +- .../UpdateCloudInstanceActionOrBuilder.java | 2 +- .../v1/UpdateUserInstanceConfigAction.java | 2 +- ...dateUserInstanceConfigActionOrBuilder.java | 2 +- .../com/google/spanner/executor/v1/Value.java | 2 +- .../google/spanner/executor/v1/ValueList.java | 2 +- .../executor/v1/ValueListOrBuilder.java | 2 +- .../spanner/executor/v1/ValueOrBuilder.java | 2 +- .../executor/v1/WriteMutationsAction.java | 2 +- .../v1/WriteMutationsActionOrBuilder.java | 2 +- .../v1/BatchCreateSessionsRequest.java | 2 +- .../BatchCreateSessionsRequestOrBuilder.java | 2 +- .../v1/BatchCreateSessionsResponse.java | 2 +- .../BatchCreateSessionsResponseOrBuilder.java | 2 +- .../google/spanner/v1/BatchWriteRequest.java | 2 +- .../v1/BatchWriteRequestOrBuilder.java | 2 +- .../google/spanner/v1/BatchWriteResponse.java | 2 +- .../v1/BatchWriteResponseOrBuilder.java | 2 +- .../spanner/v1/BeginTransactionRequest.java | 2 +- .../v1/BeginTransactionRequestOrBuilder.java | 2 +- .../com/google/spanner/v1/CommitRequest.java | 352 ++++++++++++- .../spanner/v1/CommitRequestOrBuilder.java | 52 +- .../com/google/spanner/v1/CommitResponse.java | 2 +- .../spanner/v1/CommitResponseOrBuilder.java | 2 +- .../spanner/v1/CommitResponseProto.java | 2 +- .../spanner/v1/CreateSessionRequest.java | 2 +- .../v1/CreateSessionRequestOrBuilder.java | 2 +- .../spanner/v1/DeleteSessionRequest.java | 2 +- .../v1/DeleteSessionRequestOrBuilder.java | 2 +- .../spanner/v1/DirectedReadOptions.java | 2 +- .../v1/DirectedReadOptionsOrBuilder.java | 2 +- .../spanner/v1/ExecuteBatchDmlRequest.java | 2 +- .../v1/ExecuteBatchDmlRequestOrBuilder.java | 2 +- .../spanner/v1/ExecuteBatchDmlResponse.java | 2 +- .../v1/ExecuteBatchDmlResponseOrBuilder.java | 2 +- .../google/spanner/v1/ExecuteSqlRequest.java | 2 +- .../v1/ExecuteSqlRequestOrBuilder.java | 2 +- .../google/spanner/v1/GetSessionRequest.java | 2 +- .../v1/GetSessionRequestOrBuilder.java | 2 +- .../java/com/google/spanner/v1/KeyRange.java | 2 +- .../google/spanner/v1/KeyRangeOrBuilder.java | 2 +- .../java/com/google/spanner/v1/KeySet.java | 2 +- .../google/spanner/v1/KeySetOrBuilder.java | 2 +- .../java/com/google/spanner/v1/KeysProto.java | 2 +- .../spanner/v1/ListSessionsRequest.java | 2 +- .../v1/ListSessionsRequestOrBuilder.java | 2 +- .../spanner/v1/ListSessionsResponse.java | 2 +- .../v1/ListSessionsResponseOrBuilder.java | 2 +- .../java/com/google/spanner/v1/Mutation.java | 2 +- .../google/spanner/v1/MutationOrBuilder.java | 2 +- .../com/google/spanner/v1/MutationProto.java | 2 +- .../google/spanner/v1/PartialResultSet.java | 2 +- .../spanner/v1/PartialResultSetOrBuilder.java | 2 +- .../java/com/google/spanner/v1/Partition.java | 2 +- .../google/spanner/v1/PartitionOptions.java | 2 +- .../spanner/v1/PartitionOptionsOrBuilder.java | 2 +- .../google/spanner/v1/PartitionOrBuilder.java | 2 +- .../spanner/v1/PartitionQueryRequest.java | 2 +- .../v1/PartitionQueryRequestOrBuilder.java | 2 +- .../spanner/v1/PartitionReadRequest.java | 2 +- .../v1/PartitionReadRequestOrBuilder.java | 2 +- .../google/spanner/v1/PartitionResponse.java | 2 +- .../v1/PartitionResponseOrBuilder.java | 2 +- .../java/com/google/spanner/v1/PlanNode.java | 2 +- .../google/spanner/v1/PlanNodeOrBuilder.java | 2 +- .../java/com/google/spanner/v1/QueryPlan.java | 2 +- .../google/spanner/v1/QueryPlanOrBuilder.java | 2 +- .../com/google/spanner/v1/QueryPlanProto.java | 2 +- .../com/google/spanner/v1/ReadRequest.java | 2 +- .../spanner/v1/ReadRequestOrBuilder.java | 2 +- .../com/google/spanner/v1/RequestOptions.java | 2 +- .../spanner/v1/RequestOptionsOrBuilder.java | 2 +- .../java/com/google/spanner/v1/ResultSet.java | 2 +- .../google/spanner/v1/ResultSetMetadata.java | 2 +- .../v1/ResultSetMetadataOrBuilder.java | 2 +- .../google/spanner/v1/ResultSetOrBuilder.java | 2 +- .../com/google/spanner/v1/ResultSetProto.java | 2 +- .../com/google/spanner/v1/ResultSetStats.java | 2 +- .../spanner/v1/ResultSetStatsOrBuilder.java | 2 +- .../google/spanner/v1/RollbackRequest.java | 2 +- .../spanner/v1/RollbackRequestOrBuilder.java | 2 +- .../java/com/google/spanner/v1/Session.java | 2 +- .../google/spanner/v1/SessionOrBuilder.java | 2 +- .../com/google/spanner/v1/SpannerProto.java | 489 +++++++++--------- .../com/google/spanner/v1/StructType.java | 2 +- .../spanner/v1/StructTypeOrBuilder.java | 2 +- .../com/google/spanner/v1/Transaction.java | 2 +- .../google/spanner/v1/TransactionOptions.java | 2 +- .../v1/TransactionOptionsOrBuilder.java | 2 +- .../spanner/v1/TransactionOrBuilder.java | 2 +- .../google/spanner/v1/TransactionProto.java | 2 +- .../spanner/v1/TransactionSelector.java | 2 +- .../v1/TransactionSelectorOrBuilder.java | 2 +- .../main/java/com/google/spanner/v1/Type.java | 212 +++++++- .../google/spanner/v1/TypeAnnotationCode.java | 2 +- .../java/com/google/spanner/v1/TypeCode.java | 48 +- .../com/google/spanner/v1/TypeOrBuilder.java | 35 +- .../java/com/google/spanner/v1/TypeProto.java | 39 +- .../proto/google/spanner/v1/spanner.proto | 9 + .../main/proto/google/spanner/v1/type.proto | 14 + 381 files changed, 3230 insertions(+), 913 deletions(-) diff --git a/google-cloud-spanner-executor/src/main/java/com/google/cloud/spanner/executor/v1/SpannerExecutorProxyClient.java b/google-cloud-spanner-executor/src/main/java/com/google/cloud/spanner/executor/v1/SpannerExecutorProxyClient.java index 2bbfdbc89dd..3ca0a53a94f 100644 --- a/google-cloud-spanner-executor/src/main/java/com/google/cloud/spanner/executor/v1/SpannerExecutorProxyClient.java +++ b/google-cloud-spanner-executor/src/main/java/com/google/cloud/spanner/executor/v1/SpannerExecutorProxyClient.java @@ -59,19 +59,26 @@ * resources such as threads. In the example above, try-with-resources is used, which automatically * calls close(). * - *

The surface of this class includes several types of Java methods for each of the API's - * methods: - * - *

    - *
  1. A "flattened" method. With this type of method, the fields of the request type have been - * converted into function parameters. It may be the case that not all fields are available as - * parameters, and not every API method will have a flattened method entry point. - *
  2. A "request object" method. This type of method only takes one parameter, a request object, - * which must be constructed before the call. Not every API method will have a request object - * method. - *
  3. A "callable" method. This type of method takes no parameters and returns an immutable API - * callable object, which can be used to initiate calls to the service. - *
+ * + * + * + * + * + * + * + * + * + * + * + * + *
Methods
MethodDescriptionMethod Variants

ExecuteActionAsync

ExecuteActionAsync is a streaming call that starts executing a new Spanner action. + *

For each request, the server will reply with one or more responses, but only the last response will contain status in the outcome. + *

Responses can be matched to requests by action_id. It is allowed to have multiple actions in flight--in that case, actions are be executed in parallel.

+ *

Callable method variants take no parameters and return an immutable API callable object, which can be used to initiate calls to the service.

+ *
    + *
  • executeActionAsyncCallable() + *

+ *
* *

See the individual methods for example code. * diff --git a/google-cloud-spanner-executor/src/main/java/com/google/cloud/spanner/executor/v1/stub/SpannerExecutorProxyStubSettings.java b/google-cloud-spanner-executor/src/main/java/com/google/cloud/spanner/executor/v1/stub/SpannerExecutorProxyStubSettings.java index 126106a5b69..9ed12c6b257 100644 --- a/google-cloud-spanner-executor/src/main/java/com/google/cloud/spanner/executor/v1/stub/SpannerExecutorProxyStubSettings.java +++ b/google-cloud-spanner-executor/src/main/java/com/google/cloud/spanner/executor/v1/stub/SpannerExecutorProxyStubSettings.java @@ -108,6 +108,21 @@ public SpannerExecutorProxyStub createStub() throws IOException { "Transport not supported: %s", getTransportChannelProvider().getTransportName())); } + /** Returns the endpoint set by the user or the the service's default endpoint. */ + @Override + public String getEndpoint() { + if (super.getEndpoint() != null) { + return super.getEndpoint(); + } + return getDefaultEndpoint(); + } + + /** Returns the default service name. */ + @Override + public String getServiceName() { + return "spanner-cloud-executor"; + } + /** Returns a builder for the default ExecutorProvider for this service. */ public static InstantiatingExecutorProvider.Builder defaultExecutorProviderBuilder() { return InstantiatingExecutorProvider.newBuilder(); @@ -229,7 +244,6 @@ private static Builder createDefault() { builder.setTransportChannelProvider(defaultTransportChannelProvider()); builder.setCredentialsProvider(defaultCredentialsProviderBuilder().build()); builder.setInternalHeaderProvider(defaultApiClientHeaderProviderBuilder().build()); - builder.setEndpoint(getDefaultEndpoint()); builder.setMtlsEndpoint(getDefaultMtlsEndpoint()); builder.setSwitchToMtlsEndpointAllowed(true); @@ -261,6 +275,15 @@ public Builder applyToAllUnaryMethods( return executeActionAsyncSettings; } + /** Returns the endpoint set by the user or the the service's default endpoint. */ + @Override + public String getEndpoint() { + if (super.getEndpoint() != null) { + return super.getEndpoint(); + } + return getDefaultEndpoint(); + } + @Override public SpannerExecutorProxyStubSettings build() throws IOException { return new SpannerExecutorProxyStubSettings(this); diff --git a/google-cloud-spanner/src/main/java/com/google/cloud/spanner/admin/database/v1/DatabaseAdminClient.java b/google-cloud-spanner/src/main/java/com/google/cloud/spanner/admin/database/v1/DatabaseAdminClient.java index 2cc03907b7b..b898bceedf5 100644 --- a/google-cloud-spanner/src/main/java/com/google/cloud/spanner/admin/database/v1/DatabaseAdminClient.java +++ b/google-cloud-spanner/src/main/java/com/google/cloud/spanner/admin/database/v1/DatabaseAdminClient.java @@ -107,19 +107,415 @@ *

Note: close() needs to be called on the DatabaseAdminClient object to clean up resources such * as threads. In the example above, try-with-resources is used, which automatically calls close(). * - *

The surface of this class includes several types of Java methods for each of the API's - * methods: - * - *

    - *
  1. A "flattened" method. With this type of method, the fields of the request type have been - * converted into function parameters. It may be the case that not all fields are available as - * parameters, and not every API method will have a flattened method entry point. - *
  2. A "request object" method. This type of method only takes one parameter, a request object, - * which must be constructed before the call. Not every API method will have a request object - * method. - *
  3. A "callable" method. This type of method takes no parameters and returns an immutable API - * callable object, which can be used to initiate calls to the service. - *
+ * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + *
Methods
MethodDescriptionMethod Variants

ListDatabases

Lists Cloud Spanner databases.

+ *

Request object method variants only take one parameter, a request object, which must be constructed before the call.

+ *
    + *
  • listDatabases(ListDatabasesRequest request) + *

+ *

"Flattened" method variants have converted the fields of the request object into function parameters to enable multiple ways to call the same method.

+ *
    + *
  • listDatabases(InstanceName parent) + *

  • listDatabases(String parent) + *

+ *

Callable method variants take no parameters and return an immutable API callable object, which can be used to initiate calls to the service.

+ *
    + *
  • listDatabasesPagedCallable() + *

  • listDatabasesCallable() + *

+ *

CreateDatabase

Creates a new Cloud Spanner database and starts to prepare it for serving. The returned [long-running operation][google.longrunning.Operation] will have a name of the format `<database_name>/operations/<operation_id>` and can be used to track preparation of the database. The [metadata][google.longrunning.Operation.metadata] field type is [CreateDatabaseMetadata][google.spanner.admin.database.v1.CreateDatabaseMetadata]. The [response][google.longrunning.Operation.response] field type is [Database][google.spanner.admin.database.v1.Database], if successful.

+ *

Request object method variants only take one parameter, a request object, which must be constructed before the call.

+ *
    + *
  • createDatabaseAsync(CreateDatabaseRequest request) + *

+ *

Methods that return long-running operations have "Async" method variants that return `OperationFuture`, which is used to track polling of the service.

+ *
    + *
  • createDatabaseAsync(InstanceName parent, String createStatement) + *

  • createDatabaseAsync(String parent, String createStatement) + *

+ *

Callable method variants take no parameters and return an immutable API callable object, which can be used to initiate calls to the service.

+ *
    + *
  • createDatabaseOperationCallable() + *

  • createDatabaseCallable() + *

+ *

GetDatabase

Gets the state of a Cloud Spanner database.

+ *

Request object method variants only take one parameter, a request object, which must be constructed before the call.

+ *
    + *
  • getDatabase(GetDatabaseRequest request) + *

+ *

"Flattened" method variants have converted the fields of the request object into function parameters to enable multiple ways to call the same method.

+ *
    + *
  • getDatabase(DatabaseName name) + *

  • getDatabase(String name) + *

+ *

Callable method variants take no parameters and return an immutable API callable object, which can be used to initiate calls to the service.

+ *
    + *
  • getDatabaseCallable() + *

+ *

UpdateDatabase

Updates a Cloud Spanner database. The returned [long-running operation][google.longrunning.Operation] can be used to track the progress of updating the database. If the named database does not exist, returns `NOT_FOUND`. + *

While the operation is pending: + *

* The database's [reconciling][google.spanner.admin.database.v1.Database.reconciling] field is set to true. * Cancelling the operation is best-effort. If the cancellation succeeds, the operation metadata's [cancel_time][google.spanner.admin.database.v1.UpdateDatabaseMetadata.cancel_time] is set, the updates are reverted, and the operation terminates with a `CANCELLED` status. * New UpdateDatabase requests will return a `FAILED_PRECONDITION` error until the pending operation is done (returns successfully or with error). * Reading the database via the API continues to give the pre-request values. + *

Upon completion of the returned operation: + *

* The new values are in effect and readable via the API. * The database's [reconciling][google.spanner.admin.database.v1.Database.reconciling] field becomes false. + *

The returned [long-running operation][google.longrunning.Operation] will have a name of the format `projects/<project>/instances/<instance>/databases/<database>/operations/<operation_id>` and can be used to track the database modification. The [metadata][google.longrunning.Operation.metadata] field type is [UpdateDatabaseMetadata][google.spanner.admin.database.v1.UpdateDatabaseMetadata]. The [response][google.longrunning.Operation.response] field type is [Database][google.spanner.admin.database.v1.Database], if successful.

+ *

Request object method variants only take one parameter, a request object, which must be constructed before the call.

+ *
    + *
  • updateDatabaseAsync(UpdateDatabaseRequest request) + *

+ *

Methods that return long-running operations have "Async" method variants that return `OperationFuture`, which is used to track polling of the service.

+ *
    + *
  • updateDatabaseAsync(Database database, FieldMask updateMask) + *

+ *

Callable method variants take no parameters and return an immutable API callable object, which can be used to initiate calls to the service.

+ *
    + *
  • updateDatabaseOperationCallable() + *

  • updateDatabaseCallable() + *

+ *

UpdateDatabaseDdl

Updates the schema of a Cloud Spanner database by creating/altering/dropping tables, columns, indexes, etc. The returned [long-running operation][google.longrunning.Operation] will have a name of the format `<database_name>/operations/<operation_id>` and can be used to track execution of the schema change(s). The [metadata][google.longrunning.Operation.metadata] field type is [UpdateDatabaseDdlMetadata][google.spanner.admin.database.v1.UpdateDatabaseDdlMetadata]. The operation has no response.

+ *

Request object method variants only take one parameter, a request object, which must be constructed before the call.

+ *
    + *
  • updateDatabaseDdlAsync(UpdateDatabaseDdlRequest request) + *

+ *

Methods that return long-running operations have "Async" method variants that return `OperationFuture`, which is used to track polling of the service.

+ *
    + *
  • updateDatabaseDdlAsync(DatabaseName database, List<String> statements) + *

  • updateDatabaseDdlAsync(String database, List<String> statements) + *

+ *

Callable method variants take no parameters and return an immutable API callable object, which can be used to initiate calls to the service.

+ *
    + *
  • updateDatabaseDdlOperationCallable() + *

  • updateDatabaseDdlCallable() + *

+ *

DropDatabase

Drops (aka deletes) a Cloud Spanner database. Completed backups for the database will be retained according to their `expire_time`. Note: Cloud Spanner might continue to accept requests for a few seconds after the database has been deleted.

+ *

Request object method variants only take one parameter, a request object, which must be constructed before the call.

+ *
    + *
  • dropDatabase(DropDatabaseRequest request) + *

+ *

"Flattened" method variants have converted the fields of the request object into function parameters to enable multiple ways to call the same method.

+ *
    + *
  • dropDatabase(DatabaseName database) + *

  • dropDatabase(String database) + *

+ *

Callable method variants take no parameters and return an immutable API callable object, which can be used to initiate calls to the service.

+ *
    + *
  • dropDatabaseCallable() + *

+ *

GetDatabaseDdl

Returns the schema of a Cloud Spanner database as a list of formatted DDL statements. This method does not show pending schema updates, those may be queried using the [Operations][google.longrunning.Operations] API.

+ *

Request object method variants only take one parameter, a request object, which must be constructed before the call.

+ *
    + *
  • getDatabaseDdl(GetDatabaseDdlRequest request) + *

+ *

"Flattened" method variants have converted the fields of the request object into function parameters to enable multiple ways to call the same method.

+ *
    + *
  • getDatabaseDdl(DatabaseName database) + *

  • getDatabaseDdl(String database) + *

+ *

Callable method variants take no parameters and return an immutable API callable object, which can be used to initiate calls to the service.

+ *
    + *
  • getDatabaseDdlCallable() + *

+ *

SetIamPolicy

Sets the access control policy on a database or backup resource. Replaces any existing policy. + *

Authorization requires `spanner.databases.setIamPolicy` permission on [resource][google.iam.v1.SetIamPolicyRequest.resource]. For backups, authorization requires `spanner.backups.setIamPolicy` permission on [resource][google.iam.v1.SetIamPolicyRequest.resource].

+ *

Request object method variants only take one parameter, a request object, which must be constructed before the call.

+ *
    + *
  • setIamPolicy(SetIamPolicyRequest request) + *

+ *

"Flattened" method variants have converted the fields of the request object into function parameters to enable multiple ways to call the same method.

+ *
    + *
  • setIamPolicy(ResourceName resource, Policy policy) + *

  • setIamPolicy(String resource, Policy policy) + *

+ *

Callable method variants take no parameters and return an immutable API callable object, which can be used to initiate calls to the service.

+ *
    + *
  • setIamPolicyCallable() + *

+ *

GetIamPolicy

Gets the access control policy for a database or backup resource. Returns an empty policy if a database or backup exists but does not have a policy set. + *

Authorization requires `spanner.databases.getIamPolicy` permission on [resource][google.iam.v1.GetIamPolicyRequest.resource]. For backups, authorization requires `spanner.backups.getIamPolicy` permission on [resource][google.iam.v1.GetIamPolicyRequest.resource].

+ *

Request object method variants only take one parameter, a request object, which must be constructed before the call.

+ *
    + *
  • getIamPolicy(GetIamPolicyRequest request) + *

+ *

"Flattened" method variants have converted the fields of the request object into function parameters to enable multiple ways to call the same method.

+ *
    + *
  • getIamPolicy(ResourceName resource) + *

  • getIamPolicy(String resource) + *

+ *

Callable method variants take no parameters and return an immutable API callable object, which can be used to initiate calls to the service.

+ *
    + *
  • getIamPolicyCallable() + *

+ *

TestIamPermissions

Returns permissions that the caller has on the specified database or backup resource. + *

Attempting this RPC on a non-existent Cloud Spanner database will result in a NOT_FOUND error if the user has `spanner.databases.list` permission on the containing Cloud Spanner instance. Otherwise returns an empty set of permissions. Calling this method on a backup that does not exist will result in a NOT_FOUND error if the user has `spanner.backups.list` permission on the containing instance.

+ *

Request object method variants only take one parameter, a request object, which must be constructed before the call.

+ *
    + *
  • testIamPermissions(TestIamPermissionsRequest request) + *

+ *

"Flattened" method variants have converted the fields of the request object into function parameters to enable multiple ways to call the same method.

+ *
    + *
  • testIamPermissions(ResourceName resource, List<String> permissions) + *

  • testIamPermissions(String resource, List<String> permissions) + *

+ *

Callable method variants take no parameters and return an immutable API callable object, which can be used to initiate calls to the service.

+ *
    + *
  • testIamPermissionsCallable() + *

+ *

CreateBackup

Starts creating a new Cloud Spanner Backup. The returned backup [long-running operation][google.longrunning.Operation] will have a name of the format `projects/<project>/instances/<instance>/backups/<backup>/operations/<operation_id>` and can be used to track creation of the backup. The [metadata][google.longrunning.Operation.metadata] field type is [CreateBackupMetadata][google.spanner.admin.database.v1.CreateBackupMetadata]. The [response][google.longrunning.Operation.response] field type is [Backup][google.spanner.admin.database.v1.Backup], if successful. Cancelling the returned operation will stop the creation and delete the backup. There can be only one pending backup creation per database. Backup creation of different databases can run concurrently.

+ *

Request object method variants only take one parameter, a request object, which must be constructed before the call.

+ *
    + *
  • createBackupAsync(CreateBackupRequest request) + *

+ *

Methods that return long-running operations have "Async" method variants that return `OperationFuture`, which is used to track polling of the service.

+ *
    + *
  • createBackupAsync(InstanceName parent, Backup backup, String backupId) + *

  • createBackupAsync(String parent, Backup backup, String backupId) + *

+ *

Callable method variants take no parameters and return an immutable API callable object, which can be used to initiate calls to the service.

+ *
    + *
  • createBackupOperationCallable() + *

  • createBackupCallable() + *

+ *

CopyBackup

Starts copying a Cloud Spanner Backup. The returned backup [long-running operation][google.longrunning.Operation] will have a name of the format `projects/<project>/instances/<instance>/backups/<backup>/operations/<operation_id>` and can be used to track copying of the backup. The operation is associated with the destination backup. The [metadata][google.longrunning.Operation.metadata] field type is [CopyBackupMetadata][google.spanner.admin.database.v1.CopyBackupMetadata]. The [response][google.longrunning.Operation.response] field type is [Backup][google.spanner.admin.database.v1.Backup], if successful. Cancelling the returned operation will stop the copying and delete the backup. Concurrent CopyBackup requests can run on the same source backup.

+ *

Request object method variants only take one parameter, a request object, which must be constructed before the call.

+ *
    + *
  • copyBackupAsync(CopyBackupRequest request) + *

+ *

Methods that return long-running operations have "Async" method variants that return `OperationFuture`, which is used to track polling of the service.

+ *
    + *
  • copyBackupAsync(InstanceName parent, String backupId, BackupName sourceBackup, Timestamp expireTime) + *

  • copyBackupAsync(InstanceName parent, String backupId, String sourceBackup, Timestamp expireTime) + *

  • copyBackupAsync(String parent, String backupId, BackupName sourceBackup, Timestamp expireTime) + *

  • copyBackupAsync(String parent, String backupId, String sourceBackup, Timestamp expireTime) + *

+ *

Callable method variants take no parameters and return an immutable API callable object, which can be used to initiate calls to the service.

+ *
    + *
  • copyBackupOperationCallable() + *

  • copyBackupCallable() + *

+ *

GetBackup

Gets metadata on a pending or completed [Backup][google.spanner.admin.database.v1.Backup].

+ *

Request object method variants only take one parameter, a request object, which must be constructed before the call.

+ *
    + *
  • getBackup(GetBackupRequest request) + *

+ *

"Flattened" method variants have converted the fields of the request object into function parameters to enable multiple ways to call the same method.

+ *
    + *
  • getBackup(BackupName name) + *

  • getBackup(String name) + *

+ *

Callable method variants take no parameters and return an immutable API callable object, which can be used to initiate calls to the service.

+ *
    + *
  • getBackupCallable() + *

+ *

UpdateBackup

Updates a pending or completed [Backup][google.spanner.admin.database.v1.Backup].

+ *

Request object method variants only take one parameter, a request object, which must be constructed before the call.

+ *
    + *
  • updateBackup(UpdateBackupRequest request) + *

+ *

"Flattened" method variants have converted the fields of the request object into function parameters to enable multiple ways to call the same method.

+ *
    + *
  • updateBackup(Backup backup, FieldMask updateMask) + *

+ *

Callable method variants take no parameters and return an immutable API callable object, which can be used to initiate calls to the service.

+ *
    + *
  • updateBackupCallable() + *

+ *

DeleteBackup

Deletes a pending or completed [Backup][google.spanner.admin.database.v1.Backup].

+ *

Request object method variants only take one parameter, a request object, which must be constructed before the call.

+ *
    + *
  • deleteBackup(DeleteBackupRequest request) + *

+ *

"Flattened" method variants have converted the fields of the request object into function parameters to enable multiple ways to call the same method.

+ *
    + *
  • deleteBackup(BackupName name) + *

  • deleteBackup(String name) + *

+ *

Callable method variants take no parameters and return an immutable API callable object, which can be used to initiate calls to the service.

+ *
    + *
  • deleteBackupCallable() + *

+ *

ListBackups

Lists completed and pending backups. Backups returned are ordered by `create_time` in descending order, starting from the most recent `create_time`.

+ *

Request object method variants only take one parameter, a request object, which must be constructed before the call.

+ *
    + *
  • listBackups(ListBackupsRequest request) + *

+ *

"Flattened" method variants have converted the fields of the request object into function parameters to enable multiple ways to call the same method.

+ *
    + *
  • listBackups(InstanceName parent) + *

  • listBackups(String parent) + *

+ *

Callable method variants take no parameters and return an immutable API callable object, which can be used to initiate calls to the service.

+ *
    + *
  • listBackupsPagedCallable() + *

  • listBackupsCallable() + *

+ *

RestoreDatabase

Create a new database by restoring from a completed backup. The new database must be in the same project and in an instance with the same instance configuration as the instance containing the backup. The returned database [long-running operation][google.longrunning.Operation] has a name of the format `projects/<project>/instances/<instance>/databases/<database>/operations/<operation_id>`, and can be used to track the progress of the operation, and to cancel it. The [metadata][google.longrunning.Operation.metadata] field type is [RestoreDatabaseMetadata][google.spanner.admin.database.v1.RestoreDatabaseMetadata]. The [response][google.longrunning.Operation.response] type is [Database][google.spanner.admin.database.v1.Database], if successful. Cancelling the returned operation will stop the restore and delete the database. There can be only one database being restored into an instance at a time. Once the restore operation completes, a new restore operation can be initiated, without waiting for the optimize operation associated with the first restore to complete.

+ *

Request object method variants only take one parameter, a request object, which must be constructed before the call.

+ *
    + *
  • restoreDatabaseAsync(RestoreDatabaseRequest request) + *

+ *

Methods that return long-running operations have "Async" method variants that return `OperationFuture`, which is used to track polling of the service.

+ *
    + *
  • restoreDatabaseAsync(InstanceName parent, String databaseId, BackupName backup) + *

  • restoreDatabaseAsync(InstanceName parent, String databaseId, String backup) + *

  • restoreDatabaseAsync(String parent, String databaseId, BackupName backup) + *

  • restoreDatabaseAsync(String parent, String databaseId, String backup) + *

+ *

Callable method variants take no parameters and return an immutable API callable object, which can be used to initiate calls to the service.

+ *
    + *
  • restoreDatabaseOperationCallable() + *

  • restoreDatabaseCallable() + *

+ *

ListDatabaseOperations

Lists database [longrunning-operations][google.longrunning.Operation]. A database operation has a name of the form `projects/<project>/instances/<instance>/databases/<database>/operations/<operation>`. The long-running operation [metadata][google.longrunning.Operation.metadata] field type `metadata.type_url` describes the type of the metadata. Operations returned include those that have completed/failed/canceled within the last 7 days, and pending operations.

+ *

Request object method variants only take one parameter, a request object, which must be constructed before the call.

+ *
    + *
  • listDatabaseOperations(ListDatabaseOperationsRequest request) + *

+ *

"Flattened" method variants have converted the fields of the request object into function parameters to enable multiple ways to call the same method.

+ *
    + *
  • listDatabaseOperations(InstanceName parent) + *

  • listDatabaseOperations(String parent) + *

+ *

Callable method variants take no parameters and return an immutable API callable object, which can be used to initiate calls to the service.

+ *
    + *
  • listDatabaseOperationsPagedCallable() + *

  • listDatabaseOperationsCallable() + *

+ *

ListBackupOperations

Lists the backup [long-running operations][google.longrunning.Operation] in the given instance. A backup operation has a name of the form `projects/<project>/instances/<instance>/backups/<backup>/operations/<operation>`. The long-running operation [metadata][google.longrunning.Operation.metadata] field type `metadata.type_url` describes the type of the metadata. Operations returned include those that have completed/failed/canceled within the last 7 days, and pending operations. Operations returned are ordered by `operation.metadata.value.progress.start_time` in descending order starting from the most recently started operation.

+ *

Request object method variants only take one parameter, a request object, which must be constructed before the call.

+ *
    + *
  • listBackupOperations(ListBackupOperationsRequest request) + *

+ *

"Flattened" method variants have converted the fields of the request object into function parameters to enable multiple ways to call the same method.

+ *
    + *
  • listBackupOperations(InstanceName parent) + *

  • listBackupOperations(String parent) + *

+ *

Callable method variants take no parameters and return an immutable API callable object, which can be used to initiate calls to the service.

+ *
    + *
  • listBackupOperationsPagedCallable() + *

  • listBackupOperationsCallable() + *

+ *

ListDatabaseRoles

Lists Cloud Spanner database roles.

+ *

Request object method variants only take one parameter, a request object, which must be constructed before the call.

+ *
    + *
  • listDatabaseRoles(ListDatabaseRolesRequest request) + *

+ *

"Flattened" method variants have converted the fields of the request object into function parameters to enable multiple ways to call the same method.

+ *
    + *
  • listDatabaseRoles(DatabaseName parent) + *

  • listDatabaseRoles(String parent) + *

+ *

Callable method variants take no parameters and return an immutable API callable object, which can be used to initiate calls to the service.

+ *
    + *
  • listDatabaseRolesPagedCallable() + *

  • listDatabaseRolesCallable() + *

+ *
* *

See the individual methods for example code. * @@ -527,6 +923,7 @@ public final OperationFuture createDatabaseAsy * .addAllExtraStatements(new ArrayList()) * .setEncryptionConfig(EncryptionConfig.newBuilder().build()) * .setDatabaseDialect(DatabaseDialect.forNumber(0)) + * .setProtoDescriptors(ByteString.EMPTY) * .build(); * Database response = databaseAdminClient.createDatabaseAsync(request).get(); * } @@ -566,6 +963,7 @@ public final OperationFuture createDatabaseAsy * .addAllExtraStatements(new ArrayList()) * .setEncryptionConfig(EncryptionConfig.newBuilder().build()) * .setDatabaseDialect(DatabaseDialect.forNumber(0)) + * .setProtoDescriptors(ByteString.EMPTY) * .build(); * OperationFuture future = * databaseAdminClient.createDatabaseOperationCallable().futureCall(request); @@ -605,6 +1003,7 @@ public final OperationFuture createDatabaseAsy * .addAllExtraStatements(new ArrayList()) * .setEncryptionConfig(EncryptionConfig.newBuilder().build()) * .setDatabaseDialect(DatabaseDialect.forNumber(0)) + * .setProtoDescriptors(ByteString.EMPTY) * .build(); * ApiFuture future = * databaseAdminClient.createDatabaseCallable().futureCall(request); @@ -1058,6 +1457,7 @@ public final OperationFuture updateDatabaseDdl * .setDatabase(DatabaseName.of("[PROJECT]", "[INSTANCE]", "[DATABASE]").toString()) * .addAllStatements(new ArrayList()) * .setOperationId("operationId129704162") + * .setProtoDescriptors(ByteString.EMPTY) * .build(); * databaseAdminClient.updateDatabaseDdlAsync(request).get(); * } @@ -1095,6 +1495,7 @@ public final OperationFuture updateDatabaseDdl * .setDatabase(DatabaseName.of("[PROJECT]", "[INSTANCE]", "[DATABASE]").toString()) * .addAllStatements(new ArrayList()) * .setOperationId("operationId129704162") + * .setProtoDescriptors(ByteString.EMPTY) * .build(); * OperationFuture future = * databaseAdminClient.updateDatabaseDdlOperationCallable().futureCall(request); @@ -1132,6 +1533,7 @@ public final OperationFuture updateDatabaseDdl * .setDatabase(DatabaseName.of("[PROJECT]", "[INSTANCE]", "[DATABASE]").toString()) * .addAllStatements(new ArrayList()) * .setOperationId("operationId129704162") + * .setProtoDescriptors(ByteString.EMPTY) * .build(); * ApiFuture future = * databaseAdminClient.updateDatabaseDdlCallable().futureCall(request); diff --git a/google-cloud-spanner/src/main/java/com/google/cloud/spanner/admin/database/v1/stub/DatabaseAdminStubSettings.java b/google-cloud-spanner/src/main/java/com/google/cloud/spanner/admin/database/v1/stub/DatabaseAdminStubSettings.java index 0697aaf54f5..08ac4062926 100644 --- a/google-cloud-spanner/src/main/java/com/google/cloud/spanner/admin/database/v1/stub/DatabaseAdminStubSettings.java +++ b/google-cloud-spanner/src/main/java/com/google/cloud/spanner/admin/database/v1/stub/DatabaseAdminStubSettings.java @@ -654,6 +654,21 @@ public DatabaseAdminStub createStub() throws IOException { "Transport not supported: %s", getTransportChannelProvider().getTransportName())); } + /** Returns the endpoint set by the user or the the service's default endpoint. */ + @Override + public String getEndpoint() { + if (super.getEndpoint() != null) { + return super.getEndpoint(); + } + return getDefaultEndpoint(); + } + + /** Returns the default service name. */ + @Override + public String getServiceName() { + return "spanner"; + } + /** Returns a builder for the default ExecutorProvider for this service. */ public static InstantiatingExecutorProvider.Builder defaultExecutorProviderBuilder() { return InstantiatingExecutorProvider.newBuilder(); @@ -1022,7 +1037,6 @@ private static Builder createDefault() { builder.setTransportChannelProvider(defaultTransportChannelProvider()); builder.setCredentialsProvider(defaultCredentialsProviderBuilder().build()); builder.setInternalHeaderProvider(defaultApiClientHeaderProviderBuilder().build()); - builder.setEndpoint(getDefaultEndpoint()); builder.setMtlsEndpoint(getDefaultMtlsEndpoint()); builder.setSwitchToMtlsEndpointAllowed(true); @@ -1035,7 +1049,6 @@ private static Builder createHttpJsonDefault() { builder.setTransportChannelProvider(defaultHttpJsonTransportProviderBuilder().build()); builder.setCredentialsProvider(defaultCredentialsProviderBuilder().build()); builder.setInternalHeaderProvider(defaultHttpJsonApiClientHeaderProviderBuilder().build()); - builder.setEndpoint(getDefaultEndpoint()); builder.setMtlsEndpoint(getDefaultMtlsEndpoint()); builder.setSwitchToMtlsEndpointAllowed(true); @@ -1470,6 +1483,15 @@ public UnaryCallSettings.Builder restoreDatab return listDatabaseRolesSettings; } + /** Returns the endpoint set by the user or the the service's default endpoint. */ + @Override + public String getEndpoint() { + if (super.getEndpoint() != null) { + return super.getEndpoint(); + } + return getDefaultEndpoint(); + } + @Override public DatabaseAdminStubSettings build() throws IOException { return new DatabaseAdminStubSettings(this); diff --git a/google-cloud-spanner/src/main/java/com/google/cloud/spanner/admin/instance/v1/InstanceAdminClient.java b/google-cloud-spanner/src/main/java/com/google/cloud/spanner/admin/instance/v1/InstanceAdminClient.java index 325f0704ad6..8ad508278ed 100644 --- a/google-cloud-spanner/src/main/java/com/google/cloud/spanner/admin/instance/v1/InstanceAdminClient.java +++ b/google-cloud-spanner/src/main/java/com/google/cloud/spanner/admin/instance/v1/InstanceAdminClient.java @@ -106,19 +106,326 @@ *

Note: close() needs to be called on the InstanceAdminClient object to clean up resources such * as threads. In the example above, try-with-resources is used, which automatically calls close(). * - *

The surface of this class includes several types of Java methods for each of the API's - * methods: - * - *

    - *
  1. A "flattened" method. With this type of method, the fields of the request type have been - * converted into function parameters. It may be the case that not all fields are available as - * parameters, and not every API method will have a flattened method entry point. - *
  2. A "request object" method. This type of method only takes one parameter, a request object, - * which must be constructed before the call. Not every API method will have a request object - * method. - *
  3. A "callable" method. This type of method takes no parameters and returns an immutable API - * callable object, which can be used to initiate calls to the service. - *
+ * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + *
Methods
MethodDescriptionMethod Variants

ListInstanceConfigs

Lists the supported instance configurations for a given project.

+ *

Request object method variants only take one parameter, a request object, which must be constructed before the call.

+ *
    + *
  • listInstanceConfigs(ListInstanceConfigsRequest request) + *

+ *

"Flattened" method variants have converted the fields of the request object into function parameters to enable multiple ways to call the same method.

+ *
    + *
  • listInstanceConfigs(ProjectName parent) + *

  • listInstanceConfigs(String parent) + *

+ *

Callable method variants take no parameters and return an immutable API callable object, which can be used to initiate calls to the service.

+ *
    + *
  • listInstanceConfigsPagedCallable() + *

  • listInstanceConfigsCallable() + *

+ *

GetInstanceConfig

Gets information about a particular instance configuration.

+ *

Request object method variants only take one parameter, a request object, which must be constructed before the call.

+ *
    + *
  • getInstanceConfig(GetInstanceConfigRequest request) + *

+ *

"Flattened" method variants have converted the fields of the request object into function parameters to enable multiple ways to call the same method.

+ *
    + *
  • getInstanceConfig(InstanceConfigName name) + *

  • getInstanceConfig(String name) + *

+ *

Callable method variants take no parameters and return an immutable API callable object, which can be used to initiate calls to the service.

+ *
    + *
  • getInstanceConfigCallable() + *

+ *

CreateInstanceConfig

Creates an instance config and begins preparing it to be used. The returned [long-running operation][google.longrunning.Operation] can be used to track the progress of preparing the new instance config. The instance config name is assigned by the caller. If the named instance config already exists, `CreateInstanceConfig` returns `ALREADY_EXISTS`. + *

Immediately after the request returns: + *

* The instance config is readable via the API, with all requested attributes. The instance config's [reconciling][google.spanner.admin.instance.v1.InstanceConfig.reconciling] field is set to true. Its state is `CREATING`. + *

While the operation is pending: + *

* Cancelling the operation renders the instance config immediately unreadable via the API. * Except for deleting the creating resource, all other attempts to modify the instance config are rejected. + *

Upon completion of the returned operation: + *

* Instances can be created using the instance configuration. * The instance config's [reconciling][google.spanner.admin.instance.v1.InstanceConfig.reconciling] field becomes false. Its state becomes `READY`. + *

The returned [long-running operation][google.longrunning.Operation] will have a name of the format `<instance_config_name>/operations/<operation_id>` and can be used to track creation of the instance config. The [metadata][google.longrunning.Operation.metadata] field type is [CreateInstanceConfigMetadata][google.spanner.admin.instance.v1.CreateInstanceConfigMetadata]. The [response][google.longrunning.Operation.response] field type is [InstanceConfig][google.spanner.admin.instance.v1.InstanceConfig], if successful. + *

Authorization requires `spanner.instanceConfigs.create` permission on the resource [parent][google.spanner.admin.instance.v1.CreateInstanceConfigRequest.parent].

+ *

Request object method variants only take one parameter, a request object, which must be constructed before the call.

+ *
    + *
  • createInstanceConfigAsync(CreateInstanceConfigRequest request) + *

+ *

Methods that return long-running operations have "Async" method variants that return `OperationFuture`, which is used to track polling of the service.

+ *
    + *
  • createInstanceConfigAsync(ProjectName parent, InstanceConfig instanceConfig, String instanceConfigId) + *

  • createInstanceConfigAsync(String parent, InstanceConfig instanceConfig, String instanceConfigId) + *

+ *

Callable method variants take no parameters and return an immutable API callable object, which can be used to initiate calls to the service.

+ *
    + *
  • createInstanceConfigOperationCallable() + *

  • createInstanceConfigCallable() + *

+ *

UpdateInstanceConfig

Updates an instance config. The returned [long-running operation][google.longrunning.Operation] can be used to track the progress of updating the instance. If the named instance config does not exist, returns `NOT_FOUND`. + *

Only user managed configurations can be updated. + *

Immediately after the request returns: + *

* The instance config's [reconciling][google.spanner.admin.instance.v1.InstanceConfig.reconciling] field is set to true. + *

While the operation is pending: + *

* Cancelling the operation sets its metadata's [cancel_time][google.spanner.admin.instance.v1.UpdateInstanceConfigMetadata.cancel_time]. The operation is guaranteed to succeed at undoing all changes, after which point it terminates with a `CANCELLED` status. * All other attempts to modify the instance config are rejected. * Reading the instance config via the API continues to give the pre-request values. + *

Upon completion of the returned operation: + *

* Creating instances using the instance configuration uses the new values. * The instance config's new values are readable via the API. * The instance config's [reconciling][google.spanner.admin.instance.v1.InstanceConfig.reconciling] field becomes false. + *

The returned [long-running operation][google.longrunning.Operation] will have a name of the format `<instance_config_name>/operations/<operation_id>` and can be used to track the instance config modification. The [metadata][google.longrunning.Operation.metadata] field type is [UpdateInstanceConfigMetadata][google.spanner.admin.instance.v1.UpdateInstanceConfigMetadata]. The [response][google.longrunning.Operation.response] field type is [InstanceConfig][google.spanner.admin.instance.v1.InstanceConfig], if successful. + *

Authorization requires `spanner.instanceConfigs.update` permission on the resource [name][google.spanner.admin.instance.v1.InstanceConfig.name].

+ *

Request object method variants only take one parameter, a request object, which must be constructed before the call.

+ *
    + *
  • updateInstanceConfigAsync(UpdateInstanceConfigRequest request) + *

+ *

Methods that return long-running operations have "Async" method variants that return `OperationFuture`, which is used to track polling of the service.

+ *
    + *
  • updateInstanceConfigAsync(InstanceConfig instanceConfig, FieldMask updateMask) + *

+ *

Callable method variants take no parameters and return an immutable API callable object, which can be used to initiate calls to the service.

+ *
    + *
  • updateInstanceConfigOperationCallable() + *

  • updateInstanceConfigCallable() + *

+ *

DeleteInstanceConfig

Deletes the instance config. Deletion is only allowed when no instances are using the configuration. If any instances are using the config, returns `FAILED_PRECONDITION`. + *

Only user managed configurations can be deleted. + *

Authorization requires `spanner.instanceConfigs.delete` permission on the resource [name][google.spanner.admin.instance.v1.InstanceConfig.name].

+ *

Request object method variants only take one parameter, a request object, which must be constructed before the call.

+ *
    + *
  • deleteInstanceConfig(DeleteInstanceConfigRequest request) + *

+ *

"Flattened" method variants have converted the fields of the request object into function parameters to enable multiple ways to call the same method.

+ *
    + *
  • deleteInstanceConfig(InstanceConfigName name) + *

  • deleteInstanceConfig(String name) + *

+ *

Callable method variants take no parameters and return an immutable API callable object, which can be used to initiate calls to the service.

+ *
    + *
  • deleteInstanceConfigCallable() + *

+ *

ListInstanceConfigOperations

Lists the user-managed instance config [long-running operations][google.longrunning.Operation] in the given project. An instance config operation has a name of the form `projects/<project>/instanceConfigs/<instance_config>/operations/<operation>`. The long-running operation [metadata][google.longrunning.Operation.metadata] field type `metadata.type_url` describes the type of the metadata. Operations returned include those that have completed/failed/canceled within the last 7 days, and pending operations. Operations returned are ordered by `operation.metadata.value.start_time` in descending order starting from the most recently started operation.

+ *

Request object method variants only take one parameter, a request object, which must be constructed before the call.

+ *
    + *
  • listInstanceConfigOperations(ListInstanceConfigOperationsRequest request) + *

+ *

"Flattened" method variants have converted the fields of the request object into function parameters to enable multiple ways to call the same method.

+ *
    + *
  • listInstanceConfigOperations(ProjectName parent) + *

  • listInstanceConfigOperations(String parent) + *

+ *

Callable method variants take no parameters and return an immutable API callable object, which can be used to initiate calls to the service.

+ *
    + *
  • listInstanceConfigOperationsPagedCallable() + *

  • listInstanceConfigOperationsCallable() + *

+ *

ListInstances

Lists all instances in the given project.

+ *

Request object method variants only take one parameter, a request object, which must be constructed before the call.

+ *
    + *
  • listInstances(ListInstancesRequest request) + *

+ *

"Flattened" method variants have converted the fields of the request object into function parameters to enable multiple ways to call the same method.

+ *
    + *
  • listInstances(ProjectName parent) + *

  • listInstances(String parent) + *

+ *

Callable method variants take no parameters and return an immutable API callable object, which can be used to initiate calls to the service.

+ *
    + *
  • listInstancesPagedCallable() + *

  • listInstancesCallable() + *

+ *

GetInstance

Gets information about a particular instance.

+ *

Request object method variants only take one parameter, a request object, which must be constructed before the call.

+ *
    + *
  • getInstance(GetInstanceRequest request) + *

+ *

"Flattened" method variants have converted the fields of the request object into function parameters to enable multiple ways to call the same method.

+ *
    + *
  • getInstance(InstanceName name) + *

  • getInstance(String name) + *

+ *

Callable method variants take no parameters and return an immutable API callable object, which can be used to initiate calls to the service.

+ *
    + *
  • getInstanceCallable() + *

+ *

CreateInstance

Creates an instance and begins preparing it to begin serving. The returned [long-running operation][google.longrunning.Operation] can be used to track the progress of preparing the new instance. The instance name is assigned by the caller. If the named instance already exists, `CreateInstance` returns `ALREADY_EXISTS`. + *

Immediately upon completion of this request: + *

* The instance is readable via the API, with all requested attributes but no allocated resources. Its state is `CREATING`. + *

Until completion of the returned operation: + *

* Cancelling the operation renders the instance immediately unreadable via the API. * The instance can be deleted. * All other attempts to modify the instance are rejected. + *

Upon completion of the returned operation: + *

* Billing for all successfully-allocated resources begins (some types may have lower than the requested levels). * Databases can be created in the instance. * The instance's allocated resource levels are readable via the API. * The instance's state becomes `READY`. + *

The returned [long-running operation][google.longrunning.Operation] will have a name of the format `<instance_name>/operations/<operation_id>` and can be used to track creation of the instance. The [metadata][google.longrunning.Operation.metadata] field type is [CreateInstanceMetadata][google.spanner.admin.instance.v1.CreateInstanceMetadata]. The [response][google.longrunning.Operation.response] field type is [Instance][google.spanner.admin.instance.v1.Instance], if successful.

+ *

Request object method variants only take one parameter, a request object, which must be constructed before the call.

+ *
    + *
  • createInstanceAsync(CreateInstanceRequest request) + *

+ *

Methods that return long-running operations have "Async" method variants that return `OperationFuture`, which is used to track polling of the service.

+ *
    + *
  • createInstanceAsync(ProjectName parent, String instanceId, Instance instance) + *

  • createInstanceAsync(String parent, String instanceId, Instance instance) + *

+ *

Callable method variants take no parameters and return an immutable API callable object, which can be used to initiate calls to the service.

+ *
    + *
  • createInstanceOperationCallable() + *

  • createInstanceCallable() + *

+ *

UpdateInstance

Updates an instance, and begins allocating or releasing resources as requested. The returned [long-running operation][google.longrunning.Operation] can be used to track the progress of updating the instance. If the named instance does not exist, returns `NOT_FOUND`. + *

Immediately upon completion of this request: + *

* For resource types for which a decrease in the instance's allocation has been requested, billing is based on the newly-requested level. + *

Until completion of the returned operation: + *

* Cancelling the operation sets its metadata's [cancel_time][google.spanner.admin.instance.v1.UpdateInstanceMetadata.cancel_time], and begins restoring resources to their pre-request values. The operation is guaranteed to succeed at undoing all resource changes, after which point it terminates with a `CANCELLED` status. * All other attempts to modify the instance are rejected. * Reading the instance via the API continues to give the pre-request resource levels. + *

Upon completion of the returned operation: + *

* Billing begins for all successfully-allocated resources (some types may have lower than the requested levels). * All newly-reserved resources are available for serving the instance's tables. * The instance's new resource levels are readable via the API. + *

The returned [long-running operation][google.longrunning.Operation] will have a name of the format `<instance_name>/operations/<operation_id>` and can be used to track the instance modification. The [metadata][google.longrunning.Operation.metadata] field type is [UpdateInstanceMetadata][google.spanner.admin.instance.v1.UpdateInstanceMetadata]. The [response][google.longrunning.Operation.response] field type is [Instance][google.spanner.admin.instance.v1.Instance], if successful. + *

Authorization requires `spanner.instances.update` permission on the resource [name][google.spanner.admin.instance.v1.Instance.name].

+ *

Request object method variants only take one parameter, a request object, which must be constructed before the call.

+ *
    + *
  • updateInstanceAsync(UpdateInstanceRequest request) + *

+ *

Methods that return long-running operations have "Async" method variants that return `OperationFuture`, which is used to track polling of the service.

+ *
    + *
  • updateInstanceAsync(Instance instance, FieldMask fieldMask) + *

+ *

Callable method variants take no parameters and return an immutable API callable object, which can be used to initiate calls to the service.

+ *
    + *
  • updateInstanceOperationCallable() + *

  • updateInstanceCallable() + *

+ *

DeleteInstance

Deletes an instance. + *

Immediately upon completion of the request: + *

* Billing ceases for all of the instance's reserved resources. + *

Soon afterward: + *

* The instance and *all of its databases* immediately and irrevocably disappear from the API. All data in the databases is permanently deleted.

+ *

Request object method variants only take one parameter, a request object, which must be constructed before the call.

+ *
    + *
  • deleteInstance(DeleteInstanceRequest request) + *

+ *

"Flattened" method variants have converted the fields of the request object into function parameters to enable multiple ways to call the same method.

+ *
    + *
  • deleteInstance(InstanceName name) + *

  • deleteInstance(String name) + *

+ *

Callable method variants take no parameters and return an immutable API callable object, which can be used to initiate calls to the service.

+ *
    + *
  • deleteInstanceCallable() + *

+ *

SetIamPolicy

Sets the access control policy on an instance resource. Replaces any existing policy. + *

Authorization requires `spanner.instances.setIamPolicy` on [resource][google.iam.v1.SetIamPolicyRequest.resource].

+ *

Request object method variants only take one parameter, a request object, which must be constructed before the call.

+ *
    + *
  • setIamPolicy(SetIamPolicyRequest request) + *

+ *

"Flattened" method variants have converted the fields of the request object into function parameters to enable multiple ways to call the same method.

+ *
    + *
  • setIamPolicy(ResourceName resource, Policy policy) + *

  • setIamPolicy(String resource, Policy policy) + *

+ *

Callable method variants take no parameters and return an immutable API callable object, which can be used to initiate calls to the service.

+ *
    + *
  • setIamPolicyCallable() + *

+ *

GetIamPolicy

Gets the access control policy for an instance resource. Returns an empty policy if an instance exists but does not have a policy set. + *

Authorization requires `spanner.instances.getIamPolicy` on [resource][google.iam.v1.GetIamPolicyRequest.resource].

+ *

Request object method variants only take one parameter, a request object, which must be constructed before the call.

+ *
    + *
  • getIamPolicy(GetIamPolicyRequest request) + *

+ *

"Flattened" method variants have converted the fields of the request object into function parameters to enable multiple ways to call the same method.

+ *
    + *
  • getIamPolicy(ResourceName resource) + *

  • getIamPolicy(String resource) + *

+ *

Callable method variants take no parameters and return an immutable API callable object, which can be used to initiate calls to the service.

+ *
    + *
  • getIamPolicyCallable() + *

+ *

TestIamPermissions

Returns permissions that the caller has on the specified instance resource. + *

Attempting this RPC on a non-existent Cloud Spanner instance resource will result in a NOT_FOUND error if the user has `spanner.instances.list` permission on the containing Google Cloud Project. Otherwise returns an empty set of permissions.

+ *

Request object method variants only take one parameter, a request object, which must be constructed before the call.

+ *
    + *
  • testIamPermissions(TestIamPermissionsRequest request) + *

+ *

"Flattened" method variants have converted the fields of the request object into function parameters to enable multiple ways to call the same method.

+ *
    + *
  • testIamPermissions(ResourceName resource, List<String> permissions) + *

  • testIamPermissions(String resource, List<String> permissions) + *

+ *

Callable method variants take no parameters and return an immutable API callable object, which can be used to initiate calls to the service.

+ *
    + *
  • testIamPermissionsCallable() + *

+ *
* *

See the individual methods for example code. * diff --git a/google-cloud-spanner/src/main/java/com/google/cloud/spanner/admin/instance/v1/stub/InstanceAdminStubSettings.java b/google-cloud-spanner/src/main/java/com/google/cloud/spanner/admin/instance/v1/stub/InstanceAdminStubSettings.java index edbb97ba1e0..2a9ffb20763 100644 --- a/google-cloud-spanner/src/main/java/com/google/cloud/spanner/admin/instance/v1/stub/InstanceAdminStubSettings.java +++ b/google-cloud-spanner/src/main/java/com/google/cloud/spanner/admin/instance/v1/stub/InstanceAdminStubSettings.java @@ -481,6 +481,21 @@ public InstanceAdminStub createStub() throws IOException { "Transport not supported: %s", getTransportChannelProvider().getTransportName())); } + /** Returns the endpoint set by the user or the the service's default endpoint. */ + @Override + public String getEndpoint() { + if (super.getEndpoint() != null) { + return super.getEndpoint(); + } + return getDefaultEndpoint(); + } + + /** Returns the default service name. */ + @Override + public String getServiceName() { + return "spanner"; + } + /** Returns a builder for the default ExecutorProvider for this service. */ public static InstantiatingExecutorProvider.Builder defaultExecutorProviderBuilder() { return InstantiatingExecutorProvider.newBuilder(); @@ -808,7 +823,6 @@ private static Builder createDefault() { builder.setTransportChannelProvider(defaultTransportChannelProvider()); builder.setCredentialsProvider(defaultCredentialsProviderBuilder().build()); builder.setInternalHeaderProvider(defaultApiClientHeaderProviderBuilder().build()); - builder.setEndpoint(getDefaultEndpoint()); builder.setMtlsEndpoint(getDefaultMtlsEndpoint()); builder.setSwitchToMtlsEndpointAllowed(true); @@ -821,7 +835,6 @@ private static Builder createHttpJsonDefault() { builder.setTransportChannelProvider(defaultHttpJsonTransportProviderBuilder().build()); builder.setCredentialsProvider(defaultCredentialsProviderBuilder().build()); builder.setInternalHeaderProvider(defaultHttpJsonApiClientHeaderProviderBuilder().build()); - builder.setEndpoint(getDefaultEndpoint()); builder.setMtlsEndpoint(getDefaultMtlsEndpoint()); builder.setSwitchToMtlsEndpointAllowed(true); @@ -1134,6 +1147,15 @@ public UnaryCallSettings.Builder getIamPolicySettin return testIamPermissionsSettings; } + /** Returns the endpoint set by the user or the the service's default endpoint. */ + @Override + public String getEndpoint() { + if (super.getEndpoint() != null) { + return super.getEndpoint(); + } + return getDefaultEndpoint(); + } + @Override public InstanceAdminStubSettings build() throws IOException { return new InstanceAdminStubSettings(this); diff --git a/google-cloud-spanner/src/main/java/com/google/cloud/spanner/v1/SpannerClient.java b/google-cloud-spanner/src/main/java/com/google/cloud/spanner/v1/SpannerClient.java index 7358e4adcf9..9eaacdc33ba 100644 --- a/google-cloud-spanner/src/main/java/com/google/cloud/spanner/v1/SpannerClient.java +++ b/google-cloud-spanner/src/main/java/com/google/cloud/spanner/v1/SpannerClient.java @@ -88,19 +88,285 @@ *

Note: close() needs to be called on the SpannerClient object to clean up resources such as * threads. In the example above, try-with-resources is used, which automatically calls close(). * - *

The surface of this class includes several types of Java methods for each of the API's - * methods: - * - *

    - *
  1. A "flattened" method. With this type of method, the fields of the request type have been - * converted into function parameters. It may be the case that not all fields are available as - * parameters, and not every API method will have a flattened method entry point. - *
  2. A "request object" method. This type of method only takes one parameter, a request object, - * which must be constructed before the call. Not every API method will have a request object - * method. - *
  3. A "callable" method. This type of method takes no parameters and returns an immutable API - * callable object, which can be used to initiate calls to the service. - *
+ * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + *
Methods
MethodDescriptionMethod Variants

CreateSession

Creates a new session. A session can be used to perform transactions that read and/or modify data in a Cloud Spanner database. Sessions are meant to be reused for many consecutive transactions. + *

Sessions can only execute one transaction at a time. To execute multiple concurrent read-write/write-only transactions, create multiple sessions. Note that standalone reads and queries use a transaction internally, and count toward the one transaction limit. + *

Active sessions use additional server resources, so it is a good idea to delete idle and unneeded sessions. Aside from explicit deletes, Cloud Spanner may delete sessions for which no operations are sent for more than an hour. If a session is deleted, requests to it return `NOT_FOUND`. + *

Idle sessions can be kept alive by sending a trivial SQL query periodically, e.g., `"SELECT 1"`.

+ *

Request object method variants only take one parameter, a request object, which must be constructed before the call.

+ *
    + *
  • createSession(CreateSessionRequest request) + *

+ *

"Flattened" method variants have converted the fields of the request object into function parameters to enable multiple ways to call the same method.

+ *
    + *
  • createSession(DatabaseName database) + *

  • createSession(String database) + *

+ *

Callable method variants take no parameters and return an immutable API callable object, which can be used to initiate calls to the service.

+ *
    + *
  • createSessionCallable() + *

+ *

BatchCreateSessions

Creates multiple new sessions. + *

This API can be used to initialize a session cache on the clients. See https://goo.gl/TgSFN2 for best practices on session cache management.

+ *

Request object method variants only take one parameter, a request object, which must be constructed before the call.

+ *
    + *
  • batchCreateSessions(BatchCreateSessionsRequest request) + *

+ *

"Flattened" method variants have converted the fields of the request object into function parameters to enable multiple ways to call the same method.

+ *
    + *
  • batchCreateSessions(DatabaseName database, int sessionCount) + *

  • batchCreateSessions(String database, int sessionCount) + *

+ *

Callable method variants take no parameters and return an immutable API callable object, which can be used to initiate calls to the service.

+ *
    + *
  • batchCreateSessionsCallable() + *

+ *

GetSession

Gets a session. Returns `NOT_FOUND` if the session does not exist. This is mainly useful for determining whether a session is still alive.

+ *

Request object method variants only take one parameter, a request object, which must be constructed before the call.

+ *
    + *
  • getSession(GetSessionRequest request) + *

+ *

"Flattened" method variants have converted the fields of the request object into function parameters to enable multiple ways to call the same method.

+ *
    + *
  • getSession(SessionName name) + *

  • getSession(String name) + *

+ *

Callable method variants take no parameters and return an immutable API callable object, which can be used to initiate calls to the service.

+ *
    + *
  • getSessionCallable() + *

+ *

ListSessions

Lists all sessions in a given database.

+ *

Request object method variants only take one parameter, a request object, which must be constructed before the call.

+ *
    + *
  • listSessions(ListSessionsRequest request) + *

+ *

"Flattened" method variants have converted the fields of the request object into function parameters to enable multiple ways to call the same method.

+ *
    + *
  • listSessions(DatabaseName database) + *

  • listSessions(String database) + *

+ *

Callable method variants take no parameters and return an immutable API callable object, which can be used to initiate calls to the service.

+ *
    + *
  • listSessionsPagedCallable() + *

  • listSessionsCallable() + *

+ *

DeleteSession

Ends a session, releasing server resources associated with it. This will asynchronously trigger cancellation of any operations that are running with this session.

+ *

Request object method variants only take one parameter, a request object, which must be constructed before the call.

+ *
    + *
  • deleteSession(DeleteSessionRequest request) + *

+ *

"Flattened" method variants have converted the fields of the request object into function parameters to enable multiple ways to call the same method.

+ *
    + *
  • deleteSession(SessionName name) + *

  • deleteSession(String name) + *

+ *

Callable method variants take no parameters and return an immutable API callable object, which can be used to initiate calls to the service.

+ *
    + *
  • deleteSessionCallable() + *

+ *

ExecuteSql

Executes an SQL statement, returning all results in a single reply. This method cannot be used to return a result set larger than 10 MiB; if the query yields more data than that, the query fails with a `FAILED_PRECONDITION` error. + *

Operations inside read-write transactions might return `ABORTED`. If this occurs, the application should restart the transaction from the beginning. See [Transaction][google.spanner.v1.Transaction] for more details. + *

Larger result sets can be fetched in streaming fashion by calling [ExecuteStreamingSql][google.spanner.v1.Spanner.ExecuteStreamingSql] instead.

+ *

Request object method variants only take one parameter, a request object, which must be constructed before the call.

+ *
    + *
  • executeSql(ExecuteSqlRequest request) + *

+ *

Callable method variants take no parameters and return an immutable API callable object, which can be used to initiate calls to the service.

+ *
    + *
  • executeSqlCallable() + *

+ *

ExecuteStreamingSql

Like [ExecuteSql][google.spanner.v1.Spanner.ExecuteSql], except returns the result set as a stream. Unlike [ExecuteSql][google.spanner.v1.Spanner.ExecuteSql], there is no limit on the size of the returned result set. However, no individual row in the result set can exceed 100 MiB, and no column value can exceed 10 MiB.

+ *

Callable method variants take no parameters and return an immutable API callable object, which can be used to initiate calls to the service.

+ *
    + *
  • executeStreamingSqlCallable() + *

+ *

ExecuteBatchDml

Executes a batch of SQL DML statements. This method allows many statements to be run with lower latency than submitting them sequentially with [ExecuteSql][google.spanner.v1.Spanner.ExecuteSql]. + *

Statements are executed in sequential order. A request can succeed even if a statement fails. The [ExecuteBatchDmlResponse.status][google.spanner.v1.ExecuteBatchDmlResponse.status] field in the response provides information about the statement that failed. Clients must inspect this field to determine whether an error occurred. + *

Execution stops after the first failed statement; the remaining statements are not executed.

+ *

Request object method variants only take one parameter, a request object, which must be constructed before the call.

+ *
    + *
  • executeBatchDml(ExecuteBatchDmlRequest request) + *

+ *

Callable method variants take no parameters and return an immutable API callable object, which can be used to initiate calls to the service.

+ *
    + *
  • executeBatchDmlCallable() + *

+ *

Read

Reads rows from the database using key lookups and scans, as a simple key/value style alternative to [ExecuteSql][google.spanner.v1.Spanner.ExecuteSql]. This method cannot be used to return a result set larger than 10 MiB; if the read matches more data than that, the read fails with a `FAILED_PRECONDITION` error. + *

Reads inside read-write transactions might return `ABORTED`. If this occurs, the application should restart the transaction from the beginning. See [Transaction][google.spanner.v1.Transaction] for more details. + *

Larger result sets can be yielded in streaming fashion by calling [StreamingRead][google.spanner.v1.Spanner.StreamingRead] instead.

+ *

Request object method variants only take one parameter, a request object, which must be constructed before the call.

+ *
    + *
  • read(ReadRequest request) + *

+ *

Callable method variants take no parameters and return an immutable API callable object, which can be used to initiate calls to the service.

+ *
    + *
  • readCallable() + *

+ *

StreamingRead

Like [Read][google.spanner.v1.Spanner.Read], except returns the result set as a stream. Unlike [Read][google.spanner.v1.Spanner.Read], there is no limit on the size of the returned result set. However, no individual row in the result set can exceed 100 MiB, and no column value can exceed 10 MiB.

+ *

Callable method variants take no parameters and return an immutable API callable object, which can be used to initiate calls to the service.

+ *
    + *
  • streamingReadCallable() + *

+ *

BeginTransaction

Begins a new transaction. This step can often be skipped: [Read][google.spanner.v1.Spanner.Read], [ExecuteSql][google.spanner.v1.Spanner.ExecuteSql] and [Commit][google.spanner.v1.Spanner.Commit] can begin a new transaction as a side-effect.

+ *

Request object method variants only take one parameter, a request object, which must be constructed before the call.

+ *
    + *
  • beginTransaction(BeginTransactionRequest request) + *

+ *

"Flattened" method variants have converted the fields of the request object into function parameters to enable multiple ways to call the same method.

+ *
    + *
  • beginTransaction(SessionName session, TransactionOptions options) + *

  • beginTransaction(String session, TransactionOptions options) + *

+ *

Callable method variants take no parameters and return an immutable API callable object, which can be used to initiate calls to the service.

+ *
    + *
  • beginTransactionCallable() + *

+ *

Commit

Commits a transaction. The request includes the mutations to be applied to rows in the database. + *

`Commit` might return an `ABORTED` error. This can occur at any time; commonly, the cause is conflicts with concurrent transactions. However, it can also happen for a variety of other reasons. If `Commit` returns `ABORTED`, the caller should re-attempt the transaction from the beginning, re-using the same session. + *

On very rare occasions, `Commit` might return `UNKNOWN`. This can happen, for example, if the client job experiences a 1+ hour networking failure. At that point, Cloud Spanner has lost track of the transaction outcome and we recommend that you perform another read from the database to see the state of things as they are now.

+ *

Request object method variants only take one parameter, a request object, which must be constructed before the call.

+ *
    + *
  • commit(CommitRequest request) + *

+ *

"Flattened" method variants have converted the fields of the request object into function parameters to enable multiple ways to call the same method.

+ *
    + *
  • commit(SessionName session, ByteString transactionId, List<Mutation> mutations) + *

  • commit(SessionName session, TransactionOptions singleUseTransaction, List<Mutation> mutations) + *

  • commit(String session, ByteString transactionId, List<Mutation> mutations) + *

  • commit(String session, TransactionOptions singleUseTransaction, List<Mutation> mutations) + *

+ *

Callable method variants take no parameters and return an immutable API callable object, which can be used to initiate calls to the service.

+ *
    + *
  • commitCallable() + *

+ *

Rollback

Rolls back a transaction, releasing any locks it holds. It is a good idea to call this for any transaction that includes one or more [Read][google.spanner.v1.Spanner.Read] or [ExecuteSql][google.spanner.v1.Spanner.ExecuteSql] requests and ultimately decides not to commit. + *

`Rollback` returns `OK` if it successfully aborts the transaction, the transaction was already aborted, or the transaction is not found. `Rollback` never returns `ABORTED`.

+ *

Request object method variants only take one parameter, a request object, which must be constructed before the call.

+ *
    + *
  • rollback(RollbackRequest request) + *

+ *

"Flattened" method variants have converted the fields of the request object into function parameters to enable multiple ways to call the same method.

+ *
    + *
  • rollback(SessionName session, ByteString transactionId) + *

  • rollback(String session, ByteString transactionId) + *

+ *

Callable method variants take no parameters and return an immutable API callable object, which can be used to initiate calls to the service.

+ *
    + *
  • rollbackCallable() + *

+ *

PartitionQuery

Creates a set of partition tokens that can be used to execute a query operation in parallel. Each of the returned partition tokens can be used by [ExecuteStreamingSql][google.spanner.v1.Spanner.ExecuteStreamingSql] to specify a subset of the query result to read. The same session and read-only transaction must be used by the PartitionQueryRequest used to create the partition tokens and the ExecuteSqlRequests that use the partition tokens. + *

Partition tokens become invalid when the session used to create them is deleted, is idle for too long, begins a new transaction, or becomes too old. When any of these happen, it is not possible to resume the query, and the whole operation must be restarted from the beginning.

+ *

Request object method variants only take one parameter, a request object, which must be constructed before the call.

+ *
    + *
  • partitionQuery(PartitionQueryRequest request) + *

+ *

Callable method variants take no parameters and return an immutable API callable object, which can be used to initiate calls to the service.

+ *
    + *
  • partitionQueryCallable() + *

+ *

PartitionRead

Creates a set of partition tokens that can be used to execute a read operation in parallel. Each of the returned partition tokens can be used by [StreamingRead][google.spanner.v1.Spanner.StreamingRead] to specify a subset of the read result to read. The same session and read-only transaction must be used by the PartitionReadRequest used to create the partition tokens and the ReadRequests that use the partition tokens. There are no ordering guarantees on rows returned among the returned partition tokens, or even within each individual StreamingRead call issued with a partition_token. + *

Partition tokens become invalid when the session used to create them is deleted, is idle for too long, begins a new transaction, or becomes too old. When any of these happen, it is not possible to resume the read, and the whole operation must be restarted from the beginning.

+ *

Request object method variants only take one parameter, a request object, which must be constructed before the call.

+ *
    + *
  • partitionRead(PartitionReadRequest request) + *

+ *

Callable method variants take no parameters and return an immutable API callable object, which can be used to initiate calls to the service.

+ *
    + *
  • partitionReadCallable() + *

+ *

BatchWrite

Batches the supplied mutation groups in a collection of efficient transactions. All mutations in a group are committed atomically. However, mutations across groups can be committed non-atomically in an unspecified order and thus, they must be independent of each other. Partial failure is possible, i.e., some groups may have been committed successfully, while some may have failed. The results of individual batches are streamed into the response as the batches are applied. + *

BatchWrite requests are not replay protected, meaning that each mutation group may be applied more than once. Replays of non-idempotent mutations may have undesirable effects. For example, replays of an insert mutation may produce an already exists error or if you use generated or commit timestamp-based keys, it may result in additional rows being added to the mutation's table. We recommend structuring your mutation groups to be idempotent to avoid this issue.

+ *

Callable method variants take no parameters and return an immutable API callable object, which can be used to initiate calls to the service.

+ *
    + *
  • batchWriteCallable() + *

+ *
* *

See the individual methods for example code. * @@ -1643,6 +1909,7 @@ public final CommitResponse commit( * SessionName.of("[PROJECT]", "[INSTANCE]", "[DATABASE]", "[SESSION]").toString()) * .addAllMutations(new ArrayList()) * .setReturnCommitStats(true) + * .setMaxCommitDelay(Duration.newBuilder().build()) * .setRequestOptions(RequestOptions.newBuilder().build()) * .build(); * CommitResponse response = spannerClient.commit(request); @@ -1686,6 +1953,7 @@ public final CommitResponse commit(CommitRequest request) { * SessionName.of("[PROJECT]", "[INSTANCE]", "[DATABASE]", "[SESSION]").toString()) * .addAllMutations(new ArrayList()) * .setReturnCommitStats(true) + * .setMaxCommitDelay(Duration.newBuilder().build()) * .setRequestOptions(RequestOptions.newBuilder().build()) * .build(); * ApiFuture future = spannerClient.commitCallable().futureCall(request); diff --git a/google-cloud-spanner/src/main/java/com/google/cloud/spanner/v1/stub/SpannerStubSettings.java b/google-cloud-spanner/src/main/java/com/google/cloud/spanner/v1/stub/SpannerStubSettings.java index ac47e6177e1..5b6939e7dad 100644 --- a/google-cloud-spanner/src/main/java/com/google/cloud/spanner/v1/stub/SpannerStubSettings.java +++ b/google-cloud-spanner/src/main/java/com/google/cloud/spanner/v1/stub/SpannerStubSettings.java @@ -299,6 +299,21 @@ public SpannerStub createStub() throws IOException { "Transport not supported: %s", getTransportChannelProvider().getTransportName())); } + /** Returns the endpoint set by the user or the the service's default endpoint. */ + @Override + public String getEndpoint() { + if (super.getEndpoint() != null) { + return super.getEndpoint(); + } + return getDefaultEndpoint(); + } + + /** Returns the default service name. */ + @Override + public String getServiceName() { + return "spanner"; + } + /** Returns a builder for the default ExecutorProvider for this service. */ public static InstantiatingExecutorProvider.Builder defaultExecutorProviderBuilder() { return InstantiatingExecutorProvider.newBuilder(); @@ -588,7 +603,6 @@ private static Builder createDefault() { builder.setTransportChannelProvider(defaultTransportChannelProvider()); builder.setCredentialsProvider(defaultCredentialsProviderBuilder().build()); builder.setInternalHeaderProvider(defaultApiClientHeaderProviderBuilder().build()); - builder.setEndpoint(getDefaultEndpoint()); builder.setMtlsEndpoint(getDefaultMtlsEndpoint()); builder.setSwitchToMtlsEndpointAllowed(true); @@ -601,7 +615,6 @@ private static Builder createHttpJsonDefault() { builder.setTransportChannelProvider(defaultHttpJsonTransportProviderBuilder().build()); builder.setCredentialsProvider(defaultCredentialsProviderBuilder().build()); builder.setInternalHeaderProvider(defaultHttpJsonApiClientHeaderProviderBuilder().build()); - builder.setEndpoint(getDefaultEndpoint()); builder.setMtlsEndpoint(getDefaultMtlsEndpoint()); builder.setSwitchToMtlsEndpointAllowed(true); @@ -797,6 +810,15 @@ public UnaryCallSettings.Builder rollbackSettings() { return batchWriteSettings; } + /** Returns the endpoint set by the user or the the service's default endpoint. */ + @Override + public String getEndpoint() { + if (super.getEndpoint() != null) { + return super.getEndpoint(); + } + return getDefaultEndpoint(); + } + @Override public SpannerStubSettings build() throws IOException { return new SpannerStubSettings(this); diff --git a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/admin/database/v1/DatabaseAdminClientHttpJsonTest.java b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/admin/database/v1/DatabaseAdminClientHttpJsonTest.java index 67530cb07f5..e55bf0cd988 100644 --- a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/admin/database/v1/DatabaseAdminClientHttpJsonTest.java +++ b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/admin/database/v1/DatabaseAdminClientHttpJsonTest.java @@ -702,7 +702,10 @@ public void dropDatabaseExceptionTest2() throws Exception { @Test public void getDatabaseDdlTest() throws Exception { GetDatabaseDdlResponse expectedResponse = - GetDatabaseDdlResponse.newBuilder().addAllStatements(new ArrayList()).build(); + GetDatabaseDdlResponse.newBuilder() + .addAllStatements(new ArrayList()) + .setProtoDescriptors(ByteString.EMPTY) + .build(); mockService.addResponse(expectedResponse); DatabaseName database = DatabaseName.of("[PROJECT]", "[INSTANCE]", "[DATABASE]"); @@ -744,7 +747,10 @@ public void getDatabaseDdlExceptionTest() throws Exception { @Test public void getDatabaseDdlTest2() throws Exception { GetDatabaseDdlResponse expectedResponse = - GetDatabaseDdlResponse.newBuilder().addAllStatements(new ArrayList()).build(); + GetDatabaseDdlResponse.newBuilder() + .addAllStatements(new ArrayList()) + .setProtoDescriptors(ByteString.EMPTY) + .build(); mockService.addResponse(expectedResponse); String database = "projects/project-3102/instances/instance-3102/databases/database-3102"; diff --git a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/admin/database/v1/DatabaseAdminClientTest.java b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/admin/database/v1/DatabaseAdminClientTest.java index a9711017db2..35936093c1c 100644 --- a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/admin/database/v1/DatabaseAdminClientTest.java +++ b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/admin/database/v1/DatabaseAdminClientTest.java @@ -654,7 +654,10 @@ public void dropDatabaseExceptionTest2() throws Exception { @Test public void getDatabaseDdlTest() throws Exception { GetDatabaseDdlResponse expectedResponse = - GetDatabaseDdlResponse.newBuilder().addAllStatements(new ArrayList()).build(); + GetDatabaseDdlResponse.newBuilder() + .addAllStatements(new ArrayList()) + .setProtoDescriptors(ByteString.EMPTY) + .build(); mockDatabaseAdmin.addResponse(expectedResponse); DatabaseName database = DatabaseName.of("[PROJECT]", "[INSTANCE]", "[DATABASE]"); @@ -690,7 +693,10 @@ public void getDatabaseDdlExceptionTest() throws Exception { @Test public void getDatabaseDdlTest2() throws Exception { GetDatabaseDdlResponse expectedResponse = - GetDatabaseDdlResponse.newBuilder().addAllStatements(new ArrayList()).build(); + GetDatabaseDdlResponse.newBuilder() + .addAllStatements(new ArrayList()) + .setProtoDescriptors(ByteString.EMPTY) + .build(); mockDatabaseAdmin.addResponse(expectedResponse); String database = "database1789464955"; diff --git a/grpc-google-cloud-spanner-admin-database-v1/src/main/java/com/google/spanner/admin/database/v1/DatabaseAdminGrpc.java b/grpc-google-cloud-spanner-admin-database-v1/src/main/java/com/google/spanner/admin/database/v1/DatabaseAdminGrpc.java index 8f3341ba7d0..d2f6339bae4 100644 --- a/grpc-google-cloud-spanner-admin-database-v1/src/main/java/com/google/spanner/admin/database/v1/DatabaseAdminGrpc.java +++ b/grpc-google-cloud-spanner-admin-database-v1/src/main/java/com/google/spanner/admin/database/v1/DatabaseAdminGrpc.java @@ -1,5 +1,5 @@ /* - * Copyright 2023 Google LLC + * Copyright 2024 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/grpc-google-cloud-spanner-admin-instance-v1/src/main/java/com/google/spanner/admin/instance/v1/InstanceAdminGrpc.java b/grpc-google-cloud-spanner-admin-instance-v1/src/main/java/com/google/spanner/admin/instance/v1/InstanceAdminGrpc.java index 5126b2b45cb..400cb20ae90 100644 --- a/grpc-google-cloud-spanner-admin-instance-v1/src/main/java/com/google/spanner/admin/instance/v1/InstanceAdminGrpc.java +++ b/grpc-google-cloud-spanner-admin-instance-v1/src/main/java/com/google/spanner/admin/instance/v1/InstanceAdminGrpc.java @@ -1,5 +1,5 @@ /* - * Copyright 2023 Google LLC + * Copyright 2024 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/grpc-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/SpannerExecutorProxyGrpc.java b/grpc-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/SpannerExecutorProxyGrpc.java index 141c4afeb41..c0b46bb0d38 100644 --- a/grpc-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/SpannerExecutorProxyGrpc.java +++ b/grpc-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/SpannerExecutorProxyGrpc.java @@ -1,5 +1,5 @@ /* - * Copyright 2023 Google LLC + * Copyright 2024 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/grpc-google-cloud-spanner-v1/src/main/java/com/google/spanner/v1/SpannerGrpc.java b/grpc-google-cloud-spanner-v1/src/main/java/com/google/spanner/v1/SpannerGrpc.java index d8e401457af..ff9ea44f98f 100644 --- a/grpc-google-cloud-spanner-v1/src/main/java/com/google/spanner/v1/SpannerGrpc.java +++ b/grpc-google-cloud-spanner-v1/src/main/java/com/google/spanner/v1/SpannerGrpc.java @@ -1,5 +1,5 @@ /* - * Copyright 2023 Google LLC + * Copyright 2024 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/proto-google-cloud-spanner-admin-database-v1/src/main/java/com/google/spanner/admin/database/v1/Backup.java b/proto-google-cloud-spanner-admin-database-v1/src/main/java/com/google/spanner/admin/database/v1/Backup.java index bf59b96fd5c..ed3d469de3e 100644 --- a/proto-google-cloud-spanner-admin-database-v1/src/main/java/com/google/spanner/admin/database/v1/Backup.java +++ b/proto-google-cloud-spanner-admin-database-v1/src/main/java/com/google/spanner/admin/database/v1/Backup.java @@ -1,5 +1,5 @@ /* - * Copyright 2023 Google LLC + * Copyright 2024 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/proto-google-cloud-spanner-admin-database-v1/src/main/java/com/google/spanner/admin/database/v1/BackupInfo.java b/proto-google-cloud-spanner-admin-database-v1/src/main/java/com/google/spanner/admin/database/v1/BackupInfo.java index 6d44eae9ef3..f6ce4483d08 100644 --- a/proto-google-cloud-spanner-admin-database-v1/src/main/java/com/google/spanner/admin/database/v1/BackupInfo.java +++ b/proto-google-cloud-spanner-admin-database-v1/src/main/java/com/google/spanner/admin/database/v1/BackupInfo.java @@ -1,5 +1,5 @@ /* - * Copyright 2023 Google LLC + * Copyright 2024 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/proto-google-cloud-spanner-admin-database-v1/src/main/java/com/google/spanner/admin/database/v1/BackupInfoOrBuilder.java b/proto-google-cloud-spanner-admin-database-v1/src/main/java/com/google/spanner/admin/database/v1/BackupInfoOrBuilder.java index b90885b9e84..6b2589ac817 100644 --- a/proto-google-cloud-spanner-admin-database-v1/src/main/java/com/google/spanner/admin/database/v1/BackupInfoOrBuilder.java +++ b/proto-google-cloud-spanner-admin-database-v1/src/main/java/com/google/spanner/admin/database/v1/BackupInfoOrBuilder.java @@ -1,5 +1,5 @@ /* - * Copyright 2023 Google LLC + * Copyright 2024 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/proto-google-cloud-spanner-admin-database-v1/src/main/java/com/google/spanner/admin/database/v1/BackupOrBuilder.java b/proto-google-cloud-spanner-admin-database-v1/src/main/java/com/google/spanner/admin/database/v1/BackupOrBuilder.java index c7d7a6e60e2..3a228b9e222 100644 --- a/proto-google-cloud-spanner-admin-database-v1/src/main/java/com/google/spanner/admin/database/v1/BackupOrBuilder.java +++ b/proto-google-cloud-spanner-admin-database-v1/src/main/java/com/google/spanner/admin/database/v1/BackupOrBuilder.java @@ -1,5 +1,5 @@ /* - * Copyright 2023 Google LLC + * Copyright 2024 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/proto-google-cloud-spanner-admin-database-v1/src/main/java/com/google/spanner/admin/database/v1/BackupProto.java b/proto-google-cloud-spanner-admin-database-v1/src/main/java/com/google/spanner/admin/database/v1/BackupProto.java index 617e00b29b9..32abcd22825 100644 --- a/proto-google-cloud-spanner-admin-database-v1/src/main/java/com/google/spanner/admin/database/v1/BackupProto.java +++ b/proto-google-cloud-spanner-admin-database-v1/src/main/java/com/google/spanner/admin/database/v1/BackupProto.java @@ -1,5 +1,5 @@ /* - * Copyright 2023 Google LLC + * Copyright 2024 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/proto-google-cloud-spanner-admin-database-v1/src/main/java/com/google/spanner/admin/database/v1/CommonProto.java b/proto-google-cloud-spanner-admin-database-v1/src/main/java/com/google/spanner/admin/database/v1/CommonProto.java index 32077585ec4..160c6f4e200 100644 --- a/proto-google-cloud-spanner-admin-database-v1/src/main/java/com/google/spanner/admin/database/v1/CommonProto.java +++ b/proto-google-cloud-spanner-admin-database-v1/src/main/java/com/google/spanner/admin/database/v1/CommonProto.java @@ -1,5 +1,5 @@ /* - * Copyright 2023 Google LLC + * Copyright 2024 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/proto-google-cloud-spanner-admin-database-v1/src/main/java/com/google/spanner/admin/database/v1/CopyBackupEncryptionConfig.java b/proto-google-cloud-spanner-admin-database-v1/src/main/java/com/google/spanner/admin/database/v1/CopyBackupEncryptionConfig.java index 189d80f4cbb..445c4b8dccf 100644 --- a/proto-google-cloud-spanner-admin-database-v1/src/main/java/com/google/spanner/admin/database/v1/CopyBackupEncryptionConfig.java +++ b/proto-google-cloud-spanner-admin-database-v1/src/main/java/com/google/spanner/admin/database/v1/CopyBackupEncryptionConfig.java @@ -1,5 +1,5 @@ /* - * Copyright 2023 Google LLC + * Copyright 2024 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/proto-google-cloud-spanner-admin-database-v1/src/main/java/com/google/spanner/admin/database/v1/CopyBackupEncryptionConfigOrBuilder.java b/proto-google-cloud-spanner-admin-database-v1/src/main/java/com/google/spanner/admin/database/v1/CopyBackupEncryptionConfigOrBuilder.java index ad4c312b7b6..66137234c3a 100644 --- a/proto-google-cloud-spanner-admin-database-v1/src/main/java/com/google/spanner/admin/database/v1/CopyBackupEncryptionConfigOrBuilder.java +++ b/proto-google-cloud-spanner-admin-database-v1/src/main/java/com/google/spanner/admin/database/v1/CopyBackupEncryptionConfigOrBuilder.java @@ -1,5 +1,5 @@ /* - * Copyright 2023 Google LLC + * Copyright 2024 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/proto-google-cloud-spanner-admin-database-v1/src/main/java/com/google/spanner/admin/database/v1/CopyBackupMetadata.java b/proto-google-cloud-spanner-admin-database-v1/src/main/java/com/google/spanner/admin/database/v1/CopyBackupMetadata.java index ed2b5db4e68..39d29484b7e 100644 --- a/proto-google-cloud-spanner-admin-database-v1/src/main/java/com/google/spanner/admin/database/v1/CopyBackupMetadata.java +++ b/proto-google-cloud-spanner-admin-database-v1/src/main/java/com/google/spanner/admin/database/v1/CopyBackupMetadata.java @@ -1,5 +1,5 @@ /* - * Copyright 2023 Google LLC + * Copyright 2024 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/proto-google-cloud-spanner-admin-database-v1/src/main/java/com/google/spanner/admin/database/v1/CopyBackupMetadataOrBuilder.java b/proto-google-cloud-spanner-admin-database-v1/src/main/java/com/google/spanner/admin/database/v1/CopyBackupMetadataOrBuilder.java index b888c5d233c..143fc873851 100644 --- a/proto-google-cloud-spanner-admin-database-v1/src/main/java/com/google/spanner/admin/database/v1/CopyBackupMetadataOrBuilder.java +++ b/proto-google-cloud-spanner-admin-database-v1/src/main/java/com/google/spanner/admin/database/v1/CopyBackupMetadataOrBuilder.java @@ -1,5 +1,5 @@ /* - * Copyright 2023 Google LLC + * Copyright 2024 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/proto-google-cloud-spanner-admin-database-v1/src/main/java/com/google/spanner/admin/database/v1/CopyBackupRequest.java b/proto-google-cloud-spanner-admin-database-v1/src/main/java/com/google/spanner/admin/database/v1/CopyBackupRequest.java index bb321f0cf97..9db3421dbb5 100644 --- a/proto-google-cloud-spanner-admin-database-v1/src/main/java/com/google/spanner/admin/database/v1/CopyBackupRequest.java +++ b/proto-google-cloud-spanner-admin-database-v1/src/main/java/com/google/spanner/admin/database/v1/CopyBackupRequest.java @@ -1,5 +1,5 @@ /* - * Copyright 2023 Google LLC + * Copyright 2024 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/proto-google-cloud-spanner-admin-database-v1/src/main/java/com/google/spanner/admin/database/v1/CopyBackupRequestOrBuilder.java b/proto-google-cloud-spanner-admin-database-v1/src/main/java/com/google/spanner/admin/database/v1/CopyBackupRequestOrBuilder.java index 1ce1a78ee2b..496a31d533e 100644 --- a/proto-google-cloud-spanner-admin-database-v1/src/main/java/com/google/spanner/admin/database/v1/CopyBackupRequestOrBuilder.java +++ b/proto-google-cloud-spanner-admin-database-v1/src/main/java/com/google/spanner/admin/database/v1/CopyBackupRequestOrBuilder.java @@ -1,5 +1,5 @@ /* - * Copyright 2023 Google LLC + * Copyright 2024 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/proto-google-cloud-spanner-admin-database-v1/src/main/java/com/google/spanner/admin/database/v1/CreateBackupEncryptionConfig.java b/proto-google-cloud-spanner-admin-database-v1/src/main/java/com/google/spanner/admin/database/v1/CreateBackupEncryptionConfig.java index e1c679437b4..f3ece3e4ddc 100644 --- a/proto-google-cloud-spanner-admin-database-v1/src/main/java/com/google/spanner/admin/database/v1/CreateBackupEncryptionConfig.java +++ b/proto-google-cloud-spanner-admin-database-v1/src/main/java/com/google/spanner/admin/database/v1/CreateBackupEncryptionConfig.java @@ -1,5 +1,5 @@ /* - * Copyright 2023 Google LLC + * Copyright 2024 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/proto-google-cloud-spanner-admin-database-v1/src/main/java/com/google/spanner/admin/database/v1/CreateBackupEncryptionConfigOrBuilder.java b/proto-google-cloud-spanner-admin-database-v1/src/main/java/com/google/spanner/admin/database/v1/CreateBackupEncryptionConfigOrBuilder.java index 266ca42fd54..3763805ad2c 100644 --- a/proto-google-cloud-spanner-admin-database-v1/src/main/java/com/google/spanner/admin/database/v1/CreateBackupEncryptionConfigOrBuilder.java +++ b/proto-google-cloud-spanner-admin-database-v1/src/main/java/com/google/spanner/admin/database/v1/CreateBackupEncryptionConfigOrBuilder.java @@ -1,5 +1,5 @@ /* - * Copyright 2023 Google LLC + * Copyright 2024 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/proto-google-cloud-spanner-admin-database-v1/src/main/java/com/google/spanner/admin/database/v1/CreateBackupMetadata.java b/proto-google-cloud-spanner-admin-database-v1/src/main/java/com/google/spanner/admin/database/v1/CreateBackupMetadata.java index b3d0e8c71e3..4ef7b1dfe40 100644 --- a/proto-google-cloud-spanner-admin-database-v1/src/main/java/com/google/spanner/admin/database/v1/CreateBackupMetadata.java +++ b/proto-google-cloud-spanner-admin-database-v1/src/main/java/com/google/spanner/admin/database/v1/CreateBackupMetadata.java @@ -1,5 +1,5 @@ /* - * Copyright 2023 Google LLC + * Copyright 2024 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/proto-google-cloud-spanner-admin-database-v1/src/main/java/com/google/spanner/admin/database/v1/CreateBackupMetadataOrBuilder.java b/proto-google-cloud-spanner-admin-database-v1/src/main/java/com/google/spanner/admin/database/v1/CreateBackupMetadataOrBuilder.java index 35ac9312ee5..c6692033bf2 100644 --- a/proto-google-cloud-spanner-admin-database-v1/src/main/java/com/google/spanner/admin/database/v1/CreateBackupMetadataOrBuilder.java +++ b/proto-google-cloud-spanner-admin-database-v1/src/main/java/com/google/spanner/admin/database/v1/CreateBackupMetadataOrBuilder.java @@ -1,5 +1,5 @@ /* - * Copyright 2023 Google LLC + * Copyright 2024 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/proto-google-cloud-spanner-admin-database-v1/src/main/java/com/google/spanner/admin/database/v1/CreateBackupRequest.java b/proto-google-cloud-spanner-admin-database-v1/src/main/java/com/google/spanner/admin/database/v1/CreateBackupRequest.java index b8d2b57b4a3..2b9a450eda5 100644 --- a/proto-google-cloud-spanner-admin-database-v1/src/main/java/com/google/spanner/admin/database/v1/CreateBackupRequest.java +++ b/proto-google-cloud-spanner-admin-database-v1/src/main/java/com/google/spanner/admin/database/v1/CreateBackupRequest.java @@ -1,5 +1,5 @@ /* - * Copyright 2023 Google LLC + * Copyright 2024 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/proto-google-cloud-spanner-admin-database-v1/src/main/java/com/google/spanner/admin/database/v1/CreateBackupRequestOrBuilder.java b/proto-google-cloud-spanner-admin-database-v1/src/main/java/com/google/spanner/admin/database/v1/CreateBackupRequestOrBuilder.java index 0fde8792ab4..ec8d6c11ff9 100644 --- a/proto-google-cloud-spanner-admin-database-v1/src/main/java/com/google/spanner/admin/database/v1/CreateBackupRequestOrBuilder.java +++ b/proto-google-cloud-spanner-admin-database-v1/src/main/java/com/google/spanner/admin/database/v1/CreateBackupRequestOrBuilder.java @@ -1,5 +1,5 @@ /* - * Copyright 2023 Google LLC + * Copyright 2024 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/proto-google-cloud-spanner-admin-database-v1/src/main/java/com/google/spanner/admin/database/v1/CreateDatabaseMetadata.java b/proto-google-cloud-spanner-admin-database-v1/src/main/java/com/google/spanner/admin/database/v1/CreateDatabaseMetadata.java index d0c55bb862c..f30b3907a24 100644 --- a/proto-google-cloud-spanner-admin-database-v1/src/main/java/com/google/spanner/admin/database/v1/CreateDatabaseMetadata.java +++ b/proto-google-cloud-spanner-admin-database-v1/src/main/java/com/google/spanner/admin/database/v1/CreateDatabaseMetadata.java @@ -1,5 +1,5 @@ /* - * Copyright 2023 Google LLC + * Copyright 2024 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/proto-google-cloud-spanner-admin-database-v1/src/main/java/com/google/spanner/admin/database/v1/CreateDatabaseMetadataOrBuilder.java b/proto-google-cloud-spanner-admin-database-v1/src/main/java/com/google/spanner/admin/database/v1/CreateDatabaseMetadataOrBuilder.java index f63442138d0..0e86443b2ba 100644 --- a/proto-google-cloud-spanner-admin-database-v1/src/main/java/com/google/spanner/admin/database/v1/CreateDatabaseMetadataOrBuilder.java +++ b/proto-google-cloud-spanner-admin-database-v1/src/main/java/com/google/spanner/admin/database/v1/CreateDatabaseMetadataOrBuilder.java @@ -1,5 +1,5 @@ /* - * Copyright 2023 Google LLC + * Copyright 2024 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/proto-google-cloud-spanner-admin-database-v1/src/main/java/com/google/spanner/admin/database/v1/CreateDatabaseRequest.java b/proto-google-cloud-spanner-admin-database-v1/src/main/java/com/google/spanner/admin/database/v1/CreateDatabaseRequest.java index 54065db2840..439e89fdfb6 100644 --- a/proto-google-cloud-spanner-admin-database-v1/src/main/java/com/google/spanner/admin/database/v1/CreateDatabaseRequest.java +++ b/proto-google-cloud-spanner-admin-database-v1/src/main/java/com/google/spanner/admin/database/v1/CreateDatabaseRequest.java @@ -1,5 +1,5 @@ /* - * Copyright 2023 Google LLC + * Copyright 2024 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -42,6 +42,7 @@ private CreateDatabaseRequest() { createStatement_ = ""; extraStatements_ = com.google.protobuf.LazyStringArrayList.emptyList(); databaseDialect_ = 0; + protoDescriptors_ = com.google.protobuf.ByteString.EMPTY; } @java.lang.Override @@ -361,6 +362,38 @@ public com.google.spanner.admin.database.v1.DatabaseDialect getDatabaseDialect() : result; } + public static final int PROTO_DESCRIPTORS_FIELD_NUMBER = 6; + private com.google.protobuf.ByteString protoDescriptors_ = com.google.protobuf.ByteString.EMPTY; + /** + * + * + *

+   * Optional. Proto descriptors used by CREATE/ALTER PROTO BUNDLE statements in
+   * 'extra_statements' above.
+   * Contains a protobuf-serialized
+   * [google.protobuf.FileDescriptorSet](https://github.com/protocolbuffers/protobuf/blob/main/src/google/protobuf/descriptor.proto).
+   * To generate it, [install](https://grpc.io/docs/protoc-installation/) and
+   * run `protoc` with --include_imports and --descriptor_set_out. For example,
+   * to generate for moon/shot/app.proto, run
+   * ```
+   * $protoc  --proto_path=/app_path --proto_path=/lib_path \
+   *          --include_imports \
+   *          --descriptor_set_out=descriptors.data \
+   *          moon/shot/app.proto
+   * ```
+   * For more details, see protobuffer [self
+   * description](https://developers.google.com/protocol-buffers/docs/techniques#self-description).
+   * 
+ * + * bytes proto_descriptors = 6 [(.google.api.field_behavior) = OPTIONAL]; + * + * @return The protoDescriptors. + */ + @java.lang.Override + public com.google.protobuf.ByteString getProtoDescriptors() { + return protoDescriptors_; + } + private byte memoizedIsInitialized = -1; @java.lang.Override @@ -392,6 +425,9 @@ public void writeTo(com.google.protobuf.CodedOutputStream output) throws java.io .getNumber()) { output.writeEnum(5, databaseDialect_); } + if (!protoDescriptors_.isEmpty()) { + output.writeBytes(6, protoDescriptors_); + } getUnknownFields().writeTo(output); } @@ -423,6 +459,9 @@ public int getSerializedSize() { .getNumber()) { size += com.google.protobuf.CodedOutputStream.computeEnumSize(5, databaseDialect_); } + if (!protoDescriptors_.isEmpty()) { + size += com.google.protobuf.CodedOutputStream.computeBytesSize(6, protoDescriptors_); + } size += getUnknownFields().getSerializedSize(); memoizedSize = size; return size; @@ -447,6 +486,7 @@ public boolean equals(final java.lang.Object obj) { if (!getEncryptionConfig().equals(other.getEncryptionConfig())) return false; } if (databaseDialect_ != other.databaseDialect_) return false; + if (!getProtoDescriptors().equals(other.getProtoDescriptors())) return false; if (!getUnknownFields().equals(other.getUnknownFields())) return false; return true; } @@ -472,6 +512,8 @@ public int hashCode() { } hash = (37 * hash) + DATABASE_DIALECT_FIELD_NUMBER; hash = (53 * hash) + databaseDialect_; + hash = (37 * hash) + PROTO_DESCRIPTORS_FIELD_NUMBER; + hash = (53 * hash) + getProtoDescriptors().hashCode(); hash = (29 * hash) + getUnknownFields().hashCode(); memoizedHashCode = hash; return hash; @@ -621,6 +663,7 @@ public Builder clear() { encryptionConfigBuilder_ = null; } databaseDialect_ = 0; + protoDescriptors_ = com.google.protobuf.ByteString.EMPTY; return this; } @@ -674,6 +717,9 @@ private void buildPartial0(com.google.spanner.admin.database.v1.CreateDatabaseRe if (((from_bitField0_ & 0x00000010) != 0)) { result.databaseDialect_ = databaseDialect_; } + if (((from_bitField0_ & 0x00000020) != 0)) { + result.protoDescriptors_ = protoDescriptors_; + } } @java.lang.Override @@ -748,6 +794,9 @@ public Builder mergeFrom(com.google.spanner.admin.database.v1.CreateDatabaseRequ if (other.databaseDialect_ != 0) { setDatabaseDialectValue(other.getDatabaseDialectValue()); } + if (other.getProtoDescriptors() != com.google.protobuf.ByteString.EMPTY) { + setProtoDescriptors(other.getProtoDescriptors()); + } this.mergeUnknownFields(other.getUnknownFields()); onChanged(); return this; @@ -806,6 +855,12 @@ public Builder mergeFrom( bitField0_ |= 0x00000010; break; } // case 40 + case 50: + { + protoDescriptors_ = input.readBytes(); + bitField0_ |= 0x00000020; + break; + } // case 50 default: { if (!super.parseUnknownField(input, extensionRegistry, tag)) { @@ -1600,6 +1655,103 @@ public Builder clearDatabaseDialect() { return this; } + private com.google.protobuf.ByteString protoDescriptors_ = com.google.protobuf.ByteString.EMPTY; + /** + * + * + *
+     * Optional. Proto descriptors used by CREATE/ALTER PROTO BUNDLE statements in
+     * 'extra_statements' above.
+     * Contains a protobuf-serialized
+     * [google.protobuf.FileDescriptorSet](https://github.com/protocolbuffers/protobuf/blob/main/src/google/protobuf/descriptor.proto).
+     * To generate it, [install](https://grpc.io/docs/protoc-installation/) and
+     * run `protoc` with --include_imports and --descriptor_set_out. For example,
+     * to generate for moon/shot/app.proto, run
+     * ```
+     * $protoc  --proto_path=/app_path --proto_path=/lib_path \
+     *          --include_imports \
+     *          --descriptor_set_out=descriptors.data \
+     *          moon/shot/app.proto
+     * ```
+     * For more details, see protobuffer [self
+     * description](https://developers.google.com/protocol-buffers/docs/techniques#self-description).
+     * 
+ * + * bytes proto_descriptors = 6 [(.google.api.field_behavior) = OPTIONAL]; + * + * @return The protoDescriptors. + */ + @java.lang.Override + public com.google.protobuf.ByteString getProtoDescriptors() { + return protoDescriptors_; + } + /** + * + * + *
+     * Optional. Proto descriptors used by CREATE/ALTER PROTO BUNDLE statements in
+     * 'extra_statements' above.
+     * Contains a protobuf-serialized
+     * [google.protobuf.FileDescriptorSet](https://github.com/protocolbuffers/protobuf/blob/main/src/google/protobuf/descriptor.proto).
+     * To generate it, [install](https://grpc.io/docs/protoc-installation/) and
+     * run `protoc` with --include_imports and --descriptor_set_out. For example,
+     * to generate for moon/shot/app.proto, run
+     * ```
+     * $protoc  --proto_path=/app_path --proto_path=/lib_path \
+     *          --include_imports \
+     *          --descriptor_set_out=descriptors.data \
+     *          moon/shot/app.proto
+     * ```
+     * For more details, see protobuffer [self
+     * description](https://developers.google.com/protocol-buffers/docs/techniques#self-description).
+     * 
+ * + * bytes proto_descriptors = 6 [(.google.api.field_behavior) = OPTIONAL]; + * + * @param value The protoDescriptors to set. + * @return This builder for chaining. + */ + public Builder setProtoDescriptors(com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + protoDescriptors_ = value; + bitField0_ |= 0x00000020; + onChanged(); + return this; + } + /** + * + * + *
+     * Optional. Proto descriptors used by CREATE/ALTER PROTO BUNDLE statements in
+     * 'extra_statements' above.
+     * Contains a protobuf-serialized
+     * [google.protobuf.FileDescriptorSet](https://github.com/protocolbuffers/protobuf/blob/main/src/google/protobuf/descriptor.proto).
+     * To generate it, [install](https://grpc.io/docs/protoc-installation/) and
+     * run `protoc` with --include_imports and --descriptor_set_out. For example,
+     * to generate for moon/shot/app.proto, run
+     * ```
+     * $protoc  --proto_path=/app_path --proto_path=/lib_path \
+     *          --include_imports \
+     *          --descriptor_set_out=descriptors.data \
+     *          moon/shot/app.proto
+     * ```
+     * For more details, see protobuffer [self
+     * description](https://developers.google.com/protocol-buffers/docs/techniques#self-description).
+     * 
+ * + * bytes proto_descriptors = 6 [(.google.api.field_behavior) = OPTIONAL]; + * + * @return This builder for chaining. + */ + public Builder clearProtoDescriptors() { + bitField0_ = (bitField0_ & ~0x00000020); + protoDescriptors_ = getDefaultInstance().getProtoDescriptors(); + onChanged(); + return this; + } + @java.lang.Override public final Builder setUnknownFields(final com.google.protobuf.UnknownFieldSet unknownFields) { return super.setUnknownFields(unknownFields); diff --git a/proto-google-cloud-spanner-admin-database-v1/src/main/java/com/google/spanner/admin/database/v1/CreateDatabaseRequestOrBuilder.java b/proto-google-cloud-spanner-admin-database-v1/src/main/java/com/google/spanner/admin/database/v1/CreateDatabaseRequestOrBuilder.java index 2a71d1e2808..aa756e03c3a 100644 --- a/proto-google-cloud-spanner-admin-database-v1/src/main/java/com/google/spanner/admin/database/v1/CreateDatabaseRequestOrBuilder.java +++ b/proto-google-cloud-spanner-admin-database-v1/src/main/java/com/google/spanner/admin/database/v1/CreateDatabaseRequestOrBuilder.java @@ -1,5 +1,5 @@ /* - * Copyright 2023 Google LLC + * Copyright 2024 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -225,4 +225,31 @@ public interface CreateDatabaseRequestOrBuilder * @return The databaseDialect. */ com.google.spanner.admin.database.v1.DatabaseDialect getDatabaseDialect(); + + /** + * + * + *
+   * Optional. Proto descriptors used by CREATE/ALTER PROTO BUNDLE statements in
+   * 'extra_statements' above.
+   * Contains a protobuf-serialized
+   * [google.protobuf.FileDescriptorSet](https://github.com/protocolbuffers/protobuf/blob/main/src/google/protobuf/descriptor.proto).
+   * To generate it, [install](https://grpc.io/docs/protoc-installation/) and
+   * run `protoc` with --include_imports and --descriptor_set_out. For example,
+   * to generate for moon/shot/app.proto, run
+   * ```
+   * $protoc  --proto_path=/app_path --proto_path=/lib_path \
+   *          --include_imports \
+   *          --descriptor_set_out=descriptors.data \
+   *          moon/shot/app.proto
+   * ```
+   * For more details, see protobuffer [self
+   * description](https://developers.google.com/protocol-buffers/docs/techniques#self-description).
+   * 
+ * + * bytes proto_descriptors = 6 [(.google.api.field_behavior) = OPTIONAL]; + * + * @return The protoDescriptors. + */ + com.google.protobuf.ByteString getProtoDescriptors(); } diff --git a/proto-google-cloud-spanner-admin-database-v1/src/main/java/com/google/spanner/admin/database/v1/Database.java b/proto-google-cloud-spanner-admin-database-v1/src/main/java/com/google/spanner/admin/database/v1/Database.java index ab488e87b81..4f95d642696 100644 --- a/proto-google-cloud-spanner-admin-database-v1/src/main/java/com/google/spanner/admin/database/v1/Database.java +++ b/proto-google-cloud-spanner-admin-database-v1/src/main/java/com/google/spanner/admin/database/v1/Database.java @@ -1,5 +1,5 @@ /* - * Copyright 2023 Google LLC + * Copyright 2024 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/proto-google-cloud-spanner-admin-database-v1/src/main/java/com/google/spanner/admin/database/v1/DatabaseDialect.java b/proto-google-cloud-spanner-admin-database-v1/src/main/java/com/google/spanner/admin/database/v1/DatabaseDialect.java index 1c8a6f37a26..188070a6d65 100644 --- a/proto-google-cloud-spanner-admin-database-v1/src/main/java/com/google/spanner/admin/database/v1/DatabaseDialect.java +++ b/proto-google-cloud-spanner-admin-database-v1/src/main/java/com/google/spanner/admin/database/v1/DatabaseDialect.java @@ -1,5 +1,5 @@ /* - * Copyright 2023 Google LLC + * Copyright 2024 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/proto-google-cloud-spanner-admin-database-v1/src/main/java/com/google/spanner/admin/database/v1/DatabaseOrBuilder.java b/proto-google-cloud-spanner-admin-database-v1/src/main/java/com/google/spanner/admin/database/v1/DatabaseOrBuilder.java index 860ac8d9d73..eb64c44abc3 100644 --- a/proto-google-cloud-spanner-admin-database-v1/src/main/java/com/google/spanner/admin/database/v1/DatabaseOrBuilder.java +++ b/proto-google-cloud-spanner-admin-database-v1/src/main/java/com/google/spanner/admin/database/v1/DatabaseOrBuilder.java @@ -1,5 +1,5 @@ /* - * Copyright 2023 Google LLC + * Copyright 2024 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/proto-google-cloud-spanner-admin-database-v1/src/main/java/com/google/spanner/admin/database/v1/DatabaseRole.java b/proto-google-cloud-spanner-admin-database-v1/src/main/java/com/google/spanner/admin/database/v1/DatabaseRole.java index 8518141cf47..c8f58eed3cd 100644 --- a/proto-google-cloud-spanner-admin-database-v1/src/main/java/com/google/spanner/admin/database/v1/DatabaseRole.java +++ b/proto-google-cloud-spanner-admin-database-v1/src/main/java/com/google/spanner/admin/database/v1/DatabaseRole.java @@ -1,5 +1,5 @@ /* - * Copyright 2023 Google LLC + * Copyright 2024 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/proto-google-cloud-spanner-admin-database-v1/src/main/java/com/google/spanner/admin/database/v1/DatabaseRoleOrBuilder.java b/proto-google-cloud-spanner-admin-database-v1/src/main/java/com/google/spanner/admin/database/v1/DatabaseRoleOrBuilder.java index cc15677e0dd..23a276eb710 100644 --- a/proto-google-cloud-spanner-admin-database-v1/src/main/java/com/google/spanner/admin/database/v1/DatabaseRoleOrBuilder.java +++ b/proto-google-cloud-spanner-admin-database-v1/src/main/java/com/google/spanner/admin/database/v1/DatabaseRoleOrBuilder.java @@ -1,5 +1,5 @@ /* - * Copyright 2023 Google LLC + * Copyright 2024 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/proto-google-cloud-spanner-admin-database-v1/src/main/java/com/google/spanner/admin/database/v1/DdlStatementActionInfo.java b/proto-google-cloud-spanner-admin-database-v1/src/main/java/com/google/spanner/admin/database/v1/DdlStatementActionInfo.java index 0c5e9ceea38..a074693c0d6 100644 --- a/proto-google-cloud-spanner-admin-database-v1/src/main/java/com/google/spanner/admin/database/v1/DdlStatementActionInfo.java +++ b/proto-google-cloud-spanner-admin-database-v1/src/main/java/com/google/spanner/admin/database/v1/DdlStatementActionInfo.java @@ -1,5 +1,5 @@ /* - * Copyright 2023 Google LLC + * Copyright 2024 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/proto-google-cloud-spanner-admin-database-v1/src/main/java/com/google/spanner/admin/database/v1/DdlStatementActionInfoOrBuilder.java b/proto-google-cloud-spanner-admin-database-v1/src/main/java/com/google/spanner/admin/database/v1/DdlStatementActionInfoOrBuilder.java index 5e9ad55d53b..f9007075e50 100644 --- a/proto-google-cloud-spanner-admin-database-v1/src/main/java/com/google/spanner/admin/database/v1/DdlStatementActionInfoOrBuilder.java +++ b/proto-google-cloud-spanner-admin-database-v1/src/main/java/com/google/spanner/admin/database/v1/DdlStatementActionInfoOrBuilder.java @@ -1,5 +1,5 @@ /* - * Copyright 2023 Google LLC + * Copyright 2024 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/proto-google-cloud-spanner-admin-database-v1/src/main/java/com/google/spanner/admin/database/v1/DeleteBackupRequest.java b/proto-google-cloud-spanner-admin-database-v1/src/main/java/com/google/spanner/admin/database/v1/DeleteBackupRequest.java index ba8a0bad913..61ad6932973 100644 --- a/proto-google-cloud-spanner-admin-database-v1/src/main/java/com/google/spanner/admin/database/v1/DeleteBackupRequest.java +++ b/proto-google-cloud-spanner-admin-database-v1/src/main/java/com/google/spanner/admin/database/v1/DeleteBackupRequest.java @@ -1,5 +1,5 @@ /* - * Copyright 2023 Google LLC + * Copyright 2024 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/proto-google-cloud-spanner-admin-database-v1/src/main/java/com/google/spanner/admin/database/v1/DeleteBackupRequestOrBuilder.java b/proto-google-cloud-spanner-admin-database-v1/src/main/java/com/google/spanner/admin/database/v1/DeleteBackupRequestOrBuilder.java index b6d592f7164..6e741f3c9d3 100644 --- a/proto-google-cloud-spanner-admin-database-v1/src/main/java/com/google/spanner/admin/database/v1/DeleteBackupRequestOrBuilder.java +++ b/proto-google-cloud-spanner-admin-database-v1/src/main/java/com/google/spanner/admin/database/v1/DeleteBackupRequestOrBuilder.java @@ -1,5 +1,5 @@ /* - * Copyright 2023 Google LLC + * Copyright 2024 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/proto-google-cloud-spanner-admin-database-v1/src/main/java/com/google/spanner/admin/database/v1/DropDatabaseRequest.java b/proto-google-cloud-spanner-admin-database-v1/src/main/java/com/google/spanner/admin/database/v1/DropDatabaseRequest.java index f5708ef9c41..09454ce896b 100644 --- a/proto-google-cloud-spanner-admin-database-v1/src/main/java/com/google/spanner/admin/database/v1/DropDatabaseRequest.java +++ b/proto-google-cloud-spanner-admin-database-v1/src/main/java/com/google/spanner/admin/database/v1/DropDatabaseRequest.java @@ -1,5 +1,5 @@ /* - * Copyright 2023 Google LLC + * Copyright 2024 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/proto-google-cloud-spanner-admin-database-v1/src/main/java/com/google/spanner/admin/database/v1/DropDatabaseRequestOrBuilder.java b/proto-google-cloud-spanner-admin-database-v1/src/main/java/com/google/spanner/admin/database/v1/DropDatabaseRequestOrBuilder.java index 76701950637..837a3f8aad1 100644 --- a/proto-google-cloud-spanner-admin-database-v1/src/main/java/com/google/spanner/admin/database/v1/DropDatabaseRequestOrBuilder.java +++ b/proto-google-cloud-spanner-admin-database-v1/src/main/java/com/google/spanner/admin/database/v1/DropDatabaseRequestOrBuilder.java @@ -1,5 +1,5 @@ /* - * Copyright 2023 Google LLC + * Copyright 2024 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/proto-google-cloud-spanner-admin-database-v1/src/main/java/com/google/spanner/admin/database/v1/EncryptionConfig.java b/proto-google-cloud-spanner-admin-database-v1/src/main/java/com/google/spanner/admin/database/v1/EncryptionConfig.java index 7413956be14..b50ba4d39e4 100644 --- a/proto-google-cloud-spanner-admin-database-v1/src/main/java/com/google/spanner/admin/database/v1/EncryptionConfig.java +++ b/proto-google-cloud-spanner-admin-database-v1/src/main/java/com/google/spanner/admin/database/v1/EncryptionConfig.java @@ -1,5 +1,5 @@ /* - * Copyright 2023 Google LLC + * Copyright 2024 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/proto-google-cloud-spanner-admin-database-v1/src/main/java/com/google/spanner/admin/database/v1/EncryptionConfigOrBuilder.java b/proto-google-cloud-spanner-admin-database-v1/src/main/java/com/google/spanner/admin/database/v1/EncryptionConfigOrBuilder.java index 34b1811b5c5..a4225837277 100644 --- a/proto-google-cloud-spanner-admin-database-v1/src/main/java/com/google/spanner/admin/database/v1/EncryptionConfigOrBuilder.java +++ b/proto-google-cloud-spanner-admin-database-v1/src/main/java/com/google/spanner/admin/database/v1/EncryptionConfigOrBuilder.java @@ -1,5 +1,5 @@ /* - * Copyright 2023 Google LLC + * Copyright 2024 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/proto-google-cloud-spanner-admin-database-v1/src/main/java/com/google/spanner/admin/database/v1/EncryptionInfo.java b/proto-google-cloud-spanner-admin-database-v1/src/main/java/com/google/spanner/admin/database/v1/EncryptionInfo.java index 6f7ff1958d5..deeaa859ae1 100644 --- a/proto-google-cloud-spanner-admin-database-v1/src/main/java/com/google/spanner/admin/database/v1/EncryptionInfo.java +++ b/proto-google-cloud-spanner-admin-database-v1/src/main/java/com/google/spanner/admin/database/v1/EncryptionInfo.java @@ -1,5 +1,5 @@ /* - * Copyright 2023 Google LLC + * Copyright 2024 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/proto-google-cloud-spanner-admin-database-v1/src/main/java/com/google/spanner/admin/database/v1/EncryptionInfoOrBuilder.java b/proto-google-cloud-spanner-admin-database-v1/src/main/java/com/google/spanner/admin/database/v1/EncryptionInfoOrBuilder.java index f08cca64b75..f10242165d1 100644 --- a/proto-google-cloud-spanner-admin-database-v1/src/main/java/com/google/spanner/admin/database/v1/EncryptionInfoOrBuilder.java +++ b/proto-google-cloud-spanner-admin-database-v1/src/main/java/com/google/spanner/admin/database/v1/EncryptionInfoOrBuilder.java @@ -1,5 +1,5 @@ /* - * Copyright 2023 Google LLC + * Copyright 2024 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/proto-google-cloud-spanner-admin-database-v1/src/main/java/com/google/spanner/admin/database/v1/GetBackupRequest.java b/proto-google-cloud-spanner-admin-database-v1/src/main/java/com/google/spanner/admin/database/v1/GetBackupRequest.java index 2f42294375e..78f179aeab9 100644 --- a/proto-google-cloud-spanner-admin-database-v1/src/main/java/com/google/spanner/admin/database/v1/GetBackupRequest.java +++ b/proto-google-cloud-spanner-admin-database-v1/src/main/java/com/google/spanner/admin/database/v1/GetBackupRequest.java @@ -1,5 +1,5 @@ /* - * Copyright 2023 Google LLC + * Copyright 2024 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/proto-google-cloud-spanner-admin-database-v1/src/main/java/com/google/spanner/admin/database/v1/GetBackupRequestOrBuilder.java b/proto-google-cloud-spanner-admin-database-v1/src/main/java/com/google/spanner/admin/database/v1/GetBackupRequestOrBuilder.java index 7973d261061..93f49963ea3 100644 --- a/proto-google-cloud-spanner-admin-database-v1/src/main/java/com/google/spanner/admin/database/v1/GetBackupRequestOrBuilder.java +++ b/proto-google-cloud-spanner-admin-database-v1/src/main/java/com/google/spanner/admin/database/v1/GetBackupRequestOrBuilder.java @@ -1,5 +1,5 @@ /* - * Copyright 2023 Google LLC + * Copyright 2024 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/proto-google-cloud-spanner-admin-database-v1/src/main/java/com/google/spanner/admin/database/v1/GetDatabaseDdlRequest.java b/proto-google-cloud-spanner-admin-database-v1/src/main/java/com/google/spanner/admin/database/v1/GetDatabaseDdlRequest.java index 3447e8ac1c2..19a564cd4dc 100644 --- a/proto-google-cloud-spanner-admin-database-v1/src/main/java/com/google/spanner/admin/database/v1/GetDatabaseDdlRequest.java +++ b/proto-google-cloud-spanner-admin-database-v1/src/main/java/com/google/spanner/admin/database/v1/GetDatabaseDdlRequest.java @@ -1,5 +1,5 @@ /* - * Copyright 2023 Google LLC + * Copyright 2024 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/proto-google-cloud-spanner-admin-database-v1/src/main/java/com/google/spanner/admin/database/v1/GetDatabaseDdlRequestOrBuilder.java b/proto-google-cloud-spanner-admin-database-v1/src/main/java/com/google/spanner/admin/database/v1/GetDatabaseDdlRequestOrBuilder.java index 3520a2333b0..59e9312a816 100644 --- a/proto-google-cloud-spanner-admin-database-v1/src/main/java/com/google/spanner/admin/database/v1/GetDatabaseDdlRequestOrBuilder.java +++ b/proto-google-cloud-spanner-admin-database-v1/src/main/java/com/google/spanner/admin/database/v1/GetDatabaseDdlRequestOrBuilder.java @@ -1,5 +1,5 @@ /* - * Copyright 2023 Google LLC + * Copyright 2024 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/proto-google-cloud-spanner-admin-database-v1/src/main/java/com/google/spanner/admin/database/v1/GetDatabaseDdlResponse.java b/proto-google-cloud-spanner-admin-database-v1/src/main/java/com/google/spanner/admin/database/v1/GetDatabaseDdlResponse.java index b35f72c212c..0aaa9ab3354 100644 --- a/proto-google-cloud-spanner-admin-database-v1/src/main/java/com/google/spanner/admin/database/v1/GetDatabaseDdlResponse.java +++ b/proto-google-cloud-spanner-admin-database-v1/src/main/java/com/google/spanner/admin/database/v1/GetDatabaseDdlResponse.java @@ -1,5 +1,5 @@ /* - * Copyright 2023 Google LLC + * Copyright 2024 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -39,6 +39,7 @@ private GetDatabaseDdlResponse(com.google.protobuf.GeneratedMessageV3.Builder private GetDatabaseDdlResponse() { statements_ = com.google.protobuf.LazyStringArrayList.emptyList(); + protoDescriptors_ = com.google.protobuf.ByteString.EMPTY; } @java.lang.Override @@ -130,6 +131,28 @@ public com.google.protobuf.ByteString getStatementsBytes(int index) { return statements_.getByteString(index); } + public static final int PROTO_DESCRIPTORS_FIELD_NUMBER = 2; + private com.google.protobuf.ByteString protoDescriptors_ = com.google.protobuf.ByteString.EMPTY; + /** + * + * + *
+   * Proto descriptors stored in the database.
+   * Contains a protobuf-serialized
+   * [google.protobuf.FileDescriptorSet](https://github.com/protocolbuffers/protobuf/blob/main/src/google/protobuf/descriptor.proto).
+   * For more details, see protobuffer [self
+   * description](https://developers.google.com/protocol-buffers/docs/techniques#self-description).
+   * 
+ * + * bytes proto_descriptors = 2; + * + * @return The protoDescriptors. + */ + @java.lang.Override + public com.google.protobuf.ByteString getProtoDescriptors() { + return protoDescriptors_; + } + private byte memoizedIsInitialized = -1; @java.lang.Override @@ -147,6 +170,9 @@ public void writeTo(com.google.protobuf.CodedOutputStream output) throws java.io for (int i = 0; i < statements_.size(); i++) { com.google.protobuf.GeneratedMessageV3.writeString(output, 1, statements_.getRaw(i)); } + if (!protoDescriptors_.isEmpty()) { + output.writeBytes(2, protoDescriptors_); + } getUnknownFields().writeTo(output); } @@ -164,6 +190,9 @@ public int getSerializedSize() { size += dataSize; size += 1 * getStatementsList().size(); } + if (!protoDescriptors_.isEmpty()) { + size += com.google.protobuf.CodedOutputStream.computeBytesSize(2, protoDescriptors_); + } size += getUnknownFields().getSerializedSize(); memoizedSize = size; return size; @@ -181,6 +210,7 @@ public boolean equals(final java.lang.Object obj) { (com.google.spanner.admin.database.v1.GetDatabaseDdlResponse) obj; if (!getStatementsList().equals(other.getStatementsList())) return false; + if (!getProtoDescriptors().equals(other.getProtoDescriptors())) return false; if (!getUnknownFields().equals(other.getUnknownFields())) return false; return true; } @@ -196,6 +226,8 @@ public int hashCode() { hash = (37 * hash) + STATEMENTS_FIELD_NUMBER; hash = (53 * hash) + getStatementsList().hashCode(); } + hash = (37 * hash) + PROTO_DESCRIPTORS_FIELD_NUMBER; + hash = (53 * hash) + getProtoDescriptors().hashCode(); hash = (29 * hash) + getUnknownFields().hashCode(); memoizedHashCode = hash; return hash; @@ -337,6 +369,7 @@ public Builder clear() { super.clear(); bitField0_ = 0; statements_ = com.google.protobuf.LazyStringArrayList.emptyList(); + protoDescriptors_ = com.google.protobuf.ByteString.EMPTY; return this; } @@ -377,6 +410,9 @@ private void buildPartial0(com.google.spanner.admin.database.v1.GetDatabaseDdlRe statements_.makeImmutable(); result.statements_ = statements_; } + if (((from_bitField0_ & 0x00000002) != 0)) { + result.protoDescriptors_ = protoDescriptors_; + } } @java.lang.Override @@ -435,6 +471,9 @@ public Builder mergeFrom(com.google.spanner.admin.database.v1.GetDatabaseDdlResp } onChanged(); } + if (other.getProtoDescriptors() != com.google.protobuf.ByteString.EMPTY) { + setProtoDescriptors(other.getProtoDescriptors()); + } this.mergeUnknownFields(other.getUnknownFields()); onChanged(); return this; @@ -468,6 +507,12 @@ public Builder mergeFrom( statements_.add(s); break; } // case 10 + case 18: + { + protoDescriptors_ = input.readBytes(); + bitField0_ |= 0x00000002; + break; + } // case 18 default: { if (!super.parseUnknownField(input, extensionRegistry, tag)) { @@ -670,6 +715,73 @@ public Builder addStatementsBytes(com.google.protobuf.ByteString value) { return this; } + private com.google.protobuf.ByteString protoDescriptors_ = com.google.protobuf.ByteString.EMPTY; + /** + * + * + *
+     * Proto descriptors stored in the database.
+     * Contains a protobuf-serialized
+     * [google.protobuf.FileDescriptorSet](https://github.com/protocolbuffers/protobuf/blob/main/src/google/protobuf/descriptor.proto).
+     * For more details, see protobuffer [self
+     * description](https://developers.google.com/protocol-buffers/docs/techniques#self-description).
+     * 
+ * + * bytes proto_descriptors = 2; + * + * @return The protoDescriptors. + */ + @java.lang.Override + public com.google.protobuf.ByteString getProtoDescriptors() { + return protoDescriptors_; + } + /** + * + * + *
+     * Proto descriptors stored in the database.
+     * Contains a protobuf-serialized
+     * [google.protobuf.FileDescriptorSet](https://github.com/protocolbuffers/protobuf/blob/main/src/google/protobuf/descriptor.proto).
+     * For more details, see protobuffer [self
+     * description](https://developers.google.com/protocol-buffers/docs/techniques#self-description).
+     * 
+ * + * bytes proto_descriptors = 2; + * + * @param value The protoDescriptors to set. + * @return This builder for chaining. + */ + public Builder setProtoDescriptors(com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + protoDescriptors_ = value; + bitField0_ |= 0x00000002; + onChanged(); + return this; + } + /** + * + * + *
+     * Proto descriptors stored in the database.
+     * Contains a protobuf-serialized
+     * [google.protobuf.FileDescriptorSet](https://github.com/protocolbuffers/protobuf/blob/main/src/google/protobuf/descriptor.proto).
+     * For more details, see protobuffer [self
+     * description](https://developers.google.com/protocol-buffers/docs/techniques#self-description).
+     * 
+ * + * bytes proto_descriptors = 2; + * + * @return This builder for chaining. + */ + public Builder clearProtoDescriptors() { + bitField0_ = (bitField0_ & ~0x00000002); + protoDescriptors_ = getDefaultInstance().getProtoDescriptors(); + onChanged(); + return this; + } + @java.lang.Override public final Builder setUnknownFields(final com.google.protobuf.UnknownFieldSet unknownFields) { return super.setUnknownFields(unknownFields); diff --git a/proto-google-cloud-spanner-admin-database-v1/src/main/java/com/google/spanner/admin/database/v1/GetDatabaseDdlResponseOrBuilder.java b/proto-google-cloud-spanner-admin-database-v1/src/main/java/com/google/spanner/admin/database/v1/GetDatabaseDdlResponseOrBuilder.java index c436d5c844f..e972c5faa9d 100644 --- a/proto-google-cloud-spanner-admin-database-v1/src/main/java/com/google/spanner/admin/database/v1/GetDatabaseDdlResponseOrBuilder.java +++ b/proto-google-cloud-spanner-admin-database-v1/src/main/java/com/google/spanner/admin/database/v1/GetDatabaseDdlResponseOrBuilder.java @@ -1,5 +1,5 @@ /* - * Copyright 2023 Google LLC + * Copyright 2024 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -77,4 +77,21 @@ public interface GetDatabaseDdlResponseOrBuilder * @return The bytes of the statements at the given index. */ com.google.protobuf.ByteString getStatementsBytes(int index); + + /** + * + * + *
+   * Proto descriptors stored in the database.
+   * Contains a protobuf-serialized
+   * [google.protobuf.FileDescriptorSet](https://github.com/protocolbuffers/protobuf/blob/main/src/google/protobuf/descriptor.proto).
+   * For more details, see protobuffer [self
+   * description](https://developers.google.com/protocol-buffers/docs/techniques#self-description).
+   * 
+ * + * bytes proto_descriptors = 2; + * + * @return The protoDescriptors. + */ + com.google.protobuf.ByteString getProtoDescriptors(); } diff --git a/proto-google-cloud-spanner-admin-database-v1/src/main/java/com/google/spanner/admin/database/v1/GetDatabaseRequest.java b/proto-google-cloud-spanner-admin-database-v1/src/main/java/com/google/spanner/admin/database/v1/GetDatabaseRequest.java index 9d8c2aa67f5..d9e26ee2e63 100644 --- a/proto-google-cloud-spanner-admin-database-v1/src/main/java/com/google/spanner/admin/database/v1/GetDatabaseRequest.java +++ b/proto-google-cloud-spanner-admin-database-v1/src/main/java/com/google/spanner/admin/database/v1/GetDatabaseRequest.java @@ -1,5 +1,5 @@ /* - * Copyright 2023 Google LLC + * Copyright 2024 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/proto-google-cloud-spanner-admin-database-v1/src/main/java/com/google/spanner/admin/database/v1/GetDatabaseRequestOrBuilder.java b/proto-google-cloud-spanner-admin-database-v1/src/main/java/com/google/spanner/admin/database/v1/GetDatabaseRequestOrBuilder.java index 1f8d75ff8f8..42524b6d2f4 100644 --- a/proto-google-cloud-spanner-admin-database-v1/src/main/java/com/google/spanner/admin/database/v1/GetDatabaseRequestOrBuilder.java +++ b/proto-google-cloud-spanner-admin-database-v1/src/main/java/com/google/spanner/admin/database/v1/GetDatabaseRequestOrBuilder.java @@ -1,5 +1,5 @@ /* - * Copyright 2023 Google LLC + * Copyright 2024 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/proto-google-cloud-spanner-admin-database-v1/src/main/java/com/google/spanner/admin/database/v1/ListBackupOperationsRequest.java b/proto-google-cloud-spanner-admin-database-v1/src/main/java/com/google/spanner/admin/database/v1/ListBackupOperationsRequest.java index f7a89b62763..d9cae43e3df 100644 --- a/proto-google-cloud-spanner-admin-database-v1/src/main/java/com/google/spanner/admin/database/v1/ListBackupOperationsRequest.java +++ b/proto-google-cloud-spanner-admin-database-v1/src/main/java/com/google/spanner/admin/database/v1/ListBackupOperationsRequest.java @@ -1,5 +1,5 @@ /* - * Copyright 2023 Google LLC + * Copyright 2024 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/proto-google-cloud-spanner-admin-database-v1/src/main/java/com/google/spanner/admin/database/v1/ListBackupOperationsRequestOrBuilder.java b/proto-google-cloud-spanner-admin-database-v1/src/main/java/com/google/spanner/admin/database/v1/ListBackupOperationsRequestOrBuilder.java index 4255d075607..1b6e0133c34 100644 --- a/proto-google-cloud-spanner-admin-database-v1/src/main/java/com/google/spanner/admin/database/v1/ListBackupOperationsRequestOrBuilder.java +++ b/proto-google-cloud-spanner-admin-database-v1/src/main/java/com/google/spanner/admin/database/v1/ListBackupOperationsRequestOrBuilder.java @@ -1,5 +1,5 @@ /* - * Copyright 2023 Google LLC + * Copyright 2024 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/proto-google-cloud-spanner-admin-database-v1/src/main/java/com/google/spanner/admin/database/v1/ListBackupOperationsResponse.java b/proto-google-cloud-spanner-admin-database-v1/src/main/java/com/google/spanner/admin/database/v1/ListBackupOperationsResponse.java index 119484dffb1..69b61c9945e 100644 --- a/proto-google-cloud-spanner-admin-database-v1/src/main/java/com/google/spanner/admin/database/v1/ListBackupOperationsResponse.java +++ b/proto-google-cloud-spanner-admin-database-v1/src/main/java/com/google/spanner/admin/database/v1/ListBackupOperationsResponse.java @@ -1,5 +1,5 @@ /* - * Copyright 2023 Google LLC + * Copyright 2024 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/proto-google-cloud-spanner-admin-database-v1/src/main/java/com/google/spanner/admin/database/v1/ListBackupOperationsResponseOrBuilder.java b/proto-google-cloud-spanner-admin-database-v1/src/main/java/com/google/spanner/admin/database/v1/ListBackupOperationsResponseOrBuilder.java index ba6b8352ec7..44b3bae4fb4 100644 --- a/proto-google-cloud-spanner-admin-database-v1/src/main/java/com/google/spanner/admin/database/v1/ListBackupOperationsResponseOrBuilder.java +++ b/proto-google-cloud-spanner-admin-database-v1/src/main/java/com/google/spanner/admin/database/v1/ListBackupOperationsResponseOrBuilder.java @@ -1,5 +1,5 @@ /* - * Copyright 2023 Google LLC + * Copyright 2024 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/proto-google-cloud-spanner-admin-database-v1/src/main/java/com/google/spanner/admin/database/v1/ListBackupsRequest.java b/proto-google-cloud-spanner-admin-database-v1/src/main/java/com/google/spanner/admin/database/v1/ListBackupsRequest.java index ec4724c8267..84701664bec 100644 --- a/proto-google-cloud-spanner-admin-database-v1/src/main/java/com/google/spanner/admin/database/v1/ListBackupsRequest.java +++ b/proto-google-cloud-spanner-admin-database-v1/src/main/java/com/google/spanner/admin/database/v1/ListBackupsRequest.java @@ -1,5 +1,5 @@ /* - * Copyright 2023 Google LLC + * Copyright 2024 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/proto-google-cloud-spanner-admin-database-v1/src/main/java/com/google/spanner/admin/database/v1/ListBackupsRequestOrBuilder.java b/proto-google-cloud-spanner-admin-database-v1/src/main/java/com/google/spanner/admin/database/v1/ListBackupsRequestOrBuilder.java index 74def9180b7..6eb63234798 100644 --- a/proto-google-cloud-spanner-admin-database-v1/src/main/java/com/google/spanner/admin/database/v1/ListBackupsRequestOrBuilder.java +++ b/proto-google-cloud-spanner-admin-database-v1/src/main/java/com/google/spanner/admin/database/v1/ListBackupsRequestOrBuilder.java @@ -1,5 +1,5 @@ /* - * Copyright 2023 Google LLC + * Copyright 2024 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/proto-google-cloud-spanner-admin-database-v1/src/main/java/com/google/spanner/admin/database/v1/ListBackupsResponse.java b/proto-google-cloud-spanner-admin-database-v1/src/main/java/com/google/spanner/admin/database/v1/ListBackupsResponse.java index 368f505e606..c7467445ef8 100644 --- a/proto-google-cloud-spanner-admin-database-v1/src/main/java/com/google/spanner/admin/database/v1/ListBackupsResponse.java +++ b/proto-google-cloud-spanner-admin-database-v1/src/main/java/com/google/spanner/admin/database/v1/ListBackupsResponse.java @@ -1,5 +1,5 @@ /* - * Copyright 2023 Google LLC + * Copyright 2024 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/proto-google-cloud-spanner-admin-database-v1/src/main/java/com/google/spanner/admin/database/v1/ListBackupsResponseOrBuilder.java b/proto-google-cloud-spanner-admin-database-v1/src/main/java/com/google/spanner/admin/database/v1/ListBackupsResponseOrBuilder.java index 9c1ccadf998..403a90b291a 100644 --- a/proto-google-cloud-spanner-admin-database-v1/src/main/java/com/google/spanner/admin/database/v1/ListBackupsResponseOrBuilder.java +++ b/proto-google-cloud-spanner-admin-database-v1/src/main/java/com/google/spanner/admin/database/v1/ListBackupsResponseOrBuilder.java @@ -1,5 +1,5 @@ /* - * Copyright 2023 Google LLC + * Copyright 2024 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/proto-google-cloud-spanner-admin-database-v1/src/main/java/com/google/spanner/admin/database/v1/ListDatabaseOperationsRequest.java b/proto-google-cloud-spanner-admin-database-v1/src/main/java/com/google/spanner/admin/database/v1/ListDatabaseOperationsRequest.java index 37d86fbdedb..9db28bb0075 100644 --- a/proto-google-cloud-spanner-admin-database-v1/src/main/java/com/google/spanner/admin/database/v1/ListDatabaseOperationsRequest.java +++ b/proto-google-cloud-spanner-admin-database-v1/src/main/java/com/google/spanner/admin/database/v1/ListDatabaseOperationsRequest.java @@ -1,5 +1,5 @@ /* - * Copyright 2023 Google LLC + * Copyright 2024 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/proto-google-cloud-spanner-admin-database-v1/src/main/java/com/google/spanner/admin/database/v1/ListDatabaseOperationsRequestOrBuilder.java b/proto-google-cloud-spanner-admin-database-v1/src/main/java/com/google/spanner/admin/database/v1/ListDatabaseOperationsRequestOrBuilder.java index 9f67dc38b95..336d9ee2918 100644 --- a/proto-google-cloud-spanner-admin-database-v1/src/main/java/com/google/spanner/admin/database/v1/ListDatabaseOperationsRequestOrBuilder.java +++ b/proto-google-cloud-spanner-admin-database-v1/src/main/java/com/google/spanner/admin/database/v1/ListDatabaseOperationsRequestOrBuilder.java @@ -1,5 +1,5 @@ /* - * Copyright 2023 Google LLC + * Copyright 2024 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/proto-google-cloud-spanner-admin-database-v1/src/main/java/com/google/spanner/admin/database/v1/ListDatabaseOperationsResponse.java b/proto-google-cloud-spanner-admin-database-v1/src/main/java/com/google/spanner/admin/database/v1/ListDatabaseOperationsResponse.java index 9331109f4bb..df3af219b98 100644 --- a/proto-google-cloud-spanner-admin-database-v1/src/main/java/com/google/spanner/admin/database/v1/ListDatabaseOperationsResponse.java +++ b/proto-google-cloud-spanner-admin-database-v1/src/main/java/com/google/spanner/admin/database/v1/ListDatabaseOperationsResponse.java @@ -1,5 +1,5 @@ /* - * Copyright 2023 Google LLC + * Copyright 2024 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/proto-google-cloud-spanner-admin-database-v1/src/main/java/com/google/spanner/admin/database/v1/ListDatabaseOperationsResponseOrBuilder.java b/proto-google-cloud-spanner-admin-database-v1/src/main/java/com/google/spanner/admin/database/v1/ListDatabaseOperationsResponseOrBuilder.java index 97a577e30ef..29aca1b67e4 100644 --- a/proto-google-cloud-spanner-admin-database-v1/src/main/java/com/google/spanner/admin/database/v1/ListDatabaseOperationsResponseOrBuilder.java +++ b/proto-google-cloud-spanner-admin-database-v1/src/main/java/com/google/spanner/admin/database/v1/ListDatabaseOperationsResponseOrBuilder.java @@ -1,5 +1,5 @@ /* - * Copyright 2023 Google LLC + * Copyright 2024 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/proto-google-cloud-spanner-admin-database-v1/src/main/java/com/google/spanner/admin/database/v1/ListDatabaseRolesRequest.java b/proto-google-cloud-spanner-admin-database-v1/src/main/java/com/google/spanner/admin/database/v1/ListDatabaseRolesRequest.java index 679e8885de8..19b5f77c5f6 100644 --- a/proto-google-cloud-spanner-admin-database-v1/src/main/java/com/google/spanner/admin/database/v1/ListDatabaseRolesRequest.java +++ b/proto-google-cloud-spanner-admin-database-v1/src/main/java/com/google/spanner/admin/database/v1/ListDatabaseRolesRequest.java @@ -1,5 +1,5 @@ /* - * Copyright 2023 Google LLC + * Copyright 2024 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/proto-google-cloud-spanner-admin-database-v1/src/main/java/com/google/spanner/admin/database/v1/ListDatabaseRolesRequestOrBuilder.java b/proto-google-cloud-spanner-admin-database-v1/src/main/java/com/google/spanner/admin/database/v1/ListDatabaseRolesRequestOrBuilder.java index b465a2a2625..14ea0fe6c8d 100644 --- a/proto-google-cloud-spanner-admin-database-v1/src/main/java/com/google/spanner/admin/database/v1/ListDatabaseRolesRequestOrBuilder.java +++ b/proto-google-cloud-spanner-admin-database-v1/src/main/java/com/google/spanner/admin/database/v1/ListDatabaseRolesRequestOrBuilder.java @@ -1,5 +1,5 @@ /* - * Copyright 2023 Google LLC + * Copyright 2024 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/proto-google-cloud-spanner-admin-database-v1/src/main/java/com/google/spanner/admin/database/v1/ListDatabaseRolesResponse.java b/proto-google-cloud-spanner-admin-database-v1/src/main/java/com/google/spanner/admin/database/v1/ListDatabaseRolesResponse.java index 7ba8415ac39..e5fd4f87235 100644 --- a/proto-google-cloud-spanner-admin-database-v1/src/main/java/com/google/spanner/admin/database/v1/ListDatabaseRolesResponse.java +++ b/proto-google-cloud-spanner-admin-database-v1/src/main/java/com/google/spanner/admin/database/v1/ListDatabaseRolesResponse.java @@ -1,5 +1,5 @@ /* - * Copyright 2023 Google LLC + * Copyright 2024 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/proto-google-cloud-spanner-admin-database-v1/src/main/java/com/google/spanner/admin/database/v1/ListDatabaseRolesResponseOrBuilder.java b/proto-google-cloud-spanner-admin-database-v1/src/main/java/com/google/spanner/admin/database/v1/ListDatabaseRolesResponseOrBuilder.java index 93d63bfefad..81687250021 100644 --- a/proto-google-cloud-spanner-admin-database-v1/src/main/java/com/google/spanner/admin/database/v1/ListDatabaseRolesResponseOrBuilder.java +++ b/proto-google-cloud-spanner-admin-database-v1/src/main/java/com/google/spanner/admin/database/v1/ListDatabaseRolesResponseOrBuilder.java @@ -1,5 +1,5 @@ /* - * Copyright 2023 Google LLC + * Copyright 2024 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/proto-google-cloud-spanner-admin-database-v1/src/main/java/com/google/spanner/admin/database/v1/ListDatabasesRequest.java b/proto-google-cloud-spanner-admin-database-v1/src/main/java/com/google/spanner/admin/database/v1/ListDatabasesRequest.java index 6d281f2ad5a..406e7eb09b9 100644 --- a/proto-google-cloud-spanner-admin-database-v1/src/main/java/com/google/spanner/admin/database/v1/ListDatabasesRequest.java +++ b/proto-google-cloud-spanner-admin-database-v1/src/main/java/com/google/spanner/admin/database/v1/ListDatabasesRequest.java @@ -1,5 +1,5 @@ /* - * Copyright 2023 Google LLC + * Copyright 2024 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/proto-google-cloud-spanner-admin-database-v1/src/main/java/com/google/spanner/admin/database/v1/ListDatabasesRequestOrBuilder.java b/proto-google-cloud-spanner-admin-database-v1/src/main/java/com/google/spanner/admin/database/v1/ListDatabasesRequestOrBuilder.java index b8cd5819beb..a396c328330 100644 --- a/proto-google-cloud-spanner-admin-database-v1/src/main/java/com/google/spanner/admin/database/v1/ListDatabasesRequestOrBuilder.java +++ b/proto-google-cloud-spanner-admin-database-v1/src/main/java/com/google/spanner/admin/database/v1/ListDatabasesRequestOrBuilder.java @@ -1,5 +1,5 @@ /* - * Copyright 2023 Google LLC + * Copyright 2024 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/proto-google-cloud-spanner-admin-database-v1/src/main/java/com/google/spanner/admin/database/v1/ListDatabasesResponse.java b/proto-google-cloud-spanner-admin-database-v1/src/main/java/com/google/spanner/admin/database/v1/ListDatabasesResponse.java index 76505b943fc..7ea3272f2f2 100644 --- a/proto-google-cloud-spanner-admin-database-v1/src/main/java/com/google/spanner/admin/database/v1/ListDatabasesResponse.java +++ b/proto-google-cloud-spanner-admin-database-v1/src/main/java/com/google/spanner/admin/database/v1/ListDatabasesResponse.java @@ -1,5 +1,5 @@ /* - * Copyright 2023 Google LLC + * Copyright 2024 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/proto-google-cloud-spanner-admin-database-v1/src/main/java/com/google/spanner/admin/database/v1/ListDatabasesResponseOrBuilder.java b/proto-google-cloud-spanner-admin-database-v1/src/main/java/com/google/spanner/admin/database/v1/ListDatabasesResponseOrBuilder.java index 6c09054c001..f8c8fe7999c 100644 --- a/proto-google-cloud-spanner-admin-database-v1/src/main/java/com/google/spanner/admin/database/v1/ListDatabasesResponseOrBuilder.java +++ b/proto-google-cloud-spanner-admin-database-v1/src/main/java/com/google/spanner/admin/database/v1/ListDatabasesResponseOrBuilder.java @@ -1,5 +1,5 @@ /* - * Copyright 2023 Google LLC + * Copyright 2024 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/proto-google-cloud-spanner-admin-database-v1/src/main/java/com/google/spanner/admin/database/v1/OperationProgress.java b/proto-google-cloud-spanner-admin-database-v1/src/main/java/com/google/spanner/admin/database/v1/OperationProgress.java index 11c77e5af17..c1b86277cf0 100644 --- a/proto-google-cloud-spanner-admin-database-v1/src/main/java/com/google/spanner/admin/database/v1/OperationProgress.java +++ b/proto-google-cloud-spanner-admin-database-v1/src/main/java/com/google/spanner/admin/database/v1/OperationProgress.java @@ -1,5 +1,5 @@ /* - * Copyright 2023 Google LLC + * Copyright 2024 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/proto-google-cloud-spanner-admin-database-v1/src/main/java/com/google/spanner/admin/database/v1/OperationProgressOrBuilder.java b/proto-google-cloud-spanner-admin-database-v1/src/main/java/com/google/spanner/admin/database/v1/OperationProgressOrBuilder.java index 2636bad9ba3..32187fbcdc8 100644 --- a/proto-google-cloud-spanner-admin-database-v1/src/main/java/com/google/spanner/admin/database/v1/OperationProgressOrBuilder.java +++ b/proto-google-cloud-spanner-admin-database-v1/src/main/java/com/google/spanner/admin/database/v1/OperationProgressOrBuilder.java @@ -1,5 +1,5 @@ /* - * Copyright 2023 Google LLC + * Copyright 2024 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/proto-google-cloud-spanner-admin-database-v1/src/main/java/com/google/spanner/admin/database/v1/OptimizeRestoredDatabaseMetadata.java b/proto-google-cloud-spanner-admin-database-v1/src/main/java/com/google/spanner/admin/database/v1/OptimizeRestoredDatabaseMetadata.java index 08529ae165f..f729e5bdeef 100644 --- a/proto-google-cloud-spanner-admin-database-v1/src/main/java/com/google/spanner/admin/database/v1/OptimizeRestoredDatabaseMetadata.java +++ b/proto-google-cloud-spanner-admin-database-v1/src/main/java/com/google/spanner/admin/database/v1/OptimizeRestoredDatabaseMetadata.java @@ -1,5 +1,5 @@ /* - * Copyright 2023 Google LLC + * Copyright 2024 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/proto-google-cloud-spanner-admin-database-v1/src/main/java/com/google/spanner/admin/database/v1/OptimizeRestoredDatabaseMetadataOrBuilder.java b/proto-google-cloud-spanner-admin-database-v1/src/main/java/com/google/spanner/admin/database/v1/OptimizeRestoredDatabaseMetadataOrBuilder.java index 1ef0a9fbae9..7d6ffdb4a02 100644 --- a/proto-google-cloud-spanner-admin-database-v1/src/main/java/com/google/spanner/admin/database/v1/OptimizeRestoredDatabaseMetadataOrBuilder.java +++ b/proto-google-cloud-spanner-admin-database-v1/src/main/java/com/google/spanner/admin/database/v1/OptimizeRestoredDatabaseMetadataOrBuilder.java @@ -1,5 +1,5 @@ /* - * Copyright 2023 Google LLC + * Copyright 2024 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/proto-google-cloud-spanner-admin-database-v1/src/main/java/com/google/spanner/admin/database/v1/RestoreDatabaseEncryptionConfig.java b/proto-google-cloud-spanner-admin-database-v1/src/main/java/com/google/spanner/admin/database/v1/RestoreDatabaseEncryptionConfig.java index 12df82b01d7..2b8ea40391f 100644 --- a/proto-google-cloud-spanner-admin-database-v1/src/main/java/com/google/spanner/admin/database/v1/RestoreDatabaseEncryptionConfig.java +++ b/proto-google-cloud-spanner-admin-database-v1/src/main/java/com/google/spanner/admin/database/v1/RestoreDatabaseEncryptionConfig.java @@ -1,5 +1,5 @@ /* - * Copyright 2023 Google LLC + * Copyright 2024 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/proto-google-cloud-spanner-admin-database-v1/src/main/java/com/google/spanner/admin/database/v1/RestoreDatabaseEncryptionConfigOrBuilder.java b/proto-google-cloud-spanner-admin-database-v1/src/main/java/com/google/spanner/admin/database/v1/RestoreDatabaseEncryptionConfigOrBuilder.java index 03e5beb45fa..581735dba1e 100644 --- a/proto-google-cloud-spanner-admin-database-v1/src/main/java/com/google/spanner/admin/database/v1/RestoreDatabaseEncryptionConfigOrBuilder.java +++ b/proto-google-cloud-spanner-admin-database-v1/src/main/java/com/google/spanner/admin/database/v1/RestoreDatabaseEncryptionConfigOrBuilder.java @@ -1,5 +1,5 @@ /* - * Copyright 2023 Google LLC + * Copyright 2024 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/proto-google-cloud-spanner-admin-database-v1/src/main/java/com/google/spanner/admin/database/v1/RestoreDatabaseMetadata.java b/proto-google-cloud-spanner-admin-database-v1/src/main/java/com/google/spanner/admin/database/v1/RestoreDatabaseMetadata.java index 427be919b66..75b761ebe56 100644 --- a/proto-google-cloud-spanner-admin-database-v1/src/main/java/com/google/spanner/admin/database/v1/RestoreDatabaseMetadata.java +++ b/proto-google-cloud-spanner-admin-database-v1/src/main/java/com/google/spanner/admin/database/v1/RestoreDatabaseMetadata.java @@ -1,5 +1,5 @@ /* - * Copyright 2023 Google LLC + * Copyright 2024 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/proto-google-cloud-spanner-admin-database-v1/src/main/java/com/google/spanner/admin/database/v1/RestoreDatabaseMetadataOrBuilder.java b/proto-google-cloud-spanner-admin-database-v1/src/main/java/com/google/spanner/admin/database/v1/RestoreDatabaseMetadataOrBuilder.java index e697cd2438c..e7c1689b4bf 100644 --- a/proto-google-cloud-spanner-admin-database-v1/src/main/java/com/google/spanner/admin/database/v1/RestoreDatabaseMetadataOrBuilder.java +++ b/proto-google-cloud-spanner-admin-database-v1/src/main/java/com/google/spanner/admin/database/v1/RestoreDatabaseMetadataOrBuilder.java @@ -1,5 +1,5 @@ /* - * Copyright 2023 Google LLC + * Copyright 2024 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/proto-google-cloud-spanner-admin-database-v1/src/main/java/com/google/spanner/admin/database/v1/RestoreDatabaseRequest.java b/proto-google-cloud-spanner-admin-database-v1/src/main/java/com/google/spanner/admin/database/v1/RestoreDatabaseRequest.java index 0b2e139f288..d6760e99860 100644 --- a/proto-google-cloud-spanner-admin-database-v1/src/main/java/com/google/spanner/admin/database/v1/RestoreDatabaseRequest.java +++ b/proto-google-cloud-spanner-admin-database-v1/src/main/java/com/google/spanner/admin/database/v1/RestoreDatabaseRequest.java @@ -1,5 +1,5 @@ /* - * Copyright 2023 Google LLC + * Copyright 2024 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/proto-google-cloud-spanner-admin-database-v1/src/main/java/com/google/spanner/admin/database/v1/RestoreDatabaseRequestOrBuilder.java b/proto-google-cloud-spanner-admin-database-v1/src/main/java/com/google/spanner/admin/database/v1/RestoreDatabaseRequestOrBuilder.java index a3a1be382f6..14c8cb633b7 100644 --- a/proto-google-cloud-spanner-admin-database-v1/src/main/java/com/google/spanner/admin/database/v1/RestoreDatabaseRequestOrBuilder.java +++ b/proto-google-cloud-spanner-admin-database-v1/src/main/java/com/google/spanner/admin/database/v1/RestoreDatabaseRequestOrBuilder.java @@ -1,5 +1,5 @@ /* - * Copyright 2023 Google LLC + * Copyright 2024 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/proto-google-cloud-spanner-admin-database-v1/src/main/java/com/google/spanner/admin/database/v1/RestoreInfo.java b/proto-google-cloud-spanner-admin-database-v1/src/main/java/com/google/spanner/admin/database/v1/RestoreInfo.java index 07b08825bcb..b403ca128f3 100644 --- a/proto-google-cloud-spanner-admin-database-v1/src/main/java/com/google/spanner/admin/database/v1/RestoreInfo.java +++ b/proto-google-cloud-spanner-admin-database-v1/src/main/java/com/google/spanner/admin/database/v1/RestoreInfo.java @@ -1,5 +1,5 @@ /* - * Copyright 2023 Google LLC + * Copyright 2024 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/proto-google-cloud-spanner-admin-database-v1/src/main/java/com/google/spanner/admin/database/v1/RestoreInfoOrBuilder.java b/proto-google-cloud-spanner-admin-database-v1/src/main/java/com/google/spanner/admin/database/v1/RestoreInfoOrBuilder.java index f36f8bce23b..d1021cec96a 100644 --- a/proto-google-cloud-spanner-admin-database-v1/src/main/java/com/google/spanner/admin/database/v1/RestoreInfoOrBuilder.java +++ b/proto-google-cloud-spanner-admin-database-v1/src/main/java/com/google/spanner/admin/database/v1/RestoreInfoOrBuilder.java @@ -1,5 +1,5 @@ /* - * Copyright 2023 Google LLC + * Copyright 2024 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/proto-google-cloud-spanner-admin-database-v1/src/main/java/com/google/spanner/admin/database/v1/RestoreSourceType.java b/proto-google-cloud-spanner-admin-database-v1/src/main/java/com/google/spanner/admin/database/v1/RestoreSourceType.java index cbd229d2e3c..906fb06f37b 100644 --- a/proto-google-cloud-spanner-admin-database-v1/src/main/java/com/google/spanner/admin/database/v1/RestoreSourceType.java +++ b/proto-google-cloud-spanner-admin-database-v1/src/main/java/com/google/spanner/admin/database/v1/RestoreSourceType.java @@ -1,5 +1,5 @@ /* - * Copyright 2023 Google LLC + * Copyright 2024 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/proto-google-cloud-spanner-admin-database-v1/src/main/java/com/google/spanner/admin/database/v1/SpannerDatabaseAdminProto.java b/proto-google-cloud-spanner-admin-database-v1/src/main/java/com/google/spanner/admin/database/v1/SpannerDatabaseAdminProto.java index 9fd014fc9ac..8646b50bd53 100644 --- a/proto-google-cloud-spanner-admin-database-v1/src/main/java/com/google/spanner/admin/database/v1/SpannerDatabaseAdminProto.java +++ b/proto-google-cloud-spanner-admin-database-v1/src/main/java/com/google/spanner/admin/database/v1/SpannerDatabaseAdminProto.java @@ -1,5 +1,5 @@ /* - * Copyright 2023 Google LLC + * Copyright 2024 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -176,225 +176,228 @@ public static com.google.protobuf.Descriptors.FileDescriptor getDescriptor() { + "oken\030\004 \001(\t\"o\n\025ListDatabasesResponse\022=\n\td" + "atabases\030\001 \003(\0132*.google.spanner.admin.da" + "tabase.v1.Database\022\027\n\017next_page_token\030\002 " - + "\001(\t\"\271\002\n\025CreateDatabaseRequest\0228\n\006parent\030" + + "\001(\t\"\332\002\n\025CreateDatabaseRequest\0228\n\006parent\030" + "\001 \001(\tB(\342A\001\002\372A!\n\037spanner.googleapis.com/I" + "nstance\022\036\n\020create_statement\030\002 \001(\tB\004\342A\001\002\022" + "\036\n\020extra_statements\030\003 \003(\tB\004\342A\001\001\022S\n\021encry" + "ption_config\030\004 \001(\01322.google.spanner.admi" + "n.database.v1.EncryptionConfigB\004\342A\001\001\022Q\n\020" + "database_dialect\030\005 \001(\01621.google.spanner." - + "admin.database.v1.DatabaseDialectB\004\342A\001\001\"" - + "P\n\026CreateDatabaseMetadata\0226\n\010database\030\001 " - + "\001(\tB$\372A!\n\037spanner.googleapis.com/Databas" - + "e\"L\n\022GetDatabaseRequest\0226\n\004name\030\001 \001(\tB(\342" - + "A\001\002\372A!\n\037spanner.googleapis.com/Database\"" - + "\222\001\n\025UpdateDatabaseRequest\022B\n\010database\030\001 " - + "\001(\0132*.google.spanner.admin.database.v1.D" - + "atabaseB\004\342A\001\002\0225\n\013update_mask\030\002 \001(\0132\032.goo" - + "gle.protobuf.FieldMaskB\004\342A\001\002\"\332\001\n\026UpdateD" - + "atabaseMetadata\022H\n\007request\030\001 \001(\01327.googl" - + "e.spanner.admin.database.v1.UpdateDataba" - + "seRequest\022E\n\010progress\030\002 \001(\01323.google.spa" - + "nner.admin.database.v1.OperationProgress" - + "\022/\n\013cancel_time\030\003 \001(\0132\032.google.protobuf." - + "Timestamp\"\206\001\n\030UpdateDatabaseDdlRequest\022:" - + "\n\010database\030\001 \001(\tB(\342A\001\002\372A!\n\037spanner.googl" - + "eapis.com/Database\022\030\n\nstatements\030\002 \003(\tB\004" - + "\342A\001\002\022\024\n\014operation_id\030\003 \001(\t\"S\n\026DdlStateme" - + "ntActionInfo\022\016\n\006action\030\001 \001(\t\022\023\n\013entity_t" - + "ype\030\002 \001(\t\022\024\n\014entity_names\030\003 \003(\t\"\311\002\n\031Upda" - + "teDatabaseDdlMetadata\0226\n\010database\030\001 \001(\tB" - + "$\372A!\n\037spanner.googleapis.com/Database\022\022\n" - + "\nstatements\030\002 \003(\t\0225\n\021commit_timestamps\030\003" - + " \003(\0132\032.google.protobuf.Timestamp\022\027\n\tthro" - + "ttled\030\004 \001(\010B\004\342A\001\003\022E\n\010progress\030\005 \003(\01323.go" - + "ogle.spanner.admin.database.v1.Operation" - + "Progress\022I\n\007actions\030\006 \003(\01328.google.spann" - + "er.admin.database.v1.DdlStatementActionI" - + "nfo\"Q\n\023DropDatabaseRequest\022:\n\010database\030\001" - + " \001(\tB(\342A\001\002\372A!\n\037spanner.googleapis.com/Da" - + "tabase\"S\n\025GetDatabaseDdlRequest\022:\n\010datab" + + "admin.database.v1.DatabaseDialectB\004\342A\001\001\022" + + "\037\n\021proto_descriptors\030\006 \001(\014B\004\342A\001\001\"P\n\026Crea" + + "teDatabaseMetadata\0226\n\010database\030\001 \001(\tB$\372A" + + "!\n\037spanner.googleapis.com/Database\"L\n\022Ge" + + "tDatabaseRequest\0226\n\004name\030\001 \001(\tB(\342A\001\002\372A!\n" + + "\037spanner.googleapis.com/Database\"\222\001\n\025Upd" + + "ateDatabaseRequest\022B\n\010database\030\001 \001(\0132*.g" + + "oogle.spanner.admin.database.v1.Database" + + "B\004\342A\001\002\0225\n\013update_mask\030\002 \001(\0132\032.google.pro" + + "tobuf.FieldMaskB\004\342A\001\002\"\332\001\n\026UpdateDatabase" + + "Metadata\022H\n\007request\030\001 \001(\01327.google.spann" + + "er.admin.database.v1.UpdateDatabaseReque" + + "st\022E\n\010progress\030\002 \001(\01323.google.spanner.ad" + + "min.database.v1.OperationProgress\022/\n\013can" + + "cel_time\030\003 \001(\0132\032.google.protobuf.Timesta" + + "mp\"\247\001\n\030UpdateDatabaseDdlRequest\022:\n\010datab" + "ase\030\001 \001(\tB(\342A\001\002\372A!\n\037spanner.googleapis.c" - + "om/Database\",\n\026GetDatabaseDdlResponse\022\022\n" - + "\nstatements\030\001 \003(\t\"\220\001\n\035ListDatabaseOperat" - + "ionsRequest\0228\n\006parent\030\001 \001(\tB(\342A\001\002\372A!\n\037sp" - + "anner.googleapis.com/Instance\022\016\n\006filter\030" - + "\002 \001(\t\022\021\n\tpage_size\030\003 \001(\005\022\022\n\npage_token\030\004" - + " \001(\t\"l\n\036ListDatabaseOperationsResponse\0221" - + "\n\noperations\030\001 \003(\0132\035.google.longrunning." - + "Operation\022\027\n\017next_page_token\030\002 \001(\t\"\221\002\n\026R" - + "estoreDatabaseRequest\0228\n\006parent\030\001 \001(\tB(\342" - + "A\001\002\372A!\n\037spanner.googleapis.com/Instance\022" - + "\031\n\013database_id\030\002 \001(\tB\004\342A\001\002\0224\n\006backup\030\003 \001" - + "(\tB\"\372A\037\n\035spanner.googleapis.com/BackupH\000" - + "\022b\n\021encryption_config\030\004 \001(\0132A.google.spa" - + "nner.admin.database.v1.RestoreDatabaseEn" - + "cryptionConfigB\004\342A\001\001B\010\n\006source\"\365\002\n\037Resto" - + "reDatabaseEncryptionConfig\022o\n\017encryption" - + "_type\030\001 \001(\0162P.google.spanner.admin.datab" - + "ase.v1.RestoreDatabaseEncryptionConfig.E" - + "ncryptionTypeB\004\342A\001\002\022@\n\014kms_key_name\030\002 \001(" - + "\tB*\342A\001\001\372A#\n!cloudkms.googleapis.com/Cryp" - + "toKey\"\236\001\n\016EncryptionType\022\037\n\033ENCRYPTION_T" - + "YPE_UNSPECIFIED\020\000\022+\n\'USE_CONFIG_DEFAULT_" - + "OR_BACKUP_ENCRYPTION\020\001\022\035\n\031GOOGLE_DEFAULT" - + "_ENCRYPTION\020\002\022\037\n\033CUSTOMER_MANAGED_ENCRYP" - + "TION\020\003\"\215\003\n\027RestoreDatabaseMetadata\0222\n\004na" - + "me\030\001 \001(\tB$\372A!\n\037spanner.googleapis.com/Da" - + "tabase\022H\n\013source_type\030\002 \001(\01623.google.spa" - + "nner.admin.database.v1.RestoreSourceType" - + "\022C\n\013backup_info\030\003 \001(\0132,.google.spanner.a" - + "dmin.database.v1.BackupInfoH\000\022E\n\010progres" - + "s\030\004 \001(\01323.google.spanner.admin.database." - + "v1.OperationProgress\022/\n\013cancel_time\030\005 \001(" - + "\0132\032.google.protobuf.Timestamp\022(\n optimiz" - + "e_database_operation_name\030\006 \001(\tB\r\n\013sourc" - + "e_info\"\235\001\n OptimizeRestoredDatabaseMetad" - + "ata\0222\n\004name\030\001 \001(\tB$\372A!\n\037spanner.googleap" - + "is.com/Database\022E\n\010progress\030\002 \001(\01323.goog" - + "le.spanner.admin.database.v1.OperationPr" - + "ogress\"\237\001\n\014DatabaseRole\022\022\n\004name\030\001 \001(\tB\004\342" - + "A\001\002:{\352Ax\n#spanner.googleapis.com/Databas" - + "eRole\022Qprojects/{project}/instances/{ins" - + "tance}/databases/{database}/databaseRole" - + "s/{role}\"{\n\030ListDatabaseRolesRequest\0228\n\006" - + "parent\030\001 \001(\tB(\342A\001\002\372A!\n\037spanner.googleapi" - + "s.com/Database\022\021\n\tpage_size\030\002 \001(\005\022\022\n\npag" - + "e_token\030\003 \001(\t\"|\n\031ListDatabaseRolesRespon" - + "se\022F\n\016database_roles\030\001 \003(\0132..google.span" - + "ner.admin.database.v1.DatabaseRole\022\027\n\017ne" - + "xt_page_token\030\002 \001(\t*5\n\021RestoreSourceType" - + "\022\024\n\020TYPE_UNSPECIFIED\020\000\022\n\n\006BACKUP\020\0012\356%\n\rD" - + "atabaseAdmin\022\300\001\n\rListDatabases\0226.google." - + "spanner.admin.database.v1.ListDatabasesR" - + "equest\0327.google.spanner.admin.database.v" - + "1.ListDatabasesResponse\">\332A\006parent\202\323\344\223\002/" - + "\022-/v1/{parent=projects/*/instances/*}/da" - + "tabases\022\244\002\n\016CreateDatabase\0227.google.span" - + "ner.admin.database.v1.CreateDatabaseRequ" - + "est\032\035.google.longrunning.Operation\"\271\001\312Ad" - + "\n)google.spanner.admin.database.v1.Datab" - + "ase\0227google.spanner.admin.database.v1.Cr" - + "eateDatabaseMetadata\332A\027parent,create_sta" - + "tement\202\323\344\223\0022\"-/v1/{parent=projects/*/ins" - + "tances/*}/databases:\001*\022\255\001\n\013GetDatabase\0224" - + ".google.spanner.admin.database.v1.GetDat" - + "abaseRequest\032*.google.spanner.admin.data" - + "base.v1.Database\"<\332A\004name\202\323\344\223\002/\022-/v1/{na" - + "me=projects/*/instances/*/databases/*}\022\357" - + "\001\n\016UpdateDatabase\0227.google.spanner.admin" - + ".database.v1.UpdateDatabaseRequest\032\035.goo" - + "gle.longrunning.Operation\"\204\001\312A\"\n\010Databas" - + "e\022\026UpdateDatabaseMetadata\332A\024database,upd" - + "ate_mask\202\323\344\223\002B26/v1/{database.name=proje" - + "cts/*/instances/*/databases/*}:\010database" - + "\022\235\002\n\021UpdateDatabaseDdl\022:.google.spanner." - + "admin.database.v1.UpdateDatabaseDdlReque" - + "st\032\035.google.longrunning.Operation\"\254\001\312AS\n" - + "\025google.protobuf.Empty\022:google.spanner.a" - + "dmin.database.v1.UpdateDatabaseDdlMetada" - + "ta\332A\023database,statements\202\323\344\223\002:25/v1/{dat" - + "abase=projects/*/instances/*/databases/*" - + "}/ddl:\001*\022\243\001\n\014DropDatabase\0225.google.spann" - + "er.admin.database.v1.DropDatabaseRequest" - + "\032\026.google.protobuf.Empty\"D\332A\010database\202\323\344" - + "\223\0023*1/v1/{database=projects/*/instances/" - + "*/databases/*}\022\315\001\n\016GetDatabaseDdl\0227.goog" - + "le.spanner.admin.database.v1.GetDatabase" - + "DdlRequest\0328.google.spanner.admin.databa" - + "se.v1.GetDatabaseDdlResponse\"H\332A\010databas" - + "e\202\323\344\223\0027\0225/v1/{database=projects/*/instan" - + "ces/*/databases/*}/ddl\022\353\001\n\014SetIamPolicy\022" - + "\".google.iam.v1.SetIamPolicyRequest\032\025.go" - + "ogle.iam.v1.Policy\"\237\001\332A\017resource,policy\202" - + "\323\344\223\002\206\001\">/v1/{resource=projects/*/instanc" - + "es/*/databases/*}:setIamPolicy:\001*ZA\"/" - + "v1/{resource=projects/*/instances/*/data" - + "bases/*}:getIamPolicy:\001*ZA\".google.spanner.admin.database.v1.L" - + "istBackupOperationsResponse\"E\332A\006parent\202\323" - + "\344\223\0026\0224/v1/{parent=projects/*/instances/*" - + "}/backupOperations\022\334\001\n\021ListDatabaseRoles" - + "\022:.google.spanner.admin.database.v1.List" - + "DatabaseRolesRequest\032;.google.spanner.ad" - + "min.database.v1.ListDatabaseRolesRespons" - + "e\"N\332A\006parent\202\323\344\223\002?\022=/v1/{parent=projects" - + "/*/instances/*/databases/*}/databaseRole" - + "s\032x\312A\026spanner.googleapis.com\322A\\https://w" - + "ww.googleapis.com/auth/cloud-platform,ht" - + "tps://www.googleapis.com/auth/spanner.ad" - + "minB\330\002\n$com.google.spanner.admin.databas" - + "e.v1B\031SpannerDatabaseAdminProtoP\001ZFcloud" - + ".google.com/go/spanner/admin/database/ap" - + "iv1/databasepb;databasepb\252\002&Google.Cloud" - + ".Spanner.Admin.Database.V1\312\002&Google\\Clou" - + "d\\Spanner\\Admin\\Database\\V1\352\002+Google::Cl" - + "oud::Spanner::Admin::Database::V1\352AJ\n\037sp" - + "anner.googleapis.com/Instance\022\'projects/" - + "{project}/instances/{instance}b\006proto3" + + "om/Database\022\030\n\nstatements\030\002 \003(\tB\004\342A\001\002\022\024\n" + + "\014operation_id\030\003 \001(\t\022\037\n\021proto_descriptors" + + "\030\004 \001(\014B\004\342A\001\001\"S\n\026DdlStatementActionInfo\022\016" + + "\n\006action\030\001 \001(\t\022\023\n\013entity_type\030\002 \001(\t\022\024\n\014e" + + "ntity_names\030\003 \003(\t\"\311\002\n\031UpdateDatabaseDdlM" + + "etadata\0226\n\010database\030\001 \001(\tB$\372A!\n\037spanner." + + "googleapis.com/Database\022\022\n\nstatements\030\002 " + + "\003(\t\0225\n\021commit_timestamps\030\003 \003(\0132\032.google." + + "protobuf.Timestamp\022\027\n\tthrottled\030\004 \001(\010B\004\342" + + "A\001\003\022E\n\010progress\030\005 \003(\01323.google.spanner.a" + + "dmin.database.v1.OperationProgress\022I\n\007ac" + + "tions\030\006 \003(\01328.google.spanner.admin.datab" + + "ase.v1.DdlStatementActionInfo\"Q\n\023DropDat" + + "abaseRequest\022:\n\010database\030\001 \001(\tB(\342A\001\002\372A!\n" + + "\037spanner.googleapis.com/Database\"S\n\025GetD" + + "atabaseDdlRequest\022:\n\010database\030\001 \001(\tB(\342A\001" + + "\002\372A!\n\037spanner.googleapis.com/Database\"G\n" + + "\026GetDatabaseDdlResponse\022\022\n\nstatements\030\001 " + + "\003(\t\022\031\n\021proto_descriptors\030\002 \001(\014\"\220\001\n\035ListD" + + "atabaseOperationsRequest\0228\n\006parent\030\001 \001(\t" + + "B(\342A\001\002\372A!\n\037spanner.googleapis.com/Instan" + + "ce\022\016\n\006filter\030\002 \001(\t\022\021\n\tpage_size\030\003 \001(\005\022\022\n" + + "\npage_token\030\004 \001(\t\"l\n\036ListDatabaseOperati" + + "onsResponse\0221\n\noperations\030\001 \003(\0132\035.google" + + ".longrunning.Operation\022\027\n\017next_page_toke" + + "n\030\002 \001(\t\"\221\002\n\026RestoreDatabaseRequest\0228\n\006pa" + + "rent\030\001 \001(\tB(\342A\001\002\372A!\n\037spanner.googleapis." + + "com/Instance\022\031\n\013database_id\030\002 \001(\tB\004\342A\001\002\022" + + "4\n\006backup\030\003 \001(\tB\"\372A\037\n\035spanner.googleapis" + + ".com/BackupH\000\022b\n\021encryption_config\030\004 \001(\013" + + "2A.google.spanner.admin.database.v1.Rest" + + "oreDatabaseEncryptionConfigB\004\342A\001\001B\010\n\006sou" + + "rce\"\365\002\n\037RestoreDatabaseEncryptionConfig\022" + + "o\n\017encryption_type\030\001 \001(\0162P.google.spanne" + + "r.admin.database.v1.RestoreDatabaseEncry" + + "ptionConfig.EncryptionTypeB\004\342A\001\002\022@\n\014kms_" + + "key_name\030\002 \001(\tB*\342A\001\001\372A#\n!cloudkms.google" + + "apis.com/CryptoKey\"\236\001\n\016EncryptionType\022\037\n" + + "\033ENCRYPTION_TYPE_UNSPECIFIED\020\000\022+\n\'USE_CO" + + "NFIG_DEFAULT_OR_BACKUP_ENCRYPTION\020\001\022\035\n\031G" + + "OOGLE_DEFAULT_ENCRYPTION\020\002\022\037\n\033CUSTOMER_M" + + "ANAGED_ENCRYPTION\020\003\"\215\003\n\027RestoreDatabaseM" + + "etadata\0222\n\004name\030\001 \001(\tB$\372A!\n\037spanner.goog" + + "leapis.com/Database\022H\n\013source_type\030\002 \001(\016" + + "23.google.spanner.admin.database.v1.Rest" + + "oreSourceType\022C\n\013backup_info\030\003 \001(\0132,.goo" + + "gle.spanner.admin.database.v1.BackupInfo" + + "H\000\022E\n\010progress\030\004 \001(\01323.google.spanner.ad" + + "min.database.v1.OperationProgress\022/\n\013can" + + "cel_time\030\005 \001(\0132\032.google.protobuf.Timesta" + + "mp\022(\n optimize_database_operation_name\030\006" + + " \001(\tB\r\n\013source_info\"\235\001\n OptimizeRestored" + + "DatabaseMetadata\0222\n\004name\030\001 \001(\tB$\372A!\n\037spa" + + "nner.googleapis.com/Database\022E\n\010progress" + + "\030\002 \001(\01323.google.spanner.admin.database.v" + + "1.OperationProgress\"\237\001\n\014DatabaseRole\022\022\n\004" + + "name\030\001 \001(\tB\004\342A\001\002:{\352Ax\n#spanner.googleapi" + + "s.com/DatabaseRole\022Qprojects/{project}/i" + + "nstances/{instance}/databases/{database}" + + "/databaseRoles/{role}\"{\n\030ListDatabaseRol" + + "esRequest\0228\n\006parent\030\001 \001(\tB(\342A\001\002\372A!\n\037span" + + "ner.googleapis.com/Database\022\021\n\tpage_size" + + "\030\002 \001(\005\022\022\n\npage_token\030\003 \001(\t\"|\n\031ListDataba" + + "seRolesResponse\022F\n\016database_roles\030\001 \003(\0132" + + "..google.spanner.admin.database.v1.Datab" + + "aseRole\022\027\n\017next_page_token\030\002 \001(\t*5\n\021Rest" + + "oreSourceType\022\024\n\020TYPE_UNSPECIFIED\020\000\022\n\n\006B" + + "ACKUP\020\0012\356%\n\rDatabaseAdmin\022\300\001\n\rListDataba" + + "ses\0226.google.spanner.admin.database.v1.L" + + "istDatabasesRequest\0327.google.spanner.adm" + + "in.database.v1.ListDatabasesResponse\">\332A" + + "\006parent\202\323\344\223\002/\022-/v1/{parent=projects/*/in" + + "stances/*}/databases\022\244\002\n\016CreateDatabase\022" + + "7.google.spanner.admin.database.v1.Creat" + + "eDatabaseRequest\032\035.google.longrunning.Op" + + "eration\"\271\001\312Ad\n)google.spanner.admin.data" + + "base.v1.Database\0227google.spanner.admin.d" + + "atabase.v1.CreateDatabaseMetadata\332A\027pare" + + "nt,create_statement\202\323\344\223\0022\"-/v1/{parent=p" + + "rojects/*/instances/*}/databases:\001*\022\255\001\n\013" + + "GetDatabase\0224.google.spanner.admin.datab" + + "ase.v1.GetDatabaseRequest\032*.google.spann" + + "er.admin.database.v1.Database\"<\332A\004name\202\323" + + "\344\223\002/\022-/v1/{name=projects/*/instances/*/d" + + "atabases/*}\022\357\001\n\016UpdateDatabase\0227.google." + + "spanner.admin.database.v1.UpdateDatabase" + + "Request\032\035.google.longrunning.Operation\"\204" + + "\001\312A\"\n\010Database\022\026UpdateDatabaseMetadata\332A" + + "\024database,update_mask\202\323\344\223\002B26/v1/{databa" + + "se.name=projects/*/instances/*/databases" + + "/*}:\010database\022\235\002\n\021UpdateDatabaseDdl\022:.go" + + "ogle.spanner.admin.database.v1.UpdateDat" + + "abaseDdlRequest\032\035.google.longrunning.Ope" + + "ration\"\254\001\312AS\n\025google.protobuf.Empty\022:goo" + + "gle.spanner.admin.database.v1.UpdateData" + + "baseDdlMetadata\332A\023database,statements\202\323\344" + + "\223\002:25/v1/{database=projects/*/instances/" + + "*/databases/*}/ddl:\001*\022\243\001\n\014DropDatabase\0225" + + ".google.spanner.admin.database.v1.DropDa" + + "tabaseRequest\032\026.google.protobuf.Empty\"D\332" + + "A\010database\202\323\344\223\0023*1/v1/{database=projects" + + "/*/instances/*/databases/*}\022\315\001\n\016GetDatab" + + "aseDdl\0227.google.spanner.admin.database.v" + + "1.GetDatabaseDdlRequest\0328.google.spanner" + + ".admin.database.v1.GetDatabaseDdlRespons" + + "e\"H\332A\010database\202\323\344\223\0027\0225/v1/{database=proj" + + "ects/*/instances/*/databases/*}/ddl\022\353\001\n\014" + + "SetIamPolicy\022\".google.iam.v1.SetIamPolic" + + "yRequest\032\025.google.iam.v1.Policy\"\237\001\332A\017res" + + "ource,policy\202\323\344\223\002\206\001\">/v1/{resource=proje" + + "cts/*/instances/*/databases/*}:setIamPol" + + "icy:\001*ZA\"/v1/{resource=projects/*/ins" + + "tances/*/databases/*}:getIamPolicy:\001*ZA\"" + + ".google.spanner.admin." + + "database.v1.ListBackupOperationsResponse" + + "\"E\332A\006parent\202\323\344\223\0026\0224/v1/{parent=projects/" + + "*/instances/*}/backupOperations\022\334\001\n\021List" + + "DatabaseRoles\022:.google.spanner.admin.dat" + + "abase.v1.ListDatabaseRolesRequest\032;.goog" + + "le.spanner.admin.database.v1.ListDatabas" + + "eRolesResponse\"N\332A\006parent\202\323\344\223\002?\022=/v1/{pa" + + "rent=projects/*/instances/*/databases/*}" + + "/databaseRoles\032x\312A\026spanner.googleapis.co" + + "m\322A\\https://www.googleapis.com/auth/clou" + + "d-platform,https://www.googleapis.com/au" + + "th/spanner.adminB\330\002\n$com.google.spanner." + + "admin.database.v1B\031SpannerDatabaseAdminP" + + "rotoP\001ZFcloud.google.com/go/spanner/admi" + + "n/database/apiv1/databasepb;databasepb\252\002" + + "&Google.Cloud.Spanner.Admin.Database.V1\312" + + "\002&Google\\Cloud\\Spanner\\Admin\\Database\\V1" + + "\352\002+Google::Cloud::Spanner::Admin::Databa" + + "se::V1\352AJ\n\037spanner.googleapis.com/Instan" + + "ce\022\'projects/{project}/instances/{instan" + + "ce}b\006proto3" }; descriptor = com.google.protobuf.Descriptors.FileDescriptor.internalBuildGeneratedFileFrom( @@ -462,7 +465,12 @@ public static com.google.protobuf.Descriptors.FileDescriptor getDescriptor() { new com.google.protobuf.GeneratedMessageV3.FieldAccessorTable( internal_static_google_spanner_admin_database_v1_CreateDatabaseRequest_descriptor, new java.lang.String[] { - "Parent", "CreateStatement", "ExtraStatements", "EncryptionConfig", "DatabaseDialect", + "Parent", + "CreateStatement", + "ExtraStatements", + "EncryptionConfig", + "DatabaseDialect", + "ProtoDescriptors", }); internal_static_google_spanner_admin_database_v1_CreateDatabaseMetadata_descriptor = getDescriptor().getMessageTypes().get(5); @@ -502,7 +510,7 @@ public static com.google.protobuf.Descriptors.FileDescriptor getDescriptor() { new com.google.protobuf.GeneratedMessageV3.FieldAccessorTable( internal_static_google_spanner_admin_database_v1_UpdateDatabaseDdlRequest_descriptor, new java.lang.String[] { - "Database", "Statements", "OperationId", + "Database", "Statements", "OperationId", "ProtoDescriptors", }); internal_static_google_spanner_admin_database_v1_DdlStatementActionInfo_descriptor = getDescriptor().getMessageTypes().get(10); @@ -542,7 +550,7 @@ public static com.google.protobuf.Descriptors.FileDescriptor getDescriptor() { new com.google.protobuf.GeneratedMessageV3.FieldAccessorTable( internal_static_google_spanner_admin_database_v1_GetDatabaseDdlResponse_descriptor, new java.lang.String[] { - "Statements", + "Statements", "ProtoDescriptors", }); internal_static_google_spanner_admin_database_v1_ListDatabaseOperationsRequest_descriptor = getDescriptor().getMessageTypes().get(15); diff --git a/proto-google-cloud-spanner-admin-database-v1/src/main/java/com/google/spanner/admin/database/v1/UpdateBackupRequest.java b/proto-google-cloud-spanner-admin-database-v1/src/main/java/com/google/spanner/admin/database/v1/UpdateBackupRequest.java index bf34a574996..5645f3e03e7 100644 --- a/proto-google-cloud-spanner-admin-database-v1/src/main/java/com/google/spanner/admin/database/v1/UpdateBackupRequest.java +++ b/proto-google-cloud-spanner-admin-database-v1/src/main/java/com/google/spanner/admin/database/v1/UpdateBackupRequest.java @@ -1,5 +1,5 @@ /* - * Copyright 2023 Google LLC + * Copyright 2024 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/proto-google-cloud-spanner-admin-database-v1/src/main/java/com/google/spanner/admin/database/v1/UpdateBackupRequestOrBuilder.java b/proto-google-cloud-spanner-admin-database-v1/src/main/java/com/google/spanner/admin/database/v1/UpdateBackupRequestOrBuilder.java index cffc8d5e4f2..0339bd06fc6 100644 --- a/proto-google-cloud-spanner-admin-database-v1/src/main/java/com/google/spanner/admin/database/v1/UpdateBackupRequestOrBuilder.java +++ b/proto-google-cloud-spanner-admin-database-v1/src/main/java/com/google/spanner/admin/database/v1/UpdateBackupRequestOrBuilder.java @@ -1,5 +1,5 @@ /* - * Copyright 2023 Google LLC + * Copyright 2024 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/proto-google-cloud-spanner-admin-database-v1/src/main/java/com/google/spanner/admin/database/v1/UpdateDatabaseDdlMetadata.java b/proto-google-cloud-spanner-admin-database-v1/src/main/java/com/google/spanner/admin/database/v1/UpdateDatabaseDdlMetadata.java index 552455f8175..c8956be4985 100644 --- a/proto-google-cloud-spanner-admin-database-v1/src/main/java/com/google/spanner/admin/database/v1/UpdateDatabaseDdlMetadata.java +++ b/proto-google-cloud-spanner-admin-database-v1/src/main/java/com/google/spanner/admin/database/v1/UpdateDatabaseDdlMetadata.java @@ -1,5 +1,5 @@ /* - * Copyright 2023 Google LLC + * Copyright 2024 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/proto-google-cloud-spanner-admin-database-v1/src/main/java/com/google/spanner/admin/database/v1/UpdateDatabaseDdlMetadataOrBuilder.java b/proto-google-cloud-spanner-admin-database-v1/src/main/java/com/google/spanner/admin/database/v1/UpdateDatabaseDdlMetadataOrBuilder.java index 1668105e9ca..8e6315bcfec 100644 --- a/proto-google-cloud-spanner-admin-database-v1/src/main/java/com/google/spanner/admin/database/v1/UpdateDatabaseDdlMetadataOrBuilder.java +++ b/proto-google-cloud-spanner-admin-database-v1/src/main/java/com/google/spanner/admin/database/v1/UpdateDatabaseDdlMetadataOrBuilder.java @@ -1,5 +1,5 @@ /* - * Copyright 2023 Google LLC + * Copyright 2024 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/proto-google-cloud-spanner-admin-database-v1/src/main/java/com/google/spanner/admin/database/v1/UpdateDatabaseDdlRequest.java b/proto-google-cloud-spanner-admin-database-v1/src/main/java/com/google/spanner/admin/database/v1/UpdateDatabaseDdlRequest.java index dee90581940..075dcbbd7b4 100644 --- a/proto-google-cloud-spanner-admin-database-v1/src/main/java/com/google/spanner/admin/database/v1/UpdateDatabaseDdlRequest.java +++ b/proto-google-cloud-spanner-admin-database-v1/src/main/java/com/google/spanner/admin/database/v1/UpdateDatabaseDdlRequest.java @@ -1,5 +1,5 @@ /* - * Copyright 2023 Google LLC + * Copyright 2024 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -56,6 +56,7 @@ private UpdateDatabaseDdlRequest() { database_ = ""; statements_ = com.google.protobuf.LazyStringArrayList.emptyList(); operationId_ = ""; + protoDescriptors_ = com.google.protobuf.ByteString.EMPTY; } @java.lang.Override @@ -285,6 +286,37 @@ public com.google.protobuf.ByteString getOperationIdBytes() { } } + public static final int PROTO_DESCRIPTORS_FIELD_NUMBER = 4; + private com.google.protobuf.ByteString protoDescriptors_ = com.google.protobuf.ByteString.EMPTY; + /** + * + * + *
+   * Optional. Proto descriptors used by CREATE/ALTER PROTO BUNDLE statements.
+   * Contains a protobuf-serialized
+   * [google.protobuf.FileDescriptorSet](https://github.com/protocolbuffers/protobuf/blob/main/src/google/protobuf/descriptor.proto).
+   * To generate it, [install](https://grpc.io/docs/protoc-installation/) and
+   * run `protoc` with --include_imports and --descriptor_set_out. For example,
+   * to generate for moon/shot/app.proto, run
+   * ```
+   * $protoc  --proto_path=/app_path --proto_path=/lib_path \
+   *          --include_imports \
+   *          --descriptor_set_out=descriptors.data \
+   *          moon/shot/app.proto
+   * ```
+   * For more details, see protobuffer [self
+   * description](https://developers.google.com/protocol-buffers/docs/techniques#self-description).
+   * 
+ * + * bytes proto_descriptors = 4 [(.google.api.field_behavior) = OPTIONAL]; + * + * @return The protoDescriptors. + */ + @java.lang.Override + public com.google.protobuf.ByteString getProtoDescriptors() { + return protoDescriptors_; + } + private byte memoizedIsInitialized = -1; @java.lang.Override @@ -308,6 +340,9 @@ public void writeTo(com.google.protobuf.CodedOutputStream output) throws java.io if (!com.google.protobuf.GeneratedMessageV3.isStringEmpty(operationId_)) { com.google.protobuf.GeneratedMessageV3.writeString(output, 3, operationId_); } + if (!protoDescriptors_.isEmpty()) { + output.writeBytes(4, protoDescriptors_); + } getUnknownFields().writeTo(output); } @@ -331,6 +366,9 @@ public int getSerializedSize() { if (!com.google.protobuf.GeneratedMessageV3.isStringEmpty(operationId_)) { size += com.google.protobuf.GeneratedMessageV3.computeStringSize(3, operationId_); } + if (!protoDescriptors_.isEmpty()) { + size += com.google.protobuf.CodedOutputStream.computeBytesSize(4, protoDescriptors_); + } size += getUnknownFields().getSerializedSize(); memoizedSize = size; return size; @@ -350,6 +388,7 @@ public boolean equals(final java.lang.Object obj) { if (!getDatabase().equals(other.getDatabase())) return false; if (!getStatementsList().equals(other.getStatementsList())) return false; if (!getOperationId().equals(other.getOperationId())) return false; + if (!getProtoDescriptors().equals(other.getProtoDescriptors())) return false; if (!getUnknownFields().equals(other.getUnknownFields())) return false; return true; } @@ -369,6 +408,8 @@ public int hashCode() { } hash = (37 * hash) + OPERATION_ID_FIELD_NUMBER; hash = (53 * hash) + getOperationId().hashCode(); + hash = (37 * hash) + PROTO_DESCRIPTORS_FIELD_NUMBER; + hash = (53 * hash) + getProtoDescriptors().hashCode(); hash = (29 * hash) + getUnknownFields().hashCode(); memoizedHashCode = hash; return hash; @@ -527,6 +568,7 @@ public Builder clear() { database_ = ""; statements_ = com.google.protobuf.LazyStringArrayList.emptyList(); operationId_ = ""; + protoDescriptors_ = com.google.protobuf.ByteString.EMPTY; return this; } @@ -575,6 +617,9 @@ private void buildPartial0( if (((from_bitField0_ & 0x00000004) != 0)) { result.operationId_ = operationId_; } + if (((from_bitField0_ & 0x00000008) != 0)) { + result.protoDescriptors_ = protoDescriptors_; + } } @java.lang.Override @@ -644,6 +689,9 @@ public Builder mergeFrom(com.google.spanner.admin.database.v1.UpdateDatabaseDdlR bitField0_ |= 0x00000004; onChanged(); } + if (other.getProtoDescriptors() != com.google.protobuf.ByteString.EMPTY) { + setProtoDescriptors(other.getProtoDescriptors()); + } this.mergeUnknownFields(other.getUnknownFields()); onChanged(); return this; @@ -689,6 +737,12 @@ public Builder mergeFrom( bitField0_ |= 0x00000004; break; } // case 26 + case 34: + { + protoDescriptors_ = input.readBytes(); + bitField0_ |= 0x00000008; + break; + } // case 34 default: { if (!super.parseUnknownField(input, extensionRegistry, tag)) { @@ -1194,6 +1248,100 @@ public Builder setOperationIdBytes(com.google.protobuf.ByteString value) { return this; } + private com.google.protobuf.ByteString protoDescriptors_ = com.google.protobuf.ByteString.EMPTY; + /** + * + * + *
+     * Optional. Proto descriptors used by CREATE/ALTER PROTO BUNDLE statements.
+     * Contains a protobuf-serialized
+     * [google.protobuf.FileDescriptorSet](https://github.com/protocolbuffers/protobuf/blob/main/src/google/protobuf/descriptor.proto).
+     * To generate it, [install](https://grpc.io/docs/protoc-installation/) and
+     * run `protoc` with --include_imports and --descriptor_set_out. For example,
+     * to generate for moon/shot/app.proto, run
+     * ```
+     * $protoc  --proto_path=/app_path --proto_path=/lib_path \
+     *          --include_imports \
+     *          --descriptor_set_out=descriptors.data \
+     *          moon/shot/app.proto
+     * ```
+     * For more details, see protobuffer [self
+     * description](https://developers.google.com/protocol-buffers/docs/techniques#self-description).
+     * 
+ * + * bytes proto_descriptors = 4 [(.google.api.field_behavior) = OPTIONAL]; + * + * @return The protoDescriptors. + */ + @java.lang.Override + public com.google.protobuf.ByteString getProtoDescriptors() { + return protoDescriptors_; + } + /** + * + * + *
+     * Optional. Proto descriptors used by CREATE/ALTER PROTO BUNDLE statements.
+     * Contains a protobuf-serialized
+     * [google.protobuf.FileDescriptorSet](https://github.com/protocolbuffers/protobuf/blob/main/src/google/protobuf/descriptor.proto).
+     * To generate it, [install](https://grpc.io/docs/protoc-installation/) and
+     * run `protoc` with --include_imports and --descriptor_set_out. For example,
+     * to generate for moon/shot/app.proto, run
+     * ```
+     * $protoc  --proto_path=/app_path --proto_path=/lib_path \
+     *          --include_imports \
+     *          --descriptor_set_out=descriptors.data \
+     *          moon/shot/app.proto
+     * ```
+     * For more details, see protobuffer [self
+     * description](https://developers.google.com/protocol-buffers/docs/techniques#self-description).
+     * 
+ * + * bytes proto_descriptors = 4 [(.google.api.field_behavior) = OPTIONAL]; + * + * @param value The protoDescriptors to set. + * @return This builder for chaining. + */ + public Builder setProtoDescriptors(com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + protoDescriptors_ = value; + bitField0_ |= 0x00000008; + onChanged(); + return this; + } + /** + * + * + *
+     * Optional. Proto descriptors used by CREATE/ALTER PROTO BUNDLE statements.
+     * Contains a protobuf-serialized
+     * [google.protobuf.FileDescriptorSet](https://github.com/protocolbuffers/protobuf/blob/main/src/google/protobuf/descriptor.proto).
+     * To generate it, [install](https://grpc.io/docs/protoc-installation/) and
+     * run `protoc` with --include_imports and --descriptor_set_out. For example,
+     * to generate for moon/shot/app.proto, run
+     * ```
+     * $protoc  --proto_path=/app_path --proto_path=/lib_path \
+     *          --include_imports \
+     *          --descriptor_set_out=descriptors.data \
+     *          moon/shot/app.proto
+     * ```
+     * For more details, see protobuffer [self
+     * description](https://developers.google.com/protocol-buffers/docs/techniques#self-description).
+     * 
+ * + * bytes proto_descriptors = 4 [(.google.api.field_behavior) = OPTIONAL]; + * + * @return This builder for chaining. + */ + public Builder clearProtoDescriptors() { + bitField0_ = (bitField0_ & ~0x00000008); + protoDescriptors_ = getDefaultInstance().getProtoDescriptors(); + onChanged(); + return this; + } + @java.lang.Override public final Builder setUnknownFields(final com.google.protobuf.UnknownFieldSet unknownFields) { return super.setUnknownFields(unknownFields); diff --git a/proto-google-cloud-spanner-admin-database-v1/src/main/java/com/google/spanner/admin/database/v1/UpdateDatabaseDdlRequestOrBuilder.java b/proto-google-cloud-spanner-admin-database-v1/src/main/java/com/google/spanner/admin/database/v1/UpdateDatabaseDdlRequestOrBuilder.java index ead26bcfab8..a618ebf9779 100644 --- a/proto-google-cloud-spanner-admin-database-v1/src/main/java/com/google/spanner/admin/database/v1/UpdateDatabaseDdlRequestOrBuilder.java +++ b/proto-google-cloud-spanner-admin-database-v1/src/main/java/com/google/spanner/admin/database/v1/UpdateDatabaseDdlRequestOrBuilder.java @@ -1,5 +1,5 @@ /* - * Copyright 2023 Google LLC + * Copyright 2024 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -163,4 +163,30 @@ public interface UpdateDatabaseDdlRequestOrBuilder * @return The bytes for operationId. */ com.google.protobuf.ByteString getOperationIdBytes(); + + /** + * + * + *
+   * Optional. Proto descriptors used by CREATE/ALTER PROTO BUNDLE statements.
+   * Contains a protobuf-serialized
+   * [google.protobuf.FileDescriptorSet](https://github.com/protocolbuffers/protobuf/blob/main/src/google/protobuf/descriptor.proto).
+   * To generate it, [install](https://grpc.io/docs/protoc-installation/) and
+   * run `protoc` with --include_imports and --descriptor_set_out. For example,
+   * to generate for moon/shot/app.proto, run
+   * ```
+   * $protoc  --proto_path=/app_path --proto_path=/lib_path \
+   *          --include_imports \
+   *          --descriptor_set_out=descriptors.data \
+   *          moon/shot/app.proto
+   * ```
+   * For more details, see protobuffer [self
+   * description](https://developers.google.com/protocol-buffers/docs/techniques#self-description).
+   * 
+ * + * bytes proto_descriptors = 4 [(.google.api.field_behavior) = OPTIONAL]; + * + * @return The protoDescriptors. + */ + com.google.protobuf.ByteString getProtoDescriptors(); } diff --git a/proto-google-cloud-spanner-admin-database-v1/src/main/java/com/google/spanner/admin/database/v1/UpdateDatabaseMetadata.java b/proto-google-cloud-spanner-admin-database-v1/src/main/java/com/google/spanner/admin/database/v1/UpdateDatabaseMetadata.java index f8cd92a0673..81b6adec5f7 100644 --- a/proto-google-cloud-spanner-admin-database-v1/src/main/java/com/google/spanner/admin/database/v1/UpdateDatabaseMetadata.java +++ b/proto-google-cloud-spanner-admin-database-v1/src/main/java/com/google/spanner/admin/database/v1/UpdateDatabaseMetadata.java @@ -1,5 +1,5 @@ /* - * Copyright 2023 Google LLC + * Copyright 2024 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/proto-google-cloud-spanner-admin-database-v1/src/main/java/com/google/spanner/admin/database/v1/UpdateDatabaseMetadataOrBuilder.java b/proto-google-cloud-spanner-admin-database-v1/src/main/java/com/google/spanner/admin/database/v1/UpdateDatabaseMetadataOrBuilder.java index c96e6bef5fa..e4480f1e014 100644 --- a/proto-google-cloud-spanner-admin-database-v1/src/main/java/com/google/spanner/admin/database/v1/UpdateDatabaseMetadataOrBuilder.java +++ b/proto-google-cloud-spanner-admin-database-v1/src/main/java/com/google/spanner/admin/database/v1/UpdateDatabaseMetadataOrBuilder.java @@ -1,5 +1,5 @@ /* - * Copyright 2023 Google LLC + * Copyright 2024 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/proto-google-cloud-spanner-admin-database-v1/src/main/java/com/google/spanner/admin/database/v1/UpdateDatabaseRequest.java b/proto-google-cloud-spanner-admin-database-v1/src/main/java/com/google/spanner/admin/database/v1/UpdateDatabaseRequest.java index 0934d93a05c..0756611771c 100644 --- a/proto-google-cloud-spanner-admin-database-v1/src/main/java/com/google/spanner/admin/database/v1/UpdateDatabaseRequest.java +++ b/proto-google-cloud-spanner-admin-database-v1/src/main/java/com/google/spanner/admin/database/v1/UpdateDatabaseRequest.java @@ -1,5 +1,5 @@ /* - * Copyright 2023 Google LLC + * Copyright 2024 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/proto-google-cloud-spanner-admin-database-v1/src/main/java/com/google/spanner/admin/database/v1/UpdateDatabaseRequestOrBuilder.java b/proto-google-cloud-spanner-admin-database-v1/src/main/java/com/google/spanner/admin/database/v1/UpdateDatabaseRequestOrBuilder.java index a802b81253d..20294f24bd8 100644 --- a/proto-google-cloud-spanner-admin-database-v1/src/main/java/com/google/spanner/admin/database/v1/UpdateDatabaseRequestOrBuilder.java +++ b/proto-google-cloud-spanner-admin-database-v1/src/main/java/com/google/spanner/admin/database/v1/UpdateDatabaseRequestOrBuilder.java @@ -1,5 +1,5 @@ /* - * Copyright 2023 Google LLC + * Copyright 2024 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/proto-google-cloud-spanner-admin-database-v1/src/main/proto/google/spanner/admin/database/v1/spanner_database_admin.proto b/proto-google-cloud-spanner-admin-database-v1/src/main/proto/google/spanner/admin/database/v1/spanner_database_admin.proto index 6cf0e5a4b94..a522c08c18a 100644 --- a/proto-google-cloud-spanner-admin-database-v1/src/main/proto/google/spanner/admin/database/v1/spanner_database_admin.proto +++ b/proto-google-cloud-spanner-admin-database-v1/src/main/proto/google/spanner/admin/database/v1/spanner_database_admin.proto @@ -572,6 +572,23 @@ message CreateDatabaseRequest { // Optional. The dialect of the Cloud Spanner Database. DatabaseDialect database_dialect = 5 [(google.api.field_behavior) = OPTIONAL]; + + // Optional. Proto descriptors used by CREATE/ALTER PROTO BUNDLE statements in + // 'extra_statements' above. + // Contains a protobuf-serialized + // [google.protobuf.FileDescriptorSet](https://github.com/protocolbuffers/protobuf/blob/main/src/google/protobuf/descriptor.proto). + // To generate it, [install](https://grpc.io/docs/protoc-installation/) and + // run `protoc` with --include_imports and --descriptor_set_out. For example, + // to generate for moon/shot/app.proto, run + // ``` + // $protoc --proto_path=/app_path --proto_path=/lib_path \ + // --include_imports \ + // --descriptor_set_out=descriptors.data \ + // moon/shot/app.proto + // ``` + // For more details, see protobuffer [self + // description](https://developers.google.com/protocol-buffers/docs/techniques#self-description). + bytes proto_descriptors = 6 [(google.api.field_behavior) = OPTIONAL]; } // Metadata type for the operation returned by @@ -674,6 +691,22 @@ message UpdateDatabaseDdlRequest { // [UpdateDatabaseDdl][google.spanner.admin.database.v1.DatabaseAdmin.UpdateDatabaseDdl] returns // `ALREADY_EXISTS`. string operation_id = 3; + + // Optional. Proto descriptors used by CREATE/ALTER PROTO BUNDLE statements. + // Contains a protobuf-serialized + // [google.protobuf.FileDescriptorSet](https://github.com/protocolbuffers/protobuf/blob/main/src/google/protobuf/descriptor.proto). + // To generate it, [install](https://grpc.io/docs/protoc-installation/) and + // run `protoc` with --include_imports and --descriptor_set_out. For example, + // to generate for moon/shot/app.proto, run + // ``` + // $protoc --proto_path=/app_path --proto_path=/lib_path \ + // --include_imports \ + // --descriptor_set_out=descriptors.data \ + // moon/shot/app.proto + // ``` + // For more details, see protobuffer [self + // description](https://developers.google.com/protocol-buffers/docs/techniques#self-description). + bytes proto_descriptors = 4 [(google.api.field_behavior) = OPTIONAL]; } // Action information extracted from a DDL statement. This proto is used to @@ -762,6 +795,13 @@ message GetDatabaseDdlResponse { // A list of formatted DDL statements defining the schema of the database // specified in the request. repeated string statements = 1; + + // Proto descriptors stored in the database. + // Contains a protobuf-serialized + // [google.protobuf.FileDescriptorSet](https://github.com/protocolbuffers/protobuf/blob/main/src/google/protobuf/descriptor.proto). + // For more details, see protobuffer [self + // description](https://developers.google.com/protocol-buffers/docs/techniques#self-description). + bytes proto_descriptors = 2; } // The request for diff --git a/proto-google-cloud-spanner-admin-instance-v1/src/main/java/com/google/spanner/admin/instance/v1/AutoscalingConfig.java b/proto-google-cloud-spanner-admin-instance-v1/src/main/java/com/google/spanner/admin/instance/v1/AutoscalingConfig.java index ba30c86c6fd..fb20213f572 100644 --- a/proto-google-cloud-spanner-admin-instance-v1/src/main/java/com/google/spanner/admin/instance/v1/AutoscalingConfig.java +++ b/proto-google-cloud-spanner-admin-instance-v1/src/main/java/com/google/spanner/admin/instance/v1/AutoscalingConfig.java @@ -1,5 +1,5 @@ /* - * Copyright 2023 Google LLC + * Copyright 2024 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/proto-google-cloud-spanner-admin-instance-v1/src/main/java/com/google/spanner/admin/instance/v1/AutoscalingConfigOrBuilder.java b/proto-google-cloud-spanner-admin-instance-v1/src/main/java/com/google/spanner/admin/instance/v1/AutoscalingConfigOrBuilder.java index b9449ad2a0f..358a5281c8b 100644 --- a/proto-google-cloud-spanner-admin-instance-v1/src/main/java/com/google/spanner/admin/instance/v1/AutoscalingConfigOrBuilder.java +++ b/proto-google-cloud-spanner-admin-instance-v1/src/main/java/com/google/spanner/admin/instance/v1/AutoscalingConfigOrBuilder.java @@ -1,5 +1,5 @@ /* - * Copyright 2023 Google LLC + * Copyright 2024 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/proto-google-cloud-spanner-admin-instance-v1/src/main/java/com/google/spanner/admin/instance/v1/CommonProto.java b/proto-google-cloud-spanner-admin-instance-v1/src/main/java/com/google/spanner/admin/instance/v1/CommonProto.java index 7ba46aef4c8..95b9e723cf2 100644 --- a/proto-google-cloud-spanner-admin-instance-v1/src/main/java/com/google/spanner/admin/instance/v1/CommonProto.java +++ b/proto-google-cloud-spanner-admin-instance-v1/src/main/java/com/google/spanner/admin/instance/v1/CommonProto.java @@ -1,5 +1,5 @@ /* - * Copyright 2023 Google LLC + * Copyright 2024 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/proto-google-cloud-spanner-admin-instance-v1/src/main/java/com/google/spanner/admin/instance/v1/CreateInstanceConfigMetadata.java b/proto-google-cloud-spanner-admin-instance-v1/src/main/java/com/google/spanner/admin/instance/v1/CreateInstanceConfigMetadata.java index 383a27b4ffb..11dc2aa5fe6 100644 --- a/proto-google-cloud-spanner-admin-instance-v1/src/main/java/com/google/spanner/admin/instance/v1/CreateInstanceConfigMetadata.java +++ b/proto-google-cloud-spanner-admin-instance-v1/src/main/java/com/google/spanner/admin/instance/v1/CreateInstanceConfigMetadata.java @@ -1,5 +1,5 @@ /* - * Copyright 2023 Google LLC + * Copyright 2024 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/proto-google-cloud-spanner-admin-instance-v1/src/main/java/com/google/spanner/admin/instance/v1/CreateInstanceConfigMetadataOrBuilder.java b/proto-google-cloud-spanner-admin-instance-v1/src/main/java/com/google/spanner/admin/instance/v1/CreateInstanceConfigMetadataOrBuilder.java index 42188854244..233a017fba4 100644 --- a/proto-google-cloud-spanner-admin-instance-v1/src/main/java/com/google/spanner/admin/instance/v1/CreateInstanceConfigMetadataOrBuilder.java +++ b/proto-google-cloud-spanner-admin-instance-v1/src/main/java/com/google/spanner/admin/instance/v1/CreateInstanceConfigMetadataOrBuilder.java @@ -1,5 +1,5 @@ /* - * Copyright 2023 Google LLC + * Copyright 2024 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/proto-google-cloud-spanner-admin-instance-v1/src/main/java/com/google/spanner/admin/instance/v1/CreateInstanceConfigRequest.java b/proto-google-cloud-spanner-admin-instance-v1/src/main/java/com/google/spanner/admin/instance/v1/CreateInstanceConfigRequest.java index ca7fbf66518..def7e7476f7 100644 --- a/proto-google-cloud-spanner-admin-instance-v1/src/main/java/com/google/spanner/admin/instance/v1/CreateInstanceConfigRequest.java +++ b/proto-google-cloud-spanner-admin-instance-v1/src/main/java/com/google/spanner/admin/instance/v1/CreateInstanceConfigRequest.java @@ -1,5 +1,5 @@ /* - * Copyright 2023 Google LLC + * Copyright 2024 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/proto-google-cloud-spanner-admin-instance-v1/src/main/java/com/google/spanner/admin/instance/v1/CreateInstanceConfigRequestOrBuilder.java b/proto-google-cloud-spanner-admin-instance-v1/src/main/java/com/google/spanner/admin/instance/v1/CreateInstanceConfigRequestOrBuilder.java index 80f27abe104..ad187989070 100644 --- a/proto-google-cloud-spanner-admin-instance-v1/src/main/java/com/google/spanner/admin/instance/v1/CreateInstanceConfigRequestOrBuilder.java +++ b/proto-google-cloud-spanner-admin-instance-v1/src/main/java/com/google/spanner/admin/instance/v1/CreateInstanceConfigRequestOrBuilder.java @@ -1,5 +1,5 @@ /* - * Copyright 2023 Google LLC + * Copyright 2024 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/proto-google-cloud-spanner-admin-instance-v1/src/main/java/com/google/spanner/admin/instance/v1/CreateInstanceMetadata.java b/proto-google-cloud-spanner-admin-instance-v1/src/main/java/com/google/spanner/admin/instance/v1/CreateInstanceMetadata.java index 0aa8cef0567..7d0e1b14f0b 100644 --- a/proto-google-cloud-spanner-admin-instance-v1/src/main/java/com/google/spanner/admin/instance/v1/CreateInstanceMetadata.java +++ b/proto-google-cloud-spanner-admin-instance-v1/src/main/java/com/google/spanner/admin/instance/v1/CreateInstanceMetadata.java @@ -1,5 +1,5 @@ /* - * Copyright 2023 Google LLC + * Copyright 2024 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/proto-google-cloud-spanner-admin-instance-v1/src/main/java/com/google/spanner/admin/instance/v1/CreateInstanceMetadataOrBuilder.java b/proto-google-cloud-spanner-admin-instance-v1/src/main/java/com/google/spanner/admin/instance/v1/CreateInstanceMetadataOrBuilder.java index c294c0d46bf..cd3fe91d321 100644 --- a/proto-google-cloud-spanner-admin-instance-v1/src/main/java/com/google/spanner/admin/instance/v1/CreateInstanceMetadataOrBuilder.java +++ b/proto-google-cloud-spanner-admin-instance-v1/src/main/java/com/google/spanner/admin/instance/v1/CreateInstanceMetadataOrBuilder.java @@ -1,5 +1,5 @@ /* - * Copyright 2023 Google LLC + * Copyright 2024 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/proto-google-cloud-spanner-admin-instance-v1/src/main/java/com/google/spanner/admin/instance/v1/CreateInstanceRequest.java b/proto-google-cloud-spanner-admin-instance-v1/src/main/java/com/google/spanner/admin/instance/v1/CreateInstanceRequest.java index 19cbc45e551..5b2719a04ea 100644 --- a/proto-google-cloud-spanner-admin-instance-v1/src/main/java/com/google/spanner/admin/instance/v1/CreateInstanceRequest.java +++ b/proto-google-cloud-spanner-admin-instance-v1/src/main/java/com/google/spanner/admin/instance/v1/CreateInstanceRequest.java @@ -1,5 +1,5 @@ /* - * Copyright 2023 Google LLC + * Copyright 2024 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/proto-google-cloud-spanner-admin-instance-v1/src/main/java/com/google/spanner/admin/instance/v1/CreateInstanceRequestOrBuilder.java b/proto-google-cloud-spanner-admin-instance-v1/src/main/java/com/google/spanner/admin/instance/v1/CreateInstanceRequestOrBuilder.java index 8f97e2a94ca..a89c49804eb 100644 --- a/proto-google-cloud-spanner-admin-instance-v1/src/main/java/com/google/spanner/admin/instance/v1/CreateInstanceRequestOrBuilder.java +++ b/proto-google-cloud-spanner-admin-instance-v1/src/main/java/com/google/spanner/admin/instance/v1/CreateInstanceRequestOrBuilder.java @@ -1,5 +1,5 @@ /* - * Copyright 2023 Google LLC + * Copyright 2024 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/proto-google-cloud-spanner-admin-instance-v1/src/main/java/com/google/spanner/admin/instance/v1/DeleteInstanceConfigRequest.java b/proto-google-cloud-spanner-admin-instance-v1/src/main/java/com/google/spanner/admin/instance/v1/DeleteInstanceConfigRequest.java index 902f2c7043f..67f46b56ace 100644 --- a/proto-google-cloud-spanner-admin-instance-v1/src/main/java/com/google/spanner/admin/instance/v1/DeleteInstanceConfigRequest.java +++ b/proto-google-cloud-spanner-admin-instance-v1/src/main/java/com/google/spanner/admin/instance/v1/DeleteInstanceConfigRequest.java @@ -1,5 +1,5 @@ /* - * Copyright 2023 Google LLC + * Copyright 2024 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/proto-google-cloud-spanner-admin-instance-v1/src/main/java/com/google/spanner/admin/instance/v1/DeleteInstanceConfigRequestOrBuilder.java b/proto-google-cloud-spanner-admin-instance-v1/src/main/java/com/google/spanner/admin/instance/v1/DeleteInstanceConfigRequestOrBuilder.java index 396f633f9a3..0657b4b9c2a 100644 --- a/proto-google-cloud-spanner-admin-instance-v1/src/main/java/com/google/spanner/admin/instance/v1/DeleteInstanceConfigRequestOrBuilder.java +++ b/proto-google-cloud-spanner-admin-instance-v1/src/main/java/com/google/spanner/admin/instance/v1/DeleteInstanceConfigRequestOrBuilder.java @@ -1,5 +1,5 @@ /* - * Copyright 2023 Google LLC + * Copyright 2024 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/proto-google-cloud-spanner-admin-instance-v1/src/main/java/com/google/spanner/admin/instance/v1/DeleteInstanceRequest.java b/proto-google-cloud-spanner-admin-instance-v1/src/main/java/com/google/spanner/admin/instance/v1/DeleteInstanceRequest.java index 06d344081a7..594fde31b58 100644 --- a/proto-google-cloud-spanner-admin-instance-v1/src/main/java/com/google/spanner/admin/instance/v1/DeleteInstanceRequest.java +++ b/proto-google-cloud-spanner-admin-instance-v1/src/main/java/com/google/spanner/admin/instance/v1/DeleteInstanceRequest.java @@ -1,5 +1,5 @@ /* - * Copyright 2023 Google LLC + * Copyright 2024 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/proto-google-cloud-spanner-admin-instance-v1/src/main/java/com/google/spanner/admin/instance/v1/DeleteInstanceRequestOrBuilder.java b/proto-google-cloud-spanner-admin-instance-v1/src/main/java/com/google/spanner/admin/instance/v1/DeleteInstanceRequestOrBuilder.java index 57d7ec7faaf..f31c322641e 100644 --- a/proto-google-cloud-spanner-admin-instance-v1/src/main/java/com/google/spanner/admin/instance/v1/DeleteInstanceRequestOrBuilder.java +++ b/proto-google-cloud-spanner-admin-instance-v1/src/main/java/com/google/spanner/admin/instance/v1/DeleteInstanceRequestOrBuilder.java @@ -1,5 +1,5 @@ /* - * Copyright 2023 Google LLC + * Copyright 2024 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/proto-google-cloud-spanner-admin-instance-v1/src/main/java/com/google/spanner/admin/instance/v1/GetInstanceConfigRequest.java b/proto-google-cloud-spanner-admin-instance-v1/src/main/java/com/google/spanner/admin/instance/v1/GetInstanceConfigRequest.java index c4de114d587..bdfa0d8bb0c 100644 --- a/proto-google-cloud-spanner-admin-instance-v1/src/main/java/com/google/spanner/admin/instance/v1/GetInstanceConfigRequest.java +++ b/proto-google-cloud-spanner-admin-instance-v1/src/main/java/com/google/spanner/admin/instance/v1/GetInstanceConfigRequest.java @@ -1,5 +1,5 @@ /* - * Copyright 2023 Google LLC + * Copyright 2024 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/proto-google-cloud-spanner-admin-instance-v1/src/main/java/com/google/spanner/admin/instance/v1/GetInstanceConfigRequestOrBuilder.java b/proto-google-cloud-spanner-admin-instance-v1/src/main/java/com/google/spanner/admin/instance/v1/GetInstanceConfigRequestOrBuilder.java index 00bdd435ba3..cec59d4a80a 100644 --- a/proto-google-cloud-spanner-admin-instance-v1/src/main/java/com/google/spanner/admin/instance/v1/GetInstanceConfigRequestOrBuilder.java +++ b/proto-google-cloud-spanner-admin-instance-v1/src/main/java/com/google/spanner/admin/instance/v1/GetInstanceConfigRequestOrBuilder.java @@ -1,5 +1,5 @@ /* - * Copyright 2023 Google LLC + * Copyright 2024 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/proto-google-cloud-spanner-admin-instance-v1/src/main/java/com/google/spanner/admin/instance/v1/GetInstanceRequest.java b/proto-google-cloud-spanner-admin-instance-v1/src/main/java/com/google/spanner/admin/instance/v1/GetInstanceRequest.java index b720c34def6..ba09001f47f 100644 --- a/proto-google-cloud-spanner-admin-instance-v1/src/main/java/com/google/spanner/admin/instance/v1/GetInstanceRequest.java +++ b/proto-google-cloud-spanner-admin-instance-v1/src/main/java/com/google/spanner/admin/instance/v1/GetInstanceRequest.java @@ -1,5 +1,5 @@ /* - * Copyright 2023 Google LLC + * Copyright 2024 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/proto-google-cloud-spanner-admin-instance-v1/src/main/java/com/google/spanner/admin/instance/v1/GetInstanceRequestOrBuilder.java b/proto-google-cloud-spanner-admin-instance-v1/src/main/java/com/google/spanner/admin/instance/v1/GetInstanceRequestOrBuilder.java index 5376dc8e957..ad5fd65c9d6 100644 --- a/proto-google-cloud-spanner-admin-instance-v1/src/main/java/com/google/spanner/admin/instance/v1/GetInstanceRequestOrBuilder.java +++ b/proto-google-cloud-spanner-admin-instance-v1/src/main/java/com/google/spanner/admin/instance/v1/GetInstanceRequestOrBuilder.java @@ -1,5 +1,5 @@ /* - * Copyright 2023 Google LLC + * Copyright 2024 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/proto-google-cloud-spanner-admin-instance-v1/src/main/java/com/google/spanner/admin/instance/v1/Instance.java b/proto-google-cloud-spanner-admin-instance-v1/src/main/java/com/google/spanner/admin/instance/v1/Instance.java index de469ab4ee1..2140d88bc24 100644 --- a/proto-google-cloud-spanner-admin-instance-v1/src/main/java/com/google/spanner/admin/instance/v1/Instance.java +++ b/proto-google-cloud-spanner-admin-instance-v1/src/main/java/com/google/spanner/admin/instance/v1/Instance.java @@ -1,5 +1,5 @@ /* - * Copyright 2023 Google LLC + * Copyright 2024 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/proto-google-cloud-spanner-admin-instance-v1/src/main/java/com/google/spanner/admin/instance/v1/InstanceConfig.java b/proto-google-cloud-spanner-admin-instance-v1/src/main/java/com/google/spanner/admin/instance/v1/InstanceConfig.java index d2da1f12a60..ef83dd4a1f4 100644 --- a/proto-google-cloud-spanner-admin-instance-v1/src/main/java/com/google/spanner/admin/instance/v1/InstanceConfig.java +++ b/proto-google-cloud-spanner-admin-instance-v1/src/main/java/com/google/spanner/admin/instance/v1/InstanceConfig.java @@ -1,5 +1,5 @@ /* - * Copyright 2023 Google LLC + * Copyright 2024 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/proto-google-cloud-spanner-admin-instance-v1/src/main/java/com/google/spanner/admin/instance/v1/InstanceConfigOrBuilder.java b/proto-google-cloud-spanner-admin-instance-v1/src/main/java/com/google/spanner/admin/instance/v1/InstanceConfigOrBuilder.java index cf2d7e56c9f..3a2a3629377 100644 --- a/proto-google-cloud-spanner-admin-instance-v1/src/main/java/com/google/spanner/admin/instance/v1/InstanceConfigOrBuilder.java +++ b/proto-google-cloud-spanner-admin-instance-v1/src/main/java/com/google/spanner/admin/instance/v1/InstanceConfigOrBuilder.java @@ -1,5 +1,5 @@ /* - * Copyright 2023 Google LLC + * Copyright 2024 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/proto-google-cloud-spanner-admin-instance-v1/src/main/java/com/google/spanner/admin/instance/v1/InstanceOrBuilder.java b/proto-google-cloud-spanner-admin-instance-v1/src/main/java/com/google/spanner/admin/instance/v1/InstanceOrBuilder.java index 81305322e75..b2d4f2ba3f0 100644 --- a/proto-google-cloud-spanner-admin-instance-v1/src/main/java/com/google/spanner/admin/instance/v1/InstanceOrBuilder.java +++ b/proto-google-cloud-spanner-admin-instance-v1/src/main/java/com/google/spanner/admin/instance/v1/InstanceOrBuilder.java @@ -1,5 +1,5 @@ /* - * Copyright 2023 Google LLC + * Copyright 2024 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/proto-google-cloud-spanner-admin-instance-v1/src/main/java/com/google/spanner/admin/instance/v1/ListInstanceConfigOperationsRequest.java b/proto-google-cloud-spanner-admin-instance-v1/src/main/java/com/google/spanner/admin/instance/v1/ListInstanceConfigOperationsRequest.java index e92b768f4b1..9068c1d1686 100644 --- a/proto-google-cloud-spanner-admin-instance-v1/src/main/java/com/google/spanner/admin/instance/v1/ListInstanceConfigOperationsRequest.java +++ b/proto-google-cloud-spanner-admin-instance-v1/src/main/java/com/google/spanner/admin/instance/v1/ListInstanceConfigOperationsRequest.java @@ -1,5 +1,5 @@ /* - * Copyright 2023 Google LLC + * Copyright 2024 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/proto-google-cloud-spanner-admin-instance-v1/src/main/java/com/google/spanner/admin/instance/v1/ListInstanceConfigOperationsRequestOrBuilder.java b/proto-google-cloud-spanner-admin-instance-v1/src/main/java/com/google/spanner/admin/instance/v1/ListInstanceConfigOperationsRequestOrBuilder.java index f07f113e887..ac6be607e17 100644 --- a/proto-google-cloud-spanner-admin-instance-v1/src/main/java/com/google/spanner/admin/instance/v1/ListInstanceConfigOperationsRequestOrBuilder.java +++ b/proto-google-cloud-spanner-admin-instance-v1/src/main/java/com/google/spanner/admin/instance/v1/ListInstanceConfigOperationsRequestOrBuilder.java @@ -1,5 +1,5 @@ /* - * Copyright 2023 Google LLC + * Copyright 2024 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/proto-google-cloud-spanner-admin-instance-v1/src/main/java/com/google/spanner/admin/instance/v1/ListInstanceConfigOperationsResponse.java b/proto-google-cloud-spanner-admin-instance-v1/src/main/java/com/google/spanner/admin/instance/v1/ListInstanceConfigOperationsResponse.java index 13089b74288..9ac6ecc3b4f 100644 --- a/proto-google-cloud-spanner-admin-instance-v1/src/main/java/com/google/spanner/admin/instance/v1/ListInstanceConfigOperationsResponse.java +++ b/proto-google-cloud-spanner-admin-instance-v1/src/main/java/com/google/spanner/admin/instance/v1/ListInstanceConfigOperationsResponse.java @@ -1,5 +1,5 @@ /* - * Copyright 2023 Google LLC + * Copyright 2024 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/proto-google-cloud-spanner-admin-instance-v1/src/main/java/com/google/spanner/admin/instance/v1/ListInstanceConfigOperationsResponseOrBuilder.java b/proto-google-cloud-spanner-admin-instance-v1/src/main/java/com/google/spanner/admin/instance/v1/ListInstanceConfigOperationsResponseOrBuilder.java index f2ee88e1cbf..c0bd54d5020 100644 --- a/proto-google-cloud-spanner-admin-instance-v1/src/main/java/com/google/spanner/admin/instance/v1/ListInstanceConfigOperationsResponseOrBuilder.java +++ b/proto-google-cloud-spanner-admin-instance-v1/src/main/java/com/google/spanner/admin/instance/v1/ListInstanceConfigOperationsResponseOrBuilder.java @@ -1,5 +1,5 @@ /* - * Copyright 2023 Google LLC + * Copyright 2024 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/proto-google-cloud-spanner-admin-instance-v1/src/main/java/com/google/spanner/admin/instance/v1/ListInstanceConfigsRequest.java b/proto-google-cloud-spanner-admin-instance-v1/src/main/java/com/google/spanner/admin/instance/v1/ListInstanceConfigsRequest.java index 5e8a8d11666..ee90cbd02e3 100644 --- a/proto-google-cloud-spanner-admin-instance-v1/src/main/java/com/google/spanner/admin/instance/v1/ListInstanceConfigsRequest.java +++ b/proto-google-cloud-spanner-admin-instance-v1/src/main/java/com/google/spanner/admin/instance/v1/ListInstanceConfigsRequest.java @@ -1,5 +1,5 @@ /* - * Copyright 2023 Google LLC + * Copyright 2024 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/proto-google-cloud-spanner-admin-instance-v1/src/main/java/com/google/spanner/admin/instance/v1/ListInstanceConfigsRequestOrBuilder.java b/proto-google-cloud-spanner-admin-instance-v1/src/main/java/com/google/spanner/admin/instance/v1/ListInstanceConfigsRequestOrBuilder.java index 1776f0fb515..30ac4de8e19 100644 --- a/proto-google-cloud-spanner-admin-instance-v1/src/main/java/com/google/spanner/admin/instance/v1/ListInstanceConfigsRequestOrBuilder.java +++ b/proto-google-cloud-spanner-admin-instance-v1/src/main/java/com/google/spanner/admin/instance/v1/ListInstanceConfigsRequestOrBuilder.java @@ -1,5 +1,5 @@ /* - * Copyright 2023 Google LLC + * Copyright 2024 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/proto-google-cloud-spanner-admin-instance-v1/src/main/java/com/google/spanner/admin/instance/v1/ListInstanceConfigsResponse.java b/proto-google-cloud-spanner-admin-instance-v1/src/main/java/com/google/spanner/admin/instance/v1/ListInstanceConfigsResponse.java index 69956ba6452..cd540ab9172 100644 --- a/proto-google-cloud-spanner-admin-instance-v1/src/main/java/com/google/spanner/admin/instance/v1/ListInstanceConfigsResponse.java +++ b/proto-google-cloud-spanner-admin-instance-v1/src/main/java/com/google/spanner/admin/instance/v1/ListInstanceConfigsResponse.java @@ -1,5 +1,5 @@ /* - * Copyright 2023 Google LLC + * Copyright 2024 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/proto-google-cloud-spanner-admin-instance-v1/src/main/java/com/google/spanner/admin/instance/v1/ListInstanceConfigsResponseOrBuilder.java b/proto-google-cloud-spanner-admin-instance-v1/src/main/java/com/google/spanner/admin/instance/v1/ListInstanceConfigsResponseOrBuilder.java index c2942f5005c..dec55bfe4fc 100644 --- a/proto-google-cloud-spanner-admin-instance-v1/src/main/java/com/google/spanner/admin/instance/v1/ListInstanceConfigsResponseOrBuilder.java +++ b/proto-google-cloud-spanner-admin-instance-v1/src/main/java/com/google/spanner/admin/instance/v1/ListInstanceConfigsResponseOrBuilder.java @@ -1,5 +1,5 @@ /* - * Copyright 2023 Google LLC + * Copyright 2024 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/proto-google-cloud-spanner-admin-instance-v1/src/main/java/com/google/spanner/admin/instance/v1/ListInstancesRequest.java b/proto-google-cloud-spanner-admin-instance-v1/src/main/java/com/google/spanner/admin/instance/v1/ListInstancesRequest.java index dd38de27baf..7597a8863ce 100644 --- a/proto-google-cloud-spanner-admin-instance-v1/src/main/java/com/google/spanner/admin/instance/v1/ListInstancesRequest.java +++ b/proto-google-cloud-spanner-admin-instance-v1/src/main/java/com/google/spanner/admin/instance/v1/ListInstancesRequest.java @@ -1,5 +1,5 @@ /* - * Copyright 2023 Google LLC + * Copyright 2024 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/proto-google-cloud-spanner-admin-instance-v1/src/main/java/com/google/spanner/admin/instance/v1/ListInstancesRequestOrBuilder.java b/proto-google-cloud-spanner-admin-instance-v1/src/main/java/com/google/spanner/admin/instance/v1/ListInstancesRequestOrBuilder.java index 60ec0277046..9ef5fb3958c 100644 --- a/proto-google-cloud-spanner-admin-instance-v1/src/main/java/com/google/spanner/admin/instance/v1/ListInstancesRequestOrBuilder.java +++ b/proto-google-cloud-spanner-admin-instance-v1/src/main/java/com/google/spanner/admin/instance/v1/ListInstancesRequestOrBuilder.java @@ -1,5 +1,5 @@ /* - * Copyright 2023 Google LLC + * Copyright 2024 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/proto-google-cloud-spanner-admin-instance-v1/src/main/java/com/google/spanner/admin/instance/v1/ListInstancesResponse.java b/proto-google-cloud-spanner-admin-instance-v1/src/main/java/com/google/spanner/admin/instance/v1/ListInstancesResponse.java index 70c637a4301..f43b0ea91c2 100644 --- a/proto-google-cloud-spanner-admin-instance-v1/src/main/java/com/google/spanner/admin/instance/v1/ListInstancesResponse.java +++ b/proto-google-cloud-spanner-admin-instance-v1/src/main/java/com/google/spanner/admin/instance/v1/ListInstancesResponse.java @@ -1,5 +1,5 @@ /* - * Copyright 2023 Google LLC + * Copyright 2024 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/proto-google-cloud-spanner-admin-instance-v1/src/main/java/com/google/spanner/admin/instance/v1/ListInstancesResponseOrBuilder.java b/proto-google-cloud-spanner-admin-instance-v1/src/main/java/com/google/spanner/admin/instance/v1/ListInstancesResponseOrBuilder.java index 41ab85f5df8..b0d689128b9 100644 --- a/proto-google-cloud-spanner-admin-instance-v1/src/main/java/com/google/spanner/admin/instance/v1/ListInstancesResponseOrBuilder.java +++ b/proto-google-cloud-spanner-admin-instance-v1/src/main/java/com/google/spanner/admin/instance/v1/ListInstancesResponseOrBuilder.java @@ -1,5 +1,5 @@ /* - * Copyright 2023 Google LLC + * Copyright 2024 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/proto-google-cloud-spanner-admin-instance-v1/src/main/java/com/google/spanner/admin/instance/v1/OperationProgress.java b/proto-google-cloud-spanner-admin-instance-v1/src/main/java/com/google/spanner/admin/instance/v1/OperationProgress.java index 1046948b1fd..5afada05c75 100644 --- a/proto-google-cloud-spanner-admin-instance-v1/src/main/java/com/google/spanner/admin/instance/v1/OperationProgress.java +++ b/proto-google-cloud-spanner-admin-instance-v1/src/main/java/com/google/spanner/admin/instance/v1/OperationProgress.java @@ -1,5 +1,5 @@ /* - * Copyright 2023 Google LLC + * Copyright 2024 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/proto-google-cloud-spanner-admin-instance-v1/src/main/java/com/google/spanner/admin/instance/v1/OperationProgressOrBuilder.java b/proto-google-cloud-spanner-admin-instance-v1/src/main/java/com/google/spanner/admin/instance/v1/OperationProgressOrBuilder.java index 0cd1e8f90fe..9bf5fea69f1 100644 --- a/proto-google-cloud-spanner-admin-instance-v1/src/main/java/com/google/spanner/admin/instance/v1/OperationProgressOrBuilder.java +++ b/proto-google-cloud-spanner-admin-instance-v1/src/main/java/com/google/spanner/admin/instance/v1/OperationProgressOrBuilder.java @@ -1,5 +1,5 @@ /* - * Copyright 2023 Google LLC + * Copyright 2024 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/proto-google-cloud-spanner-admin-instance-v1/src/main/java/com/google/spanner/admin/instance/v1/ReplicaInfo.java b/proto-google-cloud-spanner-admin-instance-v1/src/main/java/com/google/spanner/admin/instance/v1/ReplicaInfo.java index 503d8ca6587..97612776a2f 100644 --- a/proto-google-cloud-spanner-admin-instance-v1/src/main/java/com/google/spanner/admin/instance/v1/ReplicaInfo.java +++ b/proto-google-cloud-spanner-admin-instance-v1/src/main/java/com/google/spanner/admin/instance/v1/ReplicaInfo.java @@ -1,5 +1,5 @@ /* - * Copyright 2023 Google LLC + * Copyright 2024 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/proto-google-cloud-spanner-admin-instance-v1/src/main/java/com/google/spanner/admin/instance/v1/ReplicaInfoOrBuilder.java b/proto-google-cloud-spanner-admin-instance-v1/src/main/java/com/google/spanner/admin/instance/v1/ReplicaInfoOrBuilder.java index e166098b1ac..3abaeac5336 100644 --- a/proto-google-cloud-spanner-admin-instance-v1/src/main/java/com/google/spanner/admin/instance/v1/ReplicaInfoOrBuilder.java +++ b/proto-google-cloud-spanner-admin-instance-v1/src/main/java/com/google/spanner/admin/instance/v1/ReplicaInfoOrBuilder.java @@ -1,5 +1,5 @@ /* - * Copyright 2023 Google LLC + * Copyright 2024 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/proto-google-cloud-spanner-admin-instance-v1/src/main/java/com/google/spanner/admin/instance/v1/SpannerInstanceAdminProto.java b/proto-google-cloud-spanner-admin-instance-v1/src/main/java/com/google/spanner/admin/instance/v1/SpannerInstanceAdminProto.java index a4e360935ef..a7dde50d2e0 100644 --- a/proto-google-cloud-spanner-admin-instance-v1/src/main/java/com/google/spanner/admin/instance/v1/SpannerInstanceAdminProto.java +++ b/proto-google-cloud-spanner-admin-instance-v1/src/main/java/com/google/spanner/admin/instance/v1/SpannerInstanceAdminProto.java @@ -1,5 +1,5 @@ /* - * Copyright 2023 Google LLC + * Copyright 2024 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/proto-google-cloud-spanner-admin-instance-v1/src/main/java/com/google/spanner/admin/instance/v1/UpdateInstanceConfigMetadata.java b/proto-google-cloud-spanner-admin-instance-v1/src/main/java/com/google/spanner/admin/instance/v1/UpdateInstanceConfigMetadata.java index 9a271d701a4..474d58cfc6a 100644 --- a/proto-google-cloud-spanner-admin-instance-v1/src/main/java/com/google/spanner/admin/instance/v1/UpdateInstanceConfigMetadata.java +++ b/proto-google-cloud-spanner-admin-instance-v1/src/main/java/com/google/spanner/admin/instance/v1/UpdateInstanceConfigMetadata.java @@ -1,5 +1,5 @@ /* - * Copyright 2023 Google LLC + * Copyright 2024 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/proto-google-cloud-spanner-admin-instance-v1/src/main/java/com/google/spanner/admin/instance/v1/UpdateInstanceConfigMetadataOrBuilder.java b/proto-google-cloud-spanner-admin-instance-v1/src/main/java/com/google/spanner/admin/instance/v1/UpdateInstanceConfigMetadataOrBuilder.java index 8f52d338583..4d25b350f9d 100644 --- a/proto-google-cloud-spanner-admin-instance-v1/src/main/java/com/google/spanner/admin/instance/v1/UpdateInstanceConfigMetadataOrBuilder.java +++ b/proto-google-cloud-spanner-admin-instance-v1/src/main/java/com/google/spanner/admin/instance/v1/UpdateInstanceConfigMetadataOrBuilder.java @@ -1,5 +1,5 @@ /* - * Copyright 2023 Google LLC + * Copyright 2024 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/proto-google-cloud-spanner-admin-instance-v1/src/main/java/com/google/spanner/admin/instance/v1/UpdateInstanceConfigRequest.java b/proto-google-cloud-spanner-admin-instance-v1/src/main/java/com/google/spanner/admin/instance/v1/UpdateInstanceConfigRequest.java index ab6d545bf53..90bc2be6dbb 100644 --- a/proto-google-cloud-spanner-admin-instance-v1/src/main/java/com/google/spanner/admin/instance/v1/UpdateInstanceConfigRequest.java +++ b/proto-google-cloud-spanner-admin-instance-v1/src/main/java/com/google/spanner/admin/instance/v1/UpdateInstanceConfigRequest.java @@ -1,5 +1,5 @@ /* - * Copyright 2023 Google LLC + * Copyright 2024 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/proto-google-cloud-spanner-admin-instance-v1/src/main/java/com/google/spanner/admin/instance/v1/UpdateInstanceConfigRequestOrBuilder.java b/proto-google-cloud-spanner-admin-instance-v1/src/main/java/com/google/spanner/admin/instance/v1/UpdateInstanceConfigRequestOrBuilder.java index 18c8ce272a8..42fe6edb719 100644 --- a/proto-google-cloud-spanner-admin-instance-v1/src/main/java/com/google/spanner/admin/instance/v1/UpdateInstanceConfigRequestOrBuilder.java +++ b/proto-google-cloud-spanner-admin-instance-v1/src/main/java/com/google/spanner/admin/instance/v1/UpdateInstanceConfigRequestOrBuilder.java @@ -1,5 +1,5 @@ /* - * Copyright 2023 Google LLC + * Copyright 2024 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/proto-google-cloud-spanner-admin-instance-v1/src/main/java/com/google/spanner/admin/instance/v1/UpdateInstanceMetadata.java b/proto-google-cloud-spanner-admin-instance-v1/src/main/java/com/google/spanner/admin/instance/v1/UpdateInstanceMetadata.java index 9b4e9855386..96de4f4b9d7 100644 --- a/proto-google-cloud-spanner-admin-instance-v1/src/main/java/com/google/spanner/admin/instance/v1/UpdateInstanceMetadata.java +++ b/proto-google-cloud-spanner-admin-instance-v1/src/main/java/com/google/spanner/admin/instance/v1/UpdateInstanceMetadata.java @@ -1,5 +1,5 @@ /* - * Copyright 2023 Google LLC + * Copyright 2024 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/proto-google-cloud-spanner-admin-instance-v1/src/main/java/com/google/spanner/admin/instance/v1/UpdateInstanceMetadataOrBuilder.java b/proto-google-cloud-spanner-admin-instance-v1/src/main/java/com/google/spanner/admin/instance/v1/UpdateInstanceMetadataOrBuilder.java index e520e83b19f..403a22419c7 100644 --- a/proto-google-cloud-spanner-admin-instance-v1/src/main/java/com/google/spanner/admin/instance/v1/UpdateInstanceMetadataOrBuilder.java +++ b/proto-google-cloud-spanner-admin-instance-v1/src/main/java/com/google/spanner/admin/instance/v1/UpdateInstanceMetadataOrBuilder.java @@ -1,5 +1,5 @@ /* - * Copyright 2023 Google LLC + * Copyright 2024 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/proto-google-cloud-spanner-admin-instance-v1/src/main/java/com/google/spanner/admin/instance/v1/UpdateInstanceRequest.java b/proto-google-cloud-spanner-admin-instance-v1/src/main/java/com/google/spanner/admin/instance/v1/UpdateInstanceRequest.java index a0b42cf11d5..071251a3442 100644 --- a/proto-google-cloud-spanner-admin-instance-v1/src/main/java/com/google/spanner/admin/instance/v1/UpdateInstanceRequest.java +++ b/proto-google-cloud-spanner-admin-instance-v1/src/main/java/com/google/spanner/admin/instance/v1/UpdateInstanceRequest.java @@ -1,5 +1,5 @@ /* - * Copyright 2023 Google LLC + * Copyright 2024 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/proto-google-cloud-spanner-admin-instance-v1/src/main/java/com/google/spanner/admin/instance/v1/UpdateInstanceRequestOrBuilder.java b/proto-google-cloud-spanner-admin-instance-v1/src/main/java/com/google/spanner/admin/instance/v1/UpdateInstanceRequestOrBuilder.java index 1733dec0e18..eac3c8584a6 100644 --- a/proto-google-cloud-spanner-admin-instance-v1/src/main/java/com/google/spanner/admin/instance/v1/UpdateInstanceRequestOrBuilder.java +++ b/proto-google-cloud-spanner-admin-instance-v1/src/main/java/com/google/spanner/admin/instance/v1/UpdateInstanceRequestOrBuilder.java @@ -1,5 +1,5 @@ /* - * Copyright 2023 Google LLC + * Copyright 2024 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/AdminAction.java b/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/AdminAction.java index 0477201f7a6..d5aef54c8b9 100644 --- a/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/AdminAction.java +++ b/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/AdminAction.java @@ -1,5 +1,5 @@ /* - * Copyright 2023 Google LLC + * Copyright 2024 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/AdminActionOrBuilder.java b/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/AdminActionOrBuilder.java index c8684d19270..df2560195c5 100644 --- a/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/AdminActionOrBuilder.java +++ b/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/AdminActionOrBuilder.java @@ -1,5 +1,5 @@ /* - * Copyright 2023 Google LLC + * Copyright 2024 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/AdminResult.java b/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/AdminResult.java index d88a95bf2ea..f6872a1144f 100644 --- a/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/AdminResult.java +++ b/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/AdminResult.java @@ -1,5 +1,5 @@ /* - * Copyright 2023 Google LLC + * Copyright 2024 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/AdminResultOrBuilder.java b/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/AdminResultOrBuilder.java index 371d0bcc7b6..bcc51df88d2 100644 --- a/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/AdminResultOrBuilder.java +++ b/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/AdminResultOrBuilder.java @@ -1,5 +1,5 @@ /* - * Copyright 2023 Google LLC + * Copyright 2024 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/BatchDmlAction.java b/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/BatchDmlAction.java index e437cfe7700..2b6c605cd4e 100644 --- a/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/BatchDmlAction.java +++ b/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/BatchDmlAction.java @@ -1,5 +1,5 @@ /* - * Copyright 2023 Google LLC + * Copyright 2024 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/BatchDmlActionOrBuilder.java b/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/BatchDmlActionOrBuilder.java index 498f7f0098d..a6fe62f7c62 100644 --- a/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/BatchDmlActionOrBuilder.java +++ b/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/BatchDmlActionOrBuilder.java @@ -1,5 +1,5 @@ /* - * Copyright 2023 Google LLC + * Copyright 2024 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/BatchPartition.java b/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/BatchPartition.java index ea5c14f7415..f1db4c3a632 100644 --- a/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/BatchPartition.java +++ b/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/BatchPartition.java @@ -1,5 +1,5 @@ /* - * Copyright 2023 Google LLC + * Copyright 2024 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/BatchPartitionOrBuilder.java b/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/BatchPartitionOrBuilder.java index 73ebc822f2e..685b11e8bff 100644 --- a/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/BatchPartitionOrBuilder.java +++ b/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/BatchPartitionOrBuilder.java @@ -1,5 +1,5 @@ /* - * Copyright 2023 Google LLC + * Copyright 2024 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/CancelOperationAction.java b/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/CancelOperationAction.java index 1338d97cb87..6990c640710 100644 --- a/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/CancelOperationAction.java +++ b/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/CancelOperationAction.java @@ -1,5 +1,5 @@ /* - * Copyright 2023 Google LLC + * Copyright 2024 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/CancelOperationActionOrBuilder.java b/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/CancelOperationActionOrBuilder.java index 37ca9213375..c54975f6947 100644 --- a/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/CancelOperationActionOrBuilder.java +++ b/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/CancelOperationActionOrBuilder.java @@ -1,5 +1,5 @@ /* - * Copyright 2023 Google LLC + * Copyright 2024 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/ChangeStreamRecord.java b/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/ChangeStreamRecord.java index 4dc95858445..3e200a82272 100644 --- a/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/ChangeStreamRecord.java +++ b/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/ChangeStreamRecord.java @@ -1,5 +1,5 @@ /* - * Copyright 2023 Google LLC + * Copyright 2024 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/ChangeStreamRecordOrBuilder.java b/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/ChangeStreamRecordOrBuilder.java index 2ad85229b56..97e7ce956be 100644 --- a/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/ChangeStreamRecordOrBuilder.java +++ b/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/ChangeStreamRecordOrBuilder.java @@ -1,5 +1,5 @@ /* - * Copyright 2023 Google LLC + * Copyright 2024 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/ChildPartitionsRecord.java b/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/ChildPartitionsRecord.java index a4197d3585b..617c3682527 100644 --- a/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/ChildPartitionsRecord.java +++ b/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/ChildPartitionsRecord.java @@ -1,5 +1,5 @@ /* - * Copyright 2023 Google LLC + * Copyright 2024 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/ChildPartitionsRecordOrBuilder.java b/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/ChildPartitionsRecordOrBuilder.java index 14f6b486013..223d78b1783 100644 --- a/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/ChildPartitionsRecordOrBuilder.java +++ b/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/ChildPartitionsRecordOrBuilder.java @@ -1,5 +1,5 @@ /* - * Copyright 2023 Google LLC + * Copyright 2024 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/CloseBatchTransactionAction.java b/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/CloseBatchTransactionAction.java index 3620bf80b9c..55cfd04958e 100644 --- a/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/CloseBatchTransactionAction.java +++ b/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/CloseBatchTransactionAction.java @@ -1,5 +1,5 @@ /* - * Copyright 2023 Google LLC + * Copyright 2024 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/CloseBatchTransactionActionOrBuilder.java b/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/CloseBatchTransactionActionOrBuilder.java index e03dd6b1d39..bd0d25a644c 100644 --- a/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/CloseBatchTransactionActionOrBuilder.java +++ b/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/CloseBatchTransactionActionOrBuilder.java @@ -1,5 +1,5 @@ /* - * Copyright 2023 Google LLC + * Copyright 2024 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/CloudBackupResponse.java b/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/CloudBackupResponse.java index c07e07e8ada..d0a00188131 100644 --- a/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/CloudBackupResponse.java +++ b/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/CloudBackupResponse.java @@ -1,5 +1,5 @@ /* - * Copyright 2023 Google LLC + * Copyright 2024 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/CloudBackupResponseOrBuilder.java b/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/CloudBackupResponseOrBuilder.java index c311139f028..c8036dbf040 100644 --- a/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/CloudBackupResponseOrBuilder.java +++ b/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/CloudBackupResponseOrBuilder.java @@ -1,5 +1,5 @@ /* - * Copyright 2023 Google LLC + * Copyright 2024 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/CloudDatabaseResponse.java b/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/CloudDatabaseResponse.java index c3032219788..0484d3adaf7 100644 --- a/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/CloudDatabaseResponse.java +++ b/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/CloudDatabaseResponse.java @@ -1,5 +1,5 @@ /* - * Copyright 2023 Google LLC + * Copyright 2024 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/CloudDatabaseResponseOrBuilder.java b/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/CloudDatabaseResponseOrBuilder.java index bca2dfd5276..bbf9c84acaa 100644 --- a/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/CloudDatabaseResponseOrBuilder.java +++ b/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/CloudDatabaseResponseOrBuilder.java @@ -1,5 +1,5 @@ /* - * Copyright 2023 Google LLC + * Copyright 2024 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/CloudExecutorProto.java b/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/CloudExecutorProto.java index b7d00e38d0f..e58ca5e2747 100644 --- a/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/CloudExecutorProto.java +++ b/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/CloudExecutorProto.java @@ -1,5 +1,5 @@ /* - * Copyright 2023 Google LLC + * Copyright 2024 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/CloudInstanceConfigResponse.java b/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/CloudInstanceConfigResponse.java index 21bb70d4246..911b2dc28c5 100644 --- a/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/CloudInstanceConfigResponse.java +++ b/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/CloudInstanceConfigResponse.java @@ -1,5 +1,5 @@ /* - * Copyright 2023 Google LLC + * Copyright 2024 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/CloudInstanceConfigResponseOrBuilder.java b/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/CloudInstanceConfigResponseOrBuilder.java index a7fd4d019b1..137e83c2f8f 100644 --- a/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/CloudInstanceConfigResponseOrBuilder.java +++ b/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/CloudInstanceConfigResponseOrBuilder.java @@ -1,5 +1,5 @@ /* - * Copyright 2023 Google LLC + * Copyright 2024 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/CloudInstanceResponse.java b/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/CloudInstanceResponse.java index 20e31f94b9f..c2f3e8e73ac 100644 --- a/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/CloudInstanceResponse.java +++ b/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/CloudInstanceResponse.java @@ -1,5 +1,5 @@ /* - * Copyright 2023 Google LLC + * Copyright 2024 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/CloudInstanceResponseOrBuilder.java b/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/CloudInstanceResponseOrBuilder.java index 64811c8b29a..bd771f2d74b 100644 --- a/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/CloudInstanceResponseOrBuilder.java +++ b/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/CloudInstanceResponseOrBuilder.java @@ -1,5 +1,5 @@ /* - * Copyright 2023 Google LLC + * Copyright 2024 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/ColumnMetadata.java b/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/ColumnMetadata.java index da69ce0dd65..5d51e2c7180 100644 --- a/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/ColumnMetadata.java +++ b/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/ColumnMetadata.java @@ -1,5 +1,5 @@ /* - * Copyright 2023 Google LLC + * Copyright 2024 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/ColumnMetadataOrBuilder.java b/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/ColumnMetadataOrBuilder.java index 43a8ddc31fb..53d4dbdfd82 100644 --- a/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/ColumnMetadataOrBuilder.java +++ b/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/ColumnMetadataOrBuilder.java @@ -1,5 +1,5 @@ /* - * Copyright 2023 Google LLC + * Copyright 2024 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/Concurrency.java b/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/Concurrency.java index 8660df865c9..b078fdc4b8d 100644 --- a/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/Concurrency.java +++ b/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/Concurrency.java @@ -1,5 +1,5 @@ /* - * Copyright 2023 Google LLC + * Copyright 2024 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/ConcurrencyOrBuilder.java b/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/ConcurrencyOrBuilder.java index fbed2003495..0c84680cec9 100644 --- a/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/ConcurrencyOrBuilder.java +++ b/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/ConcurrencyOrBuilder.java @@ -1,5 +1,5 @@ /* - * Copyright 2023 Google LLC + * Copyright 2024 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/CopyCloudBackupAction.java b/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/CopyCloudBackupAction.java index 2a9a2c39648..7e90da4a653 100644 --- a/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/CopyCloudBackupAction.java +++ b/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/CopyCloudBackupAction.java @@ -1,5 +1,5 @@ /* - * Copyright 2023 Google LLC + * Copyright 2024 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/CopyCloudBackupActionOrBuilder.java b/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/CopyCloudBackupActionOrBuilder.java index 3711ba08389..1a45aa91bfb 100644 --- a/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/CopyCloudBackupActionOrBuilder.java +++ b/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/CopyCloudBackupActionOrBuilder.java @@ -1,5 +1,5 @@ /* - * Copyright 2023 Google LLC + * Copyright 2024 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/CreateCloudBackupAction.java b/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/CreateCloudBackupAction.java index 58c05a75645..c789c6f0b32 100644 --- a/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/CreateCloudBackupAction.java +++ b/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/CreateCloudBackupAction.java @@ -1,5 +1,5 @@ /* - * Copyright 2023 Google LLC + * Copyright 2024 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/CreateCloudBackupActionOrBuilder.java b/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/CreateCloudBackupActionOrBuilder.java index bec47bf3112..c91cd5a410e 100644 --- a/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/CreateCloudBackupActionOrBuilder.java +++ b/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/CreateCloudBackupActionOrBuilder.java @@ -1,5 +1,5 @@ /* - * Copyright 2023 Google LLC + * Copyright 2024 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/CreateCloudDatabaseAction.java b/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/CreateCloudDatabaseAction.java index fcf13229671..d8aab2498e6 100644 --- a/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/CreateCloudDatabaseAction.java +++ b/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/CreateCloudDatabaseAction.java @@ -1,5 +1,5 @@ /* - * Copyright 2023 Google LLC + * Copyright 2024 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/CreateCloudDatabaseActionOrBuilder.java b/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/CreateCloudDatabaseActionOrBuilder.java index 82f57ec3511..fa2d08522e2 100644 --- a/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/CreateCloudDatabaseActionOrBuilder.java +++ b/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/CreateCloudDatabaseActionOrBuilder.java @@ -1,5 +1,5 @@ /* - * Copyright 2023 Google LLC + * Copyright 2024 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/CreateCloudInstanceAction.java b/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/CreateCloudInstanceAction.java index 612ae8e2bb1..116adf58145 100644 --- a/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/CreateCloudInstanceAction.java +++ b/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/CreateCloudInstanceAction.java @@ -1,5 +1,5 @@ /* - * Copyright 2023 Google LLC + * Copyright 2024 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/CreateCloudInstanceActionOrBuilder.java b/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/CreateCloudInstanceActionOrBuilder.java index ea178d0fc75..02b8849911c 100644 --- a/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/CreateCloudInstanceActionOrBuilder.java +++ b/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/CreateCloudInstanceActionOrBuilder.java @@ -1,5 +1,5 @@ /* - * Copyright 2023 Google LLC + * Copyright 2024 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/CreateUserInstanceConfigAction.java b/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/CreateUserInstanceConfigAction.java index 2c38021fcd4..6bd929cbae2 100644 --- a/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/CreateUserInstanceConfigAction.java +++ b/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/CreateUserInstanceConfigAction.java @@ -1,5 +1,5 @@ /* - * Copyright 2023 Google LLC + * Copyright 2024 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/CreateUserInstanceConfigActionOrBuilder.java b/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/CreateUserInstanceConfigActionOrBuilder.java index c439a37c934..aa468a1ff3d 100644 --- a/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/CreateUserInstanceConfigActionOrBuilder.java +++ b/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/CreateUserInstanceConfigActionOrBuilder.java @@ -1,5 +1,5 @@ /* - * Copyright 2023 Google LLC + * Copyright 2024 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/DataChangeRecord.java b/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/DataChangeRecord.java index dee22a9a6ad..a95d4b3cd02 100644 --- a/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/DataChangeRecord.java +++ b/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/DataChangeRecord.java @@ -1,5 +1,5 @@ /* - * Copyright 2023 Google LLC + * Copyright 2024 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/DataChangeRecordOrBuilder.java b/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/DataChangeRecordOrBuilder.java index a90dcd59314..57fc31058b5 100644 --- a/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/DataChangeRecordOrBuilder.java +++ b/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/DataChangeRecordOrBuilder.java @@ -1,5 +1,5 @@ /* - * Copyright 2023 Google LLC + * Copyright 2024 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/DeleteCloudBackupAction.java b/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/DeleteCloudBackupAction.java index 35017e99411..a8a4e8e2cca 100644 --- a/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/DeleteCloudBackupAction.java +++ b/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/DeleteCloudBackupAction.java @@ -1,5 +1,5 @@ /* - * Copyright 2023 Google LLC + * Copyright 2024 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/DeleteCloudBackupActionOrBuilder.java b/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/DeleteCloudBackupActionOrBuilder.java index 425f0ca134a..deef4f5268a 100644 --- a/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/DeleteCloudBackupActionOrBuilder.java +++ b/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/DeleteCloudBackupActionOrBuilder.java @@ -1,5 +1,5 @@ /* - * Copyright 2023 Google LLC + * Copyright 2024 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/DeleteCloudInstanceAction.java b/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/DeleteCloudInstanceAction.java index dd686b8f6a3..36d0c421a3b 100644 --- a/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/DeleteCloudInstanceAction.java +++ b/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/DeleteCloudInstanceAction.java @@ -1,5 +1,5 @@ /* - * Copyright 2023 Google LLC + * Copyright 2024 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/DeleteCloudInstanceActionOrBuilder.java b/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/DeleteCloudInstanceActionOrBuilder.java index 47efef6e091..0fd46ae70cf 100644 --- a/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/DeleteCloudInstanceActionOrBuilder.java +++ b/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/DeleteCloudInstanceActionOrBuilder.java @@ -1,5 +1,5 @@ /* - * Copyright 2023 Google LLC + * Copyright 2024 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/DeleteUserInstanceConfigAction.java b/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/DeleteUserInstanceConfigAction.java index 4797f360e46..e9450e53a10 100644 --- a/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/DeleteUserInstanceConfigAction.java +++ b/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/DeleteUserInstanceConfigAction.java @@ -1,5 +1,5 @@ /* - * Copyright 2023 Google LLC + * Copyright 2024 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/DeleteUserInstanceConfigActionOrBuilder.java b/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/DeleteUserInstanceConfigActionOrBuilder.java index 05af4717e2a..04f36caf837 100644 --- a/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/DeleteUserInstanceConfigActionOrBuilder.java +++ b/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/DeleteUserInstanceConfigActionOrBuilder.java @@ -1,5 +1,5 @@ /* - * Copyright 2023 Google LLC + * Copyright 2024 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/DmlAction.java b/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/DmlAction.java index 0da95103de4..4ae847ee6bc 100644 --- a/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/DmlAction.java +++ b/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/DmlAction.java @@ -1,5 +1,5 @@ /* - * Copyright 2023 Google LLC + * Copyright 2024 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/DmlActionOrBuilder.java b/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/DmlActionOrBuilder.java index 150769c53b4..5e75d04028b 100644 --- a/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/DmlActionOrBuilder.java +++ b/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/DmlActionOrBuilder.java @@ -1,5 +1,5 @@ /* - * Copyright 2023 Google LLC + * Copyright 2024 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/DropCloudDatabaseAction.java b/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/DropCloudDatabaseAction.java index c584cae1fdb..c97f898f66a 100644 --- a/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/DropCloudDatabaseAction.java +++ b/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/DropCloudDatabaseAction.java @@ -1,5 +1,5 @@ /* - * Copyright 2023 Google LLC + * Copyright 2024 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/DropCloudDatabaseActionOrBuilder.java b/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/DropCloudDatabaseActionOrBuilder.java index 76870d4764f..5132a22c0f7 100644 --- a/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/DropCloudDatabaseActionOrBuilder.java +++ b/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/DropCloudDatabaseActionOrBuilder.java @@ -1,5 +1,5 @@ /* - * Copyright 2023 Google LLC + * Copyright 2024 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/ExecuteChangeStreamQuery.java b/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/ExecuteChangeStreamQuery.java index c54424ced16..29abc5b64d3 100644 --- a/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/ExecuteChangeStreamQuery.java +++ b/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/ExecuteChangeStreamQuery.java @@ -1,5 +1,5 @@ /* - * Copyright 2023 Google LLC + * Copyright 2024 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/ExecuteChangeStreamQueryOrBuilder.java b/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/ExecuteChangeStreamQueryOrBuilder.java index 6c56630f2d3..44a50603237 100644 --- a/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/ExecuteChangeStreamQueryOrBuilder.java +++ b/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/ExecuteChangeStreamQueryOrBuilder.java @@ -1,5 +1,5 @@ /* - * Copyright 2023 Google LLC + * Copyright 2024 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/ExecutePartitionAction.java b/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/ExecutePartitionAction.java index 0a809a3f468..ebb8c78c1da 100644 --- a/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/ExecutePartitionAction.java +++ b/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/ExecutePartitionAction.java @@ -1,5 +1,5 @@ /* - * Copyright 2023 Google LLC + * Copyright 2024 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/ExecutePartitionActionOrBuilder.java b/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/ExecutePartitionActionOrBuilder.java index a6b6713a9ed..d10640206d1 100644 --- a/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/ExecutePartitionActionOrBuilder.java +++ b/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/ExecutePartitionActionOrBuilder.java @@ -1,5 +1,5 @@ /* - * Copyright 2023 Google LLC + * Copyright 2024 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/FinishTransactionAction.java b/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/FinishTransactionAction.java index 7648770a9a4..e9842ecdef9 100644 --- a/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/FinishTransactionAction.java +++ b/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/FinishTransactionAction.java @@ -1,5 +1,5 @@ /* - * Copyright 2023 Google LLC + * Copyright 2024 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/FinishTransactionActionOrBuilder.java b/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/FinishTransactionActionOrBuilder.java index 9b8b1833b5f..fe1b168f73b 100644 --- a/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/FinishTransactionActionOrBuilder.java +++ b/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/FinishTransactionActionOrBuilder.java @@ -1,5 +1,5 @@ /* - * Copyright 2023 Google LLC + * Copyright 2024 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/GenerateDbPartitionsForQueryAction.java b/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/GenerateDbPartitionsForQueryAction.java index 82558241ea1..1b902bcbb8e 100644 --- a/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/GenerateDbPartitionsForQueryAction.java +++ b/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/GenerateDbPartitionsForQueryAction.java @@ -1,5 +1,5 @@ /* - * Copyright 2023 Google LLC + * Copyright 2024 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/GenerateDbPartitionsForQueryActionOrBuilder.java b/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/GenerateDbPartitionsForQueryActionOrBuilder.java index 5fc93a7d88c..aec1a29344d 100644 --- a/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/GenerateDbPartitionsForQueryActionOrBuilder.java +++ b/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/GenerateDbPartitionsForQueryActionOrBuilder.java @@ -1,5 +1,5 @@ /* - * Copyright 2023 Google LLC + * Copyright 2024 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/GenerateDbPartitionsForReadAction.java b/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/GenerateDbPartitionsForReadAction.java index 4650176ef55..869ae0eb1cb 100644 --- a/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/GenerateDbPartitionsForReadAction.java +++ b/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/GenerateDbPartitionsForReadAction.java @@ -1,5 +1,5 @@ /* - * Copyright 2023 Google LLC + * Copyright 2024 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/GenerateDbPartitionsForReadActionOrBuilder.java b/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/GenerateDbPartitionsForReadActionOrBuilder.java index 894e57aeaa0..3905e44fb73 100644 --- a/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/GenerateDbPartitionsForReadActionOrBuilder.java +++ b/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/GenerateDbPartitionsForReadActionOrBuilder.java @@ -1,5 +1,5 @@ /* - * Copyright 2023 Google LLC + * Copyright 2024 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/GetCloudBackupAction.java b/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/GetCloudBackupAction.java index d3f8cbc5e68..2cdb1e3b641 100644 --- a/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/GetCloudBackupAction.java +++ b/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/GetCloudBackupAction.java @@ -1,5 +1,5 @@ /* - * Copyright 2023 Google LLC + * Copyright 2024 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/GetCloudBackupActionOrBuilder.java b/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/GetCloudBackupActionOrBuilder.java index 993df879633..ff3b57d82cd 100644 --- a/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/GetCloudBackupActionOrBuilder.java +++ b/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/GetCloudBackupActionOrBuilder.java @@ -1,5 +1,5 @@ /* - * Copyright 2023 Google LLC + * Copyright 2024 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/GetCloudDatabaseAction.java b/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/GetCloudDatabaseAction.java index bda9567e815..544f7e751f8 100644 --- a/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/GetCloudDatabaseAction.java +++ b/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/GetCloudDatabaseAction.java @@ -1,5 +1,5 @@ /* - * Copyright 2023 Google LLC + * Copyright 2024 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/GetCloudDatabaseActionOrBuilder.java b/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/GetCloudDatabaseActionOrBuilder.java index 39196819f75..0ca91c26175 100644 --- a/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/GetCloudDatabaseActionOrBuilder.java +++ b/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/GetCloudDatabaseActionOrBuilder.java @@ -1,5 +1,5 @@ /* - * Copyright 2023 Google LLC + * Copyright 2024 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/GetCloudInstanceAction.java b/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/GetCloudInstanceAction.java index 5e0a0e201df..aee8372c9ea 100644 --- a/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/GetCloudInstanceAction.java +++ b/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/GetCloudInstanceAction.java @@ -1,5 +1,5 @@ /* - * Copyright 2023 Google LLC + * Copyright 2024 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/GetCloudInstanceActionOrBuilder.java b/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/GetCloudInstanceActionOrBuilder.java index 95714251e02..41ea5db664b 100644 --- a/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/GetCloudInstanceActionOrBuilder.java +++ b/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/GetCloudInstanceActionOrBuilder.java @@ -1,5 +1,5 @@ /* - * Copyright 2023 Google LLC + * Copyright 2024 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/GetCloudInstanceConfigAction.java b/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/GetCloudInstanceConfigAction.java index 1be88c14e67..1cb45e0ba90 100644 --- a/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/GetCloudInstanceConfigAction.java +++ b/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/GetCloudInstanceConfigAction.java @@ -1,5 +1,5 @@ /* - * Copyright 2023 Google LLC + * Copyright 2024 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/GetCloudInstanceConfigActionOrBuilder.java b/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/GetCloudInstanceConfigActionOrBuilder.java index a15a7820bb6..1886d88e9d9 100644 --- a/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/GetCloudInstanceConfigActionOrBuilder.java +++ b/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/GetCloudInstanceConfigActionOrBuilder.java @@ -1,5 +1,5 @@ /* - * Copyright 2023 Google LLC + * Copyright 2024 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/GetOperationAction.java b/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/GetOperationAction.java index e5dfcecd53d..7ff9277e82a 100644 --- a/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/GetOperationAction.java +++ b/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/GetOperationAction.java @@ -1,5 +1,5 @@ /* - * Copyright 2023 Google LLC + * Copyright 2024 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/GetOperationActionOrBuilder.java b/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/GetOperationActionOrBuilder.java index 6148a800015..a8fd39772e5 100644 --- a/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/GetOperationActionOrBuilder.java +++ b/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/GetOperationActionOrBuilder.java @@ -1,5 +1,5 @@ /* - * Copyright 2023 Google LLC + * Copyright 2024 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/HeartbeatRecord.java b/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/HeartbeatRecord.java index 6ca0298ebb8..41240ae5b57 100644 --- a/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/HeartbeatRecord.java +++ b/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/HeartbeatRecord.java @@ -1,5 +1,5 @@ /* - * Copyright 2023 Google LLC + * Copyright 2024 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/HeartbeatRecordOrBuilder.java b/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/HeartbeatRecordOrBuilder.java index 74d3fe25420..92334fe3ae2 100644 --- a/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/HeartbeatRecordOrBuilder.java +++ b/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/HeartbeatRecordOrBuilder.java @@ -1,5 +1,5 @@ /* - * Copyright 2023 Google LLC + * Copyright 2024 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/KeyRange.java b/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/KeyRange.java index fd29416a5d7..71eb93a201f 100644 --- a/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/KeyRange.java +++ b/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/KeyRange.java @@ -1,5 +1,5 @@ /* - * Copyright 2023 Google LLC + * Copyright 2024 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/KeyRangeOrBuilder.java b/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/KeyRangeOrBuilder.java index 7b06df2b79b..6b8cd6c47cb 100644 --- a/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/KeyRangeOrBuilder.java +++ b/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/KeyRangeOrBuilder.java @@ -1,5 +1,5 @@ /* - * Copyright 2023 Google LLC + * Copyright 2024 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/KeySet.java b/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/KeySet.java index 42e3abdea5c..edd508c9b7a 100644 --- a/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/KeySet.java +++ b/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/KeySet.java @@ -1,5 +1,5 @@ /* - * Copyright 2023 Google LLC + * Copyright 2024 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/KeySetOrBuilder.java b/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/KeySetOrBuilder.java index 6e8533c5469..88fae3d5494 100644 --- a/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/KeySetOrBuilder.java +++ b/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/KeySetOrBuilder.java @@ -1,5 +1,5 @@ /* - * Copyright 2023 Google LLC + * Copyright 2024 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/ListCloudBackupOperationsAction.java b/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/ListCloudBackupOperationsAction.java index ab8e30e959a..a7cf3236781 100644 --- a/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/ListCloudBackupOperationsAction.java +++ b/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/ListCloudBackupOperationsAction.java @@ -1,5 +1,5 @@ /* - * Copyright 2023 Google LLC + * Copyright 2024 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/ListCloudBackupOperationsActionOrBuilder.java b/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/ListCloudBackupOperationsActionOrBuilder.java index 13716f3b9d3..a2318445b5f 100644 --- a/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/ListCloudBackupOperationsActionOrBuilder.java +++ b/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/ListCloudBackupOperationsActionOrBuilder.java @@ -1,5 +1,5 @@ /* - * Copyright 2023 Google LLC + * Copyright 2024 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/ListCloudBackupsAction.java b/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/ListCloudBackupsAction.java index 48a3c038bde..b9d1ff3079a 100644 --- a/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/ListCloudBackupsAction.java +++ b/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/ListCloudBackupsAction.java @@ -1,5 +1,5 @@ /* - * Copyright 2023 Google LLC + * Copyright 2024 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/ListCloudBackupsActionOrBuilder.java b/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/ListCloudBackupsActionOrBuilder.java index ebdff68355e..10cfff838fa 100644 --- a/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/ListCloudBackupsActionOrBuilder.java +++ b/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/ListCloudBackupsActionOrBuilder.java @@ -1,5 +1,5 @@ /* - * Copyright 2023 Google LLC + * Copyright 2024 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/ListCloudDatabaseOperationsAction.java b/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/ListCloudDatabaseOperationsAction.java index bd8e1a4a53e..0673ac50085 100644 --- a/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/ListCloudDatabaseOperationsAction.java +++ b/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/ListCloudDatabaseOperationsAction.java @@ -1,5 +1,5 @@ /* - * Copyright 2023 Google LLC + * Copyright 2024 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/ListCloudDatabaseOperationsActionOrBuilder.java b/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/ListCloudDatabaseOperationsActionOrBuilder.java index fc74a4fb86a..8ef1b0c7c6f 100644 --- a/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/ListCloudDatabaseOperationsActionOrBuilder.java +++ b/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/ListCloudDatabaseOperationsActionOrBuilder.java @@ -1,5 +1,5 @@ /* - * Copyright 2023 Google LLC + * Copyright 2024 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/ListCloudDatabasesAction.java b/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/ListCloudDatabasesAction.java index 73f4de7ed68..b268cc6dda9 100644 --- a/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/ListCloudDatabasesAction.java +++ b/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/ListCloudDatabasesAction.java @@ -1,5 +1,5 @@ /* - * Copyright 2023 Google LLC + * Copyright 2024 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/ListCloudDatabasesActionOrBuilder.java b/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/ListCloudDatabasesActionOrBuilder.java index 95e13ccb1c3..9a2844e7586 100644 --- a/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/ListCloudDatabasesActionOrBuilder.java +++ b/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/ListCloudDatabasesActionOrBuilder.java @@ -1,5 +1,5 @@ /* - * Copyright 2023 Google LLC + * Copyright 2024 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/ListCloudInstanceConfigsAction.java b/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/ListCloudInstanceConfigsAction.java index 980fbf4beaf..650bf1cdba0 100644 --- a/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/ListCloudInstanceConfigsAction.java +++ b/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/ListCloudInstanceConfigsAction.java @@ -1,5 +1,5 @@ /* - * Copyright 2023 Google LLC + * Copyright 2024 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/ListCloudInstanceConfigsActionOrBuilder.java b/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/ListCloudInstanceConfigsActionOrBuilder.java index 410273d191a..c2f1420bff2 100644 --- a/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/ListCloudInstanceConfigsActionOrBuilder.java +++ b/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/ListCloudInstanceConfigsActionOrBuilder.java @@ -1,5 +1,5 @@ /* - * Copyright 2023 Google LLC + * Copyright 2024 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/ListCloudInstancesAction.java b/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/ListCloudInstancesAction.java index 0915a22818f..d1795e5deed 100644 --- a/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/ListCloudInstancesAction.java +++ b/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/ListCloudInstancesAction.java @@ -1,5 +1,5 @@ /* - * Copyright 2023 Google LLC + * Copyright 2024 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/ListCloudInstancesActionOrBuilder.java b/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/ListCloudInstancesActionOrBuilder.java index b6a066d1390..9c342a78160 100644 --- a/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/ListCloudInstancesActionOrBuilder.java +++ b/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/ListCloudInstancesActionOrBuilder.java @@ -1,5 +1,5 @@ /* - * Copyright 2023 Google LLC + * Copyright 2024 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/MutationAction.java b/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/MutationAction.java index aa426efc254..7b138f35ac8 100644 --- a/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/MutationAction.java +++ b/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/MutationAction.java @@ -1,5 +1,5 @@ /* - * Copyright 2023 Google LLC + * Copyright 2024 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/MutationActionOrBuilder.java b/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/MutationActionOrBuilder.java index b0ccf3f80f5..f5771e4851d 100644 --- a/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/MutationActionOrBuilder.java +++ b/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/MutationActionOrBuilder.java @@ -1,5 +1,5 @@ /* - * Copyright 2023 Google LLC + * Copyright 2024 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/OperationResponse.java b/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/OperationResponse.java index e427e7bf92d..da4cfa9d6b7 100644 --- a/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/OperationResponse.java +++ b/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/OperationResponse.java @@ -1,5 +1,5 @@ /* - * Copyright 2023 Google LLC + * Copyright 2024 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/OperationResponseOrBuilder.java b/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/OperationResponseOrBuilder.java index 2b36023bf5f..53bbd4466af 100644 --- a/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/OperationResponseOrBuilder.java +++ b/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/OperationResponseOrBuilder.java @@ -1,5 +1,5 @@ /* - * Copyright 2023 Google LLC + * Copyright 2024 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/PartitionedUpdateAction.java b/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/PartitionedUpdateAction.java index ee24bb9a499..fa716c7a0bb 100644 --- a/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/PartitionedUpdateAction.java +++ b/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/PartitionedUpdateAction.java @@ -1,5 +1,5 @@ /* - * Copyright 2023 Google LLC + * Copyright 2024 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/PartitionedUpdateActionOrBuilder.java b/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/PartitionedUpdateActionOrBuilder.java index c0cad580e62..9386bedfb0a 100644 --- a/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/PartitionedUpdateActionOrBuilder.java +++ b/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/PartitionedUpdateActionOrBuilder.java @@ -1,5 +1,5 @@ /* - * Copyright 2023 Google LLC + * Copyright 2024 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/QueryAction.java b/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/QueryAction.java index f39dec65282..3130a56da57 100644 --- a/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/QueryAction.java +++ b/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/QueryAction.java @@ -1,5 +1,5 @@ /* - * Copyright 2023 Google LLC + * Copyright 2024 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/QueryActionOrBuilder.java b/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/QueryActionOrBuilder.java index 5a9fb614d31..2e482430166 100644 --- a/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/QueryActionOrBuilder.java +++ b/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/QueryActionOrBuilder.java @@ -1,5 +1,5 @@ /* - * Copyright 2023 Google LLC + * Copyright 2024 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/QueryResult.java b/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/QueryResult.java index 485bffb85dc..ba42dce286b 100644 --- a/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/QueryResult.java +++ b/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/QueryResult.java @@ -1,5 +1,5 @@ /* - * Copyright 2023 Google LLC + * Copyright 2024 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/QueryResultOrBuilder.java b/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/QueryResultOrBuilder.java index f70058d2505..1b48cacecf3 100644 --- a/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/QueryResultOrBuilder.java +++ b/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/QueryResultOrBuilder.java @@ -1,5 +1,5 @@ /* - * Copyright 2023 Google LLC + * Copyright 2024 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/ReadAction.java b/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/ReadAction.java index 78eb70bec94..e585d521025 100644 --- a/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/ReadAction.java +++ b/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/ReadAction.java @@ -1,5 +1,5 @@ /* - * Copyright 2023 Google LLC + * Copyright 2024 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/ReadActionOrBuilder.java b/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/ReadActionOrBuilder.java index 10caf502805..b6b3f49659c 100644 --- a/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/ReadActionOrBuilder.java +++ b/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/ReadActionOrBuilder.java @@ -1,5 +1,5 @@ /* - * Copyright 2023 Google LLC + * Copyright 2024 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/ReadResult.java b/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/ReadResult.java index a3f95026a08..f04cb51a9ee 100644 --- a/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/ReadResult.java +++ b/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/ReadResult.java @@ -1,5 +1,5 @@ /* - * Copyright 2023 Google LLC + * Copyright 2024 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/ReadResultOrBuilder.java b/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/ReadResultOrBuilder.java index 776a79a81be..c4f6ac2f657 100644 --- a/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/ReadResultOrBuilder.java +++ b/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/ReadResultOrBuilder.java @@ -1,5 +1,5 @@ /* - * Copyright 2023 Google LLC + * Copyright 2024 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/ReconfigureCloudDatabaseAction.java b/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/ReconfigureCloudDatabaseAction.java index 9a4193791d0..24b31e43cd9 100644 --- a/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/ReconfigureCloudDatabaseAction.java +++ b/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/ReconfigureCloudDatabaseAction.java @@ -1,5 +1,5 @@ /* - * Copyright 2023 Google LLC + * Copyright 2024 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/ReconfigureCloudDatabaseActionOrBuilder.java b/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/ReconfigureCloudDatabaseActionOrBuilder.java index 3faad5b6f92..bb01604d2ab 100644 --- a/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/ReconfigureCloudDatabaseActionOrBuilder.java +++ b/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/ReconfigureCloudDatabaseActionOrBuilder.java @@ -1,5 +1,5 @@ /* - * Copyright 2023 Google LLC + * Copyright 2024 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/RestoreCloudDatabaseAction.java b/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/RestoreCloudDatabaseAction.java index 29b08596e0d..06d12e58b6a 100644 --- a/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/RestoreCloudDatabaseAction.java +++ b/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/RestoreCloudDatabaseAction.java @@ -1,5 +1,5 @@ /* - * Copyright 2023 Google LLC + * Copyright 2024 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/RestoreCloudDatabaseActionOrBuilder.java b/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/RestoreCloudDatabaseActionOrBuilder.java index 0630ed25a4f..baf8b75ab05 100644 --- a/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/RestoreCloudDatabaseActionOrBuilder.java +++ b/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/RestoreCloudDatabaseActionOrBuilder.java @@ -1,5 +1,5 @@ /* - * Copyright 2023 Google LLC + * Copyright 2024 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/SpannerAction.java b/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/SpannerAction.java index 93900be1ff0..87db61a803d 100644 --- a/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/SpannerAction.java +++ b/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/SpannerAction.java @@ -1,5 +1,5 @@ /* - * Copyright 2023 Google LLC + * Copyright 2024 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/SpannerActionOrBuilder.java b/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/SpannerActionOrBuilder.java index 9925dc008c2..b6985fd0202 100644 --- a/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/SpannerActionOrBuilder.java +++ b/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/SpannerActionOrBuilder.java @@ -1,5 +1,5 @@ /* - * Copyright 2023 Google LLC + * Copyright 2024 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/SpannerActionOutcome.java b/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/SpannerActionOutcome.java index bbae0a9f28f..7f2936808ad 100644 --- a/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/SpannerActionOutcome.java +++ b/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/SpannerActionOutcome.java @@ -1,5 +1,5 @@ /* - * Copyright 2023 Google LLC + * Copyright 2024 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/SpannerActionOutcomeOrBuilder.java b/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/SpannerActionOutcomeOrBuilder.java index 9e226d5df82..81e0873dab9 100644 --- a/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/SpannerActionOutcomeOrBuilder.java +++ b/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/SpannerActionOutcomeOrBuilder.java @@ -1,5 +1,5 @@ /* - * Copyright 2023 Google LLC + * Copyright 2024 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/SpannerAsyncActionRequest.java b/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/SpannerAsyncActionRequest.java index 82b3b635ac7..650324f04f0 100644 --- a/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/SpannerAsyncActionRequest.java +++ b/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/SpannerAsyncActionRequest.java @@ -1,5 +1,5 @@ /* - * Copyright 2023 Google LLC + * Copyright 2024 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/SpannerAsyncActionRequestOrBuilder.java b/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/SpannerAsyncActionRequestOrBuilder.java index 7b43292bb5e..9c7e98f0075 100644 --- a/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/SpannerAsyncActionRequestOrBuilder.java +++ b/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/SpannerAsyncActionRequestOrBuilder.java @@ -1,5 +1,5 @@ /* - * Copyright 2023 Google LLC + * Copyright 2024 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/SpannerAsyncActionResponse.java b/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/SpannerAsyncActionResponse.java index b085cbe14ad..53f6aaa3b1c 100644 --- a/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/SpannerAsyncActionResponse.java +++ b/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/SpannerAsyncActionResponse.java @@ -1,5 +1,5 @@ /* - * Copyright 2023 Google LLC + * Copyright 2024 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/SpannerAsyncActionResponseOrBuilder.java b/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/SpannerAsyncActionResponseOrBuilder.java index 4cd40921dc2..e757b8f2686 100644 --- a/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/SpannerAsyncActionResponseOrBuilder.java +++ b/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/SpannerAsyncActionResponseOrBuilder.java @@ -1,5 +1,5 @@ /* - * Copyright 2023 Google LLC + * Copyright 2024 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/StartBatchTransactionAction.java b/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/StartBatchTransactionAction.java index 8151ddd2d1a..bc40dbd08f1 100644 --- a/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/StartBatchTransactionAction.java +++ b/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/StartBatchTransactionAction.java @@ -1,5 +1,5 @@ /* - * Copyright 2023 Google LLC + * Copyright 2024 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/StartBatchTransactionActionOrBuilder.java b/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/StartBatchTransactionActionOrBuilder.java index 36a9b82e176..5b19898c541 100644 --- a/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/StartBatchTransactionActionOrBuilder.java +++ b/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/StartBatchTransactionActionOrBuilder.java @@ -1,5 +1,5 @@ /* - * Copyright 2023 Google LLC + * Copyright 2024 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/StartTransactionAction.java b/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/StartTransactionAction.java index 5a59ea38137..3d10545d660 100644 --- a/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/StartTransactionAction.java +++ b/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/StartTransactionAction.java @@ -1,5 +1,5 @@ /* - * Copyright 2023 Google LLC + * Copyright 2024 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/StartTransactionActionOrBuilder.java b/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/StartTransactionActionOrBuilder.java index b3019e84c78..ca0cdcd78fb 100644 --- a/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/StartTransactionActionOrBuilder.java +++ b/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/StartTransactionActionOrBuilder.java @@ -1,5 +1,5 @@ /* - * Copyright 2023 Google LLC + * Copyright 2024 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/TableMetadata.java b/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/TableMetadata.java index d7ab699a2ee..156d21349f6 100644 --- a/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/TableMetadata.java +++ b/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/TableMetadata.java @@ -1,5 +1,5 @@ /* - * Copyright 2023 Google LLC + * Copyright 2024 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/TableMetadataOrBuilder.java b/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/TableMetadataOrBuilder.java index 31b3ffb83ba..faf82e13e1a 100644 --- a/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/TableMetadataOrBuilder.java +++ b/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/TableMetadataOrBuilder.java @@ -1,5 +1,5 @@ /* - * Copyright 2023 Google LLC + * Copyright 2024 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/TransactionExecutionOptions.java b/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/TransactionExecutionOptions.java index 4770c3dfd4d..60b1432eeb0 100644 --- a/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/TransactionExecutionOptions.java +++ b/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/TransactionExecutionOptions.java @@ -1,5 +1,5 @@ /* - * Copyright 2023 Google LLC + * Copyright 2024 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/TransactionExecutionOptionsOrBuilder.java b/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/TransactionExecutionOptionsOrBuilder.java index 252a463d808..ccd889659f7 100644 --- a/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/TransactionExecutionOptionsOrBuilder.java +++ b/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/TransactionExecutionOptionsOrBuilder.java @@ -1,5 +1,5 @@ /* - * Copyright 2023 Google LLC + * Copyright 2024 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/UpdateCloudBackupAction.java b/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/UpdateCloudBackupAction.java index d03b821373f..26b9ba8e817 100644 --- a/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/UpdateCloudBackupAction.java +++ b/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/UpdateCloudBackupAction.java @@ -1,5 +1,5 @@ /* - * Copyright 2023 Google LLC + * Copyright 2024 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/UpdateCloudBackupActionOrBuilder.java b/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/UpdateCloudBackupActionOrBuilder.java index 5df3e1907b1..78af4416876 100644 --- a/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/UpdateCloudBackupActionOrBuilder.java +++ b/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/UpdateCloudBackupActionOrBuilder.java @@ -1,5 +1,5 @@ /* - * Copyright 2023 Google LLC + * Copyright 2024 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/UpdateCloudDatabaseAction.java b/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/UpdateCloudDatabaseAction.java index a0deaeaacab..53bbe9e2c8a 100644 --- a/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/UpdateCloudDatabaseAction.java +++ b/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/UpdateCloudDatabaseAction.java @@ -1,5 +1,5 @@ /* - * Copyright 2023 Google LLC + * Copyright 2024 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/UpdateCloudDatabaseActionOrBuilder.java b/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/UpdateCloudDatabaseActionOrBuilder.java index c2e887b6e7d..38b0091a9af 100644 --- a/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/UpdateCloudDatabaseActionOrBuilder.java +++ b/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/UpdateCloudDatabaseActionOrBuilder.java @@ -1,5 +1,5 @@ /* - * Copyright 2023 Google LLC + * Copyright 2024 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/UpdateCloudDatabaseDdlAction.java b/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/UpdateCloudDatabaseDdlAction.java index 86e645c2dba..dd68ed881e5 100644 --- a/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/UpdateCloudDatabaseDdlAction.java +++ b/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/UpdateCloudDatabaseDdlAction.java @@ -1,5 +1,5 @@ /* - * Copyright 2023 Google LLC + * Copyright 2024 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/UpdateCloudDatabaseDdlActionOrBuilder.java b/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/UpdateCloudDatabaseDdlActionOrBuilder.java index 9a0b79ff9cd..cb4486defe1 100644 --- a/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/UpdateCloudDatabaseDdlActionOrBuilder.java +++ b/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/UpdateCloudDatabaseDdlActionOrBuilder.java @@ -1,5 +1,5 @@ /* - * Copyright 2023 Google LLC + * Copyright 2024 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/UpdateCloudInstanceAction.java b/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/UpdateCloudInstanceAction.java index 7fe449ce299..7bdc57e1a2f 100644 --- a/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/UpdateCloudInstanceAction.java +++ b/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/UpdateCloudInstanceAction.java @@ -1,5 +1,5 @@ /* - * Copyright 2023 Google LLC + * Copyright 2024 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/UpdateCloudInstanceActionOrBuilder.java b/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/UpdateCloudInstanceActionOrBuilder.java index c5a8732c17e..4f7c1b1c3b2 100644 --- a/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/UpdateCloudInstanceActionOrBuilder.java +++ b/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/UpdateCloudInstanceActionOrBuilder.java @@ -1,5 +1,5 @@ /* - * Copyright 2023 Google LLC + * Copyright 2024 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/UpdateUserInstanceConfigAction.java b/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/UpdateUserInstanceConfigAction.java index 553f3d8d5fd..688d1058a7a 100644 --- a/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/UpdateUserInstanceConfigAction.java +++ b/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/UpdateUserInstanceConfigAction.java @@ -1,5 +1,5 @@ /* - * Copyright 2023 Google LLC + * Copyright 2024 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/UpdateUserInstanceConfigActionOrBuilder.java b/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/UpdateUserInstanceConfigActionOrBuilder.java index 2635287c66f..8f0ba4454d8 100644 --- a/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/UpdateUserInstanceConfigActionOrBuilder.java +++ b/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/UpdateUserInstanceConfigActionOrBuilder.java @@ -1,5 +1,5 @@ /* - * Copyright 2023 Google LLC + * Copyright 2024 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/Value.java b/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/Value.java index 86061d944ef..6960bd47d48 100644 --- a/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/Value.java +++ b/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/Value.java @@ -1,5 +1,5 @@ /* - * Copyright 2023 Google LLC + * Copyright 2024 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/ValueList.java b/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/ValueList.java index 2ff09046383..1f7243061ae 100644 --- a/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/ValueList.java +++ b/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/ValueList.java @@ -1,5 +1,5 @@ /* - * Copyright 2023 Google LLC + * Copyright 2024 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/ValueListOrBuilder.java b/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/ValueListOrBuilder.java index 5578961a158..84d25b45614 100644 --- a/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/ValueListOrBuilder.java +++ b/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/ValueListOrBuilder.java @@ -1,5 +1,5 @@ /* - * Copyright 2023 Google LLC + * Copyright 2024 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/ValueOrBuilder.java b/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/ValueOrBuilder.java index f92f72e9957..b52def016e1 100644 --- a/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/ValueOrBuilder.java +++ b/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/ValueOrBuilder.java @@ -1,5 +1,5 @@ /* - * Copyright 2023 Google LLC + * Copyright 2024 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/WriteMutationsAction.java b/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/WriteMutationsAction.java index 811fec8a11e..4a05d270422 100644 --- a/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/WriteMutationsAction.java +++ b/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/WriteMutationsAction.java @@ -1,5 +1,5 @@ /* - * Copyright 2023 Google LLC + * Copyright 2024 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/WriteMutationsActionOrBuilder.java b/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/WriteMutationsActionOrBuilder.java index 3a412678808..eb15709e015 100644 --- a/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/WriteMutationsActionOrBuilder.java +++ b/proto-google-cloud-spanner-executor-v1/src/main/java/com/google/spanner/executor/v1/WriteMutationsActionOrBuilder.java @@ -1,5 +1,5 @@ /* - * Copyright 2023 Google LLC + * Copyright 2024 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/proto-google-cloud-spanner-v1/src/main/java/com/google/spanner/v1/BatchCreateSessionsRequest.java b/proto-google-cloud-spanner-v1/src/main/java/com/google/spanner/v1/BatchCreateSessionsRequest.java index ad23fd19b8c..a05b036eb56 100644 --- a/proto-google-cloud-spanner-v1/src/main/java/com/google/spanner/v1/BatchCreateSessionsRequest.java +++ b/proto-google-cloud-spanner-v1/src/main/java/com/google/spanner/v1/BatchCreateSessionsRequest.java @@ -1,5 +1,5 @@ /* - * Copyright 2023 Google LLC + * Copyright 2024 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/proto-google-cloud-spanner-v1/src/main/java/com/google/spanner/v1/BatchCreateSessionsRequestOrBuilder.java b/proto-google-cloud-spanner-v1/src/main/java/com/google/spanner/v1/BatchCreateSessionsRequestOrBuilder.java index e4dc50f286d..ba05e28a79c 100644 --- a/proto-google-cloud-spanner-v1/src/main/java/com/google/spanner/v1/BatchCreateSessionsRequestOrBuilder.java +++ b/proto-google-cloud-spanner-v1/src/main/java/com/google/spanner/v1/BatchCreateSessionsRequestOrBuilder.java @@ -1,5 +1,5 @@ /* - * Copyright 2023 Google LLC + * Copyright 2024 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/proto-google-cloud-spanner-v1/src/main/java/com/google/spanner/v1/BatchCreateSessionsResponse.java b/proto-google-cloud-spanner-v1/src/main/java/com/google/spanner/v1/BatchCreateSessionsResponse.java index f5f7a7e031b..5981571de28 100644 --- a/proto-google-cloud-spanner-v1/src/main/java/com/google/spanner/v1/BatchCreateSessionsResponse.java +++ b/proto-google-cloud-spanner-v1/src/main/java/com/google/spanner/v1/BatchCreateSessionsResponse.java @@ -1,5 +1,5 @@ /* - * Copyright 2023 Google LLC + * Copyright 2024 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/proto-google-cloud-spanner-v1/src/main/java/com/google/spanner/v1/BatchCreateSessionsResponseOrBuilder.java b/proto-google-cloud-spanner-v1/src/main/java/com/google/spanner/v1/BatchCreateSessionsResponseOrBuilder.java index 37aa55ad7ae..2bc45d986b3 100644 --- a/proto-google-cloud-spanner-v1/src/main/java/com/google/spanner/v1/BatchCreateSessionsResponseOrBuilder.java +++ b/proto-google-cloud-spanner-v1/src/main/java/com/google/spanner/v1/BatchCreateSessionsResponseOrBuilder.java @@ -1,5 +1,5 @@ /* - * Copyright 2023 Google LLC + * Copyright 2024 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/proto-google-cloud-spanner-v1/src/main/java/com/google/spanner/v1/BatchWriteRequest.java b/proto-google-cloud-spanner-v1/src/main/java/com/google/spanner/v1/BatchWriteRequest.java index f790301b43c..5f6c3a2165e 100644 --- a/proto-google-cloud-spanner-v1/src/main/java/com/google/spanner/v1/BatchWriteRequest.java +++ b/proto-google-cloud-spanner-v1/src/main/java/com/google/spanner/v1/BatchWriteRequest.java @@ -1,5 +1,5 @@ /* - * Copyright 2023 Google LLC + * Copyright 2024 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/proto-google-cloud-spanner-v1/src/main/java/com/google/spanner/v1/BatchWriteRequestOrBuilder.java b/proto-google-cloud-spanner-v1/src/main/java/com/google/spanner/v1/BatchWriteRequestOrBuilder.java index 88615ac1c88..614ef426948 100644 --- a/proto-google-cloud-spanner-v1/src/main/java/com/google/spanner/v1/BatchWriteRequestOrBuilder.java +++ b/proto-google-cloud-spanner-v1/src/main/java/com/google/spanner/v1/BatchWriteRequestOrBuilder.java @@ -1,5 +1,5 @@ /* - * Copyright 2023 Google LLC + * Copyright 2024 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/proto-google-cloud-spanner-v1/src/main/java/com/google/spanner/v1/BatchWriteResponse.java b/proto-google-cloud-spanner-v1/src/main/java/com/google/spanner/v1/BatchWriteResponse.java index b7525340d07..d65a0676c69 100644 --- a/proto-google-cloud-spanner-v1/src/main/java/com/google/spanner/v1/BatchWriteResponse.java +++ b/proto-google-cloud-spanner-v1/src/main/java/com/google/spanner/v1/BatchWriteResponse.java @@ -1,5 +1,5 @@ /* - * Copyright 2023 Google LLC + * Copyright 2024 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/proto-google-cloud-spanner-v1/src/main/java/com/google/spanner/v1/BatchWriteResponseOrBuilder.java b/proto-google-cloud-spanner-v1/src/main/java/com/google/spanner/v1/BatchWriteResponseOrBuilder.java index 9fe756ecf03..baff5215516 100644 --- a/proto-google-cloud-spanner-v1/src/main/java/com/google/spanner/v1/BatchWriteResponseOrBuilder.java +++ b/proto-google-cloud-spanner-v1/src/main/java/com/google/spanner/v1/BatchWriteResponseOrBuilder.java @@ -1,5 +1,5 @@ /* - * Copyright 2023 Google LLC + * Copyright 2024 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/proto-google-cloud-spanner-v1/src/main/java/com/google/spanner/v1/BeginTransactionRequest.java b/proto-google-cloud-spanner-v1/src/main/java/com/google/spanner/v1/BeginTransactionRequest.java index f097d007ecd..452acfa3064 100644 --- a/proto-google-cloud-spanner-v1/src/main/java/com/google/spanner/v1/BeginTransactionRequest.java +++ b/proto-google-cloud-spanner-v1/src/main/java/com/google/spanner/v1/BeginTransactionRequest.java @@ -1,5 +1,5 @@ /* - * Copyright 2023 Google LLC + * Copyright 2024 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/proto-google-cloud-spanner-v1/src/main/java/com/google/spanner/v1/BeginTransactionRequestOrBuilder.java b/proto-google-cloud-spanner-v1/src/main/java/com/google/spanner/v1/BeginTransactionRequestOrBuilder.java index 0e392cd708f..1e2e2529e6e 100644 --- a/proto-google-cloud-spanner-v1/src/main/java/com/google/spanner/v1/BeginTransactionRequestOrBuilder.java +++ b/proto-google-cloud-spanner-v1/src/main/java/com/google/spanner/v1/BeginTransactionRequestOrBuilder.java @@ -1,5 +1,5 @@ /* - * Copyright 2023 Google LLC + * Copyright 2024 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/proto-google-cloud-spanner-v1/src/main/java/com/google/spanner/v1/CommitRequest.java b/proto-google-cloud-spanner-v1/src/main/java/com/google/spanner/v1/CommitRequest.java index 3858c140451..8aa04b7474b 100644 --- a/proto-google-cloud-spanner-v1/src/main/java/com/google/spanner/v1/CommitRequest.java +++ b/proto-google-cloud-spanner-v1/src/main/java/com/google/spanner/v1/CommitRequest.java @@ -1,5 +1,5 @@ /* - * Copyright 2023 Google LLC + * Copyright 2024 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -378,6 +378,71 @@ public boolean getReturnCommitStats() { return returnCommitStats_; } + public static final int MAX_COMMIT_DELAY_FIELD_NUMBER = 8; + private com.google.protobuf.Duration maxCommitDelay_; + /** + * + * + *
+   * Optional. The amount of latency this request is willing to incur in order
+   * to improve throughput. If this field is not set, Spanner assumes requests
+   * are relatively latency sensitive and automatically determines an
+   * appropriate delay time. You can specify a batching delay value between 0
+   * and 500 ms.
+   * 
+ * + * .google.protobuf.Duration max_commit_delay = 8 [(.google.api.field_behavior) = OPTIONAL]; + * + * + * @return Whether the maxCommitDelay field is set. + */ + @java.lang.Override + public boolean hasMaxCommitDelay() { + return maxCommitDelay_ != null; + } + /** + * + * + *
+   * Optional. The amount of latency this request is willing to incur in order
+   * to improve throughput. If this field is not set, Spanner assumes requests
+   * are relatively latency sensitive and automatically determines an
+   * appropriate delay time. You can specify a batching delay value between 0
+   * and 500 ms.
+   * 
+ * + * .google.protobuf.Duration max_commit_delay = 8 [(.google.api.field_behavior) = OPTIONAL]; + * + * + * @return The maxCommitDelay. + */ + @java.lang.Override + public com.google.protobuf.Duration getMaxCommitDelay() { + return maxCommitDelay_ == null + ? com.google.protobuf.Duration.getDefaultInstance() + : maxCommitDelay_; + } + /** + * + * + *
+   * Optional. The amount of latency this request is willing to incur in order
+   * to improve throughput. If this field is not set, Spanner assumes requests
+   * are relatively latency sensitive and automatically determines an
+   * appropriate delay time. You can specify a batching delay value between 0
+   * and 500 ms.
+   * 
+ * + * .google.protobuf.Duration max_commit_delay = 8 [(.google.api.field_behavior) = OPTIONAL]; + * + */ + @java.lang.Override + public com.google.protobuf.DurationOrBuilder getMaxCommitDelayOrBuilder() { + return maxCommitDelay_ == null + ? com.google.protobuf.Duration.getDefaultInstance() + : maxCommitDelay_; + } + public static final int REQUEST_OPTIONS_FIELD_NUMBER = 6; private com.google.spanner.v1.RequestOptions requestOptions_; /** @@ -460,6 +525,9 @@ public void writeTo(com.google.protobuf.CodedOutputStream output) throws java.io if (requestOptions_ != null) { output.writeMessage(6, getRequestOptions()); } + if (maxCommitDelay_ != null) { + output.writeMessage(8, getMaxCommitDelay()); + } getUnknownFields().writeTo(output); } @@ -491,6 +559,9 @@ public int getSerializedSize() { if (requestOptions_ != null) { size += com.google.protobuf.CodedOutputStream.computeMessageSize(6, getRequestOptions()); } + if (maxCommitDelay_ != null) { + size += com.google.protobuf.CodedOutputStream.computeMessageSize(8, getMaxCommitDelay()); + } size += getUnknownFields().getSerializedSize(); memoizedSize = size; return size; @@ -509,6 +580,10 @@ public boolean equals(final java.lang.Object obj) { if (!getSession().equals(other.getSession())) return false; if (!getMutationsList().equals(other.getMutationsList())) return false; if (getReturnCommitStats() != other.getReturnCommitStats()) return false; + if (hasMaxCommitDelay() != other.hasMaxCommitDelay()) return false; + if (hasMaxCommitDelay()) { + if (!getMaxCommitDelay().equals(other.getMaxCommitDelay())) return false; + } if (hasRequestOptions() != other.hasRequestOptions()) return false; if (hasRequestOptions()) { if (!getRequestOptions().equals(other.getRequestOptions())) return false; @@ -543,6 +618,10 @@ public int hashCode() { } hash = (37 * hash) + RETURN_COMMIT_STATS_FIELD_NUMBER; hash = (53 * hash) + com.google.protobuf.Internal.hashBoolean(getReturnCommitStats()); + if (hasMaxCommitDelay()) { + hash = (37 * hash) + MAX_COMMIT_DELAY_FIELD_NUMBER; + hash = (53 * hash) + getMaxCommitDelay().hashCode(); + } if (hasRequestOptions()) { hash = (37 * hash) + REQUEST_OPTIONS_FIELD_NUMBER; hash = (53 * hash) + getRequestOptions().hashCode(); @@ -709,6 +788,11 @@ public Builder clear() { } bitField0_ = (bitField0_ & ~0x00000008); returnCommitStats_ = false; + maxCommitDelay_ = null; + if (maxCommitDelayBuilder_ != null) { + maxCommitDelayBuilder_.dispose(); + maxCommitDelayBuilder_ = null; + } requestOptions_ = null; if (requestOptionsBuilder_ != null) { requestOptionsBuilder_.dispose(); @@ -772,6 +856,10 @@ private void buildPartial0(com.google.spanner.v1.CommitRequest result) { result.returnCommitStats_ = returnCommitStats_; } if (((from_bitField0_ & 0x00000020) != 0)) { + result.maxCommitDelay_ = + maxCommitDelayBuilder_ == null ? maxCommitDelay_ : maxCommitDelayBuilder_.build(); + } + if (((from_bitField0_ & 0x00000040) != 0)) { result.requestOptions_ = requestOptionsBuilder_ == null ? requestOptions_ : requestOptionsBuilder_.build(); } @@ -865,6 +953,9 @@ public Builder mergeFrom(com.google.spanner.v1.CommitRequest other) { if (other.getReturnCommitStats() != false) { setReturnCommitStats(other.getReturnCommitStats()); } + if (other.hasMaxCommitDelay()) { + mergeMaxCommitDelay(other.getMaxCommitDelay()); + } if (other.hasRequestOptions()) { mergeRequestOptions(other.getRequestOptions()); } @@ -950,9 +1041,15 @@ public Builder mergeFrom( case 50: { input.readMessage(getRequestOptionsFieldBuilder().getBuilder(), extensionRegistry); - bitField0_ |= 0x00000020; + bitField0_ |= 0x00000040; break; } // case 50 + case 66: + { + input.readMessage(getMaxCommitDelayFieldBuilder().getBuilder(), extensionRegistry); + bitField0_ |= 0x00000020; + break; + } // case 66 default: { if (!super.parseUnknownField(input, extensionRegistry, tag)) { @@ -1896,6 +1993,243 @@ public Builder clearReturnCommitStats() { return this; } + private com.google.protobuf.Duration maxCommitDelay_; + private com.google.protobuf.SingleFieldBuilderV3< + com.google.protobuf.Duration, + com.google.protobuf.Duration.Builder, + com.google.protobuf.DurationOrBuilder> + maxCommitDelayBuilder_; + /** + * + * + *
+     * Optional. The amount of latency this request is willing to incur in order
+     * to improve throughput. If this field is not set, Spanner assumes requests
+     * are relatively latency sensitive and automatically determines an
+     * appropriate delay time. You can specify a batching delay value between 0
+     * and 500 ms.
+     * 
+ * + * + * .google.protobuf.Duration max_commit_delay = 8 [(.google.api.field_behavior) = OPTIONAL]; + * + * + * @return Whether the maxCommitDelay field is set. + */ + public boolean hasMaxCommitDelay() { + return ((bitField0_ & 0x00000020) != 0); + } + /** + * + * + *
+     * Optional. The amount of latency this request is willing to incur in order
+     * to improve throughput. If this field is not set, Spanner assumes requests
+     * are relatively latency sensitive and automatically determines an
+     * appropriate delay time. You can specify a batching delay value between 0
+     * and 500 ms.
+     * 
+ * + * + * .google.protobuf.Duration max_commit_delay = 8 [(.google.api.field_behavior) = OPTIONAL]; + * + * + * @return The maxCommitDelay. + */ + public com.google.protobuf.Duration getMaxCommitDelay() { + if (maxCommitDelayBuilder_ == null) { + return maxCommitDelay_ == null + ? com.google.protobuf.Duration.getDefaultInstance() + : maxCommitDelay_; + } else { + return maxCommitDelayBuilder_.getMessage(); + } + } + /** + * + * + *
+     * Optional. The amount of latency this request is willing to incur in order
+     * to improve throughput. If this field is not set, Spanner assumes requests
+     * are relatively latency sensitive and automatically determines an
+     * appropriate delay time. You can specify a batching delay value between 0
+     * and 500 ms.
+     * 
+ * + * + * .google.protobuf.Duration max_commit_delay = 8 [(.google.api.field_behavior) = OPTIONAL]; + * + */ + public Builder setMaxCommitDelay(com.google.protobuf.Duration value) { + if (maxCommitDelayBuilder_ == null) { + if (value == null) { + throw new NullPointerException(); + } + maxCommitDelay_ = value; + } else { + maxCommitDelayBuilder_.setMessage(value); + } + bitField0_ |= 0x00000020; + onChanged(); + return this; + } + /** + * + * + *
+     * Optional. The amount of latency this request is willing to incur in order
+     * to improve throughput. If this field is not set, Spanner assumes requests
+     * are relatively latency sensitive and automatically determines an
+     * appropriate delay time. You can specify a batching delay value between 0
+     * and 500 ms.
+     * 
+ * + * + * .google.protobuf.Duration max_commit_delay = 8 [(.google.api.field_behavior) = OPTIONAL]; + * + */ + public Builder setMaxCommitDelay(com.google.protobuf.Duration.Builder builderForValue) { + if (maxCommitDelayBuilder_ == null) { + maxCommitDelay_ = builderForValue.build(); + } else { + maxCommitDelayBuilder_.setMessage(builderForValue.build()); + } + bitField0_ |= 0x00000020; + onChanged(); + return this; + } + /** + * + * + *
+     * Optional. The amount of latency this request is willing to incur in order
+     * to improve throughput. If this field is not set, Spanner assumes requests
+     * are relatively latency sensitive and automatically determines an
+     * appropriate delay time. You can specify a batching delay value between 0
+     * and 500 ms.
+     * 
+ * + * + * .google.protobuf.Duration max_commit_delay = 8 [(.google.api.field_behavior) = OPTIONAL]; + * + */ + public Builder mergeMaxCommitDelay(com.google.protobuf.Duration value) { + if (maxCommitDelayBuilder_ == null) { + if (((bitField0_ & 0x00000020) != 0) + && maxCommitDelay_ != null + && maxCommitDelay_ != com.google.protobuf.Duration.getDefaultInstance()) { + getMaxCommitDelayBuilder().mergeFrom(value); + } else { + maxCommitDelay_ = value; + } + } else { + maxCommitDelayBuilder_.mergeFrom(value); + } + bitField0_ |= 0x00000020; + onChanged(); + return this; + } + /** + * + * + *
+     * Optional. The amount of latency this request is willing to incur in order
+     * to improve throughput. If this field is not set, Spanner assumes requests
+     * are relatively latency sensitive and automatically determines an
+     * appropriate delay time. You can specify a batching delay value between 0
+     * and 500 ms.
+     * 
+ * + * + * .google.protobuf.Duration max_commit_delay = 8 [(.google.api.field_behavior) = OPTIONAL]; + * + */ + public Builder clearMaxCommitDelay() { + bitField0_ = (bitField0_ & ~0x00000020); + maxCommitDelay_ = null; + if (maxCommitDelayBuilder_ != null) { + maxCommitDelayBuilder_.dispose(); + maxCommitDelayBuilder_ = null; + } + onChanged(); + return this; + } + /** + * + * + *
+     * Optional. The amount of latency this request is willing to incur in order
+     * to improve throughput. If this field is not set, Spanner assumes requests
+     * are relatively latency sensitive and automatically determines an
+     * appropriate delay time. You can specify a batching delay value between 0
+     * and 500 ms.
+     * 
+ * + * + * .google.protobuf.Duration max_commit_delay = 8 [(.google.api.field_behavior) = OPTIONAL]; + * + */ + public com.google.protobuf.Duration.Builder getMaxCommitDelayBuilder() { + bitField0_ |= 0x00000020; + onChanged(); + return getMaxCommitDelayFieldBuilder().getBuilder(); + } + /** + * + * + *
+     * Optional. The amount of latency this request is willing to incur in order
+     * to improve throughput. If this field is not set, Spanner assumes requests
+     * are relatively latency sensitive and automatically determines an
+     * appropriate delay time. You can specify a batching delay value between 0
+     * and 500 ms.
+     * 
+ * + * + * .google.protobuf.Duration max_commit_delay = 8 [(.google.api.field_behavior) = OPTIONAL]; + * + */ + public com.google.protobuf.DurationOrBuilder getMaxCommitDelayOrBuilder() { + if (maxCommitDelayBuilder_ != null) { + return maxCommitDelayBuilder_.getMessageOrBuilder(); + } else { + return maxCommitDelay_ == null + ? com.google.protobuf.Duration.getDefaultInstance() + : maxCommitDelay_; + } + } + /** + * + * + *
+     * Optional. The amount of latency this request is willing to incur in order
+     * to improve throughput. If this field is not set, Spanner assumes requests
+     * are relatively latency sensitive and automatically determines an
+     * appropriate delay time. You can specify a batching delay value between 0
+     * and 500 ms.
+     * 
+ * + * + * .google.protobuf.Duration max_commit_delay = 8 [(.google.api.field_behavior) = OPTIONAL]; + * + */ + private com.google.protobuf.SingleFieldBuilderV3< + com.google.protobuf.Duration, + com.google.protobuf.Duration.Builder, + com.google.protobuf.DurationOrBuilder> + getMaxCommitDelayFieldBuilder() { + if (maxCommitDelayBuilder_ == null) { + maxCommitDelayBuilder_ = + new com.google.protobuf.SingleFieldBuilderV3< + com.google.protobuf.Duration, + com.google.protobuf.Duration.Builder, + com.google.protobuf.DurationOrBuilder>( + getMaxCommitDelay(), getParentForChildren(), isClean()); + maxCommitDelay_ = null; + } + return maxCommitDelayBuilder_; + } + private com.google.spanner.v1.RequestOptions requestOptions_; private com.google.protobuf.SingleFieldBuilderV3< com.google.spanner.v1.RequestOptions, @@ -1914,7 +2248,7 @@ public Builder clearReturnCommitStats() { * @return Whether the requestOptions field is set. */ public boolean hasRequestOptions() { - return ((bitField0_ & 0x00000020) != 0); + return ((bitField0_ & 0x00000040) != 0); } /** * @@ -1954,7 +2288,7 @@ public Builder setRequestOptions(com.google.spanner.v1.RequestOptions value) { } else { requestOptionsBuilder_.setMessage(value); } - bitField0_ |= 0x00000020; + bitField0_ |= 0x00000040; onChanged(); return this; } @@ -1973,7 +2307,7 @@ public Builder setRequestOptions(com.google.spanner.v1.RequestOptions.Builder bu } else { requestOptionsBuilder_.setMessage(builderForValue.build()); } - bitField0_ |= 0x00000020; + bitField0_ |= 0x00000040; onChanged(); return this; } @@ -1988,7 +2322,7 @@ public Builder setRequestOptions(com.google.spanner.v1.RequestOptions.Builder bu */ public Builder mergeRequestOptions(com.google.spanner.v1.RequestOptions value) { if (requestOptionsBuilder_ == null) { - if (((bitField0_ & 0x00000020) != 0) + if (((bitField0_ & 0x00000040) != 0) && requestOptions_ != null && requestOptions_ != com.google.spanner.v1.RequestOptions.getDefaultInstance()) { getRequestOptionsBuilder().mergeFrom(value); @@ -1998,7 +2332,7 @@ public Builder mergeRequestOptions(com.google.spanner.v1.RequestOptions value) { } else { requestOptionsBuilder_.mergeFrom(value); } - bitField0_ |= 0x00000020; + bitField0_ |= 0x00000040; onChanged(); return this; } @@ -2012,7 +2346,7 @@ public Builder mergeRequestOptions(com.google.spanner.v1.RequestOptions value) { * .google.spanner.v1.RequestOptions request_options = 6; */ public Builder clearRequestOptions() { - bitField0_ = (bitField0_ & ~0x00000020); + bitField0_ = (bitField0_ & ~0x00000040); requestOptions_ = null; if (requestOptionsBuilder_ != null) { requestOptionsBuilder_.dispose(); @@ -2031,7 +2365,7 @@ public Builder clearRequestOptions() { * .google.spanner.v1.RequestOptions request_options = 6; */ public com.google.spanner.v1.RequestOptions.Builder getRequestOptionsBuilder() { - bitField0_ |= 0x00000020; + bitField0_ |= 0x00000040; onChanged(); return getRequestOptionsFieldBuilder().getBuilder(); } diff --git a/proto-google-cloud-spanner-v1/src/main/java/com/google/spanner/v1/CommitRequestOrBuilder.java b/proto-google-cloud-spanner-v1/src/main/java/com/google/spanner/v1/CommitRequestOrBuilder.java index 70f16028376..7ae8b1d841d 100644 --- a/proto-google-cloud-spanner-v1/src/main/java/com/google/spanner/v1/CommitRequestOrBuilder.java +++ b/proto-google-cloud-spanner-v1/src/main/java/com/google/spanner/v1/CommitRequestOrBuilder.java @@ -1,5 +1,5 @@ /* - * Copyright 2023 Google LLC + * Copyright 2024 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -212,6 +212,56 @@ public interface CommitRequestOrBuilder */ boolean getReturnCommitStats(); + /** + * + * + *
+   * Optional. The amount of latency this request is willing to incur in order
+   * to improve throughput. If this field is not set, Spanner assumes requests
+   * are relatively latency sensitive and automatically determines an
+   * appropriate delay time. You can specify a batching delay value between 0
+   * and 500 ms.
+   * 
+ * + * .google.protobuf.Duration max_commit_delay = 8 [(.google.api.field_behavior) = OPTIONAL]; + * + * + * @return Whether the maxCommitDelay field is set. + */ + boolean hasMaxCommitDelay(); + /** + * + * + *
+   * Optional. The amount of latency this request is willing to incur in order
+   * to improve throughput. If this field is not set, Spanner assumes requests
+   * are relatively latency sensitive and automatically determines an
+   * appropriate delay time. You can specify a batching delay value between 0
+   * and 500 ms.
+   * 
+ * + * .google.protobuf.Duration max_commit_delay = 8 [(.google.api.field_behavior) = OPTIONAL]; + * + * + * @return The maxCommitDelay. + */ + com.google.protobuf.Duration getMaxCommitDelay(); + /** + * + * + *
+   * Optional. The amount of latency this request is willing to incur in order
+   * to improve throughput. If this field is not set, Spanner assumes requests
+   * are relatively latency sensitive and automatically determines an
+   * appropriate delay time. You can specify a batching delay value between 0
+   * and 500 ms.
+   * 
+ * + * .google.protobuf.Duration max_commit_delay = 8 [(.google.api.field_behavior) = OPTIONAL]; + * + */ + com.google.protobuf.DurationOrBuilder getMaxCommitDelayOrBuilder(); + /** * * diff --git a/proto-google-cloud-spanner-v1/src/main/java/com/google/spanner/v1/CommitResponse.java b/proto-google-cloud-spanner-v1/src/main/java/com/google/spanner/v1/CommitResponse.java index cdbd0e0ac8d..079eb168933 100644 --- a/proto-google-cloud-spanner-v1/src/main/java/com/google/spanner/v1/CommitResponse.java +++ b/proto-google-cloud-spanner-v1/src/main/java/com/google/spanner/v1/CommitResponse.java @@ -1,5 +1,5 @@ /* - * Copyright 2023 Google LLC + * Copyright 2024 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/proto-google-cloud-spanner-v1/src/main/java/com/google/spanner/v1/CommitResponseOrBuilder.java b/proto-google-cloud-spanner-v1/src/main/java/com/google/spanner/v1/CommitResponseOrBuilder.java index f3a1917c261..e8de2e60ea6 100644 --- a/proto-google-cloud-spanner-v1/src/main/java/com/google/spanner/v1/CommitResponseOrBuilder.java +++ b/proto-google-cloud-spanner-v1/src/main/java/com/google/spanner/v1/CommitResponseOrBuilder.java @@ -1,5 +1,5 @@ /* - * Copyright 2023 Google LLC + * Copyright 2024 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/proto-google-cloud-spanner-v1/src/main/java/com/google/spanner/v1/CommitResponseProto.java b/proto-google-cloud-spanner-v1/src/main/java/com/google/spanner/v1/CommitResponseProto.java index a0275299548..c1382f78d32 100644 --- a/proto-google-cloud-spanner-v1/src/main/java/com/google/spanner/v1/CommitResponseProto.java +++ b/proto-google-cloud-spanner-v1/src/main/java/com/google/spanner/v1/CommitResponseProto.java @@ -1,5 +1,5 @@ /* - * Copyright 2023 Google LLC + * Copyright 2024 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/proto-google-cloud-spanner-v1/src/main/java/com/google/spanner/v1/CreateSessionRequest.java b/proto-google-cloud-spanner-v1/src/main/java/com/google/spanner/v1/CreateSessionRequest.java index c990f56b5a9..3a5fbeb1363 100644 --- a/proto-google-cloud-spanner-v1/src/main/java/com/google/spanner/v1/CreateSessionRequest.java +++ b/proto-google-cloud-spanner-v1/src/main/java/com/google/spanner/v1/CreateSessionRequest.java @@ -1,5 +1,5 @@ /* - * Copyright 2023 Google LLC + * Copyright 2024 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/proto-google-cloud-spanner-v1/src/main/java/com/google/spanner/v1/CreateSessionRequestOrBuilder.java b/proto-google-cloud-spanner-v1/src/main/java/com/google/spanner/v1/CreateSessionRequestOrBuilder.java index 283b6307c33..23d956f3103 100644 --- a/proto-google-cloud-spanner-v1/src/main/java/com/google/spanner/v1/CreateSessionRequestOrBuilder.java +++ b/proto-google-cloud-spanner-v1/src/main/java/com/google/spanner/v1/CreateSessionRequestOrBuilder.java @@ -1,5 +1,5 @@ /* - * Copyright 2023 Google LLC + * Copyright 2024 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/proto-google-cloud-spanner-v1/src/main/java/com/google/spanner/v1/DeleteSessionRequest.java b/proto-google-cloud-spanner-v1/src/main/java/com/google/spanner/v1/DeleteSessionRequest.java index 6f10b8712d9..17bfb7641e4 100644 --- a/proto-google-cloud-spanner-v1/src/main/java/com/google/spanner/v1/DeleteSessionRequest.java +++ b/proto-google-cloud-spanner-v1/src/main/java/com/google/spanner/v1/DeleteSessionRequest.java @@ -1,5 +1,5 @@ /* - * Copyright 2023 Google LLC + * Copyright 2024 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/proto-google-cloud-spanner-v1/src/main/java/com/google/spanner/v1/DeleteSessionRequestOrBuilder.java b/proto-google-cloud-spanner-v1/src/main/java/com/google/spanner/v1/DeleteSessionRequestOrBuilder.java index 7e36ce651d1..e1f31d051bb 100644 --- a/proto-google-cloud-spanner-v1/src/main/java/com/google/spanner/v1/DeleteSessionRequestOrBuilder.java +++ b/proto-google-cloud-spanner-v1/src/main/java/com/google/spanner/v1/DeleteSessionRequestOrBuilder.java @@ -1,5 +1,5 @@ /* - * Copyright 2023 Google LLC + * Copyright 2024 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/proto-google-cloud-spanner-v1/src/main/java/com/google/spanner/v1/DirectedReadOptions.java b/proto-google-cloud-spanner-v1/src/main/java/com/google/spanner/v1/DirectedReadOptions.java index dcdd4ba12a2..6d75ace7a8b 100644 --- a/proto-google-cloud-spanner-v1/src/main/java/com/google/spanner/v1/DirectedReadOptions.java +++ b/proto-google-cloud-spanner-v1/src/main/java/com/google/spanner/v1/DirectedReadOptions.java @@ -1,5 +1,5 @@ /* - * Copyright 2023 Google LLC + * Copyright 2024 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/proto-google-cloud-spanner-v1/src/main/java/com/google/spanner/v1/DirectedReadOptionsOrBuilder.java b/proto-google-cloud-spanner-v1/src/main/java/com/google/spanner/v1/DirectedReadOptionsOrBuilder.java index 1fe6a3fdee4..df1488d5e62 100644 --- a/proto-google-cloud-spanner-v1/src/main/java/com/google/spanner/v1/DirectedReadOptionsOrBuilder.java +++ b/proto-google-cloud-spanner-v1/src/main/java/com/google/spanner/v1/DirectedReadOptionsOrBuilder.java @@ -1,5 +1,5 @@ /* - * Copyright 2023 Google LLC + * Copyright 2024 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/proto-google-cloud-spanner-v1/src/main/java/com/google/spanner/v1/ExecuteBatchDmlRequest.java b/proto-google-cloud-spanner-v1/src/main/java/com/google/spanner/v1/ExecuteBatchDmlRequest.java index c1ba384a7de..2b735cb4367 100644 --- a/proto-google-cloud-spanner-v1/src/main/java/com/google/spanner/v1/ExecuteBatchDmlRequest.java +++ b/proto-google-cloud-spanner-v1/src/main/java/com/google/spanner/v1/ExecuteBatchDmlRequest.java @@ -1,5 +1,5 @@ /* - * Copyright 2023 Google LLC + * Copyright 2024 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/proto-google-cloud-spanner-v1/src/main/java/com/google/spanner/v1/ExecuteBatchDmlRequestOrBuilder.java b/proto-google-cloud-spanner-v1/src/main/java/com/google/spanner/v1/ExecuteBatchDmlRequestOrBuilder.java index 1e19f95d84e..d6370c8148b 100644 --- a/proto-google-cloud-spanner-v1/src/main/java/com/google/spanner/v1/ExecuteBatchDmlRequestOrBuilder.java +++ b/proto-google-cloud-spanner-v1/src/main/java/com/google/spanner/v1/ExecuteBatchDmlRequestOrBuilder.java @@ -1,5 +1,5 @@ /* - * Copyright 2023 Google LLC + * Copyright 2024 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/proto-google-cloud-spanner-v1/src/main/java/com/google/spanner/v1/ExecuteBatchDmlResponse.java b/proto-google-cloud-spanner-v1/src/main/java/com/google/spanner/v1/ExecuteBatchDmlResponse.java index f1ab37d5e57..1453b8c7995 100644 --- a/proto-google-cloud-spanner-v1/src/main/java/com/google/spanner/v1/ExecuteBatchDmlResponse.java +++ b/proto-google-cloud-spanner-v1/src/main/java/com/google/spanner/v1/ExecuteBatchDmlResponse.java @@ -1,5 +1,5 @@ /* - * Copyright 2023 Google LLC + * Copyright 2024 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/proto-google-cloud-spanner-v1/src/main/java/com/google/spanner/v1/ExecuteBatchDmlResponseOrBuilder.java b/proto-google-cloud-spanner-v1/src/main/java/com/google/spanner/v1/ExecuteBatchDmlResponseOrBuilder.java index eff5a0dc0ab..8c764b5139b 100644 --- a/proto-google-cloud-spanner-v1/src/main/java/com/google/spanner/v1/ExecuteBatchDmlResponseOrBuilder.java +++ b/proto-google-cloud-spanner-v1/src/main/java/com/google/spanner/v1/ExecuteBatchDmlResponseOrBuilder.java @@ -1,5 +1,5 @@ /* - * Copyright 2023 Google LLC + * Copyright 2024 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/proto-google-cloud-spanner-v1/src/main/java/com/google/spanner/v1/ExecuteSqlRequest.java b/proto-google-cloud-spanner-v1/src/main/java/com/google/spanner/v1/ExecuteSqlRequest.java index fcbb077b944..b287c4db6d3 100644 --- a/proto-google-cloud-spanner-v1/src/main/java/com/google/spanner/v1/ExecuteSqlRequest.java +++ b/proto-google-cloud-spanner-v1/src/main/java/com/google/spanner/v1/ExecuteSqlRequest.java @@ -1,5 +1,5 @@ /* - * Copyright 2023 Google LLC + * Copyright 2024 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/proto-google-cloud-spanner-v1/src/main/java/com/google/spanner/v1/ExecuteSqlRequestOrBuilder.java b/proto-google-cloud-spanner-v1/src/main/java/com/google/spanner/v1/ExecuteSqlRequestOrBuilder.java index 6ab39195f10..cd78fa0b36f 100644 --- a/proto-google-cloud-spanner-v1/src/main/java/com/google/spanner/v1/ExecuteSqlRequestOrBuilder.java +++ b/proto-google-cloud-spanner-v1/src/main/java/com/google/spanner/v1/ExecuteSqlRequestOrBuilder.java @@ -1,5 +1,5 @@ /* - * Copyright 2023 Google LLC + * Copyright 2024 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/proto-google-cloud-spanner-v1/src/main/java/com/google/spanner/v1/GetSessionRequest.java b/proto-google-cloud-spanner-v1/src/main/java/com/google/spanner/v1/GetSessionRequest.java index 2f06025e247..4da3701235d 100644 --- a/proto-google-cloud-spanner-v1/src/main/java/com/google/spanner/v1/GetSessionRequest.java +++ b/proto-google-cloud-spanner-v1/src/main/java/com/google/spanner/v1/GetSessionRequest.java @@ -1,5 +1,5 @@ /* - * Copyright 2023 Google LLC + * Copyright 2024 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/proto-google-cloud-spanner-v1/src/main/java/com/google/spanner/v1/GetSessionRequestOrBuilder.java b/proto-google-cloud-spanner-v1/src/main/java/com/google/spanner/v1/GetSessionRequestOrBuilder.java index 4f43c14e649..cb9e8e11e47 100644 --- a/proto-google-cloud-spanner-v1/src/main/java/com/google/spanner/v1/GetSessionRequestOrBuilder.java +++ b/proto-google-cloud-spanner-v1/src/main/java/com/google/spanner/v1/GetSessionRequestOrBuilder.java @@ -1,5 +1,5 @@ /* - * Copyright 2023 Google LLC + * Copyright 2024 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/proto-google-cloud-spanner-v1/src/main/java/com/google/spanner/v1/KeyRange.java b/proto-google-cloud-spanner-v1/src/main/java/com/google/spanner/v1/KeyRange.java index 7c5560e1ac0..f1ed673a74a 100644 --- a/proto-google-cloud-spanner-v1/src/main/java/com/google/spanner/v1/KeyRange.java +++ b/proto-google-cloud-spanner-v1/src/main/java/com/google/spanner/v1/KeyRange.java @@ -1,5 +1,5 @@ /* - * Copyright 2023 Google LLC + * Copyright 2024 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/proto-google-cloud-spanner-v1/src/main/java/com/google/spanner/v1/KeyRangeOrBuilder.java b/proto-google-cloud-spanner-v1/src/main/java/com/google/spanner/v1/KeyRangeOrBuilder.java index 3310e6af4af..f417d881369 100644 --- a/proto-google-cloud-spanner-v1/src/main/java/com/google/spanner/v1/KeyRangeOrBuilder.java +++ b/proto-google-cloud-spanner-v1/src/main/java/com/google/spanner/v1/KeyRangeOrBuilder.java @@ -1,5 +1,5 @@ /* - * Copyright 2023 Google LLC + * Copyright 2024 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/proto-google-cloud-spanner-v1/src/main/java/com/google/spanner/v1/KeySet.java b/proto-google-cloud-spanner-v1/src/main/java/com/google/spanner/v1/KeySet.java index fb43bbec4a0..7bc3c382a9b 100644 --- a/proto-google-cloud-spanner-v1/src/main/java/com/google/spanner/v1/KeySet.java +++ b/proto-google-cloud-spanner-v1/src/main/java/com/google/spanner/v1/KeySet.java @@ -1,5 +1,5 @@ /* - * Copyright 2023 Google LLC + * Copyright 2024 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/proto-google-cloud-spanner-v1/src/main/java/com/google/spanner/v1/KeySetOrBuilder.java b/proto-google-cloud-spanner-v1/src/main/java/com/google/spanner/v1/KeySetOrBuilder.java index 4aa83584ea3..9465c3c1558 100644 --- a/proto-google-cloud-spanner-v1/src/main/java/com/google/spanner/v1/KeySetOrBuilder.java +++ b/proto-google-cloud-spanner-v1/src/main/java/com/google/spanner/v1/KeySetOrBuilder.java @@ -1,5 +1,5 @@ /* - * Copyright 2023 Google LLC + * Copyright 2024 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/proto-google-cloud-spanner-v1/src/main/java/com/google/spanner/v1/KeysProto.java b/proto-google-cloud-spanner-v1/src/main/java/com/google/spanner/v1/KeysProto.java index 7db545a22ec..1eaf784655a 100644 --- a/proto-google-cloud-spanner-v1/src/main/java/com/google/spanner/v1/KeysProto.java +++ b/proto-google-cloud-spanner-v1/src/main/java/com/google/spanner/v1/KeysProto.java @@ -1,5 +1,5 @@ /* - * Copyright 2023 Google LLC + * Copyright 2024 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/proto-google-cloud-spanner-v1/src/main/java/com/google/spanner/v1/ListSessionsRequest.java b/proto-google-cloud-spanner-v1/src/main/java/com/google/spanner/v1/ListSessionsRequest.java index eca16a1e187..7bfd6d58aca 100644 --- a/proto-google-cloud-spanner-v1/src/main/java/com/google/spanner/v1/ListSessionsRequest.java +++ b/proto-google-cloud-spanner-v1/src/main/java/com/google/spanner/v1/ListSessionsRequest.java @@ -1,5 +1,5 @@ /* - * Copyright 2023 Google LLC + * Copyright 2024 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/proto-google-cloud-spanner-v1/src/main/java/com/google/spanner/v1/ListSessionsRequestOrBuilder.java b/proto-google-cloud-spanner-v1/src/main/java/com/google/spanner/v1/ListSessionsRequestOrBuilder.java index ad370bb1147..c51a674ccc2 100644 --- a/proto-google-cloud-spanner-v1/src/main/java/com/google/spanner/v1/ListSessionsRequestOrBuilder.java +++ b/proto-google-cloud-spanner-v1/src/main/java/com/google/spanner/v1/ListSessionsRequestOrBuilder.java @@ -1,5 +1,5 @@ /* - * Copyright 2023 Google LLC + * Copyright 2024 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/proto-google-cloud-spanner-v1/src/main/java/com/google/spanner/v1/ListSessionsResponse.java b/proto-google-cloud-spanner-v1/src/main/java/com/google/spanner/v1/ListSessionsResponse.java index 99a23a3b878..22a5e8d157a 100644 --- a/proto-google-cloud-spanner-v1/src/main/java/com/google/spanner/v1/ListSessionsResponse.java +++ b/proto-google-cloud-spanner-v1/src/main/java/com/google/spanner/v1/ListSessionsResponse.java @@ -1,5 +1,5 @@ /* - * Copyright 2023 Google LLC + * Copyright 2024 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/proto-google-cloud-spanner-v1/src/main/java/com/google/spanner/v1/ListSessionsResponseOrBuilder.java b/proto-google-cloud-spanner-v1/src/main/java/com/google/spanner/v1/ListSessionsResponseOrBuilder.java index 19f27332c0b..9b7679883fc 100644 --- a/proto-google-cloud-spanner-v1/src/main/java/com/google/spanner/v1/ListSessionsResponseOrBuilder.java +++ b/proto-google-cloud-spanner-v1/src/main/java/com/google/spanner/v1/ListSessionsResponseOrBuilder.java @@ -1,5 +1,5 @@ /* - * Copyright 2023 Google LLC + * Copyright 2024 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/proto-google-cloud-spanner-v1/src/main/java/com/google/spanner/v1/Mutation.java b/proto-google-cloud-spanner-v1/src/main/java/com/google/spanner/v1/Mutation.java index 74825356015..45ec79dca78 100644 --- a/proto-google-cloud-spanner-v1/src/main/java/com/google/spanner/v1/Mutation.java +++ b/proto-google-cloud-spanner-v1/src/main/java/com/google/spanner/v1/Mutation.java @@ -1,5 +1,5 @@ /* - * Copyright 2023 Google LLC + * Copyright 2024 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/proto-google-cloud-spanner-v1/src/main/java/com/google/spanner/v1/MutationOrBuilder.java b/proto-google-cloud-spanner-v1/src/main/java/com/google/spanner/v1/MutationOrBuilder.java index 9f662719d55..70254ca757d 100644 --- a/proto-google-cloud-spanner-v1/src/main/java/com/google/spanner/v1/MutationOrBuilder.java +++ b/proto-google-cloud-spanner-v1/src/main/java/com/google/spanner/v1/MutationOrBuilder.java @@ -1,5 +1,5 @@ /* - * Copyright 2023 Google LLC + * Copyright 2024 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/proto-google-cloud-spanner-v1/src/main/java/com/google/spanner/v1/MutationProto.java b/proto-google-cloud-spanner-v1/src/main/java/com/google/spanner/v1/MutationProto.java index 8176ccbd8ad..947d33fa1ee 100644 --- a/proto-google-cloud-spanner-v1/src/main/java/com/google/spanner/v1/MutationProto.java +++ b/proto-google-cloud-spanner-v1/src/main/java/com/google/spanner/v1/MutationProto.java @@ -1,5 +1,5 @@ /* - * Copyright 2023 Google LLC + * Copyright 2024 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/proto-google-cloud-spanner-v1/src/main/java/com/google/spanner/v1/PartialResultSet.java b/proto-google-cloud-spanner-v1/src/main/java/com/google/spanner/v1/PartialResultSet.java index 7cc3aafbb4d..f54d024bc26 100644 --- a/proto-google-cloud-spanner-v1/src/main/java/com/google/spanner/v1/PartialResultSet.java +++ b/proto-google-cloud-spanner-v1/src/main/java/com/google/spanner/v1/PartialResultSet.java @@ -1,5 +1,5 @@ /* - * Copyright 2023 Google LLC + * Copyright 2024 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/proto-google-cloud-spanner-v1/src/main/java/com/google/spanner/v1/PartialResultSetOrBuilder.java b/proto-google-cloud-spanner-v1/src/main/java/com/google/spanner/v1/PartialResultSetOrBuilder.java index a81cfafe132..287a8fab009 100644 --- a/proto-google-cloud-spanner-v1/src/main/java/com/google/spanner/v1/PartialResultSetOrBuilder.java +++ b/proto-google-cloud-spanner-v1/src/main/java/com/google/spanner/v1/PartialResultSetOrBuilder.java @@ -1,5 +1,5 @@ /* - * Copyright 2023 Google LLC + * Copyright 2024 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/proto-google-cloud-spanner-v1/src/main/java/com/google/spanner/v1/Partition.java b/proto-google-cloud-spanner-v1/src/main/java/com/google/spanner/v1/Partition.java index f569b078cfb..74608dab6b0 100644 --- a/proto-google-cloud-spanner-v1/src/main/java/com/google/spanner/v1/Partition.java +++ b/proto-google-cloud-spanner-v1/src/main/java/com/google/spanner/v1/Partition.java @@ -1,5 +1,5 @@ /* - * Copyright 2023 Google LLC + * Copyright 2024 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/proto-google-cloud-spanner-v1/src/main/java/com/google/spanner/v1/PartitionOptions.java b/proto-google-cloud-spanner-v1/src/main/java/com/google/spanner/v1/PartitionOptions.java index 74cd83c3b58..6b7aeb4d577 100644 --- a/proto-google-cloud-spanner-v1/src/main/java/com/google/spanner/v1/PartitionOptions.java +++ b/proto-google-cloud-spanner-v1/src/main/java/com/google/spanner/v1/PartitionOptions.java @@ -1,5 +1,5 @@ /* - * Copyright 2023 Google LLC + * Copyright 2024 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/proto-google-cloud-spanner-v1/src/main/java/com/google/spanner/v1/PartitionOptionsOrBuilder.java b/proto-google-cloud-spanner-v1/src/main/java/com/google/spanner/v1/PartitionOptionsOrBuilder.java index 644c2542184..35e4d67c2df 100644 --- a/proto-google-cloud-spanner-v1/src/main/java/com/google/spanner/v1/PartitionOptionsOrBuilder.java +++ b/proto-google-cloud-spanner-v1/src/main/java/com/google/spanner/v1/PartitionOptionsOrBuilder.java @@ -1,5 +1,5 @@ /* - * Copyright 2023 Google LLC + * Copyright 2024 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/proto-google-cloud-spanner-v1/src/main/java/com/google/spanner/v1/PartitionOrBuilder.java b/proto-google-cloud-spanner-v1/src/main/java/com/google/spanner/v1/PartitionOrBuilder.java index 60daac111a6..be92636ee54 100644 --- a/proto-google-cloud-spanner-v1/src/main/java/com/google/spanner/v1/PartitionOrBuilder.java +++ b/proto-google-cloud-spanner-v1/src/main/java/com/google/spanner/v1/PartitionOrBuilder.java @@ -1,5 +1,5 @@ /* - * Copyright 2023 Google LLC + * Copyright 2024 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/proto-google-cloud-spanner-v1/src/main/java/com/google/spanner/v1/PartitionQueryRequest.java b/proto-google-cloud-spanner-v1/src/main/java/com/google/spanner/v1/PartitionQueryRequest.java index c07eebde669..3a78ca9046a 100644 --- a/proto-google-cloud-spanner-v1/src/main/java/com/google/spanner/v1/PartitionQueryRequest.java +++ b/proto-google-cloud-spanner-v1/src/main/java/com/google/spanner/v1/PartitionQueryRequest.java @@ -1,5 +1,5 @@ /* - * Copyright 2023 Google LLC + * Copyright 2024 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/proto-google-cloud-spanner-v1/src/main/java/com/google/spanner/v1/PartitionQueryRequestOrBuilder.java b/proto-google-cloud-spanner-v1/src/main/java/com/google/spanner/v1/PartitionQueryRequestOrBuilder.java index 5a0e5a44a1b..3f84655dc95 100644 --- a/proto-google-cloud-spanner-v1/src/main/java/com/google/spanner/v1/PartitionQueryRequestOrBuilder.java +++ b/proto-google-cloud-spanner-v1/src/main/java/com/google/spanner/v1/PartitionQueryRequestOrBuilder.java @@ -1,5 +1,5 @@ /* - * Copyright 2023 Google LLC + * Copyright 2024 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/proto-google-cloud-spanner-v1/src/main/java/com/google/spanner/v1/PartitionReadRequest.java b/proto-google-cloud-spanner-v1/src/main/java/com/google/spanner/v1/PartitionReadRequest.java index e43bc079369..06fbea7caf8 100644 --- a/proto-google-cloud-spanner-v1/src/main/java/com/google/spanner/v1/PartitionReadRequest.java +++ b/proto-google-cloud-spanner-v1/src/main/java/com/google/spanner/v1/PartitionReadRequest.java @@ -1,5 +1,5 @@ /* - * Copyright 2023 Google LLC + * Copyright 2024 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/proto-google-cloud-spanner-v1/src/main/java/com/google/spanner/v1/PartitionReadRequestOrBuilder.java b/proto-google-cloud-spanner-v1/src/main/java/com/google/spanner/v1/PartitionReadRequestOrBuilder.java index 64b9832eba3..dff07390bf3 100644 --- a/proto-google-cloud-spanner-v1/src/main/java/com/google/spanner/v1/PartitionReadRequestOrBuilder.java +++ b/proto-google-cloud-spanner-v1/src/main/java/com/google/spanner/v1/PartitionReadRequestOrBuilder.java @@ -1,5 +1,5 @@ /* - * Copyright 2023 Google LLC + * Copyright 2024 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/proto-google-cloud-spanner-v1/src/main/java/com/google/spanner/v1/PartitionResponse.java b/proto-google-cloud-spanner-v1/src/main/java/com/google/spanner/v1/PartitionResponse.java index bb7ef647d0d..fc4278dd616 100644 --- a/proto-google-cloud-spanner-v1/src/main/java/com/google/spanner/v1/PartitionResponse.java +++ b/proto-google-cloud-spanner-v1/src/main/java/com/google/spanner/v1/PartitionResponse.java @@ -1,5 +1,5 @@ /* - * Copyright 2023 Google LLC + * Copyright 2024 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/proto-google-cloud-spanner-v1/src/main/java/com/google/spanner/v1/PartitionResponseOrBuilder.java b/proto-google-cloud-spanner-v1/src/main/java/com/google/spanner/v1/PartitionResponseOrBuilder.java index 9af27927b29..2cfeba230ed 100644 --- a/proto-google-cloud-spanner-v1/src/main/java/com/google/spanner/v1/PartitionResponseOrBuilder.java +++ b/proto-google-cloud-spanner-v1/src/main/java/com/google/spanner/v1/PartitionResponseOrBuilder.java @@ -1,5 +1,5 @@ /* - * Copyright 2023 Google LLC + * Copyright 2024 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/proto-google-cloud-spanner-v1/src/main/java/com/google/spanner/v1/PlanNode.java b/proto-google-cloud-spanner-v1/src/main/java/com/google/spanner/v1/PlanNode.java index 0db01a2bacb..708d2a74021 100644 --- a/proto-google-cloud-spanner-v1/src/main/java/com/google/spanner/v1/PlanNode.java +++ b/proto-google-cloud-spanner-v1/src/main/java/com/google/spanner/v1/PlanNode.java @@ -1,5 +1,5 @@ /* - * Copyright 2023 Google LLC + * Copyright 2024 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/proto-google-cloud-spanner-v1/src/main/java/com/google/spanner/v1/PlanNodeOrBuilder.java b/proto-google-cloud-spanner-v1/src/main/java/com/google/spanner/v1/PlanNodeOrBuilder.java index 073eb24077e..7a0521e5013 100644 --- a/proto-google-cloud-spanner-v1/src/main/java/com/google/spanner/v1/PlanNodeOrBuilder.java +++ b/proto-google-cloud-spanner-v1/src/main/java/com/google/spanner/v1/PlanNodeOrBuilder.java @@ -1,5 +1,5 @@ /* - * Copyright 2023 Google LLC + * Copyright 2024 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/proto-google-cloud-spanner-v1/src/main/java/com/google/spanner/v1/QueryPlan.java b/proto-google-cloud-spanner-v1/src/main/java/com/google/spanner/v1/QueryPlan.java index 0738552475f..3a32a15d36c 100644 --- a/proto-google-cloud-spanner-v1/src/main/java/com/google/spanner/v1/QueryPlan.java +++ b/proto-google-cloud-spanner-v1/src/main/java/com/google/spanner/v1/QueryPlan.java @@ -1,5 +1,5 @@ /* - * Copyright 2023 Google LLC + * Copyright 2024 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/proto-google-cloud-spanner-v1/src/main/java/com/google/spanner/v1/QueryPlanOrBuilder.java b/proto-google-cloud-spanner-v1/src/main/java/com/google/spanner/v1/QueryPlanOrBuilder.java index 3f0567d3375..29ddb7fbbc1 100644 --- a/proto-google-cloud-spanner-v1/src/main/java/com/google/spanner/v1/QueryPlanOrBuilder.java +++ b/proto-google-cloud-spanner-v1/src/main/java/com/google/spanner/v1/QueryPlanOrBuilder.java @@ -1,5 +1,5 @@ /* - * Copyright 2023 Google LLC + * Copyright 2024 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/proto-google-cloud-spanner-v1/src/main/java/com/google/spanner/v1/QueryPlanProto.java b/proto-google-cloud-spanner-v1/src/main/java/com/google/spanner/v1/QueryPlanProto.java index 863a047faa2..26cd4907b55 100644 --- a/proto-google-cloud-spanner-v1/src/main/java/com/google/spanner/v1/QueryPlanProto.java +++ b/proto-google-cloud-spanner-v1/src/main/java/com/google/spanner/v1/QueryPlanProto.java @@ -1,5 +1,5 @@ /* - * Copyright 2023 Google LLC + * Copyright 2024 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/proto-google-cloud-spanner-v1/src/main/java/com/google/spanner/v1/ReadRequest.java b/proto-google-cloud-spanner-v1/src/main/java/com/google/spanner/v1/ReadRequest.java index f367b772f22..d063b3f5338 100644 --- a/proto-google-cloud-spanner-v1/src/main/java/com/google/spanner/v1/ReadRequest.java +++ b/proto-google-cloud-spanner-v1/src/main/java/com/google/spanner/v1/ReadRequest.java @@ -1,5 +1,5 @@ /* - * Copyright 2023 Google LLC + * Copyright 2024 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/proto-google-cloud-spanner-v1/src/main/java/com/google/spanner/v1/ReadRequestOrBuilder.java b/proto-google-cloud-spanner-v1/src/main/java/com/google/spanner/v1/ReadRequestOrBuilder.java index 88b1db505b7..9954ab1d609 100644 --- a/proto-google-cloud-spanner-v1/src/main/java/com/google/spanner/v1/ReadRequestOrBuilder.java +++ b/proto-google-cloud-spanner-v1/src/main/java/com/google/spanner/v1/ReadRequestOrBuilder.java @@ -1,5 +1,5 @@ /* - * Copyright 2023 Google LLC + * Copyright 2024 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/proto-google-cloud-spanner-v1/src/main/java/com/google/spanner/v1/RequestOptions.java b/proto-google-cloud-spanner-v1/src/main/java/com/google/spanner/v1/RequestOptions.java index 46bdfe3297b..fe57a86722c 100644 --- a/proto-google-cloud-spanner-v1/src/main/java/com/google/spanner/v1/RequestOptions.java +++ b/proto-google-cloud-spanner-v1/src/main/java/com/google/spanner/v1/RequestOptions.java @@ -1,5 +1,5 @@ /* - * Copyright 2023 Google LLC + * Copyright 2024 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/proto-google-cloud-spanner-v1/src/main/java/com/google/spanner/v1/RequestOptionsOrBuilder.java b/proto-google-cloud-spanner-v1/src/main/java/com/google/spanner/v1/RequestOptionsOrBuilder.java index 399b1a3b2ee..d7a64132f90 100644 --- a/proto-google-cloud-spanner-v1/src/main/java/com/google/spanner/v1/RequestOptionsOrBuilder.java +++ b/proto-google-cloud-spanner-v1/src/main/java/com/google/spanner/v1/RequestOptionsOrBuilder.java @@ -1,5 +1,5 @@ /* - * Copyright 2023 Google LLC + * Copyright 2024 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/proto-google-cloud-spanner-v1/src/main/java/com/google/spanner/v1/ResultSet.java b/proto-google-cloud-spanner-v1/src/main/java/com/google/spanner/v1/ResultSet.java index 9fe21bb3fc8..01a9a629734 100644 --- a/proto-google-cloud-spanner-v1/src/main/java/com/google/spanner/v1/ResultSet.java +++ b/proto-google-cloud-spanner-v1/src/main/java/com/google/spanner/v1/ResultSet.java @@ -1,5 +1,5 @@ /* - * Copyright 2023 Google LLC + * Copyright 2024 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/proto-google-cloud-spanner-v1/src/main/java/com/google/spanner/v1/ResultSetMetadata.java b/proto-google-cloud-spanner-v1/src/main/java/com/google/spanner/v1/ResultSetMetadata.java index 704acc2d543..6351c1a5a64 100644 --- a/proto-google-cloud-spanner-v1/src/main/java/com/google/spanner/v1/ResultSetMetadata.java +++ b/proto-google-cloud-spanner-v1/src/main/java/com/google/spanner/v1/ResultSetMetadata.java @@ -1,5 +1,5 @@ /* - * Copyright 2023 Google LLC + * Copyright 2024 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/proto-google-cloud-spanner-v1/src/main/java/com/google/spanner/v1/ResultSetMetadataOrBuilder.java b/proto-google-cloud-spanner-v1/src/main/java/com/google/spanner/v1/ResultSetMetadataOrBuilder.java index f78edce7a6d..d8c5f239c77 100644 --- a/proto-google-cloud-spanner-v1/src/main/java/com/google/spanner/v1/ResultSetMetadataOrBuilder.java +++ b/proto-google-cloud-spanner-v1/src/main/java/com/google/spanner/v1/ResultSetMetadataOrBuilder.java @@ -1,5 +1,5 @@ /* - * Copyright 2023 Google LLC + * Copyright 2024 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/proto-google-cloud-spanner-v1/src/main/java/com/google/spanner/v1/ResultSetOrBuilder.java b/proto-google-cloud-spanner-v1/src/main/java/com/google/spanner/v1/ResultSetOrBuilder.java index 4e01eda0560..fdff9180d1b 100644 --- a/proto-google-cloud-spanner-v1/src/main/java/com/google/spanner/v1/ResultSetOrBuilder.java +++ b/proto-google-cloud-spanner-v1/src/main/java/com/google/spanner/v1/ResultSetOrBuilder.java @@ -1,5 +1,5 @@ /* - * Copyright 2023 Google LLC + * Copyright 2024 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/proto-google-cloud-spanner-v1/src/main/java/com/google/spanner/v1/ResultSetProto.java b/proto-google-cloud-spanner-v1/src/main/java/com/google/spanner/v1/ResultSetProto.java index 5c3bbe434fc..8502d336ef9 100644 --- a/proto-google-cloud-spanner-v1/src/main/java/com/google/spanner/v1/ResultSetProto.java +++ b/proto-google-cloud-spanner-v1/src/main/java/com/google/spanner/v1/ResultSetProto.java @@ -1,5 +1,5 @@ /* - * Copyright 2023 Google LLC + * Copyright 2024 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/proto-google-cloud-spanner-v1/src/main/java/com/google/spanner/v1/ResultSetStats.java b/proto-google-cloud-spanner-v1/src/main/java/com/google/spanner/v1/ResultSetStats.java index acd90adc55d..80a08682ca9 100644 --- a/proto-google-cloud-spanner-v1/src/main/java/com/google/spanner/v1/ResultSetStats.java +++ b/proto-google-cloud-spanner-v1/src/main/java/com/google/spanner/v1/ResultSetStats.java @@ -1,5 +1,5 @@ /* - * Copyright 2023 Google LLC + * Copyright 2024 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/proto-google-cloud-spanner-v1/src/main/java/com/google/spanner/v1/ResultSetStatsOrBuilder.java b/proto-google-cloud-spanner-v1/src/main/java/com/google/spanner/v1/ResultSetStatsOrBuilder.java index 2cc3b8e2fbc..04d371b2e3c 100644 --- a/proto-google-cloud-spanner-v1/src/main/java/com/google/spanner/v1/ResultSetStatsOrBuilder.java +++ b/proto-google-cloud-spanner-v1/src/main/java/com/google/spanner/v1/ResultSetStatsOrBuilder.java @@ -1,5 +1,5 @@ /* - * Copyright 2023 Google LLC + * Copyright 2024 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/proto-google-cloud-spanner-v1/src/main/java/com/google/spanner/v1/RollbackRequest.java b/proto-google-cloud-spanner-v1/src/main/java/com/google/spanner/v1/RollbackRequest.java index 2d4647ff4d2..7e1dee1e6e5 100644 --- a/proto-google-cloud-spanner-v1/src/main/java/com/google/spanner/v1/RollbackRequest.java +++ b/proto-google-cloud-spanner-v1/src/main/java/com/google/spanner/v1/RollbackRequest.java @@ -1,5 +1,5 @@ /* - * Copyright 2023 Google LLC + * Copyright 2024 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/proto-google-cloud-spanner-v1/src/main/java/com/google/spanner/v1/RollbackRequestOrBuilder.java b/proto-google-cloud-spanner-v1/src/main/java/com/google/spanner/v1/RollbackRequestOrBuilder.java index 441b691f1f0..980880ba996 100644 --- a/proto-google-cloud-spanner-v1/src/main/java/com/google/spanner/v1/RollbackRequestOrBuilder.java +++ b/proto-google-cloud-spanner-v1/src/main/java/com/google/spanner/v1/RollbackRequestOrBuilder.java @@ -1,5 +1,5 @@ /* - * Copyright 2023 Google LLC + * Copyright 2024 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/proto-google-cloud-spanner-v1/src/main/java/com/google/spanner/v1/Session.java b/proto-google-cloud-spanner-v1/src/main/java/com/google/spanner/v1/Session.java index 8b7eab15c65..1479dcb5d1f 100644 --- a/proto-google-cloud-spanner-v1/src/main/java/com/google/spanner/v1/Session.java +++ b/proto-google-cloud-spanner-v1/src/main/java/com/google/spanner/v1/Session.java @@ -1,5 +1,5 @@ /* - * Copyright 2023 Google LLC + * Copyright 2024 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/proto-google-cloud-spanner-v1/src/main/java/com/google/spanner/v1/SessionOrBuilder.java b/proto-google-cloud-spanner-v1/src/main/java/com/google/spanner/v1/SessionOrBuilder.java index 6df98f7ebef..016b6aeb71a 100644 --- a/proto-google-cloud-spanner-v1/src/main/java/com/google/spanner/v1/SessionOrBuilder.java +++ b/proto-google-cloud-spanner-v1/src/main/java/com/google/spanner/v1/SessionOrBuilder.java @@ -1,5 +1,5 @@ /* - * Copyright 2023 Google LLC + * Copyright 2024 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/proto-google-cloud-spanner-v1/src/main/java/com/google/spanner/v1/SpannerProto.java b/proto-google-cloud-spanner-v1/src/main/java/com/google/spanner/v1/SpannerProto.java index 37a423159ae..a70082261b4 100644 --- a/proto-google-cloud-spanner-v1/src/main/java/com/google/spanner/v1/SpannerProto.java +++ b/proto-google-cloud-spanner-v1/src/main/java/com/google/spanner/v1/SpannerProto.java @@ -1,5 +1,5 @@ /* - * Copyright 2023 Google LLC + * Copyright 2024 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -177,249 +177,251 @@ public static com.google.protobuf.Descriptors.FileDescriptor getDescriptor() { + "esponse.proto\032\034google/api/annotations.pr" + "oto\032\027google/api/client.proto\032\037google/api" + "/field_behavior.proto\032\031google/api/resour" - + "ce.proto\032\033google/protobuf/empty.proto\032\034g" - + "oogle/protobuf/struct.proto\032\037google/prot" - + "obuf/timestamp.proto\032\027google/rpc/status." - + "proto\032\034google/spanner/v1/keys.proto\032 goo" - + "gle/spanner/v1/mutation.proto\032\"google/sp" - + "anner/v1/result_set.proto\032#google/spanne" - + "r/v1/transaction.proto\032\034google/spanner/v" - + "1/type.proto\"\205\001\n\024CreateSessionRequest\022:\n" - + "\010database\030\001 \001(\tB(\342A\001\002\372A!\n\037spanner.google" - + "apis.com/Database\0221\n\007session\030\002 \001(\0132\032.goo" - + "gle.spanner.v1.SessionB\004\342A\001\002\"\253\001\n\032BatchCr" - + "eateSessionsRequest\022:\n\010database\030\001 \001(\tB(\342" - + "A\001\002\372A!\n\037spanner.googleapis.com/Database\022" - + "4\n\020session_template\030\002 \001(\0132\032.google.spann" - + "er.v1.Session\022\033\n\rsession_count\030\003 \001(\005B\004\342A" - + "\001\002\"J\n\033BatchCreateSessionsResponse\022+\n\007ses" - + "sion\030\001 \003(\0132\032.google.spanner.v1.Session\"\214" - + "\003\n\007Session\022\022\n\004name\030\001 \001(\tB\004\342A\001\003\0226\n\006labels" - + "\030\002 \003(\0132&.google.spanner.v1.Session.Label" - + "sEntry\0225\n\013create_time\030\003 \001(\0132\032.google.pro" - + "tobuf.TimestampB\004\342A\001\003\022C\n\031approximate_las" - + "t_use_time\030\004 \001(\0132\032.google.protobuf.Times" - + "tampB\004\342A\001\003\022\024\n\014creator_role\030\005 \001(\t\032-\n\013Labe" - + "lsEntry\022\013\n\003key\030\001 \001(\t\022\r\n\005value\030\002 \001(\t:\0028\001:" - + "t\352Aq\n\036spanner.googleapis.com/Session\022Opr" - + "ojects/{project}/instances/{instance}/da" - + "tabases/{database}/sessions/{session}\"J\n" - + "\021GetSessionRequest\0225\n\004name\030\001 \001(\tB\'\342A\001\002\372A" - + " \n\036spanner.googleapis.com/Session\"\210\001\n\023Li" - + "stSessionsRequest\022:\n\010database\030\001 \001(\tB(\342A\001" - + "\002\372A!\n\037spanner.googleapis.com/Database\022\021\n" - + "\tpage_size\030\002 \001(\005\022\022\n\npage_token\030\003 \001(\t\022\016\n\006" - + "filter\030\004 \001(\t\"]\n\024ListSessionsResponse\022,\n\010" - + "sessions\030\001 \003(\0132\032.google.spanner.v1.Sessi" - + "on\022\027\n\017next_page_token\030\002 \001(\t\"M\n\024DeleteSes" - + "sionRequest\0225\n\004name\030\001 \001(\tB\'\342A\001\002\372A \n\036span" - + "ner.googleapis.com/Session\"\334\001\n\016RequestOp" - + "tions\022<\n\010priority\030\001 \001(\0162*.google.spanner" - + ".v1.RequestOptions.Priority\022\023\n\013request_t" - + "ag\030\002 \001(\t\022\027\n\017transaction_tag\030\003 \001(\t\"^\n\010Pri" - + "ority\022\030\n\024PRIORITY_UNSPECIFIED\020\000\022\020\n\014PRIOR" - + "ITY_LOW\020\001\022\023\n\017PRIORITY_MEDIUM\020\002\022\021\n\rPRIORI" - + "TY_HIGH\020\003\"\352\004\n\023DirectedReadOptions\022R\n\020inc" - + "lude_replicas\030\001 \001(\01326.google.spanner.v1." - + "DirectedReadOptions.IncludeReplicasH\000\022R\n" - + "\020exclude_replicas\030\002 \001(\01326.google.spanner" - + ".v1.DirectedReadOptions.ExcludeReplicasH" - + "\000\032\255\001\n\020ReplicaSelection\022\020\n\010location\030\001 \001(\t" - + "\022J\n\004type\030\002 \001(\0162<.google.spanner.v1.Direc" - + "tedReadOptions.ReplicaSelection.Type\";\n\004" - + "Type\022\024\n\020TYPE_UNSPECIFIED\020\000\022\016\n\nREAD_WRITE" - + "\020\001\022\r\n\tREAD_ONLY\020\002\032\206\001\n\017IncludeReplicas\022S\n" - + "\022replica_selections\030\001 \003(\01327.google.spann" - + "er.v1.DirectedReadOptions.ReplicaSelecti" - + "on\022\036\n\026auto_failover_disabled\030\002 \001(\010\032f\n\017Ex" - + "cludeReplicas\022S\n\022replica_selections\030\001 \003(" - + "\01327.google.spanner.v1.DirectedReadOption" - + "s.ReplicaSelectionB\n\n\010replicas\"\311\006\n\021Execu" - + "teSqlRequest\0228\n\007session\030\001 \001(\tB\'\342A\001\002\372A \n\036" - + "spanner.googleapis.com/Session\022;\n\013transa" - + "ction\030\002 \001(\0132&.google.spanner.v1.Transact" - + "ionSelector\022\021\n\003sql\030\003 \001(\tB\004\342A\001\002\022\'\n\006params" - + "\030\004 \001(\0132\027.google.protobuf.Struct\022I\n\013param" - + "_types\030\005 \003(\01324.google.spanner.v1.Execute" - + "SqlRequest.ParamTypesEntry\022\024\n\014resume_tok" - + "en\030\006 \001(\014\022B\n\nquery_mode\030\007 \001(\0162..google.sp" - + "anner.v1.ExecuteSqlRequest.QueryMode\022\027\n\017" - + "partition_token\030\010 \001(\014\022\r\n\005seqno\030\t \001(\003\022H\n\r" - + "query_options\030\n \001(\01321.google.spanner.v1." - + "ExecuteSqlRequest.QueryOptions\022:\n\017reques" - + "t_options\030\013 \001(\0132!.google.spanner.v1.Requ" - + "estOptions\022E\n\025directed_read_options\030\017 \001(" - + "\0132&.google.spanner.v1.DirectedReadOption" - + "s\022\032\n\022data_boost_enabled\030\020 \001(\010\032O\n\014QueryOp" - + "tions\022\031\n\021optimizer_version\030\001 \001(\t\022$\n\034opti" - + "mizer_statistics_package\030\002 \001(\t\032J\n\017ParamT" - + "ypesEntry\022\013\n\003key\030\001 \001(\t\022&\n\005value\030\002 \001(\0132\027." - + "google.spanner.v1.Type:\0028\001\".\n\tQueryMode\022" - + "\n\n\006NORMAL\020\000\022\010\n\004PLAN\020\001\022\013\n\007PROFILE\020\002\"\245\004\n\026E" - + "xecuteBatchDmlRequest\0228\n\007session\030\001 \001(\tB\'" - + "\342A\001\002\372A \n\036spanner.googleapis.com/Session\022" - + "A\n\013transaction\030\002 \001(\0132&.google.spanner.v1" - + ".TransactionSelectorB\004\342A\001\002\022M\n\nstatements" - + "\030\003 \003(\01323.google.spanner.v1.ExecuteBatchD" - + "mlRequest.StatementB\004\342A\001\002\022\023\n\005seqno\030\004 \001(\003" - + "B\004\342A\001\002\022:\n\017request_options\030\005 \001(\0132!.google" - + ".spanner.v1.RequestOptions\032\355\001\n\tStatement" - + "\022\021\n\003sql\030\001 \001(\tB\004\342A\001\002\022\'\n\006params\030\002 \001(\0132\027.go" - + "ogle.protobuf.Struct\022X\n\013param_types\030\003 \003(" - + "\0132C.google.spanner.v1.ExecuteBatchDmlReq" - + "uest.Statement.ParamTypesEntry\032J\n\017ParamT" - + "ypesEntry\022\013\n\003key\030\001 \001(\t\022&\n\005value\030\002 \001(\0132\027." - + "google.spanner.v1.Type:\0028\001\"p\n\027ExecuteBat" - + "chDmlResponse\0221\n\013result_sets\030\001 \003(\0132\034.goo" - + "gle.spanner.v1.ResultSet\022\"\n\006status\030\002 \001(\013" - + "2\022.google.rpc.Status\"H\n\020PartitionOptions" - + "\022\034\n\024partition_size_bytes\030\001 \001(\003\022\026\n\016max_pa" - + "rtitions\030\002 \001(\003\"\245\003\n\025PartitionQueryRequest" - + "\0228\n\007session\030\001 \001(\tB\'\342A\001\002\372A \n\036spanner.goog" - + "leapis.com/Session\022;\n\013transaction\030\002 \001(\0132" - + "&.google.spanner.v1.TransactionSelector\022" - + "\021\n\003sql\030\003 \001(\tB\004\342A\001\002\022\'\n\006params\030\004 \001(\0132\027.goo" - + "gle.protobuf.Struct\022M\n\013param_types\030\005 \003(\013" - + "28.google.spanner.v1.PartitionQueryReque" - + "st.ParamTypesEntry\022>\n\021partition_options\030" - + "\006 \001(\0132#.google.spanner.v1.PartitionOptio" - + "ns\032J\n\017ParamTypesEntry\022\013\n\003key\030\001 \001(\t\022&\n\005va" - + "lue\030\002 \001(\0132\027.google.spanner.v1.Type:\0028\001\"\264" - + "\002\n\024PartitionReadRequest\0228\n\007session\030\001 \001(\t" - + "B\'\342A\001\002\372A \n\036spanner.googleapis.com/Sessio" - + "n\022;\n\013transaction\030\002 \001(\0132&.google.spanner." - + "v1.TransactionSelector\022\023\n\005table\030\003 \001(\tB\004\342" - + "A\001\002\022\r\n\005index\030\004 \001(\t\022\017\n\007columns\030\005 \003(\t\0220\n\007k" - + "ey_set\030\006 \001(\0132\031.google.spanner.v1.KeySetB" - + "\004\342A\001\002\022>\n\021partition_options\030\t \001(\0132#.googl" - + "e.spanner.v1.PartitionOptions\"$\n\tPartiti" - + "on\022\027\n\017partition_token\030\001 \001(\014\"z\n\021Partition" - + "Response\0220\n\npartitions\030\001 \003(\0132\034.google.sp" - + "anner.v1.Partition\0223\n\013transaction\030\002 \001(\0132" - + "\036.google.spanner.v1.Transaction\"\316\003\n\013Read" - + "Request\0228\n\007session\030\001 \001(\tB\'\342A\001\002\372A \n\036spann" - + "er.googleapis.com/Session\022;\n\013transaction" - + "\030\002 \001(\0132&.google.spanner.v1.TransactionSe" - + "lector\022\023\n\005table\030\003 \001(\tB\004\342A\001\002\022\r\n\005index\030\004 \001" - + "(\t\022\025\n\007columns\030\005 \003(\tB\004\342A\001\002\0220\n\007key_set\030\006 \001" - + "(\0132\031.google.spanner.v1.KeySetB\004\342A\001\002\022\r\n\005l" - + "imit\030\010 \001(\003\022\024\n\014resume_token\030\t \001(\014\022\027\n\017part" - + "ition_token\030\n \001(\014\022:\n\017request_options\030\013 \001" - + "(\0132!.google.spanner.v1.RequestOptions\022E\n" - + "\025directed_read_options\030\016 \001(\0132&.google.sp" - + "anner.v1.DirectedReadOptions\022\032\n\022data_boo" - + "st_enabled\030\017 \001(\010\"\315\001\n\027BeginTransactionReq" + + "ce.proto\032\036google/protobuf/duration.proto" + + "\032\033google/protobuf/empty.proto\032\034google/pr" + + "otobuf/struct.proto\032\037google/protobuf/tim" + + "estamp.proto\032\027google/rpc/status.proto\032\034g" + + "oogle/spanner/v1/keys.proto\032 google/span" + + "ner/v1/mutation.proto\032\"google/spanner/v1" + + "/result_set.proto\032#google/spanner/v1/tra" + + "nsaction.proto\032\034google/spanner/v1/type.p" + + "roto\"\205\001\n\024CreateSessionRequest\022:\n\010databas" + + "e\030\001 \001(\tB(\342A\001\002\372A!\n\037spanner.googleapis.com" + + "/Database\0221\n\007session\030\002 \001(\0132\032.google.span" + + "ner.v1.SessionB\004\342A\001\002\"\253\001\n\032BatchCreateSess" + + "ionsRequest\022:\n\010database\030\001 \001(\tB(\342A\001\002\372A!\n\037" + + "spanner.googleapis.com/Database\0224\n\020sessi" + + "on_template\030\002 \001(\0132\032.google.spanner.v1.Se" + + "ssion\022\033\n\rsession_count\030\003 \001(\005B\004\342A\001\002\"J\n\033Ba" + + "tchCreateSessionsResponse\022+\n\007session\030\001 \003" + + "(\0132\032.google.spanner.v1.Session\"\214\003\n\007Sessi" + + "on\022\022\n\004name\030\001 \001(\tB\004\342A\001\003\0226\n\006labels\030\002 \003(\0132&" + + ".google.spanner.v1.Session.LabelsEntry\0225" + + "\n\013create_time\030\003 \001(\0132\032.google.protobuf.Ti" + + "mestampB\004\342A\001\003\022C\n\031approximate_last_use_ti" + + "me\030\004 \001(\0132\032.google.protobuf.TimestampB\004\342A" + + "\001\003\022\024\n\014creator_role\030\005 \001(\t\032-\n\013LabelsEntry\022" + + "\013\n\003key\030\001 \001(\t\022\r\n\005value\030\002 \001(\t:\0028\001:t\352Aq\n\036sp" + + "anner.googleapis.com/Session\022Oprojects/{" + + "project}/instances/{instance}/databases/" + + "{database}/sessions/{session}\"J\n\021GetSess" + + "ionRequest\0225\n\004name\030\001 \001(\tB\'\342A\001\002\372A \n\036spann" + + "er.googleapis.com/Session\"\210\001\n\023ListSessio" + + "nsRequest\022:\n\010database\030\001 \001(\tB(\342A\001\002\372A!\n\037sp" + + "anner.googleapis.com/Database\022\021\n\tpage_si" + + "ze\030\002 \001(\005\022\022\n\npage_token\030\003 \001(\t\022\016\n\006filter\030\004" + + " \001(\t\"]\n\024ListSessionsResponse\022,\n\010sessions" + + "\030\001 \003(\0132\032.google.spanner.v1.Session\022\027\n\017ne" + + "xt_page_token\030\002 \001(\t\"M\n\024DeleteSessionRequ" + + "est\0225\n\004name\030\001 \001(\tB\'\342A\001\002\372A \n\036spanner.goog" + + "leapis.com/Session\"\334\001\n\016RequestOptions\022<\n" + + "\010priority\030\001 \001(\0162*.google.spanner.v1.Requ" + + "estOptions.Priority\022\023\n\013request_tag\030\002 \001(\t" + + "\022\027\n\017transaction_tag\030\003 \001(\t\"^\n\010Priority\022\030\n" + + "\024PRIORITY_UNSPECIFIED\020\000\022\020\n\014PRIORITY_LOW\020" + + "\001\022\023\n\017PRIORITY_MEDIUM\020\002\022\021\n\rPRIORITY_HIGH\020" + + "\003\"\352\004\n\023DirectedReadOptions\022R\n\020include_rep" + + "licas\030\001 \001(\01326.google.spanner.v1.Directed" + + "ReadOptions.IncludeReplicasH\000\022R\n\020exclude" + + "_replicas\030\002 \001(\01326.google.spanner.v1.Dire" + + "ctedReadOptions.ExcludeReplicasH\000\032\255\001\n\020Re" + + "plicaSelection\022\020\n\010location\030\001 \001(\t\022J\n\004type" + + "\030\002 \001(\0162<.google.spanner.v1.DirectedReadO" + + "ptions.ReplicaSelection.Type\";\n\004Type\022\024\n\020" + + "TYPE_UNSPECIFIED\020\000\022\016\n\nREAD_WRITE\020\001\022\r\n\tRE" + + "AD_ONLY\020\002\032\206\001\n\017IncludeReplicas\022S\n\022replica" + + "_selections\030\001 \003(\01327.google.spanner.v1.Di" + + "rectedReadOptions.ReplicaSelection\022\036\n\026au" + + "to_failover_disabled\030\002 \001(\010\032f\n\017ExcludeRep" + + "licas\022S\n\022replica_selections\030\001 \003(\01327.goog" + + "le.spanner.v1.DirectedReadOptions.Replic" + + "aSelectionB\n\n\010replicas\"\311\006\n\021ExecuteSqlReq" + "uest\0228\n\007session\030\001 \001(\tB\'\342A\001\002\372A \n\036spanner." - + "googleapis.com/Session\022<\n\007options\030\002 \001(\0132" - + "%.google.spanner.v1.TransactionOptionsB\004" - + "\342A\001\002\022:\n\017request_options\030\003 \001(\0132!.google.s" - + "panner.v1.RequestOptions\"\304\002\n\rCommitReque" - + "st\0228\n\007session\030\001 \001(\tB\'\342A\001\002\372A \n\036spanner.go" - + "ogleapis.com/Session\022\030\n\016transaction_id\030\002" - + " \001(\014H\000\022G\n\026single_use_transaction\030\003 \001(\0132%" - + ".google.spanner.v1.TransactionOptionsH\000\022" - + ".\n\tmutations\030\004 \003(\0132\033.google.spanner.v1.M" - + "utation\022\033\n\023return_commit_stats\030\005 \001(\010\022:\n\017" - + "request_options\030\006 \001(\0132!.google.spanner.v" - + "1.RequestOptionsB\r\n\013transaction\"i\n\017Rollb" - + "ackRequest\0228\n\007session\030\001 \001(\tB\'\342A\001\002\372A \n\036sp" - + "anner.googleapis.com/Session\022\034\n\016transact" - + "ion_id\030\002 \001(\014B\004\342A\001\002\"\243\002\n\021BatchWriteRequest" - + "\0228\n\007session\030\001 \001(\tB\'\342A\001\002\372A \n\036spanner.goog" - + "leapis.com/Session\022:\n\017request_options\030\003 " - + "\001(\0132!.google.spanner.v1.RequestOptions\022Q" - + "\n\017mutation_groups\030\004 \003(\01322.google.spanner" - + ".v1.BatchWriteRequest.MutationGroupB\004\342A\001" - + "\002\032E\n\rMutationGroup\0224\n\tmutations\030\001 \003(\0132\033." - + "google.spanner.v1.MutationB\004\342A\001\002\"\177\n\022Batc" - + "hWriteResponse\022\017\n\007indexes\030\001 \003(\005\022\"\n\006statu" - + "s\030\002 \001(\0132\022.google.rpc.Status\0224\n\020commit_ti" - + "mestamp\030\003 \001(\0132\032.google.protobuf.Timestam" - + "p2\213\030\n\007Spanner\022\246\001\n\rCreateSession\022\'.google" - + ".spanner.v1.CreateSessionRequest\032\032.googl" - + "e.spanner.v1.Session\"P\332A\010database\202\323\344\223\002?\"" - + ":/v1/{database=projects/*/instances/*/da" - + "tabases/*}/sessions:\001*\022\340\001\n\023BatchCreateSe" - + "ssions\022-.google.spanner.v1.BatchCreateSe" - + "ssionsRequest\032..google.spanner.v1.BatchC" - + "reateSessionsResponse\"j\332A\026database,sessi" - + "on_count\202\323\344\223\002K\"F/v1/{database=projects/*" - + "/instances/*/databases/*}/sessions:batch" - + "Create:\001*\022\227\001\n\nGetSession\022$.google.spanne" - + "r.v1.GetSessionRequest\032\032.google.spanner." - + "v1.Session\"G\332A\004name\202\323\344\223\002:\0228/v1/{name=pro" - + "jects/*/instances/*/databases/*/sessions" - + "/*}\022\256\001\n\014ListSessions\022&.google.spanner.v1" - + ".ListSessionsRequest\032\'.google.spanner.v1" - + ".ListSessionsResponse\"M\332A\010database\202\323\344\223\002<" - + "\022:/v1/{database=projects/*/instances/*/d" - + "atabases/*}/sessions\022\231\001\n\rDeleteSession\022\'" - + ".google.spanner.v1.DeleteSessionRequest\032" - + "\026.google.protobuf.Empty\"G\332A\004name\202\323\344\223\002:*8" - + "/v1/{name=projects/*/instances/*/databas" - + "es/*/sessions/*}\022\243\001\n\nExecuteSql\022$.google" - + ".spanner.v1.ExecuteSqlRequest\032\034.google.s" - + "panner.v1.ResultSet\"Q\202\323\344\223\002K\"F/v1/{sessio" - + "n=projects/*/instances/*/databases/*/ses" - + "sions/*}:executeSql:\001*\022\276\001\n\023ExecuteStream" - + "ingSql\022$.google.spanner.v1.ExecuteSqlReq" - + "uest\032#.google.spanner.v1.PartialResultSe" - + "t\"Z\202\323\344\223\002T\"O/v1/{session=projects/*/insta" - + "nces/*/databases/*/sessions/*}:executeSt" - + "reamingSql:\001*0\001\022\300\001\n\017ExecuteBatchDml\022).go" - + "ogle.spanner.v1.ExecuteBatchDmlRequest\032*" - + ".google.spanner.v1.ExecuteBatchDmlRespon" - + "se\"V\202\323\344\223\002P\"K/v1/{session=projects/*/inst" - + "ances/*/databases/*/sessions/*}:executeB" - + "atchDml:\001*\022\221\001\n\004Read\022\036.google.spanner.v1." - + "ReadRequest\032\034.google.spanner.v1.ResultSe" - + "t\"K\202\323\344\223\002E\"@/v1/{session=projects/*/insta" - + "nces/*/databases/*/sessions/*}:read:\001*\022\254" - + "\001\n\rStreamingRead\022\036.google.spanner.v1.Rea" - + "dRequest\032#.google.spanner.v1.PartialResu" - + "ltSet\"T\202\323\344\223\002N\"I/v1/{session=projects/*/i" - + "nstances/*/databases/*/sessions/*}:strea" - + "mingRead:\001*0\001\022\311\001\n\020BeginTransaction\022*.goo" - + "gle.spanner.v1.BeginTransactionRequest\032\036" - + ".google.spanner.v1.Transaction\"i\332A\017sessi" - + "on,options\202\323\344\223\002Q\"L/v1/{session=projects/" - + "*/instances/*/databases/*/sessions/*}:be" - + "ginTransaction:\001*\022\353\001\n\006Commit\022 .google.sp" - + "anner.v1.CommitRequest\032!.google.spanner." - + "v1.CommitResponse\"\233\001\332A session,transacti" - + "on_id,mutations\332A(session,single_use_tra" - + "nsaction,mutations\202\323\344\223\002G\"B/v1/{session=p" - + "rojects/*/instances/*/databases/*/sessio" - + "ns/*}:commit:\001*\022\260\001\n\010Rollback\022\".google.sp" - + "anner.v1.RollbackRequest\032\026.google.protob" - + "uf.Empty\"h\332A\026session,transaction_id\202\323\344\223\002" - + "I\"D/v1/{session=projects/*/instances/*/d" - + "atabases/*/sessions/*}:rollback:\001*\022\267\001\n\016P" - + "artitionQuery\022(.google.spanner.v1.Partit" - + "ionQueryRequest\032$.google.spanner.v1.Part" - + "itionResponse\"U\202\323\344\223\002O\"J/v1/{session=proj" + + "googleapis.com/Session\022;\n\013transaction\030\002 " + + "\001(\0132&.google.spanner.v1.TransactionSelec" + + "tor\022\021\n\003sql\030\003 \001(\tB\004\342A\001\002\022\'\n\006params\030\004 \001(\0132\027" + + ".google.protobuf.Struct\022I\n\013param_types\030\005" + + " \003(\01324.google.spanner.v1.ExecuteSqlReque" + + "st.ParamTypesEntry\022\024\n\014resume_token\030\006 \001(\014" + + "\022B\n\nquery_mode\030\007 \001(\0162..google.spanner.v1" + + ".ExecuteSqlRequest.QueryMode\022\027\n\017partitio" + + "n_token\030\010 \001(\014\022\r\n\005seqno\030\t \001(\003\022H\n\rquery_op" + + "tions\030\n \001(\01321.google.spanner.v1.ExecuteS" + + "qlRequest.QueryOptions\022:\n\017request_option" + + "s\030\013 \001(\0132!.google.spanner.v1.RequestOptio" + + "ns\022E\n\025directed_read_options\030\017 \001(\0132&.goog" + + "le.spanner.v1.DirectedReadOptions\022\032\n\022dat" + + "a_boost_enabled\030\020 \001(\010\032O\n\014QueryOptions\022\031\n" + + "\021optimizer_version\030\001 \001(\t\022$\n\034optimizer_st" + + "atistics_package\030\002 \001(\t\032J\n\017ParamTypesEntr" + + "y\022\013\n\003key\030\001 \001(\t\022&\n\005value\030\002 \001(\0132\027.google.s" + + "panner.v1.Type:\0028\001\".\n\tQueryMode\022\n\n\006NORMA" + + "L\020\000\022\010\n\004PLAN\020\001\022\013\n\007PROFILE\020\002\"\245\004\n\026ExecuteBa" + + "tchDmlRequest\0228\n\007session\030\001 \001(\tB\'\342A\001\002\372A \n" + + "\036spanner.googleapis.com/Session\022A\n\013trans" + + "action\030\002 \001(\0132&.google.spanner.v1.Transac" + + "tionSelectorB\004\342A\001\002\022M\n\nstatements\030\003 \003(\01323" + + ".google.spanner.v1.ExecuteBatchDmlReques" + + "t.StatementB\004\342A\001\002\022\023\n\005seqno\030\004 \001(\003B\004\342A\001\002\022:" + + "\n\017request_options\030\005 \001(\0132!.google.spanner" + + ".v1.RequestOptions\032\355\001\n\tStatement\022\021\n\003sql\030" + + "\001 \001(\tB\004\342A\001\002\022\'\n\006params\030\002 \001(\0132\027.google.pro" + + "tobuf.Struct\022X\n\013param_types\030\003 \003(\0132C.goog" + + "le.spanner.v1.ExecuteBatchDmlRequest.Sta" + + "tement.ParamTypesEntry\032J\n\017ParamTypesEntr" + + "y\022\013\n\003key\030\001 \001(\t\022&\n\005value\030\002 \001(\0132\027.google.s" + + "panner.v1.Type:\0028\001\"p\n\027ExecuteBatchDmlRes" + + "ponse\0221\n\013result_sets\030\001 \003(\0132\034.google.span" + + "ner.v1.ResultSet\022\"\n\006status\030\002 \001(\0132\022.googl" + + "e.rpc.Status\"H\n\020PartitionOptions\022\034\n\024part" + + "ition_size_bytes\030\001 \001(\003\022\026\n\016max_partitions" + + "\030\002 \001(\003\"\245\003\n\025PartitionQueryRequest\0228\n\007sess" + + "ion\030\001 \001(\tB\'\342A\001\002\372A \n\036spanner.googleapis.c" + + "om/Session\022;\n\013transaction\030\002 \001(\0132&.google" + + ".spanner.v1.TransactionSelector\022\021\n\003sql\030\003" + + " \001(\tB\004\342A\001\002\022\'\n\006params\030\004 \001(\0132\027.google.prot" + + "obuf.Struct\022M\n\013param_types\030\005 \003(\01328.googl" + + "e.spanner.v1.PartitionQueryRequest.Param" + + "TypesEntry\022>\n\021partition_options\030\006 \001(\0132#." + + "google.spanner.v1.PartitionOptions\032J\n\017Pa" + + "ramTypesEntry\022\013\n\003key\030\001 \001(\t\022&\n\005value\030\002 \001(" + + "\0132\027.google.spanner.v1.Type:\0028\001\"\264\002\n\024Parti" + + "tionReadRequest\0228\n\007session\030\001 \001(\tB\'\342A\001\002\372A" + + " \n\036spanner.googleapis.com/Session\022;\n\013tra" + + "nsaction\030\002 \001(\0132&.google.spanner.v1.Trans" + + "actionSelector\022\023\n\005table\030\003 \001(\tB\004\342A\001\002\022\r\n\005i" + + "ndex\030\004 \001(\t\022\017\n\007columns\030\005 \003(\t\0220\n\007key_set\030\006" + + " \001(\0132\031.google.spanner.v1.KeySetB\004\342A\001\002\022>\n" + + "\021partition_options\030\t \001(\0132#.google.spanne" + + "r.v1.PartitionOptions\"$\n\tPartition\022\027\n\017pa" + + "rtition_token\030\001 \001(\014\"z\n\021PartitionResponse" + + "\0220\n\npartitions\030\001 \003(\0132\034.google.spanner.v1" + + ".Partition\0223\n\013transaction\030\002 \001(\0132\036.google" + + ".spanner.v1.Transaction\"\316\003\n\013ReadRequest\022" + + "8\n\007session\030\001 \001(\tB\'\342A\001\002\372A \n\036spanner.googl" + + "eapis.com/Session\022;\n\013transaction\030\002 \001(\0132&" + + ".google.spanner.v1.TransactionSelector\022\023" + + "\n\005table\030\003 \001(\tB\004\342A\001\002\022\r\n\005index\030\004 \001(\t\022\025\n\007co" + + "lumns\030\005 \003(\tB\004\342A\001\002\0220\n\007key_set\030\006 \001(\0132\031.goo" + + "gle.spanner.v1.KeySetB\004\342A\001\002\022\r\n\005limit\030\010 \001" + + "(\003\022\024\n\014resume_token\030\t \001(\014\022\027\n\017partition_to" + + "ken\030\n \001(\014\022:\n\017request_options\030\013 \001(\0132!.goo" + + "gle.spanner.v1.RequestOptions\022E\n\025directe" + + "d_read_options\030\016 \001(\0132&.google.spanner.v1" + + ".DirectedReadOptions\022\032\n\022data_boost_enabl" + + "ed\030\017 \001(\010\"\315\001\n\027BeginTransactionRequest\0228\n\007" + + "session\030\001 \001(\tB\'\342A\001\002\372A \n\036spanner.googleap" + + "is.com/Session\022<\n\007options\030\002 \001(\0132%.google" + + ".spanner.v1.TransactionOptionsB\004\342A\001\002\022:\n\017" + + "request_options\030\003 \001(\0132!.google.spanner.v" + + "1.RequestOptions\"\377\002\n\rCommitRequest\0228\n\007se" + + "ssion\030\001 \001(\tB\'\342A\001\002\372A \n\036spanner.googleapis" + + ".com/Session\022\030\n\016transaction_id\030\002 \001(\014H\000\022G" + + "\n\026single_use_transaction\030\003 \001(\0132%.google." + + "spanner.v1.TransactionOptionsH\000\022.\n\tmutat" + + "ions\030\004 \003(\0132\033.google.spanner.v1.Mutation\022" + + "\033\n\023return_commit_stats\030\005 \001(\010\0229\n\020max_comm" + + "it_delay\030\010 \001(\0132\031.google.protobuf.Duratio" + + "nB\004\342A\001\001\022:\n\017request_options\030\006 \001(\0132!.googl" + + "e.spanner.v1.RequestOptionsB\r\n\013transacti" + + "on\"i\n\017RollbackRequest\0228\n\007session\030\001 \001(\tB\'" + + "\342A\001\002\372A \n\036spanner.googleapis.com/Session\022" + + "\034\n\016transaction_id\030\002 \001(\014B\004\342A\001\002\"\243\002\n\021BatchW" + + "riteRequest\0228\n\007session\030\001 \001(\tB\'\342A\001\002\372A \n\036s" + + "panner.googleapis.com/Session\022:\n\017request" + + "_options\030\003 \001(\0132!.google.spanner.v1.Reque" + + "stOptions\022Q\n\017mutation_groups\030\004 \003(\01322.goo" + + "gle.spanner.v1.BatchWriteRequest.Mutatio" + + "nGroupB\004\342A\001\002\032E\n\rMutationGroup\0224\n\tmutatio" + + "ns\030\001 \003(\0132\033.google.spanner.v1.MutationB\004\342" + + "A\001\002\"\177\n\022BatchWriteResponse\022\017\n\007indexes\030\001 \003" + + "(\005\022\"\n\006status\030\002 \001(\0132\022.google.rpc.Status\0224" + + "\n\020commit_timestamp\030\003 \001(\0132\032.google.protob" + + "uf.Timestamp2\213\030\n\007Spanner\022\246\001\n\rCreateSessi" + + "on\022\'.google.spanner.v1.CreateSessionRequ" + + "est\032\032.google.spanner.v1.Session\"P\332A\010data" + + "base\202\323\344\223\002?\":/v1/{database=projects/*/ins" + + "tances/*/databases/*}/sessions:\001*\022\340\001\n\023Ba" + + "tchCreateSessions\022-.google.spanner.v1.Ba" + + "tchCreateSessionsRequest\032..google.spanne" + + "r.v1.BatchCreateSessionsResponse\"j\332A\026dat" + + "abase,session_count\202\323\344\223\002K\"F/v1/{database" + + "=projects/*/instances/*/databases/*}/ses" + + "sions:batchCreate:\001*\022\227\001\n\nGetSession\022$.go" + + "ogle.spanner.v1.GetSessionRequest\032\032.goog" + + "le.spanner.v1.Session\"G\332A\004name\202\323\344\223\002:\0228/v" + + "1/{name=projects/*/instances/*/databases" + + "/*/sessions/*}\022\256\001\n\014ListSessions\022&.google" + + ".spanner.v1.ListSessionsRequest\032\'.google" + + ".spanner.v1.ListSessionsResponse\"M\332A\010dat" + + "abase\202\323\344\223\002<\022:/v1/{database=projects/*/in" + + "stances/*/databases/*}/sessions\022\231\001\n\rDele" + + "teSession\022\'.google.spanner.v1.DeleteSess" + + "ionRequest\032\026.google.protobuf.Empty\"G\332A\004n" + + "ame\202\323\344\223\002:*8/v1/{name=projects/*/instance" + + "s/*/databases/*/sessions/*}\022\243\001\n\nExecuteS" + + "ql\022$.google.spanner.v1.ExecuteSqlRequest" + + "\032\034.google.spanner.v1.ResultSet\"Q\202\323\344\223\002K\"F" + + "/v1/{session=projects/*/instances/*/data" + + "bases/*/sessions/*}:executeSql:\001*\022\276\001\n\023Ex" + + "ecuteStreamingSql\022$.google.spanner.v1.Ex" + + "ecuteSqlRequest\032#.google.spanner.v1.Part" + + "ialResultSet\"Z\202\323\344\223\002T\"O/v1/{session=proje" + + "cts/*/instances/*/databases/*/sessions/*" + + "}:executeStreamingSql:\001*0\001\022\300\001\n\017ExecuteBa" + + "tchDml\022).google.spanner.v1.ExecuteBatchD" + + "mlRequest\032*.google.spanner.v1.ExecuteBat" + + "chDmlResponse\"V\202\323\344\223\002P\"K/v1/{session=proj" + "ects/*/instances/*/databases/*/sessions/" - + "*}:partitionQuery:\001*\022\264\001\n\rPartitionRead\022\'" - + ".google.spanner.v1.PartitionReadRequest\032" - + "$.google.spanner.v1.PartitionResponse\"T\202" - + "\323\344\223\002N\"I/v1/{session=projects/*/instances" - + "/*/databases/*/sessions/*}:partitionRead" - + ":\001*\022\310\001\n\nBatchWrite\022$.google.spanner.v1.B" - + "atchWriteRequest\032%.google.spanner.v1.Bat" - + "chWriteResponse\"k\332A\027session,mutation_gro" - + "ups\202\323\344\223\002K\"F/v1/{session=projects/*/insta" - + "nces/*/databases/*/sessions/*}:batchWrit" - + "e:\001*0\001\032w\312A\026spanner.googleapis.com\322A[http" - + "s://www.googleapis.com/auth/cloud-platfo" - + "rm,https://www.googleapis.com/auth/spann" - + "er.dataB\221\002\n\025com.google.spanner.v1B\014Spann" - + "erProtoP\001Z5cloud.google.com/go/spanner/a" - + "piv1/spannerpb;spannerpb\252\002\027Google.Cloud." - + "Spanner.V1\312\002\027Google\\Cloud\\Spanner\\V1\352\002\032G" - + "oogle::Cloud::Spanner::V1\352A_\n\037spanner.go" - + "ogleapis.com/Database\022 builder) { private Type() { code_ = 0; typeAnnotation_ = 0; + protoTypeFqn_ = ""; } @java.lang.Override @@ -246,6 +247,65 @@ public com.google.spanner.v1.TypeAnnotationCode getTypeAnnotation() { return result == null ? com.google.spanner.v1.TypeAnnotationCode.UNRECOGNIZED : result; } + public static final int PROTO_TYPE_FQN_FIELD_NUMBER = 5; + + @SuppressWarnings("serial") + private volatile java.lang.Object protoTypeFqn_ = ""; + /** + * + * + *
+   * If [code][google.spanner.v1.Type.code] ==
+   * [PROTO][google.spanner.v1.TypeCode.PROTO] or
+   * [code][google.spanner.v1.Type.code] ==
+   * [ENUM][google.spanner.v1.TypeCode.ENUM], then `proto_type_fqn` is the fully
+   * qualified name of the proto type representing the proto/enum definition.
+   * 
+ * + * string proto_type_fqn = 5; + * + * @return The protoTypeFqn. + */ + @java.lang.Override + public java.lang.String getProtoTypeFqn() { + java.lang.Object ref = protoTypeFqn_; + if (ref instanceof java.lang.String) { + return (java.lang.String) ref; + } else { + com.google.protobuf.ByteString bs = (com.google.protobuf.ByteString) ref; + java.lang.String s = bs.toStringUtf8(); + protoTypeFqn_ = s; + return s; + } + } + /** + * + * + *
+   * If [code][google.spanner.v1.Type.code] ==
+   * [PROTO][google.spanner.v1.TypeCode.PROTO] or
+   * [code][google.spanner.v1.Type.code] ==
+   * [ENUM][google.spanner.v1.TypeCode.ENUM], then `proto_type_fqn` is the fully
+   * qualified name of the proto type representing the proto/enum definition.
+   * 
+ * + * string proto_type_fqn = 5; + * + * @return The bytes for protoTypeFqn. + */ + @java.lang.Override + public com.google.protobuf.ByteString getProtoTypeFqnBytes() { + java.lang.Object ref = protoTypeFqn_; + if (ref instanceof java.lang.String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8((java.lang.String) ref); + protoTypeFqn_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + private byte memoizedIsInitialized = -1; @java.lang.Override @@ -273,6 +333,9 @@ public void writeTo(com.google.protobuf.CodedOutputStream output) throws java.io != com.google.spanner.v1.TypeAnnotationCode.TYPE_ANNOTATION_CODE_UNSPECIFIED.getNumber()) { output.writeEnum(4, typeAnnotation_); } + if (!com.google.protobuf.GeneratedMessageV3.isStringEmpty(protoTypeFqn_)) { + com.google.protobuf.GeneratedMessageV3.writeString(output, 5, protoTypeFqn_); + } getUnknownFields().writeTo(output); } @@ -295,6 +358,9 @@ public int getSerializedSize() { != com.google.spanner.v1.TypeAnnotationCode.TYPE_ANNOTATION_CODE_UNSPECIFIED.getNumber()) { size += com.google.protobuf.CodedOutputStream.computeEnumSize(4, typeAnnotation_); } + if (!com.google.protobuf.GeneratedMessageV3.isStringEmpty(protoTypeFqn_)) { + size += com.google.protobuf.GeneratedMessageV3.computeStringSize(5, protoTypeFqn_); + } size += getUnknownFields().getSerializedSize(); memoizedSize = size; return size; @@ -320,6 +386,7 @@ public boolean equals(final java.lang.Object obj) { if (!getStructType().equals(other.getStructType())) return false; } if (typeAnnotation_ != other.typeAnnotation_) return false; + if (!getProtoTypeFqn().equals(other.getProtoTypeFqn())) return false; if (!getUnknownFields().equals(other.getUnknownFields())) return false; return true; } @@ -343,6 +410,8 @@ public int hashCode() { } hash = (37 * hash) + TYPE_ANNOTATION_FIELD_NUMBER; hash = (53 * hash) + typeAnnotation_; + hash = (37 * hash) + PROTO_TYPE_FQN_FIELD_NUMBER; + hash = (53 * hash) + getProtoTypeFqn().hashCode(); hash = (29 * hash) + getUnknownFields().hashCode(); memoizedHashCode = hash; return hash; @@ -492,6 +561,7 @@ public Builder clear() { structTypeBuilder_ = null; } typeAnnotation_ = 0; + protoTypeFqn_ = ""; return this; } @@ -539,6 +609,9 @@ private void buildPartial0(com.google.spanner.v1.Type result) { if (((from_bitField0_ & 0x00000008) != 0)) { result.typeAnnotation_ = typeAnnotation_; } + if (((from_bitField0_ & 0x00000010) != 0)) { + result.protoTypeFqn_ = protoTypeFqn_; + } } @java.lang.Override @@ -598,6 +671,11 @@ public Builder mergeFrom(com.google.spanner.v1.Type other) { if (other.typeAnnotation_ != 0) { setTypeAnnotationValue(other.getTypeAnnotationValue()); } + if (!other.getProtoTypeFqn().isEmpty()) { + protoTypeFqn_ = other.protoTypeFqn_; + bitField0_ |= 0x00000010; + onChanged(); + } this.mergeUnknownFields(other.getUnknownFields()); onChanged(); return this; @@ -649,6 +727,12 @@ public Builder mergeFrom( bitField0_ |= 0x00000008; break; } // case 32 + case 42: + { + protoTypeFqn_ = input.readStringRequireUtf8(); + bitField0_ |= 0x00000010; + break; + } // case 42 default: { if (!super.parseUnknownField(input, extensionRegistry, tag)) { @@ -1256,6 +1340,132 @@ public Builder clearTypeAnnotation() { return this; } + private java.lang.Object protoTypeFqn_ = ""; + /** + * + * + *
+     * If [code][google.spanner.v1.Type.code] ==
+     * [PROTO][google.spanner.v1.TypeCode.PROTO] or
+     * [code][google.spanner.v1.Type.code] ==
+     * [ENUM][google.spanner.v1.TypeCode.ENUM], then `proto_type_fqn` is the fully
+     * qualified name of the proto type representing the proto/enum definition.
+     * 
+ * + * string proto_type_fqn = 5; + * + * @return The protoTypeFqn. + */ + public java.lang.String getProtoTypeFqn() { + java.lang.Object ref = protoTypeFqn_; + if (!(ref instanceof java.lang.String)) { + com.google.protobuf.ByteString bs = (com.google.protobuf.ByteString) ref; + java.lang.String s = bs.toStringUtf8(); + protoTypeFqn_ = s; + return s; + } else { + return (java.lang.String) ref; + } + } + /** + * + * + *
+     * If [code][google.spanner.v1.Type.code] ==
+     * [PROTO][google.spanner.v1.TypeCode.PROTO] or
+     * [code][google.spanner.v1.Type.code] ==
+     * [ENUM][google.spanner.v1.TypeCode.ENUM], then `proto_type_fqn` is the fully
+     * qualified name of the proto type representing the proto/enum definition.
+     * 
+ * + * string proto_type_fqn = 5; + * + * @return The bytes for protoTypeFqn. + */ + public com.google.protobuf.ByteString getProtoTypeFqnBytes() { + java.lang.Object ref = protoTypeFqn_; + if (ref instanceof String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8((java.lang.String) ref); + protoTypeFqn_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + /** + * + * + *
+     * If [code][google.spanner.v1.Type.code] ==
+     * [PROTO][google.spanner.v1.TypeCode.PROTO] or
+     * [code][google.spanner.v1.Type.code] ==
+     * [ENUM][google.spanner.v1.TypeCode.ENUM], then `proto_type_fqn` is the fully
+     * qualified name of the proto type representing the proto/enum definition.
+     * 
+ * + * string proto_type_fqn = 5; + * + * @param value The protoTypeFqn to set. + * @return This builder for chaining. + */ + public Builder setProtoTypeFqn(java.lang.String value) { + if (value == null) { + throw new NullPointerException(); + } + protoTypeFqn_ = value; + bitField0_ |= 0x00000010; + onChanged(); + return this; + } + /** + * + * + *
+     * If [code][google.spanner.v1.Type.code] ==
+     * [PROTO][google.spanner.v1.TypeCode.PROTO] or
+     * [code][google.spanner.v1.Type.code] ==
+     * [ENUM][google.spanner.v1.TypeCode.ENUM], then `proto_type_fqn` is the fully
+     * qualified name of the proto type representing the proto/enum definition.
+     * 
+ * + * string proto_type_fqn = 5; + * + * @return This builder for chaining. + */ + public Builder clearProtoTypeFqn() { + protoTypeFqn_ = getDefaultInstance().getProtoTypeFqn(); + bitField0_ = (bitField0_ & ~0x00000010); + onChanged(); + return this; + } + /** + * + * + *
+     * If [code][google.spanner.v1.Type.code] ==
+     * [PROTO][google.spanner.v1.TypeCode.PROTO] or
+     * [code][google.spanner.v1.Type.code] ==
+     * [ENUM][google.spanner.v1.TypeCode.ENUM], then `proto_type_fqn` is the fully
+     * qualified name of the proto type representing the proto/enum definition.
+     * 
+ * + * string proto_type_fqn = 5; + * + * @param value The bytes for protoTypeFqn to set. + * @return This builder for chaining. + */ + public Builder setProtoTypeFqnBytes(com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + checkByteStringIsUtf8(value); + protoTypeFqn_ = value; + bitField0_ |= 0x00000010; + onChanged(); + return this; + } + @java.lang.Override public final Builder setUnknownFields(final com.google.protobuf.UnknownFieldSet unknownFields) { return super.setUnknownFields(unknownFields); diff --git a/proto-google-cloud-spanner-v1/src/main/java/com/google/spanner/v1/TypeAnnotationCode.java b/proto-google-cloud-spanner-v1/src/main/java/com/google/spanner/v1/TypeAnnotationCode.java index 52b4fd1b08e..2a74f743be4 100644 --- a/proto-google-cloud-spanner-v1/src/main/java/com/google/spanner/v1/TypeAnnotationCode.java +++ b/proto-google-cloud-spanner-v1/src/main/java/com/google/spanner/v1/TypeAnnotationCode.java @@ -1,5 +1,5 @@ /* - * Copyright 2023 Google LLC + * Copyright 2024 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/proto-google-cloud-spanner-v1/src/main/java/com/google/spanner/v1/TypeCode.java b/proto-google-cloud-spanner-v1/src/main/java/com/google/spanner/v1/TypeCode.java index 736f0f0ef63..f3e13962f95 100644 --- a/proto-google-cloud-spanner-v1/src/main/java/com/google/spanner/v1/TypeCode.java +++ b/proto-google-cloud-spanner-v1/src/main/java/com/google/spanner/v1/TypeCode.java @@ -1,5 +1,5 @@ /* - * Copyright 2023 Google LLC + * Copyright 2024 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -181,6 +181,27 @@ public enum TypeCode implements com.google.protobuf.ProtocolMessageEnum { * JSON = 11; */ JSON(11), + /** + * + * + *
+   * Encoded as a base64-encoded `string`, as described in RFC 4648,
+   * section 4.
+   * 
+ * + * PROTO = 13; + */ + PROTO(13), + /** + * + * + *
+   * Encoded as `string`, in decimal format.
+   * 
+ * + * ENUM = 14; + */ + ENUM(14), UNRECOGNIZED(-1), ; @@ -331,6 +352,27 @@ public enum TypeCode implements com.google.protobuf.ProtocolMessageEnum { * JSON = 11; */ public static final int JSON_VALUE = 11; + /** + * + * + *
+   * Encoded as a base64-encoded `string`, as described in RFC 4648,
+   * section 4.
+   * 
+ * + * PROTO = 13; + */ + public static final int PROTO_VALUE = 13; + /** + * + * + *
+   * Encoded as `string`, in decimal format.
+   * 
+ * + * ENUM = 14; + */ + public static final int ENUM_VALUE = 14; public final int getNumber() { if (this == UNRECOGNIZED) { @@ -380,6 +422,10 @@ public static TypeCode forNumber(int value) { return NUMERIC; case 11: return JSON; + case 13: + return PROTO; + case 14: + return ENUM; default: return null; } diff --git a/proto-google-cloud-spanner-v1/src/main/java/com/google/spanner/v1/TypeOrBuilder.java b/proto-google-cloud-spanner-v1/src/main/java/com/google/spanner/v1/TypeOrBuilder.java index 35e645298d1..79c2028861f 100644 --- a/proto-google-cloud-spanner-v1/src/main/java/com/google/spanner/v1/TypeOrBuilder.java +++ b/proto-google-cloud-spanner-v1/src/main/java/com/google/spanner/v1/TypeOrBuilder.java @@ -1,5 +1,5 @@ /* - * Copyright 2023 Google LLC + * Copyright 2024 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -158,4 +158,37 @@ public interface TypeOrBuilder * @return The typeAnnotation. */ com.google.spanner.v1.TypeAnnotationCode getTypeAnnotation(); + + /** + * + * + *
+   * If [code][google.spanner.v1.Type.code] ==
+   * [PROTO][google.spanner.v1.TypeCode.PROTO] or
+   * [code][google.spanner.v1.Type.code] ==
+   * [ENUM][google.spanner.v1.TypeCode.ENUM], then `proto_type_fqn` is the fully
+   * qualified name of the proto type representing the proto/enum definition.
+   * 
+ * + * string proto_type_fqn = 5; + * + * @return The protoTypeFqn. + */ + java.lang.String getProtoTypeFqn(); + /** + * + * + *
+   * If [code][google.spanner.v1.Type.code] ==
+   * [PROTO][google.spanner.v1.TypeCode.PROTO] or
+   * [code][google.spanner.v1.Type.code] ==
+   * [ENUM][google.spanner.v1.TypeCode.ENUM], then `proto_type_fqn` is the fully
+   * qualified name of the proto type representing the proto/enum definition.
+   * 
+ * + * string proto_type_fqn = 5; + * + * @return The bytes for protoTypeFqn. + */ + com.google.protobuf.ByteString getProtoTypeFqnBytes(); } diff --git a/proto-google-cloud-spanner-v1/src/main/java/com/google/spanner/v1/TypeProto.java b/proto-google-cloud-spanner-v1/src/main/java/com/google/spanner/v1/TypeProto.java index 4df6b4e7c63..7c7cd131dc1 100644 --- a/proto-google-cloud-spanner-v1/src/main/java/com/google/spanner/v1/TypeProto.java +++ b/proto-google-cloud-spanner-v1/src/main/java/com/google/spanner/v1/TypeProto.java @@ -1,5 +1,5 @@ /* - * Copyright 2023 Google LLC + * Copyright 2024 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -50,27 +50,28 @@ public static com.google.protobuf.Descriptors.FileDescriptor getDescriptor() { java.lang.String[] descriptorData = { "\n\034google/spanner/v1/type.proto\022\021google.s" + "panner.v1\032\037google/api/field_behavior.pro" - + "to\"\340\001\n\004Type\022/\n\004code\030\001 \001(\0162\033.google.spann" + + "to\"\370\001\n\004Type\022/\n\004code\030\001 \001(\0162\033.google.spann" + "er.v1.TypeCodeB\004\342A\001\002\0223\n\022array_element_ty" + "pe\030\002 \001(\0132\027.google.spanner.v1.Type\0222\n\013str" + "uct_type\030\003 \001(\0132\035.google.spanner.v1.Struc" + "tType\022>\n\017type_annotation\030\004 \001(\0162%.google." - + "spanner.v1.TypeAnnotationCode\"\177\n\nStructT" - + "ype\0223\n\006fields\030\001 \003(\0132#.google.spanner.v1." - + "StructType.Field\032<\n\005Field\022\014\n\004name\030\001 \001(\t\022" - + "%\n\004type\030\002 \001(\0132\027.google.spanner.v1.Type*\245" - + "\001\n\010TypeCode\022\031\n\025TYPE_CODE_UNSPECIFIED\020\000\022\010" - + "\n\004BOOL\020\001\022\t\n\005INT64\020\002\022\013\n\007FLOAT64\020\003\022\r\n\tTIME" - + "STAMP\020\004\022\010\n\004DATE\020\005\022\n\n\006STRING\020\006\022\t\n\005BYTES\020\007" - + "\022\t\n\005ARRAY\020\010\022\n\n\006STRUCT\020\t\022\013\n\007NUMERIC\020\n\022\010\n\004" - + "JSON\020\013*d\n\022TypeAnnotationCode\022$\n TYPE_ANN" - + "OTATION_CODE_UNSPECIFIED\020\000\022\016\n\nPG_NUMERIC" - + "\020\002\022\014\n\010PG_JSONB\020\003\022\n\n\006PG_OID\020\004B\254\001\n\025com.goo" - + "gle.spanner.v1B\tTypeProtoP\001Z5cloud.googl" - + "e.com/go/spanner/apiv1/spannerpb;spanner" - + "pb\252\002\027Google.Cloud.Spanner.V1\312\002\027Google\\Cl" - + "oud\\Spanner\\V1\352\002\032Google::Cloud::Spanner:" - + ":V1b\006proto3" + + "spanner.v1.TypeAnnotationCode\022\026\n\016proto_t" + + "ype_fqn\030\005 \001(\t\"\177\n\nStructType\0223\n\006fields\030\001 " + + "\003(\0132#.google.spanner.v1.StructType.Field" + + "\032<\n\005Field\022\014\n\004name\030\001 \001(\t\022%\n\004type\030\002 \001(\0132\027." + + "google.spanner.v1.Type*\272\001\n\010TypeCode\022\031\n\025T" + + "YPE_CODE_UNSPECIFIED\020\000\022\010\n\004BOOL\020\001\022\t\n\005INT6" + + "4\020\002\022\013\n\007FLOAT64\020\003\022\r\n\tTIMESTAMP\020\004\022\010\n\004DATE\020" + + "\005\022\n\n\006STRING\020\006\022\t\n\005BYTES\020\007\022\t\n\005ARRAY\020\010\022\n\n\006S" + + "TRUCT\020\t\022\013\n\007NUMERIC\020\n\022\010\n\004JSON\020\013\022\t\n\005PROTO\020" + + "\r\022\010\n\004ENUM\020\016*d\n\022TypeAnnotationCode\022$\n TYP" + + "E_ANNOTATION_CODE_UNSPECIFIED\020\000\022\016\n\nPG_NU" + + "MERIC\020\002\022\014\n\010PG_JSONB\020\003\022\n\n\006PG_OID\020\004B\254\001\n\025co" + + "m.google.spanner.v1B\tTypeProtoP\001Z5cloud." + + "google.com/go/spanner/apiv1/spannerpb;sp" + + "annerpb\252\002\027Google.Cloud.Spanner.V1\312\002\027Goog" + + "le\\Cloud\\Spanner\\V1\352\002\032Google::Cloud::Spa" + + "nner::V1b\006proto3" }; descriptor = com.google.protobuf.Descriptors.FileDescriptor.internalBuildGeneratedFileFrom( @@ -83,7 +84,7 @@ public static com.google.protobuf.Descriptors.FileDescriptor getDescriptor() { new com.google.protobuf.GeneratedMessageV3.FieldAccessorTable( internal_static_google_spanner_v1_Type_descriptor, new java.lang.String[] { - "Code", "ArrayElementType", "StructType", "TypeAnnotation", + "Code", "ArrayElementType", "StructType", "TypeAnnotation", "ProtoTypeFqn", }); internal_static_google_spanner_v1_StructType_descriptor = getDescriptor().getMessageTypes().get(1); diff --git a/proto-google-cloud-spanner-v1/src/main/proto/google/spanner/v1/spanner.proto b/proto-google-cloud-spanner-v1/src/main/proto/google/spanner/v1/spanner.proto index 367928a4515..5f26cea11fc 100644 --- a/proto-google-cloud-spanner-v1/src/main/proto/google/spanner/v1/spanner.proto +++ b/proto-google-cloud-spanner-v1/src/main/proto/google/spanner/v1/spanner.proto @@ -22,6 +22,7 @@ import "google/api/annotations.proto"; import "google/api/client.proto"; import "google/api/field_behavior.proto"; import "google/api/resource.proto"; +import "google/protobuf/duration.proto"; import "google/protobuf/empty.proto"; import "google/protobuf/struct.proto"; import "google/protobuf/timestamp.proto"; @@ -1163,6 +1164,14 @@ message CommitRequest { // Default value is `false`. bool return_commit_stats = 5; + // Optional. The amount of latency this request is willing to incur in order + // to improve throughput. If this field is not set, Spanner assumes requests + // are relatively latency sensitive and automatically determines an + // appropriate delay time. You can specify a batching delay value between 0 + // and 500 ms. + google.protobuf.Duration max_commit_delay = 8 + [(google.api.field_behavior) = OPTIONAL]; + // Common options for this request. RequestOptions request_options = 6; } diff --git a/proto-google-cloud-spanner-v1/src/main/proto/google/spanner/v1/type.proto b/proto-google-cloud-spanner-v1/src/main/proto/google/spanner/v1/type.proto index 412cfa12625..abd0c768176 100644 --- a/proto-google-cloud-spanner-v1/src/main/proto/google/spanner/v1/type.proto +++ b/proto-google-cloud-spanner-v1/src/main/proto/google/spanner/v1/type.proto @@ -47,6 +47,13 @@ message Type { // typically is not needed to process the content of a value (it doesn't // affect serialization) and clients can ignore it on the read path. TypeAnnotationCode type_annotation = 4; + + // If [code][google.spanner.v1.Type.code] == + // [PROTO][google.spanner.v1.TypeCode.PROTO] or + // [code][google.spanner.v1.Type.code] == + // [ENUM][google.spanner.v1.TypeCode.ENUM], then `proto_type_fqn` is the fully + // qualified name of the proto type representing the proto/enum definition. + string proto_type_fqn = 5; } // `StructType` defines the fields of a [STRUCT][google.spanner.v1.TypeCode.STRUCT] type. @@ -145,6 +152,13 @@ enum TypeCode { // preserved. // - JSON array elements will have their order preserved. JSON = 11; + + // Encoded as a base64-encoded `string`, as described in RFC 4648, + // section 4. + PROTO = 13; + + // Encoded as `string`, in decimal format. + ENUM = 14; } // `TypeAnnotationCode` is used as a part of [Type][google.spanner.v1.Type] to From 95f064f9f60a17de375e532ec6dd78dca0743e79 Mon Sep 17 00:00:00 2001 From: Mend Renovate Date: Thu, 25 Jan 2024 18:42:30 +0100 Subject: [PATCH 10/21] deps: update dependency com.google.cloud:google-cloud-shared-dependencies to v3.23.0 (#2801) --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 31fc8561520..c6542501373 100644 --- a/pom.xml +++ b/pom.xml @@ -54,7 +54,7 @@ UTF-8 github google-cloud-spanner-parent - 3.22.0 + 3.23.0
From 30d37dd80c91b2dffdfee732677607ce028fb8d2 Mon Sep 17 00:00:00 2001 From: Sri Harsha CH <57220027+harshachinta@users.noreply.github.com> Date: Fri, 26 Jan 2024 19:03:24 +0530 Subject: [PATCH 11/21] feat: add support for Proto Columns (#2779) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * feat: Support for Proto Messages & Enums (#2155) * feat: Importing Proto Changes Commit will be reverted, once PROTO changes are available publicly. * feat: Proto Message Implementation * feat: Adding support for enum * feat: Code refactoring Adding default implementation for newly added methods ByteArray compatability changes for Proto Messages * docs: Adding Java docs for all the newly added methods. * test: Sample Proto & Generated classes for unit test * feat: Adding bytes/proto & int64/enum compatability Adding Additional check for ChecksumResultSet * test: Adding unit tests * test: Adding unit tests for ValueBinder.java * feat: refactoring to add support for getValue & other minor changes * feat: Minor refactoring 1. Adding docs and formatting the code. 2. Adding additional methods for enum and message which accepts descriptors. * feat: Adding bytes/message & int64/enum compatability in Value * refactor: Minor refactoring * feat: Adding Proto Array Implementation * test: Implementing unit tests for array of protos and enums * refactor: adding clirr ignores * feat: Adding support for enum as Primary Key * feat: Code Review Changes, minor refactoring and adding docs * feat: Addressing review comments -Modified Docs/Comments -Minor Refactoring * refactor: Using Column instead of column to avoid test failures * feat: Minor refactoring -code review comments -adding function docs * samples: Adding samples for updating & querying Proto messages & enums (#2211) * samples: Adding samples for updating & querying Proto messages & enums * style: linting * style: linting * docs: Adding function and class doc * test: Proto Column Integration tests (#2212) * test: Adding Integration tests for Proto Messages & Enums * test: Adding additional test for Parameterized Queries, Primary Keys & Invalid Wire type errors. * style: Formatting * style: Formatting * test: Updating instance and db name * test: Adding inter compatability check while writing data * Configured jitpack.yml to use OpenJDK 11 (#2218) Co-authored-by: Pavol Juhos * feat: add support for Proto Columns DDL (#2277) * feat: add code changes and tests for Proto columns DDL support * feat: add auto generated code * feat: code changes and tests for Proto columns DDL support * feat: add descriptors file * feat: code refactoring * feat: Integration tests and code refactoring * feat: code refactoring * feat: unit tests and clirr differences * feat: lint changes * feat: code refactor * feat: code refactoring * feat: code refactoring * feat: code refactoring * feat: add java docs to new methods * feat: lint formatting * feat: lint formatting changes * feat: lint formatting * feat: lint formatting * feat: test exception cases * feat: code refactoring * feat: add java docs and refactoring * feat: add java docs * feat: java docs refactor * feat: remove overload method setProtoDescriptors that accepts file path as input to avoid unexpected issues * feat: remove updateDdl method overload to update proto descriptor * teat: update pom file to run tests on cloud-devel region temporarily to validate main branch update * 🦉 Updates from OwlBot post-processor See https://github.com/googleapis/repo-automation-bots/blob/main/packages/owl-bot/README.md * fix: revert host changes in pom.xml file * 🦉 Updates from OwlBot post-processor See https://github.com/googleapis/repo-automation-bots/blob/main/packages/owl-bot/README.md * feat(spanner): revert autogenerated code * 🦉 Updates from OwlBot post-processor See https://github.com/googleapis/repo-automation-bots/blob/main/packages/owl-bot/README.md * feat(spanner): remove samples * 🦉 Updates from OwlBot post-processor See https://github.com/googleapis/repo-automation-bots/blob/main/packages/owl-bot/README.md * feat(spanner): remove clirr * feat(spanner): skip emulator test * feat(spanner): clirr * feat(spanner): fix javadoc * 🦉 Updates from OwlBot post-processor See https://github.com/googleapis/repo-automation-bots/blob/main/packages/owl-bot/README.md * feat(spanner): fix javadoc * feat(spanner): fix javadoc * feat(spanner): fix javadoc * 🦉 Updates from OwlBot post-processor See https://github.com/googleapis/repo-automation-bots/blob/main/packages/owl-bot/README.md * feat(spanner): fix emulator skip * build: ignore all changes in v1 package * feat(spanner): add optimizations to deserialize proto messages * feat(spanner): remove TODO * feat(spanner): remove TODO --------- Co-authored-by: Gaurav Purohit Co-authored-by: Pavol Juhos Co-authored-by: Owl Bot Co-authored-by: Knut Olav Løite --- .../clirr-ignored-differences.xml | 79 ++ google-cloud-spanner/pom.xml | 9 + .../cloud/spanner/AbstractResultSet.java | 138 +- .../cloud/spanner/AbstractStructReader.java | 128 +- .../cloud/spanner/DatabaseAdminClient.java | 55 +- .../spanner/DatabaseAdminClientImpl.java | 19 +- .../google/cloud/spanner/DatabaseInfo.java | 67 +- .../cloud/spanner/ForwardingStructReader.java | 55 + .../java/com/google/cloud/spanner/Key.java | 12 + .../com/google/cloud/spanner/ResultSets.java | 47 + .../java/com/google/cloud/spanner/Struct.java | 30 + .../google/cloud/spanner/StructReader.java | 115 ++ .../java/com/google/cloud/spanner/Type.java | 47 +- .../java/com/google/cloud/spanner/Value.java | 448 +++++- .../com/google/cloud/spanner/ValueBinder.java | 60 + .../spanner/connection/ChecksumResultSet.java | 6 + .../connection/DirectExecuteResultSet.java | 55 + .../ReplaceableForwardingResultSet.java | 55 + .../cloud/spanner/spi/v1/GapicSpannerRpc.java | 33 +- .../cloud/spanner/spi/v1/SpannerRpc.java | 7 +- .../AbstractStructReaderTypesTest.java | 26 + .../spanner/DatabaseAdminClientImplTest.java | 26 +- .../google/cloud/spanner/DatabaseTest.java | 58 + .../cloud/spanner/GrpcResultSetTest.java | 135 ++ .../google/cloud/spanner/MutationTest.java | 28 + .../google/cloud/spanner/ResultSetsTest.java | 84 +- .../com/google/cloud/spanner/SingerProto.java | 1199 +++++++++++++++++ .../com/google/cloud/spanner/TypeTest.java | 64 +- .../google/cloud/spanner/ValueBinderTest.java | 42 +- .../com/google/cloud/spanner/ValueTest.java | 116 ++ .../connection/ChecksumResultSetTest.java | 47 +- .../DirectExecuteResultSetTest.java | 52 +- .../connection/RandomResultSetGenerator.java | 171 ++- .../connection/ReadWriteTransactionTest.java | 74 +- .../ReplaceableForwardingResultSetTest.java | 52 +- .../cloud/spanner/it/ITProtoColumnTest.java | 402 ++++++ .../com/google/cloud/spanner/descriptors.pb | Bin 0 -> 251 bytes .../com/google/cloud/spanner/singer.proto | 21 + 38 files changed, 3945 insertions(+), 117 deletions(-) create mode 100644 google-cloud-spanner/src/test/java/com/google/cloud/spanner/SingerProto.java create mode 100644 google-cloud-spanner/src/test/java/com/google/cloud/spanner/it/ITProtoColumnTest.java create mode 100644 google-cloud-spanner/src/test/resources/com/google/cloud/spanner/descriptors.pb create mode 100644 google-cloud-spanner/src/test/resources/com/google/cloud/spanner/singer.proto diff --git a/google-cloud-spanner/clirr-ignored-differences.xml b/google-cloud-spanner/clirr-ignored-differences.xml index 84822306323..56e946eb3d4 100644 --- a/google-cloud-spanner/clirr-ignored-differences.xml +++ b/google-cloud-spanner/clirr-ignored-differences.xml @@ -192,6 +192,46 @@ com/google/cloud/spanner/StructReader java.util.List getPgJsonbList(java.lang.String) + + 7012 + com/google/cloud/spanner/StructReader + com.google.protobuf.ProtocolMessageEnum getProtoEnum(int, java.util.function.Function) + + + 7012 + com/google/cloud/spanner/StructReader + com.google.protobuf.ProtocolMessageEnum getProtoEnum(java.lang.String, java.util.function.Function) + + + 7012 + com/google/cloud/spanner/StructReader + com.google.protobuf.AbstractMessage getProtoMessage(int, com.google.protobuf.AbstractMessage) + + + 7012 + com/google/cloud/spanner/StructReader + com.google.protobuf.AbstractMessage getProtoMessage(java.lang.String, com.google.protobuf.AbstractMessage) + + + 7012 + com/google/cloud/spanner/StructReader + java.util.List getProtoEnumList(int, java.util.function.Function) + + + 7012 + com/google/cloud/spanner/StructReader + java.util.List getProtoEnumList(java.lang.String, java.util.function.Function) + + + 7012 + com/google/cloud/spanner/StructReader + java.util.List getProtoMessageList(int, com.google.protobuf.AbstractMessage) + + + 7012 + com/google/cloud/spanner/StructReader + java.util.List getProtoMessageList(java.lang.String, com.google.protobuf.AbstractMessage) + 7012 com/google/cloud/spanner/BatchClient @@ -222,6 +262,38 @@ com/google/cloud/spanner/connection/Connection com.google.cloud.spanner.ResultSet analyzeUpdateStatement(com.google.cloud.spanner.Statement, com.google.cloud.spanner.ReadContext$QueryAnalyzeMode, com.google.cloud.spanner.Options$UpdateOption[]) + + 7012 + com/google/cloud/spanner/DatabaseAdminClient + com.google.spanner.admin.database.v1.GetDatabaseDdlResponse getDatabaseDdlResponse(java.lang.String, java.lang.String) + + + 7012 + com/google/cloud/spanner/DatabaseAdminClient + com.google.api.gax.longrunning.OperationFuture updateDatabaseDdl(com.google.cloud.spanner.Database, java.lang.Iterable, java.lang.String) + + + 7013 + com/google/cloud/spanner/DatabaseInfo$Builder + com.google.cloud.spanner.DatabaseInfo$Builder setProtoDescriptors(byte[]) + + + 7013 + com/google/cloud/spanner/DatabaseInfo$Builder + com.google.cloud.spanner.DatabaseInfo$Builder setProtoDescriptors(java.io.InputStream) + + + 7013 + com/google/cloud/spanner/DatabaseInfo$Builder + com.google.cloud.spanner.DatabaseInfo$Builder setProtoDescriptors(java.lang.String) + + + 7006 + com/google/cloud/spanner/spi/v1/GapicSpannerRpc + java.util.List getDatabaseDdl(java.lang.String) + java.util.List + com.google.spanner.admin.database.v1.GetDatabaseDdlResponse + 7004 com/google/cloud/spanner/spi/v1/GapicSpannerRpc @@ -277,6 +349,13 @@ com.google.spanner.v1.ResultSet executeQuery(com.google.spanner.v1.ExecuteSqlRequest, java.util.Map) com.google.cloud.spanner.spi.v1.SpannerRpc$StreamingCall + + 7006 + com/google/cloud/spanner/spi/v1/SpannerRpc + java.util.List getDatabaseDdl(java.lang.String) + java.util.List + com.google.spanner.admin.database.v1.GetDatabaseDdlResponse + 7004 com/google/cloud/spanner/spi/v1/SpannerRpc diff --git a/google-cloud-spanner/pom.xml b/google-cloud-spanner/pom.xml index 24abc0d2195..999f49b77f0 100644 --- a/google-cloud-spanner/pom.xml +++ b/google-cloud-spanner/pom.xml @@ -134,6 +134,15 @@ org.codehaus.mojo flatten-maven-plugin + + + org.codehaus.mojo + clirr-maven-plugin + + + com/google/cloud/spanner/spi/v1/** + + diff --git a/google-cloud-spanner/src/main/java/com/google/cloud/spanner/AbstractResultSet.java b/google-cloud-spanner/src/main/java/com/google/cloud/spanner/AbstractResultSet.java index b0d5ab2bbaf..c18e64165bc 100644 --- a/google-cloud-spanner/src/main/java/com/google/cloud/spanner/AbstractResultSet.java +++ b/google-cloud-spanner/src/main/java/com/google/cloud/spanner/AbstractResultSet.java @@ -39,10 +39,13 @@ import com.google.common.collect.AbstractIterator; import com.google.common.collect.ImmutableMap; import com.google.common.collect.Lists; +import com.google.common.io.CharSource; import com.google.common.util.concurrent.Uninterruptibles; +import com.google.protobuf.AbstractMessage; import com.google.protobuf.ByteString; import com.google.protobuf.ListValue; import com.google.protobuf.NullValue; +import com.google.protobuf.ProtocolMessageEnum; import com.google.protobuf.Value.KindCase; import com.google.spanner.v1.PartialResultSet; import com.google.spanner.v1.ResultSetMetadata; @@ -58,6 +61,7 @@ import java.io.IOException; import java.io.Serializable; import java.math.BigDecimal; +import java.nio.charset.StandardCharsets; import java.util.AbstractList; import java.util.ArrayList; import java.util.Base64; @@ -73,6 +77,7 @@ import java.util.concurrent.Executor; import java.util.concurrent.LinkedBlockingQueue; import java.util.concurrent.TimeUnit; +import java.util.function.Function; import java.util.logging.Level; import java.util.logging.Logger; import java.util.stream.Collectors; @@ -477,6 +482,14 @@ private Object writeReplace() { case JSON: builder.set(fieldName).to(Value.json((String) value)); break; + case PROTO: + builder + .set(fieldName) + .to(Value.protoMessage((ByteArray) value, fieldType.getProtoTypeFqn())); + break; + case ENUM: + builder.set(fieldName).to(Value.protoEnum((Long) value, fieldType.getProtoTypeFqn())); + break; case PG_JSONB: builder.set(fieldName).to(Value.pgJsonb((String) value)); break; @@ -500,6 +513,7 @@ private Object writeReplace() { builder.set(fieldName).toBoolArray((Iterable) value); break; case INT64: + case ENUM: builder.set(fieldName).toInt64Array((Iterable) value); break; case FLOAT64: @@ -521,6 +535,7 @@ private Object writeReplace() { builder.set(fieldName).toPgJsonbArray((Iterable) value); break; case BYTES: + case PROTO: builder .set(fieldName) .toBytesArrayFromBase64( @@ -596,6 +611,7 @@ private static Object decodeValue(Type fieldType, com.google.protobuf.Value prot checkType(fieldType, proto, KindCase.BOOL_VALUE); return proto.getBoolValue(); case INT64: + case ENUM: checkType(fieldType, proto, KindCase.STRING_VALUE); return Long.parseLong(proto.getStringValue()); case FLOAT64: @@ -610,6 +626,7 @@ private static Object decodeValue(Type fieldType, com.google.protobuf.Value prot checkType(fieldType, proto, KindCase.STRING_VALUE); return proto.getStringValue(); case BYTES: + case PROTO: checkType(fieldType, proto, KindCase.STRING_VALUE); return new LazyByteArray(proto.getStringValue()); case TIMESTAMP: @@ -649,7 +666,8 @@ private static Struct decodeStructValue(Type structType, ListValue structValue) static Object decodeArrayValue(Type elementType, ListValue listValue) { switch (elementType.getCode()) { case INT64: - // For int64/float64 types, use custom containers. These avoid wrapper object + case ENUM: + // For int64/float64/enum types, use custom containers. These avoid wrapper object // creation for non-null arrays. return new Int64Array(listValue); case FLOAT64: @@ -664,6 +682,7 @@ static Object decodeArrayValue(Type elementType, ListValue listValue) { case TIMESTAMP: case DATE: case STRUCT: + case PROTO: return Lists.transform( listValue.getValuesList(), input -> decodeValue(elementType, input)); default: @@ -699,6 +718,35 @@ public boolean isNull(int columnIndex) { return rowData.get(columnIndex) == null; } + @Override + protected T getProtoMessageInternal(int columnIndex, T message) { + Preconditions.checkNotNull( + message, + "Proto message may not be null. Use MyProtoClass.getDefaultInstance() as a parameter value."); + try { + return (T) + message + .toBuilder() + .mergeFrom( + Base64.getDecoder() + .wrap( + CharSource.wrap(((LazyByteArray) rowData.get(columnIndex)).base64String) + .asByteSource(StandardCharsets.UTF_8) + .openStream())) + .build(); + } catch (IOException ioException) { + throw SpannerExceptionFactory.asSpannerException(ioException); + } + } + + @Override + protected T getProtoEnumInternal( + int columnIndex, Function method) { + Preconditions.checkNotNull( + method, "Method may not be null. Use 'MyProtoEnum::forNumber' as a parameter value."); + return (T) method.apply((int) getLongInternal(columnIndex)); + } + @Override protected boolean getBooleanInternal(int columnIndex) { return (Boolean) rowData.get(columnIndex); @@ -768,6 +816,8 @@ protected Value getValueInternal(int columnIndex) { return Value.bool(isNull ? null : getBooleanInternal(columnIndex)); case INT64: return Value.int64(isNull ? null : getLongInternal(columnIndex)); + case ENUM: + return Value.protoEnum(getLongInternal(columnIndex), columnType.getProtoTypeFqn()); case NUMERIC: return Value.numeric(isNull ? null : getBigDecimalInternal(columnIndex)); case PG_NUMERIC: @@ -782,6 +832,8 @@ protected Value getValueInternal(int columnIndex) { return Value.pgJsonb(isNull ? null : getPgJsonbInternal(columnIndex)); case BYTES: return Value.internalBytes(isNull ? null : getLazyBytesInternal(columnIndex)); + case PROTO: + return Value.protoMessage(getBytesInternal(columnIndex), columnType.getProtoTypeFqn()); case TIMESTAMP: return Value.timestamp(isNull ? null : getTimestampInternal(columnIndex)); case DATE: @@ -812,6 +864,12 @@ protected Value getValueInternal(int columnIndex) { return Value.pgJsonbArray(isNull ? null : getPgJsonbListInternal(columnIndex)); case BYTES: return Value.bytesArray(isNull ? null : getBytesListInternal(columnIndex)); + case PROTO: + return Value.protoMessageArray( + isNull ? null : getBytesListInternal(columnIndex), elementType.getProtoTypeFqn()); + case ENUM: + return Value.protoEnumArray( + isNull ? null : getLongListInternal(columnIndex), elementType.getProtoTypeFqn()); case TIMESTAMP: return Value.timestampArray(isNull ? null : getTimestampListInternal(columnIndex)); case DATE: @@ -891,6 +949,61 @@ protected List getJsonListInternal(int columnIndex) { return Collections.unmodifiableList((List) rowData.get(columnIndex)); } + @Override + @SuppressWarnings("unchecked") // We know ARRAY produces a List. + protected List getProtoMessageListInternal( + int columnIndex, T message) { + Preconditions.checkNotNull( + message, + "Proto message may not be null. Use MyProtoClass.getDefaultInstance() as a parameter value."); + + List bytesArray = (List) rowData.get(columnIndex); + + try { + List protoMessagesList = new ArrayList<>(bytesArray.size()); + for (LazyByteArray protoMessageBytes : bytesArray) { + if (protoMessageBytes == null) { + protoMessagesList.add(null); + } else { + protoMessagesList.add( + (T) + message + .toBuilder() + .mergeFrom( + Base64.getDecoder() + .wrap( + CharSource.wrap(protoMessageBytes.base64String) + .asByteSource(StandardCharsets.UTF_8) + .openStream())) + .build()); + } + } + return protoMessagesList; + } catch (IOException ioException) { + throw SpannerExceptionFactory.asSpannerException(ioException); + } + } + + @Override + @SuppressWarnings("unchecked") // We know ARRAY produces a List. + protected List getProtoEnumListInternal( + int columnIndex, Function method) { + Preconditions.checkNotNull( + method, "Method may not be null. Use 'MyProtoEnum::forNumber' as a parameter value."); + + List enumIntArray = (List) rowData.get(columnIndex); + List protoEnumList = new ArrayList<>(enumIntArray.size()); + for (Long enumIntValue : enumIntArray) { + if (enumIntValue == null) { + protoEnumList.add(null); + } else { + protoEnumList.add((T) method.apply(enumIntValue.intValue())); + } + } + + return protoEnumList; + } + @Override @SuppressWarnings("unchecked") // We know ARRAY produces a List. protected List getPgJsonbListInternal(int columnIndex) { @@ -1489,6 +1602,17 @@ protected String getStringInternal(int columnIndex) { return currRow().getStringInternal(columnIndex); } + @Override + protected T getProtoMessageInternal(int columnIndex, T message) { + return currRow().getProtoMessageInternal(columnIndex, message); + } + + @Override + protected T getProtoEnumInternal( + int columnIndex, Function method) { + return currRow().getProtoEnumInternal(columnIndex, method); + } + @Override protected String getJsonInternal(int columnIndex) { return currRow().getJsonInternal(columnIndex); @@ -1574,6 +1698,18 @@ protected List getBytesListInternal(int columnIndex) { return currRow().getBytesListInternal(columnIndex); } + @Override + protected List getProtoMessageListInternal( + int columnIndex, T message) { + return currRow().getProtoMessageListInternal(columnIndex, message); + } + + @Override + protected List getProtoEnumListInternal( + int columnIndex, Function method) { + return currRow().getProtoEnumListInternal(columnIndex, method); + } + @Override protected List getTimestampListInternal(int columnIndex) { return currRow().getTimestampListInternal(columnIndex); diff --git a/google-cloud-spanner/src/main/java/com/google/cloud/spanner/AbstractStructReader.java b/google-cloud-spanner/src/main/java/com/google/cloud/spanner/AbstractStructReader.java index c868678f109..53c49a5a54b 100644 --- a/google-cloud-spanner/src/main/java/com/google/cloud/spanner/AbstractStructReader.java +++ b/google-cloud-spanner/src/main/java/com/google/cloud/spanner/AbstractStructReader.java @@ -21,9 +21,14 @@ import com.google.cloud.ByteArray; import com.google.cloud.Date; import com.google.cloud.Timestamp; +import com.google.cloud.spanner.Type.Code; +import com.google.protobuf.AbstractMessage; +import com.google.protobuf.ProtocolMessageEnum; import java.math.BigDecimal; import java.util.Arrays; +import java.util.Collections; import java.util.List; +import java.util.function.Function; /** * Base class for assisting {@link StructReader} implementations. @@ -58,6 +63,25 @@ protected String getPgJsonbInternal(int columnIndex) { protected abstract Date getDateInternal(int columnIndex); + protected T getProtoMessageInternal(int columnIndex, T message) { + throw new UnsupportedOperationException("Not implemented"); + } + + protected T getProtoEnumInternal( + int columnIndex, Function method) { + throw new UnsupportedOperationException("Not implemented"); + } + + protected List getProtoMessageListInternal( + int columnIndex, T message) { + throw new UnsupportedOperationException("Not implemented"); + } + + protected List getProtoEnumListInternal( + int columnIndex, Function method) { + throw new UnsupportedOperationException("Not implemented"); + } + protected Value getValueInternal(int columnIndex) { throw new UnsupportedOperationException("method should be overwritten"); } @@ -129,14 +153,14 @@ public boolean getBoolean(String columnName) { @Override public long getLong(int columnIndex) { - checkNonNullOfType(columnIndex, Type.int64(), columnIndex); + checkNonNullOfCodes(columnIndex, Arrays.asList(Code.ENUM, Code.INT64), columnIndex); return getLongInternal(columnIndex); } @Override public long getLong(String columnName) { int columnIndex = getColumnIndex(columnName); - checkNonNullOfType(columnIndex, Type.int64(), columnName); + checkNonNullOfCodes(columnIndex, Arrays.asList(Code.ENUM, Code.INT64), columnName); return getLongInternal(columnIndex); } @@ -212,14 +236,14 @@ public String getPgJsonb(String columnName) { @Override public ByteArray getBytes(int columnIndex) { - checkNonNullOfType(columnIndex, Type.bytes(), columnIndex); + checkNonNullOfCodes(columnIndex, Arrays.asList(Code.PROTO, Code.BYTES), columnIndex); return getBytesInternal(columnIndex); } @Override public ByteArray getBytes(String columnName) { int columnIndex = getColumnIndex(columnName); - checkNonNullOfType(columnIndex, Type.bytes(), columnName); + checkNonNullOfCodes(columnIndex, Arrays.asList(Code.PROTO, Code.BYTES), columnName); return getBytesInternal(columnIndex); } @@ -249,6 +273,34 @@ public Date getDate(String columnName) { return getDateInternal(columnIndex); } + @Override + public T getProtoEnum( + int columnIndex, Function method) { + checkNonNullOfCodes(columnIndex, Arrays.asList(Code.ENUM, Code.INT64), columnIndex); + return getProtoEnumInternal(columnIndex, method); + } + + @Override + public T getProtoEnum( + String columnName, Function method) { + int columnIndex = getColumnIndex(columnName); + checkNonNullOfCodes(columnIndex, Arrays.asList(Code.ENUM, Code.INT64), columnName); + return getProtoEnumInternal(columnIndex, method); + } + + @Override + public T getProtoMessage(int columnIndex, T message) { + checkNonNullOfCodes(columnIndex, Arrays.asList(Code.PROTO, Code.BYTES), columnIndex); + return getProtoMessageInternal(columnIndex, message); + } + + @Override + public T getProtoMessage(String columnName, T message) { + int columnIndex = getColumnIndex(columnName); + checkNonNullOfCodes(columnIndex, Arrays.asList(Code.PROTO, Code.BYTES), columnName); + return getProtoMessageInternal(columnIndex, message); + } + @Override public Value getValue(int columnIndex) { return getValueInternal(columnIndex); @@ -301,14 +353,16 @@ public long[] getLongArray(String columnName) { @Override public List getLongList(int columnIndex) { - checkNonNullOfType(columnIndex, Type.array(Type.int64()), columnIndex); + checkNonNullOfCodes(columnIndex, Collections.singletonList(Code.ARRAY), columnIndex); + checkArrayElementType(columnIndex, Arrays.asList(Code.ENUM, Code.INT64), columnIndex); return getLongListInternal(columnIndex); } @Override public List getLongList(String columnName) { int columnIndex = getColumnIndex(columnName); - checkNonNullOfType(columnIndex, Type.array(Type.int64()), columnName); + checkNonNullOfCodes(columnIndex, Collections.singletonList(Code.ARRAY), columnName); + checkArrayElementType(columnIndex, Arrays.asList(Code.ENUM, Code.INT64), columnName); return getLongListInternal(columnIndex); } @@ -400,17 +454,51 @@ public List getPgJsonbList(String columnName) { @Override public List getBytesList(int columnIndex) { - checkNonNullOfType(columnIndex, Type.array(Type.bytes()), columnIndex); + checkNonNullOfCodes(columnIndex, Collections.singletonList(Code.ARRAY), columnIndex); + checkArrayElementType(columnIndex, Arrays.asList(Code.PROTO, Code.BYTES), columnIndex); return getBytesListInternal(columnIndex); } @Override public List getBytesList(String columnName) { int columnIndex = getColumnIndex(columnName); - checkNonNullOfType(columnIndex, Type.array(Type.bytes()), columnName); + checkNonNullOfCodes(columnIndex, Collections.singletonList(Code.ARRAY), columnName); + checkArrayElementType(columnIndex, Arrays.asList(Code.PROTO, Code.BYTES), columnName); return getBytesListInternal(columnIndex); } + @Override + public List getProtoMessageList(int columnIndex, T message) { + checkNonNullOfCodes(columnIndex, Collections.singletonList(Code.ARRAY), columnIndex); + checkArrayElementType(columnIndex, Arrays.asList(Code.PROTO, Code.BYTES), columnIndex); + return getProtoMessageListInternal(columnIndex, message); + } + + @Override + public List getProtoMessageList(String columnName, T message) { + int columnIndex = getColumnIndex(columnName); + checkNonNullOfCodes(columnIndex, Collections.singletonList(Code.ARRAY), columnName); + checkArrayElementType(columnIndex, Arrays.asList(Code.PROTO, Code.BYTES), columnName); + return getProtoMessageListInternal(columnIndex, message); + } + + @Override + public List getProtoEnumList( + int columnIndex, Function method) { + checkNonNullOfCodes(columnIndex, Collections.singletonList(Code.ARRAY), columnIndex); + checkArrayElementType(columnIndex, Arrays.asList(Code.ENUM, Code.INT64), columnIndex); + return getProtoEnumListInternal(columnIndex, method); + } + + @Override + public List getProtoEnumList( + String columnName, Function method) { + int columnIndex = getColumnIndex(columnName); + checkNonNullOfCodes(columnIndex, Collections.singletonList(Code.ARRAY), columnName); + checkArrayElementType(columnIndex, Arrays.asList(Code.ENUM, Code.INT64), columnName); + return getProtoEnumListInternal(columnIndex, method); + } + @Override public List getTimestampList(int columnIndex) { checkNonNullOfType(columnIndex, Type.array(Type.timestamp()), columnIndex); @@ -476,6 +564,30 @@ private void checkNonNullOfType(int columnIndex, Type expectedType, Object colum checkNonNull(columnIndex, columnNameForError); } + /** Checks if the value at {@code columnIndex} is one of {@code expectedCode} */ + private void checkNonNullOfCodes( + int columnIndex, List expectedCodes, Object columnNameForError) { + Type actualType = getColumnType(columnIndex); + checkState( + expectedCodes.contains(actualType.getCode()), + "Column %s is not of correct type code: expected one of [%s] but was %s", + columnNameForError, + expectedCodes, + actualType); + checkNonNull(columnIndex, columnNameForError); + } + + private void checkArrayElementType( + int columnIndex, List expectedCodes, Object columnNameForError) { + Type arrayElementType = getColumnType(columnIndex).getArrayElementType(); + checkState( + expectedCodes.contains(arrayElementType.getCode()), + "Array element for Column %s is not of correct type code: expected one of [%s] but was %s", + columnNameForError, + expectedCodes, + Type.array(arrayElementType)); + } + private void checkNonNullOfTypes( int columnIndex, List expectedTypes, diff --git a/google-cloud-spanner/src/main/java/com/google/cloud/spanner/DatabaseAdminClient.java b/google-cloud-spanner/src/main/java/com/google/cloud/spanner/DatabaseAdminClient.java index 8372bb61fd3..f961a13845b 100644 --- a/google-cloud-spanner/src/main/java/com/google/cloud/spanner/DatabaseAdminClient.java +++ b/google-cloud-spanner/src/main/java/com/google/cloud/spanner/DatabaseAdminClient.java @@ -26,6 +26,7 @@ import com.google.spanner.admin.database.v1.CreateBackupMetadata; import com.google.spanner.admin.database.v1.CreateDatabaseMetadata; import com.google.spanner.admin.database.v1.CreateDatabaseRequest; +import com.google.spanner.admin.database.v1.GetDatabaseDdlResponse; import com.google.spanner.admin.database.v1.RestoreDatabaseMetadata; import com.google.spanner.admin.database.v1.UpdateDatabaseDdlMetadata; import com.google.spanner.admin.database.v1.UpdateDatabaseMetadata; @@ -424,7 +425,8 @@ OperationFuture updateDatabase( * *

If an operation already exists with the given operation id, the operation will be resumed * and the returned future will complete when the original operation finishes. See more - * information in {@link com.google.cloud.spanner.spi.v1.GapicSpannerRpc#updateDatabaseDdl(String, + * information in {@link + * com.google.cloud.spanner.spi.v1.GapicSpannerRpc#updateDatabaseDdl(com.google.cloud.spanner.Database, * Iterable, String)} * *

Example to update the database DDL. @@ -449,6 +451,40 @@ OperationFuture updateDatabaseDdl( @Nullable String operationId) throws SpannerException; + /** + * Updates a database in a Cloud Spanner instance. Any proto descriptors that have been set for + * the {@link com.google.cloud.spanner.Database} instance will be included in the {@link + * com.google.spanner.admin.database.v1.UpdateDatabaseDdlRequest}. + * + *

If an operation already exists with the given operation id, the operation will be resumed + * and the returned future will complete when the original operation finishes. See more + * information in {@link + * com.google.cloud.spanner.spi.v1.GapicSpannerRpc#updateDatabaseDdl(com.google.cloud.spanner.Database, + * Iterable, String)} + * + *

Example to update the database DDL with proto descriptors. + * + *

{@code
+   * Database dbInfo =
+   *         dbClient
+   *            .newDatabaseBuilder(DatabaseId.of("my_project_id", "my_instance_id", "my_database_id"))
+   *            .setProtoDescriptors("com/google/cloud/spanner/descriptors.pb")
+   *            .build();
+   * dbAdminClient.updateDatabaseDdl(dbInfo,
+   *     Arrays.asList("ALTER TABLE Albums ADD COLUMN MarketingBudget INT64"),
+   *     null).waitFor();
+   * }
+ * + * @param database Database object to set configuration options such as proto_descriptors. + * @param statements DDL statements to run while updating the database. + * @param operationId Operation id assigned to this operation. If null, system will autogenerate + * one. This must be unique within a database abd must be a valid identifier + * [a-zA-Z][a-zA-Z0-9_]*. + */ + OperationFuture updateDatabaseDdl( + Database database, Iterable statements, @Nullable String operationId) + throws SpannerException; + /** * Drops a Cloud Spanner database. * @@ -476,6 +512,23 @@ OperationFuture updateDatabaseDdl( */ List getDatabaseDdl(String instanceId, String databaseId); + /** + * Returns the GetDatabaseDdlResponse object of a Cloud Spanner database. + * + *

Example to get GetDatabaseDdlResponse object of a Cloud Spanner database. + * + *

{@code
+   * String instanceId = my_instance_id;
+   * String databaseId = my_database_id;
+   * GetDatabaseDdlResponse response = dbAdminClient.getDatabaseDdl(instanceId, databaseId);
+   * }
+ * + * @param instanceId the id of the instance where the database was created. + * @param databaseId the id of the database. + * @return GetDatabaseDdlResponse object + */ + GetDatabaseDdlResponse getDatabaseDdlResponse(String instanceId, String databaseId); + /** * Returns the list of Cloud Spanner database in the given instance. * diff --git a/google-cloud-spanner/src/main/java/com/google/cloud/spanner/DatabaseAdminClientImpl.java b/google-cloud-spanner/src/main/java/com/google/cloud/spanner/DatabaseAdminClientImpl.java index 8a5d0d613a5..f53ae3bb0d3 100644 --- a/google-cloud-spanner/src/main/java/com/google/cloud/spanner/DatabaseAdminClientImpl.java +++ b/google-cloud-spanner/src/main/java/com/google/cloud/spanner/DatabaseAdminClientImpl.java @@ -444,10 +444,20 @@ public OperationFuture updateDatabaseDdl( final Iterable statements, @Nullable String operationId) throws SpannerException { - final String dbName = getDatabaseName(instanceId, databaseId); + + return updateDatabaseDdl( + newDatabaseBuilder(DatabaseId.of(projectId, instanceId, databaseId)).build(), + statements, + operationId); + } + + @Override + public OperationFuture updateDatabaseDdl( + Database database, final Iterable statements, @Nullable String operationId) + throws SpannerException { final String opId = operationId != null ? operationId : randomOperationId(); OperationFuture rawOperationFuture = - rpc.updateDatabaseDdl(dbName, statements, opId); + rpc.updateDatabaseDdl(database, statements, opId); return new OperationFutureImpl<>( rawOperationFuture.getPollingFuture(), rawOperationFuture.getInitialFuture(), @@ -469,6 +479,11 @@ public void dropDatabase(String instanceId, String databaseId) throws SpannerExc @Override public List getDatabaseDdl(String instanceId, String databaseId) { + return getDatabaseDdlResponse(instanceId, databaseId).getStatementsList(); + } + + @Override + public GetDatabaseDdlResponse getDatabaseDdlResponse(String instanceId, String databaseId) { String dbName = getDatabaseName(instanceId, databaseId); return rpc.getDatabaseDdl(dbName); } diff --git a/google-cloud-spanner/src/main/java/com/google/cloud/spanner/DatabaseInfo.java b/google-cloud-spanner/src/main/java/com/google/cloud/spanner/DatabaseInfo.java index d231ef34e37..3f1a0f81eb0 100644 --- a/google-cloud-spanner/src/main/java/com/google/cloud/spanner/DatabaseInfo.java +++ b/google-cloud-spanner/src/main/java/com/google/cloud/spanner/DatabaseInfo.java @@ -20,9 +20,13 @@ import com.google.cloud.Timestamp; import com.google.cloud.spanner.encryption.CustomerManagedEncryption; import com.google.common.base.Preconditions; +import com.google.protobuf.ByteString; import com.google.protobuf.FieldMask; import com.google.spanner.admin.database.v1.Database.State; +import java.io.IOException; +import java.io.InputStream; import java.util.Objects; +import javax.annotation.Nonnull; import javax.annotation.Nullable; /** Represents a Cloud Spanner database. */ @@ -97,6 +101,34 @@ protected Builder setReconciling(boolean reconciling) { throw new UnsupportedOperationException("Unimplemented"); } + /** + * Optional for creating a new database. + * + *

It is used by CREATE/ALTER PROTO BUNDLE statements which are part of DDL statements. + * Contains a protobuf-serialized [google.protobuf.FileDescriptorSet]. To generate a proto + * descriptors file run {@code protoc --include_imports + * --descriptor_set_out=DESCRIPTOR_OUTPUT_LOCATION LOCATION-OF-PROTO-FILES} + * + * @param protoDescriptors The proto descriptors input as byte[] to be used for the database. + * @return {@link Builder} + */ + public abstract Builder setProtoDescriptors(@Nonnull byte[] protoDescriptors); + + /** + * Optional for creating a new database. + * + *

It is used by CREATE/ALTER PROTO BUNDLE statements which are part of DDL statements. + * Contains a protobuf-serialized [google.protobuf.FileDescriptorSet]. To generate a proto + * descriptors file run {@code protoc --include_imports + * --descriptor_set_out=DESCRIPTOR_OUTPUT_LOCATION LOCATION-OF-PROTO-FILES} + * + * @param inputStream The proto descriptors input as InputStream to be used for the database. + * @return {@link Builder} + * @throws IOException if there is a problem reading the underlying stream. + */ + public abstract Builder setProtoDescriptors(@Nonnull InputStream inputStream) + throws IOException; + abstract Builder setProto(com.google.spanner.admin.database.v1.Database proto); /** Builds the database from this builder. */ @@ -115,6 +147,7 @@ abstract static class BuilderImpl extends Builder { private Dialect dialect = Dialect.GOOGLE_STANDARD_SQL; private boolean dropProtectionEnabled; private boolean reconciling; + private ByteString protoDescriptors; private com.google.spanner.admin.database.v1.Database proto; BuilderImpl(DatabaseId id) { @@ -131,6 +164,7 @@ abstract static class BuilderImpl extends Builder { this.encryptionConfig = other.encryptionConfig; this.defaultLeader = other.defaultLeader; this.dialect = other.dialect; + this.protoDescriptors = other.protoDescriptors; this.proto = other.proto; } @@ -200,6 +234,20 @@ protected Builder setReconciling(boolean reconciling) { return this; } + @Override + public Builder setProtoDescriptors(@Nonnull byte[] protoDescriptors) { + Preconditions.checkNotNull(protoDescriptors); + this.protoDescriptors = ByteString.copyFrom(protoDescriptors); + return this; + } + + @Override + public Builder setProtoDescriptors(@Nonnull InputStream inputStream) throws IOException { + Preconditions.checkNotNull(inputStream); + this.protoDescriptors = ByteString.readFrom(inputStream); + return this; + } + @Override Builder setProto(@Nullable com.google.spanner.admin.database.v1.Database proto) { this.proto = proto; @@ -252,6 +300,8 @@ public com.google.spanner.admin.database.v1.Database.State toProto() { private final Dialect dialect; private final boolean dropProtectionEnabled; private final boolean reconciling; + + private final ByteString protoDescriptors; private final com.google.spanner.admin.database.v1.Database proto; public DatabaseInfo(DatabaseId id, State state) { @@ -266,6 +316,7 @@ public DatabaseInfo(DatabaseId id, State state) { this.dialect = null; this.dropProtectionEnabled = false; this.reconciling = false; + this.protoDescriptors = null; this.proto = null; } @@ -281,6 +332,7 @@ public DatabaseInfo(DatabaseId id, State state) { this.dialect = builder.dialect; this.dropProtectionEnabled = builder.dropProtectionEnabled; this.reconciling = builder.reconciling; + this.protoDescriptors = builder.protoDescriptors; this.proto = builder.proto; } @@ -357,6 +409,10 @@ public boolean getReconciling() { return reconciling; } + public ByteString getProtoDescriptors() { + return protoDescriptors; + } + /** Returns the raw proto instance that was used to construct this {@link Database}. */ public @Nullable com.google.spanner.admin.database.v1.Database getProto() { return proto; @@ -381,7 +437,8 @@ public boolean equals(Object o) { && Objects.equals(defaultLeader, that.defaultLeader) && Objects.equals(dialect, that.dialect) && Objects.equals(dropProtectionEnabled, that.dropProtectionEnabled) - && Objects.equals(reconciling, that.reconciling); + && Objects.equals(reconciling, that.reconciling) + && Objects.equals(protoDescriptors, that.protoDescriptors); } @Override @@ -397,13 +454,14 @@ public int hashCode() { defaultLeader, dialect, dropProtectionEnabled, - reconciling); + reconciling, + protoDescriptors); } @Override public String toString() { return String.format( - "Database[%s, %s, %s, %s, %s, %s, %s, %s, %s %s %s]", + "Database[%s, %s, %s, %s, %s, %s, %s, %s, %s %s %s %s]", id.getName(), state, createTime, @@ -414,6 +472,7 @@ public String toString() { defaultLeader, dialect, dropProtectionEnabled, - reconciling); + reconciling, + protoDescriptors); } } diff --git a/google-cloud-spanner/src/main/java/com/google/cloud/spanner/ForwardingStructReader.java b/google-cloud-spanner/src/main/java/com/google/cloud/spanner/ForwardingStructReader.java index 2a85006fa95..97c39c00a8d 100644 --- a/google-cloud-spanner/src/main/java/com/google/cloud/spanner/ForwardingStructReader.java +++ b/google-cloud-spanner/src/main/java/com/google/cloud/spanner/ForwardingStructReader.java @@ -22,8 +22,11 @@ import com.google.common.base.Preconditions; import com.google.common.base.Supplier; import com.google.common.base.Suppliers; +import com.google.protobuf.AbstractMessage; +import com.google.protobuf.ProtocolMessageEnum; import java.math.BigDecimal; import java.util.List; +import java.util.function.Function; /** Forwarding implements of StructReader */ public class ForwardingStructReader implements StructReader { @@ -370,6 +373,32 @@ public List getDateList(String columnName) { return delegate.get().getDateList(columnName); } + @Override + public List getProtoMessageList(int columnIndex, T message) { + checkValidState(); + return delegate.get().getProtoMessageList(columnIndex, message); + } + + @Override + public List getProtoMessageList(String columnName, T message) { + checkValidState(); + return delegate.get().getProtoMessageList(columnName, message); + } + + @Override + public List getProtoEnumList( + int columnIndex, Function method) { + checkValidState(); + return delegate.get().getProtoEnumList(columnIndex, method); + } + + @Override + public List getProtoEnumList( + String columnName, Function method) { + checkValidState(); + return delegate.get().getProtoEnumList(columnName, method); + } + @Override public List getStructList(int columnIndex) { checkValidState(); @@ -382,6 +411,32 @@ public List getStructList(String columnName) { return delegate.get().getStructList(columnName); } + @Override + public T getProtoMessage(int columnIndex, T message) { + checkValidState(); + return delegate.get().getProtoMessage(columnIndex, message); + } + + @Override + public T getProtoMessage(String columnName, T message) { + checkValidState(); + return delegate.get().getProtoMessage(columnName, message); + } + + @Override + public T getProtoEnum( + int columnIndex, Function method) { + checkValidState(); + return delegate.get().getProtoEnum(columnIndex, method); + } + + @Override + public T getProtoEnum( + String columnName, Function method) { + checkValidState(); + return delegate.get().getProtoEnum(columnName, method); + } + @Override public Value getValue(int columnIndex) { checkValidState(); diff --git a/google-cloud-spanner/src/main/java/com/google/cloud/spanner/Key.java b/google-cloud-spanner/src/main/java/com/google/cloud/spanner/Key.java index 15d4e995bf0..3467052605a 100644 --- a/google-cloud-spanner/src/main/java/com/google/cloud/spanner/Key.java +++ b/google-cloud-spanner/src/main/java/com/google/cloud/spanner/Key.java @@ -24,6 +24,7 @@ import com.google.common.base.Joiner; import com.google.protobuf.ListValue; import com.google.protobuf.NullValue; +import com.google.protobuf.ProtocolMessageEnum; import com.google.protobuf.Value; import java.io.Serializable; import java.math.BigDecimal; @@ -141,6 +142,11 @@ public Builder append(@Nullable BigDecimal value) { buffer.add(value); return this; } + /** Appends a {@code ENUM} value to the key. */ + public Builder append(@Nullable ProtocolMessageEnum value) { + buffer.add(value); + return this; + } /** Appends a {@code STRING} value to the key. */ public Builder append(@Nullable String value) { buffer.add(value); @@ -192,6 +198,8 @@ public Builder appendObject(@Nullable Object value) { append((Timestamp) value); } else if (value instanceof Date) { append((Date) value); + } else if (value instanceof ProtocolMessageEnum) { + append((ProtocolMessageEnum) value); } else { throw new IllegalArgumentException( "Unsupported type [" @@ -300,6 +308,10 @@ ListValue toProto() { builder.addValuesBuilder().setStringValue(part.toString()); } else if (part instanceof Date) { builder.addValuesBuilder().setStringValue(part.toString()); + } else if (part instanceof ProtocolMessageEnum) { + builder + .addValuesBuilder() + .setStringValue(Long.toString(((ProtocolMessageEnum) part).getNumber())); } else { throw new AssertionError("Illegal key part: " + part.getClass()); } diff --git a/google-cloud-spanner/src/main/java/com/google/cloud/spanner/ResultSets.java b/google-cloud-spanner/src/main/java/com/google/cloud/spanner/ResultSets.java index fa054ba0cda..d55d4091b9f 100644 --- a/google-cloud-spanner/src/main/java/com/google/cloud/spanner/ResultSets.java +++ b/google-cloud-spanner/src/main/java/com/google/cloud/spanner/ResultSets.java @@ -29,10 +29,13 @@ import com.google.common.base.Supplier; import com.google.common.collect.Lists; import com.google.common.util.concurrent.ThreadFactoryBuilder; +import com.google.protobuf.AbstractMessage; +import com.google.protobuf.ProtocolMessageEnum; import com.google.spanner.v1.ResultSetMetadata; import com.google.spanner.v1.ResultSetStats; import java.math.BigDecimal; import java.util.List; +import java.util.function.Function; /** Utility methods for working with {@link com.google.cloud.spanner.ResultSet}. */ public final class ResultSets { @@ -300,6 +303,28 @@ public Date getDate(String columnName) { return getCurrentRowAsStruct().getDate(columnName); } + @Override + public T getProtoMessage(int columnIndex, T message) { + return getCurrentRowAsStruct().getProtoMessage(columnIndex, message); + } + + @Override + public T getProtoMessage(String columnName, T message) { + return getCurrentRowAsStruct().getProtoMessage(columnName, message); + } + + @Override + public T getProtoEnum( + int columnIndex, Function method) { + return getCurrentRowAsStruct().getProtoEnum(columnIndex, method); + } + + @Override + public T getProtoEnum( + String columnName, Function method) { + return getCurrentRowAsStruct().getProtoEnum(columnName, method); + } + @Override public Value getValue(int columnIndex) { return getCurrentRowAsStruct().getValue(columnIndex); @@ -440,6 +465,28 @@ public List getDateList(String columnName) { return getCurrentRowAsStruct().getDateList(columnName); } + @Override + public List getProtoMessageList(int columnIndex, T message) { + return getCurrentRowAsStruct().getProtoMessageList(columnIndex, message); + } + + @Override + public List getProtoMessageList(String columnName, T message) { + return getCurrentRowAsStruct().getProtoMessageList(columnName, message); + } + + @Override + public List getProtoEnumList( + int columnIndex, Function method) { + return getCurrentRowAsStruct().getProtoEnumList(columnIndex, method); + } + + @Override + public List getProtoEnumList( + String columnName, Function method) { + return getCurrentRowAsStruct().getProtoEnumList(columnName, method); + } + @Override public List getStructList(int columnIndex) { return getCurrentRowAsStruct().getStructList(columnIndex); diff --git a/google-cloud-spanner/src/main/java/com/google/cloud/spanner/Struct.java b/google-cloud-spanner/src/main/java/com/google/cloud/spanner/Struct.java index 48c989d145e..40c30148d0e 100644 --- a/google-cloud-spanner/src/main/java/com/google/cloud/spanner/Struct.java +++ b/google-cloud-spanner/src/main/java/com/google/cloud/spanner/Struct.java @@ -28,11 +28,14 @@ import com.google.common.primitives.Booleans; import com.google.common.primitives.Doubles; import com.google.common.primitives.Longs; +import com.google.protobuf.AbstractMessage; +import com.google.protobuf.ProtocolMessageEnum; import java.io.Serializable; import java.math.BigDecimal; import java.util.ArrayList; import java.util.List; import java.util.Objects; +import java.util.function.Function; import javax.annotation.concurrent.Immutable; /** @@ -217,6 +220,17 @@ protected Date getDateInternal(int columnIndex) { return values.get(columnIndex).getDate(); } + @Override + protected T getProtoMessageInternal(int columnIndex, T message) { + return values.get(columnIndex).getProtoMessage(message); + } + + @Override + protected T getProtoEnumInternal( + int columnIndex, Function method) { + return values.get(columnIndex).getProtoEnum(method); + } + @Override protected Value getValueInternal(int columnIndex) { return values.get(columnIndex); @@ -287,6 +301,18 @@ protected List getTimestampListInternal(int columnIndex) { return values.get(columnIndex).getTimestampArray(); } + @Override + protected List getProtoMessageListInternal( + int columnIndex, T message) { + return values.get(columnIndex).getProtoMessageArray(message); + } + + @Override + protected List getProtoEnumListInternal( + int columnIndex, Function method) { + return values.get(columnIndex).getProtoEnumArray(method); + } + @Override protected List getDateListInternal(int columnIndex) { return values.get(columnIndex).getDateArray(); @@ -354,6 +380,7 @@ private Object getAsObject(int columnIndex) { case BOOL: return getBooleanInternal(columnIndex); case INT64: + case ENUM: return getLongInternal(columnIndex); case FLOAT64: return getDoubleInternal(columnIndex); @@ -368,6 +395,7 @@ private Object getAsObject(int columnIndex) { case PG_JSONB: return getPgJsonbInternal(columnIndex); case BYTES: + case PROTO: return getBytesInternal(columnIndex); case TIMESTAMP: return getTimestampInternal(columnIndex); @@ -380,6 +408,7 @@ private Object getAsObject(int columnIndex) { case BOOL: return getBooleanListInternal(columnIndex); case INT64: + case ENUM: return getLongListInternal(columnIndex); case FLOAT64: return getDoubleListInternal(columnIndex); @@ -394,6 +423,7 @@ private Object getAsObject(int columnIndex) { case PG_JSONB: return getPgJsonbListInternal(columnIndex); case BYTES: + case PROTO: return getBytesListInternal(columnIndex); case TIMESTAMP: return getTimestampListInternal(columnIndex); diff --git a/google-cloud-spanner/src/main/java/com/google/cloud/spanner/StructReader.java b/google-cloud-spanner/src/main/java/com/google/cloud/spanner/StructReader.java index ad085ca2dcc..fd8cb77f397 100644 --- a/google-cloud-spanner/src/main/java/com/google/cloud/spanner/StructReader.java +++ b/google-cloud-spanner/src/main/java/com/google/cloud/spanner/StructReader.java @@ -19,8 +19,11 @@ import com.google.cloud.ByteArray; import com.google.cloud.Date; import com.google.cloud.Timestamp; +import com.google.protobuf.AbstractMessage; +import com.google.protobuf.ProtocolMessageEnum; import java.math.BigDecimal; import java.util.List; +import java.util.function.Function; /** * A base interface for reading the fields of a {@code STRUCT}. The Cloud Spanner yields {@code @@ -188,6 +191,60 @@ default String getPgJsonb(String columnName) { throw new UnsupportedOperationException("method should be overwritten"); } + /** + * To get the proto message of generic type {@code T} from Struct. + * + * @param columnIndex Index of the column. + * @param message Proto message object. Message can't be null as it's internally used to find the + * type of proto. Use @code{MyProtoClass.getDefaultInstance()}. @see getDefaultInstance() + * @return The value of a non-{@code NULL} column with type {@link Type#proto(String)} ()}. + */ + default T getProtoMessage(int columnIndex, T message) { + throw new UnsupportedOperationException("method should be overwritten"); + } + + /** + * To get the proto message of type {@code T} from Struct. + * + * @param columnName Name of the column. + * @param message Proto message object. Message can't be null as it's internally used to find the + * type of proto. Use @code{MyProtoClass.getDefaultInstance()}. @see getDefaultInstance() + * @return The value of a non-{@code NULL} column with type {@link Type#proto(String)} ()}. + */ + default T getProtoMessage(String columnName, T message) { + throw new UnsupportedOperationException("method should be overwritten"); + } + + /** + * To get the proto enum of type {@code T} from Struct. + * + * @param columnIndex Index of the column. + * @param method A function that takes enum integer constant as argument and returns the enum. Use + * method @code{forNumber} from generated enum class (eg: MyProtoEnum::forNumber). @see forNumber + * @return The value of a non-{@code NULL} column with type {@link Type#protoEnum(String)} ()}. + */ + default T getProtoEnum( + int columnIndex, Function method) { + throw new UnsupportedOperationException("method should be overwritten"); + } + + /** + * To get the proto enum of type {@code T} from Struct. + * + * @param columnName Name of the column. + * @param method A function that takes enum integer constant as argument and returns the enum. Use + * method @code{forNumber} from generated enum class (eg: MyProtoEnum::forNumber). @see forNumber + * @return The value of a non-{@code NULL} column with type {@link Type#protoEnum(String)} ()}. + */ + default T getProtoEnum( + String columnName, Function method) { + throw new UnsupportedOperationException("method should be overwritten"); + } + /** * @param columnIndex index of the column * @return the value of a non-{@code NULL} column with type {@link Type#bytes()}. @@ -408,6 +465,64 @@ default List getPgJsonbList(String columnName) { throw new UnsupportedOperationException("method should be overwritten"); }; + /** + * To get the proto message of generic type {@code T} from Struct. + * + * @param columnIndex Index of the column. + * @param message Proto message object. Message can't be null as it's internally used to find the + * type of proto. Use @code{MyProtoClass.getDefaultInstance()}. @see getDefaultInstance() + * @return The value of a non-{@code NULL} column with type {@code + * Type.array(Type.proto(String))}. + */ + default List getProtoMessageList(int columnIndex, T message) { + throw new UnsupportedOperationException("method should be overwritten"); + } + + /** + * To get the proto message of type {@code T} from Struct. + * + * @param columnName Name of the column. + * @param message Proto message object. Message can't be null as it's internally used to find the + * type of proto. Use @code{MyProtoClass.getDefaultInstance()}. @see getDefaultInstance() + * @return The value of a non-{@code NULL} column with type {@code + * Type.array(Type.proto(String))}. + */ + default List getProtoMessageList(String columnName, T message) { + throw new UnsupportedOperationException("method should be overwritten"); + } + + /** + * To get the proto enum of type {@code T} from Struct. + * + * @param columnIndex Index of the column. + * @param method A function that takes enum integer constant as argument and returns the enum. Use + * method @code{forNumber} from generated enum class (eg: MyProtoEnum::forNumber). @see forNumber + * @return The value of a non-{@code NULL} column with type {@code + * Type.array(Type.protoEnum(String))}. + */ + default List getProtoEnumList( + int columnIndex, Function method) { + throw new UnsupportedOperationException("method should be overwritten"); + } + + /** + * To get the proto enum list of type {@code T} from Struct. + * + * @param columnName Name of the column. + * @param method A function that takes enum integer constant as argument and returns the enum. Use + * method @code{forNumber} from generated enum class (eg: MyProtoEnum::forNumber). @see forNumber + * @return The value of a non-{@code NULL} column with type {@code + * Type.array(Type.protoEnum(String))}. + */ + default List getProtoEnumList( + String columnName, Function method) { + throw new UnsupportedOperationException("method should be overwritten"); + } + /** * @param columnIndex index of the column * @return the value of a non-{@code NULL} column with type {@code Type.array(Type.bytes())}. The diff --git a/google-cloud-spanner/src/main/java/com/google/cloud/spanner/Type.java b/google-cloud-spanner/src/main/java/com/google/cloud/spanner/Type.java index 37262cc6b3f..348db5d04ae 100644 --- a/google-cloud-spanner/src/main/java/com/google/cloud/spanner/Type.java +++ b/google-cloud-spanner/src/main/java/com/google/cloud/spanner/Type.java @@ -127,6 +127,24 @@ public static Type pgJsonb() { return TYPE_PG_JSONB; } + /** + * To get the descriptor for the {@code PROTO} type. + * + * @param protoTypeFqn Proto fully qualified name (ex: "spanner.examples.music.SingerInfo"). + */ + public static Type proto(String protoTypeFqn) { + return new Type(Code.PROTO, protoTypeFqn); + } + + /** + * To get the descriptor for the {@code ENUM} type. + * + * @param protoTypeFqn Proto ENUM fully qualified name (ex: "spanner.examples.music.Genre") + */ + public static Type protoEnum(String protoTypeFqn) { + return new Type(Code.ENUM, protoTypeFqn); + } + /** Returns the descriptor for the {@code BYTES} type: a variable-length byte string. */ public static Type bytes() { return TYPE_BYTES; @@ -199,6 +217,7 @@ public static Type struct(StructField... fields) { private final Code code; private final Type arrayElementType; private final ImmutableList structFields; + private String protoTypeFqn; /** * Map of field name to field index. Ambiguous names are indexed to {@link #AMBIGUOUS_FIELD}. The @@ -232,6 +251,11 @@ private Type( this.structFields = structFields; } + private Type(Code code, @Nonnull String protoTypeFqn) { + this(code, null, null); + this.protoTypeFqn = protoTypeFqn; + } + /** Enumerates the categories of types. */ public enum Code { UNRECOGNIZED(TypeCode.UNRECOGNIZED, "unknown"), @@ -243,6 +267,8 @@ public enum Code { STRING(TypeCode.STRING, "character varying"), JSON(TypeCode.JSON, "unknown"), PG_JSONB(TypeCode.JSON, "jsonb", TypeAnnotationCode.PG_JSONB), + PROTO(TypeCode.PROTO, "proto"), + ENUM(TypeCode.ENUM, "enum"), BYTES(TypeCode.BYTES, "bytea"), TIMESTAMP(TypeCode.TIMESTAMP, "timestamp with time zone"), DATE(TypeCode.DATE, "date"), @@ -373,6 +399,17 @@ public List getStructFields() { return structFields; } + /** + * Returns the full package name for elements of this {@code Proto or @code Enum} type. + * + * @throws IllegalStateException if {@code code() != Code.PROTO or code() != Code.ENUM} + */ + public String getProtoTypeFqn() { + Preconditions.checkState( + (code == Code.PROTO || code == Code.ENUM), "Illegal call for non-Proto type"); + return protoTypeFqn; + } + /** * Returns the index of the field named {@code fieldName} in this {@code STRUCT} type. * @@ -488,7 +525,8 @@ public boolean equals(Object o) { } return code == that.code && Objects.equals(arrayElementType, that.arrayElementType) - && Objects.equals(structFields, that.structFields); + && Objects.equals(structFields, that.structFields) + && Objects.equals(protoTypeFqn, that.protoTypeFqn); } @Override @@ -513,7 +551,10 @@ com.google.spanner.v1.Type toProto() { for (StructField field : structFields) { fields.addFieldsBuilder().setName(field.getName()).setType(field.getType().toProto()); } + } else if (code == Code.PROTO || code == Code.ENUM) { + proto.setProtoTypeFqn(protoTypeFqn); } + return proto.build(); } @@ -542,6 +583,10 @@ static Type fromProto(com.google.spanner.v1.Type proto) { return timestamp(); case DATE: return date(); + case PROTO: + return proto(proto.getProtoTypeFqn()); + case ENUM: + return protoEnum(proto.getProtoTypeFqn()); case ARRAY: checkArgument( proto.hasArrayElementType(), diff --git a/google-cloud-spanner/src/main/java/com/google/cloud/spanner/Value.java b/google-cloud-spanner/src/main/java/com/google/cloud/spanner/Value.java index c30847d6fe3..7cc7b675780 100644 --- a/google-cloud-spanner/src/main/java/com/google/cloud/spanner/Value.java +++ b/google-cloud-spanner/src/main/java/com/google/cloud/spanner/Value.java @@ -26,19 +26,28 @@ import com.google.common.collect.ImmutableList; import com.google.common.collect.Iterables; import com.google.common.collect.Lists; +import com.google.common.io.CharSource; +import com.google.protobuf.AbstractMessage; +import com.google.protobuf.Descriptors.Descriptor; +import com.google.protobuf.Descriptors.EnumDescriptor; +import com.google.protobuf.InvalidProtocolBufferException; import com.google.protobuf.ListValue; import com.google.protobuf.NullValue; +import com.google.protobuf.ProtocolMessageEnum; import com.google.protobuf.Value.KindCase; import java.io.IOException; import java.io.Serializable; import java.math.BigDecimal; +import java.nio.charset.StandardCharsets; import java.util.ArrayList; import java.util.Arrays; +import java.util.Base64; import java.util.BitSet; import java.util.Collection; import java.util.Collections; import java.util.List; import java.util.Objects; +import java.util.function.Function; import java.util.stream.Collectors; import javax.annotation.Nonnull; import javax.annotation.Nullable; @@ -232,7 +241,87 @@ public static Value pgJsonb(@Nullable String v) { } /** - * Returns a {@code BYTES} value. + * Return a {@code PROTO} value for not null proto messages. + * + * @param v Not null Proto message. + */ + public static Value protoMessage(AbstractMessage v) { + Preconditions.checkNotNull( + v, "Use protoMessage((ByteArray) null, MyProtoClass.getDescriptor()) for null values."); + return protoMessage( + ByteArray.copyFrom(v.toByteArray()), v.getDescriptorForType().getFullName()); + } + + /** + * Return a {@code PROTO} value + * + * @param v Serialized Proto Array, which may be null. + * @param protoTypeFqn Fully qualified name of proto representing the proto definition. Use static + * method from proto class {@code MyProtoClass.getDescriptor().getFullName()} + */ + public static Value protoMessage(@Nullable ByteArray v, String protoTypeFqn) { + return new ProtoMessageImpl(v == null, v, protoTypeFqn); + } + + /** + * Return a {@code PROTO} value + * + * @param v Serialized Proto Array, which may be null. + * @param descriptor Proto Type Descriptor, use static method from proto class {@code + * MyProtoClass.getDescriptor()}. + */ + public static Value protoMessage(@Nullable ByteArray v, Descriptor descriptor) { + Preconditions.checkNotNull(descriptor, "descriptor can't be null."); + return protoMessage(v, descriptor.getFullName()); + } + + /** + * Return a {@code ENUM} value for not null proto messages. + * + * @param v Proto Enum, which may be null. + */ + public static Value protoEnum(ProtocolMessageEnum v) { + Preconditions.checkNotNull( + v, "Use protoEnum((Long) null, MyProtoEnum.getDescriptor()) for null values."); + return protoEnum(v.getNumber(), v.getDescriptorForType().getFullName()); + } + + /** + * Return a {@code ENUM} value. + * + * @param v Enum non-primitive Integer constant. + * @param protoTypeFqn Fully qualified name of proto representing the enum definition. Use static + * method from proto class {@code MyProtoEnum.getDescriptor().getFullName()} + */ + public static Value protoEnum(@Nullable Long v, String protoTypeFqn) { + return new ProtoEnumImpl(v == null, v, protoTypeFqn); + } + + /** + * Return a {@code ENUM} value. + * + * @param v Enum non-primitive Integer constant. + * @param enumDescriptor Enum Type Descriptor. Use static method from proto class {@code * + * MyProtoEnum.getDescriptor()}. + */ + public static Value protoEnum(@Nullable Long v, EnumDescriptor enumDescriptor) { + Preconditions.checkNotNull(enumDescriptor, "descriptor can't be null."); + return protoEnum(v, enumDescriptor.getFullName()); + } + + /** + * Return a {@code ENUM} value. + * + * @param v Enum integer primitive constant. + * @param protoTypeFqn Fully qualified name of proto representing the enum definition. Use static + * method from proto class {@code MyProtoEnum.getDescriptor().getFullName()} + */ + public static Value protoEnum(long v, String protoTypeFqn) { + return new ProtoEnumImpl(false, v, protoTypeFqn); + } + + /** + * e Returns a {@code BYTES} value. Returns a {@code BYTES} value. * * @param v the value, which may be null */ @@ -450,6 +539,85 @@ public static Value pgJsonbArray(@Nullable Iterable v) { return new PgJsonbArrayImpl(v == null, v == null ? null : immutableCopyOf(v)); } + /** + * Returns an {@code ARRAY} value. + * + * @param v the source of element values. This may be {@code null} to produce a value for which + * {@code isNull()} is {@code true}. Individual elements may also be {@code null}. + * @param descriptor Proto Type Descriptor, use static method from proto class {@code + * MyProtoClass.getDescriptor()}. + */ + public static Value protoMessageArray( + @Nullable Iterable v, Descriptor descriptor) { + if (v == null) { + return new ProtoMessageArrayImpl(true, null, descriptor.getFullName()); + } + + List serializedArray = new ArrayList<>(); + v.forEach( + (message) -> { + if (message != null) { + serializedArray.add(ByteArray.copyFrom(message.toByteArray())); + } else { + serializedArray.add(null); + } + }); + + return new ProtoMessageArrayImpl(false, serializedArray, descriptor.getFullName()); + } + + /** + * Returns an {@code ARRAY} value. + * + * @param v the source of element values. This may be {@code null} to produce a value for which + * {@code isNull()} is {@code true}. Individual elements may also be {@code null}. + * @param protoTypeFqn Fully qualified name of proto representing the proto definition. Use static + * method from proto class {@code MyProtoClass.getDescriptor().getFullName()} + */ + public static Value protoMessageArray(@Nullable Iterable v, String protoTypeFqn) { + return new ProtoMessageArrayImpl( + v == null, v != null ? immutableCopyOf(v) : null, protoTypeFqn); + } + + /** + * Returns an {@code ARRAY} value. + * + * @param v the source of element values. This may be {@code null} to produce a value for which + * {@code isNull()} is {@code true}. Individual elements may also be {@code null}. + * @param descriptor Proto Type Descriptor, use static method from proto class {@code + * MyProtoClass.getDescriptor()}. + */ + public static Value protoEnumArray( + @Nullable Iterable v, EnumDescriptor descriptor) { + if (v == null) { + return new ProtoEnumArrayImpl(true, null, descriptor.getFullName()); + } + + List enumConstValues = new ArrayList<>(); + v.forEach( + (protoEnum) -> { + if (protoEnum != null) { + enumConstValues.add((long) protoEnum.getNumber()); + } else { + enumConstValues.add(null); + } + }); + + return new ProtoEnumArrayImpl(false, enumConstValues, descriptor.getFullName()); + } + + /** + * Returns an {@code ARRAY} value. + * + * @param v the source of element values. This may be {@code null} to produce a value for which + * {@code isNull()} is {@code true}. Individual elements may also be {@code null}. + * @param protoTypeFqn Fully qualified name of proto representing the enum definition. Use static + * method from proto class {@code MyProtoEnum.getDescriptor().getFullName()} + */ + public static Value protoEnumArray(@Nullable Iterable v, String protoTypeFqn) { + return new ProtoEnumArrayImpl(v == null, v != null ? immutableCopyOf(v) : null, protoTypeFqn); + } + /** * Returns an {@code ARRAY} value. * @@ -600,6 +768,25 @@ public String getPgJsonb() { throw new UnsupportedOperationException("Not implemented"); } + /** + * Returns the value of a {@code PROTO}-typed instance. + * + * @throws IllegalStateException if {@code isNull()} or the value is not of the expected type + */ + public T getProtoMessage(T m) { + throw new UnsupportedOperationException("Not implemented"); + } + + /** + * Returns the value of a {@code ENUM}-typed instance. + * + * @throws IllegalStateException if {@code isNull()} or the value is not of the expected type + */ + public T getProtoEnum( + Function method) { + throw new UnsupportedOperationException("Not implemented"); + } + /** * Returns the value of a {@code BYTES}-typed instance. * @@ -692,6 +879,27 @@ public List getPgJsonbArray() { throw new UnsupportedOperationException("Not implemented"); } + /** + * Returns the value of an {@code ARRAY}-typed instance. While the returned list itself + * will never be {@code null}, elements of that list may be null. + * + * @throws IllegalStateException if {@code isNull()} or the value is not of the expected type + */ + public List getProtoMessageArray(T m) { + throw new UnsupportedOperationException("Not implemented"); + } + + /** + * Returns the value of an {@code ARRAY}-typed instance. While the returned list itself will + * never be {@code null}, elements of that list may be null. + * + * @throws IllegalStateException if {@code isNull()} or the value is not of the expected type + */ + public List getProtoEnumArray( + Function method) { + throw new UnsupportedOperationException("Not implemented"); + } + /** * Returns the value of an {@code ARRAY}-typed instance. While the returned list itself * will never be {@code null}, elements of that list may be null. @@ -1254,6 +1462,15 @@ public long getInt64() { return value; } + @Override + public T getProtoEnum( + Function method) { + Preconditions.checkNotNull( + method, "Method may not be null. Use 'MyProtoEnum::forNumber' as a parameter value."); + checkNotNull(); + return (T) method.apply((int) value); + } + @Override com.google.protobuf.Value valueToProto() { return com.google.protobuf.Value.newBuilder().setStringValue(Long.toString(value)).build(); @@ -1463,6 +1680,27 @@ public ByteArray getBytes() { return value.getByteArray(); } + @Override + public T getProtoMessage(T m) { + Preconditions.checkNotNull( + m, + "Proto message may not be null. Use MyProtoClass.getDefaultInstance() as a parameter value."); + checkNotNull(); + try { + return (T) + m.toBuilder() + .mergeFrom( + Base64.getDecoder() + .wrap( + CharSource.wrap(value.getBase64String()) + .asByteSource(StandardCharsets.UTF_8) + .openStream())) + .build(); + } catch (IOException ioException) { + throw SpannerExceptionFactory.asSpannerException(ioException); + } + } + @Override com.google.protobuf.Value valueToProto() { return com.google.protobuf.Value.newBuilder().setStringValue(value.getBase64String()).build(); @@ -1480,6 +1718,75 @@ void valueToString(StringBuilder b) { } } + private static class ProtoMessageImpl extends AbstractObjectValue { + + private ProtoMessageImpl(boolean isNull, ByteArray serializedProtoArray, String protoTypeFqn) { + super(isNull, Type.proto(protoTypeFqn), serializedProtoArray); + } + + @Override + public ByteArray getBytes() { + checkNotNull(); + return value; + } + + @Override + public T getProtoMessage(T m) { + Preconditions.checkNotNull( + m, + "Proto message may not be null. Use MyProtoClass.getDefaultInstance() as a parameter value."); + checkNotNull(); + try { + return (T) m.toBuilder().mergeFrom(value.toByteArray()).build(); + } catch (InvalidProtocolBufferException e) { + throw SpannerExceptionFactory.asSpannerException(e); + } + } + + @Override + com.google.protobuf.Value valueToProto() { + String base64EncodedString = value.toBase64(); + return com.google.protobuf.Value.newBuilder().setStringValue(base64EncodedString).build(); + } + + @Override + void valueToString(StringBuilder b) { + b.append(value.toString()); + } + } + + private static class ProtoEnumImpl extends AbstractObjectValue { + + private ProtoEnumImpl(boolean isNull, Long enumValue, String protoTypeFqn) { + super(isNull, Type.protoEnum(protoTypeFqn), enumValue); + } + + @Override + public long getInt64() { + checkNotNull(); + return value; + } + + @Override + public T getProtoEnum( + Function method) { + Preconditions.checkNotNull( + method, "Method may not be null. Use 'MyProtoEnum::forNumber' as a parameter value."); + checkNotNull(); + return (T) method.apply(value.intValue()); + } + + @Override + void valueToString(StringBuilder b) { + b.append(value.toString()); + } + + @Override + com.google.protobuf.Value valueToProto() { + return com.google.protobuf.Value.newBuilder().setStringValue(Long.toString(value)).build(); + } + } + private static class TimestampImpl extends AbstractObjectValue { private static final String COMMIT_TIMESTAMP_STRING = "spanner.commit_timestamp()"; @@ -1742,6 +2049,24 @@ public List getInt64Array() { return getArray(); } + @Override + public List getProtoEnumArray( + Function method) { + Preconditions.checkNotNull( + method, "Method may not be null. Use 'MyProtoEnum::forNumber' as a parameter value."); + checkNotNull(); + + List protoEnumList = new ArrayList<>(); + for (Long enumIntValue : values) { + if (enumIntValue == null) { + protoEnumList.add(null); + } else { + protoEnumList.add((T) method.apply(enumIntValue.intValue())); + } + } + return protoEnumList; + } + @Override boolean valueEquals(Value v) { Int64ArrayImpl that = (Int64ArrayImpl) v; @@ -1962,6 +2287,36 @@ public List getBytesArray() { } } + @Override + public List getProtoMessageArray(T m) { + Preconditions.checkNotNull( + m, + "Proto message may not be null. Use MyProtoClass.getDefaultInstance() as a parameter value."); + checkNotNull(); + try { + List protoMessagesList = new ArrayList<>(value.size()); + for (LazyByteArray protoMessageBytes : value) { + if (protoMessageBytes == null) { + protoMessagesList.add(null); + } else { + protoMessagesList.add( + (T) + m.toBuilder() + .mergeFrom( + Base64.getDecoder() + .wrap( + CharSource.wrap(protoMessageBytes.getBase64String()) + .asByteSource(StandardCharsets.UTF_8) + .openStream())) + .build()); + } + } + return protoMessagesList; + } catch (IOException e) { + throw new RuntimeException(e); + } + } + @Override String elementToString(LazyByteArray element) { return element.getBase64String(); @@ -1991,6 +2346,91 @@ void appendElement(StringBuilder b, Timestamp element) { } } + private static class ProtoMessageArrayImpl extends AbstractArrayValue { + + private ProtoMessageArrayImpl( + boolean isNull, @Nullable List values, String protoTypeFqn) { + super(isNull, Type.proto(protoTypeFqn), values); + } + + @Override + public List getBytesArray() { + return value; + } + + @Override + public List getProtoMessageArray(T m) { + Preconditions.checkNotNull( + m, + "Proto message may not be null. Use MyProtoClass.getDefaultInstance() as a parameter value."); + checkNotNull(); + try { + List protoMessagesList = new ArrayList<>(value.size()); + for (ByteArray protoMessageBytes : value) { + if (protoMessageBytes == null) { + protoMessagesList.add(null); + } else { + protoMessagesList.add( + (T) m.toBuilder().mergeFrom(protoMessageBytes.toByteArray()).build()); + } + } + return protoMessagesList; + } catch (InvalidProtocolBufferException e) { + throw SpannerExceptionFactory.asSpannerException(e); + } + } + + @Override + String elementToString(ByteArray element) { + return element.toBase64(); + } + + @Override + void appendElement(StringBuilder b, ByteArray element) { + b.append(element.toString()); + } + } + + private static class ProtoEnumArrayImpl extends AbstractArrayValue { + + private ProtoEnumArrayImpl(boolean isNull, @Nullable List values, String protoTypeFqn) { + super(isNull, Type.protoEnum(protoTypeFqn), values); + } + + @Override + public List getInt64Array() { + return value; + } + + @Override + public List getProtoEnumArray( + Function method) { + Preconditions.checkNotNull( + method, "Method may not be null. Use 'MyProtoEnum::forNumber' as a parameter value."); + checkNotNull(); + + List protoEnumList = new ArrayList<>(); + for (Long enumIntValue : value) { + if (enumIntValue == null) { + protoEnumList.add(null); + } else { + protoEnumList.add((T) method.apply(enumIntValue.intValue())); + } + } + return protoEnumList; + } + + @Override + String elementToString(Long element) { + return Long.toString(element); + } + + @Override + void appendElement(StringBuilder b, Long element) { + b.append(element); + } + } + private static class DateArrayImpl extends AbstractArrayValue { private DateArrayImpl(boolean isNull, @Nullable List values) { @@ -2148,6 +2588,10 @@ private Value getValue(int fieldIndex) { return Value.date(value.getDate(fieldIndex)); case TIMESTAMP: return Value.timestamp(value.getTimestamp(fieldIndex)); + case PROTO: + return Value.protoMessage(value.getBytes(fieldIndex), fieldType.getProtoTypeFqn()); + case ENUM: + return Value.protoEnum(value.getLong(fieldIndex), fieldType.getProtoTypeFqn()); case STRUCT: return Value.struct(value.getStruct(fieldIndex)); case ARRAY: @@ -2157,6 +2601,7 @@ private Value getValue(int fieldIndex) { case BOOL: return Value.boolArray(value.getBooleanList(fieldIndex)); case INT64: + case ENUM: return Value.int64Array(value.getLongList(fieldIndex)); case STRING: return Value.stringArray(value.getStringList(fieldIndex)); @@ -2165,6 +2610,7 @@ private Value getValue(int fieldIndex) { case PG_JSONB: return Value.pgJsonbArray(value.getPgJsonbList(fieldIndex)); case BYTES: + case PROTO: return Value.bytesArray(value.getBytesList(fieldIndex)); case FLOAT64: return Value.float64Array(value.getDoubleList(fieldIndex)); diff --git a/google-cloud-spanner/src/main/java/com/google/cloud/spanner/ValueBinder.java b/google-cloud-spanner/src/main/java/com/google/cloud/spanner/ValueBinder.java index 07066470da6..9915e12175a 100644 --- a/google-cloud-spanner/src/main/java/com/google/cloud/spanner/ValueBinder.java +++ b/google-cloud-spanner/src/main/java/com/google/cloud/spanner/ValueBinder.java @@ -19,6 +19,10 @@ import com.google.cloud.ByteArray; import com.google.cloud.Date; import com.google.cloud.Timestamp; +import com.google.protobuf.AbstractMessage; +import com.google.protobuf.Descriptors.Descriptor; +import com.google.protobuf.Descriptors.EnumDescriptor; +import com.google.protobuf.ProtocolMessageEnum; import java.math.BigDecimal; import javax.annotation.Nullable; @@ -97,6 +101,41 @@ public R to(@Nullable String value) { return handle(Value.string(value)); } + /** Binds to {@code Value.protoMessage(value)} */ + public R to(AbstractMessage m) { + return handle(Value.protoMessage(m)); + } + + /** Binds to {@code Value.protoMessage(value, protoType)} */ + public R to(@Nullable ByteArray v, String protoTypFqn) { + return handle(Value.protoMessage(v, protoTypFqn)); + } + + /** Binds to {@code Value.protoMessage(value, descriptor)} */ + public R to(@Nullable ByteArray v, Descriptor descriptor) { + return handle(Value.protoMessage(v, descriptor)); + } + + /** Binds to {@code Value.protoEnum(value)} */ + public R to(ProtocolMessageEnum value) { + return handle(Value.protoEnum(value)); + } + + /** Binds to {@code Value.protoEnum(value, protoType)} */ + public R to(@Nullable Long v, String protoTypFqn) { + return handle(Value.protoEnum(v, protoTypFqn)); + } + + /** Binds to {@code Value.protoEnum(value, enumDescriptor)} */ + public R to(@Nullable Long v, EnumDescriptor enumDescriptor) { + return handle(Value.protoEnum(v, enumDescriptor)); + } + + /** Binds to {@code Value.protoEnum(value, protoType)} */ + public R to(long v, String protoTypFqn) { + return handle(Value.protoEnum(v, protoTypFqn)); + } + /** * Binds to {@code Value.bytes(value)}. Use {@link #to(Value)} in combination with {@link * Value#bytesFromBase64(String)} if you already have the value that you want to bind in base64 @@ -218,6 +257,27 @@ public R toTimestampArray(@Nullable Iterable values) { return handle(Value.timestampArray(values)); } + /** Binds to {@code Value.protoMessageArray(values, descriptor)} */ + public R toProtoMessageArray(@Nullable Iterable values, Descriptor descriptor) { + return handle(Value.protoMessageArray(values, descriptor)); + } + + /** Binds to {@code Value.protoMessageArray(values, protoTypeFq)} */ + public R toProtoMessageArray(@Nullable Iterable values, String protoTypeFq) { + return handle(Value.protoMessageArray(values, protoTypeFq)); + } + + /** Binds to {@code Value.protoEnumArray(values, descriptor)} */ + public R toProtoEnumArray( + @Nullable Iterable values, EnumDescriptor descriptor) { + return handle(Value.protoEnumArray(values, descriptor)); + } + + /** Binds to {@code Value.protoEnumArray(values, protoTypeFq)} */ + public R toProtoEnumArray(@Nullable Iterable values, String protoTypeFq) { + return handle(Value.protoEnumArray(values, protoTypeFq)); + } + /** Binds to {@code Value.dateArray(values)} */ public R toDateArray(@Nullable Iterable values) { return handle(Value.dateArray(values)); diff --git a/google-cloud-spanner/src/main/java/com/google/cloud/spanner/connection/ChecksumResultSet.java b/google-cloud-spanner/src/main/java/com/google/cloud/spanner/connection/ChecksumResultSet.java index bb2f2fb817a..24389546669 100644 --- a/google-cloud-spanner/src/main/java/com/google/cloud/spanner/connection/ChecksumResultSet.java +++ b/google-cloud-spanner/src/main/java/com/google/cloud/spanner/connection/ChecksumResultSet.java @@ -225,6 +225,7 @@ public void funnel(Struct row, PrimitiveSink into) { funnelValue(type, row.getBoolean(i), into); break; case BYTES: + case PROTO: funnelValue(type, row.getBytes(i), into); break; case DATE: @@ -240,6 +241,7 @@ public void funnel(Struct row, PrimitiveSink into) { funnelValue(type, row.getString(i), into); break; case INT64: + case ENUM: funnelValue(type, row.getLong(i), into); break; case STRING: @@ -274,6 +276,7 @@ private void funnelArray( } break; case BYTES: + case PROTO: into.putInt(row.getBytesList(columnIndex).size()); for (ByteArray value : row.getBytesList(columnIndex)) { funnelValue(Code.BYTES, value, into); @@ -304,6 +307,7 @@ private void funnelArray( } break; case INT64: + case ENUM: into.putInt(row.getLongList(columnIndex).size()); for (Long value : row.getLongList(columnIndex)) { funnelValue(Code.INT64, value, into); @@ -357,6 +361,7 @@ private void funnelValue(Code type, T value, PrimitiveSink into) { into.putBoolean((Boolean) value); break; case BYTES: + case PROTO: ByteArray byteArray = (ByteArray) value; into.putInt(byteArray.length()); into.putBytes(byteArray.toByteArray()); @@ -374,6 +379,7 @@ private void funnelValue(Code type, T value, PrimitiveSink into) { into.putUnencodedChars(stringRepresentation); break; case INT64: + case ENUM: into.putLong((Long) value); break; case PG_NUMERIC: diff --git a/google-cloud-spanner/src/main/java/com/google/cloud/spanner/connection/DirectExecuteResultSet.java b/google-cloud-spanner/src/main/java/com/google/cloud/spanner/connection/DirectExecuteResultSet.java index 8690e154f4e..dff915e2cce 100644 --- a/google-cloud-spanner/src/main/java/com/google/cloud/spanner/connection/DirectExecuteResultSet.java +++ b/google-cloud-spanner/src/main/java/com/google/cloud/spanner/connection/DirectExecuteResultSet.java @@ -25,10 +25,13 @@ import com.google.cloud.spanner.Type; import com.google.cloud.spanner.Value; import com.google.common.base.Preconditions; +import com.google.protobuf.AbstractMessage; +import com.google.protobuf.ProtocolMessageEnum; import com.google.spanner.v1.ResultSetMetadata; import com.google.spanner.v1.ResultSetStats; import java.math.BigDecimal; import java.util.List; +import java.util.function.Function; /** * {@link ResultSet} implementation used by the Spanner connection API to ensure that the query for @@ -425,6 +428,32 @@ public List getDateList(String columnName) { return delegate.getDateList(columnName); } + @Override + public List getProtoMessageList(int columnIndex, T message) { + Preconditions.checkState(nextCalledByClient, MISSING_NEXT_CALL); + return delegate.getProtoMessageList(columnIndex, message); + } + + @Override + public List getProtoMessageList(String columnName, T message) { + Preconditions.checkState(nextCalledByClient, MISSING_NEXT_CALL); + return delegate.getProtoMessageList(columnName, message); + } + + @Override + public List getProtoEnumList( + int columnIndex, Function method) { + Preconditions.checkState(nextCalledByClient, MISSING_NEXT_CALL); + return delegate.getProtoEnumList(columnIndex, method); + } + + @Override + public List getProtoEnumList( + String columnName, Function method) { + Preconditions.checkState(nextCalledByClient, MISSING_NEXT_CALL); + return delegate.getProtoEnumList(columnName, method); + } + @Override public List getStructList(int columnIndex) { Preconditions.checkState(nextCalledByClient, MISSING_NEXT_CALL); @@ -437,6 +466,32 @@ public List getStructList(String columnName) { return delegate.getStructList(columnName); } + @Override + public T getProtoEnum( + int columnIndex, Function method) { + Preconditions.checkState(nextCalledByClient, MISSING_NEXT_CALL); + return delegate.getProtoEnum(columnIndex, method); + } + + @Override + public T getProtoEnum( + String columnName, Function method) { + Preconditions.checkState(nextCalledByClient, MISSING_NEXT_CALL); + return delegate.getProtoEnum(columnName, method); + } + + @Override + public T getProtoMessage(int columnIndex, T message) { + Preconditions.checkState(nextCalledByClient, MISSING_NEXT_CALL); + return delegate.getProtoMessage(columnIndex, message); + } + + @Override + public T getProtoMessage(String columnName, T message) { + Preconditions.checkState(nextCalledByClient, MISSING_NEXT_CALL); + return delegate.getProtoMessage(columnName, message); + } + @Override public boolean equals(Object o) { if (!(o instanceof DirectExecuteResultSet)) { diff --git a/google-cloud-spanner/src/main/java/com/google/cloud/spanner/connection/ReplaceableForwardingResultSet.java b/google-cloud-spanner/src/main/java/com/google/cloud/spanner/connection/ReplaceableForwardingResultSet.java index 07e755b2b25..7370551a46f 100644 --- a/google-cloud-spanner/src/main/java/com/google/cloud/spanner/connection/ReplaceableForwardingResultSet.java +++ b/google-cloud-spanner/src/main/java/com/google/cloud/spanner/connection/ReplaceableForwardingResultSet.java @@ -27,10 +27,13 @@ import com.google.cloud.spanner.Type; import com.google.cloud.spanner.Value; import com.google.common.base.Preconditions; +import com.google.protobuf.AbstractMessage; +import com.google.protobuf.ProtocolMessageEnum; import com.google.spanner.v1.ResultSetMetadata; import com.google.spanner.v1.ResultSetStats; import java.math.BigDecimal; import java.util.List; +import java.util.function.Function; /** * Forwarding implementation of {@link ResultSet} that forwards all calls to a delegate that can be @@ -430,6 +433,32 @@ public List getDateList(String columnName) { return delegate.getDateList(columnName); } + @Override + public List getProtoMessageList(int columnIndex, T message) { + checkClosed(); + return delegate.getProtoMessageList(columnIndex, message); + } + + @Override + public List getProtoMessageList(String columnName, T message) { + checkClosed(); + return delegate.getProtoMessageList(columnName, message); + } + + @Override + public List getProtoEnumList( + int columnIndex, Function method) { + checkClosed(); + return delegate.getProtoEnumList(columnIndex, method); + } + + @Override + public List getProtoEnumList( + String columnName, Function method) { + checkClosed(); + return delegate.getProtoEnumList(columnName, method); + } + @Override public List getStructList(int columnIndex) { checkClosed(); @@ -441,4 +470,30 @@ public List getStructList(String columnName) { checkClosed(); return delegate.getStructList(columnName); } + + @Override + public T getProtoMessage(int columnIndex, T message) { + checkClosed(); + return delegate.getProtoMessage(columnIndex, message); + } + + @Override + public T getProtoMessage(String columnName, T message) { + checkClosed(); + return delegate.getProtoMessage(columnName, message); + } + + @Override + public T getProtoEnum( + int columnIndex, Function method) { + checkClosed(); + return delegate.getProtoEnum(columnIndex, method); + } + + @Override + public T getProtoEnum( + String columnName, Function method) { + checkClosed(); + return delegate.getProtoEnum(columnName, method); + } } diff --git a/google-cloud-spanner/src/main/java/com/google/cloud/spanner/spi/v1/GapicSpannerRpc.java b/google-cloud-spanner/src/main/java/com/google/cloud/spanner/spi/v1/GapicSpannerRpc.java index d75b6636a56..a65e533338f 100644 --- a/google-cloud-spanner/src/main/java/com/google/cloud/spanner/spi/v1/GapicSpannerRpc.java +++ b/google-cloud-spanner/src/main/java/com/google/cloud/spanner/spi/v1/GapicSpannerRpc.java @@ -118,6 +118,7 @@ import com.google.spanner.admin.database.v1.DropDatabaseRequest; import com.google.spanner.admin.database.v1.GetBackupRequest; import com.google.spanner.admin.database.v1.GetDatabaseDdlRequest; +import com.google.spanner.admin.database.v1.GetDatabaseDdlResponse; import com.google.spanner.admin.database.v1.GetDatabaseRequest; import com.google.spanner.admin.database.v1.ListBackupOperationsRequest; import com.google.spanner.admin.database.v1.ListBackupOperationsResponse; @@ -1156,8 +1157,10 @@ public OperationFuture createDatabase( if (databaseInfo.getDialect() != null) { requestBuilder.setDatabaseDialect(databaseInfo.getDialect().toProto()); } + if (databaseInfo.getProtoDescriptors() != null) { + requestBuilder.setProtoDescriptors(databaseInfo.getProtoDescriptors()); + } final CreateDatabaseRequest request = requestBuilder.build(); - OperationFutureCallable callable = new OperationFutureCallable<>( databaseAdminStub.createDatabaseOperationCallable(), @@ -1212,19 +1215,27 @@ public OperationFuture createDatabase( */ @Override public OperationFuture updateDatabaseDdl( - final String databaseName, + com.google.cloud.spanner.Database databaseInfo, final Iterable updateDatabaseStatements, @Nullable final String updateId) throws SpannerException { acquireAdministrativeRequestsRateLimiter(); - final UpdateDatabaseDdlRequest request = + Preconditions.checkNotNull(databaseInfo.getId()); + UpdateDatabaseDdlRequest.Builder requestBuilder = UpdateDatabaseDdlRequest.newBuilder() - .setDatabase(databaseName) + .setDatabase(databaseInfo.getId().getName()) .addAllStatements(updateDatabaseStatements) - .setOperationId(MoreObjects.firstNonNull(updateId, "")) - .build(); + .setOperationId(MoreObjects.firstNonNull(updateId, "")); + if (databaseInfo.getProtoDescriptors() != null) { + requestBuilder.setProtoDescriptors(databaseInfo.getProtoDescriptors()); + } + final UpdateDatabaseDdlRequest request = requestBuilder.build(); final GrpcCallContext context = - newCallContext(null, databaseName, request, DatabaseAdminGrpc.getUpdateDatabaseDdlMethod()); + newCallContext( + null, + databaseInfo.getId().getName(), + request, + DatabaseAdminGrpc.getUpdateDatabaseDdlMethod()); final OperationCallable callable = databaseAdminStub.updateDatabaseDdlOperationCallable(); @@ -1246,7 +1257,7 @@ public OperationFuture updateDatabaseDdl( if (t instanceof AlreadyExistsException) { String operationName = OPERATION_NAME_TEMPLATE.instantiate( - "database", databaseName, "operation", updateId); + "database", databaseInfo.getId().getName(), "operation", updateId); return callable.resumeFutureCall(operationName, context); } } @@ -1293,7 +1304,7 @@ public OperationFuture updateDatabase( } @Override - public List getDatabaseDdl(String databaseName) throws SpannerException { + public GetDatabaseDdlResponse getDatabaseDdl(String databaseName) throws SpannerException { acquireAdministrativeRequestsRateLimiter(); final GetDatabaseDdlRequest request = GetDatabaseDdlRequest.newBuilder().setDatabase(databaseName).build(); @@ -1301,9 +1312,7 @@ public List getDatabaseDdl(String databaseName) throws SpannerException final GrpcCallContext context = newCallContext(null, databaseName, request, DatabaseAdminGrpc.getGetDatabaseDdlMethod()); return runWithRetryOnAdministrativeRequestsExceeded( - () -> - get(databaseAdminStub.getDatabaseDdlCallable().futureCall(request, context)) - .getStatementsList()); + () -> get(databaseAdminStub.getDatabaseDdlCallable().futureCall(request, context))); } @Override diff --git a/google-cloud-spanner/src/main/java/com/google/cloud/spanner/spi/v1/SpannerRpc.java b/google-cloud-spanner/src/main/java/com/google/cloud/spanner/spi/v1/SpannerRpc.java index 39f798e0113..89659e4741e 100644 --- a/google-cloud-spanner/src/main/java/com/google/cloud/spanner/spi/v1/SpannerRpc.java +++ b/google-cloud-spanner/src/main/java/com/google/cloud/spanner/spi/v1/SpannerRpc.java @@ -43,6 +43,7 @@ import com.google.spanner.admin.database.v1.CreateDatabaseMetadata; import com.google.spanner.admin.database.v1.Database; import com.google.spanner.admin.database.v1.DatabaseRole; +import com.google.spanner.admin.database.v1.GetDatabaseDdlResponse; import com.google.spanner.admin.database.v1.RestoreDatabaseMetadata; import com.google.spanner.admin.database.v1.UpdateDatabaseDdlMetadata; import com.google.spanner.admin.database.v1.UpdateDatabaseMetadata; @@ -233,7 +234,9 @@ OperationFuture createDatabase( throws SpannerException; OperationFuture updateDatabaseDdl( - String databaseName, Iterable updateDatabaseStatements, @Nullable String updateId) + com.google.cloud.spanner.Database database, + Iterable updateDatabaseStatements, + @Nullable String updateId) throws SpannerException; void dropDatabase(String databaseName) throws SpannerException; @@ -253,7 +256,7 @@ OperationFuture updateDatabaseDdl( OperationFuture updateDatabase( Database database, FieldMask fieldMask) throws SpannerException; - List getDatabaseDdl(String databaseName) throws SpannerException; + GetDatabaseDdlResponse getDatabaseDdl(String databaseName) throws SpannerException; /** Lists the backups in the specified instance. */ Paginated listBackups( String instanceName, int pageSize, @Nullable String filter, @Nullable String pageToken) diff --git a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/AbstractStructReaderTypesTest.java b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/AbstractStructReaderTypesTest.java index 1b6280a6369..4fc3c67ceba 100644 --- a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/AbstractStructReaderTypesTest.java +++ b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/AbstractStructReaderTypesTest.java @@ -27,6 +27,8 @@ import com.google.cloud.Date; import com.google.cloud.Timestamp; import com.google.common.base.Throwables; +import com.google.protobuf.AbstractMessage; +import com.google.protobuf.ProtocolMessageEnum; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.math.BigDecimal; @@ -34,6 +36,7 @@ import java.util.Collection; import java.util.Collections; import java.util.List; +import java.util.function.Function; import javax.annotation.Nullable; import org.junit.Before; import org.junit.Test; @@ -95,6 +98,17 @@ protected Date getDateInternal(int columnIndex) { return null; } + @Override + protected T getProtoMessageInternal(int columnIndex, T message) { + return null; + } + + @Override + protected T getProtoEnumInternal( + int columnIndex, Function method) { + return null; + } + @Override protected Value getValueInternal(int columnIndex) { return null; @@ -160,6 +174,18 @@ protected List getTimestampListInternal(int columnIndex) { return null; } + @Override + protected List getProtoMessageListInternal( + int columnIndex, T message) { + return null; + } + + @Override + protected List getProtoEnumListInternal( + int columnIndex, Function method) { + return null; + } + @Override protected List getDateListInternal(int columnIndex) { return null; diff --git a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/DatabaseAdminClientImplTest.java b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/DatabaseAdminClientImplTest.java index ace26977bd3..8715d4e8107 100644 --- a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/DatabaseAdminClientImplTest.java +++ b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/DatabaseAdminClientImplTest.java @@ -54,6 +54,7 @@ import com.google.spanner.admin.database.v1.DatabaseDialect; import com.google.spanner.admin.database.v1.DatabaseRole; import com.google.spanner.admin.database.v1.EncryptionInfo; +import com.google.spanner.admin.database.v1.GetDatabaseDdlResponse; import com.google.spanner.admin.database.v1.RestoreDatabaseMetadata; import com.google.spanner.admin.database.v1.UpdateDatabaseDdlMetadata; import com.google.spanner.admin.database.v1.UpdateDatabaseMetadata; @@ -227,7 +228,9 @@ public void updateDatabaseDdl() throws Exception { OperationFuture rawOperationFuture = OperationFutureUtil.immediateOperationFuture( opName, Empty.getDefaultInstance(), UpdateDatabaseDdlMetadata.getDefaultInstance()); - when(rpc.updateDatabaseDdl(DB_NAME, ddl, opId)).thenReturn(rawOperationFuture); + when(rpc.updateDatabaseDdl( + client.newDatabaseBuilder(DatabaseId.of(DB_NAME)).build(), ddl, opId)) + .thenReturn(rawOperationFuture); OperationFuture op = client.updateDatabaseDdl(INSTANCE_ID, DB_ID, ddl, opId); assertThat(op.isDone()).isTrue(); @@ -245,7 +248,9 @@ public void updateDatabaseDdlOpAlreadyExists() throws Exception { UpdateDatabaseDdlMetadata.getDefaultInstance()); String newOpId = "newop"; - when(rpc.updateDatabaseDdl(DB_NAME, ddl, newOpId)).thenReturn(originalOp); + when(rpc.updateDatabaseDdl( + client.newDatabaseBuilder(DatabaseId.of(DB_NAME)).build(), ddl, newOpId)) + .thenReturn(originalOp); OperationFuture op = client.updateDatabaseDdl(INSTANCE_ID, DB_ID, ddl, newOpId); assertThat(op.getName()).isEqualTo(originalOpName); @@ -278,10 +283,25 @@ public void dropDatabase() { @Test public void getDatabaseDdl() { List ddl = ImmutableList.of("CREATE TABLE mytable()"); - when(rpc.getDatabaseDdl(DB_NAME)).thenReturn(ddl); + when(rpc.getDatabaseDdl(DB_NAME)) + .thenReturn(GetDatabaseDdlResponse.newBuilder().addAllStatements(ddl).build()); assertThat(client.getDatabaseDdl(INSTANCE_ID, DB_ID)).isEqualTo(ddl); } + @Test + public void getDatabaseDdlResponse() { + List ddl = ImmutableList.of("CREATE TABLE mytable()"); + when(rpc.getDatabaseDdl(DB_NAME)) + .thenReturn( + GetDatabaseDdlResponse.newBuilder() + .addAllStatements(ddl) + .setProtoDescriptors(ByteString.EMPTY) + .build()); + GetDatabaseDdlResponse response = client.getDatabaseDdlResponse(INSTANCE_ID, DB_ID); + assertThat(response.getStatementsList()).isEqualTo(ddl); + assertThat(response.getProtoDescriptors()).isEqualTo(ByteString.EMPTY); + } + @Test public void listDatabases() { String pageToken = "token"; diff --git a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/DatabaseTest.java b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/DatabaseTest.java index 78c04ae61bc..f49ba026d43 100644 --- a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/DatabaseTest.java +++ b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/DatabaseTest.java @@ -19,6 +19,7 @@ import static com.google.cloud.spanner.DatabaseInfo.State.CREATING; import static com.google.common.truth.Truth.assertThat; import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertThrows; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; @@ -30,10 +31,14 @@ import com.google.cloud.Timestamp; import com.google.cloud.spanner.DatabaseInfo.State; import com.google.cloud.spanner.encryption.EncryptionConfigs; +import com.google.common.io.ByteStreams; +import com.google.protobuf.ByteString; import com.google.rpc.Code; import com.google.rpc.Status; import com.google.spanner.admin.database.v1.DatabaseDialect; import com.google.spanner.admin.database.v1.EncryptionInfo; +import java.io.IOException; +import java.io.InputStream; import java.util.Collections; import java.util.List; import org.junit.Before; @@ -66,6 +71,10 @@ public class DatabaseTest { .build()); private static final String DEFAULT_LEADER = "default-leader"; private static final DatabaseDialect DEFAULT_DIALECT = DatabaseDialect.GOOGLE_STANDARD_SQL; + private static ByteString protoDescriptors; + private static byte[] protoDescriptorsByteArray; + private static final String PROTO_DESCRIPTORS_RESOURCE_PATH = + "com/google/cloud/spanner/descriptors.pb"; private static final boolean DROP_PROTECTION_ENABLED = true; @@ -83,6 +92,15 @@ public void setUp() { .thenAnswer( invocation -> new Database.Builder(dbClient, (DatabaseId) invocation.getArguments()[0])); + try { + InputStream protoDescriptorsInputStream = + getClass().getClassLoader().getResourceAsStream(PROTO_DESCRIPTORS_RESOURCE_PATH); + assertNotNull(protoDescriptorsInputStream); + protoDescriptorsByteArray = ByteStreams.toByteArray(protoDescriptorsInputStream); + protoDescriptors = ByteString.copyFrom(protoDescriptorsByteArray); + } catch (IOException e) { + e.printStackTrace(); + } } @Test @@ -198,6 +216,46 @@ public void testBuildWithDatabaseDialect() { assertEquals(Dialect.GOOGLE_STANDARD_SQL, database.getDialect()); } + @Test + public void testBuildWithProtoDescriptorsFromInputStream() throws IOException { + InputStream in = + getClass().getClassLoader().getResourceAsStream(PROTO_DESCRIPTORS_RESOURCE_PATH); + assertNotNull(in); + final Database database = + dbClient + .newDatabaseBuilder(DatabaseId.of("my-project", "my-instance", "my-database")) + .setProtoDescriptors(in) + .build(); + + assertEquals(protoDescriptors, database.getProtoDescriptors()); + } + + @Test + public void testBuildWithProtoDescriptorsFromByteArray() { + final Database database = + dbClient + .newDatabaseBuilder(DatabaseId.of("my-project", "my-instance", "my-database")) + .setProtoDescriptors(protoDescriptorsByteArray) + .build(); + + assertEquals(protoDescriptors, database.getProtoDescriptors()); + } + + @Test + public void testBuildWithProtoDescriptorsThrowsException() throws IOException { + InputStream in = + getClass().getClassLoader().getResourceAsStream(PROTO_DESCRIPTORS_RESOURCE_PATH); + in.close(); + // case1: Test one of the IOException case, where InputStream is closed before read + assertThrows( + IOException.class, + () -> + dbClient + .newDatabaseBuilder(DatabaseId.of("my-project", "my-instance", "my-database")) + .setProtoDescriptors(in) + .build()); + } + @Test public void getIAMPolicy() { Database database = diff --git a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/GrpcResultSetTest.java b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/GrpcResultSetTest.java index 82300a93090..914ce391f4a 100644 --- a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/GrpcResultSetTest.java +++ b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/GrpcResultSetTest.java @@ -27,6 +27,8 @@ import com.google.cloud.ByteArray; import com.google.cloud.Date; import com.google.cloud.Timestamp; +import com.google.cloud.spanner.SingerProto.Genre; +import com.google.cloud.spanner.SingerProto.SingerInfo; import com.google.cloud.spanner.spi.v1.SpannerRpc; import com.google.common.base.Function; import com.google.common.base.Strings; @@ -765,6 +767,68 @@ public void getPgJsonb() { assertEquals("[]", resultSet.getPgJsonb(0)); } + @Test + public void getProtoMessage() { + SingerInfo singerInfo1 = + SingerInfo.newBuilder() + .setSingerId(111) + .setNationality("COUNTRY1") + .setGenre(Genre.FOLK) + .build(); + SingerInfo singerInfo2 = SingerInfo.newBuilder().setSingerId(222).setGenre(Genre.JAZZ).build(); + String singerInfoFullName = SingerInfo.getDescriptor().getFullName(); + + consumer.onPartialResultSet( + PartialResultSet.newBuilder() + .setMetadata( + makeMetadata(Type.struct(Type.StructField.of("f", Type.proto(singerInfoFullName))))) + .addValues(Value.protoMessage(singerInfo1).toProto()) + .addValues( + Value.protoMessage( + ByteArray.copyFrom(singerInfo2.toByteArray()), singerInfoFullName) + .toProto()) + .addValues(Value.protoMessage(null, SingerInfo.getDescriptor().getFullName()).toProto()) + .build()); + consumer.onCompleted(); + + assertTrue(resultSet.next()); + assertEquals(singerInfo1, resultSet.getProtoMessage(0, SingerInfo.getDefaultInstance())); + assertTrue(resultSet.next()); + assertEquals(singerInfo2, resultSet.getProtoMessage(0, SingerInfo.getDefaultInstance())); + assertTrue(resultSet.next()); + assertThrows( + NullPointerException.class, + () -> { + resultSet.getProtoMessage(0, SingerInfo.getDefaultInstance()); + }); + } + + @Test + public void getProtoEnum() { + String genreFullyQualifiedName = Genre.getDescriptor().getFullName(); + consumer.onPartialResultSet( + PartialResultSet.newBuilder() + .setMetadata( + makeMetadata( + Type.struct(Type.StructField.of("f", Type.protoEnum(genreFullyQualifiedName))))) + .addValues(Value.protoEnum(Genre.FOLK).toProto()) + .addValues(Value.protoEnum(Genre.JAZZ.getNumber(), genreFullyQualifiedName).toProto()) + .addValues(Value.protoEnum(null, genreFullyQualifiedName).toProto()) + .build()); + consumer.onCompleted(); + + assertTrue(resultSet.next()); + assertEquals(Genre.FOLK, resultSet.getProtoEnum(0, Genre::forNumber)); + assertTrue(resultSet.next()); + assertEquals(Genre.JAZZ, resultSet.getProtoEnum(0, Genre::forNumber)); + assertTrue(resultSet.next()); + assertThrows( + NullPointerException.class, + () -> { + resultSet.getProtoEnum(0, Genre::forNumber); + }); + } + @Test public void getBooleanArray() { boolean[] boolArray = {true, true, false}; @@ -906,4 +970,75 @@ public void getPgJsonbList() { assertTrue(resultSet.next()); assertEquals(jsonList, resultSet.getPgJsonbList(0)); } + + @Test + public void getProtoMessageList() { + SingerInfo singerInfo1 = + SingerInfo.newBuilder() + .setSingerId(111) + .setNationality("COUNTRY1") + .setGenre(Genre.FOLK) + .build(); + SingerInfo singerInfo2 = SingerInfo.newBuilder().setSingerId(222).setGenre(Genre.JAZZ).build(); + String singerInfoFullName = SingerInfo.getDescriptor().getFullName(); + + consumer.onPartialResultSet( + PartialResultSet.newBuilder() + .setMetadata( + makeMetadata( + Type.struct( + Type.StructField.of("f", Type.array(Type.proto(singerInfoFullName)))))) + .addValues( + Value.protoMessageArray( + Arrays.asList(singerInfo1, singerInfo2), SingerInfo.getDescriptor()) + .toProto()) + .addValues( + Value.protoMessageArray( + Arrays.asList(singerInfo2, null, singerInfo1), SingerInfo.getDescriptor()) + .toProto()) + .addValues(Value.protoMessageArray(null, SingerInfo.getDescriptor()).toProto()) + .build()); + consumer.onCompleted(); + + assertTrue(resultSet.next()); + assertEquals( + Arrays.asList(singerInfo1, singerInfo2), + resultSet.getProtoMessageList(0, SingerInfo.getDefaultInstance())); + assertTrue(resultSet.next()); + assertEquals( + Arrays.asList(singerInfo2, null, singerInfo1), + resultSet.getProtoMessageList(0, SingerInfo.getDefaultInstance())); + assertTrue(resultSet.next()); + assertThrows( + NullPointerException.class, + () -> { + resultSet.getProtoMessageList(0, SingerInfo.getDefaultInstance()); + }); + } + + @Test + public void getProtoEnumList() { + String genreFullyQualifiedName = Genre.getDescriptor().getFullName(); + consumer.onPartialResultSet( + PartialResultSet.newBuilder() + .setMetadata( + makeMetadata( + Type.struct(Type.StructField.of("f", Type.protoEnum(genreFullyQualifiedName))))) + .addValues(Value.protoEnum(Genre.FOLK).toProto()) + .addValues(Value.protoEnum(Genre.JAZZ.getNumber(), genreFullyQualifiedName).toProto()) + .addValues(Value.protoEnum(null, genreFullyQualifiedName).toProto()) + .build()); + consumer.onCompleted(); + + assertTrue(resultSet.next()); + assertEquals(Genre.FOLK, resultSet.getProtoEnum(0, Genre::forNumber)); + assertTrue(resultSet.next()); + assertEquals(Genre.JAZZ, resultSet.getProtoEnum(0, Genre::forNumber)); + assertTrue(resultSet.next()); + assertThrows( + NullPointerException.class, + () -> { + resultSet.getProtoEnum(0, Genre::forNumber); + }); + } } diff --git a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/MutationTest.java b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/MutationTest.java index fe2b7aec94b..f38b5e47b8d 100644 --- a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/MutationTest.java +++ b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/MutationTest.java @@ -23,6 +23,8 @@ import com.google.cloud.ByteArray; import com.google.cloud.Date; import com.google.cloud.Timestamp; +import com.google.cloud.spanner.SingerProto.Genre; +import com.google.cloud.spanner.SingerProto.SingerInfo; import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableMap; import com.google.common.testing.EqualsTester; @@ -545,6 +547,14 @@ private Mutation.WriteBuilder appendAllTypes(Mutation.WriteBuilder builder) { .to(Value.json("{\"key\": \"value\"}}")) .set("jsonNull") .to(Value.json(null)) + .set("protoMessage") + .to(SingerInfo.newBuilder().setSingerId(232).setGenre(Genre.POP).build()) + .set("protoMessageNull") + .to(Value.protoMessage(null, SingerInfo.getDescriptor().getFullName())) + .set("protoEnum") + .to(Genre.JAZZ) + .set("protoEnumNull") + .to(Value.protoEnum(null, SingerInfo.getDescriptor().getFullName())) .set("pgJsonb") .to(Value.pgJsonb("{\"key\": \"value\"}}")) .set("pgJsonbNull") @@ -603,6 +613,24 @@ private Mutation.WriteBuilder appendAllTypes(Mutation.WriteBuilder builder) { .toJsonArray(null) .set("jsonArrValue") .to(Value.jsonArray(ImmutableList.of("{\"key\": \"value1\"}}", "{\"key\": \"value2\"}"))) + .set("protoMessageArr") + .toProtoMessageArray( + ImmutableList.of(SingerInfo.newBuilder().setSingerId(232).setGenre(Genre.POP).build()), + SingerInfo.getDescriptor()) + .set("protoMessageArrNull") + .toProtoMessageArray(null, SingerInfo.getDescriptor()) + .set("protoMessageArrValue") + .to( + Value.protoMessageArray( + ImmutableList.of( + SingerInfo.newBuilder().setSingerId(232).setGenre(Genre.POP).build()), + SingerInfo.getDescriptor())) + .set("protoEnumArr") + .toProtoEnumArray(ImmutableList.of(Genre.JAZZ), Genre.getDescriptor()) + .set("protoEnumArrNull") + .toProtoEnumArray(null, Genre.getDescriptor()) + .set("protoEnumArrValue") + .to(Value.protoEnumArray(ImmutableList.of(Genre.JAZZ), Genre.getDescriptor())) .set("pgJsonbArr") .toPgJsonbArray(ImmutableList.of("{\"key\": \"value1\"}}", "{\"key\": \"value2\"}")) .set("pgJsonbArrNull") diff --git a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/ResultSetsTest.java b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/ResultSetsTest.java index 87be602808c..8e1f257594b 100644 --- a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/ResultSetsTest.java +++ b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/ResultSetsTest.java @@ -28,9 +28,13 @@ import com.google.cloud.Date; import com.google.cloud.Timestamp; import com.google.cloud.spanner.AsyncResultSet.CallbackResponse; +import com.google.cloud.spanner.SingerProto.Genre; +import com.google.cloud.spanner.SingerProto.SingerInfo; import com.google.common.primitives.Doubles; import com.google.common.primitives.Longs; import com.google.common.util.concurrent.MoreExecutors; +import com.google.protobuf.AbstractMessage; +import com.google.protobuf.ProtocolMessageEnum; import java.math.BigDecimal; import java.util.Arrays; import java.util.Collections; @@ -52,6 +56,13 @@ public void resultSetIteration() { BigDecimal bigDecimalVal = BigDecimal.valueOf(123, 2); String stringVal = "stringVal"; String jsonVal = "{\"color\":\"red\",\"value\":\"#f00\"}"; + SingerInfo protoMessageVal = + SingerInfo.newBuilder() + .setSingerId(111) + .setNationality("COUNTRY1") + .setGenre(Genre.FOLK) + .build(); + ProtocolMessageEnum protoEnumVal = Genre.ROCK; String byteVal = "101"; long usecs = 32343; int year = 2018; @@ -80,6 +91,10 @@ public void resultSetIteration() { }; String[] stringArray = {"abc", "def", "ghi"}; String[] jsonArray = {"{}", "{\"color\":\"red\",\"value\":\"#f00\"}", "[]"}; + AbstractMessage[] protoMessageArray = { + protoMessageVal, SingerInfo.newBuilder().setSingerId(1).build() + }; + ProtocolMessageEnum[] protoEnumArray = {protoEnumVal, Genre.JAZZ}; Type type = Type.struct( @@ -94,6 +109,10 @@ public void resultSetIteration() { Type.StructField.of("byteVal", Type.bytes()), Type.StructField.of("timestamp", Type.timestamp()), Type.StructField.of("date", Type.date()), + Type.StructField.of( + "protoMessage", Type.proto(protoMessageVal.getDescriptorForType().getFullName())), + Type.StructField.of( + "protoEnum", Type.protoEnum(protoEnumVal.getDescriptorForType().getFullName())), Type.StructField.of("boolArray", Type.array(Type.bool())), Type.StructField.of("longArray", Type.array(Type.int64())), Type.StructField.of("doubleArray", Type.array(Type.float64())), @@ -103,7 +122,12 @@ public void resultSetIteration() { Type.StructField.of("dateArray", Type.array(Type.date())), Type.StructField.of("stringArray", Type.array(Type.string())), Type.StructField.of("jsonArray", Type.array(Type.json())), - Type.StructField.of("pgJsonbArray", Type.array(Type.pgJsonb()))); + Type.StructField.of("pgJsonbArray", Type.array(Type.pgJsonb())), + Type.StructField.of( + "protoMessageArray", + Type.array(Type.proto(SingerInfo.getDescriptor().getFullName()))), + Type.StructField.of( + "protoEnumArray", Type.array(Type.protoEnum(Genre.getDescriptor().getFullName())))); Struct struct1 = Struct.newBuilder() .set("f1") @@ -128,6 +152,10 @@ public void resultSetIteration() { .to(Timestamp.ofTimeMicroseconds(usecs)) .set("date") .to(Date.fromYearMonthDay(year, month, day)) + .set("protoMessage") + .to(protoMessageVal) + .set("protoEnum") + .to(protoEnumVal) .set("boolArray") .to(Value.boolArray(boolArray)) .set("longArray") @@ -148,6 +176,14 @@ public void resultSetIteration() { .to(Value.jsonArray(Arrays.asList(jsonArray))) .set("pgJsonbArray") .to(Value.pgJsonbArray(Arrays.asList(jsonArray))) + .set("protoMessageArray") + .to( + Value.protoMessageArray( + Arrays.asList(protoMessageArray), protoMessageVal.getDescriptorForType())) + .set("protoEnumArray") + .to( + Value.protoEnumArray( + Arrays.asList(protoEnumArray), protoEnumVal.getDescriptorForType())) .build(); Struct struct2 = Struct.newBuilder() @@ -173,6 +209,10 @@ public void resultSetIteration() { .to(Timestamp.ofTimeMicroseconds(usecs)) .set("date") .to(Date.fromYearMonthDay(year, month, day)) + .set("protoMessage") + .to(protoMessageVal) + .set("protoEnum") + .to(protoEnumVal) .set("boolArray") .to(Value.boolArray(boolArray)) .set("longArray") @@ -193,6 +233,14 @@ public void resultSetIteration() { .to(Value.jsonArray(Arrays.asList(jsonArray))) .set("pgJsonbArray") .to(Value.pgJsonbArray(Arrays.asList(jsonArray))) + .set("protoMessageArray") + .to( + Value.protoMessageArray( + Arrays.asList(protoMessageArray), protoMessageVal.getDescriptorForType())) + .set("protoEnumArray") + .to( + Value.protoEnumArray( + Arrays.asList(protoEnumArray), protoEnumVal.getDescriptorForType())) .build(); ResultSet rs = ResultSets.forRows(type, Arrays.asList(struct1, struct2)); @@ -259,6 +307,18 @@ public void resultSetIteration() { .isEqualTo(Value.date(Date.fromYearMonthDay(year, month, day))); assertThat(rs.getDate("date")).isEqualTo(Date.fromYearMonthDay(year, month, day)); assertThat(rs.getValue("date")).isEqualTo(Value.date(Date.fromYearMonthDay(year, month, day))); + + assertEquals(protoMessageVal, rs.getProtoMessage(columnIndex, SingerInfo.getDefaultInstance())); + assertEquals(Value.protoMessage(protoMessageVal), rs.getValue(columnIndex++)); + assertEquals( + protoMessageVal, rs.getProtoMessage("protoMessage", SingerInfo.getDefaultInstance())); + assertEquals(Value.protoMessage(protoMessageVal), rs.getValue("protoMessage")); + + assertEquals(protoEnumVal, rs.getProtoEnum(columnIndex, Genre::forNumber)); + assertEquals(Value.protoEnum(protoEnumVal), rs.getValue(columnIndex++)); + assertEquals(protoEnumVal, rs.getProtoEnum("protoEnum", Genre::forNumber)); + assertEquals(Value.protoEnum(protoEnumVal), rs.getValue("protoEnum")); + assertThat(rs.getBooleanArray(columnIndex)).isEqualTo(boolArray); assertThat(rs.getValue(columnIndex++)).isEqualTo(Value.boolArray(boolArray)); assertThat(rs.getBooleanArray("boolArray")).isEqualTo(boolArray); @@ -305,9 +365,29 @@ public void resultSetIteration() { assertThat(rs.getJsonList(columnIndex++)).isEqualTo(Arrays.asList(jsonArray)); assertThat(rs.getJsonList("jsonArray")).isEqualTo(Arrays.asList(jsonArray)); - assertEquals(Arrays.asList(jsonArray), rs.getPgJsonbList(columnIndex)); + assertEquals(Arrays.asList(jsonArray), rs.getPgJsonbList(columnIndex++)); assertEquals(Arrays.asList(jsonArray), rs.getPgJsonbList("pgJsonbArray")); + assertThat(rs.getProtoMessageList(columnIndex, SingerInfo.getDefaultInstance())) + .isEqualTo(Arrays.asList(protoMessageArray)); + assertThat(rs.getValue(columnIndex++)) + .isEqualTo( + Value.protoMessageArray(Arrays.asList(protoMessageArray), SingerInfo.getDescriptor())); + assertThat(rs.getProtoMessageList("protoMessageArray", SingerInfo.getDefaultInstance())) + .isEqualTo(Arrays.asList(protoMessageArray)); + assertThat(rs.getValue("protoMessageArray")) + .isEqualTo( + Value.protoMessageArray(Arrays.asList(protoMessageArray), SingerInfo.getDescriptor())); + + assertThat(rs.getProtoEnumList(columnIndex, Genre::forNumber)) + .isEqualTo(Arrays.asList(protoEnumArray)); + assertThat(rs.getValue(columnIndex)) + .isEqualTo(Value.protoEnumArray(Arrays.asList(protoEnumArray), Genre.getDescriptor())); + assertThat(rs.getProtoEnumList("protoEnumArray", Genre::forNumber)) + .isEqualTo(Arrays.asList(protoEnumArray)); + assertThat(rs.getValue("protoEnumArray")) + .isEqualTo(Value.protoEnumArray(Arrays.asList(protoEnumArray), Genre.getDescriptor())); + assertThat(rs.next()).isTrue(); assertThat(rs.getCurrentRowAsStruct()).isEqualTo(struct2); assertThat(rs.getString(0)).isEqualTo("y"); diff --git a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/SingerProto.java b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/SingerProto.java new file mode 100644 index 00000000000..56fb82c15d2 --- /dev/null +++ b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/SingerProto.java @@ -0,0 +1,1199 @@ +/* + * 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. + */ + +// Generated by the protocol buffer compiler. DO NOT EDIT! +// source: src/test/resources/com/google/cloud/spanner/singer.proto +package com.google.cloud.spanner; + +public final class SingerProto { + private SingerProto() {} + + public static void registerAllExtensions(com.google.protobuf.ExtensionRegistryLite registry) {} + + public static void registerAllExtensions(com.google.protobuf.ExtensionRegistry registry) { + registerAllExtensions((com.google.protobuf.ExtensionRegistryLite) registry); + } + /** Protobuf enum {@code spanner.examples.music.Genre} */ + public enum Genre implements com.google.protobuf.ProtocolMessageEnum { + /** POP = 0; */ + POP(0), + /** JAZZ = 1; */ + JAZZ(1), + /** FOLK = 2; */ + FOLK(2), + /** ROCK = 3; */ + ROCK(3), + ; + + /** POP = 0; */ + public static final int POP_VALUE = 0; + /** JAZZ = 1; */ + public static final int JAZZ_VALUE = 1; + /** FOLK = 2; */ + public static final int FOLK_VALUE = 2; + /** ROCK = 3; */ + public static final int ROCK_VALUE = 3; + + public final int getNumber() { + return value; + } + + /** + * @param value The numeric wire value of the corresponding enum entry. + * @return The enum associated with the given numeric wire value. + * @deprecated Use {@link #forNumber(int)} instead. + */ + @java.lang.Deprecated + public static Genre valueOf(int value) { + return forNumber(value); + } + + /** + * @param value The numeric wire value of the corresponding enum entry. + * @return The enum associated with the given numeric wire value. + */ + public static Genre forNumber(int value) { + switch (value) { + case 0: + return POP; + case 1: + return JAZZ; + case 2: + return FOLK; + case 3: + return ROCK; + default: + return null; + } + } + + public static com.google.protobuf.Internal.EnumLiteMap internalGetValueMap() { + return internalValueMap; + } + + private static final com.google.protobuf.Internal.EnumLiteMap internalValueMap = + new com.google.protobuf.Internal.EnumLiteMap() { + public Genre findValueByNumber(int number) { + return Genre.forNumber(number); + } + }; + + public final com.google.protobuf.Descriptors.EnumValueDescriptor getValueDescriptor() { + return getDescriptor().getValues().get(ordinal()); + } + + public final com.google.protobuf.Descriptors.EnumDescriptor getDescriptorForType() { + return getDescriptor(); + } + + public static final com.google.protobuf.Descriptors.EnumDescriptor getDescriptor() { + return com.google.cloud.spanner.SingerProto.getDescriptor().getEnumTypes().get(0); + } + + private static final Genre[] VALUES = values(); + + public static Genre valueOf(com.google.protobuf.Descriptors.EnumValueDescriptor desc) { + if (desc.getType() != getDescriptor()) { + throw new java.lang.IllegalArgumentException("EnumValueDescriptor is not for this type."); + } + return VALUES[desc.getIndex()]; + } + + private final int value; + + private Genre(int value) { + this.value = value; + } + + // @@protoc_insertion_point(enum_scope:spanner.examples.music.Genre) + } + + public interface SingerInfoOrBuilder + extends + // @@protoc_insertion_point(interface_extends:spanner.examples.music.SingerInfo) + com.google.protobuf.MessageOrBuilder { + + /** + * optional int64 singer_id = 1; + * + * @return Whether the singerId field is set. + */ + boolean hasSingerId(); + /** + * optional int64 singer_id = 1; + * + * @return The singerId. + */ + long getSingerId(); + + /** + * optional string birth_date = 2; + * + * @return Whether the birthDate field is set. + */ + boolean hasBirthDate(); + /** + * optional string birth_date = 2; + * + * @return The birthDate. + */ + java.lang.String getBirthDate(); + /** + * optional string birth_date = 2; + * + * @return The bytes for birthDate. + */ + com.google.protobuf.ByteString getBirthDateBytes(); + + /** + * optional string nationality = 3; + * + * @return Whether the nationality field is set. + */ + boolean hasNationality(); + /** + * optional string nationality = 3; + * + * @return The nationality. + */ + java.lang.String getNationality(); + /** + * optional string nationality = 3; + * + * @return The bytes for nationality. + */ + com.google.protobuf.ByteString getNationalityBytes(); + + /** + * optional .spanner.examples.music.Genre genre = 4; + * + * @return Whether the genre field is set. + */ + boolean hasGenre(); + /** + * optional .spanner.examples.music.Genre genre = 4; + * + * @return The genre. + */ + com.google.cloud.spanner.SingerProto.Genre getGenre(); + } + /** Protobuf type {@code spanner.examples.music.SingerInfo} */ + public static final class SingerInfo extends com.google.protobuf.GeneratedMessageV3 + implements + // @@protoc_insertion_point(message_implements:spanner.examples.music.SingerInfo) + SingerInfoOrBuilder { + private static final long serialVersionUID = 0L; + // Use SingerInfo.newBuilder() to construct. + private SingerInfo(com.google.protobuf.GeneratedMessageV3.Builder builder) { + super(builder); + } + + private SingerInfo() { + birthDate_ = ""; + nationality_ = ""; + genre_ = 0; + } + + @java.lang.Override + @SuppressWarnings({"unused"}) + protected java.lang.Object newInstance(UnusedPrivateParameter unused) { + return new SingerInfo(); + } + + @java.lang.Override + public final com.google.protobuf.UnknownFieldSet getUnknownFields() { + return this.unknownFields; + } + + private SingerInfo( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + this(); + if (extensionRegistry == null) { + throw new java.lang.NullPointerException(); + } + int mutable_bitField0_ = 0; + com.google.protobuf.UnknownFieldSet.Builder unknownFields = + com.google.protobuf.UnknownFieldSet.newBuilder(); + try { + boolean done = false; + while (!done) { + int tag = input.readTag(); + switch (tag) { + case 0: + done = true; + break; + case 8: + { + bitField0_ |= 0x00000001; + singerId_ = input.readInt64(); + break; + } + case 18: + { + com.google.protobuf.ByteString bs = input.readBytes(); + bitField0_ |= 0x00000002; + birthDate_ = bs; + break; + } + case 26: + { + com.google.protobuf.ByteString bs = input.readBytes(); + bitField0_ |= 0x00000004; + nationality_ = bs; + break; + } + case 32: + { + int rawValue = input.readEnum(); + @SuppressWarnings("deprecation") + com.google.cloud.spanner.SingerProto.Genre value = + com.google.cloud.spanner.SingerProto.Genre.valueOf(rawValue); + if (value == null) { + unknownFields.mergeVarintField(4, rawValue); + } else { + bitField0_ |= 0x00000008; + genre_ = rawValue; + } + break; + } + default: + { + if (!parseUnknownField(input, unknownFields, extensionRegistry, tag)) { + done = true; + } + break; + } + } + } + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + throw e.setUnfinishedMessage(this); + } catch (java.io.IOException e) { + throw new com.google.protobuf.InvalidProtocolBufferException(e).setUnfinishedMessage(this); + } finally { + this.unknownFields = unknownFields.build(); + makeExtensionsImmutable(); + } + } + + public static final com.google.protobuf.Descriptors.Descriptor getDescriptor() { + return com.google.cloud.spanner.SingerProto + .internal_static_spanner_examples_music_SingerInfo_descriptor; + } + + @java.lang.Override + protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable + internalGetFieldAccessorTable() { + return com.google.cloud.spanner.SingerProto + .internal_static_spanner_examples_music_SingerInfo_fieldAccessorTable + .ensureFieldAccessorsInitialized( + com.google.cloud.spanner.SingerProto.SingerInfo.class, + com.google.cloud.spanner.SingerProto.SingerInfo.Builder.class); + } + + private int bitField0_; + public static final int SINGER_ID_FIELD_NUMBER = 1; + private long singerId_; + /** + * optional int64 singer_id = 1; + * + * @return Whether the singerId field is set. + */ + @java.lang.Override + public boolean hasSingerId() { + return ((bitField0_ & 0x00000001) != 0); + } + /** + * optional int64 singer_id = 1; + * + * @return The singerId. + */ + @java.lang.Override + public long getSingerId() { + return singerId_; + } + + public static final int BIRTH_DATE_FIELD_NUMBER = 2; + private volatile java.lang.Object birthDate_; + /** + * optional string birth_date = 2; + * + * @return Whether the birthDate field is set. + */ + @java.lang.Override + public boolean hasBirthDate() { + return ((bitField0_ & 0x00000002) != 0); + } + /** + * optional string birth_date = 2; + * + * @return The birthDate. + */ + @java.lang.Override + public java.lang.String getBirthDate() { + java.lang.Object ref = birthDate_; + if (ref instanceof java.lang.String) { + return (java.lang.String) ref; + } else { + com.google.protobuf.ByteString bs = (com.google.protobuf.ByteString) ref; + java.lang.String s = bs.toStringUtf8(); + if (bs.isValidUtf8()) { + birthDate_ = s; + } + return s; + } + } + /** + * optional string birth_date = 2; + * + * @return The bytes for birthDate. + */ + @java.lang.Override + public com.google.protobuf.ByteString getBirthDateBytes() { + java.lang.Object ref = birthDate_; + if (ref instanceof java.lang.String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8((java.lang.String) ref); + birthDate_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + + public static final int NATIONALITY_FIELD_NUMBER = 3; + private volatile java.lang.Object nationality_; + /** + * optional string nationality = 3; + * + * @return Whether the nationality field is set. + */ + @java.lang.Override + public boolean hasNationality() { + return ((bitField0_ & 0x00000004) != 0); + } + /** + * optional string nationality = 3; + * + * @return The nationality. + */ + @java.lang.Override + public java.lang.String getNationality() { + java.lang.Object ref = nationality_; + if (ref instanceof java.lang.String) { + return (java.lang.String) ref; + } else { + com.google.protobuf.ByteString bs = (com.google.protobuf.ByteString) ref; + java.lang.String s = bs.toStringUtf8(); + if (bs.isValidUtf8()) { + nationality_ = s; + } + return s; + } + } + /** + * optional string nationality = 3; + * + * @return The bytes for nationality. + */ + @java.lang.Override + public com.google.protobuf.ByteString getNationalityBytes() { + java.lang.Object ref = nationality_; + if (ref instanceof java.lang.String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8((java.lang.String) ref); + nationality_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + + public static final int GENRE_FIELD_NUMBER = 4; + private int genre_; + /** + * optional .spanner.examples.music.Genre genre = 4; + * + * @return Whether the genre field is set. + */ + @java.lang.Override + public boolean hasGenre() { + return ((bitField0_ & 0x00000008) != 0); + } + /** + * optional .spanner.examples.music.Genre genre = 4; + * + * @return The genre. + */ + @java.lang.Override + public com.google.cloud.spanner.SingerProto.Genre getGenre() { + @SuppressWarnings("deprecation") + com.google.cloud.spanner.SingerProto.Genre result = + com.google.cloud.spanner.SingerProto.Genre.valueOf(genre_); + return result == null ? com.google.cloud.spanner.SingerProto.Genre.POP : result; + } + + private byte memoizedIsInitialized = -1; + + @java.lang.Override + public final boolean isInitialized() { + byte isInitialized = memoizedIsInitialized; + if (isInitialized == 1) return true; + if (isInitialized == 0) return false; + + memoizedIsInitialized = 1; + return true; + } + + @java.lang.Override + public void writeTo(com.google.protobuf.CodedOutputStream output) throws java.io.IOException { + if (((bitField0_ & 0x00000001) != 0)) { + output.writeInt64(1, singerId_); + } + if (((bitField0_ & 0x00000002) != 0)) { + com.google.protobuf.GeneratedMessageV3.writeString(output, 2, birthDate_); + } + if (((bitField0_ & 0x00000004) != 0)) { + com.google.protobuf.GeneratedMessageV3.writeString(output, 3, nationality_); + } + if (((bitField0_ & 0x00000008) != 0)) { + output.writeEnum(4, genre_); + } + unknownFields.writeTo(output); + } + + @java.lang.Override + public int getSerializedSize() { + int size = memoizedSize; + if (size != -1) return size; + + size = 0; + if (((bitField0_ & 0x00000001) != 0)) { + size += com.google.protobuf.CodedOutputStream.computeInt64Size(1, singerId_); + } + if (((bitField0_ & 0x00000002) != 0)) { + size += com.google.protobuf.GeneratedMessageV3.computeStringSize(2, birthDate_); + } + if (((bitField0_ & 0x00000004) != 0)) { + size += com.google.protobuf.GeneratedMessageV3.computeStringSize(3, nationality_); + } + if (((bitField0_ & 0x00000008) != 0)) { + size += com.google.protobuf.CodedOutputStream.computeEnumSize(4, genre_); + } + size += unknownFields.getSerializedSize(); + memoizedSize = size; + return size; + } + + @java.lang.Override + public boolean equals(final java.lang.Object obj) { + if (obj == this) { + return true; + } + if (!(obj instanceof com.google.cloud.spanner.SingerProto.SingerInfo)) { + return super.equals(obj); + } + com.google.cloud.spanner.SingerProto.SingerInfo other = + (com.google.cloud.spanner.SingerProto.SingerInfo) obj; + + if (hasSingerId() != other.hasSingerId()) return false; + if (hasSingerId()) { + if (getSingerId() != other.getSingerId()) return false; + } + if (hasBirthDate() != other.hasBirthDate()) return false; + if (hasBirthDate()) { + if (!getBirthDate().equals(other.getBirthDate())) return false; + } + if (hasNationality() != other.hasNationality()) return false; + if (hasNationality()) { + if (!getNationality().equals(other.getNationality())) return false; + } + if (hasGenre() != other.hasGenre()) return false; + if (hasGenre()) { + if (genre_ != other.genre_) return false; + } + if (!unknownFields.equals(other.unknownFields)) return false; + return true; + } + + @java.lang.Override + public int hashCode() { + if (memoizedHashCode != 0) { + return memoizedHashCode; + } + int hash = 41; + hash = (19 * hash) + getDescriptor().hashCode(); + if (hasSingerId()) { + hash = (37 * hash) + SINGER_ID_FIELD_NUMBER; + hash = (53 * hash) + com.google.protobuf.Internal.hashLong(getSingerId()); + } + if (hasBirthDate()) { + hash = (37 * hash) + BIRTH_DATE_FIELD_NUMBER; + hash = (53 * hash) + getBirthDate().hashCode(); + } + if (hasNationality()) { + hash = (37 * hash) + NATIONALITY_FIELD_NUMBER; + hash = (53 * hash) + getNationality().hashCode(); + } + if (hasGenre()) { + hash = (37 * hash) + GENRE_FIELD_NUMBER; + hash = (53 * hash) + genre_; + } + hash = (29 * hash) + unknownFields.hashCode(); + memoizedHashCode = hash; + return hash; + } + + public static com.google.cloud.spanner.SingerProto.SingerInfo parseFrom( + java.nio.ByteBuffer data) throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + + public static com.google.cloud.spanner.SingerProto.SingerInfo parseFrom( + java.nio.ByteBuffer data, com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + + public static com.google.cloud.spanner.SingerProto.SingerInfo parseFrom( + com.google.protobuf.ByteString data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + + public static com.google.cloud.spanner.SingerProto.SingerInfo parseFrom( + com.google.protobuf.ByteString data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + + public static com.google.cloud.spanner.SingerProto.SingerInfo parseFrom(byte[] data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + + public static com.google.cloud.spanner.SingerProto.SingerInfo parseFrom( + byte[] data, com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + + public static com.google.cloud.spanner.SingerProto.SingerInfo parseFrom( + java.io.InputStream input) throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3.parseWithIOException(PARSER, input); + } + + public static com.google.cloud.spanner.SingerProto.SingerInfo parseFrom( + java.io.InputStream input, com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3.parseWithIOException( + PARSER, input, extensionRegistry); + } + + public static com.google.cloud.spanner.SingerProto.SingerInfo parseDelimitedFrom( + java.io.InputStream input) throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3.parseDelimitedWithIOException(PARSER, input); + } + + public static com.google.cloud.spanner.SingerProto.SingerInfo parseDelimitedFrom( + java.io.InputStream input, com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3.parseDelimitedWithIOException( + PARSER, input, extensionRegistry); + } + + public static com.google.cloud.spanner.SingerProto.SingerInfo parseFrom( + com.google.protobuf.CodedInputStream input) throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3.parseWithIOException(PARSER, input); + } + + public static com.google.cloud.spanner.SingerProto.SingerInfo parseFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3.parseWithIOException( + PARSER, input, extensionRegistry); + } + + @java.lang.Override + public Builder newBuilderForType() { + return newBuilder(); + } + + public static Builder newBuilder() { + return DEFAULT_INSTANCE.toBuilder(); + } + + public static Builder newBuilder(com.google.cloud.spanner.SingerProto.SingerInfo prototype) { + return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype); + } + + @java.lang.Override + public Builder toBuilder() { + return this == DEFAULT_INSTANCE ? new Builder() : new Builder().mergeFrom(this); + } + + @java.lang.Override + protected Builder newBuilderForType( + com.google.protobuf.GeneratedMessageV3.BuilderParent parent) { + Builder builder = new Builder(parent); + return builder; + } + /** Protobuf type {@code spanner.examples.music.SingerInfo} */ + public static final class Builder + extends com.google.protobuf.GeneratedMessageV3.Builder + implements + // @@protoc_insertion_point(builder_implements:spanner.examples.music.SingerInfo) + com.google.cloud.spanner.SingerProto.SingerInfoOrBuilder { + public static final com.google.protobuf.Descriptors.Descriptor getDescriptor() { + return com.google.cloud.spanner.SingerProto + .internal_static_spanner_examples_music_SingerInfo_descriptor; + } + + @java.lang.Override + protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable + internalGetFieldAccessorTable() { + return com.google.cloud.spanner.SingerProto + .internal_static_spanner_examples_music_SingerInfo_fieldAccessorTable + .ensureFieldAccessorsInitialized( + com.google.cloud.spanner.SingerProto.SingerInfo.class, + com.google.cloud.spanner.SingerProto.SingerInfo.Builder.class); + } + + // Construct using com.google.cloud.spanner.SingerProto.SingerInfo.newBuilder() + private Builder() { + maybeForceBuilderInitialization(); + } + + private Builder(com.google.protobuf.GeneratedMessageV3.BuilderParent parent) { + super(parent); + maybeForceBuilderInitialization(); + } + + private void maybeForceBuilderInitialization() { + if (com.google.protobuf.GeneratedMessageV3.alwaysUseFieldBuilders) {} + } + + @java.lang.Override + public Builder clear() { + super.clear(); + singerId_ = 0L; + bitField0_ = (bitField0_ & ~0x00000001); + birthDate_ = ""; + bitField0_ = (bitField0_ & ~0x00000002); + nationality_ = ""; + bitField0_ = (bitField0_ & ~0x00000004); + genre_ = 0; + bitField0_ = (bitField0_ & ~0x00000008); + return this; + } + + @java.lang.Override + public com.google.protobuf.Descriptors.Descriptor getDescriptorForType() { + return com.google.cloud.spanner.SingerProto + .internal_static_spanner_examples_music_SingerInfo_descriptor; + } + + @java.lang.Override + public com.google.cloud.spanner.SingerProto.SingerInfo getDefaultInstanceForType() { + return com.google.cloud.spanner.SingerProto.SingerInfo.getDefaultInstance(); + } + + @java.lang.Override + public com.google.cloud.spanner.SingerProto.SingerInfo build() { + com.google.cloud.spanner.SingerProto.SingerInfo result = buildPartial(); + if (!result.isInitialized()) { + throw newUninitializedMessageException(result); + } + return result; + } + + @java.lang.Override + public com.google.cloud.spanner.SingerProto.SingerInfo buildPartial() { + com.google.cloud.spanner.SingerProto.SingerInfo result = + new com.google.cloud.spanner.SingerProto.SingerInfo(this); + int from_bitField0_ = bitField0_; + int to_bitField0_ = 0; + if (((from_bitField0_ & 0x00000001) != 0)) { + result.singerId_ = singerId_; + to_bitField0_ |= 0x00000001; + } + if (((from_bitField0_ & 0x00000002) != 0)) { + to_bitField0_ |= 0x00000002; + } + result.birthDate_ = birthDate_; + if (((from_bitField0_ & 0x00000004) != 0)) { + to_bitField0_ |= 0x00000004; + } + result.nationality_ = nationality_; + if (((from_bitField0_ & 0x00000008) != 0)) { + to_bitField0_ |= 0x00000008; + } + result.genre_ = genre_; + result.bitField0_ = to_bitField0_; + onBuilt(); + return result; + } + + @java.lang.Override + public Builder clone() { + return super.clone(); + } + + @java.lang.Override + public Builder setField( + com.google.protobuf.Descriptors.FieldDescriptor field, java.lang.Object value) { + return super.setField(field, value); + } + + @java.lang.Override + public Builder clearField(com.google.protobuf.Descriptors.FieldDescriptor field) { + return super.clearField(field); + } + + @java.lang.Override + public Builder clearOneof(com.google.protobuf.Descriptors.OneofDescriptor oneof) { + return super.clearOneof(oneof); + } + + @java.lang.Override + public Builder setRepeatedField( + com.google.protobuf.Descriptors.FieldDescriptor field, + int index, + java.lang.Object value) { + return super.setRepeatedField(field, index, value); + } + + @java.lang.Override + public Builder addRepeatedField( + com.google.protobuf.Descriptors.FieldDescriptor field, java.lang.Object value) { + return super.addRepeatedField(field, value); + } + + @java.lang.Override + public Builder mergeFrom(com.google.protobuf.Message other) { + if (other instanceof com.google.cloud.spanner.SingerProto.SingerInfo) { + return mergeFrom((com.google.cloud.spanner.SingerProto.SingerInfo) other); + } else { + super.mergeFrom(other); + return this; + } + } + + public Builder mergeFrom(com.google.cloud.spanner.SingerProto.SingerInfo other) { + if (other == com.google.cloud.spanner.SingerProto.SingerInfo.getDefaultInstance()) + return this; + if (other.hasSingerId()) { + setSingerId(other.getSingerId()); + } + if (other.hasBirthDate()) { + bitField0_ |= 0x00000002; + birthDate_ = other.birthDate_; + onChanged(); + } + if (other.hasNationality()) { + bitField0_ |= 0x00000004; + nationality_ = other.nationality_; + onChanged(); + } + if (other.hasGenre()) { + setGenre(other.getGenre()); + } + this.mergeUnknownFields(other.unknownFields); + onChanged(); + return this; + } + + @java.lang.Override + public final boolean isInitialized() { + return true; + } + + @java.lang.Override + public Builder mergeFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + com.google.cloud.spanner.SingerProto.SingerInfo parsedMessage = null; + try { + parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry); + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + parsedMessage = + (com.google.cloud.spanner.SingerProto.SingerInfo) e.getUnfinishedMessage(); + throw e.unwrapIOException(); + } finally { + if (parsedMessage != null) { + mergeFrom(parsedMessage); + } + } + return this; + } + + private int bitField0_; + + private long singerId_; + /** + * optional int64 singer_id = 1; + * + * @return Whether the singerId field is set. + */ + @java.lang.Override + public boolean hasSingerId() { + return ((bitField0_ & 0x00000001) != 0); + } + /** + * optional int64 singer_id = 1; + * + * @return The singerId. + */ + @java.lang.Override + public long getSingerId() { + return singerId_; + } + /** + * optional int64 singer_id = 1; + * + * @param value The singerId to set. + * @return This builder for chaining. + */ + public Builder setSingerId(long value) { + bitField0_ |= 0x00000001; + singerId_ = value; + onChanged(); + return this; + } + /** + * optional int64 singer_id = 1; + * + * @return This builder for chaining. + */ + public Builder clearSingerId() { + bitField0_ = (bitField0_ & ~0x00000001); + singerId_ = 0L; + onChanged(); + return this; + } + + private java.lang.Object birthDate_ = ""; + /** + * optional string birth_date = 2; + * + * @return Whether the birthDate field is set. + */ + public boolean hasBirthDate() { + return ((bitField0_ & 0x00000002) != 0); + } + /** + * optional string birth_date = 2; + * + * @return The birthDate. + */ + public java.lang.String getBirthDate() { + java.lang.Object ref = birthDate_; + if (!(ref instanceof java.lang.String)) { + com.google.protobuf.ByteString bs = (com.google.protobuf.ByteString) ref; + java.lang.String s = bs.toStringUtf8(); + if (bs.isValidUtf8()) { + birthDate_ = s; + } + return s; + } else { + return (java.lang.String) ref; + } + } + /** + * optional string birth_date = 2; + * + * @return The bytes for birthDate. + */ + public com.google.protobuf.ByteString getBirthDateBytes() { + java.lang.Object ref = birthDate_; + if (ref instanceof String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8((java.lang.String) ref); + birthDate_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + /** + * optional string birth_date = 2; + * + * @param value The birthDate to set. + * @return This builder for chaining. + */ + public Builder setBirthDate(java.lang.String value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000002; + birthDate_ = value; + onChanged(); + return this; + } + /** + * optional string birth_date = 2; + * + * @return This builder for chaining. + */ + public Builder clearBirthDate() { + bitField0_ = (bitField0_ & ~0x00000002); + birthDate_ = getDefaultInstance().getBirthDate(); + onChanged(); + return this; + } + /** + * optional string birth_date = 2; + * + * @param value The bytes for birthDate to set. + * @return This builder for chaining. + */ + public Builder setBirthDateBytes(com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000002; + birthDate_ = value; + onChanged(); + return this; + } + + private java.lang.Object nationality_ = ""; + /** + * optional string nationality = 3; + * + * @return Whether the nationality field is set. + */ + public boolean hasNationality() { + return ((bitField0_ & 0x00000004) != 0); + } + /** + * optional string nationality = 3; + * + * @return The nationality. + */ + public java.lang.String getNationality() { + java.lang.Object ref = nationality_; + if (!(ref instanceof java.lang.String)) { + com.google.protobuf.ByteString bs = (com.google.protobuf.ByteString) ref; + java.lang.String s = bs.toStringUtf8(); + if (bs.isValidUtf8()) { + nationality_ = s; + } + return s; + } else { + return (java.lang.String) ref; + } + } + /** + * optional string nationality = 3; + * + * @return The bytes for nationality. + */ + public com.google.protobuf.ByteString getNationalityBytes() { + java.lang.Object ref = nationality_; + if (ref instanceof String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8((java.lang.String) ref); + nationality_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + /** + * optional string nationality = 3; + * + * @param value The nationality to set. + * @return This builder for chaining. + */ + public Builder setNationality(java.lang.String value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000004; + nationality_ = value; + onChanged(); + return this; + } + /** + * optional string nationality = 3; + * + * @return This builder for chaining. + */ + public Builder clearNationality() { + bitField0_ = (bitField0_ & ~0x00000004); + nationality_ = getDefaultInstance().getNationality(); + onChanged(); + return this; + } + /** + * optional string nationality = 3; + * + * @param value The bytes for nationality to set. + * @return This builder for chaining. + */ + public Builder setNationalityBytes(com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000004; + nationality_ = value; + onChanged(); + return this; + } + + private int genre_ = 0; + /** + * optional .spanner.examples.music.Genre genre = 4; + * + * @return Whether the genre field is set. + */ + @java.lang.Override + public boolean hasGenre() { + return ((bitField0_ & 0x00000008) != 0); + } + /** + * optional .spanner.examples.music.Genre genre = 4; + * + * @return The genre. + */ + @java.lang.Override + public com.google.cloud.spanner.SingerProto.Genre getGenre() { + @SuppressWarnings("deprecation") + com.google.cloud.spanner.SingerProto.Genre result = + com.google.cloud.spanner.SingerProto.Genre.valueOf(genre_); + return result == null ? com.google.cloud.spanner.SingerProto.Genre.POP : result; + } + /** + * optional .spanner.examples.music.Genre genre = 4; + * + * @param value The genre to set. + * @return This builder for chaining. + */ + public Builder setGenre(com.google.cloud.spanner.SingerProto.Genre value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000008; + genre_ = value.getNumber(); + onChanged(); + return this; + } + /** + * optional .spanner.examples.music.Genre genre = 4; + * + * @return This builder for chaining. + */ + public Builder clearGenre() { + bitField0_ = (bitField0_ & ~0x00000008); + genre_ = 0; + onChanged(); + return this; + } + + @java.lang.Override + public final Builder setUnknownFields( + final com.google.protobuf.UnknownFieldSet unknownFields) { + return super.setUnknownFields(unknownFields); + } + + @java.lang.Override + public final Builder mergeUnknownFields( + final com.google.protobuf.UnknownFieldSet unknownFields) { + return super.mergeUnknownFields(unknownFields); + } + + // @@protoc_insertion_point(builder_scope:spanner.examples.music.SingerInfo) + } + + // @@protoc_insertion_point(class_scope:spanner.examples.music.SingerInfo) + private static final com.google.cloud.spanner.SingerProto.SingerInfo DEFAULT_INSTANCE; + + static { + DEFAULT_INSTANCE = new com.google.cloud.spanner.SingerProto.SingerInfo(); + } + + public static com.google.cloud.spanner.SingerProto.SingerInfo getDefaultInstance() { + return DEFAULT_INSTANCE; + } + + @java.lang.Deprecated + public static final com.google.protobuf.Parser PARSER = + new com.google.protobuf.AbstractParser() { + @java.lang.Override + public SingerInfo parsePartialFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return new SingerInfo(input, extensionRegistry); + } + }; + + public static com.google.protobuf.Parser parser() { + return PARSER; + } + + @java.lang.Override + public com.google.protobuf.Parser getParserForType() { + return PARSER; + } + + @java.lang.Override + public com.google.cloud.spanner.SingerProto.SingerInfo getDefaultInstanceForType() { + return DEFAULT_INSTANCE; + } + } + + private static final com.google.protobuf.Descriptors.Descriptor + internal_static_spanner_examples_music_SingerInfo_descriptor; + private static final com.google.protobuf.GeneratedMessageV3.FieldAccessorTable + internal_static_spanner_examples_music_SingerInfo_fieldAccessorTable; + + public static com.google.protobuf.Descriptors.FileDescriptor getDescriptor() { + return descriptor; + } + + private static com.google.protobuf.Descriptors.FileDescriptor descriptor; + + static { + java.lang.String[] descriptorData = { + "\n\014singer.proto\022\026spanner.examples.music\"v" + + "\n\nSingerInfo\022\021\n\tsinger_id\030\001 \001(\003\022\022\n\nbirth" + + "_date\030\002 \001(\t\022\023\n\013nationality\030\003 \001(\t\022,\n\005genr" + + "e\030\004 \001(\0162\035.spanner.examples.music.Genre*." + + "\n\005Genre\022\007\n\003POP\020\000\022\010\n\004JAZZ\020\001\022\010\n\004FOLK\020\002\022\010\n\004" + + "ROCK\020\003B)\n\030com.google.cloud.spannerB\013Sing" + + "erProtoP\000" + }; + descriptor = + com.google.protobuf.Descriptors.FileDescriptor.internalBuildGeneratedFileFrom( + descriptorData, new com.google.protobuf.Descriptors.FileDescriptor[] {}); + internal_static_spanner_examples_music_SingerInfo_descriptor = + getDescriptor().getMessageTypes().get(0); + internal_static_spanner_examples_music_SingerInfo_fieldAccessorTable = + new com.google.protobuf.GeneratedMessageV3.FieldAccessorTable( + internal_static_spanner_examples_music_SingerInfo_descriptor, + new java.lang.String[] { + "SingerId", "BirthDate", "Nationality", "Genre", + }); + } + + // @@protoc_insertion_point(outer_class_scope) +} diff --git a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/TypeTest.java b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/TypeTest.java index 48fe282b12b..11b708ed48b 100644 --- a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/TypeTest.java +++ b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/TypeTest.java @@ -40,6 +40,7 @@ private abstract static class ScalarTypeTester { private final Type.Code expectedCode; private final TypeCode expectedTypeCode; private final TypeAnnotationCode expectedTypeAnnotationCode; + private String protoTypeFqn = ""; ScalarTypeTester(Type.Code expectedCode, TypeCode expectedTypeCode) { this(expectedCode, expectedTypeCode, TypeAnnotationCode.TYPE_ANNOTATION_CODE_UNSPECIFIED); @@ -54,12 +55,17 @@ private abstract static class ScalarTypeTester { this.expectedTypeAnnotationCode = expectedTypeAnnotationCode; } + ScalarTypeTester(Type.Code expectedCode, TypeCode expectedTypeCode, String protoTypeFqn) { + this(expectedCode, expectedTypeCode); + this.protoTypeFqn = protoTypeFqn; + } + abstract Type newType(); void test() { Type t = newType(); assertThat(t.getCode()).isEqualTo(expectedCode); - assertThat(newType()).isSameInstanceAs(t); // Interned. + assertThat(newType()).isEqualTo(t); // Interned. // String form is deliberately the same as the corresponding type enum in the public API. if (expectedTypeAnnotationCode != TypeAnnotationCode.TYPE_ANNOTATION_CODE_UNSPECIFIED) { assertThat(t.toString()) @@ -72,13 +78,13 @@ void test() { com.google.spanner.v1.Type proto = t.toProto(); assertThat(proto.getCode()).isEqualTo(expectedTypeCode); assertThat(proto.getTypeAnnotation()).isEqualTo(expectedTypeAnnotationCode); + assertThat(proto.getProtoTypeFqn()).isEqualTo(protoTypeFqn); assertThat(proto.hasArrayElementType()).isFalse(); assertThat(proto.hasStructType()).isFalse(); // Round trip. Type fromProto = Type.fromProto(proto); assertThat(fromProto).isEqualTo(t); - assertThat(fromProto).isSameInstanceAs(t); reserializeAndAssert(t); } @@ -174,6 +180,26 @@ Type newType() { }.test(); } + @Test + public void proto() { + new ScalarTypeTester(Type.Code.PROTO, TypeCode.PROTO, "com.google.temp") { + @Override + Type newType() { + return Type.proto("com.google.temp"); + } + }.test(); + } + + @Test + public void protoEnum() { + new ScalarTypeTester(Type.Code.ENUM, TypeCode.ENUM, "com.google.temp.enum") { + @Override + Type newType() { + return Type.protoEnum("com.google.temp.enum"); + } + }.test(); + } + @Test public void timestamp() { new ScalarTypeTester(Type.Code.TIMESTAMP, TypeCode.TIMESTAMP) { @@ -199,6 +225,7 @@ abstract static class ArrayTypeTester { private final TypeCode expectedElementTypeCode; private final TypeAnnotationCode expectedTypeAnnotationCode; private final boolean expectInterned; + private String protoTypeFqn = ""; ArrayTypeTester( Type.Code expectedElementCode, TypeCode expectedElementTypeCode, boolean expectInterned) { @@ -209,6 +236,19 @@ abstract static class ArrayTypeTester { expectInterned); } + ArrayTypeTester( + Type.Code expectedElementCode, + TypeCode expectedElementTypeCode, + String protoTypeFqn, + boolean expectInterned) { + this( + expectedElementCode, + expectedElementTypeCode, + TypeAnnotationCode.TYPE_ANNOTATION_CODE_UNSPECIFIED, + expectInterned); + this.protoTypeFqn = protoTypeFqn; + } + ArrayTypeTester( Type.Code expectedElementCode, TypeCode expectedElementTypeCode, @@ -358,6 +398,26 @@ Type newElementType() { }.test(); } + @Test + public void protoArray() { + new ArrayTypeTester(Type.Code.PROTO, TypeCode.PROTO, "com.google.temp", false) { + @Override + Type newElementType() { + return Type.proto("com.google.temp"); + } + }.test(); + } + + @Test + public void protoEnumArray() { + new ArrayTypeTester(Type.Code.ENUM, TypeCode.ENUM, "com.google.temp.enum", false) { + @Override + Type newElementType() { + return Type.protoEnum("com.google.temp.enum"); + } + }.test(); + } + @Test public void arrayOfArray() { new ArrayTypeTester(Type.Code.ARRAY, TypeCode.ARRAY, false /* not interned */) { diff --git a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/ValueBinderTest.java b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/ValueBinderTest.java index 8da5c0322dc..d50814e84d4 100644 --- a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/ValueBinderTest.java +++ b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/ValueBinderTest.java @@ -25,6 +25,12 @@ import com.google.cloud.ByteArray; import com.google.cloud.Date; import com.google.cloud.Timestamp; +import com.google.cloud.spanner.SingerProto.Genre; +import com.google.cloud.spanner.SingerProto.SingerInfo; +import com.google.protobuf.AbstractMessage; +import com.google.protobuf.Descriptors.Descriptor; +import com.google.protobuf.Descriptors.EnumDescriptor; +import com.google.protobuf.ProtocolMessageEnum; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.lang.reflect.Modifier; @@ -43,6 +49,8 @@ public class ValueBinderTest { private static final String JSON_METHOD_NAME = "json"; private static final String PG_JSONB_METHOD_NAME = "pgJsonb"; private static final String PG_NUMERIC_METHOD_NAME = "pgNumeric"; + private static final String PROTO_MESSAGE_METHOD_NAME = "protoMessage"; + private static final String PROTO_ENUM_METHOD_NAME = "protoEnum"; private static final String BYTES_BASE64_METHOD_NAME = "bytesFromBase64"; public static final String DEFAULT_PG_NUMERIC = "1.23"; @@ -125,7 +133,9 @@ public void reflection() } } else if (binderMethod.getParameterTypes().length == 1) { // Test unary null. - if (!binderMethod.getParameterTypes()[0].isPrimitive()) { + if (!binderMethod.getParameterTypes()[0].isPrimitive() + && (!method.getName().equalsIgnoreCase(PROTO_MESSAGE_METHOD_NAME) + && !method.getName().equalsIgnoreCase(PROTO_ENUM_METHOD_NAME))) { if (method.getName().equalsIgnoreCase(JSON_METHOD_NAME)) { // Special case for json to change the method from ValueBinder.to(String) to // ValueBinder.to(Value) @@ -147,7 +157,6 @@ public void reflection() } Value expected = (Value) method.invoke(Value.class, (Object) null); assertThat(lastValue).isEqualTo(expected); - assertThat(binder.to(expected)).isEqualTo(lastReturnValue); assertThat(lastValue).isEqualTo(expected); } @@ -180,6 +189,27 @@ public void reflection() Value expected = (Value) method.invoke(Value.class, defaultObject); assertThat(lastValue).isEqualTo(expected); + assertThat(binder.to(expected)).isEqualTo(lastReturnValue); + assertThat(lastValue).isEqualTo(expected); + } else if (binderMethod.getParameterTypes().length == 2 + && (method.getName().contains(PROTO_MESSAGE_METHOD_NAME) + || method.getName().contains(PROTO_ENUM_METHOD_NAME))) { + // Test unary null. + Object firstArgument = null; + if (binderMethod.getParameterTypes()[0].isPrimitive()) { + firstArgument = 0; + } + + Object secondArgument = "com.proto.example"; + if (binderMethod.getParameterTypes()[1] == Descriptor.class) { + secondArgument = SingerInfo.getDescriptor(); + } else if (binderMethod.getParameterTypes()[1] == EnumDescriptor.class) { + secondArgument = Genre.getDescriptor(); + } + assertThat(binderMethod.invoke(binder, firstArgument, secondArgument)) + .isEqualTo(lastReturnValue); + Value expected = (Value) method.invoke(Value.class, firstArgument, secondArgument); + assertThat(lastValue).isEqualTo(expected); assertThat(binder.to(expected)).isEqualTo(lastReturnValue); assertThat(lastValue).isEqualTo(expected); } else { @@ -247,6 +277,14 @@ public static BigDecimal defaultBigDecimal() { return BigDecimal.valueOf(123, 2); } + public static AbstractMessage defaultAbstractMessage() { + return SingerInfo.newBuilder().setSingerId(323).build(); + } + + public static ProtocolMessageEnum defaultProtocolMessageEnum() { + return Genre.FOLK; + } + public static String defaultString() { return "x"; } diff --git a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/ValueTest.java b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/ValueTest.java index bf806795fa6..5176013cf38 100644 --- a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/ValueTest.java +++ b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/ValueTest.java @@ -33,6 +33,8 @@ import com.google.cloud.Date; import com.google.cloud.Timestamp; import com.google.cloud.spanner.AbstractResultSet.LazyByteArray; +import com.google.cloud.spanner.SingerProto.Genre; +import com.google.cloud.spanner.SingerProto.SingerInfo; import com.google.cloud.spanner.Type.StructField; import com.google.common.base.Strings; import com.google.common.collect.ForwardingList; @@ -674,6 +676,56 @@ public void dateNull() { assertEquals("NULL", v.getAsString()); } + @Test + public void protoMessage() { + SingerInfo singerInfo = SingerInfo.newBuilder().setSingerId(111).setGenre(Genre.FOLK).build(); + Value v = Value.protoMessage(singerInfo); + assertThat(v.getType()).isEqualTo(Type.proto(SingerInfo.getDescriptor().getFullName())); + assertThat(v.isNull()).isFalse(); + assertThat(v.getProtoMessage(SingerInfo.getDefaultInstance())).isEqualTo(singerInfo); + assertThat(v.getBytes().toByteArray()).isEqualTo(singerInfo.toByteArray()); + } + + @Test + public void protoMessageNull() { + Value v = Value.protoMessage(null, SingerInfo.getDescriptor().getFullName()); + assertThat(v.getType()).isEqualTo(Type.proto(SingerInfo.getDescriptor().getFullName())); + assertThat(v.isNull()).isTrue(); + assertThat(v.toString()).isEqualTo(NULL_STRING); + IllegalStateException e = + assertThrows( + IllegalStateException.class, + () -> { + v.getProtoMessage(SingerInfo.getDefaultInstance()); + }); + assertThat(e.getMessage()).contains("null value"); + } + + @Test + public void protoEnum() { + Genre genre = Genre.FOLK; + Value v = Value.protoEnum(genre); + assertThat(v.getType()).isEqualTo(Type.protoEnum(Genre.getDescriptor().getFullName())); + assertThat(v.isNull()).isFalse(); + assertThat(v.getInt64()).isEqualTo(genre.getNumber()); + assertEquals(genre, v.getProtoEnum(Genre::forNumber)); + } + + @Test + public void protoEnumNull() { + Value v = Value.protoEnum(null, Genre.getDescriptor().getFullName()); + assertThat(v.getType()).isEqualTo(Type.protoEnum(Genre.getDescriptor().getFullName())); + assertThat(v.isNull()).isTrue(); + assertThat(v.toString()).isEqualTo(NULL_STRING); + IllegalStateException e = + assertThrows( + IllegalStateException.class, + () -> { + v.getProtoEnum(Genre::forNumber); + }); + assertThat(e.getMessage()).contains("null value"); + } + @Test public void boolArray() { Value v = Value.boolArray(new boolean[] {true, false}); @@ -1137,6 +1189,70 @@ public void dateArrayNull() { assertEquals("NULL", v.getAsString()); } + @Test + public void protoMessageArray() { + SingerInfo singerInfo1 = SingerInfo.newBuilder().setSingerId(111).setGenre(Genre.FOLK).build(); + SingerInfo singerInfo2 = SingerInfo.newBuilder().setSingerId(222).build(); + Value v = + Value.protoMessageArray( + Arrays.asList(singerInfo1, null, singerInfo2), SingerInfo.getDescriptor()); + assertThat(v.getType()) + .isEqualTo(Type.array(Type.proto(SingerInfo.getDescriptor().getFullName()))); + assertThat(v.isNull()).isFalse(); + assertThat(v.getProtoMessageArray(SingerInfo.getDefaultInstance())) + .containsExactly(singerInfo1, null, singerInfo2); + assertThat(v.getBytesArray()) + .containsExactly( + ByteArray.copyFrom(singerInfo1.toByteArray()), + null, + ByteArray.copyFrom(singerInfo2.toByteArray())); + } + + @Test + public void protoMessageNullArray() { + Value v = Value.protoMessageArray(null, SingerInfo.getDescriptor()); + assertThat(v.getType()) + .isEqualTo(Type.array(Type.proto(SingerInfo.getDescriptor().getFullName()))); + assertThat(v.isNull()).isTrue(); + assertThat(v.toString()).isEqualTo(NULL_STRING); + IllegalStateException e = + assertThrows( + IllegalStateException.class, + () -> { + v.getProtoMessageArray(SingerInfo.getDefaultInstance()); + }); + assertThat(e.getMessage()).contains("null value"); + } + + @Test + public void protoEnumArray() { + Genre genre1 = Genre.ROCK; + Genre genre2 = Genre.JAZZ; + Value v = Value.protoEnumArray(Arrays.asList(genre1, null, genre2), Genre.getDescriptor()); + assertThat(v.getType()) + .isEqualTo(Type.array(Type.protoEnum(Genre.getDescriptor().getFullName()))); + assertThat(v.isNull()).isFalse(); + assertThat(v.getProtoEnumArray(Genre::forNumber)).containsExactly(genre1, null, genre2); + assertThat(v.getInt64Array()) + .containsExactly((long) genre1.getNumber(), null, (long) genre2.getNumber()); + } + + @Test + public void protoEnumNullArray() { + Value v = Value.protoEnumArray(null, Genre.getDescriptor()); + assertThat(v.getType()) + .isEqualTo(Type.array(Type.protoEnum(Genre.getDescriptor().getFullName()))); + assertThat(v.isNull()).isTrue(); + assertThat(v.toString()).isEqualTo(NULL_STRING); + IllegalStateException e = + assertThrows( + IllegalStateException.class, + () -> { + v.getProtoEnumArray(Genre::forNumber); + }); + assertThat(e.getMessage()).contains("null value"); + } + @Test public void struct() { Struct struct = Struct.newBuilder().set("f1").to("v1").set("f2").to(30).build(); diff --git a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/connection/ChecksumResultSetTest.java b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/connection/ChecksumResultSetTest.java index 1f3f59e96ab..4e8fb0cfcbb 100644 --- a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/connection/ChecksumResultSetTest.java +++ b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/connection/ChecksumResultSetTest.java @@ -29,6 +29,8 @@ import com.google.cloud.spanner.AbortedException; import com.google.cloud.spanner.ResultSet; import com.google.cloud.spanner.ResultSets; +import com.google.cloud.spanner.SingerProto.Genre; +import com.google.cloud.spanner.SingerProto.SingerInfo; import com.google.cloud.spanner.Statement; import com.google.cloud.spanner.Struct; import com.google.cloud.spanner.Struct.Builder; @@ -65,6 +67,10 @@ public class ChecksumResultSetTest { .to(Value.json("{\"color\":\"red\",\"value\":\"#ff0\"}")) .set("pgJsonbVal") .to(Value.pgJsonb("{\"color\":\"red\",\"value\":\"#00f\"}")) + .set("protoMessageVal") + .to(SingerInfo.newBuilder().setSingerId(23).build()) + .set("protoEnumVal") + .to(Genre.JAZZ) .set("byteVal") .to(Value.bytes(ByteArray.copyFrom("bytes".getBytes(StandardCharsets.UTF_8)))) .set("timestamp") @@ -104,6 +110,15 @@ public class ChecksumResultSetTest { .to( Value.pgJsonbArray( Arrays.asList("{\"color\":\"red\",\"value\":\"#f00\"}", null, "[]"))) + .set("protoMessageArray") + .to( + Value.protoMessageArray( + Arrays.asList( + SingerInfo.newBuilder().setSingerId(23).build(), + SingerInfo.getDefaultInstance()), + SingerInfo.getDescriptor())) + .set("protoEnumArray") + .to(Value.protoEnumArray(Arrays.asList(Genre.JAZZ, Genre.ROCK), Genre.getDescriptor())) .build(); @Test @@ -118,6 +133,10 @@ public void testRetry() { Type.StructField.of("stringVal", Type.string()), Type.StructField.of("jsonVal", Type.json()), Type.StructField.of("pgJsonbVal", Type.pgJsonb()), + Type.StructField.of( + "protoMessageVal", Type.proto(SingerInfo.getDescriptor().getFullName())), + Type.StructField.of( + "protoEnumVal", Type.protoEnum(Genre.getDescriptor().getFullName())), Type.StructField.of("byteVal", Type.bytes()), Type.StructField.of("timestamp", Type.timestamp()), Type.StructField.of("date", Type.date()), @@ -131,7 +150,12 @@ public void testRetry() { Type.StructField.of("dateArray", Type.array(Type.date())), Type.StructField.of("stringArray", Type.array(Type.string())), Type.StructField.of("jsonArray", Type.array(Type.json())), - Type.StructField.of("pgJsonbArray", Type.array(Type.pgJsonb()))); + Type.StructField.of("pgJsonbArray", Type.array(Type.pgJsonb())), + Type.StructField.of( + "protoMessageArray", + Type.array(Type.proto(SingerInfo.getDescriptor().getFullName()))), + Type.StructField.of( + "protoEnumArray", Type.array(Type.protoEnum(Genre.getDescriptor().getFullName())))); Struct rowNonNullValues = Struct.newBuilder() .set("boolVal") @@ -150,6 +174,10 @@ public void testRetry() { .to(Value.json("{\"color\":\"red\",\"value\":\"#f00\"}")) .set("pgJsonbVal") .to(Value.pgJsonb("{\"color\":\"red\",\"value\":\"#f00\"}")) + .set("protoMessageVal") + .to(SingerInfo.newBuilder().setSingerId(98).setNationality("C1").build()) + .set("protoEnumVal") + .to(Genre.POP) .set("byteVal") .to(Value.bytes(ByteArray.copyFrom("test".getBytes(StandardCharsets.UTF_8)))) .set("timestamp") @@ -192,6 +220,15 @@ public void testRetry() { .to( Value.pgJsonbArray( Arrays.asList("{\"color\":\"red\",\"value\":\"#f00\"}", null, "{}"))) + .set("protoMessageArray") + .to( + Value.protoMessageArray( + Arrays.asList( + SingerInfo.newBuilder().setSingerId(11).setNationality("C1").build(), + SingerInfo.getDefaultInstance()), + SingerInfo.getDescriptor())) + .set("protoEnumArray") + .to(Value.protoEnumArray(Arrays.asList(Genre.POP, Genre.ROCK), Genre.getDescriptor())) .build(); Struct rowNullValues = Struct.newBuilder() @@ -211,6 +248,10 @@ public void testRetry() { .to(Value.json(null)) .set("pgJsonbVal") .to(Value.pgJsonb(null)) + .set("protoMessageVal") + .to(Value.protoMessage(null, SingerInfo.getDescriptor().getFullName())) + .set("protoEnumVal") + .to(Value.protoEnum(null, Genre.getDescriptor().getFullName())) .set("byteVal") .to((ByteArray) null) .set("timestamp") @@ -239,6 +280,10 @@ public void testRetry() { .toJsonArray(null) .set("pgJsonbArray") .toPgJsonbArray(null) + .set("protoMessageArray") + .to(Value.protoMessageArray(null, SingerInfo.getDescriptor())) + .set("protoEnumArray") + .to(Value.protoEnumArray(null, Genre.getDescriptor())) .build(); ParsedStatement parsedStatement = mock(ParsedStatement.class); diff --git a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/connection/DirectExecuteResultSetTest.java b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/connection/DirectExecuteResultSetTest.java index 346055060ab..1e4f96d1568 100644 --- a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/connection/DirectExecuteResultSetTest.java +++ b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/connection/DirectExecuteResultSetTest.java @@ -25,15 +25,20 @@ import com.google.cloud.spanner.ResultSet; import com.google.cloud.spanner.ResultSets; +import com.google.cloud.spanner.SingerProto.Genre; +import com.google.cloud.spanner.SingerProto.SingerInfo; import com.google.cloud.spanner.Struct; import com.google.cloud.spanner.Type; import com.google.cloud.spanner.Type.StructField; +import com.google.protobuf.AbstractMessage; +import com.google.protobuf.ProtocolMessageEnum; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.lang.reflect.Modifier; import java.util.Arrays; import java.util.Collections; import java.util.List; +import java.util.function.Function; import org.junit.Test; import org.junit.runner.RunWith; import org.junit.runners.JUnit4; @@ -123,7 +128,7 @@ private void callMethods( boolean exception = false; int numberOfParameters = method.getParameterTypes().length; Class firstParameterType = null; - if (numberOfParameters == 1) { + if (numberOfParameters >= 1) { firstParameterType = method.getParameterTypes()[0]; } try { @@ -140,8 +145,32 @@ private void callMethods( fail("unknown parameter type"); } break; + case 2: + Class secondParameterType = method.getParameterTypes()[1]; + Object firstArgument = null, secondArgument = null; + + if (firstParameterType == String.class) { + firstArgument = "test"; + } else if (firstParameterType == int.class) { + firstArgument = 0; + } + + if (secondParameterType == Function.class) { + Function lambdaFunction = + (val) -> Genre.forNumber(val.intValue()); + secondArgument = lambdaFunction; + } else if (secondParameterType == AbstractMessage.class) { + secondArgument = SingerInfo.getDefaultInstance(); + } + + if (firstArgument != null && secondArgument != null) { + method.invoke(subject, firstArgument, secondArgument); + } else { + fail("unknown parameter type"); + } + break; default: - fail("method with more than 1 parameter is unknown"); + fail("method with more than 2 parameters is unknown"); } } catch (InvocationTargetException e) { if (e.getCause().getClass().equals(expectedException)) { @@ -261,6 +290,25 @@ public void testValidMethodCall() throws IllegalArgumentException { subject.getPgJsonbList("test2"); verify(delegate).getPgJsonbList("test2"); + subject.getProtoMessage(0, SingerInfo.getDefaultInstance()); + verify(delegate).getProtoMessage(0, SingerInfo.getDefaultInstance()); + subject.getProtoMessage("test0", SingerInfo.getDefaultInstance()); + verify(delegate).getProtoMessage("test0", SingerInfo.getDefaultInstance()); + subject.getProtoMessageList(0, SingerInfo.getDefaultInstance()); + verify(delegate).getProtoMessageList(0, SingerInfo.getDefaultInstance()); + subject.getProtoMessageList("test0", SingerInfo.getDefaultInstance()); + verify(delegate).getProtoMessageList("test0", SingerInfo.getDefaultInstance()); + + Function lambdaFunction = Genre::forNumber; + subject.getProtoEnum(0, lambdaFunction); + verify(delegate).getProtoEnum(0, lambdaFunction); + subject.getProtoEnum("test0", lambdaFunction); + verify(delegate).getProtoEnum("test0", lambdaFunction); + subject.getProtoEnumList(0, lambdaFunction); + verify(delegate).getProtoEnumList(0, lambdaFunction); + subject.getProtoEnumList("test0", lambdaFunction); + verify(delegate).getProtoEnumList("test0", lambdaFunction); + subject.getStructList(0); subject.getStructList("test0"); diff --git a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/connection/RandomResultSetGenerator.java b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/connection/RandomResultSetGenerator.java index f8415fb00eb..69ae89b2ee9 100644 --- a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/connection/RandomResultSetGenerator.java +++ b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/connection/RandomResultSetGenerator.java @@ -19,6 +19,8 @@ import com.google.cloud.Date; import com.google.cloud.Timestamp; import com.google.cloud.spanner.Dialect; +import com.google.cloud.spanner.SingerProto.Genre; +import com.google.cloud.spanner.SingerProto.SingerInfo; import com.google.common.io.BaseEncoding; import com.google.protobuf.ListValue; import com.google.protobuf.NullValue; @@ -32,6 +34,9 @@ import com.google.spanner.v1.TypeAnnotationCode; import com.google.spanner.v1.TypeCode; import java.math.BigDecimal; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; import java.util.Random; /** @@ -40,73 +45,103 @@ */ public class RandomResultSetGenerator { public static Type[] generateAllTypes(Dialect dialect) { - return new Type[] { - Type.newBuilder().setCode(TypeCode.BOOL).build(), - Type.newBuilder().setCode(TypeCode.INT64).build(), - Type.newBuilder().setCode(TypeCode.FLOAT64).build(), - dialect == Dialect.POSTGRESQL - ? Type.newBuilder() - .setCode(TypeCode.NUMERIC) - .setTypeAnnotation(TypeAnnotationCode.PG_NUMERIC) - .build() - : Type.newBuilder().setCode(TypeCode.NUMERIC).build(), - Type.newBuilder().setCode(TypeCode.STRING).build(), - dialect == Dialect.POSTGRESQL - ? Type.newBuilder() - .setCode(TypeCode.JSON) - .setTypeAnnotation(TypeAnnotationCode.PG_JSONB) - .build() - : Type.newBuilder().setCode(TypeCode.JSON).build(), - Type.newBuilder().setCode(TypeCode.BYTES).build(), - Type.newBuilder().setCode(TypeCode.DATE).build(), - Type.newBuilder().setCode(TypeCode.TIMESTAMP).build(), - Type.newBuilder() - .setCode(TypeCode.ARRAY) - .setArrayElementType(Type.newBuilder().setCode(TypeCode.BOOL)) - .build(), - Type.newBuilder() - .setCode(TypeCode.ARRAY) - .setArrayElementType(Type.newBuilder().setCode(TypeCode.INT64)) - .build(), - Type.newBuilder() - .setCode(TypeCode.ARRAY) - .setArrayElementType(Type.newBuilder().setCode(TypeCode.FLOAT64)) - .build(), - Type.newBuilder() - .setCode(TypeCode.ARRAY) - .setArrayElementType( - dialect == Dialect.POSTGRESQL - ? Type.newBuilder() - .setCode(TypeCode.NUMERIC) - .setTypeAnnotation(TypeAnnotationCode.PG_NUMERIC) - : Type.newBuilder().setCode(TypeCode.NUMERIC)) - .build(), - Type.newBuilder() - .setCode(TypeCode.ARRAY) - .setArrayElementType(Type.newBuilder().setCode(TypeCode.STRING)) - .build(), - Type.newBuilder() - .setCode(TypeCode.ARRAY) - .setArrayElementType( - dialect == Dialect.POSTGRESQL - ? Type.newBuilder() - .setCode(TypeCode.JSON) - .setTypeAnnotation(TypeAnnotationCode.PG_JSONB) - : Type.newBuilder().setCode(TypeCode.JSON)) - .build(), - Type.newBuilder() - .setCode(TypeCode.ARRAY) - .setArrayElementType(Type.newBuilder().setCode(TypeCode.BYTES)) - .build(), - Type.newBuilder() - .setCode(TypeCode.ARRAY) - .setArrayElementType(Type.newBuilder().setCode(TypeCode.DATE)) - .build(), - Type.newBuilder() - .setCode(TypeCode.ARRAY) - .setArrayElementType(Type.newBuilder().setCode(TypeCode.TIMESTAMP)) - .build(), - }; + List types = + new ArrayList( + Arrays.asList( + Type.newBuilder().setCode(TypeCode.BOOL).build(), + Type.newBuilder().setCode(TypeCode.INT64).build(), + Type.newBuilder().setCode(TypeCode.FLOAT64).build(), + dialect == Dialect.POSTGRESQL + ? Type.newBuilder() + .setCode(TypeCode.NUMERIC) + .setTypeAnnotation(TypeAnnotationCode.PG_NUMERIC) + .build() + : Type.newBuilder().setCode(TypeCode.NUMERIC).build(), + Type.newBuilder().setCode(TypeCode.STRING).build(), + dialect == Dialect.POSTGRESQL + ? Type.newBuilder() + .setCode(TypeCode.JSON) + .setTypeAnnotation(TypeAnnotationCode.PG_JSONB) + .build() + : Type.newBuilder().setCode(TypeCode.JSON).build(), + Type.newBuilder().setCode(TypeCode.BYTES).build(), + Type.newBuilder().setCode(TypeCode.DATE).build(), + Type.newBuilder().setCode(TypeCode.TIMESTAMP).build(), + Type.newBuilder() + .setCode(TypeCode.ARRAY) + .setArrayElementType(Type.newBuilder().setCode(TypeCode.BOOL)) + .build(), + Type.newBuilder() + .setCode(TypeCode.ARRAY) + .setArrayElementType(Type.newBuilder().setCode(TypeCode.INT64)) + .build(), + Type.newBuilder() + .setCode(TypeCode.ARRAY) + .setArrayElementType(Type.newBuilder().setCode(TypeCode.FLOAT64)) + .build(), + Type.newBuilder() + .setCode(TypeCode.ARRAY) + .setArrayElementType( + dialect == Dialect.POSTGRESQL + ? Type.newBuilder() + .setCode(TypeCode.NUMERIC) + .setTypeAnnotation(TypeAnnotationCode.PG_NUMERIC) + : Type.newBuilder().setCode(TypeCode.NUMERIC)) + .build(), + Type.newBuilder() + .setCode(TypeCode.ARRAY) + .setArrayElementType(Type.newBuilder().setCode(TypeCode.STRING)) + .build(), + Type.newBuilder() + .setCode(TypeCode.ARRAY) + .setArrayElementType( + dialect == Dialect.POSTGRESQL + ? Type.newBuilder() + .setCode(TypeCode.JSON) + .setTypeAnnotation(TypeAnnotationCode.PG_JSONB) + : Type.newBuilder().setCode(TypeCode.JSON)) + .build(), + Type.newBuilder() + .setCode(TypeCode.ARRAY) + .setArrayElementType(Type.newBuilder().setCode(TypeCode.BYTES)) + .build(), + Type.newBuilder() + .setCode(TypeCode.ARRAY) + .setArrayElementType(Type.newBuilder().setCode(TypeCode.DATE)) + .build(), + Type.newBuilder() + .setCode(TypeCode.ARRAY) + .setArrayElementType(Type.newBuilder().setCode(TypeCode.TIMESTAMP)) + .build())); + + // appendProtoTypes(types, dialect); + Type[] typeArray = new Type[types.size()]; + typeArray = types.toArray(typeArray); + return typeArray; + } + + /** To append Proto & Enum types * */ + private static void appendProtoTypes(List types, Dialect dialect) { + if (dialect == Dialect.GOOGLE_STANDARD_SQL) { + types.add(Type.newBuilder().setCode(TypeCode.PROTO).setProtoTypeFqn("testProto").build()); + types.add(Type.newBuilder().setCode(TypeCode.ENUM).setProtoTypeFqn("testEnum").build()); + types.add( + Type.newBuilder() + .setCode(TypeCode.ARRAY) + .setArrayElementType( + Type.newBuilder() + .setCode(TypeCode.PROTO) + .setProtoTypeFqn(SingerInfo.getDescriptor().getFullName())) + .build()); + types.add( + Type.newBuilder() + .setCode(TypeCode.ARRAY) + .setArrayElementType( + Type.newBuilder() + .setCode(TypeCode.ENUM) + .setProtoTypeFqn(Genre.getDescriptor().getFullName())) + .build()); + } } public static ResultSetMetadata generateAllTypesMetadata(Type[] types) { @@ -171,6 +206,7 @@ private void setRandomValue(Value.Builder builder, Type type) { break; case STRING: case BYTES: + case PROTO: byte[] bytes = new byte[random.nextInt(200)]; random.nextBytes(bytes); builder.setStringValue(BaseEncoding.base64().encode(bytes)); @@ -199,6 +235,7 @@ private void setRandomValue(Value.Builder builder, Type type) { } break; case INT64: + case ENUM: builder.setStringValue(String.valueOf(random.nextLong())); break; case TIMESTAMP: diff --git a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/connection/ReadWriteTransactionTest.java b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/connection/ReadWriteTransactionTest.java index 358e8faf284..0f083fd1e50 100644 --- a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/connection/ReadWriteTransactionTest.java +++ b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/connection/ReadWriteTransactionTest.java @@ -40,6 +40,8 @@ import com.google.cloud.spanner.ReadContext.QueryAnalyzeMode; import com.google.cloud.spanner.ResultSet; import com.google.cloud.spanner.ResultSets; +import com.google.cloud.spanner.SingerProto.Genre; +import com.google.cloud.spanner.SingerProto.SingerInfo; import com.google.cloud.spanner.SpannerException; import com.google.cloud.spanner.SpannerExceptionFactory; import com.google.cloud.spanner.Statement; @@ -53,6 +55,7 @@ import com.google.cloud.spanner.connection.AbstractStatementParser.ParsedStatement; import com.google.cloud.spanner.connection.AbstractStatementParser.StatementType; import com.google.cloud.spanner.connection.UnitOfWork.CallType; +import com.google.protobuf.ProtocolMessageEnum; import com.google.rpc.RetryInfo; import com.google.spanner.v1.ResultSetStats; import io.grpc.Metadata; @@ -508,13 +511,25 @@ public void testChecksumResultSet() { "[{\"color\":\"red\",\"value\":\"#f00\"},{\"color\":\"green\",\"value\":\"#0f0\"},{\"color\":\"blue\",\"value\":\"#00f\"},{\"color\":\"cyan\",\"value\":\"#0ff\"},{\"color\":\"magenta\",\"value\":\"#f0f\"},{\"color\":\"yellow\",\"value\":\"#ff0\"},{\"color\":\"black\",\"value\":\"#000\"}]"; String emptyArrayJson = "[]"; String simpleJson = "{\"color\":\"red\",\"value\":\"#f00\"}"; + SingerInfo protoMessageVal = + SingerInfo.newBuilder() + .setSingerId(111) + .setNationality("COUNTRY1") + .setGenre(Genre.FOLK) + .build(); + ProtocolMessageEnum protoEnumVal = Genre.ROCK; ResultSet delegate1 = ResultSets.forRows( Type.struct( StructField.of("ID", Type.int64()), StructField.of("NAME", Type.string()), StructField.of("AMOUNT", Type.numeric()), - StructField.of("JSON", Type.json())), + StructField.of("JSON", Type.json()), + StructField.of( + "PROTO", Type.proto(protoMessageVal.getDescriptorForType().getFullName())), + StructField.of( + "PROTOENUM", + Type.protoEnum(protoEnumVal.getDescriptorForType().getFullName()))), Arrays.asList( Struct.newBuilder() .set("ID") @@ -525,6 +540,10 @@ public void testChecksumResultSet() { .to(BigDecimal.valueOf(550, 2)) .set("JSON") .to(Value.json(simpleJson)) + .set("PROTO") + .to(protoMessageVal) + .set("PROTOENUM") + .to(protoEnumVal) .build(), Struct.newBuilder() .set("ID") @@ -535,6 +554,10 @@ public void testChecksumResultSet() { .to(BigDecimal.valueOf(750, 2)) .set("JSON") .to(Value.json(arrayJson)) + .set("PROTO") + .to(protoMessageVal) + .set("PROTOENUM") + .to(Genre.JAZZ) .build())); ChecksumResultSet rs1 = transaction.createChecksumResultSet(delegate1, parsedStatement, AnalyzeMode.NONE); @@ -544,7 +567,12 @@ public void testChecksumResultSet() { StructField.of("ID", Type.int64()), StructField.of("NAME", Type.string()), StructField.of("AMOUNT", Type.numeric()), - StructField.of("JSON", Type.json())), + StructField.of("JSON", Type.json()), + StructField.of( + "PROTO", Type.proto(protoMessageVal.getDescriptorForType().getFullName())), + StructField.of( + "PROTOENUM", + Type.protoEnum(protoEnumVal.getDescriptorForType().getFullName()))), Arrays.asList( Struct.newBuilder() .set("ID") @@ -555,6 +583,10 @@ public void testChecksumResultSet() { .to(new BigDecimal("5.50")) .set("JSON") .to(Value.json(simpleJson)) + .set("PROTO") + .to(protoMessageVal) + .set("PROTOENUM") + .to(protoEnumVal) .build(), Struct.newBuilder() .set("ID") @@ -565,6 +597,10 @@ public void testChecksumResultSet() { .to(new BigDecimal("7.50")) .set("JSON") .to(Value.json(arrayJson)) + .set("PROTO") + .to(protoMessageVal) + .set("PROTOENUM") + .to(Genre.JAZZ) .build())); ChecksumResultSet rs2 = transaction.createChecksumResultSet(delegate2, parsedStatement, AnalyzeMode.NONE); @@ -575,7 +611,12 @@ public void testChecksumResultSet() { StructField.of("ID", Type.int64()), StructField.of("NAME", Type.string()), StructField.of("AMOUNT", Type.numeric()), - StructField.of("JSON", Type.json())), + StructField.of("JSON", Type.json()), + StructField.of( + "PROTO", Type.proto(protoMessageVal.getDescriptorForType().getFullName())), + StructField.of( + "PROTOENUM", + Type.protoEnum(protoEnumVal.getDescriptorForType().getFullName()))), Arrays.asList( Struct.newBuilder() .set("ID") @@ -586,6 +627,10 @@ public void testChecksumResultSet() { .to(new BigDecimal("7.50")) .set("JSON") .to(Value.json(arrayJson)) + .set("PROTO") + .to(protoMessageVal) + .set("PROTOENUM") + .to(Genre.JAZZ) .build(), Struct.newBuilder() .set("ID") @@ -596,6 +641,10 @@ public void testChecksumResultSet() { .to(new BigDecimal("5.50")) .set("JSON") .to(Value.json(simpleJson)) + .set("PROTO") + .to(protoMessageVal) + .set("PROTOENUM") + .to(protoEnumVal) .build())); ChecksumResultSet rs3 = transaction.createChecksumResultSet(delegate3, parsedStatement, AnalyzeMode.NONE); @@ -607,7 +656,12 @@ public void testChecksumResultSet() { StructField.of("ID", Type.int64()), StructField.of("NAME", Type.string()), StructField.of("AMOUNT", Type.numeric()), - StructField.of("JSON", Type.json())), + StructField.of("JSON", Type.json()), + StructField.of( + "PROTO", Type.proto(protoMessageVal.getDescriptorForType().getFullName())), + StructField.of( + "PROTOENUM", + Type.protoEnum(protoEnumVal.getDescriptorForType().getFullName()))), Arrays.asList( Struct.newBuilder() .set("ID") @@ -618,6 +672,10 @@ public void testChecksumResultSet() { .to(new BigDecimal("5.50")) .set("JSON") .to(Value.json(simpleJson)) + .set("PROTO") + .to(protoMessageVal) + .set("PROTOENUM") + .to(protoEnumVal) .build(), Struct.newBuilder() .set("ID") @@ -628,6 +686,10 @@ public void testChecksumResultSet() { .to(new BigDecimal("7.50")) .set("JSON") .to(Value.json(arrayJson)) + .set("PROTO") + .to(protoMessageVal) + .set("PROTOENUM") + .to(Genre.JAZZ) .build(), Struct.newBuilder() .set("ID") @@ -638,6 +700,10 @@ public void testChecksumResultSet() { .to(new BigDecimal("9.99")) .set("JSON") .to(Value.json(emptyArrayJson)) + .set("PROTO") + .to(null, SingerInfo.getDescriptor()) + .set("PROTOENUM") + .to(Genre.POP) .build())); ChecksumResultSet rs4 = transaction.createChecksumResultSet(delegate4, parsedStatement, AnalyzeMode.NONE); diff --git a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/connection/ReplaceableForwardingResultSetTest.java b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/connection/ReplaceableForwardingResultSetTest.java index 3f69c2171e4..bbb34675147 100644 --- a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/connection/ReplaceableForwardingResultSetTest.java +++ b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/connection/ReplaceableForwardingResultSetTest.java @@ -26,16 +26,21 @@ import com.google.cloud.spanner.ResultSet; import com.google.cloud.spanner.ResultSets; +import com.google.cloud.spanner.SingerProto.Genre; +import com.google.cloud.spanner.SingerProto.SingerInfo; import com.google.cloud.spanner.SpannerException; import com.google.cloud.spanner.Struct; import com.google.cloud.spanner.Type; import com.google.cloud.spanner.Type.StructField; +import com.google.protobuf.AbstractMessage; +import com.google.protobuf.ProtocolMessageEnum; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.lang.reflect.Modifier; import java.util.Arrays; import java.util.Collections; import java.util.List; +import java.util.function.Function; import org.junit.Test; import org.junit.runner.RunWith; import org.junit.runners.JUnit4; @@ -164,7 +169,7 @@ private void callMethods( boolean exception = false; int numberOfParameters = method.getParameterTypes().length; Class firstParameterType = null; - if (numberOfParameters == 1) { + if (numberOfParameters >= 1) { firstParameterType = method.getParameterTypes()[0]; } try { @@ -181,8 +186,32 @@ private void callMethods( fail("unknown parameter type"); } break; + case 2: + Class secondParameterType = method.getParameterTypes()[1]; + Object firstArgument = null, secondArgument = null; + + if (firstParameterType == String.class) { + firstArgument = "test"; + } else if (firstParameterType == int.class) { + firstArgument = 0; + } + + if (secondParameterType == Function.class) { + Function lambdaFunction = + (val) -> Genre.forNumber(val.intValue()); + secondArgument = lambdaFunction; + } else if (secondParameterType == AbstractMessage.class) { + secondArgument = SingerInfo.getDefaultInstance(); + } + + if (firstArgument != null && secondArgument != null) { + method.invoke(subject, firstArgument, secondArgument); + } else { + fail("unknown parameter type"); + } + break; default: - fail("method with more than 1 parameter is unknown"); + fail("method with more than 2 parameters is unknown"); } } catch (InvocationTargetException e) { if (e.getCause().getClass().equals(expectedException)) { @@ -296,6 +325,25 @@ public void testValidMethodCall() throws IllegalArgumentException { subject.getJsonList("test2"); verify(delegate).getJsonList("test2"); + subject.getProtoMessage(0, SingerInfo.getDefaultInstance()); + verify(delegate).getProtoMessage(0, SingerInfo.getDefaultInstance()); + subject.getProtoMessage("test0", SingerInfo.getDefaultInstance()); + verify(delegate).getProtoMessage("test0", SingerInfo.getDefaultInstance()); + subject.getProtoMessageList(0, SingerInfo.getDefaultInstance()); + verify(delegate).getProtoMessageList(0, SingerInfo.getDefaultInstance()); + subject.getProtoMessageList("test0", SingerInfo.getDefaultInstance()); + verify(delegate).getProtoMessageList("test0", SingerInfo.getDefaultInstance()); + + Function lambdaFunction = Genre::forNumber; + subject.getProtoEnum(0, lambdaFunction); + verify(delegate).getProtoEnum(0, lambdaFunction); + subject.getProtoEnum("test0", lambdaFunction); + verify(delegate).getProtoEnum("test0", lambdaFunction); + subject.getProtoEnumList(0, lambdaFunction); + verify(delegate).getProtoEnumList(0, lambdaFunction); + subject.getProtoEnumList("test0", lambdaFunction); + verify(delegate).getProtoEnumList("test0", lambdaFunction); + subject.getStructList(0); subject.getStructList("test0"); diff --git a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/it/ITProtoColumnTest.java b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/it/ITProtoColumnTest.java new file mode 100644 index 00000000000..c1e06f9ad7b --- /dev/null +++ b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/it/ITProtoColumnTest.java @@ -0,0 +1,402 @@ +/* + * 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.google.cloud.spanner.it; + +import static com.google.cloud.spanner.testing.EmulatorSpannerHelper.isUsingEmulator; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertThrows; +import static org.junit.Assume.assumeFalse; + +import com.google.cloud.ByteArray; +import com.google.cloud.spanner.Database; +import com.google.cloud.spanner.DatabaseAdminClient; +import com.google.cloud.spanner.DatabaseClient; +import com.google.cloud.spanner.DatabaseId; +import com.google.cloud.spanner.IntegrationTestEnv; +import com.google.cloud.spanner.Key; +import com.google.cloud.spanner.KeySet; +import com.google.cloud.spanner.Mutation; +import com.google.cloud.spanner.ParallelIntegrationTest; +import com.google.cloud.spanner.ResultSet; +import com.google.cloud.spanner.SingerProto.Genre; +import com.google.cloud.spanner.SingerProto.SingerInfo; +import com.google.cloud.spanner.SpannerException; +import com.google.cloud.spanner.Statement; +import com.google.cloud.spanner.testing.EmulatorSpannerHelper; +import com.google.cloud.spanner.testing.RemoteSpannerHelper; +import com.google.common.collect.ImmutableList; +import com.google.protobuf.AbstractMessage; +import com.google.protobuf.InvalidProtocolBufferException.InvalidWireTypeException; +import com.google.protobuf.ProtocolMessageEnum; +import com.google.spanner.admin.database.v1.Backup; +import com.google.spanner.admin.database.v1.GetDatabaseDdlResponse; +import java.io.InputStream; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; +import java.util.concurrent.TimeUnit; +import org.junit.After; +import org.junit.AfterClass; +import org.junit.BeforeClass; +import org.junit.ClassRule; +import org.junit.Test; +import org.junit.experimental.categories.Category; +import org.junit.runner.RunWith; +import org.junit.runners.JUnit4; + +// Integration Tests to test DDL, DML and DQL for Proto Columns and Enums +@Category(ParallelIntegrationTest.class) +@RunWith(JUnit4.class) +public class ITProtoColumnTest { + + @ClassRule public static IntegrationTestEnv env = new IntegrationTestEnv(); + private static DatabaseId databaseID; + private static DatabaseAdminClient dbAdminClient; + private static DatabaseClient databaseClient; + + @BeforeClass + public static void setUpDatabase() throws Exception { + assumeFalse( + "Proto Column is not supported in the emulator", EmulatorSpannerHelper.isUsingEmulator()); + RemoteSpannerHelper testHelper = env.getTestHelper(); + databaseID = DatabaseId.of(testHelper.getInstanceId(), testHelper.getUniqueDatabaseId()); + dbAdminClient = testHelper.getClient().getDatabaseAdminClient(); + createDatabase(); + databaseClient = testHelper.getClient().getDatabaseClient(databaseID); + } + + public static void createDatabase() throws Exception { + InputStream in = + ITProtoColumnTest.class + .getClassLoader() + .getResourceAsStream("com/google/cloud/spanner/descriptors.pb"); + final Database databaseToCreate = + dbAdminClient.newDatabaseBuilder(databaseID).setProtoDescriptors(in).build(); + final Database createdDatabase = + dbAdminClient + .createDatabase( + databaseToCreate, + Arrays.asList( + "CREATE PROTO BUNDLE (" + + "spanner.examples.music.SingerInfo," + + "spanner.examples.music.Genre," + + ")", + "CREATE TABLE Singers (" + + " SingerId INT64 NOT NULL," + + " FirstName STRING(1024)," + + " LastName STRING(1024)," + + " SingerInfo spanner.examples.music.SingerInfo," + + " SingerGenre spanner.examples.music.Genre," + + " SingerNationality STRING(1024) AS (SingerInfo.nationality) STORED," + + " ) PRIMARY KEY (SingerNationality, SingerGenre)", + "CREATE TABLE Types (" + + " RowID INT64 NOT NULL," + + " Int64a INT64," + + " Bytes BYTES(MAX)," + + " Int64Array ARRAY," + + " BytesArray ARRAY," + + " ProtoMessage spanner.examples.music.SingerInfo," + + " ProtoEnum spanner.examples.music.Genre," + + " ProtoMessageArray ARRAY," + + " ProtoEnumArray ARRAY," + + " ) PRIMARY KEY (RowID)", + "CREATE INDEX SingerByNationalityAndGenre ON Singers(SingerNationality, SingerGenre)" + + " STORING (SingerId, FirstName, LastName)")) + .get(5, TimeUnit.MINUTES); + + assertEquals(databaseID.getDatabase(), createdDatabase.getId().getDatabase()); + + GetDatabaseDdlResponse response = + dbAdminClient.getDatabaseDdlResponse( + databaseID.getInstanceId().getInstance(), databaseID.getDatabase()); + assertNotNull(response.getProtoDescriptors()); + in.close(); + } + + @AfterClass + public static void afterClass() throws Exception { + try { + if (!isUsingEmulator()) { + dbAdminClient.dropDatabase( + databaseID.getInstanceId().getInstance(), databaseID.getDatabase()); + } + } catch (Exception e) { + System.err.println( + "Failed to drop database " + + dbAdminClient + .getDatabase(databaseID.getInstanceId().getInstance(), databaseID.getDatabase()) + .getId() + + ", skipping...: " + + e.getMessage()); + } + } + + @After + public void after() throws Exception { + databaseClient.write(ImmutableList.of(Mutation.delete("Types", KeySet.all()))); + databaseClient.write(ImmutableList.of(Mutation.delete("Singers", KeySet.all()))); + } + + /** + * Test to check data update and read queries on Proto Messages, Proto Enums and their arrays. + * Test also checks for compatability between following types: 1. Proto Messages and Bytes 2. + * Proto Enums and Int64 + */ + @Test + public void testProtoColumnsUpdateAndRead() { + assumeFalse( + "Proto Column is not supported in the emulator", EmulatorSpannerHelper.isUsingEmulator()); + SingerInfo singerInfo = + SingerInfo.newBuilder().setSingerId(1).setNationality("Country1").build(); + ByteArray singerInfoBytes = ByteArray.copyFrom(singerInfo.toByteArray()); + + Genre genre = Genre.JAZZ; + long genreConst = genre.getNumber(); + + List singerInfoList = + Arrays.asList(singerInfo, null, SingerInfo.getDefaultInstance()); + List singerInfoBytesList = + Arrays.asList( + singerInfoBytes, + null, + ByteArray.copyFrom(SingerInfo.getDefaultInstance().toByteArray())); + + List enumList = Arrays.asList(Genre.FOLK, null, Genre.ROCK); + List enumConstList = + Arrays.asList((long) Genre.FOLK_VALUE, null, (long) Genre.ROCK_VALUE); + + // Inserting two rows with same data except rowID as it's used as PK. + databaseClient.write( + ImmutableList.of( + Mutation.newInsertOrUpdateBuilder("Types") + .set("RowID") + .to(1) + .set("Int64a") + .to(genreConst) + .set("Bytes") + .to(singerInfoBytes) + .set("Int64Array") + .toInt64Array(enumConstList) + .set("BytesArray") + .toBytesArray(singerInfoBytesList) + .set("ProtoMessage") + .to(singerInfo) + .set("ProtoEnum") + .to(genre) + .set("ProtoMessageArray") + .toProtoMessageArray(singerInfoList, SingerInfo.getDescriptor()) + .set("ProtoEnumArray") + .toProtoEnumArray(enumList, Genre.getDescriptor()) + .build(), + // Inter Compatability check between ProtoMessages/Bytes and Int64/Enum. + Mutation.newInsertOrUpdateBuilder("Types") + .set("RowID") + .to(2) + .set("Int64a") + .to(genre) + .set("Bytes") + .to(singerInfo) + .set("Int64Array") + .toProtoEnumArray(enumList, Genre.getDescriptor()) + .set("BytesArray") + .toProtoMessageArray(singerInfoList, SingerInfo.getDescriptor()) + .set("ProtoMessage") + .to(singerInfoBytes) + .set("ProtoEnum") + .to(genreConst) + .set("ProtoMessageArray") + .toBytesArray(singerInfoBytesList) + .set("ProtoEnumArray") + .toInt64Array(enumConstList) + .build())); + + try (ResultSet resultSet = + databaseClient.singleUse().executeQuery(Statement.of("SELECT * FROM " + "Types"))) { + + for (int i = 0; i < 2; i++) { + resultSet.next(); + assertEquals(i + 1, resultSet.getLong("RowID")); + assertEquals(genreConst, resultSet.getLong("Int64a")); + assertEquals(singerInfoBytes, resultSet.getBytes("Bytes")); + assertEquals(enumConstList, resultSet.getLongList("Int64Array")); + assertEquals(singerInfoBytesList, resultSet.getBytesList("BytesArray")); + assertEquals( + singerInfo, resultSet.getProtoMessage("ProtoMessage", SingerInfo.getDefaultInstance())); + assertEquals(genre, resultSet.getProtoEnum("ProtoEnum", Genre::forNumber)); + assertEquals( + singerInfoList, + resultSet.getProtoMessageList("ProtoMessageArray", SingerInfo.getDefaultInstance())); + assertEquals(enumList, resultSet.getProtoEnumList("ProtoEnumArray", Genre::forNumber)); + + // Check compatability between Proto Messages and Bytes + assertEquals(singerInfoBytes, resultSet.getBytes("ProtoMessage")); + assertEquals( + singerInfo, resultSet.getProtoMessage("Bytes", SingerInfo.getDefaultInstance())); + + assertEquals(singerInfoBytesList, resultSet.getBytesList("ProtoMessageArray")); + assertEquals( + singerInfoList, + resultSet.getProtoMessageList("BytesArray", SingerInfo.getDefaultInstance())); + + // Check compatability between Proto Enum and Int64 + assertEquals(genreConst, resultSet.getLong("ProtoEnum")); + assertEquals(genre, resultSet.getProtoEnum("Int64a", Genre::forNumber)); + + assertEquals(enumConstList, resultSet.getLongList("ProtoEnumArray")); + assertEquals(enumList, resultSet.getProtoEnumList("Int64Array", Genre::forNumber)); + } + } + } + + // Test to check Parameterized Queries, Primary Keys and Indexes. + @Test + public void testProtoColumnsDMLParameterizedQueriesPKAndIndexes() { + assumeFalse( + "Proto Column is not supported in the emulator", EmulatorSpannerHelper.isUsingEmulator()); + + SingerInfo singerInfo1 = + SingerInfo.newBuilder().setSingerId(1).setNationality("Country1").build(); + Genre genre1 = Genre.FOLK; + + SingerInfo singerInfo2 = + SingerInfo.newBuilder().setSingerId(2).setNationality("Country2").build(); + Genre genre2 = Genre.JAZZ; + + databaseClient + .readWriteTransaction() + .run( + transaction -> { + Statement statement1 = + Statement.newBuilder( + "INSERT INTO Singers (SingerId, FirstName, LastName, SingerInfo, SingerGenre) VALUES (1, \"FirstName1\", \"LastName1\", @singerInfo, @singerGenre)") + .bind("singerInfo") + .to(singerInfo1) + .bind("singerGenre") + .to(genre1) + .build(); + + Statement statement2 = + Statement.newBuilder( + "INSERT INTO Singers (SingerId, FirstName, LastName, SingerInfo, SingerGenre) VALUES (2, \"FirstName2\", \"LastName2\", @singerInfo, @singerGenre)") + .bind("singerInfo") + .to(singerInfo2) + .bind("singerGenre") + .to(genre2) + .build(); + + transaction.batchUpdate(Arrays.asList(statement1, statement2)); + return null; + }); + + // Read all rows based on Proto Message field and Proto Enum Primary key column values + ResultSet resultSet1 = + databaseClient + .singleUse() + .read( + "Singers", + KeySet.newBuilder() + .addKey(Key.of("Country1", Genre.FOLK)) + .addKey(Key.of("Country2", Genre.JAZZ)) + .build(), + Arrays.asList("SingerId", "FirstName", "LastName", "SingerInfo", "SingerGenre")); + + resultSet1.next(); + assertEquals(1, resultSet1.getLong("SingerId")); + assertEquals("FirstName1", resultSet1.getString("FirstName")); + assertEquals("LastName1", resultSet1.getString("LastName")); + assertEquals( + singerInfo1, resultSet1.getProtoMessage("SingerInfo", SingerInfo.getDefaultInstance())); + assertEquals(genre1, resultSet1.getProtoEnum("SingerGenre", Genre::forNumber)); + + resultSet1.next(); + assertEquals(2, resultSet1.getLong("SingerId")); + assertEquals("FirstName2", resultSet1.getString("FirstName")); + assertEquals("LastName2", resultSet1.getString("LastName")); + assertEquals( + singerInfo2, resultSet1.getProtoMessage("SingerInfo", SingerInfo.getDefaultInstance())); + assertEquals(genre2, resultSet1.getProtoEnum("SingerGenre", Genre::forNumber)); + + // Read rows using Index on Proto Message field and Proto Enum column + ResultSet resultSet2 = + databaseClient + .singleUse() + .readUsingIndex( + "Singers", + "SingerByNationalityAndGenre", + KeySet.singleKey(Key.of("Country2", Genre.JAZZ)), + Arrays.asList("SingerId", "FirstName", "LastName")); + resultSet2.next(); + assertEquals(2, resultSet2.getLong("SingerId")); + assertEquals("FirstName2", resultSet2.getString("FirstName")); + assertEquals("LastName2", resultSet2.getString("LastName")); + + // Filter using Parameterized DQL + ResultSet resultSet3 = + databaseClient + .singleUse() + .executeQuery( + Statement.newBuilder( + "SELECT SingerId, SingerInfo, SingerGenre FROM " + + "Singers WHERE SingerInfo.Nationality=@country AND SingerGenre=@genre") + .bind("country") + .to("Country2") + .bind("genre") + .to(Genre.JAZZ) + .build()); + + resultSet3.next(); + assertEquals(2, resultSet1.getLong("SingerId")); + assertEquals( + singerInfo2, resultSet1.getProtoMessage("SingerInfo", SingerInfo.getDefaultInstance())); + assertEquals(genre2, resultSet1.getProtoEnum("SingerGenre", Genre::forNumber)); + } + + // Test the exception in case Invalid protocol message object is provided while deserializing the + // data. + @Test + public void testProtoMessageDeserializationError() { + assumeFalse( + "Proto Column is not supported in the emulator", EmulatorSpannerHelper.isUsingEmulator()); + + SingerInfo singerInfo = + SingerInfo.newBuilder().setSingerId(1).setNationality("Country1").build(); + + databaseClient.write( + ImmutableList.of( + Mutation.newInsertOrUpdateBuilder("Types") + .set("RowID") + .to(1) + .set("ProtoMessage") + .to(singerInfo) + .build())); + + ResultSet resultSet = + databaseClient + .singleUse() + .read("Types", KeySet.all(), Collections.singletonList("ProtoMessage")); + resultSet.next(); + + SpannerException e = + assertThrows( + SpannerException.class, + () -> resultSet.getProtoMessage("ProtoMessage", Backup.getDefaultInstance())); + + // Underlying cause is InvalidWireTypeException + assertEquals(InvalidWireTypeException.class, e.getCause().getClass()); + } +} diff --git a/google-cloud-spanner/src/test/resources/com/google/cloud/spanner/descriptors.pb b/google-cloud-spanner/src/test/resources/com/google/cloud/spanner/descriptors.pb new file mode 100644 index 0000000000000000000000000000000000000000..3ebb79420b3ffd2ca3b3b57433a4a10bfa22b675 GIT binary patch literal 251 zcmd=3!N|o^oSB!NTBKJ{lwXoBBvxFIn3o6SrdA~87UZNB>*bafXC^DnXXN4v1}pT; zOUoCM=Hi5Ci_c7vU{qk#U=HGd2zaIl$#QWeWfqlW#HS>dq)IRWWjTX5!6Gg|0U-r0 z?!3g3%>2B>oXnC+31+Z7vXGE57i)TIUQwz93s8>FNLCNKqx9TCih>|&we+}H!F(Zh lF6IFL009Oe4lWii$EYX)Mi9%*-^W{k3B(HWclH)w1^^+RM@0Yt literal 0 HcmV?d00001 diff --git a/google-cloud-spanner/src/test/resources/com/google/cloud/spanner/singer.proto b/google-cloud-spanner/src/test/resources/com/google/cloud/spanner/singer.proto new file mode 100644 index 00000000000..b62b48ed67f --- /dev/null +++ b/google-cloud-spanner/src/test/resources/com/google/cloud/spanner/singer.proto @@ -0,0 +1,21 @@ +syntax = "proto2"; + +package spanner.examples.music; + +option java_package = "com.google.cloud.spanner"; +option java_outer_classname = "SingerProto"; +option java_multiple_files = false; + +message SingerInfo { + optional int64 singer_id = 1; + optional string birth_date = 2; + optional string nationality = 3; + optional Genre genre = 4; +} + +enum Genre { + POP = 0; + JAZZ = 1; + FOLK = 2; + ROCK = 3; +} From 420dcf4ab72428ac6ee314c78c3aff6fa95dc909 Mon Sep 17 00:00:00 2001 From: Tomo Suzuki Date: Fri, 26 Jan 2024 08:59:22 -0500 Subject: [PATCH 12/21] chore: README for google-cloud-spanner-executor module (#2818) --- google-cloud-spanner-executor/README.md | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 google-cloud-spanner-executor/README.md diff --git a/google-cloud-spanner-executor/README.md b/google-cloud-spanner-executor/README.md new file mode 100644 index 00000000000..78739a4949d --- /dev/null +++ b/google-cloud-spanner-executor/README.md @@ -0,0 +1,4 @@ +This module is for Google-internal use ([details]( +http://go/cloud-spanner-client-testing-design)). +This is not for customers. + From d3b08125da2237f21b405a2dcee307c69a7cc4cf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Knut=20Olav=20L=C3=B8ite?= Date: Fri, 26 Jan 2024 19:05:32 +0100 Subject: [PATCH 13/21] test: reduce test log spam (#2794) Several tests spammed the build log with various warnings and other log items that were irrelevant for the test output. This change removes as much as possible of that. --- .../com/google/cloud/spanner/SpannerImpl.java | 4 +- .../cloud/spanner/BaseSessionPoolTest.java | 2 +- .../cloud/spanner/ChannelUsageTest.java | 17 + .../spanner/DatabaseAdminClientTest.java | 27 +- .../cloud/spanner/DatabaseClientImplTest.java | 1201 +++++++++-------- .../com/google/cloud/spanner/FakeClock.java | 5 +- .../cloud/spanner/SessionPoolLeakTest.java | 3 +- .../spanner/SessionPoolMaintainerTest.java | 12 +- .../google/cloud/spanner/SessionPoolTest.java | 47 +- .../cloud/spanner/SpannerOptionsTest.java | 18 + .../connection/StatementTimeoutTest.java | 7 +- 11 files changed, 723 insertions(+), 620 deletions(-) diff --git a/google-cloud-spanner/src/main/java/com/google/cloud/spanner/SpannerImpl.java b/google-cloud-spanner/src/main/java/com/google/cloud/spanner/SpannerImpl.java index 5ff916bbe93..f1a7888c62c 100644 --- a/google-cloud-spanner/src/main/java/com/google/cloud/spanner/SpannerImpl.java +++ b/google-cloud-spanner/src/main/java/com/google/cloud/spanner/SpannerImpl.java @@ -250,13 +250,13 @@ void close(long timeout, TimeUnit unit) { synchronized (this) { checkClosed(); closedException = new ClosedException(); + } + try { closureFutures = new ArrayList<>(); for (DatabaseClientImpl dbClient : dbClients.values()) { closureFutures.add(dbClient.closeAsync(closedException)); } dbClients.clear(); - } - try { Futures.successfulAsList(closureFutures).get(timeout, unit); } catch (InterruptedException | ExecutionException | TimeoutException e) { throw SpannerExceptionFactory.newSpannerException(e); diff --git a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/BaseSessionPoolTest.java b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/BaseSessionPoolTest.java index d36d32bda2a..cbfa4bbb609 100644 --- a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/BaseSessionPoolTest.java +++ b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/BaseSessionPoolTest.java @@ -124,7 +124,7 @@ public CommitResponse writeWithOptions( void runMaintenanceLoop(FakeClock clock, SessionPool pool, long numCycles) { for (int i = 0; i < numCycles; i++) { pool.poolMaintainer.maintainPool(); - clock.currentTimeMillis += pool.poolMaintainer.loopFrequency; + clock.currentTimeMillis.addAndGet(pool.poolMaintainer.loopFrequency); } } } diff --git a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/ChannelUsageTest.java b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/ChannelUsageTest.java index 0e1f102b6da..5af4ad4d41f 100644 --- a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/ChannelUsageTest.java +++ b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/ChannelUsageTest.java @@ -52,6 +52,8 @@ import java.util.concurrent.ExecutionException; import java.util.concurrent.Executors; import java.util.concurrent.TimeUnit; +import java.util.logging.Level; +import java.util.logging.Logger; import org.junit.After; import org.junit.AfterClass; import org.junit.BeforeClass; @@ -111,6 +113,8 @@ public static Collection data() { ConcurrentHashMap.newKeySet(); private static final Set executeSqlLocalIps = ConcurrentHashMap.newKeySet(); + private static Level originalLogLevel; + @BeforeClass public static void startServer() throws IOException { mockSpanner = new MockSpannerServiceImpl(); @@ -167,6 +171,19 @@ public static void stopServer() throws InterruptedException { server.awaitTermination(); } + @BeforeClass + public static void disableLogging() { + Logger logger = Logger.getLogger(""); + originalLogLevel = logger.getLevel(); + logger.setLevel(Level.OFF); + } + + @AfterClass + public static void resetLogging() { + Logger logger = Logger.getLogger(""); + logger.setLevel(originalLogLevel); + } + @After public void reset() { mockSpanner.reset(); diff --git a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/DatabaseAdminClientTest.java b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/DatabaseAdminClientTest.java index 5ef7b508049..8bb644e75ce 100644 --- a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/DatabaseAdminClientTest.java +++ b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/DatabaseAdminClientTest.java @@ -85,7 +85,6 @@ public class DatabaseAdminClientTest { private static MockOperationsServiceImpl mockOperations; private static MockDatabaseAdminServiceImpl mockDatabaseAdmin; private static Server server; - private static InetSocketAddress address; private static Spanner spanner; private static DatabaseAdminClient client; @@ -98,7 +97,7 @@ public static void startStaticServer() throws Exception { mockOperations = new MockOperationsServiceImpl(); mockDatabaseAdmin = new MockDatabaseAdminServiceImpl(mockOperations); // This test uses a NettyServer to properly test network and timeout issues. - address = new InetSocketAddress("localhost", 0); + InetSocketAddress address = new InetSocketAddress("localhost", 0); server = NettyServerBuilder.forAddress(address) .addService(mockOperations) @@ -952,14 +951,20 @@ public void testRetriesDisabledForOperationOnAdminMethodQuotaPerMinutePerProject Status.RESOURCE_EXHAUSTED.withDescription("foo").asRuntimeException(trailers)); mockDatabaseAdmin.clearRequests(); - Spanner spannerWithoutRetries = - spanner.getOptions().toBuilder().disableAdministrativeRequestRetries().build().getService(); - AdminRequestsPerMinuteExceededException exception = - assertThrows( - AdminRequestsPerMinuteExceededException.class, - () -> spannerWithoutRetries.getDatabaseAdminClient().getDatabase(INSTANCE_ID, DB_ID)); - assertEquals(ErrorCode.RESOURCE_EXHAUSTED, exception.getErrorCode()); - // There should be only one request on the server, as the request was not retried. - assertEquals(1, mockDatabaseAdmin.countRequestsOfType(GetDatabaseRequest.class)); + try (Spanner spannerWithoutRetries = + spanner + .getOptions() + .toBuilder() + .disableAdministrativeRequestRetries() + .build() + .getService()) { + AdminRequestsPerMinuteExceededException exception = + assertThrows( + AdminRequestsPerMinuteExceededException.class, + () -> spannerWithoutRetries.getDatabaseAdminClient().getDatabase(INSTANCE_ID, DB_ID)); + assertEquals(ErrorCode.RESOURCE_EXHAUSTED, exception.getErrorCode()); + // There should be only one request on the server, as the request was not retried. + assertEquals(1, mockDatabaseAdmin.countRequestsOfType(GetDatabaseRequest.class)); + } } } diff --git a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/DatabaseClientImplTest.java b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/DatabaseClientImplTest.java index e6263568fe5..24c7e3fd95d 100644 --- a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/DatabaseClientImplTest.java +++ b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/DatabaseClientImplTest.java @@ -277,7 +277,7 @@ public void tearDown() { .setLoopFrequency(1000L) // main thread runs every 1s .setPoolMaintainerClock(poolMaintainerClock) .build(); - spanner = + try (Spanner spanner = SpannerOptions.newBuilder() .setProjectId(TEST_PROJECT) .setDatabaseRole(TEST_DATABASE_ROLE) @@ -285,52 +285,53 @@ public void tearDown() { .setCredentials(NoCredentials.getInstance()) .setSessionPoolOption(sessionPoolOptions) .build() - .getService(); - DatabaseClientImpl client = - (DatabaseClientImpl) - spanner.getDatabaseClient(DatabaseId.of(TEST_PROJECT, TEST_INSTANCE, TEST_DATABASE)); - Instant initialExecutionTime = client.pool.poolMaintainer.lastExecutionTime; - - poolMaintainerClock.currentTimeMillis += Duration.ofMinutes(3).toMillis(); - - try (TransactionManager manager = client.transactionManager()) { - TransactionContext transaction = manager.begin(); - mockSpanner.setCommitExecutionTime( - SimulatedExecutionTime.ofException( - mockSpanner.createSessionNotFoundException("TEST_SESSION_NAME"))); - while (true) { - try { - transaction.executeUpdate(UPDATE_STATEMENT); - - // Simulate a delay of 3 minutes to ensure that the below transaction is a long-running - // one. - // As per this test, anything which takes more than 2s is long-running - poolMaintainerClock.currentTimeMillis += Duration.ofMinutes(3).toMillis(); - // force trigger pool maintainer to check for long-running sessions - client.pool.poolMaintainer.maintainPool(); - - manager.commit(); - assertNotNull(manager.getCommitTimestamp()); - break; - } catch (AbortedException e) { - transaction = manager.resetForRetry(); + .getService()) { + DatabaseClientImpl client = + (DatabaseClientImpl) + spanner.getDatabaseClient(DatabaseId.of(TEST_PROJECT, TEST_INSTANCE, TEST_DATABASE)); + Instant initialExecutionTime = client.pool.poolMaintainer.lastExecutionTime; + + poolMaintainerClock.currentTimeMillis.addAndGet(Duration.ofMinutes(3).toMillis()); + + try (TransactionManager manager = client.transactionManager()) { + TransactionContext transaction = manager.begin(); + mockSpanner.setCommitExecutionTime( + SimulatedExecutionTime.ofException( + mockSpanner.createSessionNotFoundException("TEST_SESSION_NAME"))); + while (true) { + try { + transaction.executeUpdate(UPDATE_STATEMENT); + + // Simulate a delay of 3 minutes to ensure that the below transaction is a long-running + // one. + // As per this test, anything which takes more than 2s is long-running + poolMaintainerClock.currentTimeMillis.addAndGet(Duration.ofMinutes(3).toMillis()); + // force trigger pool maintainer to check for long-running sessions + client.pool.poolMaintainer.maintainPool(); + + manager.commit(); + assertNotNull(manager.getCommitTimestamp()); + break; + } catch (AbortedException e) { + transaction = manager.resetForRetry(); + } + mockSpanner.setCommitExecutionTime(SimulatedExecutionTime.ofMinimumAndRandomTime(0, 0)); } - mockSpanner.setCommitExecutionTime(SimulatedExecutionTime.ofMinimumAndRandomTime(0, 0)); } + Instant endExecutionTime = client.pool.poolMaintainer.lastExecutionTime; + + // first session executed update, session found to be long-running and cleaned up. + // During commit, SessionNotFound exception from backend caused replacement of session and + // transaction needs to be retried. + // On retry, session again found to be long-running and cleaned up. + // During commit, there was no exception from backend. + + assertNotEquals( + endExecutionTime, + initialExecutionTime); // if session clean up task runs then these timings won't match + assertEquals(2, client.pool.numLeakedSessionsRemoved()); + assertTrue(client.pool.getNumberOfSessionsInPool() <= client.pool.totalSessions()); } - Instant endExecutionTime = client.pool.poolMaintainer.lastExecutionTime; - - // first session executed update, session found to be long-running and cleaned up. - // During commit, SessionNotFound exception from backend caused replacement of session and - // transaction needs to be retried. - // On retry, session again found to be long-running and cleaned up. - // During commit, there was no exception from backend. - - assertNotEquals( - endExecutionTime, - initialExecutionTime); // if session clean up task runs then these timings won't match - assertEquals(2, client.pool.numLeakedSessionsRemoved()); - assertTrue(client.pool.getNumberOfSessionsInPool() <= client.pool.totalSessions()); } @Test @@ -353,7 +354,7 @@ public void tearDown() { .setLoopFrequency(1000L) // main thread runs every 1s .setPoolMaintainerClock(poolMaintainerClock) .build(); - spanner = + try (Spanner spanner = SpannerOptions.newBuilder() .setProjectId(TEST_PROJECT) .setDatabaseRole(TEST_DATABASE_ROLE) @@ -361,47 +362,48 @@ public void tearDown() { .setCredentials(NoCredentials.getInstance()) .setSessionPoolOption(sessionPoolOptions) .build() - .getService(); - DatabaseClientImpl client = - (DatabaseClientImpl) - spanner.getDatabaseClient(DatabaseId.of(TEST_PROJECT, TEST_INSTANCE, TEST_DATABASE)); - Instant initialExecutionTime = client.pool.poolMaintainer.lastExecutionTime; - - poolMaintainerClock.currentTimeMillis += Duration.ofMinutes(3).toMillis(); - - try (TransactionManager manager = client.transactionManager()) { - TransactionContext transaction = manager.begin(); - while (true) { - try { - transaction.executeUpdate(UPDATE_STATEMENT); - - // Simulate a delay of 3 minutes to ensure that the below transaction is a long-running - // one. - // As per this test, anything which takes more than 2s is long-running - poolMaintainerClock.currentTimeMillis += Duration.ofMinutes(3).toMillis(); - // force trigger pool maintainer to check for long-running sessions - client.pool.poolMaintainer.maintainPool(); - - manager.commit(); - assertNotNull(manager.getCommitTimestamp()); - break; - } catch (AbortedException e) { - transaction = manager.resetForRetry(); + .getService()) { + DatabaseClientImpl client = + (DatabaseClientImpl) + spanner.getDatabaseClient(DatabaseId.of(TEST_PROJECT, TEST_INSTANCE, TEST_DATABASE)); + Instant initialExecutionTime = client.pool.poolMaintainer.lastExecutionTime; + + poolMaintainerClock.currentTimeMillis.addAndGet(Duration.ofMinutes(3).toMillis()); + + try (TransactionManager manager = client.transactionManager()) { + TransactionContext transaction = manager.begin(); + while (true) { + try { + transaction.executeUpdate(UPDATE_STATEMENT); + + // Simulate a delay of 3 minutes to ensure that the below transaction is a long-running + // one. + // As per this test, anything which takes more than 2s is long-running + poolMaintainerClock.currentTimeMillis.addAndGet(Duration.ofMinutes(3).toMillis()); + // force trigger pool maintainer to check for long-running sessions + client.pool.poolMaintainer.maintainPool(); + + manager.commit(); + assertNotNull(manager.getCommitTimestamp()); + break; + } catch (AbortedException e) { + transaction = manager.resetForRetry(); + } } } + Instant endExecutionTime = client.pool.poolMaintainer.lastExecutionTime; + + // first session executed update, session found to be long-running and cleaned up. + // During commit, SessionNotFound exception from backend caused replacement of session and + // transaction needs to be retried. + // On retry, session again found to be long-running and cleaned up. + // During commit, there was no exception from backend. + assertNotEquals( + endExecutionTime, + initialExecutionTime); // if session clean up task runs then these timings won't match + assertEquals(1, client.pool.numLeakedSessionsRemoved()); + assertTrue(client.pool.getNumberOfSessionsInPool() <= client.pool.totalSessions()); } - Instant endExecutionTime = client.pool.poolMaintainer.lastExecutionTime; - - // first session executed update, session found to be long-running and cleaned up. - // During commit, SessionNotFound exception from backend caused replacement of session and - // transaction needs to be retried. - // On retry, session again found to be long-running and cleaned up. - // During commit, there was no exception from backend. - assertNotEquals( - endExecutionTime, - initialExecutionTime); // if session clean up task runs then these timings won't match - assertEquals(1, client.pool.numLeakedSessionsRemoved()); - assertTrue(client.pool.getNumberOfSessionsInPool() <= client.pool.totalSessions()); } @Test @@ -424,7 +426,7 @@ public void testPoolMaintainer_whenLongRunningPartitionedUpdateRequest_takeNoAct .setPoolMaintainerClock(poolMaintainerClock) .build(); - spanner = + try (Spanner spanner = SpannerOptions.newBuilder() .setProjectId(TEST_PROJECT) .setDatabaseRole(TEST_DATABASE_ROLE) @@ -432,29 +434,30 @@ public void testPoolMaintainer_whenLongRunningPartitionedUpdateRequest_takeNoAct .setCredentials(NoCredentials.getInstance()) .setSessionPoolOption(sessionPoolOptions) .build() - .getService(); - DatabaseClientImpl client = - (DatabaseClientImpl) - spanner.getDatabaseClient(DatabaseId.of(TEST_PROJECT, TEST_INSTANCE, TEST_DATABASE)); - Instant initialExecutionTime = client.pool.poolMaintainer.lastExecutionTime; - poolMaintainerClock.currentTimeMillis += Duration.ofMinutes(3).toMillis(); + .getService()) { + DatabaseClientImpl client = + (DatabaseClientImpl) + spanner.getDatabaseClient(DatabaseId.of(TEST_PROJECT, TEST_INSTANCE, TEST_DATABASE)); + Instant initialExecutionTime = client.pool.poolMaintainer.lastExecutionTime; + poolMaintainerClock.currentTimeMillis.addAndGet(Duration.ofMinutes(3).toMillis()); - client.executePartitionedUpdate(UPDATE_STATEMENT); + client.executePartitionedUpdate(UPDATE_STATEMENT); - // Simulate a delay of 3 minutes to ensure that the below transaction is a long-running one. - // As per this test, anything which takes more than 2s is long-running - poolMaintainerClock.currentTimeMillis += Duration.ofMinutes(3).toMillis(); + // Simulate a delay of 3 minutes to ensure that the below transaction is a long-running one. + // As per this test, anything which takes more than 2s is long-running + poolMaintainerClock.currentTimeMillis.addAndGet(Duration.ofMinutes(3).toMillis()); - // force trigger pool maintainer to check for long-running sessions - client.pool.poolMaintainer.maintainPool(); + // force trigger pool maintainer to check for long-running sessions + client.pool.poolMaintainer.maintainPool(); - Instant endExecutionTime = client.pool.poolMaintainer.lastExecutionTime; + Instant endExecutionTime = client.pool.poolMaintainer.lastExecutionTime; - assertNotEquals( - endExecutionTime, - initialExecutionTime); // if session clean up task runs then these timings won't match - assertEquals(0, client.pool.numLeakedSessionsRemoved()); - assertTrue(client.pool.getNumberOfSessionsInPool() <= client.pool.totalSessions()); + assertNotEquals( + endExecutionTime, + initialExecutionTime); // if session clean up task runs then these timings won't match + assertEquals(0, client.pool.numLeakedSessionsRemoved()); + assertTrue(client.pool.getNumberOfSessionsInPool() <= client.pool.totalSessions()); + } } /** @@ -486,7 +489,7 @@ public void testPoolMaintainer_whenPDMLFollowedByInactiveTransaction_removeSessi .setLoopFrequency(1000L) // main thread runs every 1s .setPoolMaintainerClock(poolMaintainerClock) .build(); - spanner = + try (Spanner spanner = SpannerOptions.newBuilder() .setProjectId(TEST_PROJECT) .setDatabaseRole(TEST_DATABASE_ROLE) @@ -494,66 +497,67 @@ public void testPoolMaintainer_whenPDMLFollowedByInactiveTransaction_removeSessi .setCredentials(NoCredentials.getInstance()) .setSessionPoolOption(sessionPoolOptions) .build() - .getService(); - DatabaseClientImpl client = - (DatabaseClientImpl) - spanner.getDatabaseClient(DatabaseId.of(TEST_PROJECT, TEST_INSTANCE, TEST_DATABASE)); - Instant initialExecutionTime = client.pool.poolMaintainer.lastExecutionTime; - - poolMaintainerClock.currentTimeMillis += Duration.ofMinutes(3).toMillis(); - - client.executePartitionedUpdate(UPDATE_STATEMENT); - - // Simulate a delay of 3 minutes to ensure that the below transaction is a long-running one. - // As per this test, anything which takes more than 2s is long-running - poolMaintainerClock.currentTimeMillis += Duration.ofMinutes(3).toMillis(); - - // force trigger pool maintainer to check for long-running sessions - client.pool.poolMaintainer.maintainPool(); - - Instant endExecutionTime = client.pool.poolMaintainer.lastExecutionTime; - - assertNotEquals( - endExecutionTime, - initialExecutionTime); // if session clean up task runs then these timings won't match - assertEquals(0, client.pool.numLeakedSessionsRemoved()); - assertTrue(client.pool.getNumberOfSessionsInPool() <= client.pool.totalSessions()); - - poolMaintainerClock.currentTimeMillis += Duration.ofMinutes(3).toMillis(); - - try (TransactionManager manager = client.transactionManager()) { - TransactionContext transaction = manager.begin(); - while (true) { - try { - transaction.executeUpdate(UPDATE_STATEMENT); - - // Simulate a delay of 3 minutes to ensure that the below transaction is a long-running - // one. - // As per this test, anything which takes more than 2s is long-running - poolMaintainerClock.currentTimeMillis += Duration.ofMinutes(3).toMillis(); - // force trigger pool maintainer to check for long-running sessions - client.pool.poolMaintainer.maintainPool(); - - manager.commit(); - assertNotNull(manager.getCommitTimestamp()); - break; - } catch (AbortedException e) { - transaction = manager.resetForRetry(); + .getService()) { + DatabaseClientImpl client = + (DatabaseClientImpl) + spanner.getDatabaseClient(DatabaseId.of(TEST_PROJECT, TEST_INSTANCE, TEST_DATABASE)); + Instant initialExecutionTime = client.pool.poolMaintainer.lastExecutionTime; + + poolMaintainerClock.currentTimeMillis.addAndGet(Duration.ofMinutes(3).toMillis()); + + client.executePartitionedUpdate(UPDATE_STATEMENT); + + // Simulate a delay of 3 minutes to ensure that the below transaction is a long-running one. + // As per this test, anything which takes more than 2s is long-running + poolMaintainerClock.currentTimeMillis.addAndGet(Duration.ofMinutes(3).toMillis()); + + // force trigger pool maintainer to check for long-running sessions + client.pool.poolMaintainer.maintainPool(); + + Instant endExecutionTime = client.pool.poolMaintainer.lastExecutionTime; + + assertNotEquals( + endExecutionTime, + initialExecutionTime); // if session clean up task runs then these timings won't match + assertEquals(0, client.pool.numLeakedSessionsRemoved()); + assertTrue(client.pool.getNumberOfSessionsInPool() <= client.pool.totalSessions()); + + poolMaintainerClock.currentTimeMillis.addAndGet(Duration.ofMinutes(3).toMillis()); + + try (TransactionManager manager = client.transactionManager()) { + TransactionContext transaction = manager.begin(); + while (true) { + try { + transaction.executeUpdate(UPDATE_STATEMENT); + + // Simulate a delay of 3 minutes to ensure that the below transaction is a long-running + // one. + // As per this test, anything which takes more than 2s is long-running + poolMaintainerClock.currentTimeMillis.addAndGet(Duration.ofMinutes(3).toMillis()); + // force trigger pool maintainer to check for long-running sessions + client.pool.poolMaintainer.maintainPool(); + + manager.commit(); + assertNotNull(manager.getCommitTimestamp()); + break; + } catch (AbortedException e) { + transaction = manager.resetForRetry(); + } } } + endExecutionTime = client.pool.poolMaintainer.lastExecutionTime; + + // first session executed update, session found to be long-running and cleaned up. + // During commit, SessionNotFound exception from backend caused replacement of session and + // transaction needs to be retried. + // On retry, session again found to be long-running and cleaned up. + // During commit, there was no exception from backend. + assertNotEquals( + endExecutionTime, + initialExecutionTime); // if session clean up task runs then these timings won't match + assertEquals(1, client.pool.numLeakedSessionsRemoved()); + assertTrue(client.pool.getNumberOfSessionsInPool() <= client.pool.totalSessions()); } - endExecutionTime = client.pool.poolMaintainer.lastExecutionTime; - - // first session executed update, session found to be long-running and cleaned up. - // During commit, SessionNotFound exception from backend caused replacement of session and - // transaction needs to be retried. - // On retry, session again found to be long-running and cleaned up. - // During commit, there was no exception from backend. - assertNotEquals( - endExecutionTime, - initialExecutionTime); // if session clean up task runs then these timings won't match - assertEquals(1, client.pool.numLeakedSessionsRemoved()); - assertTrue(client.pool.getNumberOfSessionsInPool() <= client.pool.totalSessions()); } @Test @@ -577,7 +581,7 @@ public void testPoolMaintainer_whenPDMLFollowedByInactiveTransaction_removeSessi .setLoopFrequency(1000L) // main thread runs every 1s .setPoolMaintainerClock(poolMaintainerClock) .build(); - spanner = + try (Spanner spanner = SpannerOptions.newBuilder() .setProjectId(TEST_PROJECT) .setDatabaseRole(TEST_DATABASE_ROLE) @@ -585,53 +589,53 @@ public void testPoolMaintainer_whenPDMLFollowedByInactiveTransaction_removeSessi .setCredentials(NoCredentials.getInstance()) .setSessionPoolOption(sessionPoolOptions) .build() - .getService(); - DatabaseClientImpl client = - (DatabaseClientImpl) - spanner.getDatabaseClient(DatabaseId.of(TEST_PROJECT, TEST_INSTANCE, TEST_DATABASE)); - Instant initialExecutionTime = client.pool.poolMaintainer.lastExecutionTime; - - TransactionRunner runner = client.readWriteTransaction(); - runner.run( - transaction -> { - try (ResultSet resultSet = - transaction.read( - READ_TABLE_NAME, - KeySet.singleKey(Key.of(1L)), - READ_COLUMN_NAMES, - Options.priority(RpcPriority.HIGH))) { - while (resultSet.next()) {} - } - poolMaintainerClock.currentTimeMillis += Duration.ofMillis(1050).toMillis(); - - try (ResultSet resultSet = - transaction.read( - READ_TABLE_NAME, - KeySet.singleKey(Key.of(1L)), - READ_COLUMN_NAMES, - Options.priority(RpcPriority.HIGH))) { - while (resultSet.next()) {} - } - poolMaintainerClock.currentTimeMillis += Duration.ofMillis(2050).toMillis(); + .getService()) { + DatabaseClientImpl client = + (DatabaseClientImpl) + spanner.getDatabaseClient(DatabaseId.of(TEST_PROJECT, TEST_INSTANCE, TEST_DATABASE)); + Instant initialExecutionTime = client.pool.poolMaintainer.lastExecutionTime; + + TransactionRunner runner = client.readWriteTransaction(); + runner.run( + transaction -> { + try (ResultSet resultSet = + transaction.read( + READ_TABLE_NAME, + KeySet.singleKey(Key.of(1L)), + READ_COLUMN_NAMES, + Options.priority(RpcPriority.HIGH))) { + consumeResults(resultSet); + } + poolMaintainerClock.currentTimeMillis.addAndGet(Duration.ofMillis(1050).toMillis()); + + try (ResultSet resultSet = + transaction.read( + READ_TABLE_NAME, + KeySet.singleKey(Key.of(1L)), + READ_COLUMN_NAMES, + Options.priority(RpcPriority.HIGH))) { + consumeResults(resultSet); + } + poolMaintainerClock.currentTimeMillis.addAndGet(Duration.ofMillis(2050).toMillis()); - // force trigger pool maintainer to check for long-running sessions - client.pool.poolMaintainer.maintainPool(); + // force trigger pool maintainer to check for long-running sessions + client.pool.poolMaintainer.maintainPool(); - return null; - }); + return null; + }); - Instant endExecutionTime = client.pool.poolMaintainer.lastExecutionTime; + Instant endExecutionTime = client.pool.poolMaintainer.lastExecutionTime; - assertNotEquals( - endExecutionTime, - initialExecutionTime); // if session clean up task runs then these timings won't match - assertEquals(0, client.pool.numLeakedSessionsRemoved()); + assertNotEquals( + endExecutionTime, + initialExecutionTime); // if session clean up task runs then these timings won't match + assertEquals(0, client.pool.numLeakedSessionsRemoved()); + } } @Test public void - testPoolMaintainer_whenLongRunningQueriesUsingTransactionRunner_retainSessionForTransaction() - throws Exception { + testPoolMaintainer_whenLongRunningQueriesUsingTransactionRunner_retainSessionForTransaction() { FakeClock poolMaintainerClock = new FakeClock(); InactiveTransactionRemovalOptions inactiveTransactionRemovalOptions = InactiveTransactionRemovalOptions.newBuilder() @@ -649,7 +653,7 @@ public void testPoolMaintainer_whenPDMLFollowedByInactiveTransaction_removeSessi .setLoopFrequency(1000L) // main thread runs every 1s .setPoolMaintainerClock(poolMaintainerClock) .build(); - spanner = + try (Spanner spanner = SpannerOptions.newBuilder() .setProjectId(TEST_PROJECT) .setDatabaseRole(TEST_DATABASE_ROLE) @@ -657,43 +661,43 @@ public void testPoolMaintainer_whenPDMLFollowedByInactiveTransaction_removeSessi .setCredentials(NoCredentials.getInstance()) .setSessionPoolOption(sessionPoolOptions) .build() - .getService(); - DatabaseClientImpl client = - (DatabaseClientImpl) - spanner.getDatabaseClient(DatabaseId.of(TEST_PROJECT, TEST_INSTANCE, TEST_DATABASE)); - Instant initialExecutionTime = client.pool.poolMaintainer.lastExecutionTime; - - TransactionRunner runner = client.readWriteTransaction(); - runner.run( - transaction -> { - try (ResultSet resultSet = transaction.executeQuery(SELECT1)) { - while (resultSet.next()) {} - } - poolMaintainerClock.currentTimeMillis += Duration.ofMillis(1050).toMillis(); + .getService()) { + DatabaseClientImpl client = + (DatabaseClientImpl) + spanner.getDatabaseClient(DatabaseId.of(TEST_PROJECT, TEST_INSTANCE, TEST_DATABASE)); + Instant initialExecutionTime = client.pool.poolMaintainer.lastExecutionTime; + + TransactionRunner runner = client.readWriteTransaction(); + runner.run( + transaction -> { + try (ResultSet resultSet = transaction.executeQuery(SELECT1)) { + consumeResults(resultSet); + } + poolMaintainerClock.currentTimeMillis.addAndGet(Duration.ofMillis(1050).toMillis()); - try (ResultSet resultSet = transaction.executeQuery(SELECT1)) { - while (resultSet.next()) {} - } - poolMaintainerClock.currentTimeMillis += Duration.ofMillis(2050).toMillis(); + try (ResultSet resultSet = transaction.executeQuery(SELECT1)) { + consumeResults(resultSet); + } + poolMaintainerClock.currentTimeMillis.addAndGet(Duration.ofMillis(2050).toMillis()); - // force trigger pool maintainer to check for long-running sessions - client.pool.poolMaintainer.maintainPool(); + // force trigger pool maintainer to check for long-running sessions + client.pool.poolMaintainer.maintainPool(); - return null; - }); + return null; + }); - Instant endExecutionTime = client.pool.poolMaintainer.lastExecutionTime; + Instant endExecutionTime = client.pool.poolMaintainer.lastExecutionTime; - assertNotEquals( - endExecutionTime, - initialExecutionTime); // if session clean up task runs then these timings won't match - assertEquals(0, client.pool.numLeakedSessionsRemoved()); + assertNotEquals( + endExecutionTime, + initialExecutionTime); // if session clean up task runs then these timings won't match + assertEquals(0, client.pool.numLeakedSessionsRemoved()); + } } @Test public void - testPoolMaintainer_whenLongRunningUpdatesUsingTransactionManager_retainSessionForTransaction() - throws Exception { + testPoolMaintainer_whenLongRunningUpdatesUsingTransactionManager_retainSessionForTransaction() { FakeClock poolMaintainerClock = new FakeClock(); InactiveTransactionRemovalOptions inactiveTransactionRemovalOptions = InactiveTransactionRemovalOptions.newBuilder() @@ -711,7 +715,7 @@ public void testPoolMaintainer_whenPDMLFollowedByInactiveTransaction_removeSessi .setLoopFrequency(1000L) // main thread runs every 1s .setPoolMaintainerClock(poolMaintainerClock) .build(); - spanner = + try (Spanner spanner = SpannerOptions.newBuilder() .setProjectId(TEST_PROJECT) .setDatabaseRole(TEST_DATABASE_ROLE) @@ -719,40 +723,41 @@ public void testPoolMaintainer_whenPDMLFollowedByInactiveTransaction_removeSessi .setCredentials(NoCredentials.getInstance()) .setSessionPoolOption(sessionPoolOptions) .build() - .getService(); - DatabaseClientImpl client = - (DatabaseClientImpl) - spanner.getDatabaseClient(DatabaseId.of(TEST_PROJECT, TEST_INSTANCE, TEST_DATABASE)); - Instant initialExecutionTime = client.pool.poolMaintainer.lastExecutionTime; - - try (TransactionManager manager = client.transactionManager()) { - TransactionContext transaction = manager.begin(); - while (true) { - try { - transaction.executeUpdate(UPDATE_STATEMENT); - poolMaintainerClock.currentTimeMillis += Duration.ofMillis(1050).toMillis(); - - transaction.executeUpdate(UPDATE_STATEMENT); - poolMaintainerClock.currentTimeMillis += Duration.ofMillis(2050).toMillis(); - - // force trigger pool maintainer to check for long-running sessions - client.pool.poolMaintainer.maintainPool(); - - manager.commit(); - assertNotNull(manager.getCommitTimestamp()); - break; - } catch (AbortedException e) { - transaction = manager.resetForRetry(); + .getService()) { + DatabaseClientImpl client = + (DatabaseClientImpl) + spanner.getDatabaseClient(DatabaseId.of(TEST_PROJECT, TEST_INSTANCE, TEST_DATABASE)); + Instant initialExecutionTime = client.pool.poolMaintainer.lastExecutionTime; + + try (TransactionManager manager = client.transactionManager()) { + TransactionContext transaction = manager.begin(); + while (true) { + try { + transaction.executeUpdate(UPDATE_STATEMENT); + poolMaintainerClock.currentTimeMillis.addAndGet(Duration.ofMillis(1050).toMillis()); + + transaction.executeUpdate(UPDATE_STATEMENT); + poolMaintainerClock.currentTimeMillis.addAndGet(Duration.ofMillis(2050).toMillis()); + + // force trigger pool maintainer to check for long-running sessions + client.pool.poolMaintainer.maintainPool(); + + manager.commit(); + assertNotNull(manager.getCommitTimestamp()); + break; + } catch (AbortedException e) { + transaction = manager.resetForRetry(); + } } } - } - Instant endExecutionTime = client.pool.poolMaintainer.lastExecutionTime; + Instant endExecutionTime = client.pool.poolMaintainer.lastExecutionTime; - assertNotEquals( - endExecutionTime, - initialExecutionTime); // if session clean up task runs then these timings won't match - assertEquals(0, client.pool.numLeakedSessionsRemoved()); - assertTrue(client.pool.getNumberOfSessionsInPool() <= client.pool.totalSessions()); + assertNotEquals( + endExecutionTime, + initialExecutionTime); // if session clean up task runs then these timings won't match + assertEquals(0, client.pool.numLeakedSessionsRemoved()); + assertTrue(client.pool.getNumberOfSessionsInPool() <= client.pool.totalSessions()); + } } @Test @@ -775,7 +780,7 @@ public void testPoolMaintainer_whenPDMLFollowedByInactiveTransaction_removeSessi .setLoopFrequency(1000L) // main thread runs every 1s .setPoolMaintainerClock(poolMaintainerClock) .build(); - spanner = + try (Spanner spanner = SpannerOptions.newBuilder() .setProjectId(TEST_PROJECT) .setDatabaseRole(TEST_DATABASE_ROLE) @@ -783,56 +788,55 @@ public void testPoolMaintainer_whenPDMLFollowedByInactiveTransaction_removeSessi .setCredentials(NoCredentials.getInstance()) .setSessionPoolOption(sessionPoolOptions) .build() - .getService(); - DatabaseClientImpl client = - (DatabaseClientImpl) - spanner.getDatabaseClient(DatabaseId.of(TEST_PROJECT, TEST_INSTANCE, TEST_DATABASE)); - Instant initialExecutionTime = client.pool.poolMaintainer.lastExecutionTime; - - try (TransactionManager manager = client.transactionManager()) { - TransactionContext transaction = manager.begin(); - while (true) { - try { - try (ResultSet resultSet = - transaction.read( - READ_TABLE_NAME, - KeySet.singleKey(Key.of(1L)), - READ_COLUMN_NAMES, - Options.priority(RpcPriority.HIGH))) { - - while (resultSet.next()) {} - } - poolMaintainerClock.currentTimeMillis += Duration.ofMillis(1050).toMillis(); + .getService()) { + DatabaseClientImpl client = + (DatabaseClientImpl) + spanner.getDatabaseClient(DatabaseId.of(TEST_PROJECT, TEST_INSTANCE, TEST_DATABASE)); + Instant initialExecutionTime = client.pool.poolMaintainer.lastExecutionTime; + + try (TransactionManager manager = client.transactionManager()) { + TransactionContext transaction = manager.begin(); + while (true) { + try { + try (ResultSet resultSet = + transaction.read( + READ_TABLE_NAME, + KeySet.singleKey(Key.of(1L)), + READ_COLUMN_NAMES, + Options.priority(RpcPriority.HIGH))) { + consumeResults(resultSet); + } + poolMaintainerClock.currentTimeMillis.addAndGet(Duration.ofMillis(1050).toMillis()); + + try (ResultSet resultSet = + transaction.read( + READ_TABLE_NAME, + KeySet.singleKey(Key.of(1L)), + READ_COLUMN_NAMES, + Options.priority(RpcPriority.HIGH))) { + consumeResults(resultSet); + } + poolMaintainerClock.currentTimeMillis.addAndGet(Duration.ofMillis(2050).toMillis()); - try (ResultSet resultSet = - transaction.read( - READ_TABLE_NAME, - KeySet.singleKey(Key.of(1L)), - READ_COLUMN_NAMES, - Options.priority(RpcPriority.HIGH))) { + // force trigger pool maintainer to check for long-running sessions + client.pool.poolMaintainer.maintainPool(); - while (resultSet.next()) {} + manager.commit(); + assertNotNull(manager.getCommitTimestamp()); + break; + } catch (AbortedException e) { + transaction = manager.resetForRetry(); } - poolMaintainerClock.currentTimeMillis += Duration.ofMillis(2050).toMillis(); - - // force trigger pool maintainer to check for long-running sessions - client.pool.poolMaintainer.maintainPool(); - - manager.commit(); - assertNotNull(manager.getCommitTimestamp()); - break; - } catch (AbortedException e) { - transaction = manager.resetForRetry(); } } - } - Instant endExecutionTime = client.pool.poolMaintainer.lastExecutionTime; + Instant endExecutionTime = client.pool.poolMaintainer.lastExecutionTime; - assertNotEquals( - endExecutionTime, - initialExecutionTime); // if session clean up task runs then these timings won't match - assertEquals(0, client.pool.numLeakedSessionsRemoved()); - assertTrue(client.pool.getNumberOfSessionsInPool() <= client.pool.totalSessions()); + assertNotEquals( + endExecutionTime, + initialExecutionTime); // if session clean up task runs then these timings won't match + assertEquals(0, client.pool.numLeakedSessionsRemoved()); + assertTrue(client.pool.getNumberOfSessionsInPool() <= client.pool.totalSessions()); + } } @Test @@ -855,7 +859,7 @@ public void testPoolMaintainer_whenPDMLFollowedByInactiveTransaction_removeSessi .setLoopFrequency(1000L) // main thread runs every 1s .setPoolMaintainerClock(poolMaintainerClock) .build(); - spanner = + try (Spanner spanner = SpannerOptions.newBuilder() .setProjectId(TEST_PROJECT) .setDatabaseRole(TEST_DATABASE_ROLE) @@ -863,42 +867,43 @@ public void testPoolMaintainer_whenPDMLFollowedByInactiveTransaction_removeSessi .setCredentials(NoCredentials.getInstance()) .setSessionPoolOption(sessionPoolOptions) .build() - .getService(); - DatabaseClientImpl client = - (DatabaseClientImpl) - spanner.getDatabaseClient(DatabaseId.of(TEST_PROJECT, TEST_INSTANCE, TEST_DATABASE)); - Instant initialExecutionTime = client.pool.poolMaintainer.lastExecutionTime; + .getService()) { + DatabaseClientImpl client = + (DatabaseClientImpl) + spanner.getDatabaseClient(DatabaseId.of(TEST_PROJECT, TEST_INSTANCE, TEST_DATABASE)); + Instant initialExecutionTime = client.pool.poolMaintainer.lastExecutionTime; - try (TransactionManager manager = client.transactionManager()) { - TransactionContext transaction = manager.begin(); - while (true) { - try { - transaction.readRow(READ_TABLE_NAME, Key.of(1L), READ_COLUMN_NAMES); + try (TransactionManager manager = client.transactionManager()) { + TransactionContext transaction = manager.begin(); + while (true) { + try { + transaction.readRow(READ_TABLE_NAME, Key.of(1L), READ_COLUMN_NAMES); - poolMaintainerClock.currentTimeMillis += Duration.ofMillis(1050).toMillis(); + poolMaintainerClock.currentTimeMillis.addAndGet(Duration.ofMillis(1050).toMillis()); - transaction.readRow(READ_TABLE_NAME, Key.of(1L), READ_COLUMN_NAMES); + transaction.readRow(READ_TABLE_NAME, Key.of(1L), READ_COLUMN_NAMES); - poolMaintainerClock.currentTimeMillis += Duration.ofMillis(2050).toMillis(); + poolMaintainerClock.currentTimeMillis.addAndGet(Duration.ofMillis(2050).toMillis()); - // force trigger pool maintainer to check for long-running sessions - client.pool.poolMaintainer.maintainPool(); + // force trigger pool maintainer to check for long-running sessions + client.pool.poolMaintainer.maintainPool(); - manager.commit(); - assertNotNull(manager.getCommitTimestamp()); - break; - } catch (AbortedException e) { - transaction = manager.resetForRetry(); + manager.commit(); + assertNotNull(manager.getCommitTimestamp()); + break; + } catch (AbortedException e) { + transaction = manager.resetForRetry(); + } } } - } - Instant endExecutionTime = client.pool.poolMaintainer.lastExecutionTime; + Instant endExecutionTime = client.pool.poolMaintainer.lastExecutionTime; - assertNotEquals( - endExecutionTime, - initialExecutionTime); // if session clean up task runs then these timings won't match - assertEquals(0, client.pool.numLeakedSessionsRemoved()); - assertTrue(client.pool.getNumberOfSessionsInPool() <= client.pool.totalSessions()); + assertNotEquals( + endExecutionTime, + initialExecutionTime); // if session clean up task runs then these timings won't match + assertEquals(0, client.pool.numLeakedSessionsRemoved()); + assertTrue(client.pool.getNumberOfSessionsInPool() <= client.pool.totalSessions()); + } } @Test @@ -921,7 +926,7 @@ public void testPoolMaintainer_whenPDMLFollowedByInactiveTransaction_removeSessi .setLoopFrequency(1000L) // main thread runs every 1s .setPoolMaintainerClock(poolMaintainerClock) .build(); - spanner = + try (Spanner spanner = SpannerOptions.newBuilder() .setProjectId(TEST_PROJECT) .setDatabaseRole(TEST_DATABASE_ROLE) @@ -929,46 +934,47 @@ public void testPoolMaintainer_whenPDMLFollowedByInactiveTransaction_removeSessi .setCredentials(NoCredentials.getInstance()) .setSessionPoolOption(sessionPoolOptions) .build() - .getService(); - DatabaseClientImpl client = - (DatabaseClientImpl) - spanner.getDatabaseClient(DatabaseId.of(TEST_PROJECT, TEST_INSTANCE, TEST_DATABASE)); - Instant initialExecutionTime = client.pool.poolMaintainer.lastExecutionTime; - - try (TransactionManager manager = client.transactionManager()) { - TransactionContext transaction = manager.begin(); - while (true) { - try { - try (ResultSet resultSet = - transaction.analyzeUpdateStatement(UPDATE_STATEMENT, QueryAnalyzeMode.PROFILE); ) { - while (resultSet.next()) {} - } - poolMaintainerClock.currentTimeMillis += Duration.ofMillis(1050).toMillis(); + .getService()) { + DatabaseClientImpl client = + (DatabaseClientImpl) + spanner.getDatabaseClient(DatabaseId.of(TEST_PROJECT, TEST_INSTANCE, TEST_DATABASE)); + Instant initialExecutionTime = client.pool.poolMaintainer.lastExecutionTime; + + try (TransactionManager manager = client.transactionManager()) { + TransactionContext transaction = manager.begin(); + while (true) { + try { + try (ResultSet resultSet = + transaction.analyzeUpdateStatement(UPDATE_STATEMENT, QueryAnalyzeMode.PROFILE)) { + consumeResults(resultSet); + } + poolMaintainerClock.currentTimeMillis.addAndGet(Duration.ofMillis(1050).toMillis()); - try (ResultSet resultSet = - transaction.analyzeUpdateStatement(UPDATE_STATEMENT, QueryAnalyzeMode.PROFILE); ) { - while (resultSet.next()) {} - } - poolMaintainerClock.currentTimeMillis += Duration.ofMillis(2050).toMillis(); + try (ResultSet resultSet = + transaction.analyzeUpdateStatement(UPDATE_STATEMENT, QueryAnalyzeMode.PROFILE)) { + consumeResults(resultSet); + } + poolMaintainerClock.currentTimeMillis.addAndGet(Duration.ofMillis(2050).toMillis()); - // force trigger pool maintainer to check for long-running sessions - client.pool.poolMaintainer.maintainPool(); + // force trigger pool maintainer to check for long-running sessions + client.pool.poolMaintainer.maintainPool(); - manager.commit(); - assertNotNull(manager.getCommitTimestamp()); - break; - } catch (AbortedException e) { - transaction = manager.resetForRetry(); + manager.commit(); + assertNotNull(manager.getCommitTimestamp()); + break; + } catch (AbortedException e) { + transaction = manager.resetForRetry(); + } } } - } - Instant endExecutionTime = client.pool.poolMaintainer.lastExecutionTime; + Instant endExecutionTime = client.pool.poolMaintainer.lastExecutionTime; - assertNotEquals( - endExecutionTime, - initialExecutionTime); // if session clean up task runs then these timings won't match - assertEquals(0, client.pool.numLeakedSessionsRemoved()); - assertTrue(client.pool.getNumberOfSessionsInPool() <= client.pool.totalSessions()); + assertNotEquals( + endExecutionTime, + initialExecutionTime); // if session clean up task runs then these timings won't match + assertEquals(0, client.pool.numLeakedSessionsRemoved()); + assertTrue(client.pool.getNumberOfSessionsInPool() <= client.pool.totalSessions()); + } } @Test @@ -991,7 +997,7 @@ public void testPoolMaintainer_whenPDMLFollowedByInactiveTransaction_removeSessi .setLoopFrequency(1000L) // main thread runs every 1s .setPoolMaintainerClock(poolMaintainerClock) .build(); - spanner = + try (Spanner spanner = SpannerOptions.newBuilder() .setProjectId(TEST_PROJECT) .setDatabaseRole(TEST_DATABASE_ROLE) @@ -999,42 +1005,43 @@ public void testPoolMaintainer_whenPDMLFollowedByInactiveTransaction_removeSessi .setCredentials(NoCredentials.getInstance()) .setSessionPoolOption(sessionPoolOptions) .build() - .getService(); - DatabaseClientImpl client = - (DatabaseClientImpl) - spanner.getDatabaseClient(DatabaseId.of(TEST_PROJECT, TEST_INSTANCE, TEST_DATABASE)); - Instant initialExecutionTime = client.pool.poolMaintainer.lastExecutionTime; + .getService()) { + DatabaseClientImpl client = + (DatabaseClientImpl) + spanner.getDatabaseClient(DatabaseId.of(TEST_PROJECT, TEST_INSTANCE, TEST_DATABASE)); + Instant initialExecutionTime = client.pool.poolMaintainer.lastExecutionTime; - try (TransactionManager manager = client.transactionManager()) { - TransactionContext transaction = manager.begin(); - while (true) { - try { - transaction.batchUpdate(Lists.newArrayList(UPDATE_STATEMENT)); + try (TransactionManager manager = client.transactionManager()) { + TransactionContext transaction = manager.begin(); + while (true) { + try { + transaction.batchUpdate(Lists.newArrayList(UPDATE_STATEMENT)); - poolMaintainerClock.currentTimeMillis += Duration.ofMillis(1050).toMillis(); + poolMaintainerClock.currentTimeMillis.addAndGet(Duration.ofMillis(1050).toMillis()); - transaction.batchUpdate(Lists.newArrayList(UPDATE_STATEMENT)); + transaction.batchUpdate(Lists.newArrayList(UPDATE_STATEMENT)); - poolMaintainerClock.currentTimeMillis += Duration.ofMillis(2050).toMillis(); + poolMaintainerClock.currentTimeMillis.addAndGet(Duration.ofMillis(2050).toMillis()); - // force trigger pool maintainer to check for long-running sessions - client.pool.poolMaintainer.maintainPool(); + // force trigger pool maintainer to check for long-running sessions + client.pool.poolMaintainer.maintainPool(); - manager.commit(); - assertNotNull(manager.getCommitTimestamp()); - break; - } catch (AbortedException e) { - transaction = manager.resetForRetry(); + manager.commit(); + assertNotNull(manager.getCommitTimestamp()); + break; + } catch (AbortedException e) { + transaction = manager.resetForRetry(); + } } } - } - Instant endExecutionTime = client.pool.poolMaintainer.lastExecutionTime; + Instant endExecutionTime = client.pool.poolMaintainer.lastExecutionTime; - assertNotEquals( - endExecutionTime, - initialExecutionTime); // if session clean up task runs then these timings won't match - assertEquals(0, client.pool.numLeakedSessionsRemoved()); - assertTrue(client.pool.getNumberOfSessionsInPool() <= client.pool.totalSessions()); + assertNotEquals( + endExecutionTime, + initialExecutionTime); // if session clean up task runs then these timings won't match + assertEquals(0, client.pool.numLeakedSessionsRemoved()); + assertTrue(client.pool.getNumberOfSessionsInPool() <= client.pool.totalSessions()); + } } @Test @@ -1057,7 +1064,7 @@ public void testPoolMaintainer_whenPDMLFollowedByInactiveTransaction_removeSessi .setLoopFrequency(1000L) // main thread runs every 1s .setPoolMaintainerClock(poolMaintainerClock) .build(); - spanner = + try (Spanner spanner = SpannerOptions.newBuilder() .setProjectId(TEST_PROJECT) .setDatabaseRole(TEST_DATABASE_ROLE) @@ -1065,42 +1072,43 @@ public void testPoolMaintainer_whenPDMLFollowedByInactiveTransaction_removeSessi .setCredentials(NoCredentials.getInstance()) .setSessionPoolOption(sessionPoolOptions) .build() - .getService(); - DatabaseClientImpl client = - (DatabaseClientImpl) - spanner.getDatabaseClient(DatabaseId.of(TEST_PROJECT, TEST_INSTANCE, TEST_DATABASE)); - Instant initialExecutionTime = client.pool.poolMaintainer.lastExecutionTime; + .getService()) { + DatabaseClientImpl client = + (DatabaseClientImpl) + spanner.getDatabaseClient(DatabaseId.of(TEST_PROJECT, TEST_INSTANCE, TEST_DATABASE)); + Instant initialExecutionTime = client.pool.poolMaintainer.lastExecutionTime; - try (TransactionManager manager = client.transactionManager()) { - TransactionContext transaction = manager.begin(); - while (true) { - try { - transaction.batchUpdateAsync(Lists.newArrayList(UPDATE_STATEMENT)); + try (TransactionManager manager = client.transactionManager()) { + TransactionContext transaction = manager.begin(); + while (true) { + try { + transaction.batchUpdateAsync(Lists.newArrayList(UPDATE_STATEMENT)); - poolMaintainerClock.currentTimeMillis += Duration.ofMillis(1050).toMillis(); + poolMaintainerClock.currentTimeMillis.addAndGet(Duration.ofMillis(1050).toMillis()); - transaction.batchUpdateAsync(Lists.newArrayList(UPDATE_STATEMENT)); + transaction.batchUpdateAsync(Lists.newArrayList(UPDATE_STATEMENT)); - poolMaintainerClock.currentTimeMillis += Duration.ofMillis(2050).toMillis(); + poolMaintainerClock.currentTimeMillis.addAndGet(Duration.ofMillis(2050).toMillis()); - // force trigger pool maintainer to check for long-running sessions - client.pool.poolMaintainer.maintainPool(); + // force trigger pool maintainer to check for long-running sessions + client.pool.poolMaintainer.maintainPool(); - manager.commit(); - assertNotNull(manager.getCommitTimestamp()); - break; - } catch (AbortedException e) { - transaction = manager.resetForRetry(); + manager.commit(); + assertNotNull(manager.getCommitTimestamp()); + break; + } catch (AbortedException e) { + transaction = manager.resetForRetry(); + } } } - } - Instant endExecutionTime = client.pool.poolMaintainer.lastExecutionTime; + Instant endExecutionTime = client.pool.poolMaintainer.lastExecutionTime; - assertNotEquals( - endExecutionTime, - initialExecutionTime); // if session clean up task runs then these timings won't match - assertEquals(0, client.pool.numLeakedSessionsRemoved()); - assertTrue(client.pool.getNumberOfSessionsInPool() <= client.pool.totalSessions()); + assertNotEquals( + endExecutionTime, + initialExecutionTime); // if session clean up task runs then these timings won't match + assertEquals(0, client.pool.numLeakedSessionsRemoved()); + assertTrue(client.pool.getNumberOfSessionsInPool() <= client.pool.totalSessions()); + } } @Test @@ -1123,7 +1131,7 @@ public void testPoolMaintainer_whenPDMLFollowedByInactiveTransaction_removeSessi .setLoopFrequency(1000L) // main thread runs every 1s .setPoolMaintainerClock(poolMaintainerClock) .build(); - spanner = + try (Spanner spanner = SpannerOptions.newBuilder() .setProjectId(TEST_PROJECT) .setDatabaseRole(TEST_DATABASE_ROLE) @@ -1131,44 +1139,45 @@ public void testPoolMaintainer_whenPDMLFollowedByInactiveTransaction_removeSessi .setCredentials(NoCredentials.getInstance()) .setSessionPoolOption(sessionPoolOptions) .build() - .getService(); - DatabaseClientImpl client = - (DatabaseClientImpl) - spanner.getDatabaseClient(DatabaseId.of(TEST_PROJECT, TEST_INSTANCE, TEST_DATABASE)); - Instant initialExecutionTime = client.pool.poolMaintainer.lastExecutionTime; - - try (TransactionManager manager = client.transactionManager()) { - TransactionContext transaction = manager.begin(); - while (true) { - try { - try (ResultSet resultSet = transaction.executeQuery(SELECT1)) { - while (resultSet.next()) {} - } - poolMaintainerClock.currentTimeMillis += Duration.ofMillis(1050).toMillis(); + .getService()) { + DatabaseClientImpl client = + (DatabaseClientImpl) + spanner.getDatabaseClient(DatabaseId.of(TEST_PROJECT, TEST_INSTANCE, TEST_DATABASE)); + Instant initialExecutionTime = client.pool.poolMaintainer.lastExecutionTime; + + try (TransactionManager manager = client.transactionManager()) { + TransactionContext transaction = manager.begin(); + while (true) { + try { + try (ResultSet resultSet = transaction.executeQuery(SELECT1)) { + consumeResults(resultSet); + } + poolMaintainerClock.currentTimeMillis.addAndGet(Duration.ofMillis(1050).toMillis()); - try (ResultSet resultSet = transaction.executeQuery(SELECT1)) { - while (resultSet.next()) {} - } - poolMaintainerClock.currentTimeMillis += Duration.ofMillis(2050).toMillis(); + try (ResultSet resultSet = transaction.executeQuery(SELECT1)) { + consumeResults(resultSet); + } + poolMaintainerClock.currentTimeMillis.addAndGet(Duration.ofMillis(2050).toMillis()); - // force trigger pool maintainer to check for long-running sessions - client.pool.poolMaintainer.maintainPool(); + // force trigger pool maintainer to check for long-running sessions + client.pool.poolMaintainer.maintainPool(); - manager.commit(); - assertNotNull(manager.getCommitTimestamp()); - break; - } catch (AbortedException e) { - transaction = manager.resetForRetry(); + manager.commit(); + assertNotNull(manager.getCommitTimestamp()); + break; + } catch (AbortedException e) { + transaction = manager.resetForRetry(); + } } } - } - Instant endExecutionTime = client.pool.poolMaintainer.lastExecutionTime; + Instant endExecutionTime = client.pool.poolMaintainer.lastExecutionTime; - assertNotEquals( - endExecutionTime, - initialExecutionTime); // if session clean up task runs then these timings won't match - assertEquals(0, client.pool.numLeakedSessionsRemoved()); - assertTrue(client.pool.getNumberOfSessionsInPool() <= client.pool.totalSessions()); + assertNotEquals( + endExecutionTime, + initialExecutionTime); // if session clean up task runs then these timings won't match + assertEquals(0, client.pool.numLeakedSessionsRemoved()); + assertTrue(client.pool.getNumberOfSessionsInPool() <= client.pool.totalSessions()); + } } @Test @@ -1191,7 +1200,7 @@ public void testPoolMaintainer_whenPDMLFollowedByInactiveTransaction_removeSessi .setLoopFrequency(1000L) // main thread runs every 1s .setPoolMaintainerClock(poolMaintainerClock) .build(); - spanner = + try (Spanner spanner = SpannerOptions.newBuilder() .setProjectId(TEST_PROJECT) .setDatabaseRole(TEST_DATABASE_ROLE) @@ -1199,44 +1208,45 @@ public void testPoolMaintainer_whenPDMLFollowedByInactiveTransaction_removeSessi .setCredentials(NoCredentials.getInstance()) .setSessionPoolOption(sessionPoolOptions) .build() - .getService(); - DatabaseClientImpl client = - (DatabaseClientImpl) - spanner.getDatabaseClient(DatabaseId.of(TEST_PROJECT, TEST_INSTANCE, TEST_DATABASE)); - Instant initialExecutionTime = client.pool.poolMaintainer.lastExecutionTime; - - try (TransactionManager manager = client.transactionManager()) { - TransactionContext transaction = manager.begin(); - while (true) { - try { - try (ResultSet resultSet = transaction.executeQueryAsync(SELECT1)) { - while (resultSet.next()) {} - } - poolMaintainerClock.currentTimeMillis += Duration.ofMillis(1050).toMillis(); + .getService()) { + DatabaseClientImpl client = + (DatabaseClientImpl) + spanner.getDatabaseClient(DatabaseId.of(TEST_PROJECT, TEST_INSTANCE, TEST_DATABASE)); + Instant initialExecutionTime = client.pool.poolMaintainer.lastExecutionTime; + + try (TransactionManager manager = client.transactionManager()) { + TransactionContext transaction = manager.begin(); + while (true) { + try { + try (ResultSet resultSet = transaction.executeQueryAsync(SELECT1)) { + consumeResults(resultSet); + } + poolMaintainerClock.currentTimeMillis.addAndGet(Duration.ofMillis(1050).toMillis()); - try (ResultSet resultSet = transaction.executeQueryAsync(SELECT1)) { - while (resultSet.next()) {} - } - poolMaintainerClock.currentTimeMillis += Duration.ofMillis(2050).toMillis(); + try (ResultSet resultSet = transaction.executeQueryAsync(SELECT1)) { + consumeResults(resultSet); + } + poolMaintainerClock.currentTimeMillis.addAndGet(Duration.ofMillis(2050).toMillis()); - // force trigger pool maintainer to check for long-running sessions - client.pool.poolMaintainer.maintainPool(); + // force trigger pool maintainer to check for long-running sessions + client.pool.poolMaintainer.maintainPool(); - manager.commit(); - assertNotNull(manager.getCommitTimestamp()); - break; - } catch (AbortedException e) { - transaction = manager.resetForRetry(); + manager.commit(); + assertNotNull(manager.getCommitTimestamp()); + break; + } catch (AbortedException e) { + transaction = manager.resetForRetry(); + } } } - } - Instant endExecutionTime = client.pool.poolMaintainer.lastExecutionTime; + Instant endExecutionTime = client.pool.poolMaintainer.lastExecutionTime; - assertNotEquals( - endExecutionTime, - initialExecutionTime); // if session clean up task runs then these timings won't match - assertEquals(0, client.pool.numLeakedSessionsRemoved()); - assertTrue(client.pool.getNumberOfSessionsInPool() <= client.pool.totalSessions()); + assertNotEquals( + endExecutionTime, + initialExecutionTime); // if session clean up task runs then these timings won't match + assertEquals(0, client.pool.numLeakedSessionsRemoved()); + assertTrue(client.pool.getNumberOfSessionsInPool() <= client.pool.totalSessions()); + } } @Test @@ -1259,7 +1269,7 @@ public void testPoolMaintainer_whenPDMLFollowedByInactiveTransaction_removeSessi .setLoopFrequency(1000L) // main thread runs every 1s .setPoolMaintainerClock(poolMaintainerClock) .build(); - spanner = + try (Spanner spanner = SpannerOptions.newBuilder() .setProjectId(TEST_PROJECT) .setDatabaseRole(TEST_DATABASE_ROLE) @@ -1267,44 +1277,47 @@ public void testPoolMaintainer_whenPDMLFollowedByInactiveTransaction_removeSessi .setCredentials(NoCredentials.getInstance()) .setSessionPoolOption(sessionPoolOptions) .build() - .getService(); - DatabaseClientImpl client = - (DatabaseClientImpl) - spanner.getDatabaseClient(DatabaseId.of(TEST_PROJECT, TEST_INSTANCE, TEST_DATABASE)); - Instant initialExecutionTime = client.pool.poolMaintainer.lastExecutionTime; - - try (TransactionManager manager = client.transactionManager()) { - TransactionContext transaction = manager.begin(); - while (true) { - try { - try (ResultSet resultSet = transaction.analyzeQuery(SELECT1, QueryAnalyzeMode.PROFILE)) { - while (resultSet.next()) {} - } - poolMaintainerClock.currentTimeMillis += Duration.ofMillis(1050).toMillis(); + .getService()) { + DatabaseClientImpl client = + (DatabaseClientImpl) + spanner.getDatabaseClient(DatabaseId.of(TEST_PROJECT, TEST_INSTANCE, TEST_DATABASE)); + Instant initialExecutionTime = client.pool.poolMaintainer.lastExecutionTime; + + try (TransactionManager manager = client.transactionManager()) { + TransactionContext transaction = manager.begin(); + while (true) { + try { + try (ResultSet resultSet = + transaction.analyzeQuery(SELECT1, QueryAnalyzeMode.PROFILE)) { + consumeResults(resultSet); + } + poolMaintainerClock.currentTimeMillis.addAndGet(Duration.ofMillis(1050).toMillis()); - try (ResultSet resultSet = transaction.analyzeQuery(SELECT1, QueryAnalyzeMode.PROFILE)) { - while (resultSet.next()) {} - } - poolMaintainerClock.currentTimeMillis += Duration.ofMillis(2050).toMillis(); + try (ResultSet resultSet = + transaction.analyzeQuery(SELECT1, QueryAnalyzeMode.PROFILE)) { + consumeResults(resultSet); + } + poolMaintainerClock.currentTimeMillis.addAndGet(Duration.ofMillis(2050).toMillis()); - // force trigger pool maintainer to check for long-running sessions - client.pool.poolMaintainer.maintainPool(); + // force trigger pool maintainer to check for long-running sessions + client.pool.poolMaintainer.maintainPool(); - manager.commit(); - assertNotNull(manager.getCommitTimestamp()); - break; - } catch (AbortedException e) { - transaction = manager.resetForRetry(); + manager.commit(); + assertNotNull(manager.getCommitTimestamp()); + break; + } catch (AbortedException e) { + transaction = manager.resetForRetry(); + } } } - } - Instant endExecutionTime = client.pool.poolMaintainer.lastExecutionTime; + Instant endExecutionTime = client.pool.poolMaintainer.lastExecutionTime; - assertNotEquals( - endExecutionTime, - initialExecutionTime); // if session clean up task runs then these timings won't match - assertEquals(0, client.pool.numLeakedSessionsRemoved()); - assertTrue(client.pool.getNumberOfSessionsInPool() <= client.pool.totalSessions()); + assertNotEquals( + endExecutionTime, + initialExecutionTime); // if session clean up task runs then these timings won't match + assertEquals(0, client.pool.numLeakedSessionsRemoved()); + assertTrue(client.pool.getNumberOfSessionsInPool() <= client.pool.totalSessions()); + } } @Test @@ -1489,11 +1502,9 @@ public void testBatchWriteAtLeastOnceWithoutOptions() { public void testBatchWriteAtLeastOnceWithOptions() { DatabaseClient client = spanner.getDatabaseClient(DatabaseId.of(TEST_PROJECT, TEST_INSTANCE, TEST_DATABASE)); - ServerStream responseStream = - client.batchWriteAtLeastOnce(MUTATION_GROUPS, Options.priority(RpcPriority.LOW)); - for (BatchWriteResponse response : responseStream) {} + consumeBatchWriteStream( + client.batchWriteAtLeastOnce(MUTATION_GROUPS, Options.priority(RpcPriority.LOW))); - assertNotNull(responseStream); List requests = mockSpanner.getRequestsOfType(BatchWriteRequest.class); assertEquals(requests.size(), 1); BatchWriteRequest request = requests.get(0); @@ -1505,11 +1516,9 @@ public void testBatchWriteAtLeastOnceWithOptions() { public void testBatchWriteAtLeastOnceWithTagOptions() { DatabaseClient client = spanner.getDatabaseClient(DatabaseId.of(TEST_PROJECT, TEST_INSTANCE, TEST_DATABASE)); - ServerStream responseStream = - client.batchWriteAtLeastOnce(MUTATION_GROUPS, Options.tag("app=spanner,env=test")); - for (BatchWriteResponse response : responseStream) {} + consumeBatchWriteStream( + client.batchWriteAtLeastOnce(MUTATION_GROUPS, Options.tag("app=spanner,env=test"))); - assertNotNull(responseStream); List requests = mockSpanner.getRequestsOfType(BatchWriteRequest.class); assertEquals(requests.size(), 1); BatchWriteRequest request = requests.get(0); @@ -1526,7 +1535,7 @@ public void testExecuteQueryWithTag() { client .singleUse() .executeQuery(SELECT1, Options.tag("app=spanner,env=test,action=query"))) { - while (resultSet.next()) {} + consumeResults(resultSet); } List requests = mockSpanner.getRequestsOfType(ExecuteSqlRequest.class); @@ -1544,7 +1553,7 @@ public void testExecuteQuery_withDirectedReadOptionsViaRequest() { spanner.getDatabaseClient(DatabaseId.of(TEST_PROJECT, TEST_INSTANCE, TEST_DATABASE)); try (ResultSet resultSet = client.singleUse().executeQuery(SELECT1, Options.directedRead(DIRECTED_READ_OPTIONS1))) { - while (resultSet.next()) {} + consumeResults(resultSet); } List requests = mockSpanner.getRequestsOfType(ExecuteSqlRequest.class); @@ -1567,7 +1576,7 @@ public void testExecuteQuery_withDirectedReadOptionsViaSpannerOptions() { spannerWithDirectedReadOptions.getDatabaseClient( DatabaseId.of(TEST_PROJECT, TEST_INSTANCE, TEST_DATABASE)); try (ResultSet resultSet = client.singleUse().executeQuery(SELECT1)) { - while (resultSet.next()) {} + consumeResults(resultSet); } List requests = mockSpanner.getRequestsOfType(ExecuteSqlRequest.class); @@ -1591,7 +1600,7 @@ public void testExecuteQuery_whenMultipleDirectedReadsOptions_preferRequestOptio DatabaseId.of(TEST_PROJECT, TEST_INSTANCE, TEST_DATABASE)); try (ResultSet resultSet = client.singleUse().executeQuery(SELECT1, Options.directedRead(DIRECTED_READ_OPTIONS1))) { - while (resultSet.next()) {} + consumeResults(resultSet); } List requests = mockSpanner.getRequestsOfType(ExecuteSqlRequest.class); @@ -1613,7 +1622,7 @@ public void testExecuteReadWithTag() { KeySet.singleKey(Key.of(1L)), READ_COLUMN_NAMES, Options.tag("app=spanner,env=test,action=read"))) { - while (resultSet.next()) {} + consumeResults(resultSet); } List requests = mockSpanner.getRequestsOfType(ReadRequest.class); @@ -1637,7 +1646,7 @@ public void testExecuteReadWithDirectedReadOptions() { KeySet.singleKey(Key.of(1L)), READ_COLUMN_NAMES, Options.directedRead(DIRECTED_READ_OPTIONS1))) { - while (resultSet.next()) {} + consumeResults(resultSet); } List requests = mockSpanner.getRequestsOfType(ReadRequest.class); @@ -1661,7 +1670,7 @@ public void testExecuteReadWithDirectedReadOptionsViaSpannerOptions() { DatabaseId.of(TEST_PROJECT, TEST_INSTANCE, TEST_DATABASE)); try (ResultSet resultSet = client.singleUse().read(READ_TABLE_NAME, KeySet.singleKey(Key.of(1L)), READ_COLUMN_NAMES)) { - while (resultSet.next()) {} + consumeResults(resultSet); } List requests = mockSpanner.getRequestsOfType(ReadRequest.class); @@ -1687,7 +1696,7 @@ public void testReadWriteExecuteQueryWithDirectedReadOptionsViaSpannerOptions() runner.run( transaction -> { try (ResultSet resultSet = transaction.executeQuery(SELECT1)) { - while (resultSet.next()) {} + consumeResults(resultSet); } return null; }); @@ -1708,7 +1717,7 @@ public void testReadWriteExecuteQueryWithTag() { transaction -> { try (ResultSet resultSet = transaction.executeQuery(SELECT1, Options.tag("app=spanner,env=test,action=query"))) { - while (resultSet.next()) {} + consumeResults(resultSet); } return null; }); @@ -1737,7 +1746,7 @@ public void testReadWriteExecuteReadWithTag() { KeySet.singleKey(Key.of(1L)), READ_COLUMN_NAMES, Options.tag("app=spanner,env=test,action=read"))) { - while (resultSet.next()) {} + consumeResults(resultSet); } return null; }); @@ -1835,11 +1844,12 @@ public void testCommitWithTag() { public void testTransactionManagerCommitWithTag() { DatabaseClient client = spanner.getDatabaseClient(DatabaseId.of(TEST_PROJECT, TEST_INSTANCE, TEST_DATABASE)); - TransactionManager manager = - client.transactionManager(Options.tag("app=spanner,env=test,action=manager")); - TransactionContext transaction = manager.begin(); - transaction.buffer(Mutation.delete("TEST", KeySet.all())); - manager.commit(); + try (TransactionManager manager = + client.transactionManager(Options.tag("app=spanner,env=test,action=manager"))) { + TransactionContext transaction = manager.begin(); + transaction.buffer(Mutation.delete("TEST", KeySet.all())); + manager.commit(); + } List requests = mockSpanner.getRequestsOfType(CommitRequest.class); assertThat(requests).hasSize(1); @@ -2257,7 +2267,7 @@ public void runAsyncWithException() throws Exception { txn -> ApiFutures.immediateFuture(txn.executeUpdate(INVALID_UPDATE_STATEMENT)), executor); - ExecutionException e = assertThrows(ExecutionException.class, () -> fut.get()); + ExecutionException e = assertThrows(ExecutionException.class, fut::get); assertThat(e.getCause()).isInstanceOf(SpannerException.class); SpannerException se = (SpannerException) e.getCause(); assertThat(se.getErrorCode()).isEqualTo(ErrorCode.INVALID_ARGUMENT); @@ -2265,7 +2275,6 @@ public void runAsyncWithException() throws Exception { executor.shutdown(); } - @SuppressWarnings("resource") @Test public void testTransactionManager() { DatabaseClient client = @@ -2285,7 +2294,6 @@ public void testTransactionManager() { } } - @SuppressWarnings("resource") @Test public void testTransactionManager_returnsCommitStats() { DatabaseClient client = @@ -2307,7 +2315,6 @@ public void testTransactionManager_returnsCommitStats() { } } - @SuppressWarnings("resource") @Test public void transactionManagerIsNonBlocking() throws Exception { mockSpanner.freeze(); @@ -2323,6 +2330,7 @@ public void transactionManagerIsNonBlocking() throws Exception { txManager.commit(); break; } catch (AbortedException e) { + //noinspection BusyWait Thread.sleep(e.getRetryDelayInMillis()); transaction = txManager.resetForRetry(); } @@ -2330,9 +2338,8 @@ public void transactionManagerIsNonBlocking() throws Exception { } } - @SuppressWarnings("resource") @Test - public void transactionManagerExecuteQueryAsync() throws Exception { + public void transactionManagerExecuteQueryAsync() { DatabaseClient client = spanner.getDatabaseClient(DatabaseId.of(TEST_PROJECT, TEST_INSTANCE, TEST_DATABASE)); final AtomicInteger rowCount = new AtomicInteger(); @@ -2470,7 +2477,7 @@ public void testPartitionedDmlWithLowerTimeout() { DatabaseClient client = spanner.getDatabaseClient(DatabaseId.of(TEST_PROJECT, TEST_INSTANCE, TEST_DATABASE)); assertThat(spanner.getOptions().getPartitionedDmlTimeout()).isEqualTo(Duration.ofMillis(10L)); - // PDML should timeout with these settings. + // PDML should time out with these settings. mockSpanner.setExecuteSqlExecutionTime( SimulatedExecutionTime.ofMinimumAndRandomTime(1000, 0)); SpannerException e = @@ -2478,9 +2485,9 @@ public void testPartitionedDmlWithLowerTimeout() { SpannerException.class, () -> client.executePartitionedUpdate(UPDATE_STATEMENT)); assertEquals(ErrorCode.DEADLINE_EXCEEDED, e.getErrorCode()); - // Normal DML should not timeout. + // Normal DML should not time out. mockSpanner.setExecuteSqlExecutionTime(SimulatedExecutionTime.ofMinimumAndRandomTime(10, 0)); - long updateCount = + Long updateCount = client .readWriteTransaction() .run(transaction -> transaction.executeUpdate(UPDATE_STATEMENT)); @@ -2580,6 +2587,7 @@ public void testDatabaseOrInstanceDoesNotExistOnInitialization() throws Exceptio Stopwatch watch = Stopwatch.createStarted(); while (watch.elapsed(TimeUnit.SECONDS) < 5 && dbClient.pool.getNumberOfSessionsBeingCreated() > 0) { + //noinspection BusyWait Thread.sleep(1L); } // All session creation should fail and stop trying. @@ -2618,11 +2626,11 @@ public void testDatabaseOrInstanceDoesNotExistOnCreate() { DatabaseId.of(TEST_PROJECT, TEST_INSTANCE, TEST_DATABASE)); // The create session failure should propagate to the client and not retry. try (ResultSet rs = dbClient.singleUse().executeQuery(SELECT1)) { - assertThrows(ResourceNotFoundException.class, () -> rs.next()); + assertThrows(ResourceNotFoundException.class, rs::next); // The server should only receive one BatchCreateSessions request. assertThat(mockSpanner.getRequests()).hasSize(1); } - assertThrows(ResourceNotFoundException.class, () -> dbClient.readWriteTransaction()); + assertThrows(ResourceNotFoundException.class, dbClient::readWriteTransaction); // No additional requests should have been sent by the client. assertThat(mockSpanner.getRequests()).hasSize(1); } @@ -2658,6 +2666,7 @@ public void testDatabaseOrInstanceDoesNotExistOnReplenish() throws Exception { Stopwatch watch = Stopwatch.createStarted(); while (watch.elapsed(TimeUnit.SECONDS) < 5 && dbClient.pool.getNumberOfSessionsBeingCreated() > 0) { + //noinspection BusyWait Thread.sleep(1L); } // All session creation should fail and stop trying. @@ -2666,9 +2675,10 @@ public void testDatabaseOrInstanceDoesNotExistOnReplenish() throws Exception { // Force a maintainer run. This should schedule new session creation. dbClient.pool.poolMaintainer.maintainPool(); // Wait until the replenish has finished. - watch = watch.reset().start(); + watch.reset().start(); while (watch.elapsed(TimeUnit.SECONDS) < 5 && dbClient.pool.getNumberOfSessionsBeingCreated() > 0) { + //noinspection BusyWait Thread.sleep(1L); } // All session creation from replenishPool should fail and stop trying. @@ -2710,6 +2720,7 @@ public void testDatabaseOrInstanceIsDeletedAndThenRecreated() throws Exception { Stopwatch watch = Stopwatch.createStarted(); while (watch.elapsed(TimeUnit.SECONDS) < 5 && (dbClient.pool.getNumberOfSessionsBeingCreated() > 0)) { + //noinspection BusyWait Thread.sleep(1L); } // Simulate that the database or instance has been deleted. @@ -2718,7 +2729,7 @@ public void testDatabaseOrInstanceIsDeletedAndThenRecreated() throws Exception { // All subsequent calls should fail with a DatabaseNotFoundException. try (ResultSet rs = dbClient.singleUse().executeQuery(SELECT1)) { - assertThrows(ResourceNotFoundException.class, () -> rs.next()); + assertThrows(ResourceNotFoundException.class, rs::next); } assertThrows( ResourceNotFoundException.class, @@ -2745,7 +2756,7 @@ public void testDatabaseOrInstanceIsDeletedAndThenRecreated() throws Exception { assertThat(newClient).isNotSameInstanceAs(dbClient); // Executing a query should now work without problems. try (ResultSet rs = newClient.singleUse().executeQuery(SELECT1)) { - while (rs.next()) {} + consumeResults(rs); } assertThat(mockSpanner.getRequests()).isNotEmpty(); } @@ -2807,6 +2818,7 @@ public void testAllowNestedTransactions() throws InterruptedException { Stopwatch watch = Stopwatch.createStarted(); while (watch.elapsed(TimeUnit.SECONDS) < 5 && client.pool.getNumberOfSessionsInPool() < minSessions) { + //noinspection BusyWait Thread.sleep(1L); } assertThat(client.pool.getNumberOfSessionsInPool()).isEqualTo(minSessions); @@ -2838,6 +2850,7 @@ public void testNestedTransactionsUsingTwoDatabases() throws InterruptedExceptio while (watch.elapsed(TimeUnit.SECONDS) < 5 && (client1.pool.getNumberOfSessionsInPool() < minSessions || client2.pool.getNumberOfSessionsInPool() < minSessions)) { + //noinspection BusyWait Thread.sleep(1L); } assertThat(client1.pool.getNumberOfSessionsInPool()).isEqualTo(minSessions); @@ -2869,6 +2882,7 @@ public void testNestedTransactionsUsingTwoDatabases() throws InterruptedExceptio return 0L; } }); + assertNotNull(add); try (ResultSet rs = transaction.executeQuery(SELECT1)) { if (rs.next()) { return add + rs.getLong(0); @@ -2908,7 +2922,7 @@ public void testBackendQueryOptions() { .build()) .build())) { // Just iterate over the results to execute the query. - while (rs.next()) {} + consumeResults(rs); } // Check that the last query was executed using a custom optimizer version and statistics // package. @@ -2949,7 +2963,7 @@ public void testBackendQueryOptionsWithAnalyzeQuery() { .build(), QueryAnalyzeMode.PROFILE)) { // Just iterate over the results to execute the query. - while (rs.next()) {} + consumeResults(rs); } } // Check that the last query was executed using a custom optimizer version and statistics @@ -2996,7 +3010,7 @@ public void testBackendPartitionQueryOptions() { Options.directedRead(DIRECTED_READ_OPTIONS1)); try (ResultSet rs = transaction.execute(partitions.get(0))) { // Just iterate over the results to execute the query. - while (rs.next()) {} + consumeResults(rs); } finally { transaction.cleanup(); } @@ -3046,7 +3060,7 @@ public void testBackendPartitionQueryOptions() { .build()); try (ResultSet rs = transaction.execute(partitions.get(0))) { // Just iterate over the results to execute the query. - while (rs.next()) {} + consumeResults(rs); } finally { transaction.cleanup(); } @@ -3092,7 +3106,7 @@ public void testBackendPartitionReadOptions() { Options.directedRead(DIRECTED_READ_OPTIONS1)); try (ResultSet rs = transaction.execute(partitions.get(0))) { // Just iterate over the results to execute the query. - while (rs.next()) {} + consumeResults(rs); } finally { transaction.cleanup(); } @@ -3134,6 +3148,7 @@ public void testBackendPartitionReadOptions() { Lists.newArrayList("1")); try (ResultSet rs = transaction.execute(partitions.get(0))) { // Just iterate over the results to execute the query. + //noinspection StatementWithEmptyBody while (rs.next()) {} } finally { transaction.cleanup(); @@ -3245,7 +3260,7 @@ public void testBatchCreateSessionsPermissionDenied() { // The following call is non-blocking and will not generate an exception. ResultSet rs = client.singleUse().executeQuery(SELECT1); // Actually trying to get any results will cause an exception. - SpannerException e = assertThrows(SpannerException.class, () -> rs.next()); + SpannerException e = assertThrows(SpannerException.class, rs::next); assertEquals(ErrorCode.PERMISSION_DENIED, e.getErrorCode()); } } @@ -3262,7 +3277,7 @@ public void testExceptionIncludesStatement() { .singleUse() .executeQuery( Statement.newBuilder("SELECT * FROM FOO WHERE ID=@id").bind("id").to(1L).build())) { - SpannerException e = assertThrows(SpannerException.class, () -> rs.next()); + SpannerException e = assertThrows(SpannerException.class, rs::next); assertThat(e.getErrorCode()).isEqualTo(ErrorCode.INVALID_ARGUMENT); assertThat(e.getMessage()).contains("Statement: 'SELECT * FROM FOO WHERE ID=@id'"); // The error message should normally not include the parameter values to prevent sensitive @@ -3281,7 +3296,7 @@ public void testExceptionIncludesStatement() { .executeQuery( Statement.newBuilder("SELECT * FROM FOO WHERE ID=@id").bind("id").to(1L).build())) { logger.setLevel(Level.FINEST); - SpannerException e = assertThrows(SpannerException.class, () -> rs.next()); + SpannerException e = assertThrows(SpannerException.class, rs::next); // With log level set to FINEST the error should also include the parameter values. assertThat(e.getErrorCode()).isEqualTo(ErrorCode.INVALID_ARGUMENT); assertThat(e.getMessage()).contains("Statement: 'SELECT * FROM FOO WHERE ID=@id {id: 1}'"); @@ -3299,7 +3314,7 @@ public void testReadDoesNotIncludeStatement() { spanner.getDatabaseClient(DatabaseId.of(TEST_PROJECT, TEST_INSTANCE, TEST_DATABASE)); try (ResultSet rs = client.singleUse().read("FOO", KeySet.singleKey(Key.of(1L)), ImmutableList.of("BAR"))) { - SpannerException e = assertThrows(SpannerException.class, () -> rs.next()); + SpannerException e = assertThrows(SpannerException.class, rs::next); assertThat(e.getErrorCode()).isEqualTo(ErrorCode.INVALID_ARGUMENT); assertThat(e.getMessage()).doesNotContain("Statement:"); } @@ -3320,7 +3335,7 @@ public void testSpecificTimeout() { () -> { // Query should fail with a timeout. try (ResultSet rs = client.singleUse().executeQuery(SELECT1)) { - SpannerException e = assertThrows(SpannerException.class, () -> rs.next()); + SpannerException e = assertThrows(SpannerException.class, rs::next); assertThat(e.getErrorCode()).isEqualTo(ErrorCode.DEADLINE_EXCEEDED); } // Update should succeed. @@ -3342,7 +3357,7 @@ public void testBatchCreateSessionsFailure_shouldNotPropagateToCloseMethod() { // This will not cause any failure as getting a session from the pool is guaranteed to be // non-blocking, and any exceptions will be delayed until actual query execution. try (ResultSet rs = client.singleUse().executeQuery(SELECT1)) { - SpannerException e = assertThrows(SpannerException.class, () -> rs.next()); + SpannerException e = assertThrows(SpannerException.class, rs::next); assertThat(e.getErrorCode()).isEqualTo(ErrorCode.RESOURCE_EXHAUSTED); } } finally { @@ -3371,9 +3386,9 @@ public void testTransactionManager_usesOptions() { TransactionOption option = mock(TransactionOption.class); DatabaseClientImpl client = new DatabaseClientImpl(pool); - client.transactionManager(option); - - verify(session).transactionManager(option); + try (TransactionManager ignore = client.transactionManager(option)) { + verify(session).transactionManager(option); + } } @Test @@ -3397,9 +3412,9 @@ public void testTransactionManagerAsync_usesOptions() { TransactionOption option = mock(TransactionOption.class); DatabaseClientImpl client = new DatabaseClientImpl(pool); - client.transactionManagerAsync(option); - - verify(session).transactionManagerAsync(option); + try (AsyncTransactionManager ignore = client.transactionManagerAsync(option)) { + verify(session).transactionManagerAsync(option); + } } @Test @@ -3408,6 +3423,7 @@ public void testExecuteQueryWithPriority() { spanner.getDatabaseClient(DatabaseId.of(TEST_PROJECT, TEST_INSTANCE, TEST_DATABASE)); try (ResultSet resultSet = client.singleUse().executeQuery(SELECT1, Options.priority(RpcPriority.HIGH))) { + //noinspection StatementWithEmptyBody while (resultSet.next()) {} } @@ -3430,6 +3446,7 @@ public void testExecuteReadWithPriority() { KeySet.singleKey(Key.of(1L)), READ_COLUMN_NAMES, Options.priority(RpcPriority.HIGH))) { + //noinspection StatementWithEmptyBody while (resultSet.next()) {} } @@ -3449,6 +3466,7 @@ public void testReadWriteExecuteQueryWithPriority() { transaction -> { try (ResultSet resultSet = transaction.executeQuery(SELECT1, Options.priority(RpcPriority.HIGH))) { + //noinspection StatementWithEmptyBody while (resultSet.next()) {} } return null; @@ -3474,6 +3492,7 @@ public void testReadWriteExecuteReadWithPriority() { KeySet.singleKey(Key.of(1L)), READ_COLUMN_NAMES, Options.priority(RpcPriority.HIGH))) { + //noinspection StatementWithEmptyBody while (resultSet.next()) {} } return null; @@ -3555,10 +3574,12 @@ public void testCommitWithPriority() { public void testTransactionManagerCommitWithPriority() { DatabaseClient client = spanner.getDatabaseClient(DatabaseId.of(TEST_PROJECT, TEST_INSTANCE, TEST_DATABASE)); - TransactionManager manager = client.transactionManager(Options.priority(RpcPriority.HIGH)); - TransactionContext transaction = manager.begin(); - transaction.buffer(Mutation.delete("TEST", KeySet.all())); - manager.commit(); + try (TransactionManager manager = + client.transactionManager(Options.priority(RpcPriority.HIGH))) { + TransactionContext transaction = manager.begin(); + transaction.buffer(Mutation.delete("TEST", KeySet.all())); + manager.commit(); + } List requests = mockSpanner.getRequestsOfType(CommitRequest.class); assertThat(requests).hasSize(1); @@ -3694,16 +3715,16 @@ public Long apply(TransactionContext transactionContext) { ctx = transactionContext; } try (ResultSet rs = ctx.executeQuery(SELECT1)) { + //noinspection StatementWithEmptyBody while (rs.next()) {} } return 1L; } }; - assertEquals(Long.valueOf(1L), client.readWriteTransaction().run(tx -> function.apply(tx))); + assertEquals(Long.valueOf(1L), client.readWriteTransaction().run(function::apply)); SpannerException exception = assertThrows( - SpannerException.class, - () -> client.readWriteTransaction().run(tx -> function.apply(tx))); + SpannerException.class, () -> client.readWriteTransaction().run(function::apply)); assertTrue(exception.getMessage().contains("Context has been closed")); } @@ -4596,4 +4617,14 @@ static void assertAsString(ImmutableList expected, ResultSet resultSet, expected.stream().collect(Collectors.joining(",", "[", "]")), resultSet.getValue(col).getAsString()); } + + private void consumeResults(ResultSet resultSet) { + //noinspection StatementWithEmptyBody + while (resultSet.next()) {} + } + + private void consumeBatchWriteStream(ServerStream stream) { + //noinspection StatementWithEmptyBody + for (BatchWriteResponse ignore : stream) {} + } } diff --git a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/FakeClock.java b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/FakeClock.java index 4bee3cc18e1..d46618ce2d0 100644 --- a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/FakeClock.java +++ b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/FakeClock.java @@ -15,6 +15,7 @@ */ package com.google.cloud.spanner; +import java.util.concurrent.atomic.AtomicLong; import org.threeten.bp.Instant; /** @@ -22,10 +23,10 @@ * tests. */ class FakeClock extends Clock { - volatile long currentTimeMillis; + final AtomicLong currentTimeMillis = new AtomicLong(); @Override public Instant instant() { - return Instant.ofEpochMilli(currentTimeMillis); + return Instant.ofEpochMilli(currentTimeMillis.get()); } } diff --git a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/SessionPoolLeakTest.java b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/SessionPoolLeakTest.java index 7bcde30f30b..91352cc1a14 100644 --- a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/SessionPoolLeakTest.java +++ b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/SessionPoolLeakTest.java @@ -148,6 +148,7 @@ public void testIgnoreLeakedSession() { // This will cause a session leak. ReadOnlyTransaction transaction = client.readOnlyTransaction(); try (ResultSet resultSet = transaction.executeQuery(Statement.of("SELECT 1"))) { + //noinspection StatementWithEmptyBody while (resultSet.next()) { // ignore } @@ -218,7 +219,7 @@ private void transactionManagerTest(Runnable setup, int expectedNumberOfSessions assertEquals(0, pool.getNumberOfSessionsInPool()); setup.run(); try (TransactionManager txManager = client.transactionManager()) { - SpannerException e = assertThrows(SpannerException.class, () -> txManager.begin()); + SpannerException e = assertThrows(SpannerException.class, txManager::begin); assertEquals(ErrorCode.FAILED_PRECONDITION, e.getErrorCode()); } assertEquals(expectedNumberOfSessionsAfterExecution, pool.getNumberOfSessionsInPool()); diff --git a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/SessionPoolMaintainerTest.java b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/SessionPoolMaintainerTest.java index 217e214c832..010e13c4390 100644 --- a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/SessionPoolMaintainerTest.java +++ b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/SessionPoolMaintainerTest.java @@ -154,7 +154,8 @@ public void testKeepAlive() throws Exception { // Now advance the time enough for both sessions in the pool to be idled. Then do one // maintenance loop. This should cause the last session to have been checked back into the pool // to get a ping, but not the second session. - clock.currentTimeMillis += TimeUnit.MINUTES.toMillis(options.getKeepAliveIntervalMinutes()) + 1; + clock.currentTimeMillis.addAndGet( + TimeUnit.MINUTES.toMillis(options.getKeepAliveIntervalMinutes()) + 1); runMaintenanceLoop(clock, pool, 1); assertThat(pingedSessions).containsExactly(session1.getName(), 1); // Do another maintenance loop. This should cause the other session to also get a ping. @@ -174,13 +175,15 @@ public void testKeepAlive() throws Exception { session4.close(); session3.close(); // Advance the clock to force pings for the sessions in the pool and do three maintenance loops. - clock.currentTimeMillis += TimeUnit.MINUTES.toMillis(options.getKeepAliveIntervalMinutes()) + 1; + clock.currentTimeMillis.addAndGet( + TimeUnit.MINUTES.toMillis(options.getKeepAliveIntervalMinutes()) + 1); runMaintenanceLoop(clock, pool, 3); assertThat(pingedSessions).containsExactly(session1.getName(), 2, session2.getName(), 2); // Advance the clock to idle all sessions in the pool again and then check out one session. This // should cause only one session to get a ping. - clock.currentTimeMillis += TimeUnit.MINUTES.toMillis(options.getKeepAliveIntervalMinutes()) + 1; + clock.currentTimeMillis.addAndGet( + TimeUnit.MINUTES.toMillis(options.getKeepAliveIntervalMinutes()) + 1); // We are now checking out session2 because Session session6 = pool.getSession(); // The session that was first in the pool now is equal to the initial first session as each full @@ -210,7 +213,8 @@ public void testKeepAlive() throws Exception { session8.close(); session9.close(); - clock.currentTimeMillis += TimeUnit.MINUTES.toMillis(options.getKeepAliveIntervalMinutes()) + 1; + clock.currentTimeMillis.addAndGet( + TimeUnit.MINUTES.toMillis(options.getKeepAliveIntervalMinutes()) + 1); runMaintenanceLoop(clock, pool, 3); // session1 will not get a ping this time, as it was checked in first and is now the last // session in the pool. diff --git a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/SessionPoolTest.java b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/SessionPoolTest.java index 65c7c7c03c1..dc06c1c5b3e 100644 --- a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/SessionPoolTest.java +++ b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/SessionPoolTest.java @@ -91,8 +91,12 @@ import java.util.concurrent.Future; import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicBoolean; +import java.util.logging.Level; +import java.util.logging.Logger; import java.util.stream.Collectors; +import org.junit.AfterClass; import org.junit.Before; +import org.junit.BeforeClass; import org.junit.Test; import org.junit.runner.RunWith; import org.junit.runners.Parameterized; @@ -107,6 +111,7 @@ /** Tests for SessionPool that mock out the underlying stub. */ @RunWith(Parameterized.class) public class SessionPoolTest extends BaseSessionPoolTest { + private static Level originalLogLevel; private final ExecutorService executor = Executors.newSingleThreadExecutor(); @Parameter public int minSessions; @@ -147,6 +152,19 @@ private SessionPool createPool( labelValues); } + @BeforeClass + public static void disableLogging() { + Logger logger = Logger.getLogger(""); + originalLogLevel = logger.getLevel(); + logger.setLevel(Level.OFF); + } + + @AfterClass + public static void resetLogging() { + Logger logger = Logger.getLogger(""); + logger.setLevel(originalLogLevel); + } + @Before public void setUp() { initMocks(this); @@ -667,7 +685,7 @@ public void idleSessionCleanup() throws Exception { .asyncBatchCreateSessions(Mockito.eq(1), Mockito.anyBoolean(), any(SessionConsumer.class)); FakeClock clock = new FakeClock(); - clock.currentTimeMillis = System.currentTimeMillis(); + clock.currentTimeMillis.set(System.currentTimeMillis()); mockKeepAlive(context); @@ -761,7 +779,6 @@ public void longRunningTransactionsCleanup_whenActionSetToWarn_verifyInactiveSes .setMinSessions(1) .setMaxSessions(3) .setIncStep(1) - .setMaxIdleSessions(0) .setWarnIfInactiveTransactions() // set option to warn (via logs) inactive transactions .build(); Clock clock = mock(Clock.class); @@ -793,6 +810,10 @@ public void longRunningTransactionsCleanup_whenActionSetToWarn_verifyInactiveSes assertEquals(3, pool.totalSessions()); assertEquals(3, pool.checkedOutSessions.size()); assertEquals(0, pool.numLeakedSessionsRemoved()); + + readSession1.close(); + readSession2.close(); + readSession3.close(); pool.closeAsync(new SpannerImpl.ClosedException()).get(5L, TimeUnit.SECONDS); } @@ -1031,6 +1052,10 @@ public void longRunningTransactionsCleanup_whenException_doNothing() throws Exce assertEquals(3, pool.totalSessions()); assertEquals(3, pool.checkedOutSessions.size()); assertEquals(0, pool.numLeakedSessionsRemoved()); + + readSession1.close(); + readSession2.close(); + readSession3.close(); pool.closeAsync(new SpannerImpl.ClosedException()).get(5L, TimeUnit.SECONDS); } @@ -1087,7 +1112,7 @@ public void keepAlive() throws Exception { .when(sessionClient) .asyncBatchCreateSessions(anyInt(), Mockito.anyBoolean(), any(SessionConsumer.class)); FakeClock clock = new FakeClock(); - clock.currentTimeMillis = System.currentTimeMillis(); + clock.currentTimeMillis.set(System.currentTimeMillis()); pool = createPool(clock); PooledSessionFuture session1 = pool.getSession(); PooledSessionFuture session2 = pool.getSession(); @@ -1099,8 +1124,8 @@ public void keepAlive() throws Exception { verify(context, never()).executeQuery(any(Statement.class)); runMaintenanceLoop(clock, pool, pool.poolMaintainer.numKeepAliveCycles); verify(context, times(2)).executeQuery(Statement.newBuilder("SELECT 1").build()); - clock.currentTimeMillis += - clock.currentTimeMillis + (options.getKeepAliveIntervalMinutes() + 5) * 60 * 1000; + clock.currentTimeMillis.addAndGet( + clock.currentTimeMillis.get() + (options.getKeepAliveIntervalMinutes() + 5L) * 60L * 1000L); session1 = pool.getSession(); session1.writeAtLeastOnceWithOptions(new ArrayList<>()); session1.close(); @@ -1248,7 +1273,7 @@ public void testSessionNotFoundSingleUse() { .when(sessionClient) .asyncBatchCreateSessions(Mockito.eq(1), Mockito.anyBoolean(), any(SessionConsumer.class)); FakeClock clock = new FakeClock(); - clock.currentTimeMillis = System.currentTimeMillis(); + clock.currentTimeMillis.set(System.currentTimeMillis()); pool = createPool(clock); ReadContext context = pool.getSession().singleUse(); ResultSet resultSet = context.executeQuery(statement); @@ -1292,7 +1317,7 @@ public void testSessionNotFoundReadOnlyTransaction() { .when(sessionClient) .asyncBatchCreateSessions(Mockito.eq(1), Mockito.anyBoolean(), any(SessionConsumer.class)); FakeClock clock = new FakeClock(); - clock.currentTimeMillis = System.currentTimeMillis(); + clock.currentTimeMillis.set(System.currentTimeMillis()); pool = createPool(clock); ReadOnlyTransaction transaction = pool.getSession().readOnlyTransaction(); ResultSet resultSet = transaction.executeQuery(statement); @@ -1527,7 +1552,7 @@ public void testSessionNotFoundWrite() { .asyncBatchCreateSessions(Mockito.eq(1), Mockito.anyBoolean(), any(SessionConsumer.class)); FakeClock clock = new FakeClock(); - clock.currentTimeMillis = System.currentTimeMillis(); + clock.currentTimeMillis.set(System.currentTimeMillis()); pool = createPool(clock); DatabaseClientImpl impl = new DatabaseClientImpl(pool); assertThat(impl.write(mutations)).isNotNull(); @@ -1569,7 +1594,7 @@ public void testSessionNotFoundWriteAtLeastOnce() { .when(sessionClient) .asyncBatchCreateSessions(Mockito.eq(1), Mockito.anyBoolean(), any(SessionConsumer.class)); FakeClock clock = new FakeClock(); - clock.currentTimeMillis = System.currentTimeMillis(); + clock.currentTimeMillis.set(System.currentTimeMillis()); pool = createPool(clock); DatabaseClientImpl impl = new DatabaseClientImpl(pool); assertThat(impl.writeAtLeastOnce(mutations)).isNotNull(); @@ -1608,7 +1633,7 @@ public void testSessionNotFoundPartitionedUpdate() { .when(sessionClient) .asyncBatchCreateSessions(Mockito.eq(1), Mockito.anyBoolean(), any(SessionConsumer.class)); FakeClock clock = new FakeClock(); - clock.currentTimeMillis = System.currentTimeMillis(); + clock.currentTimeMillis.set(System.currentTimeMillis()); pool = createPool(clock); DatabaseClientImpl impl = new DatabaseClientImpl(pool); assertThat(impl.executePartitionedUpdate(statement)).isEqualTo(1L); @@ -1625,7 +1650,7 @@ public void testSessionMetrics() throws Exception { .setInitialWaitForSessionTimeoutMillis(50L) .build(); FakeClock clock = new FakeClock(); - clock.currentTimeMillis = System.currentTimeMillis(); + clock.currentTimeMillis.set(System.currentTimeMillis()); FakeMetricRegistry metricRegistry = new FakeMetricRegistry(); List labelValues = Arrays.asList( diff --git a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/SpannerOptionsTest.java b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/SpannerOptionsTest.java index 42e53a6b8e7..4e41660bca1 100644 --- a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/SpannerOptionsTest.java +++ b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/SpannerOptionsTest.java @@ -68,7 +68,11 @@ import java.util.Map; import java.util.concurrent.Callable; import java.util.concurrent.ScheduledExecutorService; +import java.util.logging.Level; +import java.util.logging.Logger; import javax.annotation.Nonnull; +import org.junit.AfterClass; +import org.junit.BeforeClass; import org.junit.Test; import org.junit.runner.RunWith; import org.junit.runners.JUnit4; @@ -78,6 +82,20 @@ /** Unit tests for {@link com.google.cloud.spanner.SpannerOptions}. */ @RunWith(JUnit4.class) public class SpannerOptionsTest { + private static Level originalLogLevel; + + @BeforeClass + public static void disableLogging() { + Logger logger = Logger.getLogger(""); + originalLogLevel = logger.getLevel(); + logger.setLevel(Level.OFF); + } + + @AfterClass + public static void resetLogging() { + Logger logger = Logger.getLogger(""); + logger.setLevel(originalLogLevel); + } @Test public void defaultBuilder() { diff --git a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/connection/StatementTimeoutTest.java b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/connection/StatementTimeoutTest.java index af6190a8fd6..da30fc4a203 100644 --- a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/connection/StatementTimeoutTest.java +++ b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/connection/StatementTimeoutTest.java @@ -88,7 +88,7 @@ public class StatementTimeoutTest extends AbstractMockServerTest { ITConnection createConnection() { ConnectionOptions options = ConnectionOptions.newBuilder() - .setUri(getBaseUrl()) + .setUri(getBaseUrl() + ";trackSessionLeaks=false") .setConfigurator( optionsConfigurator -> optionsConfigurator @@ -508,13 +508,14 @@ private void testInterruptedException(final ConnectionConsumer consumer) thread.set(Thread.currentThread()); latch.countDown(); - try (ResultSet rs = connection.executeQuery(SELECT_RANDOM_STATEMENT)) {} + //noinspection EmptyTryBlock + try (ResultSet ignore = connection.executeQuery(SELECT_RANDOM_STATEMENT)) {} return false; } catch (SpannerException e) { return e.getErrorCode() == ErrorCode.CANCELLED; } }); - latch.await(10L, TimeUnit.SECONDS); + assertTrue(latch.await(10L, TimeUnit.SECONDS)); waitForRequestsToContain(ExecuteSqlRequest.class); thread.get().interrupt(); assertTrue(future.get()); From 383fea5b5dc434621585a1b5cfd128a01780472a Mon Sep 17 00:00:00 2001 From: "gcf-owl-bot[bot]" <78513119+gcf-owl-bot[bot]@users.noreply.github.com> Date: Sat, 27 Jan 2024 09:51:57 +0100 Subject: [PATCH 14/21] feat: add FLOAT32 enum to TypeCode (#2800) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * feat: add FLOAT32 enum to TypeCode PiperOrigin-RevId: 601176446 Source-Link: https://github.com/googleapis/googleapis/commit/584ecd4102d83b2a2898c31acf7e429d09cefa13 Source-Link: https://github.com/googleapis/googleapis-gen/commit/0bdb815779d0fd7824bafff0c91046a7dca5cd5f Copy-Tag: eyJwIjoiLmdpdGh1Yi8uT3dsQm90LnlhbWwiLCJoIjoiMGJkYjgxNTc3OWQwZmQ3ODI0YmFmZmYwYzkxMDQ2YTdkY2E1Y2Q1ZiJ9 * 🦉 Updates from OwlBot post-processor See https://github.com/googleapis/repo-automation-bots/blob/main/packages/owl-bot/README.md --------- Co-authored-by: Owl Bot --- .../java/com/google/spanner/v1/TypeCode.java | 24 +++++++++++++++++++ .../java/com/google/spanner/v1/TypeProto.java | 24 +++++++++---------- .../main/proto/google/spanner/v1/type.proto | 4 ++++ 3 files changed, 40 insertions(+), 12 deletions(-) diff --git a/proto-google-cloud-spanner-v1/src/main/java/com/google/spanner/v1/TypeCode.java b/proto-google-cloud-spanner-v1/src/main/java/com/google/spanner/v1/TypeCode.java index f3e13962f95..0af42e8582f 100644 --- a/proto-google-cloud-spanner-v1/src/main/java/com/google/spanner/v1/TypeCode.java +++ b/proto-google-cloud-spanner-v1/src/main/java/com/google/spanner/v1/TypeCode.java @@ -75,6 +75,17 @@ public enum TypeCode implements com.google.protobuf.ProtocolMessageEnum { * FLOAT64 = 3; */ FLOAT64(3), + /** + * + * + *

+   * Encoded as `number`, or the strings `"NaN"`, `"Infinity"`, or
+   * `"-Infinity"`.
+   * 
+ * + * FLOAT32 = 15; + */ + FLOAT32(15), /** * * @@ -246,6 +257,17 @@ public enum TypeCode implements com.google.protobuf.ProtocolMessageEnum { * FLOAT64 = 3; */ public static final int FLOAT64_VALUE = 3; + /** + * + * + *
+   * Encoded as `number`, or the strings `"NaN"`, `"Infinity"`, or
+   * `"-Infinity"`.
+   * 
+ * + * FLOAT32 = 15; + */ + public static final int FLOAT32_VALUE = 15; /** * * @@ -406,6 +428,8 @@ public static TypeCode forNumber(int value) { return INT64; case 3: return FLOAT64; + case 15: + return FLOAT32; case 4: return TIMESTAMP; case 5: diff --git a/proto-google-cloud-spanner-v1/src/main/java/com/google/spanner/v1/TypeProto.java b/proto-google-cloud-spanner-v1/src/main/java/com/google/spanner/v1/TypeProto.java index 7c7cd131dc1..fdd1c65338c 100644 --- a/proto-google-cloud-spanner-v1/src/main/java/com/google/spanner/v1/TypeProto.java +++ b/proto-google-cloud-spanner-v1/src/main/java/com/google/spanner/v1/TypeProto.java @@ -59,19 +59,19 @@ public static com.google.protobuf.Descriptors.FileDescriptor getDescriptor() { + "ype_fqn\030\005 \001(\t\"\177\n\nStructType\0223\n\006fields\030\001 " + "\003(\0132#.google.spanner.v1.StructType.Field" + "\032<\n\005Field\022\014\n\004name\030\001 \001(\t\022%\n\004type\030\002 \001(\0132\027." - + "google.spanner.v1.Type*\272\001\n\010TypeCode\022\031\n\025T" + + "google.spanner.v1.Type*\307\001\n\010TypeCode\022\031\n\025T" + "YPE_CODE_UNSPECIFIED\020\000\022\010\n\004BOOL\020\001\022\t\n\005INT6" - + "4\020\002\022\013\n\007FLOAT64\020\003\022\r\n\tTIMESTAMP\020\004\022\010\n\004DATE\020" - + "\005\022\n\n\006STRING\020\006\022\t\n\005BYTES\020\007\022\t\n\005ARRAY\020\010\022\n\n\006S" - + "TRUCT\020\t\022\013\n\007NUMERIC\020\n\022\010\n\004JSON\020\013\022\t\n\005PROTO\020" - + "\r\022\010\n\004ENUM\020\016*d\n\022TypeAnnotationCode\022$\n TYP" - + "E_ANNOTATION_CODE_UNSPECIFIED\020\000\022\016\n\nPG_NU" - + "MERIC\020\002\022\014\n\010PG_JSONB\020\003\022\n\n\006PG_OID\020\004B\254\001\n\025co" - + "m.google.spanner.v1B\tTypeProtoP\001Z5cloud." - + "google.com/go/spanner/apiv1/spannerpb;sp" - + "annerpb\252\002\027Google.Cloud.Spanner.V1\312\002\027Goog" - + "le\\Cloud\\Spanner\\V1\352\002\032Google::Cloud::Spa" - + "nner::V1b\006proto3" + + "4\020\002\022\013\n\007FLOAT64\020\003\022\013\n\007FLOAT32\020\017\022\r\n\tTIMESTA" + + "MP\020\004\022\010\n\004DATE\020\005\022\n\n\006STRING\020\006\022\t\n\005BYTES\020\007\022\t\n" + + "\005ARRAY\020\010\022\n\n\006STRUCT\020\t\022\013\n\007NUMERIC\020\n\022\010\n\004JSO" + + "N\020\013\022\t\n\005PROTO\020\r\022\010\n\004ENUM\020\016*d\n\022TypeAnnotati" + + "onCode\022$\n TYPE_ANNOTATION_CODE_UNSPECIFI" + + "ED\020\000\022\016\n\nPG_NUMERIC\020\002\022\014\n\010PG_JSONB\020\003\022\n\n\006PG" + + "_OID\020\004B\254\001\n\025com.google.spanner.v1B\tTypePr" + + "otoP\001Z5cloud.google.com/go/spanner/apiv1" + + "/spannerpb;spannerpb\252\002\027Google.Cloud.Span" + + "ner.V1\312\002\027Google\\Cloud\\Spanner\\V1\352\002\032Googl" + + "e::Cloud::Spanner::V1b\006proto3" }; descriptor = com.google.protobuf.Descriptors.FileDescriptor.internalBuildGeneratedFileFrom( diff --git a/proto-google-cloud-spanner-v1/src/main/proto/google/spanner/v1/type.proto b/proto-google-cloud-spanner-v1/src/main/proto/google/spanner/v1/type.proto index abd0c768176..8e28fa7fd63 100644 --- a/proto-google-cloud-spanner-v1/src/main/proto/google/spanner/v1/type.proto +++ b/proto-google-cloud-spanner-v1/src/main/proto/google/spanner/v1/type.proto @@ -103,6 +103,10 @@ enum TypeCode { // `"-Infinity"`. FLOAT64 = 3; + // Encoded as `number`, or the strings `"NaN"`, `"Infinity"`, or + // `"-Infinity"`. + FLOAT32 = 15; + // Encoded as `string` in RFC 3339 timestamp format. The time zone // must be present, and must be `"Z"`. // From b8d5451b0fbda71a0c77f273adfb31595f58758c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Knut=20Olav=20L=C3=B8ite?= Date: Sat, 27 Jan 2024 09:54:42 +0100 Subject: [PATCH 15/21] test: add tests for concatenated literals (#2791) --- .../connection/StatementParserTest.java | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/connection/StatementParserTest.java b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/connection/StatementParserTest.java index 1c20bc94ec6..ef0fd4f18a3 100644 --- a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/connection/StatementParserTest.java +++ b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/connection/StatementParserTest.java @@ -1578,6 +1578,25 @@ int skipMultiLineComment(String sql, int startIndex) { return PostgreSQLStatementParser.skipMultiLineComment(sql, startIndex, null); } + @Test + public void testConcatenatedLiterals() { + assumeTrue(dialect == Dialect.GOOGLE_STANDARD_SQL); + + assertTrue(parser.isUpdateStatement("UPDATE foo SET name='foo' 'bar' WHERE ID=1")); + assertTrue(parser.isQuery("SELECT 'boo' 'bar' FROM my_table WHERE value='lit1''lit2'")); + assertTrue( + parser.checkReturningClause( + "insert into my_table (id, value) values (1, 'value' '1') then return id")); + assertTrue(parser.isUpdateStatement("UPDATE foo SET name=b'foo' b'bar' WHERE ID=1")); + + assertEquals( + 1, + parser.convertPositionalParametersToNamedParameters( + '?', "select 'foo?''bar?' where id=? and value='?' '?'") + .numberOfParameters, + 1); + } + @Test public void testSkipSingleLineComment() { assumeTrue(dialect == Dialect.POSTGRESQL); From 2c0a34b75d08a5091c0f860289eb61625dcf7565 Mon Sep 17 00:00:00 2001 From: Scott Nam Date: Sat, 27 Jan 2024 00:58:15 -0800 Subject: [PATCH 16/21] chore: Include RENAME in DDL statement list (#2784) Fixes #2783 --- .../spanner/connection/AbstractStatementParser.java | 2 +- .../spanner/connection/StatementParserTest.java | 13 +++++++++++++ 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/google-cloud-spanner/src/main/java/com/google/cloud/spanner/connection/AbstractStatementParser.java b/google-cloud-spanner/src/main/java/com/google/cloud/spanner/connection/AbstractStatementParser.java index 6c35fe5c96d..cc4731cb094 100644 --- a/google-cloud-spanner/src/main/java/com/google/cloud/spanner/connection/AbstractStatementParser.java +++ b/google-cloud-spanner/src/main/java/com/google/cloud/spanner/connection/AbstractStatementParser.java @@ -356,7 +356,7 @@ ClientSideStatement getClientSideStatement() { } static final Set ddlStatements = - ImmutableSet.of("CREATE", "DROP", "ALTER", "ANALYZE", "GRANT", "REVOKE"); + ImmutableSet.of("CREATE", "DROP", "ALTER", "ANALYZE", "GRANT", "REVOKE", "RENAME"); static final Set selectStatements = ImmutableSet.of("SELECT", "WITH", "SHOW"); static final Set dmlStatements = ImmutableSet.of("INSERT", "UPDATE", "DELETE"); private final Set statements; diff --git a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/connection/StatementParserTest.java b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/connection/StatementParserTest.java index ef0fd4f18a3..fde743c229a 100644 --- a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/connection/StatementParserTest.java +++ b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/connection/StatementParserTest.java @@ -553,6 +553,19 @@ public void testIsDdlStatement() { assertTrue(parser.parse(Statement.of("\t ANALYZE\n ")).isDdl()); assertTrue(parser.parse(Statement.of("/* This is a comment */ ANALYZE ")).isDdl()); assertTrue(parser.parse(Statement.of("-- comment\n ANALYZE ")).isDdl()); + assertTrue(parser.parse(Statement.of("RENAME TABLE foo TO foo2")).isDdl()); + assertTrue( + parser.parse(Statement.of("/* Fix typo */ RENAME TABLE studens TO students")).isDdl()); + assertTrue( + parser.parse(Statement.of("/* Fix typo */ rename TABLE studens TO students")).isDdl()); + assertTrue( + parser.parse(Statement.of("RENAME INDEX idx_foo TO idx_students_last_name")).isDdl()); + assertTrue( + parser.parse(Statement.of("/* Fix typo */ Rename TABLE studens TO students")).isDdl()); + assertTrue( + parser + .parse(Statement.of(" \t\nRENAME\n INDEX idx_foo TO idx_students_last_name")) + .isDdl()); } @Test From 04f72ee0d7309a88e8f739d0365c3696fee50d35 Mon Sep 17 00:00:00 2001 From: Sri Harsha CH <57220027+harshachinta@users.noreply.github.com> Date: Sun, 28 Jan 2024 10:29:02 +0530 Subject: [PATCH 17/21] test: update proto columns test (#2845) * test(spanner): add try-with-resources block to free up resources * test(spanner): add test for to string * test(spanner): fix tests --- .../java/com/google/cloud/spanner/Value.java | 10 +- .../cloud/spanner/DatabaseClientImplTest.java | 437 ++++++++++-------- .../connection/MergedResultSetTest.java | 2 +- .../PartitionedQueryMockServerTest.java | 4 +- .../connection/RandomResultSetGenerator.java | 14 +- .../cloud/spanner/it/ITProtoColumnTest.java | 86 ++-- 6 files changed, 304 insertions(+), 249 deletions(-) diff --git a/google-cloud-spanner/src/main/java/com/google/cloud/spanner/Value.java b/google-cloud-spanner/src/main/java/com/google/cloud/spanner/Value.java index 7cc7b675780..a845eb118bf 100644 --- a/google-cloud-spanner/src/main/java/com/google/cloud/spanner/Value.java +++ b/google-cloud-spanner/src/main/java/com/google/cloud/spanner/Value.java @@ -1749,9 +1749,15 @@ com.google.protobuf.Value valueToProto() { return com.google.protobuf.Value.newBuilder().setStringValue(base64EncodedString).build(); } + @Nonnull + @Override + public String getAsString() { + return value == null ? NULL_STRING : value.toBase64(); + } + @Override void valueToString(StringBuilder b) { - b.append(value.toString()); + b.append(value.toBase64()); } } @@ -2387,7 +2393,7 @@ String elementToString(ByteArray element) { @Override void appendElement(StringBuilder b, ByteArray element) { - b.append(element.toString()); + b.append(element.toBase64()); } } diff --git a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/DatabaseClientImplTest.java b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/DatabaseClientImplTest.java index 24c7e3fd95d..2c2d5a1a139 100644 --- a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/DatabaseClientImplTest.java +++ b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/DatabaseClientImplTest.java @@ -57,6 +57,8 @@ import com.google.cloud.spanner.SessionPool.PooledSessionFuture; import com.google.cloud.spanner.SessionPoolOptions.ActionOnInactiveTransaction; import com.google.cloud.spanner.SessionPoolOptions.InactiveTransactionRemovalOptions; +import com.google.cloud.spanner.SingerProto.Genre; +import com.google.cloud.spanner.SingerProto.SingerInfo; import com.google.cloud.spanner.SpannerException.ResourceNotFoundException; import com.google.cloud.spanner.SpannerOptions.CallContextConfigurator; import com.google.cloud.spanner.SpannerOptions.SpannerCallContextTimeoutConfigurator; @@ -3950,6 +3952,7 @@ public void testByteArray() { @Test public void testGetAllTypesAsString() { + SingerInfo info = SingerInfo.newBuilder().setSingerId(1).build(); for (Dialect dialect : Dialect.values()) { Statement statement = Statement.of("select * from all_types"); mockSpanner.putStatementResult( @@ -3959,205 +3962,7 @@ public void testGetAllTypesAsString() { .setMetadata( RandomResultSetGenerator.generateAllTypesMetadata( RandomResultSetGenerator.generateAllTypes(dialect))) - .addRows( - ListValue.newBuilder() - .addValues( - com.google.protobuf.Value.newBuilder().setBoolValue(true).build()) - .addValues( - com.google.protobuf.Value.newBuilder().setStringValue("100").build()) - .addValues( - com.google.protobuf.Value.newBuilder().setNumberValue(3.14d).build()) - .addValues( - com.google.protobuf.Value.newBuilder() - .setStringValue("6.626") - .build()) - .addValues( - com.google.protobuf.Value.newBuilder() - .setStringValue("test-string") - .build()) - .addValues( - com.google.protobuf.Value.newBuilder() - .setStringValue("{\"key1\": \"value1\"}") - .build()) - .addValues( - com.google.protobuf.Value.newBuilder() - .setStringValue( - Base64.getEncoder() - .encodeToString( - "test-bytes".getBytes(StandardCharsets.UTF_8))) - .build()) - .addValues( - com.google.protobuf.Value.newBuilder() - .setStringValue("2023-01-11") - .build()) - .addValues( - com.google.protobuf.Value.newBuilder() - .setStringValue("2023-01-11T11:55:18.123456789Z") - .build()) - .addValues( - com.google.protobuf.Value.newBuilder() - .setListValue( - ListValue.newBuilder() - .addValues( - com.google.protobuf.Value.newBuilder() - .setBoolValue(true) - .build()) - .addValues( - com.google.protobuf.Value.newBuilder() - .setNullValue(NullValue.NULL_VALUE) - .build()) - .addValues( - com.google.protobuf.Value.newBuilder() - .setBoolValue(false) - .build()) - .build())) - .addValues( - com.google.protobuf.Value.newBuilder() - .setListValue( - ListValue.newBuilder() - .addValues( - com.google.protobuf.Value.newBuilder() - .setStringValue(String.valueOf(Long.MAX_VALUE)) - .build()) - .addValues( - com.google.protobuf.Value.newBuilder() - .setStringValue(String.valueOf(Long.MIN_VALUE)) - .build()) - .addValues( - com.google.protobuf.Value.newBuilder() - .setNullValue(NullValue.NULL_VALUE) - .build()) - .build())) - .addValues( - com.google.protobuf.Value.newBuilder() - .setListValue( - ListValue.newBuilder() - .addValues( - com.google.protobuf.Value.newBuilder() - .setNullValue(NullValue.NULL_VALUE) - .build()) - .addValues( - com.google.protobuf.Value.newBuilder() - .setNumberValue(-12345.6789d) - .build()) - .addValues( - com.google.protobuf.Value.newBuilder() - .setNumberValue(3.14d) - .build()) - .build())) - .addValues( - com.google.protobuf.Value.newBuilder() - .setListValue( - ListValue.newBuilder() - .addValues( - com.google.protobuf.Value.newBuilder() - .setStringValue("6.626") - .build()) - .addValues( - com.google.protobuf.Value.newBuilder() - .setNullValue(NullValue.NULL_VALUE) - .build()) - .addValues( - com.google.protobuf.Value.newBuilder() - .setStringValue("-8.9123") - .build()) - .build())) - .addValues( - com.google.protobuf.Value.newBuilder() - .setListValue( - ListValue.newBuilder() - .addValues( - com.google.protobuf.Value.newBuilder() - .setStringValue("test-string1") - .build()) - .addValues( - com.google.protobuf.Value.newBuilder() - .setNullValue(NullValue.NULL_VALUE) - .build()) - .addValues( - com.google.protobuf.Value.newBuilder() - .setStringValue("test-string2") - .build()) - .build())) - .addValues( - com.google.protobuf.Value.newBuilder() - .setListValue( - ListValue.newBuilder() - .addValues( - com.google.protobuf.Value.newBuilder() - .setStringValue("{\"key\": \"value1\"}") - .build()) - .addValues( - com.google.protobuf.Value.newBuilder() - .setStringValue("{\"key\": \"value2\"}") - .build()) - .addValues( - com.google.protobuf.Value.newBuilder() - .setNullValue(NullValue.NULL_VALUE) - .build()) - .build())) - .addValues( - com.google.protobuf.Value.newBuilder() - .setListValue( - ListValue.newBuilder() - .addValues( - com.google.protobuf.Value.newBuilder() - .setStringValue( - Base64.getEncoder() - .encodeToString( - "test-bytes1" - .getBytes( - StandardCharsets.UTF_8))) - .build()) - .addValues( - com.google.protobuf.Value.newBuilder() - .setStringValue( - Base64.getEncoder() - .encodeToString( - "test-bytes2" - .getBytes( - StandardCharsets.UTF_8))) - .build()) - .addValues( - com.google.protobuf.Value.newBuilder() - .setNullValue(NullValue.NULL_VALUE) - .build()) - .build())) - .addValues( - com.google.protobuf.Value.newBuilder() - .setListValue( - ListValue.newBuilder() - .addValues( - com.google.protobuf.Value.newBuilder() - .setStringValue("2000-02-29") - .build()) - .addValues( - com.google.protobuf.Value.newBuilder() - .setNullValue(NullValue.NULL_VALUE) - .build()) - .addValues( - com.google.protobuf.Value.newBuilder() - .setStringValue("2000-01-01") - .build()) - .build())) - .addValues( - com.google.protobuf.Value.newBuilder() - .setListValue( - ListValue.newBuilder() - .addValues( - com.google.protobuf.Value.newBuilder() - .setStringValue("2023-01-11T11:55:18.123456789Z") - .build()) - .addValues( - com.google.protobuf.Value.newBuilder() - .setNullValue(NullValue.NULL_VALUE) - .build()) - .addValues( - com.google.protobuf.Value.newBuilder() - .setStringValue("2023-01-12T11:55:18Z") - .build()) - .build())) - .build()) + .addRows(getRows(dialect)) .build())); DatabaseClient client = @@ -4209,7 +4014,18 @@ public void testGetAllTypesAsString() { ImmutableList.of("2023-01-11T11:55:18.123456789Z", "NULL", "2023-01-12T11:55:18Z"), resultSet, col++); - + if (dialect == Dialect.GOOGLE_STANDARD_SQL) { + assertAsString(Base64.getEncoder().encodeToString(info.toByteArray()), resultSet, col++); + assertAsString(String.valueOf(Genre.JAZZ_VALUE), resultSet, col++); + assertAsString( + ImmutableList.of( + String.format("%s", Base64.getEncoder().encodeToString(info.toByteArray())), + "NULL"), + resultSet, + col++); + assertAsString( + ImmutableList.of(String.format("%d", Genre.JAZZ_VALUE), "NULL"), resultSet, col++); + } assertFalse(resultSet.next()); } } @@ -4627,4 +4443,225 @@ private void consumeBatchWriteStream(ServerStream stream) { //noinspection StatementWithEmptyBody for (BatchWriteResponse ignore : stream) {} } + + private ListValue getRows(Dialect dialect) { + SingerInfo info = SingerInfo.newBuilder().setSingerId(1).build(); + ListValue.Builder valuesBuilder = + ListValue.newBuilder() + .addValues(com.google.protobuf.Value.newBuilder().setBoolValue(true).build()) + .addValues(com.google.protobuf.Value.newBuilder().setStringValue("100").build()) + .addValues(com.google.protobuf.Value.newBuilder().setNumberValue(3.14d).build()) + .addValues(com.google.protobuf.Value.newBuilder().setStringValue("6.626").build()) + .addValues(com.google.protobuf.Value.newBuilder().setStringValue("test-string").build()) + .addValues( + com.google.protobuf.Value.newBuilder() + .setStringValue("{\"key1\": \"value1\"}") + .build()) + .addValues( + com.google.protobuf.Value.newBuilder() + .setStringValue( + Base64.getEncoder() + .encodeToString("test-bytes".getBytes(StandardCharsets.UTF_8))) + .build()) + .addValues(com.google.protobuf.Value.newBuilder().setStringValue("2023-01-11").build()) + .addValues( + com.google.protobuf.Value.newBuilder() + .setStringValue("2023-01-11T11:55:18.123456789Z") + .build()) + .addValues( + com.google.protobuf.Value.newBuilder() + .setListValue( + ListValue.newBuilder() + .addValues( + com.google.protobuf.Value.newBuilder().setBoolValue(true).build()) + .addValues( + com.google.protobuf.Value.newBuilder() + .setNullValue(NullValue.NULL_VALUE) + .build()) + .addValues( + com.google.protobuf.Value.newBuilder().setBoolValue(false).build()) + .build())) + .addValues( + com.google.protobuf.Value.newBuilder() + .setListValue( + ListValue.newBuilder() + .addValues( + com.google.protobuf.Value.newBuilder() + .setStringValue(String.valueOf(Long.MAX_VALUE)) + .build()) + .addValues( + com.google.protobuf.Value.newBuilder() + .setStringValue(String.valueOf(Long.MIN_VALUE)) + .build()) + .addValues( + com.google.protobuf.Value.newBuilder() + .setNullValue(NullValue.NULL_VALUE) + .build()) + .build())) + .addValues( + com.google.protobuf.Value.newBuilder() + .setListValue( + ListValue.newBuilder() + .addValues( + com.google.protobuf.Value.newBuilder() + .setNullValue(NullValue.NULL_VALUE) + .build()) + .addValues( + com.google.protobuf.Value.newBuilder() + .setNumberValue(-12345.6789d) + .build()) + .addValues( + com.google.protobuf.Value.newBuilder() + .setNumberValue(3.14d) + .build()) + .build())) + .addValues( + com.google.protobuf.Value.newBuilder() + .setListValue( + ListValue.newBuilder() + .addValues( + com.google.protobuf.Value.newBuilder() + .setStringValue("6.626") + .build()) + .addValues( + com.google.protobuf.Value.newBuilder() + .setNullValue(NullValue.NULL_VALUE) + .build()) + .addValues( + com.google.protobuf.Value.newBuilder() + .setStringValue("-8.9123") + .build()) + .build())) + .addValues( + com.google.protobuf.Value.newBuilder() + .setListValue( + ListValue.newBuilder() + .addValues( + com.google.protobuf.Value.newBuilder() + .setStringValue("test-string1") + .build()) + .addValues( + com.google.protobuf.Value.newBuilder() + .setNullValue(NullValue.NULL_VALUE) + .build()) + .addValues( + com.google.protobuf.Value.newBuilder() + .setStringValue("test-string2") + .build()) + .build())) + .addValues( + com.google.protobuf.Value.newBuilder() + .setListValue( + ListValue.newBuilder() + .addValues( + com.google.protobuf.Value.newBuilder() + .setStringValue("{\"key\": \"value1\"}") + .build()) + .addValues( + com.google.protobuf.Value.newBuilder() + .setStringValue("{\"key\": \"value2\"}") + .build()) + .addValues( + com.google.protobuf.Value.newBuilder() + .setNullValue(NullValue.NULL_VALUE) + .build()) + .build())) + .addValues( + com.google.protobuf.Value.newBuilder() + .setListValue( + ListValue.newBuilder() + .addValues( + com.google.protobuf.Value.newBuilder() + .setStringValue( + Base64.getEncoder() + .encodeToString( + "test-bytes1".getBytes(StandardCharsets.UTF_8))) + .build()) + .addValues( + com.google.protobuf.Value.newBuilder() + .setStringValue( + Base64.getEncoder() + .encodeToString( + "test-bytes2".getBytes(StandardCharsets.UTF_8))) + .build()) + .addValues( + com.google.protobuf.Value.newBuilder() + .setNullValue(NullValue.NULL_VALUE) + .build()) + .build())) + .addValues( + com.google.protobuf.Value.newBuilder() + .setListValue( + ListValue.newBuilder() + .addValues( + com.google.protobuf.Value.newBuilder() + .setStringValue("2000-02-29") + .build()) + .addValues( + com.google.protobuf.Value.newBuilder() + .setNullValue(NullValue.NULL_VALUE) + .build()) + .addValues( + com.google.protobuf.Value.newBuilder() + .setStringValue("2000-01-01") + .build()) + .build())) + .addValues( + com.google.protobuf.Value.newBuilder() + .setListValue( + ListValue.newBuilder() + .addValues( + com.google.protobuf.Value.newBuilder() + .setStringValue("2023-01-11T11:55:18.123456789Z") + .build()) + .addValues( + com.google.protobuf.Value.newBuilder() + .setNullValue(NullValue.NULL_VALUE) + .build()) + .addValues( + com.google.protobuf.Value.newBuilder() + .setStringValue("2023-01-12T11:55:18Z") + .build()) + .build())); + if (dialect == Dialect.GOOGLE_STANDARD_SQL) { + // Proto columns is supported only for GOOGLE_STANDARD_SQL + valuesBuilder + .addValues( + com.google.protobuf.Value.newBuilder() + .setStringValue(Base64.getEncoder().encodeToString(info.toByteArray())) + .build()) + .addValues( + com.google.protobuf.Value.newBuilder() + .setStringValue(String.valueOf(Genre.JAZZ_VALUE)) + .build()) + .addValues( + com.google.protobuf.Value.newBuilder() + .setListValue( + ListValue.newBuilder() + .addValues( + com.google.protobuf.Value.newBuilder() + .setStringValue( + Base64.getEncoder().encodeToString(info.toByteArray())) + .build()) + .addValues( + com.google.protobuf.Value.newBuilder() + .setNullValue(NullValue.NULL_VALUE) + .build()) + .build())) + .addValues( + com.google.protobuf.Value.newBuilder() + .setListValue( + ListValue.newBuilder() + .addValues( + com.google.protobuf.Value.newBuilder() + .setStringValue(String.valueOf(Genre.JAZZ_VALUE)) + .build()) + .addValues( + com.google.protobuf.Value.newBuilder() + .setNullValue(NullValue.NULL_VALUE) + .build()) + .build())); + } + return valuesBuilder.build(); + } } diff --git a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/connection/MergedResultSetTest.java b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/connection/MergedResultSetTest.java index c8295fd5eca..3cf717e176a 100644 --- a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/connection/MergedResultSetTest.java +++ b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/connection/MergedResultSetTest.java @@ -150,7 +150,7 @@ public void testAllResultsAreReturned() { if (numPartitions == 0) { assertEquals(0, resultSet.getColumnCount()); } else { - assertEquals(18, resultSet.getColumnCount()); + assertEquals(22, resultSet.getColumnCount()); assertEquals(Type.bool(), resultSet.getColumnType(0)); assertEquals(Type.bool(), resultSet.getColumnType("COL0")); assertEquals(10, resultSet.getColumnIndex("COL10")); diff --git a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/connection/PartitionedQueryMockServerTest.java b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/connection/PartitionedQueryMockServerTest.java index af586b3f986..e5731ff0f6a 100644 --- a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/connection/PartitionedQueryMockServerTest.java +++ b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/connection/PartitionedQueryMockServerTest.java @@ -349,9 +349,9 @@ public void testRunEmptyPartitionedQuery() { statement, PartitionOptions.newBuilder().setMaxPartitions(maxPartitions).build())) { assertFalse(resultSet.next()); assertNotNull(resultSet.getMetadata()); - assertEquals(18, resultSet.getMetadata().getRowType().getFieldsCount()); + assertEquals(22, resultSet.getMetadata().getRowType().getFieldsCount()); assertNotNull(resultSet.getType()); - assertEquals(18, resultSet.getType().getStructFields().size()); + assertEquals(22, resultSet.getType().getStructFields().size()); } } assertEquals(1, mockSpanner.countRequestsOfType(CreateSessionRequest.class)); diff --git a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/connection/RandomResultSetGenerator.java b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/connection/RandomResultSetGenerator.java index 69ae89b2ee9..3091364e17a 100644 --- a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/connection/RandomResultSetGenerator.java +++ b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/connection/RandomResultSetGenerator.java @@ -114,7 +114,7 @@ public static Type[] generateAllTypes(Dialect dialect) { .setArrayElementType(Type.newBuilder().setCode(TypeCode.TIMESTAMP)) .build())); - // appendProtoTypes(types, dialect); + appendProtoTypes(types, dialect); Type[] typeArray = new Type[types.size()]; typeArray = types.toArray(typeArray); return typeArray; @@ -123,8 +123,16 @@ public static Type[] generateAllTypes(Dialect dialect) { /** To append Proto & Enum types * */ private static void appendProtoTypes(List types, Dialect dialect) { if (dialect == Dialect.GOOGLE_STANDARD_SQL) { - types.add(Type.newBuilder().setCode(TypeCode.PROTO).setProtoTypeFqn("testProto").build()); - types.add(Type.newBuilder().setCode(TypeCode.ENUM).setProtoTypeFqn("testEnum").build()); + types.add( + Type.newBuilder() + .setCode(TypeCode.PROTO) + .setProtoTypeFqn(SingerInfo.getDescriptor().getFullName()) + .build()); + types.add( + Type.newBuilder() + .setCode(TypeCode.ENUM) + .setProtoTypeFqn(Genre.getDescriptor().getFullName()) + .build()); types.add( Type.newBuilder() .setCode(TypeCode.ARRAY) diff --git a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/it/ITProtoColumnTest.java b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/it/ITProtoColumnTest.java index c1e06f9ad7b..82e51c32933 100644 --- a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/it/ITProtoColumnTest.java +++ b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/it/ITProtoColumnTest.java @@ -304,7 +304,7 @@ public void testProtoColumnsDMLParameterizedQueriesPKAndIndexes() { }); // Read all rows based on Proto Message field and Proto Enum Primary key column values - ResultSet resultSet1 = + try (ResultSet resultSet1 = databaseClient .singleUse() .read( @@ -313,40 +313,42 @@ public void testProtoColumnsDMLParameterizedQueriesPKAndIndexes() { .addKey(Key.of("Country1", Genre.FOLK)) .addKey(Key.of("Country2", Genre.JAZZ)) .build(), - Arrays.asList("SingerId", "FirstName", "LastName", "SingerInfo", "SingerGenre")); - - resultSet1.next(); - assertEquals(1, resultSet1.getLong("SingerId")); - assertEquals("FirstName1", resultSet1.getString("FirstName")); - assertEquals("LastName1", resultSet1.getString("LastName")); - assertEquals( - singerInfo1, resultSet1.getProtoMessage("SingerInfo", SingerInfo.getDefaultInstance())); - assertEquals(genre1, resultSet1.getProtoEnum("SingerGenre", Genre::forNumber)); - - resultSet1.next(); - assertEquals(2, resultSet1.getLong("SingerId")); - assertEquals("FirstName2", resultSet1.getString("FirstName")); - assertEquals("LastName2", resultSet1.getString("LastName")); - assertEquals( - singerInfo2, resultSet1.getProtoMessage("SingerInfo", SingerInfo.getDefaultInstance())); - assertEquals(genre2, resultSet1.getProtoEnum("SingerGenre", Genre::forNumber)); + Arrays.asList("SingerId", "FirstName", "LastName", "SingerInfo", "SingerGenre"))) { + resultSet1.next(); + assertEquals(1, resultSet1.getLong("SingerId")); + assertEquals("FirstName1", resultSet1.getString("FirstName")); + assertEquals("LastName1", resultSet1.getString("LastName")); + assertEquals( + singerInfo1, resultSet1.getProtoMessage("SingerInfo", SingerInfo.getDefaultInstance())); + assertEquals(genre1, resultSet1.getProtoEnum("SingerGenre", Genre::forNumber)); + + resultSet1.next(); + assertEquals(2, resultSet1.getLong("SingerId")); + assertEquals("FirstName2", resultSet1.getString("FirstName")); + assertEquals("LastName2", resultSet1.getString("LastName")); + assertEquals( + singerInfo2, resultSet1.getProtoMessage("SingerInfo", SingerInfo.getDefaultInstance())); + assertEquals(genre2, resultSet1.getProtoEnum("SingerGenre", Genre::forNumber)); + } // Read rows using Index on Proto Message field and Proto Enum column - ResultSet resultSet2 = + try (ResultSet resultSet2 = databaseClient .singleUse() .readUsingIndex( "Singers", "SingerByNationalityAndGenre", KeySet.singleKey(Key.of("Country2", Genre.JAZZ)), - Arrays.asList("SingerId", "FirstName", "LastName")); - resultSet2.next(); - assertEquals(2, resultSet2.getLong("SingerId")); - assertEquals("FirstName2", resultSet2.getString("FirstName")); - assertEquals("LastName2", resultSet2.getString("LastName")); + Arrays.asList("SingerId", "FirstName", "LastName"))) { + + resultSet2.next(); + assertEquals(2, resultSet2.getLong("SingerId")); + assertEquals("FirstName2", resultSet2.getString("FirstName")); + assertEquals("LastName2", resultSet2.getString("LastName")); + } // Filter using Parameterized DQL - ResultSet resultSet3 = + try (ResultSet resultSet3 = databaseClient .singleUse() .executeQuery( @@ -357,13 +359,13 @@ public void testProtoColumnsDMLParameterizedQueriesPKAndIndexes() { .to("Country2") .bind("genre") .to(Genre.JAZZ) - .build()); - - resultSet3.next(); - assertEquals(2, resultSet1.getLong("SingerId")); - assertEquals( - singerInfo2, resultSet1.getProtoMessage("SingerInfo", SingerInfo.getDefaultInstance())); - assertEquals(genre2, resultSet1.getProtoEnum("SingerGenre", Genre::forNumber)); + .build())) { + resultSet3.next(); + assertEquals(2, resultSet3.getLong("SingerId")); + assertEquals( + singerInfo2, resultSet3.getProtoMessage("SingerInfo", SingerInfo.getDefaultInstance())); + assertEquals(genre2, resultSet3.getProtoEnum("SingerGenre", Genre::forNumber)); + } } // Test the exception in case Invalid protocol message object is provided while deserializing the @@ -385,18 +387,20 @@ public void testProtoMessageDeserializationError() { .to(singerInfo) .build())); - ResultSet resultSet = + try (ResultSet resultSet = databaseClient .singleUse() - .read("Types", KeySet.all(), Collections.singletonList("ProtoMessage")); - resultSet.next(); + .read("Types", KeySet.all(), Collections.singletonList("ProtoMessage"))) { - SpannerException e = - assertThrows( - SpannerException.class, - () -> resultSet.getProtoMessage("ProtoMessage", Backup.getDefaultInstance())); + resultSet.next(); - // Underlying cause is InvalidWireTypeException - assertEquals(InvalidWireTypeException.class, e.getCause().getClass()); + SpannerException e = + assertThrows( + SpannerException.class, + () -> resultSet.getProtoMessage("ProtoMessage", Backup.getDefaultInstance())); + + // Underlying cause is InvalidWireTypeException + assertEquals(InvalidWireTypeException.class, e.getCause().getClass()); + } } } From 655000a3b0471b279cbcbe8a4a601337e7274ef8 Mon Sep 17 00:00:00 2001 From: Tomo Suzuki Date: Sun, 28 Jan 2024 16:22:59 -0500 Subject: [PATCH 18/21] fix: remove google-cloud-spanner-executor from the BOM (#2844) --- google-cloud-spanner-bom/pom.xml | 5 ----- 1 file changed, 5 deletions(-) diff --git a/google-cloud-spanner-bom/pom.xml b/google-cloud-spanner-bom/pom.xml index 257c3bb24b5..b155938f9dc 100644 --- a/google-cloud-spanner-bom/pom.xml +++ b/google-cloud-spanner-bom/pom.xml @@ -55,11 +55,6 @@ google-cloud-spanner 6.56.1-SNAPSHOT - - com.google.cloud - google-cloud-spanner-executor - 6.56.1-SNAPSHOT - com.google.cloud google-cloud-spanner From 340ba138fefcf81fd73a644431418679d03fea3c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Knut=20Olav=20L=C3=B8ite?= Date: Mon, 29 Jan 2024 11:46:54 +0100 Subject: [PATCH 19/21] chore: use a cache for the statement parser (#2790) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * chore: use a cache for the statement parser Add a cache for the statement parser that is used in the Connection API. This will reduce the number of times that a SQL string needs to be parsed by the JDBC driver and PGAdapter. * docs: fix/update comments * chore: add 'mb' to cache size property name * chore: use variable * 🦉 Updates from OwlBot post-processor See https://github.com/googleapis/repo-automation-bots/blob/main/packages/owl-bot/README.md --------- Co-authored-by: Owl Bot --- .../connection/AbstractStatementParser.java | 111 ++++++++++++++++-- .../cloud/spanner/SessionPoolStressTest.java | 1 + .../connection/StatementParserTest.java | 73 ++++++++++++ 3 files changed, 177 insertions(+), 8 deletions(-) diff --git a/google-cloud-spanner/src/main/java/com/google/cloud/spanner/connection/AbstractStatementParser.java b/google-cloud-spanner/src/main/java/com/google/cloud/spanner/connection/AbstractStatementParser.java index cc4731cb094..629ab9cca6a 100644 --- a/google-cloud-spanner/src/main/java/com/google/cloud/spanner/connection/AbstractStatementParser.java +++ b/google-cloud-spanner/src/main/java/com/google/cloud/spanner/connection/AbstractStatementParser.java @@ -25,6 +25,10 @@ import com.google.cloud.spanner.connection.StatementResult.ClientSideStatementType; import com.google.common.annotations.VisibleForTesting; import com.google.common.base.Preconditions; +import com.google.common.cache.Cache; +import com.google.common.cache.CacheBuilder; +import com.google.common.cache.CacheStats; +import com.google.common.cache.Weigher; import com.google.common.collect.ImmutableMap; import com.google.common.collect.ImmutableSet; import com.google.spanner.v1.ExecuteSqlRequest.QueryOptions; @@ -59,6 +63,13 @@ public abstract class AbstractStatementParser { Dialect.POSTGRESQL, PostgreSQLStatementParser.class); + @VisibleForTesting + static void resetParsers() { + synchronized (lock) { + INSTANCES.clear(); + } + } + /** * Get an instance of {@link AbstractStatementParser} for the specified dialect. * @@ -171,7 +182,7 @@ private static ParsedStatement ddl(Statement statement, String sqlWithoutComment private static ParsedStatement query( Statement statement, String sqlWithoutComments, QueryOptions defaultQueryOptions) { return new ParsedStatement( - StatementType.QUERY, statement, sqlWithoutComments, defaultQueryOptions, false); + StatementType.QUERY, null, statement, sqlWithoutComments, defaultQueryOptions, false); } private static ParsedStatement update( @@ -193,7 +204,7 @@ private ParsedStatement( this.type = StatementType.CLIENT_SIDE; this.clientSideStatement = clientSideStatement; this.statement = statement; - this.sqlWithoutComments = sqlWithoutComments; + this.sqlWithoutComments = Preconditions.checkNotNull(sqlWithoutComments); this.returningClause = false; } @@ -202,28 +213,48 @@ private ParsedStatement( Statement statement, String sqlWithoutComments, boolean returningClause) { - this(type, statement, sqlWithoutComments, null, returningClause); + this(type, null, statement, sqlWithoutComments, null, returningClause); } private ParsedStatement(StatementType type, Statement statement, String sqlWithoutComments) { - this(type, statement, sqlWithoutComments, null, false); + this(type, null, statement, sqlWithoutComments, null, false); } private ParsedStatement( StatementType type, + ClientSideStatementImpl clientSideStatement, Statement statement, String sqlWithoutComments, QueryOptions defaultQueryOptions, boolean returningClause) { Preconditions.checkNotNull(type); - Preconditions.checkNotNull(statement); this.type = type; - this.clientSideStatement = null; - this.statement = mergeQueryOptions(statement, defaultQueryOptions); - this.sqlWithoutComments = sqlWithoutComments; + this.clientSideStatement = clientSideStatement; + this.statement = statement == null ? null : mergeQueryOptions(statement, defaultQueryOptions); + this.sqlWithoutComments = Preconditions.checkNotNull(sqlWithoutComments); this.returningClause = returningClause; } + private ParsedStatement copy(Statement statement, QueryOptions defaultQueryOptions) { + return new ParsedStatement( + this.type, + this.clientSideStatement, + statement, + this.sqlWithoutComments, + defaultQueryOptions, + this.returningClause); + } + + private ParsedStatement forCache() { + return new ParsedStatement( + this.type, + this.clientSideStatement, + null, + this.sqlWithoutComments, + null, + this.returningClause); + } + @Override public int hashCode() { return Objects.hash( @@ -361,8 +392,58 @@ ClientSideStatement getClientSideStatement() { static final Set dmlStatements = ImmutableSet.of("INSERT", "UPDATE", "DELETE"); private final Set statements; + /** The default maximum size of the statement cache in Mb. */ + public static final int DEFAULT_MAX_STATEMENT_CACHE_SIZE_MB = 5; + + private static int getMaxStatementCacheSize() { + String stringValue = System.getProperty("spanner.statement_cache_size_mb"); + if (stringValue == null) { + return DEFAULT_MAX_STATEMENT_CACHE_SIZE_MB; + } + int value = 0; + try { + value = Integer.parseInt(stringValue); + } catch (NumberFormatException ignore) { + } + return Math.max(value, 0); + } + + private static boolean isRecordStatementCacheStats() { + return "true" + .equalsIgnoreCase(System.getProperty("spanner.record_statement_cache_stats", "false")); + } + + /** + * Cache for parsed statements. This prevents statements that are executed multiple times by the + * application to be parsed over and over again. The default maximum size is 5Mb. + */ + private final Cache statementCache; + AbstractStatementParser(Set statements) { this.statements = Collections.unmodifiableSet(statements); + int maxCacheSize = getMaxStatementCacheSize(); + if (maxCacheSize > 0) { + CacheBuilder cacheBuilder = + CacheBuilder.newBuilder() + // Set the max size to (approx) 5MB (by default). + .maximumWeight(maxCacheSize * 1024L * 1024L) + // We do length*2 because Java uses 2 bytes for each char. + .weigher( + (Weigher) + (key, value) -> 2 * key.length() + 2 * value.sqlWithoutComments.length()) + .concurrencyLevel(Runtime.getRuntime().availableProcessors()); + if (isRecordStatementCacheStats()) { + cacheBuilder.recordStats(); + } + this.statementCache = cacheBuilder.build(); + } else { + this.statementCache = null; + } + } + + @VisibleForTesting + CacheStats getStatementCacheStats() { + return statementCache == null ? null : statementCache.stats(); } @VisibleForTesting @@ -383,6 +464,20 @@ public ParsedStatement parse(Statement statement) { } ParsedStatement parse(Statement statement, QueryOptions defaultQueryOptions) { + if (statementCache == null) { + return internalParse(statement, defaultQueryOptions); + } + + ParsedStatement parsedStatement = statementCache.getIfPresent(statement.getSql()); + if (parsedStatement == null) { + parsedStatement = internalParse(statement, null); + statementCache.put(statement.getSql(), parsedStatement.forCache()); + return parsedStatement; + } + return parsedStatement.copy(statement, defaultQueryOptions); + } + + private ParsedStatement internalParse(Statement statement, QueryOptions defaultQueryOptions) { String sql = removeCommentsAndTrim(statement.getSql()); ClientSideStatementImpl client = parseClientSideStatement(sql); if (client != null) { diff --git a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/SessionPoolStressTest.java b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/SessionPoolStressTest.java index 8a3a67b2de4..61d37145aa4 100644 --- a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/SessionPoolStressTest.java +++ b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/SessionPoolStressTest.java @@ -294,6 +294,7 @@ public void stressTest() throws Exception { () -> { while (!stopMaintenance.get()) { runMaintenanceLoop(clock, pool, 1); + Uninterruptibles.sleepUninterruptibly(1L, TimeUnit.MILLISECONDS); } }) .start(); diff --git a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/connection/StatementParserTest.java b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/connection/StatementParserTest.java index fde743c229a..d3438b2b661 100644 --- a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/connection/StatementParserTest.java +++ b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/connection/StatementParserTest.java @@ -22,6 +22,7 @@ import static org.hamcrest.MatcherAssert.assertThat; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotSame; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; import static org.junit.Assume.assumeTrue; @@ -34,6 +35,7 @@ import com.google.cloud.spanner.connection.AbstractStatementParser.StatementType; import com.google.cloud.spanner.connection.ClientSideStatementImpl.CompileException; import com.google.cloud.spanner.connection.StatementResult.ClientSideStatementType; +import com.google.common.cache.CacheStats; import com.google.common.collect.ImmutableMap; import com.google.common.collect.ImmutableSet; import com.google.common.truth.Truth; @@ -43,9 +45,12 @@ import java.util.List; import java.util.Scanner; import java.util.Set; +import java.util.UUID; import java.util.regex.Matcher; import java.util.regex.Pattern; +import org.junit.AfterClass; import org.junit.Before; +import org.junit.BeforeClass; import org.junit.Test; import org.junit.runner.RunWith; import org.junit.runners.Parameterized; @@ -81,6 +86,17 @@ public static Object[] data() { private AbstractStatementParser parser; + @BeforeClass + public static void enableStatementCacheStats() { + AbstractStatementParser.resetParsers(); + System.setProperty("spanner.record_statement_cache_stats", "true"); + } + + @AfterClass + public static void disableStatementCacheStats() { + System.clearProperty("spanner.record_statement_cache_stats"); + } + @Before public void setupParser() { parser = AbstractStatementParser.getInstance(dialect); @@ -1641,6 +1657,63 @@ public void testSkipMultiLineComment() { skipMultiLineComment("/* foo /* inner comment */ not in inner comment */ bar", 0)); } + @Test + public void testStatementCache_NonParameterizedStatement() { + CacheStats statsBefore = parser.getStatementCacheStats(); + + String sql = "select foo from bar where id=" + UUID.randomUUID(); + ParsedStatement parsedStatement1 = parser.parse(Statement.of(sql)); + assertEquals(StatementType.QUERY, parsedStatement1.getType()); + + ParsedStatement parsedStatement2 = parser.parse(Statement.of(sql)); + assertEquals(StatementType.QUERY, parsedStatement2.getType()); + + // Even though the parsed statements are cached, the returned instances are not the same. + // This makes sure that statements with the same SQL string and different parameter values + // can use the cache. + assertNotSame(parsedStatement1, parsedStatement2); + + CacheStats statsAfter = parser.getStatementCacheStats(); + CacheStats stats = statsAfter.minus(statsBefore); + + // The first query had a cache miss. The second a cache hit. + assertEquals(1, stats.missCount()); + assertEquals(1, stats.hitCount()); + } + + @Test + public void testStatementCache_ParameterizedStatement() { + CacheStats statsBefore = parser.getStatementCacheStats(); + + String sql = + "select " + + UUID.randomUUID() + + " from bar where id=" + + (dialect == Dialect.POSTGRESQL ? "$1" : "@p1"); + Statement statement1 = Statement.newBuilder(sql).bind("p1").to(1L).build(); + Statement statement2 = Statement.newBuilder(sql).bind("p1").to(2L).build(); + + ParsedStatement parsedStatement1 = parser.parse(statement1); + assertEquals(StatementType.QUERY, parsedStatement1.getType()); + assertEquals(parsedStatement1.getStatement(), statement1); + + ParsedStatement parsedStatement2 = parser.parse(statement2); + assertEquals(StatementType.QUERY, parsedStatement2.getType()); + assertEquals(parsedStatement2.getStatement(), statement2); + + // Even though the parsed statements are cached, the returned instances are not the same. + // This makes sure that statements with the same SQL string and different parameter values + // can use the cache. + assertNotSame(parsedStatement1, parsedStatement2); + + CacheStats statsAfter = parser.getStatementCacheStats(); + CacheStats stats = statsAfter.minus(statsBefore); + + // The first query had a cache miss. The second a cache hit. + assertEquals(1, stats.missCount()); + assertEquals(1, stats.hitCount()); + } + private void assertUnclosedLiteral(String sql) { try { parser.convertPositionalParametersToNamedParameters('?', sql); From c99189c50661aaa4325d2469b26e20f412587ed9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Knut=20Olav=20L=C3=B8ite?= Date: Mon, 29 Jan 2024 12:20:15 +0100 Subject: [PATCH 20/21] chore: add support for virtual threads to Connection API (#2789) Adds support for using virtual threads in the Connection API. Virtual threads can be enabled for two things: 1. As the StatementExecutor thread for each connection. 2. As the gRPC transport thread pool. Both options can (for now) only be set in the Connection API. Setting any of these options only has any effect if the application is running on Java 21 or higher. --- .../google/cloud/spanner/SpannerOptions.java | 25 ++++- .../cloud/spanner/ThreadFactoryUtil.java | 99 +++++++++++++++++++ .../spanner/connection/ChecksumResultSet.java | 9 +- .../spanner/connection/ConnectionImpl.java | 7 +- .../spanner/connection/ConnectionOptions.java | 43 ++++++++ .../connection/ConnectionSpannerOptions.java | 48 +++++++++ .../connection/ReadWriteTransaction.java | 9 +- .../cloud/spanner/connection/SpannerPool.java | 13 ++- .../spanner/connection/StatementExecutor.java | 46 +++++---- .../cloud/spanner/spi/v1/GapicSpannerRpc.java | 10 +- .../cloud/spanner/SessionPoolStressTest.java | 2 + .../cloud/spanner/ThreadFactoryUtilTest.java | 76 ++++++++++++++ .../connection/ConnectionOptionsTest.java | 52 ++++++++++ .../connection/SavepointMockServerTest.java | 43 ++++++-- .../connection/it/ITTransactionRetryTest.java | 5 +- 15 files changed, 444 insertions(+), 43 deletions(-) create mode 100644 google-cloud-spanner/src/main/java/com/google/cloud/spanner/ThreadFactoryUtil.java create mode 100644 google-cloud-spanner/src/main/java/com/google/cloud/spanner/connection/ConnectionSpannerOptions.java create mode 100644 google-cloud-spanner/src/test/java/com/google/cloud/spanner/ThreadFactoryUtilTest.java diff --git a/google-cloud-spanner/src/main/java/com/google/cloud/spanner/SpannerOptions.java b/google-cloud-spanner/src/main/java/com/google/cloud/spanner/SpannerOptions.java index 877ea72e467..0d9f3b85c19 100644 --- a/google-cloud-spanner/src/main/java/com/google/cloud/spanner/SpannerOptions.java +++ b/google-cloud-spanner/src/main/java/com/google/cloud/spanner/SpannerOptions.java @@ -140,6 +140,7 @@ public class SpannerOptions extends ServiceOptions { private final boolean leaderAwareRoutingEnabled; private final boolean attemptDirectPath; private final DirectedReadOptions directedReadOptions; + private final boolean useVirtualThreads; /** Interface that can be used to provide {@link CallCredentials} to {@link SpannerOptions}. */ public interface CallCredentialsProvider { @@ -580,9 +581,9 @@ public static CloseableExecutorProvider createAsyncExecutorProvider( return FixedCloseableExecutorProvider.create(executor); } - private SpannerOptions(Builder builder) { + protected SpannerOptions(Builder builder) { super(SpannerFactory.class, SpannerRpcFactory.class, builder, new SpannerDefaults()); - numChannels = builder.numChannels; + numChannels = builder.numChannels == null ? DEFAULT_CHANNELS : builder.numChannels; Preconditions.checkArgument( numChannels >= 1 && numChannels <= MAX_CHANNELS, "Number of channels must fall in the range [1, %s], found: %s", @@ -631,6 +632,7 @@ private SpannerOptions(Builder builder) { leaderAwareRoutingEnabled = builder.leaderAwareRoutingEnabled; attemptDirectPath = builder.attemptDirectPath; directedReadOptions = builder.directedReadOptions; + useVirtualThreads = builder.useVirtualThreads; } /** @@ -734,12 +736,13 @@ public static class Builder private boolean leaderAwareRoutingEnabled = true; private boolean attemptDirectPath = true; private DirectedReadOptions directedReadOptions; + private boolean useVirtualThreads = false; private static String createCustomClientLibToken(String token) { return token + " " + ServiceOptions.getGoogApiClientLibName(); } - private Builder() { + protected Builder() { // Manually set retry and polling settings that work. OperationTimedPollAlgorithm longRunningPollingAlgorithm = OperationTimedPollAlgorithm.create( @@ -795,6 +798,7 @@ private Builder() { this.interceptorProvider = options.interceptorProvider; this.attemptDirectPath = options.attemptDirectPath; this.directedReadOptions = options.directedReadOptions; + this.useVirtualThreads = options.useVirtualThreads; } @Override @@ -1263,6 +1267,16 @@ public Builder disableDirectPath() { return this; } + /** + * Enables/disables the use of virtual threads for the gRPC executor. Setting this option only + * has any effect on Java 21 and higher. In all other cases, the option will be ignored. + */ + @BetaApi + protected Builder setUseVirtualThreads(boolean useVirtualThreads) { + this.useVirtualThreads = useVirtualThreads; + return this; + } + @SuppressWarnings("rawtypes") @Override public SpannerOptions build() { @@ -1412,6 +1426,11 @@ public boolean isAttemptDirectPath() { return attemptDirectPath; } + @BetaApi + public boolean isUseVirtualThreads() { + return useVirtualThreads; + } + /** Returns the default query options to use for the specific database. */ public QueryOptions getDefaultQueryOptions(DatabaseId databaseId) { // Use the specific query options for the database if any have been specified. These have diff --git a/google-cloud-spanner/src/main/java/com/google/cloud/spanner/ThreadFactoryUtil.java b/google-cloud-spanner/src/main/java/com/google/cloud/spanner/ThreadFactoryUtil.java new file mode 100644 index 00000000000..67f4d3230d4 --- /dev/null +++ b/google-cloud-spanner/src/main/java/com/google/cloud/spanner/ThreadFactoryUtil.java @@ -0,0 +1,99 @@ +/* + * Copyright 2024 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.google.cloud.spanner; + +import com.google.api.core.InternalApi; +import com.google.common.util.concurrent.ThreadFactoryBuilder; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.ThreadFactory; +import javax.annotation.Nullable; + +/** Utility class for creating a thread factory for daemon or virtual threads. */ +@InternalApi +public class ThreadFactoryUtil { + + /** + * Tries to create a thread factory for virtual threads, and otherwise falls back to creating a + * platform thread factory that creates daemon threads. Virtual threads are supported from JDK21. + * + * @param baseNameFormat the base name format for the threads, '-%d' will be appended to the + * actual thread name format + * @param tryVirtualThreads whether to try to use virtual threads if available or not + * @return a {@link ThreadFactory} that produces virtual threads (Java 21 or higher) or platform + * daemon threads + */ + @InternalApi + public static ThreadFactory createVirtualOrPlatformDaemonThreadFactory( + String baseNameFormat, boolean tryVirtualThreads) { + ThreadFactory virtualThreadFactory = + tryVirtualThreads ? tryCreateVirtualThreadFactory(baseNameFormat) : null; + if (virtualThreadFactory != null) { + return virtualThreadFactory; + } + + return new ThreadFactoryBuilder().setDaemon(true).setNameFormat(baseNameFormat + "-%d").build(); + } + + /** + * Tries to create a {@link ThreadFactory} that creates virtual threads. Returns null if virtual + * threads are not supported on this JVM. + */ + @InternalApi + @Nullable + public static ThreadFactory tryCreateVirtualThreadFactory(String baseNameFormat) { + try { + Class threadBuilderClass = Class.forName("java.lang.Thread$Builder"); + Method ofVirtualMethod = Thread.class.getDeclaredMethod("ofVirtual"); + Object virtualBuilder = ofVirtualMethod.invoke(null); + Method nameMethod = threadBuilderClass.getDeclaredMethod("name", String.class, long.class); + virtualBuilder = nameMethod.invoke(virtualBuilder, baseNameFormat + "-", 0); + Method factoryMethod = threadBuilderClass.getDeclaredMethod("factory"); + return (ThreadFactory) factoryMethod.invoke(virtualBuilder); + } catch (ClassNotFoundException | NoSuchMethodException ignore) { + return null; + } catch (InvocationTargetException | IllegalAccessException e) { + throw new RuntimeException(e); + } + } + + /** + * Tries to create an {@link ExecutorService} that creates a new virtual thread for each task that + * it runs. Creating a new virtual thread is the recommended way to create executors using virtual + * threads, instead of creating a pool of virtual threads. Returns null if virtual threads are not + * supported on this JVM. + */ + @InternalApi + @Nullable + public static ExecutorService tryCreateVirtualThreadPerTaskExecutor(String baseNameFormat) { + ThreadFactory factory = tryCreateVirtualThreadFactory(baseNameFormat); + if (factory != null) { + try { + Method newThreadPerTaskExecutorMethod = + Executors.class.getDeclaredMethod("newThreadPerTaskExecutor", ThreadFactory.class); + return (ExecutorService) newThreadPerTaskExecutorMethod.invoke(null, factory); + } catch (NoSuchMethodException ignore) { + return null; + } catch (InvocationTargetException | IllegalAccessException e) { + throw new RuntimeException(e); + } + } + return null; + } +} diff --git a/google-cloud-spanner/src/main/java/com/google/cloud/spanner/connection/ChecksumResultSet.java b/google-cloud-spanner/src/main/java/com/google/cloud/spanner/connection/ChecksumResultSet.java index 24389546669..dc373cf03bd 100644 --- a/google-cloud-spanner/src/main/java/com/google/cloud/spanner/connection/ChecksumResultSet.java +++ b/google-cloud-spanner/src/main/java/com/google/cloud/spanner/connection/ChecksumResultSet.java @@ -39,6 +39,7 @@ import java.math.BigDecimal; import java.util.Objects; import java.util.concurrent.Callable; +import java.util.concurrent.atomic.AtomicLong; /** * {@link ResultSet} implementation that keeps a running checksum that can be used to determine @@ -66,7 +67,7 @@ @VisibleForTesting class ChecksumResultSet extends ReplaceableForwardingResultSet implements RetriableStatement { private final ReadWriteTransaction transaction; - private volatile long numberOfNextCalls; + private final AtomicLong numberOfNextCalls = new AtomicLong(); private final ParsedStatement statement; private final AnalyzeMode analyzeMode; private final QueryOption[] options; @@ -103,7 +104,7 @@ public Boolean call() { if (res) { checksumCalculator.calculateNextChecksum(getCurrentRowAsStruct()); } - numberOfNextCalls++; + numberOfNextCalls.incrementAndGet(); return res; } } @@ -142,7 +143,7 @@ public void retry(AbortedException aborted) throws AbortedException { DirectExecuteResultSet.ofResultSet( transaction.internalExecuteQuery(statement, analyzeMode, options)); boolean next = true; - while (counter < numberOfNextCalls && next) { + while (counter < numberOfNextCalls.get() && next) { transaction .getStatementExecutor() .invokeInterceptors( @@ -169,7 +170,7 @@ public void retry(AbortedException aborted) throws AbortedException { // Check that we have the same number of rows and the same checksum. HashCode newChecksum = newChecksumCalculator.getChecksum(); HashCode currentChecksum = checksumCalculator.getChecksum(); - if (counter == numberOfNextCalls && Objects.equals(newChecksum, currentChecksum)) { + if (counter == numberOfNextCalls.get() && Objects.equals(newChecksum, currentChecksum)) { // Checksum is ok, we only need to replace the delegate result set if it's still open. if (isClosed()) { resultSet.close(); diff --git a/google-cloud-spanner/src/main/java/com/google/cloud/spanner/connection/ConnectionImpl.java b/google-cloud-spanner/src/main/java/com/google/cloud/spanner/connection/ConnectionImpl.java index 9135fc44a54..3e524e4fe92 100644 --- a/google-cloud-spanner/src/main/java/com/google/cloud/spanner/connection/ConnectionImpl.java +++ b/google-cloud-spanner/src/main/java/com/google/cloud/spanner/connection/ConnectionImpl.java @@ -248,7 +248,9 @@ static UnitOfWorkType of(TransactionMode transactionMode) { Preconditions.checkNotNull(options); this.leakedException = options.isTrackConnectionLeaks() ? new LeakedConnectionException() : null; - this.statementExecutor = new StatementExecutor(options.getStatementExecutionInterceptors()); + this.statementExecutor = + new StatementExecutor( + options.isUseVirtualThreads(), options.getStatementExecutionInterceptors()); this.spannerPool = SpannerPool.INSTANCE; this.options = options; this.spanner = spannerPool.getSpanner(options, this); @@ -283,7 +285,8 @@ static UnitOfWorkType of(TransactionMode transactionMode) { BatchClient batchClient) { this.leakedException = options.isTrackConnectionLeaks() ? new LeakedConnectionException() : null; - this.statementExecutor = new StatementExecutor(Collections.emptyList()); + this.statementExecutor = + new StatementExecutor(options.isUseVirtualThreads(), Collections.emptyList()); this.spannerPool = Preconditions.checkNotNull(spannerPool); this.options = Preconditions.checkNotNull(options); this.spanner = spannerPool.getSpanner(options, this); diff --git a/google-cloud-spanner/src/main/java/com/google/cloud/spanner/connection/ConnectionOptions.java b/google-cloud-spanner/src/main/java/com/google/cloud/spanner/connection/ConnectionOptions.java index e8c2855af50..268661aef9c 100644 --- a/google-cloud-spanner/src/main/java/com/google/cloud/spanner/connection/ConnectionOptions.java +++ b/google-cloud-spanner/src/main/java/com/google/cloud/spanner/connection/ConnectionOptions.java @@ -167,6 +167,8 @@ public String[] getValidValues() { static final boolean DEFAULT_AUTOCOMMIT = true; static final boolean DEFAULT_READONLY = false; static final boolean DEFAULT_RETRY_ABORTS_INTERNALLY = true; + static final boolean DEFAULT_USE_VIRTUAL_THREADS = false; + static final boolean DEFAULT_USE_VIRTUAL_GRPC_TRANSPORT_THREADS = false; private static final String DEFAULT_CREDENTIALS = null; private static final String DEFAULT_OAUTH_TOKEN = null; private static final String DEFAULT_MIN_SESSIONS = null; @@ -204,6 +206,11 @@ public String[] getValidValues() { public static final String ROUTE_TO_LEADER_PROPERTY_NAME = "routeToLeader"; /** Name of the 'retry aborts internally' connection property. */ public static final String RETRY_ABORTS_INTERNALLY_PROPERTY_NAME = "retryAbortsInternally"; + /** Name of the property to enable/disable virtual threads for the statement executor. */ + public static final String USE_VIRTUAL_THREADS_PROPERTY_NAME = "useVirtualThreads"; + /** Name of the property to enable/disable virtual threads for gRPC transport. */ + public static final String USE_VIRTUAL_GRPC_TRANSPORT_THREADS_PROPERTY_NAME = + "useVirtualGrpcTransportThreads"; /** Name of the 'credentials' connection property. */ public static final String CREDENTIALS_PROPERTY_NAME = "credentials"; /** Name of the 'encodedCredentials' connection property. */ @@ -293,6 +300,16 @@ private static String generateGuardedConnectionPropertyError( RETRY_ABORTS_INTERNALLY_PROPERTY_NAME, "Should the connection automatically retry Aborted errors (true/false)", DEFAULT_RETRY_ABORTS_INTERNALLY), + ConnectionProperty.createBooleanProperty( + USE_VIRTUAL_THREADS_PROPERTY_NAME, + "Use a virtual thread instead of a platform thread for each connection (true/false). " + + "This option only has any effect if the application is running on Java 21 or higher. In all other cases, the option is ignored.", + DEFAULT_USE_VIRTUAL_THREADS), + ConnectionProperty.createBooleanProperty( + USE_VIRTUAL_GRPC_TRANSPORT_THREADS_PROPERTY_NAME, + "Use a virtual thread instead of a platform thread for the gRPC executor (true/false). " + + "This option only has any effect if the application is running on Java 21 or higher. In all other cases, the option is ignored.", + DEFAULT_USE_VIRTUAL_GRPC_TRANSPORT_THREADS), ConnectionProperty.createStringProperty( CREDENTIALS_PROPERTY_NAME, "The location of the credentials file to use for this connection. If neither this property or encoded credentials are set, the connection will use the default Google Cloud credentials for the runtime environment."), @@ -672,6 +689,8 @@ public static Builder newBuilder() { private final boolean readOnly; private final boolean routeToLeader; private final boolean retryAbortsInternally; + private final boolean useVirtualThreads; + private final boolean useVirtualGrpcTransportThreads; private final List statementExecutionInterceptors; private final SpannerOptionsConfigurator configurator; @@ -771,6 +790,8 @@ private ConnectionOptions(Builder builder) { this.readOnly = parseReadOnly(this.uri); this.routeToLeader = parseRouteToLeader(this.uri); this.retryAbortsInternally = parseRetryAbortsInternally(this.uri); + this.useVirtualThreads = parseUseVirtualThreads(this.uri); + this.useVirtualGrpcTransportThreads = parseUseVirtualGrpcTransportThreads(this.uri); this.statementExecutionInterceptors = Collections.unmodifiableList(builder.statementExecutionInterceptors); this.configurator = builder.configurator; @@ -873,6 +894,18 @@ static boolean parseRetryAbortsInternally(String uri) { return value != null ? Boolean.parseBoolean(value) : DEFAULT_RETRY_ABORTS_INTERNALLY; } + @VisibleForTesting + static boolean parseUseVirtualThreads(String uri) { + String value = parseUriProperty(uri, USE_VIRTUAL_THREADS_PROPERTY_NAME); + return value != null ? Boolean.parseBoolean(value) : DEFAULT_USE_VIRTUAL_THREADS; + } + + @VisibleForTesting + static boolean parseUseVirtualGrpcTransportThreads(String uri) { + String value = parseUriProperty(uri, USE_VIRTUAL_GRPC_TRANSPORT_THREADS_PROPERTY_NAME); + return value != null ? Boolean.parseBoolean(value) : DEFAULT_USE_VIRTUAL_GRPC_TRANSPORT_THREADS; + } + @VisibleForTesting static @Nullable String parseCredentials(String uri) { String value = parseUriProperty(uri, CREDENTIALS_PROPERTY_NAME); @@ -1293,6 +1326,16 @@ public boolean isRetryAbortsInternally() { return retryAbortsInternally; } + /** Whether connections should use virtual threads for connection executors. */ + public boolean isUseVirtualThreads() { + return useVirtualThreads; + } + + /** Whether virtual threads should be used for gRPC transport. */ + public boolean isUseVirtualGrpcTransportThreads() { + return useVirtualGrpcTransportThreads; + } + /** Any warnings that were generated while creating the {@link ConnectionOptions} instance. */ @Nullable public String getWarnings() { diff --git a/google-cloud-spanner/src/main/java/com/google/cloud/spanner/connection/ConnectionSpannerOptions.java b/google-cloud-spanner/src/main/java/com/google/cloud/spanner/connection/ConnectionSpannerOptions.java new file mode 100644 index 00000000000..f9d310b69e3 --- /dev/null +++ b/google-cloud-spanner/src/main/java/com/google/cloud/spanner/connection/ConnectionSpannerOptions.java @@ -0,0 +1,48 @@ +/* + * Copyright 2024 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.google.cloud.spanner.connection; + +import com.google.cloud.spanner.SpannerOptions; + +/** + * This class is used for building {@link SpannerOptions} for {@link Connection} instances. It gives + * access to (experimental) properties that are not public in the standard {@link SpannerOptions} + * implementation. + */ +class ConnectionSpannerOptions extends SpannerOptions { + public static Builder newBuilder() { + return new Builder(); + } + + static class Builder extends SpannerOptions.Builder { + Builder() {} + + @Override + protected SpannerOptions.Builder setUseVirtualThreads(boolean useVirtualThreads) { + return super.setUseVirtualThreads(useVirtualThreads); + } + + @Override + public ConnectionSpannerOptions build() { + return new ConnectionSpannerOptions(this); + } + } + + ConnectionSpannerOptions(Builder builder) { + super(builder); + } +} diff --git a/google-cloud-spanner/src/main/java/com/google/cloud/spanner/connection/ReadWriteTransaction.java b/google-cloud-spanner/src/main/java/com/google/cloud/spanner/connection/ReadWriteTransaction.java index a618851ad85..e1fb87e4ade 100644 --- a/google-cloud-spanner/src/main/java/com/google/cloud/spanner/connection/ReadWriteTransaction.java +++ b/google-cloud-spanner/src/main/java/com/google/cloud/spanner/connection/ReadWriteTransaction.java @@ -62,6 +62,7 @@ import java.util.Objects; import java.util.concurrent.Callable; import java.util.concurrent.atomic.AtomicLong; +import java.util.concurrent.locks.ReentrantLock; import java.util.logging.Level; import java.util.logging.Logger; @@ -80,6 +81,7 @@ class ReadWriteTransaction extends AbstractMultiUseTransaction { private static final String MAX_INTERNAL_RETRIES_EXCEEDED = "Internal transaction retry maximum exceeded"; private static final int MAX_INTERNAL_RETRIES = 50; + private final ReentrantLock abortedLock = new ReentrantLock(); private final long transactionId; private final DatabaseClient dbClient; private final TransactionOption[] transactionOptions; @@ -100,7 +102,6 @@ class ReadWriteTransaction extends AbstractMultiUseTransaction { private final List statements = new ArrayList<>(); private final List mutations = new ArrayList<>(); private Timestamp transactionStarted; - final Object abortedLock = new Object(); private static final class RollbackToSavepointException extends Exception {} @@ -772,7 +773,8 @@ public ApiFuture commitAsync(CallType callType) { */ T runWithRetry(Callable callable) throws SpannerException { while (true) { - synchronized (abortedLock) { + abortedLock.lock(); + try { checkAborted(); try { checkRolledBackToSavepoint(); @@ -784,6 +786,8 @@ T runWithRetry(Callable callable) throws SpannerException { } catch (Exception e) { throw SpannerExceptionFactory.asSpannerException(e); } + } finally { + abortedLock.unlock(); } } } @@ -870,6 +874,7 @@ private void handleAborted(AbortedException aborted) { long delay = aborted.getRetryDelayInMillis(); try { if (delay > 0L) { + //noinspection BusyWait Thread.sleep(delay); } } catch (InterruptedException ie) { diff --git a/google-cloud-spanner/src/main/java/com/google/cloud/spanner/connection/SpannerPool.java b/google-cloud-spanner/src/main/java/com/google/cloud/spanner/connection/SpannerPool.java index df7190f11a1..2a5a805c2c7 100644 --- a/google-cloud-spanner/src/main/java/com/google/cloud/spanner/connection/SpannerPool.java +++ b/google-cloud-spanner/src/main/java/com/google/cloud/spanner/connection/SpannerPool.java @@ -22,7 +22,6 @@ import com.google.cloud.spanner.Spanner; import com.google.cloud.spanner.SpannerException; import com.google.cloud.spanner.SpannerExceptionFactory; -import com.google.cloud.spanner.SpannerOptions; import com.google.common.annotations.VisibleForTesting; import com.google.common.base.Function; import com.google.common.base.MoreObjects; @@ -155,6 +154,7 @@ static class SpannerPoolKey { private final String userAgent; private final String databaseRole; private final boolean routeToLeader; + private final boolean useVirtualGrpcTransportThreads; @VisibleForTesting static SpannerPoolKey of(ConnectionOptions options) { @@ -181,6 +181,7 @@ private SpannerPoolKey(ConnectionOptions options) throws IOException { this.usePlainText = options.isUsePlainText(); this.userAgent = options.getUserAgent(); this.routeToLeader = options.isRouteToLeader(); + this.useVirtualGrpcTransportThreads = options.isUseVirtualGrpcTransportThreads(); } @Override @@ -197,7 +198,9 @@ public boolean equals(Object o) { && Objects.equals(this.databaseRole, other.databaseRole) && Objects.equals(this.usePlainText, other.usePlainText) && Objects.equals(this.userAgent, other.userAgent) - && Objects.equals(this.routeToLeader, other.routeToLeader); + && Objects.equals(this.routeToLeader, other.routeToLeader) + && Objects.equals( + this.useVirtualGrpcTransportThreads, other.useVirtualGrpcTransportThreads); } @Override @@ -211,7 +214,8 @@ public int hashCode() { this.usePlainText, this.databaseRole, this.userAgent, - this.routeToLeader); + this.routeToLeader, + this.useVirtualGrpcTransportThreads); } } @@ -332,8 +336,9 @@ private void initialize() { @VisibleForTesting Spanner createSpanner(SpannerPoolKey key, ConnectionOptions options) { - SpannerOptions.Builder builder = SpannerOptions.newBuilder(); + ConnectionSpannerOptions.Builder builder = ConnectionSpannerOptions.newBuilder(); builder + .setUseVirtualThreads(key.useVirtualGrpcTransportThreads) .setClientLibToken(MoreObjects.firstNonNull(key.userAgent, CONNECTION_API_CLIENT_LIB_TOKEN)) .setHost(key.host) .setProjectId(key.projectId) diff --git a/google-cloud-spanner/src/main/java/com/google/cloud/spanner/connection/StatementExecutor.java b/google-cloud-spanner/src/main/java/com/google/cloud/spanner/connection/StatementExecutor.java index 438fc749fdc..f3c93c6dd1c 100644 --- a/google-cloud-spanner/src/main/java/com/google/cloud/spanner/connection/StatementExecutor.java +++ b/google-cloud-spanner/src/main/java/com/google/cloud/spanner/connection/StatementExecutor.java @@ -16,15 +16,17 @@ package com.google.cloud.spanner.connection; +import static com.google.cloud.spanner.connection.ConnectionOptions.DEFAULT_USE_VIRTUAL_THREADS; + import com.google.api.core.ApiFuture; import com.google.api.core.ListenableFutureToApiFuture; +import com.google.cloud.spanner.ThreadFactoryUtil; import com.google.cloud.spanner.connection.AbstractStatementParser.ParsedStatement; import com.google.cloud.spanner.connection.ReadOnlyStalenessUtil.DurationValueGetter; import com.google.common.annotations.VisibleForTesting; import com.google.common.base.Preconditions; import com.google.common.util.concurrent.ListeningExecutorService; import com.google.common.util.concurrent.MoreExecutors; -import com.google.common.util.concurrent.ThreadFactoryBuilder; import com.google.protobuf.Duration; import java.util.Collections; import java.util.List; @@ -130,37 +132,45 @@ org.threeten.bp.Duration asDuration() { } /** - * Use a {@link ThreadFactory} that produces daemon threads and sets recognizable name on the + * Use a {@link ThreadFactory} that produces daemon or virtual threads and sets a recognizable + * name on the threads. + */ + private static final ThreadFactory DEFAULT_VIRTUAL_THREAD_FACTORY = + ThreadFactoryUtil.createVirtualOrPlatformDaemonThreadFactory("connection-executor", true); + /** + * Use a {@link ThreadFactory} that produces daemon threads and sets a recognizable name on the * threads. */ - private static final ThreadFactory THREAD_FACTORY = - new ThreadFactoryBuilder() - .setDaemon(true) - .setNameFormat("connection-executor-%d") - .setThreadFactory(MoreExecutors.platformThreadFactory()) - .build(); + private static final ThreadFactory DEFAULT_DAEMON_THREAD_FACTORY = + ThreadFactoryUtil.createVirtualOrPlatformDaemonThreadFactory("connection-executor", false); /** Creates an {@link ExecutorService} for a {@link StatementExecutor}. */ - private static ListeningExecutorService createExecutorService() { + private static ListeningExecutorService createExecutorService(boolean useVirtualThreads) { return MoreExecutors.listeningDecorator( new ThreadPoolExecutor( - 1, 1, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<>(), THREAD_FACTORY)); + 1, + 1, + 0L, + TimeUnit.MILLISECONDS, + new LinkedBlockingQueue<>(), + useVirtualThreads ? DEFAULT_VIRTUAL_THREAD_FACTORY : DEFAULT_DAEMON_THREAD_FACTORY)); } - private ListeningExecutorService executor = createExecutorService(); + private final ListeningExecutorService executor; /** * Interceptors that should be invoked before or after a statement is executed can be registered - * for a connection. This are added to this list. The interceptors are intended for test usage. + * for a connection. These are added to this list. The interceptors are intended for test usage. */ private final List interceptors; @VisibleForTesting StatementExecutor() { - this.interceptors = Collections.emptyList(); + this(DEFAULT_USE_VIRTUAL_THREADS, Collections.emptyList()); } - StatementExecutor(List interceptors) { + StatementExecutor(boolean useVirtualThreads, List interceptors) { + this.executor = createExecutorService(useVirtualThreads); this.interceptors = Collections.unmodifiableList(interceptors); } @@ -168,15 +178,11 @@ void shutdown() { executor.shutdown(); } - void awaitTermination(long timeout, TimeUnit unit) throws InterruptedException { - executor.awaitTermination(timeout, unit); - } - /** * Shutdown this executor now and do not wait for any statement that is being executed to finish. */ - List shutdownNow() { - return executor.shutdownNow(); + void shutdownNow() { + executor.shutdownNow(); } /** Execute a statement on this {@link StatementExecutor}. */ diff --git a/google-cloud-spanner/src/main/java/com/google/cloud/spanner/spi/v1/GapicSpannerRpc.java b/google-cloud-spanner/src/main/java/com/google/cloud/spanner/spi/v1/GapicSpannerRpc.java index a65e533338f..a8618af5c79 100644 --- a/google-cloud-spanner/src/main/java/com/google/cloud/spanner/spi/v1/GapicSpannerRpc.java +++ b/google-cloud-spanner/src/main/java/com/google/cloud/spanner/spi/v1/GapicSpannerRpc.java @@ -17,6 +17,7 @@ package com.google.cloud.spanner.spi.v1; import static com.google.cloud.spanner.SpannerExceptionFactory.newSpannerException; +import static com.google.cloud.spanner.ThreadFactoryUtil.tryCreateVirtualThreadPerTaskExecutor; import com.google.api.core.ApiFunction; import com.google.api.core.ApiFuture; @@ -202,6 +203,7 @@ import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentMap; import java.util.concurrent.ExecutionException; +import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.Future; import java.util.concurrent.ScheduledExecutorService; @@ -351,7 +353,13 @@ public GapicSpannerRpc(final SpannerOptions options) { options.isAttemptDirectPath() && !Objects.equals( options.getScopedCredentials(), NoCredentials.getInstance())); - + if (options.isUseVirtualThreads()) { + ExecutorService executor = + tryCreateVirtualThreadPerTaskExecutor("spanner-virtual-grpc-executor"); + if (executor != null) { + defaultChannelProviderBuilder.setExecutor(executor); + } + } // If it is enabled in options uses the channel pool provided by the gRPC-GCP extension. maybeEnableGrpcGcpExtension(defaultChannelProviderBuilder, options); diff --git a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/SessionPoolStressTest.java b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/SessionPoolStressTest.java index 61d37145aa4..535423bb9e4 100644 --- a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/SessionPoolStressTest.java +++ b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/SessionPoolStressTest.java @@ -294,6 +294,8 @@ public void stressTest() throws Exception { () -> { while (!stopMaintenance.get()) { runMaintenanceLoop(clock, pool, 1); + // Sleep 1ms between maintenance loops to prevent the long-running session remover + // from stealing all sessions before they can be used. Uninterruptibles.sleepUninterruptibly(1L, TimeUnit.MILLISECONDS); } }) diff --git a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/ThreadFactoryUtilTest.java b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/ThreadFactoryUtilTest.java new file mode 100644 index 00000000000..faf70ff577a --- /dev/null +++ b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/ThreadFactoryUtilTest.java @@ -0,0 +1,76 @@ +/* + * Copyright 2024 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.google.cloud.spanner; + +import static com.google.cloud.spanner.ThreadFactoryUtil.createVirtualOrPlatformDaemonThreadFactory; +import static com.google.cloud.spanner.ThreadFactoryUtil.tryCreateVirtualThreadFactory; +import static com.google.cloud.spanner.ThreadFactoryUtil.tryCreateVirtualThreadPerTaskExecutor; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertTrue; + +import com.google.common.util.concurrent.SettableFuture; +import java.util.concurrent.ThreadFactory; +import java.util.concurrent.TimeUnit; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.JUnit4; + +@RunWith(JUnit4.class) +public class ThreadFactoryUtilTest { + + @Test + public void testCreateThreadFactory() throws Exception { + ThreadFactory threadFactory = createVirtualOrPlatformDaemonThreadFactory("test-thread", true); + assertNotNull(threadFactory); + SettableFuture future = SettableFuture.create(); + Thread thread = threadFactory.newThread(() -> future.set(true)); + assertNotNull(thread); + // Virtual threads are by definition always daemon threads. + assertTrue(thread.isDaemon()); + thread.start(); + assertTrue(future.get(1L, TimeUnit.SECONDS)); + + if (isJava21OrHigher()) { + ThreadFactory virtualFactory = tryCreateVirtualThreadFactory("test-thread"); + assertNotNull(virtualFactory); + assertEquals(virtualFactory.getClass(), threadFactory.getClass()); + } else { + assertNull(tryCreateVirtualThreadFactory("test-thread")); + } + } + + @Test + public void testTryCreateVirtualThreadPerTaskExecutor() { + if (isJava21OrHigher()) { + assertNotNull(tryCreateVirtualThreadPerTaskExecutor("test-virtual-thread")); + } else { + assertNull(tryCreateVirtualThreadPerTaskExecutor("test-virtual-thread")); + } + } + + private static boolean isJava21OrHigher() { + String[] versionElements = System.getProperty("java.version").split("\\."); + int majorVersion = Integer.parseInt(versionElements[0]); + // Java 1.8 (Java 8) and lower used the format 1.8 etc. + // Java 9 and higher use the format 9.x + if (majorVersion == 1) { + majorVersion = Integer.parseInt(versionElements[1]); + } + return majorVersion >= 21; + } +} diff --git a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/connection/ConnectionOptionsTest.java b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/connection/ConnectionOptionsTest.java index ca0b779981f..bdca80a214d 100644 --- a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/connection/ConnectionOptionsTest.java +++ b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/connection/ConnectionOptionsTest.java @@ -1035,4 +1035,56 @@ public void testExternalChannelProvider_WithoutEnablingProperty() throws Throwab .build()); assertEquals(ErrorCode.FAILED_PRECONDITION, exception.getErrorCode()); } + + @Test + public void testUseVirtualThreads() { + assertTrue( + ConnectionOptions.newBuilder() + .setUri( + "cloudspanner:/projects/test-project-123/instances/test-instance/databases/test-database?useVirtualThreads=true") + .setCredentials(NoCredentials.getInstance()) + .build() + .isUseVirtualThreads()); + assertFalse( + ConnectionOptions.newBuilder() + .setUri( + "cloudspanner:/projects/test-project-123/instances/test-instance/databases/test-database?useVirtualThreads=false") + .setCredentials(NoCredentials.getInstance()) + .build() + .isUseVirtualThreads()); + assertEquals( + ConnectionOptions.DEFAULT_USE_VIRTUAL_THREADS, + ConnectionOptions.newBuilder() + .setUri( + "cloudspanner:/projects/test-project-123/instances/test-instance/databases/test-database") + .setCredentials(NoCredentials.getInstance()) + .build() + .isUseVirtualThreads()); + } + + @Test + public void testUseVirtualGrpcTransportThreads() { + assertTrue( + ConnectionOptions.newBuilder() + .setUri( + "cloudspanner:/projects/test-project-123/instances/test-instance/databases/test-database?useVirtualGrpcTransportThreads=true") + .setCredentials(NoCredentials.getInstance()) + .build() + .isUseVirtualGrpcTransportThreads()); + assertFalse( + ConnectionOptions.newBuilder() + .setUri( + "cloudspanner:/projects/test-project-123/instances/test-instance/databases/test-database?useVirtualGrpcTransportThreads=false") + .setCredentials(NoCredentials.getInstance()) + .build() + .isUseVirtualGrpcTransportThreads()); + assertEquals( + ConnectionOptions.DEFAULT_USE_VIRTUAL_GRPC_TRANSPORT_THREADS, + ConnectionOptions.newBuilder() + .setUri( + "cloudspanner:/projects/test-project-123/instances/test-instance/databases/test-database") + .setCredentials(NoCredentials.getInstance()) + .build() + .isUseVirtualThreads()); + } } diff --git a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/connection/SavepointMockServerTest.java b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/connection/SavepointMockServerTest.java index 537617f4a0c..e2ab63b3213 100644 --- a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/connection/SavepointMockServerTest.java +++ b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/connection/SavepointMockServerTest.java @@ -28,6 +28,7 @@ import com.google.cloud.spanner.ResultSet; import com.google.cloud.spanner.SpannerException; import com.google.cloud.spanner.Statement; +import com.google.cloud.spanner.connection.ITAbstractSpannerTest.ITConnection; import com.google.common.base.Strings; import com.google.common.collect.ImmutableList; import com.google.protobuf.AbstractMessage; @@ -36,6 +37,7 @@ import com.google.spanner.v1.ExecuteBatchDmlRequest; import com.google.spanner.v1.ExecuteSqlRequest; import com.google.spanner.v1.RollbackRequest; +import java.util.Collection; import java.util.List; import java.util.stream.Collectors; import org.junit.After; @@ -49,22 +51,51 @@ @RunWith(Parameterized.class) public class SavepointMockServerTest extends AbstractMockServerTest { - @Parameters(name = "dialect = {0}") - public static Object[] data() { - return Dialect.values(); + // This test uses both platform threads and virtual threads (when available). We use specifically + // this test for testing virtual threads, because it relies heavily on the internal checksum retry + // strategy. This is the only significant calculation that is executed by the StatementExecutor + // thread, meaning that this shows that using a virtual thread for those calculations also works. + @Parameters(name = "dialect = {0}, useVirtualThreads = {1}") + public static Collection data() { + ImmutableList.Builder builder = ImmutableList.builder(); + for (Dialect dialect : Dialect.values()) { + for (boolean useVirtualThreads : new boolean[] {true, false}) { + builder.add(new Object[] {dialect, useVirtualThreads}); + } + } + return builder.build(); } - @Parameter public Dialect dialect; + @Parameter(0) + public Dialect dialect; + + @Parameter(1) + public boolean useVirtualThreads; + + private Dialect currentDialect; @Before public void setupDialect() { - mockSpanner.putStatementResult(StatementResult.detectDialectResult(dialect)); + if (currentDialect != dialect) { + // Reset the dialect result. + SpannerPool.closeSpannerPool(); + mockSpanner.putStatementResult(StatementResult.detectDialectResult(dialect)); + currentDialect = dialect; + } } @After public void clearRequests() { mockSpanner.clearRequests(); - SpannerPool.closeSpannerPool(); + } + + @Override + public ITConnection createConnection() { + return createConnection( + ";useVirtualThreads=" + + useVirtualThreads + + ";useVirtualGrpcTransportThreads=" + + useVirtualThreads); } @Test diff --git a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/connection/it/ITTransactionRetryTest.java b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/connection/it/ITTransactionRetryTest.java index 1d7de23cb40..0cf3abda6bf 100644 --- a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/connection/it/ITTransactionRetryTest.java +++ b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/connection/it/ITTransactionRetryTest.java @@ -59,7 +59,10 @@ public class ITTransactionRetryTest extends ITAbstractSpannerTest { @Override protected void appendConnectionUri(StringBuilder uri) { - uri.append(";autocommit=false;retryAbortsInternally=true"); + // This test uses virtual threads when available to verify that the checksum calculation can + // reliably be executed by virtual threads. + uri.append( + ";autocommit=false;retryAbortsInternally=true;useVirtualThreads=true;useVirtualGrpcTransportThreads=true"); } @Override From 32aace18763e3a1352907b5ddc825fa28d28ff40 Mon Sep 17 00:00:00 2001 From: "release-please[bot]" <55107282+release-please[bot]@users.noreply.github.com> Date: Mon, 29 Jan 2024 13:04:15 +0000 Subject: [PATCH 21/21] chore(main): release 6.57.0 (#2782) :robot: I have created a release *beep* *boop* --- ## [6.57.0](https://togithub.com/googleapis/java-spanner/compare/v6.56.0...v6.57.0) (2024-01-29) ### Features * Add FLOAT32 enum to TypeCode ([#2800](https://togithub.com/googleapis/java-spanner/issues/2800)) ([383fea5](https://togithub.com/googleapis/java-spanner/commit/383fea5b5dc434621585a1b5cfd128a01780472a)) * Add support for Proto Columns ([#2779](https://togithub.com/googleapis/java-spanner/issues/2779)) ([30d37dd](https://togithub.com/googleapis/java-spanner/commit/30d37dd80c91b2dffdfee732677607ce028fb8d2)) * **spanner:** Add proto descriptors for proto and enum types in create/update/get database ddl requests ([#2774](https://togithub.com/googleapis/java-spanner/issues/2774)) ([4a906bf](https://togithub.com/googleapis/java-spanner/commit/4a906bf2719c30dcd7371f497a8a28c250db77be)) ### Bug Fixes * Remove google-cloud-spanner-executor from the BOM ([#2844](https://togithub.com/googleapis/java-spanner/issues/2844)) ([655000a](https://togithub.com/googleapis/java-spanner/commit/655000a3b0471b279cbcbe8a4a601337e7274ef8)) ### Dependencies * Update dependency com.google.cloud:google-cloud-shared-dependencies to v3.22.0 ([#2785](https://togithub.com/googleapis/java-spanner/issues/2785)) ([f689f74](https://togithub.com/googleapis/java-spanner/commit/f689f742d8754134523ed0394b9c1b8256adcae2)) * Update dependency com.google.cloud:google-cloud-shared-dependencies to v3.23.0 ([#2801](https://togithub.com/googleapis/java-spanner/issues/2801)) ([95f064f](https://togithub.com/googleapis/java-spanner/commit/95f064f9f60a17de375e532ec6dd78dca0743e79)) ### Documentation * Samples and tests for instance APIs. ([#2768](https://togithub.com/googleapis/java-spanner/issues/2768)) ([88e24c7](https://togithub.com/googleapis/java-spanner/commit/88e24c7a7d046056605a2a824450e0153b339c86)) --- This PR was generated with [Release Please](https://togithub.com/googleapis/release-please). See [documentation](https://togithub.com/googleapis/release-please#release-please). --- CHANGELOG.md | 25 +++++++++++++++++++ google-cloud-spanner-bom/pom.xml | 18 ++++++------- google-cloud-spanner-executor/pom.xml | 4 +-- google-cloud-spanner/pom.xml | 4 +-- .../pom.xml | 4 +-- .../pom.xml | 4 +-- grpc-google-cloud-spanner-executor-v1/pom.xml | 4 +-- grpc-google-cloud-spanner-v1/pom.xml | 4 +-- pom.xml | 20 +++++++-------- .../pom.xml | 4 +-- .../pom.xml | 4 +-- .../pom.xml | 4 +-- proto-google-cloud-spanner-v1/pom.xml | 4 +-- samples/snapshot/pom.xml | 2 +- versions.txt | 20 +++++++-------- 15 files changed, 75 insertions(+), 50 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4c6da056da6..e0d281d6f31 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,30 @@ # Changelog +## [6.57.0](https://github.com/googleapis/java-spanner/compare/v6.56.0...v6.57.0) (2024-01-29) + + +### Features + +* Add FLOAT32 enum to TypeCode ([#2800](https://github.com/googleapis/java-spanner/issues/2800)) ([383fea5](https://github.com/googleapis/java-spanner/commit/383fea5b5dc434621585a1b5cfd128a01780472a)) +* Add support for Proto Columns ([#2779](https://github.com/googleapis/java-spanner/issues/2779)) ([30d37dd](https://github.com/googleapis/java-spanner/commit/30d37dd80c91b2dffdfee732677607ce028fb8d2)) +* **spanner:** Add proto descriptors for proto and enum types in create/update/get database ddl requests ([#2774](https://github.com/googleapis/java-spanner/issues/2774)) ([4a906bf](https://github.com/googleapis/java-spanner/commit/4a906bf2719c30dcd7371f497a8a28c250db77be)) + + +### Bug Fixes + +* Remove google-cloud-spanner-executor from the BOM ([#2844](https://github.com/googleapis/java-spanner/issues/2844)) ([655000a](https://github.com/googleapis/java-spanner/commit/655000a3b0471b279cbcbe8a4a601337e7274ef8)) + + +### Dependencies + +* Update dependency com.google.cloud:google-cloud-shared-dependencies to v3.22.0 ([#2785](https://github.com/googleapis/java-spanner/issues/2785)) ([f689f74](https://github.com/googleapis/java-spanner/commit/f689f742d8754134523ed0394b9c1b8256adcae2)) +* Update dependency com.google.cloud:google-cloud-shared-dependencies to v3.23.0 ([#2801](https://github.com/googleapis/java-spanner/issues/2801)) ([95f064f](https://github.com/googleapis/java-spanner/commit/95f064f9f60a17de375e532ec6dd78dca0743e79)) + + +### Documentation + +* Samples and tests for instance APIs. ([#2768](https://github.com/googleapis/java-spanner/issues/2768)) ([88e24c7](https://github.com/googleapis/java-spanner/commit/88e24c7a7d046056605a2a824450e0153b339c86)) + ## [6.56.0](https://github.com/googleapis/java-spanner/compare/v6.55.0...v6.56.0) (2024-01-05) diff --git a/google-cloud-spanner-bom/pom.xml b/google-cloud-spanner-bom/pom.xml index b155938f9dc..eb873766fa0 100644 --- a/google-cloud-spanner-bom/pom.xml +++ b/google-cloud-spanner-bom/pom.xml @@ -3,7 +3,7 @@ 4.0.0 com.google.cloud google-cloud-spanner-bom - 6.56.1-SNAPSHOT + 6.57.0 pom com.google.cloud @@ -53,43 +53,43 @@ com.google.cloud google-cloud-spanner - 6.56.1-SNAPSHOT + 6.57.0 com.google.cloud google-cloud-spanner test-jar - 6.56.1-SNAPSHOT + 6.57.0 com.google.api.grpc grpc-google-cloud-spanner-v1 - 6.56.1-SNAPSHOT + 6.57.0 com.google.api.grpc grpc-google-cloud-spanner-admin-instance-v1 - 6.56.1-SNAPSHOT + 6.57.0 com.google.api.grpc grpc-google-cloud-spanner-admin-database-v1 - 6.56.1-SNAPSHOT + 6.57.0 com.google.api.grpc proto-google-cloud-spanner-admin-instance-v1 - 6.56.1-SNAPSHOT + 6.57.0 com.google.api.grpc proto-google-cloud-spanner-v1 - 6.56.1-SNAPSHOT + 6.57.0 com.google.api.grpc proto-google-cloud-spanner-admin-database-v1 - 6.56.1-SNAPSHOT + 6.57.0
diff --git a/google-cloud-spanner-executor/pom.xml b/google-cloud-spanner-executor/pom.xml index 094a0933e5b..b7cbf4daf65 100644 --- a/google-cloud-spanner-executor/pom.xml +++ b/google-cloud-spanner-executor/pom.xml @@ -5,14 +5,14 @@ 4.0.0 com.google.cloud google-cloud-spanner-executor - 6.56.1-SNAPSHOT + 6.57.0 jar Google Cloud Spanner Executor com.google.cloud google-cloud-spanner-parent - 6.56.1-SNAPSHOT + 6.57.0 diff --git a/google-cloud-spanner/pom.xml b/google-cloud-spanner/pom.xml index 999f49b77f0..860a10fc46a 100644 --- a/google-cloud-spanner/pom.xml +++ b/google-cloud-spanner/pom.xml @@ -3,7 +3,7 @@ 4.0.0 com.google.cloud google-cloud-spanner - 6.56.1-SNAPSHOT + 6.57.0 jar Google Cloud Spanner https://github.com/googleapis/java-spanner @@ -11,7 +11,7 @@ com.google.cloud google-cloud-spanner-parent - 6.56.1-SNAPSHOT + 6.57.0 google-cloud-spanner diff --git a/grpc-google-cloud-spanner-admin-database-v1/pom.xml b/grpc-google-cloud-spanner-admin-database-v1/pom.xml index 5878efe3231..efcd9b7acba 100644 --- a/grpc-google-cloud-spanner-admin-database-v1/pom.xml +++ b/grpc-google-cloud-spanner-admin-database-v1/pom.xml @@ -4,13 +4,13 @@ 4.0.0 com.google.api.grpc grpc-google-cloud-spanner-admin-database-v1 - 6.56.1-SNAPSHOT + 6.57.0 grpc-google-cloud-spanner-admin-database-v1 GRPC library for grpc-google-cloud-spanner-admin-database-v1 com.google.cloud google-cloud-spanner-parent - 6.56.1-SNAPSHOT + 6.57.0 diff --git a/grpc-google-cloud-spanner-admin-instance-v1/pom.xml b/grpc-google-cloud-spanner-admin-instance-v1/pom.xml index a24a3a237f2..f52e0fc618d 100644 --- a/grpc-google-cloud-spanner-admin-instance-v1/pom.xml +++ b/grpc-google-cloud-spanner-admin-instance-v1/pom.xml @@ -4,13 +4,13 @@ 4.0.0 com.google.api.grpc grpc-google-cloud-spanner-admin-instance-v1 - 6.56.1-SNAPSHOT + 6.57.0 grpc-google-cloud-spanner-admin-instance-v1 GRPC library for grpc-google-cloud-spanner-admin-instance-v1 com.google.cloud google-cloud-spanner-parent - 6.56.1-SNAPSHOT + 6.57.0 diff --git a/grpc-google-cloud-spanner-executor-v1/pom.xml b/grpc-google-cloud-spanner-executor-v1/pom.xml index 905f35a2c95..c77e7989388 100644 --- a/grpc-google-cloud-spanner-executor-v1/pom.xml +++ b/grpc-google-cloud-spanner-executor-v1/pom.xml @@ -4,13 +4,13 @@ 4.0.0 com.google.api.grpc grpc-google-cloud-spanner-executor-v1 - 6.56.1-SNAPSHOT + 6.57.0 grpc-google-cloud-spanner-executor-v1 GRPC library for google-cloud-spanner com.google.cloud google-cloud-spanner-parent - 6.56.1-SNAPSHOT + 6.57.0 diff --git a/grpc-google-cloud-spanner-v1/pom.xml b/grpc-google-cloud-spanner-v1/pom.xml index b76dad98579..7a99b0b5a61 100644 --- a/grpc-google-cloud-spanner-v1/pom.xml +++ b/grpc-google-cloud-spanner-v1/pom.xml @@ -4,13 +4,13 @@ 4.0.0 com.google.api.grpc grpc-google-cloud-spanner-v1 - 6.56.1-SNAPSHOT + 6.57.0 grpc-google-cloud-spanner-v1 GRPC library for grpc-google-cloud-spanner-v1 com.google.cloud google-cloud-spanner-parent - 6.56.1-SNAPSHOT + 6.57.0 diff --git a/pom.xml b/pom.xml index c6542501373..38cd574b29e 100644 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ com.google.cloud google-cloud-spanner-parent pom - 6.56.1-SNAPSHOT + 6.57.0 Google Cloud Spanner Parent https://github.com/googleapis/java-spanner @@ -62,47 +62,47 @@ com.google.api.grpc proto-google-cloud-spanner-admin-instance-v1 - 6.56.1-SNAPSHOT + 6.57.0 com.google.api.grpc proto-google-cloud-spanner-executor-v1 - 6.56.1-SNAPSHOT + 6.57.0 com.google.api.grpc grpc-google-cloud-spanner-executor-v1 - 6.56.1-SNAPSHOT + 6.57.0 com.google.api.grpc proto-google-cloud-spanner-v1 - 6.56.1-SNAPSHOT + 6.57.0 com.google.api.grpc proto-google-cloud-spanner-admin-database-v1 - 6.56.1-SNAPSHOT + 6.57.0 com.google.api.grpc grpc-google-cloud-spanner-v1 - 6.56.1-SNAPSHOT + 6.57.0 com.google.api.grpc grpc-google-cloud-spanner-admin-instance-v1 - 6.56.1-SNAPSHOT + 6.57.0 com.google.api.grpc grpc-google-cloud-spanner-admin-database-v1 - 6.56.1-SNAPSHOT + 6.57.0 com.google.cloud google-cloud-spanner - 6.56.1-SNAPSHOT + 6.57.0 diff --git a/proto-google-cloud-spanner-admin-database-v1/pom.xml b/proto-google-cloud-spanner-admin-database-v1/pom.xml index 58aaca468f9..ba2ef61db7b 100644 --- a/proto-google-cloud-spanner-admin-database-v1/pom.xml +++ b/proto-google-cloud-spanner-admin-database-v1/pom.xml @@ -4,13 +4,13 @@ 4.0.0 com.google.api.grpc proto-google-cloud-spanner-admin-database-v1 - 6.56.1-SNAPSHOT + 6.57.0 proto-google-cloud-spanner-admin-database-v1 PROTO library for proto-google-cloud-spanner-admin-database-v1 com.google.cloud google-cloud-spanner-parent - 6.56.1-SNAPSHOT + 6.57.0 diff --git a/proto-google-cloud-spanner-admin-instance-v1/pom.xml b/proto-google-cloud-spanner-admin-instance-v1/pom.xml index 3cceb9e3471..142ed3179ab 100644 --- a/proto-google-cloud-spanner-admin-instance-v1/pom.xml +++ b/proto-google-cloud-spanner-admin-instance-v1/pom.xml @@ -4,13 +4,13 @@ 4.0.0 com.google.api.grpc proto-google-cloud-spanner-admin-instance-v1 - 6.56.1-SNAPSHOT + 6.57.0 proto-google-cloud-spanner-admin-instance-v1 PROTO library for proto-google-cloud-spanner-admin-instance-v1 com.google.cloud google-cloud-spanner-parent - 6.56.1-SNAPSHOT + 6.57.0 diff --git a/proto-google-cloud-spanner-executor-v1/pom.xml b/proto-google-cloud-spanner-executor-v1/pom.xml index f75db302663..ba0ff626523 100644 --- a/proto-google-cloud-spanner-executor-v1/pom.xml +++ b/proto-google-cloud-spanner-executor-v1/pom.xml @@ -4,13 +4,13 @@ 4.0.0 com.google.api.grpc proto-google-cloud-spanner-executor-v1 - 6.56.1-SNAPSHOT + 6.57.0 proto-google-cloud-spanner-executor-v1 Proto library for google-cloud-spanner com.google.cloud google-cloud-spanner-parent - 6.56.1-SNAPSHOT + 6.57.0 diff --git a/proto-google-cloud-spanner-v1/pom.xml b/proto-google-cloud-spanner-v1/pom.xml index 94c2ea3bba0..922262b8344 100644 --- a/proto-google-cloud-spanner-v1/pom.xml +++ b/proto-google-cloud-spanner-v1/pom.xml @@ -4,13 +4,13 @@ 4.0.0 com.google.api.grpc proto-google-cloud-spanner-v1 - 6.56.1-SNAPSHOT + 6.57.0 proto-google-cloud-spanner-v1 PROTO library for proto-google-cloud-spanner-v1 com.google.cloud google-cloud-spanner-parent - 6.56.1-SNAPSHOT + 6.57.0 diff --git a/samples/snapshot/pom.xml b/samples/snapshot/pom.xml index 1bd0971d430..f518465160d 100644 --- a/samples/snapshot/pom.xml +++ b/samples/snapshot/pom.xml @@ -32,7 +32,7 @@ com.google.cloud google-cloud-spanner - 6.56.1-SNAPSHOT + 6.57.0 diff --git a/versions.txt b/versions.txt index 264eb030ceb..5543d65ee61 100644 --- a/versions.txt +++ b/versions.txt @@ -1,13 +1,13 @@ # Format: # module:released-version:current-version -proto-google-cloud-spanner-admin-instance-v1:6.56.0:6.56.1-SNAPSHOT -proto-google-cloud-spanner-v1:6.56.0:6.56.1-SNAPSHOT -proto-google-cloud-spanner-admin-database-v1:6.56.0:6.56.1-SNAPSHOT -grpc-google-cloud-spanner-v1:6.56.0:6.56.1-SNAPSHOT -grpc-google-cloud-spanner-admin-instance-v1:6.56.0:6.56.1-SNAPSHOT -grpc-google-cloud-spanner-admin-database-v1:6.56.0:6.56.1-SNAPSHOT -google-cloud-spanner:6.56.0:6.56.1-SNAPSHOT -google-cloud-spanner-executor:6.56.0:6.56.1-SNAPSHOT -proto-google-cloud-spanner-executor-v1:6.56.0:6.56.1-SNAPSHOT -grpc-google-cloud-spanner-executor-v1:6.56.0:6.56.1-SNAPSHOT +proto-google-cloud-spanner-admin-instance-v1:6.57.0:6.57.0 +proto-google-cloud-spanner-v1:6.57.0:6.57.0 +proto-google-cloud-spanner-admin-database-v1:6.57.0:6.57.0 +grpc-google-cloud-spanner-v1:6.57.0:6.57.0 +grpc-google-cloud-spanner-admin-instance-v1:6.57.0:6.57.0 +grpc-google-cloud-spanner-admin-database-v1:6.57.0:6.57.0 +google-cloud-spanner:6.57.0:6.57.0 +google-cloud-spanner-executor:6.57.0:6.57.0 +proto-google-cloud-spanner-executor-v1:6.57.0:6.57.0 +grpc-google-cloud-spanner-executor-v1:6.57.0:6.57.0