}
private static Set<ColumnValues> resolveDependingPks(IDatabaseConnection connection, Edge edge,
Set<ColumnValues> toPks, ColumnValuesTableMap resolvedPks) throws SQLException {
RelationshipTranslation translation = edge.getTranslation();
if (translation.getRelationTable() == null) {
if (toPks == null) {
return null;
}
//get the foreign keys in the "to" table
Set<ColumnValues> columnValues = getValuesFromTable(connection, edge.getTo().getTranslation()
.getTableName(), translation.getToColumns(), toPks);
//now rename the foreign keys to their foreign key counterparts in the "from" table
for (int i = 0; i < translation.getFromColumns().length; ++i) {
for (ColumnValues cols : columnValues) {
cols.getColumns().get(i).setName(translation.getFromColumns()[i]);
}
}
EntityTranslation fromTranslation = edge.getFrom().getTranslation();
//now translate the foreign keys into primary keys
//but first check if we even need to do it by comparing the column names
boolean columnsDiffer = false;
Set<String> pkColumns = new HashSet<String>(Arrays.asList(fromTranslation.getPkColumns()));
for(String col : translation.getFromColumns()) {
if (!pkColumns.contains(col)) {
columnsDiffer = true;
break;
}
}
if (columnsDiffer) {
columnValues = getValuesFromTable(connection, fromTranslation.getTableName(),
fromTranslation.getPkColumns(), removeValuesWithNullColumn(columnValues));
}
return removeValuesWithNullColumn(columnValues);
} else {
//only bother with one-to-many relationships. A many-to-many
//relationship implicitly means that the two entities are not tightly
//connected (with a many-to-many relationship, either of the entities
//can always "live without" the entities from the other side of the relationship).
if (edge.getDependencyType() != DependencyType.MANY_TO_MANY) {
//copy the toPks to columnValues. We'll use the pks from the to table
//to find the corresponding entries in the relation table
Set<ColumnValues> columnValues = null;
if (toPks != null) {
columnValues = new HashSet<ColumnValues>();
for (ColumnValues pk : toPks) {
columnValues.add(pk.clone());
}
//now change the names of the columns in columnValues to the corresponding
//relationTableToColumns (this assumes the same order of the columns
//in the case of composite pk)
for (int i = 0; i < translation.getRelationTableToColumns().length; ++i) {
for (ColumnValues cols : columnValues) {
cols.getColumns().get(i).setName(translation.getRelationTableToColumns()[i]);
}
}
}
String[] fromAndToCols = new String[translation.getRelationTableFromColumns().length
+ translation.getRelationTableToColumns().length];
System.arraycopy(translation.getRelationTableFromColumns(), 0, fromAndToCols, 0,
translation.getRelationTableFromColumns().length);
System.arraycopy(translation.getRelationTableToColumns(), 0, fromAndToCols,
translation.getRelationTableFromColumns().length, translation.getRelationTableToColumns().length);
if (toPks != null) {
Set<ColumnValues> fromAndToValues = getValuesFromTable(connection, translation.getRelationTable(),
fromAndToCols, columnValues);
//add the relation table to the resolvedPks using fromAndToValues as its primary keys
resolvedPks.getOrCreate(translation.getRelationTable()).addAll(fromAndToValues);
//now read out the to pks from fromAndToCols are return them as the "from" table primary keys
Set<ColumnValues> fromPks = new HashSet<ColumnValues>();
for (ColumnValues cols : fromAndToValues) {
ColumnValues fromPk = new ColumnValues();
for (int i = 0; i < translation.getRelationTableFromColumns().length; ++i) {
String colName = translation.getRelationTableFromColumns()[i];
String pkName = edge.getFrom().getTranslation().getPkColumns()[i];
fromPk.add(pkName, cols.getColumnByName(colName).getValue());
}
fromPks.add(fromPk);
}
return removeValuesWithNullColumn(fromPks);
} else {
resolvedPks.put(translation.getRelationTable(), null);
return null;
}
} else {
//put no restrictions on the search if the toPks are null (unrestricted)
//otherwise pretend there's nothing depending.