IndexedDB 2.0: Support IDBIndex name assignment.
[WebKit-https.git] / Source / WebCore / Modules / indexeddb / server / MemoryIDBBackingStore.cpp
1 /*
2  * Copyright (C) 2015 Apple Inc. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  * 1. Redistributions of source code must retain the above copyright
8  *    notice, this list of conditions and the following disclaimer.
9  * 2. Redistributions in binary form must reproduce the above copyright
10  *    notice, this list of conditions and the following disclaimer in the
11  *    documentation and/or other materials provided with the distribution.
12  *
13  * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
14  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
15  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
17  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
18  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
19  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
20  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
21  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
22  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
23  * THE POSSIBILITY OF SUCH DAMAGE.
24  */
25
26 #include "config.h"
27 #include "MemoryIDBBackingStore.h"
28
29 #if ENABLE(INDEXED_DATABASE)
30
31 #include "IDBCursorInfo.h"
32 #include "IDBGetResult.h"
33 #include "IDBIndexInfo.h"
34 #include "IDBKeyRangeData.h"
35 #include "Logging.h"
36 #include "MemoryIndexCursor.h"
37 #include "MemoryObjectStore.h"
38 #include "MemoryObjectStoreCursor.h"
39
40 namespace WebCore {
41 namespace IDBServer {
42
43 // The IndexedDB spec states the value you can get from the key generator is 2^53
44 static uint64_t maxGeneratedKeyValue = 0x20000000000000;
45
46 std::unique_ptr<MemoryIDBBackingStore> MemoryIDBBackingStore::create(const IDBDatabaseIdentifier& identifier)
47 {
48     return std::make_unique<MemoryIDBBackingStore>(identifier);
49 }
50
51 MemoryIDBBackingStore::MemoryIDBBackingStore(const IDBDatabaseIdentifier& identifier)
52     : m_identifier(identifier)
53 {
54 }
55
56 MemoryIDBBackingStore::~MemoryIDBBackingStore()
57 {
58 }
59
60 IDBError MemoryIDBBackingStore::getOrEstablishDatabaseInfo(IDBDatabaseInfo& info)
61 {
62     if (!m_databaseInfo)
63         m_databaseInfo = std::make_unique<IDBDatabaseInfo>(m_identifier.databaseName(), 0);
64
65     info = *m_databaseInfo;
66     return { };
67 }
68
69 void MemoryIDBBackingStore::setDatabaseInfo(const IDBDatabaseInfo& info)
70 {
71     // It is not valid to directly set database info on a backing store that hasn't already set its own database info.
72     ASSERT(m_databaseInfo);
73
74     m_databaseInfo = std::make_unique<IDBDatabaseInfo>(info);
75 }
76
77 IDBError MemoryIDBBackingStore::beginTransaction(const IDBTransactionInfo& info)
78 {
79     LOG(IndexedDB, "MemoryIDBBackingStore::beginTransaction");
80
81     if (m_transactions.contains(info.identifier()))
82         return IDBError(IDBDatabaseException::InvalidStateError, "Backing store asked to create transaction it already has a record of");
83
84     auto transaction = MemoryBackingStoreTransaction::create(*this, info);
85
86     // VersionChange transactions are scoped to "every object store".
87     if (transaction->isVersionChange()) {
88         for (auto& objectStore : m_objectStoresByIdentifier.values())
89             transaction->addExistingObjectStore(*objectStore);
90     } else if (transaction->isWriting()) {
91         for (auto& iterator : m_objectStoresByName) {
92             if (info.objectStores().contains(iterator.key))
93                 transaction->addExistingObjectStore(*iterator.value);
94         }
95     }
96
97     m_transactions.set(info.identifier(), WTFMove(transaction));
98
99     return IDBError();
100 }
101
102 IDBError MemoryIDBBackingStore::abortTransaction(const IDBResourceIdentifier& transactionIdentifier)
103 {
104     LOG(IndexedDB, "MemoryIDBBackingStore::abortTransaction - %s", transactionIdentifier.loggingString().utf8().data());
105
106     auto transaction = m_transactions.take(transactionIdentifier);
107     if (!transaction)
108         return IDBError(IDBDatabaseException::InvalidStateError, "Backing store asked to abort transaction it didn't have record of");
109
110     transaction->abort();
111
112     return IDBError();
113 }
114
115 IDBError MemoryIDBBackingStore::commitTransaction(const IDBResourceIdentifier& transactionIdentifier)
116 {
117     LOG(IndexedDB, "MemoryIDBBackingStore::commitTransaction - %s", transactionIdentifier.loggingString().utf8().data());
118
119     auto transaction = m_transactions.take(transactionIdentifier);
120     if (!transaction)
121         return IDBError(IDBDatabaseException::InvalidStateError, "Backing store asked to commit transaction it didn't have record of");
122
123     transaction->commit();
124
125     return IDBError();
126 }
127
128 IDBError MemoryIDBBackingStore::createObjectStore(const IDBResourceIdentifier& transactionIdentifier, const IDBObjectStoreInfo& info)
129 {
130     LOG(IndexedDB, "MemoryIDBBackingStore::createObjectStore - adding OS %s with ID %" PRIu64, info.name().utf8().data(), info.identifier());
131
132     ASSERT(m_databaseInfo);
133     if (m_databaseInfo->hasObjectStore(info.name()))
134         return IDBError(IDBDatabaseException::ConstraintError);
135
136     ASSERT(!m_objectStoresByIdentifier.contains(info.identifier()));
137     auto objectStore = MemoryObjectStore::create(info);
138
139     m_databaseInfo->addExistingObjectStore(info);
140
141     auto rawTransaction = m_transactions.get(transactionIdentifier);
142     ASSERT(rawTransaction);
143     ASSERT(rawTransaction->isVersionChange());
144
145     rawTransaction->addNewObjectStore(objectStore.get());
146     registerObjectStore(WTFMove(objectStore));
147
148     return IDBError();
149 }
150
151 IDBError MemoryIDBBackingStore::deleteObjectStore(const IDBResourceIdentifier& transactionIdentifier, uint64_t objectStoreIdentifier)
152 {
153     LOG(IndexedDB, "MemoryIDBBackingStore::deleteObjectStore");
154
155     ASSERT(m_databaseInfo);
156     if (!m_databaseInfo->infoForExistingObjectStore(objectStoreIdentifier))
157         return IDBError(IDBDatabaseException::ConstraintError);
158
159     auto transaction = m_transactions.get(transactionIdentifier);
160     ASSERT(transaction);
161     ASSERT(transaction->isVersionChange());
162
163     auto objectStore = takeObjectStoreByIdentifier(objectStoreIdentifier);
164     ASSERT(objectStore);
165     if (!objectStore)
166         return IDBError(IDBDatabaseException::ConstraintError);
167
168     m_databaseInfo->deleteObjectStore(objectStore->info().name());
169     transaction->objectStoreDeleted(*objectStore);
170
171     return IDBError();
172 }
173
174 IDBError MemoryIDBBackingStore::renameObjectStore(const IDBResourceIdentifier& transactionIdentifier, uint64_t objectStoreIdentifier, const String& newName)
175 {
176     LOG(IndexedDB, "MemoryIDBBackingStore::renameObjectStore");
177
178     ASSERT(m_databaseInfo);
179     if (!m_databaseInfo->infoForExistingObjectStore(objectStoreIdentifier))
180         return IDBError(IDBDatabaseException::ConstraintError);
181
182     auto transaction = m_transactions.get(transactionIdentifier);
183     ASSERT(transaction);
184     ASSERT(transaction->isVersionChange());
185
186     auto objectStore = m_objectStoresByIdentifier.get(objectStoreIdentifier);
187     ASSERT(objectStore);
188     if (!objectStore)
189         return IDBError(IDBDatabaseException::ConstraintError);
190
191     String oldName = objectStore->info().name();
192     objectStore->rename(newName);
193     transaction->objectStoreRenamed(*objectStore, oldName);
194
195     m_databaseInfo->renameObjectStore(objectStoreIdentifier, newName);
196
197     return IDBError();
198 }
199
200 IDBError MemoryIDBBackingStore::clearObjectStore(const IDBResourceIdentifier& transactionIdentifier, uint64_t objectStoreIdentifier)
201 {
202     LOG(IndexedDB, "MemoryIDBBackingStore::clearObjectStore");
203     ASSERT(objectStoreIdentifier);
204
205     ASSERT_UNUSED(transactionIdentifier, m_transactions.contains(transactionIdentifier));
206
207 #if !LOG_DISABLED
208     auto transaction = m_transactions.get(transactionIdentifier);
209     ASSERT(transaction->isWriting());
210 #endif
211
212     auto objectStore = m_objectStoresByIdentifier.get(objectStoreIdentifier);
213     if (!objectStore)
214         return IDBError(IDBDatabaseException::ConstraintError);
215
216     objectStore->clear();
217
218     return IDBError();
219 }
220
221 IDBError MemoryIDBBackingStore::createIndex(const IDBResourceIdentifier& transactionIdentifier, const IDBIndexInfo& info)
222 {
223     LOG(IndexedDB, "MemoryIDBBackingStore::createIndex");
224
225     auto rawTransaction = m_transactions.get(transactionIdentifier);
226     ASSERT(rawTransaction);
227     ASSERT(rawTransaction->isVersionChange());
228
229     auto* objectStore = m_objectStoresByIdentifier.get(info.objectStoreIdentifier());
230     if (!objectStore)
231         return IDBError(IDBDatabaseException::ConstraintError);
232
233     return objectStore->createIndex(*rawTransaction, info);
234 }
235
236 IDBError MemoryIDBBackingStore::deleteIndex(const IDBResourceIdentifier& transactionIdentifier, uint64_t objectStoreIdentifier, uint64_t indexIdentifier)
237 {
238     LOG(IndexedDB, "MemoryIDBBackingStore::deleteIndex");
239
240     auto rawTransaction = m_transactions.get(transactionIdentifier);
241     ASSERT(rawTransaction);
242     ASSERT(rawTransaction->isVersionChange());
243
244     auto* objectStore = m_objectStoresByIdentifier.get(objectStoreIdentifier);
245     if (!objectStore)
246         return IDBError(IDBDatabaseException::ConstraintError);
247
248     return objectStore->deleteIndex(*rawTransaction, indexIdentifier);
249 }
250
251 IDBError MemoryIDBBackingStore::renameIndex(const IDBResourceIdentifier& transactionIdentifier, uint64_t objectStoreIdentifier, uint64_t indexIdentifier, const String& newName)
252 {
253     LOG(IndexedDB, "MemoryIDBBackingStore::renameIndex");
254
255     ASSERT(m_databaseInfo);
256     auto* objectStoreInfo = m_databaseInfo->infoForExistingObjectStore(objectStoreIdentifier);
257     if (!objectStoreInfo)
258         return IDBError(IDBDatabaseException::ConstraintError);
259
260     auto* indexInfo = objectStoreInfo->infoForExistingIndex(indexIdentifier);
261     if (!indexInfo)
262         return IDBError(IDBDatabaseException::ConstraintError);
263
264     auto transaction = m_transactions.get(transactionIdentifier);
265     ASSERT(transaction);
266     ASSERT(transaction->isVersionChange());
267
268     auto objectStore = m_objectStoresByIdentifier.get(objectStoreIdentifier);
269     ASSERT(objectStore);
270     if (!objectStore)
271         return IDBError(IDBDatabaseException::ConstraintError);
272
273     auto* index = objectStore->indexForIdentifier(indexIdentifier);
274     ASSERT(index);
275     if (!index)
276         return IDBError(IDBDatabaseException::ConstraintError);
277
278     String oldName = index->info().name();
279     objectStore->renameIndex(*index, newName);
280     transaction->indexRenamed(*index, oldName);
281
282     indexInfo->rename(newName);
283
284     return IDBError();
285 }
286
287 void MemoryIDBBackingStore::removeObjectStoreForVersionChangeAbort(MemoryObjectStore& objectStore)
288 {
289     LOG(IndexedDB, "MemoryIDBBackingStore::removeObjectStoreForVersionChangeAbort");
290
291     if (!m_objectStoresByIdentifier.contains(objectStore.info().identifier()))
292         return;
293
294     ASSERT(m_objectStoresByIdentifier.get(objectStore.info().identifier()) == &objectStore);
295
296     unregisterObjectStore(objectStore);
297 }
298
299 void MemoryIDBBackingStore::restoreObjectStoreForVersionChangeAbort(Ref<MemoryObjectStore>&& objectStore)
300 {
301     registerObjectStore(WTFMove(objectStore));
302 }
303
304 IDBError MemoryIDBBackingStore::keyExistsInObjectStore(const IDBResourceIdentifier&, uint64_t objectStoreIdentifier, const IDBKeyData& keyData, bool& keyExists)
305 {
306     LOG(IndexedDB, "MemoryIDBBackingStore::keyExistsInObjectStore");
307
308     ASSERT(objectStoreIdentifier);
309
310     MemoryObjectStore* objectStore = m_objectStoresByIdentifier.get(objectStoreIdentifier);
311     RELEASE_ASSERT(objectStore);
312
313     keyExists = objectStore->containsRecord(keyData);
314     return IDBError();
315 }
316
317 IDBError MemoryIDBBackingStore::deleteRange(const IDBResourceIdentifier& transactionIdentifier, uint64_t objectStoreIdentifier, const IDBKeyRangeData& range)
318 {
319     LOG(IndexedDB, "MemoryIDBBackingStore::deleteRange");
320
321     ASSERT(objectStoreIdentifier);
322
323     if (!m_transactions.contains(transactionIdentifier))
324         return IDBError(IDBDatabaseException::UnknownError, ASCIILiteral("No backing store transaction found to delete from"));
325
326     MemoryObjectStore* objectStore = m_objectStoresByIdentifier.get(objectStoreIdentifier);
327     if (!objectStore)
328         return IDBError(IDBDatabaseException::UnknownError, ASCIILiteral("No backing store object store found"));
329
330     objectStore->deleteRange(range);
331     return IDBError();
332 }
333
334 IDBError MemoryIDBBackingStore::addRecord(const IDBResourceIdentifier& transactionIdentifier, const IDBObjectStoreInfo& objectStoreInfo, const IDBKeyData& keyData, const IDBValue& value)
335 {
336     LOG(IndexedDB, "MemoryIDBBackingStore::addRecord");
337
338     ASSERT(objectStoreInfo.identifier());
339
340     auto transaction = m_transactions.get(transactionIdentifier);
341     if (!transaction)
342         return IDBError(IDBDatabaseException::UnknownError, ASCIILiteral("No backing store transaction found to put record"));
343
344     MemoryObjectStore* objectStore = m_objectStoresByIdentifier.get(objectStoreInfo.identifier());
345     if (!objectStore)
346         return IDBError(IDBDatabaseException::UnknownError, ASCIILiteral("No backing store object store found to put record"));
347
348     return objectStore->addRecord(*transaction, keyData, value);
349 }
350
351 IDBError MemoryIDBBackingStore::getRecord(const IDBResourceIdentifier& transactionIdentifier, uint64_t objectStoreIdentifier, const IDBKeyRangeData& range, IDBGetResult& outValue)
352 {
353     LOG(IndexedDB, "MemoryIDBBackingStore::getRecord");
354
355     ASSERT(objectStoreIdentifier);
356
357     if (!m_transactions.contains(transactionIdentifier))
358         return IDBError(IDBDatabaseException::UnknownError, ASCIILiteral("No backing store transaction found to get record"));
359
360     MemoryObjectStore* objectStore = m_objectStoresByIdentifier.get(objectStoreIdentifier);
361     if (!objectStore)
362         return IDBError(IDBDatabaseException::UnknownError, ASCIILiteral("No backing store object store found"));
363
364     outValue = objectStore->valueForKeyRange(range);
365     return IDBError();
366 }
367
368 IDBError MemoryIDBBackingStore::getIndexRecord(const IDBResourceIdentifier& transactionIdentifier, uint64_t objectStoreIdentifier, uint64_t indexIdentifier, IndexedDB::IndexRecordType recordType, const IDBKeyRangeData& range, IDBGetResult& outValue)
369 {
370     LOG(IndexedDB, "MemoryIDBBackingStore::getIndexRecord");
371
372     ASSERT(objectStoreIdentifier);
373
374     if (!m_transactions.contains(transactionIdentifier))
375         return IDBError(IDBDatabaseException::UnknownError, ASCIILiteral("No backing store transaction found to get record"));
376
377     MemoryObjectStore* objectStore = m_objectStoresByIdentifier.get(objectStoreIdentifier);
378     if (!objectStore)
379         return IDBError(IDBDatabaseException::UnknownError, ASCIILiteral("No backing store object store found"));
380
381     outValue = objectStore->indexValueForKeyRange(indexIdentifier, recordType, range);
382     return IDBError();
383 }
384
385 IDBError MemoryIDBBackingStore::getCount(const IDBResourceIdentifier& transactionIdentifier, uint64_t objectStoreIdentifier, uint64_t indexIdentifier, const IDBKeyRangeData& range, uint64_t& outCount)
386 {
387     LOG(IndexedDB, "MemoryIDBBackingStore::getCount");
388
389     ASSERT(objectStoreIdentifier);
390
391     if (!m_transactions.contains(transactionIdentifier))
392         return IDBError(IDBDatabaseException::UnknownError, ASCIILiteral("No backing store transaction found to get count"));
393
394     MemoryObjectStore* objectStore = m_objectStoresByIdentifier.get(objectStoreIdentifier);
395     if (!objectStore)
396         return IDBError(IDBDatabaseException::UnknownError, ASCIILiteral("No backing store object store found"));
397
398     outCount = objectStore->countForKeyRange(indexIdentifier, range);
399
400     return IDBError();
401 }
402
403 IDBError MemoryIDBBackingStore::generateKeyNumber(const IDBResourceIdentifier& transactionIdentifier, uint64_t objectStoreIdentifier, uint64_t& keyNumber)
404 {
405     LOG(IndexedDB, "MemoryIDBBackingStore::generateKeyNumber");
406     ASSERT(objectStoreIdentifier);
407     ASSERT_UNUSED(transactionIdentifier, m_transactions.contains(transactionIdentifier));
408     ASSERT_UNUSED(transactionIdentifier, m_transactions.get(transactionIdentifier)->isWriting());
409
410     MemoryObjectStore* objectStore = m_objectStoresByIdentifier.get(objectStoreIdentifier);
411     RELEASE_ASSERT(objectStore);
412
413     keyNumber = objectStore->currentKeyGeneratorValue();
414     if (keyNumber > maxGeneratedKeyValue)
415         return { IDBDatabaseException::ConstraintError, "Cannot generate new key value over 2^53 for object store operation" };
416
417     objectStore->setKeyGeneratorValue(keyNumber + 1);
418
419     return IDBError();
420 }
421
422 IDBError MemoryIDBBackingStore::revertGeneratedKeyNumber(const IDBResourceIdentifier& transactionIdentifier, uint64_t objectStoreIdentifier, uint64_t keyNumber)
423 {
424     LOG(IndexedDB, "MemoryIDBBackingStore::revertGeneratedKeyNumber");
425     ASSERT(objectStoreIdentifier);
426     ASSERT_UNUSED(transactionIdentifier, m_transactions.contains(transactionIdentifier));
427     ASSERT_UNUSED(transactionIdentifier, m_transactions.get(transactionIdentifier)->isWriting());
428
429     MemoryObjectStore* objectStore = m_objectStoresByIdentifier.get(objectStoreIdentifier);
430     RELEASE_ASSERT(objectStore);
431
432     objectStore->setKeyGeneratorValue(keyNumber);
433
434     return { };
435 }
436
437 IDBError MemoryIDBBackingStore::maybeUpdateKeyGeneratorNumber(const IDBResourceIdentifier& transactionIdentifier, uint64_t objectStoreIdentifier, double newKeyNumber)
438 {
439     LOG(IndexedDB, "MemoryIDBBackingStore::maybeUpdateKeyGeneratorNumber");
440     ASSERT(objectStoreIdentifier);
441     ASSERT_UNUSED(transactionIdentifier, m_transactions.contains(transactionIdentifier));
442     ASSERT_UNUSED(transactionIdentifier, m_transactions.get(transactionIdentifier)->isWriting());
443
444     MemoryObjectStore* objectStore = m_objectStoresByIdentifier.get(objectStoreIdentifier);
445     RELEASE_ASSERT(objectStore);
446
447     if (newKeyNumber < objectStore->currentKeyGeneratorValue())
448         return { };
449
450     uint64_t newKeyInteger(newKeyNumber);
451     if (newKeyInteger <= uint64_t(newKeyNumber))
452         ++newKeyInteger;
453
454     ASSERT(newKeyInteger > uint64_t(newKeyNumber));
455
456     objectStore->setKeyGeneratorValue(newKeyInteger);
457
458     return { };
459 }
460
461 IDBError MemoryIDBBackingStore::openCursor(const IDBResourceIdentifier& transactionIdentifier, const IDBCursorInfo& info, IDBGetResult& outData)
462 {
463     LOG(IndexedDB, "MemoryIDBBackingStore::openCursor");
464
465     ASSERT(!MemoryCursor::cursorForIdentifier(info.identifier()));
466
467     if (!m_transactions.contains(transactionIdentifier))
468         return IDBError(IDBDatabaseException::UnknownError, ASCIILiteral("No backing store transaction found in which to open a cursor"));
469
470     switch (info.cursorSource()) {
471     case IndexedDB::CursorSource::ObjectStore: {
472         auto* objectStore = m_objectStoresByIdentifier.get(info.sourceIdentifier());
473         if (!objectStore)
474             return IDBError(IDBDatabaseException::UnknownError, ASCIILiteral("No backing store object store found"));
475
476         MemoryCursor* cursor = objectStore->maybeOpenCursor(info);
477         if (!cursor)
478             return IDBError(IDBDatabaseException::UnknownError, ASCIILiteral("Could not create object store cursor in backing store"));
479
480         cursor->currentData(outData);
481         break;
482     }
483     case IndexedDB::CursorSource::Index:
484         auto* objectStore = m_objectStoresByIdentifier.get(info.objectStoreIdentifier());
485         if (!objectStore)
486             return IDBError(IDBDatabaseException::UnknownError, ASCIILiteral("No backing store object store found"));
487
488         auto* index = objectStore->indexForIdentifier(info.sourceIdentifier());
489         if (!index)
490             return IDBError(IDBDatabaseException::UnknownError, ASCIILiteral("No backing store index found"));
491
492         MemoryCursor* cursor = index->maybeOpenCursor(info);
493         if (!cursor)
494             return IDBError(IDBDatabaseException::UnknownError, ASCIILiteral("Could not create index cursor in backing store"));
495
496         cursor->currentData(outData);
497         break;
498     }
499
500     return { };
501 }
502
503 IDBError MemoryIDBBackingStore::iterateCursor(const IDBResourceIdentifier& transactionIdentifier, const IDBResourceIdentifier& cursorIdentifier, const IDBKeyData& key, uint32_t count, IDBGetResult& outData)
504 {
505     LOG(IndexedDB, "MemoryIDBBackingStore::iterateCursor");
506
507     if (!m_transactions.contains(transactionIdentifier))
508         return IDBError(IDBDatabaseException::UnknownError, ASCIILiteral("No backing store transaction found in which to iterate cursor"));
509
510     auto* cursor = MemoryCursor::cursorForIdentifier(cursorIdentifier);
511     if (!cursor)
512         return IDBError(IDBDatabaseException::UnknownError, ASCIILiteral("No backing store cursor found in which to iterate cursor"));
513
514     cursor->iterate(key, count, outData);
515
516     return { };
517 }
518
519 void MemoryIDBBackingStore::registerObjectStore(Ref<MemoryObjectStore>&& objectStore)
520 {
521     ASSERT(!m_objectStoresByIdentifier.contains(objectStore->info().identifier()));
522     ASSERT(!m_objectStoresByName.contains(objectStore->info().name()));
523
524     m_objectStoresByName.set(objectStore->info().name(), &objectStore.get());
525     m_objectStoresByIdentifier.set(objectStore->info().identifier(), WTFMove(objectStore));
526 }
527
528 void MemoryIDBBackingStore::unregisterObjectStore(MemoryObjectStore& objectStore)
529 {
530     ASSERT(m_objectStoresByIdentifier.contains(objectStore.info().identifier()));
531     ASSERT(m_objectStoresByName.contains(objectStore.info().name()));
532
533     m_objectStoresByName.remove(objectStore.info().name());
534     m_objectStoresByIdentifier.remove(objectStore.info().identifier());
535 }
536
537 RefPtr<MemoryObjectStore> MemoryIDBBackingStore::takeObjectStoreByIdentifier(uint64_t identifier)
538 {
539     auto objectStoreByIdentifier = m_objectStoresByIdentifier.take(identifier);
540     if (!objectStoreByIdentifier)
541         return nullptr;
542
543     auto objectStore = m_objectStoresByName.take(objectStoreByIdentifier->info().name());
544     ASSERT_UNUSED(objectStore, objectStore);
545
546     return objectStoreByIdentifier;
547 }
548
549 IDBObjectStoreInfo* MemoryIDBBackingStore::infoForObjectStore(uint64_t objectStoreIdentifier)
550 {
551     ASSERT(m_databaseInfo);
552     return m_databaseInfo->infoForExistingObjectStore(objectStoreIdentifier);
553 }
554
555 void MemoryIDBBackingStore::deleteBackingStore()
556 {
557     // The in-memory IDB backing store doesn't need to do any cleanup when it is deleted.
558 }
559
560 } // namespace IDBServer
561 } // namespace WebCore
562
563 #endif // ENABLE(INDEXED_DATABASE)