package org.deephacks.confit.internal.jpa;
import org.deephacks.confit.test.JUnitUtils;
import java.io.File;
import java.io.IOException;
import java.nio.charset.Charset;
import java.sql.SQLException;
import java.text.MessageFormat;
import java.util.List;
import static com.google.common.io.Files.readLines;
/**
* The machine that runs the test must specify username, password and host
* for the database.
*
* Port configuration is not supported at the moment in order to have
* simple and unified configuration for list databases.
*/
public class Database {
/**
* Properties for test databases kept in confit for configuration.
*/
public static final String DB_HOST_CONFIT_PROPERTY = "confit.testdb.host";
private static final String INSTALL_DDL = "install_config_{0}.ddl";
private static final String UNINSTALL_DDL = "uninstall_config_{0}.ddl";
/**
* Database providers. Derby is default.
*/
public static final String DERBY = "derby";
public static final String DERBY_DRIVER = "org.apache.derby.jdbc.EmbeddedDriver";
public static final String MYSQL = "mysql";
public static final String MYSQL_DRIVER = "com.mysql.jdbc.Driver";
public static final String POSTGRESQL = "postgresql";
public static final String POSTGRESQL_DRIVER = "org.postgresql.Driver";
// TO BE IMPLEMENTED LATER
public static final String ORACLE = "oracle";
public static final String DB2 = "db2";
public static final String SQLITE = "sqlite";
public static final String HSQL = "hsql";
private String username;
private String password;
private String host;
private String url;
private String tablespace;
private String driver;
private String dbProvider;
private List<String> installDdl;
private List<String> uninstallDdl;
private Database(String dbProvider, List<String> installDdl, List<String> uninstallDdl) {
this.dbProvider = dbProvider;
this.installDdl = installDdl;
this.uninstallDdl = uninstallDdl;
this.username = System.getProperty("user.name");
this.password = System.getProperty("user.name");
this.host = "localhost";
this.tablespace = System.getProperty("user.name");
if (DERBY.equals(dbProvider)) {
driver = DERBY_DRIVER;
forName(driver);
url = "jdbc:derby:memory:" + tablespace + ";create=true";
} else if (MYSQL.equals(dbProvider)) {
driver = MYSQL_DRIVER;
url = "jdbc:mysql://" + host + ":3306/" + tablespace;
} else if (POSTGRESQL.equals(dbProvider)) {
driver = POSTGRESQL_DRIVER;
url = "jdbc:postgresql://" + host + ":5432/" + tablespace;
} else {
throw new UnsupportedOperationException("DB provider not supported [" + dbProvider
+ "]");
}
}
public static Database create(String dbProvider, File dbScriptDir) {
try {
List<String> installDdl = readLines(
new File(dbScriptDir, MessageFormat.format(INSTALL_DDL, dbProvider)),
Charset.defaultCharset());
List<String> uninstallDdl = readLines(
new File(dbScriptDir, MessageFormat.format(UNINSTALL_DDL, dbProvider)),
Charset.defaultCharset());
return new Database(dbProvider, installDdl, uninstallDdl);
} catch (IOException e) {
throw new RuntimeException(e);
}
}
public static Database create(String dbProvider, Class<?> clazz) {
List<String> installDdl = JUnitUtils.readMetaInfResource(clazz,
MessageFormat.format(INSTALL_DDL, dbProvider));
List<String> uninstallDdl = JUnitUtils.readMetaInfResource(clazz,
MessageFormat.format(UNINSTALL_DDL, dbProvider));
return new Database(dbProvider, installDdl, uninstallDdl);
}
public String getDatabaseProvider() {
return this.dbProvider;
}
public void initalize() {
try {
if (dbProvider == DERBY) {
try {
/**
* Derby is a special case that, at the moment, does not support support "if exist".
* The only option is to ignore SQLException from dropping stuff.
*/
DdlExec.execute(uninstallDdl, url, username, password, true);
} catch (SQLException e) {
// ignore, probably the first DROP TABLE of a non-existing table
}
DdlExec.execute(installDdl, url, username, password, false);
} else {
DdlExec.execute(uninstallDdl, url, username, password, false);
DdlExec.execute(installDdl, url, username, password, false);
}
} catch (Exception e) {
throw new RuntimeException(e);
}
}
public String getUsername() {
return username;
}
public String getPassword() {
return password;
}
public String getHost() {
return host;
}
public String getUrl() {
return url;
}
public String getTablespace() {
return tablespace;
}
public String getDriver() {
return driver;
}
public String getDbProvider() {
return dbProvider;
}
public static Class<?> forName(String className) {
try {
return Thread.currentThread().getContextClassLoader().loadClass(className);
} catch (ClassNotFoundException e) {
throw new RuntimeException(e);
}
}
}