while (filterIter.hasNext()) { FilterPredicate pred = filterIter.next(); str.append(pred.getPropertyName() + pred.getOperator() + pred.getValue()); if (filterIter.hasNext()) { str.append(" AND ");
bld.append(filter.getPropertyName()); bld.append(filter.getOperator().name()); bld.append(filter.getValue());
break; default: minOutput.remove(fp.getPropertyName()); // minus and-path filtered break; if (minOutput.contains(fp.getPropertyName()))
private void validateJoinQuery(QueryData qd, DatastoreQuery query, String joinSortProp) { // all filters on the primary must be equality for (Query.FilterPredicate fp : qd.primaryDatastoreQuery.getFilterPredicates()) { if (fp.getOperator() != Query.FilterOperator.EQUAL) { throw query.new UnsupportedDatastoreFeatureException( "Filter on property '" + fp.getPropertyName() + "' uses operator '" + fp.getOperator() + "'. Joins are only supported when all filters are 'equals' filters."); } } // all filters on the join must be equality for (Query.FilterPredicate fp : qd.joinQuery.getFilterPredicates()) { if (fp.getOperator() != Query.FilterOperator.EQUAL) { throw query.new UnsupportedDatastoreFeatureException( "Filter on property '" + fp.getPropertyName() + "' uses operator '" + fp.getOperator() + "'. Joins are only supported when all filters are 'equals' filters."); } } List<Query.SortPredicate> primarySorts = qd.primaryDatastoreQuery.getSortPredicates(); // There must be 0 or 1 sort orders total. // If there is a sort order it must be on the join column in ascending order. // TODO(maxr): support sorting by join column in descending order if (primarySorts.size() > 1 || !qd.joinQuery.getSortPredicates().isEmpty() || (!primarySorts.isEmpty() && (!primarySorts.get(0).getPropertyName().equals(joinSortProp) || primarySorts.get(0).getDirection() != Query.SortDirection.ASCENDING))) { throw query.new UnsupportedDatastoreFeatureException( "Joins can only be sorted by the join column in " + "ascending order (in this case '" + joinSortProp +"')"); } }
/** * Method to create a PreparedQuery, for the specified filter and ordering, to get the child objects of a parent. * @param parentKey Key of the parent * @param filterPredicates Filtering required * @param sortPredicates Ordering required * @param keysOnly Whether to just returns the keys of the children * @param kindName Name of the kind that we are querying * @return The PreparedQuery */ PreparedQuery prepareChildrenQuery(Key parentKey, Iterable<FilterPredicate> filterPredicates, Iterable<SortPredicate> sortPredicates, boolean keysOnly, String kindName) { Query q = new Query(kindName, parentKey); if (keysOnly) { q.setKeysOnly(); } NucleusLogger.PERSISTENCE.debug("Preparing to query for all children of " + parentKey + " of kind " + kindName); for (FilterPredicate fp : filterPredicates) { q.addFilter(fp.getPropertyName(), fp.getOperator(), fp.getValue()); NucleusLogger.PERSISTENCE.debug(" Added filter: " + fp.getPropertyName() + " " + fp.getOperator() + " " + fp.getValue()); } for (SortPredicate sp : sortPredicates) { q.addSort(sp.getPropertyName(), sp.getDirection()); NucleusLogger.PERSISTENCE.debug(" Added sort: " + sp.getPropertyName() + " " + sp.getDirection()); } DatastoreServiceConfig config = storeMgr.getDefaultDatastoreServiceConfigForReads(); DatastoreService ds = DatastoreServiceFactoryInternal.getDatastoreService(config); return ds.prepare(q); }
@Override public int compare(FilterPredicate o1, FilterPredicate o2) { int result = o1.getPropertyName().compareTo(o2.getPropertyName()); if (result != 0) return result; result = o1.getOperator().compareTo(o2.getOperator()); if (result != 0) return result; if (o1.getValue() == null) return o2.getValue() == null ? 0 : -1; else if (o2.getValue() == null) return 1; else return o1.getValue().toString().compareTo(o2.getValue().toString()); // not perfect, but probably as good as we can do } });
/** * Make a new Query object that is exactly like the old. Too bad Query isn't Cloneable. */ protected com.google.appengine.api.datastore.Query cloneRawQuery(com.google.appengine.api.datastore.Query orig) { com.google.appengine.api.datastore.Query copy = new com.google.appengine.api.datastore.Query(orig.getKind(), orig.getAncestor()); for (FilterPredicate filter: orig.getFilterPredicates()) copy.addFilter(filter.getPropertyName(), filter.getOperator(), filter.getValue()); for (SortPredicate sort: orig.getSortPredicates()) copy.addSort(sort.getPropertyName(), sort.getDirection()); // This should be impossible but who knows what might happen in the future if (orig.isKeysOnly()) copy.setKeysOnly(); return copy; }
@Test public void testFilterPredicate() { Query query = new Query(kindName, rootKey); query.setFilter(new FilterPredicate("intData", Query.FilterOperator.EQUAL, 20)); Entity e = service.prepare(query).asSingleEntity(); assertEquals("check query kind", kindName, query.getKind()); assertEquals("check query ancesor", rootKey, query.getAncestor()); Query.FilterPredicate fp = (Query.FilterPredicate) query.getFilter(); assertEquals("check FilterPredicate name", "intData", fp.getPropertyName()); assertEquals("check FilterPredicate operator", Query.FilterOperator.EQUAL, fp.getOperator()); assertEquals("check FilterPredicate value", e.getProperty("intData").toString(), fp.getValue().toString()); }