Search in sources :

Example 1 with OfflineConnection

use of liquibase.database.OfflineConnection in project liquibase by liquibase.

the class DatabaseType method createDatabase.

public Database createDatabase(ClassLoader classLoader) {
    logParameters();
    validateParameters();
    try {
        DatabaseFactory databaseFactory = DatabaseFactory.getInstance();
        if (databaseClass != null) {
            Database databaseInstance = (Database) ClasspathUtils.newInstance(databaseClass, classLoader, Database.class);
            databaseFactory.register(databaseInstance);
        }
        DatabaseConnection jdbcConnection;
        if (getUrl().startsWith("offline:")) {
            jdbcConnection = new OfflineConnection(getUrl(), new ClassLoaderResourceAccessor(classLoader));
        } else {
            Driver driver = (Driver) ClasspathUtils.newInstance(getDriver(), classLoader, Driver.class);
            if (driver == null) {
                throw new BuildException("Unable to create Liquibase Database instance. Could not instantiate the JDBC driver.");
            }
            Properties connectionProps = new Properties();
            String user = getUser();
            if (user != null && !user.isEmpty()) {
                connectionProps.setProperty(USER, user);
            }
            String password = getPassword();
            if (password != null && !password.isEmpty()) {
                connectionProps.setProperty(PASSWORD, password);
            }
            ConnectionProperties connectionProperties = getConnectionProperties();
            if (connectionProperties != null) {
                connectionProps.putAll(connectionProperties.buildProperties());
            }
            Connection connection = driver.connect(getUrl(), connectionProps);
            if (connection == null) {
                throw new BuildException("Unable to create Liquibase Database instance. Could not connect to the database.");
            }
            jdbcConnection = new JdbcConnection(connection);
        }
        Database database = databaseFactory.findCorrectDatabaseImplementation(jdbcConnection);
        String schemaName = getDefaultSchemaName();
        if (schemaName != null) {
            database.setDefaultSchemaName(schemaName);
        }
        String catalogName = getDefaultCatalogName();
        if (catalogName != null) {
            database.setDefaultCatalogName(catalogName);
        }
        String currentDateTimeFunction = getCurrentDateTimeFunction();
        if (currentDateTimeFunction != null) {
            database.setCurrentDateTimeFunction(currentDateTimeFunction);
        }
        database.setOutputDefaultSchema(isOutputDefaultSchema());
        database.setOutputDefaultCatalog(isOutputDefaultCatalog());
        String liquibaseSchemaName = getLiquibaseSchemaName();
        if (liquibaseSchemaName != null) {
            database.setLiquibaseSchemaName(liquibaseSchemaName);
        }
        String liquibaseCatalogName = getLiquibaseCatalogName();
        if (liquibaseCatalogName != null) {
            database.setLiquibaseCatalogName(liquibaseCatalogName);
        }
        String databaseChangeLogTableName = getDatabaseChangeLogTableName();
        if (databaseChangeLogTableName != null) {
            database.setDatabaseChangeLogTableName(databaseChangeLogTableName);
        }
        String databaseChangeLogLockTableName = getDatabaseChangeLogLockTableName();
        if (databaseChangeLogLockTableName != null) {
            database.setDatabaseChangeLogLockTableName(databaseChangeLogLockTableName);
        }
        String liquibaseTablespaceName = getLiquibaseTablespaceName();
        if (liquibaseTablespaceName != null) {
            database.setLiquibaseTablespaceName(liquibaseTablespaceName);
        }
        return database;
    } catch (SQLException e) {
        throw new BuildException("Unable to create Liquibase database instance. A JDBC error occurred. " + e.toString(), e);
    } catch (DatabaseException e) {
        throw new BuildException("Unable to create Liquibase database instance. " + e.toString(), e);
    }
}
Also used : SQLException(java.sql.SQLException) Connection(java.sql.Connection) DatabaseConnection(liquibase.database.DatabaseConnection) OfflineConnection(liquibase.database.OfflineConnection) JdbcConnection(liquibase.database.jvm.JdbcConnection) Driver(java.sql.Driver) JdbcConnection(liquibase.database.jvm.JdbcConnection) OfflineConnection(liquibase.database.OfflineConnection) Properties(java.util.Properties) DatabaseFactory(liquibase.database.DatabaseFactory) Database(liquibase.database.Database) DatabaseConnection(liquibase.database.DatabaseConnection) BuildException(org.apache.tools.ant.BuildException) ClassLoaderResourceAccessor(liquibase.resource.ClassLoaderResourceAccessor) DatabaseException(liquibase.exception.DatabaseException)

Example 2 with OfflineConnection

use of liquibase.database.OfflineConnection in project liquibase by liquibase.

the class CommandLineUtils method initializeDatabase.

