Search in sources :

Example 6 with ResourcePath

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

the class RemoteSerializer method encodeQueryTarget.

public QueryTarget encodeQueryTarget(com.google.firebase.firestore.core.Target target) {
    // Dissect the path into parent, collectionId, and optional key filter.
    QueryTarget.Builder builder = QueryTarget.newBuilder();
    StructuredQuery.Builder structuredQueryBuilder = StructuredQuery.newBuilder();
    ResourcePath path = target.getPath();
    if (target.getCollectionGroup() != null) {
        hardAssert(path.length() % 2 == 0, "Collection Group queries should be within a document path or root.");
        builder.setParent(encodeQueryPath(path));
        CollectionSelector.Builder from = CollectionSelector.newBuilder();
        from.setCollectionId(target.getCollectionGroup());
        from.setAllDescendants(true);
        structuredQueryBuilder.addFrom(from);
    } else {
        hardAssert(path.length() % 2 != 0, "Document queries with filters are not supported.");
        builder.setParent(encodeQueryPath(path.popLast()));
        CollectionSelector.Builder from = CollectionSelector.newBuilder();
        from.setCollectionId(path.getLastSegment());
        structuredQueryBuilder.addFrom(from);
    }
    // Encode the filters.
    if (target.getFilters().size() > 0) {
        structuredQueryBuilder.setWhere(encodeFilters(target.getFilters()));
    }
    // Encode the orders.
    for (OrderBy orderBy : target.getOrderBy()) {
        structuredQueryBuilder.addOrderBy(encodeOrderBy(orderBy));
    }
    // Encode the limit.
    if (target.hasLimit()) {
        structuredQueryBuilder.setLimit(Int32Value.newBuilder().setValue((int) target.getLimit()));
    }
    if (target.getStartAt() != null) {
        Cursor.Builder cursor = Cursor.newBuilder();
        cursor.addAllValues(target.getStartAt().getPosition());
        cursor.setBefore(target.getStartAt().isInclusive());
        structuredQueryBuilder.setStartAt(cursor);
    }
    if (target.getEndAt() != null) {
        Cursor.Builder cursor = Cursor.newBuilder();
        cursor.addAllValues(target.getEndAt().getPosition());
        cursor.setBefore(!target.getEndAt().isInclusive());
        structuredQueryBuilder.setEndAt(cursor);
    }
    builder.setStructuredQuery(structuredQueryBuilder);
    return builder.build();
}
Also used : StructuredQuery(com.google.firestore.v1.StructuredQuery) OrderBy(com.google.firebase.firestore.core.OrderBy) QueryTarget(com.google.firestore.v1.Target.QueryTarget) ResourcePath(com.google.firebase.firestore.model.ResourcePath) CollectionSelector(com.google.firestore.v1.StructuredQuery.CollectionSelector) Cursor(com.google.firestore.v1.Cursor)

Example 7 with ResourcePath

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

the class RemoteSerializer method decodeQueryTarget.

