use of org.apache.cayenne.access.util.DefaultOperationObserver in project cayenne by apache.
the class FlattenedArcKey method buildJoinSnapshotsForDelete.
/**
* Returns pk snapshots for join records for the single-step flattened
* relationship. Multiple joins between the same pair of objects are
* theoretically possible, so the return value is a list.
*/
List buildJoinSnapshotsForDelete(DataNode node) {
Map<String, Object> snapshot = eagerJoinSnapshot();
DbEntity joinEntity = getJoinEntity();
boolean fetchKey = false;
for (DbAttribute dbAttr : joinEntity.getPrimaryKeys()) {
String dbAttrName = dbAttr.getName();
if (!snapshot.containsKey(dbAttrName)) {
fetchKey = true;
break;
}
}
if (!fetchKey) {
return Collections.singletonList(snapshot);
}
// ok, the key is not included in snapshot, must do the fetch...
// TODO: this should be optimized in the future, but now
// DeleteBatchQuery
// expects a PK snapshot, so we must provide it.
QuotingStrategy quoter = node.getAdapter().getQuotingStrategy();
StringBuilder sql = new StringBuilder("SELECT ");
Collection<DbAttribute> pk = joinEntity.getPrimaryKeys();
final List<DbAttribute> pkList = pk instanceof List ? (List<DbAttribute>) pk : new ArrayList<>(pk);
for (int i = 0; i < pkList.size(); i++) {
if (i > 0) {
sql.append(", ");
}
DbAttribute attribute = pkList.get(i);
sql.append("#result('");
sql.append(quoter.quotedName(attribute));
// since the name of the column can potentially be quoted and
// use reserved keywords as name, let's specify generated column
// name parameters to ensure the query doesn't explode
sql.append("' '").append(TypesMapping.getJavaBySqlType(attribute.getType()));
sql.append("' '").append("pk").append(i);
sql.append("')");
}
sql.append(" FROM ").append(quoter.quotedFullyQualifiedName(joinEntity)).append(" WHERE ");
int i = snapshot.size();
for (Object key : snapshot.keySet()) {
sql.append(quoter.quotedIdentifier(joinEntity, String.valueOf(key))).append(" #bindEqual($").append(key).append(")");
if (--i > 0) {
sql.append(" AND ");
}
}
SQLTemplate query = new SQLTemplate(joinEntity.getDataMap(), sql.toString(), true);
query.setParams(snapshot);
final List[] result = new List[1];
node.performQueries(Collections.singleton((Query) query), new DefaultOperationObserver() {
@Override
public void nextRows(Query query, List<?> dataRows) {
if (!dataRows.isEmpty()) {
// decode results...
List<DataRow> fixedRows = new ArrayList<>(dataRows.size());
for (Object o : dataRows) {
DataRow row = (DataRow) o;
DataRow fixedRow = new DataRow(2);
for (int i = 0; i < pkList.size(); i++) {
DbAttribute attribute = pkList.get(i);
fixedRow.put(attribute.getName(), row.get("pk" + i));
}
fixedRows.add(fixedRow);
}
dataRows = fixedRows;
}
result[0] = dataRows;
}
@Override
public void nextQueryException(Query query, Exception ex) {
throw new CayenneRuntimeException("Raising from query exception.", Util.unwindException(ex));
}
@Override
public void nextGlobalException(Exception ex) {
throw new CayenneRuntimeException("Raising from underlyingQueryEngine exception.", Util.unwindException(ex));
}
});
return result[0];
}
Aggregations