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,45 @@ 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
+ constructor ( private readonly user : User ) { }
73
+
54
74
/**
55
75
* Adds a new entry to the collection parent index.
56
76
*
@@ -114,16 +134,40 @@ export class IndexedDbIndexManager implements IndexManager {
114
134
transaction : PersistenceTransaction ,
115
135
index : FieldIndex
116
136
) : PersistencePromise < void > {
117
- // TODO(indexing): Implement
118
- return PersistencePromise . resolve ( ) ;
137
+ const indexes = indexConfigurationStore ( transaction ) ;
138
+ const dbIndex = toDbIndexConfiguration ( index ) ;
139
+ return indexes . put ( dbIndex ) . next ( ) ;
119
140
}
120
141
121
142
deleteFieldIndex (
122
143
transaction : PersistenceTransaction ,
123
144
index : FieldIndex
124
145
) : PersistencePromise < void > {
125
- // TODO(indexing): Implement
126
- return PersistencePromise . resolve ( ) ;
146
+ const indexes = indexConfigurationStore ( transaction ) ;
147
+ const states = indexStateStore ( transaction ) ;
148
+ const entries = indexEntriesStore ( transaction ) ;
149
+ return indexes
150
+ . delete ( index . indexId )
151
+ . next ( ( ) =>
152
+ states . delete (
153
+ IDBKeyRange . bound (
154
+ [ index . indexId , '' ] ,
155
+ [ index . indexId + 1 , '' ] ,
156
+ /*lowerOpen=*/ false ,
157
+ /*upperOpen=*/ true
158
+ )
159
+ )
160
+ )
161
+ . next ( ( ) =>
162
+ entries . delete (
163
+ IDBKeyRange . bound (
164
+ [ index . indexId , '' , new Uint8Array ( ) , new Uint8Array ( ) , '' ] ,
165
+ [ index . indexId + 1 , '' , new Uint8Array ( ) , new Uint8Array ( ) , '' ] ,
166
+ /*lowerOpen=*/ false ,
167
+ /*upperOpen=*/ true
168
+ )
169
+ )
170
+ ) ;
127
171
}
128
172
129
173
getDocumentsMatchingTarget (
@@ -147,24 +191,87 @@ export class IndexedDbIndexManager implements IndexManager {
147
191
transaction : PersistenceTransaction ,
148
192
collectionGroup ?: string
149
193
) : PersistencePromise < FieldIndex [ ] > {
150
- // TODO(indexing): Implement
151
- return PersistencePromise . resolve < FieldIndex [ ] > ( [ ] ) ;
194
+ const indexes = indexConfigurationStore ( transaction ) ;
195
+ const states = indexStateStore ( transaction ) ;
196
+
197
+ return (
198
+ collectionGroup
199
+ ? indexes . loadAll (
200
+ DbIndexConfiguration . collectionGroupIndex ,
201
+ IDBKeyRange . bound ( collectionGroup , collectionGroup )
202
+ )
203
+ : indexes . loadAll ( )
204
+ ) . next ( indexEntries => {
205
+ const result : FieldIndex [ ] = [ ] ;
206
+ return PersistencePromise . forEach (
207
+ indexEntries ,
208
+ ( indexEntry : DbIndexConfiguration ) => {
209
+ return states
210
+ . get ( [ indexEntry . indexId ! , this . user . uid || '' ] )
211
+ . next ( indexState => {
212
+ result . push ( fromDbIndexConfiguration ( indexEntry , indexState ! ) ) ;
213
+ } ) ;
214
+ }
215
+ ) . next ( ( ) => result ) ;
216
+ } ) ;
152
217
}
153
218
154
219
getNextCollectionGroupToUpdate (
155
220
transaction : PersistenceTransaction
156
221
) : PersistencePromise < string | null > {
157
- // TODO(indexing): Implement
158
- return PersistencePromise . resolve < string | null > ( null ) ;
222
+ let nextIndexId : number | null = null ;
223
+
224
+ const indexes = indexConfigurationStore ( transaction ) ;
225
+ const states = indexStateStore ( transaction ) ;
226
+ return states
227
+ . iterate (
228
+ {
229
+ index : DbIndexState . sequenceNumberIndex ,
230
+ range : IDBKeyRange . upperBound ( [
231
+ this . user . uid || '' ,
232
+ Number . MAX_SAFE_INTEGER
233
+ ] )
234
+ } ,
235
+ ( _ , state , controller ) => {
236
+ controller . done ( ) ;
237
+ nextIndexId = state . indexId ;
238
+ }
239
+ )
240
+ . next ( ( ) =>
241
+ nextIndexId == null
242
+ ? PersistencePromise . resolve < string | null > ( null )
243
+ : indexes
244
+ . get ( nextIndexId )
245
+ . next ( v => v ! . collectionGroup as string | null )
246
+ ) ;
159
247
}
160
248
161
249
updateCollectionGroup (
162
250
transaction : PersistenceTransaction ,
163
251
collectionGroup : string ,
164
252
offset : IndexOffset
165
253
) : PersistencePromise < void > {
166
- // TODO(indexing): Implement
167
- return PersistencePromise . resolve ( ) ;
254
+ const indexes = indexConfigurationStore ( transaction ) ;
255
+ const states = indexStateStore ( transaction ) ;
256
+ return this . getNextSequenceNumber ( transaction ) . next ( nextSequenceNumber =>
257
+ indexes
258
+ . loadAll (
259
+ DbIndexConfiguration . collectionGroupIndex ,
260
+ IDBKeyRange . bound ( collectionGroup , collectionGroup )
261
+ )
262
+ . next ( configs =>
263
+ PersistencePromise . forEach ( configs , ( config : DbIndexConfiguration ) =>
264
+ states . put (
265
+ toDbIndexState (
266
+ config . indexId ! ,
267
+ this . user ,
268
+ nextSequenceNumber ,
269
+ offset
270
+ )
271
+ )
272
+ )
273
+ )
274
+ ) ;
168
275
}
169
276
170
277
updateIndexEntries (
@@ -174,6 +281,29 @@ export class IndexedDbIndexManager implements IndexManager {
174
281
// TODO(indexing): Implement
175
282
return PersistencePromise . resolve ( ) ;
176
283
}
284
+
285
+ private getNextSequenceNumber (
286
+ transaction : PersistenceTransaction
287
+ ) : PersistencePromise < number > {
288
+ let nextSequenceNumber = 1 ;
289
+ const states = indexStateStore ( transaction ) ;
290
+ return states
291
+ . iterate (
292
+ {
293
+ index : DbIndexState . sequenceNumberIndex ,
294
+ reverse : true ,
295
+ range : IDBKeyRange . upperBound ( [
296
+ this . user . uid || '' ,
297
+ Number . MAX_SAFE_INTEGER
298
+ ] )
299
+ } ,
300
+ ( _ , state , controller ) => {
301
+ controller . done ( ) ;
302
+ nextSequenceNumber = state . sequenceNumber + 1 ;
303
+ }
304
+ )
305
+ . next ( ( ) => nextSequenceNumber ) ;
306
+ }
177
307
}
178
308
179
309
/**
@@ -188,3 +318,33 @@ function collectionParentsStore(
188
318
DbCollectionParent . store
189
319
) ;
190
320
}
321
+
322
+ /**
323
+ * Helper to get a typed SimpleDbStore for the index entry object store.
324
+ */
325
+ function indexEntriesStore (
326
+ txn : PersistenceTransaction
327
+ ) : SimpleDbStore < DbIndexEntryKey , DbIndexEntry > {
328
+ return getStore < DbIndexEntryKey , DbIndexEntry > ( txn , DbIndexEntry . store ) ;
329
+ }
330
+
331
+ /**
332
+ * Helper to get a typed SimpleDbStore for the index configuration object store.
333
+ */
334
+ function indexConfigurationStore (
335
+ txn : PersistenceTransaction
336
+ ) : SimpleDbStore < DbIndexConfigurationKey , DbIndexConfiguration > {
337
+ return getStore < DbIndexConfigurationKey , DbIndexConfiguration > (
338
+ txn ,
339
+ DbIndexConfiguration . store
340
+ ) ;
341
+ }
342
+
343
+ /**
344
+ * Helper to get a typed SimpleDbStore for the index state object store.
345
+ */
346
+ function indexStateStore (
347
+ txn : PersistenceTransaction
348
+ ) : SimpleDbStore < DbIndexStateKey , DbIndexState > {
349
+ return getStore < DbIndexStateKey , DbIndexState > ( txn , DbIndexState . store ) ;
350
+ }
0 commit comments