From aae6dc960f7c42830ceed23c65acaad3e457dcff Mon Sep 17 00:00:00 2001 From: Sebastian Schmidt Date: Thu, 22 Oct 2020 15:57:08 -0700 Subject: [PATCH] feat: add implicit ordering for startAt(DocumentReference) calls (#417) --- .../com/google/cloud/firestore/Query.java | 28 ++++++++++++++++--- .../com/google/cloud/firestore/QueryTest.java | 21 ++++++++++++++ .../cloud/firestore/it/ITSystemTest.java | 14 ++++++++++ 3 files changed, 59 insertions(+), 4 deletions(-) diff --git a/google-cloud-firestore/src/main/java/com/google/cloud/firestore/Query.java b/google-cloud-firestore/src/main/java/com/google/cloud/firestore/Query.java index 1d57f64aa..339f94b83 100644 --- a/google-cloud-firestore/src/main/java/com/google/cloud/firestore/Query.java +++ b/google-cloud-firestore/src/main/java/com/google/cloud/firestore/Query.java @@ -988,9 +988,14 @@ public Query startAt(@Nonnull DocumentSnapshot snapshot) { */ @Nonnull public Query startAt(Object... fieldValues) { - Cursor cursor = createCursor(options.getFieldOrders(), fieldValues, true); + ImmutableList fieldOrders = + fieldValues.length == 1 && fieldValues[0] instanceof DocumentReference + ? createImplicitOrderBy() + : options.getFieldOrders(); + Cursor cursor = createCursor(fieldOrders, fieldValues, true); Builder newOptions = options.toBuilder(); + newOptions.setFieldOrders(fieldOrders); newOptions.setStartCursor(cursor); return new Query(rpcContext, newOptions.build()); } @@ -1069,9 +1074,14 @@ public Query startAfter(@Nonnull DocumentSnapshot snapshot) { * @return The created Query. */ public Query startAfter(Object... fieldValues) { - Cursor cursor = createCursor(options.getFieldOrders(), fieldValues, false); + ImmutableList fieldOrders = + fieldValues.length == 1 && fieldValues[0] instanceof DocumentReference + ? createImplicitOrderBy() + : options.getFieldOrders(); + Cursor cursor = createCursor(fieldOrders, fieldValues, false); Builder newOptions = options.toBuilder(); + newOptions.setFieldOrders(fieldOrders); newOptions.setStartCursor(cursor); return new Query(rpcContext, newOptions.build()); } @@ -1105,9 +1115,14 @@ public Query endBefore(@Nonnull DocumentSnapshot snapshot) { */ @Nonnull public Query endBefore(Object... fieldValues) { - Cursor cursor = createCursor(options.getFieldOrders(), fieldValues, true); + ImmutableList fieldOrders = + fieldValues.length == 1 && fieldValues[0] instanceof DocumentReference + ? createImplicitOrderBy() + : options.getFieldOrders(); + Cursor cursor = createCursor(fieldOrders, fieldValues, true); Builder newOptions = options.toBuilder(); + newOptions.setFieldOrders(fieldOrders); newOptions.setEndCursor(cursor); return new Query(rpcContext, newOptions.build()); } @@ -1121,9 +1136,14 @@ public Query endBefore(Object... fieldValues) { */ @Nonnull public Query endAt(Object... fieldValues) { - Cursor cursor = createCursor(options.getFieldOrders(), fieldValues, false); + ImmutableList fieldOrders = + fieldValues.length == 1 && fieldValues[0] instanceof DocumentReference + ? createImplicitOrderBy() + : options.getFieldOrders(); + Cursor cursor = createCursor(fieldOrders, fieldValues, false); Builder newOptions = options.toBuilder(); + newOptions.setFieldOrders(fieldOrders); newOptions.setEndCursor(cursor); return new Query(rpcContext, newOptions.build()); } diff --git a/google-cloud-firestore/src/test/java/com/google/cloud/firestore/QueryTest.java b/google-cloud-firestore/src/test/java/com/google/cloud/firestore/QueryTest.java index 6c0d4e292..1045676df 100644 --- a/google-cloud-firestore/src/test/java/com/google/cloud/firestore/QueryTest.java +++ b/google-cloud-firestore/src/test/java/com/google/cloud/firestore/QueryTest.java @@ -18,6 +18,7 @@ import static com.google.cloud.firestore.LocalFirestoreHelper.COLLECTION_ID; import static com.google.cloud.firestore.LocalFirestoreHelper.DOCUMENT_NAME; +import static com.google.cloud.firestore.LocalFirestoreHelper.DOCUMENT_PATH; import static com.google.cloud.firestore.LocalFirestoreHelper.SINGLE_FIELD_SNAPSHOT; import static com.google.cloud.firestore.LocalFirestoreHelper.endAt; import static com.google.cloud.firestore.LocalFirestoreHelper.filter; @@ -598,6 +599,26 @@ public void withDocumentIdAndDocumentSnapshotCursor() { assertEquals(queryRequest, runQuery.getValue()); } + @Test + public void withDocumentReferenceCursor() { + doAnswer(queryResponse()) + .when(firestoreMock) + .streamRequest( + runQuery.capture(), + streamObserverCapture.capture(), + Matchers.any()); + + DocumentReference documentCursor = firestoreMock.document(DOCUMENT_PATH); + Value documentValue = reference(DOCUMENT_NAME); + + query.startAt(documentCursor).get(); + + RunQueryRequest queryRequest = + query(order("__name__", StructuredQuery.Direction.ASCENDING), startAt(documentValue, true)); + + assertEquals(queryRequest, runQuery.getValue()); + } + @Test public void withExtractedDirectionForDocumentSnapshotCursor() { doAnswer(queryResponse()) diff --git a/google-cloud-firestore/src/test/java/com/google/cloud/firestore/it/ITSystemTest.java b/google-cloud-firestore/src/test/java/com/google/cloud/firestore/it/ITSystemTest.java index c5d1bbc23..099ba73a7 100644 --- a/google-cloud-firestore/src/test/java/com/google/cloud/firestore/it/ITSystemTest.java +++ b/google-cloud-firestore/src/test/java/com/google/cloud/firestore/it/ITSystemTest.java @@ -554,6 +554,20 @@ public void startAfter() throws Exception { assertEquals(2L, querySnapshot.getDocuments().get(0).get("foo")); } + @Test + public void startAfterAddsAnImplicitOrderByForDocumentReferences() throws Exception { + DocumentReference doc1 = randomColl.document("doc1"); + DocumentReference doc2 = randomColl.document("doc2"); + + doc1.set(map("foo", 1)).get(); + doc2.set(map("foo", 1)).get(); + + QuerySnapshot querySnapshot = randomColl.startAfter(doc1).get().get(); + assertEquals(1, querySnapshot.size()); + Iterator documents = querySnapshot.iterator(); + assertEquals(doc2, documents.next().getReference()); + } + @Test public void endAt() throws Exception { addDocument("foo", 1);