Search in sources :

Example 6 with ForeignKey

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

the class AbstractDdlBuilder method getUnchangedForeignKeys.

/**
     * 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<ForeignKey> getUnchangedForeignKeys(Database currentModel, Database desiredModel, String tableName) {
    ArrayList<ForeignKey> unchangedFKs = new ArrayList<ForeignKey>();
    Table sourceTable = findTable(currentModel, tableName);
    Table targetTable = findTable(desiredModel, tableName);
    for (int idx = 0; idx < targetTable.getForeignKeyCount(); idx++) {
        ForeignKey targetFK = targetTable.getForeignKey(idx);
        ForeignKey sourceFK = findForeignKey(sourceTable, targetFK);
        if (sourceFK != null) {
            unchangedFKs.add(targetFK);
        }
    }
    return unchangedFKs;
}
Also used : Table(org.jumpmind.db.model.Table) ArrayList(java.util.ArrayList) ForeignKey(org.jumpmind.db.model.ForeignKey)

Example 7 with ForeignKey

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

the class InterbaseDdlReader method readForeignKeys.

@Override
protected Collection<ForeignKey> readForeignKeys(Connection connection, DatabaseMetaDataWrapper metaData, String tableName) throws SQLException {
    @SuppressWarnings("unchecked") Map<String, ForeignKey> fks = new ListOrderedMap();
    ResultSet fkData = null;
    try {
        if (getPlatform().getDdlBuilder().isDelimitedIdentifierModeOn()) {
            // Jaybird has a problem when delimited identifiers are used as
            // it is not able to find the foreign key info for the table
            // So we have to filter manually below
            fkData = metaData.getForeignKeys(getDefaultTablePattern());
            while (fkData.next()) {
                Map<String, Object> values = readMetaData(fkData, getColumnsForFK());
                if (tableName.equals(values.get("FKTABLE_NAME"))) {
                    readForeignKey(metaData, values, fks);
                }
            }
        } else {
            fkData = metaData.getForeignKeys(tableName);
            while (fkData.next()) {
                Map<String, Object> values = readMetaData(fkData, getColumnsForFK());
                readForeignKey(metaData, values, fks);
            }
        }
    } finally {
        if (fkData != null) {
            fkData.close();
        }
    }
    return fks.values();
}
Also used : ListOrderedMap(org.apache.commons.collections.map.ListOrderedMap) ResultSet(java.sql.ResultSet) ForeignKey(org.jumpmind.db.model.ForeignKey)

Example 8 with ForeignKey

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

the class DataService method getForeignTableRows.

protected List<TableRow> getForeignTableRows(List<TableRow> tableRows, Set<TableRow> visited) throws CloneNotSupportedException {
    List<TableRow> fkDepList = new ArrayList<TableRow>();
    for (TableRow tableRow : tableRows) {
        if (!visited.contains(tableRow)) {
            visited.add(tableRow);
            for (ForeignKey fk : tableRow.getTable().getForeignKeys()) {
                Table table = platform.getTableFromCache(fk.getForeignTableName(), false);
                if (table == null) {
                    table = fk.getForeignTable();
                    if (table == null) {
                        table = platform.getTableFromCache(tableRow.getTable().getCatalog(), tableRow.getTable().getSchema(), fk.getForeignTableName(), false);
                    }
                }
                if (table != null) {
                    Table foreignTable = (Table) table.clone();
                    for (Column column : foreignTable.getColumns()) {
                        column.setPrimaryKey(false);
                    }
                    Row whereRow = new Row(fk.getReferenceCount());
                    String referenceColumnName = null;
                    boolean[] nullValues = new boolean[fk.getReferenceCount()];
                    int index = 0;
                    for (Reference ref : fk.getReferences()) {
                        Column foreignColumn = foreignTable.findColumn(ref.getForeignColumnName());
                        Object value = tableRow.getRow().get(ref.getLocalColumnName());
                        nullValues[index++] = value == null;
                        referenceColumnName = ref.getLocalColumnName();
                        whereRow.put(foreignColumn.getName(), value);
                        foreignColumn.setPrimaryKey(true);
                    }
                    boolean allNullValues = true;
                    for (boolean b : nullValues) {
                        if (!b) {
                            allNullValues = false;
                            break;
                        }
                    }
                    if (!allNullValues) {
                        DmlStatement whereSt = platform.createDmlStatement(DmlType.WHERE, foreignTable.getCatalog(), foreignTable.getSchema(), foreignTable.getName(), foreignTable.getPrimaryKeyColumns(), foreignTable.getColumns(), nullValues, null);
                        String whereSql = whereSt.buildDynamicSql(symmetricDialect.getBinaryEncoding(), whereRow, false, true, foreignTable.getPrimaryKeyColumns()).substring(6);
                        String delimiter = platform.getDatabaseInfo().getSqlCommandDelimiter();
                        if (delimiter != null && delimiter.length() > 0) {
                            whereSql = whereSql.substring(0, whereSql.length() - delimiter.length());
                        }
                        Row foreignRow = new Row(foreignTable.getColumnCount());
                        if (foreignTable.getForeignKeyCount() > 0) {
                            DmlStatement selectSt = platform.createDmlStatement(DmlType.SELECT, foreignTable, null);
                            Object[] keys = whereRow.toArray(foreignTable.getPrimaryKeyColumnNames());
                            Map<String, Object> values = sqlTemplate.queryForMap(selectSt.getSql(), keys);
                            if (values == null) {
                                log.warn("Unable to reload rows for missing foreign key data for table '{}', parent data not found.  Using sql='{}' with keys '{}'", table.getName(), selectSt.getSql(), keys);
                            } else {
                                foreignRow.putAll(values);
                            }
                        }
                        TableRow foreignTableRow = new TableRow(foreignTable, foreignRow, whereSql, referenceColumnName, fk.getName());
                        fkDepList.add(foreignTableRow);
                        log.debug("Add foreign table reference '{}' whereSql='{}'", foreignTable.getName(), whereSql);
                    } else {
                        log.debug("The foreign table reference was null for {}", foreignTable.getName());
                    }
                } else {
                    log.debug("Foreign table '{}' not found for foreign key '{}'", fk.getForeignTableName(), fk.getName());
                }
                if (fkDepList.size() > 0) {
                    fkDepList.addAll(getForeignTableRows(fkDepList, visited));
                }
            }
        }
    }
    return fkDepList;
}
Also used : Table(org.jumpmind.db.model.Table) Reference(org.jumpmind.db.model.Reference) ArrayList(java.util.ArrayList) ForeignKey(org.jumpmind.db.model.ForeignKey) Column(org.jumpmind.db.model.Column) DmlStatement(org.jumpmind.db.sql.DmlStatement) Row(org.jumpmind.db.sql.Row)

Example 9 with ForeignKey

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

the class MySqlDdlReader method readForeignKeys.

@Override
protected Collection<ForeignKey> readForeignKeys(Connection connection, DatabaseMetaDataWrapper metaData, String tableName) throws SQLException {
    if (!isMariaDbDriver()) {
        return super.readForeignKeys(connection, metaData, tableName);
    } else {
        Map<String, ForeignKey> fks = new LinkedHashMap<String, ForeignKey>();
        ResultSet fkData = null;
        try {
            fkData = metaData.getForeignKeys(tableName);
            while (fkData.next()) {
                int count = fkData.getMetaData().getColumnCount();
                Map<String, Object> values = new HashMap<String, Object>();
                for (int i = 1; i <= count; i++) {
                    values.put(fkData.getMetaData().getColumnName(i), fkData.getObject(i));
                }
                String fkName = (String) values.get("CONSTRAINT_NAME");
                ForeignKey fk = (ForeignKey) fks.get(fkName);
                if (fk == null) {
                    fk = new ForeignKey(fkName);
                    fk.setForeignTableName((String) values.get("REFERENCED_TABLE_NAME"));
                    fks.put(fkName, fk);
                }
                Reference ref = new Reference();
                ref.setForeignColumnName((String) values.get("REFERENCED_COLUMN_NAME"));
                ref.setLocalColumnName((String) values.get("COLUMN_NAME"));
                if (values.containsKey("POSITION_IN_UNIQUE_CONSTRAINT")) {
                    ref.setSequenceValue(((Number) values.get("POSITION_IN_UNIQUE_CONSTRAINT")).intValue());
                }
                fk.addReference(ref);
            }
        } finally {
            close(fkData);
        }
        return fks.values();
    }
}
Also used : HashMap(java.util.HashMap) LinkedHashMap(java.util.LinkedHashMap) Reference(org.jumpmind.db.model.Reference) ResultSet(java.sql.ResultSet) ForeignKey(org.jumpmind.db.model.ForeignKey) LinkedHashMap(java.util.LinkedHashMap)

Example 10 with ForeignKey

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

the class DatabaseXmlUtil method nextTable.

public static Table nextTable(XmlPullParser parser, String catalog, String schema) {
    try {
        Table table = null;
        ForeignKey fk = null;
        IIndex index = null;
        boolean done = false;
        int eventType = parser.getEventType();
        while (eventType != XmlPullParser.END_DOCUMENT && !done) {
            switch(eventType) {
                case XmlPullParser.START_TAG:
                    String name = parser.getName();
                    if (name.equalsIgnoreCase("table")) {
                        table = new Table();
                        table.setCatalog(catalog);
                        table.setSchema(schema);
                        for (int i = 0; i < parser.getAttributeCount(); i++) {
                            String attributeName = parser.getAttributeName(i);
                            String attributeValue = parser.getAttributeValue(i);
                            if (attributeName.equalsIgnoreCase("name")) {
                                table.setName(attributeValue);
                            } else if (attributeName.equalsIgnoreCase("description")) {
                                table.setDescription(attributeValue);
                            }
                        }
                    } else if (name.equalsIgnoreCase("column")) {
                        Column column = new Column();
                        for (int i = 0; i < parser.getAttributeCount(); i++) {
                            String attributeName = parser.getAttributeName(i);
                            String attributeValue = parser.getAttributeValue(i);
                            if (attributeName.equalsIgnoreCase("name")) {
                                column.setName(attributeValue);
                            } else if (attributeName.equalsIgnoreCase("primaryKey")) {
                                column.setPrimaryKey(FormatUtils.toBoolean(attributeValue));
                            } else if (attributeName.equalsIgnoreCase("required")) {
                                column.setRequired(FormatUtils.toBoolean(attributeValue));
                            } else if (attributeName.equalsIgnoreCase("type")) {
                                column.setMappedType(attributeValue);
                            } else if (attributeName.equalsIgnoreCase("size")) {
                                column.setSize(attributeValue);
                            } else if (attributeName.equalsIgnoreCase("default")) {
                                if (StringUtils.isNotBlank(attributeValue)) {
                                    column.setDefaultValue(attributeValue);
                                }
                            } else if (attributeName.equalsIgnoreCase("autoIncrement")) {
                                column.setAutoIncrement(FormatUtils.toBoolean(attributeValue));
                            } else if (attributeName.equalsIgnoreCase("javaName")) {
                                column.setJavaName(attributeValue);
                            } else if (attributeName.equalsIgnoreCase("description")) {
                                column.setDescription(attributeValue);
                            } else if (attributeName.equalsIgnoreCase("unique")) {
                                column.setUnique(FormatUtils.toBoolean(attributeValue));
                            }
                        }
                        if (table != null) {
                            table.addColumn(column);
                        }
                    } else if (name.equalsIgnoreCase("platform-column")) {
                        PlatformColumn platformColumn = new PlatformColumn();
                        for (int i = 0; i < parser.getAttributeCount(); i++) {
                            String attributeName = parser.getAttributeName(i);
                            String attributeValue = parser.getAttributeValue(i);
                            if (attributeName.equalsIgnoreCase("name")) {
                                platformColumn.setName(attributeValue);
                            } else if (attributeName.equalsIgnoreCase("type")) {
                                platformColumn.setType(attributeValue);
                            } else if (attributeName.equalsIgnoreCase("default")) {
                                platformColumn.setDefaultValue(attributeValue);
                            } else if (attributeName.equalsIgnoreCase("size")) {
                                if (isNotBlank(attributeValue)) {
                                    platformColumn.setSize(Integer.parseInt(attributeValue));
                                }
                            } else if (attributeName.equalsIgnoreCase("decimalDigits")) {
                                if (isNotBlank(attributeValue)) {
                                    platformColumn.setDecimalDigits(Integer.parseInt(attributeValue));
                                }
                            }
                        }
                        if (table != null && table.getColumnCount() > 0) {
                            table.getColumn(table.getColumnCount() - 1).addPlatformColumn(platformColumn);
                        }
                    } else if (name.equalsIgnoreCase("foreign-key")) {
                        fk = new ForeignKey();
                        for (int i = 0; i < parser.getAttributeCount(); i++) {
                            String attributeName = parser.getAttributeName(i);
                            String attributeValue = parser.getAttributeValue(i);
                            if (attributeName.equalsIgnoreCase("name")) {
                                fk.setName(attributeValue);
                            } else if (attributeName.equalsIgnoreCase("foreignTable")) {
                                fk.setForeignTableName(attributeValue);
                            }
                        }
                        table.addForeignKey(fk);
                    } else if (name.equalsIgnoreCase("reference")) {
                        Reference ref = new Reference();
                        for (int i = 0; i < parser.getAttributeCount(); i++) {
                            String attributeName = parser.getAttributeName(i);
                            String attributeValue = parser.getAttributeValue(i);
                            if (attributeName.equalsIgnoreCase("local")) {
                                ref.setLocalColumnName(attributeValue);
                            } else if (attributeName.equalsIgnoreCase("foreign")) {
                                ref.setForeignColumnName(attributeValue);
                            }
                        }
                        fk.addReference(ref);
                    } else if (name.equalsIgnoreCase("index") || name.equalsIgnoreCase("unique")) {
                        if (name.equalsIgnoreCase("index")) {
                            index = new NonUniqueIndex();
                        } else {
                            index = new UniqueIndex();
                        }
                        for (int i = 0; i < parser.getAttributeCount(); i++) {
                            String attributeName = parser.getAttributeName(i);
                            String attributeValue = parser.getAttributeValue(i);
                            if (attributeName.equalsIgnoreCase("name")) {
                                index.setName(attributeValue);
                            }
                        }
                        table.addIndex(index);
                    } else if (name.equalsIgnoreCase("index-column") || name.equalsIgnoreCase("unique-column")) {
                        IndexColumn indexColumn = new IndexColumn();
                        for (int i = 0; i < parser.getAttributeCount(); i++) {
                            String attributeName = parser.getAttributeName(i);
                            String attributeValue = parser.getAttributeValue(i);
                            if (attributeName.equalsIgnoreCase("name")) {
                                indexColumn.setName(attributeValue);
                            } else if (attributeName.equalsIgnoreCase("size")) {
                                indexColumn.setSize(attributeValue);
                            }
                        }
                        indexColumn.setColumn(table.getColumnWithName(indexColumn.getName()));
                        if (index != null) {
                            index.addColumn(indexColumn);
                        }
                    }
                    break;
                case XmlPullParser.END_TAG:
                    name = parser.getName();
                    if (name.equalsIgnoreCase("table")) {
                        done = true;
                    } else if (name.equalsIgnoreCase("index") || name.equalsIgnoreCase("unique")) {
                        index = null;
                    } else if (name.equalsIgnoreCase("table")) {
                        table = null;
                    } else if (name.equalsIgnoreCase("foreign-key")) {
                        fk = null;
                    }
                    break;
            }
            if (!done) {
                eventType = parser.next();
            }
        }
        return table;
    } catch (XmlPullParserException e) {
        throw new IoException(e);
    } catch (IOException e) {
        throw new IoException(e);
    }
}
Also used : IIndex(org.jumpmind.db.model.IIndex) Table(org.jumpmind.db.model.Table) NonUniqueIndex(org.jumpmind.db.model.NonUniqueIndex) Reference(org.jumpmind.db.model.Reference) IOException(java.io.IOException) ForeignKey(org.jumpmind.db.model.ForeignKey) PlatformColumn(org.jumpmind.db.model.PlatformColumn) IndexColumn(org.jumpmind.db.model.IndexColumn) Column(org.jumpmind.db.model.Column) IndexColumn(org.jumpmind.db.model.IndexColumn) PlatformColumn(org.jumpmind.db.model.PlatformColumn) IoException(org.jumpmind.exception.IoException) XmlPullParserException(org.xmlpull.v1.XmlPullParserException) NonUniqueIndex(org.jumpmind.db.model.NonUniqueIndex) UniqueIndex(org.jumpmind.db.model.UniqueIndex)

Aggregations

ForeignKey (org.jumpmind.db.model.ForeignKey)24 Reference (org.jumpmind.db.model.Reference)13 Table (org.jumpmind.db.model.Table)12 ArrayList (java.util.ArrayList)9 Column (org.jumpmind.db.model.Column)8 IIndex (org.jumpmind.db.model.IIndex)6 ResultSet (java.sql.ResultSet)4 HashMap (java.util.HashMap)4 IndexColumn (org.jumpmind.db.model.IndexColumn)4 LinkedHashMap (java.util.LinkedHashMap)3 IOException (java.io.IOException)2 HashSet (java.util.HashSet)2 List (java.util.List)2 TableChange (org.jumpmind.db.alter.TableChange)2 Database (org.jumpmind.db.model.Database)2 PlatformColumn (org.jumpmind.db.model.PlatformColumn)2 Row (org.jumpmind.db.sql.Row)2 IoException (org.jumpmind.exception.IoException)2 File (java.io.File)1 FileWriter (java.io.FileWriter)1