Coverage Report

Created: 2018-09-25 14:53

/src/mozilla-central/dom/indexedDB/IDBObjectStore.h
Line
Count
Source (jump to first uncovered line)
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
  struct StructuredCloneInfo;
78
79
  class MOZ_STACK_CLASS ValueWrapper final
80
  {
81
    JS::Rooted<JS::Value> mValue;
82
    bool mCloned;
83
84
  public:
85
    ValueWrapper(JSContext* aCx, JS::Handle<JS::Value> aValue)
86
      : mValue(aCx, aValue)
87
      , mCloned(false)
88
    {
89
      MOZ_COUNT_CTOR(IDBObjectStore::ValueWrapper);
90
    }
91
92
    ~ValueWrapper()
93
    {
94
      MOZ_COUNT_DTOR(IDBObjectStore::ValueWrapper);
95
    }
96
97
    const JS::Rooted<JS::Value>&
98
    Value() const
99
0
    {
100
0
      return mValue;
101
0
    }
102
103
    bool
104
    Clone(JSContext* aCx);
105
  };
106
107
  static already_AddRefed<IDBObjectStore>
108
  Create(IDBTransaction* aTransaction, const ObjectStoreSpec& aSpec);
109
110
  static nsresult
111
  AppendIndexUpdateInfo(int64_t aIndexID,
112
                        const KeyPath& aKeyPath,
113
                        bool aUnique,
114
                        bool aMultiEntry,
115
                        const nsCString& aLocale,
116
                        JSContext* aCx,
117
                        JS::Handle<JS::Value> aObject,
118
                        nsTArray<IndexUpdateInfo>& aUpdateInfoArray);
119
120
  static nsresult
121
  DeserializeIndexValueToUpdateInfos(int64_t aIndexID,
122
                                     const KeyPath& aKeyPath,
123
                                     bool aUnique,
124
                                     bool aMultiEntry,
125
                                     const nsCString& aLocale,
126
                                     StructuredCloneReadInfo& aCloneInfo,
127
                                     nsTArray<IndexUpdateInfo>& aUpdateInfoArray);
128
129
  static void
130
  ClearCloneReadInfo(StructuredCloneReadInfo& aReadInfo);
131
132
  static bool
133
  DeserializeValue(JSContext* aCx,
134
                   StructuredCloneReadInfo& aCloneReadInfo,
135
                   JS::MutableHandle<JS::Value> aValue);
136
137
  static nsresult
138
  DeserializeUpgradeValueToFileIds(StructuredCloneReadInfo& aCloneReadInfo,
139
                                   nsAString& aFileIds);
140
141
  static const JSClass*
142
  DummyPropClass()
143
0
  {
144
0
    return &sDummyPropJSClass;
145
0
  }
146
147
  void
148
  AssertIsOnOwningThread() const
149
#ifdef DEBUG
150
  ;
151
#else
152
  { }
153
#endif
154
155
  int64_t
156
  Id() const
157
0
  {
158
0
    AssertIsOnOwningThread();
159
0
160
0
    return mId;
161
0
  }
162
163
  const nsString&
164
  Name() const;
165
166
  bool
167
  AutoIncrement() const;
168
169
  const KeyPath&
170
  GetKeyPath() const;
171
172
  bool
173
  HasValidKeyPath() const;
174
175
  nsPIDOMWindowInner*
176
  GetParentObject() const;
177
178
  void
179
  GetName(nsString& aName) const
180
  {
181
    AssertIsOnOwningThread();
182
183
    aName = Name();
184
  }
185
186
  void
187
  SetName(const nsAString& aName, ErrorResult& aRv);
188
189
  void
190
  GetKeyPath(JSContext* aCx, JS::MutableHandle<JS::Value> aResult,
191
             ErrorResult& aRv);
192
193
  already_AddRefed<DOMStringList>
194
  IndexNames();
195
196
  IDBTransaction*
