Search in sources :

Example 26 with PostgresDatabase

use of liquibase.database.core.PostgresDatabase in project liquibase by liquibase.

the class BooleanTypeTest method postgresqlBitStringError.

@Test(expected = UnexpectedLiquibaseException.class)
public void postgresqlBitStringError() {
    BooleanType bt = new BooleanType();
    bt.finishInitialization("bit(12)");
    assertNotEquals("b'1'", bt.objectToSql("'12'", new PostgresDatabase()));
}
Also used : PostgresDatabase(liquibase.database.core.PostgresDatabase) BooleanType(liquibase.datatype.core.BooleanType) Test(org.junit.Test)

Example 27 with PostgresDatabase

use of liquibase.database.core.PostgresDatabase in project liquibase by liquibase.

the class AbstractIntegrationTest method wipeDatabase.

/**
 * Wipes all Liquibase schemas in the database before testing starts. This includes the DATABASECHANGELOG/LOCK
 * tables.
 */
protected void wipeDatabase() {
    emptySchemas.clear();
    try {
        // TODO the cleaner solution would be to have a noCachingHasObject() Method in SnapshotGeneratorFactory
        try {
            if (database.getConnection() != null) {
                String sql = "DROP TABLE " + database.getDatabaseChangeLogLockTableName();
                for (SqlListener listener : Scope.getCurrentScope().getListeners(SqlListener.class)) {
                    listener.writeSqlWillRun(sql);
                }
                ((JdbcConnection) database.getConnection()).getUnderlyingConnection().createStatement().executeUpdate(sql);
                database.commit();
            }
        } catch (SQLException e) {
            if (database instanceof PostgresDatabase) {
                // throws "current transaction is aborted" unless we roll back the connection
                database.rollback();
            }
        }
        SnapshotGeneratorFactory.resetAll();
        LockService lockService = LockServiceFactory.getInstance().getLockService(database);
        emptyTestSchema(CatalogAndSchema.DEFAULT.getCatalogName(), CatalogAndSchema.DEFAULT.getSchemaName(), database);
        SnapshotGeneratorFactory factory = SnapshotGeneratorFactory.getInstance();
        if (database.supportsSchemas()) {
            emptyTestSchema(null, ALT_SCHEMA, database);
        }
        if (supportsAltCatalogTests()) {
            if (database.supportsSchemas() && database.supportsCatalogs()) {
                emptyTestSchema(ALT_CATALOG, ALT_SCHEMA, database);
            }
        }
        /*
             * There is a special treatment for identifiers in the case when (a) the RDBMS does NOT support
             * schemas AND (b) the RDBMS DOES support catalogs AND (c) someone uses "schemaName=..." in a
             * Liquibase ChangeSet. In this case, AbstractJdbcDatabase.escapeObjectName assumes the author
             * was intending to write "catalog=..." and transparently rewrites the expression.
             * For us, this means that we have to wipe both ALT_SCHEMA and ALT_CATALOG to be sure we
             * are doing a thorough cleanup.
             */
        CatalogAndSchema[] alternativeLocations = new CatalogAndSchema[] { new CatalogAndSchema(ALT_CATALOG, null), new CatalogAndSchema(null, ALT_SCHEMA), new CatalogAndSchema("LBCAT2", database.getDefaultSchemaName()), new CatalogAndSchema(null, "LBCAT2"), new CatalogAndSchema("lbcat2", database.getDefaultSchemaName()), new CatalogAndSchema(null, "lbcat2") };
        for (CatalogAndSchema location : alternativeLocations) {
            emptyTestSchema(location.getCatalogName(), location.getSchemaName(), database);
        }
        database.commit();
        SnapshotGeneratorFactory.resetAll();
    } catch (Exception e) {
        throw new RuntimeException(e);
    }
}
Also used : PostgresDatabase(liquibase.database.core.PostgresDatabase) SqlListener(liquibase.listener.SqlListener) LockService(liquibase.lockservice.LockService) SQLException(java.sql.SQLException) JdbcConnection(liquibase.database.jvm.JdbcConnection) SnapshotGeneratorFactory(liquibase.snapshot.SnapshotGeneratorFactory) ValidationFailedException(liquibase.exception.ValidationFailedException) ChangeLogParseException(liquibase.exception.ChangeLogParseException) SQLException(java.sql.SQLException) DatabaseException(liquibase.exception.DatabaseException) LiquibaseException(liquibase.exception.LiquibaseException)

