Search in sources :

Example 1 with Reference

use of org.jumpmind.db.model.Reference 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 2 with Reference

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

the class DbFill method buildDependentColumnValues.

protected void buildDependentColumnValues(List<Table> tables) {
    for (Table table : tables) {
        Map<String, List<ForeignKeyReference>> columnReferences = new HashMap<String, List<ForeignKeyReference>>();
        for (ForeignKey fk : table.getForeignKeys()) {
            for (Reference ref : fk.getReferences()) {
                List<ForeignKeyReference> references = columnReferences.get(ref.getLocalColumnName());
                if (references == null) {
                    references = new ArrayList<ForeignKeyReference>();
                    columnReferences.put(ref.getLocalColumnName(), references);
                }
                references.add(new ForeignKeyReference(fk, ref));
            }
        }
        for (String columnName : columnReferences.keySet()) {
            List<ForeignKeyReference> references = columnReferences.get(columnName);
            if (references.size() > 1) {
                List<Object> commonValue = new ArrayList<Object>();
                StringBuilder sb = null;
                for (ForeignKeyReference fkr : references) {
                    String key = fkr.getForeignKey().getForeignTableName() + "." + fkr.getReference().getForeignColumnName();
                    commonDependencyValues.put(key, commonValue);
                    commonDependencyTables.add(getDbTable(fkr.getForeignKey().getForeignTableName()));
                    if (verbose) {
                        sb = (sb == null) ? new StringBuilder() : sb.append(", ");
                        sb.append(key);
                    }
                }
                if (verbose) {
                    log.info("Common dependency for table {}: {}", table.getName(), sb.toString());
                }
            }
        }
    }
}
Also used : Table(org.jumpmind.db.model.Table) HashMap(java.util.HashMap) Reference(org.jumpmind.db.model.Reference) ArrayList(java.util.ArrayList) ForeignKey(org.jumpmind.db.model.ForeignKey) ArrayList(java.util.ArrayList) List(java.util.List)

Example 3 with Reference

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

the class DbFill method buildForeignKeyReferences.

protected void buildForeignKeyReferences(List<Table> tables) {
    for (Table table : tables) {
        for (ForeignKey fk : table.getForeignKeys()) {
            for (Reference ref : fk.getReferences()) {
                String key = table.getQualifiedTableName() + "." + ref.getLocalColumnName();
                foreignKeyReferences.put(key, new ForeignKeyReference(fk, ref));
            }
        }
    }
}
Also used : Table(org.jumpmind.db.model.Table) Reference(org.jumpmind.db.model.Reference) ForeignKey(org.jumpmind.db.model.ForeignKey)

Example 4 with Reference

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

the class AseDdlReader method readForeignKeys.

@Override
protected Collection<ForeignKey> readForeignKeys(Connection connection, DatabaseMetaDataWrapper metaData, String tableName) throws SQLException {
    // Sybase (or jConnect) does not return the foreign key names, thus we
    // have to
    // read the foreign keys manually from the system tables
    StringBuffer query = new StringBuffer();
    query.append("SELECT refobjs.name, localtables.id, remotetables.name, remotetables.id");
    for (int idx = 1; idx <= 16; idx++) {
        query.append(", refs.fokey");
        query.append(idx);
        query.append(", refs.refkey");
        query.append(idx);
    }
    query.append(" FROM dbo.sysreferences refs, dbo.sysobjects refobjs, dbo.sysobjects localtables, dbo.sysobjects remotetables");
    query.append(" WHERE refobjs.type = 'RI' AND refs.constrid = refobjs.id AND");
    query.append(" localtables.type = 'U' AND refs.tableid = localtables.id AND localtables.name = '");
    query.append(tableName);
    query.append("' AND remotetables.type = 'U' AND refs.reftabid = remotetables.id");
    Statement stmt = connection.createStatement();
    PreparedStatement prepStmt = connection.prepareStatement("SELECT name FROM dbo.syscolumns WHERE id = ? AND colid = ?");
    ArrayList<ForeignKey> result = new ArrayList<ForeignKey>();
    try {
        ResultSet fkRs = stmt.executeQuery(query.toString());
        while (fkRs.next()) {
            ForeignKey fk = new ForeignKey(fkRs.getString(1));
            int localTableId = fkRs.getInt(2);
            int remoteTableId = fkRs.getInt(4);
            fk.setForeignTableName(fkRs.getString(3));
            for (int idx = 0; idx < 16; idx++) {
                short fkColIdx = fkRs.getShort(5 + idx + idx);
                short pkColIdx = fkRs.getShort(6 + idx + idx);
                Reference ref = new Reference();
                if (fkColIdx == 0) {
                    break;
                }
                prepStmt.setInt(1, localTableId);
                prepStmt.setShort(2, fkColIdx);
                ResultSet colRs = prepStmt.executeQuery();
                if (colRs.next()) {
                    ref.setLocalColumnName(colRs.getString(1));
                }
                colRs.close();
                prepStmt.setInt(1, remoteTableId);
                prepStmt.setShort(2, pkColIdx);
                colRs = prepStmt.executeQuery();
                if (colRs.next()) {
                    ref.setForeignColumnName(colRs.getString(1));
                }
                colRs.close();
                fk.addReference(ref);
            }
            result.add(fk);
        }
        fkRs.close();
    } finally {
        stmt.close();
        prepStmt.close();
    }
    return result;
}
Also used : PreparedStatement(java.sql.PreparedStatement) Statement(java.sql.Statement) Reference(org.jumpmind.db.model.Reference) ArrayList(java.util.ArrayList) ResultSet(java.sql.ResultSet) PreparedStatement(java.sql.PreparedStatement) ForeignKey(org.jumpmind.db.model.ForeignKey)

Example 5 with Reference

use of org.jumpmind.db.model.Reference 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)

Aggregations

ForeignKey (org.jumpmind.db.model.ForeignKey)13 Reference (org.jumpmind.db.model.Reference)13 Column (org.jumpmind.db.model.Column)6 Table (org.jumpmind.db.model.Table)6 ArrayList (java.util.ArrayList)4 IIndex (org.jumpmind.db.model.IIndex)4 IndexColumn (org.jumpmind.db.model.IndexColumn)4 HashMap (java.util.HashMap)3 IOException (java.io.IOException)2 ResultSet (java.sql.ResultSet)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 PrintWriter (java.io.PrintWriter)1 PreparedStatement (java.sql.PreparedStatement)1 Statement (java.sql.Statement)1 LinkedHashMap (java.util.LinkedHashMap)1 List (java.util.List)1