use of com.google.firebase.firestore.core.Target in project firebase-android-sdk by firebase.
the class BundleSerializer method decodeBundledQuery.
private BundledQuery decodeBundledQuery(JSONObject bundledQuery) throws JSONException {
JSONObject structuredQuery = bundledQuery.getJSONObject("structuredQuery");
verifyNoSelect(structuredQuery);
ResourcePath parent = decodeName(bundledQuery.getString("parent"));
JSONArray from = structuredQuery.getJSONArray("from");
verifyCollectionSelector(from);
JSONObject collectionSelector = from.getJSONObject(0);
boolean allDescendants = collectionSelector.optBoolean("allDescendants", false);
@Nullable String collectionGroup = null;
if (allDescendants) {
collectionGroup = collectionSelector.getString("collectionId");
} else {
parent = parent.append(collectionSelector.getString("collectionId"));
}
List<Filter> filters = decodeWhere(structuredQuery.optJSONObject("where"));
List<OrderBy> orderBys = decodeOrderBy(structuredQuery.optJSONArray("orderBy"));
@Nullable Bound startAt = decodeStartAtBound(structuredQuery.optJSONObject("startAt"));
@Nullable Bound endAt = decodeEndAtBound(structuredQuery.optJSONObject("endAt"));
verifyNoOffset(structuredQuery);
int limit = decodeLimit(structuredQuery);
Query.LimitType limitType = decodeLimitType(bundledQuery);
return new BundledQuery(new Target(parent, collectionGroup, filters, orderBys, limit, startAt, endAt), limitType);
}
use of com.google.firebase.firestore.core.Target in project firebase-android-sdk by firebase.
the class LocalSerializer method decodeBundledQuery.
public BundledQuery decodeBundledQuery(com.google.firestore.bundle.BundledQuery bundledQuery) {
LimitType limitType = bundledQuery.getLimitType().equals(com.google.firestore.bundle.BundledQuery.LimitType.FIRST) ? LimitType.LIMIT_TO_FIRST : LimitType.LIMIT_TO_LAST;
Target target = rpcSerializer.decodeQueryTarget(bundledQuery.getParent(), bundledQuery.getStructuredQuery());
return new BundledQuery(target, limitType);
}
use of com.google.firebase.firestore.core.Target in project firebase-android-sdk by firebase.
the class LocalStoreTestCase method testHandlesSavingAndLoadingNamedQueries.
@Test
public void testHandlesSavingAndLoadingNamedQueries() {
Target target = query("foo").toTarget();
NamedQuery namedQuery = new NamedQuery("testQuery", new BundledQuery(target, Query.LimitType.LIMIT_TO_FIRST), SnapshotVersion.NONE);
saveNamedQuery(namedQuery);
assertHasNamedQuery(namedQuery);
}
use of com.google.firebase.firestore.core.Target in project firebase-android-sdk by firebase.
the class LocalStoreTestCase method testLoadingNamedQueriesAllocatesTargetsAndUpdatesTargetDocumentMapping.
@Test
public void testLoadingNamedQueriesAllocatesTargetsAndUpdatesTargetDocumentMapping() {
bundleDocuments(doc("foo1/bar", 1, map("sum", 1337)), doc("foo2/bar", 1, map("sum", 42)));
assertChanged(doc("foo1/bar", 1, map("sum", 1337)), doc("foo2/bar", 1, map("sum", 42)));
assertContains(doc("foo1/bar", 1, map("sum", 1337)));
assertContains(doc("foo2/bar", 1, map("sum", 42)));
Target target1 = Query.atPath(ResourcePath.fromString("foo1")).toTarget();
NamedQuery namedQuery1 = new NamedQuery("query-1", new BundledQuery(target1, Query.LimitType.LIMIT_TO_FIRST), new SnapshotVersion(Timestamp.now()));
saveNamedQuery(namedQuery1, key("foo1/bar"));
assertHasNamedQuery(namedQuery1);
assertQueryDocumentMapping(/* targetId= */
4, key("foo1/bar"));
Target target2 = Query.atPath(ResourcePath.fromString("foo2")).toTarget();
NamedQuery namedQuery2 = new NamedQuery("query-2", new BundledQuery(target2, Query.LimitType.LIMIT_TO_FIRST), new SnapshotVersion(Timestamp.now()));
saveNamedQuery(namedQuery2, key("foo2/bar"));
assertHasNamedQuery(namedQuery2);
assertQueryDocumentMapping(/* targetId= */
6, key("foo2/bar"));
}
use of com.google.firebase.firestore.core.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;
}
Aggregations