diff --git a/generic-contracts/scripts/objects-table-schema.json b/generic-contracts/scripts/objects-table-schema.json index 4cd2b918..475b97dd 100644 --- a/generic-contracts/scripts/objects-table-schema.json +++ b/generic-contracts/scripts/objects-table-schema.json @@ -11,9 +11,17 @@ "object_id": "TEXT", "version": "TEXT", "status": "INT", - "registered_at": "TIMESTAMP" + "registered_at": "TIMESTAMP", + "column_boolean": "BOOLEAN", + "column_bigint": "BIGINT", + "column_float": "FLOAT", + "column_double": "DOUBLE", + "column_text": "TEXT", + "column_blob": "BLOB", + "column_date": "DATE", + "column_time": "TIME", + "column_timestamptz": "TIMESTAMPTZ" }, "compaction-strategy": "LCS" } } - diff --git a/generic-contracts/src/integration-test/java/com/scalar/dl/genericcontracts/GenericContractObjectAndCollectionEndToEndTest.java b/generic-contracts/src/integration-test/java/com/scalar/dl/genericcontracts/GenericContractObjectAndCollectionEndToEndTest.java index 61d82b36..bb10e11c 100644 --- a/generic-contracts/src/integration-test/java/com/scalar/dl/genericcontracts/GenericContractObjectAndCollectionEndToEndTest.java +++ b/generic-contracts/src/integration-test/java/com/scalar/dl/genericcontracts/GenericContractObjectAndCollectionEndToEndTest.java @@ -70,7 +70,16 @@ import com.scalar.db.api.TransactionState; import com.scalar.db.common.CoreError; import com.scalar.db.exception.storage.ExecutionException; +import com.scalar.db.io.BigIntColumn; +import com.scalar.db.io.BlobColumn; +import com.scalar.db.io.BooleanColumn; +import com.scalar.db.io.Column; +import com.scalar.db.io.DataType; +import com.scalar.db.io.DoubleColumn; +import com.scalar.db.io.FloatColumn; +import com.scalar.db.io.IntColumn; import com.scalar.db.io.Key; +import com.scalar.db.io.TextColumn; import com.scalar.dl.client.exception.ClientException; import com.scalar.dl.client.service.GenericContractClientService; import com.scalar.dl.ledger.error.LedgerError; @@ -79,7 +88,11 @@ import com.scalar.dl.ledger.service.StatusCode; import com.scalar.dl.ledger.util.JacksonSerDe; import java.io.IOException; +import java.time.Instant; +import java.time.LocalDate; import java.time.LocalDateTime; +import java.time.LocalTime; +import java.time.ZoneId; import java.util.HashSet; import java.util.List; import java.util.Map; @@ -99,9 +112,6 @@ public class GenericContractObjectAndCollectionEndToEndTest private static final String ASSET_ID = "id"; private static final String ASSET_AGE = "age"; private static final String ASSET_OUTPUT = "output"; - private static final String DATA_TYPE_INT = "INT"; - private static final String DATA_TYPE_TIMESTAMP = "TIMESTAMP"; - private static final String DATA_TYPE_TEXT = "TEXT"; private static final String CONTRACT_OBJECT_GET = com.scalar.dl.genericcontracts.object.Constants.CONTRACT_GET; @@ -124,8 +134,29 @@ public class GenericContractObjectAndCollectionEndToEndTest private static final String SOME_COLUMN_NAME_2 = "version"; private static final String SOME_COLUMN_NAME_3 = "status"; private static final String SOME_COLUMN_NAME_4 = "registered_at"; + private static final String SOME_COLUMN_NAME_BOOLEAN = "column_boolean"; + private static final String SOME_COLUMN_NAME_BIGINT = "column_bigint"; + private static final String SOME_COLUMN_NAME_FLOAT = "column_float"; + private static final String SOME_COLUMN_NAME_DOUBLE = "column_double"; + private static final String SOME_COLUMN_NAME_TEXT = "column_text"; + private static final String SOME_COLUMN_NAME_BLOB = "column_blob"; + private static final String SOME_COLUMN_NAME_DATE = "column_date"; + private static final String SOME_COLUMN_NAME_TIME = "column_time"; + private static final String SOME_COLUMN_NAME_TIMESTAMPTZ = "column_timestamptz"; + private static final String SOME_DATE_TEXT = "2021-02-03"; + private static final String SOME_TIME_TEXT = "05:45:00"; private static final String SOME_TIMESTAMP_TEXT = "2021-02-03 05:45:00"; + private static final String SOME_TIMESTAMPTZ_TEXT = "2021-02-03 05:45:00.000 Z"; + private static final boolean SOME_BOOLEAN_VALUE = false; + private static final long SOME_BIGINT_VALUE = BigIntColumn.MAX_VALUE; + private static final float SOME_FLOAT_VALUE = Float.MAX_VALUE; + private static final double SOME_DOUBLE_VALUE = Double.MAX_VALUE; + private static final byte[] SOME_BLOB_VALUE = {1, 2, 3, 4, 5}; + private static final LocalDate SOME_DATE_VALUE = LocalDate.of(2021, 2, 3); + private static final LocalTime SOME_TIME_VALUE = LocalTime.of(5, 45); private static final LocalDateTime SOME_TIMESTAMP_VALUE = LocalDateTime.of(2021, 2, 3, 5, 45); + private static final Instant SOME_TIMESTAMPTZ_VALUE = + SOME_TIMESTAMP_VALUE.atZone(ZoneId.of("UTC")).toInstant(); private static final String SOME_COLLECTION_ID = "set"; private static final ArrayNode SOME_DEFAULT_OBJECT_IDS = mapper.createArrayNode().add("object1").add("object2").add("object3").add("object4"); @@ -202,41 +233,96 @@ private void prepareCollection() { prepareCollection(clientService); } - private JsonNode createColumn(String name, int value) { + private JsonNode createColumn(Column column) { + ObjectNode jsonColumn = + mapper + .createObjectNode() + .put(COLUMN_NAME, column.getName()) + .put(DATA_TYPE, column.getDataType().name()); + + switch (column.getDataType()) { + case BOOLEAN: + jsonColumn.put(VALUE, column.getBooleanValue()); + break; + case INT: + jsonColumn.put(VALUE, column.getIntValue()); + break; + case BIGINT: + jsonColumn.put(VALUE, column.getBigIntValue()); + break; + case FLOAT: + jsonColumn.put(VALUE, column.getFloatValue()); + break; + case DOUBLE: + jsonColumn.put(VALUE, column.getDoubleValue()); + break; + case TEXT: + jsonColumn.put(VALUE, column.getTextValue()); + break; + case BLOB: + jsonColumn.put(VALUE, column.getBlobValueAsBytes()); + break; + default: + throw new IllegalArgumentException("Invalid data type: " + column.getDataType()); + } + + return jsonColumn; + } + + private JsonNode createColumn(String columnName, DataType dataType, String value) { return mapper .createObjectNode() - .put(COLUMN_NAME, name) + .put(COLUMN_NAME, columnName) .put(VALUE, value) - .put(DATA_TYPE, DATA_TYPE_INT); + .put(DATA_TYPE, dataType.name()); } - private JsonNode createColumn(String name, String value) { + private JsonNode createNullColumn(String columnName, DataType dataType) { return mapper .createObjectNode() - .put(COLUMN_NAME, name) - .put(VALUE, value) - .put(DATA_TYPE, DATA_TYPE_TEXT); + .put(COLUMN_NAME, columnName) + .put(DATA_TYPE, dataType.name()) + .set(VALUE, null); } - private JsonNode createTimestampColumn(String name, String value) { + private ArrayNode createColumns(int status) { return mapper - .createObjectNode() - .put(COLUMN_NAME, name) - .put(VALUE, value) - .put(DATA_TYPE, DATA_TYPE_TIMESTAMP); + .createArrayNode() + .add(createColumn(IntColumn.of(SOME_COLUMN_NAME_3, status))) + .add(createColumn(SOME_COLUMN_NAME_4, DataType.TIMESTAMP, SOME_TIMESTAMP_TEXT)) + .add(createColumn(BooleanColumn.of(SOME_COLUMN_NAME_BOOLEAN, SOME_BOOLEAN_VALUE))) + .add(createColumn(BigIntColumn.of(SOME_COLUMN_NAME_BIGINT, SOME_BIGINT_VALUE))) + .add(createColumn(FloatColumn.of(SOME_COLUMN_NAME_FLOAT, SOME_FLOAT_VALUE))) + .add(createColumn(DoubleColumn.of(SOME_COLUMN_NAME_DOUBLE, SOME_DOUBLE_VALUE))) + .add(createColumn(BlobColumn.of(SOME_COLUMN_NAME_BLOB, SOME_BLOB_VALUE))) + .add(createColumn(SOME_COLUMN_NAME_DATE, DataType.DATE, SOME_DATE_TEXT)) + .add(createColumn(SOME_COLUMN_NAME_TIME, DataType.TIME, SOME_TIME_TEXT)) + .add( + createColumn( + SOME_COLUMN_NAME_TIMESTAMPTZ, DataType.TIMESTAMPTZ, SOME_TIMESTAMPTZ_TEXT)); } - private JsonNode createFunctionArguments( - String objectId, String version, int status, long registeredAt) { + private ArrayNode createNullColumns() { + return mapper + .createArrayNode() + .add(createNullColumn(SOME_COLUMN_NAME_3, DataType.INT)) + .add(createNullColumn(SOME_COLUMN_NAME_4, DataType.TIMESTAMP)) + .add(createNullColumn(SOME_COLUMN_NAME_BOOLEAN, DataType.BOOLEAN)) + .add(createNullColumn(SOME_COLUMN_NAME_BIGINT, DataType.BIGINT)) + .add(createNullColumn(SOME_COLUMN_NAME_FLOAT, DataType.FLOAT)) + .add(createNullColumn(SOME_COLUMN_NAME_DOUBLE, DataType.DOUBLE)) + .add(createNullColumn(SOME_COLUMN_NAME_TEXT, DataType.TEXT)) + .add(createNullColumn(SOME_COLUMN_NAME_BLOB, DataType.BLOB)) + .add(createNullColumn(SOME_COLUMN_NAME_DATE, DataType.DATE)) + .add(createNullColumn(SOME_COLUMN_NAME_TIME, DataType.TIME)) + .add(createNullColumn(SOME_COLUMN_NAME_TIMESTAMPTZ, DataType.TIMESTAMPTZ)); + } + + private ObjectNode createFunctionArguments(String objectId, String version, ArrayNode columns) { ArrayNode partitionKey = - mapper.createArrayNode().add(createColumn(SOME_COLUMN_NAME_1, objectId)); + mapper.createArrayNode().add(createColumn(TextColumn.of(SOME_COLUMN_NAME_1, objectId))); ArrayNode clusteringKey = - mapper.createArrayNode().add(createColumn(SOME_COLUMN_NAME_2, version)); - ArrayNode columns = - mapper - .createArrayNode() - .add(createColumn(SOME_COLUMN_NAME_3, status)) - .add(createTimestampColumn(SOME_COLUMN_NAME_4, SOME_TIMESTAMP_TEXT)); + mapper.createArrayNode().add(createColumn(TextColumn.of(SOME_COLUMN_NAME_2, version))); ObjectNode arguments = mapper.createObjectNode(); arguments.put(NAMESPACE, getFunctionNamespace()); @@ -248,6 +334,14 @@ private JsonNode createFunctionArguments( return arguments; } + private ObjectNode createFunctionArguments(String objectId, String version, int status) { + return createFunctionArguments(objectId, version, createColumns(status)); + } + + private ObjectNode createFunctionArgumentsWithNullColumns(String objectId, String version) { + return createFunctionArguments(objectId, version, createNullColumns()); + } + private void addObjectsToCollection( GenericContractClientService clientService, String collectionId, ArrayNode objectIds) { JsonNode arguments = @@ -519,9 +613,8 @@ public void putObject_FunctionArgumentsGiven_ShouldPutRecordToFunctionTable() .put(OBJECT_ID, SOME_OBJECT_ID) .put(HASH_VALUE, SOME_HASH_VALUE_1) .set(METADATA, SOME_METADATA_1); - JsonNode functionArguments0 = createFunctionArguments(SOME_OBJECT_ID, SOME_VERSION_ID_0, 0, 1L); - JsonNode functionArguments1 = - createFunctionArguments(SOME_OBJECT_ID, SOME_VERSION_ID_1, 1, 1234567890123L); + JsonNode functionArguments0 = createFunctionArguments(SOME_OBJECT_ID, SOME_VERSION_ID_0, 0); + JsonNode functionArguments1 = createFunctionArguments(SOME_OBJECT_ID, SOME_VERSION_ID_1, 1); Scan scan = Scan.newBuilder() .namespace(getFunctionNamespace()) @@ -544,10 +637,72 @@ public void putObject_FunctionArgumentsGiven_ShouldPutRecordToFunctionTable() assertThat(results.get(0).getText(SOME_COLUMN_NAME_2)).isEqualTo(SOME_VERSION_ID_0); assertThat(results.get(0).getInt(SOME_COLUMN_NAME_3)).isEqualTo(0); assertThat(results.get(0).getTimestamp(SOME_COLUMN_NAME_4)).isEqualTo(SOME_TIMESTAMP_VALUE); + assertThat(results.get(0).getBoolean(SOME_COLUMN_NAME_BOOLEAN)).isEqualTo(SOME_BOOLEAN_VALUE); + assertThat(results.get(0).getBigInt(SOME_COLUMN_NAME_BIGINT)).isEqualTo(SOME_BIGINT_VALUE); + assertThat(results.get(0).getFloat(SOME_COLUMN_NAME_FLOAT)).isEqualTo(SOME_FLOAT_VALUE); + assertThat(results.get(0).getDouble(SOME_COLUMN_NAME_DOUBLE)).isEqualTo(SOME_DOUBLE_VALUE); + assertThat(results.get(0).getBlobAsBytes(SOME_COLUMN_NAME_BLOB)).isEqualTo(SOME_BLOB_VALUE); + assertThat(results.get(0).getDate(SOME_COLUMN_NAME_DATE)).isEqualTo(SOME_DATE_VALUE); + assertThat(results.get(0).getTime(SOME_COLUMN_NAME_TIME)).isEqualTo(SOME_TIME_VALUE); + assertThat(results.get(0).getTimestampTZ(SOME_COLUMN_NAME_TIMESTAMPTZ)) + .isEqualTo(SOME_TIMESTAMPTZ_VALUE); assertThat(results.get(1).getText(SOME_COLUMN_NAME_1)).isEqualTo(SOME_OBJECT_ID); assertThat(results.get(1).getText(SOME_COLUMN_NAME_2)).isEqualTo(SOME_VERSION_ID_1); assertThat(results.get(1).getInt(SOME_COLUMN_NAME_3)).isEqualTo(1); assertThat(results.get(1).getTimestamp(SOME_COLUMN_NAME_4)).isEqualTo(SOME_TIMESTAMP_VALUE); + assertThat(results.get(1).getBoolean(SOME_COLUMN_NAME_BOOLEAN)).isEqualTo(SOME_BOOLEAN_VALUE); + assertThat(results.get(1).getBigInt(SOME_COLUMN_NAME_BIGINT)).isEqualTo(SOME_BIGINT_VALUE); + assertThat(results.get(1).getFloat(SOME_COLUMN_NAME_FLOAT)).isEqualTo(SOME_FLOAT_VALUE); + assertThat(results.get(1).getDouble(SOME_COLUMN_NAME_DOUBLE)).isEqualTo(SOME_DOUBLE_VALUE); + assertThat(results.get(1).getBlobAsBytes(SOME_COLUMN_NAME_BLOB)).isEqualTo(SOME_BLOB_VALUE); + assertThat(results.get(1).getDate(SOME_COLUMN_NAME_DATE)).isEqualTo(SOME_DATE_VALUE); + assertThat(results.get(1).getTime(SOME_COLUMN_NAME_TIME)).isEqualTo(SOME_TIME_VALUE); + assertThat(results.get(1).getTimestampTZ(SOME_COLUMN_NAME_TIMESTAMPTZ)) + .isEqualTo(SOME_TIMESTAMPTZ_VALUE); + } catch (IOException e) { + throw new RuntimeException(e); + } + } + + @Test + public void putObject_FunctionArgumentsWithNullColumnsGiven_ShouldPutRecordToFunctionTable() + throws ExecutionException { + // Arrange + JsonNode contractArguments = + mapper + .createObjectNode() + .put(OBJECT_ID, SOME_OBJECT_ID) + .put(HASH_VALUE, SOME_HASH_VALUE_0) + .set(METADATA, SOME_METADATA_0); + JsonNode functionArguments = + createFunctionArgumentsWithNullColumns(SOME_OBJECT_ID, SOME_VERSION_ID_0); + Scan scan = + Scan.newBuilder() + .namespace(getFunctionNamespace()) + .table(getFunctionTable()) + .partitionKey(Key.ofText(SOME_COLUMN_NAME_1, SOME_OBJECT_ID)) + .build(); + + // Act + clientService.executeContract(CONTRACT_PUT, contractArguments, FUNCTION_PUT, functionArguments); + + // Assert + try (Scanner scanner = storage.scan(scan)) { + List results = scanner.all(); + assertThat(results).hasSize(1); + assertThat(results.get(0).getText(SOME_COLUMN_NAME_1)).isEqualTo(SOME_OBJECT_ID); + assertThat(results.get(0).getText(SOME_COLUMN_NAME_2)).isEqualTo(SOME_VERSION_ID_0); + assertThat(results.get(0).isNull(SOME_COLUMN_NAME_3)).isTrue(); + assertThat(results.get(0).isNull(SOME_COLUMN_NAME_4)).isTrue(); + assertThat(results.get(0).isNull(SOME_COLUMN_NAME_BOOLEAN)).isTrue(); + assertThat(results.get(0).isNull(SOME_COLUMN_NAME_BIGINT)).isTrue(); + assertThat(results.get(0).isNull(SOME_COLUMN_NAME_FLOAT)).isTrue(); + assertThat(results.get(0).isNull(SOME_COLUMN_NAME_DOUBLE)).isTrue(); + assertThat(results.get(0).isNull(SOME_COLUMN_NAME_TEXT)).isTrue(); + assertThat(results.get(0).isNull(SOME_COLUMN_NAME_BLOB)).isTrue(); + assertThat(results.get(0).isNull(SOME_COLUMN_NAME_DATE)).isTrue(); + assertThat(results.get(0).isNull(SOME_COLUMN_NAME_TIME)).isTrue(); + assertThat(results.get(0).isNull(SOME_COLUMN_NAME_TIMESTAMPTZ)).isTrue(); } catch (IOException e) { throw new RuntimeException(e); } @@ -570,7 +725,9 @@ public void putObject_FunctionArgumentsGiven_ShouldPutRecordToFunctionTable() .put(TABLE, "foo") .set( PARTITION_KEY, - mapper.createArrayNode().add(createColumn(SOME_COLUMN_NAME_1, SOME_OBJECT_ID))); + mapper + .createArrayNode() + .add(createColumn(TextColumn.of(SOME_COLUMN_NAME_1, SOME_OBJECT_ID)))); // Act Assert assertThatThrownBy( @@ -602,8 +759,8 @@ public void putObject_FunctionArgumentsGiven_ShouldPutRecordToFunctionTable() .put(OBJECT_ID, SOME_OBJECT_ID) .put(HASH_VALUE, SOME_HASH_VALUE_1) .set(METADATA, SOME_METADATA_1); - JsonNode functionArguments0 = createFunctionArguments(SOME_OBJECT_ID, SOME_VERSION_ID_0, 0, 1L); - JsonNode functionArguments1 = createFunctionArguments(SOME_OBJECT_ID, SOME_VERSION_ID_0, 1, 1L); + JsonNode functionArguments0 = createFunctionArguments(SOME_OBJECT_ID, SOME_VERSION_ID_0, 0); + JsonNode functionArguments1 = createFunctionArguments(SOME_OBJECT_ID, SOME_VERSION_ID_0, 1); Put put = Put.newBuilder() .namespace(getFunctionNamespace()) @@ -648,16 +805,20 @@ public void putObject_FunctionArgumentsGiven_ShouldPutRecordToFunctionTable() .put(TABLE, getFunctionTable()); functionArguments.set( PARTITION_KEY, - mapper.createArrayNode().add(createColumn(SOME_COLUMN_NAME_1, SOME_OBJECT_ID))); + mapper + .createArrayNode() + .add(createColumn(TextColumn.of(SOME_COLUMN_NAME_1, SOME_OBJECT_ID)))); functionArguments.set( CLUSTERING_KEY, - mapper.createArrayNode().add(createColumn(SOME_COLUMN_NAME_2, SOME_VERSION_ID_0))); + mapper + .createArrayNode() + .add(createColumn(TextColumn.of(SOME_COLUMN_NAME_2, SOME_VERSION_ID_0)))); functionArguments.set( COLUMNS, mapper .createArrayNode() - .add(createColumn(SOME_COLUMN_NAME_3, 0)) - .add(createTimestampColumn(SOME_COLUMN_NAME_4, "2024-05-19"))); + .add(createColumn(IntColumn.of(SOME_COLUMN_NAME_3, 0))) + .add(createColumn(SOME_COLUMN_NAME_4, DataType.TIMESTAMP, "2024-05-19"))); // Act Assert assertThatThrownBy( diff --git a/generic-contracts/src/main/java/com/scalar/dl/genericcontracts/object/v1_0_0/PutToMutableDatabase.java b/generic-contracts/src/main/java/com/scalar/dl/genericcontracts/object/v1_0_0/PutToMutableDatabase.java index bef53c6d..9213afc6 100644 --- a/generic-contracts/src/main/java/com/scalar/dl/genericcontracts/object/v1_0_0/PutToMutableDatabase.java +++ b/generic-contracts/src/main/java/com/scalar/dl/genericcontracts/object/v1_0_0/PutToMutableDatabase.java @@ -172,7 +172,10 @@ private Column getColumn(JsonNode jsonColumn) { } if (dataType.equals(DataType.FLOAT)) { - if (!value.isFloat()) { + // The JSON deserializer does not distinguish between float and double values; all JSON + // numbers with a decimal point are deserialized as double. Therefore, we check for isDouble() + // here even for FLOAT columns. + if (!value.isDouble()) { throw new ContractContextException(Constants.INVALID_PUT_MUTABLE_FUNCTION_ARGUMENT_FORMAT); } return FloatColumn.of(columnName, value.floatValue()); @@ -193,7 +196,9 @@ private Column getColumn(JsonNode jsonColumn) { } if (dataType.equals(DataType.BLOB)) { - if (!value.isBinary()) { + // BLOB data is expected as a Base64-encoded string due to JSON limitations. JSON cannot + // represent binary data directly, so BLOBs must be provided as Base64-encoded strings. + if (!value.isTextual()) { throw new ContractContextException(Constants.INVALID_PUT_MUTABLE_FUNCTION_ARGUMENT_FORMAT); } try { diff --git a/generic-contracts/src/test/java/com/scalar/dl/genericcontracts/object/v1_0_0/PutToMutableDatabaseTest.java b/generic-contracts/src/test/java/com/scalar/dl/genericcontracts/object/v1_0_0/PutToMutableDatabaseTest.java index 706a1e17..95182430 100644 --- a/generic-contracts/src/test/java/com/scalar/dl/genericcontracts/object/v1_0_0/PutToMutableDatabaseTest.java +++ b/generic-contracts/src/test/java/com/scalar/dl/genericcontracts/object/v1_0_0/PutToMutableDatabaseTest.java @@ -51,7 +51,8 @@ public class PutToMutableDatabaseTest { private static final String SOME_DOUBLE_COLUMN_NAME = "double_column"; private static final double SOME_DOUBLE_COLUMN_VALUE = 1.23; private static final String SOME_BLOB_COLUMN_NAME = "blob_column"; - private static final byte[] SOME_BLOB_COLUMN_VALUE = {10, 20, 30}; + private static final byte[] SOME_BLOB_COLUMN_VALUE = {1, 2, 3, 4, 5}; + private static final String SOME_BLOB_COLUMN_TEXT = "AQIDBAU="; // Base64 of {1, 2, 3, 4, 5} private static final String SOME_DATE_COLUMN_NAME = "date_column"; private static final String SOME_DATE_COLUMN_TEXT = "2021-02-03"; private static final LocalDate SOME_DATE_COLUMN_VALUE = LocalDate.of(2021, 2, 3); @@ -101,7 +102,10 @@ public class PutToMutableDatabaseTest { mapper .createObjectNode() .put(Constants.COLUMN_NAME, SOME_FLOAT_COLUMN_NAME) - .put(Constants.VALUE, SOME_FLOAT_COLUMN_VALUE) + .put( + Constants.VALUE, + Double.valueOf( + SOME_FLOAT_COLUMN_VALUE)) // float is always converted to double in function args .put(Constants.DATA_TYPE, "FLOAT"); private static final JsonNode SOME_DOUBLE_COLUMN = mapper @@ -113,7 +117,7 @@ public class PutToMutableDatabaseTest { mapper .createObjectNode() .put(Constants.COLUMN_NAME, SOME_BLOB_COLUMN_NAME) - .put(Constants.VALUE, SOME_BLOB_COLUMN_VALUE) + .put(Constants.VALUE, SOME_BLOB_COLUMN_TEXT) .put(Constants.DATA_TYPE, "BLOB"); private static final JsonNode SOME_NULL_COLUMN = mapper @@ -533,9 +537,9 @@ public void invoke_ColumnsWithUnmatchedTypeGiven_ShouldThrowContractContextExcep mapper .createObjectNode() .put(Constants.COLUMN_NAME, SOME_FLOAT_COLUMN_NAME) - .put(Constants.VALUE, SOME_DOUBLE_COLUMN_VALUE) + .put(Constants.VALUE, SOME_INT_COLUMN_VALUE) .put(Constants.DATA_TYPE, "FLOAT"), - "DOUBLE value with FLOAT data type") + "INT value with FLOAT data type") .put( mapper .createObjectNode() @@ -547,16 +551,23 @@ public void invoke_ColumnsWithUnmatchedTypeGiven_ShouldThrowContractContextExcep mapper .createObjectNode() .put(Constants.COLUMN_NAME, SOME_TEXT_COLUMN1_NAME) - .put(Constants.VALUE, SOME_BLOB_COLUMN_VALUE) + .put(Constants.VALUE, SOME_INT_COLUMN_VALUE) .put(Constants.DATA_TYPE, "TEXT"), - "BLOB value with TEXT data type") + "INT value with TEXT data type") .put( mapper .createObjectNode() .put(Constants.COLUMN_NAME, SOME_BLOB_COLUMN_NAME) - .put(Constants.VALUE, SOME_TEXT_COLUMN1_VALUE) + .put(Constants.VALUE, SOME_BLOB_COLUMN_VALUE) .put(Constants.DATA_TYPE, "BLOB"), - "TEXT value with BLOB data type"); + "BLOB value with BLOB data type") + .put( + mapper + .createObjectNode() + .put(Constants.COLUMN_NAME, SOME_TIMESTAMP_COLUMN_NAME) + .put(Constants.VALUE, SOME_BIGINT_COLUMN_VALUE) + .put(Constants.DATA_TYPE, "TIMESTAMP"), + "BIGINT value with TIMESTAMP data type"); // Act Assert builder