diff --git a/README.md b/README.md index afe439ac3ec..0ca34109dc3 100644 --- a/README.md +++ b/README.md @@ -56,13 +56,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.19.0' +implementation 'com.google.cloud:google-cloud-spanner:6.19.1' ``` If you are using SBT, add this to your dependencies ```Scala -libraryDependencies += "com.google.cloud" % "google-cloud-spanner" % "6.19.0" +libraryDependencies += "com.google.cloud" % "google-cloud-spanner" % "6.19.1" ``` ## Authentication 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 6143386293d..bc4f224b939 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 @@ -713,6 +713,8 @@ protected Value getValueInternal(int columnIndex) { return Value.float64(isNull ? null : getDoubleInternal(columnIndex)); case STRING: return Value.string(isNull ? null : getStringInternal(columnIndex)); + case JSON: + return Value.json(isNull ? null : getJsonInternal(columnIndex)); case BYTES: return Value.bytes(isNull ? null : getBytesInternal(columnIndex)); case TIMESTAMP: @@ -736,6 +738,8 @@ protected Value getValueInternal(int columnIndex) { return Value.float64Array(isNull ? null : getDoubleListInternal(columnIndex)); case STRING: return Value.stringArray(isNull ? null : getStringListInternal(columnIndex)); + case JSON: + return Value.jsonArray(isNull ? null : getJsonListInternal(columnIndex)); case BYTES: return Value.bytesArray(isNull ? null : getBytesListInternal(columnIndex)); case TIMESTAMP: 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 db9cee56e92..0bbeb36abf0 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 @@ -1151,6 +1151,11 @@ public String getJson() { return value; } + @Override + public String getString() { + return getJson(); + } + @Override void valueToString(StringBuilder b) { if (value.length() > MAX_DEBUG_STRING_LENGTH) { @@ -1587,6 +1592,11 @@ public List getJsonArray() { return value; } + @Override + public List getStringArray() { + return getJsonArray(); + } + @Override void appendElement(StringBuilder b, String element) { b.append(element); 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 a350fe68469..08849274de5 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 @@ -19,6 +19,7 @@ import static com.google.common.testing.SerializableTester.reserializeAndAssert; import static com.google.common.truth.Truth.assertThat; import static com.google.common.truth.Truth.assertWithMessage; +import static org.junit.Assert.assertArrayEquals; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNull; @@ -42,6 +43,7 @@ import java.util.Arrays; import java.util.Collections; import java.util.List; +import java.util.function.Supplier; import org.junit.Test; import org.junit.runner.RunWith; import org.junit.runners.JUnit4; @@ -416,6 +418,7 @@ public void json() { assertEquals(Type.json(), v.getType()); assertFalse(v.isNull()); assertEquals(json, v.getJson()); + assertEquals(json, v.getString()); } @Test @@ -424,12 +427,8 @@ public void jsonNull() { assertEquals(Type.json(), v.getType()); assertTrue(v.isNull()); assertEquals(NULL_STRING, v.toString()); - try { - v.getJson(); - fail("Expected exception"); - } catch (IllegalStateException e) { - assertThat(e.getMessage().contains("null value")); - } + assertThrowsWithMessage(v::getJson, "null value"); + assertThrowsWithMessage(v::getString, "null value"); } @Test @@ -834,8 +833,9 @@ public void jsonArray() { String three = "{\"color\":\"red\",\"value\":\"#f00\"}"; Value v = Value.jsonArray(Arrays.asList(one, two, three)); assertFalse(v.isNull()); - assertThat(v.getJsonArray()).containsExactly(one, two, three).inOrder(); + assertArrayEquals(new String[] {one, two, three}, v.getJsonArray().toArray()); assertEquals("[{},NULL,{\"color\":\"red\",\"value\":\"#f00\"}]", v.toString()); + assertArrayEquals(new String[] {one, two, three}, v.getStringArray().toArray()); } @Test @@ -843,12 +843,8 @@ public void jsonArrayNull() { Value v = Value.jsonArray(null); assertTrue(v.isNull()); assertEquals(NULL_STRING, v.toString()); - try { - v.getJsonArray(); - fail("Expected exception"); - } catch (IllegalStateException e) { - assertThat(e.getMessage().contains("null value")); - } + assertThrowsWithMessage(v::getJsonArray, "null value"); + assertThrowsWithMessage(v::getStringArray, "null value"); } @Test @@ -863,14 +859,9 @@ public void jsonArrayTryGetBytesArray() { } @Test - public void jsonArrayTryGetStringArray() { - Value value = Value.jsonArray(Arrays.asList("{}")); - try { - value.getStringArray(); - fail("Expected exception"); - } catch (IllegalStateException e) { - assertThat(e.getMessage().contains("Expected: ARRAY actual: ARRAY")); - } + public void jsonArrayTryGetFloat64Array() { + Value value = Value.jsonArray(Collections.singletonList("{}")); + assertThrowsWithMessage(value::getFloat64Array, "Expected: ARRAY actual: ARRAY"); } @Test @@ -1810,4 +1801,19 @@ private void writeObject(@SuppressWarnings("unused") java.io.ObjectOutputStream throw new IllegalStateException("Serialization disabled"); } } + + private void assertThrowsWithMessage(Supplier supplier, String message) { + try { + supplier.get(); + fail("Expected exception"); + } catch (Exception e) { + assertTrue( + "Expected exception message to contain: \"" + + message + + "\", actual: \"" + + e.getMessage() + + "\"", + e.getMessage().contains(message)); + } + } } diff --git a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/it/ITResultSetGetValue.java b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/it/ITResultSetGetValue.java index 64220421bf1..e48b2f35fd0 100644 --- a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/it/ITResultSetGetValue.java +++ b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/it/ITResultSetGetValue.java @@ -101,6 +101,7 @@ public static void beforeClass() + "bytes BYTES(MAX)," + "timestamp TIMESTAMP," + "date DATE," + + "json JSON," + "boolArray ARRAY," + "int64Array ARRAY," + "float64Array ARRAY," @@ -108,7 +109,8 @@ public static void beforeClass() + "stringArray ARRAY," + "bytesArray ARRAY," + "timestampArray ARRAY," - + "dateArray ARRAY" + + "dateArray ARRAY," + + "jsonArray ARRAY" + ") PRIMARY KEY (Id)"); googleStandardSQLClient = env.getTestHelper().getDatabaseClient(googleStandardSqlDatabase); if (!EmulatorSpannerHelper.isUsingEmulator()) { @@ -167,6 +169,8 @@ public void testReadNonNullValuesGoogleStandardSQL() { .to(Timestamp.ofTimeSecondsAndNanos(1, 0)) .set("date") .to(Date.fromYearMonthDay(2021, 1, 2)) + .set("json") + .to(Value.json("{\"key\":\"value\"}")) .set("boolArray") .toBoolArray(new boolean[] {false, true}) .set("int64Array") @@ -189,6 +193,8 @@ public void testReadNonNullValuesGoogleStandardSQL() { .toDateArray( Arrays.asList( Date.fromYearMonthDay(2021, 2, 3), Date.fromYearMonthDay(2021, 3, 4))) + .set("jsonArray") + .toJsonArray(Arrays.asList("{\"key1\":\"value1\"}", "{\"key2\":\"value2\"}")) .build())); try (ResultSet resultSet = databaseClient @@ -206,6 +212,7 @@ public void testReadNonNullValuesGoogleStandardSQL() { assertEquals( Value.timestamp(Timestamp.ofTimeSecondsAndNanos(1, 0)), resultSet.getValue("timestamp")); assertEquals(Value.date(Date.fromYearMonthDay(2021, 1, 2)), resultSet.getValue("date")); + assertEquals(Value.json("{\"key\":\"value\"}"), resultSet.getValue("json")); assertEquals(Value.boolArray(new boolean[] {false, true}), resultSet.getValue("boolArray")); assertEquals(Value.int64Array(new long[] {100L, 200L}), resultSet.getValue("int64Array")); assertArrayEquals( @@ -231,6 +238,9 @@ public void testReadNonNullValuesGoogleStandardSQL() { Value.dateArray( Arrays.asList(Date.fromYearMonthDay(2021, 2, 3), Date.fromYearMonthDay(2021, 3, 4))), resultSet.getValue("dateArray")); + assertEquals( + Value.jsonArray(Arrays.asList("{\"key1\":\"value1\"}", "{\"key2\":\"value2\"}")), + resultSet.getValue("jsonArray")); } } @@ -300,6 +310,8 @@ public void testReadNullValuesGoogleStandardSQL() { IllegalStateException.class, () -> resultSet.getValue("timestamp").getTimestamp()); assertTrue(resultSet.getValue("date").isNull()); assertThrows(IllegalStateException.class, () -> resultSet.getValue("date").getDate()); + assertTrue(resultSet.getValue("json").isNull()); + assertThrows(IllegalStateException.class, () -> resultSet.getValue("json").getJson()); assertTrue(resultSet.getValue("boolArray").isNull()); assertThrows( IllegalStateException.class, () -> resultSet.getValue("boolArray").getBoolArray()); @@ -325,6 +337,9 @@ public void testReadNullValuesGoogleStandardSQL() { assertTrue(resultSet.getValue("dateArray").isNull()); assertThrows( IllegalStateException.class, () -> resultSet.getValue("dateArray").getDateArray()); + assertTrue(resultSet.getValue("jsonArray").isNull()); + assertThrows( + IllegalStateException.class, () -> resultSet.getValue("jsonArray").getJsonArray()); } } @@ -379,6 +394,8 @@ public void testReadNullValuesInArrays() { .toTimestampArray(Arrays.asList(null, Timestamp.ofTimeSecondsAndNanos(20, 0))) .set("dateArray") .toDateArray(Arrays.asList(Date.fromYearMonthDay(2021, 2, 3), null)) + .set("jsonArray") + .toJsonArray(Arrays.asList("{\"key1\":\"value1\"}", null)) .build())); try (ResultSet resultSet = @@ -406,6 +423,9 @@ public void testReadNullValuesInArrays() { assertEquals( Value.dateArray(Arrays.asList(Date.fromYearMonthDay(2021, 2, 3), null)), resultSet.getValue("dateArray")); + assertEquals( + Value.jsonArray(Arrays.asList("{\"key1\":\"value1\"}", null)), + resultSet.getValue("jsonArray")); } }