Example 28 with PostgresDatabase

use of liquibase.database.core.PostgresDatabase in project liquibase by liquibase.

the class AbstractIntegrationTest method testRerunDiffChangeLog.

@Test
public void testRerunDiffChangeLog() throws Exception {
    assumeNotNull(this.getDatabase());
    for (int run = 0; run < 2; run++) {
        // run once outputting data as insert, once as csv
        boolean outputCsv = run == 1;
        runCompleteChangeLog();
        SnapshotControl snapshotControl = new SnapshotControl(database);
        DatabaseSnapshot originalSnapshot = SnapshotGeneratorFactory.getInstance().createSnapshot(database.getDefaultSchema(), database, snapshotControl);
        CompareControl compareControl = new CompareControl();
        // database returns different data even if the same
        compareControl.addSuppressedField(Column.class, "defaultValue");
        // database returns different data even if the same
        compareControl.addSuppressedField(Column.class, "autoIncrementInformation");
        if (database instanceof OracleDatabase) {
            // database returns different nvarchar2 info even though they are the same
            compareControl.addSuppressedField(Column.class, "type");
            // database returns different nullable on views, e.g. v_person.id
            compareControl.addSuppressedField(Column.class, "nullable");
        }
        if (database instanceof PostgresDatabase) {
            // database returns different nvarchar2 info even though they are the same
            compareControl.addSuppressedField(Column.class, "type");
        }
        DiffOutputControl diffOutputControl = new DiffOutputControl();
        File tempFile = tempDirectory.getRoot().createTempFile("liquibase-test", ".xml");
        if (outputCsv) {
            diffOutputControl.setDataDir(new File(tempFile.getParentFile(), "liquibase-data").getCanonicalPath().replaceFirst("\\w:", ""));
        }
        DiffResult diffResult = DiffGeneratorFactory.getInstance().compare(database, null, compareControl);
        FileOutputStream output = new FileOutputStream(tempFile);
        try {
            new DiffToChangeLog(diffResult, new DiffOutputControl()).print(new PrintStream(output));
            output.flush();
        } finally {
            output.close();
        }
        Liquibase liquibase = createLiquibase(tempFile.getName());
        clearDatabase();
        DatabaseSnapshot emptySnapshot = SnapshotGeneratorFactory.getInstance().createSnapshot(database.getDefaultSchema(), database, new SnapshotControl(database));
        // run again to test changelog testing logic
        liquibase = createLiquibase(tempFile.getName());
        try {
            liquibase.update(this.contexts);
        } catch (ValidationFailedException e) {
            e.printDescriptiveError(System.out);
            throw e;
        }
        DatabaseSnapshot migratedSnapshot = SnapshotGeneratorFactory.getInstance().createSnapshot(database.getDefaultSchema(), database, new SnapshotControl(database));
        DiffResult finalDiffResult = DiffGeneratorFactory.getInstance().compare(originalSnapshot, migratedSnapshot, compareControl);
        try {
            assertTrue("recreating the database from the generated change log should cause both 'before' and " + "'after' snapshots to be equal.", finalDiffResult.areEqual());
        } catch (AssertionError e) {
            new DiffToReport(finalDiffResult, System.err).print();
            throw e;
        }
        // diff to empty and drop all
        DiffResult emptyDiffResult = DiffGeneratorFactory.getInstance().compare(emptySnapshot, migratedSnapshot, compareControl);
        output = new FileOutputStream(tempFile);
        try {
            new DiffToChangeLog(emptyDiffResult, new DiffOutputControl(true, true, true, null)).print(new PrintStream(output));
            output.flush();
        } finally {
            output.close();
        }
        liquibase = createLiquibase(tempFile.getName());
        Scope.getCurrentScope().getLog(getClass()).info("updating from " + tempFile.getCanonicalPath());
        try {
            liquibase.update(this.contexts);
        } catch (LiquibaseException e) {
            throw e;
        }
        DatabaseSnapshot emptyAgainSnapshot = SnapshotGeneratorFactory.getInstance().createSnapshot(database.getDefaultSchema(), database, new SnapshotControl(database));
        assertEquals("a database that was 'updated' to an empty snapshot should only have 2 tables left: " + "the database change log table and the lock table.", 2, emptyAgainSnapshot.get(Table.class).size());
        assertEquals("a database that was 'updated' to an empty snapshot should not contain any views.", 0, emptyAgainSnapshot.get(View.class).size());
    }
}
Also used : DiffOutputControl(liquibase.diff.output.DiffOutputControl) OracleDatabase(liquibase.database.core.OracleDatabase) PostgresDatabase(liquibase.database.core.PostgresDatabase) ValidationFailedException(liquibase.exception.ValidationFailedException) DiffToReport(liquibase.diff.output.report.DiffToReport) CompareControl(liquibase.diff.compare.CompareControl) DiffToChangeLog(liquibase.diff.output.changelog.DiffToChangeLog) DiffResult(liquibase.diff.DiffResult) LiquibaseException(liquibase.exception.LiquibaseException) SnapshotControl(liquibase.snapshot.SnapshotControl) DatabaseSnapshot(liquibase.snapshot.DatabaseSnapshot) Test(org.junit.Test)

