diff --git a/build.gradle b/build.gradle index de9ce6e..118b972 100644 --- a/build.gradle +++ b/build.gradle @@ -1,5 +1,5 @@ group 'com.codurance' -version '0.1.0' +version '0.2.0' apply plugin: 'java' diff --git a/src/main/java/com/codurance/lightaccess/connection/PreparedStatementBuilder.java b/src/main/java/com/codurance/lightaccess/connection/PreparedStatementBuilder.java index cdb12d3..c573dd2 100644 --- a/src/main/java/com/codurance/lightaccess/connection/PreparedStatementBuilder.java +++ b/src/main/java/com/codurance/lightaccess/connection/PreparedStatementBuilder.java @@ -31,6 +31,10 @@ public PreparedStatementBuilder withParam(LocalDate param) { return withParam((paramIndex) -> execute(() -> preparedStatement.setDate(paramIndex, Date.valueOf(param)))); } + public PreparedStatementBuilder withParam(Long param) { + return withParam((paramIndex) -> execute(() -> preparedStatement.setLong(paramIndex, param))); + } + public void executeUpdate() { execute(() -> { preparedStatement.executeUpdate(); diff --git a/src/main/java/com/codurance/lightaccess/mapping/LAResultSet.java b/src/main/java/com/codurance/lightaccess/mapping/LAResultSet.java index 3277e97..96b6a14 100644 --- a/src/main/java/com/codurance/lightaccess/mapping/LAResultSet.java +++ b/src/main/java/com/codurance/lightaccess/mapping/LAResultSet.java @@ -21,6 +21,10 @@ public int getInt(int columnIndex) { return executeQuery(() -> resultSet.getInt(columnIndex)); } + public Long getLong(int columnIndex) { + return executeQuery(() -> resultSet.getLong(columnIndex)); + } + public String getString(int columnIndex) { String stringValue = executeQuery(() -> resultSet.getString(columnIndex)); return (stringValue != null) ? stringValue : ""; diff --git a/src/test/java/com/codurance/lightaccess/mapping/LAResultSetShould.java b/src/test/java/com/codurance/lightaccess/mapping/LAResultSetShould.java index 946dec8..c840260 100644 --- a/src/test/java/com/codurance/lightaccess/mapping/LAResultSetShould.java +++ b/src/test/java/com/codurance/lightaccess/mapping/LAResultSetShould.java @@ -195,6 +195,21 @@ public void initialise() { assertThat(persons).isEqualTo(expected); } + @Test public void + return_zero_when_long_field_is_null() throws SQLException { + // JDBC java.sql.ResultSet.getInt(int columnindex) returns 0 when field is null. + given(resultSet.getLong(1)).willReturn(0L); + + assertThat(laResultSet.getLong(1)).isEqualTo(0); + } + + @Test public void + return_long_when_int_field_has_value() throws SQLException { + given(resultSet.getLong(1)).willReturn(10L); + + assertThat(laResultSet.getLong(1)).isEqualTo(10L); + } + @Test public void move_to_next_record() throws SQLException { laResultSet.nextRecord(); diff --git a/src/test/java/integration/LightAccessIntegrationTest.java b/src/test/java/integration/LightAccessIntegrationTest.java index 69ff0fb..658a3af 100644 --- a/src/test/java/integration/LightAccessIntegrationTest.java +++ b/src/test/java/integration/LightAccessIntegrationTest.java @@ -5,6 +5,7 @@ import com.codurance.lightaccess.executables.SQLCommand; import com.codurance.lightaccess.executables.SQLQuery; import com.codurance.lightaccess.mapping.LAResultSet; +import integration.dtos.Item; import integration.dtos.Product; import integration.dtos.ProductID; import org.h2.jdbcx.JdbcConnectionPool; @@ -24,6 +25,7 @@ public class LightAccessIntegrationTest { private static final String CREATE_PRODUCTS_TABLE = "CREATE TABLE products (id VARCHAR(255) PRIMARY KEY, name VARCHAR(255), date TIMESTAMP)"; + private static final String CREATE_ITEMS_TABLE = "CREATE TABLE items (id BIGINT PRIMARY KEY, name VARCHAR(255))"; private static final String CREATE_SEQUENCE_DDL = "CREATE SEQUENCE %s START WITH %s"; private static final String DROP_ALL_OBJECTS = "DROP ALL OBJECTS"; @@ -33,6 +35,9 @@ public class LightAccessIntegrationTest { private static final String UPDATE_PRODUCT_NAME_SQL = "update products set name = ? where id = ?"; private static final String SELECT_ALL_PRODUCTS_SQL = "select * from products"; private static final String SELECT_PRODUCT_BY_ID_SQL = "select * from products where id = ?"; + private static final String INSERT_ITEM_SQL = "insert into items (id, name) values (?, ?)"; + private static final String SELECT_ITEM_BY_ID_SQL = "select id, name from items where id = ?"; + private static final LocalDate TODAY = LocalDate.of(2017, 07, 27); private static final LocalDate YESTERDAY = LocalDate.of(2017, 07, 26); @@ -40,6 +45,8 @@ public class LightAccessIntegrationTest { private static Product PRODUCT_ONE = new Product(1, "Product 1", YESTERDAY); private static Product PRODUCT_TWO = new Product(2, "Product 2", TODAY); + private static Item SINGLE_ITEM = new Item(112345L, "9 Pound Hammer"); + private static LightAccess lightAccess; private static JdbcConnectionPool jdbcConnectionPool; @@ -52,6 +59,7 @@ public static void before_all_tests() throws SQLException { @Before public void before_each_test() throws Exception { lightAccess.executeDDLCommand(createProductsTable()); + lightAccess.executeDDLCommand(createItemsTable()); } @After @@ -82,8 +90,8 @@ public void after_each_test() throws Exception { @Test public void insert_records() { - lightAccess.executeCommand(insert(PRODUCT_ONE)); - lightAccess.executeCommand(insert(PRODUCT_TWO)); + lightAccess.executeCommand(insertProduct(PRODUCT_ONE)); + lightAccess.executeCommand(insertProduct(PRODUCT_TWO)); List products = lightAccess.executeQuery(retrieveAllProducts()); @@ -92,8 +100,8 @@ public void after_each_test() throws Exception { @Test public void retrieve_a_single_record_and_map_it_to_an_object() { - lightAccess.executeCommand(insert(PRODUCT_ONE)); - lightAccess.executeCommand(insert(PRODUCT_TWO)); + lightAccess.executeCommand(insertProduct(PRODUCT_ONE)); + lightAccess.executeCommand(insertProduct(PRODUCT_TWO)); Optional product = lightAccess.executeQuery(retrieveProductWithId(PRODUCT_TWO.id())); @@ -102,7 +110,7 @@ public void after_each_test() throws Exception { @Test public void retrieve_an_empty_optional_when_not_record_is_found() { - lightAccess.executeCommand(insert(PRODUCT_ONE)); + lightAccess.executeCommand(insertProduct(PRODUCT_ONE)); Optional product = lightAccess.executeQuery(retrieveProductWithId(PRODUCT_TWO.id())); @@ -111,8 +119,8 @@ public void after_each_test() throws Exception { @Test public void delete_a_record() { - lightAccess.executeCommand(insert(PRODUCT_ONE)); - lightAccess.executeCommand(insert(PRODUCT_TWO)); + lightAccess.executeCommand(insertProduct(PRODUCT_ONE)); + lightAccess.executeCommand(insertProduct(PRODUCT_TWO)); lightAccess.executeCommand(delete(PRODUCT_ONE)); @@ -122,7 +130,7 @@ public void after_each_test() throws Exception { @Test public void update_a_record() { - lightAccess.executeCommand(insert(PRODUCT_ONE)); + lightAccess.executeCommand(insertProduct(PRODUCT_ONE)); lightAccess.executeCommand(updateProductName(1, "Another name")); Optional product = lightAccess.executeQuery(retrieveProductWithId(PRODUCT_ONE.id())); @@ -152,6 +160,16 @@ public void after_each_test() throws Exception { assertThat(secondId).isEqualTo(new ProductID(11)); } + @Test public void + return_item_when_exists() { + lightAccess.executeCommand(insertItem(SINGLE_ITEM)); + + Optional item = lightAccess.executeQuery(conn -> conn.prepareStatement(SELECT_ITEM_BY_ID_SQL).withParam(SINGLE_ITEM.id) + .executeQuery().onlyResult(this::toItem)); + + assertThat(item.get()).isEqualTo(SINGLE_ITEM); + } + private SQLCommand updateProductName(int id, String name) { return conn -> conn.prepareStatement(UPDATE_PRODUCT_NAME_SQL) .withParam(name) @@ -165,7 +183,7 @@ private SQLCommand delete(Product product) { .executeUpdate(); } - private SQLCommand insert(Product product) { + private SQLCommand insertProduct(Product product) { return conn -> conn.prepareStatement(INSERT_PRODUCT_SQL) .withParam(product.id()) .withParam(product.name()) @@ -173,6 +191,13 @@ private SQLCommand insert(Product product) { .executeUpdate(); } + private SQLCommand insertItem(Item item) { + return conn -> conn.prepareStatement(INSERT_ITEM_SQL) + .withParam(item.id) + .withParam(item.name) + .executeUpdate(); + } + private SQLQuery> retrieveProductWithId(int id) { return conn -> conn.prepareStatement(SELECT_PRODUCT_BY_ID_SQL) .withParam(id) @@ -196,6 +221,11 @@ private Product toProduct(LAResultSet laResultSet) { laResultSet.getLocalDate(3)); } + private Item toItem(LAResultSet laResultSet) { + return new Item(laResultSet.getLong(1), + laResultSet.getString(2)); + } + private DDLCommand createSequence(String sequenceName, String initialValue) { String id_sequence = format(CREATE_SEQUENCE_DDL, sequenceName, initialValue); return (conn) -> conn.statement(id_sequence).execute(); @@ -205,6 +235,10 @@ private DDLCommand createProductsTable() { return (conn) -> conn.statement(CREATE_PRODUCTS_TABLE).execute(); } + private DDLCommand createItemsTable() { + return (conn) -> conn.statement(CREATE_ITEMS_TABLE).execute(); + } + private DDLCommand dropAllObjects() { return (conn) -> conn.statement(DROP_ALL_OBJECTS).execute(); } diff --git a/src/test/java/integration/dtos/Item.java b/src/test/java/integration/dtos/Item.java new file mode 100644 index 0000000..465284b --- /dev/null +++ b/src/test/java/integration/dtos/Item.java @@ -0,0 +1,26 @@ +package integration.dtos; + +import static org.apache.commons.lang3.builder.EqualsBuilder.reflectionEquals; +import static org.apache.commons.lang3.builder.HashCodeBuilder.reflectionHashCode; + +public class Item { + + public Long id; + + public String name; + + public Item(Long id, String name) { + this.id = id; + this.name = name; + } + + @Override + public boolean equals(Object other) { + return reflectionEquals(this, other); + } + + @Override + public int hashCode() { + return reflectionHashCode(this); + } +}