17
17
import { expect } from 'chai' ;
18
18
import { PersistenceSettings } from '../../../src/api/database' ;
19
19
import { SnapshotVersion } from '../../../src/core/snapshot_version' ;
20
+ import { decode , encode } from '../../../src/local/encoded_resource_path' ;
20
21
import { IndexedDbPersistence } from '../../../src/local/indexeddb_persistence' ;
21
22
import {
22
23
DbDocumentMutation ,
@@ -32,6 +33,8 @@ import {
32
33
DbRemoteDocumentGlobalKey ,
33
34
DbRemoteDocumentKey ,
34
35
DbTarget ,
36
+ DbTargetDocument ,
37
+ DbTargetDocumentKey ,
35
38
DbTargetGlobal ,
36
39
DbTargetGlobalKey ,
37
40
DbTargetKey ,
@@ -521,6 +524,92 @@ describe('IndexedDbSchema: createOrUpgradeDb', () => {
521
524
} ) ;
522
525
} ) ;
523
526
} ) ;
527
+
528
+ it ( 'can upgrade from version 6 to 7' , async ( ) => {
529
+ const oldSequenceNumber = 1 ;
530
+ // Set the highest sequence number to this value so that untagged documents
531
+ // will pick up this value.
532
+ const newSequenceNumber = 2 ;
533
+ await withDb ( 6 , db => {
534
+ const serializer = TEST_SERIALIZER ;
535
+
536
+ const sdb = new SimpleDb ( db ) ;
537
+ return sdb . runTransaction ( 'readwrite' , V6_STORES , txn => {
538
+ const targetGlobalStore = txn . store < DbTargetGlobalKey , DbTargetGlobal > (
539
+ DbTargetGlobal . store
540
+ ) ;
541
+ const remoteDocumentStore = txn . store <
542
+ DbRemoteDocumentKey ,
543
+ DbRemoteDocument
544
+ > ( DbRemoteDocument . store ) ;
545
+ const targetDocumentStore = txn . store <
546
+ DbTargetDocumentKey ,
547
+ DbTargetDocument
548
+ > ( DbTargetDocument . store ) ;
549
+ return targetGlobalStore
550
+ . get ( DbTargetGlobal . key )
551
+ . next ( metadata => {
552
+ expect ( metadata ) . to . not . be . null ;
553
+ metadata ! . highestListenSequenceNumber = newSequenceNumber ;
554
+ return targetGlobalStore . put ( DbTargetGlobal . key , metadata ! ) ;
555
+ } )
556
+ . next ( ( ) => {
557
+ // Set up some documents (we only need the keys)
558
+ // For the odd ones, add sentinel rows.
559
+ const promises : Array < PersistencePromise < void > > = [ ] ;
560
+ for ( let i = 0 ; i < 10 ; i ++ ) {
561
+ const document = doc ( 'docs/doc_' + i , 1 , { foo : 'bar' } ) ;
562
+ promises . push (
563
+ remoteDocumentStore . put (
564
+ document . key . path . toArray ( ) ,
565
+ serializer . toDbRemoteDocument ( document )
566
+ )
567
+ ) ;
568
+ if ( i % 2 === 1 ) {
569
+ promises . push (
570
+ targetDocumentStore . put (
571
+ new DbTargetDocument (
572
+ 0 ,
573
+ encode ( document . key . path ) ,
574
+ oldSequenceNumber
575
+ )
576
+ )
577
+ ) ;
578
+ }
579
+ }
580
+ return PersistencePromise . waitFor ( promises ) ;
581
+ } ) ;
582
+ } ) ;
583
+ } ) ;
584
+
585
+ // Now run the migration and verify
586
+ await withDb ( 7 , db => {
587
+ const sdb = new SimpleDb ( db ) ;
588
+ return sdb . runTransaction ( 'readonly' , V6_STORES , txn => {
589
+ const targetDocumentStore = txn . store <
590
+ DbTargetDocumentKey ,
591
+ DbTargetDocument
592
+ > ( DbTargetDocument . store ) ;
593
+ const range = IDBKeyRange . bound (
594
+ [ 0 ] ,
595
+ [ 1 ] ,
596
+ /*lowerOpen=*/ false ,
597
+ /*upperOpen=*/ true
598
+ ) ;
599
+ return targetDocumentStore . iterate (
600
+ { range } ,
601
+ ( [ _ , path ] , targetDocument ) => {
602
+ const decoded = decode ( path ) ;
603
+ const lastSegment = decoded . lastSegment ( ) ;
604
+ const docNum = + lastSegment . split ( '_' ) [ 1 ] ;
605
+ const expected =
606
+ docNum % 2 === 1 ? oldSequenceNumber : newSequenceNumber ;
607
+ expect ( targetDocument . sequenceNumber ) . to . equal ( expected ) ;
608
+ }
609
+ ) ;
610
+ } ) ;
611
+ } ) ;
612
+ } ) ;
524
613
} ) ;
525
614
526
615
describe ( 'IndexedDb: canActAsPrimary' , ( ) => {
0 commit comments