use of com.google.firebase.firestore.model.MutableDocument in project firebase-android-sdk by firebase.
the class WatchChangeAggregator method handleExistenceFilter.
/**
* Handles existence filters and synthesizes deletes for filter mismatches. Targets that are
* invalidated by filter mismatches are added to `pendingTargetResets`.
*/
public void handleExistenceFilter(ExistenceFilterWatchChange watchChange) {
int targetId = watchChange.getTargetId();
int expectedCount = watchChange.getExistenceFilter().getCount();
TargetData targetData = queryDataForActiveTarget(targetId);
if (targetData != null) {
Target target = targetData.getTarget();
if (target.isDocumentQuery()) {
if (expectedCount == 0) {
// The existence filter told us the document does not exist. We deduce that this document
// does not exist and apply a deleted document to our updates. Without applying this
// deleted document there might be another query that will raise this document as part of
// a snapshot until it is resolved, essentially exposing inconsistency between queries.
DocumentKey key = DocumentKey.fromPath(target.getPath());
MutableDocument result = MutableDocument.newNoDocument(key, SnapshotVersion.NONE);
removeDocumentFromTarget(targetId, key, result);
} else {
hardAssert(expectedCount == 1, "Single document existence filter with count: %d", expectedCount);
}
} else {
long currentSize = getCurrentDocumentCountForTarget(targetId);
if (currentSize != expectedCount) {
// Existence filter mismatch: We reset the mapping and raise a new snapshot with
// `isFromCache:true`.
resetTarget(targetId);
pendingTargetResets.add(targetId);
}
}
}
}
use of com.google.firebase.firestore.model.MutableDocument in project firebase-android-sdk by firebase.
the class WatchChangeAggregator method handleDocumentChange.
/**
* Processes and adds the DocumentWatchChange to the current set of changes.
*/
public void handleDocumentChange(DocumentChange documentChange) {
MutableDocument document = documentChange.getNewDocument();
DocumentKey documentKey = documentChange.getDocumentKey();
for (int targetId : documentChange.getUpdatedTargetIds()) {
if (document != null && document.isFoundDocument()) {
addDocumentToTarget(targetId, document);
} else {
removeDocumentFromTarget(targetId, documentKey, document);
}
}
for (int targetId : documentChange.getRemovedTargetIds()) {
removeDocumentFromTarget(targetId, documentKey, documentChange.getNewDocument());
}
}
use of com.google.firebase.firestore.model.MutableDocument in project firebase-android-sdk by firebase.
the class MutationBatch method applyToLocalDocumentSet.
/**
* Computes the local view for all provided documents given the mutations in this batch. Returns a
* {@code DocumentKey} to {@code Mutation} map which can be used to replace all the mutation
* applications.
*/
public Map<DocumentKey, Mutation> applyToLocalDocumentSet(Map<DocumentKey, OverlayedDocument> documentMap, Set<DocumentKey> documentsWithoutRemoteVersion) {
// TODO(mrschmidt): This implementation is O(n^2). If we iterate through the mutations first
// (as done in `applyToLocalView(MutableDocument d)`), we can reduce the complexity to
// O(n).
Map<DocumentKey, Mutation> overlays = new HashMap<>();
for (DocumentKey key : getKeys()) {
// TODO(mutabledocuments): This method should take a map of MutableDocuments and we should
// remove this cast.
MutableDocument document = (MutableDocument) documentMap.get(key).getDocument();
FieldMask mutatedFields = applyToLocalView(document, documentMap.get(key).getMutatedFields());
// Set mutationFields to null if the document is only from local mutations, this creates
// a Set(or Delete) mutation, instead of trying to create a patch mutation as the overlay.
mutatedFields = documentsWithoutRemoteVersion.contains(key) ? null : mutatedFields;
Mutation overlay = Mutation.calculateOverlayMutation(document, mutatedFields);
if (overlay != null) {
overlays.put(key, overlay);
}
if (!document.isValidDocument()) {
document.convertToNoDocument(SnapshotVersion.NONE);
}
}
return overlays;
}
use of com.google.firebase.firestore.model.MutableDocument in project firebase-android-sdk by firebase.
the class TestUtil method querySnapshot.
/**
* A convenience method for creating a particular query snapshot for tests.
*
* @param path To be used in constructing the query.
* @param oldDocs Provides the prior set of documents in the QuerySnapshot. Each entry maps to a
* document, with the key being the document id, and the value being the document contents.
* @param docsToAdd Specifies data to be added into the query snapshot as of now. Each entry maps
* to a document, with the key being the document id, and the value being the document
* contents.
* @param isFromCache Whether the query snapshot is cache result.
* @return A query snapshot that consists of both sets of documents.
*/
public static QuerySnapshot querySnapshot(String path, Map<String, ObjectValue> oldDocs, Map<String, ObjectValue> docsToAdd, boolean hasPendingWrites, boolean isFromCache) {
DocumentSet oldDocuments = docSet(Document.KEY_COMPARATOR);
ImmutableSortedSet<DocumentKey> mutatedKeys = DocumentKey.emptyKeySet();
for (Map.Entry<String, ObjectValue> pair : oldDocs.entrySet()) {
String docKey = path + "/" + pair.getKey();
MutableDocument doc = doc(docKey, 1L, pair.getValue());
if (hasPendingWrites) {
doc.setHasCommittedMutations();
mutatedKeys = mutatedKeys.insert(key(docKey));
}
oldDocuments = oldDocuments.add(doc);
}
DocumentSet newDocuments = docSet(Document.KEY_COMPARATOR);
List<DocumentViewChange> documentChanges = new ArrayList<>();
for (Map.Entry<String, ObjectValue> pair : docsToAdd.entrySet()) {
String docKey = path + "/" + pair.getKey();
MutableDocument docToAdd = doc(docKey, 1L, pair.getValue());
if (hasPendingWrites) {
docToAdd.setHasCommittedMutations();
mutatedKeys = mutatedKeys.insert(key(docKey));
}
newDocuments = newDocuments.add(docToAdd);
documentChanges.add(DocumentViewChange.create(Type.ADDED, docToAdd));
}
ViewSnapshot viewSnapshot = new ViewSnapshot(com.google.firebase.firestore.testutil.TestUtil.query(path), newDocuments, oldDocuments, documentChanges, isFromCache, mutatedKeys, /* didSyncStateChange= */
true, /* excludesMetadataChanges= */
false);
return new QuerySnapshot(query(path), viewSnapshot, FIRESTORE);
}
use of com.google.firebase.firestore.model.MutableDocument in project firebase-android-sdk by firebase.
the class DocumentChangeTest method validatePositions.
private static void validatePositions(com.google.firebase.firestore.core.Query query, Collection<MutableDocument> initialDocsList, Collection<MutableDocument> addedList, Collection<MutableDocument> modifiedList, Collection<MutableDocument> removedList) {
ImmutableSortedMap<DocumentKey, Document> initialDocs = docUpdates(initialDocsList.toArray(new MutableDocument[] {}));
ImmutableSortedMap<DocumentKey, Document> updates = emptyDocumentMap();
for (MutableDocument doc : addedList) {
updates = updates.insert(doc.getKey(), doc);
}
for (MutableDocument doc : modifiedList) {
updates = updates.insert(doc.getKey(), doc);
}
for (MutableDocument doc : removedList) {
updates = updates.insert(doc.getKey(), doc);
}
View view = new View(query, DocumentKey.emptyKeySet());
View.DocumentChanges initialChanges = view.computeDocChanges(initialDocs);
TargetChange initialTargetChange = ackTarget(initialDocsList.toArray(new MutableDocument[] {}));
ViewSnapshot initialSnapshot = view.applyChanges(initialChanges, initialTargetChange).getSnapshot();
View.DocumentChanges updateChanges = view.computeDocChanges(updates);
TargetChange updateTargetChange = targetChange(ByteString.EMPTY, true, addedList, modifiedList, removedList);
ViewSnapshot updatedSnapshot = view.applyChanges(updateChanges, updateTargetChange).getSnapshot();
if (updatedSnapshot == null) {
// Nothing changed, no positions to verify
return;
}
List<Document> expected = new ArrayList<>(updatedSnapshot.getDocuments().toList());
List<Document> actual = new ArrayList<>(initialSnapshot.getDocuments().toList());
FirebaseFirestore firestore = mock(FirebaseFirestore.class);
List<DocumentChange> changes = DocumentChange.changesFromSnapshot(firestore, MetadataChanges.EXCLUDE, updatedSnapshot);
for (DocumentChange change : changes) {
if (change.getType() != Type.ADDED) {
actual.remove(change.getOldIndex());
}
if (change.getType() != Type.REMOVED) {
actual.add(change.getNewIndex(), change.getDocument().getDocument());
}
}
assertEquals(expected, actual);
}
Aggregations