Search in sources :

Example 31 with DatabaseException

use of liquibase.exception.DatabaseException in project liquibase by liquibase.

the class TagDatabaseGenerator method generateSql.

@Override
public Sql[] generateSql(TagDatabaseStatement statement, Database database, SqlGeneratorChain sqlGeneratorChain) {
    String tableNameEscaped = database.escapeTableName(database.getLiquibaseCatalogName(), database.getLiquibaseSchemaName(), database.getDatabaseChangeLogTableName());
    String orderColumnNameEscaped = database.escapeObjectName("ORDEREXECUTED", Column.class);
    String dateColumnNameEscaped = database.escapeObjectName("DATEEXECUTED", Column.class);
    String tagColumnNameEscaped = database.escapeObjectName("TAG", Column.class);
    String tagEscaped = DataTypeFactory.getInstance().fromObject(statement.getTag(), database).objectToSql(statement.getTag(), database);
    if (database instanceof MySQLDatabase) {
        return new Sql[] { new UnparsedSql("UPDATE " + tableNameEscaped + " AS C " + "INNER JOIN (" + "SELECT " + orderColumnNameEscaped + ", " + dateColumnNameEscaped + " " + "FROM " + tableNameEscaped + " order by " + dateColumnNameEscaped + " desc, " + orderColumnNameEscaped + " desc limit 1) AS D " + "ON C." + orderColumnNameEscaped + " = D." + orderColumnNameEscaped + " " + "SET C." + tagColumnNameEscaped + " = " + tagEscaped) };
    } else if (database instanceof PostgresDatabase) {
        return new Sql[] { new UnparsedSql("UPDATE " + tableNameEscaped + " t SET TAG=" + tagEscaped + " FROM (SELECT " + dateColumnNameEscaped + ", " + orderColumnNameEscaped + " FROM " + tableNameEscaped + " ORDER BY " + dateColumnNameEscaped + " DESC, " + orderColumnNameEscaped + " DESC LIMIT 1) sub " + "WHERE t." + dateColumnNameEscaped + "=sub." + dateColumnNameEscaped + " AND t." + orderColumnNameEscaped + "=sub." + orderColumnNameEscaped) };
    } else if (database instanceof InformixDatabase) {
        String tempTableNameEscaped = database.escapeObjectName("max_order_temp", Table.class);
        return new Sql[] { new UnparsedSql("SELECT MAX(" + dateColumnNameEscaped + ") AS " + dateColumnNameEscaped + ", MAX(" + orderColumnNameEscaped + ") AS " + orderColumnNameEscaped + " " + "FROM " + tableNameEscaped + " " + "INTO TEMP " + tempTableNameEscaped + " WITH NO LOG"), new UnparsedSql("UPDATE " + tableNameEscaped + " " + "SET TAG = " + tagEscaped + " " + "WHERE " + dateColumnNameEscaped + " = (" + "SELECT " + dateColumnNameEscaped + " " + "FROM " + tempTableNameEscaped + ") AND " + orderColumnNameEscaped + " = (" + "SELECT " + orderColumnNameEscaped + " " + "FROM " + tempTableNameEscaped + ");"), new UnparsedSql("DROP TABLE " + tempTableNameEscaped + ";") };
    } else if (database instanceof MSSQLDatabase) {
        String changelogAliasEscaped = database.escapeObjectName("changelog", Table.class);
        String latestAliasEscaped = database.escapeObjectName("latest", Table.class);
        String idColumnEscaped = database.escapeObjectName("ID", Column.class);
        String authorColumnEscaped = database.escapeObjectName("AUTHOR", Column.class);
        String filenameColumnEscaped = database.escapeObjectName("FILENAME", Column.class);
        String topClause = "TOP (1)";
        try {
            if (database.getDatabaseMajorVersion() < 10) {
                // SQL Server 2005 or earlier
                topClause = "TOP 1";
            }
        } catch (DatabaseException ignored) {
        // assume SQL Server 2008 or later
        }
        return new Sql[] { new UnparsedSql("UPDATE " + changelogAliasEscaped + " " + "SET " + tagColumnNameEscaped + " = " + tagEscaped + " " + "FROM " + tableNameEscaped + " AS " + changelogAliasEscaped + " " + "INNER JOIN (" + "SELECT " + topClause + " " + idColumnEscaped + ", " + authorColumnEscaped + ", " + filenameColumnEscaped + " " + "FROM " + tableNameEscaped + " " + "ORDER BY " + dateColumnNameEscaped + " DESC, " + orderColumnNameEscaped + " DESC" + ") AS " + latestAliasEscaped + " " + "ON " + latestAliasEscaped + "." + idColumnEscaped + " = " + changelogAliasEscaped + "." + idColumnEscaped + " " + "AND " + latestAliasEscaped + "." + authorColumnEscaped + " = " + changelogAliasEscaped + "." + authorColumnEscaped + " " + "AND " + latestAliasEscaped + "." + filenameColumnEscaped + " = " + changelogAliasEscaped + "." + filenameColumnEscaped) };
    } else if (database instanceof OracleDatabase || database instanceof DB2Database) {
        String selectClause = "SELECT";
        String endClause = ")";
        String delimiter = "";
        if (database instanceof OracleDatabase) {
            selectClause = "SELECT * FROM (SELECT";
            endClause = ") where rownum=1)";
        } else if (database instanceof DB2Database) {
            endClause = " FETCH FIRST 1 ROWS ONLY)";
        }
        return new Sql[] { new UnparsedSql("MERGE INTO " + tableNameEscaped + " a " + "USING (" + selectClause + " " + orderColumnNameEscaped + ", " + dateColumnNameEscaped + " from " + tableNameEscaped + " order by " + dateColumnNameEscaped + " desc, " + orderColumnNameEscaped + " desc" + endClause + " b " + "ON ( a." + dateColumnNameEscaped + " = b." + dateColumnNameEscaped + " and a." + orderColumnNameEscaped + "=b." + orderColumnNameEscaped + " ) " + "WHEN MATCHED THEN " + "UPDATE SET  a.tag=" + tagEscaped + delimiter) };
    } else {
        //Only uses dateexecuted as a default. Depending on the timestamp resolution, multiple rows may be tagged which normally works fine but can cause confusion and some issues.
        //We cannot use orderexecuted alone because it is only guaranteed to be incrementing per update call.
        //TODO: Better handle other databases to use dateexecuted desc, orderexecuted desc.
        UpdateStatement updateStatement = new UpdateStatement(database.getLiquibaseCatalogName(), database.getLiquibaseSchemaName(), database.getDatabaseChangeLogTableName()).addNewColumnValue("TAG", statement.getTag()).setWhereClause(dateColumnNameEscaped + " = (" + "SELECT MAX(" + dateColumnNameEscaped + ") " + "FROM " + tableNameEscaped + ")");
        return SqlGeneratorFactory.getInstance().generateSql(updateStatement, database);
    }
}
Also used : UpdateStatement(liquibase.statement.core.UpdateStatement) Table(liquibase.structure.core.Table) UnparsedSql(liquibase.sql.UnparsedSql) Sql(liquibase.sql.Sql) UnparsedSql(liquibase.sql.UnparsedSql) Column(liquibase.structure.core.Column) DatabaseException(liquibase.exception.DatabaseException)

