⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 sqlbuilder.java

📁 OBPM是一个开源
💻 JAVA
📖 第 1 页 / 共 5 页
字号:
                                 CreationParameters params,
                                 RemoveTableChange  change) throws IOException
    {
        dropTable(change.getChangedTable());
        change.apply(currentModel, getPlatform().isDelimitedIdentifierModeOn());
    }

    /**
     * Processes the change representing the addition of a table.
     * 
     * @param currentModel The current database schema
     * @param desiredModel The desired database schema
     * @param params       The parameters used in the creation of new tables. Note that for existing
     *                     tables, the parameters won't be applied
     * @param change       The change object
     */
    protected void processChange(Database           currentModel,
                                 Database           desiredModel,
                                 CreationParameters params,
                                 AddTableChange     change) throws IOException
    {
        createTable(desiredModel, change.getNewTable(), params == null ? null : params.getParametersFor(change.getNewTable()));
        change.apply(currentModel, getPlatform().isDelimitedIdentifierModeOn());
    }

    /**
     * Processes the change representing the addition of a foreign key.
     * 
     * @param currentModel The current database schema
     * @param desiredModel The desired database schema
     * @param params       The parameters used in the creation of new tables. Note that for existing
     *                     tables, the parameters won't be applied
     * @param change       The change object
     */
    protected void processChange(Database            currentModel,
                                 Database            desiredModel,
                                 CreationParameters  params,
                                 AddForeignKeyChange change) throws IOException
    {
        writeExternalForeignKeyCreateStmt(desiredModel,
                                          change.getChangedTable(),
                                          change.getNewForeignKey());
        change.apply(currentModel, getPlatform().isDelimitedIdentifierModeOn());
    }

    /**
     * Processes the change representing the addition of an index.
     * 
     * @param currentModel The current database schema
     * @param desiredModel The desired database schema
     * @param params       The parameters used in the creation of new tables. Note that for existing
     *                     tables, the parameters won't be applied
     * @param change       The change object
     */
    protected void processChange(Database           currentModel,
                                 Database           desiredModel,
                                 CreationParameters params,
                                 AddIndexChange     change) throws IOException
    {
        writeExternalIndexCreateStmt(change.getChangedTable(), change.getNewIndex());
        change.apply(currentModel, getPlatform().isDelimitedIdentifierModeOn());
    }

    /**
     * Processes the changes to the structure of tables.
     * 
     * @param currentModel The current database schema
     * @param desiredModel The desired database schema
     * @param params       The parameters used in the creation of new tables. Note that for existing
     *                     tables, the parameters won't be applied
     * @param changes      The change objects
     */
    protected void processTableStructureChanges(Database           currentModel,
                                                Database           desiredModel,
                                                CreationParameters params,
                                                Collection         changes) throws IOException
    {
        ListOrderedMap changesPerTable = new ListOrderedMap();
        ListOrderedMap unchangedFKs    = new ListOrderedMap();
        boolean        caseSensitive   = getPlatform().isDelimitedIdentifierModeOn();

        // we first sort the changes for the tables
        // however since the changes might contain source or target tables
        // we use the names rather than the table objects
        for (Iterator changeIt = changes.iterator(); changeIt.hasNext();)
        {
            TableChange change = (TableChange)changeIt.next();
            String      name   = change.getChangedTable().getName();

            if (!caseSensitive)
            {
                name = name.toUpperCase();
            }

            List changesForTable = (ArrayList)changesPerTable.get(name);

            if (changesForTable == null)
            {
                changesForTable = new ArrayList();
                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 tableFKIt = unchangedFKs.entrySet().iterator(); tableFKIt.hasNext();)
        {
            Map.Entry entry       = (Map.Entry)tableFKIt.next();
            Table     targetTable = desiredModel.findTable((String)entry.getKey(), caseSensitive);

            for (Iterator fkIt = ((List)entry.getValue()).iterator(); fkIt.hasNext();)
            {
                writeExternalForeignKeyDropStmt(targetTable, (ForeignKey)fkIt.next());
            }
        }

        // We're using a copy of the current model so that the table structure changes can
        // modify it
        Database copyOfCurrentModel = null;

        try
        {
            copyOfCurrentModel = (Database)currentModel.clone();
        }
        catch (CloneNotSupportedException ex)
        {
            throw new DdlUtilsException(ex);
        }
        
        for (Iterator tableChangeIt = changesPerTable.entrySet().iterator(); tableChangeIt.hasNext();)
        {
            Map.Entry entry       = (Map.Entry)tableChangeIt.next();
            Table     targetTable = desiredModel.findTable((String)entry.getKey(), caseSensitive);

            processTableStructureChanges(copyOfCurrentModel,
                                         desiredModel,
                                         (String)entry.getKey(),
                                         params == null ? null : params.getParametersFor(targetTable),
                                         (List)entry.getValue());
        }
        // and finally we're re-creating the unchanged foreign keys
        for (Iterator tableFKIt = unchangedFKs.entrySet().iterator(); tableFKIt.hasNext();)
        {
            Map.Entry entry       = (Map.Entry)tableFKIt.next();
            Table     targetTable = desiredModel.findTable((String)entry.getKey(), caseSensitive);

            for (Iterator fkIt = ((List)entry.getValue()).iterator(); fkIt.hasNext();)
            {
                writeExternalForeignKeyCreateStmt(desiredModel, targetTable, (ForeignKey)fkIt.next());
            }
        }
    }

    /**
     * Determines the unchanged foreign keys of the indicated table.
     * 
     * @param currentModel The current model
     * @param desiredModel The desired model
     * @param tableName    The name of the table
     * @return The list of unchanged foreign keys
     */
    private List getUnchangedForeignKeys(Database currentModel,
                                         Database desiredModel,
                                         String   tableName)
    {
        ArrayList unchangedFKs  = new ArrayList();
        boolean   caseSensitive = getPlatform().isDelimitedIdentifierModeOn();
        Table     sourceTable   = currentModel.findTable(tableName, caseSensitive);
        Table     targetTable   = desiredModel.findTable(tableName, caseSensitive);

        for (int idx = 0; idx < targetTable.getForeignKeyCount(); idx++)
        {
            ForeignKey targetFK = targetTable.getForeignKey(idx);
            ForeignKey sourceFK = sourceTable.findForeignKey(targetFK, caseSensitive);

            if (sourceFK != null)
            {
                unchangedFKs.add(targetFK);
            }
        }
        return unchangedFKs;
    }

    /**
     * Adds the foreign keys of the unchanged tables that reference changed tables
     * to the given map.
     * 
     * @param currentModel              The current model
     * @param desiredModel              The desired model
     * @param namesOfKnownChangedTables The known names of changed tables
     * @param fksPerTable               The map table name -> foreign keys to which
     *                                  found foreign keys will be added to
     */
    private void addRelevantFKsFromUnchangedTables(Database currentModel,
                                                   Database desiredModel,
                                                   Set      namesOfKnownChangedTables,
                                                   Map      fksPerTable)
    {
        boolean caseSensitive = getPlatform().isDelimitedIdentifierModeOn();

        for (int tableIdx = 0; tableIdx < desiredModel.getTableCount(); tableIdx++)
        {
            Table  targetTable = desiredModel.getTable(tableIdx);
            String name        = targetTable.getName();
            Table  sourceTable = currentModel.findTable(name, caseSensitive);
            List   relevantFks = null;

            if (!caseSensitive)
            {
                name = name.toUpperCase();
            }
            if ((sourceTable != null) && !namesOfKnownChangedTables.contains(name))
            {
                for (int fkIdx = 0; fkIdx < targetTable.getForeignKeyCount(); fkIdx++)
                {
                    ForeignKey targetFk = targetTable.getForeignKey(fkIdx);
                    ForeignKey sourceFk = sourceTable.findForeignKey(targetFk, caseSensitive);
                    String     refName  = targetFk.getForeignTableName();

                    if (!caseSensitive)
                    {
                        refName = refName.toUpperCase();
                    }
                    if ((sourceFk != null) && namesOfKnownChangedTables.contains(refName))
                    {
                        if (relevantFks == null)
                        {
                            relevantFks = new ArrayList();
                            fksPerTable.put(name, relevantFks);
                        }
                        relevantFks.add(targetFk);
                    }
                }
            }
        }
    }
    
    /**
     * 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.
     * 
     * @param currentModel The current database schema
     * @param desiredModel The desired database schema
     * @param tableName    The name of the changed table
     * @param parameters   The creation parameters for the desired table
     * @param changes      The change objects for this table
     */
    protected void processTableStructureChanges(Database currentModel,
                                                Database desiredModel,
                                                String   tableName,
                                                Map      parameters,
                                                List     changes) throws IOException
    {
        Table sourceTable = currentModel.findTable(tableName, getPlatform().isDelimitedIdentifierModeOn());
        Table targetTable = desiredModel.findTable(tableName, getPlatform().isDelimitedIdentifierModeOn());

        processTableStructureChanges(currentModel, desiredModel, sourceTable, targetTable, parameters, changes);

        if (!changes.isEmpty())
        {
            Table tempTable       = getTemporaryTableFor(desiredModel, targetTable);
            Table realTargetTable = getRealTargetTableFor(desiredModel, sourceTable, targetTable);

            createTemporaryTable(desiredModel, tempTable, parameters);
            writeCopyDataStatement(sourceTable, tempTable);
            // 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);
            createTable(desiredModel, realTargetTable, parameters);
            writeCopyDataStatement(tempTable, targetTable);
            dropTemporaryTable(desiredModel, tempTable);
        }
    }

    /**
     * Allows database-specific implementations to handle changes in a database
     * specific manner. Any handled change should be applied to the given current
     * model (which is a copy of the real original model) and be removed from the
     * list of changes.<br/>
     * In the default implementation, all {@link AddPrimaryKeyChange} changes are
     * applied via an <code>ALTER TABLE ADD CONSTRAINT</code> statement.  
     * 
     * @param currentModel The current database schema
     * @param desiredModel The desired database schema
     * @param sourceTable  The original table
     * @param targetTable  The desired table
     * @param parameters   The creation parameters for the table
     * @param changes      The change objects for the target table
     */
    protected void processTableStructureChanges(Database currentModel,
                                                Database desiredModel,
                                                Table    sourceTable,
                                                Table    targetTable,
                                                Map      parameters,
                                                List     changes) throws IOException
    {
        if (changes.size() == 1)
        {
            TableChange change = (TableChange)changes.get(0);

            if (change instanceof AddPrimaryKeyChange)
            {
                processChange(currentModel, desiredModel, (AddPrimaryKeyChange)change);
                changes.clear();
            }
        }
    }
    
    /**
     * Creates a temporary table object that corresponds to the given table.
     * Database-specific implementations may redefine this method if e.g. the
     * database directly supports temporary tables. The default implementation
     * simply appends an underscore to the table name and uses that as the
     * table name.  
     * 
     * @param targetModel The target database
     * @param targetTable The target table
     * @return The temporary table
     */
    protected Table getTemporaryTableFor(Database targetModel, Table targetTable) throws IOException
    {

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -