Search in sources :

Example 1 with ColumnFkInfo

use of henplus.sqlmodel.ColumnFkInfo in project henplus by neurolabs.

the class DependencyResolver method sortTables.

/**
     * @return
     * 
     */
public ResolverResult sortTables() {
    final LinkedHashMap<String, Table> resolved = new LinkedHashMap<String, Table>();
    Map<String, Table> unresolved = null;
    // first run: separate tables with and without dependencies
    while (_tableIter.hasNext()) {
        final Table t = _tableIter.next();
        if (t == null) {
            continue;
        }
        final Set<ColumnFkInfo> fks = t.getForeignKeys();
        // no dependency / foreign key?
        Logger.debug("[sortTables] put %s to resolved.", t);
        if (fks == null) {
            resolved.put(t.getName(), t);
        } else {
            // dependency fulfilled?
            boolean nodep = true;
            final Iterator<ColumnFkInfo> iter2 = fks.iterator();
            while (iter2.hasNext() && nodep) {
                final ColumnFkInfo fk = iter2.next();
                if (!resolved.containsKey(fk.getPkTable())) {
                    nodep = false;
                }
            }
            if (nodep) {
                resolved.put(t.getName(), t);
            } else {
                if (unresolved == null) {
                    unresolved = new HashMap<String, Table>();
                }
                unresolved.put(t.getName(), t);
            }
        }
    }
    // second run: we check remaining deps
    if (unresolved != null) {
        for (Table t : unresolved.values()) {
            resolveDep(t, null, resolved, unresolved);
        }
    }
    // do we need a second run?
    // unresolved = cleanUnresolved( resolved, unresolved );
    // add all unresolved/conflicting tables to the resulting list
    final Collection<Table> result = resolved.values();
    if (unresolved != null) {
        for (Table table : unresolved.values()) {
            if (!result.contains(table)) {
                result.add(table);
            }
        }
    }
    return new ResolverResult(result, _cyclicDependencies);
}
Also used : Table(henplus.sqlmodel.Table) ColumnFkInfo(henplus.sqlmodel.ColumnFkInfo) LinkedHashMap(java.util.LinkedHashMap)

Example 2 with ColumnFkInfo

use of henplus.sqlmodel.ColumnFkInfo in project henplus by neurolabs.

the class ResultTablePrinter method getFkDesc.

private static String getFkDesc(final henplus.sqlmodel.Column col) {
    String fkDesc = "";
    final ColumnFkInfo fkInfo = col.getFkInfo();
    if (fkInfo != null) {
        final StringBuilder sb = new StringBuilder();
        if (fkInfo.getFkName() != null) {
            sb.append(fkInfo.getFkName()).append("\n -> ");
        } else {
            sb.append(" -> ");
        }
        sb.append(fkInfo.getPkTable()).append("(").append(fkInfo.getPkColumn()).append(")");
        fkDesc = sb.toString();
    }
    return fkDesc;
}
Also used : ColumnFkInfo(henplus.sqlmodel.ColumnFkInfo)

Example 3 with ColumnFkInfo

use of henplus.sqlmodel.ColumnFkInfo in project henplus by neurolabs.

the class SQLMetaDataBuilder method buildTable.

private Table buildTable(final String catalog, final DatabaseMetaData meta, final String tableName, final ResultSet rset) throws SQLException {
    Table table = null;
    if (rset != null) {
        table = new Table(tableName);
        final PrimaryKey pk = getPrimaryKey(meta, tableName);
        final Map<String, ColumnFkInfo> fks = getForeignKeys(meta, tableName);
        // rset = meta.getColumns(catalog, null, tableName, null);
        while (!_interrupted && rset.next()) {
            final String colname = rset.getString(COLUMN_NAME);
            final Column column = new Column(colname);
            column.setType(rset.getString(TYPE_NAME));
            column.setSize(rset.getInt(COLUMN_SIZE));
            final boolean nullable = rset.getInt(NULLABLE) == DatabaseMetaData.columnNullable ? true : false;
            column.setNullable(nullable);
            final String defaultVal = rset.getString(COLUMN_DEF);
            column.setDefault(defaultVal != null ? defaultVal.trim() : null);
            column.setPosition(rset.getInt(ORDINAL_POSITION));
            column.setPkInfo(pk.getColumnPkInfo(colname));
            column.setFkInfo(fks.get(colname));
            table.addColumn(column);
        }
        rset.close();
    }
    return table;
}
Also used : Table(henplus.sqlmodel.Table) Column(henplus.sqlmodel.Column) ColumnFkInfo(henplus.sqlmodel.ColumnFkInfo) PrimaryKey(henplus.sqlmodel.PrimaryKey)

Example 4 with ColumnFkInfo

use of henplus.sqlmodel.ColumnFkInfo in project henplus by neurolabs.

the class SQLMetaDataBuilder method getForeignKeys.