Example 32 with DatabaseException

use of liquibase.exception.DatabaseException in project liquibase by liquibase.

the class OfflineDatabaseTest method canOutputSQLFromOfflineOracleDB.

/**
	 * Check if it it's possible to output SQL from an OfflineConnection
	 * set to Oracle (offline:oracle).
	 *
	 * @see <a href="https://liquibase.jira.com/browse/CORE-2192">CORE-2192</a>
	 */
@Test
public void canOutputSQLFromOfflineOracleDB() throws Exception {
    AddColumnChange change = new AddColumnChange();
    AddColumnConfig column1 = new AddColumnConfig();
    column1.setName("column1");
    column1.setType("INT");
    change.addColumn(column1);
    AddColumnConfig column2 = new AddColumnConfig();
    column2.setName("column2");
    column2.setType("INT");
    change.addColumn(column2);
    SqlStatement[] statements = new SqlStatement[0];
    try {
        statements = change.generateStatements(createOfflineDatabase("offline:oracle"));
    } catch (DatabaseException e) {
        Assert.fail("Can't generate statements from an Offline Oracle database.");
    }
    Assert.assertEquals(1, statements.length);
    Assert.assertTrue(statements[0] instanceof AddColumnStatement);
    AddColumnStatement stmt = (AddColumnStatement) statements[0];
    Assert.assertTrue(stmt.isMultiple());
    Assert.assertEquals(2, stmt.getColumns().size());
}
Also used : SqlStatement(liquibase.statement.SqlStatement) AddColumnConfig(liquibase.change.AddColumnConfig) AddColumnChange(liquibase.change.core.AddColumnChange) DatabaseException(liquibase.exception.DatabaseException) AddColumnStatement(liquibase.statement.core.AddColumnStatement) Test(org.junit.Test)

