Search in sources :

Example 81 with DocumentKey

use of com.google.firebase.firestore.model.DocumentKey in project firebase-android-sdk by firebase.

the class KeyFieldInFilter method extractDocumentKeysFromArrayValue.

static List<DocumentKey> extractDocumentKeysFromArrayValue(Operator operator, Value value) {
    hardAssert(operator == Operator.IN || operator == Operator.NOT_IN, "extractDocumentKeysFromArrayValue requires IN or NOT_IN operators");
    hardAssert(Values.isArray(value), "KeyFieldInFilter/KeyFieldNotInFilter expects an ArrayValue");
    List<DocumentKey> keys = new ArrayList<>();
    for (Value element : value.getArrayValue().getValuesList()) {
        hardAssert(Values.isReferenceValue(element), "Comparing on key with " + operator.toString() + ", but an array value was not a ReferenceValue");
        keys.add(DocumentKey.fromName(element.getReferenceValue()));
    }
    return keys;
}
Also used : DocumentKey(com.google.firebase.firestore.model.DocumentKey) ArrayList(java.util.ArrayList) Value(com.google.firestore.v1.Value)

Example 82 with DocumentKey

use of com.google.firebase.firestore.model.DocumentKey in project firebase-android-sdk by firebase.

the class DocumentViewChangeSet method addChange.

public void addChange(DocumentViewChange change) {
    DocumentKey key = change.getDocument().getKey();
    DocumentViewChange old = changes.get(key);
    if (old == null) {
        changes.put(key, change);
        return;
    }
    Type oldType = old.getType();
    Type newType = change.getType();
    if (newType != Type.ADDED && oldType == Type.METADATA) {
        changes.put(key, change);
    } else if (newType == Type.METADATA && oldType != Type.REMOVED) {
        DocumentViewChange newChange = DocumentViewChange.create(oldType, change.getDocument());
        changes.put(key, newChange);
    } else if (newType == Type.MODIFIED && oldType == Type.MODIFIED) {
        DocumentViewChange newChange = DocumentViewChange.create(Type.MODIFIED, change.getDocument());
        changes.put(key, newChange);
    } else if (newType == Type.MODIFIED && oldType == Type.ADDED) {
        DocumentViewChange newChange = DocumentViewChange.create(Type.ADDED, change.getDocument());
        changes.put(key, newChange);
    } else if (newType == Type.REMOVED && oldType == Type.ADDED) {
        changes.remove(key);
    } else if (newType == Type.REMOVED && oldType == Type.MODIFIED) {
        DocumentViewChange newChange = DocumentViewChange.create(Type.REMOVED, old.getDocument());
        changes.put(key, newChange);
    } else if (newType == Type.ADDED && oldType == Type.REMOVED) {
        DocumentViewChange newChange = DocumentViewChange.create(Type.MODIFIED, change.getDocument());
        changes.put(key, newChange);
    } else {
        // Removed -> Metadata
        throw fail("Unsupported combination of changes %s after %s", newType, oldType);
    }
}
Also used : Type(com.google.firebase.firestore.core.DocumentViewChange.Type) DocumentKey(com.google.firebase.firestore.model.DocumentKey)

Example 83 with DocumentKey

use of com.google.firebase.firestore.model.DocumentKey in project firebase-android-sdk by firebase.

the class RemoteSerializer method decodeWatchChange.

