362 lines
17 KiB
Java
362 lines
17 KiB
Java
|
package com.google.firebase.firestore.local;
|
||
|
|
||
|
import android.database.Cursor;
|
||
|
import android.database.sqlite.SQLiteStatement;
|
||
|
import com.google.firebase.Timestamp;
|
||
|
import com.google.firebase.firestore.auth.User;
|
||
|
import com.google.firebase.firestore.local.SQLitePersistence;
|
||
|
import com.google.firebase.firestore.model.DocumentKey;
|
||
|
import com.google.firebase.firestore.model.mutation.Mutation;
|
||
|
import com.google.firebase.firestore.model.mutation.MutationBatch;
|
||
|
import com.google.firebase.firestore.proto.WriteBatch;
|
||
|
import com.google.firebase.firestore.remote.WriteStream;
|
||
|
import com.google.firebase.firestore.util.Assert;
|
||
|
import com.google.firebase.firestore.util.Consumer;
|
||
|
import com.google.firebase.firestore.util.Function;
|
||
|
import com.google.firebase.firestore.util.Preconditions;
|
||
|
import com.google.firebase.firestore.util.Util;
|
||
|
import com.google.protobuf.InvalidProtocolBufferException;
|
||
|
import java.util.ArrayList;
|
||
|
import java.util.Arrays;
|
||
|
import java.util.Collections;
|
||
|
import java.util.Comparator;
|
||
|
import java.util.HashSet;
|
||
|
import java.util.Iterator;
|
||
|
import java.util.List;
|
||
|
import java.util.Set;
|
||
|
import o.QwV;
|
||
|
|
||
|
/* JADX INFO: Access modifiers changed from: package-private */
|
||
|
/* loaded from: classes2.dex */
|
||
|
public final class SQLiteMutationQueue implements MutationQueue {
|
||
|
private final SQLitePersistence db;
|
||
|
private final IndexManager indexManager;
|
||
|
private QwV lastStreamToken;
|
||
|
private int nextBatchId;
|
||
|
private final LocalSerializer serializer;
|
||
|
private final String uid;
|
||
|
|
||
|
/* JADX INFO: Access modifiers changed from: package-private */
|
||
|
public SQLiteMutationQueue(SQLitePersistence sQLitePersistence, LocalSerializer localSerializer, User user, IndexManager indexManager) {
|
||
|
this.db = sQLitePersistence;
|
||
|
this.serializer = localSerializer;
|
||
|
this.uid = user.isAuthenticated() ? user.getUid() : "";
|
||
|
this.lastStreamToken = WriteStream.EMPTY_STREAM_TOKEN;
|
||
|
this.indexManager = indexManager;
|
||
|
}
|
||
|
|
||
|
@Override // com.google.firebase.firestore.local.MutationQueue
|
||
|
public final void start() {
|
||
|
loadNextBatchIdAcrossAllUsers();
|
||
|
if (this.db.query("SELECT last_stream_token FROM mutation_queues WHERE uid = ?").binding(this.uid).first(new Consumer(this) { // from class: com.google.firebase.firestore.local.SQLiteMutationQueue$$ExternalSyntheticLambda6
|
||
|
public final SQLiteMutationQueue f$0;
|
||
|
|
||
|
@Override // com.google.firebase.firestore.util.Consumer
|
||
|
public final void accept(Object obj) {
|
||
|
this.f$0.m213xf87fd3c7((Cursor) obj);
|
||
|
}
|
||
|
|
||
|
{
|
||
|
this.f$0 = this;
|
||
|
}
|
||
|
}) == 0) {
|
||
|
writeMutationQueueMetadata();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/* JADX INFO: Access modifiers changed from: package-private */
|
||
|
/* renamed from: lambda$start$0$com-google-firebase-firestore-local-SQLiteMutationQueue, reason: not valid java name */
|
||
|
public final /* synthetic */ void m213xf87fd3c7(Cursor cursor) {
|
||
|
this.lastStreamToken = QwV.b(cursor.getBlob(0));
|
||
|
}
|
||
|
|
||
|
private void loadNextBatchIdAcrossAllUsers() {
|
||
|
final ArrayList arrayList = new ArrayList();
|
||
|
this.db.query("SELECT uid FROM mutation_queues").forEach(new Consumer(arrayList) { // from class: com.google.firebase.firestore.local.SQLiteMutationQueue$$ExternalSyntheticLambda0
|
||
|
public final List f$0;
|
||
|
|
||
|
@Override // com.google.firebase.firestore.util.Consumer
|
||
|
public final void accept(Object obj) {
|
||
|
this.f$0.add(((Cursor) obj).getString(0));
|
||
|
}
|
||
|
|
||
|
{
|
||
|
this.f$0 = arrayList;
|
||
|
}
|
||
|
});
|
||
|
this.nextBatchId = 0;
|
||
|
Iterator it = arrayList.iterator();
|
||
|
while (it.hasNext()) {
|
||
|
this.db.query("SELECT MAX(batch_id) FROM mutations WHERE uid = ?").binding((String) it.next()).forEach(new Consumer(this) { // from class: com.google.firebase.firestore.local.SQLiteMutationQueue$$ExternalSyntheticLambda3
|
||
|
public final SQLiteMutationQueue f$0;
|
||
|
|
||
|
@Override // com.google.firebase.firestore.util.Consumer
|
||
|
public final void accept(Object obj) {
|
||
|
this.f$0.m211xa3a174c9((Cursor) obj);
|
||
|
}
|
||
|
|
||
|
{
|
||
|
this.f$0 = this;
|
||
|
}
|
||
|
});
|
||
|
}
|
||
|
this.nextBatchId++;
|
||
|
}
|
||
|
|
||
|
/* JADX INFO: Access modifiers changed from: package-private */
|
||
|
/* renamed from: lambda$loadNextBatchIdAcrossAllUsers$2$com-google-firebase-firestore-local-SQLiteMutationQueue, reason: not valid java name */
|
||
|
public final /* synthetic */ void m211xa3a174c9(Cursor cursor) {
|
||
|
this.nextBatchId = Math.max(this.nextBatchId, cursor.getInt(0));
|
||
|
}
|
||
|
|
||
|
public final boolean isEmpty() {
|
||
|
return this.db.query("SELECT batch_id FROM mutations WHERE uid = ? LIMIT 1").binding(this.uid).isEmpty();
|
||
|
}
|
||
|
|
||
|
@Override // com.google.firebase.firestore.local.MutationQueue
|
||
|
public final void acknowledgeBatch(MutationBatch mutationBatch, QwV qwV) {
|
||
|
this.lastStreamToken = (QwV) Preconditions.checkNotNull(qwV);
|
||
|
writeMutationQueueMetadata();
|
||
|
}
|
||
|
|
||
|
@Override // com.google.firebase.firestore.local.MutationQueue
|
||
|
public final void setLastStreamToken(QwV qwV) {
|
||
|
this.lastStreamToken = (QwV) Preconditions.checkNotNull(qwV);
|
||
|
writeMutationQueueMetadata();
|
||
|
}
|
||
|
|
||
|
private void writeMutationQueueMetadata() {
|
||
|
this.db.execute("INSERT OR REPLACE INTO mutation_queues (uid, last_acknowledged_batch_id, last_stream_token) VALUES (?, ?, ?)", this.uid, -1, this.lastStreamToken.j());
|
||
|
}
|
||
|
|
||
|
@Override // com.google.firebase.firestore.local.MutationQueue
|
||
|
public final MutationBatch addMutationBatch(Timestamp timestamp, List<Mutation> list, List<Mutation> list2) {
|
||
|
int i = this.nextBatchId;
|
||
|
this.nextBatchId = i + 1;
|
||
|
MutationBatch mutationBatch = new MutationBatch(i, timestamp, list, list2);
|
||
|
WriteBatch encodeMutationBatch = this.serializer.encodeMutationBatch(mutationBatch);
|
||
|
this.db.execute("INSERT INTO mutations (uid, batch_id, mutations) VALUES (?, ?, ?)", this.uid, Integer.valueOf(i), encodeMutationBatch.toByteArray());
|
||
|
HashSet hashSet = new HashSet();
|
||
|
SQLiteStatement prepare = this.db.prepare("INSERT INTO document_mutations (uid, path, batch_id) VALUES (?, ?, ?)");
|
||
|
Iterator<Mutation> it = list2.iterator();
|
||
|
while (it.hasNext()) {
|
||
|
DocumentKey key = it.next().getKey();
|
||
|
if (hashSet.add(key)) {
|
||
|
this.db.execute(prepare, this.uid, EncodedPath.encode(key.getPath()), Integer.valueOf(i));
|
||
|
this.indexManager.addToCollectionParentIndex(key.getCollectionPath());
|
||
|
}
|
||
|
}
|
||
|
return mutationBatch;
|
||
|
}
|
||
|
|
||
|
@Override // com.google.firebase.firestore.local.MutationQueue
|
||
|
public final MutationBatch lookupMutationBatch(final int i) {
|
||
|
return (MutationBatch) this.db.query("SELECT SUBSTR(mutations, 1, ?) FROM mutations WHERE uid = ? AND batch_id = ?").binding(1000000, this.uid, Integer.valueOf(i)).firstValue(new Function(this, i) { // from class: com.google.firebase.firestore.local.SQLiteMutationQueue$$ExternalSyntheticLambda8
|
||
|
public final SQLiteMutationQueue f$0;
|
||
|
public final int f$1;
|
||
|
|
||
|
@Override // com.google.firebase.firestore.util.Function
|
||
|
public final Object apply(Object obj) {
|
||
|
return this.f$0.m212xb685bf9f(this.f$1, (Cursor) obj);
|
||
|
}
|
||
|
|
||
|
{
|
||
|
this.f$0 = this;
|
||
|
this.f$1 = i;
|
||
|
}
|
||
|
});
|
||
|
}
|
||
|
|
||
|
/* JADX INFO: Access modifiers changed from: package-private */
|
||
|
/* renamed from: lambda$lookupMutationBatch$3$com-google-firebase-firestore-local-SQLiteMutationQueue, reason: not valid java name */
|
||
|
public final /* synthetic */ MutationBatch m212xb685bf9f(int i, Cursor cursor) {
|
||
|
return decodeInlineMutationBatch(i, cursor.getBlob(0));
|
||
|
}
|
||
|
|
||
|
@Override // com.google.firebase.firestore.local.MutationQueue
|
||
|
public final MutationBatch getNextMutationBatchAfterBatchId(int i) {
|
||
|
return (MutationBatch) this.db.query("SELECT batch_id, SUBSTR(mutations, 1, ?) FROM mutations WHERE uid = ? AND batch_id >= ? ORDER BY batch_id ASC LIMIT 1").binding(1000000, this.uid, Integer.valueOf(i + 1)).firstValue(new Function(this) { // from class: com.google.firebase.firestore.local.SQLiteMutationQueue$$ExternalSyntheticLambda2
|
||
|
public final SQLiteMutationQueue f$0;
|
||
|
|
||
|
@Override // com.google.firebase.firestore.util.Function
|
||
|
public final Object apply(Object obj) {
|
||
|
return this.f$0.m210x6512fc44((Cursor) obj);
|
||
|
}
|
||
|
|
||
|
{
|
||
|
this.f$0 = this;
|
||
|
}
|
||
|
});
|
||
|
}
|
||
|
|
||
|
/* JADX INFO: Access modifiers changed from: package-private */
|
||
|
/* renamed from: lambda$getNextMutationBatchAfterBatchId$4$com-google-firebase-firestore-local-SQLiteMutationQueue, reason: not valid java name */
|
||
|
public final /* synthetic */ MutationBatch m210x6512fc44(Cursor cursor) {
|
||
|
return decodeInlineMutationBatch(cursor.getInt(0), cursor.getBlob(1));
|
||
|
}
|
||
|
|
||
|
@Override // com.google.firebase.firestore.local.MutationQueue
|
||
|
public final List<MutationBatch> getAllMutationBatches() {
|
||
|
final ArrayList arrayList = new ArrayList();
|
||
|
this.db.query("SELECT batch_id, SUBSTR(mutations, 1, ?) FROM mutations WHERE uid = ? ORDER BY batch_id ASC").binding(1000000, this.uid).forEach(new Consumer(this, arrayList) { // from class: com.google.firebase.firestore.local.SQLiteMutationQueue$$ExternalSyntheticLambda5
|
||
|
public final SQLiteMutationQueue f$0;
|
||
|
public final List f$1;
|
||
|
|
||
|
@Override // com.google.firebase.firestore.util.Consumer
|
||
|
public final void accept(Object obj) {
|
||
|
this.f$0.m208x425a097f(this.f$1, (Cursor) obj);
|
||
|
}
|
||
|
|
||
|
{
|
||
|
this.f$0 = this;
|
||
|
this.f$1 = arrayList;
|
||
|
}
|
||
|
});
|
||
|
return arrayList;
|
||
|
}
|
||
|
|
||
|
/* JADX INFO: Access modifiers changed from: package-private */
|
||
|
/* renamed from: lambda$getAllMutationBatches$6$com-google-firebase-firestore-local-SQLiteMutationQueue, reason: not valid java name */
|
||
|
public final /* synthetic */ void m208x425a097f(List list, Cursor cursor) {
|
||
|
list.add(decodeInlineMutationBatch(cursor.getInt(0), cursor.getBlob(1)));
|
||
|
}
|
||
|
|
||
|
@Override // com.google.firebase.firestore.local.MutationQueue
|
||
|
public final List<MutationBatch> getAllMutationBatchesAffectingDocumentKeys(Iterable<DocumentKey> iterable) {
|
||
|
ArrayList arrayList = new ArrayList();
|
||
|
Iterator<DocumentKey> it = iterable.iterator();
|
||
|
while (it.hasNext()) {
|
||
|
arrayList.add(EncodedPath.encode(it.next().getPath()));
|
||
|
}
|
||
|
SQLitePersistence.LongQuery longQuery = new SQLitePersistence.LongQuery(this.db, "SELECT DISTINCT dm.batch_id, SUBSTR(m.mutations, 1, ?) FROM document_mutations dm, mutations m WHERE dm.uid = ? AND dm.path IN (", Arrays.asList(1000000, this.uid), arrayList, ") AND dm.uid = m.uid AND dm.batch_id = m.batch_id ORDER BY dm.batch_id");
|
||
|
final ArrayList arrayList2 = new ArrayList();
|
||
|
final HashSet hashSet = new HashSet();
|
||
|
while (longQuery.hasMoreSubqueries()) {
|
||
|
longQuery.performNextSubquery().forEach(new Consumer(this, hashSet, arrayList2) { // from class: com.google.firebase.firestore.local.SQLiteMutationQueue$$ExternalSyntheticLambda11
|
||
|
public final SQLiteMutationQueue f$0;
|
||
|
public final Set f$1;
|
||
|
public final List f$2;
|
||
|
|
||
|
@Override // com.google.firebase.firestore.util.Consumer
|
||
|
public final void accept(Object obj) {
|
||
|
this.f$0.m209x1f85c24f(this.f$1, this.f$2, (Cursor) obj);
|
||
|
}
|
||
|
|
||
|
{
|
||
|
this.f$0 = this;
|
||
|
this.f$1 = hashSet;
|
||
|
this.f$2 = arrayList2;
|
||
|
}
|
||
|
});
|
||
|
}
|
||
|
if (longQuery.getSubqueriesPerformed() > 1) {
|
||
|
Collections.sort(arrayList2, new Comparator() { // from class: com.google.firebase.firestore.local.SQLiteMutationQueue$$ExternalSyntheticLambda1
|
||
|
@Override // java.util.Comparator
|
||
|
public final int compare(Object obj, Object obj2) {
|
||
|
int compareIntegers;
|
||
|
compareIntegers = Util.compareIntegers(((MutationBatch) obj).getBatchId(), ((MutationBatch) obj2).getBatchId());
|
||
|
return compareIntegers;
|
||
|
}
|
||
|
});
|
||
|
}
|
||
|
return arrayList2;
|
||
|
}
|
||
|
|
||
|
/* JADX INFO: Access modifiers changed from: package-private */
|
||
|
/* renamed from: lambda$getAllMutationBatchesAffectingDocumentKeys$8$com-google-firebase-firestore-local-SQLiteMutationQueue, reason: not valid java name */
|
||
|
public final /* synthetic */ void m209x1f85c24f(Set set, List list, Cursor cursor) {
|
||
|
int i = cursor.getInt(0);
|
||
|
if (set.contains(Integer.valueOf(i))) {
|
||
|
return;
|
||
|
}
|
||
|
set.add(Integer.valueOf(i));
|
||
|
list.add(decodeInlineMutationBatch(i, cursor.getBlob(1)));
|
||
|
}
|
||
|
|
||
|
@Override // com.google.firebase.firestore.local.MutationQueue
|
||
|
public final void removeMutationBatch(MutationBatch mutationBatch) {
|
||
|
SQLiteStatement prepare = this.db.prepare("DELETE FROM mutations WHERE uid = ? AND batch_id = ?");
|
||
|
SQLiteStatement prepare2 = this.db.prepare("DELETE FROM document_mutations WHERE uid = ? AND path = ? AND batch_id = ?");
|
||
|
int batchId = mutationBatch.getBatchId();
|
||
|
Assert.hardAssert(this.db.execute(prepare, this.uid, Integer.valueOf(batchId)) != 0, "Mutation batch (%s, %d) did not exist", this.uid, Integer.valueOf(mutationBatch.getBatchId()));
|
||
|
Iterator<Mutation> it = mutationBatch.getMutations().iterator();
|
||
|
while (it.hasNext()) {
|
||
|
DocumentKey key = it.next().getKey();
|
||
|
this.db.execute(prepare2, this.uid, EncodedPath.encode(key.getPath()), Integer.valueOf(batchId));
|
||
|
this.db.getReferenceDelegate().removeMutationReference(key);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
@Override // com.google.firebase.firestore.local.MutationQueue
|
||
|
public final void performConsistencyCheck() {
|
||
|
if (isEmpty()) {
|
||
|
final ArrayList arrayList = new ArrayList();
|
||
|
this.db.query("SELECT path FROM document_mutations WHERE uid = ?").binding(this.uid).forEach(new Consumer(arrayList) { // from class: com.google.firebase.firestore.local.SQLiteMutationQueue$$ExternalSyntheticLambda10
|
||
|
public final List f$0;
|
||
|
|
||
|
@Override // com.google.firebase.firestore.util.Consumer
|
||
|
public final void accept(Object obj) {
|
||
|
this.f$0.add(EncodedPath.decodeResourcePath(((Cursor) obj).getString(0)));
|
||
|
}
|
||
|
|
||
|
{
|
||
|
this.f$0 = arrayList;
|
||
|
}
|
||
|
});
|
||
|
Assert.hardAssert(arrayList.isEmpty(), "Document leak -- detected dangling mutation references when queue is empty. Dangling keys: %s", arrayList);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
private MutationBatch decodeInlineMutationBatch(int i, byte[] bArr) {
|
||
|
try {
|
||
|
if (bArr.length < 1000000) {
|
||
|
return this.serializer.decodeMutationBatch(WriteBatch.parseFrom(bArr));
|
||
|
}
|
||
|
BlobAccumulator blobAccumulator = new BlobAccumulator(bArr);
|
||
|
while (blobAccumulator.more) {
|
||
|
this.db.query("SELECT SUBSTR(mutations, ?, ?) FROM mutations WHERE uid = ? AND batch_id = ?").binding(Integer.valueOf((blobAccumulator.numChunks() * 1000000) + 1), 1000000, this.uid, Integer.valueOf(i)).first(blobAccumulator);
|
||
|
}
|
||
|
return this.serializer.decodeMutationBatch(WriteBatch.parseFrom(blobAccumulator.result()));
|
||
|
} catch (InvalidProtocolBufferException e) {
|
||
|
throw Assert.fail("MutationBatch failed to parse: %s", e);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/* JADX INFO: Access modifiers changed from: package-private */
|
||
|
/* loaded from: classes2.dex */
|
||
|
public static class BlobAccumulator implements Consumer<Cursor> {
|
||
|
private final ArrayList<QwV> chunks = new ArrayList<>();
|
||
|
private boolean more = true;
|
||
|
|
||
|
BlobAccumulator(byte[] bArr) {
|
||
|
addChunk(bArr);
|
||
|
}
|
||
|
|
||
|
int numChunks() {
|
||
|
return this.chunks.size();
|
||
|
}
|
||
|
|
||
|
QwV result() {
|
||
|
return QwV.b(this.chunks);
|
||
|
}
|
||
|
|
||
|
@Override // com.google.firebase.firestore.util.Consumer
|
||
|
public void accept(Cursor cursor) {
|
||
|
byte[] blob = cursor.getBlob(0);
|
||
|
addChunk(blob);
|
||
|
if (blob.length < 1000000) {
|
||
|
this.more = false;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
private void addChunk(byte[] bArr) {
|
||
|
this.chunks.add(QwV.b(bArr));
|
||
|
}
|
||
|
}
|
||
|
|
||
|
@Override // com.google.firebase.firestore.local.MutationQueue
|
||
|
public final QwV getLastStreamToken() {
|
||
|
return this.lastStreamToken;
|
||
|
}
|
||
|
}
|