/**
     * Executes RawSqlStatements particular to each database engine to set the default schema for the given Database
     *  
     * @param username            The username used for the connection. Used with MSSQL databases
     * @param defaultCatalogName  Catalog name and schema name are similar concepts. Used if defaultCatalogName is null. 
     * @param defaultSchemaName   Catalog name and schema name are similar concepts. Catalog is used with Oracle, DB2 and MySQL, and takes
     *                             precedence over the schema name.
     * @param database            Which Database object is affected by the initialization.
     * @throws DatabaseException
     */
public static void initializeDatabase(String username, String defaultCatalogName, String defaultSchemaName, Database database) throws DatabaseException {
    if ((defaultCatalogName != null || defaultSchemaName != null) && !(database.getConnection() instanceof OfflineConnection)) {
        if (database instanceof OracleDatabase) {
            String schema = defaultCatalogName;
            if (schema == null) {
                schema = defaultSchemaName;
            }
            ExecutorService.getInstance().getExecutor(database).execute(new RawSqlStatement("ALTER SESSION SET CURRENT_SCHEMA=" + database.escapeObjectName(schema, Schema.class)));
        } else if (database instanceof MSSQLDatabase && defaultSchemaName != null) {
            boolean sql2005OrLater = true;
            try {
                sql2005OrLater = database.getDatabaseMajorVersion() >= 9;
            } catch (DatabaseException e) {
            // Assume SQL Server 2005 or later
            }
            if (sql2005OrLater && username != null) {
                ExecutorService.getInstance().getExecutor(database).execute(new RawSqlStatement("IF USER_NAME() <> N'dbo'\r\n" + "BEGIN\r\n" + "	DECLARE @sql [nvarchar](MAX)\r\n" + "	SELECT @sql = N'ALTER USER ' + QUOTENAME(USER_NAME()) + N' WITH DEFAULT_SCHEMA = " + database.escapeStringForDatabase(database.escapeObjectName(username, DatabaseObject.class)) + "'\r\n" + "	EXEC sp_executesql @sql\r\n" + "END"));
            }
        } else if (database instanceof PostgresDatabase && defaultSchemaName != null) {
            ExecutorService.getInstance().getExecutor(database).execute(new RawSqlStatement("SET SEARCH_PATH TO " + database.escapeObjectName(defaultSchemaName, Schema.class)));
        } else if (database instanceof DB2Database) {
            String schema = defaultCatalogName;
            if (schema == null) {
                schema = defaultSchemaName;
            }
            ExecutorService.getInstance().getExecutor(database).execute(new RawSqlStatement("SET CURRENT SCHEMA " + schema));
        } else if (database instanceof MySQLDatabase) {
            String schema = defaultCatalogName;
            if (schema == null) {
                schema = defaultSchemaName;
            }
            ExecutorService.getInstance().getExecutor(database).execute(new RawSqlStatement("USE " + schema));
        }
    }
}
Also used : RawSqlStatement(liquibase.statement.core.RawSqlStatement) CatalogAndSchema(liquibase.CatalogAndSchema) Schema(liquibase.structure.core.Schema) OfflineConnection(liquibase.database.OfflineConnection)

Example 3 with OfflineConnection

use of liquibase.database.OfflineConnection in project liquibase by liquibase.

the class JdbcExecutor method execute.

public Object execute(StatementCallback action, List<SqlVisitor> sqlVisitors) throws DatabaseException {
    Scope.getCurrentScope().getLog(getClass()).fine("Executing with the '" + getName() + "' executor");
    DatabaseConnection con = database.getConnection();
    Statement stmt = null;
    try {
        if (con instanceof OfflineConnection) {
            throw new DatabaseException("Cannot execute commands against an offline database");
        }
        stmt = ((JdbcConnection) con).getUnderlyingConnection().createStatement();
        Statement stmtToUse = stmt;
        return action.doInStatement(stmtToUse);
    } catch (SQLException ex) {
        // Release Connection early, to avoid potential connection pool deadlock
        // in the case when the exception translator hasn't been initialized yet.
        JdbcUtil.closeStatement(stmt);
        stmt = null;
        String url;
        if (con.isClosed()) {
            url = "CLOSED CONNECTION";
        } else {
            url = con.getURL();
        }
        throw new DatabaseException("Error executing SQL " + StringUtil.join(applyVisitors(action.getStatement(), sqlVisitors), "; on " + url) + ": " + ex.getMessage(), ex);
    } finally {
        JdbcUtil.closeStatement(stmt);
    }
}
Also used : SQLException(java.sql.SQLException) CompoundStatement(liquibase.statement.CompoundStatement) ExecutablePreparedStatement(liquibase.statement.ExecutablePreparedStatement) SqlStatement(liquibase.statement.SqlStatement) CallableSqlStatement(liquibase.statement.CallableSqlStatement) Statement(java.sql.Statement) CallableStatement(java.sql.CallableStatement) DatabaseConnection(liquibase.database.DatabaseConnection) JdbcConnection(liquibase.database.jvm.JdbcConnection) OfflineConnection(liquibase.database.OfflineConnection) DatabaseException(liquibase.exception.DatabaseException)

