15
15
* limitations under the License.
16
16
*/
17
17
18
+ import { User } from '../auth/user' ;
18
19
import { Target } from '../core/target' ;
19
20
import {
20
21
documentKeySet ,
@@ -31,26 +32,49 @@ import {
31
32
encodeResourcePath
32
33
} from './encoded_resource_path' ;
33
34
import { IndexManager } from './index_manager' ;
34
- import { DbCollectionParent , DbCollectionParentKey } from './indexeddb_schema' ;
35
+ import {
36
+ DbCollectionParent ,
37
+ DbCollectionParentKey ,
38
+ DbIndexConfiguration ,
39
+ DbIndexConfigurationKey ,
40
+ DbIndexEntry ,
41
+ DbIndexEntryKey ,
42
+ DbIndexState ,
43
+ DbIndexStateKey
44
+ } from './indexeddb_schema' ;
35
45
import { getStore } from './indexeddb_transaction' ;
46
+ import {
47
+ fromDbIndexConfiguration ,
48
+ toDbIndexConfiguration ,
49
+ toDbIndexState
50
+ } from './local_serializer' ;
36
51
import { MemoryCollectionParentIndex } from './memory_index_manager' ;
37
52
import { PersistencePromise } from './persistence_promise' ;
38
53
import { PersistenceTransaction } from './persistence_transaction' ;
39
54
import { SimpleDbStore } from './simple_db' ;
40
55
41
56
/**
42
57
* A persisted implementation of IndexManager.
58
+ *
59
+ * PORTING NOTE: Unlike iOS and Android, the Web SDK does not memoize index
60
+ * data as it supports multi-tab access.
43
61
*/
44
62
export class IndexedDbIndexManager implements IndexManager {
45
63
/**
46
64
* An in-memory copy of the index entries we've already written since the SDK
47
65
* launched. Used to avoid re-writing the same entry repeatedly.
48
66
*
49
- * This is *NOT* a complete cache of what's in persistence and so can never be used to
50
- * satisfy reads.
67
+ * This is *NOT* a complete cache of what's in persistence and so can never be
68
+ * used to satisfy reads.
51
69
*/
52
70
private collectionParentsCache = new MemoryCollectionParentIndex ( ) ;
53
71
72
+ private uid : string ;
73
+
74
+ constructor ( private user : User ) {
75
+ this . uid = user . uid || '' ;
76
+ }
77
+
54
78
/**
55
79
* Adds a new entry to the collection parent index.
56
80
*
@@ -114,16 +138,43 @@ export class IndexedDbIndexManager implements IndexManager {
114
138
transaction : PersistenceTransaction ,
115
139
index : FieldIndex
116
140
) : PersistencePromise < void > {
117
- // TODO(indexing): Implement
118
- return PersistencePromise . resolve ( ) ;
141
+ // TODO(indexing): Verify that the auto-incrementing index ID works in
142
+ // Safari & Firefox.
143
+ const indexes = indexConfigurationStore ( transaction ) ;
144
+ const dbIndex = toDbIndexConfiguration ( index ) ;
145
+ delete dbIndex . indexId ; // `indexId` is auto-populated by IndexedDb
146
+ return indexes . add ( dbIndex ) . next ( ) ;
119
147
}
120
148
121
149
deleteFieldIndex (
122
150
transaction : PersistenceTransaction ,
123
151
index : FieldIndex
124
152
) : PersistencePromise < void > {
125
- // TODO(indexing): Implement
126
- return PersistencePromise . resolve ( ) ;
153
+ const indexes = indexConfigurationStore ( transaction ) ;
154
+ const states = indexStateStore ( transaction ) ;
155
+ const entries = indexEntriesStore ( transaction ) ;
156
+ return indexes
157
+ . delete ( index . indexId )
158
+ . next ( ( ) =>
159
+ states . delete (
160
+ IDBKeyRange . bound (
161
+ [ index . indexId ] ,
162
+ [ index . indexId + 1 ] ,
163
+ /*lowerOpen=*/ false ,
164
+ /*upperOpen=*/ true
165
+ )
166
+ )
167
+ )
168
+ . next ( ( ) =>
169
+ entries . delete (
170
+ IDBKeyRange . bound (
171
+ [ index . indexId ] ,
172
+ [ index . indexId + 1 ] ,
173
+ /*lowerOpen=*/ false ,
174
+ /*upperOpen=*/ true
175
+ )
176
+ )
177
+ ) ;
127
178
}
128
179
129
180
getDocumentsMatchingTarget (
@@ -147,24 +198,71 @@ export class IndexedDbIndexManager implements IndexManager {
147
198
transaction : PersistenceTransaction ,
148
199
collectionGroup ?: string
149
200
) : PersistencePromise < FieldIndex [ ] > {
150
- // TODO(indexing): Implement
151
- return PersistencePromise . resolve < FieldIndex [ ] > ( [ ] ) ;
201
+ const indexes = indexConfigurationStore ( transaction ) ;
202
+ const states = indexStateStore ( transaction ) ;
203
+
204
+ return (
205
+ collectionGroup
206
+ ? indexes . loadAll (
207
+ DbIndexConfiguration . collectionGroupIndex ,
208
+ IDBKeyRange . bound ( collectionGroup , collectionGroup )
209
+ )
210
+ : indexes . loadAll ( )
211
+ ) . next ( indexConfigs => {
212
+ const result : FieldIndex [ ] = [ ] ;
213
+ return PersistencePromise . forEach (
214
+ indexConfigs ,
215
+ ( indexConfig : DbIndexConfiguration ) => {
216
+ return states
217
+ . get ( [ indexConfig . indexId ! , this . uid ] )
218
+ . next ( indexState => {
219
+ result . push ( fromDbIndexConfiguration ( indexConfig , indexState ) ) ;
220
+ } ) ;
221
+ }
222
+ ) . next ( ( ) => result ) ;
223
+ } ) ;
152
224
}
153
225
154
226
getNextCollectionGroupToUpdate (
155
227
transaction : PersistenceTransaction
156
228
) : PersistencePromise < string | null > {
157
- // TODO(indexing): Implement
158
- return PersistencePromise . resolve < string | null > ( null ) ;
229
+ return this . getFieldIndexes ( transaction ) . next ( indexes => {
230
+ if ( indexes . length === 0 ) {
231
+ return null ;
232
+ }
233
+ indexes . sort (
234
+ ( l , r ) => l . indexState . sequenceNumber - r . indexState . sequenceNumber
235
+ ) ;
236
+ return indexes [ 0 ] . collectionGroup ;
237
+ } ) ;
159
238
}
160
239
161
240
updateCollectionGroup (
162
241
transaction : PersistenceTransaction ,
163
242
collectionGroup : string ,
164
243
offset : IndexOffset
165
244
) : PersistencePromise < void > {
166
- // TODO(indexing): Implement
167
- return PersistencePromise . resolve ( ) ;
245
+ const indexes = indexConfigurationStore ( transaction ) ;
246
+ const states = indexStateStore ( transaction ) ;
247
+ return this . getNextSequenceNumber ( transaction ) . next ( nextSequenceNumber =>
248
+ indexes
249
+ . loadAll (
250
+ DbIndexConfiguration . collectionGroupIndex ,
251
+ IDBKeyRange . bound ( collectionGroup , collectionGroup )
252
+ )
253
+ . next ( configs =>
254
+ PersistencePromise . forEach ( configs , ( config : DbIndexConfiguration ) =>
255
+ states . put (
256
+ toDbIndexState (
257
+ config . indexId ! ,
258
+ this . user ,
259
+ nextSequenceNumber ,
260
+ offset
261
+ )
262
+ )
263
+ )
264
+ )
265
+ ) ;
168
266
}
169
267
170
268
updateIndexEntries (
@@ -174,6 +272,26 @@ export class IndexedDbIndexManager implements IndexManager {
174
272
// TODO(indexing): Implement
175
273
return PersistencePromise . resolve ( ) ;
176
274
}
275
+
276
+ private getNextSequenceNumber (
277
+ transaction : PersistenceTransaction
278
+ ) : PersistencePromise < number > {
279
+ let nextSequenceNumber = 1 ;
280
+ const states = indexStateStore ( transaction ) ;
281
+ return states
282
+ . iterate (
283
+ {
284
+ index : DbIndexState . sequenceNumberIndex ,
285
+ reverse : true ,
286
+ range : IDBKeyRange . upperBound ( [ this . uid , Number . MAX_SAFE_INTEGER ] )
287
+ } ,
288
+ ( _ , state , controller ) => {
289
+ controller . done ( ) ;
290
+ nextSequenceNumber = state . sequenceNumber + 1 ;
291
+ }
292
+ )
293
+ . next ( ( ) => nextSequenceNumber ) ;
294
+ }
177
295
}
178
296
179
297
/**
@@ -188,3 +306,33 @@ function collectionParentsStore(
188
306
DbCollectionParent . store
189
307
) ;
190
308
}
309
+
310
+ /**
311
+ * Helper to get a typed SimpleDbStore for the index entry object store.
312
+ */
313
+ function indexEntriesStore (
314
+ txn : PersistenceTransaction
315
+ ) : SimpleDbStore < DbIndexEntryKey , DbIndexEntry > {
316
+ return getStore < DbIndexEntryKey , DbIndexEntry > ( txn , DbIndexEntry . store ) ;
317
+ }
318
+
319
+ /**
320
+ * Helper to get a typed SimpleDbStore for the index configuration object store.
321
+ */
322
+ function indexConfigurationStore (
323
+ txn : PersistenceTransaction
324
+ ) : SimpleDbStore < DbIndexConfigurationKey , DbIndexConfiguration > {
325
+ return getStore < DbIndexConfigurationKey , DbIndexConfiguration > (
326
+ txn ,
327
+ DbIndexConfiguration . store
328
+ ) ;
329
+ }
330
+
331
+ /**
332
+ * Helper to get a typed SimpleDbStore for the index state object store.
333
+ */
334
+ function indexStateStore (
335
+ txn : PersistenceTransaction
336
+ ) : SimpleDbStore < DbIndexStateKey , DbIndexState > {
337
+ return getStore < DbIndexStateKey , DbIndexState > ( txn , DbIndexState . store ) ;
338
+ }
0 commit comments