IDBDatabase.h (6518B)
1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */ 3 /* This Source Code Form is subject to the terms of the Mozilla Public 4 * License, v. 2.0. If a copy of the MPL was not distributed with this 5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 6 7 #ifndef mozilla_dom_idbdatabase_h__ 8 #define mozilla_dom_idbdatabase_h__ 9 10 #include "mozilla/DOMEventTargetHelper.h" 11 #include "mozilla/UniquePtr.h" 12 #include "mozilla/dom/IDBTransactionBinding.h" 13 #include "mozilla/dom/indexedDB/PBackgroundIDBSharedTypes.h" 14 #include "mozilla/dom/quota/PersistenceType.h" 15 #include "nsHashKeys.h" 16 #include "nsString.h" 17 #include "nsTHashMap.h" 18 #include "nsTHashSet.h" 19 20 class nsIEventTarget; 21 class nsIGlobalObject; 22 23 namespace mozilla { 24 25 struct JSCallingLocation; 26 class ErrorResult; 27 class EventChainPostVisitor; 28 29 namespace dom { 30 31 class Blob; 32 class DOMStringList; 33 class IDBFactory; 34 class IDBObjectStore; 35 struct IDBObjectStoreParameters; 36 class IDBOpenDBRequest; 37 class IDBRequest; 38 class IDBTransaction; 39 template <class> 40 class Optional; 41 class StringOrStringSequence; 42 43 namespace indexedDB { 44 class BackgroundDatabaseChild; 45 class PBackgroundIDBDatabaseFileChild; 46 } // namespace indexedDB 47 48 class IDBDatabase final : public DOMEventTargetHelper { 49 using DatabaseSpec = mozilla::dom::indexedDB::DatabaseSpec; 50 using PersistenceType = mozilla::dom::quota::PersistenceType; 51 52 class Observer; 53 friend class Observer; 54 55 friend class IDBObjectStore; 56 friend class IDBIndex; 57 58 // The factory must be kept alive when IndexedDB is used in multiple 59 // processes. If it dies then the entire actor tree will be destroyed with it 60 // and the world will explode. 61 SafeRefPtr<IDBFactory> mFactory; 62 63 UniquePtr<DatabaseSpec> mSpec; 64 65 // Normally null except during a versionchange transaction. 66 UniquePtr<DatabaseSpec> mPreviousSpec; 67 68 indexedDB::BackgroundDatabaseChild* mBackgroundActor; 69 70 nsTHashSet<IDBTransaction*> mTransactions; 71 72 nsTHashMap<nsISupportsHashKey, indexedDB::PBackgroundIDBDatabaseFileChild*> 73 mFileActors; 74 75 RefPtr<Observer> mObserver; 76 77 bool mClosed; 78 bool mInvalidated; 79 bool mQuotaExceeded; 80 bool mIncreasedActiveDatabaseCount; 81 82 public: 83 [[nodiscard]] static RefPtr<IDBDatabase> Create( 84 IDBOpenDBRequest* aRequest, SafeRefPtr<IDBFactory> aFactory, 85 indexedDB::BackgroundDatabaseChild* aActor, 86 UniquePtr<DatabaseSpec> aSpec); 87 88 void AssertIsOnOwningThread() const 89 #ifdef DEBUG 90 ; 91 #else 92 { 93 } 94 #endif 95 96 nsIEventTarget* EventTarget() const; 97 98 const nsString& Name() const; 99 100 void GetName(nsAString& aName) const { 101 AssertIsOnOwningThread(); 102 103 aName = Name(); 104 } 105 106 uint64_t Version() const; 107 108 [[nodiscard]] RefPtr<Document> GetOwnerDocument() const; 109 110 void Close() { 111 AssertIsOnOwningThread(); 112 113 CloseInternal(); 114 } 115 116 bool IsClosed() const { 117 AssertIsOnOwningThread(); 118 119 return mClosed; 120 } 121 122 void Invalidate(); 123 124 // Whether or not the database has been invalidated. If it has then no further 125 // transactions for this database will be allowed to run. 126 bool IsInvalidated() const { 127 AssertIsOnOwningThread(); 128 129 return mInvalidated; 130 } 131 132 void SetQuotaExceeded() { mQuotaExceeded = true; } 133 134 void EnterSetVersionTransaction(uint64_t aNewVersion); 135 136 void ExitSetVersionTransaction(); 137 138 // Called when a versionchange transaction is aborted to reset the 139 // DatabaseInfo. 140 void RevertToPreviousState(); 141 142 void RegisterTransaction(IDBTransaction& aTransaction); 143 144 void UnregisterTransaction(IDBTransaction& aTransaction); 145 146 void AbortTransactions(bool aShouldWarn); 147 148 indexedDB::PBackgroundIDBDatabaseFileChild* GetOrCreateFileActorForBlob( 149 Blob& aBlob); 150 151 void NoteFinishedFileActor( 152 indexedDB::PBackgroundIDBDatabaseFileChild* aFileActor); 153 154 void NoteActiveTransaction(); 155 156 void NoteInactiveTransaction(); 157 158 [[nodiscard]] RefPtr<DOMStringList> ObjectStoreNames() const; 159 160 [[nodiscard]] RefPtr<IDBObjectStore> CreateObjectStore( 161 const nsAString& aName, 162 const IDBObjectStoreParameters& aOptionalParameters, ErrorResult& aRv); 163 164 void DeleteObjectStore(const nsAString& name, ErrorResult& aRv); 165 166 // This will be called from the DOM. 167 [[nodiscard]] RefPtr<IDBTransaction> Transaction( 168 JSContext* aCx, const StringOrStringSequence& aStoreNames, 169 IDBTransactionMode aMode, const IDBTransactionOptions& aOptions, 170 ErrorResult& aRv); 171 172 IMPL_EVENT_HANDLER(abort) 173 IMPL_EVENT_HANDLER(close) 174 IMPL_EVENT_HANDLER(error) 175 IMPL_EVENT_HANDLER(versionchange) 176 177 void ClearBackgroundActor() { 178 AssertIsOnOwningThread(); 179 180 // Decrease the number of active databases if it was not done in 181 // CloseInternal(). 182 MaybeDecreaseActiveDatabaseCount(); 183 184 mBackgroundActor = nullptr; 185 } 186 187 const DatabaseSpec* Spec() const { return mSpec.get(); } 188 189 template <typename Pred> 190 indexedDB::ObjectStoreSpec* LookupModifiableObjectStoreSpec(Pred&& aPred) { 191 auto& objectStores = mSpec->objectStores(); 192 const auto foundIt = 193 std::find_if(objectStores.begin(), objectStores.end(), aPred); 194 return foundIt != objectStores.end() ? &*foundIt : nullptr; 195 } 196 197 NS_DECL_ISUPPORTS_INHERITED 198 NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(IDBDatabase, DOMEventTargetHelper) 199 200 // DOMEventTargetHelper 201 void DisconnectFromOwner() override; 202 203 virtual void LastRelease() override; 204 205 // nsWrapperCache 206 virtual JSObject* WrapObject(JSContext* aCx, 207 JS::Handle<JSObject*> aGivenProto) override; 208 209 private: 210 IDBDatabase(IDBOpenDBRequest* aRequest, SafeRefPtr<IDBFactory> aFactory, 211 indexedDB::BackgroundDatabaseChild* aActor, 212 UniquePtr<DatabaseSpec> aSpec); 213 214 ~IDBDatabase(); 215 216 void CloseInternal(); 217 218 void InvalidateInternal(); 219 220 bool RunningVersionChangeTransaction() const { 221 AssertIsOnOwningThread(); 222 223 return !!mPreviousSpec; 224 } 225 226 void RefreshSpec(bool aMayDelete); 227 228 void ExpireFileActors(bool aExpireAll); 229 230 void NoteInactiveTransactionDelayed(); 231 232 void LogWarning(const char* aMessageName, const JSCallingLocation&); 233 234 // Only accessed by IDBObjectStore. 235 nsresult RenameObjectStore(int64_t aObjectStoreId, const nsAString& aName); 236 237 // Only accessed by IDBIndex. 238 nsresult RenameIndex(int64_t aObjectStoreId, int64_t aIndexId, 239 const nsAString& aName); 240 241 void IncreaseActiveDatabaseCount(); 242 243 void MaybeDecreaseActiveDatabaseCount(); 244 }; 245 246 } // namespace dom 247 } // namespace mozilla 248 249 #endif // mozilla_dom_idbdatabase_h__