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/dom/DOMException.h"
14 #include "mozilla/dom/IDBRequestBinding.h"
15 #include "mozilla/dom/ScriptSettings.h"
16 #include "mozilla/DOMEventTargetHelper.h"
17 #include "mozilla/HoldDropJSObjects.h"
18 #include "nsCycleCollectionParticipant.h"
19 #include "ReportInternalError.h"
20 #include "SafeRefPtr.h"
22 #define PRIVATE_IDBREQUEST_IID \
24 0xe68901e5, 0x1d50, 0x4ee9, { \
25 0xaf, 0x49, 0x90, 0x99, 0x4a, 0xff, 0xc8, 0x39 \
29 class nsIGlobalObject
;
45 class OwningIDBObjectStoreOrIDBIndexOrIDBCursor
;
46 class StrongWorkerRef
;
49 // This class holds the IID for use with NS_GET_IID.
50 class PrivateIDBRequest
{
52 NS_DECLARE_STATIC_IID_ACCESSOR(PRIVATE_IDBREQUEST_IID
)
55 NS_DEFINE_STATIC_IID_ACCESSOR(PrivateIDBRequest
, PRIVATE_IDBREQUEST_IID
)
59 class IDBRequest
: public DOMEventTargetHelper
{
61 // mSourceAsObjectStore and mSourceAsIndex are exclusive and one must always
62 // be set. mSourceAsCursor is sometimes set also.
63 RefPtr
<IDBObjectStore
> mSourceAsObjectStore
;
64 RefPtr
<IDBIndex
> mSourceAsIndex
;
65 RefPtr
<IDBCursor
> mSourceAsCursor
;
67 SafeRefPtr
<IDBTransaction
> mTransaction
;
69 JS::Heap
<JS::Value
> mResultVal
;
70 RefPtr
<DOMException
> mError
;
73 uint64_t mLoggingSerialNumber
;
77 bool mHaveResultOrErrorCode
;
80 [[nodiscard
]] static MovingNotNull
<RefPtr
<IDBRequest
>> Create(
81 JSContext
* aCx
, IDBDatabase
* aDatabase
,
82 SafeRefPtr
<IDBTransaction
> aTransaction
);
84 [[nodiscard
]] static MovingNotNull
<RefPtr
<IDBRequest
>> Create(
85 JSContext
* aCx
, IDBObjectStore
* aSource
, IDBDatabase
* aDatabase
,
86 SafeRefPtr
<IDBTransaction
> aTransaction
);
88 [[nodiscard
]] static MovingNotNull
<RefPtr
<IDBRequest
>> Create(
89 JSContext
* aCx
, IDBIndex
* aSource
, IDBDatabase
* aDatabase
,
90 SafeRefPtr
<IDBTransaction
> aTransaction
);
92 static void CaptureCaller(JSContext
* aCx
, nsAString
& aFilename
,
93 uint32_t* aLineNo
, uint32_t* aColumn
);
95 static uint64_t NextSerialNumber();
98 void GetEventTargetParent(EventChainPreVisitor
& aVisitor
) override
;
101 Nullable
<OwningIDBObjectStoreOrIDBIndexOrIDBCursor
>& aSource
) const;
105 template <typename ResultCallback
>
106 void SetResult(const ResultCallback
& aCallback
) {
107 AssertIsOnOwningThread();
108 MOZ_ASSERT(!mHaveResultOrErrorCode
);
109 MOZ_ASSERT(mResultVal
.isUndefined());
112 // Already disconnected from the owner.
113 if (!GetOwnerGlobal()) {
114 SetError(NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR
);
118 // See this global is still valid.
119 if (NS_WARN_IF(NS_FAILED(CheckCurrentGlobalCorrectness()))) {
120 SetError(NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR
);
125 if (!autoJS
.Init(GetOwnerGlobal())) {
126 IDB_WARNING("Failed to initialize AutoJSAPI!");
127 SetError(NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR
);
131 JSContext
* cx
= autoJS
.cx();
133 JS::Rooted
<JS::Value
> result(cx
);
134 nsresult rv
= aCallback(cx
, &result
);
135 if (NS_WARN_IF(NS_FAILED(rv
))) {
136 // This can only fail if the structured clone contains a mutable file
137 // and the child is not in the main thread and main process.
138 // In that case CreateAndWrapMutableFile() returns false which shows up
139 // as NS_ERROR_DOM_DATA_CLONE_ERR here.
140 MOZ_ASSERT(rv
== NS_ERROR_DOM_DATA_CLONE_ERR
);
142 // We are not setting a result or an error object here since we want to
143 // throw an exception when the 'result' property is being touched.
150 mozilla::HoldJSObjects(this);
152 mHaveResultOrErrorCode
= true;
155 void SetError(nsresult aRv
);
157 nsresult
GetErrorCode() const
166 DOMException
* GetErrorAfterResult() const
175 DOMException
* GetError(ErrorResult
& aRv
);
177 void GetCallerLocation(nsAString
& aFilename
, uint32_t* aLineNo
,
178 uint32_t* aColumn
) const;
180 bool IsPending() const { return !mHaveResultOrErrorCode
; }
182 uint64_t LoggingSerialNumber() const {
183 AssertIsOnOwningThread();
185 return mLoggingSerialNumber
;
188 void SetLoggingSerialNumber(uint64_t aLoggingSerialNumber
);
190 nsIGlobalObject
* GetParentObject() const { return GetOwnerGlobal(); }
192 void GetResult(JS::MutableHandle
<JS::Value
> aResult
, ErrorResult
& aRv
) const;
194 void GetResult(JSContext
* aCx
, JS::MutableHandle
<JS::Value
> aResult
,
195 ErrorResult
& aRv
) const {
196 GetResult(aResult
, aRv
);
199 Maybe
<IDBTransaction
&> MaybeTransactionRef() const {
200 AssertIsOnOwningThread();
202 return mTransaction
.maybeDeref();
205 IDBTransaction
& MutableTransactionRef() const {
206 AssertIsOnOwningThread();
208 return *mTransaction
;
211 SafeRefPtr
<IDBTransaction
> AcquireTransaction() const {
212 AssertIsOnOwningThread();
214 return mTransaction
.clonePtr();
217 // For WebIDL binding.
218 RefPtr
<IDBTransaction
> GetTransaction() const {
219 AssertIsOnOwningThread();
221 return AsRefPtr(mTransaction
.clonePtr());
224 IDBRequestReadyState
ReadyState() const;
226 void SetSource(IDBCursor
* aSource
);
228 IMPL_EVENT_HANDLER(success
);
229 IMPL_EVENT_HANDLER(error
);
231 void AssertIsOnOwningThread() const { NS_ASSERT_OWNINGTHREAD(IDBRequest
); }
233 NS_DECL_ISUPPORTS_INHERITED
234 NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS_INHERITED(IDBRequest
,
235 DOMEventTargetHelper
)
238 virtual JSObject
* WrapObject(JSContext
* aCx
,
239 JS::Handle
<JSObject
*> aGivenProto
) override
;
242 explicit IDBRequest(IDBDatabase
* aDatabase
);
243 explicit IDBRequest(nsIGlobalObject
* aGlobal
);
248 void ConstructResult();
251 class IDBOpenDBRequest final
: public IDBRequest
{
252 // Only touched on the owning thread.
253 SafeRefPtr
<IDBFactory
> mFactory
;
255 RefPtr
<StrongWorkerRef
> mWorkerRef
;
257 bool mIncreasedActiveDatabaseCount
;
260 [[nodiscard
]] static RefPtr
<IDBOpenDBRequest
> Create(
261 JSContext
* aCx
, SafeRefPtr
<IDBFactory
> aFactory
,
262 nsIGlobalObject
* aGlobal
);
264 void SetTransaction(SafeRefPtr
<IDBTransaction
> aTransaction
);
266 void DispatchNonTransactionError(nsresult aErrorCode
);
271 IMPL_EVENT_HANDLER(blocked
);
272 IMPL_EVENT_HANDLER(upgradeneeded
);
274 NS_DECL_ISUPPORTS_INHERITED
275 NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(IDBOpenDBRequest
, IDBRequest
)
278 virtual JSObject
* WrapObject(JSContext
* aCx
,
279 JS::Handle
<JSObject
*> aGivenProto
) override
;
282 IDBOpenDBRequest(SafeRefPtr
<IDBFactory
> aFactory
, nsIGlobalObject
* aGlobal
);
286 void IncreaseActiveDatabaseCount();
288 void MaybeDecreaseActiveDatabaseCount();
292 } // namespace mozilla
294 #endif // mozilla_dom_idbrequest_h__