Example 29 with PostgresDatabase

use of liquibase.database.core.PostgresDatabase in project liquibase by liquibase.

the class ChangedSequenceChangeGenerator method fixChanged.

@Override
public Change[] fixChanged(DatabaseObject changedObject, ObjectDifferences differences, DiffOutputControl control, Database referenceDatabase, Database comparisonDatabase, ChangeGeneratorChain chain) {
    Sequence sequence = (Sequence) changedObject;
    List<Change> changes = new ArrayList<>();
    AlterSequenceChange accumulatedChange = createAlterSequenceChange(sequence, control);
    if (differences.isDifferent("incrementBy")) {
        AlterSequenceChange change = createAlterSequenceChange(sequence, control);
        change.setIncrementBy(sequence.getIncrementBy());
        accumulatedChange.setIncrementBy(sequence.getIncrementBy());
        changes.add(change);
    }
    if (differences.isDifferent("maxValue")) {
        AlterSequenceChange change = createAlterSequenceChange(sequence, control);
        change.setMaxValue(sequence.getMaxValue());
        accumulatedChange.setMaxValue(sequence.getMaxValue());
        changes.add(change);
    }
    if (differences.isDifferent("minValue")) {
        AlterSequenceChange change = createAlterSequenceChange(sequence, control);
        change.setMinValue(sequence.getMinValue());
        accumulatedChange.setMinValue(sequence.getMinValue());
        changes.add(change);
        changes.add(change);
    }
    if (differences.isDifferent("ordered")) {
        AlterSequenceChange change = createAlterSequenceChange(sequence, control);
        change.setOrdered(sequence.getOrdered());
        accumulatedChange.setOrdered(sequence.getOrdered());
        changes.add(change);
    }
    if (differences.isDifferent("cacheSize")) {
        AlterSequenceChange change = createAlterSequenceChange(sequence, control);
        change.setCacheSize(sequence.getCacheSize());
        accumulatedChange.setCacheSize(sequence.getCacheSize());
        changes.add(change);
    }
    if (differences.isDifferent("willCycle")) {
        AlterSequenceChange change = createAlterSequenceChange(sequence, control);
        change.setCycle(sequence.getWillCycle());
        accumulatedChange.setCycle(sequence.getWillCycle());
        changes.add(change);
    }
    if (differences.isDifferent("dataType")) {
        AlterSequenceChange change = createAlterSequenceChange(sequence, control);
        change.setDataType(sequence.getDataType());
        accumulatedChange.setDataType(sequence.getDataType());
        changes.add(change);
    }
    if (changes.isEmpty()) {
        return null;
    } else if (comparisonDatabase instanceof PostgresDatabase) {
        return new Change[] { accumulatedChange };
    } else {
        return changes.toArray(new Change[changes.size()]);
    }
}
Also used : PostgresDatabase(liquibase.database.core.PostgresDatabase) ArrayList(java.util.ArrayList) Sequence(liquibase.structure.core.Sequence) Change(liquibase.change.Change) AlterSequenceChange(liquibase.change.core.AlterSequenceChange) AlterSequenceChange(liquibase.change.core.AlterSequenceChange)

Example 30 with PostgresDatabase

