Search in sources :

Example 6 with Database

use of org.jumpmind.db.model.Database in project symmetric-ds by JumpMind.

the class AbstractDdlBuilder method processTableStructureChanges.

/**
     * Processes the changes to the structure of tables.
     *
     * @param currentModel
     *            The current database schema
     * @param desiredModel
     *            The desired database schema
     * @param changes
     *            The change objects
     */
protected void processTableStructureChanges(Database currentModel, Database desiredModel, Collection<TableChange> changes, StringBuilder ddl) {
    filterChanges(changes);
    LinkedHashMap<String, List<TableChange>> changesPerTable = new LinkedHashMap<String, List<TableChange>>();
    LinkedHashMap<String, List<ForeignKey>> unchangedFKs = new LinkedHashMap<String, List<ForeignKey>>();
    boolean caseSensitive = delimitedIdentifierModeOn;
    // we use the names rather than the table objects
    for (Iterator<TableChange> changeIt = changes.iterator(); changeIt.hasNext(); ) {
        TableChange change = changeIt.next();
        String name = change.getChangedTable().getName();
        if (!caseSensitive) {
            name = name.toUpperCase();
        }
        List<TableChange> changesForTable = (List<TableChange>) changesPerTable.get(name);
        if (changesForTable == null) {
            changesForTable = new ArrayList<TableChange>();
            changesPerTable.put(name, changesForTable);
            unchangedFKs.put(name, getUnchangedForeignKeys(currentModel, desiredModel, name));
        }
        changesForTable.add(change);
    }
    // we also need to drop the foreign keys of the unchanged tables
    // referencing the changed tables
    addRelevantFKsFromUnchangedTables(currentModel, desiredModel, changesPerTable.keySet(), unchangedFKs);
    // we're dropping the unchanged foreign keys
    for (Iterator<Map.Entry<String, List<ForeignKey>>> tableFKIt = unchangedFKs.entrySet().iterator(); tableFKIt.hasNext(); ) {
        Map.Entry<String, List<ForeignKey>> entry = tableFKIt.next();
        Table targetTable = findTable(desiredModel, (String) entry.getKey());
        for (Iterator<ForeignKey> fkIt = entry.getValue().iterator(); fkIt.hasNext(); ) {
            writeExternalForeignKeyDropStmt(targetTable, fkIt.next(), ddl);
        }
    }
    // We're using a copy of the current model so that the table structure
    // changes can modify it
    Database copyOfCurrentModel = copy(currentModel);
    for (Iterator<Map.Entry<String, List<TableChange>>> tableChangeIt = changesPerTable.entrySet().iterator(); tableChangeIt.hasNext(); ) {
        Map.Entry<String, List<TableChange>> entry = tableChangeIt.next();
        processTableStructureChanges(copyOfCurrentModel, desiredModel, entry.getKey(), entry.getValue(), ddl);
    }
    // and finally we're re-creating the unchanged foreign keys
    for (Iterator<Map.Entry<String, List<ForeignKey>>> tableFKIt = unchangedFKs.entrySet().iterator(); tableFKIt.hasNext(); ) {
        Map.Entry<String, List<ForeignKey>> entry = tableFKIt.next();
        Table targetTable = findTable(desiredModel, (String) entry.getKey());
        for (Iterator<ForeignKey> fkIt = entry.getValue().iterator(); fkIt.hasNext(); ) {
            writeExternalForeignKeyCreateStmt(desiredModel, targetTable, fkIt.next(), ddl);
        }
    }
}
Also used : Table(org.jumpmind.db.model.Table) ForeignKey(org.jumpmind.db.model.ForeignKey) LinkedHashMap(java.util.LinkedHashMap) Database(org.jumpmind.db.model.Database) List(java.util.List) ArrayList(java.util.ArrayList) TypeMap(org.jumpmind.db.model.TypeMap) Map(java.util.Map) LinkedHashMap(java.util.LinkedHashMap) RemoveTableChange(org.jumpmind.db.alter.RemoveTableChange) TableChange(org.jumpmind.db.alter.TableChange) AddTableChange(org.jumpmind.db.alter.AddTableChange)

Example 7 with Database

use of org.jumpmind.db.model.Database in project symmetric-ds by JumpMind.

the class AbstractDdlBuilder method processTableStructureChanges.

/**
     * Processes the changes to the structure of a single table.
     * Database-specific implementations might redefine this method, but it is
     * usually sufficient to redefine the
     * {@link #processTableStructureChanges(Database, Database, Table, Table, Map, List)}
     * method instead.
     */
