/** * Process the traversal start event for a query {@link org.plasma.query.model.Property property} * within an {@link org.plasma.query.model.Expression expression} just traversing the property * path if exists and capturing context information for the current {@link * org.plasma.query.model.Expression expression}. * * @see org.plasma.query.visitor.DefaultQueryVisitor#start(org.plasma.query.model.Property) */ @Override public void start(Property property) { org.plasma.query.model.FunctionValues function = property.getFunction(); if (function != null) throw new GraphFilterException( "aggregate functions only supported in subqueries not primary queries"); Path path = property.getPath(); PlasmaType targetType = (PlasmaType) this.rootType; if (path != null) { for (int i = 0; i < path.getPathNodes().size(); i++) { AbstractPathElement pathElem = path.getPathNodes().get(i).getPathElement(); if (pathElem instanceof WildcardPathElement) throw new DataAccessException( "wildcard path elements applicable for 'Select' clause paths only, not 'Where' clause paths"); String elem = ((PathElement) pathElem).getValue(); PlasmaProperty prop = (PlasmaProperty) targetType.getProperty(elem); targetType = (PlasmaType) prop.getType(); // traverse } } PlasmaProperty endpointProp = (PlasmaProperty) targetType.getProperty(property.getName()); this.contextProperty = endpointProp; this.contextType = targetType; this.contextPropertyPath = property.asPathString(); super.start(property); }
private List<List<PropertyPair>> findResults( Query query, PropertySelectionCollector collector, PlasmaType type, Connection con) { Object[] params = new Object[0]; JDBCDataConverter converter = JDBCDataConverter.INSTANCE; if (log.isDebugEnabled()) { log(query); } AliasMap aliasMap = new AliasMap(type); Map<Type, List<String>> selectMap = collector.getResult(); // construct a filter adding to alias map JDBCFilterAssembler filterAssembler = null; Where where = query.findWhereClause(); if (where != null) { filterAssembler = new JDBCFilterAssembler(where, type, aliasMap); params = filterAssembler.getParams(); } JDBCOrderingDeclarationAssembler orderingDeclAssembler = null; OrderBy orderby = query.findOrderByClause(); if (orderby != null) orderingDeclAssembler = new JDBCOrderingDeclarationAssembler(orderby, type, aliasMap); JDBCGroupingDeclarationAssembler groupingDeclAssembler = null; GroupBy groupby = query.findGroupByClause(); if (groupby != null) groupingDeclAssembler = new JDBCGroupingDeclarationAssembler(groupby, type, aliasMap); String rootAlias = aliasMap.getAlias(type); StringBuilder sqlQuery = new StringBuilder(); sqlQuery.append("SELECT "); int i = 0; List<String> names = selectMap.get(type); for (String name : names) { PlasmaProperty prop = (PlasmaProperty) type.getProperty(name); if (prop.isMany() && !prop.getType().isDataType()) continue; if (i > 0) sqlQuery.append(", "); sqlQuery.append(rootAlias); sqlQuery.append("."); sqlQuery.append(prop.getPhysicalName()); i++; } // construct a FROM clause from alias map sqlQuery.append(" FROM "); Iterator<PlasmaType> it = aliasMap.getTypes(); int count = 0; while (it.hasNext()) { PlasmaType aliasType = it.next(); String alias = aliasMap.getAlias(aliasType); if (count > 0) sqlQuery.append(", "); sqlQuery.append(aliasType.getPhysicalName()); sqlQuery.append(" "); sqlQuery.append(alias); count++; } // append WHERE filter if (filterAssembler != null) { sqlQuery.append(" "); sqlQuery.append(filterAssembler.getFilter()); } // set the result range // FIXME: Oracle specific if (query.getStartRange() != null && query.getEndRange() != null) { if (where == null) sqlQuery.append(" WHERE "); else sqlQuery.append(" AND "); sqlQuery.append("ROWNUM >= "); sqlQuery.append(String.valueOf(query.getStartRange())); sqlQuery.append(" AND ROWNUM <= "); sqlQuery.append(String.valueOf(query.getEndRange())); } if (orderingDeclAssembler != null) { sqlQuery.append(" "); sqlQuery.append(orderingDeclAssembler.getOrderingDeclaration()); } if (groupingDeclAssembler != null) { sqlQuery.append(" "); sqlQuery.append(groupingDeclAssembler.getGroupingDeclaration()); } List<List<PropertyPair>> rows = new ArrayList<List<PropertyPair>>(); PreparedStatement statement = null; ResultSet rs = null; try { statement = con.prepareStatement( sqlQuery.toString(), ResultSet.TYPE_FORWARD_ONLY, /*ResultSet.TYPE_SCROLL_INSENSITIVE,*/ ResultSet.CONCUR_READ_ONLY); // set params // note params are pre-converted // to string in filter assembly // FIXME: are parameters relevant in SQL in this context? if (filterAssembler != null) { params = filterAssembler.getParams(); if (params != null) for (i = 0; i < params.length; i++) statement.setString(i + 1, String.valueOf(params[i])); } if (log.isDebugEnabled()) { if (params == null || params.length == 0) { log.debug("executing: " + sqlQuery.toString()); } else { StringBuilder paramBuf = new StringBuilder(); paramBuf.append(" ["); for (int p = 0; p < params.length; p++) { if (p > 0) paramBuf.append(", "); paramBuf.append(String.valueOf(params[p])); } paramBuf.append("]"); log.debug("executing: " + sqlQuery.toString() + " " + paramBuf.toString()); } } statement.execute(); rs = statement.getResultSet(); int numcols = rs.getMetaData().getColumnCount(); ResultSetMetaData rsMeta = rs.getMetaData(); List<PropertyPair> row = null; PropertyPair pair = null; while (rs.next()) { row = new ArrayList<PropertyPair>(); rows.add(row); for (i = 1; i <= numcols; i++) { String columnName = rsMeta.getColumnName(i); int columnType = rsMeta.getColumnType(i); PlasmaProperty prop = (PlasmaProperty) type.getProperty(columnName); Object value = converter.fromJDBCDataType(rs, i, columnType, prop); pair = new PropertyPair(prop, value); pair.setColumn(i); row.add(pair); } } } catch (Throwable t) { StringBuffer buf = this.generateErrorDetail(t, sqlQuery.toString(), filterAssembler); log.error(buf.toString()); throw new DataAccessException(t); } finally { try { if (rs != null) rs.close(); if (statement != null) statement.close(); } catch (SQLException e) { log.error(e.getMessage(), e); } } return rows; }