예제 #1
0
  /** @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);
  }
예제 #2
0
  private static void appendModified(
      final List<Column[]> rows,
      final LinkedHashMap<henplus.sqlmodel.Column, henplus.sqlmodel.Column> modified) {
    final Iterator<henplus.sqlmodel.Column> iter = modified.keySet().iterator();
    while (iter.hasNext()) {
      final henplus.sqlmodel.Column org = iter.next();
      final henplus.sqlmodel.Column mod = modified.get(org);

      final ExtendedColumn[] orgView = new ExtendedColumn[8];
      final ExtendedColumn[] modView = new ExtendedColumn[8];

      orgView[0] = new ExtendedColumn(STAT_MODIFIED_ORG, DESC_META[0].getAlignment());
      modView[0] = new ExtendedColumn(STAT_MODIFIED_NEW, DESC_META[0].getAlignment());

      // if this was modified it doesn't matter
      orgView[1] = new ExtendedColumn(org.getPosition(), DESC_META[1].getAlignment());
      modView[1] = new ExtendedColumn(mod.getPosition(), DESC_META[1].getAlignment());

      // this should not differ
      orgView[2] = new ExtendedColumn(org.getName(), DESC_META[2].getAlignment());
      modView[2] = new ExtendedColumn(mod.getName(), DESC_META[2].getAlignment());

      final String orgType = extractType(org);
      final String modType = extractType(mod);
      orgView[3] = new ExtendedColumn(orgType, DESC_META[3].getAlignment());
      modView[3] = new ExtendedColumn(modType, DESC_META[3].getAlignment());
      if (!modType.equals(orgType)) {
        markAsChanged(modView[3]);
      }

      orgView[4] = new ExtendedColumn(org.isNullable() ? YES : NO, DESC_META[4].getAlignment());
      modView[4] = new ExtendedColumn(mod.isNullable() ? YES : NO, DESC_META[4].getAlignment());
      if (org.isNullable() != mod.isNullable()) {
        markAsChanged(modView[4]);
      }

      Logger.debug("default: %s", org.getDefault());
      final String orgDefaultVal = org.getDefault() != null ? org.getDefault().trim() : null;
      // oracle appends newline to default values for some reason.
      orgView[5] = new ExtendedColumn(orgDefaultVal, DESC_META[5].getAlignment());

      final String modDefaultVal = mod.getDefault() != null ? mod.getDefault().trim() : null;
      modView[5] = new ExtendedColumn(modDefaultVal, DESC_META[5].getAlignment());
      if (orgDefaultVal != null && !orgDefaultVal.equals(modDefaultVal)
          || orgDefaultVal == null && modDefaultVal != null) {
        markAsChanged(modView[5]);
      }

      // primary key
      final String pkDescOrg = getPkDesc(org);
      final String pkDescMod = getPkDesc(mod);
      orgView[6] = new ExtendedColumn(pkDescOrg, DESC_META[6].getAlignment());
      modView[6] = new ExtendedColumn(pkDescMod, DESC_META[6].getAlignment());
      // check if one of the cols has to be marked as changed
      if (org.isPartOfPk() && !mod.isPartOfPk()) {
        markAsChanged(orgView[6]);
      } else if (!org.isPartOfPk() && mod.isPartOfPk()) {
        markAsChanged(modView[6]);
      } else if (org.isPartOfPk() && mod.isPartOfPk()) {
        // compare values of pk names
        if (org.getPkInfo().getPkName() != null
            && !org.getPkInfo().getPkName().equals(mod.getPkInfo().getPkName())) {
          markAsChanged(modView[6]);
        }
      }

      // foreign key
      final String fkDescOrg = getFkDesc(org);
      final String fkDescMod = getFkDesc(mod);
      orgView[7] = new ExtendedColumn(fkDescOrg, DESC_META[7].getAlignment());
      modView[7] = new ExtendedColumn(fkDescMod, DESC_META[7].getAlignment());
      // check if one of the cols has to be marked as changed
      if (org.isForeignKey() && !mod.isForeignKey()) {
        markAsChanged(orgView[7]);
      } else if (!org.isForeignKey() && mod.isForeignKey()) {
        markAsChanged(modView[7]);
      } else if (org.isForeignKey() && mod.isForeignKey()) {
        // compare values of pk names
        if (!org.getFkInfo().equals(mod.getFkInfo())) {
          markAsChanged(modView[7]);
        }
      }

      rows.add(orgView);
      rows.add(modView);
    }
  }
예제 #3
0
  /**
   * @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());

        // if there's yet a cycle with the two tables inner following t
        // 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);
    }
  }