diff options
Diffstat (limited to 'dom/indexedDB/IDBDatabase.h')
-rw-r--r-- | dom/indexedDB/IDBDatabase.h | 347 |
1 files changed, 347 insertions, 0 deletions
diff --git a/dom/indexedDB/IDBDatabase.h b/dom/indexedDB/IDBDatabase.h new file mode 100644 index 000000000..e61d5a30d --- /dev/null +++ b/dom/indexedDB/IDBDatabase.h @@ -0,0 +1,347 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef mozilla_dom_idbdatabase_h__ +#define mozilla_dom_idbdatabase_h__ + +#include "mozilla/Attributes.h" +#include "mozilla/dom/IDBTransactionBinding.h" +#include "mozilla/dom/StorageTypeBinding.h" +#include "mozilla/dom/IDBWrapperCache.h" +#include "mozilla/dom/quota/PersistenceType.h" +#include "nsAutoPtr.h" +#include "nsDataHashtable.h" +#include "nsHashKeys.h" +#include "nsString.h" +#include "nsTHashtable.h" + +class nsIDocument; +class nsPIDOMWindowInner; + +namespace mozilla { + +class ErrorResult; +class EventChainPostVisitor; + +namespace dom { + +class Blob; +class DOMStringList; +class IDBFactory; +class IDBMutableFile; +class IDBObjectStore; +struct IDBObjectStoreParameters; +class IDBOpenDBRequest; +class IDBRequest; +class IDBTransaction; +template <class> class Optional; +class StringOrStringSequence; + +namespace indexedDB { +class BackgroundDatabaseChild; +class DatabaseSpec; +class PBackgroundIDBDatabaseFileChild; +} + +class IDBDatabase final + : public IDBWrapperCache +{ + typedef mozilla::dom::indexedDB::DatabaseSpec DatabaseSpec; + typedef mozilla::dom::StorageType StorageType; + typedef mozilla::dom::quota::PersistenceType PersistenceType; + + class Observer; + friend class Observer; + + friend class IDBObjectStore; + friend class IDBIndex; + + // The factory must be kept alive when IndexedDB is used in multiple + // processes. If it dies then the entire actor tree will be destroyed with it + // and the world will explode. + RefPtr<IDBFactory> mFactory; + + nsAutoPtr<DatabaseSpec> mSpec; + + // Normally null except during a versionchange transaction. + nsAutoPtr<DatabaseSpec> mPreviousSpec; + + indexedDB::BackgroundDatabaseChild* mBackgroundActor; + + nsTHashtable<nsPtrHashKey<IDBTransaction>> mTransactions; + + nsDataHashtable<nsISupportsHashKey, indexedDB::PBackgroundIDBDatabaseFileChild*> + mFileActors; + + nsTHashtable<nsISupportsHashKey> mReceivedBlobs; + + RefPtr<Observer> mObserver; + + // Weak refs, IDBMutableFile strongly owns this IDBDatabase object. + nsTArray<IDBMutableFile*> mLiveMutableFiles; + + const bool mFileHandleDisabled; + bool mClosed; + bool mInvalidated; + bool mQuotaExceeded; + +public: + static already_AddRefed<IDBDatabase> + Create(IDBOpenDBRequest* aRequest, + IDBFactory* aFactory, + indexedDB::BackgroundDatabaseChild* aActor, + DatabaseSpec* aSpec); + +#ifdef DEBUG + void + AssertIsOnOwningThread() const; + + PRThread* + OwningThread() const; +#else + void + AssertIsOnOwningThread() const + { } +#endif + + const nsString& + Name() const; + + void + GetName(nsAString& aName) const + { + AssertIsOnOwningThread(); + + aName = Name(); + } + + uint64_t + Version() const; + + already_AddRefed<nsIDocument> + GetOwnerDocument() const; + + void + Close() + { + AssertIsOnOwningThread(); + + CloseInternal(); + } + + bool + IsClosed() const + { + AssertIsOnOwningThread(); + + return mClosed; + } + + void + Invalidate(); + + // Whether or not the database has been invalidated. If it has then no further + // transactions for this database will be allowed to run. + bool + IsInvalidated() const + { + AssertIsOnOwningThread(); + + return mInvalidated; + } + + void + SetQuotaExceeded() + { + mQuotaExceeded = true; + } + + void + EnterSetVersionTransaction(uint64_t aNewVersion); + + void + ExitSetVersionTransaction(); + + // Called when a versionchange transaction is aborted to reset the + // DatabaseInfo. + void + RevertToPreviousState(); + + IDBFactory* + Factory() const + { + AssertIsOnOwningThread(); + + return mFactory; + } + + void + RegisterTransaction(IDBTransaction* aTransaction); + + void + UnregisterTransaction(IDBTransaction* aTransaction); + + void + AbortTransactions(bool aShouldWarn); + + indexedDB::PBackgroundIDBDatabaseFileChild* + GetOrCreateFileActorForBlob(Blob* aBlob); + + void + NoteFinishedFileActor(indexedDB::PBackgroundIDBDatabaseFileChild* aFileActor); + + void + NoteReceivedBlob(Blob* aBlob); + + void + DelayedMaybeExpireFileActors(); + + // XXX This doesn't really belong here... It's only needed for IDBMutableFile + // serialization and should be removed or fixed someday. + nsresult + GetQuotaInfo(nsACString& aOrigin, PersistenceType* aPersistenceType); + + bool + IsFileHandleDisabled() const + { + return mFileHandleDisabled; + } + + void + NoteLiveMutableFile(IDBMutableFile* aMutableFile); + + void + NoteFinishedMutableFile(IDBMutableFile* aMutableFile); + + nsPIDOMWindowInner* + GetParentObject() const; + + already_AddRefed<DOMStringList> + ObjectStoreNames() const; + + already_AddRefed<IDBObjectStore> + CreateObjectStore(const nsAString& aName, + const IDBObjectStoreParameters& aOptionalParameters, + ErrorResult& aRv); + + void + DeleteObjectStore(const nsAString& name, ErrorResult& aRv); + + // This will be called from the DOM. + already_AddRefed<IDBTransaction> + Transaction(JSContext* aCx, + const StringOrStringSequence& aStoreNames, + IDBTransactionMode aMode, + ErrorResult& aRv); + + // This can be called from C++ to avoid JS exception. + nsresult + Transaction(JSContext* aCx, + const StringOrStringSequence& aStoreNames, + IDBTransactionMode aMode, + IDBTransaction** aTransaction); + + StorageType + Storage() const; + + IMPL_EVENT_HANDLER(abort) + IMPL_EVENT_HANDLER(close) + IMPL_EVENT_HANDLER(error) + IMPL_EVENT_HANDLER(versionchange) + + already_AddRefed<IDBRequest> + CreateMutableFile(JSContext* aCx, + const nsAString& aName, + const Optional<nsAString>& aType, + ErrorResult& aRv); + + already_AddRefed<IDBRequest> + MozCreateFileHandle(JSContext* aCx, + const nsAString& aName, + const Optional<nsAString>& aType, + ErrorResult& aRv) + { + return CreateMutableFile(aCx, aName, aType, aRv); + } + + void + ClearBackgroundActor() + { + AssertIsOnOwningThread(); + + mBackgroundActor = nullptr; + } + + const DatabaseSpec* + Spec() const + { + return mSpec; + } + + NS_DECL_ISUPPORTS_INHERITED + NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(IDBDatabase, IDBWrapperCache) + + // nsIDOMEventTarget + virtual void + LastRelease() override; + + virtual nsresult + PostHandleEvent(EventChainPostVisitor& aVisitor) override; + + // nsWrapperCache + virtual JSObject* + WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) override; + +private: + IDBDatabase(IDBOpenDBRequest* aRequest, + IDBFactory* aFactory, + indexedDB::BackgroundDatabaseChild* aActor, + DatabaseSpec* aSpec); + + ~IDBDatabase(); + + void + CloseInternal(); + + void + InvalidateInternal(); + + bool + RunningVersionChangeTransaction() const + { + AssertIsOnOwningThread(); + + return !!mPreviousSpec; + } + + void + RefreshSpec(bool aMayDelete); + + void + ExpireFileActors(bool aExpireAll); + + void + InvalidateMutableFiles(); + + void + LogWarning(const char* aMessageName, + const nsAString& aFilename, + uint32_t aLineNumber, + uint32_t aColumnNumber); + + // Only accessed by IDBObjectStore. + nsresult + RenameObjectStore(int64_t aObjectStoreId, const nsAString& aName); + + // Only accessed by IDBIndex. + nsresult + RenameIndex(int64_t aObjectStoreId, int64_t aIndexId, const nsAString& aName); +}; + +} // namespace dom +} // namespace mozilla + +#endif // mozilla_dom_idbdatabase_h__ |