@Override public NodeIter iter(final QueryContext ctx) throws QueryException { final Value v = checkCtx(ctx); if (!v.type.isNode()) NODESPATH.thrw(input, AxisStep.this, v.type); final AxisIter ai = axis.iter((ANode) v); final NodeCache nc = new NodeCache(); for (ANode n; (n = ai.next()) != null; ) if (test.eval(n)) nc.add(n.finish()); // evaluate predicates for (final Expr p : preds) { ctx.size = nc.size(); ctx.pos = 1; int c = 0; for (int n = 0; n < nc.size(); ++n) { ctx.value = nc.get(n); final Item i = p.test(ctx, input); if (i != null) { // assign score value nc.get(n).score(i.score()); nc.item[c++] = nc.get(n); } ctx.pos++; } nc.size(c); } return nc; }
/** * Builds a sequence of elements from a query's result set. * * @param rs result set * @return sequence of elements <tuple/> each of which represents a row from the result set * @throws QueryException query exception */ private NodeCache buildResult(final ResultSet rs) throws QueryException { try { final ResultSetMetaData metadata = rs.getMetaData(); final int columnCount = metadata.getColumnCount(); final NodeCache rows = new NodeCache(); while (rs.next()) { final NodeCache columns = new NodeCache(); for (int k = 1; k <= columnCount; k++) { // For each row add column values as children final String label = metadata.getColumnLabel(k); final Object value = rs.getObject(label); // Null values are ignored if (value != null) { // Column name final FAttr columnName = new FAttr(Q_NAME, token(label)); final NodeCache attr = new NodeCache(); attr.add(columnName); // Column value final FTxt columnValue = new FTxt(token(value.toString())); final NodeCache ch = new NodeCache(); ch.add(columnValue); // Element <sql:column name='...'>...</sql:column> columns.add(new FElem(Q_COLUMN, ch, attr, NS_SQL, null)); } } rows.add(new FElem(Q_ROW, columns, null, NS_SQL, null)); } return rows; } catch (final SQLException ex) { throw SQLEXC.thrw(input, ex.getMessage()); } }
@Override public Iter iter(final QueryContext ctx) throws QueryException { final Value cv = ctx.value; final long cs = ctx.size; final long cp = ctx.pos; try { Value r = root != null ? ctx.value(root) : cv; if (!cache || citer == null || lvalue.type != NodeType.DOC || r.type != NodeType.DOC || !((ANode) lvalue).is((ANode) r)) { lvalue = r; citer = new NodeCache().random(); if (r != null) { final Iter ir = ctx.iter(r); while ((r = ir.next()) != null) { ctx.value = r; iter(0, citer, ctx); } } else { ctx.value = null; iter(0, citer, ctx); } citer.sort(); } else { citer.reset(); } return citer; } finally { ctx.value = cv; ctx.size = cs; ctx.pos = cp; } }
/** * Recursive step iterator. * * @param l current step * @param nc node cache * @param ctx query context * @throws QueryException query exception */ private void iter(final int l, final NodeCache nc, final QueryContext ctx) throws QueryException { // cast is safe (steps will always return a {@link NodIter} instance final NodeIter ni = (NodeIter) ctx.iter(steps[l]); final boolean more = l + 1 != steps.length; for (ANode node; (node = ni.next()) != null; ) { if (more) { ctx.value = node; iter(l + 1, nc, ctx); } else { ctx.checkStop(); nc.add(node); } } }
/** * Adds children of a sub node. * * @param ch child nodes * @param nc node cache */ protected final void addDesc(final AxisMoreIter ch, final NodeCache nc) { for (ANode n; (n = ch.next()) != null; ) { nc.add(n.finish()); addDesc(n.children(), nc); } }