Example 33 with DatabaseException

use of liquibase.exception.DatabaseException in project liquibase by liquibase.

the class DatabaseTestContext method openConnection.

private DatabaseConnection openConnection(final String url) throws Exception {
    if (connectionsAttempted.containsKey(url)) {
        JdbcConnection connection = (JdbcConnection) connectionsByUrl.get(url);
        if (connection == null) {
            return null;
        } else if (connection.getUnderlyingConnection().isClosed()) {
            connectionsByUrl.put(url, openDatabaseConnection(url));
        }
        return connectionsByUrl.get(url);
    }
    connectionsAttempted.put(url, Boolean.TRUE);
    if (System.getProperty(TEST_DATABASES_PROPERTY) != null) {
        boolean shouldTest = false;
        String[] databasesToTest = System.getProperty(TEST_DATABASES_PROPERTY).split("\\s*,\\s*");
        for (String database : databasesToTest) {
            if (url.indexOf(database) >= 0) {
                shouldTest = true;
            }
        }
        if (!shouldTest) {
            System.out.println("test.databases system property forbids testing against " + url);
            return null;
        } else {
            System.out.println("Will be tested against " + url);
        }
    }
    DatabaseConnection connection = openDatabaseConnection(url);
    if (connection == null) {
        return null;
    }
    Database database = DatabaseFactory.getInstance().findCorrectDatabaseImplementation(connection);
    final DatabaseConnection databaseConnection = database.getConnection();
    if (databaseConnection.getAutoCommit()) {
        databaseConnection.setAutoCommit(false);
    }
    try {
        if (url.startsWith("jdbc:hsql")) {
            ((JdbcConnection) databaseConnection).getUnderlyingConnection().createStatement().execute("CREATE SCHEMA " + ALT_SCHEMA + " AUTHORIZATION DBA");
        } else if (url.startsWith("jdbc:sqlserver") || url.startsWith("jdbc:postgresql") || url.startsWith("jdbc:h2")) {
            ((JdbcConnection) databaseConnection).getUnderlyingConnection().createStatement().execute("CREATE SCHEMA " + ALT_SCHEMA);
        }
        if (!databaseConnection.getAutoCommit()) {
            databaseConnection.commit();
        }
    } catch (SQLException e) {
        //schema already exists
        ;
    } finally {
        try {
            databaseConnection.rollback();
        } catch (DatabaseException e) {
            if (database instanceof DB2Database) {
            //                    expected, there is a problem with it
            } else {
                throw e;
            }
        }
    }
    connectionsByUrl.put(url, databaseConnection);
    Runtime.getRuntime().addShutdownHook(new Thread(new Runnable() {

        @Override
        public void run() {
            try {
                try {
                    if (!((JdbcConnection) databaseConnection).getUnderlyingConnection().getAutoCommit()) {
                        ((JdbcConnection) databaseConnection).getUnderlyingConnection().rollback();
                    }
                } catch (SQLException e) {
                    ;
                }
                ((JdbcConnection) databaseConnection).getUnderlyingConnection().close();
            } catch (SQLException e) {
                System.out.println("Could not close " + url);
                e.printStackTrace();
            }
        }
    }));
    return databaseConnection;
}
Also used : DB2Database(liquibase.database.core.DB2Database) SQLException(java.sql.SQLException) SQLiteDatabase(liquibase.database.core.SQLiteDatabase) DB2Database(liquibase.database.core.DB2Database) MockDatabase(liquibase.sdk.database.MockDatabase) ExampleCustomDatabase(liquibase.database.example.ExampleCustomDatabase) JdbcConnection(liquibase.database.jvm.JdbcConnection) DatabaseException(liquibase.exception.DatabaseException)

Example 34 with DatabaseException

use of liquibase.exception.DatabaseException in project liquibase by liquibase.

the class LockServiceExecuteTest method fixupLockTables.

