diff --git a/dao/pom.xml b/dao/pom.xml
index 3b6fc7d1e..3f22a0cc6 100644
--- a/dao/pom.xml
+++ b/dao/pom.xml
@@ -44,6 +44,14 @@
log4j
log4j
+
+ com.h2database
+ h2
+
+
+ de.bechte.junit
+ junit-hierarchicalcontextrunner
+
diff --git a/dao/src/main/java/com/iluwatar/dao/DBCustomerDao.java b/dao/src/main/java/com/iluwatar/dao/DBCustomerDao.java
index fb53c1fed..1b9c4b981 100644
--- a/dao/src/main/java/com/iluwatar/dao/DBCustomerDao.java
+++ b/dao/src/main/java/com/iluwatar/dao/DBCustomerDao.java
@@ -1,38 +1,130 @@
package com.iluwatar.dao;
+import java.sql.Connection;
+import java.sql.DriverManager;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.util.Spliterator;
+import java.util.Spliterators;
+import java.util.function.Consumer;
import java.util.stream.Stream;
+import java.util.stream.StreamSupport;
public class DBCustomerDao implements CustomerDao {
- @Override
- public Stream getAll() {
- // TODO Auto-generated method stub
- return null;
+ private String dbUrl;
+
+ public DBCustomerDao(String dbUrl) {
+ this.dbUrl = dbUrl;
}
+ @Override
+ public Stream getAll() {
+
+ Connection connection;
+ try {
+ connection = getConnection();
+ PreparedStatement statement = connection.prepareStatement("SELECT * FROM CUSTOMERS");
+ ResultSet resultSet = statement.executeQuery();
+ return StreamSupport.stream(new Spliterators.AbstractSpliterator(Long.MAX_VALUE, Spliterator.ORDERED) {
+
+ @Override
+ public boolean tryAdvance(Consumer super Customer> action) {
+ try {
+ if (!resultSet.next()) {
+ return false;
+ }
+ action.accept(createCustomer(resultSet));
+ return true;
+ } catch (SQLException e) {
+ e.printStackTrace();
+ return false;
+ }
+
+ }}, false).onClose(() -> mutedClose(connection));
+ } catch (SQLException e) {
+ e.printStackTrace();
+ return null;
+ }
+ }
+
+ private void mutedClose(Connection connection) {
+ try {
+ connection.close();
+ } catch (SQLException e) {
+ e.printStackTrace();
+ }
+ }
+
+ private Customer createCustomer(ResultSet resultSet) throws SQLException {
+ return new Customer(resultSet.getInt("ID"),
+ resultSet.getString("FNAME"),
+ resultSet.getString("LNAME"));
+ }
+
@Override
public Customer getById(int id) {
- // TODO Auto-generated method stub
+ try (Connection connection = getConnection();
+ PreparedStatement statement = connection.prepareStatement("SELECT * FROM CUSTOMERS WHERE ID = ?")) {
+ statement.setInt(1, id);
+ ResultSet resultSet = statement.executeQuery();
+ if (resultSet.next()) {
+ return createCustomer(resultSet);
+ }
+ } catch (SQLException ex) {
+ ex.printStackTrace();
+ }
return null;
}
@Override
public boolean add(Customer customer) {
- // TODO Auto-generated method stub
- return false;
+ if (getById(customer.getId()) != null) {
+ return false;
+ }
+
+ try (Connection connection = getConnection();
+ PreparedStatement statement = connection.prepareStatement("INSERT INTO CUSTOMERS VALUES (?,?,?)")) {
+ statement.setInt(1, customer.getId());
+ statement.setString(2, customer.getFirstName());
+ statement.setString(3, customer.getLastName());
+ statement.execute();
+ return true;
+ } catch (SQLException ex) {
+ ex.printStackTrace();
+ return false;
+ }
}
@Override
public boolean update(Customer customer) {
- // TODO Auto-generated method stub
- return false;
+ try (Connection connection = getConnection();
+ PreparedStatement statement = connection.prepareStatement("UPDATE CUSTOMERS SET FNAME = ?, LNAME = ? WHERE ID = ?")) {
+ statement.setString(1, customer.getFirstName());
+ statement.setString(2, customer.getLastName());
+ statement.setInt(3, customer.getId());
+ return statement.executeUpdate() > 0;
+ } catch (SQLException ex) {
+ ex.printStackTrace();
+ return false;
+ }
}
@Override
public boolean delete(Customer customer) {
- // TODO Auto-generated method stub
- return false;
+ try (Connection connection = getConnection();
+ PreparedStatement statement = connection.prepareStatement("DELETE FROM CUSTOMERS WHERE ID = ?")) {
+ statement.setInt(1, customer.getId());
+ return statement.executeUpdate() > 0;
+ } catch (SQLException ex) {
+ ex.printStackTrace();
+ return false;
+ }
}
+ private Connection getConnection() throws SQLException {
+ return DriverManager.getConnection(dbUrl);
+ }
}
diff --git a/dao/src/test/java/com/iluwatar/dao/DBCustomerDaoTest.java b/dao/src/test/java/com/iluwatar/dao/DBCustomerDaoTest.java
new file mode 100644
index 000000000..202140e98
--- /dev/null
+++ b/dao/src/test/java/com/iluwatar/dao/DBCustomerDaoTest.java
@@ -0,0 +1,149 @@
+package com.iluwatar.dao;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assume.assumeTrue;
+
+import java.sql.Connection;
+import java.sql.DriverManager;
+import java.sql.SQLException;
+import java.sql.Statement;
+import java.util.stream.Stream;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import de.bechte.junit.runners.context.HierarchicalContextRunner;
+
+@RunWith(HierarchicalContextRunner.class)
+public class DBCustomerDaoTest {
+
+ private static final String DB_URL = "jdbc:h2:~/dao:customerdb";
+ private DBCustomerDao dao;
+ private Customer existingCustomer = new Customer(1, "Freddy", "Krueger");
+
+ @Before
+ public void createSchema() throws SQLException {
+ try (Connection connection = DriverManager.getConnection(DB_URL);
+ Statement statement = connection.createStatement()) {
+ statement.execute("CREATE TABLE CUSTOMERS (ID NUMBER, FNAME VARCHAR(100), LNAME VARCHAR(100))");
+ }
+ }
+
+ @Before
+ public void setUp() {
+ dao = new DBCustomerDao(DB_URL);
+ boolean result = dao.add(existingCustomer);
+ assumeTrue(result);
+ }
+
+ public class NonExistantCustomer {
+
+ @Test
+ public void addingShouldResultInSuccess() {
+ try (Stream allCustomers = dao.getAll()) {
+ assumeTrue(allCustomers.count() == 1);
+ }
+
+ final Customer nonExistingCustomer = new Customer(2, "Robert", "Englund");
+ boolean result = dao.add(nonExistingCustomer);
+ assertTrue(result);
+
+ assertCustomerCountIs(2);
+ assertEquals(nonExistingCustomer, dao.getById(nonExistingCustomer.getId()));
+ }
+
+ @Test
+ public void deletionShouldBeFailureAndNotAffectExistingCustomers() {
+ final Customer nonExistingCustomer = new Customer(2, "Robert", "Englund");
+ boolean result = dao.delete(nonExistingCustomer);
+
+ assertFalse(result);
+ assertCustomerCountIs(1);
+ }
+
+ @Test
+ public void updationShouldBeFailureAndNotAffectExistingCustomers() {
+ final int nonExistingId = getNonExistingCustomerId();
+ final String newFirstname = "Douglas";
+ final String newLastname = "MacArthur";
+ final Customer customer = new Customer(nonExistingId, newFirstname, newLastname);
+ boolean result = dao.update(customer);
+
+ assertFalse(result);
+ assertNull(dao.getById(nonExistingId));
+ }
+
+ @Test
+ public void retrieveShouldReturnNull() {
+ assertNull(dao.getById(getNonExistingCustomerId()));
+ }
+
+ }
+
+ public class ExistingCustomer {
+
+ @Test
+ public void addingShouldResultInFailureAndNotAffectExistingCustomers() {
+ Customer existingCustomer = new Customer(1, "Freddy", "Krueger");
+
+ boolean result = dao.add(existingCustomer);
+
+ assertFalse(result);
+ assertCustomerCountIs(1);
+ assertEquals(existingCustomer, dao.getById(existingCustomer.getId()));
+ }
+
+ @Test
+ public void deletionShouldBeSuccessAndCustomerShouldBeNonAccessible() {
+ boolean result = dao.delete(existingCustomer);
+
+ assertTrue(result);
+ assertCustomerCountIs(0);
+ assertNull(dao.getById(existingCustomer.getId()));
+ }
+
+ @Test
+ public void updationShouldBeSuccessAndAccessingTheSameCustomerShouldReturnUpdatedInformation() {
+ final String newFirstname = "Bernard";
+ final String newLastname = "Montgomery";
+ final Customer customer = new Customer(existingCustomer.getId(), newFirstname, newLastname);
+ boolean result = dao.update(customer);
+
+ assertTrue(result);
+
+ final Customer cust = dao.getById(existingCustomer.getId());
+ assertEquals(newFirstname, cust.getFirstName());
+ assertEquals(newLastname, cust.getLastName());
+ }
+
+ }
+
+ @After
+ public void deleteSchema() throws SQLException {
+ try (Connection connection = DriverManager.getConnection(DB_URL);
+ Statement statement = connection.createStatement()) {
+ statement.execute("DROP TABLE CUSTOMERS");
+ }
+ }
+
+ private void assertCustomerCountIs(int count) {
+ try (Stream allCustomers = dao.getAll()) {
+ assertTrue(allCustomers.count() == count);
+ }
+ }
+
+
+ /**
+ * An arbitrary number which does not correspond to an active Customer id.
+ *
+ * @return an int of a customer id which doesn't exist
+ */
+ private int getNonExistingCustomerId() {
+ return 999;
+ }
+}
diff --git a/pom.xml b/pom.xml
index 555844660..524a0261b 100644
--- a/pom.xml
+++ b/pom.xml
@@ -50,6 +50,7 @@
19.0
1.15.1
1.10.19
+ 4.12.1
abstract-factory
@@ -195,6 +196,12 @@
${systemrules.version}
test
+
+ de.bechte.junit
+ junit-hierarchicalcontextrunner
+ ${hierarchical-junit-runner-version}
+ test
+