/** * 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.sql.Connection; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Statement; import org.hibernate.dialect.Dialect; import org.hibernate.dialect.PostgreSQLDialect; import com.opengamma.OpenGammaRuntimeException; import com.opengamma.util.ReflectionUtils; /** * Database management for Vertica databases. * <p> * Because Vertica does not support running multiple databases on the same host, * database and schema are combined into one string, catalog___schema, * which is then used as the schema name. */ public final class VerticaDbManagement extends AbstractDbManagement { /** * Singleton instance. */ private static final VerticaDbManagement INSTANCE = new VerticaDbManagement(); /** * The underlying Hibernate dialect. Use Postgres here for now. */ private PostgreSQLDialect _hibernateDialect; /** * Restricted constructor. */ private VerticaDbManagement() { } /** * Gets the singleton instance. * * @return the instance, not null */ public static VerticaDbManagement getInstance() { return INSTANCE; } //------------------------------------------------------------------------- @Override public synchronized Dialect getHibernateDialect() { if (_hibernateDialect == null) { _hibernateDialect = new PostgreSQLDialect(); // use Postgres as closest match } return _hibernateDialect; } @Override public Class<?> getJDBCDriverClass() { return ReflectionUtils.loadClass("com.vertica.Driver"); } @Override public String getDatabaseName() { return "vertica"; } //------------------------------------------------------------------------- @Override public String getCatalogToConnectTo(String catalog) { return getDbHost(); } @Override public void setActiveSchema(Connection connection, String schema) throws SQLException { try (Statement statement = connection.createStatement()) { statement.executeUpdate("SET SEARCH_PATH TO " + schema); } } @Override public String getTestCatalog() { return null; } @Override public String getTestSchema() { return super.getTestCatalog(); } //------------------------------------------------------------------------- @Override public String getAllSchemasSQL(String catalog) { return "SELECT quote_ident(name) as name from v_internal.vs_schemata"; } @Override public String getAllForeignKeyConstraintsSQL(String catalog, String schema) { String sql = "SELECT quote_ident(constraint_name) AS name, table_name FROM v_catalog.foreign_keys WHERE table_schema = '" + schema + "'"; return sql; } @Override public String getAllSequencesSQL(String catalog, String schema) { String sql = "SELECT quote_ident(v_internal.vs_sequences.name) as name FROM v_internal.vs_sequences " + "join v_internal.vs_schemata on v_internal.vs_sequences.schema = v_internal.vs_schemata.oid " + "WHERE v_internal.vs_schemata.name = '" + schema + "'"; return sql; } @Override public String getAllTablesSQL(String catalog, String schema) { String sql = "SELECT quote_ident(table_name) AS name FROM v_catalog.tables WHERE IS_SYSTEM_TABLE = 'f'" + " AND table_schema = '" + schema + "'"; return sql; } @Override public String getAllViewsSQL(String catalog, String schema) { String sql = "SELECT quote_ident(table_name) AS name FROM v_catalog.views WHERE IS_SYSTEM_VIEW = 'f'" + " AND table_schema = '" + schema + "'"; return sql; } @Override public String getAllColumnsSQL(String catalog, String schema, String table) { String sql = "SELECT " + "column_name AS name, " + "data_type AS datatype, " + "is_nullable AS allowsnull, " + "column_default AS defaultvalue " + "FROM v_catalog.columns " + "WHERE table_name = '" + table + "' AND table_schema = '" + schema + "'"; return sql; } @Override public String getCreateSchemaSQL(String catalog, String schema) { return "CREATE SCHEMA " + schema; } @Override public String getSchemaVersionTable(String schemaGroupName) { return (schemaGroupName + SCHEMA_VERSION_TABLE_SUFFIX).toLowerCase(); } @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 VerticaCatalogCreationStrategy(); } //------------------------------------------------------------------------- /** * Strategy for catalog creation. */ private class VerticaCatalogCreationStrategy implements CatalogCreationStrategy { @Override public boolean catalogExists(String catalog) { try (Connection connection = connect(catalog)) { Statement statement = connection.createStatement(); String sql = getAllSchemasSQL(catalog); boolean exists; try (ResultSet rs = statement.executeQuery(sql)) { exists = rs.next(); } return exists; } catch (SQLException e) { throw new OpenGammaRuntimeException("Failed to check catalog existence", e); } } @Override public void create(String catalog) { return; // no possibility in Vertica to programmatically create databases. Instead schemas are encoded to contain database name as well. } } }