Example #1
0
  public Data[] execute() throws AlgorithmExecutionException {

    Table mergingTable = (Table) data[0].getData();
    Database originalDatabase = (Database) data[1].getData();
    // TODO: it would really be nice to have a way to clean up the output database if there is an
    // error related to it.
    Database outputDatabase = null;
    Connection originalConnection =
        DatabaseUtilities.connect(originalDatabase, "Unable to communicate with the database.");
    Connection outputConnection = null;

    DatabaseTable toBeMerged = inferTableToBeMerged(mergingTable);
    try {
      if (toBeMerged.presentInDatabase(originalConnection)) {
        outputDatabase = databaseService.copyDatabase(originalDatabase);
        outputConnection = outputDatabase.getConnection();
        Merger merger = collectMerges(mergingTable, toBeMerged, outputConnection);
        problems.addAll(merger.merge(outputConnection));
        if (problems.size() > 0) {
          throw new AlgorithmExecutionException(
              "The following problems were encountered while trying to merge: "
                  + formatProblems(problems));
        }

        logger.log(
            LogService.LOG_INFO,
            "Successfully merged "
                + merger.getEntitiesMergedAway()
                + " entities into other entities, leaving "
                + merger.getRemainingEntities()
                + " entities in the database.");
        Data outputData = wrapWithMetadata(outputDatabase, "with merged " + toBeMerged.toString());
        monitor.done();
        return new Data[] {outputData};

      } else {
        throw new AlgorithmExecutionException(
            "The table this merge data is for is not in the database.");
      }
    } catch (SQLException e) {
      throw new AlgorithmExecutionException(
          "There was a problem communicating with the database.", e);
    } catch (DatabaseCopyException e) {
      throw new AlgorithmExecutionException(
          "There was a problem creating the output data: " + e.getMessage(), e);
    } finally {
      DatabaseUtilities.closeConnectionQuietly(originalConnection);
      DatabaseUtilities.closeConnectionQuietly(outputConnection);
    }
  }
Example #2
0
 private DatabaseTable inferTableToBeMerged(Table mergingTable)
     throws AlgorithmExecutionException {
   String header = mergingTable.getColumnName(mergingTable.getColumnCount() - 1);
   String name = extractNameFromHeader(header);
   try {
     return DatabaseTable.fromRepresentation(name);
   } catch (InvalidRepresentationException e) {
     throw new AlgorithmExecutionException(INVALID_TABLE_NAME_HEADER_MESSAGE);
   }
 }
Example #3
0
  private Merger collectMerges(Table mergingTable, DatabaseTable toBeMerged, Connection connection)
      throws AlgorithmExecutionException {

    Merger merger = new Merger(toBeMerged, monitor);
    try {
      String[] primaryKeyColumns = toBeMerged.getPrimaryKeyColumns(connection);
      ColumnProjection primaryKeyColumnFilter = new NamedColumnProjection(primaryKeyColumns, true);

      ForeignKey[] foreignKeys = toBeMerged.getRelations(connection);
      for (ForeignKey foreignKey : foreignKeys) {
        // merge units are the units of work that will repoint the foreign keys referring to the
        // entities merged away to point at the primary entities
        merger.addMergeUnit(new MergeUnit(foreignKey));
      }

      TableIterator merges =
          mergingTable.iterator(
              mergingTable.rowsSortedBy(CreateMergingTable.MERGE_GROUP_IDENTIFIER_COLUMN, true));

      while (merges.hasNext()) {
        int row = merges.nextInt();
        Tuple tuple = mergingTable.getTuple(row);
        String groupIdentifier = tuple.getString(CreateMergingTable.MERGE_GROUP_IDENTIFIER_COLUMN);
        // for every key someone used for a merge group, there's an EntityGroup
        EntityGroup group =
            merger.getOrCreateEntityGroup(
                groupIdentifier, toBeMerged, primaryKeyColumnFilter, foreignKeys);
        try {
          group.addRecord(tuple);
        } catch (MergingErrorException e) {
          problems.add(e.getMessage());
        }
      }

      return merger;

    } catch (SQLException e) {
      throw new AlgorithmExecutionException("There was a problem creating the output data.", e);
    }
  }