PassRefPtr<IDBTransaction> IDBDatabase::transaction(ExecutionContext* context, const Vector<String>& scope, const String& modeString, ExceptionState& exceptionState) { IDB_TRACE("IDBDatabase::transaction"); blink::Platform::current()->histogramEnumeration("WebCore.IndexedDB.FrontEndAPICalls", IDBTransactionCall, IDBMethodsMax); if (!scope.size()) { exceptionState.throwDOMException(InvalidAccessError, "The storeNames parameter was empty."); return 0; } IndexedDB::TransactionMode mode = IDBTransaction::stringToMode(modeString, exceptionState); if (exceptionState.hadException()) return 0; if (m_versionChangeTransaction) { exceptionState.throwDOMException(InvalidStateError, "A version change transaction is running."); return 0; } if (m_closePending) { exceptionState.throwDOMException(InvalidStateError, "The database connection is closing."); return 0; } Vector<int64_t> objectStoreIds; for (size_t i = 0; i < scope.size(); ++i) { int64_t objectStoreId = findObjectStoreId(scope[i]); if (objectStoreId == IDBObjectStoreMetadata::InvalidId) { exceptionState.throwDOMException(NotFoundError, "One of the specified object stores was not found."); return 0; } objectStoreIds.append(objectStoreId); } int64_t transactionId = nextTransactionId(); m_backend->createTransaction(transactionId, WebIDBDatabaseCallbacksImpl::create(m_databaseCallbacks).leakPtr(), objectStoreIds, mode); RefPtr<IDBTransaction> transaction = IDBTransaction::create(context, transactionId, scope, mode, this); return transaction.release(); }
void IDBObjectStore::deleteIndex(const String& name, ExceptionState& exceptionState) { IDB_TRACE("IDBObjectStore::deleteIndex"); if (!m_transaction->isVersionChange()) { exceptionState.throwDOMException(InvalidStateError, IDBDatabase::notVersionChangeTransactionErrorMessage); return; } if (isDeleted()) { exceptionState.throwDOMException(InvalidStateError, IDBDatabase::objectStoreDeletedErrorMessage); return; } if (m_transaction->isFinished() || m_transaction->isFinishing()) { exceptionState.throwDOMException(TransactionInactiveError, IDBDatabase::transactionFinishedErrorMessage); return; } if (!m_transaction->isActive()) { exceptionState.throwDOMException(TransactionInactiveError, IDBDatabase::transactionInactiveErrorMessage); return; } int64_t indexId = findIndexId(name); if (indexId == IDBIndexMetadata::InvalidId) { exceptionState.throwDOMException(NotFoundError, IDBDatabase::noSuchIndexErrorMessage); return; } if (!backendDB()) { exceptionState.throwDOMException(InvalidStateError, IDBDatabase::databaseClosedErrorMessage); return; } backendDB()->deleteIndex(m_transaction->id(), id(), indexId); m_metadata.indexes.remove(indexId); m_transaction->db()->indexDeleted(id(), indexId); IDBIndexMap::iterator it = m_indexMap.find(name); if (it != m_indexMap.end()) { it->value->markDeleted(); m_indexMap.remove(name); } }
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()) { 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(); }
void IDBTransaction::onAbort(PassRefPtrWillBeRawPtr<DOMError> prpError) { IDB_TRACE("IDBTransaction::onAbort"); if (m_contextStopped) { m_database->transactionFinished(this); return; } RefPtrWillBeRawPtr<DOMError> error = prpError; ASSERT(m_state != Finished); if (m_state != Finishing) { ASSERT(error.get()); setError(error.release()); // Abort was not triggered by front-end, so outstanding requests must // be aborted now. while (!m_requestList.isEmpty()) { IDBRequest* request = *m_requestList.begin(); m_requestList.remove(request); request->abort(); } m_state = Finishing; } if (isVersionChange()) { for (IDBObjectStoreMetadataMap::iterator it = m_objectStoreCleanupMap.begin(); it != m_objectStoreCleanupMap.end(); ++it) it->key->setMetadata(it->value); m_database->setMetadata(m_previousMetadata); m_database->close(); } m_objectStoreCleanupMap.clear(); // Enqueue events before notifying database, as database may close which enqueues more events and order matters. enqueueEvent(Event::createBubble(EventTypeNames::abort)); m_database->transactionFinished(this); }
void IDBCursorBackendImpl::continueFunction(PassRefPtr<IDBKey> prpKey, PassRefPtr<IDBCallbacks> prpCallbacks, ExceptionCode& ec) { IDB_TRACE("IDBCursorBackendImpl::continue"); RefPtr<IDBKey> key = prpKey; if (m_cursor && key) { ASSERT(m_cursor->key()); if (m_direction == IDBCursor::NEXT || m_direction == IDBCursor::NEXT_NO_DUPLICATE) { if (!m_cursor->key()->isLessThan(key.get())) { ec = IDBDatabaseException::DATA_ERR; return; } } else { if (!key->isLessThan(m_cursor->key().get())) { ec = IDBDatabaseException::DATA_ERR; return; } } } if (!m_transaction->scheduleTask(createCallbackTask(&IDBCursorBackendImpl::continueFunctionInternal, this, key, prpCallbacks))) ec = IDBDatabaseException::TRANSACTION_INACTIVE_ERR; }
void IDBCursor::advance(unsigned long count, ExceptionCode& ec) { ec = 0; IDB_TRACE("IDBCursor::advance"); if (!m_gotValue || isDeleted()) { ec = IDBDatabaseException::InvalidStateError; return; } if (!m_transaction->isActive()) { ec = IDBDatabaseException::TransactionInactiveError; return; } if (!count) { ec = TypeError; return; } m_request->setPendingCursor(this); m_gotValue = false; m_backend->advance(count, m_request); }
PassRefPtr<IDBKey> createIDBKeyFromScriptValueAndKeyPath(DOMRequestState*, const ScriptValue& value, const IDBKeyPath& keyPath) { IDB_TRACE("createIDBKeyFromScriptValueAndKeyPath"); ASSERT(!keyPath.isNull()); ASSERT(v8::Context::InContext()); v8::HandleScope handleScope; 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]); if (!key) return 0; result.append(key); } return IDBKey::createArray(result); } ASSERT(keyPath.type() == IDBKeyPath::StringType); return createIDBKeyFromScriptValueAndKeyPath(value, keyPath.string()); }
void IDBDatabase::deleteObjectStore(const String& name, ExceptionCode& ec) { IDB_TRACE("IDBDatabase::deleteObjectStore"); HistogramSupport::histogramEnumeration("WebCore.IndexedDB.FrontEndAPICalls", IDBDeleteObjectStoreCall, IDBMethodsMax); if (!m_versionChangeTransaction) { ec = IDBDatabaseException::InvalidStateError; return; } if (!m_versionChangeTransaction->isActive()) { ec = IDBDatabaseException::TransactionInactiveError; return; } int64_t objectStoreId = findObjectStoreId(name); if (objectStoreId == IDBObjectStoreMetadata::InvalidId) { ec = IDBDatabaseException::NotFoundError; return; } m_backend->deleteObjectStore(m_versionChangeTransaction->id(), objectStoreId); m_versionChangeTransaction->objectStoreDeleted(name); m_metadata.objectStores.remove(objectStoreId); }
PassRefPtr<IDBRequest> IDBCursor::update(ScriptExecutionContext* context, PassRefPtr<SerializedScriptValue> prpValue, ExceptionCode& ec) { IDB_TRACE("IDBCursor::update"); if (!m_gotValue) { ec = INVALID_STATE_ERR; return 0; } RefPtr<SerializedScriptValue> value = prpValue; if (value->blobURLs().size() > 0) { // FIXME: Add Blob/File/FileList support ec = DATA_CLONE_ERR; return 0; } RefPtr<IDBRequest> request = IDBRequest::create(context, IDBAny::create(this), m_transaction.get()); m_backend->update(value, request, ec); if (ec) { request->markEarlyDeath(); return 0; } return request.release(); }
bool IDBTransaction::dispatchEvent(PassRefPtrWillBeRawPtr<Event> event) { IDB_TRACE("IDBTransaction::dispatchEvent"); if (m_contextStopped || !executionContext()) { m_state = Finished; return false; } ASSERT(m_state != Finished); ASSERT(m_hasPendingActivity); ASSERT(executionContext()); ASSERT(event->target() == this); m_state = Finished; // Break reference cycles. for (IDBObjectStoreMap::iterator it = m_objectStoreMap.begin(); it != m_objectStoreMap.end(); ++it) it->value->transactionFinished(); m_objectStoreMap.clear(); for (IDBObjectStoreSet::iterator it = m_deletedObjectStores.begin(); it != m_deletedObjectStores.end(); ++it) (*it)->transactionFinished(); m_deletedObjectStores.clear(); WillBeHeapVector<RefPtrWillBeMember<EventTarget>> targets; targets.append(this); targets.append(db()); // FIXME: When we allow custom event dispatching, this will probably need to change. ASSERT(event->type() == EventTypeNames::complete || event->type() == EventTypeNames::abort); bool returnValue = IDBEventDispatcher::dispatch(event.get(), targets); // FIXME: Try to construct a test where |this| outlives openDBRequest and we // get a crash. if (m_openDBRequest) { ASSERT(isVersionChange()); m_openDBRequest->transactionDidFinishAndDispatch(); } m_hasPendingActivity = false; return returnValue; }
void IDBTransactionBackendImpl::commit() { IDB_TRACE("IDBTransactionBackendImpl::commit"); // The last reference to this object may be released while performing the // commit steps below. We therefore take a self reference to keep ourselves // alive while executing this method. RefPtr<IDBTransactionBackendImpl> self(this); ASSERT(m_state == Unused || m_state == Running); ASSERT(isTaskQueueEmpty()); bool unused = m_state == Unused; m_state = Finished; bool committed = unused || m_transaction->commit(); // Backing store resources (held via cursors) must be released before script callbacks // are fired, as the script callbacks may release references and allow the backing store // itself to be released, and order is critical. closeOpenCursors(); m_transaction = 0; // Transactions must also be marked as completed before the front-end is notified, as // the transaction completion unblocks operations like closing connections. if (!unused) m_database->transactionCoordinator()->didFinishTransaction(this); m_database->transactionFinished(this); if (committed) { m_callbacks->onComplete(); m_database->transactionFinishedAndCompleteFired(this); } else { m_callbacks->onAbort(); m_database->transactionFinishedAndAbortFired(this); } m_database = 0; }
void IDBRequest::onSuccess(PassRefPtr<IDBCursorBackendInterface> backend, PassRefPtr<IDBKey> key, PassRefPtr<IDBKey> primaryKey, PassRefPtr<SharedBuffer> buffer) { IDB_TRACE("IDBRequest::onSuccess(IDBCursor)"); if (!shouldEnqueueEvent()) return; DOMRequestState::Scope scope(m_requestState); ScriptValue value = deserializeIDBValueBuffer(requestState(), buffer); ASSERT(!m_pendingCursor); RefPtr<IDBCursor> cursor; switch (m_cursorType) { case IndexedDB::CursorKeyOnly: cursor = IDBCursor::create(backend, m_cursorDirection, this, m_source.get(), m_transaction.get()); break; case IndexedDB::CursorKeyAndValue: cursor = IDBCursorWithValue::create(backend, m_cursorDirection, this, m_source.get(), m_transaction.get()); break; default: ASSERT_NOT_REACHED(); } setResultCursor(cursor, key, primaryKey, value); enqueueEvent(createSuccessEvent()); }
void IDBCursor::advance(long long count, ExceptionCode& ec) { IDB_TRACE("IDBCursor::advance"); if (!m_gotValue) { ec = IDBDatabaseException::IDB_INVALID_STATE_ERR; return; } if (!m_transaction->isActive()) { ec = IDBDatabaseException::TRANSACTION_INACTIVE_ERR; return; } // FIXME: This should only need to check for 0 once webkit.org/b/96798 lands. if (count < 1 || count > UINT_MAX) { ec = NATIVE_TYPE_ERR; return; } m_request->setPendingCursor(this); m_gotValue = false; m_backend->advance(count, m_request, ec); ASSERT(!ec); }
PassRefPtr<IDBRequest> IDBIndex::count(ExecutionContext* context, const ScriptValue& range, ExceptionState& exceptionState) { IDB_TRACE("IDBIndex::count"); if (isDeleted()) { exceptionState.throwDOMException(InvalidStateError, IDBDatabase::indexDeletedErrorMessage); return 0; } if (m_transaction->isFinished()) { exceptionState.throwDOMException(TransactionInactiveError, IDBDatabase::transactionFinishedErrorMessage); return 0; } if (!m_transaction->isActive()) { exceptionState.throwDOMException(TransactionInactiveError, IDBDatabase::transactionInactiveErrorMessage); return 0; } RefPtr<IDBKeyRange> keyRange = IDBKeyRange::fromScriptValue(context, range, exceptionState); if (exceptionState.hadException()) return 0; RefPtr<IDBRequest> request = IDBRequest::create(context, IDBAny::create(this), m_transaction.get()); backendDB()->count(m_transaction->id(), m_objectStore->id(), m_metadata.id, keyRange.release(), WebIDBCallbacksImpl::create(request).leakPtr()); return request; }
bool injectV8KeyIntoV8Value(v8::Handle<v8::Value> key, v8::Handle<v8::Value> value, const IDBKeyPath& keyPath, v8::Isolate* isolate) { IDB_TRACE("injectIDBV8KeyIntoV8Value"); ASSERT(isolate->InContext()); ASSERT(keyPath.type() == IDBKeyPath::StringType); Vector<String> keyPathElements; IDBKeyPathParseError error; IDBParseKeyPath(keyPath.string(), keyPathElements, error); ASSERT(error == IDBKeyPathParseErrorNone); if (!keyPathElements.size()) return false; v8::HandleScope handleScope(isolate); v8::Handle<v8::Value> parent(ensureNthValueOnKeyPath(value, keyPathElements, keyPathElements.size() - 1, isolate)); if (parent.IsEmpty()) return false; if (!set(parent, keyPathElements.last(), key, isolate)) return false; return true; }
PassRefPtr<IDBIndex> IDBObjectStore::index(const String& name, ExceptionCode& ec) { IDB_TRACE("IDBObjectStore::index"); if (isDeleted()) { ec = IDBDatabaseException::InvalidStateError; return 0; } if (m_transaction->isFinished()) { ec = IDBDatabaseException::InvalidStateError; return 0; } IDBIndexMap::iterator it = m_indexMap.find(name); if (it != m_indexMap.end()) return it->value; int64_t indexId = findIndexId(name); if (indexId == IDBIndexMetadata::InvalidId) { ec = IDBDatabaseException::NotFoundError; return 0; } const IDBIndexMetadata* indexMetadata(0); for (IDBObjectStoreMetadata::IndexMap::const_iterator it = m_metadata.indexes.begin(); it != m_metadata.indexes.end(); ++it) { if (it->value.name == name) { indexMetadata = &it->value; break; } } ASSERT(indexMetadata); ASSERT(indexMetadata->id != IDBIndexMetadata::InvalidId); RefPtr<IDBIndex> index = IDBIndex::create(*indexMetadata, this, m_transaction.get()); m_indexMap.set(name, index); return index.release(); }
void IDBTransaction::onAbort(PassRefPtr<DOMError> prpError) { IDB_TRACE("IDBTransaction::onAbort"); RefPtr<DOMError> error = prpError; ASSERT(m_state != Finished); if (m_state != Finishing) { ASSERT(error.get()); setError(error.release()); // Abort was not triggered by front-end, so outstanding requests must // be aborted now. while (!m_requestList.isEmpty()) { RefPtr<IDBRequest> request = *m_requestList.begin(); m_requestList.remove(request); request->abort(); } m_state = Finishing; } if (isVersionChange()) { for (IDBObjectStoreMetadataMap::iterator it = m_objectStoreCleanupMap.begin(); it != m_objectStoreCleanupMap.end(); ++it) it->key->setMetadata(it->value); m_database->setMetadata(m_previousMetadata); m_database->close(); } m_objectStoreCleanupMap.clear(); closeOpenCursors(); // Enqueue events before notifying database, as database may close which enqueues more events and order matters. enqueueEvent(Event::create(eventNames().abortEvent, true, false)); // If script has stopped and GC has completed, database may have last reference to this object. RefPtr<IDBTransaction> protect(this); m_database->transactionFinished(this); }
PassRefPtr<IDBRequest> IDBCursor::update(ScriptExecutionContext* context, PassRefPtr<SerializedScriptValue> prpValue, ExceptionCode& ec) { IDB_TRACE("IDBCursor::update"); RefPtr<SerializedScriptValue> value = prpValue; 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; } if (value->blobURLs().size() > 0) { // FIXME: Add Blob/File/FileList support ec = IDBDatabaseException::IDB_DATA_CLONE_ERR; return 0; } RefPtr<IDBObjectStore> objectStore = effectiveObjectStore(); const IDBKeyPath& keyPath = objectStore->metadata().keyPath; const bool usesInLineKeys = !keyPath.isNull(); if (usesInLineKeys) { RefPtr<IDBKey> keyPathKey = createIDBKeyFromSerializedValueAndKeyPath(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); }
PassRefPtr<SerializedScriptValue> injectIDBKeyIntoSerializedValue(PassRefPtr<IDBKey> key, PassRefPtr<SerializedScriptValue> value, const IDBKeyPath& keyPath) { IDB_TRACE("injectIDBKeyIntoSerializedValue"); ASSERT(keyPath.type() == IDBKeyPath::StringType); Vector<String> keyPathElements; IDBKeyPathParseError error; IDBParseKeyPath(keyPath.string(), keyPathElements, error); ASSERT(error == IDBKeyPathParseErrorNone); if (!keyPathElements.size()) return 0; V8AuxiliaryContext context; v8::Handle<v8::Value> v8Value(value->deserialize()); v8::Handle<v8::Value> parent(ensureNthValueOnKeyPath(v8Value, keyPathElements, keyPathElements.size() - 1)); if (parent.IsEmpty()) return 0; if (!set(parent, keyPathElements.last(), toV8(key.get()))) return 0; return SerializedScriptValue::create(v8Value); }
void IDBRequest::onSuccess(PassRefPtr<IDBTransactionBackendInterface> prpBackend) { IDB_TRACE("IDBRequest::onSuccess(IDBTransaction)"); RefPtr<IDBTransactionBackendInterface> backend = prpBackend; if (m_contextStopped || !scriptExecutionContext()) { // Should only be null in tests. if (backend.get()) backend->abort(); return; } if (!shouldEnqueueEvent()) return; RefPtr<IDBTransaction> frontend = IDBTransaction::create(scriptExecutionContext(), backend, IDBTransaction::VERSION_CHANGE, m_source->idbDatabase().get()); backend->setCallbacks(frontend.get()); m_transaction = frontend; ASSERT(m_source->type() == IDBAny::IDBDatabaseType); ASSERT(m_transaction->isVersionChange()); m_result = IDBAny::create(frontend.release()); enqueueEvent(createSuccessEvent()); }
void IDBCursor::advance(long long count, ExceptionCode& ec) { IDB_TRACE("IDBCursor::advance"); if (!m_gotValue) { ec = IDBDatabaseException::InvalidStateError; return; } if (!m_transaction->isActive()) { ec = IDBDatabaseException::TransactionInactiveError; return; } // FIXME: This should only need to check for 0 once webkit.org/b/96798 lands. if (count < 1 || count > UINT_MAX) { ec = TypeError; return; } m_request->setPendingCursor(this); m_gotValue = false; m_backend->advance(count, m_request, ec); ASSERT(!ec); }
IDBRequest* IDBObjectStore::deleteFunction(ScriptState* scriptState, const ScriptValue& key, ExceptionState& exceptionState) { IDB_TRACE("IDBObjectStore::delete"); 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 (m_transaction->isReadOnly()) { exceptionState.throwDOMException(ReadOnlyError, IDBDatabase::transactionReadOnlyErrorMessage); return nullptr; } IDBKeyRange* keyRange = IDBKeyRange::fromScriptValue(scriptState->executionContext(), key, exceptionState); if (exceptionState.hadException()) return nullptr; if (!keyRange) { exceptionState.throwDOMException(DataError, IDBDatabase::noKeyOrKeyRangeErrorMessage); return nullptr; } if (!backendDB()) { exceptionState.throwDOMException(InvalidStateError, IDBDatabase::databaseClosedErrorMessage); return nullptr; } IDBRequest* request = IDBRequest::create(scriptState, IDBAny::create(this), m_transaction.get()); backendDB()->deleteRange(m_transaction->id(), id(), keyRange, WebIDBCallbacksImpl::create(request).leakPtr()); return request; }
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) { 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); if (ec) { request->markEarlyDeath(); return 0; } return request.release(); }
IDBIndex* IDBObjectStore::index(const String& name, ExceptionState& exceptionState) { IDB_TRACE("IDBObjectStore::index"); if (isDeleted()) { exceptionState.throwDOMException(InvalidStateError, IDBDatabase::objectStoreDeletedErrorMessage); return nullptr; } if (m_transaction->isFinished() || m_transaction->isFinishing()) { exceptionState.throwDOMException(InvalidStateError, IDBDatabase::transactionFinishedErrorMessage); return nullptr; } IDBIndexMap::iterator it = m_indexMap.find(name); if (it != m_indexMap.end()) return it->value; int64_t indexId = findIndexId(name); if (indexId == IDBIndexMetadata::InvalidId) { exceptionState.throwDOMException(NotFoundError, IDBDatabase::noSuchIndexErrorMessage); return nullptr; } const IDBIndexMetadata* indexMetadata(nullptr); for (const auto& it : m_metadata.indexes) { if (it.value.name == name) { indexMetadata = &it.value; break; } } ASSERT(indexMetadata); ASSERT(indexMetadata->id != IDBIndexMetadata::InvalidId); IDBIndex* index = IDBIndex::create(*indexMetadata, this, m_transaction.get()); m_indexMap.set(name, index); return index; }
PassRefPtr<IDBRequest> IDBObjectStore::deleteFunction(ScriptExecutionContext* context, PassRefPtr<IDBKeyRange> keyRange, ExceptionCode& ec) { IDB_TRACE("IDBObjectStore::delete"); if (isDeleted()) { ec = IDBDatabaseException::InvalidStateError; return 0; } if (!m_transaction->isActive()) { ec = IDBDatabaseException::TransactionInactiveError; return 0; } if (m_transaction->isReadOnly()) { ec = IDBDatabaseException::ReadOnlyError; return 0; } if (!keyRange) { ec = IDBDatabaseException::DataError; return 0; } RefPtr<IDBRequest> request = IDBRequest::create(context, IDBAny::create(this), m_transaction.get()); backendDB()->deleteRange(m_transaction->id(), id(), keyRange, request); return request.release(); }
void IDBCursor::advance(unsigned long count, ExceptionCode& ec) { IDB_TRACE("IDBCursor::advance"); if (!m_gotValue) { ec = IDBDatabaseException::IDB_INVALID_STATE_ERR; return; } if (!m_transaction->isActive()) { ec = IDBDatabaseException::TRANSACTION_INACTIVE_ERR; return; } if (!count) { ec = NATIVE_TYPE_ERR; return; } m_request->setPendingCursor(this); m_gotValue = false; m_backend->advance(count, m_request, ec); if (ec) m_request->markEarlyDeath(); }
bool IDBObjectStore::autoIncrement() const { IDB_TRACE("IDBObjectStore::autoIncrement"); return m_backend->autoIncrement(); }
PassRefPtr<DOMStringList> IDBObjectStore::indexNames() const { IDB_TRACE("IDBObjectStore::indexNames"); return m_backend->indexNames(); }
IDBTransaction* IDBObjectStore::transaction() const { IDB_TRACE("IDBObjectStore::transaction"); return m_transaction.get(); }
PassRefPtr<IDBAny> IDBObjectStore::keyPath() const { IDB_TRACE("IDBObjectStore::keyPath"); return m_backend->keyPath(); }