|
1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ |
|
2 /* vim: set ts=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_indexeddb_idbobjectstore_h__ |
|
8 #define mozilla_dom_indexeddb_idbobjectstore_h__ |
|
9 |
|
10 #include "mozilla/dom/indexedDB/IndexedDatabase.h" |
|
11 |
|
12 #include "js/TypeDecls.h" |
|
13 #include "mozilla/dom/IDBCursorBinding.h" |
|
14 #include "mozilla/dom/IDBIndexBinding.h" |
|
15 #include "mozilla/dom/IDBObjectStoreBinding.h" |
|
16 #include "nsCycleCollectionParticipant.h" |
|
17 #include "MainThreadUtils.h" |
|
18 |
|
19 #include "mozilla/dom/indexedDB/IDBRequest.h" |
|
20 #include "mozilla/dom/indexedDB/IDBTransaction.h" |
|
21 #include "mozilla/dom/indexedDB/KeyPath.h" |
|
22 |
|
23 class nsIDOMBlob; |
|
24 class nsIScriptContext; |
|
25 class nsPIDOMWindow; |
|
26 |
|
27 namespace mozilla { |
|
28 namespace dom { |
|
29 class ContentParent; |
|
30 class PBlobChild; |
|
31 class PBlobParent; |
|
32 } |
|
33 } |
|
34 |
|
35 BEGIN_INDEXEDDB_NAMESPACE |
|
36 |
|
37 class AsyncConnectionHelper; |
|
38 class FileManager; |
|
39 class IDBCursor; |
|
40 class IDBKeyRange; |
|
41 class IDBRequest; |
|
42 class IndexedDBObjectStoreChild; |
|
43 class IndexedDBObjectStoreParent; |
|
44 class Key; |
|
45 |
|
46 struct IndexInfo; |
|
47 struct IndexUpdateInfo; |
|
48 struct ObjectStoreInfo; |
|
49 |
|
50 struct FileHandleData; |
|
51 struct BlobOrFileData; |
|
52 |
|
53 class IDBObjectStore MOZ_FINAL : public nsISupports, |
|
54 public nsWrapperCache |
|
55 { |
|
56 public: |
|
57 NS_DECL_CYCLE_COLLECTING_ISUPPORTS |
|
58 NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(IDBObjectStore) |
|
59 |
|
60 static already_AddRefed<IDBObjectStore> |
|
61 Create(IDBTransaction* aTransaction, |
|
62 ObjectStoreInfo* aInfo, |
|
63 const nsACString& aDatabaseId, |
|
64 bool aCreating); |
|
65 |
|
66 static nsresult |
|
67 AppendIndexUpdateInfo(int64_t aIndexID, |
|
68 const KeyPath& aKeyPath, |
|
69 bool aUnique, |
|
70 bool aMultiEntry, |
|
71 JSContext* aCx, |
|
72 JS::Handle<JS::Value> aObject, |
|
73 nsTArray<IndexUpdateInfo>& aUpdateInfoArray); |
|
74 |
|
75 static nsresult |
|
76 UpdateIndexes(IDBTransaction* aTransaction, |
|
77 int64_t aObjectStoreId, |
|
78 const Key& aObjectStoreKey, |
|
79 bool aOverwrite, |
|
80 int64_t aObjectDataId, |
|
81 const nsTArray<IndexUpdateInfo>& aUpdateInfoArray); |
|
82 |
|
83 static nsresult |
|
84 GetStructuredCloneReadInfoFromStatement(mozIStorageStatement* aStatement, |
|
85 uint32_t aDataIndex, |
|
86 uint32_t aFileIdsIndex, |
|
87 IDBDatabase* aDatabase, |
|
88 StructuredCloneReadInfo& aInfo); |
|
89 |
|
90 static void |
|
91 ClearCloneReadInfo(StructuredCloneReadInfo& aReadInfo); |
|
92 |
|
93 static void |
|
94 ClearCloneWriteInfo(StructuredCloneWriteInfo& aWriteInfo); |
|
95 |
|
96 static bool |
|
97 DeserializeValue(JSContext* aCx, |
|
98 StructuredCloneReadInfo& aCloneReadInfo, |
|
99 JS::MutableHandle<JS::Value> aValue); |
|
100 |
|
101 static bool |
|
102 SerializeValue(JSContext* aCx, |
|
103 StructuredCloneWriteInfo& aCloneWriteInfo, |
|
104 JS::Handle<JS::Value> aValue); |
|
105 |
|
106 template <class DeserializationTraits> |
|
107 static JSObject* |
|
108 StructuredCloneReadCallback(JSContext* aCx, |
|
109 JSStructuredCloneReader* aReader, |
|
110 uint32_t aTag, |
|
111 uint32_t aData, |
|
112 void* aClosure); |
|
113 static bool |
|
114 StructuredCloneWriteCallback(JSContext* aCx, |
|
115 JSStructuredCloneWriter* aWriter, |
|
116 JS::Handle<JSObject*> aObj, |
|
117 void* aClosure); |
|
118 |
|
119 static nsresult |
|
120 ConvertFileIdsToArray(const nsAString& aFileIds, |
|
121 nsTArray<int64_t>& aResult); |
|
122 |
|
123 // Called only in the main process. |
|
124 static nsresult |
|
125 ConvertBlobsToActors(ContentParent* aContentParent, |
|
126 FileManager* aFileManager, |
|
127 const nsTArray<StructuredCloneFile>& aFiles, |
|
128 InfallibleTArray<PBlobParent*>& aActors); |
|
129 |
|
130 // Called only in the child process. |
|
131 static void |
|
132 ConvertActorsToBlobs(const InfallibleTArray<PBlobChild*>& aActors, |
|
133 nsTArray<StructuredCloneFile>& aFiles); |
|
134 |
|
135 const nsString& Name() const |
|
136 { |
|
137 return mName; |
|
138 } |
|
139 |
|
140 bool IsAutoIncrement() const |
|
141 { |
|
142 return mAutoIncrement; |
|
143 } |
|
144 |
|
145 bool IsWriteAllowed() const |
|
146 { |
|
147 return mTransaction->IsWriteAllowed(); |
|
148 } |
|
149 |
|
150 int64_t Id() const |
|
151 { |
|
152 NS_ASSERTION(mId != INT64_MIN, "Don't ask for this yet!"); |
|
153 return mId; |
|
154 } |
|
155 |
|
156 const KeyPath& GetKeyPath() const |
|
157 { |
|
158 return mKeyPath; |
|
159 } |
|
160 |
|
161 const bool HasValidKeyPath() const |
|
162 { |
|
163 return mKeyPath.IsValid(); |
|
164 } |
|
165 |
|
166 IDBTransaction* Transaction() |
|
167 { |
|
168 return mTransaction; |
|
169 } |
|
170 |
|
171 ObjectStoreInfo* Info() |
|
172 { |
|
173 return mInfo; |
|
174 } |
|
175 |
|
176 void |
|
177 SetActor(IndexedDBObjectStoreChild* aActorChild) |
|
178 { |
|
179 NS_ASSERTION(!aActorChild || !mActorChild, "Shouldn't have more than one!"); |
|
180 mActorChild = aActorChild; |
|
181 } |
|
182 |
|
183 void |
|
184 SetActor(IndexedDBObjectStoreParent* aActorParent) |
|
185 { |
|
186 NS_ASSERTION(!aActorParent || !mActorParent, |
|
187 "Shouldn't have more than one!"); |
|
188 mActorParent = aActorParent; |
|
189 } |
|
190 |
|
191 IndexedDBObjectStoreChild* |
|
192 GetActorChild() const |
|
193 { |
|
194 return mActorChild; |
|
195 } |
|
196 |
|
197 IndexedDBObjectStoreParent* |
|
198 GetActorParent() const |
|
199 { |
|
200 return mActorParent; |
|
201 } |
|
202 |
|
203 already_AddRefed<IDBIndex> |
|
204 CreateIndexInternal(const IndexInfo& aInfo, |
|
205 ErrorResult& aRv); |
|
206 |
|
207 nsresult AddOrPutInternal( |
|
208 const SerializedStructuredCloneWriteInfo& aCloneWriteInfo, |
|
209 const Key& aKey, |
|
210 const InfallibleTArray<IndexUpdateInfo>& aUpdateInfoArray, |
|
211 const nsTArray<nsCOMPtr<nsIDOMBlob> >& aBlobs, |
|
212 bool aOverwrite, |
|
213 IDBRequest** _retval); |
|
214 |
|
215 already_AddRefed<IDBRequest> |
|
216 GetInternal(IDBKeyRange* aKeyRange, |
|
217 ErrorResult& aRv); |
|
218 |
|
219 already_AddRefed<IDBRequest> |
|
220 GetAllInternal(IDBKeyRange* aKeyRange, |
|
221 uint32_t aLimit, |
|
222 ErrorResult& aRv); |
|
223 |
|
224 already_AddRefed<IDBRequest> |
|
225 GetAllKeysInternal(IDBKeyRange* aKeyRange, |
|
226 uint32_t aLimit, |
|
227 ErrorResult& aRv); |
|
228 |
|
229 already_AddRefed<IDBRequest> |
|
230 DeleteInternal(IDBKeyRange* aKeyRange, |
|
231 ErrorResult& aRv); |
|
232 |
|
233 already_AddRefed<IDBRequest> |
|
234 CountInternal(IDBKeyRange* aKeyRange, |
|
235 ErrorResult& aRv); |
|
236 |
|
237 already_AddRefed<IDBRequest> |
|
238 OpenCursorInternal(IDBKeyRange* aKeyRange, |
|
239 size_t aDirection, |
|
240 ErrorResult& aRv); |
|
241 |
|
242 already_AddRefed<IDBRequest> |
|
243 OpenKeyCursorInternal(IDBKeyRange* aKeyRange, |
|
244 size_t aDirection, |
|
245 ErrorResult& aRv); |
|
246 |
|
247 nsresult |
|
248 OpenCursorFromChildProcess( |
|
249 IDBRequest* aRequest, |
|
250 size_t aDirection, |
|
251 const Key& aKey, |
|
252 const SerializedStructuredCloneReadInfo& aCloneInfo, |
|
253 nsTArray<StructuredCloneFile>& aBlobs, |
|
254 IDBCursor** _retval); |
|
255 |
|
256 nsresult |
|
257 OpenCursorFromChildProcess(IDBRequest* aRequest, |
|
258 size_t aDirection, |
|
259 const Key& aKey, |
|
260 IDBCursor** _retval); |
|
261 |
|
262 void |
|
263 SetInfo(ObjectStoreInfo* aInfo); |
|
264 |
|
265 static const JSClass sDummyPropJSClass; |
|
266 |
|
267 // nsWrapperCache |
|
268 virtual JSObject* |
|
269 WrapObject(JSContext* aCx) MOZ_OVERRIDE; |
|
270 |
|
271 // WebIDL |
|
272 IDBTransaction* |
|
273 GetParentObject() const |
|
274 { |
|
275 return mTransaction; |
|
276 } |
|
277 |
|
278 void |
|
279 GetName(nsString& aName) const |
|
280 { |
|
281 NS_ASSERTION(NS_IsMainThread(), "Wrong thread!"); |
|
282 aName.Assign(mName); |
|
283 } |
|
284 |
|
285 void |
|
286 GetKeyPath(JSContext* aCx, JS::MutableHandle<JS::Value> aResult, |
|
287 ErrorResult& aRv); |
|
288 |
|
289 already_AddRefed<DOMStringList> |
|
290 GetIndexNames(ErrorResult& aRv); |
|
291 |
|
292 IDBTransaction* |
|
293 Transaction() const |
|
294 { |
|
295 NS_ASSERTION(NS_IsMainThread(), "Wrong thread!"); |
|
296 return mTransaction; |
|
297 } |
|
298 |
|
299 bool |
|
300 AutoIncrement() const |
|
301 { |
|
302 NS_ASSERTION(NS_IsMainThread(), "Wrong thread!"); |
|
303 return mAutoIncrement; |
|
304 } |
|
305 |
|
306 already_AddRefed<IDBRequest> |
|
307 Put(JSContext* aCx, JS::Handle<JS::Value> aValue, |
|
308 JS::Handle<JS::Value> aKey, ErrorResult& aRv) |
|
309 { |
|
310 NS_ASSERTION(NS_IsMainThread(), "Wrong thread!"); |
|
311 return AddOrPut(aCx, aValue, aKey, true, aRv); |
|
312 } |
|
313 |
|
314 already_AddRefed<IDBRequest> |
|
315 Add(JSContext* aCx, JS::Handle<JS::Value> aValue, |
|
316 JS::Handle<JS::Value> aKey, ErrorResult& aRv) |
|
317 { |
|
318 NS_ASSERTION(NS_IsMainThread(), "Wrong thread!"); |
|
319 return AddOrPut(aCx, aValue, aKey, false, aRv); |
|
320 } |
|
321 |
|
322 already_AddRefed<IDBRequest> |
|
323 Delete(JSContext* aCx, JS::Handle<JS::Value> aKey, ErrorResult& aRv); |
|
324 |
|
325 already_AddRefed<IDBRequest> |
|
326 Get(JSContext* aCx, JS::Handle<JS::Value> aKey, ErrorResult& aRv); |
|
327 |
|
328 already_AddRefed<IDBRequest> |
|
329 Clear(ErrorResult& aRv); |
|
330 |
|
331 already_AddRefed<IDBRequest> |
|
332 OpenCursor(JSContext* aCx, JS::Handle<JS::Value> aRange, |
|
333 IDBCursorDirection aDirection, ErrorResult& aRv); |
|
334 |
|
335 already_AddRefed<IDBIndex> |
|
336 CreateIndex(JSContext* aCx, const nsAString& aName, const nsAString& aKeyPath, |
|
337 const IDBIndexParameters& aOptionalParameters, ErrorResult& aRv); |
|
338 |
|
339 already_AddRefed<IDBIndex> |
|
340 CreateIndex(JSContext* aCx, const nsAString& aName, |
|
341 const Sequence<nsString>& aKeyPath, |
|
342 const IDBIndexParameters& aOptionalParameters, ErrorResult& aRv); |
|
343 |
|
344 already_AddRefed<IDBIndex> |
|
345 Index(const nsAString& aName, ErrorResult &aRv); |
|
346 |
|
347 void |
|
348 DeleteIndex(const nsAString& aIndexName, ErrorResult& aRv); |
|
349 |
|
350 already_AddRefed<IDBRequest> |
|
351 Count(JSContext* aCx, JS::Handle<JS::Value> aKey, |
|
352 ErrorResult& aRv); |
|
353 |
|
354 already_AddRefed<IDBRequest> |
|
355 GetAll(JSContext* aCx, JS::Handle<JS::Value> aKey, |
|
356 const Optional<uint32_t>& aLimit, ErrorResult& aRv); |
|
357 |
|
358 already_AddRefed<IDBRequest> |
|
359 GetAllKeys(JSContext* aCx, JS::Handle<JS::Value> aKey, |
|
360 const Optional<uint32_t>& aLimit, ErrorResult& aRv); |
|
361 |
|
362 already_AddRefed<IDBRequest> |
|
363 OpenKeyCursor(JSContext* aCx, JS::Handle<JS::Value> aRange, |
|
364 IDBCursorDirection aDirection, ErrorResult& aRv); |
|
365 |
|
366 protected: |
|
367 IDBObjectStore(); |
|
368 ~IDBObjectStore(); |
|
369 |
|
370 nsresult GetAddInfo(JSContext* aCx, |
|
371 JS::Handle<JS::Value> aValue, |
|
372 JS::Handle<JS::Value> aKeyVal, |
|
373 StructuredCloneWriteInfo& aCloneWriteInfo, |
|
374 Key& aKey, |
|
375 nsTArray<IndexUpdateInfo>& aUpdateInfoArray); |
|
376 |
|
377 already_AddRefed<IDBRequest> |
|
378 AddOrPut(JSContext* aCx, JS::Handle<JS::Value> aValue, |
|
379 JS::Handle<JS::Value> aKey, bool aOverwrite, |
|
380 ErrorResult& aRv); |
|
381 |
|
382 already_AddRefed<IDBIndex> |
|
383 CreateIndex(JSContext* aCx, const nsAString& aName, KeyPath& aKeyPath, |
|
384 const IDBIndexParameters& aOptionalParameters, ErrorResult& aRv); |
|
385 |
|
386 static void |
|
387 ClearStructuredCloneBuffer(JSAutoStructuredCloneBuffer& aBuffer); |
|
388 |
|
389 static bool |
|
390 ReadFileHandle(JSStructuredCloneReader* aReader, |
|
391 FileHandleData* aRetval); |
|
392 |
|
393 static bool |
|
394 ReadBlobOrFile(JSStructuredCloneReader* aReader, |
|
395 uint32_t aTag, |
|
396 BlobOrFileData* aRetval); |
|
397 private: |
|
398 nsRefPtr<IDBTransaction> mTransaction; |
|
399 |
|
400 int64_t mId; |
|
401 nsString mName; |
|
402 KeyPath mKeyPath; |
|
403 JS::Heap<JS::Value> mCachedKeyPath; |
|
404 bool mRooted; |
|
405 bool mAutoIncrement; |
|
406 nsCString mDatabaseId; |
|
407 nsRefPtr<ObjectStoreInfo> mInfo; |
|
408 |
|
409 nsTArray<nsRefPtr<IDBIndex> > mCreatedIndexes; |
|
410 |
|
411 IndexedDBObjectStoreChild* mActorChild; |
|
412 IndexedDBObjectStoreParent* mActorParent; |
|
413 }; |
|
414 |
|
415 END_INDEXEDDB_NAMESPACE |
|
416 |
|
417 #endif // mozilla_dom_indexeddb_idbobjectstore_h__ |