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_idbobjectstore_h__
8 : #define mozilla_dom_idbobjectstore_h__
9 :
10 : #include "js/RootingAPI.h"
11 : #include "mozilla/dom/IDBCursorBinding.h"
12 : #include "mozilla/dom/IDBIndexBinding.h"
13 : #include "nsAutoPtr.h"
14 : #include "nsCycleCollectionParticipant.h"
15 : #include "nsISupports.h"
16 : #include "nsString.h"
17 : #include "nsTArray.h"
18 : #include "nsWrapperCache.h"
19 :
20 : struct JSClass;
21 : class nsPIDOMWindowInner;
22 :
23 : namespace mozilla {
24 :
25 : class ErrorResult;
26 :
27 : namespace dom {
28 :
29 : class DOMStringList;
30 : class IDBCursor;
31 : class IDBRequest;
32 : class IDBTransaction;
33 : class StringOrStringSequence;
34 : template <typename> class Sequence;
35 :
36 : namespace indexedDB {
37 : class Key;
38 : class KeyPath;
39 : class IndexUpdateInfo;
40 : class ObjectStoreSpec;
41 : struct StructuredCloneReadInfo;
42 : } // namespace indexedDB
43 :
44 : class IDBObjectStore final
45 : : public nsISupports
46 : , public nsWrapperCache
47 : {
48 : typedef indexedDB::IndexUpdateInfo IndexUpdateInfo;
49 : typedef indexedDB::Key Key;
50 : typedef indexedDB::KeyPath KeyPath;
51 : typedef indexedDB::ObjectStoreSpec ObjectStoreSpec;
52 : typedef indexedDB::StructuredCloneReadInfo StructuredCloneReadInfo;
53 :
54 : // For AddOrPut() and DeleteInternal().
55 : friend class IDBCursor;
56 :
57 : static const JSClass sDummyPropJSClass;
58 :
59 : RefPtr<IDBTransaction> mTransaction;
60 : JS::Heap<JS::Value> mCachedKeyPath;
61 :
62 : // This normally points to the ObjectStoreSpec owned by the parent IDBDatabase
63 : // object. However, if this objectStore is part of a versionchange transaction
64 : // and it gets deleted then the spec is copied into mDeletedSpec and mSpec is
65 : // set to point at mDeletedSpec.
66 : const ObjectStoreSpec* mSpec;
67 : nsAutoPtr<ObjectStoreSpec> mDeletedSpec;
68 :
69 : nsTArray<RefPtr<IDBIndex>> mIndexes;
70 : nsTArray<RefPtr<IDBIndex>> mDeletedIndexes;
71 :
72 : const int64_t mId;
73 : bool mRooted;
74 :
75 : public:
76 : struct StructuredCloneWriteInfo;
77 :
78 : static already_AddRefed<IDBObjectStore>
79 : Create(IDBTransaction* aTransaction, const ObjectStoreSpec& aSpec);
80 :
81 : static nsresult
82 : AppendIndexUpdateInfo(int64_t aIndexID,
83 : const KeyPath& aKeyPath,
84 : bool aUnique,
85 : bool aMultiEntry,
86 : const nsCString& aLocale,
87 : JSContext* aCx,
88 : JS::Handle<JS::Value> aObject,
89 : nsTArray<IndexUpdateInfo>& aUpdateInfoArray);
90 :
91 : static void
92 : ClearCloneReadInfo(StructuredCloneReadInfo& aReadInfo);
93 :
94 : static bool
95 : DeserializeValue(JSContext* aCx,
96 : StructuredCloneReadInfo& aCloneReadInfo,
97 : JS::MutableHandle<JS::Value> aValue);
98 :
99 : static bool
100 : DeserializeIndexValue(JSContext* aCx,
101 : StructuredCloneReadInfo& aCloneReadInfo,
102 : JS::MutableHandle<JS::Value> aValue);
103 :
104 : #if !defined(MOZ_B2G)
105 : static bool
106 : DeserializeUpgradeValue(JSContext* aCx,
107 : StructuredCloneReadInfo& aCloneReadInfo,
108 : JS::MutableHandle<JS::Value> aValue);
109 : #endif
110 :
111 : static const JSClass*
112 0 : DummyPropClass()
113 : {
114 0 : return &sDummyPropJSClass;
115 : }
116 :
117 : void
118 : AssertIsOnOwningThread() const
119 : #ifdef DEBUG
120 : ;
121 : #else
122 : { }
123 : #endif
124 :
125 : int64_t
126 0 : Id() const
127 : {
128 0 : AssertIsOnOwningThread();
129 :
130 0 : return mId;
131 : }
132 :
133 : const nsString&
134 : Name() const;
135 :
136 : bool
137 : AutoIncrement() const;
138 :
139 : const KeyPath&
140 : GetKeyPath() const;
141 :
142 : bool
143 : HasValidKeyPath() const;
144 :
145 : nsPIDOMWindowInner*
146 : GetParentObject() const;
147 :
148 : void
149 0 : GetName(nsString& aName) const
150 : {
151 0 : AssertIsOnOwningThread();
152 :
153 0 : aName = Name();
154 0 : }
155 :
156 : void
157 : SetName(const nsAString& aName, ErrorResult& aRv);
158 :
159 : void
160 : GetKeyPath(JSContext* aCx, JS::MutableHandle<JS::Value> aResult,
161 : ErrorResult& aRv);
162 :
163 : already_AddRefed<DOMStringList>
164 : IndexNames();
165 :
166 : IDBTransaction*
167 0 : Transaction() const
168 : {
169 0 : AssertIsOnOwningThread();
170 :
171 0 : return mTransaction;
172 : }
173 :
174 : already_AddRefed<IDBRequest>
175 0 : Add(JSContext* aCx,
176 : JS::Handle<JS::Value> aValue,
177 : JS::Handle<JS::Value> aKey,
178 : ErrorResult& aRv)
179 : {
180 0 : AssertIsOnOwningThread();
181 :
182 0 : return AddOrPut(aCx, aValue, aKey, false, /* aFromCursor */ false, aRv);
183 : }
184 :
185 : already_AddRefed<IDBRequest>
186 0 : Put(JSContext* aCx,
187 : JS::Handle<JS::Value> aValue,
188 : JS::Handle<JS::Value> aKey,
189 : ErrorResult& aRv)
190 : {
191 0 : AssertIsOnOwningThread();
192 :
193 0 : return AddOrPut(aCx, aValue, aKey, true, /* aFromCursor */ false, aRv);
194 : }
195 :
196 : already_AddRefed<IDBRequest>
197 0 : Delete(JSContext* aCx,
198 : JS::Handle<JS::Value> aKey,
199 : ErrorResult& aRv)
200 : {
201 0 : AssertIsOnOwningThread();
202 :
203 0 : return DeleteInternal(aCx, aKey, /* aFromCursor */ false, aRv);
204 : }
205 :
206 : already_AddRefed<IDBRequest>
207 0 : Get(JSContext* aCx,
208 : JS::Handle<JS::Value> aKey,
209 : ErrorResult& aRv)
210 : {
211 0 : AssertIsOnOwningThread();
212 :
213 0 : return GetInternal(/* aKeyOnly */ false, aCx, aKey, aRv);
214 : }
215 :
216 : already_AddRefed<IDBRequest>
217 0 : GetKey(JSContext* aCx,
218 : JS::Handle<JS::Value> aKey,
219 : ErrorResult& aRv)
220 : {
221 0 : AssertIsOnOwningThread();
222 :
223 0 : return GetInternal(/* aKeyOnly */ true, aCx, aKey, aRv);
224 : }
225 :
226 : already_AddRefed<IDBRequest>
227 : Clear(JSContext* aCx, ErrorResult& aRv);
228 :
229 : already_AddRefed<IDBIndex>
230 : CreateIndex(const nsAString& aName,
231 : const StringOrStringSequence& aKeyPath,
232 : const IDBIndexParameters& aOptionalParameters,
233 : ErrorResult& aRv);
234 :
235 : already_AddRefed<IDBIndex>
236 : Index(const nsAString& aName, ErrorResult &aRv);
237 :
238 : void
239 : DeleteIndex(const nsAString& aIndexName, ErrorResult& aRv);
240 :
241 : already_AddRefed<IDBRequest>
242 : Count(JSContext* aCx,
243 : JS::Handle<JS::Value> aKey,
244 : ErrorResult& aRv);
245 :
246 : already_AddRefed<IDBRequest>
247 0 : GetAll(JSContext* aCx,
248 : JS::Handle<JS::Value> aKey,
249 : const Optional<uint32_t>& aLimit,
250 : ErrorResult& aRv)
251 : {
252 0 : AssertIsOnOwningThread();
253 :
254 0 : return GetAllInternal(/* aKeysOnly */ false, aCx, aKey, aLimit, aRv);
255 : }
256 :
257 : already_AddRefed<IDBRequest>
258 0 : GetAllKeys(JSContext* aCx,
259 : JS::Handle<JS::Value> aKey,
260 : const Optional<uint32_t>& aLimit,
261 : ErrorResult& aRv)
262 : {
263 0 : AssertIsOnOwningThread();
264 :
265 0 : return GetAllInternal(/* aKeysOnly */ true, aCx, aKey, aLimit, aRv);
266 : }
267 :
268 : already_AddRefed<IDBRequest>
269 0 : OpenCursor(JSContext* aCx,
270 : JS::Handle<JS::Value> aRange,
271 : IDBCursorDirection aDirection,
272 : ErrorResult& aRv)
273 : {
274 0 : AssertIsOnOwningThread();
275 :
276 : return OpenCursorInternal(/* aKeysOnly */ false, aCx, aRange, aDirection,
277 0 : aRv);
278 : }
279 :
280 : already_AddRefed<IDBRequest>
281 : OpenCursor(JSContext* aCx,
282 : IDBCursorDirection aDirection,
283 : ErrorResult& aRv)
284 : {
285 : AssertIsOnOwningThread();
286 :
287 : return OpenCursorInternal(/* aKeysOnly */ false, aCx,
288 : JS::UndefinedHandleValue, aDirection, aRv);
289 : }
290 :
291 : already_AddRefed<IDBRequest>
292 0 : OpenKeyCursor(JSContext* aCx,
293 : JS::Handle<JS::Value> aRange,
294 : IDBCursorDirection aDirection,
295 : ErrorResult& aRv)
296 : {
297 0 : AssertIsOnOwningThread();
298 :
299 : return OpenCursorInternal(/* aKeysOnly */ true, aCx, aRange, aDirection,
300 0 : aRv);
301 : }
302 :
303 : void
304 : RefreshSpec(bool aMayDelete);
305 :
306 : const ObjectStoreSpec&
307 : Spec() const;
308 :
309 : void
310 : NoteDeletion();
311 :
312 : bool
313 0 : IsDeleted() const
314 : {
315 0 : AssertIsOnOwningThread();
316 :
317 0 : return !!mDeletedSpec;
318 : }
319 :
320 : NS_DECL_CYCLE_COLLECTING_ISUPPORTS
321 0 : NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(IDBObjectStore)
322 :
323 : // nsWrapperCache
324 : virtual JSObject*
325 : WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) override;
326 :
327 : private:
328 : IDBObjectStore(IDBTransaction* aTransaction, const ObjectStoreSpec* aSpec);
329 :
330 : ~IDBObjectStore();
331 :
332 : nsresult
333 : GetAddInfo(JSContext* aCx,
334 : JS::Handle<JS::Value> aValue,
335 : JS::Handle<JS::Value> aKeyVal,
336 : StructuredCloneWriteInfo& aCloneWriteInfo,
337 : Key& aKey,
338 : nsTArray<IndexUpdateInfo>& aUpdateInfoArray);
339 :
340 : already_AddRefed<IDBRequest>
341 : AddOrPut(JSContext* aCx,
342 : JS::Handle<JS::Value> aValue,
343 : JS::Handle<JS::Value> aKey,
344 : bool aOverwrite,
345 : bool aFromCursor,
346 : ErrorResult& aRv);
347 :
348 : already_AddRefed<IDBRequest>
349 : DeleteInternal(JSContext* aCx,
350 : JS::Handle<JS::Value> aKey,
351 : bool aFromCursor,
352 : ErrorResult& aRv);
353 :
354 : already_AddRefed<IDBRequest>
355 : GetInternal(bool aKeyOnly,
356 : JSContext* aCx,
357 : JS::Handle<JS::Value> aKey,
358 : ErrorResult& aRv);
359 :
360 : already_AddRefed<IDBRequest>
361 : GetAllInternal(bool aKeysOnly,
362 : JSContext* aCx,
363 : JS::Handle<JS::Value> aKey,
364 : const Optional<uint32_t>& aLimit,
365 : ErrorResult& aRv);
366 :
367 : already_AddRefed<IDBRequest>
368 : OpenCursorInternal(bool aKeysOnly,
369 : JSContext* aCx,
370 : JS::Handle<JS::Value> aRange,
371 : IDBCursorDirection aDirection,
372 : ErrorResult& aRv);
373 : };
374 :
375 : } // namespace dom
376 : } // namespace mozilla
377 :
378 : #endif // mozilla_dom_idbobjectstore_h__
|