private Map<String, ColumnFkInfo> getForeignKeys(final DatabaseMetaData meta, final String tabName) throws SQLException {
    final Map<String, ColumnFkInfo> fks = new HashMap<String, ColumnFkInfo>();
    ResultSet rset = null;
    // keys...
    try {
        rset = meta.getImportedKeys(null, null, tabName);
    } catch (final NoSuchElementException e) {
        if (VERBOSE) {
            HenPlus.msg().println("Database problem reading meta data: " + e);
        }
    }
    if (rset != null) {
        while (rset.next()) {
            final ColumnFkInfo fk = new ColumnFkInfo(rset.getString(FK_FK_NAME), rset.getString(FK_PKTABLE_NAME), rset.getString(FK_PKCOLUMN_NAME));
            final String col = rset.getString(FK_FKCOLUMN_NAME);
            fks.put(col, fk);
        }
        rset.close();
    }
    return fks;
}
Also used : HashMap(java.util.HashMap) ColumnFkInfo(henplus.sqlmodel.ColumnFkInfo) ResultSet(java.sql.ResultSet) NoSuchElementException(java.util.NoSuchElementException)

Example 5 with ColumnFkInfo

use of henplus.sqlmodel.ColumnFkInfo in project henplus by neurolabs.

the class DependencyResolver method resolveDep.

/**
     * @return
     * 
     */
/*
     * Martin: needed ? private Set restructureDeps() { Set deps = null; if (
     * cyclicDependencies != null ) { deps = new HashSet(); Iterator iter =
     * cyclicDependencies.iterator(); while ( iter.hasNext() ) deps.add(
     * ((ListMap)iter.next()).valuesList() ); } return deps; }
     */
/**
     * @param resolved
     * @param unresolved
     * @return A Map which contains all yet unresolved Tables mapped to their names.
     */
/*
     * Martin: needed ? private Map cleanUnresolved( Map resolved, Map
     * unresolved ) { Map result = null;
     * 
     * if ( unresolved != null ) { Iterator iter =
     * unresolved.keySet().iterator(); while ( iter.hasNext() ) { // type
     * element = (type) iter.next();
     * 
     * } }
     * 
     * return null; }
     */
/**
     * @param t
     * @param cyclePath
     *            The path of tables which have cyclic dependencies
     * @param resolved
     * @param unresolved
     */
private void resolveDep(final Table t, List<Table> cyclePath, final Map<String, Table> resolved, final Map<String, Table> unresolved) {
    Logger.debug("[resolveDep] >>> Starting for t: %s and cyclePath: %s", t, cyclePath);
    // if the current table is no more in the unresolved collection
    if (t == null || resolved.containsKey(t.getName())) {
        return;
    }
    boolean nodep = false;
    boolean firstrun = true;
    final Set<ColumnFkInfo> fks = t.getForeignKeys();
    final Iterator<ColumnFkInfo> iter = fks.iterator();
    while (iter.hasNext()) {
        final ColumnFkInfo fk = iter.next();
        Logger.debug("[resolveDep] FK -> %s: %s", fk.getPkTable(), resolved.containsKey(fk.getPkTable()));
        if (!resolved.containsKey(fk.getPkTable())) {
            final Table inner = unresolved.get(fk.getPkTable());
            // then proceed to the next FK and ignore this potential cycle
            if (duplicateCycle(t, inner)) {
                continue;
            }
            if (cyclePath != null && cyclePath.contains(inner)) {
                cyclePath.add(t);
                // create a new list for the detected cycle to add to the
                // cyclicDeps, the former one (cyclePath) is used further on
                final List<Table> cycle = new ArrayList<Table>(cyclePath);
                cycle.add(inner);
                if (_cyclicDependencies == null) {
                    _cyclicDependencies = new HashSet<List<Table>>();
                }
                Logger.debug("[resolveDep] +++ Putting cyclePath: %s", cycle);
                _cyclicDependencies.add(cycle);
                continue;
            } else {
                if (cyclePath == null) {
                    Logger.debug("[resolveDep] Starting cyclePath with: %s", t);
                    cyclePath = new ArrayList<Table>();
                }
                cyclePath.add(t);
            }
            resolveDep(inner, cyclePath, resolved, unresolved);
            if (resolved.containsKey(fk.getPkTable())) {
                nodep = (firstrun || nodep);
                firstrun = false;
            }
        } else {
            nodep = (firstrun || nodep);
            firstrun = false;
        }
    }
    if (nodep && !resolved.containsKey(t.getName())) {
        Logger.debug("[resolveDep] put %s to resolved.", t);
        resolved.put(t.getName(), t);
    }
}
Also used : Table(henplus.sqlmodel.Table) ColumnFkInfo(henplus.sqlmodel.ColumnFkInfo) ArrayList(java.util.ArrayList) List(java.util.List) ArrayList(java.util.ArrayList)

Aggregations

ColumnFkInfo (henplus.sqlmodel.ColumnFkInfo)5 Table (henplus.sqlmodel.Table)3 Column (henplus.sqlmodel.Column)1 PrimaryKey (henplus.sqlmodel.PrimaryKey)1 ResultSet (java.sql.ResultSet)1 ArrayList (java.util.ArrayList)1 HashMap (java.util.HashMap)1 LinkedHashMap (java.util.LinkedHashMap)1 List (java.util.List)1 NoSuchElementException (java.util.NoSuchElementException)1