1 package com
.google
.appengine
.api
.datastore
;
3 import static com
.google
.appengine
.api
.datastore
.DatastoreApiHelper
.makeAsyncCall
;
5 import com
.google
.apphosting
.api
.ApiProxy
.ApiConfig
;
6 import com
.google
.apphosting
.datastore
.DatastoreV3Pb
;
7 import com
.google
.apphosting
.datastore
.DatastoreV3Pb
.CompiledCursor
;
8 import com
.google
.apphosting
.datastore
.DatastoreV3Pb
.DatastoreService_3
.Method
;
9 import com
.google
.apphosting
.datastore
.DatastoreV3Pb
.NextRequest
;
10 import com
.google
.apphosting
.datastore
.DatastoreV3Pb
.QueryResult
;
11 import com
.google
.common
.collect
.Lists
;
12 import com
.google
.storage
.onestore
.v3
.OnestoreEntity
.CompositeIndex
;
13 import com
.google
.storage
.onestore
.v3
.OnestoreEntity
.EntityProto
;
15 import java
.util
.Collection
;
16 import java
.util
.Collections
;
17 import java
.util
.List
;
18 import java
.util
.concurrent
.Future
;
21 * V3 service specific code for iterating query results and requesting more results.
22 * Instances can be shared between queries using the same ApiConfig.
24 class QueryResultsSourceV3
extends BaseQueryResultsSource
<QueryResult
, NextRequest
, QueryResult
> {
26 private final ApiConfig apiConfig
;
28 QueryResultsSourceV3(DatastoreCallbacks callbacks
, FetchOptions fetchOptions
, Transaction txn
,
29 Query query
, Future
<QueryResult
> initialQueryResultFuture
, ApiConfig apiConfig
) {
30 super(callbacks
, fetchOptions
, txn
, query
, initialQueryResultFuture
);
31 this.apiConfig
= apiConfig
;
35 public NextRequest
buildNextCallPrototype(QueryResult initialResult
) {
36 DatastoreV3Pb
.NextRequest req
= new DatastoreV3Pb
.NextRequest();
37 req
.setCursor(initialResult
.getCursor());
38 if (initialResult
.hasCompiledCursor()) {
46 public Future
<QueryResult
> makeNextCall(NextRequest reqPrototype
, WrappedQueryResult unused
, Integer fetchCount
, Integer offsetOrNull
) {
47 DatastoreV3Pb
.NextRequest req
= reqPrototype
.clone();
48 if (fetchCount
!= null) {
49 req
.setCount(fetchCount
);
51 if (offsetOrNull
!= null) {
52 req
.setOffset(offsetOrNull
);
54 return makeAsyncCall(apiConfig
, Method
.Next
, req
, new DatastoreV3Pb
.QueryResult());
58 public WrappedQueryResult
wrapResult(QueryResult result
) {
59 return new WrappedQueryResultV3(result
);
63 public WrappedQueryResult
wrapInitialResult(QueryResult initialResult
) {
64 return new WrappedQueryResultV3(initialResult
);
67 private static class WrappedQueryResultV3
implements WrappedQueryResult
{
68 private final DatastoreV3Pb
.QueryResult res
;
70 WrappedQueryResultV3(DatastoreV3Pb
.QueryResult res
) {
75 public List
<Entity
> getEntities(Collection
<Projection
> projections
) {
76 List
<Entity
> entities
= Lists
.newArrayListWithCapacity(res
.resultSize());
77 if (projections
.isEmpty()) {
78 for (EntityProto entityProto
: res
.results()) {
79 entities
.add(EntityTranslator
.createFromPb(entityProto
));
82 for (EntityProto entityProto
: res
.results()) {
83 entities
.add(EntityTranslator
.createFromPb(entityProto
, projections
));
90 public List
<Cursor
> getResultCursors() {
91 List
<Cursor
> cursors
= Lists
.newArrayListWithCapacity(res
.resultSize());
93 for (CompiledCursor compiledCursor
: res
.resultCompiledCursors()) {
94 cursors
.add(new Cursor(compiledCursor
.toByteString()));
96 cursors
.addAll(Collections
.<Cursor
>nCopies(res
.resultSize() - cursors
.size(), null));
101 public int numSkippedResults() {
102 return res
.getSkippedResults();
106 public Cursor
getSkippedResultsCursor() {
107 return res
.hasSkippedResultsCompiledCursor()
108 ?
new Cursor(res
.getSkippedResultsCompiledCursor().toByteString()) : null;
112 public boolean hasMoreResults() {
113 return res
.isMoreResults();
117 public Cursor
getEndCursor() {
118 return res
.hasCompiledCursor() ?
new Cursor(res
.getCompiledCursor().toByteString()) : null;
122 public List
<Index
> getIndexInfo(Collection
<Index
> monitoredIndexBuffer
) {
123 List
<Index
> indexList
= Lists
.newArrayListWithCapacity(res
.indexSize());
124 for (CompositeIndex indexProtobuf
: res
.indexs()) {
125 Index index
= IndexTranslator
.convertFromPb(indexProtobuf
);
126 indexList
.add(index
);
127 if (indexProtobuf
.isOnlyUseIfRequired()) {
128 monitoredIndexBuffer
.add(index
);