Skip to content

Commit 08bdae5

Browse files
---
yaml --- r: 12247 b: refs/heads/autosynth-os-login c: 411bc1c h: refs/heads/master i: 12245: bb63a60 12243: 77b7c03 12239: a1642ed
1 parent 9b8afb2 commit 08bdae5

9 files changed

Lines changed: 167 additions & 21 deletions

File tree

[refs]

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -136,7 +136,7 @@ refs/heads/autosynth-firestore: 92b27fbc8855c9902168695abb0a8f1f433b750b
136136
refs/heads/autosynth-iot: 9d732be07d99843d8cb53d34ec0837328a807fce
137137
refs/heads/autosynth-kms: dcc6e15d68759010c8735cc868135bd7e6c1cc5f
138138
refs/heads/autosynth-language: 8972866b016473559702424205ce5569de47b34d
139-
refs/heads/autosynth-os-login: a7703f2593ba312c0b2dde6fdfd4f5c764bb55ac
139+
refs/heads/autosynth-os-login: 411bc1c609d008dfa091558189b366ce2bb4dd56
140140
refs/heads/autosynth-redis: 1259b3a2193c6ee73b91064b5ebdedd6b51396bc
141141
refs/heads/autosynth-scheduler: 22f042c3461cee9346c46fdade5c8fad1a80f431
142142
refs/heads/autosynth-securitycenter: 1b300406bfc0f022d0ae98286c419d54d08d2ad4

branches/autosynth-os-login/google-cloud-clients/google-cloud-firestore/src/main/java/com/google/cloud/firestore/DocumentMask.java renamed to branches/autosynth-os-login/google-cloud-clients/google-cloud-firestore/src/main/java/com/google/cloud/firestore/FieldMask.java

Lines changed: 35 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -17,29 +17,57 @@
1717
package com.google.cloud.firestore;
1818

1919
import java.util.ArrayList;
20+
import java.util.Arrays;
2021
import java.util.Collection;
2122
import java.util.List;
2223
import java.util.Map;
2324
import java.util.SortedSet;
2425
import java.util.TreeSet;
26+
import javax.annotation.Nonnull;
2527

