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);
}
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;
}
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;
}
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;
}
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);
}
}
Aggregations