197
  Transaction() const
198
  {
199
    AssertIsOnOwningThread();
200
201
    return mTransaction;
202
  }
203
204
  already_AddRefed<IDBRequest>
205
  Add(JSContext* aCx,
206
      JS::Handle<JS::Value> aValue,
207
      JS::Handle<JS::Value> aKey,
208
      ErrorResult& aRv)
209
  {
210
    AssertIsOnOwningThread();
211
212
    ValueWrapper valueWrapper(aCx, aValue);
213
214
    return AddOrPut(aCx, valueWrapper, aKey, false, /* aFromCursor */ false,
215
                    aRv);
216
  }
217
218
  already_AddRefed<IDBRequest>
219
  Put(JSContext* aCx,
220
      JS::Handle<JS::Value> aValue,
221
      JS::Handle<JS::Value> aKey,
222
      ErrorResult& aRv)
223
  {
224
    AssertIsOnOwningThread();
225
226
    ValueWrapper valueWrapper(aCx, aValue);
227
228
    return AddOrPut(aCx, valueWrapper, aKey, true, /* aFromCursor */ false,
229
                    aRv);
230
  }
231
232
  already_AddRefed<IDBRequest>
233
  Delete(JSContext* aCx,
234
         JS::Handle<JS::Value> aKey,
235
         ErrorResult& aRv)
236
  {
237
    AssertIsOnOwningThread();
238
239
    return DeleteInternal(aCx, aKey, /* aFromCursor */ false, aRv);
240
  }
241
242
  already_AddRefed<IDBRequest>
243
  Get(JSContext* aCx,
244
      JS::Handle<JS::Value> aKey,
245
      ErrorResult& aRv)
246
  {
247
    AssertIsOnOwningThread();
248
249
    return GetInternal(/* aKeyOnly */ false, aCx, aKey, aRv);
250
  }
251
252
  already_AddRefed<IDBRequest>
253
  GetKey(JSContext* aCx,
254
         JS::Handle<JS::Value> aKey,
255
         ErrorResult& aRv)
256
  {
257
    AssertIsOnOwningThread();
258
259
    return GetInternal(/* aKeyOnly */ true, aCx, aKey, aRv);
260
  }
261
262
  already_AddRefed<IDBRequest>
263
  Clear(JSContext* aCx, ErrorResult& aRv);
264
265
  already_AddRefed<IDBIndex>
266
  CreateIndex(const nsAString& aName,
267
              const StringOrStringSequence& aKeyPath,
268
              const IDBIndexParameters& aOptionalParameters,
269
              ErrorResult& aRv);
270
271
  already_AddRefed<IDBIndex>
272
  Index(const nsAString& aName, ErrorResult &aRv);
273
274
  void
275
  DeleteIndex(const nsAString& aIndexName, ErrorResult& aRv);
276
277
  already_AddRefed<IDBRequest>
278
  Count(JSContext* aCx,
279
        JS::Handle<JS::Value> aKey,
280
        ErrorResult& aRv);
281
282
  already_AddRefed<IDBRequest>
283
  GetAll(JSContext* aCx,
284
         JS::Handle<JS::Value> aKey,
285
         const Optional<uint32_t>& aLimit,
286
         ErrorResult& aRv)
287
  {
288
    AssertIsOnOwningThread();
289
290
    return GetAllInternal(/* aKeysOnly */ false, aCx, aKey, aLimit, aRv);
291
  }
292
293
  already_AddRefed<IDBRequest>
294
  GetAllKeys(JSContext* aCx,
295
             JS::Handle<JS::Value> aKey,
296
             const Optional<uint32_t>& aLimit,
297
             ErrorResult& aRv)
298
  {
299
    AssertIsOnOwningThread();
300
301
    return GetAllInternal(/* aKeysOnly */ true, aCx, aKey, aLimit, aRv);
302
  }
303
304
  already_AddRefed<IDBRequest>
