package com.datascience.datastoring.backends.db;
import com.datascience.datastoring.IBackend;
import org.apache.log4j.Logger;
import org.apache.tomcat.jdbc.pool.DataSource;
import org.apache.tomcat.jdbc.pool.PoolProperties;
import java.sql.*;
import java.util.*;
/**
* NOTE: we have to be case insensitive in database/table/fields names!
*
* User: artur
* Date: 6/4/13
*/
public class DBBackend implements IBackend {
protected final static Logger logger = Logger.getLogger(DBBackend.class);
protected String dbName;
protected DataSource ds;
protected SQLCommandOperatorFactory sqlCmdFactory;
public DBBackend(String dbName, PoolProperties poolProperties, SQLCommandOperatorFactory sqlCmdFactory){
this.dbName = dbName;
ds = new DataSource(poolProperties);
this.sqlCmdFactory = sqlCmdFactory;
}
public SQLCommandOperator getSQLCmdOperatorNoDB() throws SQLException{
return sqlCmdFactory.create(ds.getConnection());
}
public SQLCommandOperator getSQLCmdOperator() throws SQLException{
SQLCommandOperator sqlCommandOperator = getSQLCmdOperatorNoDB();
if (!dbName.equals("")) {
try {
sqlCommandOperator.setDB(dbName);
} catch (SQLException ex) {
logger.warn("Couldn't set DB: " + dbName, ex);
}
}
return sqlCommandOperator;
}
@Override
public void test() throws Exception {
SQLCommandOperator sqlCO = null;
try {
sqlCO = getSQLCmdOperator();
sqlCO.test();
} finally {
cleanup(sqlCO);
}
}
protected void cleanup(SQLCommandOperator sqlCO) throws SQLException{
if (sqlCO != null) sqlCO.close();
}
@Override
public void stop() throws Exception {
close();
}
protected void close() throws SQLException {
ds.close();
}
public void dropTable(String tableName) throws SQLException {
SQLCommandOperator sqlCO = getSQLCmdOperator();
try {
sqlCO.dropTable(tableName);
logger.info("Table " + tableName + " successfully dropped");
} finally {
sqlCO.close();
}
}
public void clear(Collection<String> tables) throws SQLException {
SQLCommandOperator sqlCO = getSQLCmdOperator();
try {
for (String t : tables){
sqlCO.dropTable(t);
}
logger.info("Tables successfully dropped");
} finally {
sqlCO.close();
}
}
public void rebuild(Map<String, String> tables) throws SQLException {
try {
createDatabase();
} catch (SQLException ex){
logger.warn("Error when creating db during rebuild", ex);
}
SQLCommandOperator sqlCO = getSQLCmdOperator();
try {
for (Map.Entry<String, String> e : tables.entrySet()){
sqlCO.createTable(e.getKey(), e.getValue());
sqlCO.createIndex(e.getKey());
}
} finally {
sqlCO.close();
}
}
public void createDatabase() throws SQLException {
if (dbName.equals("")) {
logger.warn("Skipping db creation due to empty dbName");
return;
}
SQLCommandOperator sqlCO = getSQLCmdOperatorNoDB();
try {
logger.info("Creating database");
sqlCO.createDatabase(dbName);
logger.info("Database created successfully");
} finally {
sqlCO.close();
}
}
public void createTable(String tableName, String tableColumns) throws SQLException {
SQLCommandOperator sqlCO = getSQLCmdOperator();
try {
sqlCO.createTable(tableName, tableColumns);
logger.info("Table " + tableName + " successfully created");
} finally {
sqlCO.close();
}
}
/**
* NOTE: case-insensitive in table names
*/
public void checkTables(Collection<String> tables) throws Exception {
SQLCommandOperator sqlCO = getSQLCmdOperator();
try {
Set<String> existingTables = sqlCO.getAllTables(dbName);
for (String tableName : tables){
if (!existingTables.contains(tableName.toLowerCase())){
throw new Exception("There is no table named: " + tableName);
}
}
} finally {
sqlCO.close();
}
}
}