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_idbrequest_h__
8 #define mozilla_dom_idbrequest_h__
10 #include "js/RootingAPI.h"
11 #include "mozilla/Attributes.h"
12 #include "mozilla/EventForwards.h"
13 #include "mozilla/SourceLocation.h"
14 #include "mozilla/dom/DOMException.h"
15 #include "mozilla/dom/IDBRequestBinding.h"
16 #include "mozilla/dom/ScriptSettings.h"
17 #include "mozilla/DOMEventTargetHelper.h"
18 #include "mozilla/HoldDropJSObjects.h"
19 #include "nsCycleCollectionParticipant.h"
20 #include "ReportInternalError.h"
21 #include "SafeRefPtr.h"
23 #define PRIVATE_IDBREQUEST_IID \
25 0xe68901e5, 0x1d50, 0x4ee9, { \
26 0xaf, 0x49, 0x90, 0x99, 0x4a, 0xff, 0xc8, 0x39 \
30 class nsIGlobalObject
;
46 class OwningIDBObjectStoreOrIDBIndexOrIDBCursor
;
47 class StrongWorkerRef
;
50 // This class holds the IID for use with NS_GET_IID.
51 class PrivateIDBRequest
{
53 NS_DECLARE_STATIC_IID_ACCESSOR(PRIVATE_IDBREQUEST_IID
)
56 NS_DEFINE_STATIC_IID_ACCESSOR(PrivateIDBRequest
, PRIVATE_IDBREQUEST_IID
)
60 class IDBRequest
: public DOMEventTargetHelper
{
62 // mSourceAsObjectStore and mSourceAsIndex are exclusive and one must always
63 // be set. mSourceAsCursor is sometimes set also.
64 RefPtr
<IDBObjectStore
> mSourceAsObjectStore
;
65 RefPtr
<IDBIndex
> mSourceAsIndex
;
66 RefPtr
<IDBCursor
> mSourceAsCursor
;
68 SafeRefPtr
<IDBTransaction
> mTransaction
;
70 JS::Heap
<JS::Value
> mResultVal
;
71 RefPtr
<DOMException
> mError
;
73 JSCallingLocation mCallerLocation
;
74 uint64_t mLoggingSerialNumber
;
76 bool mHaveResultOrErrorCode
;
79 [[nodiscard
]] static MovingNotNull
<RefPtr
<IDBRequest
>> Create(
80 JSContext
* aCx
, IDBDatabase
* aDatabase
,
81 SafeRefPtr
<IDBTransaction
> aTransaction
);
83 [[nodiscard
]] static MovingNotNull
<RefPtr
<IDBRequest
>> Create(
84 JSContext
* aCx
, IDBObjectStore
* aSource
, IDBDatabase
* aDatabase
,
85 SafeRefPtr
<IDBTransaction
> aTransaction
);
87 [[nodiscard
]] static MovingNotNull
<RefPtr
<IDBRequest
>> Create(
88 JSContext
* aCx
, IDBIndex
* aSource
, IDBDatabase
* aDatabase
,
89 SafeRefPtr
<IDBTransaction
> aTransaction
);
91 static uint64_t NextSerialNumber();
94 void GetEventTargetParent(EventChainPreVisitor
& aVisitor
) override
;
97 Nullable
<OwningIDBObjectStoreOrIDBIndexOrIDBCursor
>& aSource
) const;
101 template <typename ResultCallback
>
102 void SetResult(const ResultCallback
& aCallback
) {
103 AssertIsOnOwningThread();
104 MOZ_ASSERT(!mHaveResultOrErrorCode
);
105 MOZ_ASSERT(mResultVal
.isUndefined());
108 // Already disconnected from the owner.
109 if (!GetOwnerGlobal()) {
110 SetError(NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR
);
114 // See this global is still valid.
115 if (NS_WARN_IF(NS_FAILED(CheckCurrentGlobalCorrectness()))) {
116 SetError(NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR
);
121 if (!autoJS
.Init(GetOwnerGlobal())) {
122 IDB_WARNING("Failed to initialize AutoJSAPI!");
123 SetError(NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR
);
127 JSContext
* cx
= autoJS
.cx();
129 JS::Rooted
<JS::Value
> result(cx
);
130 nsresult rv
= aCallback(cx
, &result
);
131 if (NS_WARN_IF(NS_FAILED(rv
))) {
132 // This can only fail if the structured clone contains a mutable file
133 // and the child is not in the main thread and main process.
134 // In that case CreateAndWrapMutableFile() returns false which shows up
135 // as NS_ERROR_DOM_DATA_CLONE_ERR here.
136 MOZ_ASSERT(rv
== NS_ERROR_DOM_DATA_CLONE_ERR
);
138 // We are not setting a result or an error object here since we want to
139 // throw an exception when the 'result' property is being touched.
146 mozilla::HoldJSObjects(this);
148 mHaveResultOrErrorCode
= true;
151 void SetError(nsresult aRv
);
153 nsresult
GetErrorCode() const
162 DOMException
* GetErrorAfterResult() const
171 DOMException
* GetError(ErrorResult
& aRv
);
173 const JSCallingLocation
& GetCallerLocation() const { return mCallerLocation
; }
175 bool IsPending() const { return !mHaveResultOrErrorCode
; }
177 uint64_t LoggingSerialNumber() const {
178 AssertIsOnOwningThread();
180 return mLoggingSerialNumber
;
183 void SetLoggingSerialNumber(uint64_t aLoggingSerialNumber
);
185 nsIGlobalObject
* GetParentObject() const { return GetOwnerGlobal(); }
187 void GetResult(JS::MutableHandle
<JS::Value
> aResult
, ErrorResult
& aRv
) const;
189 void GetResult(JSContext
* aCx
, JS::MutableHandle
<JS::Value
> aResult
,
190 ErrorResult
& aRv
) const {
191 GetResult(aResult
, aRv
);
194 Maybe
<IDBTransaction
&> MaybeTransactionRef() const {
195 AssertIsOnOwningThread();
197 return mTransaction
.maybeDeref();
200 IDBTransaction
& MutableTransactionRef() const {
201 AssertIsOnOwningThread();
203 return *mTransaction
;
206 SafeRefPtr
<IDBTransaction
> AcquireTransaction() const {
207 AssertIsOnOwningThread();
209 return mTransaction
.clonePtr();
212 // For WebIDL binding.
213 RefPtr
<IDBTransaction
> GetTransaction() const {
214 AssertIsOnOwningThread();
216 return AsRefPtr(mTransaction
.clonePtr());
219 IDBRequestReadyState
ReadyState() const;
221 void SetSource(IDBCursor
* aSource
);
223 IMPL_EVENT_HANDLER(success
);
224 IMPL_EVENT_HANDLER(error
);
226 void AssertIsOnOwningThread() const { NS_ASSERT_OWNINGTHREAD(IDBRequest
); }
228 NS_DECL_ISUPPORTS_INHERITED
229 NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS_INHERITED(IDBRequest
,
230 DOMEventTargetHelper
)
233 virtual JSObject
* WrapObject(JSContext
* aCx
,
234 JS::Handle
<JSObject
*> aGivenProto
) override
;
237 explicit IDBRequest(IDBDatabase
* aDatabase
);
238 explicit IDBRequest(nsIGlobalObject
* aGlobal
);
243 void ConstructResult();
246 class IDBOpenDBRequest final
: public IDBRequest
{
247 // Only touched on the owning thread.
248 SafeRefPtr
<IDBFactory
> mFactory
;
250 RefPtr
<StrongWorkerRef
> mWorkerRef
;
252 bool mIncreasedActiveDatabaseCount
;
255 [[nodiscard
]] static RefPtr
<IDBOpenDBRequest
> Create(
256 JSContext
* aCx
, SafeRefPtr
<IDBFactory
> aFactory
,
257 nsIGlobalObject
* aGlobal
);
259 void SetTransaction(SafeRefPtr
<IDBTransaction
> aTransaction
);
261 void DispatchNonTransactionError(nsresult aErrorCode
);
266 IMPL_EVENT_HANDLER(blocked
);
267 IMPL_EVENT_HANDLER(upgradeneeded
);
269 NS_DECL_ISUPPORTS_INHERITED
270 NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(IDBOpenDBRequest
, IDBRequest
)
273 virtual JSObject
* WrapObject(JSContext
* aCx
,
274 JS::Handle
<JSObject
*> aGivenProto
) override
;
277 IDBOpenDBRequest(SafeRefPtr
<IDBFactory
> aFactory
, nsIGlobalObject
* aGlobal
);
281 void IncreaseActiveDatabaseCount();
283 void MaybeDecreaseActiveDatabaseCount();
287 } // namespace mozilla
289 #endif // mozilla_dom_idbrequest_h__