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.getType() == 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_createdIndexes.add(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. IndexPopulator* indexPopulator = IndexPopulator::create(scriptState, transaction()->db(), m_transaction->id(), id(), metadata); indexRequest->setOnsuccess(indexPopulator); return index; }
IDBResourceIdentifier::IDBResourceIdentifier(const IDBClient::IDBConnectionProxy& connectionProxy, const IDBRequest& request) : m_idbConnectionIdentifier(connectionProxy.serverConnectionIdentifier()) , m_resourceNumber(request.resourceIdentifier().m_resourceNumber) { }
IDBResourceIdentifier::IDBResourceIdentifier(const IDBClient::IDBConnectionToServer& connection, const IDBRequest& request) : m_idbConnectionIdentifier(connection.identifier()) , m_resourceNumber(request.resourceIdentifier().m_resourceNumber) { }