protected void processTableStructureChanges(Database currentModel, Database desiredModel, String tableName, List<TableChange> changes, StringBuilder ddl) {
    StringBuilder tableDdl = new StringBuilder();
    Database originalModel = copy(currentModel);
    Table sourceTable = findTable(originalModel, tableName);
    Table targetTable = findTable(desiredModel, tableName);
    // we're enforcing a full rebuild in case of the addition of a required
    // column without a default value that is not autoincrement
    boolean requiresFullRebuild = false;
    for (Iterator<TableChange> changeIt = changes.iterator(); !requiresFullRebuild && changeIt.hasNext(); ) {
        TableChange change = changeIt.next();
        if (change instanceof AddColumnChange) {
            AddColumnChange addColumnChange = (AddColumnChange) change;
            if (addColumnChange.getNewColumn().isRequired() && (addColumnChange.getNewColumn().getDefaultValue() == null) && !addColumnChange.getNewColumn().isAutoIncrement()) {
                requiresFullRebuild = true;
            }
        }
    }
    if (!requiresFullRebuild) {
        processTableStructureChanges(currentModel, desiredModel, sourceTable, targetTable, changes, tableDdl);
    }
    if (!changes.isEmpty()) {
        // we can only copy the data if no required columns without default
        // value and non-autoincrement have been added
        boolean canMigrateData = true;
        Table tempTable = getTemporaryTableFor(sourceTable);
        for (Iterator<TableChange> it = changes.iterator(); canMigrateData && it.hasNext(); ) {
            TableChange change = it.next();
            if (change instanceof AddColumnChange) {
                AddColumnChange addColumnChange = (AddColumnChange) change;
                if (addColumnChange.getNewColumn().isRequired() && !addColumnChange.getNewColumn().isAutoIncrement() && (addColumnChange.getNewColumn().getDefaultValue() == null)) {
                    log.warn("Data cannot be retained in table " + change.getChangedTable().getName() + " because of the addition of the required column " + addColumnChange.getNewColumn().getName() + " . The data is backed up in " + tempTable + ", consider manually migrating the data back or dropping this temp table.");
                    canMigrateData = false;
                }
            }
        }
        Table realTargetTable = getRealTargetTableFor(desiredModel, sourceTable, targetTable);
        dropTemporaryTable(tempTable, ddl);
        createTemporaryTable(tempTable, ddl);
        writeCopyDataStatement(sourceTable, tempTable, ddl);
        /*
             * Note that we don't drop the indices here because the DROP
             * TABLE will take care of that Likewise, foreign keys have
             * already been dropped as necessary
             */
        dropTable(sourceTable, ddl, false, true);
        createTable(realTargetTable, ddl, false, true);
        if (canMigrateData) {
            writeCopyDataStatement(tempTable, targetTable, ddl);
            dropTemporaryTable(tempTable, ddl);
            writeFixLastIdentityValues(targetTable, ddl);
        }
    } else {
        ddl.append(tableDdl);
    }
}
Also used : Table(org.jumpmind.db.model.Table) Database(org.jumpmind.db.model.Database) AddColumnChange(org.jumpmind.db.alter.AddColumnChange) RemoveTableChange(org.jumpmind.db.alter.RemoveTableChange) TableChange(org.jumpmind.db.alter.TableChange) AddTableChange(org.jumpmind.db.alter.AddTableChange)

Example 8 with Database

use of org.jumpmind.db.model.Database in project symmetric-ds by JumpMind.

the class AbstractDatabasePlatform method readDatabaseFromXml.

public Database readDatabaseFromXml(InputStream is, boolean alterCaseToMatchDatabaseDefaultCase) {
    InputStreamReader reader = new InputStreamReader(is);
    Database database = DatabaseXmlUtil.read(reader);
    if (alterCaseToMatchDatabaseDefaultCase) {
        alterCaseToMatchDatabaseDefaultCase(database);
    }
    return database;
}
Also used : InputStreamReader(java.io.InputStreamReader) Database(org.jumpmind.db.model.Database)

Example 9 with Database

use of org.jumpmind.db.model.Database in project symmetric-ds by JumpMind.

the class AbstractDatabasePlatform method readFromDatabase.

public Database readFromDatabase(Table... tables) {
    Database fromDb = new Database();
    for (Table tableFromXml : tables) {
        Table tableFromDatabase = getTableFromCache(tableFromXml.getCatalog(), tableFromXml.getSchema(), tableFromXml.getName(), true);
        if (tableFromDatabase != null) {
            fromDb.addTable(tableFromDatabase);
        }
    }
    fromDb.initialize();
    return fromDb;
}
Also used : Table(org.jumpmind.db.model.Table) Database(org.jumpmind.db.model.Database)

Example 10 with Database

use of org.jumpmind.db.model.Database in project symmetric-ds by JumpMind.

the class MsSqlSymmetricDialect method readSymmetricSchemaFromXml.

@Override
public Database readSymmetricSchemaFromXml() {
    Database db = super.readSymmetricSchemaFromXml();
    if (parameterService.is(ParameterConstants.MSSQL_USE_NTYPES_FOR_SYNC)) {
        Table table = db.findTable(TableConstants.getTableName(getTablePrefix(), TableConstants.SYM_DATA));
        setColumnToNtext(table.getColumnWithName("row_data"));
        setColumnToNtext(table.getColumnWithName("old_data"));
        setColumnToNtext(table.getColumnWithName("pk_data"));
    }
    return db;
}
Also used : Table(org.jumpmind.db.model.Table) Database(org.jumpmind.db.model.Database)

Aggregations

Database (org.jumpmind.db.model.Database)37 Table (org.jumpmind.db.model.Table)21 IDatabasePlatform (org.jumpmind.db.platform.IDatabasePlatform)9 Test (org.junit.Test)7 IOException (java.io.IOException)6 IoException (org.jumpmind.exception.IoException)6 AbstractServiceTest (org.jumpmind.symmetric.service.impl.AbstractServiceTest)5 IDdlBuilder (org.jumpmind.db.platform.IDdlBuilder)4 SqlException (org.jumpmind.db.sql.SqlException)4 SqlScript (org.jumpmind.db.sql.SqlScript)4 DbExport (org.jumpmind.symmetric.io.data.DbExport)4 DbImport (org.jumpmind.symmetric.io.data.DbImport)4 File (java.io.File)3 ArrayList (java.util.ArrayList)3 InputStreamReader (java.io.InputStreamReader)2 LinkedHashMap (java.util.LinkedHashMap)2 AddTableChange (org.jumpmind.db.alter.AddTableChange)2 RemoveTableChange (org.jumpmind.db.alter.RemoveTableChange)2 TableChange (org.jumpmind.db.alter.TableChange)2 Column (org.jumpmind.db.model.Column)2