diff --git a/google-cloud-clients/google-cloud-datastore/src/main/java/com/google/cloud/datastore/QueryResults.java b/google-cloud-clients/google-cloud-datastore/src/main/java/com/google/cloud/datastore/QueryResults.java index 8e4818ddc73e..8c03bda46bcc 100644 --- a/google-cloud-clients/google-cloud-datastore/src/main/java/com/google/cloud/datastore/QueryResults.java +++ b/google-cloud-clients/google-cloud-datastore/src/main/java/com/google/cloud/datastore/QueryResults.java @@ -55,4 +55,19 @@ public interface QueryResults extends Iterator { * } */ Cursor getCursorAfter(); + + /** + * Returns the number of results skipped, typically because of an offset. + * + *

A simple use case to count entities: + * + *

{@code
+   * Query query = Query.newKeyQueryBuilder().setOffset(Integer.MAX_VALUE).build();
+   * QueryResults result = datasore.datastore.run(query);
+   * if (!result.hasNext()) {
+   *  int numberOfEntities = result.getSkippedResults();
+   * }
+   * }
+ */ + int getSkippedResults(); } diff --git a/google-cloud-clients/google-cloud-datastore/src/main/java/com/google/cloud/datastore/QueryResultsImpl.java b/google-cloud-clients/google-cloud-datastore/src/main/java/com/google/cloud/datastore/QueryResultsImpl.java index a3156093dcc6..dde12d8a8dd8 100644 --- a/google-cloud-clients/google-cloud-datastore/src/main/java/com/google/cloud/datastore/QueryResultsImpl.java +++ b/google-cloud-clients/google-cloud-datastore/src/main/java/com/google/cloud/datastore/QueryResultsImpl.java @@ -114,4 +114,9 @@ public Class getResultClass() { public Cursor getCursorAfter() { return new Cursor(cursor); } + + @Override + public int getSkippedResults() { + return runQueryResponsePb.getBatch().getSkippedResults(); + } } diff --git a/google-cloud-clients/google-cloud-datastore/src/test/java/com/google/cloud/datastore/DatastoreTest.java b/google-cloud-clients/google-cloud-datastore/src/test/java/com/google/cloud/datastore/DatastoreTest.java index 329f4e7ea7d4..931da0dc0626 100644 --- a/google-cloud-clients/google-cloud-datastore/src/test/java/com/google/cloud/datastore/DatastoreTest.java +++ b/google-cloud-clients/google-cloud-datastore/src/test/java/com/google/cloud/datastore/DatastoreTest.java @@ -633,6 +633,13 @@ public void testQueryPaginationWithLimit() throws DatastoreException { EasyMock.verify(rpcFactoryMock, rpcMock); } + @Test + public void testRunKeyQueryWithOffset() { + Query query = Query.newKeyQueryBuilder().setOffset(Integer.MAX_VALUE).build(); + int numberOfEntities = datastore.run(query).getSkippedResults(); + assertEquals(2, numberOfEntities); + } + private List buildResponsesForQueryPaginationWithLimit() { Entity entity4 = Entity.newBuilder(KEY4).set("value", StringValue.of("value")).build(); Entity entity5 = Entity.newBuilder(KEY5).set("value", "value").build(); diff --git a/google-cloud-clients/google-cloud-datastore/src/test/java/com/google/cloud/datastore/it/ITDatastoreTest.java b/google-cloud-clients/google-cloud-datastore/src/test/java/com/google/cloud/datastore/it/ITDatastoreTest.java index dab2145f3e19..9f3bd9001019 100644 --- a/google-cloud-clients/google-cloud-datastore/src/test/java/com/google/cloud/datastore/it/ITDatastoreTest.java +++ b/google-cloud-clients/google-cloud-datastore/src/test/java/com/google/cloud/datastore/it/ITDatastoreTest.java @@ -851,4 +851,11 @@ public Integer run(DatastoreReaderWriter transaction) { assertEquals(3, ((DatastoreException) expected.getCause()).getCode()); } } + + @Test + public void testSkippedResults() { + Query query = Query.newKeyQueryBuilder().setOffset(Integer.MAX_VALUE).build(); + int numberOfEntities = DATASTORE.run(query).getSkippedResults(); + assertEquals(2, numberOfEntities); + } }