Example 4 with OfflineConnection

use of liquibase.database.OfflineConnection in project liquibase by liquibase.

the class ColumnSnapshotGenerator method setAutoIncrementDetails.

protected void setAutoIncrementDetails(Column column, Database database, DatabaseSnapshot snapshot) {
    if ((column.getAutoIncrementInformation() != null) && (database instanceof MSSQLDatabase) && (database.getConnection() != null) && !(database.getConnection() instanceof OfflineConnection)) {
        Map<String, Column.AutoIncrementInformation> autoIncrementColumns = (Map) snapshot.getScratchData("autoIncrementColumns");
        if (autoIncrementColumns == null) {
            autoIncrementColumns = new HashMap<>();
            Executor executor = Scope.getCurrentScope().getSingleton(ExecutorService.class).getExecutor("jdbc", database);
            try {
                List<Map<String, ?>> rows = executor.queryForList(new RawSqlStatement("SELECT object_schema_name(object_id) AS schema_name, " + "object_name(object_id) AS table_name, name AS column_name, " + "CAST(seed_value AS bigint) AS start_value, " + "CAST(increment_value AS bigint) AS increment_by " + "FROM sys.identity_columns"));
                for (Map row : rows) {
                    String schemaName = (String) row.get("SCHEMA_NAME");
                    String tableName = (String) row.get("TABLE_NAME");
                    String columnName = (String) row.get("COLUMN_NAME");
                    Long startValue = (Long) row.get("START_VALUE");
                    Long incrementBy = (Long) row.get("INCREMENT_BY");
                    Column.AutoIncrementInformation info = new Column.AutoIncrementInformation(startValue, incrementBy);
                    autoIncrementColumns.put(schemaName + "." + tableName + "." + columnName, info);
                }
                snapshot.setScratchData("autoIncrementColumns", autoIncrementColumns);
            } catch (DatabaseException e) {
                Scope.getCurrentScope().getLog(getClass()).info("Could not read identity information", e);
            }
        }
        if ((column.getRelation() != null) && (column.getSchema() != null)) {
            Column.AutoIncrementInformation autoIncrementInformation = autoIncrementColumns.get(column.getSchema().getName() + "." + column.getRelation().getName() + "." + column.getName());
            if (autoIncrementInformation != null) {
                column.setAutoIncrementInformation(autoIncrementInformation);
            }
        }
    }
}
Also used : RawSqlStatement(liquibase.statement.core.RawSqlStatement) OfflineConnection(liquibase.database.OfflineConnection) Executor(liquibase.executor.Executor) ExecutorService(liquibase.executor.ExecutorService) HashMap(java.util.HashMap) Map(java.util.Map) TreeMap(java.util.TreeMap) DatabaseException(liquibase.exception.DatabaseException)

Example 5 with OfflineConnection

use of liquibase.database.OfflineConnection in project liquibase by liquibase.

the class OracleDatabase method setConnection.

