Line data Source code
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_idbtransaction_h__
8 : #define mozilla_dom_idbtransaction_h__
9 :
10 : #include "mozilla/Attributes.h"
11 : #include "mozilla/dom/IDBTransactionBinding.h"
12 : #include "mozilla/dom/IDBWrapperCache.h"
13 : #include "nsAutoPtr.h"
14 : #include "nsCycleCollectionParticipant.h"
15 : #include "nsIRunnable.h"
16 : #include "nsString.h"
17 : #include "nsTArray.h"
18 :
19 : class nsPIDOMWindowInner;
20 :
21 : namespace mozilla {
22 :
23 : class ErrorResult;
24 : class EventChainPreVisitor;
25 :
26 : namespace dom {
27 :
28 : class DOMError;
29 : class DOMStringList;
30 : class IDBDatabase;
31 : class IDBObjectStore;
32 : class IDBOpenDBRequest;
33 : class IDBRequest;
34 :
35 : namespace indexedDB {
36 : class BackgroundCursorChild;
37 : class BackgroundRequestChild;
38 : class BackgroundTransactionChild;
39 : class BackgroundVersionChangeTransactionChild;
40 : class IndexMetadata;
41 : class ObjectStoreSpec;
42 : class OpenCursorParams;
43 : class RequestParams;
44 : }
45 :
46 : class IDBTransaction final
47 : : public IDBWrapperCache
48 : , public nsIRunnable
49 : {
50 : friend class indexedDB::BackgroundCursorChild;
51 : friend class indexedDB::BackgroundRequestChild;
52 :
53 : class WorkerHolder;
54 : friend class WorkerHolder;
55 :
56 : public:
57 : enum Mode
58 : {
59 : READ_ONLY = 0,
60 : READ_WRITE,
61 : READ_WRITE_FLUSH,
62 : CLEANUP,
63 : VERSION_CHANGE,
64 :
65 : // Only needed for IPC serialization helper, should never be used in code.
66 : MODE_INVALID
67 : };
68 :
69 : enum ReadyState
70 : {
71 : INITIAL = 0,
72 : LOADING,
73 : COMMITTING,
74 : DONE
75 : };
76 :
77 : private:
78 : RefPtr<IDBDatabase> mDatabase;
79 : RefPtr<DOMError> mError;
80 : nsTArray<nsString> mObjectStoreNames;
81 : nsTArray<RefPtr<IDBObjectStore>> mObjectStores;
82 : nsTArray<RefPtr<IDBObjectStore>> mDeletedObjectStores;
83 : nsAutoPtr<WorkerHolder> mWorkerHolder;
84 :
85 : // Tagged with mMode. If mMode is VERSION_CHANGE then mBackgroundActor will be
86 : // a BackgroundVersionChangeTransactionChild. Otherwise it will be a
87 : // BackgroundTransactionChild.
88 : union {
89 : indexedDB::BackgroundTransactionChild* mNormalBackgroundActor;
90 : indexedDB::BackgroundVersionChangeTransactionChild* mVersionChangeBackgroundActor;
91 : } mBackgroundActor;
92 :
93 : const int64_t mLoggingSerialNumber;
94 :
95 : // Only used for VERSION_CHANGE transactions.
96 : int64_t mNextObjectStoreId;
97 : int64_t mNextIndexId;
98 :
99 : nsresult mAbortCode;
100 : uint32_t mPendingRequestCount;
101 :
102 : nsString mFilename;
103 : uint32_t mLineNo;
104 : uint32_t mColumn;
105 :
106 : ReadyState mReadyState;
107 : Mode mMode;
108 :
109 : bool mCreating;
110 : bool mRegistered;
111 : bool mAbortedByScript;
112 : bool mNotedActiveTransaction;
113 :
114 : #ifdef DEBUG
115 : bool mSentCommitOrAbort;
116 : bool mFiredCompleteOrAbort;
117 : #endif
118 :
119 : public:
120 : static already_AddRefed<IDBTransaction>
121 : CreateVersionChange(IDBDatabase* aDatabase,
122 : indexedDB::BackgroundVersionChangeTransactionChild* aActor,
123 : IDBOpenDBRequest* aOpenRequest,
124 : int64_t aNextObjectStoreId,
125 : int64_t aNextIndexId);
126 :
127 : static already_AddRefed<IDBTransaction>
128 : Create(JSContext* aCx, IDBDatabase* aDatabase,
129 : const nsTArray<nsString>& aObjectStoreNames,
130 : Mode aMode);
131 :
132 : static IDBTransaction*
133 : GetCurrent();
134 :
135 : void
136 : AssertIsOnOwningThread() const
137 : #ifdef DEBUG
138 : ;
139 : #else
140 : { }
141 : #endif
142 :
143 : void
144 : SetBackgroundActor(indexedDB::BackgroundTransactionChild* aBackgroundActor);
145 :
146 : void
147 0 : ClearBackgroundActor()
148 : {
149 0 : AssertIsOnOwningThread();
150 :
151 0 : if (mMode == VERSION_CHANGE) {
152 0 : mBackgroundActor.mVersionChangeBackgroundActor = nullptr;
153 : } else {
154 0 : mBackgroundActor.mNormalBackgroundActor = nullptr;
155 : }
156 :
157 : // Note inactive transaction here if we didn't receive the Complete message
158 : // from the parent.
159 0 : MaybeNoteInactiveTransaction();
160 0 : }
161 :
162 : indexedDB::BackgroundRequestChild*
163 : StartRequest(IDBRequest* aRequest, const indexedDB::RequestParams& aParams);
164 :
165 : void
166 : OpenCursor(indexedDB::BackgroundCursorChild* aBackgroundActor,
167 : const indexedDB::OpenCursorParams& aParams);
168 :
169 : void
170 : RefreshSpec(bool aMayDelete);
171 :
172 : bool
173 : IsOpen() const;
174 :
175 : bool
176 0 : IsCommittingOrDone() const
177 : {
178 0 : AssertIsOnOwningThread();
179 :
180 0 : return mReadyState == COMMITTING || mReadyState == DONE;
181 : }
182 :
183 : bool
184 0 : IsDone() const
185 : {
186 0 : AssertIsOnOwningThread();
187 :
188 0 : return mReadyState == DONE;
189 : }
190 :
191 : bool
192 0 : IsWriteAllowed() const
193 : {
194 0 : AssertIsOnOwningThread();
195 0 : return mMode == READ_WRITE ||
196 0 : mMode == READ_WRITE_FLUSH ||
197 0 : mMode == CLEANUP ||
198 0 : mMode == VERSION_CHANGE;
199 : }
200 :
201 : bool
202 0 : IsAborted() const
203 : {
204 0 : AssertIsOnOwningThread();
205 0 : return NS_FAILED(mAbortCode);
206 : }
207 :
208 : nsresult
209 0 : AbortCode() const
210 : {
211 0 : AssertIsOnOwningThread();
212 0 : return mAbortCode;
213 : }
214 :
215 : void
216 : GetCallerLocation(nsAString& aFilename, uint32_t* aLineNo,
217 : uint32_t* aColumn) const;
218 :
219 : // 'Get' prefix is to avoid name collisions with the enum
220 : Mode
221 0 : GetMode() const
222 : {
223 0 : AssertIsOnOwningThread();
224 0 : return mMode;
225 : }
226 :
227 : IDBDatabase*
228 0 : Database() const
229 : {
230 0 : AssertIsOnOwningThread();
231 0 : return mDatabase;
232 : }
233 :
234 : IDBDatabase*
235 0 : Db() const
236 : {
237 0 : return Database();
238 : }
239 :
240 : const nsTArray<nsString>&
241 0 : ObjectStoreNamesInternal() const
242 : {
243 0 : AssertIsOnOwningThread();
244 0 : return mObjectStoreNames;
245 : }
246 :
247 : already_AddRefed<IDBObjectStore>
248 : CreateObjectStore(const indexedDB::ObjectStoreSpec& aSpec);
249 :
250 : void
251 : DeleteObjectStore(int64_t aObjectStoreId);
252 :
253 : void
254 : RenameObjectStore(int64_t aObjectStoreId, const nsAString& aName);
255 :
256 : void
257 : CreateIndex(IDBObjectStore* aObjectStore, const indexedDB::IndexMetadata& aMetadata);
258 :
259 : void
260 : DeleteIndex(IDBObjectStore* aObjectStore, int64_t aIndexId);
261 :
262 : void
263 : RenameIndex(IDBObjectStore* aObjectStore, int64_t aIndexId, const nsAString& aName);
264 :
265 : void
266 : Abort(IDBRequest* aRequest);
267 :
268 : void
269 : Abort(nsresult aAbortCode);
270 :
271 : int64_t
272 0 : LoggingSerialNumber() const
273 : {
274 0 : AssertIsOnOwningThread();
275 :
276 0 : return mLoggingSerialNumber;
277 : }
278 :
279 : nsPIDOMWindowInner*
280 : GetParentObject() const;
281 :
282 : IDBTransactionMode
283 : GetMode(ErrorResult& aRv) const;
284 :
285 : DOMError*
286 : GetError() const;
287 :
288 : already_AddRefed<IDBObjectStore>
289 : ObjectStore(const nsAString& aName, ErrorResult& aRv);
290 :
291 : void
292 : Abort(ErrorResult& aRv);
293 :
294 0 : IMPL_EVENT_HANDLER(abort)
295 0 : IMPL_EVENT_HANDLER(complete)
296 0 : IMPL_EVENT_HANDLER(error)
297 :
298 : already_AddRefed<DOMStringList>
299 : ObjectStoreNames() const;
300 :
301 : void
302 : FireCompleteOrAbortEvents(nsresult aResult);
303 :
304 : // Only for VERSION_CHANGE transactions.
305 : int64_t
306 : NextObjectStoreId();
307 :
308 : // Only for VERSION_CHANGE transactions.
309 : int64_t
310 : NextIndexId();
311 :
312 : NS_DECL_ISUPPORTS_INHERITED
313 : NS_DECL_NSIRUNNABLE
314 0 : NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(IDBTransaction, IDBWrapperCache)
315 :
316 : // nsWrapperCache
317 : virtual JSObject*
318 : WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) override;
319 :
320 : // nsIDOMEventTarget
321 : virtual nsresult
322 : GetEventTargetParent(EventChainPreVisitor& aVisitor) override;
323 :
324 : private:
325 : IDBTransaction(IDBDatabase* aDatabase,
326 : const nsTArray<nsString>& aObjectStoreNames,
327 : Mode aMode);
328 : ~IDBTransaction();
329 :
330 : void
331 : AbortInternal(nsresult aAbortCode, already_AddRefed<DOMError> aError);
332 :
333 : void
334 : SendCommit();
335 :
336 : void
337 : SendAbort(nsresult aResultCode);
338 :
339 : void
340 : NoteActiveTransaction();
341 :
342 : void
343 : MaybeNoteInactiveTransaction();
344 :
345 : void
346 : OnNewRequest();
347 :
348 : void
349 : OnRequestFinished(bool aActorDestroyedNormally);
350 : };
351 :
352 : } // namespace dom
353 : } // namespace mozilla
354 :
355 : #endif // mozilla_dom_idbtransaction_h__
|