public com.google.firebase.firestore.core.Target decodeQueryTarget(String parent, StructuredQuery query) {
    ResourcePath path = decodeQueryPath(parent);
    String collectionGroup = null;
    int fromCount = query.getFromCount();
    if (fromCount > 0) {
        hardAssert(fromCount == 1, "StructuredQuery.from with more than one collection is not supported.");
        CollectionSelector from = query.getFrom(0);
        if (from.getAllDescendants()) {
            collectionGroup = from.getCollectionId();
        } else {
            path = path.append(from.getCollectionId());
        }
    }
    List<Filter> filterBy;
    if (query.hasWhere()) {
        filterBy = decodeFilters(query.getWhere());
    } else {
        filterBy = Collections.emptyList();
    }
    List<OrderBy> orderBy;
    int orderByCount = query.getOrderByCount();
    if (orderByCount > 0) {
        orderBy = new ArrayList<>(orderByCount);
        for (int i = 0; i < orderByCount; i++) {
            orderBy.add(decodeOrderBy(query.getOrderBy(i)));
        }
    } else {
        orderBy = Collections.emptyList();
    }
    long limit = com.google.firebase.firestore.core.Target.NO_LIMIT;
    if (query.hasLimit()) {
        limit = query.getLimit().getValue();
    }
    Bound startAt = null;
    if (query.hasStartAt()) {
        startAt = new Bound(query.getStartAt().getValuesList(), query.getStartAt().getBefore());
    }
    Bound endAt = null;
    if (query.hasEndAt()) {
        endAt = new Bound(query.getEndAt().getValuesList(), !query.getEndAt().getBefore());
    }
    return new com.google.firebase.firestore.core.Target(path, collectionGroup, filterBy, orderBy, limit, startAt, endAt);
}
Also used : OrderBy(com.google.firebase.firestore.core.OrderBy) Bound(com.google.firebase.firestore.core.Bound) DocumentsTarget(com.google.firestore.v1.Target.DocumentsTarget) Target(com.google.firestore.v1.Target) QueryTarget(com.google.firestore.v1.Target.QueryTarget) ResourcePath(com.google.firebase.firestore.model.ResourcePath) CollectionSelector(com.google.firestore.v1.StructuredQuery.CollectionSelector) FieldFilter(com.google.firebase.firestore.core.FieldFilter) CompositeFilter(com.google.firestore.v1.StructuredQuery.CompositeFilter) UnaryFilter(com.google.firestore.v1.StructuredQuery.UnaryFilter) Filter(com.google.firebase.firestore.core.Filter)

Example 8 with ResourcePath

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

the class SQLiteLruReferenceDelegate method removeOrphanedDocuments.

@Override
public int removeOrphanedDocuments(long upperBound) {
    int[] count = new int[1];
    boolean resultsRemaining = true;
    List<DocumentKey> docsToRemove = new ArrayList<>();
    while (resultsRemaining) {
        int rowsProccessed = persistence.query("select path from target_documents group by path having COUNT(*) = 1 AND target_id = 0 AND sequence_number <= ? LIMIT ?").binding(upperBound, REMOVE_ORPHANED_DOCUMENTS_BATCH_SIZE).forEach(row -> {
            ResourcePath path = EncodedPath.decodeResourcePath(row.getString(0));
            DocumentKey key = DocumentKey.fromPath(path);
            if (!isPinned(key)) {
                count[0]++;
                docsToRemove.add(key);
                removeSentinel(key);
            }
        });
        resultsRemaining = (rowsProccessed == REMOVE_ORPHANED_DOCUMENTS_BATCH_SIZE);
    }
    persistence.getRemoteDocumentCache().removeAll(docsToRemove);
    return count[0];
}
Also used : ResourcePath(com.google.firebase.firestore.model.ResourcePath) DocumentKey(com.google.firebase.firestore.model.DocumentKey) ArrayList(java.util.ArrayList)

Example 9 with ResourcePath

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

the class SQLiteRemoteDocumentCache method getAll.

@Override
public Map<DocumentKey, MutableDocument> getAll(String collectionGroup, IndexOffset offset, int limit) {
    List<ResourcePath> collectionParents = indexManager.getCollectionParents(collectionGroup);
    List<ResourcePath> collections = new ArrayList<>(collectionParents.size());
    for (ResourcePath collectionParent : collectionParents) {
        collections.add(collectionParent.append(collectionGroup));
    }
    if (collections.isEmpty()) {
        return Collections.emptyMap();
    } else if (BINDS_PER_STATEMENT * collections.size() < SQLitePersistence.MAX_ARGS) {
        return getAll(collections, offset, limit);
    } else {
        // We need to fan out our collection scan since SQLite only supports 999 binds per statement.
        Map<DocumentKey, MutableDocument> results = new HashMap<>();
        int pageSize = SQLitePersistence.MAX_ARGS / BINDS_PER_STATEMENT;
        for (int i = 0; i < collections.size(); i += pageSize) {
            results.putAll(getAll(collections.subList(i, Math.min(collections.size(), i + pageSize)), offset, limit));
        }
        return firstNEntries(results, limit, IndexOffset.DOCUMENT_COMPARATOR);
    }
}
Also used : ResourcePath(com.google.firebase.firestore.model.ResourcePath) ArrayList(java.util.ArrayList) HashMap(java.util.HashMap) Map(java.util.Map) ImmutableSortedMap(com.google.firebase.database.collection.ImmutableSortedMap) DocumentCollections.emptyDocumentMap(com.google.firebase.firestore.model.DocumentCollections.emptyDocumentMap)

