{
Class> resultClass();
/**
- * Returns the Cursor for the point after the value returned in the last {@link #next} call.
- * Currently, {@code cursorAfter} returns null in all cases but the last result.
+ * Returns the Cursor for the point after the value returned in the last {@link #next} call. This
+ * cursor can be used to issue subsequent queries (with the same constraints) that may return
+ * additional results.
+ *
+ * A simple use case:
+ *
{@code
+ * Query query = Query.entityQueryBuilder()
+ * .kind("Person")
+ * .filter(PropertyFilter.eq("favoriteFood", "pizza"))
+ * .build();
+ * QueryResults results = datastore.run(query);
+ * // Consume some results (using results.next()) and do any other actions as necessary.
+ * query = query.toBuilder().startCursor(results.cursorAfter()).build();
+ * results = datastore.run(query); // now we will iterate over all entities not yet consumed
+ * }
*/
Cursor cursorAfter();
}
diff --git a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/QueryResultsImpl.java b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/QueryResultsImpl.java
index 3c2e0d177f80..ec3a652c6131 100644
--- a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/QueryResultsImpl.java
+++ b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/QueryResultsImpl.java
@@ -16,10 +16,9 @@
package com.google.gcloud.datastore;
-import com.google.api.services.datastore.DatastoreV1;
-import com.google.api.services.datastore.DatastoreV1.QueryResultBatch.MoreResultsType;
import com.google.common.base.Preconditions;
import com.google.common.collect.AbstractIterator;
+import com.google.datastore.v1beta3.QueryResultBatch.MoreResultsType;
import com.google.gcloud.datastore.Query.ResultType;
import com.google.protobuf.ByteString;
@@ -29,46 +28,56 @@
class QueryResultsImpl extends AbstractIterator implements QueryResults {
private final DatastoreImpl datastore;
- private final DatastoreV1.ReadOptions readOptionsPb;
- private final DatastoreV1.PartitionId partitionIdPb;
+ private final com.google.datastore.v1beta3.ReadOptions readOptionsPb;
+ private final com.google.datastore.v1beta3.PartitionId partitionIdPb;
private final ResultType queryResultType;
private Query query;
private ResultType> actualResultType;
- private DatastoreV1.QueryResultBatch queryResultBatchPb;
+ private com.google.datastore.v1beta3.RunQueryResponse runQueryResponsePb;
+ private com.google.datastore.v1beta3.Query mostRecentQueryPb;
private boolean lastBatch;
- private Iterator entityResultPbIter;
- private ByteString cursor; // only available in v1beta3
+ private Iterator entityResultPbIter;
+ private ByteString cursor;
-
- QueryResultsImpl(DatastoreImpl datastore, DatastoreV1.ReadOptions readOptionsPb,
+ QueryResultsImpl(DatastoreImpl datastore, com.google.datastore.v1beta3.ReadOptions readOptionsPb,
Query query) {
this.datastore = datastore;
this.readOptionsPb = readOptionsPb;
this.query = query;
queryResultType = query.type();
- DatastoreV1.PartitionId.Builder pbBuilder = DatastoreV1.PartitionId.newBuilder();
- pbBuilder.setDatasetId(datastore.options().projectId());
+ com.google.datastore.v1beta3.PartitionId.Builder pbBuilder =
+ com.google.datastore.v1beta3.PartitionId.newBuilder();
+ pbBuilder.setProjectId(datastore.options().projectId());
if (query.namespace() != null) {
- pbBuilder.setNamespace(query.namespace());
+ pbBuilder.setNamespaceId(query.namespace());
} else if (datastore.options().namespace() != null) {
- pbBuilder.setNamespace(datastore.options().namespace());
+ pbBuilder.setNamespaceId(datastore.options().namespace());
}
partitionIdPb = pbBuilder.build();
sendRequest();
+ if (runQueryResponsePb.getBatch().getSkippedResults() > 0) {
+ cursor = runQueryResponsePb.getBatch().getSkippedCursor();
+ } else {
+ cursor = mostRecentQueryPb.getStartCursor();
+ }
}
private void sendRequest() {
- DatastoreV1.RunQueryRequest.Builder requestPb = DatastoreV1.RunQueryRequest.newBuilder();
+ com.google.datastore.v1beta3.RunQueryRequest.Builder requestPb =
+ com.google.datastore.v1beta3.RunQueryRequest.newBuilder();
if (readOptionsPb != null) {
requestPb.setReadOptions(readOptionsPb);
}
requestPb.setPartitionId(partitionIdPb);
query.populatePb(requestPb);
- queryResultBatchPb = datastore.runQuery(requestPb.build()).getBatch();
- lastBatch = queryResultBatchPb.getMoreResults() != MoreResultsType.NOT_FINISHED;
- entityResultPbIter = queryResultBatchPb.getEntityResultList().iterator();
- // cursor = resultPb.getSkippedCursor(); // available in v1beta3, use startCursor if not skipped
- actualResultType = ResultType.fromPb(queryResultBatchPb.getEntityResultType());
+ runQueryResponsePb = datastore.runQuery(requestPb.build());
+ mostRecentQueryPb = runQueryResponsePb.getQuery();
+ if (mostRecentQueryPb == null) {
+ mostRecentQueryPb = requestPb.getQuery();
+ }
+ lastBatch = runQueryResponsePb.getBatch().getMoreResults() != MoreResultsType.NOT_FINISHED;
+ entityResultPbIter = runQueryResponsePb.getBatch().getEntityResultsList().iterator();
+ actualResultType = ResultType.fromPb(runQueryResponsePb.getBatch().getEntityResultType());
if (Objects.equals(queryResultType, ResultType.PROJECTION_ENTITY)) {
// projection entity can represent all type of results
actualResultType = ResultType.PROJECTION_ENTITY;
@@ -80,15 +89,15 @@ private void sendRequest() {
@Override
protected T computeNext() {
while (!entityResultPbIter.hasNext() && !lastBatch) {
- query = query.nextQuery(queryResultBatchPb);
+ query = query.nextQuery(runQueryResponsePb);
sendRequest();
}
if (!entityResultPbIter.hasNext()) {
- cursor = queryResultBatchPb.getEndCursor();
+ cursor = runQueryResponsePb.getBatch().getEndCursor();
return endOfData();
}
- DatastoreV1.EntityResult entityResultPb = entityResultPbIter.next();
- //cursor = entityResultPb.getCursor(); // only available in v1beta3
+ com.google.datastore.v1beta3.EntityResult entityResultPb = entityResultPbIter.next();
+ cursor = entityResultPb.getCursor();
@SuppressWarnings("unchecked")
T result = (T) actualResultType.convert(entityResultPb.getEntity());
return result;
@@ -101,7 +110,6 @@ public Class> resultClass() {
@Override
public Cursor cursorAfter() {
- return cursor == null ? null : new Cursor(cursor);
- //return new Cursor(cursor); // only available in v1beta3
+ return new Cursor(cursor);
}
}
diff --git a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/RawValue.java b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/RawValue.java
index 9d447cf4289b..cd64bcdeff05 100644
--- a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/RawValue.java
+++ b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/RawValue.java
@@ -16,19 +16,17 @@
package com.google.gcloud.datastore;
-import com.google.api.services.datastore.DatastoreV1;
-
-public final class RawValue extends Value {
+public final class RawValue extends Value {
private static final long serialVersionUID = -3359604598651897941L;
- static final BaseMarshaller MARSHALLER =
- new BaseMarshaller() {
+ static final BaseMarshaller MARSHALLER =
+ new BaseMarshaller() {
private static final long serialVersionUID = 5320642719486106244L;
@Override
- public Builder newBuilder(DatastoreV1.Value value) {
+ public Builder newBuilder(com.google.datastore.v1beta3.Value value) {
return builder(value);
}
@@ -38,18 +36,19 @@ public int getProtoFieldId() {
}
@Override
- protected DatastoreV1.Value getValue(DatastoreV1.Value from) {
+ protected com.google.datastore.v1beta3.Value getValue(
+ com.google.datastore.v1beta3.Value from) {
return from;
}
@Override
- protected void setValue(RawValue from, DatastoreV1.Value.Builder to) {
+ protected void setValue(RawValue from, com.google.datastore.v1beta3.Value.Builder to) {
to.mergeFrom(from.get());
}
};
public static final class Builder
- extends Value.BaseBuilder {
+ extends Value.BaseBuilder