/* -*- 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_indexeddb_idbdatabase_h__ #define mozilla_dom_indexeddb_idbdatabase_h__ #include "mozilla/Attributes.h" #include "mozilla/dom/IDBTransactionBinding.h" #include "mozilla/dom/StorageTypeBinding.h" #include "mozilla/dom/indexedDB/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; struct IDBObjectStoreParameters; template class Optional; class StringOrStringSequence; namespace indexedDB { class BackgroundDatabaseChild; class DatabaseSpec; class IDBFactory; class IDBMutableFile; class IDBObjectStore; class IDBOpenDBRequest; class IDBRequest; class IDBTransaction; class PBackgroundIDBDatabaseFileChild; class IDBDatabase final : public IDBWrapperCache { typedef mozilla::dom::StorageType StorageType; typedef mozilla::dom::quota::PersistenceType PersistenceType; class LogWarningRunnable; friend class LogWarningRunnable; class Observer; friend class Observer; // 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 mFactory; nsAutoPtr mSpec; // Normally null except during a versionchange transaction. nsAutoPtr mPreviousSpec; BackgroundDatabaseChild* mBackgroundActor; nsTHashtable> mTransactions; nsDataHashtable mFileActors; nsTHashtable mReceivedBlobs; RefPtr mObserver; // Weak refs, IDBMutableFile strongly owns this IDBDatabase object. nsTArray mLiveMutableFiles; const bool mFileHandleDisabled; bool mClosed; bool mInvalidated; public: static already_AddRefed Create(IDBOpenDBRequest* aRequest, IDBFactory* aFactory, 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 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 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); PBackgroundIDBDatabaseFileChild* GetOrCreateFileActorForBlob(Blob* aBlob); void NoteFinishedFileActor(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 ObjectStoreNames() const; already_AddRefed 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 Transaction(const StringOrStringSequence& aStoreNames, IDBTransactionMode aMode, ErrorResult& aRv); // This can be called from C++ to avoid JS exception. nsresult Transaction(const StringOrStringSequence& aStoreNames, IDBTransactionMode aMode, IDBTransaction** aTransaction); StorageType Storage() const; IMPL_EVENT_HANDLER(abort) IMPL_EVENT_HANDLER(error) IMPL_EVENT_HANDLER(versionchange) already_AddRefed CreateMutableFile(const nsAString& aName, const Optional& aType, ErrorResult& aRv); already_AddRefed MozCreateFileHandle(const nsAString& aName, const Optional& aType, ErrorResult& aRv) { return CreateMutableFile(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 aGivenProto) override; private: IDBDatabase(IDBOpenDBRequest* aRequest, IDBFactory* aFactory, 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); }; } // namespace indexedDB } // namespace dom } // namespace mozilla #endif // mozilla_dom_indexeddb_idbdatabase_h__