@Override
public void setConnection(DatabaseConnection conn) {
    // noinspection HardCodedStringLiteral,HardCodedStringLiteral,HardCodedStringLiteral,HardCodedStringLiteral,
    // HardCodedStringLiteral
    // more reserved words not returned by driver
    reservedWords.addAll(Arrays.asList("GROUP", "USER", "SESSION", "PASSWORD", "RESOURCE", "START", "SIZE", "UID", "DESC", "ORDER"));
    Connection sqlConn = null;
    if (!(conn instanceof OfflineConnection)) {
        try {
            /*
                 * Don't try to call getWrappedConnection if the conn instance is
                 * is not a JdbcConnection. This happens for OfflineConnection.
                 * see https://liquibase.jira.com/browse/CORE-2192
                 */
            if (conn instanceof JdbcConnection) {
                sqlConn = ((JdbcConnection) conn).getWrappedConnection();
            }
        } catch (Exception e) {
            throw new UnexpectedLiquibaseException(e);
        }
        if (sqlConn != null) {
            tryProxySession(conn.getURL(), sqlConn);
            try {
                // noinspection HardCodedStringLiteral
                reservedWords.addAll(Arrays.asList(sqlConn.getMetaData().getSQLKeywords().toUpperCase().split(",\\s*")));
            } catch (SQLException e) {
                // noinspection HardCodedStringLiteral
                Scope.getCurrentScope().getLog(getClass()).info("Could get sql keywords on OracleDatabase: " + e.getMessage());
            // can not get keywords. Continue on
            }
            try {
                Method method = sqlConn.getClass().getMethod("setRemarksReporting", Boolean.TYPE);
                method.setAccessible(true);
                method.invoke(sqlConn, true);
            } catch (Exception e) {
                // noinspection HardCodedStringLiteral
                Scope.getCurrentScope().getLog(getClass()).info("Could not set remarks reporting on OracleDatabase: " + e.getMessage());
            // cannot set it. That is OK
            }
            CallableStatement statement = null;
            try {
                // noinspection HardCodedStringLiteral
                statement = sqlConn.prepareCall("{call DBMS_UTILITY.DB_VERSION(?,?)}");
                statement.registerOutParameter(1, Types.VARCHAR);
                statement.registerOutParameter(2, Types.VARCHAR);
                statement.execute();
                String compatibleVersion = statement.getString(2);
                if (compatibleVersion != null) {
                    Matcher majorVersionMatcher = Pattern.compile("(\\d+)\\.(\\d+)\\..*").matcher(compatibleVersion);
                    if (majorVersionMatcher.matches()) {
                        this.databaseMajorVersion = Integer.valueOf(majorVersionMatcher.group(1));
                        this.databaseMinorVersion = Integer.valueOf(majorVersionMatcher.group(2));
                    }
                }
            } catch (SQLException e) {
                @SuppressWarnings("HardCodedStringLiteral") String message = "Cannot read from DBMS_UTILITY.DB_VERSION: " + e.getMessage();
                // noinspection HardCodedStringLiteral
                Scope.getCurrentScope().getLog(getClass()).info("Could not set check compatibility mode on OracleDatabase, assuming not running in any sort of compatibility mode: " + message);
            } finally {
                JdbcUtil.closeStatement(statement);
            }
            if (GlobalConfiguration.DDL_LOCK_TIMEOUT.getCurrentValue() != null) {
                int timeoutValue = GlobalConfiguration.DDL_LOCK_TIMEOUT.getCurrentValue();
                Scope.getCurrentScope().getLog(getClass()).fine("Setting DDL_LOCK_TIMEOUT value to " + timeoutValue);
                String sql = "ALTER SESSION SET DDL_LOCK_TIMEOUT=" + timeoutValue;
                PreparedStatement ddlLockTimeoutStatement = null;
                try {
                    ddlLockTimeoutStatement = sqlConn.prepareStatement(sql);
                    ddlLockTimeoutStatement.execute();
                } catch (SQLException sqle) {
                    Scope.getCurrentScope().getUI().sendErrorMessage("Unable to set the DDL_LOCK_TIMEOUT_VALUE: " + sqle.getMessage(), sqle);
                    Scope.getCurrentScope().getLog(getClass()).warning("Unable to set the DDL_LOCK_TIMEOUT_VALUE: " + sqle.getMessage(), sqle);
                } finally {
                    JdbcUtil.closeStatement(ddlLockTimeoutStatement);
                }
            }
        }
    }
    super.setConnection(conn);
}
Also used : Matcher(java.util.regex.Matcher) DatabaseConnection(liquibase.database.DatabaseConnection) OfflineConnection(liquibase.database.OfflineConnection) JdbcConnection(liquibase.database.jvm.JdbcConnection) JdbcConnection(liquibase.database.jvm.JdbcConnection) OfflineConnection(liquibase.database.OfflineConnection) Method(java.lang.reflect.Method) UnexpectedLiquibaseException(liquibase.exception.UnexpectedLiquibaseException) UnexpectedLiquibaseException(liquibase.exception.UnexpectedLiquibaseException) DatabaseException(liquibase.exception.DatabaseException)

Aggregations

OfflineConnection (liquibase.database.OfflineConnection)23 DatabaseException (liquibase.exception.DatabaseException)14 DatabaseConnection (liquibase.database.DatabaseConnection)12 JdbcConnection (liquibase.database.jvm.JdbcConnection)12 ResultSet (java.sql.ResultSet)6 SQLException (java.sql.SQLException)6 Statement (java.sql.Statement)6 Database (liquibase.database.Database)6 RawSqlStatement (liquibase.statement.core.RawSqlStatement)5 UnexpectedLiquibaseException (liquibase.exception.UnexpectedLiquibaseException)4 CallableStatement (java.sql.CallableStatement)3 ParseException (java.text.ParseException)3 DateParseException (liquibase.exception.DateParseException)3 ExecutorService (liquibase.executor.ExecutorService)3 Method (java.lang.reflect.Method)2 Connection (java.sql.Connection)2 Map (java.util.Map)2 DatabaseFactory (liquibase.database.DatabaseFactory)2 Executor (liquibase.executor.Executor)2 ParsedNode (liquibase.parser.core.ParsedNode)2