diff options
Diffstat (limited to 'Source/WebCore/Modules/indexeddb/IDBIndex.cpp')
-rw-r--r-- | Source/WebCore/Modules/indexeddb/IDBIndex.cpp | 451 |
1 files changed, 312 insertions, 139 deletions
diff --git a/Source/WebCore/Modules/indexeddb/IDBIndex.cpp b/Source/WebCore/Modules/indexeddb/IDBIndex.cpp index e6fdf5cb8..3ec51603c 100644 --- a/Source/WebCore/Modules/indexeddb/IDBIndex.cpp +++ b/Source/WebCore/Modules/indexeddb/IDBIndex.cpp @@ -1,26 +1,26 @@ /* - * Copyright (C) 2010 Google Inc. All rights reserved. + * Copyright (C) 2015 Apple Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. */ #include "config.h" @@ -28,181 +28,354 @@ #if ENABLE(INDEXED_DATABASE) +#include "ExceptionCode.h" +#include "IDBBindingUtilities.h" +#include "IDBCursor.h" +#include "IDBDatabase.h" #include "IDBDatabaseException.h" -#include "IDBKey.h" -#include "IDBKeyRange.h" +#include "IDBKeyRangeData.h" #include "IDBObjectStore.h" #include "IDBRequest.h" #include "IDBTransaction.h" #include "Logging.h" -#include "ScriptExecutionContext.h" +#include <heap/HeapInlines.h> + +using namespace JSC; namespace WebCore { -IDBIndex::IDBIndex(const IDBIndexMetadata& metadata, IDBObjectStore* objectStore, IDBTransaction* transaction) - : m_metadata(metadata) +IDBIndex::IDBIndex(ScriptExecutionContext& context, const IDBIndexInfo& info, IDBObjectStore& objectStore) + : ActiveDOMObject(&context) + , m_info(info) + , m_originalInfo(info) , m_objectStore(objectStore) - , m_transaction(transaction) - , m_deleted(false) { - ASSERT(m_objectStore); - ASSERT(m_transaction); - ASSERT(m_metadata.id != IDBIndexMetadata::InvalidId); + ASSERT(currentThread() == m_objectStore.transaction().database().originThreadID()); + + suspendIfNeeded(); } IDBIndex::~IDBIndex() { + ASSERT(currentThread() == m_objectStore.transaction().database().originThreadID()); } -PassRefPtr<IDBRequest> IDBIndex::openCursor(ScriptExecutionContext* context, PassRefPtr<IDBKeyRange> keyRange, const String& directionString, ExceptionCode& ec) +const char* IDBIndex::activeDOMObjectName() const { - LOG(StorageAPI, "IDBIndex::openCursor"); - if (m_deleted) { - ec = IDBDatabaseException::InvalidStateError; - return 0; - } - if (!m_transaction->isActive()) { - ec = IDBDatabaseException::TransactionInactiveError; - return 0; - } - IndexedDB::CursorDirection direction = IDBCursor::stringToDirection(directionString, ec); - if (ec) - return 0; + return "IDBIndex"; +} - RefPtr<IDBRequest> request = IDBRequest::create(context, IDBAny::create(this), m_transaction.get()); - request->setCursorDetails(IndexedDB::CursorType::KeyAndValue, direction); - backendDB()->openCursor(m_transaction->id(), m_objectStore->id(), m_metadata.id, keyRange, direction, false, IDBDatabaseBackend::NormalTask, request); - return request; +bool IDBIndex::canSuspendForDocumentSuspension() const +{ + return false; } -PassRefPtr<IDBRequest> IDBIndex::openCursor(ScriptExecutionContext* context, const Deprecated::ScriptValue& key, const String& direction, ExceptionCode& ec) +bool IDBIndex::hasPendingActivity() const { - LOG(StorageAPI, "IDBIndex::openCursor"); - RefPtr<IDBKeyRange> keyRange = IDBKeyRange::only(context, key, ec); - if (ec) - return 0; - return openCursor(context, keyRange.release(), direction, ec); + return !m_objectStore.transaction().isFinished(); } -PassRefPtr<IDBRequest> IDBIndex::count(ScriptExecutionContext* context, PassRefPtr<IDBKeyRange> keyRange, ExceptionCode& ec) +const String& IDBIndex::name() const { - LOG(StorageAPI, "IDBIndex::count"); - if (m_deleted) { - ec = IDBDatabaseException::InvalidStateError; - return 0; - } - if (!m_transaction->isActive()) { - ec = IDBDatabaseException::TransactionInactiveError; - return 0; - } - RefPtr<IDBRequest> request = IDBRequest::create(context, IDBAny::create(this), m_transaction.get()); - backendDB()->count(m_transaction->id(), m_objectStore->id(), m_metadata.id, keyRange, request); - return request; + ASSERT(currentThread() == m_objectStore.transaction().database().originThreadID()); + return m_info.name(); } -PassRefPtr<IDBRequest> IDBIndex::count(ScriptExecutionContext* context, const Deprecated::ScriptValue& key, ExceptionCode& ec) +ExceptionOr<void> IDBIndex::setName(const String& name) { - LOG(StorageAPI, "IDBIndex::count"); - RefPtr<IDBKeyRange> keyRange = IDBKeyRange::only(context, key, ec); - if (ec) - return 0; - return count(context, keyRange.release(), ec); + ASSERT(currentThread() == m_objectStore.transaction().database().originThreadID()); + + if (m_deleted) + return Exception { INVALID_STATE_ERR, ASCIILiteral("Failed set property 'name' on 'IDBIndex': The index has been deleted.") }; + + if (m_objectStore.isDeleted()) + return Exception { INVALID_STATE_ERR, ASCIILiteral("Failed set property 'name' on 'IDBIndex': The index's object store has been deleted.") }; + + if (!m_objectStore.transaction().isVersionChange()) + return Exception { INVALID_STATE_ERR, ASCIILiteral("Failed set property 'name' on 'IDBIndex': The index's transaction is not a version change transaction.") }; + + if (!m_objectStore.transaction().isActive()) + return Exception { IDBDatabaseException::TransactionInactiveError, ASCIILiteral("Failed set property 'name' on 'IDBIndex': The index's transaction is not active.") }; + + if (m_info.name() == name) + return { }; + + if (m_objectStore.info().hasIndex(name)) + return Exception { IDBDatabaseException::ConstraintError, makeString("Failed set property 'name' on 'IDBIndex': The owning object store already has an index named '", name, "'.") }; + + m_objectStore.transaction().database().renameIndex(*this, name); + m_info.rename(name); + + return { }; } -PassRefPtr<IDBRequest> IDBIndex::openKeyCursor(ScriptExecutionContext* context, PassRefPtr<IDBKeyRange> keyRange, const String& directionString, ExceptionCode& ec) +IDBObjectStore& IDBIndex::objectStore() { - LOG(StorageAPI, "IDBIndex::openKeyCursor"); - if (m_deleted) { - ec = IDBDatabaseException::InvalidStateError; - return 0; - } - if (!m_transaction->isActive()) { - ec = IDBDatabaseException::TransactionInactiveError; - return 0; - } - IndexedDB::CursorDirection direction = IDBCursor::stringToDirection(directionString, ec); - if (ec) - return 0; + ASSERT(currentThread() == m_objectStore.transaction().database().originThreadID()); + return m_objectStore; +} - RefPtr<IDBRequest> request = IDBRequest::create(context, IDBAny::create(this), m_transaction.get()); - request->setCursorDetails(IndexedDB::CursorType::KeyOnly, direction); - backendDB()->openCursor(m_transaction->id(), m_objectStore->id(), m_metadata.id, keyRange, direction, true, IDBDatabaseBackend::NormalTask, request); - return request; +const IDBKeyPath& IDBIndex::keyPath() const +{ + ASSERT(currentThread() == m_objectStore.transaction().database().originThreadID()); + return m_info.keyPath(); } -PassRefPtr<IDBRequest> IDBIndex::openKeyCursor(ScriptExecutionContext* context, const Deprecated::ScriptValue& key, const String& direction, ExceptionCode& ec) +bool IDBIndex::unique() const { - LOG(StorageAPI, "IDBIndex::openKeyCursor"); - RefPtr<IDBKeyRange> keyRange = IDBKeyRange::only(context, key, ec); - if (ec) - return 0; - return openKeyCursor(context, keyRange.release(), direction, ec); + ASSERT(currentThread() == m_objectStore.transaction().database().originThreadID()); + return m_info.unique(); } -PassRefPtr<IDBRequest> IDBIndex::get(ScriptExecutionContext* context, const Deprecated::ScriptValue& key, ExceptionCode& ec) +bool IDBIndex::multiEntry() const { - LOG(StorageAPI, "IDBIndex::get"); - RefPtr<IDBKeyRange> keyRange = IDBKeyRange::only(context, key, ec); - if (ec) - return 0; - return get(context, keyRange.release(), ec); + ASSERT(currentThread() == m_objectStore.transaction().database().originThreadID()); + return m_info.multiEntry(); } -PassRefPtr<IDBRequest> IDBIndex::get(ScriptExecutionContext* context, PassRefPtr<IDBKeyRange> keyRange, ExceptionCode& ec) +void IDBIndex::rollbackInfoForVersionChangeAbort() { - LOG(StorageAPI, "IDBIndex::get"); - if (m_deleted) { - ec = IDBDatabaseException::InvalidStateError; - return 0; - } - if (!m_transaction->isActive()) { - ec = IDBDatabaseException::TransactionInactiveError; - return 0; - } - if (!keyRange) { - ec = IDBDatabaseException::DataError; - return 0; + ASSERT(currentThread() == m_objectStore.transaction().database().originThreadID()); + + // Only rollback to the original info if this index still exists in the rolled-back database info. + auto* objectStoreInfo = m_objectStore.transaction().database().info().infoForExistingObjectStore(m_objectStore.info().identifier()); + if (!objectStoreInfo) + return; + + if (!objectStoreInfo->hasIndex(m_info.identifier())) { + m_deleted = true; + return; } - RefPtr<IDBRequest> request = IDBRequest::create(context, IDBAny::create(this), m_transaction.get()); - backendDB()->get(m_transaction->id(), m_objectStore->id(), m_metadata.id, keyRange, false, request); - return request; + m_info = m_originalInfo; + m_deleted = false; } -PassRefPtr<IDBRequest> IDBIndex::getKey(ScriptExecutionContext* context, const Deprecated::ScriptValue& key, ExceptionCode& ec) +ExceptionOr<Ref<IDBRequest>> IDBIndex::openCursor(ExecState& execState, IDBKeyRange* range, IDBCursorDirection direction) { - LOG(StorageAPI, "IDBIndex::getKey"); - RefPtr<IDBKeyRange> keyRange = IDBKeyRange::only(context, key, ec); - if (ec) - return 0; + LOG(IndexedDB, "IDBIndex::openCursor"); + ASSERT(currentThread() == m_objectStore.transaction().database().originThreadID()); + + if (m_deleted || m_objectStore.isDeleted()) + return Exception { IDBDatabaseException::InvalidStateError, ASCIILiteral("Failed to execute 'openCursor' on 'IDBIndex': The index or its object store has been deleted.") }; + + if (!m_objectStore.transaction().isActive()) + return Exception { IDBDatabaseException::TransactionInactiveError, ASCIILiteral("Failed to execute 'openCursor' on 'IDBIndex': The transaction is inactive or finished.") }; - return getKey(context, keyRange.release(), ec); + IDBKeyRangeData rangeData = range; + if (rangeData.lowerKey.isNull()) + rangeData.lowerKey = IDBKeyData::minimum(); + if (rangeData.upperKey.isNull()) + rangeData.upperKey = IDBKeyData::maximum(); + + auto info = IDBCursorInfo::indexCursor(m_objectStore.transaction(), m_objectStore.info().identifier(), m_info.identifier(), rangeData, direction, IndexedDB::CursorType::KeyAndValue); + return m_objectStore.transaction().requestOpenCursor(execState, *this, info); } -PassRefPtr<IDBRequest> IDBIndex::getKey(ScriptExecutionContext* context, PassRefPtr<IDBKeyRange> keyRange, ExceptionCode& ec) +ExceptionOr<Ref<IDBRequest>> IDBIndex::openCursor(ExecState& execState, JSValue key, IDBCursorDirection direction) { - LOG(StorageAPI, "IDBIndex::getKey"); - if (m_deleted) { - ec = IDBDatabaseException::InvalidStateError; - return 0; - } - if (!m_transaction->isActive()) { - ec = IDBDatabaseException::TransactionInactiveError; - return 0; - } - if (!keyRange) { - ec = IDBDatabaseException::DataError; - return 0; - } + LOG(IndexedDB, "IDBIndex::openCursor"); + ASSERT(currentThread() == m_objectStore.transaction().database().originThreadID()); + + auto keyRange = IDBKeyRange::only(execState, key); + if (keyRange.hasException()) + return Exception { IDBDatabaseException::DataError, ASCIILiteral("Failed to execute 'openCursor' on 'IDBIndex': The parameter is not a valid key.") }; + + return openCursor(execState, keyRange.releaseReturnValue().ptr(), direction); +} + +ExceptionOr<Ref<IDBRequest>> IDBIndex::openKeyCursor(ExecState& execState, IDBKeyRange* range, IDBCursorDirection direction) +{ + LOG(IndexedDB, "IDBIndex::openKeyCursor"); + ASSERT(currentThread() == m_objectStore.transaction().database().originThreadID()); + + if (m_deleted || m_objectStore.isDeleted()) + return Exception { IDBDatabaseException::InvalidStateError, ASCIILiteral("Failed to execute 'openKeyCursor' on 'IDBIndex': The index or its object store has been deleted.") }; + + if (!m_objectStore.transaction().isActive()) + return Exception { IDBDatabaseException::TransactionInactiveError, ASCIILiteral("Failed to execute 'openKeyCursor' on 'IDBIndex': The transaction is inactive or finished.") }; - RefPtr<IDBRequest> request = IDBRequest::create(context, IDBAny::create(this), m_transaction.get()); - backendDB()->get(m_transaction->id(), m_objectStore->id(), m_metadata.id, keyRange, true, request); - return request; + auto info = IDBCursorInfo::indexCursor(m_objectStore.transaction(), m_objectStore.info().identifier(), m_info.identifier(), range, direction, IndexedDB::CursorType::KeyOnly); + return m_objectStore.transaction().requestOpenCursor(execState, *this, info); +} + +ExceptionOr<Ref<IDBRequest>> IDBIndex::openKeyCursor(ExecState& execState, JSValue key, IDBCursorDirection direction) +{ + LOG(IndexedDB, "IDBIndex::openKeyCursor"); + + auto keyRange = IDBKeyRange::only(execState, key); + if (keyRange.hasException()) + return Exception { IDBDatabaseException::DataError, ASCIILiteral("Failed to execute 'openKeyCursor' on 'IDBIndex': The parameter is not a valid key.") }; + return openKeyCursor(execState, keyRange.releaseReturnValue().ptr(), direction); +} + +ExceptionOr<Ref<IDBRequest>> IDBIndex::count(ExecState& execState, IDBKeyRange* range) +{ + LOG(IndexedDB, "IDBIndex::count"); + + return doCount(execState, range ? IDBKeyRangeData(range) : IDBKeyRangeData::allKeys()); +} + +ExceptionOr<Ref<IDBRequest>> IDBIndex::count(ExecState& execState, JSValue key) +{ + LOG(IndexedDB, "IDBIndex::count"); + + auto idbKey = scriptValueToIDBKey(execState, key); + if (!idbKey->isValid()) + return Exception { IDBDatabaseException::DataError, ASCIILiteral("Failed to execute 'count' on 'IDBIndex': The parameter is not a valid key.") }; + + return doCount(execState, IDBKeyRangeData(idbKey.ptr())); +} + +ExceptionOr<Ref<IDBRequest>> IDBIndex::doCount(ExecState& execState, const IDBKeyRangeData& range) +{ + ASSERT(currentThread() == m_objectStore.transaction().database().originThreadID()); + + if (m_deleted || m_objectStore.isDeleted()) + return Exception { IDBDatabaseException::InvalidStateError, ASCIILiteral("Failed to execute 'count' on 'IDBIndex': The index or its object store has been deleted.") }; + + if (!range.isValid()) + return Exception { IDBDatabaseException::DataError }; + + auto& transaction = m_objectStore.transaction(); + if (!transaction.isActive()) + return Exception { IDBDatabaseException::TransactionInactiveError, ASCIILiteral("Failed to execute 'count' on 'IDBIndex': The transaction is inactive or finished.") }; + + return transaction.requestCount(execState, *this, range); +} + +ExceptionOr<Ref<IDBRequest>> IDBIndex::get(ExecState& execState, IDBKeyRange* range) +{ + LOG(IndexedDB, "IDBIndex::get"); + + return doGet(execState, IDBKeyRangeData(range)); +} + +ExceptionOr<Ref<IDBRequest>> IDBIndex::get(ExecState& execState, JSValue key) +{ + LOG(IndexedDB, "IDBIndex::get"); + + auto idbKey = scriptValueToIDBKey(execState, key); + if (!idbKey->isValid()) + return Exception { IDBDatabaseException::DataError, ASCIILiteral("Failed to execute 'get' on 'IDBIndex': The parameter is not a valid key.") }; + + return doGet(execState, IDBKeyRangeData(idbKey.ptr())); +} + +ExceptionOr<Ref<IDBRequest>> IDBIndex::doGet(ExecState& execState, const IDBKeyRangeData& range) +{ + ASSERT(currentThread() == m_objectStore.transaction().database().originThreadID()); + + if (m_deleted || m_objectStore.isDeleted()) + return Exception { IDBDatabaseException::InvalidStateError, ASCIILiteral("Failed to execute 'get' on 'IDBIndex': The index or its object store has been deleted.") }; + + if (range.isNull) + return Exception { IDBDatabaseException::DataError }; + + auto& transaction = m_objectStore.transaction(); + if (!transaction.isActive()) + return Exception { IDBDatabaseException::TransactionInactiveError, ASCIILiteral("Failed to execute 'get' on 'IDBIndex': The transaction is inactive or finished.") }; + + return transaction.requestGetValue(execState, *this, range); +} + +ExceptionOr<Ref<IDBRequest>> IDBIndex::getKey(ExecState& execState, IDBKeyRange* range) +{ + LOG(IndexedDB, "IDBIndex::getKey"); + + return doGetKey(execState, IDBKeyRangeData(range)); +} + +ExceptionOr<Ref<IDBRequest>> IDBIndex::getKey(ExecState& execState, JSValue key) +{ + LOG(IndexedDB, "IDBIndex::getKey"); + + auto idbKey = scriptValueToIDBKey(execState, key); + if (!idbKey->isValid()) + return Exception { IDBDatabaseException::DataError, ASCIILiteral("Failed to execute 'getKey' on 'IDBIndex': The parameter is not a valid key.") }; + + return doGetKey(execState, IDBKeyRangeData(idbKey.ptr())); +} + +ExceptionOr<Ref<IDBRequest>> IDBIndex::doGetKey(ExecState& execState, const IDBKeyRangeData& range) +{ + ASSERT(currentThread() == m_objectStore.transaction().database().originThreadID()); + + if (m_deleted || m_objectStore.isDeleted()) + return Exception { IDBDatabaseException::InvalidStateError, ASCIILiteral("Failed to execute 'getKey' on 'IDBIndex': The index or its object store has been deleted.") }; + + if (range.isNull) + return Exception { IDBDatabaseException::DataError }; + + auto& transaction = m_objectStore.transaction(); + if (!transaction.isActive()) + return Exception { IDBDatabaseException::TransactionInactiveError, ASCIILiteral("Failed to execute 'getKey' on 'IDBIndex': The transaction is inactive or finished.") }; + + return transaction.requestGetKey(execState, *this, range); +} + +ExceptionOr<Ref<IDBRequest>> IDBIndex::getAll(ExecState& execState, RefPtr<IDBKeyRange> range, std::optional<uint32_t> count) +{ + LOG(IndexedDB, "IDBIndex::getAll"); + ASSERT(currentThread() == m_objectStore.transaction().database().originThreadID()); + + if (m_deleted || m_objectStore.isDeleted()) + return Exception { IDBDatabaseException::InvalidStateError, ASCIILiteral("Failed to execute 'getAll' on 'IDBIndex': The index or its object store has been deleted.") }; + + if (!m_objectStore.transaction().isActive()) + return Exception { IDBDatabaseException::TransactionInactiveError, ASCIILiteral("Failed to execute 'getAll' on 'IDBIndex': The transaction is inactive or finished.") }; + + return m_objectStore.transaction().requestGetAllIndexRecords(execState, *this, range.get(), IndexedDB::GetAllType::Values, count); +} + +ExceptionOr<Ref<IDBRequest>> IDBIndex::getAll(ExecState& execState, JSValue key, std::optional<uint32_t> count) +{ + auto onlyResult = IDBKeyRange::only(execState, key); + if (onlyResult.hasException()) + return Exception { IDBDatabaseException::DataError, ASCIILiteral("Failed to execute 'getAll' on 'IDBIndex': The parameter is not a valid key.") }; + + return getAll(execState, onlyResult.releaseReturnValue(), count); +} + +ExceptionOr<Ref<IDBRequest>> IDBIndex::getAllKeys(ExecState& execState, RefPtr<IDBKeyRange> range, std::optional<uint32_t> count) +{ + LOG(IndexedDB, "IDBIndex::getAllKeys"); + ASSERT(currentThread() == m_objectStore.transaction().database().originThreadID()); + + if (m_deleted || m_objectStore.isDeleted()) + return Exception { IDBDatabaseException::InvalidStateError, ASCIILiteral("Failed to execute 'getAllKeys' on 'IDBIndex': The index or its object store has been deleted.") }; + + if (!m_objectStore.transaction().isActive()) + return Exception { IDBDatabaseException::TransactionInactiveError, ASCIILiteral("Failed to execute 'getAllKeys' on 'IDBIndex': The transaction is inactive or finished.") }; + + return m_objectStore.transaction().requestGetAllIndexRecords(execState, *this, range.get(), IndexedDB::GetAllType::Keys, count); +} + +ExceptionOr<Ref<IDBRequest>> IDBIndex::getAllKeys(ExecState& execState, JSValue key, std::optional<uint32_t> count) +{ + auto onlyResult = IDBKeyRange::only(execState, key); + if (onlyResult.hasException()) + return Exception { IDBDatabaseException::DataError, ASCIILiteral("Failed to execute 'getAllKeys' on 'IDBIndex': The parameter is not a valid key.") }; + + return getAllKeys(execState, onlyResult.releaseReturnValue(), count); +} + +void IDBIndex::markAsDeleted() +{ + ASSERT(currentThread() == m_objectStore.transaction().database().originThreadID()); + + ASSERT(!m_deleted); + m_deleted = true; +} + +void IDBIndex::ref() +{ + m_objectStore.ref(); } -IDBDatabaseBackend* IDBIndex::backendDB() const +void IDBIndex::deref() { - return m_transaction->backendDB(); + m_objectStore.deref(); } } // namespace WebCore |