305
  OpenCursor(JSContext* aCx,
306
             JS::Handle<JS::Value> aRange,
307
             IDBCursorDirection aDirection,
308
             ErrorResult& aRv)
309
  {
310
    AssertIsOnOwningThread();
311
312
    return OpenCursorInternal(/* aKeysOnly */ false, aCx, aRange, aDirection,
313
                              aRv);
314
  }
315
316
  already_AddRefed<IDBRequest>
317
  OpenCursor(JSContext* aCx,
318
             IDBCursorDirection aDirection,
319
             ErrorResult& aRv)
320
  {
321
    AssertIsOnOwningThread();
322
323
    return OpenCursorInternal(/* aKeysOnly */ false, aCx,
324
                              JS::UndefinedHandleValue, aDirection, aRv);
325
  }
326
327
  already_AddRefed<IDBRequest>
328
  OpenKeyCursor(JSContext* aCx,
329
                JS::Handle<JS::Value> aRange,
330
                IDBCursorDirection aDirection,
331
                ErrorResult& aRv)
332
  {
333
    AssertIsOnOwningThread();
334
335
    return OpenCursorInternal(/* aKeysOnly */ true, aCx, aRange, aDirection,
336
                              aRv);
337
  }
338
339
  void
340
  RefreshSpec(bool aMayDelete);
341
342
  const ObjectStoreSpec&
343
  Spec() const;
344
345
  void
346
  NoteDeletion();
347
348
  bool
349
  IsDeleted() const
350
0
  {
351
0
    AssertIsOnOwningThread();
352
0
353
0
    return !!mDeletedSpec;
354
0
  }
355
356
  NS_DECL_CYCLE_COLLECTING_ISUPPORTS
357
  NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(IDBObjectStore)
358
359
  // nsWrapperCache
360
  virtual JSObject*
361
  WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) override;
362
363
private:
364
  IDBObjectStore(IDBTransaction* aTransaction, const ObjectStoreSpec* aSpec);
365
366
  ~IDBObjectStore();
367
368
  nsresult
369
  GetAddInfo(JSContext* aCx,
370
             ValueWrapper& aValueWrapper,
371
             JS::Handle<JS::Value> aKeyVal,
372
             StructuredCloneWriteInfo& aCloneWriteInfo,
373
             Key& aKey,
374
             nsTArray<IndexUpdateInfo>& aUpdateInfoArray);
375
376
  already_AddRefed<IDBRequest>
377
  AddOrPut(JSContext* aCx,
378
           ValueWrapper& aValueWrapper,
379
           JS::Handle<JS::Value> aKey,
380
           bool aOverwrite,
381
           bool aFromCursor,
382
           ErrorResult& aRv);
383
384
  already_AddRefed<IDBRequest>
385
  DeleteInternal(JSContext* aCx,
386
                 JS::Handle<JS::Value> aKey,
387
                 bool aFromCursor,
388
                 ErrorResult& aRv);
389
390
  already_AddRefed<IDBRequest>
391
  GetInternal(bool aKeyOnly,
392
              JSContext* aCx,
393
              JS::Handle<JS::Value> aKey,
394
              ErrorResult& aRv);
395
396
  already_AddRefed<IDBRequest>
397
  GetAllInternal(bool aKeysOnly,
398
                 JSContext* aCx,
399
                 JS::Handle<JS::Value> aKey,
400
                 const Optional<uint32_t>& aLimit,
401
                 ErrorResult& aRv);
402
403
  already_AddRefed<IDBRequest>
404
  OpenCursorInternal(bool aKeysOnly,
405
                     JSContext* aCx,
406
                     JS::Handle<JS::Value> aRange,
407
                     IDBCursorDirection aDirection,
408
                     ErrorResult& aRv);
409
};
410
411
} // namespace dom
412
} // namespace mozilla
413
414
#endif // mozilla_dom_idbobjectstore_h__