michael@0: /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ michael@0: /* vim: set ts=2 et sw=2 tw=80: */ michael@0: /* This Source Code Form is subject to the terms of the Mozilla Public michael@0: * License, v. 2.0. If a copy of the MPL was not distributed with this michael@0: * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ michael@0: michael@0: #ifndef mozilla_dom_indexeddb_idbcursor_h__ michael@0: #define mozilla_dom_indexeddb_idbcursor_h__ michael@0: michael@0: #include "mozilla/dom/indexedDB/IndexedDatabase.h" michael@0: michael@0: #include "mozilla/Attributes.h" michael@0: #include "mozilla/dom/IDBCursorBinding.h" michael@0: #include "mozilla/ErrorResult.h" michael@0: #include "nsCycleCollectionParticipant.h" michael@0: #include "nsWrapperCache.h" michael@0: michael@0: #include "mozilla/dom/indexedDB/IDBObjectStore.h" michael@0: #include "mozilla/dom/indexedDB/Key.h" michael@0: michael@0: class nsIRunnable; michael@0: class nsIScriptContext; michael@0: class nsPIDOMWindow; michael@0: michael@0: namespace mozilla { michael@0: namespace dom { michael@0: class OwningIDBObjectStoreOrIDBIndex; michael@0: } michael@0: } michael@0: michael@0: BEGIN_INDEXEDDB_NAMESPACE michael@0: michael@0: class ContinueHelper; michael@0: class ContinueObjectStoreHelper; michael@0: class ContinueIndexHelper; michael@0: class ContinueIndexObjectHelper; michael@0: class IDBIndex; michael@0: class IDBRequest; michael@0: class IDBTransaction; michael@0: class IndexedDBCursorChild; michael@0: class IndexedDBCursorParent; michael@0: michael@0: class IDBCursor MOZ_FINAL : public nsISupports, michael@0: public nsWrapperCache michael@0: { michael@0: friend class ContinueHelper; michael@0: friend class ContinueObjectStoreHelper; michael@0: friend class ContinueIndexHelper; michael@0: friend class ContinueIndexObjectHelper; michael@0: michael@0: public: michael@0: NS_DECL_CYCLE_COLLECTING_ISUPPORTS michael@0: NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(IDBCursor) michael@0: michael@0: enum Type michael@0: { michael@0: OBJECTSTORE = 0, michael@0: OBJECTSTOREKEY, michael@0: INDEXKEY, michael@0: INDEXOBJECT michael@0: }; michael@0: michael@0: enum Direction michael@0: { michael@0: NEXT = 0, michael@0: NEXT_UNIQUE, michael@0: PREV, michael@0: PREV_UNIQUE, michael@0: michael@0: // Only needed for IPC serialization helper, should never be used in code. michael@0: DIRECTION_INVALID michael@0: }; michael@0: michael@0: // For OBJECTSTORE cursors. michael@0: static michael@0: already_AddRefed michael@0: Create(IDBRequest* aRequest, michael@0: IDBTransaction* aTransaction, michael@0: IDBObjectStore* aObjectStore, michael@0: Direction aDirection, michael@0: const Key& aRangeKey, michael@0: const nsACString& aContinueQuery, michael@0: const nsACString& aContinueToQuery, michael@0: const Key& aKey, michael@0: StructuredCloneReadInfo&& aCloneReadInfo); michael@0: michael@0: // For OBJECTSTOREKEY cursors. michael@0: static michael@0: already_AddRefed michael@0: Create(IDBRequest* aRequest, michael@0: IDBTransaction* aTransaction, michael@0: IDBObjectStore* aObjectStore, michael@0: Direction aDirection, michael@0: const Key& aRangeKey, michael@0: const nsACString& aContinueQuery, michael@0: const nsACString& aContinueToQuery, michael@0: const Key& aKey); michael@0: michael@0: // For INDEXKEY cursors. michael@0: static michael@0: already_AddRefed michael@0: Create(IDBRequest* aRequest, michael@0: IDBTransaction* aTransaction, michael@0: IDBIndex* aIndex, michael@0: Direction aDirection, michael@0: const Key& aRangeKey, michael@0: const nsACString& aContinueQuery, michael@0: const nsACString& aContinueToQuery, michael@0: const Key& aKey, michael@0: const Key& aObjectKey); michael@0: michael@0: // For INDEXOBJECT cursors. michael@0: static michael@0: already_AddRefed michael@0: Create(IDBRequest* aRequest, michael@0: IDBTransaction* aTransaction, michael@0: IDBIndex* aIndex, michael@0: Direction aDirection, michael@0: const Key& aRangeKey, michael@0: const nsACString& aContinueQuery, michael@0: const nsACString& aContinueToQuery, michael@0: const Key& aKey, michael@0: const Key& aObjectKey, michael@0: StructuredCloneReadInfo&& aCloneReadInfo); michael@0: michael@0: IDBTransaction* Transaction() const michael@0: { michael@0: return mTransaction; michael@0: } michael@0: michael@0: IDBRequest* Request() const michael@0: { michael@0: return mRequest; michael@0: } michael@0: michael@0: static Direction michael@0: ConvertDirection(IDBCursorDirection aDirection); michael@0: michael@0: void michael@0: SetActor(IndexedDBCursorChild* aActorChild) michael@0: { michael@0: NS_ASSERTION(!aActorChild || !mActorChild, "Shouldn't have more than one!"); michael@0: mActorChild = aActorChild; michael@0: } michael@0: michael@0: void michael@0: SetActor(IndexedDBCursorParent* aActorParent) michael@0: { michael@0: NS_ASSERTION(!aActorParent || !mActorParent, michael@0: "Shouldn't have more than one!"); michael@0: mActorParent = aActorParent; michael@0: } michael@0: michael@0: IndexedDBCursorChild* michael@0: GetActorChild() const michael@0: { michael@0: return mActorChild; michael@0: } michael@0: michael@0: IndexedDBCursorParent* michael@0: GetActorParent() const michael@0: { michael@0: return mActorParent; michael@0: } michael@0: michael@0: void michael@0: ContinueInternal(const Key& aKey, int32_t aCount, michael@0: ErrorResult& aRv); michael@0: michael@0: // nsWrapperCache michael@0: virtual JSObject* michael@0: WrapObject(JSContext* aCx) MOZ_OVERRIDE; michael@0: michael@0: // WebIDL michael@0: IDBTransaction* michael@0: GetParentObject() const michael@0: { michael@0: return mTransaction; michael@0: } michael@0: michael@0: void michael@0: GetSource(OwningIDBObjectStoreOrIDBIndex& aSource) const; michael@0: michael@0: IDBCursorDirection michael@0: GetDirection() const; michael@0: michael@0: void michael@0: GetKey(JSContext* aCx, JS::MutableHandle aResult, michael@0: ErrorResult& aRv); michael@0: michael@0: void michael@0: GetPrimaryKey(JSContext* aCx, JS::MutableHandle aResult, michael@0: ErrorResult& aRv); michael@0: michael@0: already_AddRefed michael@0: Update(JSContext* aCx, JS::Handle aValue, ErrorResult& aRv); michael@0: michael@0: void michael@0: Advance(uint32_t aCount, ErrorResult& aRv); michael@0: michael@0: void michael@0: Continue(JSContext* aCx, JS::Handle aKey, ErrorResult& aRv); michael@0: michael@0: already_AddRefed michael@0: Delete(JSContext* aCx, ErrorResult& aRv); michael@0: michael@0: void michael@0: GetValue(JSContext* aCx, JS::MutableHandle aResult, michael@0: ErrorResult& aRv); michael@0: michael@0: protected: michael@0: IDBCursor(); michael@0: ~IDBCursor(); michael@0: michael@0: void DropJSObjects(); michael@0: michael@0: static michael@0: already_AddRefed michael@0: CreateCommon(IDBRequest* aRequest, michael@0: IDBTransaction* aTransaction, michael@0: IDBObjectStore* aObjectStore, michael@0: Direction aDirection, michael@0: const Key& aRangeKey, michael@0: const nsACString& aContinueQuery, michael@0: const nsACString& aContinueToQuery); michael@0: michael@0: nsRefPtr mRequest; michael@0: nsRefPtr mTransaction; michael@0: nsRefPtr mObjectStore; michael@0: nsRefPtr mIndex; michael@0: michael@0: JS::Heap mScriptOwner; michael@0: michael@0: Type mType; michael@0: Direction mDirection; michael@0: nsCString mContinueQuery; michael@0: nsCString mContinueToQuery; michael@0: michael@0: // These are cycle-collected! michael@0: JS::Heap mCachedKey; michael@0: JS::Heap mCachedPrimaryKey; michael@0: JS::Heap mCachedValue; michael@0: michael@0: Key mRangeKey; michael@0: michael@0: Key mKey; michael@0: Key mObjectKey; michael@0: StructuredCloneReadInfo mCloneReadInfo; michael@0: Key mContinueToKey; michael@0: michael@0: IndexedDBCursorChild* mActorChild; michael@0: IndexedDBCursorParent* mActorParent; michael@0: michael@0: bool mHaveCachedKey; michael@0: bool mHaveCachedPrimaryKey; michael@0: bool mHaveCachedValue; michael@0: bool mRooted; michael@0: bool mContinueCalled; michael@0: bool mHaveValue; michael@0: }; michael@0: michael@0: END_INDEXEDDB_NAMESPACE michael@0: michael@0: #endif // mozilla_dom_indexeddb_idbcursor_h__