/**
* Copyright (C) 2009 - present by OpenGamma Inc. and the OpenGamma group of companies
*
* Please see distribution for license.
*/
package com.opengamma.util.db.management;
import java.io.File;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import org.hibernate.dialect.DerbyDialect;
import org.hibernate.dialect.Dialect;
import com.opengamma.OpenGammaRuntimeException;
/**
* Database management for Derby databases.
*/
public final class DerbyDbManagement extends AbstractDbManagement {
/**
* Singleton instance.
*/
private static final DerbyDbManagement INSTANCE = new DerbyDbManagement();
/**
* The underlying Hibernate dialect.
*/
private DerbyDialect _hibernateDialect;
/**
* Restricted constructor.
*/
private DerbyDbManagement() {
}
/**
* Gets the singleton instance.
*
* @return the instance, not null
*/
public static DerbyDbManagement getInstance() {
return INSTANCE;
}
//-------------------------------------------------------------------------
@Override
public synchronized Dialect getHibernateDialect() {
if (_hibernateDialect == null) {
// constructed lazily so we don't get log message about 'using dialect' if we're not actually using it
_hibernateDialect = new DerbyDialect();
}
return _hibernateDialect;
}
@Override
public Class<?> getJDBCDriverClass() {
return org.apache.derby.jdbc.EmbeddedDriver.class;
}
@Override
public String getDatabaseName() {
return "derby";
}
//-------------------------------------------------------------------------
@Override
public void reset(String catalog) {
super.reset(catalog);
// for Derby, we shutdown the database to avoid locking issues
System.out.println("Closing connection to " + catalog + "...");
try {
DriverManager.getConnection("jdbc:derby:;shutdown=true");
} catch (SQLException e) {
if (e.getErrorCode() != 50000 || !"XJ015".equals(e.getSQLState())) {
throw new OpenGammaRuntimeException("Could not shutdown Derby " + e.getErrorCode() + " - " + e.getSQLState() + " - " + e.getMessage(), e);
}
}
}
@Override
public void shutdown(String catalog) {
super.shutdown(catalog);
System.out.println("Closing connection to " + catalog + "...");
try {
DriverManager.getConnection("jdbc:derby:;shutdown=true");
} catch (SQLException e) {
if (e.getErrorCode() != 50000 || !"XJ015".equals(e.getSQLState())) {
throw new OpenGammaRuntimeException("Could not shutdown Derby " + e.getErrorCode() + " - " + e.getSQLState() + " - " + e.getMessage(), e);
}
}
}
//-------------------------------------------------------------------------
@Override
public String getAllSchemasSQL(String catalog) {
return "SELECT schemaname AS name FROM SYS.SYSSCHEMAS";
}
@Override
public String getAllForeignKeyConstraintsSQL(String catalog, String schema) {
String sql = "SELECT constraintname AS name, " +
"tablename AS table_name " +
"FROM SYS.SYSCONSTRAINTS, SYS.SYSTABLES " +
"WHERE SYS.SYSTABLES.tableid = SYS.SYSCONSTRAINTS.tableid AND type = 'F'";
if (schema != null) {
sql += " AND SYS.SYSCONSTRAINTS.schemaid = (SELECT schemaid FROM SYS.SYSSCHEMAS WHERE schemaname = '" + schema + "')";
}
return sql;
}
@Override
public String getAllSequencesSQL(String catalog, String schema) {
String sql = "SELECT sequencename AS name FROM SYS.SYSSEQUENCES ";
if (schema != null) {
sql += " WHERE schemaid = (SELECT schemaid FROM SYS.SYSSCHEMAS WHERE schemaname = '" + schema + "')";
}
return sql;
}
@Override
public String getAllTablesSQL(String catalog, String schema) {
String sql = "SELECT tablename AS name FROM SYS.SYSTABLES WHERE tabletype = 'T'";
if (schema != null) {
sql += " AND schemaid = (SELECT schemaid FROM SYS.SYSSCHEMAS WHERE schemaname = '" + schema + "')";
}
return sql;
}
@Override
public String getAllViewsSQL(String catalog, String schema) {
String sql = "SELECT tablename AS name FROM SYS.SYSTABLES WHERE tabletype = 'V'";
if (schema != null) {
sql += " AND schemaid = (SELECT schemaid FROM SYS.SYSSCHEMAS WHERE schemaname = '" + schema + "')";
}
return sql;
}
@Override
public String getAllColumnsSQL(String catalog, String schema, String table) {
StringBuilder sql = new StringBuilder("SELECT c.columnname AS name,c.columndatatype AS datatype,'' AS allowsnull,c.columndefault AS defaultvalue " +
"FROM SYS.SYSCOLUMNS AS c INNER JOIN SYS.SYSTABLES AS t ON c.referenceid=t.tableid WHERE t.tablename='");
sql.append(table).append("'");
if (schema != null) {
sql.append(" AND t.schemaid=(SELECT schemaid FROM SYS.SYSSCHEMAS WHERE schemaname='").append(schema).append("')");
}
return sql.toString();
}
@Override
public String getCreateSchemaSQL(String catalog, String schema) {
return "CREATE SCHEMA " + schema;
}
@Override
public String getSchemaVersionTable(String schemaGroupName) {
return (schemaGroupName + SCHEMA_VERSION_TABLE_SUFFIX).toUpperCase();
}
@Override
public String getSchemaVersionSQL(String catalog, String schemaGroupName) {
return "SELECT version_value FROM " + getSchemaVersionTable(schemaGroupName) + " WHERE version_key = 'schema_patch'";
}
@Override
public CatalogCreationStrategy getCatalogCreationStrategy() {
return new DerbyCatalogCreationStrategy();
}
//-------------------------------------------------------------------------
/**
* Strategy for creating a Derby database.
*/
private class DerbyCatalogCreationStrategy implements CatalogCreationStrategy {
private File getFile() {
String dbHost = getDbHost().trim();
String filePart = dbHost.substring("jdbc:derby:".length());
return new File(filePart);
}
@Override
public boolean catalogExists(String catalog) {
File catalogDir = new File(getFile(), catalog);
return catalogDir.exists();
}
@Override
public void create(String catalog) {
if (!catalogExists(catalog)) {
try (Connection conn = connect(catalog + ";create=true")) {
// connect is all that is needed
} catch (SQLException e) {
throw new OpenGammaRuntimeException("Cannot create Derby DB", e);
}
}
}
}
}