// Watch changes
public WatchChange decodeWatchChange(ListenResponse protoChange) {
    WatchChange watchChange;
    switch(protoChange.getResponseTypeCase()) {
        case TARGET_CHANGE:
            com.google.firestore.v1.TargetChange targetChange = protoChange.getTargetChange();
            WatchTargetChangeType changeType;
            Status cause = null;
            switch(targetChange.getTargetChangeType()) {
                case NO_CHANGE:
                    changeType = WatchTargetChangeType.NoChange;
                    break;
                case ADD:
                    changeType = WatchTargetChangeType.Added;
                    break;
                case REMOVE:
                    changeType = WatchTargetChangeType.Removed;
                    cause = fromStatus(targetChange.getCause());
                    break;
                case CURRENT:
                    changeType = WatchTargetChangeType.Current;
                    break;
                case RESET:
                    changeType = WatchTargetChangeType.Reset;
                    break;
                case UNRECOGNIZED:
                default:
                    throw new IllegalArgumentException("Unknown target change type");
            }
            watchChange = new WatchTargetChange(changeType, targetChange.getTargetIdsList(), targetChange.getResumeToken(), cause);
            break;
        case DOCUMENT_CHANGE:
            DocumentChange docChange = protoChange.getDocumentChange();
            List<Integer> added = docChange.getTargetIdsList();
            List<Integer> removed = docChange.getRemovedTargetIdsList();
            DocumentKey key = decodeKey(docChange.getDocument().getName());
            SnapshotVersion version = decodeVersion(docChange.getDocument().getUpdateTime());
            hardAssert(!version.equals(SnapshotVersion.NONE), "Got a document change without an update time");
            ObjectValue data = ObjectValue.fromMap(docChange.getDocument().getFieldsMap());
            MutableDocument document = MutableDocument.newFoundDocument(key, version, data);
            watchChange = new WatchChange.DocumentChange(added, removed, document.getKey(), document);
            break;
        case DOCUMENT_DELETE:
            DocumentDelete docDelete = protoChange.getDocumentDelete();
            removed = docDelete.getRemovedTargetIdsList();
            key = decodeKey(docDelete.getDocument());
            // Note that version might be unset in which case we use SnapshotVersion.NONE
            version = decodeVersion(docDelete.getReadTime());
            MutableDocument doc = MutableDocument.newNoDocument(key, version);
            watchChange = new WatchChange.DocumentChange(Collections.emptyList(), removed, doc.getKey(), doc);
            break;
        case DOCUMENT_REMOVE:
            DocumentRemove docRemove = protoChange.getDocumentRemove();
            removed = docRemove.getRemovedTargetIdsList();
            key = decodeKey(docRemove.getDocument());
            watchChange = new WatchChange.DocumentChange(Collections.emptyList(), removed, key, null);
            break;
        case FILTER:
            com.google.firestore.v1.ExistenceFilter protoFilter = protoChange.getFilter();
            // TODO: implement existence filter parsing (see b/33076578)
            ExistenceFilter filter = new ExistenceFilter(protoFilter.getCount());
            int targetId = protoFilter.getTargetId();
            watchChange = new ExistenceFilterWatchChange(targetId, filter);
            break;
        case RESPONSETYPE_NOT_SET:
        default:
            throw new IllegalArgumentException("Unknown change type set");
    }
    return watchChange;
}
Also used : Status(io.grpc.Status) DocumentRemove(com.google.firestore.v1.DocumentRemove) MutableDocument(com.google.firebase.firestore.model.MutableDocument) WatchTargetChangeType(com.google.firebase.firestore.remote.WatchChange.WatchTargetChangeType) DocumentChange(com.google.firestore.v1.DocumentChange) WatchTargetChange(com.google.firebase.firestore.remote.WatchChange.WatchTargetChange) DocumentDelete(com.google.firestore.v1.DocumentDelete) ObjectValue(com.google.firebase.firestore.model.ObjectValue) SnapshotVersion(com.google.firebase.firestore.model.SnapshotVersion) ExistenceFilterWatchChange(com.google.firebase.firestore.remote.WatchChange.ExistenceFilterWatchChange) DocumentKey(com.google.firebase.firestore.model.DocumentKey) ExistenceFilterWatchChange(com.google.firebase.firestore.remote.WatchChange.ExistenceFilterWatchChange)

Example 84 with DocumentKey

use of com.google.firebase.firestore.model.DocumentKey in project firebase-android-sdk by firebase.

the class RemoteSerializer method decodeFoundDocument.

private MutableDocument decodeFoundDocument(BatchGetDocumentsResponse response) {
    Assert.hardAssert(response.getResultCase().equals(ResultCase.FOUND), "Tried to deserialize a found document from a missing document.");
    DocumentKey key = decodeKey(response.getFound().getName());
    ObjectValue value = ObjectValue.fromMap(response.getFound().getFieldsMap());
    SnapshotVersion version = decodeVersion(response.getFound().getUpdateTime());
    hardAssert(!version.equals(SnapshotVersion.NONE), "Got a document response with no snapshot version");
    return MutableDocument.newFoundDocument(key, version, value);
}
Also used : ObjectValue(com.google.firebase.firestore.model.ObjectValue) SnapshotVersion(com.google.firebase.firestore.model.SnapshotVersion) DocumentKey(com.google.firebase.firestore.model.DocumentKey)

Example 85 with DocumentKey

use of com.google.firebase.firestore.model.DocumentKey in project firebase-android-sdk by firebase.

the class WatchChangeAggregator method createRemoteEvent.

/**
 * Converts the currently accumulated state into a remote event at the provided snapshot version.
 * Resets the accumulated changes before returning.
 */
