void IDBRequest::onSuccess(PassRefPtr<SharedBuffer> valueBuffer, PassRefPtr<IDBKey> prpPrimaryKey, const IDBKeyPath& keyPath) { LOG(StorageAPI, "IDBRequest::onSuccess(SharedBuffer, IDBKey, IDBKeyPath)"); if (!shouldEnqueueEvent()) return; #ifndef NDEBUG ASSERT(keyPath == effectiveObjectStore(m_source)->keyPath()); #endif DOMRequestState::Scope scope(m_requestState); // FIXME: By not knowing whether or not the key is defined here, we don't know // if a null valueBuffer means the value is null or the value is undefined. Deprecated::ScriptValue value = deserializeIDBValueBuffer(requestState(), valueBuffer, true); RefPtr<IDBKey> primaryKey = prpPrimaryKey; if (!keyPath.isNull()) { #ifndef NDEBUG RefPtr<IDBKey> expectedKey = createIDBKeyFromScriptValueAndKeyPath(requestState()->exec(), value, keyPath); ASSERT(!expectedKey || expectedKey->isEqual(primaryKey.get())); #endif bool injected = injectIDBKeyIntoScriptValue(requestState(), primaryKey, value, keyPath); ASSERT_UNUSED(injected, injected); } onSuccessInternal(value); }
RefPtr<WebCore::IDBObjectStore> IDBDatabase::createObjectStore(const String& name, const IDBKeyPath& keyPath, bool autoIncrement, ExceptionCodeWithMessage& ec) { LOG(IndexedDB, "IDBDatabase::createObjectStore - (%s %s)", m_info.name().utf8().data(), name.utf8().data()); ASSERT(currentThread() == originThreadID()); ASSERT(!m_versionChangeTransaction || m_versionChangeTransaction->isVersionChange()); if (!m_versionChangeTransaction) { ec.code = IDBDatabaseException::InvalidStateError; ec.message = ASCIILiteral("Failed to execute 'createObjectStore' on 'IDBDatabase': The database is not running a version change transaction."); return nullptr; } if (!m_versionChangeTransaction->isActive()) { ec.code = IDBDatabaseException::TransactionInactiveError; return nullptr; } if (m_info.hasObjectStore(name)) { ec.code = IDBDatabaseException::ConstraintError; ec.message = ASCIILiteral("Failed to execute 'createObjectStore' on 'IDBDatabase': An object store with the specified name already exists."); return nullptr; } if (!keyPath.isNull() && !keyPath.isValid()) { ec.code = IDBDatabaseException::SyntaxError; ec.message = ASCIILiteral("Failed to execute 'createObjectStore' on 'IDBDatabase': The keyPath option is not a valid key path."); return nullptr; } if (autoIncrement && !keyPath.isNull()) { if ((keyPath.type() == IDBKeyPath::Type::String && keyPath.string().isEmpty()) || keyPath.type() == IDBKeyPath::Type::Array) { ec.code = IDBDatabaseException::InvalidAccessError; ec.message = ASCIILiteral("Failed to execute 'createObjectStore' on 'IDBDatabase': The autoIncrement option was set but the keyPath option was empty or an array."); return nullptr; } } // Install the new ObjectStore into the connection's metadata. IDBObjectStoreInfo info = m_info.createNewObjectStore(name, keyPath, autoIncrement); // Create the actual IDBObjectStore from the transaction, which also schedules the operation server side. Ref<IDBObjectStore> objectStore = m_versionChangeTransaction->createObjectStore(info); return adoptRef(&objectStore.leakRef()); }
PassRefPtr<IDBObjectStore> IDBDatabase::createObjectStore(const String& name, const Dictionary& options, ExceptionCode& ec) { if (!m_versionChangeTransaction) { ec = IDBDatabaseException::IDB_INVALID_STATE_ERR; return 0; } if (!m_versionChangeTransaction->isActive()) { ec = IDBDatabaseException::TRANSACTION_INACTIVE_ERR; return 0; } IDBKeyPath keyPath; if (!options.isUndefinedOrNull()) { String keyPathString; Vector<String> keyPathArray; if (options.get("keyPath", keyPathArray)) keyPath = IDBKeyPath(keyPathArray); else if (options.getWithUndefinedOrNullCheck("keyPath", keyPathString)) keyPath = IDBKeyPath(keyPathString); } if (containsObjectStore(name)) { ec = IDBDatabaseException::CONSTRAINT_ERR; return 0; } if (!keyPath.isNull() && !keyPath.isValid()) { ec = IDBDatabaseException::IDB_SYNTAX_ERR; return 0; } bool autoIncrement = false; if (!options.isUndefinedOrNull()) options.get("autoIncrement", autoIncrement); if (autoIncrement && ((keyPath.type() == IDBKeyPath::StringType && keyPath.string().isEmpty()) || keyPath.type() == IDBKeyPath::ArrayType)) { ec = IDBDatabaseException::IDB_INVALID_ACCESS_ERR; return 0; } int64_t objectStoreId = m_metadata.maxObjectStoreId + 1; RefPtr<IDBObjectStoreBackendInterface> objectStoreBackend = m_backend->createObjectStore(objectStoreId, name, keyPath, autoIncrement, m_versionChangeTransaction->backend(), ec); if (!objectStoreBackend) { ASSERT(ec); return 0; } IDBObjectStoreMetadata metadata(name, objectStoreId, keyPath, autoIncrement, IDBObjectStoreBackendInterface::MinimumIndexId); RefPtr<IDBObjectStore> objectStore = IDBObjectStore::create(metadata, objectStoreBackend.release(), m_versionChangeTransaction.get()); m_metadata.objectStores.set(metadata.id, metadata); ++m_metadata.maxObjectStoreId; m_versionChangeTransaction->objectStoreCreated(name, objectStore); return objectStore.release(); }
RefPtr<WebCore::IDBObjectStore> IDBDatabase::createObjectStore(const String& name, const IDBKeyPath& keyPath, bool autoIncrement, ExceptionCode& ec) { LOG(IndexedDB, "IDBDatabase::createObjectStore"); ASSERT(!m_versionChangeTransaction || m_versionChangeTransaction->isVersionChange()); if (!m_versionChangeTransaction) { ec = IDBDatabaseException::InvalidStateError; return nullptr; } if (!m_versionChangeTransaction->isActive()) { ec = IDBDatabaseException::TransactionInactiveError; return nullptr; } if (m_info.hasObjectStore(name)) { ec = IDBDatabaseException::ConstraintError; return nullptr; } if (!keyPath.isNull() && !keyPath.isValid()) { ec = IDBDatabaseException::SyntaxError; return nullptr; } if (autoIncrement && !keyPath.isNull()) { if ((keyPath.type() == IndexedDB::KeyPathType::String && keyPath.string().isEmpty()) || keyPath.type() == IndexedDB::KeyPathType::Array) { ec = IDBDatabaseException::InvalidAccessError; return nullptr; } } // Install the new ObjectStore into the connection's metadata. IDBObjectStoreInfo info = m_info.createNewObjectStore(name, keyPath, autoIncrement); // Create the actual IDBObjectStore from the transaction, which also schedules the operation server side. Ref<IDBObjectStore> objectStore = m_versionChangeTransaction->createObjectStore(info); return adoptRef(&objectStore.leakRef()); }
PassRefPtr<IDBObjectStore> IDBDatabase::createObjectStore(const String& name, const IDBKeyPath& keyPath, bool autoIncrement, ExceptionState& exceptionState) { IDB_TRACE("IDBDatabase::createObjectStore"); blink::Platform::current()->histogramEnumeration("WebCore.IndexedDB.FrontEndAPICalls", IDBCreateObjectStoreCall, IDBMethodsMax); if (!m_versionChangeTransaction) { exceptionState.throwDOMException(InvalidStateError, IDBDatabase::notVersionChangeTransactionErrorMessage); return nullptr; } if (m_versionChangeTransaction->isFinished()) { exceptionState.throwDOMException(TransactionInactiveError, IDBDatabase::transactionFinishedErrorMessage); return nullptr; } if (!m_versionChangeTransaction->isActive()) { exceptionState.throwDOMException(TransactionInactiveError, IDBDatabase::transactionInactiveErrorMessage); return nullptr; } if (containsObjectStore(name)) { exceptionState.throwDOMException(ConstraintError, "An object store with the specified name already exists."); return nullptr; } if (!keyPath.isNull() && !keyPath.isValid()) { exceptionState.throwDOMException(SyntaxError, "The keyPath option is not a valid key path."); return nullptr; } if (autoIncrement && ((keyPath.type() == IDBKeyPath::StringType && keyPath.string().isEmpty()) || keyPath.type() == IDBKeyPath::ArrayType)) { exceptionState.throwDOMException(InvalidAccessError, "The autoIncrement option was set but the keyPath option was empty or an array."); return nullptr; } int64_t objectStoreId = m_metadata.maxObjectStoreId + 1; m_backend->createObjectStore(m_versionChangeTransaction->id(), objectStoreId, name, keyPath, autoIncrement); IDBObjectStoreMetadata metadata(name, objectStoreId, keyPath, autoIncrement, WebIDBDatabase::minimumIndexId); RefPtr<IDBObjectStore> objectStore = IDBObjectStore::create(metadata, m_versionChangeTransaction.get()); m_metadata.objectStores.set(metadata.id, metadata); ++m_metadata.maxObjectStoreId; m_versionChangeTransaction->objectStoreCreated(name, objectStore); return objectStore.release(); }
RefPtr<IDBKey> maybeCreateIDBKeyFromScriptValueAndKeyPath(ExecState& exec, const Deprecated::ScriptValue& value, const IDBKeyPath& keyPath) { ASSERT(!keyPath.isNull()); if (keyPath.type() == IndexedDB::KeyPathType::Array) { Vector<RefPtr<IDBKey>> result; const Vector<String>& array = keyPath.array(); for (size_t i = 0; i < array.size(); i++) { RefPtr<IDBKey> key = internalCreateIDBKeyFromScriptValueAndKeyPath(&exec, value, array[i]); if (!key) return nullptr; result.append(key); } return IDBKey::createArray(result); } ASSERT(keyPath.type() == IndexedDB::KeyPathType::String); return internalCreateIDBKeyFromScriptValueAndKeyPath(&exec, value, keyPath.string()); }
RefPtr<IDBKey> maybeCreateIDBKeyFromScriptValueAndKeyPath(ExecState& exec, const JSC::JSValue& value, const IDBKeyPath& keyPath) { ASSERT(!keyPath.isNull()); if (keyPath.type() == IndexedDB::KeyPathType::Array) { const Vector<String>& array = keyPath.array(); Vector<RefPtr<IDBKey>> result; result.reserveInitialCapacity(array.size()); for (auto& string : array) { RefPtr<IDBKey> key = internalCreateIDBKeyFromScriptValueAndKeyPath(&exec, value, string); if (!key) return nullptr; result.uncheckedAppend(WTFMove(key)); } return IDBKey::createArray(WTFMove(result)); } ASSERT(keyPath.type() == IndexedDB::KeyPathType::String); return internalCreateIDBKeyFromScriptValueAndKeyPath(&exec, value, keyPath.string()); }
RefPtr<IDBKey> createIDBKeyFromScriptValueAndKeyPath(ExecState* exec, const Deprecated::ScriptValue& value, const IDBKeyPath& keyPath) { LOG(StorageAPI, "createIDBKeyFromScriptValueAndKeyPath"); ASSERT(!keyPath.isNull()); if (keyPath.type() == IDBKeyPath::ArrayType) { Vector<RefPtr<IDBKey>> result; const Vector<String>& array = keyPath.array(); for (size_t i = 0; i < array.size(); i++) { RefPtr<IDBKey> key = internalCreateIDBKeyFromScriptValueAndKeyPath(exec, value, array[i]); if (!key) return nullptr; result.append(key); } return IDBKey::createArray(result); } ASSERT(keyPath.type() == IDBKeyPath::StringType); return internalCreateIDBKeyFromScriptValueAndKeyPath(exec, value, keyPath.string()); }
PassRefPtr<IDBObjectStore> IDBDatabase::createObjectStore(const String& name, const IDBKeyPath& keyPath, bool autoIncrement, ExceptionCode& ec) { IDB_TRACE("IDBDatabase::createObjectStore"); HistogramSupport::histogramEnumeration("WebCore.IndexedDB.FrontEndAPICalls", IDBCreateObjectStoreCall, IDBMethodsMax); if (!m_versionChangeTransaction) { ec = IDBDatabaseException::InvalidStateError; return 0; } if (!m_versionChangeTransaction->isActive()) { ec = IDBDatabaseException::TransactionInactiveError; return 0; } if (containsObjectStore(name)) { ec = IDBDatabaseException::ConstraintError; return 0; } if (!keyPath.isNull() && !keyPath.isValid()) { ec = IDBDatabaseException::SyntaxError; return 0; } if (autoIncrement && ((keyPath.type() == IDBKeyPath::StringType && keyPath.string().isEmpty()) || keyPath.type() == IDBKeyPath::ArrayType)) { ec = IDBDatabaseException::InvalidAccessError; return 0; } int64_t objectStoreId = m_metadata.maxObjectStoreId + 1; m_backend->createObjectStore(m_versionChangeTransaction->id(), objectStoreId, name, keyPath, autoIncrement); IDBObjectStoreMetadata metadata(name, objectStoreId, keyPath, autoIncrement, IDBDatabaseBackendInterface::MinimumIndexId); RefPtr<IDBObjectStore> objectStore = IDBObjectStore::create(metadata, m_versionChangeTransaction.get()); m_metadata.objectStores.set(metadata.id, metadata); ++m_metadata.maxObjectStoreId; m_versionChangeTransaction->objectStoreCreated(name, objectStore); return objectStore.release(); }
PassRefPtr<IDBKey> createIDBKeyFromScriptValueAndKeyPath(DOMRequestState* state, const ScriptValue& value, const IDBKeyPath& keyPath) { IDB_TRACE("createIDBKeyFromScriptValueAndKeyPath"); ASSERT(!keyPath.isNull()); v8::Isolate* isolate = state ? state->context()->GetIsolate() : v8::Isolate::GetCurrent(); ASSERT(isolate->InContext()); v8::HandleScope handleScope(isolate); if (keyPath.type() == IDBKeyPath::ArrayType) { IDBKey::KeyArray result; const Vector<String>& array = keyPath.array(); for (size_t i = 0; i < array.size(); ++i) { RefPtr<IDBKey> key = createIDBKeyFromScriptValueAndKeyPath(value, array[i], isolate); if (!key) return 0; result.append(key); } return IDBKey::createArray(result); } ASSERT(keyPath.type() == IDBKeyPath::StringType); return createIDBKeyFromScriptValueAndKeyPath(value, keyPath.string(), isolate); }
PassRefPtr<IDBKey> createIDBKeyFromScriptValueAndKeyPath(DOMRequestState* requestState, const ScriptValue& value, const IDBKeyPath& keyPath) { IDB_TRACE("createIDBKeyFromScriptValueAndKeyPath"); ASSERT(!keyPath.isNull()); ExecState* exec = requestState->exec(); if (keyPath.type() == IDBKeyPath::ArrayType) { IDBKey::KeyArray result; const Vector<String>& array = keyPath.array(); for (size_t i = 0; i < array.size(); i++) { RefPtr<IDBKey> key = createIDBKeyFromScriptValueAndKeyPath(exec, value, array[i]); if (!key) return 0; result.append(key); } return IDBKey::createArray(result); } ASSERT(keyPath.type() == IDBKeyPath::StringType); return createIDBKeyFromScriptValueAndKeyPath(exec, value, keyPath.string()); }
PassRefPtr<IDBKey> createIDBKeyFromSerializedValueAndKeyPath(PassRefPtr<SerializedScriptValue> prpValue, const IDBKeyPath& keyPath) { IDB_TRACE("createIDBKeyFromSerializedValueAndKeyPath"); ASSERT(!keyPath.isNull()); RefPtr<SerializedScriptValue> value = prpValue; if (keyPath.type() == IDBKeyPath::ArrayType) { IDBKey::KeyArray result; const Vector<String>& array = keyPath.array(); for (size_t i = 0; i < array.size(); ++i) { RefPtr<IDBKey> key = createIDBKeyFromSerializedValueAndKeyPath(value, array[i]); if (!key) return 0; result.append(key); } return IDBKey::createArray(result); } ASSERT(keyPath.type() == IDBKeyPath::StringType); return createIDBKeyFromSerializedValueAndKeyPath(value, keyPath.string()); }
RefPtr<IDBObjectStore> LegacyDatabase::createObjectStore(const String& name, const IDBKeyPath& keyPath, bool autoIncrement, ExceptionCode& ec) { LOG(StorageAPI, "LegacyDatabase::createObjectStore"); if (!m_versionChangeTransaction) { ec = IDBDatabaseException::InvalidStateError; return 0; } if (!m_versionChangeTransaction->isActive()) { ec = IDBDatabaseException::TransactionInactiveError; return 0; } if (containsObjectStore(name)) { ec = IDBDatabaseException::ConstraintError; return 0; } if (!keyPath.isNull() && !keyPath.isValid()) { ec = IDBDatabaseException::SyntaxError; return 0; } if (autoIncrement && ((keyPath.type() == IDBKeyPath::StringType && keyPath.string().isEmpty()) || keyPath.type() == IDBKeyPath::ArrayType)) { ec = IDBDatabaseException::InvalidAccessError; return 0; } int64_t objectStoreId = m_metadata.maxObjectStoreId + 1; m_backend->createObjectStore(m_versionChangeTransaction->id(), objectStoreId, name, keyPath, autoIncrement); IDBObjectStoreMetadata metadata(name, objectStoreId, keyPath, autoIncrement, IDBDatabaseBackend::MinimumIndexId); RefPtr<LegacyObjectStore> objectStore = LegacyObjectStore::create(metadata, m_versionChangeTransaction.get()); m_metadata.objectStores.set(metadata.id, metadata); ++m_metadata.maxObjectStoreId; m_versionChangeTransaction->objectStoreCreated(name, objectStore); return objectStore.release(); }