IDBKeyData IndexValueStore::lowestKeyWithRecordInRange(const IDBKeyRangeData& range) const { LOG(IndexedDB, "IndexValueStore::lowestKeyWithRecordInRange - %s", range.loggingString().utf8().data()); if (range.isExactlyOneKey()) return m_records.contains(range.lowerKey) ? range.lowerKey : IDBKeyData(); auto iterator = lowestIteratorInRange(range); if (iterator == m_orderedKeys.end()) return { }; return *iterator; }
IDBKeyData MemoryObjectStore::lowestKeyWithRecordInRange(const IDBKeyRangeData& keyRangeData) const { if (!m_keyValueStore) return { }; if (keyRangeData.isExactlyOneKey() && m_keyValueStore->contains(keyRangeData.lowerKey)) return keyRangeData.lowerKey; ASSERT(m_orderedKeys); auto lowestInRange = m_orderedKeys->lower_bound(keyRangeData.lowerKey); if (lowestInRange == m_orderedKeys->end()) return { }; if (keyRangeData.lowerOpen && *lowestInRange == keyRangeData.lowerKey) ++lowestInRange; if (lowestInRange == m_orderedKeys->end()) return { }; if (!keyRangeData.upperKey.isNull()) { if (lowestInRange->compare(keyRangeData.upperKey) > 0) return { }; if (keyRangeData.upperOpen && *lowestInRange == keyRangeData.upperKey) return { }; } return *lowestInRange; }
RefPtr<IDBRequest> IDBObjectStore::doCount(ScriptExecutionContext& context, const IDBKeyRangeData& range, ExceptionCodeWithMessage& ec) { ASSERT(currentThread() == m_transaction->database().originThreadID()); // The IDB spec for several IDBObjectStore methods states that transaction related exceptions should fire before // the exception for an object store being deleted. // However, a handful of W3C IDB tests expect the deleted exception even though the transaction inactive exception also applies. // Additionally, Chrome and Edge agree with the test, as does Legacy IDB in WebKit. // Until this is sorted out, we'll agree with the test and the majority share browsers. if (m_deleted) { ec.code = IDBDatabaseException::InvalidStateError; ec.message = ASCIILiteral("Failed to execute 'count' on 'IDBObjectStore': The object store has been deleted."); return nullptr; } if (!m_transaction->isActive()) { ec.code = IDBDatabaseException::TransactionInactiveError; ec.message = ASCIILiteral("Failed to execute 'count' on 'IDBObjectStore': The transaction is inactive or finished."); return nullptr; } if (!range.isValid()) { ec.code = IDBDatabaseException::DataError; return nullptr; } return m_transaction->requestCount(context, *this, range); }
IDBGetResult MemoryIndex::getResultForKeyRange(IndexedDB::IndexRecordType type, const IDBKeyRangeData& range) const { LOG(IndexedDB, "MemoryIndex::getResultForKeyRange - %s", range.loggingString().utf8().data()); if (!m_records) return { }; IDBKeyData keyToLookFor; if (range.isExactlyOneKey()) keyToLookFor = range.lowerKey; else keyToLookFor = m_records->lowestKeyWithRecordInRange(range); if (keyToLookFor.isNull()) return { }; const IDBKeyData* keyValue = m_records->lowestValueForKey(keyToLookFor); if (!keyValue) return { }; return type == IndexedDB::IndexRecordType::Key ? IDBGetResult(*keyValue) : IDBGetResult(m_objectStore.valueForKeyRange(*keyValue)); }
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); }
RefPtr<WebCore::IDBRequest> IDBIndex::doCount(ScriptExecutionContext& context, const IDBKeyRangeData& range, ExceptionCodeWithMessage& ec) { if (m_deleted || m_objectStore->isDeleted()) { ec.code = IDBDatabaseException::InvalidStateError; ec.message = ASCIILiteral("Failed to execute 'count' on 'IDBIndex': The index or its object store has been deleted."); return nullptr; } if (!range.isValid()) { ec.code = IDBDatabaseException::DataError; return nullptr; } auto& transaction = m_objectStore->modernTransaction(); if (!transaction.isActive()) { ec.code = IDBDatabaseException::TransactionInactiveError; ec.message = ASCIILiteral("Failed to execute 'count' on 'IDBIndex': The transaction is inactive or finished."); return nullptr; } return transaction.requestCount(context, *this, range); }
void MemoryObjectStore::deleteRange(const IDBKeyRangeData& inputRange) { LOG(IndexedDB, "MemoryObjectStore::deleteRange"); ASSERT(m_writeTransaction); if (inputRange.isExactlyOneKey()) { deleteRecord(inputRange.lowerKey); return; } IDBKeyRangeData range = inputRange; while (true) { auto key = lowestKeyWithRecordInRange(range); if (key.isNull()) break; deleteRecord(key); range.lowerKey = key; range.lowerOpen = true; } }
CrossThreadCopierBase<false, false, IDBKeyRangeData>::Type CrossThreadCopierBase<false, false, IDBKeyRangeData>::copy(const IDBKeyRangeData& keyRangeData) { return keyRangeData.isolatedCopy(); }