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_idbindex_h__
8 #define mozilla_dom_idbindex_h__
9 
10 #include "js/RootingAPI.h"
11 #include "mozilla/Attributes.h"
12 #include "mozilla/dom/IDBCursorBinding.h"
13 #include "mozilla/UniquePtr.h"
14 #include "nsCycleCollectionParticipant.h"
15 #include "nsISupports.h"
16 #include "nsTArrayForwardDeclare.h"
17 #include "nsWrapperCache.h"
18 
19 class nsIGlobalObject;
20 
21 namespace mozilla {
22 
23 class ErrorResult;
24 
25 namespace dom {
26 
27 class IDBObjectStore;
28 class IDBRequest;
29 template <typename>
30 class Sequence;
31 
32 namespace indexedDB {
33 class IndexMetadata;
34 class KeyPath;
35 }  // namespace indexedDB
36 
37 class IDBIndex final : public nsISupports, public nsWrapperCache {
38   // TODO: This could be made const if Bug 1575173 is resolved. It is
39   // initialized in the constructor and never modified/cleared.
40   RefPtr<IDBObjectStore> mObjectStore;
41 
42   JS::Heap<JS::Value> mCachedKeyPath;
43 
44   // This normally points to the IndexMetadata owned by the parent IDBDatabase
45   // object. However, if this index is part of a versionchange transaction and
46   // it gets deleted then the metadata is copied into mDeletedMetadata and
47   // mMetadata is set to point at mDeletedMetadata.
48   const indexedDB::IndexMetadata* mMetadata;
49   UniquePtr<indexedDB::IndexMetadata> mDeletedMetadata;
50 
51   const int64_t mId;
52   bool mRooted;
53 
54  public:
55   NS_DECL_CYCLE_COLLECTING_ISUPPORTS
56   NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(IDBIndex)
57 
58   [[nodiscard]] static RefPtr<IDBIndex> Create(
59       IDBObjectStore* aObjectStore, const indexedDB::IndexMetadata& aMetadata);
60 
Id()61   int64_t Id() const {
62     AssertIsOnOwningThread();
63 
64     return mId;
65   }
66 
67   const nsString& Name() const;
68 
69   bool Unique() const;
70 
71   bool MultiEntry() const;
72 
73   bool LocaleAware() const;
74 
75   const indexedDB::KeyPath& GetKeyPath() const;
76 
77   void GetLocale(nsString& aLocale) const;
78 
79   const nsCString& Locale() const;
80 
81   bool IsAutoLocale() const;
82 
ObjectStore()83   IDBObjectStore* ObjectStore() const {
84     AssertIsOnOwningThread();
85     return mObjectStore;
86   }
87 
88   nsIGlobalObject* GetParentObject() const;
89 
GetName(nsString & aName)90   void GetName(nsString& aName) const { aName = Name(); }
91 
92   void SetName(const nsAString& aName, ErrorResult& aRv);
93 
94   void GetKeyPath(JSContext* aCx, JS::MutableHandle<JS::Value> aResult,
95                   ErrorResult& aRv);
96 
97   [[nodiscard]] RefPtr<IDBRequest> OpenCursor(JSContext* aCx,
98                                               JS::Handle<JS::Value> aRange,
99                                               IDBCursorDirection aDirection,
100                                               ErrorResult& aRv);
101 
102   [[nodiscard]] RefPtr<IDBRequest> OpenKeyCursor(JSContext* aCx,
103                                                  JS::Handle<JS::Value> aRange,
104                                                  IDBCursorDirection aDirection,
105                                                  ErrorResult& aRv);
106 
107   [[nodiscard]] RefPtr<IDBRequest> Get(JSContext* aCx,
108                                        JS::Handle<JS::Value> aKey,
109                                        ErrorResult& aRv);
110 
111   [[nodiscard]] RefPtr<IDBRequest> GetKey(JSContext* aCx,
112                                           JS::Handle<JS::Value> aKey,
113                                           ErrorResult& aRv);
114 
115   [[nodiscard]] RefPtr<IDBRequest> Count(JSContext* aCx,
116                                          JS::Handle<JS::Value> aKey,
117                                          ErrorResult& aRv);
118 
119   [[nodiscard]] RefPtr<IDBRequest> GetAll(JSContext* aCx,
120                                           JS::Handle<JS::Value> aKey,
121                                           const Optional<uint32_t>& aLimit,
122                                           ErrorResult& aRv);
123 
124   [[nodiscard]] RefPtr<IDBRequest> GetAllKeys(JSContext* aCx,
125                                               JS::Handle<JS::Value> aKey,
126                                               const Optional<uint32_t>& aLimit,
127                                               ErrorResult& aRv);
128 
129   void RefreshMetadata(bool aMayDelete);
130 
131   void NoteDeletion();
132 
IsDeleted()133   bool IsDeleted() const {
134     AssertIsOnOwningThread();
135 
136     return !!mDeletedMetadata;
137   }
138 
139   void AssertIsOnOwningThread() const
140 #ifdef DEBUG
141       ;
142 #else
143   {
144   }
145 #endif
146 
147   // nsWrapperCache
148   virtual JSObject* WrapObject(JSContext* aCx,
149                                JS::Handle<JSObject*> aGivenProto) override;
150 
151  private:
152   IDBIndex(IDBObjectStore* aObjectStore,
153            const indexedDB::IndexMetadata* aMetadata);
154 
155   ~IDBIndex();
156 
157   [[nodiscard]] RefPtr<IDBRequest> GetInternal(bool aKeyOnly, JSContext* aCx,
158                                                JS::Handle<JS::Value> aKey,
159                                                ErrorResult& aRv);
160 
161   [[nodiscard]] RefPtr<IDBRequest> GetAllInternal(
162       bool aKeysOnly, JSContext* aCx, JS::Handle<JS::Value> aKey,
163       const Optional<uint32_t>& aLimit, ErrorResult& aRv);
164 
165   [[nodiscard]] RefPtr<IDBRequest> OpenCursorInternal(
166       bool aKeysOnly, JSContext* aCx, JS::Handle<JS::Value> aRange,
167       IDBCursorDirection aDirection, ErrorResult& aRv);
168 };
169 
170 }  // namespace dom
171 }  // namespace mozilla
172 
173 #endif  // mozilla_dom_idbindex_h__
174