Search in sources :

Example 86 with MutableDocument

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);
            }
        }
    }
}
Also used : TargetData(com.google.firebase.firestore.local.TargetData) Target(com.google.firebase.firestore.core.Target) DocumentKey(com.google.firebase.firestore.model.DocumentKey) MutableDocument(com.google.firebase.firestore.model.MutableDocument)

Example 87 with MutableDocument

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());
    }
}
Also used : MutableDocument(com.google.firebase.firestore.model.MutableDocument) DocumentKey(com.google.firebase.firestore.model.DocumentKey)

Example 88 with MutableDocument

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;
}
Also used : HashMap(java.util.HashMap) DocumentKey(com.google.firebase.firestore.model.DocumentKey) MutableDocument(com.google.firebase.firestore.model.MutableDocument)

Example 89 with MutableDocument

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);
}
Also used : MutableDocument(com.google.firebase.firestore.model.MutableDocument) ArrayList(java.util.ArrayList) ViewSnapshot(com.google.firebase.firestore.core.ViewSnapshot) ObjectValue(com.google.firebase.firestore.model.ObjectValue) DocumentViewChange(com.google.firebase.firestore.core.DocumentViewChange) DocumentKey(com.google.firebase.firestore.model.DocumentKey) DocumentSet(com.google.firebase.firestore.model.DocumentSet) Map(java.util.Map)

Example 90 with MutableDocument

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);
}
Also used : MutableDocument(com.google.firebase.firestore.model.MutableDocument) ArrayList(java.util.ArrayList) Document(com.google.firebase.firestore.model.Document) MutableDocument(com.google.firebase.firestore.model.MutableDocument) View(com.google.firebase.firestore.core.View) ViewSnapshot(com.google.firebase.firestore.core.ViewSnapshot) TargetChange(com.google.firebase.firestore.remote.TargetChange) DocumentKey(com.google.firebase.firestore.model.DocumentKey)

Aggregations

MutableDocument (com.google.firebase.firestore.model.MutableDocument)166 Test (org.junit.Test)125 DocumentKey (com.google.firebase.firestore.model.DocumentKey)43 Mutation.calculateOverlayMutation (com.google.firebase.firestore.model.mutation.Mutation.calculateOverlayMutation)30 TestUtil.deleteMutation (com.google.firebase.firestore.testutil.TestUtil.deleteMutation)30 TestUtil.mergeMutation (com.google.firebase.firestore.testutil.TestUtil.mergeMutation)30 TestUtil.patchMutation (com.google.firebase.firestore.testutil.TestUtil.patchMutation)30 TestUtil.setMutation (com.google.firebase.firestore.testutil.TestUtil.setMutation)30 HashMap (java.util.HashMap)22 TestUtil.wrapObject (com.google.firebase.firestore.testutil.TestUtil.wrapObject)18 ArrayList (java.util.ArrayList)18 TargetData (com.google.firebase.firestore.local.TargetData)15 WatchTargetChange (com.google.firebase.firestore.remote.WatchChange.WatchTargetChange)14 DocumentChange (com.google.firebase.firestore.remote.WatchChange.DocumentChange)13 ResourcePath (com.google.firebase.firestore.model.ResourcePath)12 Query (com.google.firebase.firestore.core.Query)10 Map (java.util.Map)10 SnapshotVersion (com.google.firebase.firestore.model.SnapshotVersion)8 Document (com.google.firebase.firestore.model.Document)7 Timestamp (com.google.firebase.Timestamp)6