/* * Copyright (c) 2011-2015 Spotify AB * * Licensed under the Apache License, Version 2.0 (the "License"); you may not * use this file except in compliance with the License. You may obtain a copy of * the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * License for the specific language governing permissions and limitations under * the License. */ package com.spotify.asyncdatastoreclient; import com.google.api.client.util.Lists; import com.google.datastore.v1.Projection; import com.google.datastore.v1.PropertyReference; import com.google.protobuf.ByteString; import com.google.protobuf.Int32Value; import java.util.Arrays; import java.util.List; import java.util.stream.Collectors; /** * A query statement. * * Retrieves one or more entities that satisfy a given criteria and order. */ public class Query implements Statement { private final com.google.datastore.v1.Query.Builder query; private final List<Filter> filters; Query() { query = com.google.datastore.v1.Query.newBuilder(); filters = Lists.newArrayList(); } /** * Specifies that only entity keys should be returned and not all * properties. * * @return this query statement. */ public Query keysOnly() { query.addProjection( Projection .newBuilder() .setProperty(PropertyReference.newBuilder().setName("__key__").build())); return this; } /** * Only return a given set of properties, otherwise known as a Projection Query. * * @param properties one or more property names to return. * @return this query statement. */ public Query properties(final String... properties) { return properties(Arrays.asList(properties)); } /** * Only return a given set of properties, otherwise known as a Projection Query. * * @param properties one or more property names to return. * @return this query statement. */ public Query properties(final List<String> properties) { query.addAllProjection(properties.stream() .map(property -> Projection.newBuilder() .setProperty(com.google.datastore.v1.PropertyReference .newBuilder() .setName(property)) .build()) .collect(Collectors.toList())); return this; } /** * Query entities of a given kind. * * @param kind the kind of entity to query. * @return this query statement. */ public Query kindOf(final String kind) { query.addKind(com.google.datastore.v1.KindExpression.newBuilder().setName(kind)); return this; } /** * Apply a given filter to the query. * * @param filter the query filter to apply. * @return this query statement. */ public Query filterBy(final Filter filter) { filters.add(filter); return this; } /** * Apply a given order to the query. * * @param order the query order to apply. * @return this query statement. */ public Query orderBy(final Order order) { query.addOrder(order.getPb()); return this; } /** * Apply a given group to the query. * * @param group the query group to apply. * @return this query statement. */ public Query groupBy(final Group group) { query.addDistinctOn(group.getPb()); return this; } /** * Tell Datastore to begin returning entities from a given cursor * position. This is used to page results; the last cursor position * is returned in {@code QueryResult}. * * @param cursor the last query cursor position. * @return this query statement. */ public Query fromCursor(final ByteString cursor) { query.setStartCursor(cursor); return this; } /** * Limit the number of entities returned in this query. The last * cursor position will be returned in {@code QueryResult} if more * entities are required. * * @param limit the maximum number of entities to return. * @return this query statement. */ public Query limit(final int limit) { query.setLimit(Int32Value.newBuilder().setValue(limit)); return this; } com.google.datastore.v1.Query getPb(String namespace) { if (filters.size() == 1) { query.setFilter(filters.get(0).getPb(namespace)); } else if (filters.size() > 1) { query.setFilter(com.google.datastore.v1.Filter.newBuilder() .setCompositeFilter( com.google.datastore.v1.CompositeFilter.newBuilder() .addAllFilters(filters.stream().map(f -> f.getPb(namespace)).collect(Collectors.toList())) .setOp(com.google.datastore.v1.CompositeFilter.Operator.AND))); } return query.build(); } }