diff --git a/org/geekhub/Test.java b/org/geekhub/Test.java index 65e4d30..dc22fa6 100644 --- a/org/geekhub/Test.java +++ b/org/geekhub/Test.java @@ -6,11 +6,12 @@ import org.geekhub.storage.Storage; import java.sql.Connection; +import java.sql.DriverManager; import java.util.List; public class Test { public static void main(String[] args) throws Exception { - Connection connection = createConnection("root", "root", "geekdb"); + Connection connection = createConnection("root", "admin", "geekdb"); Storage storage = new DatabaseStorage(connection); List cats = storage.list(Cat.class); @@ -56,7 +57,6 @@ public static void main(String[] args) throws Exception { } private static Connection createConnection(String login, String password, String dbName) throws Exception { - //implement me: initiate connection - return null; + return DriverManager.getConnection("jdbc:mysql://localhost:3306/" + dbName, login, password); } } diff --git a/org/geekhub/objects/Cat.java b/org/geekhub/objects/Cat.java index 68af6c1..1db9eb8 100644 --- a/org/geekhub/objects/Cat.java +++ b/org/geekhub/objects/Cat.java @@ -1,6 +1,6 @@ package org.geekhub.objects; -public class Cat { +public class Cat extends Entity{ private String name; private int age; diff --git a/org/geekhub/objects/User.java b/org/geekhub/objects/User.java index e29e381..6ef7485 100644 --- a/org/geekhub/objects/User.java +++ b/org/geekhub/objects/User.java @@ -7,6 +7,8 @@ public class User extends Entity { private Integer age; private Boolean admin; private Double balance; + + @Ignore private Date creationDate; public User() { diff --git a/org/geekhub/storage/DatabaseStorage.java b/org/geekhub/storage/DatabaseStorage.java index 385e797..b4b3067 100644 --- a/org/geekhub/storage/DatabaseStorage.java +++ b/org/geekhub/storage/DatabaseStorage.java @@ -1,9 +1,13 @@ package org.geekhub.storage; import org.geekhub.objects.Entity; +import org.geekhub.objects.Ignore; + +import java.lang.reflect.Field; import java.sql.*; -import java.util.List; -import java.util.Map; +import java.sql.Connection; +import java.sql.Statement; +import java.util.*; /** * Implementation of {@link org.geekhub.storage.Storage} that uses database as a storage for objects. @@ -21,7 +25,6 @@ public DatabaseStorage(Connection connection) { @Override public T get(Class clazz, Integer id) throws Exception { - //this method is fully implemented, no need to do anything, it's just an example String sql = "SELECT * FROM " + clazz.getSimpleName() + " WHERE id = " + id; try(Statement statement = connection.createStatement()) { List result = extractResult(clazz, statement.executeQuery(sql)); @@ -31,14 +34,19 @@ public T get(Class clazz, Integer id) throws Exception { @Override public List list(Class clazz) throws Exception { - //implement me according to interface by using extractResult method - return null; + String sql = "SELECT * FROM " + clazz.getSimpleName(); + try (Statement statement = connection.createStatement()) { + List result = extractResult(clazz, statement.executeQuery(sql)); + return result.isEmpty() ? Collections.emptyList() : result; + } } @Override public boolean delete(T entity) throws Exception { - //implement me - return false; + String sql = "DELETE FROM " + entity.getClass().getSimpleName() + " WHERE id=" + entity.getId(); + try (Statement statement = connection.createStatement()) { + return 0 != statement.executeUpdate(sql); + } } @Override @@ -47,25 +55,79 @@ public void save(T entity) throws Exception { String sql = null; if (entity.isNew()) { - //implement me - //need to define right SQL query to create object + StringBuilder columnName = new StringBuilder(); + StringBuilder values = new StringBuilder(); + + for (Map.Entry entry : data.entrySet()) { + columnName.append(entry.getKey()).append(", "); + values.append("'").append(entry.getValue()).append("', "); + } + + columnName.setLength(columnName.length() - 2); + values.setLength(values.length() - 2); + + sql = "INSERT INTO " + entity.getClass().getSimpleName() + " ( " + columnName + " ) VALUES " + " ( " + values + " ) "; + } else { - //implement me - //need to define right SQL query to update object + sql = "UPDATE " + entity.getClass().getSimpleName() + " SET "; + + for (Map.Entry entry : data.entrySet()) { + sql += entry.getKey() + " = '" + entry.getValue().toString() + "', "; + } + + sql = sql.substring(0, sql.length() - 2); + sql += " WHERE id = " + entity.getId(); } - //implement me, need to save/update object and update it with new id if it's a creation + try (Statement statement = connection.createStatement()) { + statement.executeUpdate(sql); + + if (entity.isNew()) { + ResultSet resultSet = statement.getGeneratedKeys(); + resultSet.next(); + entity.setId(resultSet.getInt(1)); + } + } } //converts object to map, could be helpful in save method private Map prepareEntity(T entity) throws Exception { - //implement me - return null; + Map data = new HashMap<>(); + Field[] fields = entity.getClass().getDeclaredFields(); + + for (Field field : fields) { + field.setAccessible(true); + if (!field.isAnnotationPresent(Ignore.class)) { + if (field.getType().equals(Boolean.class)) { + data.put(field.getName(), (Boolean)field.get(entity) ? 1 : 0); + } else { + data.put(field.getName(), field.get(entity)); + } + } + } + + return data; } //creates list of new instances of clazz by using data from resultset private List extractResult(Class clazz, ResultSet resultset) throws Exception { - //implement me - return null; + List data = new ArrayList<>(); + Field[] fields = clazz.getDeclaredFields(); + + while (resultset.next()) { + T entity = clazz.newInstance(); + entity.setId(resultset.getInt("id")); + + for (Field field : fields) { + field.setAccessible(true); + if (!field.isAnnotationPresent(Ignore.class)) { + field.set(entity, resultset.getObject(field.getName())); + } + } + + data.add(entity); + } + + return data; } }