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,42 @@ 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
+ return indexes . add ( dbIndex ) . next ( ) ;
119
146
}
120
147
121
148
deleteFieldIndex (
122
149
transaction : PersistenceTransaction ,
123
150
index : FieldIndex
124
151
) : PersistencePromise < void > {
125
- // TODO(indexing): Implement
126
- return PersistencePromise . resolve ( ) ;
152
+ const indexes = indexConfigurationStore ( transaction ) ;
153
+ const states = indexStateStore ( transaction ) ;
154
+ const entries = indexEntriesStore ( transaction ) ;
155
+ return indexes
156
+ . delete ( index . indexId )
157
+ . next ( ( ) =>
158
+ states . delete (
159
+ IDBKeyRange . bound (
160
+ [ index . indexId ] ,
161
+ [ index . indexId + 1 ] ,
162
+ /*lowerOpen=*/ false ,
163
+ /*upperOpen=*/ true
164
+ )
165
+ )
166
+ )
167
+ . next ( ( ) =>
168
+ entries . delete (
169
+ IDBKeyRange . bound (
170
+ [ index . indexId ] ,
171
+ [ index . indexId + 1 ] ,
172
+ /*lowerOpen=*/ false ,
173
+ /*upperOpen=*/ true
174
+ )
175
+ )
176
+ ) ;
127
177
}
128
178
129
179
getDocumentsMatchingTarget (
@@ -147,24 +197,71 @@ export class IndexedDbIndexManager implements IndexManager {
147
197
transaction : PersistenceTransaction ,
148
198
collectionGroup ?: string
149
199
) : PersistencePromise < FieldIndex [ ] > {
150
- // TODO(indexing): Implement
151
- return PersistencePromise . resolve < FieldIndex [ ] > ( [ ] ) ;
200
+ const indexes = indexConfigurationStore ( transaction ) ;
201
+ const states = indexStateStore ( transaction ) ;
202
+
203
+ return (
204
+ collectionGroup
205
+ ? indexes . loadAll (
206
+ DbIndexConfiguration . collectionGroupIndex ,
207
+ IDBKeyRange . bound ( collectionGroup , collectionGroup )
208
+ )
209
+ : indexes . loadAll ( )
210
+ ) . next ( indexEntries => {
211
+ const result : FieldIndex [ ] = [ ] ;
212
+ return PersistencePromise . forEach (
213
+ indexEntries ,
214
+ ( indexEntry : DbIndexConfiguration ) => {
215
+ return states
216
+ . get ( [ indexEntry . indexId ! , this . uid ] )
217
+ . next ( indexState => {
218
+ result . push ( fromDbIndexConfiguration ( indexEntry , indexState ) ) ;
219
+ } ) ;
220
+ }
221
+ ) . next ( ( ) => result ) ;
222
+ } ) ;
152
223
}
153
224
154
225
getNextCollectionGroupToUpdate (
155
226
transaction : PersistenceTransaction
156
227
) : PersistencePromise < string | null > {
157
- // TODO(indexing): Implement
158
- return PersistencePromise . resolve < string | null > ( null ) ;
228
+ return this . getFieldIndexes ( transaction ) . next ( indexes => {
229
+ if ( indexes . length === 0 ) {
230
+ return null ;
231
+ }
232
+ indexes . sort (
233
+ ( l , r ) => l . indexState . sequenceNumber - r . indexState . sequenceNumber
234
+ ) ;
235
+ return indexes [ 0 ] . collectionGroup ;
236
+ } ) ;
159
237
}
160
238
161
239
updateCollectionGroup (
162
240
transaction : PersistenceTransaction ,
163
241
collectionGroup : string ,
164
242
offset : IndexOffset
165
243
) : PersistencePromise < void > {
166
- // TODO(indexing): Implement
167
- return PersistencePromise . resolve ( ) ;
244
+ const indexes = indexConfigurationStore ( transaction ) ;
245
+ const states = indexStateStore ( transaction ) ;
246
+ return this . getNextSequenceNumber ( transaction ) . next ( nextSequenceNumber =>
247
+ indexes
248
+ . loadAll (
249
+ DbIndexConfiguration . collectionGroupIndex ,
250
+ IDBKeyRange . bound ( collectionGroup , collectionGroup )
251
+ )
252
+ . next ( configs =>
253
+ PersistencePromise . forEach ( configs , ( config : DbIndexConfiguration ) =>
254
+ states . put (
255
+ toDbIndexState (
256
+ config . indexId ! ,
257
+ this . user ,
258
+ nextSequenceNumber ,
259
+ offset
260
+ )
261
+ )
262
+ )
263
+ )
264
+ ) ;
168
265
}
169
266
170
267
updateIndexEntries (
@@ -174,6 +271,26 @@ export class IndexedDbIndexManager implements IndexManager {
174
271
// TODO(indexing): Implement
175
272
return PersistencePromise . resolve ( ) ;
176
273
}
274
+
275
+ private getNextSequenceNumber (
276
+ transaction : PersistenceTransaction
277
+ ) : PersistencePromise < number > {
278
+ let nextSequenceNumber = 1 ;
279
+ const states = indexStateStore ( transaction ) ;
280
+ return states
281
+ . iterate (
282
+ {
283
+ index : DbIndexState . sequenceNumberIndex ,
284
+ reverse : true ,
285
+ range : IDBKeyRange . upperBound ( [ this . uid , Number . MAX_SAFE_INTEGER ] )
286
+ } ,
287
+ ( _ , state , controller ) => {
288
+ controller . done ( ) ;
289
+ nextSequenceNumber = state . sequenceNumber + 1 ;
290
+ }
291
+ )
292
+ . next ( ( ) => nextSequenceNumber ) ;
293
+ }
177
294
}
178
295
179
296
/**
@@ -188,3 +305,33 @@ function collectionParentsStore(
188
305
DbCollectionParent . store
189
306
) ;
190
307
}
308
+
309
+ /**
310
+ * Helper to get a typed SimpleDbStore for the index entry object store.
311
+ */
312
+ function indexEntriesStore (
313
+ txn : PersistenceTransaction
314
+ ) : SimpleDbStore < DbIndexEntryKey , DbIndexEntry > {
315
+ return getStore < DbIndexEntryKey , DbIndexEntry > ( txn , DbIndexEntry . store ) ;
316
+ }
317
+
318
+ /**
319
+ * Helper to get a typed SimpleDbStore for the index configuration object store.
320
+ */
321
+ function indexConfigurationStore (
322
+ txn : PersistenceTransaction
323
+ ) : SimpleDbStore < DbIndexConfigurationKey , DbIndexConfiguration > {
324
+ return getStore < DbIndexConfigurationKey , DbIndexConfiguration > (
325
+ txn ,
326
+ DbIndexConfiguration . store
327
+ ) ;
328
+ }
329
+
330
+ /**
331
+ * Helper to get a typed SimpleDbStore for the index state object store.
332
+ */
333
+ function indexStateStore (
334
+ txn : PersistenceTransaction
335
+ ) : SimpleDbStore < DbIndexStateKey , DbIndexState > {
336
+ return getStore < DbIndexStateKey , DbIndexState > ( txn , DbIndexState . store ) ;
337
+ }
0 commit comments