private void fixupLockTables() throws DatabaseException, LockException {
    for (Database database : TestContext.getInstance().getAllDatabases()) {
        if (database.getConnection() != null) {
            Statement statement = null;
            try {
                statement = ((JdbcConnection) database.getConnection()).getUnderlyingConnection().createStatement();
                try {
                    statement.execute("drop table " + database.escapeTableName(database.getLiquibaseCatalogName(), database.getLiquibaseSchemaName(), database.getDatabaseChangeLogTableName()));
                } catch (Exception e) {
                //ok
                }
                try {
                    statement.execute("drop table " + database.escapeTableName(database.getLiquibaseCatalogName(), database.getLiquibaseSchemaName(), database.getDatabaseChangeLogLockTableName()));
                } catch (Exception e) {
                //ok
                }
                statement.close();
                database.commit();
            } catch (SQLException e) {
                throw new DatabaseException(e);
            }
        }
    }
}
Also used : SQLException(java.sql.SQLException) Statement(java.sql.Statement) Database(liquibase.database.Database) JdbcConnection(liquibase.database.jvm.JdbcConnection) DatabaseException(liquibase.exception.DatabaseException) LockException(liquibase.exception.LockException) DatabaseException(liquibase.exception.DatabaseException) SQLException(java.sql.SQLException)

Example 35 with DatabaseException

use of liquibase.exception.DatabaseException in project liquibase by liquibase.

the class AbstractIntegrationTest method clearDatabase.

protected void clearDatabase(Liquibase liquibase) throws DatabaseException {
    liquibase.dropAll(getSchemasToDrop());
    try {
        Statement statement = null;
        try {
            statement = ((JdbcConnection) database.getConnection()).getUnderlyingConnection().createStatement();
            statement.execute("drop table " + database.escapeTableName(database.getLiquibaseCatalogName(), database.getLiquibaseSchemaName(), database.getDatabaseChangeLogTableName()));
            database.commit();
        } catch (Exception e) {
            System.out.println("Probably expected error dropping databasechangelog table");
            e.printStackTrace();
            database.rollback();
        } finally {
            if (statement != null) {
                statement.close();
            }
        }
        try {
            statement = ((JdbcConnection) database.getConnection()).getUnderlyingConnection().createStatement();
            statement.execute("drop table " + database.escapeTableName(database.getLiquibaseCatalogName(), database.getLiquibaseSchemaName(), database.getDatabaseChangeLogLockTableName()));
            database.commit();
        } catch (Exception e) {
            System.out.println("Probably expected error dropping databasechangeloglock table");
            e.printStackTrace();
            database.rollback();
        } finally {
            if (statement != null) {
                statement.close();
            }
        }
    } catch (SQLException e) {
        throw new DatabaseException(e);
    }
    SnapshotGeneratorFactory.resetAll();
    DatabaseFactory.reset();
}
Also used : SQLException(java.sql.SQLException) DropTableStatement(liquibase.statement.core.DropTableStatement) Statement(java.sql.Statement) JdbcConnection(liquibase.database.jvm.JdbcConnection) DatabaseException(liquibase.exception.DatabaseException) ValidationFailedException(liquibase.exception.ValidationFailedException) ChangeLogParseException(liquibase.exception.ChangeLogParseException) SQLException(java.sql.SQLException) DatabaseException(liquibase.exception.DatabaseException) LiquibaseException(liquibase.exception.LiquibaseException)

Aggregations

DatabaseException (liquibase.exception.DatabaseException)73 SQLException (java.sql.SQLException)25 Database (liquibase.database.Database)24 UnexpectedLiquibaseException (liquibase.exception.UnexpectedLiquibaseException)16 AbstractJdbcDatabase (liquibase.database.AbstractJdbcDatabase)14 CatalogAndSchema (liquibase.CatalogAndSchema)13 LiquibaseException (liquibase.exception.LiquibaseException)13 MSSQLDatabase (liquibase.database.core.MSSQLDatabase)12 JdbcConnection (liquibase.database.jvm.JdbcConnection)12 CachedRow (liquibase.snapshot.CachedRow)10 InvalidExampleException (liquibase.snapshot.InvalidExampleException)10 JdbcDatabaseSnapshot (liquibase.snapshot.JdbcDatabaseSnapshot)10 Executor (liquibase.executor.Executor)9 DatabaseConnection (liquibase.database.DatabaseConnection)7 OfflineConnection (liquibase.database.OfflineConnection)7 Connection (java.sql.Connection)6 Statement (java.sql.Statement)6 SQLiteDatabase (liquibase.database.core.SQLiteDatabase)6 RawSqlStatement (liquibase.statement.core.RawSqlStatement)6 IOException (java.io.IOException)5