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_idbcursor_h__ 8 #define mozilla_dom_idbcursor_h__ 9 10 #include "IndexedDatabase.h" 11 #include "js/RootingAPI.h" 12 #include "mozilla/Attributes.h" 13 #include "mozilla/dom/IDBCursorBinding.h" 14 #include "mozilla/dom/indexedDB/Key.h" 15 #include "nsCycleCollectionParticipant.h" 16 #include "nsWrapperCache.h" 17 18 class nsPIDOMWindowInner; 19 20 namespace mozilla { 21 22 class ErrorResult; 23 24 namespace dom { 25 26 class IDBIndex; 27 class IDBObjectStore; 28 class IDBRequest; 29 class IDBTransaction; 30 class OwningIDBObjectStoreOrIDBIndex; 31 32 namespace indexedDB { 33 class BackgroundCursorChild; 34 } 35 36 class IDBCursor final : public nsISupports, public nsWrapperCache { 37 public: 38 typedef indexedDB::Key Key; 39 typedef indexedDB::StructuredCloneReadInfo StructuredCloneReadInfo; 40 41 enum Direction { 42 NEXT = 0, 43 NEXT_UNIQUE, 44 PREV, 45 PREV_UNIQUE, 46 47 // Only needed for IPC serialization helper, should never be used in code. 48 DIRECTION_INVALID 49 }; 50 51 private: 52 enum Type { 53 Type_ObjectStore, 54 Type_ObjectStoreKey, 55 Type_Index, 56 Type_IndexKey, 57 }; 58 59 indexedDB::BackgroundCursorChild* mBackgroundActor; 60 61 RefPtr<IDBRequest> mRequest; 62 RefPtr<IDBObjectStore> mSourceObjectStore; 63 RefPtr<IDBIndex> mSourceIndex; 64 65 // mSourceObjectStore or mSourceIndex will hold this alive. 66 IDBTransaction* mTransaction; 67 68 JS::Heap<JSObject*> mScriptOwner; 69 70 // These are cycle-collected! 71 JS::Heap<JS::Value> mCachedKey; 72 JS::Heap<JS::Value> mCachedPrimaryKey; 73 JS::Heap<JS::Value> mCachedValue; 74 75 Key mKey; 76 Key mSortKey; 77 Key mPrimaryKey; 78 StructuredCloneReadInfo mCloneInfo; 79 80 const Type mType; 81 const Direction mDirection; 82 83 bool mHaveCachedKey : 1; 84 bool mHaveCachedPrimaryKey : 1; 85 bool mHaveCachedValue : 1; 86 bool mRooted : 1; 87 bool mContinueCalled : 1; 88 bool mHaveValue : 1; 89 90 public: 91 static already_AddRefed<IDBCursor> Create( 92 indexedDB::BackgroundCursorChild* aBackgroundActor, const Key& aKey, 93 StructuredCloneReadInfo&& aCloneInfo); 94 95 static already_AddRefed<IDBCursor> Create( 96 indexedDB::BackgroundCursorChild* aBackgroundActor, const Key& aKey); 97 98 static already_AddRefed<IDBCursor> Create( 99 indexedDB::BackgroundCursorChild* aBackgroundActor, const Key& aKey, 100 const Key& aSortKey, const Key& aPrimaryKey, 101 StructuredCloneReadInfo&& aCloneInfo); 102 103 static already_AddRefed<IDBCursor> Create( 104 indexedDB::BackgroundCursorChild* aBackgroundActor, const Key& aKey, 105 const Key& aSortKey, const Key& aPrimaryKey); 106 107 static Direction ConvertDirection(IDBCursorDirection aDirection); 108 109 void AssertIsOnOwningThread() const 110 #ifdef DEBUG 111 ; 112 #else 113 { 114 } 115 #endif 116 117 nsPIDOMWindowInner* GetParentObject() const; 118 119 void GetSource(OwningIDBObjectStoreOrIDBIndex& aSource) const; 120 121 IDBCursorDirection GetDirection() const; 122 123 void GetKey(JSContext* aCx, JS::MutableHandle<JS::Value> aResult, 124 ErrorResult& aRv); 125 126 void GetPrimaryKey(JSContext* aCx, JS::MutableHandle<JS::Value> aResult, 127 ErrorResult& aRv); 128 129 void GetValue(JSContext* aCx, JS::MutableHandle<JS::Value> aResult, 130 ErrorResult& aRv); 131 132 void Continue(JSContext* aCx, JS::Handle<JS::Value> aKey, ErrorResult& aRv); 133 134 void ContinuePrimaryKey(JSContext* aCx, JS::Handle<JS::Value> aKey, 135 JS::Handle<JS::Value> aPrimaryKey, ErrorResult& aRv); 136 137 void Advance(uint32_t aCount, ErrorResult& aRv); 138 139 already_AddRefed<IDBRequest> Update(JSContext* aCx, 140 JS::Handle<JS::Value> aValue, 141 ErrorResult& aRv); 142 143 already_AddRefed<IDBRequest> Delete(JSContext* aCx, ErrorResult& aRv); 144 145 void Reset(); 146 147 void Reset(Key&& aKey, StructuredCloneReadInfo&& aValue); 148 149 void Reset(Key&& aKey); 150 151 void Reset(Key&& aKey, Key&& aSortKey, Key&& aPrimaryKey, 152 StructuredCloneReadInfo&& aValue); 153 154 void Reset(Key&& aKey, Key&& aSortKey, Key&& aPrimaryKey); 155 ClearBackgroundActor()156 void ClearBackgroundActor() { 157 AssertIsOnOwningThread(); 158 159 mBackgroundActor = nullptr; 160 } 161 162 NS_DECL_CYCLE_COLLECTING_ISUPPORTS 163 NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(IDBCursor) 164 165 // nsWrapperCache 166 virtual JSObject* WrapObject(JSContext* aCx, 167 JS::Handle<JSObject*> aGivenProto) override; 168 169 private: 170 IDBCursor(Type aType, indexedDB::BackgroundCursorChild* aBackgroundActor, 171 const Key& aKey); 172 173 ~IDBCursor(); 174 175 // Checks if this is a locale aware cursor (ie. the index's sortKey is unset) 176 bool IsLocaleAware() const; 177 178 void DropJSObjects(); 179 180 bool IsSourceDeleted() const; 181 }; 182 183 } // namespace dom 184 } // namespace mozilla 185 186 #endif // mozilla_dom_idbcursor_h__ 187