📄 modelcomparator.java
字号:
package org.apache.ddlutils.alteration;
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.ddlutils.PlatformInfo;
import org.apache.ddlutils.model.Column;
import org.apache.ddlutils.model.Database;
import org.apache.ddlutils.model.ForeignKey;
import org.apache.ddlutils.model.Index;
import org.apache.ddlutils.model.Table;
/**
* Compares two database models and creates change objects that express how to
* adapt the first model so that it becomes the second one. Neither of the models
* are changed in the process, however, it is also assumed that the models do not
* change in between.
*
* TODO: Add support and tests for the change of the column order
*
* @version $Revision: $
*/
public class ModelComparator
{
/** The log for this comparator. */
private final Log _log = LogFactory.getLog(ModelComparator.class);
/** The platform information. */
private PlatformInfo _platformInfo;
/** Whether comparison is case sensitive. */
private boolean _caseSensitive;
/**
* Creates a new model comparator object.
*
* @param platformInfo The platform info
* @param caseSensitive Whether comparison is case sensitive
*/
public ModelComparator(PlatformInfo platformInfo, boolean caseSensitive)
{
_platformInfo = platformInfo;
_caseSensitive = caseSensitive;
}
/**
* Compares the two models and returns the changes necessary to create the second
* model from the first one.
*
* @param sourceModel The source model
* @param targetModel The target model
* @return The changes
*/
public List compare(Database sourceModel, Database targetModel)
{
ArrayList changes = new ArrayList();
for (int tableIdx = 0; tableIdx < targetModel.getTableCount(); tableIdx++)
{
Table targetTable = targetModel.getTable(tableIdx);
Table sourceTable = sourceModel.findTable(targetTable.getName(), _caseSensitive);
if (sourceTable == null)
{
if (_log.isInfoEnabled())
{
_log.info("Table " + targetTable.getName() + " needs to be added");
}
changes.add(new AddTableChange(targetTable));
for (int fkIdx = 0; fkIdx < targetTable.getForeignKeyCount(); fkIdx++)
{
// we have to use target table's definition here because the
// complete table is new
changes.add(new AddForeignKeyChange(targetTable, targetTable.getForeignKey(fkIdx)));
}
}
else
{
changes.addAll(compareTables(sourceModel, sourceTable, targetModel, targetTable));
}
}
for (int tableIdx = 0; tableIdx < sourceModel.getTableCount(); tableIdx++)
{
Table sourceTable = sourceModel.getTable(tableIdx);
Table targetTable = targetModel.findTable(sourceTable.getName(), _caseSensitive);
if ((targetTable == null) && (sourceTable.getName() != null) && (sourceTable.getName().length() > 0))
{
if (_log.isInfoEnabled())
{
_log.info("Table " + sourceTable.getName() + " needs to be removed");
}
changes.add(new RemoveTableChange(sourceTable));
// we assume that the target model is sound, ie. that there are no longer any foreign
// keys to this table in the target model; thus we already have removeFK changes for
// these from the compareTables method and we only need to create changes for the fks
// originating from this table
for (int fkIdx = 0; fkIdx < sourceTable.getForeignKeyCount(); fkIdx++)
{
changes.add(new RemoveForeignKeyChange(sourceTable, sourceTable.getForeignKey(fkIdx)));
}
}
}
return changes;
}
/**
* Compares the two tables and returns the changes necessary to create the second
* table from the first one.
*
* @param sourceModel The source model which contains the source table
* @param sourceTable The source table
* @param targetModel The target model which contains the target table
* @param targetTable The target table
* @return The changes
*/
public List compareTables(Database sourceModel,
Table sourceTable,
Database targetModel,
Table targetTable)
{
ArrayList changes = new ArrayList();
for (int fkIdx = 0; fkIdx < sourceTable.getForeignKeyCount(); fkIdx++)
{
ForeignKey sourceFk = sourceTable.getForeignKey(fkIdx);
ForeignKey targetFk = findCorrespondingForeignKey(targetTable, sourceFk);
if (targetFk == null)
{
if (_log.isInfoEnabled())
{
_log.info("Foreign key " + sourceFk + " needs to be removed from table " + sourceTable.getName());
}
changes.add(new RemoveForeignKeyChange(sourceTable, sourceFk));
}
}
for (int fkIdx = 0; fkIdx < targetTable.getForeignKeyCount(); fkIdx++)
{
ForeignKey targetFk = targetTable.getForeignKey(fkIdx);
ForeignKey sourceFk = findCorrespondingForeignKey(sourceTable, targetFk);
if (sourceFk == null)
{
if (_log.isInfoEnabled())
{
_log.info("Foreign key " + targetFk + " needs to be created for table " + sourceTable.getName());
}
// we have to use the target table here because the foreign key might
// reference a new column
changes.add(new AddForeignKeyChange(targetTable, targetFk));
}
}
for (int indexIdx = 0; indexIdx < sourceTable.getIndexCount(); indexIdx++)
{
Index sourceIndex = sourceTable.getIndex(indexIdx);
Index targetIndex = findCorrespondingIndex(targetTable, sourceIndex);
if (targetIndex == null)
{
if (_log.isInfoEnabled())
{
_log.info("Index " + sourceIndex.getName() + " needs to be removed from table " + sourceTable.getName());
}
changes.add(new RemoveIndexChange(sourceTable, sourceIndex));
}
}
for (int indexIdx = 0; indexIdx < targetTable.getIndexCount(); indexIdx++)
{
Index targetIndex = targetTable.getIndex(indexIdx);
Index sourceIndex = findCorrespondingIndex(sourceTable, targetIndex);
if (sourceIndex == null)
{
if (_log.isInfoEnabled())
{
_log.info("Index " + targetIndex.getName() + " needs to be created for table " + sourceTable.getName());
}
// we have to use the target table here because the index might
// reference a new column
changes.add(new AddIndexChange(targetTable, targetIndex));
}
}
HashMap addColumnChanges = new HashMap();
for (int columnIdx = 0; columnIdx < targetTable.getColumnCount(); columnIdx++)
{
Column targetColumn = targetTable.getColumn(columnIdx);
Column sourceColumn = sourceTable.findColumn(targetColumn.getName(), _caseSensitive);
if (sourceColumn == null)
{
if (_log.isInfoEnabled())
{
_log.info("Column " + targetColumn.getName() + " needs to be created for table " + sourceTable.getName());
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -