16
16
17
17
import static com .google .firebase .firestore .local .EncodedPath .decodeResourcePath ;
18
18
import static com .google .firebase .firestore .local .EncodedPath .encode ;
19
+ import static com .google .firebase .firestore .testutil .TestUtil .key ;
19
20
import static com .google .firebase .firestore .testutil .TestUtil .map ;
20
21
import static com .google .firebase .firestore .testutil .TestUtil .path ;
22
+ import static com .google .firebase .firestore .testutil .TestUtil .query ;
23
+ import static com .google .firebase .firestore .testutil .TestUtil .version ;
21
24
import static java .util .Arrays .asList ;
22
25
import static org .junit .Assert .assertEquals ;
23
26
import static org .junit .Assert .assertFalse ;
28
31
import android .database .sqlite .SQLiteDatabase ;
29
32
import android .database .sqlite .SQLiteOpenHelper ;
30
33
import androidx .test .core .app .ApplicationProvider ;
34
+ import com .google .firebase .database .collection .ImmutableSortedMap ;
31
35
import com .google .firebase .firestore .model .DatabaseId ;
36
+ import com .google .firebase .firestore .model .DocumentKey ;
32
37
import com .google .firebase .firestore .model .ResourcePath ;
38
+ import com .google .firebase .firestore .proto .MaybeDocument ;
33
39
import com .google .firebase .firestore .proto .WriteBatch ;
40
+ import com .google .firebase .firestore .remote .RemoteSerializer ;
34
41
import com .google .firestore .v1 .Document ;
35
42
import com .google .firestore .v1 .Write ;
36
43
import java .util .ArrayList ;
@@ -55,10 +62,11 @@ public class SQLiteSchemaTest {
55
62
56
63
private SQLiteDatabase db ;
57
64
private SQLiteSchema schema ;
65
+ private SQLiteOpenHelper opener ;
58
66
59
67
@ Before
60
68
public void setUp () {
61
- SQLiteOpenHelper opener =
69
+ opener =
62
70
new SQLiteOpenHelper (ApplicationProvider .getApplicationContext (), "foo" , null , 1 ) {
63
71
@ Override
64
72
public void onCreate (SQLiteDatabase db ) {}
@@ -394,6 +402,68 @@ public void canCreateCollectionParentsIndex() {
394
402
assertEquals (expectedParents , actualParents );
395
403
}
396
404
405
+ @ Test
406
+ public void existingDocumentsRemainReadableAfterIndexFreeMigration () {
407
+ // Initialize the schema to the state prior to the index-free migration.
408
+ schema .runMigrations (0 , 8 );
409
+ db .execSQL (
410
+ "INSERT INTO remote_documents (path, contents) VALUES (?, ?)" ,
411
+ new Object [] {encode (path ("coll/existing" )), createDummyDocument ("coll/existing" )});
412
+
413
+ // Run the index-free migration.
414
+ schema .runMigrations (8 , 9 );
415
+ db .execSQL (
416
+ "INSERT INTO remote_documents (path, read_time_seconds, read_time_nanos, contents) VALUES (?, ?, ?, ?)" ,
417
+ new Object [] {encode (path ("coll/old" )), 0 , 1000 , createDummyDocument ("coll/old" )});
418
+ db .execSQL (
419
+ "INSERT INTO remote_documents (path, read_time_seconds, read_time_nanos, contents) VALUES (?, ?, ?, ?)" ,
420
+ new Object [] {encode (path ("coll/current" )), 0 , 2000 , createDummyDocument ("coll/current" )});
421
+ db .execSQL (
422
+ "INSERT INTO remote_documents (path, read_time_seconds, read_time_nanos, contents) VALUES (?, ?, ?, ?)" ,
423
+ new Object [] {encode (path ("coll/new" )), 0 , 3000 , createDummyDocument ("coll/new" )});
424
+
425
+ SQLiteRemoteDocumentCache remoteDocumentCache = createRemoteDocumentCache ();
426
+ ImmutableSortedMap <DocumentKey , com .google .firebase .firestore .model .Document > results =
427
+ remoteDocumentCache .getAllDocumentsMatchingQuery (query ("coll" ), version (2 ));
428
+
429
+ // Verify that queries return the documents that existed prior to the index-free migration, as
430
+ // well as any documents with a newer read time than the one passed in.
431
+ assertResultsContain (results , "coll/existing" , "coll/new" );
432
+ }
433
+
434
+ private SQLiteRemoteDocumentCache createRemoteDocumentCache () {
435
+ DatabaseId databaseId = DatabaseId .forProject ("foo" );
436
+ LocalSerializer serializer = new LocalSerializer (new RemoteSerializer (databaseId ));
437
+ SQLitePersistence persistence =
438
+ new SQLitePersistence (
439
+ serializer ,
440
+ StatsCollector .NO_OP_STATS_COLLECTOR ,
441
+ LruGarbageCollector .Params .Default (),
442
+ opener );
443
+ persistence .start ();
444
+ return new SQLiteRemoteDocumentCache (
445
+ persistence , serializer , StatsCollector .NO_OP_STATS_COLLECTOR );
446
+ }
447
+
448
+ private byte [] createDummyDocument (String name ) {
449
+ return MaybeDocument .newBuilder ()
450
+ .setDocument (
451
+ Document .newBuilder ()
452
+ .setName ("projects/foo/databases/(default)/documents/" + name )
453
+ .build ())
454
+ .build ()
455
+ .toByteArray ();
456
+ }
457
+
458
+ private void assertResultsContain (
459
+ ImmutableSortedMap <DocumentKey , com .google .firebase .firestore .model .Document > actualResults ,
460
+ String ... docs ) {
461
+ for (String doc : docs ) {
462
+ assertTrue ("Expected result for " + doc , actualResults .containsKey (key (doc )));
463
+ }
464
+ assertEquals ("Results contain unexpected entries" , docs .length , actualResults .size ());
465
+ }
466
+
397
467
private void assertNoResultsForQuery (String query , String [] args ) {
398
468
Cursor cursor = null ;
399
469
try {
0 commit comments