18
18
import static com .google .firebase .firestore .util .Assert .fail ;
19
19
import static com .google .firebase .firestore .util .Assert .hardAssert ;
20
20
21
+ import android .database .sqlite .SQLiteDoneException ;
21
22
import android .database .sqlite .SQLiteStatement ;
22
23
import android .os .ParcelFileDescriptor ;
23
24
import com .google .firebase .Timestamp ;
@@ -208,26 +209,47 @@ public MutationBatch addMutationBatch(Timestamp localWriteTime, List<Mutation> m
208
209
@ Nullable
209
210
@ Override
210
211
public MutationBatch lookupMutationBatch (int batchId ) {
211
- return db . query (
212
- "SELECT m.batch_id, SUBSTR(m. mutations, 1, ?) "
213
- + "FROM mutations m "
214
- + "WHERE uid = ? AND batch_id = ?" )
215
- . binding ( BLOB_MAX_INLINE_LENGTH , uid , batchId )
216
- . firstValue ( row -> decodeMutationBatchRow ( row . getInt ( 0 ), row . getBlob ( 1 )) );
212
+ SQLiteStatement query =
213
+ db . prepare ( "SELECT mutations FROM mutations WHERE uid = ? AND batch_id = ?" );
214
+ query . bindString ( 1 , uid );
215
+ query . bindLong ( 2 , batchId );
216
+
217
+ return executeSimpleMutationBatchLookup ( query );
217
218
}
218
219
219
220
@ Nullable
220
221
@ Override
221
222
public MutationBatch getNextMutationBatchAfterBatchId (int batchId ) {
222
223
int nextBatchId = batchId + 1 ;
223
224
224
- return db .query (
225
- "SELECT m.batch_id, SUBSTR(m.mutations, 1, ?) "
226
- + "FROM mutations m "
227
- + "WHERE uid = ? AND batch_id >= ? "
228
- + "ORDER BY batch_id ASC LIMIT 1" )
229
- .binding (BLOB_MAX_INLINE_LENGTH , uid , nextBatchId )
230
- .firstValue (row -> decodeMutationBatchRow (row .getInt (0 ), row .getBlob (1 )));
225
+ SQLiteStatement query =
226
+ db .prepare ("SELECT mutations FROM mutations "
227
+ + "WHERE uid = ? AND batch_id >= ? "
228
+ + "ORDER BY batch_id ASC LIMIT 1" );
229
+ query .bindString (1 , uid );
230
+ query .bindLong (2 , nextBatchId );
231
+
232
+ return executeSimpleMutationBatchLookup (query );
233
+ }
234
+
235
+ @ Nullable
236
+ private MutationBatch executeSimpleMutationBatchLookup (SQLiteStatement query ) {
237
+ ParcelFileDescriptor blobFile ;
238
+ try {
239
+ blobFile = query .simpleQueryForBlobFileDescriptor ();
240
+ } catch (SQLiteDoneException e ) {
241
+ return null ;
242
+ }
243
+
244
+ try (ParcelFileDescriptor .AutoCloseInputStream stream =
245
+ new ParcelFileDescriptor .AutoCloseInputStream (blobFile )) {
246
+ return serializer .decodeMutationBatch (
247
+ com .google .firebase .firestore .proto .WriteBatch .parseFrom (stream ));
248
+ } catch (InvalidProtocolBufferException e ) {
249
+ throw fail ("MutationBatch failed to parse: %s" , e );
250
+ } catch (IOException e ) {
251
+ throw fail ("MutationBatch failed to load: %s" , e );
252
+ }
231
253
}
232
254
233
255
@ Override
@@ -238,7 +260,7 @@ public List<MutationBatch> getAllMutationBatches() {
238
260
+ "FROM mutations m "
239
261
+ "WHERE uid = ? ORDER BY batch_id ASC" )
240
262
.binding (BLOB_MAX_INLINE_LENGTH , uid )
241
- .forEach (row -> result .add (decodeMutationBatchRow (row .getInt (0 ), row .getBlob (1 ))));
263
+ .forEach (row -> result .add (decodeInlineMutationBatch (row .getInt (0 ), row .getBlob (1 ))));
242
264
return result ;
243
265
}
244
266
@@ -256,7 +278,7 @@ public List<MutationBatch> getAllMutationBatchesAffectingDocumentKey(DocumentKey
256
278
+ "AND dm.batch_id = m.batch_id "
257
279
+ "ORDER BY dm.batch_id" )
258
280
.binding (BLOB_MAX_INLINE_LENGTH , uid , path )
259
- .forEach (row -> result .add (decodeMutationBatchRow (row .getInt (0 ), row .getBlob (1 ))));
281
+ .forEach (row -> result .add (decodeInlineMutationBatch (row .getInt (0 ), row .getBlob (1 ))));
260
282
return result ;
261
283
}
262
284
@@ -292,7 +314,7 @@ public List<MutationBatch> getAllMutationBatchesAffectingDocumentKeys(
292
314
int batchId = row .getInt (0 );
293
315
if (!uniqueBatchIds .contains (batchId )) {
294
316
uniqueBatchIds .add (batchId );
295
- result .add (decodeMutationBatchRow (batchId , row .getBlob (1 )));
317
+ result .add (decodeInlineMutationBatch (batchId , row .getBlob (1 )));
296
318
}
297
319
});
298
320
}
@@ -364,7 +386,7 @@ public List<MutationBatch> getAllMutationBatchesAffectingQuery(Query query) {
364
386
return ;
365
387
}
366
388
367
- result .add (decodeMutationBatchRow (batchId , row .getBlob (2 )));
389
+ result .add (decodeInlineMutationBatch (batchId , row .getBlob (2 )));
368
390
});
369
391
370
392
return result ;
@@ -417,32 +439,16 @@ public void performConsistencyCheck() {
417
439
* Decodes a mutation batch row containing a batch id and a substring of a blob. If the blob is
418
440
* too large, executes another query to load the blob directly.
419
441
*
420
- * @param batchId The batch ID of the row containing the blob
442
+ * @param batchId The batch ID of the row containing the bytes, for fallback lookup if the value
443
+ * is too large.
421
444
* @param bytes The bytes represented
422
- * @return
423
445
*/
424
- private MutationBatch decodeMutationBatchRow (int batchId , byte [] bytes ) {
446
+ private MutationBatch decodeInlineMutationBatch (int batchId , byte [] bytes ) {
425
447
if (bytes .length < BLOB_MAX_INLINE_LENGTH ) {
426
448
return decodeMutationBatch (bytes );
427
449
}
428
450
429
- SQLiteStatement loader =
430
- db .prepare ("SELECT mutations FROM mutations WHERE uid = ? AND batch_id = ?" );
431
- loader .bindString (1 , uid );
432
- loader .bindLong (2 , batchId );
433
-
434
- ParcelFileDescriptor blobFile = loader .simpleQueryForBlobFileDescriptor ();
435
- hardAssert (blobFile != null , "Blob exists so descriptor should not be null" );
436
-
437
- try (ParcelFileDescriptor .AutoCloseInputStream stream =
438
- new ParcelFileDescriptor .AutoCloseInputStream (blobFile )) {
439
- return serializer .decodeMutationBatch (
440
- com .google .firebase .firestore .proto .WriteBatch .parseFrom (stream ));
441
- } catch (InvalidProtocolBufferException e ) {
442
- throw fail ("MutationBatch failed to parse: %s" , e );
443
- } catch (IOException e ) {
444
- throw fail ("Failed to read blob for uid=%s, batch_id=%d: %s" , uid , batchId , e );
445
- }
451
+ return lookupMutationBatch (batchId );
446
452
}
447
453
448
454
private MutationBatch decodeMutationBatch (byte [] bytes ) {
0 commit comments