Bug 1941128 - Turn off network.dns.native_https_query on Mac again
[gecko.git] / dom / indexedDB / IDBTransaction.h
blob997bbbd2e9927c8c88e118c9ff5d0d1cb852ffe3
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/. */
7 #ifndef mozilla_dom_idbtransaction_h__
8 #define mozilla_dom_idbtransaction_h__
10 #include "FlippedOnce.h"
11 #include "mozilla/Attributes.h"
12 #include "mozilla/SourceLocation.h"
13 #include "mozilla/dom/IDBTransactionBinding.h"
14 #include "mozilla/dom/quota/CheckedUnsafePtr.h"
15 #include "mozilla/DOMEventTargetHelper.h"
16 #include "nsCycleCollectionParticipant.h"
17 #include "nsIRunnable.h"
18 #include "nsString.h"
19 #include "nsTArray.h"
20 #include "SafeRefPtr.h"
22 namespace mozilla {
24 class ErrorResult;
25 class EventChainPreVisitor;
27 namespace dom {
29 class DOMException;
30 class DOMStringList;
31 class IDBCursor;
32 class IDBDatabase;
33 class IDBObjectStore;
34 class IDBOpenDBRequest;
35 class IDBRequest;
36 class StrongWorkerRef;
38 namespace indexedDB {
39 class PBackgroundIDBCursorChild;
40 class BackgroundRequestChild;
41 class BackgroundTransactionChild;
42 class BackgroundVersionChangeTransactionChild;
43 class IndexMetadata;
44 class ObjectStoreSpec;
45 class OpenCursorParams;
46 class RequestParams;
47 } // namespace indexedDB
49 class IDBTransaction final
50 : public DOMEventTargetHelper,
51 public nsIRunnable,
52 public SupportsCheckedUnsafePtr<CheckIf<DiagnosticAssertEnabled>> {
53 friend class indexedDB::BackgroundRequestChild;
55 public:
56 enum struct Mode {
57 ReadOnly = 0,
58 ReadWrite,
59 ReadWriteFlush,
60 Cleanup,
61 VersionChange,
63 // Only needed for IPC serialization helper, should never be used in code.
64 Invalid
67 enum struct Durability {
68 Default = 0,
69 Strict,
70 Relaxed,
72 // Only needed for IPC serialization helper, should never be used in code.
73 Invalid
76 enum struct ReadyState { Active, Inactive, Committing, Finished };
78 private:
79 // TODO: Only non-const because of Bug 1575173.
80 RefPtr<IDBDatabase> mDatabase;
81 RefPtr<DOMException> mError;
82 const nsTArray<nsString> mObjectStoreNames;
83 nsTArray<RefPtr<IDBObjectStore>> mObjectStores;
84 nsTArray<RefPtr<IDBObjectStore>> mDeletedObjectStores;
85 RefPtr<StrongWorkerRef> mWorkerRef;
86 nsTArray<NotNull<IDBCursor*>> mCursors;
88 // Tagged with mMode. If mMode is Mode::VersionChange then mBackgroundActor
89 // will be a BackgroundVersionChangeTransactionChild. Otherwise it will be a
90 // BackgroundTransactionChild.
91 union {
92 indexedDB::BackgroundTransactionChild* mNormalBackgroundActor;
93 indexedDB::BackgroundVersionChangeTransactionChild*
94 mVersionChangeBackgroundActor;
95 } mBackgroundActor;
97 const int64_t mLoggingSerialNumber;
99 // Only used for Mode::VersionChange transactions.
100 int64_t mNextObjectStoreId;
101 int64_t mNextIndexId;
103 // Request ids are issued starting from 0 and incremented by one as we send
104 // actor creation messages to the parent process. Used to support the
105 // explicit commit() request.
106 int64_t mNextRequestId;
108 nsresult mAbortCode; ///< The result that caused the transaction to be
109 ///< aborted, or NS_OK if not aborted.
110 ///< NS_ERROR_DOM_INDEXEDDB_ABORT_ERR indicates that the
111 ///< user explicitly requested aborting. Should be
112 ///< renamed to mResult or so, because it is actually
113 ///< used to check if the transaction has been aborted.
114 uint32_t mPendingRequestCount; ///< Counted via OnNewRequest and
115 ///< OnRequestFinished, so that the
116 ///< transaction can auto-commit when the last
117 ///< pending request finished.
119 const JSCallingLocation mCallerLocation;
121 ReadyState mReadyState = ReadyState::Active;
122 FlippedOnce<false> mStarted;
123 const Mode mMode;
124 const Durability mDurability;
126 bool mRegistered; ///< Whether mDatabase->RegisterTransaction() has been
127 ///< called (which may not be the case if construction was
128 ///< incomplete).
129 FlippedOnce<false> mAbortedByScript;
130 bool mNotedActiveTransaction;
131 FlippedOnce<false> mSentCommitOrAbort;
133 #ifdef DEBUG
134 FlippedOnce<false> mFiredCompleteOrAbort;
135 FlippedOnce<false> mWasExplicitlyCommitted;
136 #endif
138 public:
139 [[nodiscard]] static SafeRefPtr<IDBTransaction> CreateVersionChange(
140 IDBDatabase* aDatabase,
141 indexedDB::BackgroundVersionChangeTransactionChild* aActor,
142 NotNull<IDBOpenDBRequest*> aOpenRequest, int64_t aNextObjectStoreId,
143 int64_t aNextIndexId);
145 [[nodiscard]] static SafeRefPtr<IDBTransaction> Create(
146 JSContext* aCx, IDBDatabase* aDatabase,
147 const nsTArray<nsString>& aObjectStoreNames, Mode aMode,
148 Durability aDurability);
150 static Maybe<IDBTransaction&> MaybeCurrent();
152 void AssertIsOnOwningThread() const
153 #ifdef DEBUG
155 #else
158 #endif
160 void SetBackgroundActor(
161 indexedDB::BackgroundTransactionChild* aBackgroundActor);
163 void ClearBackgroundActor() {
164 AssertIsOnOwningThread();
166 if (mMode == Mode::VersionChange) {
167 mBackgroundActor.mVersionChangeBackgroundActor = nullptr;
168 } else {
169 mBackgroundActor.mNormalBackgroundActor = nullptr;
172 // Note inactive transaction here if we didn't receive the Complete message
173 // from the parent.
174 MaybeNoteInactiveTransaction();
177 indexedDB::BackgroundRequestChild* StartRequest(
178 MovingNotNull<RefPtr<mozilla::dom::IDBRequest>> aRequest,
179 const indexedDB::RequestParams& aParams);
181 void OpenCursor(indexedDB::PBackgroundIDBCursorChild& aBackgroundActor,
182 const indexedDB::OpenCursorParams& aParams);
184 void RefreshSpec(bool aMayDelete);
186 bool IsCommittingOrFinished() const {
187 AssertIsOnOwningThread();
189 return mReadyState == ReadyState::Committing ||
190 mReadyState == ReadyState::Finished;
193 bool IsActive() const {
194 AssertIsOnOwningThread();
196 return mReadyState == ReadyState::Active;
199 bool IsInactive() const {
200 AssertIsOnOwningThread();
202 return mReadyState == ReadyState::Inactive;
205 bool IsFinished() const {
206 AssertIsOnOwningThread();
208 return mReadyState == ReadyState::Finished;
211 bool IsWriteAllowed() const {
212 AssertIsOnOwningThread();
213 return mMode == Mode::ReadWrite || mMode == Mode::ReadWriteFlush ||
214 mMode == Mode::Cleanup || mMode == Mode::VersionChange;
217 bool IsAborted() const {
218 AssertIsOnOwningThread();
219 return NS_FAILED(mAbortCode);
222 #ifdef DEBUG
223 bool WasExplicitlyCommitted() const { return mWasExplicitlyCommitted; }
224 #endif
226 void TransitionToActive() {
227 MOZ_ASSERT(mReadyState == ReadyState::Inactive);
228 mReadyState = ReadyState::Active;
231 void TransitionToInactive() {
232 MOZ_ASSERT(mReadyState == ReadyState::Active);
233 mReadyState = ReadyState::Inactive;
236 nsresult AbortCode() const {
237 AssertIsOnOwningThread();
238 return mAbortCode;
241 const JSCallingLocation& GetCallerLocation() const {
242 AssertIsOnOwningThread();
243 return mCallerLocation;
246 // 'Get' prefix is to avoid name collisions with the enum
247 Mode GetMode() const {
248 AssertIsOnOwningThread();
249 return mMode;
252 Durability GetDurability() const {
253 AssertIsOnOwningThread();
254 return mDurability;
257 uint32_t GetPendingRequestCount() const { return mPendingRequestCount; }
259 IDBDatabase* Database() const {
260 AssertIsOnOwningThread();
261 return mDatabase;
264 // Only for use by ProfilerHelpers.h
265 const nsTArray<nsString>& ObjectStoreNamesInternal() const {
266 AssertIsOnOwningThread();
267 return mObjectStoreNames;
270 [[nodiscard]] RefPtr<IDBObjectStore> CreateObjectStore(
271 indexedDB::ObjectStoreSpec& aSpec);
273 void DeleteObjectStore(int64_t aObjectStoreId);
275 void RenameObjectStore(int64_t aObjectStoreId, const nsAString& aName) const;
277 void CreateIndex(IDBObjectStore* aObjectStore,
278 const indexedDB::IndexMetadata& aMetadata) const;
280 void DeleteIndex(IDBObjectStore* aObjectStore, int64_t aIndexId) const;
282 void RenameIndex(IDBObjectStore* aObjectStore, int64_t aIndexId,
283 const nsAString& aName) const;
285 void Abort(IDBRequest* aRequest);
287 void Abort(nsresult aErrorCode);
289 int64_t LoggingSerialNumber() const {
290 AssertIsOnOwningThread();
292 return mLoggingSerialNumber;
295 nsIGlobalObject* GetParentObject() const;
297 void FireCompleteOrAbortEvents(nsresult aResult);
299 // Only for Mode::VersionChange transactions.
300 int64_t NextObjectStoreId();
302 // Only for Mode::VersionChange transactions.
303 int64_t NextIndexId();
305 // See the comment for mNextRequestId.
306 int64_t NextRequestId();
308 void InvalidateCursorCaches();
309 void RegisterCursor(IDBCursor& aCursor);
310 void UnregisterCursor(IDBCursor& aCursor);
312 NS_DECL_ISUPPORTS_INHERITED
313 NS_DECL_NSIRUNNABLE
314 NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(IDBTransaction, DOMEventTargetHelper)
316 void CommitIfNotStarted();
318 // nsWrapperCache
319 JSObject* WrapObject(JSContext* aCx,
320 JS::Handle<JSObject*> aGivenProto) override;
322 // Methods bound via WebIDL.
323 IDBDatabase* Db() const { return Database(); }
325 IDBTransactionMode GetMode(ErrorResult& aRv) const;
327 IDBTransactionDurability GetDurability(ErrorResult& aRv) const;
329 DOMException* GetError() const;
331 [[nodiscard]] RefPtr<IDBObjectStore> ObjectStore(const nsAString& aName,
332 ErrorResult& aRv);
334 void Commit(ErrorResult& aRv);
336 void Abort(ErrorResult& aRv);
338 IMPL_EVENT_HANDLER(abort)
339 IMPL_EVENT_HANDLER(complete)
340 IMPL_EVENT_HANDLER(error)
342 [[nodiscard]] RefPtr<DOMStringList> ObjectStoreNames() const;
344 // EventTarget
345 void GetEventTargetParent(EventChainPreVisitor& aVisitor) override;
347 private:
348 struct CreatedFromFactoryFunction {};
350 public:
351 IDBTransaction(IDBDatabase* aDatabase,
352 const nsTArray<nsString>& aObjectStoreNames, Mode aMode,
353 Durability aDurability, JSCallingLocation&& aCallerLocation,
354 CreatedFromFactoryFunction aDummy);
356 private:
357 ~IDBTransaction();
359 void AbortInternal(nsresult aAbortCode, RefPtr<DOMException> aError);
361 void SendCommit(bool aAutoCommit);
363 void SendAbort(nsresult aResultCode);
365 void NoteActiveTransaction();
367 void MaybeNoteInactiveTransaction();
369 // TODO consider making private again, or move to the right place
370 public:
371 void OnNewRequest();
373 void OnRequestFinished(bool aRequestCompletedSuccessfully);
375 private:
376 template <typename Func>
377 auto DoWithTransactionChild(const Func& aFunc) const;
379 bool HasTransactionChild() const;
382 inline bool ReferenceEquals(const Maybe<IDBTransaction&>& aLHS,
383 const Maybe<IDBTransaction&>& aRHS) {
384 if (aLHS.isNothing() != aRHS.isNothing()) {
385 return false;
387 return aLHS.isNothing() || &aLHS.ref() == &aRHS.ref();
390 } // namespace dom
391 } // namespace mozilla
393 #endif // mozilla_dom_idbtransaction_h__