use of com.google.firestore.v1.Target 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;
}
use of com.google.firestore.v1.Target in project firebase-android-sdk by firebase.
the class SQLiteIndexManager method getDocumentsMatchingTarget.
@Override
public Set<DocumentKey> getDocumentsMatchingTarget(Target target) {
hardAssert(started, "IndexManager not started");
List<String> subQueries = new ArrayList<>();
List<Object> bindings = new ArrayList<>();
for (Target subTarget : getSubTargets(target)) {
FieldIndex fieldIndex = getFieldIndex(subTarget);
if (fieldIndex == null) {
return null;
}
@Nullable List<Value> arrayValues = subTarget.getArrayValues(fieldIndex);
@Nullable Collection<Value> notInValues = subTarget.getNotInValues(fieldIndex);
@Nullable Bound lowerBound = subTarget.getLowerBound(fieldIndex);
@Nullable Bound upperBound = subTarget.getUpperBound(fieldIndex);
if (Logger.isDebugEnabled()) {
Logger.debug(TAG, "Using index '%s' to execute '%s' (Arrays: %s, Lower bound: %s, Upper bound: %s)", fieldIndex, subTarget, arrayValues, lowerBound, upperBound);
}
Object[] lowerBoundEncoded = encodeBound(fieldIndex, subTarget, lowerBound);
String lowerBoundOp = lowerBound != null && lowerBound.isInclusive() ? ">=" : ">";
Object[] upperBoundEncoded = encodeBound(fieldIndex, subTarget, upperBound);
String upperBoundOp = upperBound != null && upperBound.isInclusive() ? "<=" : "<";
Object[] notInEncoded = encodeValues(fieldIndex, subTarget, notInValues);
Object[] subQueryAndBindings = generateQueryAndBindings(subTarget, fieldIndex.getIndexId(), arrayValues, lowerBoundEncoded, lowerBoundOp, upperBoundEncoded, upperBoundOp, notInEncoded);
subQueries.add(String.valueOf(subQueryAndBindings[0]));
bindings.addAll(Arrays.asList(subQueryAndBindings).subList(1, subQueryAndBindings.length));
}
String queryString;
if (subQueries.size() == 1) {
// If there's only one subQuery, just execute the one subQuery.
queryString = subQueries.get(0);
} else {
// Construct "SELECT * FROM (subQuery1 UNION subQuery2 UNION ...) LIMIT N"
queryString = "SELECT * FROM (" + TextUtils.join(" UNION ", subQueries) + ")";
if (target.getLimit() != -1) {
queryString = queryString + " LIMIT " + target.getLimit();
}
}
hardAssert(bindings.size() < 1000, "Cannot perform query with more than 999 bind elements");
SQLitePersistence.Query query = db.query(queryString).binding(bindings.toArray());
Set<DocumentKey> result = new HashSet<>();
query.forEach(row -> result.add(DocumentKey.fromPath(ResourcePath.fromString(row.getString(0)))));
Logger.debug(TAG, "Index scan returned %s documents", result.size());
return result;
}
use of com.google.firestore.v1.Target in project firebase-android-sdk by firebase.
the class TargetTest method arrayContainsQueryBound.
@Test
public void arrayContainsQueryBound() {
Target target = query("c").filter(filter("foo", "array-contains", "bar")).toTarget();
FieldIndex index = fieldIndex("c", "foo", FieldIndex.Segment.Kind.CONTAINS);
List<Value> arrayValues = target.getArrayValues(index);
assertThat(arrayValues).containsExactly(wrap("bar"));
Bound lowerBound = target.getLowerBound(index);
verifyBound(lowerBound, true);
Bound upperBound = target.getUpperBound(index);
verifyBound(upperBound, true);
}
use of com.google.firestore.v1.Target in project firebase-android-sdk by firebase.
the class TargetTest method arrayContainsAnyQueryBound.
@Test
public void arrayContainsAnyQueryBound() {
Target target = query("c").filter(filter("foo", "array-contains-any", Arrays.asList("bar", "baz"))).toTarget();
FieldIndex index = fieldIndex("c", "foo", FieldIndex.Segment.Kind.CONTAINS);
List<Value> arrayValues = target.getArrayValues(index);
assertThat(arrayValues).containsExactly(wrap("bar"), wrap("baz"));
Bound lowerBound = target.getLowerBound(index);
verifyBound(lowerBound, true);
Bound upperBound = target.getUpperBound(index);
verifyBound(upperBound, true);
}
use of com.google.firestore.v1.Target in project firebase-android-sdk by firebase.
the class RemoteSerializerTest method testEncodesLimits.
@Test
public void testEncodesLimits() {
Query q = Query.atPath(ResourcePath.fromString("docs")).limitToFirst(26);
Target actual = serializer.encodeTarget(wrapTargetData(q));
StructuredQuery.Builder structuredQueryBuilder = StructuredQuery.newBuilder().addFrom(CollectionSelector.newBuilder().setCollectionId("docs")).addOrderBy(defaultKeyOrder()).setLimit(Int32Value.newBuilder().setValue(26));
QueryTarget.Builder queryBuilder = QueryTarget.newBuilder().setParent("projects/p/databases/d/documents").setStructuredQuery(structuredQueryBuilder);
Target expected = Target.newBuilder().setQuery(queryBuilder).setTargetId(1).setResumeToken(ByteString.EMPTY).build();
assertEquals(expected, actual);
assertEquals(serializer.decodeQueryTarget(serializer.encodeQueryTarget(q.toTarget())), q.toTarget());
}
Aggregations