use of org.activityinfo.model.formula.eval.FormSymbolTable in project activityinfo by bedatadriven.
the class OldGetSitesHandler method joinCalculatedIndicatorValues.
private void joinCalculatedIndicatorValues(final Promise<Void> complete, SqlTransaction tx, final Multimap<Integer, SiteDTO> siteMap) {
Log.trace("Starting joinIndicatorValues()");
final Set<Integer> activityIds = Sets.newHashSet();
for (SiteDTO siteDTO : siteMap.values()) {
activityIds.add(siteDTO.getActivityId());
}
SqlQuery query = SqlQuery.select().appendColumn("I.IndicatorId", "indicatorId").appendColumn("I.Name", "indicatorName").appendColumn("I.ActivityId", "activityId").appendColumn("I.Type", "type").appendColumn("I.Expression", "expression").appendColumn("I.nameInExpression", "code").appendColumn("I.calculatedAutomatically", "calculatedAutomatically").from(Tables.INDICATOR, "I").where("I.ActivityId").in(activityIds).and("I.dateDeleted IS NULL").orderBy("I.SortOrder");
Log.info(query.toString());
query.execute(tx, new SqlResultCallback() {
@Override
public void onSuccess(SqlTransaction tx, final SqlResultSet results) {
Multimap<Integer, FormField> fields = HashMultimap.create();
for (SqlResultSetRow row : results.getRows()) {
fields.put(row.getInt("activityId"), createField(row));
}
// Have to resolve symbols on a per-form basis
for (Integer activityId : fields.keySet()) {
Collection<FormField> activityFields = fields.get(activityId);
FormSymbolTable symbolTable = new FormSymbolTable(activityFields);
PartialEvaluator<SiteDTO> evaluator = new PartialEvaluator<>(symbolTable, new SiteFieldReaderFactory());
List<CalculatedIndicatorReader> readers = Lists.newArrayList();
for (FormField field : activityFields) {
if (field.getType() instanceof CalculatedFieldType) {
try {
FieldReader<SiteDTO> reader = evaluator.partiallyEvaluate(field);
if (reader.getType() instanceof QuantityType) {
readers.add(new CalculatedIndicatorReader(field, reader));
}
} catch (Exception e) {
// we don't want to fail whole GetSites command due to invalid expression.
Log.error("Failed to evaluate calculated field: " + field + ", expression: " + ((CalculatedFieldType) field.getType()).getExpression(), e);
}
}
}
for (SiteDTO site : siteMap.values()) {
for (CalculatedIndicatorReader reader : readers) {
reader.read(site);
}
}
}
complete.onSuccess(null);
}
});
}
use of org.activityinfo.model.formula.eval.FormSymbolTable in project activityinfo by bedatadriven.
the class ExprQueryBuilder method computeFormClass.
private FormSymbolTable computeFormClass(FormSymbolTable parent, FormulaNode formulaNode) {
if (formulaNode instanceof SymbolNode) {
FormField field = parent.resolveSymbol((SymbolNode) formulaNode);
if (field.getType() instanceof RecordFieldType) {
RecordFieldType recordFieldType = (RecordFieldType) field.getType();
FormClass recordFormClass = recordFieldType.getFormClass();
return new FormSymbolTable(recordFormClass);
} else {
throw new IllegalStateException(field.getName() + " is not a record type field.");
}
} else if (formulaNode instanceof CompoundExpr) {
CompoundExpr compoundExpr = (CompoundExpr) formulaNode;
FormSymbolTable child = computeFormClass(parent, compoundExpr.getValue());
return computeFormClass(child, compoundExpr.getValue());
} else {
throw new UnsupportedOperationException("exprNode: " + formulaNode);
}
}
Aggregations