diff --git a/java-spanner/google-cloud-spanner/src/main/java/com/google/cloud/spanner/AbstractStructReader.java b/java-spanner/google-cloud-spanner/src/main/java/com/google/cloud/spanner/AbstractStructReader.java index 60ff4fd330e6..9dc8690dc899 100644 --- a/java-spanner/google-cloud-spanner/src/main/java/com/google/cloud/spanner/AbstractStructReader.java +++ b/java-spanner/google-cloud-spanner/src/main/java/com/google/cloud/spanner/AbstractStructReader.java @@ -16,17 +16,14 @@ package com.google.cloud.spanner; -import static com.google.common.base.Preconditions.checkState; - import com.google.cloud.ByteArray; import com.google.cloud.Date; import com.google.cloud.Timestamp; import com.google.cloud.spanner.Type.Code; +import com.google.common.collect.ImmutableList; import com.google.protobuf.AbstractMessage; import com.google.protobuf.ProtocolMessageEnum; import java.math.BigDecimal; -import java.util.Arrays; -import java.util.Collections; import java.util.List; import java.util.UUID; import java.util.function.Function; @@ -40,6 +37,20 @@ * type appropriate for the method. */ public abstract class AbstractStructReader implements StructReader { + private static final ImmutableList VALID_LONG_TYPE_CODES = + ImmutableList.of(Code.ENUM, Code.PG_OID, Code.INT64); + private static final ImmutableList VALID_ENUM_TYPE_CODES = + ImmutableList.of(Code.ENUM, Code.INT64); + private static final ImmutableList VALID_BYTES_CODES = + ImmutableList.of(Code.PROTO, Code.BYTES); + private static final ImmutableList VALID_PROTO_CODES = + ImmutableList.of(Code.PROTO, Code.BYTES); + private static final ImmutableList VALID_STRING_TYPES = + ImmutableList.of(Type.string(), Type.pgNumeric()); + private static final ImmutableList VALID_ARRAY_CODES = ImmutableList.of(Code.ARRAY); + private static final ImmutableList VALID_STRING_ARRAY_TYPES = + ImmutableList.of(Type.TYPE_ARRAY_STRING, Type.TYPE_ARRAY_PG_NUMERIC); + protected abstract boolean getBooleanInternal(int columnIndex); protected abstract long getLongInternal(int columnIndex); @@ -169,7 +180,7 @@ public boolean isNull(String columnName) { @Override public boolean getBoolean(int columnIndex) { - checkNonNullOfType(columnIndex, Type.bool(), columnIndex); + checkNonNullOfType(columnIndex, Type.bool()); return getBooleanInternal(columnIndex); } @@ -182,21 +193,20 @@ public boolean getBoolean(String columnName) { @Override public long getLong(int columnIndex) { - checkNonNullOfCodes( - columnIndex, Arrays.asList(Code.ENUM, Code.PG_OID, Code.INT64), columnIndex); + checkNonNullOfCodes(columnIndex, VALID_LONG_TYPE_CODES); return getLongInternal(columnIndex); } @Override public long getLong(String columnName) { int columnIndex = getColumnIndex(columnName); - checkNonNullOfCodes(columnIndex, Arrays.asList(Code.ENUM, Code.PG_OID, Code.INT64), columnName); + checkNonNullOfCodes(columnIndex, VALID_LONG_TYPE_CODES, columnName); return getLongInternal(columnIndex); } @Override public float getFloat(int columnIndex) { - checkNonNullOfType(columnIndex, Type.float32(), columnIndex); + checkNonNullOfType(columnIndex, Type.float32()); return getFloatInternal(columnIndex); } @@ -209,7 +219,7 @@ public float getFloat(String columnName) { @Override public double getDouble(int columnIndex) { - checkNonNullOfType(columnIndex, Type.float64(), columnIndex); + checkNonNullOfType(columnIndex, Type.float64()); return getDoubleInternal(columnIndex); } @@ -222,7 +232,7 @@ public double getDouble(String columnName) { @Override public BigDecimal getBigDecimal(int columnIndex) { - checkNonNullOfType(columnIndex, Type.numeric(), columnIndex); + checkNonNullOfType(columnIndex, Type.numeric()); return getBigDecimalInternal(columnIndex); } @@ -235,25 +245,20 @@ public BigDecimal getBigDecimal(String columnName) { @Override public String getString(int columnIndex) { - checkNonNullOfTypes( - columnIndex, - Arrays.asList(Type.string(), Type.pgNumeric()), - columnIndex, - "STRING, NUMERIC"); + checkNonNullOfTypes(columnIndex, VALID_STRING_TYPES, "STRING, NUMERIC"); return getStringInternal(columnIndex); } @Override public String getString(String columnName) { int columnIndex = getColumnIndex(columnName); - checkNonNullOfTypes( - columnIndex, Arrays.asList(Type.string(), Type.pgNumeric()), columnName, "STRING, NUMERIC"); + checkNonNullOfTypes(columnIndex, VALID_STRING_TYPES, columnName, "STRING, NUMERIC"); return getStringInternal(columnIndex); } @Override public String getJson(int columnIndex) { - checkNonNullOfType(columnIndex, Type.json(), columnIndex); + checkNonNullOfType(columnIndex, Type.json()); return getJsonInternal(columnIndex); } @@ -266,7 +271,7 @@ public String getJson(String columnName) { @Override public String getPgJsonb(int columnIndex) { - checkNonNullOfType(columnIndex, Type.pgJsonb(), columnIndex); + checkNonNullOfType(columnIndex, Type.pgJsonb()); return getPgJsonbInternal(columnIndex); } @@ -279,20 +284,20 @@ public String getPgJsonb(String columnName) { @Override public ByteArray getBytes(int columnIndex) { - checkNonNullOfCodes(columnIndex, Arrays.asList(Code.PROTO, Code.BYTES), columnIndex); + checkNonNullOfCodes(columnIndex, VALID_BYTES_CODES); return getBytesInternal(columnIndex); } @Override public ByteArray getBytes(String columnName) { int columnIndex = getColumnIndex(columnName); - checkNonNullOfCodes(columnIndex, Arrays.asList(Code.PROTO, Code.BYTES), columnName); + checkNonNullOfCodes(columnIndex, VALID_BYTES_CODES, columnName); return getBytesInternal(columnIndex); } @Override public Timestamp getTimestamp(int columnIndex) { - checkNonNullOfType(columnIndex, Type.timestamp(), columnIndex); + checkNonNullOfType(columnIndex, Type.timestamp()); return getTimestampInternal(columnIndex); } @@ -305,7 +310,7 @@ public Timestamp getTimestamp(String columnName) { @Override public Date getDate(int columnIndex) { - checkNonNullOfType(columnIndex, Type.date(), columnIndex); + checkNonNullOfType(columnIndex, Type.date()); return getDateInternal(columnIndex); } @@ -318,7 +323,7 @@ public Date getDate(String columnName) { @Override public UUID getUuid(int columnIndex) { - checkNonNullOfType(columnIndex, Type.uuid(), columnIndex); + checkNonNullOfType(columnIndex, Type.uuid()); return getUuidInternal(columnIndex); } @@ -331,7 +336,7 @@ public UUID getUuid(String columnName) { @Override public Interval getInterval(int columnIndex) { - checkNonNullOfType(columnIndex, Type.interval(), columnIndex); + checkNonNullOfType(columnIndex, Type.interval()); return getIntervalInternal(columnIndex); } @@ -345,7 +350,7 @@ public Interval getInterval(String columnName) { @Override public T getProtoEnum( int columnIndex, Function method) { - checkNonNullOfCodes(columnIndex, Arrays.asList(Code.ENUM, Code.INT64), columnIndex); + checkNonNullOfCodes(columnIndex, VALID_ENUM_TYPE_CODES); return getProtoEnumInternal(columnIndex, method); } @@ -353,20 +358,20 @@ public T getProtoEnum( public T getProtoEnum( String columnName, Function method) { int columnIndex = getColumnIndex(columnName); - checkNonNullOfCodes(columnIndex, Arrays.asList(Code.ENUM, Code.INT64), columnName); + checkNonNullOfCodes(columnIndex, VALID_ENUM_TYPE_CODES, columnName); return getProtoEnumInternal(columnIndex, method); } @Override public T getProtoMessage(int columnIndex, T message) { - checkNonNullOfCodes(columnIndex, Arrays.asList(Code.PROTO, Code.BYTES), columnIndex); + checkNonNullOfCodes(columnIndex, VALID_PROTO_CODES); return getProtoMessageInternal(columnIndex, message); } @Override public T getProtoMessage(String columnName, T message) { int columnIndex = getColumnIndex(columnName); - checkNonNullOfCodes(columnIndex, Arrays.asList(Code.PROTO, Code.BYTES), columnName); + checkNonNullOfCodes(columnIndex, VALID_PROTO_CODES, columnName); return getProtoMessageInternal(columnIndex, message); } @@ -383,136 +388,128 @@ public Value getValue(String columnName) { @Override public boolean[] getBooleanArray(int columnIndex) { - checkNonNullOfType(columnIndex, Type.array(Type.bool()), columnIndex); + checkNonNullOfType(columnIndex, Type.TYPE_ARRAY_BOOL); return getBooleanArrayInternal(columnIndex); } @Override public boolean[] getBooleanArray(String columnName) { int columnIndex = getColumnIndex(columnName); - checkNonNullOfType(columnIndex, Type.array(Type.bool()), columnName); + checkNonNullOfType(columnIndex, Type.TYPE_ARRAY_BOOL, columnName); return getBooleanArrayInternal(columnIndex); } @Override public List getBooleanList(int columnIndex) { - checkNonNullOfType(columnIndex, Type.array(Type.bool()), columnIndex); + checkNonNullOfType(columnIndex, Type.TYPE_ARRAY_BOOL); return getBooleanListInternal(columnIndex); } @Override public List getBooleanList(String columnName) { int columnIndex = getColumnIndex(columnName); - checkNonNullOfType(columnIndex, Type.array(Type.bool()), columnName); + checkNonNullOfType(columnIndex, Type.TYPE_ARRAY_BOOL, columnName); return getBooleanListInternal(columnIndex); } @Override public long[] getLongArray(int columnIndex) { - checkNonNullOfCodes(columnIndex, Collections.singletonList(Code.ARRAY), columnIndex); - checkArrayElementType( - columnIndex, Arrays.asList(Code.ENUM, Code.PG_OID, Code.INT64), columnIndex); + checkNonNullOfCodes(columnIndex, VALID_ARRAY_CODES); + checkArrayElementType(columnIndex, VALID_LONG_TYPE_CODES); return getLongArrayInternal(columnIndex); } @Override public long[] getLongArray(String columnName) { int columnIndex = getColumnIndex(columnName); - checkNonNullOfCodes(columnIndex, Collections.singletonList(Code.ARRAY), columnName); - checkArrayElementType( - columnIndex, Arrays.asList(Code.ENUM, Code.PG_OID, Code.INT64), columnName); + checkNonNullOfCodes(columnIndex, VALID_ARRAY_CODES, columnName); + checkArrayElementType(columnIndex, VALID_LONG_TYPE_CODES, columnName); return getLongArrayInternal(columnIndex); } @Override public List getLongList(int columnIndex) { - checkNonNullOfCodes(columnIndex, Collections.singletonList(Code.ARRAY), columnIndex); - checkArrayElementType( - columnIndex, Arrays.asList(Code.ENUM, Code.PG_OID, Code.INT64), columnIndex); + checkNonNullOfCodes(columnIndex, VALID_ARRAY_CODES); + checkArrayElementType(columnIndex, VALID_LONG_TYPE_CODES); return getLongListInternal(columnIndex); } @Override public List getLongList(String columnName) { int columnIndex = getColumnIndex(columnName); - checkNonNullOfCodes(columnIndex, Collections.singletonList(Code.ARRAY), columnName); - checkArrayElementType( - columnIndex, Arrays.asList(Code.ENUM, Code.PG_OID, Code.INT64), columnName); + checkNonNullOfCodes(columnIndex, VALID_ARRAY_CODES, columnName); + checkArrayElementType(columnIndex, VALID_LONG_TYPE_CODES, columnName); return getLongListInternal(columnIndex); } @Override public float[] getFloatArray(int columnIndex) { - checkNonNullOfType(columnIndex, Type.array(Type.float32()), columnIndex); + checkNonNullOfType(columnIndex, Type.TYPE_ARRAY_FLOAT32); return getFloatArrayInternal(columnIndex); } @Override public float[] getFloatArray(String columnName) { int columnIndex = getColumnIndex(columnName); - checkNonNullOfType(columnIndex, Type.array(Type.float32()), columnName); + checkNonNullOfType(columnIndex, Type.TYPE_ARRAY_FLOAT32, columnName); return getFloatArrayInternal(columnIndex); } @Override public List getFloatList(int columnIndex) { - checkNonNullOfType(columnIndex, Type.array(Type.float32()), columnIndex); + checkNonNullOfType(columnIndex, Type.TYPE_ARRAY_FLOAT32); return getFloatListInternal(columnIndex); } @Override public List getFloatList(String columnName) { int columnIndex = getColumnIndex(columnName); - checkNonNullOfType(columnIndex, Type.array(Type.float32()), columnName); + checkNonNullOfType(columnIndex, Type.TYPE_ARRAY_FLOAT32, columnName); return getFloatListInternal(columnIndex); } @Override public double[] getDoubleArray(int columnIndex) { - checkNonNullOfType(columnIndex, Type.array(Type.float64()), columnIndex); + checkNonNullOfType(columnIndex, Type.TYPE_ARRAY_FLOAT64); return getDoubleArrayInternal(columnIndex); } @Override public double[] getDoubleArray(String columnName) { int columnIndex = getColumnIndex(columnName); - checkNonNullOfType(columnIndex, Type.array(Type.float64()), columnName); + checkNonNullOfType(columnIndex, Type.TYPE_ARRAY_FLOAT64, columnName); return getDoubleArrayInternal(columnIndex); } @Override public List getDoubleList(int columnIndex) { - checkNonNullOfType(columnIndex, Type.array(Type.float64()), columnIndex); + checkNonNullOfType(columnIndex, Type.TYPE_ARRAY_FLOAT64); return getDoubleListInternal(columnIndex); } @Override public List getDoubleList(String columnName) { int columnIndex = getColumnIndex(columnName); - checkNonNullOfType(columnIndex, Type.array(Type.float64()), columnName); + checkNonNullOfType(columnIndex, Type.TYPE_ARRAY_FLOAT64, columnName); return getDoubleListInternal(columnIndex); } @Override public List getBigDecimalList(int columnIndex) { - checkNonNullOfType(columnIndex, Type.array(Type.numeric()), columnIndex); + checkNonNullOfType(columnIndex, Type.TYPE_ARRAY_NUMERIC); return getBigDecimalListInternal(columnIndex); } @Override public List getBigDecimalList(String columnName) { int columnIndex = getColumnIndex(columnName); - checkNonNullOfType(columnIndex, Type.array(Type.numeric()), columnName); + checkNonNullOfType(columnIndex, Type.TYPE_ARRAY_NUMERIC, columnName); return getBigDecimalListInternal(columnIndex); } @Override public List getStringList(int columnIndex) { - checkNonNullOfTypes( - columnIndex, - Arrays.asList(Type.array(Type.string()), Type.array(Type.pgNumeric())), - columnIndex, - "ARRAY, ARRAY"); + checkNonNullOfTypes(columnIndex, VALID_STRING_ARRAY_TYPES, "ARRAY, ARRAY"); return getStringListInternal(columnIndex); } @@ -520,74 +517,71 @@ public List getStringList(int columnIndex) { public List getStringList(String columnName) { int columnIndex = getColumnIndex(columnName); checkNonNullOfTypes( - columnIndex, - Arrays.asList(Type.array(Type.string()), Type.array(Type.pgNumeric())), - columnName, - "ARRAY, ARRAY"); + columnIndex, VALID_STRING_ARRAY_TYPES, columnName, "ARRAY, ARRAY"); return getStringListInternal(columnIndex); } @Override public List getJsonList(int columnIndex) { - checkNonNullOfType(columnIndex, Type.array(Type.json()), columnIndex); + checkNonNullOfType(columnIndex, Type.TYPE_ARRAY_JSON); return getJsonListInternal(columnIndex); } @Override public List getJsonList(String columnName) { int columnIndex = getColumnIndex(columnName); - checkNonNullOfType(columnIndex, Type.array(Type.json()), columnName); + checkNonNullOfType(columnIndex, Type.TYPE_ARRAY_JSON, columnName); return getJsonListInternal(columnIndex); } @Override public List getPgJsonbList(int columnIndex) { - checkNonNullOfType(columnIndex, Type.array(Type.pgJsonb()), columnIndex); + checkNonNullOfType(columnIndex, Type.TYPE_ARRAY_PG_JSONB); return getPgJsonbListInternal(columnIndex); } @Override public List getPgJsonbList(String columnName) { int columnIndex = getColumnIndex(columnName); - checkNonNullOfType(columnIndex, Type.array(Type.pgJsonb()), columnName); + checkNonNullOfType(columnIndex, Type.TYPE_ARRAY_PG_JSONB, columnName); return getPgJsonbListInternal(columnIndex); } @Override public List getBytesList(int columnIndex) { - checkNonNullOfCodes(columnIndex, Collections.singletonList(Code.ARRAY), columnIndex); - checkArrayElementType(columnIndex, Arrays.asList(Code.PROTO, Code.BYTES), columnIndex); + checkNonNullOfCodes(columnIndex, VALID_ARRAY_CODES); + checkArrayElementType(columnIndex, VALID_PROTO_CODES); return getBytesListInternal(columnIndex); } @Override public List getBytesList(String columnName) { int columnIndex = getColumnIndex(columnName); - checkNonNullOfCodes(columnIndex, Collections.singletonList(Code.ARRAY), columnName); - checkArrayElementType(columnIndex, Arrays.asList(Code.PROTO, Code.BYTES), columnName); + checkNonNullOfCodes(columnIndex, VALID_ARRAY_CODES, columnName); + checkArrayElementType(columnIndex, VALID_PROTO_CODES, columnName); return getBytesListInternal(columnIndex); } @Override public List getProtoMessageList(int columnIndex, T message) { - checkNonNullOfCodes(columnIndex, Collections.singletonList(Code.ARRAY), columnIndex); - checkArrayElementType(columnIndex, Arrays.asList(Code.PROTO, Code.BYTES), columnIndex); + checkNonNullOfCodes(columnIndex, VALID_ARRAY_CODES); + checkArrayElementType(columnIndex, VALID_PROTO_CODES); return getProtoMessageListInternal(columnIndex, message); } @Override public List getProtoMessageList(String columnName, T message) { int columnIndex = getColumnIndex(columnName); - checkNonNullOfCodes(columnIndex, Collections.singletonList(Code.ARRAY), columnName); - checkArrayElementType(columnIndex, Arrays.asList(Code.PROTO, Code.BYTES), columnName); + checkNonNullOfCodes(columnIndex, VALID_ARRAY_CODES, columnName); + checkArrayElementType(columnIndex, VALID_PROTO_CODES, columnName); return getProtoMessageListInternal(columnIndex, message); } @Override public List getProtoEnumList( int columnIndex, Function method) { - checkNonNullOfCodes(columnIndex, Collections.singletonList(Code.ARRAY), columnIndex); - checkArrayElementType(columnIndex, Arrays.asList(Code.ENUM, Code.INT64), columnIndex); + checkNonNullOfCodes(columnIndex, VALID_ARRAY_CODES); + checkArrayElementType(columnIndex, VALID_ENUM_TYPE_CODES); return getProtoEnumListInternal(columnIndex, method); } @@ -595,66 +589,66 @@ public List getProtoEnumList( public List getProtoEnumList( String columnName, Function method) { int columnIndex = getColumnIndex(columnName); - checkNonNullOfCodes(columnIndex, Collections.singletonList(Code.ARRAY), columnName); - checkArrayElementType(columnIndex, Arrays.asList(Code.ENUM, Code.INT64), columnName); + checkNonNullOfCodes(columnIndex, VALID_ARRAY_CODES, columnName); + checkArrayElementType(columnIndex, VALID_ENUM_TYPE_CODES, columnName); return getProtoEnumListInternal(columnIndex, method); } @Override public List getTimestampList(int columnIndex) { - checkNonNullOfType(columnIndex, Type.array(Type.timestamp()), columnIndex); + checkNonNullOfType(columnIndex, Type.TYPE_ARRAY_TIMESTAMP); return getTimestampListInternal(columnIndex); } @Override public List getTimestampList(String columnName) { int columnIndex = getColumnIndex(columnName); - checkNonNullOfType(columnIndex, Type.array(Type.timestamp()), columnName); + checkNonNullOfType(columnIndex, Type.TYPE_ARRAY_TIMESTAMP, columnName); return getTimestampListInternal(columnIndex); } @Override public List getDateList(int columnIndex) { - checkNonNullOfType(columnIndex, Type.array(Type.date()), columnIndex); + checkNonNullOfType(columnIndex, Type.TYPE_ARRAY_DATE); return getDateListInternal(columnIndex); } @Override public List getDateList(String columnName) { int columnIndex = getColumnIndex(columnName); - checkNonNullOfType(columnIndex, Type.array(Type.date()), columnName); + checkNonNullOfType(columnIndex, Type.TYPE_ARRAY_DATE, columnName); return getDateListInternal(columnIndex); } @Override public List getUuidList(int columnIndex) { - checkNonNullOfType(columnIndex, Type.array(Type.uuid()), columnIndex); + checkNonNullOfType(columnIndex, Type.TYPE_ARRAY_UUID); return getUuidListInternal(columnIndex); } @Override public List getUuidList(String columnName) { final int columnIndex = getColumnIndex(columnName); - checkNonNullOfType(columnIndex, Type.array(Type.uuid()), columnName); + checkNonNullOfType(columnIndex, Type.TYPE_ARRAY_UUID, columnName); return getUuidListInternal(columnIndex); } @Override public List getIntervalList(int columnIndex) { - checkNonNullOfType(columnIndex, Type.array(Type.interval()), columnIndex); + checkNonNullOfType(columnIndex, Type.TYPE_ARRAY_INTERVAL); return getIntervalListInternal(columnIndex); } @Override public List getIntervalList(String columnName) { int columnIndex = getColumnIndex(columnName); - checkNonNullOfType(columnIndex, Type.array(Type.interval()), columnName); + checkNonNullOfType(columnIndex, Type.TYPE_ARRAY_INTERVAL, columnName); return getIntervalListInternal(columnIndex); } @Override public List getStructList(int columnIndex) { - checkNonNullArrayOfStruct(columnIndex, columnIndex); + checkNonNullArrayOfStruct(columnIndex); return getStructListInternal(columnIndex); } @@ -674,70 +668,141 @@ public int getColumnIndex(String columnName) { return getType().getFieldIndex(columnName); } - protected void checkNonNull(int columnIndex, Object columnNameForError) { + protected void checkNonNull(int columnIndex, String columnNameForError) { if (isNull(columnIndex)) { throw new NullPointerException("Column " + columnNameForError + " contains NULL value"); } } - private void checkNonNullOfType(int columnIndex, Type expectedType, Object columnNameForError) { + /** + * @deprecated use {@link #checkNonNull(int, String)} instead. + */ + @Deprecated + protected void checkNonNull(int columnIndex, Object columnNameForError) { + checkNonNull(columnIndex, String.valueOf(columnNameForError)); + } + + protected void checkNonNull(int columnIndex) { + if (isNull(columnIndex)) { + throw new NullPointerException("Column " + columnIndex + " contains NULL value"); + } + } + + private void checkNonNullOfType(int columnIndex, Type expectedType, String columnNameForError) { Type actualType = getColumnType(columnIndex); - checkState( - expectedType.equals(actualType), - "Column %s is not of correct type: expected %s but was %s", - columnNameForError, - expectedType, - actualType); + if (!expectedType.equals(actualType)) { + throw new IllegalStateException( + String.format( + "Column %s is not of correct type: expected %s but was %s", + columnNameForError, expectedType, actualType)); + } checkNonNull(columnIndex, columnNameForError); } + private void checkNonNullOfType(int columnIndex, Type expectedType) { + Type actualType = getColumnType(columnIndex); + if (!expectedType.equals(actualType)) { + throw new IllegalStateException( + String.format( + "Column %d is not of correct type: expected %s but was %s", + columnIndex, expectedType, actualType)); + } + checkNonNull(columnIndex); + } + /** Checks if the value at {@code columnIndex} is one of {@code expectedCode} */ private void checkNonNullOfCodes( - int columnIndex, List expectedCodes, Object columnNameForError) { + int columnIndex, List expectedCodes, String columnNameForError) { Type actualType = getColumnType(columnIndex); - checkState( - expectedCodes.contains(actualType.getCode()), - "Column %s is not of correct type code: expected one of [%s] but was %s", - columnNameForError, - expectedCodes, - actualType); + if (!expectedCodes.contains(actualType.getCode())) { + throw new IllegalStateException( + String.format( + "Column %s is not of correct type code: expected one of [%s] but was %s", + columnNameForError, expectedCodes, actualType)); + } checkNonNull(columnIndex, columnNameForError); } + private void checkNonNullOfCodes(int columnIndex, List expectedCodes) { + Type actualType = getColumnType(columnIndex); + if (!expectedCodes.contains(actualType.getCode())) { + throw new IllegalStateException( + String.format( + "Column %d is not of correct type code: expected one of [%s] but was %s", + columnIndex, expectedCodes, actualType)); + } + checkNonNull(columnIndex); + } + private void checkArrayElementType( - int columnIndex, List expectedCodes, Object columnNameForError) { + int columnIndex, List expectedCodes, String columnNameForError) { + Type arrayElementType = getColumnType(columnIndex).getArrayElementType(); + if (!expectedCodes.contains(arrayElementType.getCode())) { + throw new IllegalStateException( + String.format( + "Array element for Column %s is not of correct type code: expected one of [%s] but was %s", + columnNameForError, expectedCodes, Type.array(arrayElementType))); + } + } + + private void checkArrayElementType(int columnIndex, List expectedCodes) { Type arrayElementType = getColumnType(columnIndex).getArrayElementType(); - checkState( - expectedCodes.contains(arrayElementType.getCode()), - "Array element for Column %s is not of correct type code: expected one of [%s] but was %s", - columnNameForError, - expectedCodes, - Type.array(arrayElementType)); + if (!expectedCodes.contains(arrayElementType.getCode())) { + throw new IllegalStateException( + String.format( + "Array element for Column %d is not of correct type code: expected one of [%s] but was %s", + columnIndex, expectedCodes, Type.array(arrayElementType))); + } } private void checkNonNullOfTypes( int columnIndex, List expectedTypes, - Object columnNameForError, + String columnNameForError, String expectedTypeNames) { Type actualType = getColumnType(columnIndex); - checkState( - expectedTypes.contains(actualType), - "Column %s is not of correct type: expected one of [%s] but was %s", - columnNameForError, - expectedTypeNames, - actualType); + if (!expectedTypes.contains(actualType)) { + throw new IllegalStateException( + String.format( + "Column %s is not of correct type: expected one of [%s] but was %s", + columnNameForError, expectedTypeNames, actualType)); + } checkNonNull(columnIndex, columnNameForError); } - private void checkNonNullArrayOfStruct(int columnIndex, Object columnNameForError) { + private void checkNonNullOfTypes( + int columnIndex, List expectedTypes, String expectedTypeNames) { Type actualType = getColumnType(columnIndex); - checkState( - actualType.getCode() == Type.Code.ARRAY - && actualType.getArrayElementType().getCode() == Type.Code.STRUCT, - "Column %s is not of correct type: expected ARRAY> but was %s", - columnNameForError, - actualType); + if (!expectedTypes.contains(actualType)) { + throw new IllegalStateException( + String.format( + "Column %d is not of correct type: expected one of [%s] but was %s", + columnIndex, expectedTypeNames, actualType)); + } + checkNonNull(columnIndex); + } + + private void checkNonNullArrayOfStruct(int columnIndex, String columnNameForError) { + Type actualType = getColumnType(columnIndex); + if (actualType.getCode() != Type.Code.ARRAY + || actualType.getArrayElementType().getCode() != Type.Code.STRUCT) { + throw new IllegalStateException( + String.format( + "Column %s is not of correct type: expected ARRAY> but was %s", + columnNameForError, actualType)); + } checkNonNull(columnIndex, columnNameForError); } + + private void checkNonNullArrayOfStruct(int columnIndex) { + Type actualType = getColumnType(columnIndex); + if (actualType.getCode() != Type.Code.ARRAY + || actualType.getArrayElementType().getCode() != Type.Code.STRUCT) { + throw new IllegalStateException( + String.format( + "Column %d is not of correct type: expected ARRAY> but was %s", + columnIndex, actualType)); + } + checkNonNull(columnIndex); + } } diff --git a/java-spanner/google-cloud-spanner/src/main/java/com/google/cloud/spanner/Struct.java b/java-spanner/google-cloud-spanner/src/main/java/com/google/cloud/spanner/Struct.java index 38a47e99dffe..b597e02cda48 100644 --- a/java-spanner/google-cloud-spanner/src/main/java/com/google/cloud/spanner/Struct.java +++ b/java-spanner/google-cloud-spanner/src/main/java/com/google/cloud/spanner/Struct.java @@ -17,7 +17,6 @@ package com.google.cloud.spanner; import static com.google.common.base.Preconditions.checkNotNull; -import static com.google.common.base.Preconditions.checkState; import com.google.cloud.ByteArray; import com.google.cloud.Date; @@ -125,7 +124,9 @@ private void addInternal(String fieldName, Value value) { private void checkBindingInProgress(boolean expectInProgress) { if (expectInProgress) { - checkState(currentField != null, "No binding currently active"); + if (currentField == null) { + throw new IllegalStateException("No binding currently active"); + } } else if (currentField != null) { throw new IllegalStateException("Incomplete binding for column " + currentField); } @@ -139,7 +140,7 @@ private void checkBindingInProgress(boolean expectInProgress) { /* Public methods for accessing struct-typed fields */ public Struct getStruct(int columnIndex) { - checkNonNullStruct(columnIndex, columnIndex); + checkNonNullStruct(columnIndex); return getStructInternal(columnIndex); } @@ -152,16 +153,28 @@ public Struct getStruct(String columnName) { /* Sub-classes must implement this method */ protected abstract Struct getStructInternal(int columnIndex); - private void checkNonNullStruct(int columnIndex, Object columnNameForError) { + private void checkNonNullStruct(int columnIndex, String columnNameForError) { Type actualType = getColumnType(columnIndex); - checkState( - actualType.getCode() == Code.STRUCT, - "Column %s is not of correct type: expected STRUCT<...> but was %s", - columnNameForError, - actualType); + if (actualType.getCode() != Code.STRUCT) { + throw new IllegalStateException( + String.format( + "Column %s is not of correct type: expected STRUCT<...> but was %s", + columnNameForError, actualType)); + } checkNonNull(columnIndex, columnNameForError); } + private void checkNonNullStruct(int columnIndex) { + Type actualType = getColumnType(columnIndex); + if (actualType.getCode() != Code.STRUCT) { + throw new IllegalStateException( + String.format( + "Column %d is not of correct type: expected STRUCT<...> but was %s", + columnIndex, actualType)); + } + checkNonNull(columnIndex); + } + /** Default implementation for value structs produced by {@link Builder}. */ private static class ValueListStruct extends Struct { private final Type type; diff --git a/java-spanner/google-cloud-spanner/src/main/java/com/google/cloud/spanner/Type.java b/java-spanner/google-cloud-spanner/src/main/java/com/google/cloud/spanner/Type.java index 71120a0f420f..4a22505350f4 100644 --- a/java-spanner/google-cloud-spanner/src/main/java/com/google/cloud/spanner/Type.java +++ b/java-spanner/google-cloud-spanner/src/main/java/com/google/cloud/spanner/Type.java @@ -61,21 +61,21 @@ public final class Type implements Serializable { private static final Type TYPE_DATE = new Type(Code.DATE, null, null); private static final Type TYPE_UUID = new Type(Code.UUID, null, null); private static final Type TYPE_INTERVAL = new Type(Code.INTERVAL, null, null); - private static final Type TYPE_ARRAY_BOOL = new Type(Code.ARRAY, TYPE_BOOL, null); - private static final Type TYPE_ARRAY_INT64 = new Type(Code.ARRAY, TYPE_INT64, null); - private static final Type TYPE_ARRAY_FLOAT32 = new Type(Code.ARRAY, TYPE_FLOAT32, null); - private static final Type TYPE_ARRAY_FLOAT64 = new Type(Code.ARRAY, TYPE_FLOAT64, null); - private static final Type TYPE_ARRAY_NUMERIC = new Type(Code.ARRAY, TYPE_NUMERIC, null); - private static final Type TYPE_ARRAY_PG_NUMERIC = new Type(Code.ARRAY, TYPE_PG_NUMERIC, null); - private static final Type TYPE_ARRAY_STRING = new Type(Code.ARRAY, TYPE_STRING, null); - private static final Type TYPE_ARRAY_JSON = new Type(Code.ARRAY, TYPE_JSON, null); - private static final Type TYPE_ARRAY_PG_JSONB = new Type(Code.ARRAY, TYPE_PG_JSONB, null); - private static final Type TYPE_ARRAY_PG_OID = new Type(Code.ARRAY, TYPE_PG_OID, null); - private static final Type TYPE_ARRAY_BYTES = new Type(Code.ARRAY, TYPE_BYTES, null); - private static final Type TYPE_ARRAY_TIMESTAMP = new Type(Code.ARRAY, TYPE_TIMESTAMP, null); - private static final Type TYPE_ARRAY_DATE = new Type(Code.ARRAY, TYPE_DATE, null); - private static final Type TYPE_ARRAY_UUID = new Type(Code.ARRAY, TYPE_UUID, null); - private static final Type TYPE_ARRAY_INTERVAL = new Type(Code.ARRAY, TYPE_INTERVAL, null); + static final Type TYPE_ARRAY_BOOL = new Type(Code.ARRAY, TYPE_BOOL, null); + static final Type TYPE_ARRAY_INT64 = new Type(Code.ARRAY, TYPE_INT64, null); + static final Type TYPE_ARRAY_FLOAT32 = new Type(Code.ARRAY, TYPE_FLOAT32, null); + static final Type TYPE_ARRAY_FLOAT64 = new Type(Code.ARRAY, TYPE_FLOAT64, null); + static final Type TYPE_ARRAY_NUMERIC = new Type(Code.ARRAY, TYPE_NUMERIC, null); + static final Type TYPE_ARRAY_PG_NUMERIC = new Type(Code.ARRAY, TYPE_PG_NUMERIC, null); + static final Type TYPE_ARRAY_STRING = new Type(Code.ARRAY, TYPE_STRING, null); + static final Type TYPE_ARRAY_JSON = new Type(Code.ARRAY, TYPE_JSON, null); + static final Type TYPE_ARRAY_PG_JSONB = new Type(Code.ARRAY, TYPE_PG_JSONB, null); + static final Type TYPE_ARRAY_PG_OID = new Type(Code.ARRAY, TYPE_PG_OID, null); + static final Type TYPE_ARRAY_BYTES = new Type(Code.ARRAY, TYPE_BYTES, null); + static final Type TYPE_ARRAY_TIMESTAMP = new Type(Code.ARRAY, TYPE_TIMESTAMP, null); + static final Type TYPE_ARRAY_DATE = new Type(Code.ARRAY, TYPE_DATE, null); + static final Type TYPE_ARRAY_UUID = new Type(Code.ARRAY, TYPE_UUID, null); + static final Type TYPE_ARRAY_INTERVAL = new Type(Code.ARRAY, TYPE_INTERVAL, null); private static final int AMBIGUOUS_FIELD = -1; private static final long serialVersionUID = -3076152125004114582L;