IDBIndex* IDBObjectStore::createIndex(ScriptState* scriptState, const String& name, const IDBKeyPath& keyPath, const IDBIndexParameters& options, ExceptionState& exceptionState) { IDB_TRACE("IDBObjectStore::createIndex"); if (!m_transaction->isVersionChange()) { exceptionState.throwDOMException(InvalidStateError, IDBDatabase::notVersionChangeTransactionErrorMessage); return nullptr; } if (isDeleted()) { exceptionState.throwDOMException(InvalidStateError, IDBDatabase::objectStoreDeletedErrorMessage); 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 (!keyPath.isValid()) { exceptionState.throwDOMException(SyntaxError, "The keyPath argument contains an invalid key path."); return nullptr; } if (containsIndex(name)) { exceptionState.throwDOMException(ConstraintError, "An index with the specified name already exists."); return nullptr; } if (keyPath.type() == IDBKeyPath::ArrayType && options.multiEntry()) { exceptionState.throwDOMException(InvalidAccessError, "The keyPath argument was an array and the multiEntry option is true."); return nullptr; } if (!backendDB()) { exceptionState.throwDOMException(InvalidStateError, IDBDatabase::databaseClosedErrorMessage); return nullptr; } int64_t indexId = m_metadata.maxIndexId + 1; backendDB()->createIndex(m_transaction->id(), id(), indexId, name, keyPath, options.unique(), options.multiEntry()); ++m_metadata.maxIndexId; IDBIndexMetadata metadata(name, indexId, keyPath, options.unique(), options.multiEntry()); IDBIndex* index = IDBIndex::create(metadata, this, m_transaction.get()); m_indexMap.set(name, index); m_metadata.indexes.set(indexId, metadata); m_transaction->db()->indexCreated(id(), metadata); ASSERT(!exceptionState.hadException()); if (exceptionState.hadException()) return nullptr; IDBRequest* indexRequest = openCursor(scriptState, nullptr, WebIDBCursorDirectionNext, WebIDBTaskTypePreemptive); indexRequest->preventPropagation(); // This is kept alive by being the success handler of the request, which is in turn kept alive by the owning transaction. RefPtrWillBeRawPtr<IndexPopulator> indexPopulator = IndexPopulator::create(scriptState, transaction()->db(), m_transaction->id(), id(), metadata); indexRequest->setOnsuccess(indexPopulator); return index; }
void setJSIDBRequestOnsuccess(ExecState* exec, JSObject* thisObject, JSValue value) { UNUSED_PARAM(exec); JSIDBRequest* castedThis = static_cast<JSIDBRequest*>(thisObject); IDBRequest* imp = static_cast<IDBRequest*>(castedThis->impl()); imp->setOnsuccess(createJSAttributeEventListener(exec, value, thisObject)); }