use of liquibase.database.core.PostgresDatabase in project liquibase by liquibase.

the class MissingTableChangeGenerator method fixMissing.

@Override
public Change[] fixMissing(DatabaseObject missingObject, DiffOutputControl control, Database referenceDatabase, Database comparisonDatabase, ChangeGeneratorChain chain) {
    Table missingTable = (Table) missingObject;
    PrimaryKey primaryKey = missingTable.getPrimaryKey();
    List<String> pkColumnList = ((primaryKey != null) ? primaryKey.getColumnNamesAsList() : null);
    Map<Column, UniqueConstraint> singleUniqueConstraints = getSingleColumnUniqueConstraints(missingTable);
    CreateTableChange change = createCreateTableChange();
    change.setTableName(missingTable.getName());
    if (control.getIncludeCatalog()) {
        change.setCatalogName(missingTable.getSchema().getCatalogName());
    }
    if (control.getIncludeSchema()) {
        change.setSchemaName(missingTable.getSchema().getName());
    }
    if (missingTable.getRemarks() != null) {
        change.setRemarks(missingTable.getRemarks());
    }
    if (control.getIncludeTablespace() && (missingTable.getTablespace() != null) && comparisonDatabase.supportsTablespaces()) {
        change.setTablespace(missingTable.getTablespace());
    }
    for (Column column : missingTable.getColumns()) {
        ColumnConfig columnConfig = new ColumnConfig();
        columnConfig.setName(column.getName());
        LiquibaseDataType ldt = DataTypeFactory.getInstance().from(column.getType(), referenceDatabase);
        DatabaseDataType ddt = ldt.toDatabaseDataType(comparisonDatabase);
        String typeString = ddt.toString();
        if (comparisonDatabase instanceof MSSQLDatabase) {
            typeString = comparisonDatabase.unescapeDataTypeString(typeString);
        }
        columnConfig.setType(typeString);
        if (column.isAutoIncrement()) {
            columnConfig.setAutoIncrement(true);
        }
        boolean primaryKeyOrderMatchesTableOrder = checkPrimaryKeyOrderMatchesTableOrder(missingTable, pkColumnList);
        ConstraintsConfig constraintsConfig = null;
        // In MySQL, the primary key must be specified at creation for an autoincrement column
        if ((pkColumnList != null) && primaryKeyOrderMatchesTableOrder && pkColumnList.contains(column.getName())) {
            if ((referenceDatabase instanceof MSSQLDatabase) && (primaryKey.getBackingIndex() != null) && (primaryKey.getBackingIndex().getClustered() != null) && !primaryKey.getBackingIndex().getClustered()) {
            // have to handle PK as a separate statement
            } else if ((referenceDatabase instanceof PostgresDatabase) && (primaryKey.getBackingIndex() != null) && (primaryKey.getBackingIndex().getClustered() != null) && primaryKey.getBackingIndex().getClustered()) {
            // have to handle PK as a separate statement
            } else {
                constraintsConfig = new ConstraintsConfig();
                if (shouldAddPrimarykeyToConstraints(missingObject, control, referenceDatabase, comparisonDatabase)) {
                    constraintsConfig.setPrimaryKey(true);
                    constraintsConfig.setPrimaryKeyTablespace(primaryKey.getTablespace());
                    // MySQL sets some primary key names as PRIMARY which is invalid
                    if ((comparisonDatabase instanceof MySQLDatabase) && "PRIMARY".equals(primaryKey.getName())) {
                        constraintsConfig.setPrimaryKeyName(null);
                    } else {
                        constraintsConfig.setPrimaryKeyName(primaryKey.getName());
                    }
                    control.setAlreadyHandledMissing(primaryKey);
                    control.setAlreadyHandledMissing(primaryKey.getBackingIndex());
                } else {
                    constraintsConfig.setNullable(false);
                }
            }
        }
        if ((column.isNullable() != null) && !column.isNullable()) {
            if (constraintsConfig == null) {
                constraintsConfig = new ConstraintsConfig();
            }
            constraintsConfig.setNullable(false);
            if (!column.getValidateNullable()) {
                constraintsConfig.setValidateNullable(false);
            }
            constraintsConfig.setNotNullConstraintName(column.getAttribute("notNullConstraintName", String.class));
        }
        if (referenceDatabase instanceof MySQLDatabase) {
            UniqueConstraint uniqueConstraint = singleUniqueConstraints.get(column);
            if (uniqueConstraint != null) {
                if (!control.alreadyHandledMissing(uniqueConstraint, referenceDatabase)) {
                    if (constraintsConfig == null) {
                        constraintsConfig = new ConstraintsConfig();
                    }
                    constraintsConfig.setUnique(true);
                    control.setAlreadyHandledMissing(uniqueConstraint);
                    control.setAlreadyHandledMissing(uniqueConstraint.getBackingIndex());
                }
            }
        }
        if (constraintsConfig != null) {
            columnConfig.setConstraints(constraintsConfig);
        }
        setDefaultValue(columnConfig, column, referenceDatabase);
        if (column.getRemarks() != null) {
            columnConfig.setRemarks(column.getRemarks());
        }
        Column.AutoIncrementInformation autoIncrementInfo = column.getAutoIncrementInformation();
        if (autoIncrementInfo != null) {
            BigInteger startWith = autoIncrementInfo.getStartWith();
            BigInteger incrementBy = autoIncrementInfo.getIncrementBy();
            String generationType = autoIncrementInfo.getGenerationType();
            Boolean defaultOnNull = autoIncrementInfo.getDefaultOnNull();
            if ((startWith != null) && !startWith.equals(BigInteger.ONE)) {
                columnConfig.setStartWith(startWith);
            }
            if ((incrementBy != null) && !incrementBy.equals(BigInteger.ONE)) {
                columnConfig.setIncrementBy(incrementBy);
            }
            if (StringUtil.isNotEmpty(generationType)) {
                columnConfig.setGenerationType(generationType);
                if (defaultOnNull != null) {
                    columnConfig.setDefaultOnNull(defaultOnNull);
                }
            }
        }
        // 
        if (column.getComputed() != null) {
            columnConfig.setComputed(column.getComputed());
        }
        change.addColumn(columnConfig);
        control.setAlreadyHandledMissing(column);
    }
    return new Change[] { change };
}
Also used : Table(liquibase.structure.core.Table) ColumnConfig(liquibase.change.ColumnConfig) LiquibaseDataType(liquibase.datatype.LiquibaseDataType) PrimaryKey(liquibase.structure.core.PrimaryKey) UniqueConstraint(liquibase.structure.core.UniqueConstraint) MySQLDatabase(liquibase.database.core.MySQLDatabase) Change(liquibase.change.Change) CreateTableChange(liquibase.change.core.CreateTableChange) PostgresDatabase(liquibase.database.core.PostgresDatabase) DatabaseDataType(liquibase.datatype.DatabaseDataType) Column(liquibase.structure.core.Column) CreateTableChange(liquibase.change.core.CreateTableChange) ConstraintsConfig(liquibase.change.ConstraintsConfig) BigInteger(java.math.BigInteger) MSSQLDatabase(liquibase.database.core.MSSQLDatabase)

