diff --git a/src/ru/javawebinar/basejava/Config.java b/src/ru/javawebinar/basejava/Config.java index 492c24b..3f71ee4 100644 --- a/src/ru/javawebinar/basejava/Config.java +++ b/src/ru/javawebinar/basejava/Config.java @@ -12,6 +12,9 @@ public class Config { private Properties props = new Properties(); private File storageDir; + private String dbUrl; + private String dbUser; + private String dbPassword; public static Config get() { return INSTANCE; @@ -21,6 +24,9 @@ private Config() { try (InputStream is = new FileInputStream(PROPS)) { props.load(is); storageDir = new File(props.getProperty("storage.dir")); + dbUrl = props.getProperty("db.url"); + dbUser = props.getProperty("db.user"); + dbPassword = props.getProperty("db.password"); } catch (IOException e) { throw new IllegalStateException("Invalid config file " + PROPS.getAbsolutePath()); } @@ -29,4 +35,16 @@ private Config() { public File getStorageDir() { return storageDir; } + + public String getDbUrl() { + return dbUrl; + } + + public String getDbUser() { + return dbUser; + } + + public String getDbPassword() { + return dbPassword; + } } \ No newline at end of file diff --git a/src/ru/javawebinar/basejava/sql/ABlockOfCode.java b/src/ru/javawebinar/basejava/sql/ABlockOfCode.java new file mode 100644 index 0000000..2aef8b7 --- /dev/null +++ b/src/ru/javawebinar/basejava/sql/ABlockOfCode.java @@ -0,0 +1,8 @@ +package ru.javawebinar.basejava.sql; + +import java.sql.PreparedStatement; +import java.sql.SQLException; + +public interface ABlockOfCode { + Object accept(PreparedStatement ps) throws SQLException; +} diff --git a/src/ru/javawebinar/basejava/sql/TransactionTemplate.java b/src/ru/javawebinar/basejava/sql/TransactionTemplate.java new file mode 100644 index 0000000..370c75d --- /dev/null +++ b/src/ru/javawebinar/basejava/sql/TransactionTemplate.java @@ -0,0 +1,26 @@ +package ru.javawebinar.basejava.sql; + +import ru.javawebinar.basejava.exception.StorageException; + +import java.sql.Connection; +import java.sql.DriverManager; +import java.sql.PreparedStatement; +import java.sql.SQLException; + +public class TransactionTemplate { + + public final ConnectionFactory connectionFactory; + + public TransactionTemplate(String dbUrl, String dbUser, String dbPassword) { + connectionFactory = () -> DriverManager.getConnection(dbUrl, dbUser, dbPassword); + } + + public Object action(String sql, ABlockOfCode aBlockOfCode) { + try (Connection conn = connectionFactory.getConnection(); + PreparedStatement ps = conn.prepareStatement(sql)) { + return aBlockOfCode.accept(ps); + } catch (SQLException e) { + throw new StorageException(e); + } + } +} diff --git a/src/ru/javawebinar/basejava/storage/SqlStorage.java b/src/ru/javawebinar/basejava/storage/SqlStorage.java index 87e6d7b..528b630 100644 --- a/src/ru/javawebinar/basejava/storage/SqlStorage.java +++ b/src/ru/javawebinar/basejava/storage/SqlStorage.java @@ -1,74 +1,96 @@ package ru.javawebinar.basejava.storage; import ru.javawebinar.basejava.exception.NotExistStorageException; -import ru.javawebinar.basejava.exception.StorageException; import ru.javawebinar.basejava.model.Resume; -import ru.javawebinar.basejava.sql.ConnectionFactory; +import ru.javawebinar.basejava.sql.TransactionTemplate; -import java.sql.*; +import java.sql.ResultSet; +import java.util.ArrayList; import java.util.List; public class SqlStorage implements Storage { - public final ConnectionFactory connectionFactory; - public SqlStorage(String dbUrl, String dbUser, String dbPassword) { - connectionFactory = () -> DriverManager.getConnection(dbUrl, dbUser, dbPassword); + private TransactionTemplate transaction; + + public SqlStorage(TransactionTemplate transaction) { + this.transaction = transaction; } @Override public void clear() { - try (Connection conn = connectionFactory.getConnection(); - PreparedStatement ps = conn.prepareStatement("DELETE FROM resume")) { + transaction.action("DELETE FROM resume", (ps -> { ps.execute(); - } catch (SQLException e) { - throw new StorageException(e); - } + return null; + })); } @Override public Resume get(String uuid) { - try (Connection conn = connectionFactory.getConnection(); - PreparedStatement ps = conn.prepareStatement("SELECT * FROM resume r WHERE r.uuid =?")) { + return (Resume) transaction.action("SELECT * FROM resume r WHERE r.uuid =?", ps -> { ps.setString(1, uuid); ResultSet rs = ps.executeQuery(); if (!rs.next()) { throw new NotExistStorageException(uuid); } return new Resume(uuid, rs.getString("full_name")); - } catch (SQLException e) { - throw new StorageException(e); - } + }); } @Override public void update(Resume r) { - + transaction.action("UPDATE resume r SET full_name = ? WHERE uuid = ?", ps -> { + ps.setString(1, r.getUuid()); + ps.setString(2, r.getFullName()); + ps.execute(); + return null; + }); } @Override public void save(Resume r) { - try (Connection conn = connectionFactory.getConnection(); - PreparedStatement ps = conn.prepareStatement("INSERT INTO resume (uuid, full_name) VALUES (?,?)")) { + transaction.action("INSERT INTO resume (uuid, full_name) VALUES (?,?)", ps -> { ps.setString(1, r.getUuid()); ps.setString(2, r.getFullName()); ps.execute(); - } catch (SQLException e) { - throw new StorageException(e); - } + return null; + }); } + @Override - public void delete(String uuid) { + public List getAllSorted() { + return (List) transaction.action("SELECT * FROM resume order by full_name", ps -> { + ResultSet rs = ps.executeQuery(); + List resumes = new ArrayList<>(); + while (rs.next()) { + resumes.add(new Resume(rs.getString("uuid").trim(), rs.getString("full_name").trim())); + } + return resumes; + }); } @Override - public List getAllSorted() { - return null; + public int size() { + return (Integer) transaction.action("SELECT count(*) as size FROM resume", ps -> { + ResultSet rs = ps.executeQuery(); + if (rs.next()) { + return rs.getInt(1); + } + return 0; + }); + } + @Override - public int size() { - return 0; + public void delete(String uuid) { + transaction.action("DELETE FROM resume r WHERE r.uuid = ?", ps -> { + ps.setString(1, uuid); + ps.execute(); + return null; + }); } + + } \ No newline at end of file diff --git a/test/ru/javawebinar/basejava/storage/AbstractStorageTest.java b/test/ru/javawebinar/basejava/storage/AbstractStorageTest.java index 5b97e6b..8771706 100644 --- a/test/ru/javawebinar/basejava/storage/AbstractStorageTest.java +++ b/test/ru/javawebinar/basejava/storage/AbstractStorageTest.java @@ -39,7 +39,7 @@ public AbstractStorageTest(Storage storage) { R1 = new Resume(UUID_1, USER_1); R2 = new Resume(UUID_2, USER_2); R3 = new Resume(UUID_3, USER_3); - ResumeTestData.fillResume(); + // ResumeTestData.fillResume(); } @BeforeEach @@ -71,6 +71,7 @@ public void update() { @Test public void getAllSorted() { List resumes = storage.getAllSorted(); + assertAll("resumes", () -> assertEquals(3, resumes.size()), () -> assertEquals(resumes, Arrays.asList(R1, R2, R3))); diff --git a/test/ru/javawebinar/basejava/storage/SqlStorageTest.java b/test/ru/javawebinar/basejava/storage/SqlStorageTest.java new file mode 100644 index 0000000..7448f9f --- /dev/null +++ b/test/ru/javawebinar/basejava/storage/SqlStorageTest.java @@ -0,0 +1,29 @@ +package ru.javawebinar.basejava.storage; + +import org.junit.jupiter.api.Disabled; +import org.junit.jupiter.api.Test; +import ru.javawebinar.basejava.Config; +import ru.javawebinar.basejava.exception.StorageException; +import ru.javawebinar.basejava.sql.TransactionTemplate; + +import static org.junit.jupiter.api.Assertions.assertThrows; + +public class SqlStorageTest extends AbstractStorageTest { + + public SqlStorageTest() { + // super(new SqlStorage(Config.get().getDbUrl(), Config.get().getDbUser(), Config.get().getDbPassword())); + super(new SqlStorage(new TransactionTemplate(Config.get().getDbUrl(), Config.get().getDbUser(), Config.get().getDbPassword()))); + } + + @Disabled + @Override + void saveOverflow() { + super.saveOverflow(); + } + + @Override + @Test + public void getExist() { + assertThrows(StorageException.class, () -> storage.save(R1)); + } +} \ No newline at end of file