Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: adds getValue to ResultSet #1073

Merged
merged 11 commits into from Apr 25, 2021
13 changes: 13 additions & 0 deletions google-cloud-spanner/clirr-ignored-differences.xml
Expand Up @@ -592,4 +592,17 @@
<className>com/google/cloud/spanner/AsyncTransactionManager$CommitTimestampFuture</className>
<method>java.lang.Object get()</method>
</difference>

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Clirr does not support Java 8 features, so it thinks these are breaking changes, where in fact we have provided default implementations for the added interface methods. No need for a major release here.

<!-- Adds getValue to ResultSet -->
<!-- These are not breaking changes, since we provide default interface implementation -->
<difference>
<differenceType>7012</differenceType>
<className>com/google/cloud/spanner/StructReader</className>
<method>com.google.cloud.spanner.Value getValue(int)</method>
</difference>
<difference>
<differenceType>7012</differenceType>
<className>com/google/cloud/spanner/StructReader</className>
<method>com.google.cloud.spanner.Value getValue(java.lang.String)</method>
</difference>
</differences>

Large diffs are not rendered by default.

Expand Up @@ -49,6 +49,10 @@ public abstract class AbstractStructReader implements StructReader {

protected abstract Date getDateInternal(int columnIndex);

protected Value getValueInternal(int columnIndex) {
throw new UnsupportedOperationException("method should be overwritten");
}

protected abstract boolean[] getBooleanArrayInternal(int columnIndex);

protected abstract List<Boolean> getBooleanListInternal(int columnIndex);
Expand Down Expand Up @@ -197,6 +201,19 @@ public Date getDate(String columnName) {
return getDateInternal(columnIndex);
}

@Override
public Value getValue(int columnIndex) {
checkNonNull(columnIndex, columnIndex);
return getValueInternal(columnIndex);
}

@Override
public Value getValue(String columnName) {
int columnIndex = getColumnIndex(columnName);
checkNonNull(columnIndex, columnName);
return getValueInternal(columnIndex);
}

@Override
public boolean[] getBooleanArray(int columnIndex) {
checkNonNullOfType(columnIndex, Type.array(Type.bool()), columnIndex);
Expand Down
Expand Up @@ -333,4 +333,16 @@ public List<Struct> getStructList(String columnName) {
checkValidState();
return delegate.get().getStructList(columnName);
}

@Override
public Value getValue(int columnIndex) {
checkValidState();
return delegate.get().getValue(columnIndex);
}

@Override
public Value getValue(String columnName) {
checkValidState();
return delegate.get().getValue(columnName);
}
}
Expand Up @@ -273,6 +273,16 @@ public Date getDate(String columnName) {
return getCurrentRowAsStruct().getDate(columnName);
}

@Override
public Value getValue(int columnIndex) {
return getCurrentRowAsStruct().getValue(columnIndex);
}

@Override
public Value getValue(String columnName) {
return getCurrentRowAsStruct().getValue(columnName);
}

@Override
public boolean[] getBooleanArray(int columnIndex) {
return getCurrentRowAsStruct().getBooleanArray(columnIndex);
Expand Down
Expand Up @@ -207,6 +207,11 @@ protected Date getDateInternal(int columnIndex) {
return values.get(columnIndex).getDate();
}

@Override
protected Value getValueInternal(int columnIndex) {
return values.get(columnIndex);
}

@Override
protected Struct getStructInternal(int columnIndex) {
return values.get(columnIndex).getStruct();
Expand Down
Expand Up @@ -132,6 +132,16 @@ public interface StructReader {
/** Returns the value of a non-{@code NULL} column with type {@link Type#date()}. */
Date getDate(String columnName);

/** Returns the value of a non-{@code NULL} column as a {@link Value}. */
default Value getValue(int columnIndex) {
throw new UnsupportedOperationException("method should be overwritten");
}

/** Returns the value of a non-{@code NULL} column as a {@link Value}. */
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: This should be updated to indicate that this method can be called for columns that contain a null value, and what the behavior is when the value is null.

default Value getValue(String columnName) {
throw new UnsupportedOperationException("method should be overwritten");
}

/**
* Returns the value of a non-{@code NULL} column with type {@code Type.array(Type.bool())}.
*
Expand Down
Expand Up @@ -23,6 +23,7 @@
import com.google.cloud.spanner.SpannerException;
import com.google.cloud.spanner.Struct;
import com.google.cloud.spanner.Type;
import com.google.cloud.spanner.Value;
import com.google.common.base.Preconditions;
import com.google.spanner.v1.ResultSetStats;
import java.math.BigDecimal;
Expand Down Expand Up @@ -231,6 +232,18 @@ public Date getDate(String columnName) {
return delegate.getDate(columnName);
}

@Override
public Value getValue(int columnIndex) {
Preconditions.checkState(nextCalledByClient, MISSING_NEXT_CALL);
return delegate.getValue(columnIndex);
}

@Override
public Value getValue(String columnName) {
Preconditions.checkState(nextCalledByClient, MISSING_NEXT_CALL);
return delegate.getValue(columnName);
}

@Override
public boolean[] getBooleanArray(int columnIndex) {
Preconditions.checkState(nextCalledByClient, MISSING_NEXT_CALL);
Expand Down
Expand Up @@ -25,6 +25,7 @@
import com.google.cloud.spanner.SpannerExceptionFactory;
import com.google.cloud.spanner.Struct;
import com.google.cloud.spanner.Type;
import com.google.cloud.spanner.Value;
import com.google.common.base.Preconditions;
import com.google.spanner.v1.ResultSetStats;
import java.math.BigDecimal;
Expand Down Expand Up @@ -231,6 +232,18 @@ public Date getDate(String columnName) {
return delegate.getDate(columnName);
}

@Override
public Value getValue(int columnIndex) {
checkClosed();
return delegate.getValue(columnIndex);
}

@Override
public Value getValue(String columnName) {
checkClosed();
return delegate.getValue(columnName);
}

@Override
public boolean[] getBooleanArray(int columnIndex) {
checkClosed();
Expand Down
Expand Up @@ -32,6 +32,7 @@
import java.math.BigDecimal;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import javax.annotation.Nullable;
import org.junit.Before;
Expand Down Expand Up @@ -84,6 +85,11 @@ protected Date getDateInternal(int columnIndex) {
return null;
}

@Override
protected Value getValueInternal(int columnIndex) {
return null;
}

@Override
protected boolean[] getBooleanArrayInternal(int columnIndex) {
return null;
Expand Down Expand Up @@ -162,89 +168,119 @@ public boolean isNull(int columnIndex) {
public static Collection<Object[]> parameters() {
return Arrays.asList(
new Object[][] {
{Type.bool(), "getBooleanInternal", false, "getBoolean", null},
{Type.int64(), "getLongInternal", 123L, "getLong", null},
{Type.float64(), "getDoubleInternal", 2.0, "getDouble", null},
{
Type.bool(),
"getBooleanInternal",
false,
"getBoolean",
Collections.singletonList("getValue")
},
{Type.int64(), "getLongInternal", 123L, "getLong", Collections.singletonList("getValue")},
{
Type.float64(),
"getDoubleInternal",
2.0,
"getDouble",
Collections.singletonList("getValue")
},
{
Type.numeric(),
"getBigDecimalInternal",
BigDecimal.valueOf(21, 1),
"getBigDecimal",
null
Collections.singletonList("getValue")
},
{
Type.string(),
"getStringInternal",
"a",
"getString",
Collections.singletonList("getValue")
},
{
Type.bytes(),
"getBytesInternal",
ByteArray.copyFrom(new byte[] {0}),
"getBytes",
Collections.singletonList("getValue")
},
{Type.string(), "getStringInternal", "a", "getString", null},
{Type.bytes(), "getBytesInternal", ByteArray.copyFrom(new byte[] {0}), "getBytes", null},
{
Type.timestamp(),
"getTimestampInternal",
Timestamp.parseTimestamp("2015-09-15T00:00:00Z"),
"getTimestamp",
null
Collections.singletonList("getValue")
},
{
Type.date(),
"getDateInternal",
Date.parseDate("2015-09-15"),
"getDate",
Collections.singletonList("getValue")
},
{Type.date(), "getDateInternal", Date.parseDate("2015-09-15"), "getDate", null},
{
Type.array(Type.bool()),
"getBooleanArrayInternal",
new boolean[] {true, false},
"getBooleanArray",
Arrays.asList("getBooleanList")
Arrays.asList("getBooleanList", "getValue")
},
{
Type.array(Type.bool()),
"getBooleanListInternal",
Arrays.asList(false, true),
"getBooleanList",
Arrays.asList("getBooleanArray")
Arrays.asList("getBooleanArray", "getValue")
},
{
Type.array(Type.int64()),
"getLongArrayInternal",
new long[] {1, 2},
"getLongArray",
Arrays.asList("getLongList")
Arrays.asList("getLongList", "getValue")
},
{
Type.array(Type.int64()),
"getLongListInternal",
Arrays.asList(3L, 4L),
"getLongList",
Arrays.asList("getLongArray")
Arrays.asList("getLongArray", "getValue")
},
{
Type.array(Type.float64()),
"getDoubleArrayInternal",
new double[] {1.0, 2.0},
"getDoubleArray",
Arrays.asList("getDoubleList")
Arrays.asList("getDoubleList", "getValue")
},
{
Type.array(Type.float64()),
"getDoubleListInternal",
Arrays.asList(2.0, 4.0),
"getDoubleList",
Arrays.asList("getDoubleArray")
Arrays.asList("getDoubleArray", "getValue")
},
{
Type.array(Type.numeric()),
"getBigDecimalListInternal",
Arrays.asList(BigDecimal.valueOf(21, 1), BigDecimal.valueOf(41, 1)),
"getBigDecimalList",
null
Collections.singletonList("getValue")
},
{
Type.array(Type.string()),
"getStringListInternal",
Arrays.asList("a", "b", "c"),
"getStringList",
null
Collections.singletonList("getValue")
},
{
Type.array(Type.bytes()),
"getBytesListInternal",
Arrays.asList(
ByteArray.copyFrom("a"), ByteArray.copyFrom("b"), ByteArray.copyFrom("c")),
"getBytesList",
null
Collections.singletonList("getValue")
},
{
Type.array(Type.timestamp()),
Expand All @@ -253,14 +289,14 @@ public static Collection<Object[]> parameters() {
Timestamp.parseTimestamp("2015-09-15T00:00:00Z"),
Timestamp.parseTimestamp("2015-09-14T00:00:00Z")),
"getTimestampList",
null,
Collections.singletonList("getValue")
},
{
Type.array(Type.date()),
"getDateListInternal",
Arrays.asList(Date.parseDate("2015-09-15"), Date.parseDate("2015-09-14")),
"getDateList",
null,
Collections.singletonList("getValue")
},
{
Type.array(Type.struct(StructField.of("f1", Type.int64()))),
Expand All @@ -270,7 +306,7 @@ public static Collection<Object[]> parameters() {
Struct.newBuilder().set("f1").to(2).build(),
Struct.newBuilder().set("f1").to(3).build()),
"getStructList",
null
Collections.singletonList("getValue")
}
});
}
Expand Down Expand Up @@ -374,7 +410,7 @@ public void getterForIncorrectType() {
}
try {
getterByIndex(method.getName(), columnIndex);
fail("Expected ISE for " + method);
fail("Expected " + IllegalStateException.class.getSimpleName() + " for " + method);
} catch (IllegalStateException e) {
assertWithMessage("Exception for " + method).that(e.getMessage()).contains("was " + type);
assertWithMessage("Exception for " + method)
Expand Down