Aggregations

PostgresDatabase (liquibase.database.core.PostgresDatabase)33 Test (org.junit.Test)19 Sql (liquibase.sql.Sql)16 Database (liquibase.database.Database)11 MSSQLDatabase (liquibase.database.core.MSSQLDatabase)11 AbstractSqlGeneratorTest (liquibase.sqlgenerator.AbstractSqlGeneratorTest)11 MySQLDatabase (liquibase.database.core.MySQLDatabase)10 OracleDatabase (liquibase.database.core.OracleDatabase)10 SQLiteDatabase (liquibase.database.core.SQLiteDatabase)9 AbstractDb2Database (liquibase.database.core.AbstractDb2Database)8 H2Database (liquibase.database.core.H2Database)7 SybaseASADatabase (liquibase.database.core.SybaseASADatabase)7 SybaseDatabase (liquibase.database.core.SybaseDatabase)7 BigInteger (java.math.BigInteger)6 ColumnConfig (liquibase.change.ColumnConfig)6 DerbyDatabase (liquibase.database.core.DerbyDatabase)6 HsqlDatabase (liquibase.database.core.HsqlDatabase)6 CreateTableStatement (liquibase.statement.core.CreateTableStatement)6 MockDatabaseConnection (liquibase.database.MockDatabaseConnection)5 ArrayList (java.util.ArrayList)4