Skip to content

Commit 617120d

Browse files
committed
chore: cleanup
1 parent 4060866 commit 617120d

File tree

4 files changed

+78
-11
lines changed

4 files changed

+78
-11
lines changed

google-cloud-spanner/src/main/java/com/google/cloud/spanner/AbstractResultSet.java

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -716,8 +716,7 @@ protected BigDecimal getBigDecimalInternal(int columnIndex) {
716716

717717
@Override
718718
protected String getStringInternal(int columnIndex) {
719-
Object value = rowData.get(columnIndex);
720-
return value == null ? null : value.toString();
719+
return (String) rowData.get(columnIndex);
721720
}
722721

723722
@Override
@@ -781,8 +780,9 @@ protected Value getValueInternal(int columnIndex) {
781780
case STRUCT:
782781
return Value.struct(isNull ? null : getStructInternal(columnIndex));
783782
case UNRECOGNIZED:
784-
return Value.untyped(
785-
isNull ? NULL_VALUE : (com.google.protobuf.Value) rowData.get(columnIndex));
783+
return Value.unrecognized(
784+
isNull ? NULL_VALUE : (com.google.protobuf.Value) rowData.get(columnIndex),
785+
columnType);
786786
case ARRAY:
787787
final Type elementType = columnType.getArrayElementType();
788788
switch (elementType.getCode()) {

google-cloud-spanner/src/main/java/com/google/cloud/spanner/Value.java

Lines changed: 19 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,16 @@ public abstract class Value implements Serializable {
100100
* @param value the non-null proto value (a {@link NullValue} is allowed)
101101
*/
102102
public static Value untyped(com.google.protobuf.Value value) {
103-
return new UntypedValueImpl(Preconditions.checkNotNull(value));
103+
return new ProtoBackedValueImpl(Preconditions.checkNotNull(value), null);
104+
}
105+
106+
/** Returns a generic Value backed by a protobuf value. This is used for unrecognized types. */
107+
static Value unrecognized(com.google.protobuf.Value value, Type type) {
108+
Preconditions.checkArgument(
109+
type.getCode() == Code.UNRECOGNIZED
110+
|| type.getCode() == Code.ARRAY
111+
&& type.getArrayElementType().getCode() == Code.UNRECOGNIZED);
112+
return new ProtoBackedValueImpl(Preconditions.checkNotNull(value), type);
104113
}
105114

106115
/**
@@ -1101,11 +1110,16 @@ final void checkNotNull() {
11011110
}
11021111
}
11031112

1104-
private static class UntypedValueImpl extends AbstractValue {
1113+
/**
1114+
* This {@link Value} implementation is backed by a generic protobuf Value instance. It is used
1115+
* for untyped Values that are created by users, and for values with an unrecognized types that
1116+
* coming from the backend.
1117+
*/
1118+
private static class ProtoBackedValueImpl extends AbstractValue {
11051119
private final com.google.protobuf.Value value;
11061120

1107-
private UntypedValueImpl(com.google.protobuf.Value value) {
1108-
super(value.hasNullValue(), null);
1121+
private ProtoBackedValueImpl(com.google.protobuf.Value value, @Nullable Type type) {
1122+
super(value.hasNullValue(), type);
11091123
this.value = value;
11101124
}
11111125

@@ -1182,7 +1196,7 @@ com.google.protobuf.Value valueToProto() {
11821196

11831197
@Override
11841198
boolean valueEquals(Value v) {
1185-
return ((UntypedValueImpl) v).value.equals(value);
1199+
return ((ProtoBackedValueImpl) v).value.equals(value);
11861200
}
11871201

11881202
@Override

google-cloud-spanner/src/main/java/com/google/cloud/spanner/ValueBinder.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -97,8 +97,8 @@ public R to(@Nullable String value) {
9797

9898
/**
9999
* Binds to {@code Value.bytes(value)}. Use {@link #to(Value)} in combination with {@link
100-
* Value#bytes(String)} if you already have the value that you want to bind in base64 format. This
101-
* prevents unnecessary decoding and encoding of base64 strings.
100+
* Value#bytesFromBase64(String)} if you already have the value that you want to bind in base64
101+
* format. This prevents unnecessary decoding and encoding of base64 strings.
102102
*/
103103
public R to(@Nullable ByteArray value) {
104104
return handle(Value.bytes(value));

google-cloud-spanner/src/test/java/com/google/cloud/spanner/it/ITWriteTest.java

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,9 @@
2121
import static com.google.cloud.spanner.Type.json;
2222
import static com.google.cloud.spanner.testing.EmulatorSpannerHelper.isUsingEmulator;
2323
import static com.google.common.truth.Truth.assertThat;
24+
import static org.junit.Assert.assertArrayEquals;
2425
import static org.junit.Assert.assertEquals;
26+
import static org.junit.Assert.assertFalse;
2527
import static org.junit.Assert.assertNotNull;
2628
import static org.junit.Assert.fail;
2729
import static org.junit.Assume.assumeFalse;
@@ -42,6 +44,7 @@
4244
import com.google.cloud.spanner.ParallelIntegrationTest;
4345
import com.google.cloud.spanner.ResultSet;
4446
import com.google.cloud.spanner.SpannerException;
47+
import com.google.cloud.spanner.Statement;
4548
import com.google.cloud.spanner.Struct;
4649
import com.google.cloud.spanner.TimestampBound;
4750
import com.google.cloud.spanner.Value;
@@ -52,6 +55,7 @@
5255
import java.math.BigDecimal;
5356
import java.util.ArrayList;
5457
import java.util.Arrays;
58+
import java.util.Base64;
5559
import java.util.Collections;
5660
import java.util.HashMap;
5761
import java.util.List;
@@ -431,6 +435,55 @@ public void writeBytes() {
431435
assertThat(row.getBytes(0)).isEqualTo(data);
432436
}
433437

438+
@Test
439+
public void writeBytesAsString() {
440+
Random random = new Random();
441+
byte[] data = new byte[256];
442+
random.nextBytes(data);
443+
String base64 = Base64.getEncoder().encodeToString(data);
444+
write(baseInsert().set("BytesValue").to(base64).build());
445+
Struct row = readLastRow("BytesValue");
446+
assertFalse(row.isNull(0));
447+
assertArrayEquals(data, row.getBytes(0).toByteArray());
448+
assertEquals(base64, row.getValue(0).getAsString());
449+
}
450+
451+
@Test
452+
public void writeBytesAsStringUsingDml() {
453+
Random random = new Random();
454+
byte[] data = new byte[256];
455+
random.nextBytes(data);
456+
String base64 = Base64.getEncoder().encodeToString(data);
457+
Long updateCount =
458+
client
459+
.readWriteTransaction()
460+
.run(
461+
transaction ->
462+
transaction.executeUpdate(
463+
Statement.newBuilder(
464+
"insert into T (BytesValue, K) values ("
465+
+ queryParamString(1)
466+
+ ", "
467+
+ queryParamString(2)
468+
+ ")")
469+
.bind("p1")
470+
.to(Value.bytesFromBase64(base64))
471+
.bind("p2")
472+
.to(lastKey = uniqueString())
473+
.build()));
474+
assertNotNull(updateCount);
475+
assertEquals(1L, updateCount.longValue());
476+
477+
Struct row = readLastRow("BytesValue");
478+
assertFalse(row.isNull(0));
479+
assertArrayEquals(data, row.getBytes(0).toByteArray());
480+
assertEquals(base64, row.getValue(0).getAsString());
481+
}
482+
483+
String queryParamString(int index) {
484+
return dialect.dialect == Dialect.GOOGLE_STANDARD_SQL ? "@p" + index : "$" + index;
485+
}
486+
434487
@Test
435488
public void writeBytesRandom() {
436489
// Pseudo-random test for byte encoding. We explicitly set a random seed so that multiple

0 commit comments

Comments
 (0)