26-
/** A DocumentMask contains the field paths affected by an update. */
27-
final class DocumentMask {
28-
static final DocumentMask EMPTY_MASK = new DocumentMask(new TreeSet<FieldPath>());
28+
/** A FieldMask can be used to limit the number of fields returned by a `getAll()` call. */
29+
public final class FieldMask {
30+
static final FieldMask EMPTY_MASK = new FieldMask(new TreeSet<FieldPath>());
2931

3032
private final SortedSet<FieldPath> fieldPaths; // Sorted for testing.
3133

32-
DocumentMask(Collection<FieldPath> fieldPaths) {
34+
FieldMask(Collection<FieldPath> fieldPaths) {
3335
this(new TreeSet<>(fieldPaths));
3436
}
3537

36-
private DocumentMask(SortedSet<FieldPath> fieldPaths) {
38+
private FieldMask(SortedSet<FieldPath> fieldPaths) {
3739
this.fieldPaths = fieldPaths;
3840
}
3941

40-
static DocumentMask fromObject(Map<String, Object> values) {
42+
/**
43+
* Creates a FieldMask from the provided field paths.
44+
*
45+
* @param fieldPaths A list of field paths.
46+
* @return A {@code FieldMask} that describes a subset of fields.
47+
*/
48+
@Nonnull
49+
public static FieldMask of(String... fieldPaths) {
50+
List<FieldPath> paths = new ArrayList<>();
51+
for (String fieldPath : fieldPaths) {
52+
paths.add(FieldPath.fromDotSeparatedString(fieldPath));
53+
}
54+
return new FieldMask(paths);
55+
}
56+
57+
/**
58+
* Creates a FieldMask from the provided field paths.
59+
*
60+
* @param fieldPaths A list of field paths.
61+
* @return A {@code FieldMask} that describes a subset of fields.
62+
*/
63+
@Nonnull
64+
public static FieldMask of(FieldPath... fieldPaths) {
65+
return new FieldMask(Arrays.asList(fieldPaths));
66+
}
67+
68+
static FieldMask fromObject(Map<String, Object> values) {
4169
List<FieldPath> fieldPaths = extractFromMap(values, FieldPath.empty());
42-
return new DocumentMask(fieldPaths);
70+
return new FieldMask(fieldPaths);
4371
}
4472

4573
private static List<FieldPath> extractFromMap(Map<String, Object> values, FieldPath path) {

branches/autosynth-os-login/google-cloud-clients/google-cloud-firestore/src/main/java/com/google/cloud/firestore/Firestore.java

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
import com.google.cloud.Service;
2121
import java.util.List;
2222
import javax.annotation.Nonnull;
23+
import javax.annotation.Nullable;
2324

2425
/** Represents a Firestore Database and is the entry point for all Firestore operations */
2526
public interface Firestore extends Service<FirestoreOptions>, AutoCloseable {
@@ -93,7 +94,18 @@ <T> ApiFuture<T> runTransaction(
9394
* @param documentReferences List of Document References to fetch.
9495
*/
9596
@Nonnull
96-
ApiFuture<List<DocumentSnapshot>> getAll(final DocumentReference... documentReferences);
97+
ApiFuture<List<DocumentSnapshot>> getAll(@Nonnull DocumentReference... documentReferences);
98+
99+
/**
100+
* Retrieves multiple documents from Firestore, while optionally applying a field mask to reduce
101+
* the amount of data transmitted.
102+
*
103+
* @param documentReferences Array with Document References to fetch.
104+
* @param fieldMask If set, specifies the subset of fields to return.
105+
*/
106+
@Nonnull
107+
ApiFuture<List<DocumentSnapshot>> getAll(
108+
@Nonnull DocumentReference[] documentReferences, @Nullable FieldMask fieldMask);
97109

98110
/**
99111
* Gets a Firestore {@link WriteBatch} instance that can be used to combine multiple writes.

branches/autosynth-os-login/google-cloud-clients/google-cloud-firestore/src/main/java/com/google/cloud/firestore/FirestoreImpl.java

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -162,13 +162,23 @@ public Iterable<CollectionReference> getCollections() {
162162

163163
@Nonnull
164164
@Override
165-
public ApiFuture<List<DocumentSnapshot>> getAll(final DocumentReference... documentReferences) {
166-
return this.getAll(documentReferences, null);
165+
public ApiFuture<List<DocumentSnapshot>> getAll(
166+
@Nonnull DocumentReference... documentReferences) {
167+
return this.getAll(documentReferences, null, null);
168+
}
169+
170+
@Nonnull
171+
@Override
172+
public ApiFuture<List<DocumentSnapshot>> getAll(
173+
@Nonnull DocumentReference[] documentReferences, @Nullable FieldMask fieldMask) {
174+
return this.getAll(documentReferences, fieldMask, null);
167175
}
168176

169177
/** Internal getAll() method that accepts an optional transaction id. */
170178
ApiFuture<List<DocumentSnapshot>> getAll(
171-
final DocumentReference[] documentReferences, @Nullable ByteString transactionId) {
179+
final DocumentReference[] documentReferences,
180+
@Nullable FieldMask fieldMask,
181+
@Nullable ByteString transactionId) {
172182
final SettableApiFuture<List<DocumentSnapshot>> futureList = SettableApiFuture.create();
173183
final Map<DocumentReference, DocumentSnapshot> resultMap = new HashMap<>();
174184

@@ -238,6 +248,10 @@ public void onCompleted() {
238248
BatchGetDocumentsRequest.Builder request = BatchGetDocumentsRequest.newBuilder();
239249
request.setDatabase(getDatabaseName());
240250

251+
if (fieldMask != null) {
252+
request.setMask(fieldMask.toPb());
253+
}
254+
241255
if (transactionId != null) {
242256
request.setTransaction(transactionId);
243257
}

branches/autosynth-os-login/google-cloud-clients/google-cloud-firestore/src/main/java/com/google/cloud/firestore/Transaction.java

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -134,7 +134,7 @@ public ApiFuture<DocumentSnapshot> get(@Nonnull DocumentReference documentRef) {
134134
Preconditions.checkState(isEmpty(), READ_BEFORE_WRITE_ERROR_MSG);
135135

136136
return ApiFutures.transform(
137-
firestore.getAll(new DocumentReference[] {documentRef}, transactionId),
137+
firestore.getAll(new DocumentReference[] {documentRef}, /*fieldMask=*/ null, transactionId),
138138
new ApiFunction<List<DocumentSnapshot>, DocumentSnapshot>() {
139139
@Override
140140
public DocumentSnapshot apply(List<DocumentSnapshot> snapshots) {
@@ -150,10 +150,27 @@ public DocumentSnapshot apply(List<DocumentSnapshot> snapshots) {
150150
* @param documentReferences List of Document References to fetch.
151151
*/
152152
@Nonnull
153-
public ApiFuture<List<DocumentSnapshot>> getAll(final DocumentReference... documentReferences) {
153+
public ApiFuture<List<DocumentSnapshot>> getAll(
154+
@Nonnull DocumentReference... documentReferences) {
154155
Preconditions.checkState(isEmpty(), READ_BEFORE_WRITE_ERROR_MSG);
155156

156-
return firestore.getAll(documentReferences, transactionId);
157+
return firestore.getAll(documentReferences, /*fieldMask=*/ null, transactionId);
158+
}
159+
160+
/**
161+
* Retrieves multiple documents from Firestore, while optionally applying a field mask to reduce
162+
* the amount of data transmitted from the backend. Holds a pessimistic lock on all returned
163+
* documents.
164+
*
165+
* @param documentReferences Array with Document References to fetch.
166+
* @param fieldMask If set, specifies the subset of fields to return.
167+
*/
168+
@Nonnull
169+
public ApiFuture<List<DocumentSnapshot>> getAll(
170+
@Nonnull DocumentReference[] documentReferences, @Nullable FieldMask fieldMask) {
171+
Preconditions.checkState(isEmpty(), READ_BEFORE_WRITE_ERROR_MSG);
172+
173+
return firestore.getAll(documentReferences, fieldMask, transactionId);
157174
}
158175

159176
/**

branches/autosynth-os-login/google-cloud-clients/google-cloud-firestore/src/main/java/com/google/cloud/firestore/UpdateBuilder.java

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -243,17 +243,17 @@ private T performSet(
243243
DocumentSnapshot documentSnapshot =
244244
DocumentSnapshot.fromObject(
245245
firestore, documentReference, expandObject(documentData), options.getEncodingOptions());
246-
DocumentMask documentMask = DocumentMask.EMPTY_MASK;
246+
FieldMask documentMask = FieldMask.EMPTY_MASK;
247247
DocumentTransform documentTransform =
248248
DocumentTransform.fromFieldPathMap(documentReference, documentData);
249249

250250
if (options.isMerge()) {
251251
if (options.getFieldMask() != null) {
252252
List<FieldPath> fieldMask = new ArrayList<>(options.getFieldMask());
253253
fieldMask.removeAll(documentTransform.getFields());
254-
documentMask = new DocumentMask(fieldMask);
254+
documentMask = new FieldMask(fieldMask);
255255
} else {
256-
documentMask = DocumentMask.fromObject(fields);
256+
documentMask = FieldMask.fromObject(fields);
257257
}
258258
}
259259

@@ -528,14 +528,14 @@ public boolean allowTransform() {
528528
DocumentTransform documentTransform =
529529
DocumentTransform.fromFieldPathMap(documentReference, fields);
530530
fieldPaths.removeAll(documentTransform.getFields());
531-
DocumentMask documentMask = new DocumentMask(fieldPaths);
531+
FieldMask fieldMask = new FieldMask(fieldPaths);
532532

533533
Mutation mutation = addMutation();
534534
mutation.precondition = precondition.toPb();
535535

536-
if (!documentSnapshot.isEmpty() || !documentMask.isEmpty()) {
536+
if (!documentSnapshot.isEmpty() || !fieldMask.isEmpty()) {
537537
mutation.document = documentSnapshot.toPb();
538-
mutation.document.setUpdateMask(documentMask.toPb());
538+
mutation.document.setUpdateMask(fieldMask.toPb());
539539
}
540540

541541
if (!documentTransform.isEmpty()) {

branches/autosynth-os-login/google-cloud-clients/google-cloud-firestore/src/test/java/com/google/cloud/firestore/FirestoreTest.java

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,25 @@ public void getAll() throws Exception {
118118
assertEquals("doc3", snapshot.get(3).getId());
119119
}
120120

121+
@Test
122+
public void getAllWithFieldMask() throws Exception {
123+
doAnswer(getAllResponse(SINGLE_FIELD_PROTO))
124+
.when(firestoreMock)
125+
.streamRequest(
126+
getAllCapture.capture(),
127+
streamObserverCapture.capture(),
128+
Matchers.<ServerStreamingCallable>any());
129+
130+
DocumentReference doc1 = firestoreMock.document("coll/doc1");
131+
FieldMask fieldMask = FieldMask.of(FieldPath.of("foo", "bar"));
132+
133+
firestoreMock.getAll(new DocumentReference[]{doc1}, fieldMask).get();
134+
135+
BatchGetDocumentsRequest request = getAllCapture.getValue();
136+
assertEquals(1, request.getMask().getFieldPathsCount());
137+
assertEquals("foo.bar", request.getMask().getFieldPaths(0));
138+
}
139+
121140
@Test
122141
public void arrayUnionEquals() {
123142
FieldValue arrayUnion1 = FieldValue.arrayUnion("foo", "bar");

branches/autosynth-os-login/google-cloud-clients/google-cloud-firestore/src/test/java/com/google/cloud/firestore/TransactionTest.java

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,8 @@
4646
import com.google.api.gax.rpc.UnaryCallable;
4747
import com.google.cloud.Timestamp;
4848
import com.google.cloud.firestore.spi.v1beta1.FirestoreRpc;
49+
import com.google.firestore.v1beta1.BatchGetDocumentsRequest;
50+
import com.google.firestore.v1beta1.DocumentMask;
4951
import com.google.firestore.v1beta1.Write;
5052
import com.google.protobuf.ByteString;
5153
import com.google.protobuf.Message;
@@ -386,6 +388,50 @@ public List<DocumentSnapshot> updateCallback(Transaction transaction)
386388
assertEquals(commit(TRANSACTION_ID), requests.get(2));
387389
}
388390

391+
@Test
392+
public void getMultipleDocumentsWithFieldMask() throws Exception {
393+
doReturn(beginResponse())
394+
.doReturn(commitResponse(0, 0))
395+
.when(firestoreMock)
396+
.sendRequest(requestCapture.capture(), Matchers.<UnaryCallable<Message, Message>>any());
397+
398+
doAnswer(getAllResponse(SINGLE_FIELD_PROTO))
399+
.when(firestoreMock)
400+
.streamRequest(
401+
requestCapture.capture(),
402+
streamObserverCapture.capture(),
403+
Matchers.<ServerStreamingCallable>any());
404+
405+
final DocumentReference doc1 = firestoreMock.document("coll/doc1");
406+
final FieldMask fieldMask = FieldMask.of(FieldPath.of("foo", "bar"));
407+
408+
ApiFuture<List<DocumentSnapshot>> transaction =
409+
firestoreMock.runTransaction(
410+
new Transaction.Function<List<DocumentSnapshot>>() {
411+
@Override
412+
public List<DocumentSnapshot> updateCallback(Transaction transaction)
413+
throws ExecutionException, InterruptedException {
414+
return transaction.getAll(new DocumentReference[] {doc1}, fieldMask).get();
415+
}
416+
},
417+
options);
418+
transaction.get();
419+
420+
List<Message> requests = requestCapture.getAllValues();
421+
assertEquals(3, requests.size());
422+
423+
assertEquals(begin(), requests.get(0));
424+
BatchGetDocumentsRequest expectedGetAll =
425+
getAll(TRANSACTION_ID, doc1.getResourcePath().toString());
426+
expectedGetAll =
427+
expectedGetAll
428+
.toBuilder()
429+
.setMask(DocumentMask.newBuilder().addFieldPaths("foo.bar"))
430+
.build();
431+
assertEquals(expectedGetAll, requests.get(1));
432+
assertEquals(commit(TRANSACTION_ID), requests.get(2));
433+
}
434+
389435
@Test
390436
public void getQuery() throws Exception {
391437
doReturn(beginResponse())

branches/autosynth-os-login/google-cloud-clients/google-cloud-firestore/src/test/java/com/google/cloud/firestore/it/ITSystemTest.java

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232
import com.google.cloud.firestore.DocumentReference;
3333
import com.google.cloud.firestore.DocumentSnapshot;
3434
import com.google.cloud.firestore.EventListener;
35+
import com.google.cloud.firestore.FieldMask;
3536
import com.google.cloud.firestore.FieldValue;
3637
import com.google.cloud.firestore.Firestore;
3738
import com.google.cloud.firestore.FirestoreException;
@@ -122,6 +123,15 @@ public void getAll() throws Exception {
122123
assertEquals(SINGLE_FIELD_OBJECT, documentSnapshots.get(1).toObject(SingleField.class));
123124
}
124125

126+
@Test
127+
public void getAllWithFieldMask() throws Exception {
128+
DocumentReference ref = randomColl.document("doc1");
129+
ref.set(ALL_SUPPORTED_TYPES_MAP).get();
130+
List<DocumentSnapshot> documentSnapshots =
131+
firestore.getAll(new DocumentReference[] {ref}, FieldMask.of("foo")).get();
132+
assertEquals(map("foo", "bar"), documentSnapshots.get(0).getData());
133+
}
134+
125135
@Test
126136
public void addDocument() throws Exception {
127137
DocumentReference documentReference = randomColl.add(SINGLE_FIELD_MAP).get();

0 commit comments

Comments
 (0)