Skip to content

Commit 1d4f109

Browse files
committed
Enable support for structured ProjectionEntity queries
1 parent 6a3bf89 commit 1d4f109

File tree

3 files changed

+43
-28
lines changed

3 files changed

+43
-28
lines changed

datastore/src/main/java/io/spine/server/storage/datastore/DatastoreWrapper.java

Lines changed: 20 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -266,16 +266,18 @@ public Entity read(Key key) {
266266
*
267267
* @param query
268268
* {@link Query} to execute upon the Datastore
269+
* @param <E>
270+
* the type of queried entities
269271
* @return results fo the query as a lazily evaluated {@link Iterator}
270272
* @see DatastoreReader#run(Query)
271273
*/
272-
public DsQueryIterator read(StructuredQuery<Entity> query) {
274+
public <E extends BaseEntity<?>> DsQueryIterator<E> read(StructuredQuery<E> query) {
273275
Namespace namespace = currentNamespace();
274-
StructuredQuery<Entity> queryWithNamespace =
276+
StructuredQuery<E> queryWithNamespace =
275277
query.toBuilder()
276278
.setNamespace(namespace.getValue())
277279
.build();
278-
DsQueryIterator result = new DsQueryIterator(queryWithNamespace, actor);
280+
DsQueryIterator<E> result = new DsQueryIterator<>(queryWithNamespace, actor);
279281
return result;
280282
}
281283

@@ -292,11 +294,13 @@ public DsQueryIterator read(StructuredQuery<Entity> query) {
292294
* {@link Query} to execute upon the Datastore
293295
* @param pageSize
294296
* a non-zero number of elements to be returned per a single read from Datastore
297+
* @param <E>
298+
* the type of queried entities
295299
* @return results fo the query as a lazily evaluated {@link Iterator}
296300
* @throws IllegalArgumentException
297301
* if the provided {@linkplain StructuredQuery#getLimit() query includes a limit}
298302
*/
299-
Iterator<Entity> readAll(StructuredQuery<Entity> query, int pageSize) {
303+
<E extends BaseEntity<?>> Iterator<E> readAll(StructuredQuery<E> query, int pageSize) {
300304
return readAllPageByPage(query, pageSize);
301305
}
302306

@@ -311,11 +315,13 @@ Iterator<Entity> readAll(StructuredQuery<Entity> query, int pageSize) {
311315
*
312316
* @param query
313317
* {@link Query} to execute upon the Datastore
318+
* @param <E>
319+
* the type of queried entities
314320
* @return results fo the query as a lazily evaluated {@link Iterator}
315321
* @throws IllegalArgumentException
316322
* if the provided {@linkplain StructuredQuery#getLimit() query includes a limit}
317323
*/
318-
Iterator<Entity> readAll(StructuredQuery<Entity> query) {
324+
<E extends BaseEntity<?>> Iterator<E> readAll(StructuredQuery<E> query) {
319325
return readAllPageByPage(query, null);
320326
}
321327

@@ -333,26 +339,29 @@ Iterator<Entity> readAll(StructuredQuery<Entity> query) {
333339
* @param pageSize
334340
* a non-zero number of elements to be returned per a single read from Datastore;
335341
* if {@code null} the page size will be dictated by the Datastore
342+
* @param <E>
343+
* the type of queried entities
336344
* @return results fo the query as a lazily evaluated {@link Iterator}
337345
* @throws IllegalArgumentException
338346
* if the provided {@linkplain StructuredQuery#getLimit() query includes a limit} or
339347
* the provided {@code batchSize} is 0
340348
*/
341-
private Iterator<Entity> readAllPageByPage(StructuredQuery<Entity> query,
342-
@Nullable Integer pageSize) {
349+
@SuppressWarnings("unchecked") // Checked logically.
350+
private <E extends BaseEntity<?>> Iterator<E>
351+
readAllPageByPage(StructuredQuery<E> query, @Nullable Integer pageSize) {
343352
checkArgument(query.getLimit() == null,
344353
"Cannot limit a number of entities for \"read all\" operation.");
345354
checkArgument(pageSize == null || pageSize != 0,
346355
"The size of a single read operation cannot be 0.");
347356

348-
StructuredQuery<Entity> limitedQuery = limit(query, pageSize);
349-
return stream(new DsQueryPageIterator(limitedQuery, this))
357+
StructuredQuery<E> limitedQuery = limit(query, pageSize);
358+
return stream(new DsQueryPageIterator<>(limitedQuery, this))
350359
.flatMap(Streams::stream)
351360
.iterator();
352361
}
353362

354-
private static StructuredQuery<Entity> limit(StructuredQuery<Entity> query,
355-
@Nullable Integer batchSize) {
363+
private static <E extends BaseEntity<?>> StructuredQuery<E>
364+
limit(StructuredQuery<E> query, @Nullable Integer batchSize) {
356365
return batchSize == null
357366
? query
358367
: query.toBuilder()

datastore/src/main/java/io/spine/server/storage/datastore/DsQueryIterator.java

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -20,9 +20,9 @@
2020

2121
package io.spine.server.storage.datastore;
2222

23+
import com.google.cloud.datastore.BaseEntity;
2324
import com.google.cloud.datastore.Cursor;
2425
import com.google.cloud.datastore.DatastoreReaderWriter;
25-
import com.google.cloud.datastore.Entity;
2626
import com.google.cloud.datastore.QueryResults;
2727
import com.google.cloud.datastore.StructuredQuery;
2828
import com.google.common.collect.UnmodifiableIterator;
@@ -44,18 +44,21 @@
4444
* <p>A call to {@link #next() next()} may not cause a Datastore query.
4545
*
4646
* <p>The {@link #remove() remove()} method throws an {@link UnsupportedOperationException}.
47+
*
48+
* @param <E>
49+
* the type of queried entities
4750
*/
48-
final class DsQueryIterator extends UnmodifiableIterator<Entity> {
51+
final class DsQueryIterator<E extends BaseEntity<?>> extends UnmodifiableIterator<E> {
4952

50-
private final StructuredQuery<Entity> query;
51-
private final QueryResults<Entity> currentPage;
53+
private final StructuredQuery<E> query;
54+
private final QueryResults<E> currentPage;
5255

5356
private final Integer limit;
5457
private int readCount = 0;
5558

5659
private boolean terminated;
5760

58-
DsQueryIterator(StructuredQuery<Entity> query, DatastoreReaderWriter datastore) {
61+
DsQueryIterator(StructuredQuery<E> query, DatastoreReaderWriter datastore) {
5962
super();
6063
this.query = query;
6164
this.limit = query.getLimit();
@@ -92,21 +95,21 @@ private void terminate() {
9295
* <p>The query is built utilizing the {@linkplain Cursor Datastore Cursor} from the current
9396
* query results.
9497
*/
95-
StructuredQuery<Entity> nextPageQuery() {
98+
StructuredQuery<E> nextPageQuery() {
9699
Cursor cursorAfter = currentPage.getCursorAfter();
97-
StructuredQuery<Entity> queryForMoreResults =
100+
StructuredQuery<E> queryForMoreResults =
98101
query.toBuilder()
99102
.setStartCursor(cursorAfter)
100103
.build();
101104
return queryForMoreResults;
102105
}
103106

104107
@Override
105-
public Entity next() {
108+
public E next() {
106109
if (!hasNext()) {
107110
throw new NoSuchElementException("The query results Iterator is empty.");
108111
}
109-
Entity result = currentPage.next();
112+
E result = currentPage.next();
110113
readCount++;
111114
return result;
112115
}

datastore/src/main/java/io/spine/server/storage/datastore/DsQueryPageIterator.java

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020

2121
package io.spine.server.storage.datastore;
2222

23-
import com.google.cloud.datastore.Entity;
23+
import com.google.cloud.datastore.BaseEntity;
2424
import com.google.cloud.datastore.StructuredQuery;
2525
import org.checkerframework.checker.nullness.qual.Nullable;
2626

@@ -39,15 +39,18 @@
3939
*
4040
* <p>If the limit is not specified, then the page size is determined by the Datastore
4141
* query restrictions.
42+
*
43+
* @param <E>
44+
* the type of queried entities
4245
*/
43-
final class DsQueryPageIterator implements Iterator<DsQueryIterator> {
46+
final class DsQueryPageIterator<E extends BaseEntity<?>> implements Iterator<DsQueryIterator> {
4447

4548
private final DatastoreWrapper datastore;
4649

47-
private DsQueryIterator currentPage;
48-
private @Nullable DsQueryIterator nextPage;
50+
private DsQueryIterator<E> currentPage;
51+
private @Nullable DsQueryIterator<E> nextPage;
4952

50-
DsQueryPageIterator(StructuredQuery<Entity> query, DatastoreWrapper datastore) {
53+
DsQueryPageIterator(StructuredQuery<E> query, DatastoreWrapper datastore) {
5154
this.datastore = datastore;
5255
this.currentPage = datastore.read(query);
5356
}
@@ -61,7 +64,7 @@ public boolean hasNext() {
6164
}
6265

6366
@Override
64-
public DsQueryIterator next() {
67+
public DsQueryIterator<E> next() {
6568
if (nextPage == null) {
6669
currentPage = loadNextPage();
6770
} else {
@@ -74,8 +77,8 @@ public DsQueryIterator next() {
7477
return currentPage;
7578
}
7679

77-
private DsQueryIterator loadNextPage() {
78-
StructuredQuery<Entity> nextPageQuery = currentPage.nextPageQuery();
80+
private DsQueryIterator<E> loadNextPage() {
81+
StructuredQuery<E> nextPageQuery = currentPage.nextPageQuery();
7982
return datastore.read(nextPageQuery);
8083
}
8184
}

0 commit comments

Comments
 (0)