public FormScanBatch createNewBatch() { return new FormScanBatch( columnFactory, catalog, new FormVersionProviderAdapter(catalog), supervisor); }
private Slot<ColumnView> addColumn(Collection<NodeMatch> nodes) { // Recursively expand any calculated fields List<Slot<ColumnView>> expandedNodes = Lists.newArrayList(); for (NodeMatch node : nodes) { switch (node.getType()) { case FORM_NAME: case RECORD_ID: case FORM_ID: expandedNodes.add(batch.addColumn(filterLevel, node)); break; case FIELD: if (node.isCalculated()) { expandedNodes.add(expandCalculatedField(node)); } else { expandedNodes.add(batch.addColumn(filterLevel, node)); } break; } } if(expandedNodes.isEmpty()) { return batch.addEmptyColumn(filterLevel, rootFormClass); } else if(expandedNodes.size() == 1) { return expandedNodes.get(0); } else { return new FunctionCallSlot(CoalesceFunction.INSTANCE, expandedNodes); } }
@Override public Slot<ColumnView> visitConstant(ConstantNode node) { return batch.addConstantColumn(filterLevel, rootFormClass, node.getValue()); }
private ReferenceJoin addJoinLink(FilterLevel filterLevel, JoinNode node) { Slot<ForeignKey> foreignKey = addForeignKey(filterLevel, node); Slot<PrimaryKeyMap> primaryKey = addPrimaryKey(filterLevel, node.getRightFormId()); ReferenceJoinKey referenceJoinKey = new ReferenceJoinKey(filterLevel, foreignKey, primaryKey); ReferenceJoin joinLink = joinLinks.get(referenceJoinKey); if(joinLink == null) { joinLink = new ReferenceJoin(foreignKey, primaryKey, node.toString()); joinLinks.put(referenceJoinKey, joinLink); } return joinLink; }
private Slot<TableFilter> computeParentFilter(FilterLevel filterLevel, ResourceId formId) { if(parentFilterMap.containsKey(formId)) { return parentFilterMap.get(formId); } FormClass formClass = formClassProvider.getFormClass(formId); if(!formClass.isSubForm()) { return new PendingSlot<>(TableFilter.ALL_SELECTED); } Slot<PrimaryKeyMap> parentPrimaryKeySlot = addPrimaryKey(filterLevel, formClass.getParentFormId().get()); Slot<ColumnView> parentId = addParentColumn(FilterLevel.NONE, formId); ParentMask filter = new ParentMask(parentPrimaryKeySlot, parentId); parentFilterMap.put(formId, filter); return filter; } }
return addSubFormJoinedColumn(filterLevel, match); links.add(addJoinLink(filterLevel, joinNode)); switch (match.getType()) { case FIELD: column = getDataColumn(filterLevel, match.getFormClass().getId(), match.getFieldComponent()); break; case RECORD_ID: column = addRecordIdColumn(filterLevel, match.getFormClass().getId()); break; default:
/** * Adds a query to the batch for a column derived from a single node within the FormTree, along * with any necessary join structures required to join this column to the base table, if the column * is nested. * * @return a ColumnView Slot that can be used to retrieve the result after the batch * has finished executing. */ public Slot<ColumnView> addColumn(FilterLevel filterLevel, NodeMatch match) { if (match.isJoined()) { // requires join return addJoinedColumn(filterLevel, match); } else { // form label column, id column, simple root column or embedded form switch (match.getType()) { case FORM_NAME: return addConstantColumn(filterLevel, match.getFormClass(), match.getFormClass().getLabel()); case RECORD_ID: return addRecordIdColumn(filterLevel, match.getFormClass().getId()); case FORM_ID: return addConstantColumn(filterLevel, match.getFormClass(), match.getFormClass().getId().asString()); case FIELD: return getDataColumn(filterLevel, match.getFormClass().getId(), match.getFieldComponent()); default: throw new UnsupportedOperationException("Type: " + match.getType()); } } }
private Slot<ColumnView> addSubFormJoinedColumn(FilterLevel filterLevel, NodeMatch match) { JoinNode node = match.getJoins().get(0); Slot<PrimaryKeyMap> primaryKey = addPrimaryKey(filterLevel, node.getLeftFormId()); Slot<ColumnView> parentColumn = addParentColumn(filterLevel, node.getRightFormId()); Slot<ColumnView> dataColumn = getDataColumn(filterLevel, match.getFormClass().getId(), match.getFieldComponent()); SubFormJoin join = new SubFormJoin(primaryKey, parentColumn); return new JoinedSubFormColumnViewSlot(Collections.singletonList(join), dataColumn, node.getAggregation().or(SumFunction.INSTANCE)); }
@Override public Slot<ColumnView> visitSymbol(SymbolNode symbolNode) { // Check for recursion: are we in the process of evaluating // this symbol? Trying to do so again will lead to an infinite // loop and a StackOverflowException. if(evaluationStack.contains(symbolNode)) { return batch.addEmptyColumn(filterLevel, rootFormClass); } evaluationStack.push(symbolNode); try { Collection<NodeMatch> nodes = resolver.resolveSymbol(symbolNode); LOGGER.finer(symbolNode + " matched to " + nodes); return addColumn(nodes); } catch (AmbiguousSymbolException | SymbolNotFoundException e) { // Ambiguous or unknown symbols should result in an empty column, not full failure LOGGER.log(Level.WARNING, e.getMessage(), e); return batch.addEmptyColumn(filterLevel, rootFormClass); } finally { evaluationStack.pop(); } }
private Slot<PrimaryKeyMap> addPrimaryKey(FilterLevel filterLevel, ResourceId formId) { Slot<ColumnView> filteredIdSlot = addRecordIdColumn(filterLevel, formId); return new MemoizedSlot<>(filteredIdSlot, new Function<ColumnView, PrimaryKeyMap>() { @Override public PrimaryKeyMap apply(ColumnView columnView) { return columnFactory.newPrimaryKeyMap(columnView); } }); }
private Slot<ColumnView> expandCalculatedField(NodeMatch node) { try { Slot<ColumnView> calculation = evaluateExpression(node.getCalculation()); FormulaNode relevanceFormula = tryParseRelevance(node); if(relevanceFormula == null) { return calculation; } else { return new MemoizedSlot2<>(calculation, evaluateExpression(relevanceFormula), new BiFunction<ColumnView, ColumnView, ColumnView>() { @Override public ColumnView apply(ColumnView calculation, ColumnView relevance) { return new RelevanceViewMask(calculation, relevance); } }); } } catch (FormulaException e) { LOGGER.log(Level.WARNING, "Exception in calculated field " + node.getFormClass().getId() + "." + node.getFieldComponent() + " = " + node.getCalculation() + ": " + e.getMessage(), e); return batch.addEmptyColumn(filterLevel, node.getFormClass()); } }
FormScanBatch batch = new FormScanBatch( JsColumnFactory.INSTANCE, formTree, NullFormVersionProvider.INSTANCE,