Wed, 31 Dec 2014 06:09:35 +0100
Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.
1 /* This Source Code Form is subject to the terms of the Mozilla Public
2 * License, v. 2.0. If a copy of the MPL was not distributed with this file,
3 * You can obtain one at http://mozilla.org/MPL/2.0/. */
5 #include "base/basictypes.h"
7 #include "IndexedDBChild.h"
9 #include "nsIInputStream.h"
11 #include "mozilla/Assertions.h"
12 #include "mozilla/dom/ContentChild.h"
13 #include "mozilla/dom/quota/Client.h"
14 #include "mozilla/dom/quota/QuotaManager.h"
16 #include "AsyncConnectionHelper.h"
17 #include "DatabaseInfo.h"
18 #include "IDBEvents.h"
19 #include "IDBFactory.h"
20 #include "IDBIndex.h"
21 #include "IDBObjectStore.h"
22 #include "IDBTransaction.h"
24 USING_INDEXEDDB_NAMESPACE
26 using namespace mozilla::dom;
27 using mozilla::dom::quota::Client;
28 using mozilla::dom::quota::QuotaManager;
30 namespace {
32 class IPCOpenDatabaseHelper : public AsyncConnectionHelper
33 {
34 public:
35 IPCOpenDatabaseHelper(IDBDatabase* aDatabase, IDBOpenDBRequest* aRequest)
36 : AsyncConnectionHelper(aDatabase, aRequest)
37 {
38 MOZ_ASSERT(aRequest);
39 }
41 virtual nsresult UnpackResponseFromParentProcess(
42 const ResponseValue& aResponseValue)
43 MOZ_OVERRIDE;
45 virtual ChildProcessSendResult
46 SendResponseToChildProcess(nsresult aResultCode) MOZ_OVERRIDE;
48 virtual nsresult
49 GetSuccessResult(JSContext* aCx, JS::MutableHandle<JS::Value> aVal) MOZ_OVERRIDE;
51 virtual nsresult
52 OnSuccess() MOZ_OVERRIDE
53 {
54 static_cast<IDBOpenDBRequest*>(mRequest.get())->SetTransaction(nullptr);
55 return AsyncConnectionHelper::OnSuccess();
56 }
58 virtual void
59 OnError() MOZ_OVERRIDE
60 {
61 static_cast<IDBOpenDBRequest*>(mRequest.get())->SetTransaction(nullptr);
62 AsyncConnectionHelper::OnError();
63 }
65 virtual nsresult
66 DoDatabaseWork(mozIStorageConnection* aConnection) MOZ_OVERRIDE;
67 };
69 class IPCSetVersionHelper : public AsyncConnectionHelper
70 {
71 nsRefPtr<IDBOpenDBRequest> mOpenRequest;
72 uint64_t mOldVersion;
73 uint64_t mRequestedVersion;
75 public:
76 IPCSetVersionHelper(IDBTransaction* aTransaction, IDBOpenDBRequest* aRequest,
77 uint64_t aOldVersion, uint64_t aRequestedVersion)
78 : AsyncConnectionHelper(aTransaction, aRequest),
79 mOpenRequest(aRequest), mOldVersion(aOldVersion),
80 mRequestedVersion(aRequestedVersion)
81 {
82 MOZ_ASSERT(aTransaction);
83 MOZ_ASSERT(aRequest);
84 }
86 virtual nsresult UnpackResponseFromParentProcess(
87 const ResponseValue& aResponseValue)
88 MOZ_OVERRIDE;
90 virtual ChildProcessSendResult
91 SendResponseToChildProcess(nsresult aResultCode) MOZ_OVERRIDE;
93 virtual nsresult
94 DoDatabaseWork(mozIStorageConnection* aConnection) MOZ_OVERRIDE;
96 virtual already_AddRefed<nsIDOMEvent>
97 CreateSuccessEvent(mozilla::dom::EventTarget* aOwner) MOZ_OVERRIDE;
99 virtual nsresult
100 GetSuccessResult(JSContext* aCx, JS::MutableHandle<JS::Value> aVal) MOZ_OVERRIDE;
101 };
103 class IPCDeleteDatabaseHelper : public AsyncConnectionHelper
104 {
105 public:
106 IPCDeleteDatabaseHelper(IDBRequest* aRequest)
107 : AsyncConnectionHelper(static_cast<IDBDatabase*>(nullptr), aRequest)
108 { }
110 virtual nsresult UnpackResponseFromParentProcess(
111 const ResponseValue& aResponseValue)
112 MOZ_OVERRIDE;
114 virtual ChildProcessSendResult
115 SendResponseToChildProcess(nsresult aResultCode) MOZ_OVERRIDE;
117 virtual nsresult
118 GetSuccessResult(JSContext* aCx, JS::MutableHandle<JS::Value> aVal) MOZ_OVERRIDE;
120 virtual nsresult
121 DoDatabaseWork(mozIStorageConnection* aConnection) MOZ_OVERRIDE;
122 };
124 class VersionChangeRunnable : public nsRunnable
125 {
126 nsRefPtr<IDBDatabase> mDatabase;
127 uint64_t mOldVersion;
128 uint64_t mNewVersion;
130 public:
131 VersionChangeRunnable(IDBDatabase* aDatabase, const uint64_t& aOldVersion,
132 const uint64_t& aNewVersion)
133 : mDatabase(aDatabase), mOldVersion(aOldVersion), mNewVersion(aNewVersion)
134 {
135 MOZ_ASSERT(aDatabase);
136 }
138 NS_IMETHOD Run() MOZ_OVERRIDE
139 {
140 if (mDatabase->IsClosed()) {
141 return NS_OK;
142 }
144 nsRefPtr<Event> event =
145 IDBVersionChangeEvent::Create(mDatabase, mOldVersion, mNewVersion);
146 MOZ_ASSERT(event);
148 bool dummy;
149 nsresult rv = mDatabase->DispatchEvent(event, &dummy);
150 NS_ENSURE_SUCCESS(rv, rv);
152 return NS_OK;
153 }
154 };
156 } // anonymous namespace
158 /*******************************************************************************
159 * IndexedDBChild
160 ******************************************************************************/
162 IndexedDBChild::IndexedDBChild(const nsCString& aASCIIOrigin)
163 : mFactory(nullptr), mASCIIOrigin(aASCIIOrigin)
164 #ifdef DEBUG
165 , mDisconnected(false)
166 #endif
167 {
168 MOZ_COUNT_CTOR(IndexedDBChild);
169 }
171 IndexedDBChild::~IndexedDBChild()
172 {
173 MOZ_COUNT_DTOR(IndexedDBChild);
174 MOZ_ASSERT(!mFactory);
175 }
177 void
178 IndexedDBChild::SetFactory(IDBFactory* aFactory)
179 {
180 MOZ_ASSERT(aFactory);
181 MOZ_ASSERT(!mFactory);
183 aFactory->SetActor(this);
184 mFactory = aFactory;
185 }
187 void
188 IndexedDBChild::Disconnect()
189 {
190 #ifdef DEBUG
191 MOZ_ASSERT(!mDisconnected);
192 mDisconnected = true;
193 #endif
195 const InfallibleTArray<PIndexedDBDatabaseChild*>& databases =
196 ManagedPIndexedDBDatabaseChild();
197 for (uint32_t i = 0; i < databases.Length(); ++i) {
198 static_cast<IndexedDBDatabaseChild*>(databases[i])->Disconnect();
199 }
200 }
202 void
203 IndexedDBChild::ActorDestroy(ActorDestroyReason aWhy)
204 {
205 if (mFactory) {
206 mFactory->SetActor(static_cast<IndexedDBChild*>(nullptr));
207 #ifdef DEBUG
208 mFactory = nullptr;
209 #endif
210 }
211 }
213 PIndexedDBDatabaseChild*
214 IndexedDBChild::AllocPIndexedDBDatabaseChild(
215 const nsString& aName,
216 const uint64_t& aVersion,
217 const PersistenceType& aPersistenceType)
218 {
219 return new IndexedDBDatabaseChild(aName, aVersion);
220 }
222 bool
223 IndexedDBChild::DeallocPIndexedDBDatabaseChild(PIndexedDBDatabaseChild* aActor)
224 {
225 delete aActor;
226 return true;
227 }
229 PIndexedDBDeleteDatabaseRequestChild*
230 IndexedDBChild::AllocPIndexedDBDeleteDatabaseRequestChild(
231 const nsString& aName,
232 const PersistenceType& aPersistenceType)
233 {
234 MOZ_CRASH("Caller is supposed to manually construct a request!");
235 }
237 bool
238 IndexedDBChild::DeallocPIndexedDBDeleteDatabaseRequestChild(
239 PIndexedDBDeleteDatabaseRequestChild* aActor)
240 {
241 delete aActor;
242 return true;
243 }
245 /*******************************************************************************
246 * IndexedDBDatabaseChild
247 ******************************************************************************/
249 IndexedDBDatabaseChild::IndexedDBDatabaseChild(const nsString& aName,
250 uint64_t aVersion)
251 : mDatabase(nullptr), mName(aName), mVersion(aVersion)
252 {
253 MOZ_COUNT_CTOR(IndexedDBDatabaseChild);
254 }
256 IndexedDBDatabaseChild::~IndexedDBDatabaseChild()
257 {
258 MOZ_COUNT_DTOR(IndexedDBDatabaseChild);
259 MOZ_ASSERT(!mDatabase);
260 MOZ_ASSERT(!mStrongDatabase);
261 }
263 void
264 IndexedDBDatabaseChild::SetRequest(IDBOpenDBRequest* aRequest)
265 {
266 MOZ_ASSERT(aRequest);
267 MOZ_ASSERT(!mRequest);
269 mRequest = aRequest;
270 }
272 void
273 IndexedDBDatabaseChild::Disconnect()
274 {
275 const InfallibleTArray<PIndexedDBTransactionChild*>& transactions =
276 ManagedPIndexedDBTransactionChild();
277 for (uint32_t i = 0; i < transactions.Length(); ++i) {
278 static_cast<IndexedDBTransactionChild*>(transactions[i])->Disconnect();
279 }
280 }
282 bool
283 IndexedDBDatabaseChild::EnsureDatabase(
284 IDBOpenDBRequest* aRequest,
285 const DatabaseInfoGuts& aDBInfo,
286 const InfallibleTArray<ObjectStoreInfoGuts>& aOSInfo)
287 {
288 nsCString databaseId;
289 if (mDatabase) {
290 databaseId = mDatabase->Id();
291 }
292 else {
293 QuotaManager::GetStorageId(aDBInfo.persistenceType, aDBInfo.origin,
294 Client::IDB, aDBInfo.name, databaseId);
295 }
296 MOZ_ASSERT(!databaseId.IsEmpty());
298 nsRefPtr<DatabaseInfo> dbInfo;
299 if (DatabaseInfo::Get(databaseId, getter_AddRefs(dbInfo))) {
300 dbInfo->version = aDBInfo.version;
301 }
302 else {
303 nsRefPtr<DatabaseInfo> newInfo = new DatabaseInfo();
305 *static_cast<DatabaseInfoGuts*>(newInfo.get()) = aDBInfo;
306 newInfo->id = databaseId;
308 if (!DatabaseInfo::Put(newInfo)) {
309 NS_WARNING("Out of memory!");
310 return false;
311 }
313 newInfo.swap(dbInfo);
315 // This is more or less copied from IDBFactory::SetDatabaseMetadata.
316 for (uint32_t i = 0; i < aOSInfo.Length(); i++) {
317 nsRefPtr<ObjectStoreInfo> newInfo = new ObjectStoreInfo();
318 *static_cast<ObjectStoreInfoGuts*>(newInfo.get()) = aOSInfo[i];
320 if (!dbInfo->PutObjectStore(newInfo)) {
321 NS_WARNING("Out of memory!");
322 return false;
323 }
324 }
325 }
327 if (!mDatabase) {
328 nsRefPtr<IDBDatabase> database =
329 IDBDatabase::Create(aRequest, aRequest->Factory(), dbInfo.forget(),
330 aDBInfo.origin, nullptr, nullptr);
331 if (!database) {
332 NS_WARNING("Failed to create database!");
333 return false;
334 }
336 database->SetActor(this);
338 mDatabase = database;
339 mStrongDatabase = database.forget();
340 }
342 return true;
343 }
345 void
346 IndexedDBDatabaseChild::ActorDestroy(ActorDestroyReason aWhy)
347 {
348 if (mDatabase) {
349 mDatabase->SetActor(static_cast<IndexedDBDatabaseChild*>(nullptr));
350 #ifdef DEBUG
351 mDatabase = nullptr;
352 #endif
353 }
354 }
356 bool
357 IndexedDBDatabaseChild::RecvSuccess(
358 const DatabaseInfoGuts& aDBInfo,
359 const InfallibleTArray<ObjectStoreInfoGuts>& aOSInfo)
360 {
361 #ifdef DEBUG
362 {
363 IndexedDBChild* manager = static_cast<IndexedDBChild*>(Manager());
364 MOZ_ASSERT(aDBInfo.origin == manager->ASCIIOrigin());
365 MOZ_ASSERT(aDBInfo.name == mName);
366 MOZ_ASSERT(!mVersion || aDBInfo.version == mVersion);
367 }
368 #endif
370 MOZ_ASSERT(mRequest);
372 nsRefPtr<IDBOpenDBRequest> request;
373 mRequest.swap(request);
375 nsRefPtr<AsyncConnectionHelper> openHelper;
376 mOpenHelper.swap(openHelper);
378 if (!EnsureDatabase(request, aDBInfo, aOSInfo)) {
379 return false;
380 }
382 MOZ_ASSERT(mStrongDatabase);
383 nsRefPtr<IDBDatabase> database;
384 mStrongDatabase.swap(database);
386 if (openHelper) {
387 request->Reset();
388 }
389 else {
390 openHelper = new IPCOpenDatabaseHelper(mDatabase, request);
391 }
393 ImmediateRunEventTarget target;
394 if (NS_FAILED(openHelper->Dispatch(&target))) {
395 NS_WARNING("Dispatch of IPCOpenDatabaseHelper failed!");
396 return false;
397 }
399 return true;
400 }
402 bool
403 IndexedDBDatabaseChild::RecvError(const nsresult& aRv)
404 {
405 MOZ_ASSERT(mRequest);
407 nsRefPtr<IDBOpenDBRequest> request;
408 mRequest.swap(request);
410 nsRefPtr<IDBDatabase> database;
411 mStrongDatabase.swap(database);
413 nsRefPtr<AsyncConnectionHelper> openHelper;
414 mOpenHelper.swap(openHelper);
416 if (openHelper) {
417 request->Reset();
418 }
419 else {
420 openHelper = new IPCOpenDatabaseHelper(nullptr, request);
421 }
423 openHelper->SetError(aRv);
425 ImmediateRunEventTarget target;
426 if (NS_FAILED(openHelper->Dispatch(&target))) {
427 NS_WARNING("Dispatch of IPCOpenDatabaseHelper failed!");
428 return false;
429 }
431 return true;
432 }
434 bool
435 IndexedDBDatabaseChild::RecvBlocked(const uint64_t& aOldVersion)
436 {
437 MOZ_ASSERT(mRequest);
438 MOZ_ASSERT(!mDatabase);
440 nsCOMPtr<nsIRunnable> runnable =
441 IDBVersionChangeEvent::CreateBlockedRunnable(mRequest, aOldVersion, mVersion);
443 ImmediateRunEventTarget target;
444 if (NS_FAILED(target.Dispatch(runnable, NS_DISPATCH_NORMAL))) {
445 NS_WARNING("Dispatch of blocked event failed!");
446 }
448 return true;
449 }
451 bool
452 IndexedDBDatabaseChild::RecvVersionChange(const uint64_t& aOldVersion,
453 const uint64_t& aNewVersion)
454 {
455 MOZ_ASSERT(mDatabase);
457 nsCOMPtr<nsIRunnable> runnable =
458 new VersionChangeRunnable(mDatabase, aOldVersion, aNewVersion);
460 ImmediateRunEventTarget target;
461 if (NS_FAILED(target.Dispatch(runnable, NS_DISPATCH_NORMAL))) {
462 NS_WARNING("Dispatch of versionchange event failed!");
463 }
465 return true;
466 }
468 bool
469 IndexedDBDatabaseChild::RecvInvalidate()
470 {
471 if (mDatabase) {
472 mDatabase->Invalidate();
473 }
474 return true;
475 }
477 bool
478 IndexedDBDatabaseChild::RecvPIndexedDBTransactionConstructor(
479 PIndexedDBTransactionChild* aActor,
480 const TransactionParams& aParams)
481 {
482 // This only happens when the parent has created a version-change transaction
483 // for us.
485 IndexedDBTransactionChild* actor =
486 static_cast<IndexedDBTransactionChild*>(aActor);
487 MOZ_ASSERT(!actor->GetTransaction());
489 MOZ_ASSERT(aParams.type() ==
490 TransactionParams::TVersionChangeTransactionParams);
492 const VersionChangeTransactionParams& params =
493 aParams.get_VersionChangeTransactionParams();
495 const DatabaseInfoGuts& dbInfo = params.dbInfo();
496 const InfallibleTArray<ObjectStoreInfoGuts>& osInfo = params.osInfo();
497 uint64_t oldVersion = params.oldVersion();
499 MOZ_ASSERT(dbInfo.origin ==
500 static_cast<IndexedDBChild*>(Manager())->ASCIIOrigin());
501 MOZ_ASSERT(dbInfo.name == mName);
502 MOZ_ASSERT(!mVersion || dbInfo.version == mVersion);
503 MOZ_ASSERT(!mVersion || oldVersion < mVersion);
505 MOZ_ASSERT(mRequest);
506 MOZ_ASSERT(!mDatabase);
507 MOZ_ASSERT(!mOpenHelper);
509 if (!EnsureDatabase(mRequest, dbInfo, osInfo)) {
510 return false;
511 }
513 nsRefPtr<IPCOpenDatabaseHelper> helper =
514 new IPCOpenDatabaseHelper(mDatabase, mRequest);
516 Sequence<nsString> storesToOpen;
517 nsRefPtr<IDBTransaction> transaction =
518 IDBTransaction::CreateInternal(mDatabase, storesToOpen,
519 IDBTransaction::VERSION_CHANGE, false, true);
520 NS_ENSURE_TRUE(transaction, false);
522 nsRefPtr<IPCSetVersionHelper> versionHelper =
523 new IPCSetVersionHelper(transaction, mRequest, oldVersion, mVersion);
525 mDatabase->EnterSetVersionTransaction();
526 mDatabase->mPreviousDatabaseInfo->version = oldVersion;
528 actor->SetTransaction(transaction);
530 ImmediateRunEventTarget target;
531 if (NS_FAILED(versionHelper->Dispatch(&target))) {
532 NS_WARNING("Dispatch of IPCSetVersionHelper failed!");
533 return false;
534 }
536 mOpenHelper = helper.forget();
537 return true;
538 }
540 PIndexedDBTransactionChild*
541 IndexedDBDatabaseChild::AllocPIndexedDBTransactionChild(
542 const TransactionParams& aParams)
543 {
544 MOZ_ASSERT(aParams.type() ==
545 TransactionParams::TVersionChangeTransactionParams);
546 return new IndexedDBTransactionChild();
547 }
549 bool
550 IndexedDBDatabaseChild::DeallocPIndexedDBTransactionChild(
551 PIndexedDBTransactionChild* aActor)
552 {
553 delete aActor;
554 return true;
555 }
557 /*******************************************************************************
558 * IndexedDBTransactionChild
559 ******************************************************************************/
561 IndexedDBTransactionChild::IndexedDBTransactionChild()
562 : mTransaction(nullptr)
563 {
564 MOZ_COUNT_CTOR(IndexedDBTransactionChild);
565 }
567 IndexedDBTransactionChild::~IndexedDBTransactionChild()
568 {
569 MOZ_COUNT_DTOR(IndexedDBTransactionChild);
570 MOZ_ASSERT(!mTransaction);
571 MOZ_ASSERT(!mStrongTransaction);
572 }
574 void
575 IndexedDBTransactionChild::SetTransaction(IDBTransaction* aTransaction)
576 {
577 MOZ_ASSERT(aTransaction);
578 MOZ_ASSERT(!mTransaction);
580 aTransaction->SetActor(this);
582 mTransaction = aTransaction;
583 mStrongTransaction = aTransaction;
584 }
586 void
587 IndexedDBTransactionChild::Disconnect()
588 {
589 const InfallibleTArray<PIndexedDBObjectStoreChild*>& objectStores =
590 ManagedPIndexedDBObjectStoreChild();
591 for (uint32_t i = 0; i < objectStores.Length(); ++i) {
592 static_cast<IndexedDBObjectStoreChild*>(objectStores[i])->Disconnect();
593 }
594 }
596 void
597 IndexedDBTransactionChild::FireCompleteEvent(nsresult aRv)
598 {
599 MOZ_ASSERT(mTransaction);
600 MOZ_ASSERT(mStrongTransaction);
602 nsRefPtr<IDBTransaction> transaction;
603 mStrongTransaction.swap(transaction);
605 if (transaction->GetMode() == IDBTransaction::VERSION_CHANGE) {
606 transaction->Database()->ExitSetVersionTransaction();
607 }
609 nsRefPtr<CommitHelper> helper = new CommitHelper(transaction, aRv);
611 ImmediateRunEventTarget target;
612 if (NS_FAILED(target.Dispatch(helper, NS_DISPATCH_NORMAL))) {
613 NS_WARNING("Dispatch of CommitHelper failed!");
614 }
615 }
617 void
618 IndexedDBTransactionChild::ActorDestroy(ActorDestroyReason aWhy)
619 {
620 if (mStrongTransaction) {
621 // We're being torn down before we received a complete event from the parent
622 // so fake one here.
623 FireCompleteEvent(NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
625 MOZ_ASSERT(!mStrongTransaction);
626 }
628 if (mTransaction) {
629 mTransaction->SetActor(static_cast<IndexedDBTransactionChild*>(nullptr));
630 #ifdef DEBUG
631 mTransaction = nullptr;
632 #endif
633 }
634 }
636 bool
637 IndexedDBTransactionChild::RecvComplete(const CompleteParams& aParams)
638 {
639 MOZ_ASSERT(mTransaction);
640 MOZ_ASSERT(mStrongTransaction);
642 nsresult resultCode;
644 switch (aParams.type()) {
645 case CompleteParams::TCompleteResult:
646 resultCode = NS_OK;
647 break;
648 case CompleteParams::TAbortResult:
649 resultCode = aParams.get_AbortResult().errorCode();
650 if (NS_SUCCEEDED(resultCode)) {
651 resultCode = NS_ERROR_DOM_INDEXEDDB_ABORT_ERR;
652 }
653 break;
655 default:
656 MOZ_CRASH("Unknown union type!");
657 }
659 FireCompleteEvent(resultCode);
660 return true;
661 }
663 PIndexedDBObjectStoreChild*
664 IndexedDBTransactionChild::AllocPIndexedDBObjectStoreChild(
665 const ObjectStoreConstructorParams& aParams)
666 {
667 MOZ_CRASH("Caller is supposed to manually construct an object store!");
668 }
670 bool
671 IndexedDBTransactionChild::DeallocPIndexedDBObjectStoreChild(
672 PIndexedDBObjectStoreChild* aActor)
673 {
674 delete aActor;
675 return true;
676 }
678 /*******************************************************************************
679 * IndexedDBObjectStoreChild
680 ******************************************************************************/
682 IndexedDBObjectStoreChild::IndexedDBObjectStoreChild(
683 IDBObjectStore* aObjectStore)
684 : mObjectStore(aObjectStore)
685 {
686 MOZ_COUNT_CTOR(IndexedDBObjectStoreChild);
687 aObjectStore->SetActor(this);
688 }
690 IndexedDBObjectStoreChild::~IndexedDBObjectStoreChild()
691 {
692 MOZ_COUNT_DTOR(IndexedDBObjectStoreChild);
693 MOZ_ASSERT(!mObjectStore);
694 }
696 void
697 IndexedDBObjectStoreChild::Disconnect()
698 {
699 const InfallibleTArray<PIndexedDBRequestChild*>& requests =
700 ManagedPIndexedDBRequestChild();
701 for (uint32_t i = 0; i < requests.Length(); ++i) {
702 static_cast<IndexedDBRequestChildBase*>(requests[i])->Disconnect();
703 }
705 const InfallibleTArray<PIndexedDBIndexChild*>& indexes =
706 ManagedPIndexedDBIndexChild();
707 for (uint32_t i = 0; i < indexes.Length(); ++i) {
708 static_cast<IndexedDBIndexChild*>(indexes[i])->Disconnect();
709 }
711 const InfallibleTArray<PIndexedDBCursorChild*>& cursors =
712 ManagedPIndexedDBCursorChild();
713 for (uint32_t i = 0; i < cursors.Length(); ++i) {
714 static_cast<IndexedDBCursorChild*>(cursors[i])->Disconnect();
715 }
716 }
718 void
719 IndexedDBObjectStoreChild::ActorDestroy(ActorDestroyReason aWhy)
720 {
721 if (mObjectStore) {
722 mObjectStore->SetActor(static_cast<IndexedDBObjectStoreChild*>(nullptr));
723 #ifdef DEBUG
724 mObjectStore = nullptr;
725 #endif
726 }
727 }
729 bool
730 IndexedDBObjectStoreChild::RecvPIndexedDBCursorConstructor(
731 PIndexedDBCursorChild* aActor,
732 const ObjectStoreCursorConstructorParams& aParams)
733 {
734 IndexedDBCursorChild* actor = static_cast<IndexedDBCursorChild*>(aActor);
736 IndexedDBObjectStoreRequestChild* requestActor =
737 static_cast<IndexedDBObjectStoreRequestChild*>(aParams.requestChild());
738 NS_ASSERTION(requestActor, "Must have an actor here!");
740 nsRefPtr<IDBRequest> request = requestActor->GetRequest();
741 NS_ASSERTION(request, "Must have a request here!");
743 size_t direction = static_cast<size_t>(aParams.direction());
745 nsRefPtr<IDBCursor> cursor;
746 nsresult rv;
748 typedef ipc::OptionalStructuredCloneReadInfo CursorUnionType;
750 switch (aParams.optionalCloneInfo().type()) {
751 case CursorUnionType::TSerializedStructuredCloneReadInfo: {
752 nsTArray<StructuredCloneFile> blobs;
753 IDBObjectStore::ConvertActorsToBlobs(aParams.blobsChild(), blobs);
755 const SerializedStructuredCloneReadInfo& cloneInfo =
756 aParams.optionalCloneInfo().get_SerializedStructuredCloneReadInfo();
758 rv = mObjectStore->OpenCursorFromChildProcess(request, direction,
759 aParams.key(), cloneInfo,
760 blobs,
761 getter_AddRefs(cursor));
762 NS_ENSURE_SUCCESS(rv, false);
764 MOZ_ASSERT(blobs.IsEmpty(), "Should have swapped blob elements!");
765 } break;
767 case CursorUnionType::Tvoid_t:
768 MOZ_ASSERT(aParams.blobsChild().IsEmpty());
770 rv = mObjectStore->OpenCursorFromChildProcess(request, direction,
771 aParams.key(),
772 getter_AddRefs(cursor));
773 NS_ENSURE_SUCCESS(rv, false);
774 break;
776 default:
777 MOZ_CRASH("Unknown union type!");
778 }
780 actor->SetCursor(cursor);
781 return true;
782 }
784 PIndexedDBRequestChild*
785 IndexedDBObjectStoreChild::AllocPIndexedDBRequestChild(
786 const ObjectStoreRequestParams& aParams)
787 {
788 MOZ_CRASH("Caller is supposed to manually construct a request!");
789 }
791 bool
792 IndexedDBObjectStoreChild::DeallocPIndexedDBRequestChild(
793 PIndexedDBRequestChild* aActor)
794 {
795 delete aActor;
796 return false;
797 }
799 PIndexedDBIndexChild*
800 IndexedDBObjectStoreChild::AllocPIndexedDBIndexChild(
801 const IndexConstructorParams& aParams)
802 {
803 MOZ_CRASH("Caller is supposed to manually construct an index!");
804 }
806 bool
807 IndexedDBObjectStoreChild::DeallocPIndexedDBIndexChild(PIndexedDBIndexChild* aActor)
808 {
809 delete aActor;
810 return true;
811 }
813 PIndexedDBCursorChild*
814 IndexedDBObjectStoreChild::AllocPIndexedDBCursorChild(
815 const ObjectStoreCursorConstructorParams& aParams)
816 {
817 return new IndexedDBCursorChild();
818 }
820 bool
821 IndexedDBObjectStoreChild::DeallocPIndexedDBCursorChild(
822 PIndexedDBCursorChild* aActor)
823 {
824 delete aActor;
825 return true;
826 }
828 /*******************************************************************************
829 * IndexedDBIndexChild
830 ******************************************************************************/
832 IndexedDBIndexChild::IndexedDBIndexChild(IDBIndex* aIndex)
833 : mIndex(aIndex)
834 {
835 MOZ_COUNT_CTOR(IndexedDBIndexChild);
836 aIndex->SetActor(this);
837 }
839 IndexedDBIndexChild::~IndexedDBIndexChild()
840 {
841 MOZ_COUNT_DTOR(IndexedDBIndexChild);
842 MOZ_ASSERT(!mIndex);
843 }
845 void
846 IndexedDBIndexChild::Disconnect()
847 {
848 const InfallibleTArray<PIndexedDBRequestChild*>& requests =
849 ManagedPIndexedDBRequestChild();
850 for (uint32_t i = 0; i < requests.Length(); ++i) {
851 static_cast<IndexedDBRequestChildBase*>(requests[i])->Disconnect();
852 }
854 const InfallibleTArray<PIndexedDBCursorChild*>& cursors =
855 ManagedPIndexedDBCursorChild();
856 for (uint32_t i = 0; i < cursors.Length(); ++i) {
857 static_cast<IndexedDBCursorChild*>(cursors[i])->Disconnect();
858 }
859 }
861 void
862 IndexedDBIndexChild::ActorDestroy(ActorDestroyReason aWhy)
863 {
864 if (mIndex) {
865 mIndex->SetActor(static_cast<IndexedDBIndexChild*>(nullptr));
866 #ifdef DEBUG
867 mIndex = nullptr;
868 #endif
869 }
870 }
872 bool
873 IndexedDBIndexChild::RecvPIndexedDBCursorConstructor(
874 PIndexedDBCursorChild* aActor,
875 const IndexCursorConstructorParams& aParams)
876 {
877 IndexedDBCursorChild* actor = static_cast<IndexedDBCursorChild*>(aActor);
879 IndexedDBObjectStoreRequestChild* requestActor =
880 static_cast<IndexedDBObjectStoreRequestChild*>(aParams.requestChild());
881 NS_ASSERTION(requestActor, "Must have an actor here!");
883 nsRefPtr<IDBRequest> request = requestActor->GetRequest();
884 NS_ASSERTION(request, "Must have a request here!");
886 size_t direction = static_cast<size_t>(aParams.direction());
888 nsRefPtr<IDBCursor> cursor;
889 nsresult rv;
891 typedef ipc::OptionalStructuredCloneReadInfo CursorUnionType;
893 switch (aParams.optionalCloneInfo().type()) {
894 case CursorUnionType::TSerializedStructuredCloneReadInfo: {
895 nsTArray<StructuredCloneFile> blobs;
896 IDBObjectStore::ConvertActorsToBlobs(aParams.blobsChild(), blobs);
898 const SerializedStructuredCloneReadInfo& cloneInfo =
899 aParams.optionalCloneInfo().get_SerializedStructuredCloneReadInfo();
901 rv = mIndex->OpenCursorFromChildProcess(request, direction, aParams.key(),
902 aParams.objectKey(), cloneInfo,
903 blobs,
904 getter_AddRefs(cursor));
905 NS_ENSURE_SUCCESS(rv, false);
906 } break;
908 case CursorUnionType::Tvoid_t:
909 MOZ_ASSERT(aParams.blobsChild().IsEmpty());
911 rv = mIndex->OpenCursorFromChildProcess(request, direction, aParams.key(),
912 aParams.objectKey(),
913 getter_AddRefs(cursor));
914 NS_ENSURE_SUCCESS(rv, false);
915 break;
917 default:
918 MOZ_CRASH("Unknown union type!");
919 }
921 actor->SetCursor(cursor);
922 return true;
923 }
925 PIndexedDBRequestChild*
926 IndexedDBIndexChild::AllocPIndexedDBRequestChild(const IndexRequestParams& aParams)
927 {
928 MOZ_CRASH("Caller is supposed to manually construct a request!");
929 }
931 bool
932 IndexedDBIndexChild::DeallocPIndexedDBRequestChild(PIndexedDBRequestChild* aActor)
933 {
934 delete aActor;
935 return true;
936 }
938 PIndexedDBCursorChild*
939 IndexedDBIndexChild::AllocPIndexedDBCursorChild(
940 const IndexCursorConstructorParams& aParams)
941 {
942 return new IndexedDBCursorChild();
943 }
945 bool
946 IndexedDBIndexChild::DeallocPIndexedDBCursorChild(PIndexedDBCursorChild* aActor)
947 {
948 delete aActor;
949 return true;
950 }
952 /*******************************************************************************
953 * IndexedDBCursorChild
954 ******************************************************************************/
956 IndexedDBCursorChild::IndexedDBCursorChild()
957 : mCursor(nullptr)
958 {
959 MOZ_COUNT_CTOR(IndexedDBCursorChild);
960 }
962 IndexedDBCursorChild::~IndexedDBCursorChild()
963 {
964 MOZ_COUNT_DTOR(IndexedDBCursorChild);
965 MOZ_ASSERT(!mCursor);
966 MOZ_ASSERT(!mStrongCursor);
967 }
969 void
970 IndexedDBCursorChild::SetCursor(IDBCursor* aCursor)
971 {
972 MOZ_ASSERT(aCursor);
973 MOZ_ASSERT(!mCursor);
975 aCursor->SetActor(this);
977 mCursor = aCursor;
978 mStrongCursor = aCursor;
979 }
981 void
982 IndexedDBCursorChild::Disconnect()
983 {
984 const InfallibleTArray<PIndexedDBRequestChild*>& requests =
985 ManagedPIndexedDBRequestChild();
986 for (uint32_t i = 0; i < requests.Length(); ++i) {
987 static_cast<IndexedDBRequestChildBase*>(requests[i])->Disconnect();
988 }
989 }
991 void
992 IndexedDBCursorChild::ActorDestroy(ActorDestroyReason aWhy)
993 {
994 if (mCursor) {
995 mCursor->SetActor(static_cast<IndexedDBCursorChild*>(nullptr));
996 #ifdef DEBUG
997 mCursor = nullptr;
998 #endif
999 }
1000 }
1002 PIndexedDBRequestChild*
1003 IndexedDBCursorChild::AllocPIndexedDBRequestChild(const CursorRequestParams& aParams)
1004 {
1005 MOZ_CRASH("Caller is supposed to manually construct a request!");
1006 }
1008 bool
1009 IndexedDBCursorChild::DeallocPIndexedDBRequestChild(PIndexedDBRequestChild* aActor)
1010 {
1011 delete aActor;
1012 return true;
1013 }
1015 /*******************************************************************************
1016 * IndexedDBRequestChildBase
1017 ******************************************************************************/
1019 IndexedDBRequestChildBase::IndexedDBRequestChildBase(
1020 AsyncConnectionHelper* aHelper)
1021 : mHelper(aHelper)
1022 {
1023 MOZ_COUNT_CTOR(IndexedDBRequestChildBase);
1024 }
1026 IndexedDBRequestChildBase::~IndexedDBRequestChildBase()
1027 {
1028 MOZ_COUNT_DTOR(IndexedDBRequestChildBase);
1029 }
1031 IDBRequest*
1032 IndexedDBRequestChildBase::GetRequest() const
1033 {
1034 return mHelper ? mHelper->GetRequest() : nullptr;
1035 }
1037 void
1038 IndexedDBRequestChildBase::Disconnect()
1039 {
1040 if (mHelper) {
1041 IDBRequest* request = mHelper->GetRequest();
1043 if (request->IsPending()) {
1044 request->SetError(NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
1046 IDBTransaction* transaction = mHelper->GetTransaction();
1047 if (transaction) {
1048 transaction->OnRequestDisconnected();
1049 }
1050 }
1051 }
1052 }
1054 bool
1055 IndexedDBRequestChildBase::Recv__delete__(const ResponseValue& aResponse)
1056 {
1057 MOZ_CRASH("This should be overridden!");
1058 }
1060 /*******************************************************************************
1061 * IndexedDBObjectStoreRequestChild
1062 ******************************************************************************/
1064 IndexedDBObjectStoreRequestChild::IndexedDBObjectStoreRequestChild(
1065 AsyncConnectionHelper* aHelper,
1066 IDBObjectStore* aObjectStore,
1067 RequestType aRequestType)
1068 : IndexedDBRequestChildBase(aHelper), mObjectStore(aObjectStore),
1069 mRequestType(aRequestType)
1070 {
1071 MOZ_COUNT_CTOR(IndexedDBObjectStoreRequestChild);
1072 MOZ_ASSERT(aHelper);
1073 MOZ_ASSERT(aObjectStore);
1074 MOZ_ASSERT(aRequestType > ParamsUnionType::T__None &&
1075 aRequestType <= ParamsUnionType::T__Last);
1076 }
1078 IndexedDBObjectStoreRequestChild::~IndexedDBObjectStoreRequestChild()
1079 {
1080 MOZ_COUNT_DTOR(IndexedDBObjectStoreRequestChild);
1081 }
1083 bool
1084 IndexedDBObjectStoreRequestChild::Recv__delete__(const ResponseValue& aResponse)
1085 {
1086 switch (aResponse.type()) {
1087 case ResponseValue::Tnsresult:
1088 break;
1089 case ResponseValue::TGetResponse:
1090 MOZ_ASSERT(mRequestType == ParamsUnionType::TGetParams);
1091 break;
1092 case ResponseValue::TGetAllResponse:
1093 MOZ_ASSERT(mRequestType == ParamsUnionType::TGetAllParams);
1094 break;
1095 case ResponseValue::TGetAllKeysResponse:
1096 MOZ_ASSERT(mRequestType == ParamsUnionType::TGetAllKeysParams);
1097 break;
1098 case ResponseValue::TAddResponse:
1099 MOZ_ASSERT(mRequestType == ParamsUnionType::TAddParams);
1100 break;
1101 case ResponseValue::TPutResponse:
1102 MOZ_ASSERT(mRequestType == ParamsUnionType::TPutParams);
1103 break;
1104 case ResponseValue::TDeleteResponse:
1105 MOZ_ASSERT(mRequestType == ParamsUnionType::TDeleteParams);
1106 break;
1107 case ResponseValue::TClearResponse:
1108 MOZ_ASSERT(mRequestType == ParamsUnionType::TClearParams);
1109 break;
1110 case ResponseValue::TCountResponse:
1111 MOZ_ASSERT(mRequestType == ParamsUnionType::TCountParams);
1112 break;
1113 case ResponseValue::TOpenCursorResponse:
1114 MOZ_ASSERT(mRequestType == ParamsUnionType::TOpenCursorParams ||
1115 mRequestType == ParamsUnionType::TOpenKeyCursorParams);
1116 break;
1118 default:
1119 MOZ_CRASH("Received invalid response parameters!");
1120 }
1122 nsresult rv = mHelper->OnParentProcessRequestComplete(aResponse);
1123 NS_ENSURE_SUCCESS(rv, false);
1125 return true;
1126 }
1128 /*******************************************************************************
1129 * IndexedDBIndexRequestChild
1130 ******************************************************************************/
1132 IndexedDBIndexRequestChild::IndexedDBIndexRequestChild(
1133 AsyncConnectionHelper* aHelper,
1134 IDBIndex* aIndex,
1135 RequestType aRequestType)
1136 : IndexedDBRequestChildBase(aHelper), mIndex(aIndex), mRequestType(aRequestType)
1137 {
1138 MOZ_COUNT_CTOR(IndexedDBIndexRequestChild);
1139 MOZ_ASSERT(aHelper);
1140 MOZ_ASSERT(aIndex);
1141 MOZ_ASSERT(aRequestType > ParamsUnionType::T__None &&
1142 aRequestType <= ParamsUnionType::T__Last);
1143 }
1145 IndexedDBIndexRequestChild::~IndexedDBIndexRequestChild()
1146 {
1147 MOZ_COUNT_DTOR(IndexedDBIndexRequestChild);
1148 }
1150 bool
1151 IndexedDBIndexRequestChild::Recv__delete__(const ResponseValue& aResponse)
1152 {
1153 switch (aResponse.type()) {
1154 case ResponseValue::Tnsresult:
1155 break;
1156 case ResponseValue::TGetResponse:
1157 MOZ_ASSERT(mRequestType == ParamsUnionType::TGetParams);
1158 break;
1159 case ResponseValue::TGetKeyResponse:
1160 MOZ_ASSERT(mRequestType == ParamsUnionType::TGetKeyParams);
1161 break;
1162 case ResponseValue::TGetAllResponse:
1163 MOZ_ASSERT(mRequestType == ParamsUnionType::TGetAllParams);
1164 break;
1165 case ResponseValue::TGetAllKeysResponse:
1166 MOZ_ASSERT(mRequestType == ParamsUnionType::TGetAllKeysParams);
1167 break;
1168 case ResponseValue::TCountResponse:
1169 MOZ_ASSERT(mRequestType == ParamsUnionType::TCountParams);
1170 break;
1171 case ResponseValue::TOpenCursorResponse:
1172 MOZ_ASSERT(mRequestType == ParamsUnionType::TOpenCursorParams ||
1173 mRequestType == ParamsUnionType::TOpenKeyCursorParams);
1174 break;
1176 default:
1177 MOZ_CRASH("Received invalid response parameters!");
1178 }
1180 nsresult rv = mHelper->OnParentProcessRequestComplete(aResponse);
1181 NS_ENSURE_SUCCESS(rv, false);
1183 return true;
1184 }
1186 /*******************************************************************************
1187 * IndexedDBCursorRequestChild
1188 ******************************************************************************/
1190 IndexedDBCursorRequestChild::IndexedDBCursorRequestChild(
1191 AsyncConnectionHelper* aHelper,
1192 IDBCursor* aCursor,
1193 RequestType aRequestType)
1194 : IndexedDBRequestChildBase(aHelper), mCursor(aCursor),
1195 mRequestType(aRequestType)
1196 {
1197 MOZ_COUNT_CTOR(IndexedDBCursorRequestChild);
1198 MOZ_ASSERT(aHelper);
1199 MOZ_ASSERT(aCursor);
1200 MOZ_ASSERT(aRequestType > ParamsUnionType::T__None &&
1201 aRequestType <= ParamsUnionType::T__Last);
1202 }
1204 IndexedDBCursorRequestChild::~IndexedDBCursorRequestChild()
1205 {
1206 MOZ_COUNT_DTOR(IndexedDBCursorRequestChild);
1207 }
1209 bool
1210 IndexedDBCursorRequestChild::Recv__delete__(const ResponseValue& aResponse)
1211 {
1212 switch (aResponse.type()) {
1213 case ResponseValue::Tnsresult:
1214 break;
1215 case ResponseValue::TContinueResponse:
1216 MOZ_ASSERT(mRequestType == ParamsUnionType::TContinueParams);
1217 break;
1219 default:
1220 MOZ_CRASH("Received invalid response parameters!");
1221 }
1223 nsresult rv = mHelper->OnParentProcessRequestComplete(aResponse);
1224 NS_ENSURE_SUCCESS(rv, false);
1226 return true;
1227 }
1229 /*******************************************************************************
1230 * IndexedDBDeleteDatabaseRequestChild
1231 ******************************************************************************/
1233 IndexedDBDeleteDatabaseRequestChild::IndexedDBDeleteDatabaseRequestChild(
1234 IDBFactory* aFactory,
1235 IDBOpenDBRequest* aOpenRequest,
1236 const nsACString& aDatabaseId)
1237 : mFactory(aFactory), mOpenRequest(aOpenRequest), mDatabaseId(aDatabaseId)
1238 {
1239 MOZ_COUNT_CTOR(IndexedDBDeleteDatabaseRequestChild);
1240 MOZ_ASSERT(aFactory);
1241 MOZ_ASSERT(aOpenRequest);
1242 MOZ_ASSERT(!aDatabaseId.IsEmpty());
1243 }
1245 IndexedDBDeleteDatabaseRequestChild::~IndexedDBDeleteDatabaseRequestChild()
1246 {
1247 MOZ_COUNT_DTOR(IndexedDBDeleteDatabaseRequestChild);
1248 }
1250 bool
1251 IndexedDBDeleteDatabaseRequestChild::Recv__delete__(const nsresult& aRv)
1252 {
1253 nsRefPtr<IPCDeleteDatabaseHelper> helper =
1254 new IPCDeleteDatabaseHelper(mOpenRequest);
1256 if (NS_SUCCEEDED(aRv)) {
1257 DatabaseInfo::Remove(mDatabaseId);
1258 }
1259 else {
1260 helper->SetError(aRv);
1261 }
1263 ImmediateRunEventTarget target;
1264 if (NS_FAILED(helper->Dispatch(&target))) {
1265 NS_WARNING("Dispatch of IPCSetVersionHelper failed!");
1266 return false;
1267 }
1269 return true;
1270 }
1272 bool
1273 IndexedDBDeleteDatabaseRequestChild::RecvBlocked(
1274 const uint64_t& aCurrentVersion)
1275 {
1276 MOZ_ASSERT(mOpenRequest);
1278 nsCOMPtr<nsIRunnable> runnable =
1279 IDBVersionChangeEvent::CreateBlockedRunnable(mOpenRequest,
1280 aCurrentVersion, 0);
1282 ImmediateRunEventTarget target;
1283 if (NS_FAILED(target.Dispatch(runnable, NS_DISPATCH_NORMAL))) {
1284 NS_WARNING("Dispatch of blocked event failed!");
1285 }
1287 return true;
1288 }
1290 /*******************************************************************************
1291 * Helpers
1292 ******************************************************************************/
1294 nsresult
1295 IPCOpenDatabaseHelper::UnpackResponseFromParentProcess(
1296 const ResponseValue& aResponseValue)
1297 {
1298 NS_NOTREACHED("Should never get here!");
1299 return NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR;
1300 }
1302 AsyncConnectionHelper::ChildProcessSendResult
1303 IPCOpenDatabaseHelper::SendResponseToChildProcess(nsresult aResultCode)
1304 {
1305 MOZ_CRASH("Don't call me!");
1306 }
1308 nsresult
1309 IPCOpenDatabaseHelper::DoDatabaseWork(mozIStorageConnection* aConnection)
1310 {
1311 MOZ_CRASH("Don't call me!");
1312 }
1314 nsresult
1315 IPCOpenDatabaseHelper::GetSuccessResult(JSContext* aCx, JS::MutableHandle<JS::Value> aVal)
1316 {
1317 return WrapNative(aCx, NS_ISUPPORTS_CAST(EventTarget*, mDatabase),
1318 aVal);
1319 }
1321 nsresult
1322 IPCSetVersionHelper::UnpackResponseFromParentProcess(
1323 const ResponseValue& aResponseValue)
1324 {
1325 NS_NOTREACHED("Should never get here!");
1326 return NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR;
1327 }
1329 AsyncConnectionHelper::ChildProcessSendResult
1330 IPCSetVersionHelper::SendResponseToChildProcess(nsresult aResultCode)
1331 {
1332 MOZ_CRASH("Don't call me!");
1333 }
1335 nsresult
1336 IPCSetVersionHelper::DoDatabaseWork(mozIStorageConnection* aConnection)
1337 {
1338 MOZ_CRASH("Don't call me!");
1339 }
1341 already_AddRefed<nsIDOMEvent>
1342 IPCSetVersionHelper::CreateSuccessEvent(mozilla::dom::EventTarget* aOwner)
1343 {
1344 return IDBVersionChangeEvent::CreateUpgradeNeeded(aOwner,
1345 mOldVersion,
1346 mRequestedVersion);
1347 }
1349 nsresult
1350 IPCSetVersionHelper::GetSuccessResult(JSContext* aCx, JS::MutableHandle<JS::Value> aVal)
1351 {
1352 mOpenRequest->SetTransaction(mTransaction);
1354 return WrapNative(aCx, NS_ISUPPORTS_CAST(EventTarget*, mDatabase),
1355 aVal);
1356 }
1358 nsresult
1359 IPCDeleteDatabaseHelper::UnpackResponseFromParentProcess(
1360 const ResponseValue& aResponseValue)
1361 {
1362 MOZ_CRASH("Don't call me!");
1363 }
1365 AsyncConnectionHelper::ChildProcessSendResult
1366 IPCDeleteDatabaseHelper::SendResponseToChildProcess(nsresult aResultCode)
1367 {
1368 MOZ_CRASH("Don't call me!");
1369 }
1371 nsresult
1372 IPCDeleteDatabaseHelper::GetSuccessResult(JSContext* aCx, JS::MutableHandle<JS::Value> aVal)
1373 {
1374 aVal.setUndefined();
1375 return NS_OK;
1376 }
1378 nsresult
1379 IPCDeleteDatabaseHelper::DoDatabaseWork(mozIStorageConnection* aConnection)
1380 {
1381 MOZ_CRASH("Don't call me!");
1382 }