From 12e31e2fa4177bd6a942bf81cef8b174f136fd5d Mon Sep 17 00:00:00 2001 From: Sri Harsha CH Date: Fri, 17 May 2024 11:47:36 +0000 Subject: [PATCH 1/5] samples(spanner): add sample for Proto columns --- samples/install-without-bom/pom.xml | 5 + samples/snapshot/pom.xml | 5 + .../example/spanner/AddProtoColumnSample.java | 74 ++ .../QueryWithProtoParameterSample.java | 68 + .../java/com/example/spanner/SingerProto.java | 1144 +++++++++++++++++ .../spanner/UpdateProtoDataSample.java | 91 ++ .../UpdateProtoDataSampleUsingDml.java | 94 ++ .../com/example/spanner/descriptors.pb | Bin 0 -> 251 bytes .../example/spanner/ProtoColumnSampleIT.java | 129 ++ 9 files changed, 1610 insertions(+) create mode 100644 samples/snippets/src/main/java/com/example/spanner/AddProtoColumnSample.java create mode 100644 samples/snippets/src/main/java/com/example/spanner/QueryWithProtoParameterSample.java create mode 100644 samples/snippets/src/main/java/com/example/spanner/SingerProto.java create mode 100644 samples/snippets/src/main/java/com/example/spanner/UpdateProtoDataSample.java create mode 100644 samples/snippets/src/main/java/com/example/spanner/UpdateProtoDataSampleUsingDml.java create mode 100644 samples/snippets/src/main/resources/com/example/spanner/descriptors.pb create mode 100644 samples/snippets/src/test/java/com/example/spanner/ProtoColumnSampleIT.java diff --git a/samples/install-without-bom/pom.xml b/samples/install-without-bom/pom.xml index bc846dfdc77..8cef074d4af 100644 --- a/samples/install-without-bom/pom.xml +++ b/samples/install-without-bom/pom.xml @@ -107,6 +107,11 @@ + + + ../snippets/src/main/resources + + org.codehaus.mojo diff --git a/samples/snapshot/pom.xml b/samples/snapshot/pom.xml index edb577d2f8a..ce5d748d5dc 100644 --- a/samples/snapshot/pom.xml +++ b/samples/snapshot/pom.xml @@ -106,6 +106,11 @@ + + + ../snippets/src/main/resources + + org.codehaus.mojo diff --git a/samples/snippets/src/main/java/com/example/spanner/AddProtoColumnSample.java b/samples/snippets/src/main/java/com/example/spanner/AddProtoColumnSample.java new file mode 100644 index 00000000000..7de30c6babe --- /dev/null +++ b/samples/snippets/src/main/java/com/example/spanner/AddProtoColumnSample.java @@ -0,0 +1,74 @@ +/* + * Copyright 2024 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_add_proto_type_columns] + +import com.google.cloud.spanner.Spanner; +import com.google.cloud.spanner.SpannerOptions; +import com.google.cloud.spanner.admin.database.v1.DatabaseAdminClient; +import com.google.common.collect.ImmutableList; +import com.google.protobuf.ByteString; +import com.google.spanner.admin.database.v1.DatabaseName; +import com.google.spanner.admin.database.v1.UpdateDatabaseDdlRequest; +import java.io.IOException; +import java.io.InputStream; +import java.util.concurrent.ExecutionException; + +class AddProtoColumnSample { + + static void addProtoColumn() throws InterruptedException, ExecutionException, IOException { + // TODO(developer): Replace these variables before running the sample. + String projectId = "my-project"; + String instanceId = "my-instance"; + String databaseId = "my-database"; + + addProtoColumn(projectId, instanceId, databaseId); + } + + static void addProtoColumn(String projectId, String instanceId, String databaseId) + throws InterruptedException, ExecutionException, IOException { + InputStream in = + AddProtoColumnSample.class + .getClassLoader() + .getResourceAsStream("com/example/spanner/descriptors.pb"); + try (Spanner spanner = + SpannerOptions.newBuilder().setProjectId(projectId).build().getService(); + DatabaseAdminClient databaseAdminClient = spanner.createDatabaseAdminClient()) { + UpdateDatabaseDdlRequest request = + UpdateDatabaseDdlRequest.newBuilder() + .setDatabase(DatabaseName.of(projectId, instanceId, databaseId).toString()) + .addAllStatements( + ImmutableList.of( + "CREATE PROTO BUNDLE (" + + "examples.spanner.music.SingerInfo," + + "examples.spanner.music.Genre," + + ")", + "ALTER TABLE Singers ADD COLUMN SingerInfo examples.spanner.music.SingerInfo", + "ALTER TABLE Singers ADD COLUMN SingerInfoArray ARRAY", + "ALTER TABLE Singers ADD COLUMN SingerGenre examples.spanner.music.Genre", + "ALTER TABLE Singers ADD COLUMN SingerGenreArray ARRAY")) + .setProtoDescriptors(ByteString.readFrom(in)) + .build(); + // Wait for the operation to finish. + // This will throw an ExecutionException if the operation fails. + databaseAdminClient.updateDatabaseDdlAsync(request).get(); + System.out.printf("Added Proto columns %n"); + } + } +} +// [END spanner_add_proto_type_columns] diff --git a/samples/snippets/src/main/java/com/example/spanner/QueryWithProtoParameterSample.java b/samples/snippets/src/main/java/com/example/spanner/QueryWithProtoParameterSample.java new file mode 100644 index 00000000000..0a795201c6e --- /dev/null +++ b/samples/snippets/src/main/java/com/example/spanner/QueryWithProtoParameterSample.java @@ -0,0 +1,68 @@ +/* + * Copyright 2024 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_query_with_proto_types_parameter] +import com.example.spanner.SingerProto.Genre; +import com.example.spanner.SingerProto.SingerInfo; +import com.google.cloud.spanner.DatabaseClient; +import com.google.cloud.spanner.DatabaseId; +import com.google.cloud.spanner.ResultSet; +import com.google.cloud.spanner.Spanner; +import com.google.cloud.spanner.SpannerOptions; +import com.google.cloud.spanner.Statement; + +class QueryWithProtoParameterSample { + + static void queryWithProtoParameter() { + // TODO(developer): Replace these variables before running the sample. + String projectId = "my-project"; + String instanceId = "my-instance"; + String databaseId = "my-database"; + + try (Spanner spanner = + SpannerOptions.newBuilder().setProjectId(projectId).build().getService()) { + DatabaseClient client = + spanner.getDatabaseClient(DatabaseId.of(projectId, instanceId, databaseId)); + queryWithProtoParameter(client); + } + } + + static void queryWithProtoParameter(DatabaseClient client) { + Statement statement = + Statement.newBuilder( + "SELECT SingerId, SingerInfo, SingerInfo.nationality, SingerInfoArray, SingerGenre, SingerGenreArray FROM Singers WHERE SingerInfo.nationality=@country and SingerGenre=@singerGenre") + .bind("country") + .to("Country2") + .bind("singerGenre") + .to(Genre.FOLK) + .build(); + try (ResultSet resultSet = client.singleUse().executeQuery(statement)) { + while (resultSet.next()) { + System.out.printf( + "%d %s %s %s %s %s%n", + resultSet.getLong("SingerId"), + resultSet.getProtoMessage("SingerInfo", SingerInfo.getDefaultInstance()), + resultSet.getString("nationality"), + resultSet.getProtoMessageList("SingerInfoArray", SingerInfo.getDefaultInstance()), + resultSet.getProtoEnum("SingerGenre", Genre::forNumber), + resultSet.getProtoEnumList("SingerGenreArray", Genre::forNumber)); + } + } + } +} +// [END spanner_query_with_proto_types_parameter] diff --git a/samples/snippets/src/main/java/com/example/spanner/SingerProto.java b/samples/snippets/src/main/java/com/example/spanner/SingerProto.java new file mode 100644 index 00000000000..15e5a5e286d --- /dev/null +++ b/samples/snippets/src/main/java/com/example/spanner/SingerProto.java @@ -0,0 +1,1144 @@ +// Generated by the protocol buffer compiler. DO NOT EDIT! +// source: singer.proto + +package com.example.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 examples.spanner.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. + */ + @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 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 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:examples.spanner.music.Genre) + } + + public interface SingerInfoOrBuilder + extends + // @@protoc_insertion_point(interface_extends:examples.spanner.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. + */ + 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. + */ + String getNationality(); + /** + * optional string nationality = 3; + * + * @return The bytes for nationality. + */ + com.google.protobuf.ByteString getNationalityBytes(); + + /** + * optional .examples.spanner.music.Genre genre = 4; + * + * @return Whether the genre field is set. + */ + boolean hasGenre(); + /** + * optional .examples.spanner.music.Genre genre = 4; + * + * @return The genre. + */ + Genre getGenre(); + } + /** Protobuf type {@code examples.spanner.music.SingerInfo} */ + public static final class SingerInfo extends com.google.protobuf.GeneratedMessageV3 + implements + // @@protoc_insertion_point(message_implements:examples.spanner.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; + } + + @Override + @SuppressWarnings({"unused"}) + protected Object newInstance(UnusedPrivateParameter unused) { + return new SingerInfo(); + } + + @Override + public final com.google.protobuf.UnknownFieldSet getUnknownFields() { + return this.unknownFields; + } + + public static final com.google.protobuf.Descriptors.Descriptor getDescriptor() { + return SingerProto.internal_static_examples_spanner_music_SingerInfo_descriptor; + } + + @Override + protected FieldAccessorTable internalGetFieldAccessorTable() { + return SingerProto.internal_static_examples_spanner_music_SingerInfo_fieldAccessorTable + .ensureFieldAccessorsInitialized(SingerInfo.class, Builder.class); + } + + private int bitField0_; + public static final int SINGER_ID_FIELD_NUMBER = 1; + private long singerId_ = 0L; + /** + * optional int64 singer_id = 1; + * + * @return Whether the singerId field is set. + */ + @Override + public boolean hasSingerId() { + return ((bitField0_ & 0x00000001) != 0); + } + /** + * optional int64 singer_id = 1; + * + * @return The singerId. + */ + @Override + public long getSingerId() { + return singerId_; + } + + public static final int BIRTH_DATE_FIELD_NUMBER = 2; + + @SuppressWarnings("serial") + private volatile Object birthDate_ = ""; + /** + * optional string birth_date = 2; + * + * @return Whether the birthDate field is set. + */ + @Override + public boolean hasBirthDate() { + return ((bitField0_ & 0x00000002) != 0); + } + /** + * optional string birth_date = 2; + * + * @return The birthDate. + */ + @Override + public String getBirthDate() { + Object ref = birthDate_; + if (ref instanceof String) { + return (String) ref; + } else { + com.google.protobuf.ByteString bs = (com.google.protobuf.ByteString) ref; + String s = bs.toStringUtf8(); + if (bs.isValidUtf8()) { + birthDate_ = s; + } + return s; + } + } + /** + * optional string birth_date = 2; + * + * @return The bytes for birthDate. + */ + @Override + public com.google.protobuf.ByteString getBirthDateBytes() { + Object ref = birthDate_; + if (ref instanceof String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8((String) ref); + birthDate_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + + public static final int NATIONALITY_FIELD_NUMBER = 3; + + @SuppressWarnings("serial") + private volatile Object nationality_ = ""; + /** + * optional string nationality = 3; + * + * @return Whether the nationality field is set. + */ + @Override + public boolean hasNationality() { + return ((bitField0_ & 0x00000004) != 0); + } + /** + * optional string nationality = 3; + * + * @return The nationality. + */ + @Override + public String getNationality() { + Object ref = nationality_; + if (ref instanceof String) { + return (String) ref; + } else { + com.google.protobuf.ByteString bs = (com.google.protobuf.ByteString) ref; + String s = bs.toStringUtf8(); + if (bs.isValidUtf8()) { + nationality_ = s; + } + return s; + } + } + /** + * optional string nationality = 3; + * + * @return The bytes for nationality. + */ + @Override + public com.google.protobuf.ByteString getNationalityBytes() { + Object ref = nationality_; + if (ref instanceof String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8((String) ref); + nationality_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + + public static final int GENRE_FIELD_NUMBER = 4; + private int genre_ = 0; + /** + * optional .examples.spanner.music.Genre genre = 4; + * + * @return Whether the genre field is set. + */ + @Override + public boolean hasGenre() { + return ((bitField0_ & 0x00000008) != 0); + } + /** + * optional .examples.spanner.music.Genre genre = 4; + * + * @return The genre. + */ + @Override + public Genre getGenre() { + Genre result = Genre.forNumber(genre_); + return result == null ? Genre.POP : result; + } + + private byte memoizedIsInitialized = -1; + + @Override + public final boolean isInitialized() { + byte isInitialized = memoizedIsInitialized; + if (isInitialized == 1) return true; + if (isInitialized == 0) return false; + + memoizedIsInitialized = 1; + return true; + } + + @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_); + } + getUnknownFields().writeTo(output); + } + + @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 += getUnknownFields().getSerializedSize(); + memoizedSize = size; + return size; + } + + @Override + public boolean equals(final Object obj) { + if (obj == this) { + return true; + } + if (!(obj instanceof SingerInfo)) { + return super.equals(obj); + } + SingerInfo other = (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 (!getUnknownFields().equals(other.getUnknownFields())) return false; + return true; + } + + @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) + getUnknownFields().hashCode(); + memoizedHashCode = hash; + return hash; + } + + public static SingerInfo parseFrom(java.nio.ByteBuffer data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + + public static SingerInfo parseFrom( + java.nio.ByteBuffer data, com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + + public static SingerInfo parseFrom(com.google.protobuf.ByteString data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + + public static SingerInfo parseFrom( + com.google.protobuf.ByteString data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + + public static SingerInfo parseFrom(byte[] data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + + public static SingerInfo parseFrom( + byte[] data, com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + + public static SingerInfo parseFrom(java.io.InputStream input) throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3.parseWithIOException(PARSER, input); + } + + public static 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 SingerInfo parseDelimitedFrom(java.io.InputStream input) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3.parseDelimitedWithIOException(PARSER, input); + } + + public static 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 SingerInfo parseFrom(com.google.protobuf.CodedInputStream input) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3.parseWithIOException(PARSER, input); + } + + public static 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); + } + + @Override + public Builder newBuilderForType() { + return newBuilder(); + } + + public static Builder newBuilder() { + return DEFAULT_INSTANCE.toBuilder(); + } + + public static Builder newBuilder(SingerInfo prototype) { + return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype); + } + + @Override + public Builder toBuilder() { + return this == DEFAULT_INSTANCE ? new Builder() : new Builder().mergeFrom(this); + } + + @Override + protected Builder newBuilderForType(BuilderParent parent) { + Builder builder = new Builder(parent); + return builder; + } + /** Protobuf type {@code examples.spanner.music.SingerInfo} */ + public static final class Builder + extends com.google.protobuf.GeneratedMessageV3.Builder + implements + // @@protoc_insertion_point(builder_implements:examples.spanner.music.SingerInfo) + SingerInfoOrBuilder { + public static final com.google.protobuf.Descriptors.Descriptor getDescriptor() { + return SingerProto.internal_static_examples_spanner_music_SingerInfo_descriptor; + } + + @Override + protected FieldAccessorTable internalGetFieldAccessorTable() { + return SingerProto.internal_static_examples_spanner_music_SingerInfo_fieldAccessorTable + .ensureFieldAccessorsInitialized(SingerInfo.class, Builder.class); + } + + // Construct using com.example.spanner.SingerProto.SingerInfo.newBuilder() + private Builder() {} + + private Builder(BuilderParent parent) { + super(parent); + } + + @Override + public Builder clear() { + super.clear(); + bitField0_ = 0; + singerId_ = 0L; + birthDate_ = ""; + nationality_ = ""; + genre_ = 0; + return this; + } + + @Override + public com.google.protobuf.Descriptors.Descriptor getDescriptorForType() { + return SingerProto.internal_static_examples_spanner_music_SingerInfo_descriptor; + } + + @Override + public SingerInfo getDefaultInstanceForType() { + return SingerInfo.getDefaultInstance(); + } + + @Override + public SingerInfo build() { + SingerInfo result = buildPartial(); + if (!result.isInitialized()) { + throw newUninitializedMessageException(result); + } + return result; + } + + @Override + public SingerInfo buildPartial() { + SingerInfo result = new SingerInfo(this); + if (bitField0_ != 0) { + buildPartial0(result); + } + onBuilt(); + return result; + } + + private void buildPartial0(SingerInfo result) { + int from_bitField0_ = bitField0_; + int to_bitField0_ = 0; + if (((from_bitField0_ & 0x00000001) != 0)) { + result.singerId_ = singerId_; + to_bitField0_ |= 0x00000001; + } + if (((from_bitField0_ & 0x00000002) != 0)) { + result.birthDate_ = birthDate_; + to_bitField0_ |= 0x00000002; + } + if (((from_bitField0_ & 0x00000004) != 0)) { + result.nationality_ = nationality_; + to_bitField0_ |= 0x00000004; + } + if (((from_bitField0_ & 0x00000008) != 0)) { + result.genre_ = genre_; + to_bitField0_ |= 0x00000008; + } + result.bitField0_ |= to_bitField0_; + } + + @Override + public Builder clone() { + return super.clone(); + } + + @Override + public Builder setField(com.google.protobuf.Descriptors.FieldDescriptor field, Object value) { + return super.setField(field, value); + } + + @Override + public Builder clearField(com.google.protobuf.Descriptors.FieldDescriptor field) { + return super.clearField(field); + } + + @Override + public Builder clearOneof(com.google.protobuf.Descriptors.OneofDescriptor oneof) { + return super.clearOneof(oneof); + } + + @Override + public Builder setRepeatedField( + com.google.protobuf.Descriptors.FieldDescriptor field, int index, Object value) { + return super.setRepeatedField(field, index, value); + } + + @Override + public Builder addRepeatedField( + com.google.protobuf.Descriptors.FieldDescriptor field, Object value) { + return super.addRepeatedField(field, value); + } + + @Override + public Builder mergeFrom(com.google.protobuf.Message other) { + if (other instanceof SingerInfo) { + return mergeFrom((SingerInfo) other); + } else { + super.mergeFrom(other); + return this; + } + } + + public Builder mergeFrom(SingerInfo other) { + if (other == SingerInfo.getDefaultInstance()) return this; + if (other.hasSingerId()) { + setSingerId(other.getSingerId()); + } + if (other.hasBirthDate()) { + birthDate_ = other.birthDate_; + bitField0_ |= 0x00000002; + onChanged(); + } + if (other.hasNationality()) { + nationality_ = other.nationality_; + bitField0_ |= 0x00000004; + onChanged(); + } + if (other.hasGenre()) { + setGenre(other.getGenre()); + } + this.mergeUnknownFields(other.getUnknownFields()); + onChanged(); + return this; + } + + @Override + public final boolean isInitialized() { + return true; + } + + @Override + public Builder mergeFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + if (extensionRegistry == null) { + throw new NullPointerException(); + } + try { + boolean done = false; + while (!done) { + int tag = input.readTag(); + switch (tag) { + case 0: + done = true; + break; + case 8: + { + singerId_ = input.readInt64(); + bitField0_ |= 0x00000001; + break; + } // case 8 + case 18: + { + birthDate_ = input.readBytes(); + bitField0_ |= 0x00000002; + break; + } // case 18 + case 26: + { + nationality_ = input.readBytes(); + bitField0_ |= 0x00000004; + break; + } // case 26 + case 32: + { + int tmpRaw = input.readEnum(); + Genre tmpValue = Genre.forNumber(tmpRaw); + if (tmpValue == null) { + mergeUnknownVarintField(4, tmpRaw); + } else { + genre_ = tmpRaw; + bitField0_ |= 0x00000008; + } + break; + } // case 32 + default: + { + if (!super.parseUnknownField(input, extensionRegistry, tag)) { + done = true; // was an endgroup tag + } + break; + } // default: + } // switch (tag) + } // while (!done) + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + throw e.unwrapIOException(); + } finally { + onChanged(); + } // finally + return this; + } + + private int bitField0_; + + private long singerId_; + /** + * optional int64 singer_id = 1; + * + * @return Whether the singerId field is set. + */ + @Override + public boolean hasSingerId() { + return ((bitField0_ & 0x00000001) != 0); + } + /** + * optional int64 singer_id = 1; + * + * @return The singerId. + */ + @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) { + + singerId_ = value; + bitField0_ |= 0x00000001; + 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 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 String getBirthDate() { + Object ref = birthDate_; + if (!(ref instanceof String)) { + com.google.protobuf.ByteString bs = (com.google.protobuf.ByteString) ref; + String s = bs.toStringUtf8(); + if (bs.isValidUtf8()) { + birthDate_ = s; + } + return s; + } else { + return (String) ref; + } + } + /** + * optional string birth_date = 2; + * + * @return The bytes for birthDate. + */ + public com.google.protobuf.ByteString getBirthDateBytes() { + Object ref = birthDate_; + if (ref instanceof String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8((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(String value) { + if (value == null) { + throw new NullPointerException(); + } + birthDate_ = value; + bitField0_ |= 0x00000002; + onChanged(); + return this; + } + /** + * optional string birth_date = 2; + * + * @return This builder for chaining. + */ + public Builder clearBirthDate() { + birthDate_ = getDefaultInstance().getBirthDate(); + bitField0_ = (bitField0_ & ~0x00000002); + 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(); + } + birthDate_ = value; + bitField0_ |= 0x00000002; + onChanged(); + return this; + } + + private 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 String getNationality() { + Object ref = nationality_; + if (!(ref instanceof String)) { + com.google.protobuf.ByteString bs = (com.google.protobuf.ByteString) ref; + String s = bs.toStringUtf8(); + if (bs.isValidUtf8()) { + nationality_ = s; + } + return s; + } else { + return (String) ref; + } + } + /** + * optional string nationality = 3; + * + * @return The bytes for nationality. + */ + public com.google.protobuf.ByteString getNationalityBytes() { + Object ref = nationality_; + if (ref instanceof String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8((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(String value) { + if (value == null) { + throw new NullPointerException(); + } + nationality_ = value; + bitField0_ |= 0x00000004; + onChanged(); + return this; + } + /** + * optional string nationality = 3; + * + * @return This builder for chaining. + */ + public Builder clearNationality() { + nationality_ = getDefaultInstance().getNationality(); + bitField0_ = (bitField0_ & ~0x00000004); + 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(); + } + nationality_ = value; + bitField0_ |= 0x00000004; + onChanged(); + return this; + } + + private int genre_ = 0; + /** + * optional .examples.spanner.music.Genre genre = 4; + * + * @return Whether the genre field is set. + */ + @Override + public boolean hasGenre() { + return ((bitField0_ & 0x00000008) != 0); + } + /** + * optional .examples.spanner.music.Genre genre = 4; + * + * @return The genre. + */ + @Override + public Genre getGenre() { + Genre result = Genre.forNumber(genre_); + return result == null ? Genre.POP : result; + } + /** + * optional .examples.spanner.music.Genre genre = 4; + * + * @param value The genre to set. + * @return This builder for chaining. + */ + public Builder setGenre(Genre value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000008; + genre_ = value.getNumber(); + onChanged(); + return this; + } + /** + * optional .examples.spanner.music.Genre genre = 4; + * + * @return This builder for chaining. + */ + public Builder clearGenre() { + bitField0_ = (bitField0_ & ~0x00000008); + genre_ = 0; + onChanged(); + return this; + } + + @Override + public final Builder setUnknownFields( + final com.google.protobuf.UnknownFieldSet unknownFields) { + return super.setUnknownFields(unknownFields); + } + + @Override + public final Builder mergeUnknownFields( + final com.google.protobuf.UnknownFieldSet unknownFields) { + return super.mergeUnknownFields(unknownFields); + } + + // @@protoc_insertion_point(builder_scope:examples.spanner.music.SingerInfo) + } + + // @@protoc_insertion_point(class_scope:examples.spanner.music.SingerInfo) + private static final SingerInfo DEFAULT_INSTANCE; + + static { + DEFAULT_INSTANCE = new SingerInfo(); + } + + public static SingerInfo getDefaultInstance() { + return DEFAULT_INSTANCE; + } + + @Deprecated + public static final com.google.protobuf.Parser PARSER = + new com.google.protobuf.AbstractParser() { + @Override + public SingerInfo parsePartialFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + Builder builder = newBuilder(); + try { + builder.mergeFrom(input, extensionRegistry); + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + throw e.setUnfinishedMessage(builder.buildPartial()); + } catch (com.google.protobuf.UninitializedMessageException e) { + throw e.asInvalidProtocolBufferException() + .setUnfinishedMessage(builder.buildPartial()); + } catch (java.io.IOException e) { + throw new com.google.protobuf.InvalidProtocolBufferException(e) + .setUnfinishedMessage(builder.buildPartial()); + } + return builder.buildPartial(); + } + }; + + public static com.google.protobuf.Parser parser() { + return PARSER; + } + + @Override + public com.google.protobuf.Parser getParserForType() { + return PARSER; + } + + @Override + public SingerInfo getDefaultInstanceForType() { + return DEFAULT_INSTANCE; + } + } + + private static final com.google.protobuf.Descriptors.Descriptor + internal_static_examples_spanner_music_SingerInfo_descriptor; + private static final com.google.protobuf.GeneratedMessageV3.FieldAccessorTable + internal_static_examples_spanner_music_SingerInfo_fieldAccessorTable; + + public static com.google.protobuf.Descriptors.FileDescriptor getDescriptor() { + return descriptor; + } + + private static com.google.protobuf.Descriptors.FileDescriptor descriptor; + + static { + String[] descriptorData = { + "\n\014singer.proto\022\026examples.spanner.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.examples.spanner.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\023com.example.spannerB\013SingerPro" + + "toP\000" + }; + descriptor = + com.google.protobuf.Descriptors.FileDescriptor.internalBuildGeneratedFileFrom( + descriptorData, new com.google.protobuf.Descriptors.FileDescriptor[] {}); + internal_static_examples_spanner_music_SingerInfo_descriptor = + getDescriptor().getMessageTypes().get(0); + internal_static_examples_spanner_music_SingerInfo_fieldAccessorTable = + new com.google.protobuf.GeneratedMessageV3.FieldAccessorTable( + internal_static_examples_spanner_music_SingerInfo_descriptor, + new String[] { + "SingerId", "BirthDate", "Nationality", "Genre", + }); + } + + // @@protoc_insertion_point(outer_class_scope) +} diff --git a/samples/snippets/src/main/java/com/example/spanner/UpdateProtoDataSample.java b/samples/snippets/src/main/java/com/example/spanner/UpdateProtoDataSample.java new file mode 100644 index 00000000000..37712a27dc3 --- /dev/null +++ b/samples/snippets/src/main/java/com/example/spanner/UpdateProtoDataSample.java @@ -0,0 +1,91 @@ +/* + * Copyright 2024 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_update_data_with_proto_types] + +import com.example.spanner.SingerProto.Genre; +import com.example.spanner.SingerProto.SingerInfo; +import com.google.cloud.spanner.DatabaseClient; +import com.google.cloud.spanner.DatabaseId; +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 com.google.protobuf.AbstractMessage; +import com.google.protobuf.ProtocolMessageEnum; +import java.util.Collections; +import java.util.List; + +class UpdateProtoDataSample { + + static void updateProtoData() { + // TODO(developer): Replace these variables before running the sample. + String projectId = "my-project"; + String instanceId = "my-instance"; + String databaseId = "my-database"; + + try (Spanner spanner = + SpannerOptions.newBuilder().setProjectId(projectId).build().getService()) { + DatabaseClient client = + spanner.getDatabaseClient(DatabaseId.of(projectId, instanceId, databaseId)); + updateProtoData(client); + } + } + + static void updateProtoData(DatabaseClient client) { + SingerInfo singerInfo = + SingerInfo.newBuilder() + .setSingerId(2) + .setBirthDate("February") + .setNationality("Country2") + .setGenre(Genre.FOLK) + .build(); + Genre singerGenre = Genre.FOLK; + List singerInfoList = Collections.singletonList(singerInfo); + List singerGenreList = Collections.singletonList(singerGenre); + + client.write( + ImmutableList.of( + Mutation.newInsertOrUpdateBuilder("Singers") + .set("SingerId") + .to(2L) + .set("SingerInfo") + .to(singerInfo) + .set("SingerInfoArray") + .toProtoMessageArray(singerInfoList, SingerInfo.getDescriptor()) + .set("SingerGenre") + .to(singerGenre) + .set("SingerGenreArray") + .toProtoEnumArray(singerGenreList, Genre.getDescriptor()) + .build(), + Mutation.newInsertOrUpdateBuilder("Singers") + .set("SingerId") + .to(3L) + .set("SingerInfo") + .to(null, SingerInfo.getDescriptor()) + .set("SingerInfoArray") + .toProtoMessageArray(null, SingerInfo.getDescriptor()) + .set("SingerGenre") + .to(null, Genre.getDescriptor()) + .set("SingerGenreArray") + .toProtoEnumArray(null, Genre.getDescriptor()) + .build())); + System.out.println("Data updated"); + } +} +// [END spanner_update_data_with_proto_types] diff --git a/samples/snippets/src/main/java/com/example/spanner/UpdateProtoDataSampleUsingDml.java b/samples/snippets/src/main/java/com/example/spanner/UpdateProtoDataSampleUsingDml.java new file mode 100644 index 00000000000..3d13c981eed --- /dev/null +++ b/samples/snippets/src/main/java/com/example/spanner/UpdateProtoDataSampleUsingDml.java @@ -0,0 +1,94 @@ +/* + * Copyright 2024 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_update_data_with_proto_types_with_dml] + +import com.example.spanner.SingerProto.Genre; +import com.example.spanner.SingerProto.SingerInfo; +import com.google.cloud.spanner.DatabaseClient; +import com.google.cloud.spanner.DatabaseId; +import com.google.cloud.spanner.Spanner; +import com.google.cloud.spanner.SpannerOptions; +import com.google.cloud.spanner.Statement; +import com.google.protobuf.AbstractMessage; +import com.google.protobuf.ProtocolMessageEnum; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; + +class UpdateProtoDataSampleUsingDml { + + static void updateProtoDataUsingDml() { + // TODO(developer): Replace these variables before running the sample. + String projectId = "my-project"; + String instanceId = "my-instance"; + String databaseId = "my-database"; + + try (Spanner spanner = + SpannerOptions.newBuilder().setProjectId(projectId).build().getService()) { + DatabaseClient client = + spanner.getDatabaseClient(DatabaseId.of(projectId, instanceId, databaseId)); + updateProtoDataUsingDml(client); + } + } + + static void updateProtoDataUsingDml(DatabaseClient client) { + SingerInfo singerInfo = + SingerInfo.newBuilder() + .setSingerId(1) + .setBirthDate("January") + .setNationality("Country1") + .setGenre(Genre.ROCK) + .build(); + Genre singerGenre = Genre.ROCK; + List singerInfoList = Collections.singletonList(singerInfo); + List singerGenreList = Collections.singletonList(singerGenre); + + client + .readWriteTransaction() + .run( + transaction -> { + Statement statement1 = + Statement.newBuilder( + "UPDATE Singers SET SingerInfo = @singerInfo, SingerInfoArray=@singerInfoArray, " + + "SingerGenre=@singerGenre, SingerGenreArray=@singerGenreArray WHERE SingerId = 1") + .bind("singerInfo") + .to(singerInfo) + .bind("singerInfoArray") + .toProtoMessageArray(singerInfoList, SingerInfo.getDescriptor()) + .bind("singerGenre") + .to(singerGenre) + .bind("singerGenreArray") + .toProtoEnumArray(singerGenreList, Genre.getDescriptor()) + .build(); + + Statement statement2 = + Statement.newBuilder( + "UPDATE Singers SET SingerInfo.nationality = @singerNationality WHERE SingerId = 1") + .bind("singerNationality") + .to("Country2") + .build(); + + transaction.batchUpdate(Arrays.asList(statement1, statement2)); + return null; + }); + + System.out.println("record(s) updated"); + } +} +// [END spanner_update_data_with_proto_types_with_dml] diff --git a/samples/snippets/src/main/resources/com/example/spanner/descriptors.pb b/samples/snippets/src/main/resources/com/example/spanner/descriptors.pb new file mode 100644 index 0000000000000000000000000000000000000000..d4c018f3a3c21b18f68820eeab130d8195064e81 GIT binary patch literal 251 zcmd=3!N|o^oSB!NTBKJ{lwXoBB$ir{m|KvOTC7)GkeHVT6wfU!&P-OC&&b6U3|8ow zmzFOi&BY1P7N40S!KlEf!5qW^5%5eAlI7w`$}B3$h)+o@NtIv%%5nyAf<;__0zwL0 z+ + AddProtoColumnSample.addProtoColumn( + projectId, instanceId, databaseId.getDatabase())); + assertTrue(out.contains("Added Proto columns")); + + System.out.println("Update data with Proto Columns ..."); + out = runSample(() -> UpdateProtoDataSample.updateProtoData(client)); + assertTrue(out.contains("Data updated")); + + System.out.println("Update data with Proto Columns using DML ..."); + out = runSample(() -> UpdateProtoDataSampleUsingDml.updateProtoDataUsingDml(client)); + assertTrue(out.contains("record(s) updated")); + + System.out.println("Query data with Proto Columns ..."); + out = runSample(() -> QueryWithProtoParameterSample.queryWithProtoParameter(client)); + assertTrue(out.contains("2 singer_id: 2")); + } +} From 039855b248c9eb1df0c6f1c9b62f36674bf97cd9 Mon Sep 17 00:00:00 2001 From: Sri Harsha CH Date: Mon, 20 May 2024 10:45:35 +0000 Subject: [PATCH 2/5] samples(spanner): update proto generated files --- .../resources/com/example/spanner/README.md | 6 ++++++ .../com/example/spanner/singer.proto | 21 +++++++++++++++++++ 2 files changed, 27 insertions(+) create mode 100644 samples/snippets/src/main/resources/com/example/spanner/README.md create mode 100644 samples/snippets/src/main/resources/com/example/spanner/singer.proto diff --git a/samples/snippets/src/main/resources/com/example/spanner/README.md b/samples/snippets/src/main/resources/com/example/spanner/README.md new file mode 100644 index 00000000000..6dc4f7aa59f --- /dev/null +++ b/samples/snippets/src/main/resources/com/example/spanner/README.md @@ -0,0 +1,6 @@ +#### To generate SingerProto.java and descriptors.pb file from singer.proto using `protoc` +```shell +cd samples/snippets/src/main/resources/ +protoc --proto_path=com/example/spanner/ --include_imports --descriptor_set_out=com/example/spanner/descriptors.pb + --java_out=. com/example/spanner/singer.proto +``` diff --git a/samples/snippets/src/main/resources/com/example/spanner/singer.proto b/samples/snippets/src/main/resources/com/example/spanner/singer.proto new file mode 100644 index 00000000000..12b213f3fae --- /dev/null +++ b/samples/snippets/src/main/resources/com/example/spanner/singer.proto @@ -0,0 +1,21 @@ +syntax = "proto3"; + +package examples.spanner.music; + +option java_package = "com.example.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 3dc6add1a05ae01a30393aa92dd9a63f9476c789 Mon Sep 17 00:00:00 2001 From: Sri Harsha CH Date: Mon, 20 May 2024 10:47:03 +0000 Subject: [PATCH 3/5] samples(spanner): update generated files --- .../java/com/example/spanner/SingerProto.java | 107 +++++++++++------- .../com/example/spanner/descriptors.pb | Bin 251 -> 372 bytes 2 files changed, 69 insertions(+), 38 deletions(-) diff --git a/samples/snippets/src/main/java/com/example/spanner/SingerProto.java b/samples/snippets/src/main/java/com/example/spanner/SingerProto.java index 15e5a5e286d..32b86758a64 100644 --- a/samples/snippets/src/main/java/com/example/spanner/SingerProto.java +++ b/samples/snippets/src/main/java/com/example/spanner/SingerProto.java @@ -1,6 +1,7 @@ // Generated by the protocol buffer compiler. DO NOT EDIT! // source: singer.proto +// Protobuf Java Version: 3.25.1 package com.example.spanner; public final class SingerProto { @@ -21,6 +22,7 @@ public enum Genre implements com.google.protobuf.ProtocolMessageEnum { FOLK(2), /** ROCK = 3; */ ROCK(3), + UNRECOGNIZED(-1), ; /** POP = 0; */ @@ -33,6 +35,9 @@ public enum Genre implements com.google.protobuf.ProtocolMessageEnum { public static final int ROCK_VALUE = 3; public final int getNumber() { + if (this == UNRECOGNIZED) { + throw new IllegalArgumentException("Can't get the number of an unknown enum value."); + } return value; } @@ -77,6 +82,9 @@ public Genre findValueByNumber(int number) { }; public final com.google.protobuf.Descriptors.EnumValueDescriptor getValueDescriptor() { + if (this == UNRECOGNIZED) { + throw new IllegalStateException("Can't get the descriptor of an unrecognized enum value."); + } return getDescriptor().getValues().get(ordinal()); } @@ -94,6 +102,9 @@ public static Genre valueOf(com.google.protobuf.Descriptors.EnumValueDescriptor if (desc.getType() != getDescriptor()) { throw new IllegalArgumentException("EnumValueDescriptor is not for this type."); } + if (desc.getIndex() == -1) { + return UNRECOGNIZED; + } return VALUES[desc.getIndex()]; } @@ -168,6 +179,12 @@ public interface SingerInfoOrBuilder * @return Whether the genre field is set. */ boolean hasGenre(); + /** + * optional .examples.spanner.music.Genre genre = 4; + * + * @return The enum numeric value on the wire for genre. + */ + int getGenreValue(); /** * optional .examples.spanner.music.Genre genre = 4; * @@ -198,11 +215,6 @@ protected Object newInstance(UnusedPrivateParameter unused) { return new SingerInfo(); } - @Override - public final com.google.protobuf.UnknownFieldSet getUnknownFields() { - return this.unknownFields; - } - public static final com.google.protobuf.Descriptors.Descriptor getDescriptor() { return SingerProto.internal_static_examples_spanner_music_SingerInfo_descriptor; } @@ -261,9 +273,7 @@ public String getBirthDate() { } else { com.google.protobuf.ByteString bs = (com.google.protobuf.ByteString) ref; String s = bs.toStringUtf8(); - if (bs.isValidUtf8()) { - birthDate_ = s; - } + birthDate_ = s; return s; } } @@ -311,9 +321,7 @@ public String getNationality() { } else { com.google.protobuf.ByteString bs = (com.google.protobuf.ByteString) ref; String s = bs.toStringUtf8(); - if (bs.isValidUtf8()) { - nationality_ = s; - } + nationality_ = s; return s; } } @@ -346,6 +354,15 @@ public com.google.protobuf.ByteString getNationalityBytes() { public boolean hasGenre() { return ((bitField0_ & 0x00000008) != 0); } + /** + * optional .examples.spanner.music.Genre genre = 4; + * + * @return The enum numeric value on the wire for genre. + */ + @Override + public int getGenreValue() { + return genre_; + } /** * optional .examples.spanner.music.Genre genre = 4; * @@ -354,7 +371,7 @@ public boolean hasGenre() { @Override public Genre getGenre() { Genre result = Genre.forNumber(genre_); - return result == null ? Genre.POP : result; + return result == null ? Genre.UNRECOGNIZED : result; } private byte memoizedIsInitialized = -1; @@ -739,26 +756,20 @@ public Builder mergeFrom( } // case 8 case 18: { - birthDate_ = input.readBytes(); + birthDate_ = input.readStringRequireUtf8(); bitField0_ |= 0x00000002; break; } // case 18 case 26: { - nationality_ = input.readBytes(); + nationality_ = input.readStringRequireUtf8(); bitField0_ |= 0x00000004; break; } // case 26 case 32: { - int tmpRaw = input.readEnum(); - Genre tmpValue = Genre.forNumber(tmpRaw); - if (tmpValue == null) { - mergeUnknownVarintField(4, tmpRaw); - } else { - genre_ = tmpRaw; - bitField0_ |= 0x00000008; - } + genre_ = input.readEnum(); + bitField0_ |= 0x00000008; break; } // case 32 default: @@ -843,9 +854,7 @@ public String getBirthDate() { if (!(ref instanceof String)) { com.google.protobuf.ByteString bs = (com.google.protobuf.ByteString) ref; String s = bs.toStringUtf8(); - if (bs.isValidUtf8()) { - birthDate_ = s; - } + birthDate_ = s; return s; } else { return (String) ref; @@ -903,6 +912,7 @@ public Builder setBirthDateBytes(com.google.protobuf.ByteString value) { if (value == null) { throw new NullPointerException(); } + checkByteStringIsUtf8(value); birthDate_ = value; bitField0_ |= 0x00000002; onChanged(); @@ -928,9 +938,7 @@ public String getNationality() { if (!(ref instanceof String)) { com.google.protobuf.ByteString bs = (com.google.protobuf.ByteString) ref; String s = bs.toStringUtf8(); - if (bs.isValidUtf8()) { - nationality_ = s; - } + nationality_ = s; return s; } else { return (String) ref; @@ -988,6 +996,7 @@ public Builder setNationalityBytes(com.google.protobuf.ByteString value) { if (value == null) { throw new NullPointerException(); } + checkByteStringIsUtf8(value); nationality_ = value; bitField0_ |= 0x00000004; onChanged(); @@ -1004,6 +1013,27 @@ public Builder setNationalityBytes(com.google.protobuf.ByteString value) { public boolean hasGenre() { return ((bitField0_ & 0x00000008) != 0); } + /** + * optional .examples.spanner.music.Genre genre = 4; + * + * @return The enum numeric value on the wire for genre. + */ + @Override + public int getGenreValue() { + return genre_; + } + /** + * optional .examples.spanner.music.Genre genre = 4; + * + * @param value The enum numeric value on the wire for genre to set. + * @return This builder for chaining. + */ + public Builder setGenreValue(int value) { + genre_ = value; + bitField0_ |= 0x00000008; + onChanged(); + return this; + } /** * optional .examples.spanner.music.Genre genre = 4; * @@ -1012,7 +1042,7 @@ public boolean hasGenre() { @Override public Genre getGenre() { Genre result = Genre.forNumber(genre_); - return result == null ? Genre.POP : result; + return result == null ? Genre.UNRECOGNIZED : result; } /** * optional .examples.spanner.music.Genre genre = 4; @@ -1067,8 +1097,7 @@ public static SingerInfo getDefaultInstance() { return DEFAULT_INSTANCE; } - @Deprecated - public static final com.google.protobuf.Parser PARSER = + private static final com.google.protobuf.Parser PARSER = new com.google.protobuf.AbstractParser() { @Override public SingerInfo parsePartialFrom( @@ -1119,13 +1148,15 @@ public static com.google.protobuf.Descriptors.FileDescriptor getDescriptor() { static { String[] descriptorData = { - "\n\014singer.proto\022\026examples.spanner.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.examples.spanner.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\023com.example.spannerB\013SingerPro" - + "toP\000" + "\n\014singer.proto\022\026examples.spanner.music\"\301" + + "\001\n\nSingerInfo\022\026\n\tsinger_id\030\001 \001(\003H\000\210\001\001\022\027\n" + + "\nbirth_date\030\002 \001(\tH\001\210\001\001\022\030\n\013nationality\030\003 " + + "\001(\tH\002\210\001\001\0221\n\005genre\030\004 \001(\0162\035.examples.spann" + + "er.music.GenreH\003\210\001\001B\014\n\n_singer_idB\r\n\013_bi" + + "rth_dateB\016\n\014_nationalityB\010\n\006_genre*.\n\005Ge" + + "nre\022\007\n\003POP\020\000\022\010\n\004JAZZ\020\001\022\010\n\004FOLK\020\002\022\010\n\004ROCK" + + "\020\003B$\n\023com.example.spannerB\013SingerProtoP\000" + + "b\006proto3" }; descriptor = com.google.protobuf.Descriptors.FileDescriptor.internalBuildGeneratedFileFrom( diff --git a/samples/snippets/src/main/resources/com/example/spanner/descriptors.pb b/samples/snippets/src/main/resources/com/example/spanner/descriptors.pb index d4c018f3a3c21b18f68820eeab130d8195064e81..dd9cf8d434407f094965b1b7af479836de803d85 100644 GIT binary patch delta 255 zcmey(_=Sm?>m$=dX7&14j9gs7nR)4{MV@(S`9ca@oW)>Xd}fLSqXMG_vj;;E2Sms- zrGt@CNQsLpDYK{~BR(auBvpb5sD#slF^Cf^<^mJ~sZr(P&Py!G%+E{A$t9m-7f delta 149 zcmeyu^qY~H>j&dRX7&2{j9gs7nR)4{MV@(S`9jiMoW)>Xd}fLSqXMG_a}Wnaz%xZi zmWwMXv#2B^J|(dvRe}j9%NfK87I6Uz2q|!J=Ovb8=I15mWR_G)FoWfhg@lZ`SkqJU aic%$5fO33BvU;f#cSth@u}&6bGz9?TFe)?v From ae5b345d37ae4e9b34637a554d050b5b65a1515f Mon Sep 17 00:00:00 2001 From: Sri Harsha CH Date: Mon, 20 May 2024 12:27:07 +0000 Subject: [PATCH 4/5] samples(spanner): update checkstyle config --- samples/snippets/pom.xml | 9 +++++++++ .../example/spanner/AddProtoColumnSample.java | 6 ++++-- .../spanner/QueryWithProtoParameterSample.java | 4 +++- .../java/com/example/spanner/SingerProto.java | 18 +++++++++++++++++- .../spanner/UpdateProtoDataSampleUsingDml.java | 9 ++++++--- 5 files changed, 39 insertions(+), 7 deletions(-) diff --git a/samples/snippets/pom.xml b/samples/snippets/pom.xml index c52316baa78..1a8303cc082 100644 --- a/samples/snippets/pom.xml +++ b/samples/snippets/pom.xml @@ -189,6 +189,15 @@ + + org.apache.maven.plugins + maven-checkstyle-plugin + 3.3.1 + + + **/SingerProto.java + + diff --git a/samples/snippets/src/main/java/com/example/spanner/AddProtoColumnSample.java b/samples/snippets/src/main/java/com/example/spanner/AddProtoColumnSample.java index 7de30c6babe..36be70034f7 100644 --- a/samples/snippets/src/main/java/com/example/spanner/AddProtoColumnSample.java +++ b/samples/snippets/src/main/java/com/example/spanner/AddProtoColumnSample.java @@ -59,9 +59,11 @@ static void addProtoColumn(String projectId, String instanceId, String databaseI + "examples.spanner.music.Genre," + ")", "ALTER TABLE Singers ADD COLUMN SingerInfo examples.spanner.music.SingerInfo", - "ALTER TABLE Singers ADD COLUMN SingerInfoArray ARRAY", + "ALTER TABLE Singers ADD COLUMN " + + "SingerInfoArray ARRAY", "ALTER TABLE Singers ADD COLUMN SingerGenre examples.spanner.music.Genre", - "ALTER TABLE Singers ADD COLUMN SingerGenreArray ARRAY")) + "ALTER TABLE Singers ADD COLUMN " + + "SingerGenreArray ARRAY")) .setProtoDescriptors(ByteString.readFrom(in)) .build(); // Wait for the operation to finish. diff --git a/samples/snippets/src/main/java/com/example/spanner/QueryWithProtoParameterSample.java b/samples/snippets/src/main/java/com/example/spanner/QueryWithProtoParameterSample.java index 0a795201c6e..b700fa341fa 100644 --- a/samples/snippets/src/main/java/com/example/spanner/QueryWithProtoParameterSample.java +++ b/samples/snippets/src/main/java/com/example/spanner/QueryWithProtoParameterSample.java @@ -45,7 +45,9 @@ static void queryWithProtoParameter() { static void queryWithProtoParameter(DatabaseClient client) { Statement statement = Statement.newBuilder( - "SELECT SingerId, SingerInfo, SingerInfo.nationality, SingerInfoArray, SingerGenre, SingerGenreArray FROM Singers WHERE SingerInfo.nationality=@country and SingerGenre=@singerGenre") + "SELECT SingerId, SingerInfo, SingerInfo.nationality, SingerInfoArray, " + + "SingerGenre, SingerGenreArray FROM Singers " + + "WHERE SingerInfo.nationality=@country and SingerGenre=@singerGenre") .bind("country") .to("Country2") .bind("singerGenre") diff --git a/samples/snippets/src/main/java/com/example/spanner/SingerProto.java b/samples/snippets/src/main/java/com/example/spanner/SingerProto.java index 32b86758a64..b962e4bc6b7 100644 --- a/samples/snippets/src/main/java/com/example/spanner/SingerProto.java +++ b/samples/snippets/src/main/java/com/example/spanner/SingerProto.java @@ -1,5 +1,21 @@ +/* + * Copyright 2024 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: singer.proto +// source: samples/snippets/src/main/resources/com/example/spanner/singer.proto // Protobuf Java Version: 3.25.1 package com.example.spanner; diff --git a/samples/snippets/src/main/java/com/example/spanner/UpdateProtoDataSampleUsingDml.java b/samples/snippets/src/main/java/com/example/spanner/UpdateProtoDataSampleUsingDml.java index 3d13c981eed..9b85f774eb7 100644 --- a/samples/snippets/src/main/java/com/example/spanner/UpdateProtoDataSampleUsingDml.java +++ b/samples/snippets/src/main/java/com/example/spanner/UpdateProtoDataSampleUsingDml.java @@ -65,8 +65,10 @@ static void updateProtoDataUsingDml(DatabaseClient client) { transaction -> { Statement statement1 = Statement.newBuilder( - "UPDATE Singers SET SingerInfo = @singerInfo, SingerInfoArray=@singerInfoArray, " - + "SingerGenre=@singerGenre, SingerGenreArray=@singerGenreArray WHERE SingerId = 1") + "UPDATE Singers SET SingerInfo = @singerInfo, " + + "SingerInfoArray=@singerInfoArray, " + + "SingerGenre=@singerGenre, SingerGenreArray=@singerGenreArray " + + "WHERE SingerId = 1") .bind("singerInfo") .to(singerInfo) .bind("singerInfoArray") @@ -79,7 +81,8 @@ static void updateProtoDataUsingDml(DatabaseClient client) { Statement statement2 = Statement.newBuilder( - "UPDATE Singers SET SingerInfo.nationality = @singerNationality WHERE SingerId = 1") + "UPDATE Singers SET SingerInfo.nationality = @singerNationality " + + "WHERE SingerId = 1") .bind("singerNationality") .to("Country2") .build(); From b410e1e1b42fdf0bfca59d5693c2ad7499856a39 Mon Sep 17 00:00:00 2001 From: Owl Bot Date: Mon, 20 May 2024 15:46:57 +0000 Subject: [PATCH 5/5] =?UTF-8?q?=F0=9F=A6=89=20Updates=20from=20OwlBot=20po?= =?UTF-8?q?st-processor?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit See https://github.com/googleapis/repo-automation-bots/blob/main/packages/owl-bot/README.md --- README.md | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index fd69927635d..85322b5c637 100644 --- a/README.md +++ b/README.md @@ -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.38.0') +implementation platform('com.google.cloud:libraries-bom:26.39.0') implementation 'com.google.cloud:google-cloud-spanner' ``` @@ -436,6 +436,7 @@ Samples are in the [`samples/`](https://github.com/googleapis/java-spanner/tree/ | Add Json Column Sample | [source code](https://github.com/googleapis/java-spanner/blob/main/samples/snippets/src/main/java/com/example/spanner/AddJsonColumnSample.java) | [![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/java-spanner&page=editor&open_in_editor=samples/snippets/src/main/java/com/example/spanner/AddJsonColumnSample.java) | | Add Jsonb Column Sample | [source code](https://github.com/googleapis/java-spanner/blob/main/samples/snippets/src/main/java/com/example/spanner/AddJsonbColumnSample.java) | [![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/java-spanner&page=editor&open_in_editor=samples/snippets/src/main/java/com/example/spanner/AddJsonbColumnSample.java) | | Add Numeric Column Sample | [source code](https://github.com/googleapis/java-spanner/blob/main/samples/snippets/src/main/java/com/example/spanner/AddNumericColumnSample.java) | [![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/java-spanner&page=editor&open_in_editor=samples/snippets/src/main/java/com/example/spanner/AddNumericColumnSample.java) | +| Add Proto Column Sample | [source code](https://github.com/googleapis/java-spanner/blob/main/samples/snippets/src/main/java/com/example/spanner/AddProtoColumnSample.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/AddProtoColumnSample.java) | | Alter Sequence Sample | [source code](https://github.com/googleapis/java-spanner/blob/main/samples/snippets/src/main/java/com/example/spanner/AlterSequenceSample.java) | [![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/java-spanner&page=editor&open_in_editor=samples/snippets/src/main/java/com/example/spanner/AlterSequenceSample.java) | | Alter Table With Foreign Key Delete Cascade Sample | [source code](https://github.com/googleapis/java-spanner/blob/main/samples/snippets/src/main/java/com/example/spanner/AlterTableWithForeignKeyDeleteCascadeSample.java) | [![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/java-spanner&page=editor&open_in_editor=samples/snippets/src/main/java/com/example/spanner/AlterTableWithForeignKeyDeleteCascadeSample.java) | | Async Dml Example | [source code](https://github.com/googleapis/java-spanner/blob/main/samples/snippets/src/main/java/com/example/spanner/AsyncDmlExample.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/AsyncDmlExample.java) | @@ -494,10 +495,12 @@ Samples are in the [`samples/`](https://github.com/googleapis/java-spanner/tree/ | Query With Json Parameter Sample | [source code](https://github.com/googleapis/java-spanner/blob/main/samples/snippets/src/main/java/com/example/spanner/QueryWithJsonParameterSample.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/QueryWithJsonParameterSample.java) | | Query With Jsonb Parameter Sample | [source code](https://github.com/googleapis/java-spanner/blob/main/samples/snippets/src/main/java/com/example/spanner/QueryWithJsonbParameterSample.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/QueryWithJsonbParameterSample.java) | | Query With Numeric Parameter Sample | [source code](https://github.com/googleapis/java-spanner/blob/main/samples/snippets/src/main/java/com/example/spanner/QueryWithNumericParameterSample.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/QueryWithNumericParameterSample.java) | +| Query With Proto Parameter Sample | [source code](https://github.com/googleapis/java-spanner/blob/main/samples/snippets/src/main/java/com/example/spanner/QueryWithProtoParameterSample.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/QueryWithProtoParameterSample.java) | | Quickstart Sample | [source code](https://github.com/googleapis/java-spanner/blob/main/samples/snippets/src/main/java/com/example/spanner/QuickstartSample.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/QuickstartSample.java) | | Read Data With Database Role | [source code](https://github.com/googleapis/java-spanner/blob/main/samples/snippets/src/main/java/com/example/spanner/ReadDataWithDatabaseRole.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/ReadDataWithDatabaseRole.java) | | Restore Backup With Encryption Key | [source code](https://github.com/googleapis/java-spanner/blob/main/samples/snippets/src/main/java/com/example/spanner/RestoreBackupWithEncryptionKey.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/RestoreBackupWithEncryptionKey.java) | | Set Max Commit Delay Sample | [source code](https://github.com/googleapis/java-spanner/blob/main/samples/snippets/src/main/java/com/example/spanner/SetMaxCommitDelaySample.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/SetMaxCommitDelaySample.java) | +| Singer Proto | [source code](https://github.com/googleapis/java-spanner/blob/main/samples/snippets/src/main/java/com/example/spanner/SingerProto.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/SingerProto.java) | | Spanner Sample | [source code](https://github.com/googleapis/java-spanner/blob/main/samples/snippets/src/main/java/com/example/spanner/SpannerSample.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/SpannerSample.java) | | Statement Timeout Example | [source code](https://github.com/googleapis/java-spanner/blob/main/samples/snippets/src/main/java/com/example/spanner/StatementTimeoutExample.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/StatementTimeoutExample.java) | | Tag Sample | [source code](https://github.com/googleapis/java-spanner/blob/main/samples/snippets/src/main/java/com/example/spanner/TagSample.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/TagSample.java) | @@ -509,6 +512,8 @@ Samples are in the [`samples/`](https://github.com/googleapis/java-spanner/tree/ | Update Json Data Sample | [source code](https://github.com/googleapis/java-spanner/blob/main/samples/snippets/src/main/java/com/example/spanner/UpdateJsonDataSample.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/UpdateJsonDataSample.java) | | Update Jsonb Data Sample | [source code](https://github.com/googleapis/java-spanner/blob/main/samples/snippets/src/main/java/com/example/spanner/UpdateJsonbDataSample.java) | [![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/java-spanner&page=editor&open_in_editor=samples/snippets/src/main/java/com/example/spanner/UpdateJsonbDataSample.java) | | Update Numeric Data Sample | [source code](https://github.com/googleapis/java-spanner/blob/main/samples/snippets/src/main/java/com/example/spanner/UpdateNumericDataSample.java) | [![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/java-spanner&page=editor&open_in_editor=samples/snippets/src/main/java/com/example/spanner/UpdateNumericDataSample.java) | +| Update Proto Data Sample | [source code](https://github.com/googleapis/java-spanner/blob/main/samples/snippets/src/main/java/com/example/spanner/UpdateProtoDataSample.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/UpdateProtoDataSample.java) | +| Update Proto Data Sample Using Dml | [source code](https://github.com/googleapis/java-spanner/blob/main/samples/snippets/src/main/java/com/example/spanner/UpdateProtoDataSampleUsingDml.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/UpdateProtoDataSampleUsingDml.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) | | Add And Drop Database Role | [source code](https://github.com/googleapis/java-spanner/blob/main/samples/snippets/src/main/java/com/example/spanner/admin/archived/AddAndDropDatabaseRole.java) | [![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/java-spanner&page=editor&open_in_editor=samples/snippets/src/main/java/com/example/spanner/admin/archived/AddAndDropDatabaseRole.java) | | Add Json Column Sample | [source code](https://github.com/googleapis/java-spanner/blob/main/samples/snippets/src/main/java/com/example/spanner/admin/archived/AddJsonColumnSample.java) | [![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/java-spanner&page=editor&open_in_editor=samples/snippets/src/main/java/com/example/spanner/admin/archived/AddJsonColumnSample.java) |