/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #ifndef mozilla_dom_idbobjectstore_h__ #define mozilla_dom_idbobjectstore_h__ #include "js/RootingAPI.h" #include "mozilla/dom/IDBCursorBinding.h" #include "mozilla/dom/IDBIndexBinding.h" #include "nsAutoPtr.h" #include "nsCycleCollectionParticipant.h" #include "nsISupports.h" #include "nsString.h" #include "nsTArray.h" #include "nsWrapperCache.h" struct JSClass; class nsPIDOMWindowInner; namespace mozilla { class ErrorResult; namespace dom { class DOMStringList; class IDBCursor; class IDBRequest; class IDBTransaction; class StringOrStringSequence; template class Sequence; namespace indexedDB { class Key; class KeyPath; class IndexUpdateInfo; class ObjectStoreSpec; struct StructuredCloneReadInfo; } // namespace indexedDB class IDBObjectStore final : public nsISupports , public nsWrapperCache { typedef indexedDB::IndexUpdateInfo IndexUpdateInfo; typedef indexedDB::Key Key; typedef indexedDB::KeyPath KeyPath; typedef indexedDB::ObjectStoreSpec ObjectStoreSpec; typedef indexedDB::StructuredCloneReadInfo StructuredCloneReadInfo; // For AddOrPut() and DeleteInternal(). friend class IDBCursor; static const JSClass sDummyPropJSClass; RefPtr mTransaction; JS::Heap mCachedKeyPath; // This normally points to the ObjectStoreSpec owned by the parent IDBDatabase // object. However, if this objectStore is part of a versionchange transaction // and it gets deleted then the spec is copied into mDeletedSpec and mSpec is // set to point at mDeletedSpec. const ObjectStoreSpec* mSpec; nsAutoPtr mDeletedSpec; nsTArray> mIndexes; nsTArray> mDeletedIndexes; const int64_t mId; bool mRooted; public: struct StructuredCloneWriteInfo; static already_AddRefed Create(IDBTransaction* aTransaction, const ObjectStoreSpec& aSpec); static nsresult AppendIndexUpdateInfo(int64_t aIndexID, const KeyPath& aKeyPath, bool aUnique, bool aMultiEntry, const nsCString& aLocale, JSContext* aCx, JS::Handle aObject, nsTArray& aUpdateInfoArray); static void ClearCloneReadInfo(StructuredCloneReadInfo& aReadInfo); static bool DeserializeValue(JSContext* aCx, StructuredCloneReadInfo& aCloneReadInfo, JS::MutableHandle aValue); static bool DeserializeIndexValue(JSContext* aCx, StructuredCloneReadInfo& aCloneReadInfo, JS::MutableHandle aValue); static bool DeserializeUpgradeValue(JSContext* aCx, StructuredCloneReadInfo& aCloneReadInfo, JS::MutableHandle aValue); static const JSClass* DummyPropClass() { return &sDummyPropJSClass; } void AssertIsOnOwningThread() const #ifdef DEBUG ; #else { } #endif int64_t Id() const { AssertIsOnOwningThread(); return mId; } const nsString& Name() const; bool AutoIncrement() const; const KeyPath& GetKeyPath() const; bool HasValidKeyPath() const; nsPIDOMWindowInner* GetParentObject() const; void GetName(nsString& aName) const { AssertIsOnOwningThread(); aName = Name(); } void SetName(const nsAString& aName, ErrorResult& aRv); void GetKeyPath(JSContext* aCx, JS::MutableHandle aResult, ErrorResult& aRv); already_AddRefed IndexNames(); IDBTransaction* Transaction() const { AssertIsOnOwningThread(); return mTransaction; } already_AddRefed Add(JSContext* aCx, JS::Handle aValue, JS::Handle aKey, ErrorResult& aRv) { AssertIsOnOwningThread(); return AddOrPut(aCx, aValue, aKey, false, /* aFromCursor */ false, aRv); } already_AddRefed Put(JSContext* aCx, JS::Handle aValue, JS::Handle aKey, ErrorResult& aRv) { AssertIsOnOwningThread(); return AddOrPut(aCx, aValue, aKey, true, /* aFromCursor */ false, aRv); } already_AddRefed Delete(JSContext* aCx, JS::Handle aKey, ErrorResult& aRv) { AssertIsOnOwningThread(); return DeleteInternal(aCx, aKey, /* aFromCursor */ false, aRv); } already_AddRefed Get(JSContext* aCx, JS::Handle aKey, ErrorResult& aRv) { AssertIsOnOwningThread(); return GetInternal(/* aKeyOnly */ false, aCx, aKey, aRv); } already_AddRefed GetKey(JSContext* aCx, JS::Handle aKey, ErrorResult& aRv) { AssertIsOnOwningThread(); return GetInternal(/* aKeyOnly */ true, aCx, aKey, aRv); } already_AddRefed Clear(JSContext* aCx, ErrorResult& aRv); already_AddRefed CreateIndex(const nsAString& aName, const StringOrStringSequence& aKeyPath, const IDBIndexParameters& aOptionalParameters, ErrorResult& aRv); already_AddRefed Index(const nsAString& aName, ErrorResult &aRv); void DeleteIndex(const nsAString& aIndexName, ErrorResult& aRv); already_AddRefed Count(JSContext* aCx, JS::Handle aKey, ErrorResult& aRv); already_AddRefed GetAll(JSContext* aCx, JS::Handle aKey, const Optional& aLimit, ErrorResult& aRv) { AssertIsOnOwningThread(); return GetAllInternal(/* aKeysOnly */ false, aCx, aKey, aLimit, aRv); } already_AddRefed GetAllKeys(JSContext* aCx, JS::Handle aKey, const Optional& aLimit, ErrorResult& aRv) { AssertIsOnOwningThread(); return GetAllInternal(/* aKeysOnly */ true, aCx, aKey, aLimit, aRv); } already_AddRefed OpenCursor(JSContext* aCx, JS::Handle aRange, IDBCursorDirection aDirection, ErrorResult& aRv) { AssertIsOnOwningThread(); return OpenCursorInternal(/* aKeysOnly */ false, aCx, aRange, aDirection, aRv); } already_AddRefed OpenCursor(JSContext* aCx, IDBCursorDirection aDirection, ErrorResult& aRv) { AssertIsOnOwningThread(); return OpenCursorInternal(/* aKeysOnly */ false, aCx, JS::UndefinedHandleValue, aDirection, aRv); } already_AddRefed OpenKeyCursor(JSContext* aCx, JS::Handle aRange, IDBCursorDirection aDirection, ErrorResult& aRv) { AssertIsOnOwningThread(); return OpenCursorInternal(/* aKeysOnly */ true, aCx, aRange, aDirection, aRv); } void RefreshSpec(bool aMayDelete); const ObjectStoreSpec& Spec() const; void NoteDeletion(); bool IsDeleted() const { AssertIsOnOwningThread(); return !!mDeletedSpec; } NS_DECL_CYCLE_COLLECTING_ISUPPORTS NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(IDBObjectStore) // nsWrapperCache virtual JSObject* WrapObject(JSContext* aCx, JS::Handle aGivenProto) override; private: IDBObjectStore(IDBTransaction* aTransaction, const ObjectStoreSpec* aSpec); ~IDBObjectStore(); nsresult GetAddInfo(JSContext* aCx, JS::Handle aValue, JS::Handle aKeyVal, StructuredCloneWriteInfo& aCloneWriteInfo, Key& aKey, nsTArray& aUpdateInfoArray); already_AddRefed AddOrPut(JSContext* aCx, JS::Handle aValue, JS::Handle aKey, bool aOverwrite, bool aFromCursor, ErrorResult& aRv); already_AddRefed DeleteInternal(JSContext* aCx, JS::Handle aKey, bool aFromCursor, ErrorResult& aRv); already_AddRefed GetInternal(bool aKeyOnly, JSContext* aCx, JS::Handle aKey, ErrorResult& aRv); already_AddRefed GetAllInternal(bool aKeysOnly, JSContext* aCx, JS::Handle aKey, const Optional& aLimit, ErrorResult& aRv); already_AddRefed OpenCursorInternal(bool aKeysOnly, JSContext* aCx, JS::Handle aRange, IDBCursorDirection aDirection, ErrorResult& aRv); }; } // namespace dom } // namespace mozilla #endif // mozilla_dom_idbobjectstore_h__