IndexedDB 2.0: Support IDBObjectStore 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 void MemoryIDBBackingStore::removeObjectStoreForVersionChangeAbort(MemoryObjectStore& objectStore)
252 {
253     LOG(IndexedDB, "MemoryIDBBackingStore::removeObjectStoreForVersionChangeAbort");
254
255     if (!m_objectStoresByIdentifier.contains(objectStore.info().identifier()))
256         return;
257
258     ASSERT(m_objectStoresByIdentifier.get(objectStore.info().identifier()) == &objectStore);
259
260     unregisterObjectStore(objectStore);
261 }
262
263 void MemoryIDBBackingStore::restoreObjectStoreForVersionChangeAbort(Ref<MemoryObjectStore>&& objectStore)
264 {
265     registerObjectStore(WTFMove(objectStore));
266 }
267
268 IDBError MemoryIDBBackingStore::keyExistsInObjectStore(const IDBResourceIdentifier&, uint64_t objectStoreIdentifier, const IDBKeyData& keyData, bool& keyExists)
269 {
270     LOG(IndexedDB, "MemoryIDBBackingStore::keyExistsInObjectStore");
271
272     ASSERT(objectStoreIdentifier);
273
274     MemoryObjectStore* objectStore = m_objectStoresByIdentifier.get(objectStoreIdentifier);
275     RELEASE_ASSERT(objectStore);
276
277     keyExists = objectStore->containsRecord(keyData);
278     return IDBError();
279 }
280
281 IDBError MemoryIDBBackingStore::deleteRange(const IDBResourceIdentifier& transactionIdentifier, uint64_t objectStoreIdentifier, const IDBKeyRangeData& range)
282 {
283     LOG(IndexedDB, "MemoryIDBBackingStore::deleteRange");
284
285     ASSERT(objectStoreIdentifier);
286
287     if (!m_transactions.contains(transactionIdentifier))
288         return IDBError(IDBDatabaseException::UnknownError, ASCIILiteral("No backing store transaction found to delete from"));
289
290     MemoryObjectStore* objectStore = m_objectStoresByIdentifier.get(objectStoreIdentifier);
291     if (!objectStore)
292         return IDBError(IDBDatabaseException::UnknownError, ASCIILiteral("No backing store object store found"));
293
294     objectStore->deleteRange(range);
295     return IDBError();
296 }
297
298 IDBError MemoryIDBBackingStore::addRecord(const IDBResourceIdentifier& transactionIdentifier, const IDBObjectStoreInfo& objectStoreInfo, const IDBKeyData& keyData, const IDBValue& value)
299 {
300     LOG(IndexedDB, "MemoryIDBBackingStore::addRecord");
301
302     ASSERT(objectStoreInfo.identifier());
303
304     auto transaction = m_transactions.get(transactionIdentifier);
305     if (!transaction)
306         return IDBError(IDBDatabaseException::UnknownError, ASCIILiteral("No backing store transaction found to put record"));
307
308     MemoryObjectStore* objectStore = m_objectStoresByIdentifier.get(objectStoreInfo.identifier());
309     if (!objectStore)
310         return IDBError(IDBDatabaseException::UnknownError, ASCIILiteral("No backing store object store found to put record"));
311
312     return objectStore->addRecord(*transaction, keyData, value);
313 }
314
315 IDBError MemoryIDBBackingStore::getRecord(const IDBResourceIdentifier& transactionIdentifier, uint64_t objectStoreIdentifier, const IDBKeyRangeData& range, IDBGetResult& outValue)
316 {
317     LOG(IndexedDB, "MemoryIDBBackingStore::getRecord");
318
319     ASSERT(objectStoreIdentifier);
320
321     if (!m_transactions.contains(transactionIdentifier))
322         return IDBError(IDBDatabaseException::UnknownError, ASCIILiteral("No backing store transaction found to get record"));
323
324     MemoryObjectStore* objectStore = m_objectStoresByIdentifier.get(objectStoreIdentifier);
325     if (!objectStore)
326         return IDBError(IDBDatabaseException::UnknownError, ASCIILiteral("No backing store object store found"));
327
328     outValue = objectStore->valueForKeyRange(range);
329     return IDBError();
330 }
331
332 IDBError MemoryIDBBackingStore::getIndexRecord(const IDBResourceIdentifier& transactionIdentifier, uint64_t objectStoreIdentifier, uint64_t indexIdentifier, IndexedDB::IndexRecordType recordType, const IDBKeyRangeData& range, IDBGetResult& outValue)
333 {
334     LOG(IndexedDB, "MemoryIDBBackingStore::getIndexRecord");
335
336     ASSERT(objectStoreIdentifier);
337
338     if (!m_transactions.contains(transactionIdentifier))
339         return IDBError(IDBDatabaseException::UnknownError, ASCIILiteral("No backing store transaction found to get record"));
340
341     MemoryObjectStore* objectStore = m_objectStoresByIdentifier.get(objectStoreIdentifier);
342     if (!objectStore)
343         return IDBError(IDBDatabaseException::UnknownError, ASCIILiteral("No backing store object store found"));
344
345     outValue = objectStore->indexValueForKeyRange(indexIdentifier, recordType, range);
346     return IDBError();
347 }
348
349 IDBError MemoryIDBBackingStore::getCount(const IDBResourceIdentifier& transactionIdentifier, uint64_t objectStoreIdentifier, uint64_t indexIdentifier, const IDBKeyRangeData& range, uint64_t& outCount)
350 {
351     LOG(IndexedDB, "MemoryIDBBackingStore::getCount");
352
353     ASSERT(objectStoreIdentifier);
354
355     if (!m_transactions.contains(transactionIdentifier))
356         return IDBError(IDBDatabaseException::UnknownError, ASCIILiteral("No backing store transaction found to get count"));
357
358     MemoryObjectStore* objectStore = m_objectStoresByIdentifier.get(objectStoreIdentifier);
359     if (!objectStore)
360         return IDBError(IDBDatabaseException::UnknownError, ASCIILiteral("No backing store object store found"));
361
362     outCount = objectStore->countForKeyRange(indexIdentifier, range);
363
364     return IDBError();
365 }
366
367 IDBError MemoryIDBBackingStore::generateKeyNumber(const IDBResourceIdentifier& transactionIdentifier, uint64_t objectStoreIdentifier, uint64_t& keyNumber)
368 {
369     LOG(IndexedDB, "MemoryIDBBackingStore::generateKeyNumber");
370     ASSERT(objectStoreIdentifier);
371     ASSERT_UNUSED(transactionIdentifier, m_transactions.contains(transactionIdentifier));
372     ASSERT_UNUSED(transactionIdentifier, m_transactions.get(transactionIdentifier)->isWriting());
373
374     MemoryObjectStore* objectStore = m_objectStoresByIdentifier.get(objectStoreIdentifier);
375     RELEASE_ASSERT(objectStore);
376
377     keyNumber = objectStore->currentKeyGeneratorValue();
378     if (keyNumber > maxGeneratedKeyValue)
379         return { IDBDatabaseException::ConstraintError, "Cannot generate new key value over 2^53 for object store operation" };
380
381     objectStore->setKeyGeneratorValue(keyNumber + 1);
382
383     return IDBError();
384 }
385
386 IDBError MemoryIDBBackingStore::revertGeneratedKeyNumber(const IDBResourceIdentifier& transactionIdentifier, uint64_t objectStoreIdentifier, uint64_t keyNumber)
387 {
388     LOG(IndexedDB, "MemoryIDBBackingStore::revertGeneratedKeyNumber");
389     ASSERT(objectStoreIdentifier);
390     ASSERT_UNUSED(transactionIdentifier, m_transactions.contains(transactionIdentifier));
391     ASSERT_UNUSED(transactionIdentifier, m_transactions.get(transactionIdentifier)->isWriting());
392
393     MemoryObjectStore* objectStore = m_objectStoresByIdentifier.get(objectStoreIdentifier);
394     RELEASE_ASSERT(objectStore);
395
396     objectStore->setKeyGeneratorValue(keyNumber);
397
398     return { };
399 }
400
401 IDBError MemoryIDBBackingStore::maybeUpdateKeyGeneratorNumber(const IDBResourceIdentifier& transactionIdentifier, uint64_t objectStoreIdentifier, double newKeyNumber)
402 {
403     LOG(IndexedDB, "MemoryIDBBackingStore::maybeUpdateKeyGeneratorNumber");
404     ASSERT(objectStoreIdentifier);
405     ASSERT_UNUSED(transactionIdentifier, m_transactions.contains(transactionIdentifier));
406     ASSERT_UNUSED(transactionIdentifier, m_transactions.get(transactionIdentifier)->isWriting());
407
408     MemoryObjectStore* objectStore = m_objectStoresByIdentifier.get(objectStoreIdentifier);
409     RELEASE_ASSERT(objectStore);
410
411     if (newKeyNumber < objectStore->currentKeyGeneratorValue())
412         return { };
413
414     uint64_t newKeyInteger(newKeyNumber);
415     if (newKeyInteger <= uint64_t(newKeyNumber))
416         ++newKeyInteger;
417
418     ASSERT(newKeyInteger > uint64_t(newKeyNumber));
419
420     objectStore->setKeyGeneratorValue(newKeyInteger);
421
422     return { };
423 }
424
425 IDBError MemoryIDBBackingStore::openCursor(const IDBResourceIdentifier& transactionIdentifier, const IDBCursorInfo& info, IDBGetResult& outData)
426 {
427     LOG(IndexedDB, "MemoryIDBBackingStore::openCursor");
428
429     ASSERT(!MemoryCursor::cursorForIdentifier(info.identifier()));
430
431     if (!m_transactions.contains(transactionIdentifier))
432         return IDBError(IDBDatabaseException::UnknownError, ASCIILiteral("No backing store transaction found in which to open a cursor"));
433
434     switch (info.cursorSource()) {
435     case IndexedDB::CursorSource::ObjectStore: {
436         auto* objectStore = m_objectStoresByIdentifier.get(info.sourceIdentifier());
437         if (!objectStore)
438             return IDBError(IDBDatabaseException::UnknownError, ASCIILiteral("No backing store object store found"));
439
440         MemoryCursor* cursor = objectStore->maybeOpenCursor(info);
441         if (!cursor)
442             return IDBError(IDBDatabaseException::UnknownError, ASCIILiteral("Could not create object store cursor in backing store"));
443
444         cursor->currentData(outData);
445         break;
446     }
447     case IndexedDB::CursorSource::Index:
448         auto* objectStore = m_objectStoresByIdentifier.get(info.objectStoreIdentifier());
449         if (!objectStore)
450             return IDBError(IDBDatabaseException::UnknownError, ASCIILiteral("No backing store object store found"));
451
452         auto* index = objectStore->indexForIdentifier(info.sourceIdentifier());
453         if (!index)
454             return IDBError(IDBDatabaseException::UnknownError, ASCIILiteral("No backing store index found"));
455
456         MemoryCursor* cursor = index->maybeOpenCursor(info);
457         if (!cursor)
458             return IDBError(IDBDatabaseException::UnknownError, ASCIILiteral("Could not create index cursor in backing store"));
459
460         cursor->currentData(outData);
461         break;
462     }
463
464     return { };
465 }
466
467 IDBError MemoryIDBBackingStore::iterateCursor(const IDBResourceIdentifier& transactionIdentifier, const IDBResourceIdentifier& cursorIdentifier, const IDBKeyData& key, uint32_t count, IDBGetResult& outData)
468 {
469     LOG(IndexedDB, "MemoryIDBBackingStore::iterateCursor");
470
471     if (!m_transactions.contains(transactionIdentifier))
472         return IDBError(IDBDatabaseException::UnknownError, ASCIILiteral("No backing store transaction found in which to iterate cursor"));
473
474     auto* cursor = MemoryCursor::cursorForIdentifier(cursorIdentifier);
475     if (!cursor)
476         return IDBError(IDBDatabaseException::UnknownError, ASCIILiteral("No backing store cursor found in which to iterate cursor"));
477
478     cursor->iterate(key, count, outData);
479
480     return { };
481 }
482
483 void MemoryIDBBackingStore::registerObjectStore(Ref<MemoryObjectStore>&& objectStore)
484 {
485     ASSERT(!m_objectStoresByIdentifier.contains(objectStore->info().identifier()));
486     ASSERT(!m_objectStoresByName.contains(objectStore->info().name()));
487
488     m_objectStoresByName.set(objectStore->info().name(), &objectStore.get());
489     m_objectStoresByIdentifier.set(objectStore->info().identifier(), WTFMove(objectStore));
490 }
491
492 void MemoryIDBBackingStore::unregisterObjectStore(MemoryObjectStore& objectStore)
493 {
494     ASSERT(m_objectStoresByIdentifier.contains(objectStore.info().identifier()));
495     ASSERT(m_objectStoresByName.contains(objectStore.info().name()));
496
497     m_objectStoresByName.remove(objectStore.info().name());
498     m_objectStoresByIdentifier.remove(objectStore.info().identifier());
499 }
500
501 RefPtr<MemoryObjectStore> MemoryIDBBackingStore::takeObjectStoreByIdentifier(uint64_t identifier)
502 {
503     auto objectStoreByIdentifier = m_objectStoresByIdentifier.take(identifier);
504     if (!objectStoreByIdentifier)
505         return nullptr;
506
507     auto objectStore = m_objectStoresByName.take(objectStoreByIdentifier->info().name());
508     ASSERT_UNUSED(objectStore, objectStore);
509
510     return objectStoreByIdentifier;
511 }
512
513 IDBObjectStoreInfo* MemoryIDBBackingStore::infoForObjectStore(uint64_t objectStoreIdentifier)
514 {
515     ASSERT(m_databaseInfo);
516     return m_databaseInfo->infoForExistingObjectStore(objectStoreIdentifier);
517 }
518
519 void MemoryIDBBackingStore::deleteBackingStore()
520 {
521     // The in-memory IDB backing store doesn't need to do any cleanup when it is deleted.
522 }
523
524 } // namespace IDBServer
525 } // namespace WebCore
526
527 #endif // ENABLE(INDEXED_DATABASE)