From b3fba438ae75c78244c488e37c8e5b3c5765c804 Mon Sep 17 00:00:00 2001 From: David Conrad Date: Mon, 18 Jun 2012 15:32:46 -0400 Subject: [PATCH] Test for David Conrad; refactor Person, implement unimplemented methods plus a few extras, added tests, use commons-dbutils --- .classpath | 19 ++- lib/commons-dbutils-1.4.jar | Bin 0 -> 49572 bytes .../proquest/interview/phonebook/Person.java | 86 +++++++++- .../interview/phonebook/PhoneBook.java | 7 +- .../interview/phonebook/PhoneBookImpl.java | 161 ++++++++++++++++-- .../proquest/interview/util/DatabaseUtil.java | 11 +- .../phonebook/PhoneBookImplTest.java | 56 +++++- 7 files changed, 306 insertions(+), 34 deletions(-) create mode 100644 lib/commons-dbutils-1.4.jar diff --git a/.classpath b/.classpath index 3300db2..42620d7 100644 --- a/.classpath +++ b/.classpath @@ -1,9 +1,10 @@ - - - - - - - - - + + + + + + + + + + diff --git a/lib/commons-dbutils-1.4.jar b/lib/commons-dbutils-1.4.jar new file mode 100644 index 0000000000000000000000000000000000000000..7b846eab124d01c0082bee0328bf8f5a9c665f62 GIT binary patch literal 49572 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 allPeople(); } diff --git a/src/com/proquest/interview/phonebook/PhoneBookImpl.java b/src/com/proquest/interview/phonebook/PhoneBookImpl.java index d7eb6fe..d2b0797 100644 --- a/src/com/proquest/interview/phonebook/PhoneBookImpl.java +++ b/src/com/proquest/interview/phonebook/PhoneBookImpl.java @@ -1,31 +1,162 @@ package com.proquest.interview.phonebook; +import java.sql.Connection; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; import java.util.List; +import org.apache.commons.dbutils.DbUtils; +import org.apache.commons.dbutils.QueryRunner; +import org.apache.commons.dbutils.ResultSetHandler; + import com.proquest.interview.util.DatabaseUtil; public class PhoneBookImpl implements PhoneBook { - public List people; - + public List people = new ArrayList(); + @Override public void addPerson(Person newPerson) { - //TODO: write this method + if (newPerson == null) throw new IllegalArgumentException("null"); + people.add(newPerson); } - + @Override - public Person findPerson() { - //TODO: write this method + public Person findPerson(String firstName, String lastName) { + if (firstName == null || lastName == null) { + throw new IllegalArgumentException("null"); + // the other option here is to return null, indicating not found + } + final String nameSought = firstName + " " + lastName; + for (Person person : people) { + if (nameSought.equals(person.getName())) return person; + } + return null; + } + + public Collection allPeople() { + return Collections.unmodifiableList(people); } + @Override public String toString() { + return people.toString(); + } + public static void main(String[] args) { - DatabaseUtil.initDB(); //You should not remove this line, it creates the in-memory database - - /* TODO: create person objects and put them in the PhoneBook and database - * John Smith, (248) 123-4567, 1234 Sand Hill Dr, Royal Oak, MI - * Cynthia Smith, (824) 128-8758, 875 Main St, Ann Arbor, MI - */ - // TODO: print the phone book out to System.out - // TODO: find Cynthia Smith and print out just her entry - // TODO: insert the new person objects into the database + DatabaseUtil.initDB(); // You should not remove this line, it creates the in-memory database + + PhoneBook phoneBook = new PhoneBookImpl(); + + // create person objects and put them in the PhoneBook and database + + phoneBook.addPerson(new Person("John Smith", "(248) 123-4567", + "1234 Sand Hill Dr, Royal Oak, MI")); + phoneBook.addPerson(new Person("Cynthia Smith", "(824) 128-8758", + "875 Main St, Ann Arbor, MI")); + + // print the phone book out to System.out + + // It isn't clear to me which of these you want: + + System.out.println(phoneBook); + + for (Person person : phoneBook.allPeople()) { + System.out.println(person); + } + + // find Cynthia Smith and print out just her entry + + System.out.println("Cynthia:"); + Person cynthiaSmith = phoneBook.findPerson("Cynthia", "Smith"); + System.out.println(cynthiaSmith); + + // It was a little unclear when you wanted me to add the objects + // to the database. At the top, you said to add people to the + // phone book and the database, but at the end, you said to add + // the new people to the database. + + // insert the new person objects into the database + + insertPeople(phoneBook.allPeople()); + } + + public static ResultSetHandler> rowsToPeople() { + return new ResultSetHandler>() { + public List handle(ResultSet rs) throws SQLException { + List people = new ArrayList(); + while (rs.next()) { + people.add(new Person(rs.getString(1), rs.getString(2), rs.getString(3))); + } + return people; + } + }; + } + + public static List byCriteria(String sql, Object... criteria) { + Connection con = null; + try { + con = getConnection(); + return new QueryRunner().query(con, sql, rowsToPeople(), criteria); + } catch (SQLException e) { + e.printStackTrace(); + // questionable; maybe we should throw some application-specific exception to indicate failure + return new ArrayList(); + } finally { + DbUtils.closeQuietly(con); + } + } + + public static List everyone() { + return byCriteria("SELECT * FROM PHONEBOOK", new Object[] {}); + } + + public static List byName(String name) { + return byCriteria("SELECT * FROM PHONEBOOK WHERE NAME = ?", name); + } + + public static List byPhoneNumber(String phoneNumber) { + return byCriteria("SELECT * FROM PHONEBOOK WHERE PHONENUMBER = ?", phoneNumber); + } + + public static List byAddress(String address) { + return byCriteria("SELECT * FROM PHONEBOOK WHERE ADDRESS = ?", address); + } + + public static void insertPeople(Collection people) { + final String sql = + "INSERT INTO PHONEBOOK (NAME, PHONENUMBER, ADDRESS) VALUES(?, ?, ?)"; + + Connection con = null; + PreparedStatement ps = null; + + try { + con = getConnection(); + con.setAutoCommit(false); + ps = con.prepareStatement(sql); + QueryRunner q = new QueryRunner(); + for (Person person : people) { + q.fillStatementWithBean(ps, person, "name", "phoneNumber", "address"); + ps.addBatch(); + } + ps.executeBatch(); + con.commit(); + } catch (SQLException e) { + e.printStackTrace(); + } finally { + DbUtils.closeQuietly(ps); + DbUtils.closeQuietly(con); + } + } + + public static Connection getConnection() throws SQLException { + try { + return DatabaseUtil.getConnection(); + } catch (ClassNotFoundException e) { + // avoid dealing with CNFE; we aren't going to do anything different in that case anyway + throw new SQLException(e); + } } } diff --git a/src/com/proquest/interview/util/DatabaseUtil.java b/src/com/proquest/interview/util/DatabaseUtil.java index a23342d..8e690de 100644 --- a/src/com/proquest/interview/util/DatabaseUtil.java +++ b/src/com/proquest/interview/util/DatabaseUtil.java @@ -5,25 +5,30 @@ import java.sql.SQLException; import java.sql.Statement; +import org.apache.commons.dbutils.DbUtils; + /** * This class is just a utility class, you should not have to change anything here * @author rconklin */ public class DatabaseUtil { public static void initDB() { + Connection cn = null; try { - Connection cn = getConnection(); + cn = getConnection(); + cn.setAutoCommit(false); Statement stmt = cn.createStatement(); stmt.execute("CREATE TABLE PHONEBOOK (NAME varchar(255), PHONENUMBER varchar(255), ADDRESS varchar(255))"); stmt.execute("INSERT INTO PHONEBOOK (NAME, PHONENUMBER, ADDRESS) VALUES('Chris Johnson','(321) 231-7876', '452 Freeman Drive, Algonac, MI')"); stmt.execute("INSERT INTO PHONEBOOK (NAME, PHONENUMBER, ADDRESS) VALUES('Dave Williams','(231) 502-1236', '285 Huron St, Port Austin, MI')"); cn.commit(); - cn.close(); } catch (Exception ex) { ex.printStackTrace(); + } finally { + DbUtils.closeQuietly(cn); } - } + public static Connection getConnection() throws SQLException, ClassNotFoundException { Class.forName("org.hsqldb.jdbcDriver"); return DriverManager.getConnection("jdbc:hsqldb:mem", "sa", ""); diff --git a/test/com/proquest/interview/phonebook/PhoneBookImplTest.java b/test/com/proquest/interview/phonebook/PhoneBookImplTest.java index 33c7c14..e39e1de 100644 --- a/test/com/proquest/interview/phonebook/PhoneBookImplTest.java +++ b/test/com/proquest/interview/phonebook/PhoneBookImplTest.java @@ -1,10 +1,62 @@ package com.proquest.interview.phonebook; +import org.junit.Before; import org.junit.Test; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; public class PhoneBookImplTest { + private PhoneBook phoneBook; + + @Before + public void setUp() { + phoneBook = new PhoneBookImpl(); + phoneBook.addPerson(new Person("David Conrad", "(313) 437-3173", + "17540 Mack Ave #4, Grosse Pointe, MI")); + } + + @Test + public void emptyPhoneBookTest() { + phoneBook = new PhoneBookImpl(); + assertEquals(phoneBook.allPeople().size(), 0); + } + + @Test + public void addPersonTest() { + int formerSize = phoneBook.allPeople().size(); + phoneBook.addPerson(new Person("Jane Doe", "(313) 555-1212", + "123 Elm Ct, Anytown, MI")); + assertEquals(phoneBook.allPeople().size(), formerSize + 1); + } + + @Test(expected=IllegalArgumentException.class) + public void addNullPersonTest() { + phoneBook.addPerson(null); + } + @Test - public void shouldAddFindPerson() { - + public void findPersonTest() { + assertNotNull(phoneBook.findPerson("David", "Conrad")); + } + + @Test + public void noSuchPersonTest() { + assertNull(phoneBook.findPerson("Joe", "Schmoe")); + } + + @Test(expected=IllegalArgumentException.class) + public void findNullPersonTest() { + phoneBook.findPerson(null, null); + } + + @Test(expected=IllegalArgumentException.class) + public void findNullFirstNameTest() { + phoneBook.findPerson(null, "Jones"); + } + + @Test(expected=IllegalArgumentException.class) + public void findNullLastNameTest() { + phoneBook.findPerson("Dev", null); } }