diff --git a/pom.xml b/pom.xml index 7e7ea3b..677d609 100644 --- a/pom.xml +++ b/pom.xml @@ -1,5 +1,7 @@ - + 4.0.0 de.kreth @@ -42,10 +44,22 @@ + + org.slf4j + slf4j-api + 1.7.25 + junit junit - 4.12 + 4.12 + test + + + org.mockito + mockito-core + 2.18.3 + test diff --git a/src/main/java/de/kreth/dbmanager/Constraint.java b/src/main/java/de/kreth/dbmanager/Constraint.java new file mode 100644 index 0000000..cf2d45a --- /dev/null +++ b/src/main/java/de/kreth/dbmanager/Constraint.java @@ -0,0 +1,5 @@ +package de.kreth.dbmanager; + +public interface Constraint { + +} diff --git a/src/main/java/de/kreth/dbmanager/SqlConnection.java b/src/main/java/de/kreth/dbmanager/SqlConnection.java new file mode 100644 index 0000000..50d0998 --- /dev/null +++ b/src/main/java/de/kreth/dbmanager/SqlConnection.java @@ -0,0 +1,157 @@ +package de.kreth.dbmanager; + +import java.sql.Connection; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.sql.Statement; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Iterator; +import java.util.List; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class SqlConnection implements Database { + + private final Connection con; + private final Logger logger; + private TableDefinition version; + + public SqlConnection(Connection connection, DatabaseType dbType) { + super(); + this.con = connection; + this.logger = LoggerFactory.getLogger(getClass()); + + ColumnDefinition colVersion = new ColumnDefinition(DataType.INTEGER, + "version", "NOT NULL"); + ArrayList columns = new ArrayList(); + columns.add(colVersion); + this.version = new TableDefinition("version", dbType, columns); + } + + private void tryConnectVersionTable() { + try { + Statement stm = con.createStatement(); + String sql = DbManager.createSqlStatement(version); + stm.execute(sql); + } catch (SQLException e) { + logger.warn("Error creating version table", e); + } + } + + @Override + public void beginTransaction() throws SQLException { + con.setAutoCommit(false); + } + + @Override + public void setTransactionSuccessful() throws SQLException { + if (!con.getAutoCommit()) + con.commit(); + con.setAutoCommit(true); + } + + @Override + public void endTransaction() throws SQLException { + if (!con.getAutoCommit()) + con.rollback(); + con.setAutoCommit(true); + } + + @Override + public void execSQL(String sql) throws SQLException { + con.createStatement().execute(sql); + } + + @Override + public void execSQL(String sql, Object[] bindArgs) throws SQLException { + throw new UnsupportedOperationException(); + } + + @Override + public int getVersion() { + int version = 0; + Statement stm = null; + ResultSet rs = null; + try { + stm = con.createStatement(); + rs = stm.executeQuery("SELECT version FROM version"); + if (rs.next()) + version = rs.getInt("version"); + + } catch (SQLException e) { + if (logger.isDebugEnabled()) { + logger.debug("Error on Database fetch version, version 0?", e); + } + tryConnectVersionTable(); + } finally { + if (stm != null) + try { + stm.close(); + } catch (SQLException e) { + if (logger.isDebugEnabled()) { + logger.debug("Error on Database close", e); + } + } + } + + return version; + } + + @Override + public long insert(String table, List values) throws SQLException { + return 0; + } + + @Override + public boolean needUpgrade(int newVersion) { + return false; + } + + @Override + public Iterator> query(String table, String[] columns) + throws SQLException { + return null; + } + + @Override + public void setVersion(int version) { + Statement stm = null; + boolean autoCommit = true; + try { + autoCommit = con.getAutoCommit(); + con.setAutoCommit(false); + stm = con.createStatement(); + int rows = stm + .executeUpdate("UPDATE version SET version = " + version); + if (rows == 1) + con.commit(); + else + con.rollback(); + } catch (SQLException e) { + + try { + con.rollback(); + } catch (SQLException e1) { + logger.error("Error on database rollback after exception " + + e.getMessage(), e1); + } + logger.error("Error updating verions", e); + } finally { + try { + con.setAutoCommit(autoCommit); + } catch (SQLException e) { + logger.info("Error restoring autocommit to " + autoCommit, e); + } + } + + } + + @Override + public int delete(String table, String whereClause, String[] whereArgs) + throws SQLException { + return 0; + } + +} diff --git a/src/main/java/de/kreth/dbmanager/UniqueConstraint.java b/src/main/java/de/kreth/dbmanager/UniqueConstraint.java index 8a9dff8..4195aa7 100644 --- a/src/main/java/de/kreth/dbmanager/UniqueConstraint.java +++ b/src/main/java/de/kreth/dbmanager/UniqueConstraint.java @@ -4,7 +4,7 @@ import java.util.ArrayList; import java.util.Collections; import java.util.List; -public class UniqueConstraint { +public class UniqueConstraint implements Constraint { private List names = new ArrayList<>(); public UniqueConstraint(ColumnDefinition... defs) { diff --git a/src/test/java/de/kreth/dbmanager/SqlConnectionTest.java b/src/test/java/de/kreth/dbmanager/SqlConnectionTest.java new file mode 100644 index 0000000..b87c9f6 --- /dev/null +++ b/src/test/java/de/kreth/dbmanager/SqlConnectionTest.java @@ -0,0 +1,73 @@ +package de.kreth.dbmanager; + +import static org.junit.Assert.*; +import static org.mockito.Mockito.*; + +import java.sql.Connection; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.sql.Statement; + +import org.junit.Before; +import org.junit.Test; + +public class SqlConnectionTest { + + private Connection connection; + private Statement statement; + private ResultSet rs; + + @Before + public void initMocks() throws SQLException { + connection = mock(Connection.class); + statement = mock(Statement.class); + rs = mock(ResultSet.class); + when(connection.createStatement()).thenReturn(statement); + } + + @Test + public void testTransactionSuccessfull() throws SQLException { + SqlConnection con = new SqlConnection(connection, DatabaseType.HSQLDB); + con.beginTransaction(); + verify(connection, times(1)).setAutoCommit(false); + con.setTransactionSuccessful(); + verify(connection, times(1)).commit(); + verify(connection, times(1)).setAutoCommit(true); + } + + @Test + public void testTransactionRollback() throws SQLException { + SqlConnection con = new SqlConnection(connection, DatabaseType.HSQLDB); + con.beginTransaction(); + verify(connection, times(1)).setAutoCommit(false); + con.endTransaction(); + verify(connection, times(1)).rollback(); + verify(connection, times(1)).setAutoCommit(true); + } + + @Test + public void testGetVersion() throws SQLException { + when(rs.next()).thenReturn(false); + when(statement.executeQuery(anyString())).thenReturn(rs); + SqlConnection con = new SqlConnection(connection, DatabaseType.HSQLDB); + int version = con.getVersion(); + assertEquals(0, version); + } + + @Test + public void testGetVersionWithoutTable() throws SQLException { + when(statement.executeQuery(anyString())).thenThrow(SQLException.class); + + SqlConnection con = new SqlConnection(connection, DatabaseType.HSQLDB); + int version = con.getVersion(); + assertEquals(0, version); + } + + @Test + public void testSetVersionSuccessfull() throws SQLException { + SqlConnection con = new SqlConnection(connection, DatabaseType.HSQLDB); + when(statement.executeUpdate(anyString())).thenReturn(1); + con.setVersion(2); + verify(connection, times(1)).commit(); + } +}