Example 10 with ResourcePath

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

the class SQLiteRemoteDocumentCache method getAll.

/**
 * Returns the next {@code count} documents from the provided collections, ordered by read time.
 */
private Map<DocumentKey, MutableDocument> getAll(List<ResourcePath> collections, IndexOffset offset, int count) {
    Timestamp readTime = offset.getReadTime().getTimestamp();
    DocumentKey documentKey = offset.getDocumentKey();
    StringBuilder sql = repeatSequence("SELECT contents, read_time_seconds, read_time_nanos, path " + "FROM remote_documents " + "WHERE path >= ? AND path < ? AND path_length = ? " + "AND (read_time_seconds > ? OR ( " + "read_time_seconds = ? AND read_time_nanos > ?) OR ( " + "read_time_seconds = ? AND read_time_nanos = ? and path > ?)) ", collections.size(), " UNION ");
    sql.append("ORDER BY read_time_seconds, read_time_nanos, path LIMIT ?");
    Object[] bindVars = new Object[BINDS_PER_STATEMENT * collections.size() + 1];
    int i = 0;
    for (ResourcePath collection : collections) {
        String prefixPath = EncodedPath.encode(collection);
        bindVars[i++] = prefixPath;
        bindVars[i++] = EncodedPath.prefixSuccessor(prefixPath);
        bindVars[i++] = collection.length() + 1;
        bindVars[i++] = readTime.getSeconds();
        bindVars[i++] = readTime.getSeconds();
        bindVars[i++] = readTime.getNanoseconds();
        bindVars[i++] = readTime.getSeconds();
        bindVars[i++] = readTime.getNanoseconds();
        bindVars[i++] = EncodedPath.encode(documentKey.getPath());
    }
    bindVars[i] = count;
    BackgroundQueue backgroundQueue = new BackgroundQueue();
    Map<DocumentKey, MutableDocument> results = new HashMap<>();
    db.query(sql.toString()).binding(bindVars).forEach(row -> processRowInBackground(backgroundQueue, results, row));
    backgroundQueue.drain();
    return results;
}
Also used : BackgroundQueue(com.google.firebase.firestore.util.BackgroundQueue) ResourcePath(com.google.firebase.firestore.model.ResourcePath) HashMap(java.util.HashMap) DocumentKey(com.google.firebase.firestore.model.DocumentKey) MutableDocument(com.google.firebase.firestore.model.MutableDocument) Timestamp(com.google.firebase.Timestamp)

Aggregations

ResourcePath (com.google.firebase.firestore.model.ResourcePath)34 MutableDocument (com.google.firebase.firestore.model.MutableDocument)13 DocumentKey (com.google.firebase.firestore.model.DocumentKey)12 Test (org.junit.Test)11 ArrayList (java.util.ArrayList)8 OrderBy (com.google.firebase.firestore.core.OrderBy)4 HashMap (java.util.HashMap)4 Bound (com.google.firebase.firestore.core.Bound)3 Cursor (android.database.Cursor)2 SQLiteStatement (android.database.sqlite.SQLiteStatement)2 ImmutableSortedMap (com.google.firebase.database.collection.ImmutableSortedMap)2 ImmutableSortedSet (com.google.firebase.database.collection.ImmutableSortedSet)2 FieldFilter (com.google.firebase.firestore.core.FieldFilter)2 Filter (com.google.firebase.firestore.core.Filter)2 Query (com.google.firebase.firestore.core.Query)2 EncodedPath.decodeResourcePath (com.google.firebase.firestore.local.EncodedPath.decodeResourcePath)2 DocumentCollections.emptyDocumentMap (com.google.firebase.firestore.model.DocumentCollections.emptyDocumentMap)2 SnapshotVersion (com.google.firebase.firestore.model.SnapshotVersion)2 BackgroundQueue (com.google.firebase.firestore.util.BackgroundQueue)2 CollectionSelector (com.google.firestore.v1.StructuredQuery.CollectionSelector)2