public RemoteEvent createRemoteEvent(SnapshotVersion snapshotVersion) {
    Map<Integer, TargetChange> targetChanges = new HashMap<>();
    for (Map.Entry<Integer, TargetState> entry : targetStates.entrySet()) {
        int targetId = entry.getKey();
        TargetState targetState = entry.getValue();
        TargetData targetData = queryDataForActiveTarget(targetId);
        if (targetData != null) {
            if (targetState.isCurrent() && targetData.getTarget().isDocumentQuery()) {
                // Document queries for document that don't exist can produce an empty result set. To
                // update our local cache, we synthesize a document delete if we have not previously
                // received the document. This resolves the limbo state of the document, removing it from
                // limboDocumentRefs.
                DocumentKey key = DocumentKey.fromPath(targetData.getTarget().getPath());
                if (pendingDocumentUpdates.get(key) == null && !targetContainsDocument(targetId, key)) {
                    MutableDocument result = MutableDocument.newNoDocument(key, snapshotVersion);
                    removeDocumentFromTarget(targetId, key, result);
                }
            }
            if (targetState.hasChanges()) {
                targetChanges.put(targetId, targetState.toTargetChange());
                targetState.clearChanges();
            }
        }
    }
    Set<DocumentKey> resolvedLimboDocuments = new HashSet<>();
    // TODO(gsoltis): Expand on this comment once GC is available in the Android client.
    for (Map.Entry<DocumentKey, Set<Integer>> entry : pendingDocumentTargetMapping.entrySet()) {
        DocumentKey key = entry.getKey();
        Set<Integer> targets = entry.getValue();
        boolean isOnlyLimboTarget = true;
        for (int targetId : targets) {
            TargetData targetData = queryDataForActiveTarget(targetId);
            if (targetData != null && !targetData.getPurpose().equals(QueryPurpose.LIMBO_RESOLUTION)) {
                isOnlyLimboTarget = false;
                break;
            }
        }
        if (isOnlyLimboTarget) {
            resolvedLimboDocuments.add(key);
        }
    }
    for (MutableDocument document : pendingDocumentUpdates.values()) {
        document.setReadTime(snapshotVersion);
    }
    RemoteEvent remoteEvent = new RemoteEvent(snapshotVersion, Collections.unmodifiableMap(targetChanges), Collections.unmodifiableSet(pendingTargetResets), Collections.unmodifiableMap(pendingDocumentUpdates), Collections.unmodifiableSet(resolvedLimboDocuments));
    // Re-initialize the current state to ensure that we do not modify the generated RemoteEvent.
    pendingDocumentUpdates = new HashMap<>();
    pendingDocumentTargetMapping = new HashMap<>();
    pendingTargetResets = new HashSet<>();
    return remoteEvent;
}
Also used : Set(java.util.Set) HashSet(java.util.HashSet) ImmutableSortedSet(com.google.firebase.database.collection.ImmutableSortedSet) HashMap(java.util.HashMap) MutableDocument(com.google.firebase.firestore.model.MutableDocument) TargetData(com.google.firebase.firestore.local.TargetData) WatchTargetChange(com.google.firebase.firestore.remote.WatchChange.WatchTargetChange) DocumentKey(com.google.firebase.firestore.model.DocumentKey) HashMap(java.util.HashMap) Map(java.util.Map) HashSet(java.util.HashSet)

Aggregations

DocumentKey (com.google.firebase.firestore.model.DocumentKey)134 MutableDocument (com.google.firebase.firestore.model.MutableDocument)52 Test (org.junit.Test)36 HashMap (java.util.HashMap)29 ArrayList (java.util.ArrayList)25 Document (com.google.firebase.firestore.model.Document)23 SnapshotVersion (com.google.firebase.firestore.model.SnapshotVersion)16 Mutation (com.google.firebase.firestore.model.mutation.Mutation)15 Map (java.util.Map)15 ResourcePath (com.google.firebase.firestore.model.ResourcePath)13 MutationBatch (com.google.firebase.firestore.model.mutation.MutationBatch)11 HashSet (java.util.HashSet)11 Overlay (com.google.firebase.firestore.model.mutation.Overlay)10 ImmutableSortedMap (com.google.firebase.database.collection.ImmutableSortedMap)9 TestUtil.patchMutation (com.google.firebase.firestore.testutil.TestUtil.patchMutation)7 TestUtil.setMutation (com.google.firebase.firestore.testutil.TestUtil.setMutation)7 ByteString (com.google.protobuf.ByteString)7 Query (com.google.firebase.firestore.core.Query)6 ObjectValue (com.google.firebase.firestore.model.ObjectValue)6 Timestamp (com.google.firebase.Timestamp)5