IDBRequest* IDBCursor::update(ScriptState* scriptState, const ScriptValue& value, ExceptionState& exceptionState) { IDB_TRACE("IDBCursor::update"); if (!m_gotValue) { exceptionState.throwDOMException(InvalidStateError, IDBDatabase::noValueErrorMessage); return nullptr; } if (isKeyCursor()) { exceptionState.throwDOMException(InvalidStateError, IDBDatabase::isKeyCursorErrorMessage); return nullptr; } if (isDeleted()) { exceptionState.throwDOMException(InvalidStateError, IDBDatabase::sourceDeletedErrorMessage); return nullptr; } if (m_transaction->isFinished() || m_transaction->isFinishing()) { exceptionState.throwDOMException(TransactionInactiveError, IDBDatabase::transactionFinishedErrorMessage); return nullptr; } if (!m_transaction->isActive()) { exceptionState.throwDOMException(TransactionInactiveError, IDBDatabase::transactionInactiveErrorMessage); return nullptr; } if (m_transaction->isReadOnly()) { exceptionState.throwDOMException(ReadOnlyError, "The record may not be updated inside a read-only transaction."); return nullptr; } IDBObjectStore* objectStore = effectiveObjectStore(); return objectStore->put(scriptState, WebIDBPutModeCursorUpdate, IDBAny::create(this), value, m_primaryKey, exceptionState); }
PassRefPtr<IDBRequest> IDBCursor::update(ScriptExecutionContext* context, ScriptValue& value, ExceptionCode& ec) { IDB_TRACE("IDBCursor::update"); if (!m_gotValue || isKeyCursor()) { ec = IDBDatabaseException::IDB_INVALID_STATE_ERR; return 0; } if (!m_transaction->isActive()) { ec = IDBDatabaseException::TRANSACTION_INACTIVE_ERR; return 0; } if (m_transaction->isReadOnly()) { ec = IDBDatabaseException::READ_ONLY_ERR; return 0; } RefPtr<IDBObjectStore> objectStore = effectiveObjectStore(); const IDBKeyPath& keyPath = objectStore->metadata().keyPath; const bool usesInLineKeys = !keyPath.isNull(); if (usesInLineKeys) { RefPtr<IDBKey> keyPathKey = createIDBKeyFromScriptValueAndKeyPath(value, keyPath); if (!keyPathKey || !keyPathKey->isEqual(m_currentPrimaryKey.get())) { ec = IDBDatabaseException::DATA_ERR; return 0; } } return objectStore->put(IDBObjectStoreBackendInterface::CursorUpdate, IDBAny::create(this), context, value, m_currentPrimaryKey, ec); }
void IDBCursor::setValueReady(PassRefPtr<IDBKey> key, PassRefPtr<IDBKey> primaryKey, PassRefPtr<SerializedScriptValue> prpValue) { m_currentKey = key; m_currentPrimaryKey = primaryKey; RefPtr<SerializedScriptValue> value = prpValue; if (!isKeyCursor()) { RefPtr<IDBObjectStore> objectStore = effectiveObjectStore(); const IDBObjectStoreMetadata metadata = objectStore->metadata(); if (metadata.autoIncrement && !metadata.keyPath.isNull()) { #ifndef NDEBUG RefPtr<IDBKey> expectedKey = createIDBKeyFromSerializedValueAndKeyPath(value, metadata.keyPath); ASSERT(!expectedKey || expectedKey->isEqual(m_currentPrimaryKey.get())); #endif RefPtr<SerializedScriptValue> valueAfterInjection = injectIDBKeyIntoSerializedValue(m_currentPrimaryKey, value, metadata.keyPath); ASSERT(valueAfterInjection); // FIXME: There is no way to report errors here. Move this into onSuccessWithContinuation so that we can abort the transaction there. See: https://bugs.webkit.org/show_bug.cgi?id=92278 if (valueAfterInjection) value = valueAfterInjection; } } m_currentValue = IDBAny::create(value.release()); m_gotValue = true; m_valueIsDirty = true; }
PassRefPtr<IDBRequest> IDBCursor::update(ScriptState* state, ScriptValue& value, ExceptionCode& ec) { IDB_TRACE("IDBCursor::update"); if (!m_gotValue || isKeyCursor()) { ec = IDBDatabaseException::InvalidStateError; return 0; } if (!m_transaction->isActive()) { ec = IDBDatabaseException::TransactionInactiveError; return 0; } if (m_transaction->isReadOnly()) { ec = IDBDatabaseException::ReadOnlyError; return 0; } RefPtr<IDBObjectStore> objectStore = effectiveObjectStore(); const IDBKeyPath& keyPath = objectStore->metadata().keyPath; const bool usesInLineKeys = !keyPath.isNull(); if (usesInLineKeys) { RefPtr<IDBKey> keyPathKey = createIDBKeyFromScriptValueAndKeyPath(m_request->requestState(), value, keyPath); if (!keyPathKey || !keyPathKey->isEqual(m_currentPrimaryKey.get())) { ec = IDBDatabaseException::DataError; return 0; } } return objectStore->put(IDBDatabaseBackendInterface::CursorUpdate, IDBAny::create(this), state, value, m_currentPrimaryKey, ec); }
RefPtr<WebCore::IDBRequest> IDBCursor::update(JSC::ExecState& exec, Deprecated::ScriptValue& value, ExceptionCode& ec) { LOG(IndexedDB, "IDBCursor::update"); if (sourcesDeleted()) { ec = IDBDatabaseException::InvalidStateError; return nullptr; } if (!transaction().isActive()) { ec = IDBDatabaseException::TransactionInactiveError; return nullptr; } if (transaction().isReadOnly()) { ec = IDBDatabaseException::ReadOnlyError; return nullptr; } if (!m_gotValue) { ec = IDBDatabaseException::InvalidStateError; return nullptr; } if (isKeyCursor()) { ec = IDBDatabaseException::InvalidStateError; return nullptr; } return effectiveObjectStore().put(exec, value.jsValue(), m_deprecatedCurrentPrimaryKey.jsValue(), ec); }
void IDBCursor::setValueReady(DOMRequestState* state, PassRefPtr<IDBKey> key, PassRefPtr<IDBKey> primaryKey, ScriptValue& value) { m_currentKey = key; m_currentKeyValue = idbKeyToScriptValue(state, m_currentKey); m_currentPrimaryKey = primaryKey; m_currentPrimaryKeyValue = idbKeyToScriptValue(state, m_currentPrimaryKey); if (!isKeyCursor()) { RefPtr<IDBObjectStore> objectStore = effectiveObjectStore(); const IDBObjectStoreMetadata metadata = objectStore->metadata(); if (metadata.autoIncrement && !metadata.keyPath.isNull()) { #ifndef NDEBUG RefPtr<IDBKey> expectedKey = createIDBKeyFromScriptValueAndKeyPath(m_request->requestState(), value, metadata.keyPath); ASSERT(!expectedKey || expectedKey->isEqual(m_currentPrimaryKey.get())); #endif bool injected = injectIDBKeyIntoScriptValue(m_request->requestState(), m_currentPrimaryKey, value, metadata.keyPath); // FIXME: There is no way to report errors here. Move this into onSuccessWithContinuation so that we can abort the transaction there. See: https://bugs.webkit.org/show_bug.cgi?id=92278 ASSERT_UNUSED(injected, injected); } } m_currentValue = value; m_gotValue = true; }
void IDBCursor::setGetResult(IDBRequest& request, const IDBGetResult& getResult) { LOG(IndexedDB, "IDBCursor::setGetResult - current key %s", getResult.keyData().loggingString().utf8().data()); auto* context = request.scriptExecutionContext(); if (!context) return; if (!getResult.isDefined()) { m_deprecatedCurrentKey = { }; m_deprecatedCurrentPrimaryKey = { }; m_currentPrimaryKeyData = { }; m_deprecatedCurrentValue = { }; m_gotValue = false; return; } m_deprecatedCurrentKey = idbKeyDataToScriptValue(context, getResult.keyData()); m_deprecatedCurrentPrimaryKey = idbKeyDataToScriptValue(context, getResult.primaryKeyData()); m_currentPrimaryKeyData = getResult.primaryKeyData(); if (isKeyCursor()) m_deprecatedCurrentValue = { }; else m_deprecatedCurrentValue = deserializeIDBValueData(*context, getResult.valueBuffer()); m_gotValue = true; }
PassRefPtr<IDBRequest> IDBCursor::deleteFunction(ScriptExecutionContext* context, ExceptionCode& ec) { ec = 0; IDB_TRACE("IDBCursor::delete"); if (!m_transaction->isActive()) { ec = IDBDatabaseException::TransactionInactiveError; return 0; } if (m_transaction->isReadOnly()) { ec = IDBDatabaseException::ReadOnlyError; return 0; } if (!m_gotValue || isKeyCursor() || isDeleted()) { ec = IDBDatabaseException::InvalidStateError; return 0; } RefPtr<IDBKeyRange> keyRange = IDBKeyRange::only(m_currentPrimaryKey, ec); ASSERT(!ec); RefPtr<IDBRequest> request = IDBRequest::create(context, IDBAny::create(this), m_transaction.get()); m_transaction->backendDB()->deleteRange(m_transaction->id(), effectiveObjectStore()->id(), keyRange, request); return request.release(); }
RefPtr<WebCore::IDBRequest> IDBCursor::update(JSC::ExecState& exec, Deprecated::ScriptValue& value, ExceptionCodeWithMessage& ec) { LOG(IndexedDB, "IDBCursor::update"); if (sourcesDeleted()) { ec.code = IDBDatabaseException::InvalidStateError; return nullptr; } if (!transaction().isActive()) { ec.code = IDBDatabaseException::TransactionInactiveError; ec.message = ASCIILiteral("Failed to execute 'update' on 'IDBCursor': The transaction is inactive or finished."); return nullptr; } if (transaction().isReadOnly()) { ec.code = IDBDatabaseException::ReadOnlyError; ec.message = ASCIILiteral("Failed to execute 'update' on 'IDBCursor': The record may not be updated inside a read-only transaction."); return nullptr; } if (!m_gotValue) { ec.code = IDBDatabaseException::InvalidStateError; return nullptr; } if (isKeyCursor()) { ec.code = IDBDatabaseException::InvalidStateError; ec.message = ASCIILiteral("Failed to execute 'update' on 'IDBCursor': The cursor is a key cursor."); return nullptr; } auto& objectStore = effectiveObjectStore(); auto& keyPath = objectStore.info().keyPath(); const bool usesInLineKeys = !keyPath.isNull(); if (usesInLineKeys) { RefPtr<IDBKey> keyPathKey = maybeCreateIDBKeyFromScriptValueAndKeyPath(exec, value, keyPath); IDBKeyData keyPathKeyData(keyPathKey.get()); if (!keyPathKey || keyPathKeyData != m_currentPrimaryKeyData) { ec.code = IDBDatabaseException::DataError; ec.message = ASCIILiteral("Failed to execute 'update' on 'IDBCursor': The effective object store of this cursor uses in-line keys and evaluating the key path of the value parameter results in a different value than the cursor's effective key."); return nullptr; } } auto request = effectiveObjectStore().putForCursorUpdate(exec, value.jsValue(), m_deprecatedCurrentPrimaryKey.jsValue(), ec); if (ec.code) return nullptr; ASSERT(request); request->setSource(*this); return request; }
IDBRequest* IDBCursor::update(ScriptState* scriptState, ScriptValue& value, ExceptionState& exceptionState) { IDB_TRACE("IDBCursor::update"); if (!m_gotValue) { exceptionState.throwDOMException(InvalidStateError, IDBDatabase::noValueErrorMessage); return 0; } if (isKeyCursor()) { exceptionState.throwDOMException(InvalidStateError, IDBDatabase::isKeyCursorErrorMessage); return 0; } if (isDeleted()) { exceptionState.throwDOMException(InvalidStateError, IDBDatabase::sourceDeletedErrorMessage); return 0; } if (m_transaction->isFinished() || m_transaction->isFinishing()) { exceptionState.throwDOMException(TransactionInactiveError, IDBDatabase::transactionFinishedErrorMessage); return 0; } if (!m_transaction->isActive()) { exceptionState.throwDOMException(TransactionInactiveError, IDBDatabase::transactionInactiveErrorMessage); return 0; } if (m_transaction->isReadOnly()) { exceptionState.throwDOMException(ReadOnlyError, "The record may not be updated inside a read-only transaction."); return 0; } IDBObjectStore* objectStore = effectiveObjectStore(); const IDBKeyPath& keyPath = objectStore->metadata().keyPath; const bool usesInLineKeys = !keyPath.isNull(); if (usesInLineKeys) { IDBKey* keyPathKey = createIDBKeyFromScriptValueAndKeyPath(scriptState->isolate(), value, keyPath); if (!keyPathKey || !keyPathKey->isEqual(m_primaryKey.get())) { exceptionState.throwDOMException(DataError, "The effective object store of this cursor uses in-line keys and evaluating the key path of the value parameter results in a different value than the cursor's effective key."); return 0; } } return objectStore->put(scriptState, blink::WebIDBPutModeCursorUpdate, IDBAny::create(this), value, m_primaryKey, exceptionState); }
PassRefPtr<IDBRequest> IDBCursor::deleteFunction(ScriptExecutionContext* context, ExceptionCode& ec) { IDB_TRACE("IDBCursor::delete"); if (!m_transaction->isActive()) { ec = IDBDatabaseException::TRANSACTION_INACTIVE_ERR; return 0; } if (m_transaction->isReadOnly()) { ec = IDBDatabaseException::READ_ONLY_ERR; return 0; } if (!m_gotValue || isKeyCursor()) { ec = IDBDatabaseException::IDB_INVALID_STATE_ERR; return 0; } RefPtr<IDBRequest> request = IDBRequest::create(context, IDBAny::create(this), m_transaction.get()); m_backend->deleteFunction(request, ec); ASSERT(!ec); return request.release(); }
PassRefPtr<IDBRequest> IDBCursor::deleteFunction(ScriptExecutionContext* context, ExceptionCode& ec) { IDB_TRACE("IDBCursor::delete"); if (!m_transaction->isActive()) { ec = IDBDatabaseException::TransactionInactiveError; return 0; } if (m_transaction->isReadOnly()) { ec = IDBDatabaseException::ReadOnlyError; return 0; } if (!m_gotValue || isKeyCursor()) { ec = IDBDatabaseException::InvalidStateError; return 0; } RefPtr<IDBRequest> request = IDBRequest::create(context, IDBAny::create(this), m_transaction.get()); m_backend->deleteFunction(request, ec); ASSERT(!ec); return request.release(); }
IDBRequest* IDBCursor::deleteFunction(ScriptState* scriptState, ExceptionState& exceptionState) { IDB_TRACE("IDBCursor::delete"); if (m_transaction->isFinished() || m_transaction->isFinishing()) { exceptionState.throwDOMException(TransactionInactiveError, IDBDatabase::transactionFinishedErrorMessage); return nullptr; } if (!m_transaction->isActive()) { exceptionState.throwDOMException(TransactionInactiveError, IDBDatabase::transactionInactiveErrorMessage); return nullptr; } if (m_transaction->isReadOnly()) { exceptionState.throwDOMException(ReadOnlyError, "The record may not be deleted inside a read-only transaction."); return nullptr; } if (!m_gotValue) { exceptionState.throwDOMException(InvalidStateError, IDBDatabase::noValueErrorMessage); return nullptr; } if (isKeyCursor()) { exceptionState.throwDOMException(InvalidStateError, IDBDatabase::isKeyCursorErrorMessage); return nullptr; } if (isDeleted()) { exceptionState.throwDOMException(InvalidStateError, IDBDatabase::sourceDeletedErrorMessage); return nullptr; } if (!m_transaction->backendDB()) { exceptionState.throwDOMException(InvalidStateError, IDBDatabase::databaseClosedErrorMessage); return nullptr; } IDBKeyRange* keyRange = IDBKeyRange::only(m_primaryKey, exceptionState); ASSERT(!exceptionState.hadException()); IDBRequest* request = IDBRequest::create(scriptState, IDBAny::create(this), m_transaction.get()); m_transaction->backendDB()->deleteRange(m_transaction->id(), effectiveObjectStore()->id(), keyRange, WebIDBCallbacksImpl::create(request).leakPtr()); return request; }
RefPtr<WebCore::IDBRequest> IDBCursor::deleteFunction(ScriptExecutionContext* context, ExceptionCodeWithMessage& ec) { LOG(IndexedDB, "IDBCursor::deleteFunction"); if (!context) { ec.code = IDBDatabaseException::InvalidStateError; return nullptr; } if (sourcesDeleted()) { ec.code = IDBDatabaseException::InvalidStateError; return nullptr; } if (!transaction().isActive()) { ec.code = IDBDatabaseException::TransactionInactiveError; ec.message = ASCIILiteral("Failed to execute 'delete' on 'IDBCursor': The transaction is inactive or finished."); return nullptr; } if (transaction().isReadOnly()) { ec.code = IDBDatabaseException::ReadOnlyError; ec.message = ASCIILiteral("Failed to execute 'delete' on 'IDBCursor': The record may not be deleted inside a read-only transaction."); return nullptr; } if (!m_gotValue) { ec.code = IDBDatabaseException::InvalidStateError; return nullptr; } if (isKeyCursor()) { ec.code = IDBDatabaseException::InvalidStateError; ec.message = ASCIILiteral("Failed to execute 'delete' on 'IDBCursor': The cursor is a key cursor."); return nullptr; } return effectiveObjectStore().deleteFunction(context, m_deprecatedCurrentPrimaryKey.jsValue(), ec); }