WebKit Bugzilla
New
Browse
Search+
Log In
×
Sign in with GitHub
or
Remember my login
Create Account
·
Forgot Password
Forgotten password account recovery
[patch]
Patch
bug-89377-20120626100443.patch (text/plain), 33.87 KB, created by
Joshua Bell
on 2012-06-26 10:04:43 PDT
(
hide
)
Description:
Patch
Filename:
MIME Type:
Creator:
Joshua Bell
Created:
2012-06-26 10:04:43 PDT
Size:
33.87 KB
patch
obsolete
>Subversion Revision: 121191 >diff --git a/Source/WebCore/ChangeLog b/Source/WebCore/ChangeLog >index 093d2bdfa962abd842d6d26422cec76d53c64f8e..4bb93c623c1feb4abc1e579b7d7cffaa9d6c6ea0 100644 >--- a/Source/WebCore/ChangeLog >+++ b/Source/WebCore/ChangeLog >@@ -1,3 +1,77 @@ >+2012-06-22 Joshua Bell <jsbell@chromium.org> >+ >+ IndexedDB: Move method precondition checks to front end objects >+ https://bugs.webkit.org/show_bug.cgi?id=89377 >+ >+ Reviewed by NOBODY (OOPS!). >+ >+ Now that metadata exists on the front end, most of the pre-condition validation checks >+ done on IDB method calls from script can be moved to the front end which simplifies the >+ code significantly in the case of complex methods like IDBObjectStore::put(). >+ >+ Adds an internal "active" flag for transactions, although the behavior is not accurate >+ to the spec (it should only be true during event callbacks - http://webkit.org/b/89379). >+ The back-end methods can then be simplifed to just adding async tasks to the transaction, >+ and the front end methods can take care of all exception cases except for asynchronous >+ transaction abort which still requires plumbing back to the front end. >+ >+ No functional changes - no new tests. >+ >+ * Modules/indexeddb/IDBCursor.cpp: >+ (WebCore::IDBCursor::update): Migrate from IDBObjectStoreBackendImpl::put. >+ (WebCore::IDBCursor::advance): Add more explicit transaction-is-active check. >+ (WebCore::IDBCursor::continueFunction): Ditto. >+ (WebCore::IDBCursor::deleteFunction): Ditto. >+ (WebCore::IDBCursor::effectiveObjectStore): Convenience function (source may be store or index). >+ (WebCore): >+ * Modules/indexeddb/IDBCursor.h: >+ (WebCore::IDBCursor::isKeyCursor): Distinguish from IDBCursorWithValue. >+ (IDBCursor): >+ * Modules/indexeddb/IDBCursorBackendImpl.cpp: >+ (WebCore::IDBCursorBackendImpl::update): Remove migrated check. >+ * Modules/indexeddb/IDBCursorWithValue.h: >+ (IDBCursorWithValue): >+ * Modules/indexeddb/IDBDatabase.cpp: Migrate checks. >+ (WebCore::IDBDatabase::createObjectStore): >+ (WebCore::IDBDatabase::deleteObjectStore): >+ * Modules/indexeddb/IDBDatabaseBackendImpl.cpp: Replace checks with assertions. >+ (WebCore::IDBDatabaseBackendImpl::createObjectStore): >+ (WebCore::IDBDatabaseBackendImpl::deleteObjectStore): >+ * Modules/indexeddb/IDBIndex.cpp: Add transaction-is-active checks. >+ (WebCore::IDBIndex::openCursor): >+ (WebCore::IDBIndex::count): >+ (WebCore::IDBIndex::openKeyCursor): >+ (WebCore::IDBIndex::get): >+ (WebCore::IDBIndex::getKey): >+ * Modules/indexeddb/IDBObjectStore.cpp: Migrate cehcks. >+ (WebCore::IDBObjectStore::get): >+ (WebCore::IDBObjectStore::add): Delegates to put(PutMode) >+ (WebCore::IDBObjectStore::put): Delegates to put(PutMode) >+ (WebCore): Adds put(PutMode) which has the unified checks migrated from >+ IDBObjectStoreBackendImpl::put. >+ (WebCore::IDBObjectStore::deleteFunction): >+ (WebCore::IDBObjectStore::clear): >+ (WebCore::IDBObjectStore::createIndex): >+ (WebCore::IDBObjectStore::deleteIndex): >+ (WebCore::IDBObjectStore::openCursor): >+ (WebCore::IDBObjectStore::count): >+ * Modules/indexeddb/IDBObjectStore.h: Adds put(PutMode). >+ (IDBObjectStore): >+ * Modules/indexeddb/IDBObjectStoreBackendImpl.cpp: >+ (WebCore::IDBObjectStoreBackendImpl::getInternal): Fix trace symbol. >+ (WebCore::IDBObjectStoreBackendImpl::put): Remove migrated checks. >+ (WebCore::IDBObjectStoreBackendImpl::createIndex): Remove migrated checks. >+ (WebCore::IDBObjectStoreBackendImpl::deleteIndex): Remove migrated checks. >+ * Modules/indexeddb/IDBTransaction.cpp: Add active flag tracking. >+ (WebCore::IDBTransaction::IDBTransaction): >+ (WebCore::IDBTransaction::abort): >+ (WebCore::IDBTransaction::onAbort): >+ (WebCore::IDBTransaction::onComplete): >+ * Modules/indexeddb/IDBTransaction.h: >+ (WebCore::IDBTransaction::isActive): >+ (WebCore::IDBTransaction::isReadOnly): Group IDL/non-IDL methods. >+ (IDBTransaction): >+ > 2012-06-25 Jay Civelli <jcivelli@chromium.org> > > Fix for a memory leak with MHTMLArchives. >diff --git a/Source/WebCore/Modules/indexeddb/IDBCursor.cpp b/Source/WebCore/Modules/indexeddb/IDBCursor.cpp >index 2759514eff74224c61799cf5f60779fdce4d2423..af1c50444735eb94623fcb886a646f04bca65809 100644 >--- a/Source/WebCore/Modules/indexeddb/IDBCursor.cpp >+++ b/Source/WebCore/Modules/indexeddb/IDBCursor.cpp >@@ -29,9 +29,11 @@ > #if ENABLE(INDEXED_DATABASE) > > #include "IDBAny.h" >+#include "IDBBindingUtilities.h" > #include "IDBCallbacks.h" > #include "IDBCursorBackendInterface.h" > #include "IDBKey.h" >+#include "IDBObjectStore.h" > #include "IDBRequest.h" > #include "IDBTracing.h" > #include "IDBTransaction.h" >@@ -125,24 +127,37 @@ IDBAny* IDBCursor::source() const > PassRefPtr<IDBRequest> IDBCursor::update(ScriptExecutionContext* context, PassRefPtr<SerializedScriptValue> prpValue, ExceptionCode& ec) > { > IDB_TRACE("IDBCursor::update"); >+ RefPtr<SerializedScriptValue> value = prpValue; > >- if (!m_gotValue) { >+ 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<SerializedScriptValue> value = prpValue; > 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; >+ } >+ } >+ > RefPtr<IDBRequest> request = IDBRequest::create(context, IDBAny::create(this), m_transaction.get()); > m_backend->update(value, request, ec); > if (ec) { >@@ -160,7 +175,7 @@ void IDBCursor::advance(unsigned long count, ExceptionCode& ec) > return; > } > >- if (!m_request) { >+ if (!m_transaction->isActive()) { > ec = IDBDatabaseException::TRANSACTION_INACTIVE_ERR; > return; > } >@@ -188,7 +203,7 @@ void IDBCursor::continueFunction(PassRefPtr<IDBKey> key, ExceptionCode& ec) > return; > } > >- if (!m_request) { >+ if (!m_transaction->isActive()) { > ec = IDBDatabaseException::TRANSACTION_INACTIVE_ERR; > return; > } >@@ -213,6 +228,10 @@ void IDBCursor::continueFunction(PassRefPtr<IDBKey> key, ExceptionCode& ec) > 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; >@@ -252,6 +271,14 @@ void IDBCursor::setValueReady() > m_valueIsDirty = true; > } > >+PassRefPtr<IDBObjectStore> IDBCursor::effectiveObjectStore() >+{ >+ if (m_source->type() == IDBAny::IDBObjectStoreType) >+ return m_source->idbObjectStore(); >+ RefPtr<IDBIndex> index = m_source->idbIndex(); >+ return index->objectStore(); >+} >+ > unsigned short IDBCursor::stringToDirection(const String& directionString, ExceptionCode& ec) > { > if (directionString == IDBCursor::directionNext()) >diff --git a/Source/WebCore/Modules/indexeddb/IDBCursor.h b/Source/WebCore/Modules/indexeddb/IDBCursor.h >index 3f9d84f98811812c6bfcb53c238831ee3fbb5e6e..4f4564eeb42127aa87b06936b54e043f4e7f5586 100644 >--- a/Source/WebCore/Modules/indexeddb/IDBCursor.h >+++ b/Source/WebCore/Modules/indexeddb/IDBCursor.h >@@ -91,8 +91,11 @@ public: > > protected: > IDBCursor(PassRefPtr<IDBCursorBackendInterface>, IDBRequest*, IDBAny* source, IDBTransaction*); >+ virtual bool isKeyCursor() const { return true; } > > private: >+ PassRefPtr<IDBObjectStore> effectiveObjectStore(); >+ > RefPtr<IDBCursorBackendInterface> m_backend; > RefPtr<IDBRequest> m_request; > RefPtr<IDBAny> m_source; >diff --git a/Source/WebCore/Modules/indexeddb/IDBCursorBackendImpl.cpp b/Source/WebCore/Modules/indexeddb/IDBCursorBackendImpl.cpp >index b6246e919e0b18727c03514d7b81a92b8998f298..0a14a6f1a1b59300f8be989d32cae1e0fb93433c 100644 >--- a/Source/WebCore/Modules/indexeddb/IDBCursorBackendImpl.cpp >+++ b/Source/WebCore/Modules/indexeddb/IDBCursorBackendImpl.cpp >@@ -93,10 +93,9 @@ void IDBCursorBackendImpl::update(PassRefPtr<SerializedScriptValue> value, PassR > { > IDB_TRACE("IDBCursorBackendImpl::update"); > ASSERT(m_transaction->mode() != IDBTransaction::READ_ONLY); >- if (!m_cursor || m_cursorType == IndexKeyCursor) { >- ec = IDBDatabaseException::IDB_INVALID_STATE_ERR; >- return; >- } >+ >+ ASSERT(m_cursor); >+ ASSERT(m_cursorType != IndexKeyCursor); > > m_objectStore->put(value, m_cursor->primaryKey(), IDBObjectStoreBackendInterface::CursorUpdate, callbacks, m_transaction.get(), ec); > } >diff --git a/Source/WebCore/Modules/indexeddb/IDBCursorWithValue.h b/Source/WebCore/Modules/indexeddb/IDBCursorWithValue.h >index a1ba14f961c5a0b88cedecc30a509a154a6179e0..9b396ba35aa06b3914e072a681d704e05caef8cd 100644 >--- a/Source/WebCore/Modules/indexeddb/IDBCursorWithValue.h >+++ b/Source/WebCore/Modules/indexeddb/IDBCursorWithValue.h >@@ -41,6 +41,9 @@ public: > // The value attribute defined in the IDL is simply implemented in IDBCursor (but not exposed via > // its IDL). This is to make the implementation more simple while matching what the spec says. > >+protected: >+ virtual bool isKeyCursor() const OVERRIDE { return false; } >+ > private: > IDBCursorWithValue(PassRefPtr<IDBCursorBackendInterface>, IDBRequest*, IDBAny* source, IDBTransaction*); > }; >diff --git a/Source/WebCore/Modules/indexeddb/IDBDatabase.cpp b/Source/WebCore/Modules/indexeddb/IDBDatabase.cpp >index 0a49400bb8655eae904fce69d9ed7b4086bb7fca..ab123c3dcc94866deeacea01789ca5f228473939 100644 >--- a/Source/WebCore/Modules/indexeddb/IDBDatabase.cpp >+++ b/Source/WebCore/Modules/indexeddb/IDBDatabase.cpp >@@ -117,6 +117,10 @@ PassRefPtr<IDBObjectStore> IDBDatabase::createObjectStore(const String& name, co > ec = IDBDatabaseException::IDB_INVALID_STATE_ERR; > return 0; > } >+ if (!m_versionChangeTransaction->isActive()) { >+ ec = IDBDatabaseException::TRANSACTION_INACTIVE_ERR; >+ return 0; >+ } > > IDBKeyPath keyPath; > if (!options.isUndefinedOrNull()) { >@@ -128,6 +132,11 @@ PassRefPtr<IDBObjectStore> IDBDatabase::createObjectStore(const String& name, co > keyPath = IDBKeyPath(keyPathString); > } > >+ if (m_metadata.objectStores.contains(name)) { >+ ec = IDBDatabaseException::CONSTRAINT_ERR; >+ return 0; >+ } >+ > if (!keyPath.isNull() && !keyPath.isValid()) { > ec = IDBDatabaseException::IDB_SYNTAX_ERR; > return 0; >@@ -162,6 +171,14 @@ void IDBDatabase::deleteObjectStore(const String& name, ExceptionCode& ec) > ec = IDBDatabaseException::IDB_INVALID_STATE_ERR; > return; > } >+ if (!m_versionChangeTransaction->isActive()) { >+ ec = IDBDatabaseException::TRANSACTION_INACTIVE_ERR; >+ return; >+ } >+ if (!m_metadata.objectStores.contains(name)) { >+ ec = IDBDatabaseException::IDB_NOT_FOUND_ERR; >+ return; >+ } > > m_backend->deleteObjectStore(name, m_versionChangeTransaction->backend(), ec); > if (!ec) { >diff --git a/Source/WebCore/Modules/indexeddb/IDBDatabaseBackendImpl.cpp b/Source/WebCore/Modules/indexeddb/IDBDatabaseBackendImpl.cpp >index 5cccaa29a7fd6b56908b567838eb2c131bd73c83..505ba757be48fc1afca45c5966ffbfa004d475e8 100644 >--- a/Source/WebCore/Modules/indexeddb/IDBDatabaseBackendImpl.cpp >+++ b/Source/WebCore/Modules/indexeddb/IDBDatabaseBackendImpl.cpp >@@ -145,10 +145,7 @@ IDBDatabaseMetadata IDBDatabaseBackendImpl::metadata() const > PassRefPtr<IDBObjectStoreBackendInterface> IDBDatabaseBackendImpl::createObjectStore(const String& name, const IDBKeyPath& keyPath, bool autoIncrement, IDBTransactionBackendInterface* transactionPtr, ExceptionCode& ec) > { > ASSERT(transactionPtr->mode() == IDBTransaction::VERSION_CHANGE); >- if (m_objectStores.contains(name)) { >- ec = IDBDatabaseException::CONSTRAINT_ERR; >- return 0; >- } >+ ASSERT(!m_objectStores.contains(name)); > > RefPtr<IDBObjectStoreBackendImpl> objectStore = IDBObjectStoreBackendImpl::create(this, name, keyPath, autoIncrement); > ASSERT(objectStore->name() == name); >@@ -186,12 +183,10 @@ PassRefPtr<IDBObjectStoreBackendInterface> IDBDatabaseBackendImpl::objectStore(c > void IDBDatabaseBackendImpl::deleteObjectStore(const String& name, IDBTransactionBackendInterface* transactionPtr, ExceptionCode& ec) > { > ASSERT(transactionPtr->mode() == IDBTransaction::VERSION_CHANGE); >- RefPtr<IDBObjectStoreBackendImpl> objectStore = m_objectStores.get(name); >- if (!objectStore) { >- ec = IDBDatabaseException::IDB_NOT_FOUND_ERR; >- return; >- } >+ ASSERT(m_objectStores.contains(name)); >+ > RefPtr<IDBDatabaseBackendImpl> database = this; >+ RefPtr<IDBObjectStoreBackendImpl> objectStore = m_objectStores.get(name); > RefPtr<IDBTransactionBackendInterface> transaction = transactionPtr; > if (!transaction->scheduleTask(createCallbackTask(&IDBDatabaseBackendImpl::deleteObjectStoreInternal, database, objectStore, transaction), > createCallbackTask(&IDBDatabaseBackendImpl::addObjectStoreToMap, database, objectStore))) { >diff --git a/Source/WebCore/Modules/indexeddb/IDBIndex.cpp b/Source/WebCore/Modules/indexeddb/IDBIndex.cpp >index 31e7f5d4e762fccdbda431679499dabaaabad0f4..fd939494749272255919dc30228f3c05c978d318 100644 >--- a/Source/WebCore/Modules/indexeddb/IDBIndex.cpp >+++ b/Source/WebCore/Modules/indexeddb/IDBIndex.cpp >@@ -65,6 +65,10 @@ PassRefPtr<IDBRequest> IDBIndex::openCursor(ScriptExecutionContext* context, Pas > ec = IDBDatabaseException::IDB_INVALID_STATE_ERR; > return 0; > } >+ if (!m_transaction->isActive()) { >+ ec = IDBDatabaseException::TRANSACTION_INACTIVE_ERR; >+ return 0; >+ } > unsigned short direction = IDBCursor::stringToDirection(directionString, ec); > if (ec) > return 0; >@@ -115,6 +119,10 @@ PassRefPtr<IDBRequest> IDBIndex::count(ScriptExecutionContext* context, PassRefP > ec = IDBDatabaseException::IDB_INVALID_STATE_ERR; > return 0; > } >+ if (!m_transaction->isActive()) { >+ ec = IDBDatabaseException::TRANSACTION_INACTIVE_ERR; >+ return 0; >+ } > RefPtr<IDBRequest> request = IDBRequest::create(context, IDBAny::create(this), m_transaction.get()); > m_backend->count(keyRange, request, m_transaction->backend(), ec); > if (ec) { >@@ -140,6 +148,10 @@ PassRefPtr<IDBRequest> IDBIndex::openKeyCursor(ScriptExecutionContext* context, > ec = IDBDatabaseException::IDB_INVALID_STATE_ERR; > return 0; > } >+ if (!m_transaction->isActive()) { >+ ec = IDBDatabaseException::TRANSACTION_INACTIVE_ERR; >+ return 0; >+ } > > unsigned short direction = IDBCursor::stringToDirection(directionString, ec); > if (ec) >@@ -200,6 +212,10 @@ PassRefPtr<IDBRequest> IDBIndex::get(ScriptExecutionContext* context, PassRefPtr > ec = IDBDatabaseException::IDB_INVALID_STATE_ERR; > return 0; > } >+ if (!m_transaction->isActive()) { >+ ec = IDBDatabaseException::TRANSACTION_INACTIVE_ERR; >+ return 0; >+ } > if (!keyRange) { > ec = IDBDatabaseException::DATA_ERR; > return 0; >@@ -231,6 +247,10 @@ PassRefPtr<IDBRequest> IDBIndex::getKey(ScriptExecutionContext* context, PassRef > ec = IDBDatabaseException::IDB_INVALID_STATE_ERR; > return 0; > } >+ if (!m_transaction->isActive()) { >+ ec = IDBDatabaseException::TRANSACTION_INACTIVE_ERR; >+ return 0; >+ } > if (!keyRange) { > ec = IDBDatabaseException::DATA_ERR; > return 0; >diff --git a/Source/WebCore/Modules/indexeddb/IDBObjectStore.cpp b/Source/WebCore/Modules/indexeddb/IDBObjectStore.cpp >index 68bc17165df725e7141c81c188fc756a41c52926..6c06415929ce8bb7c857a11aef8dd1f81e332153 100644 >--- a/Source/WebCore/Modules/indexeddb/IDBObjectStore.cpp >+++ b/Source/WebCore/Modules/indexeddb/IDBObjectStore.cpp >@@ -30,6 +30,7 @@ > > #include "DOMStringList.h" > #include "IDBAny.h" >+#include "IDBBindingUtilities.h" > #include "IDBDatabase.h" > #include "IDBDatabaseException.h" > #include "IDBIndex.h" >@@ -78,6 +79,10 @@ PassRefPtr<IDBRequest> IDBObjectStore::get(ScriptExecutionContext* context, Pass > ec = IDBDatabaseException::DATA_ERR; > return 0; > } >+ if (!m_transaction->isActive()) { >+ ec = IDBDatabaseException::TRANSACTION_INACTIVE_ERR; >+ return 0; >+ } > RefPtr<IDBRequest> request = IDBRequest::create(context, IDBAny::create(this), m_transaction.get()); > m_backend->get(keyRange, request, m_transaction->backend(), ec); > if (ec) { >@@ -96,65 +101,80 @@ PassRefPtr<IDBRequest> IDBObjectStore::get(ScriptExecutionContext* context, Pass > return get(context, keyRange.release(), ec); > } > >-PassRefPtr<IDBRequest> IDBObjectStore::add(ScriptExecutionContext* context, PassRefPtr<SerializedScriptValue> prpValue, PassRefPtr<IDBKey> key, ExceptionCode& ec) >+PassRefPtr<IDBRequest> IDBObjectStore::add(ScriptExecutionContext* context, PassRefPtr<SerializedScriptValue> value, PassRefPtr<IDBKey> key, ExceptionCode& ec) > { > IDB_TRACE("IDBObjectStore::add"); >+ return put(IDBObjectStoreBackendInterface::AddOnly, context, value, key, ec); >+} >+ >+PassRefPtr<IDBRequest> IDBObjectStore::put(ScriptExecutionContext* context, PassRefPtr<SerializedScriptValue> value, PassRefPtr<IDBKey> key, ExceptionCode& ec) >+{ >+ IDB_TRACE("IDBObjectStore::put"); >+ return put(IDBObjectStoreBackendInterface::AddOrUpdate, context, value, key, ec); >+} >+ >+PassRefPtr<IDBRequest> IDBObjectStore::put(IDBObjectStoreBackendInterface::PutMode putMode, ScriptExecutionContext* context, PassRefPtr<SerializedScriptValue> prpValue, PassRefPtr<IDBKey> prpKey, ExceptionCode& ec) >+{ >+ IDB_TRACE("IDBObjectStore::put"); >+ RefPtr<SerializedScriptValue> value = prpValue; >+ RefPtr<IDBKey> key = prpKey; > if (m_deleted) { > ec = IDBDatabaseException::IDB_INVALID_STATE_ERR; > return 0; > } >- if (m_transaction->isReadOnly()) { >- ec = IDBDatabaseException::READ_ONLY_ERR; >+ if (!m_transaction->isActive()) { >+ ec = IDBDatabaseException::TRANSACTION_INACTIVE_ERR; > return 0; > } >- >- if (key && !key->isValid()) { >- ec = IDBDatabaseException::DATA_ERR; >+ if (m_transaction->isReadOnly()) { >+ ec = IDBDatabaseException::READ_ONLY_ERR; > return 0; > } >- >- RefPtr<SerializedScriptValue> value = prpValue; > if (value->blobURLs().size() > 0) { > // FIXME: Add Blob/File/FileList support > ec = IDBDatabaseException::IDB_DATA_CLONE_ERR; > return 0; > } > >- RefPtr<IDBRequest> request = IDBRequest::create(context, IDBAny::create(this), m_transaction.get()); >- m_backend->put(value, key, IDBObjectStoreBackendInterface::AddOnly, request, m_transaction->backend(), ec); >- if (ec) { >- request->markEarlyDeath(); >- return 0; >- } >- return request.release(); >-} >+ const IDBKeyPath& keyPath = m_metadata.keyPath; >+ const bool usesInLineKeys = !keyPath.isNull(); >+ const bool hasKeyGenerator = autoIncrement(); > >-PassRefPtr<IDBRequest> IDBObjectStore::put(ScriptExecutionContext* context, PassRefPtr<SerializedScriptValue> prpValue, PassRefPtr<IDBKey> key, ExceptionCode& ec) >-{ >- IDB_TRACE("IDBObjectStore::put"); >- if (m_deleted) { >- ec = IDBDatabaseException::IDB_INVALID_STATE_ERR; >+ if (usesInLineKeys && key) { >+ ec = IDBDatabaseException::DATA_ERR; > return 0; > } >- if (m_transaction->isReadOnly()) { >- ec = IDBDatabaseException::READ_ONLY_ERR; >+ if (!usesInLineKeys && !hasKeyGenerator && !key) { >+ ec = IDBDatabaseException::DATA_ERR; > return 0; > } >- >+ if (usesInLineKeys) { >+ RefPtr<IDBKey> keyPathKey = createIDBKeyFromSerializedValueAndKeyPath(value, keyPath); >+ if (keyPathKey && !keyPathKey->isValid()) { >+ ec = IDBDatabaseException::DATA_ERR; >+ return 0; >+ } >+ if (!hasKeyGenerator && !keyPathKey) { >+ ec = IDBDatabaseException::DATA_ERR; >+ return 0; >+ } >+ if (hasKeyGenerator && !keyPathKey) { >+ RefPtr<IDBKey> dummyKey = IDBKey::createNumber(-1); >+ RefPtr<SerializedScriptValue> valueAfterInjection = injectIDBKeyIntoSerializedValue(dummyKey, value, keyPath); >+ if (!valueAfterInjection) { >+ ec = IDBDatabaseException::DATA_ERR; >+ return 0; >+ } >+ } >+ } > if (key && !key->isValid()) { > ec = IDBDatabaseException::DATA_ERR; > return 0; > } > >- RefPtr<SerializedScriptValue> value = prpValue; >- if (value->blobURLs().size() > 0) { >- // FIXME: Add Blob/File/FileList support >- ec = IDBDatabaseException::IDB_DATA_CLONE_ERR; >- return 0; >- } >- > RefPtr<IDBRequest> request = IDBRequest::create(context, IDBAny::create(this), m_transaction.get()); >- m_backend->put(value, key, IDBObjectStoreBackendInterface::AddOrUpdate, request, m_transaction->backend(), ec); >+ // FIXME: Pass through keyPathKey as key to simplify back end implementation. >+ m_backend->put(value.release(), key.release(), putMode, request, m_transaction->backend(), ec); > if (ec) { > request->markEarlyDeath(); > return 0; >@@ -169,11 +189,14 @@ PassRefPtr<IDBRequest> IDBObjectStore::deleteFunction(ScriptExecutionContext* co > 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 (!keyRange) { > ec = IDBDatabaseException::DATA_ERR; > return 0; >@@ -204,6 +227,10 @@ PassRefPtr<IDBRequest> IDBObjectStore::clear(ScriptExecutionContext* context, Ex > 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; >@@ -239,11 +266,22 @@ PassRefPtr<IDBIndex> IDBObjectStore::createIndex(const String& name, const IDBKe > ec = IDBDatabaseException::IDB_INVALID_STATE_ERR; > return 0; > } >- >+ if (!m_transaction->isActive()) { >+ ec = IDBDatabaseException::TRANSACTION_INACTIVE_ERR; >+ return 0; >+ } > if (!keyPath.isValid()) { > ec = IDBDatabaseException::IDB_SYNTAX_ERR; > return 0; > } >+ if (name.isNull()) { >+ ec = IDBDatabaseException::IDB_TYPE_ERR; >+ return 0; >+ } >+ if (m_metadata.indexes.contains(name)) { >+ ec = IDBDatabaseException::CONSTRAINT_ERR; >+ return 0; >+ } > > bool unique = false; > options.get("unique", unique); >@@ -304,6 +342,14 @@ void IDBObjectStore::deleteIndex(const String& name, ExceptionCode& ec) > ec = IDBDatabaseException::IDB_INVALID_STATE_ERR; > return; > } >+ if (!m_transaction->isActive()) { >+ ec = IDBDatabaseException::TRANSACTION_INACTIVE_ERR; >+ return; >+ } >+ if (!m_metadata.indexes.contains(name)) { >+ ec = IDBDatabaseException::IDB_NOT_FOUND_ERR; >+ return; >+ } > > m_backend->deleteIndex(name, m_transaction->backend(), ec); > if (!ec) { >@@ -325,6 +371,10 @@ PassRefPtr<IDBRequest> IDBObjectStore::openCursor(ScriptExecutionContext* contex > ec = IDBDatabaseException::IDB_INVALID_STATE_ERR; > return 0; > } >+ if (!m_transaction->isActive()) { >+ ec = IDBDatabaseException::TRANSACTION_INACTIVE_ERR; >+ return 0; >+ } > unsigned short direction = IDBCursor::stringToDirection(directionString, ec); > if (ec) > return 0; >@@ -375,6 +425,10 @@ PassRefPtr<IDBRequest> IDBObjectStore::count(ScriptExecutionContext* context, Pa > ec = IDBDatabaseException::IDB_INVALID_STATE_ERR; > return 0; > } >+ if (!m_transaction->isActive()) { >+ ec = IDBDatabaseException::TRANSACTION_INACTIVE_ERR; >+ return 0; >+ } > RefPtr<IDBRequest> request = IDBRequest::create(context, IDBAny::create(this), m_transaction.get()); > m_backend->count(range, request, m_transaction->backend(), ec); > if (ec) { >diff --git a/Source/WebCore/Modules/indexeddb/IDBObjectStore.h b/Source/WebCore/Modules/indexeddb/IDBObjectStore.h >index 8181eb931fa70cc590042f22562cf78dc2ccf4c1..67b36f995517a9b84d2a1c22524958fcdaa484ce 100644 >--- a/Source/WebCore/Modules/indexeddb/IDBObjectStore.h >+++ b/Source/WebCore/Modules/indexeddb/IDBObjectStore.h >@@ -95,6 +95,7 @@ public: > PassRefPtr<IDBRequest> count(ScriptExecutionContext*, PassRefPtr<IDBKeyRange>, ExceptionCode&); > PassRefPtr<IDBRequest> count(ScriptExecutionContext*, PassRefPtr<IDBKey>, ExceptionCode&); > >+ PassRefPtr<IDBRequest> put(IDBObjectStoreBackendInterface::PutMode, ScriptExecutionContext*, PassRefPtr<SerializedScriptValue>, PassRefPtr<IDBKey>, ExceptionCode&); > void markDeleted() { m_deleted = true; } > void transactionFinished(); > >@@ -103,7 +104,6 @@ public: > > private: > IDBObjectStore(const IDBObjectStoreMetadata&, PassRefPtr<IDBObjectStoreBackendInterface>, IDBTransaction*); >- void removeTransactionFromPendingList(); > > IDBObjectStoreMetadata m_metadata; > RefPtr<IDBObjectStoreBackendInterface> m_backend; >diff --git a/Source/WebCore/Modules/indexeddb/IDBObjectStoreBackendImpl.cpp b/Source/WebCore/Modules/indexeddb/IDBObjectStoreBackendImpl.cpp >index a468654e07b8162f1a57bd5054e0359c8e2c7e4d..af30ef37115a51139c5201b09acbb494272a234b 100644 >--- a/Source/WebCore/Modules/indexeddb/IDBObjectStoreBackendImpl.cpp >+++ b/Source/WebCore/Modules/indexeddb/IDBObjectStoreBackendImpl.cpp >@@ -42,7 +42,7 @@ > #include "IDBKeyPathBackendImpl.h" > #include "IDBKeyRange.h" > #include "IDBTracing.h" >-#include "IDBTransactionBackendInterface.h" >+#include "IDBTransactionBackendImpl.h" > #include "ScriptExecutionContext.h" > > namespace WebCore { >@@ -92,7 +92,7 @@ void IDBObjectStoreBackendImpl::get(PassRefPtr<IDBKeyRange> prpKeyRange, PassRef > > void IDBObjectStoreBackendImpl::getInternal(ScriptExecutionContext*, PassRefPtr<IDBObjectStoreBackendImpl> objectStore, PassRefPtr<IDBKeyRange> keyRange, PassRefPtr<IDBCallbacks> callbacks) > { >- IDB_TRACE("IDBObjectStoreBackendImpl::getByRangeInternal"); >+ IDB_TRACE("IDBObjectStoreBackendImpl::getInternal"); > RefPtr<IDBKey> key; > if (keyRange->isOnlyKey()) > key = keyRange->lower(); >@@ -148,53 +148,6 @@ void IDBObjectStoreBackendImpl::put(PassRefPtr<SerializedScriptValue> prpValue, > RefPtr<IDBCallbacks> callbacks = prpCallbacks; > RefPtr<IDBTransactionBackendInterface> transaction = transactionPtr; > >- if (putMode != CursorUpdate) { >- const bool autoIncrement = objectStore->autoIncrement(); >- const bool hasKeyPath = !objectStore->m_keyPath.isNull(); >- >- if (hasKeyPath && key) { >- ec = IDBDatabaseException::DATA_ERR; >- return; >- } >- if (!hasKeyPath && !autoIncrement && !key) { >- ec = IDBDatabaseException::DATA_ERR; >- return; >- } >- if (hasKeyPath) { >- RefPtr<IDBKey> keyPathKey = fetchKeyFromKeyPath(value.get(), objectStore->m_keyPath); >- if (keyPathKey && !keyPathKey->isValid()) { >- ec = IDBDatabaseException::DATA_ERR; >- return; >- } >- if (!autoIncrement && !keyPathKey) { >- ec = IDBDatabaseException::DATA_ERR; >- return; >- } >- if (autoIncrement && !keyPathKey) { >- RefPtr<IDBKey> dummyKey = IDBKey::createNumber(-1); >- RefPtr<SerializedScriptValue> valueAfterInjection = injectKeyIntoKeyPath(dummyKey, value, objectStore->m_keyPath); >- if (!valueAfterInjection) { >- ec = IDBDatabaseException::DATA_ERR; >- return; >- } >- } >- } >- if (key && !key->isValid()) { >- ec = IDBDatabaseException::DATA_ERR; >- return; >- } >- } else { >- ASSERT(key); >- const bool hasKeyPath = !objectStore->m_keyPath.isNull(); >- if (hasKeyPath) { >- RefPtr<IDBKey> keyPathKey = fetchKeyFromKeyPath(value.get(), objectStore->m_keyPath); >- if (!keyPathKey || !keyPathKey->isEqual(key.get())) { >- ec = IDBDatabaseException::DATA_ERR; >- return; >- } >- } >- } >- > if (!transaction->scheduleTask( > createCallbackTask(&IDBObjectStoreBackendImpl::putInternal, objectStore, value, key, putMode, callbacks, transaction), > // FIXME: One of these per put() is overkill, since it's simply a cache invalidation. >@@ -459,18 +412,8 @@ bool IDBObjectStoreBackendImpl::populateIndex(IDBBackingStore& backingStore, int > > PassRefPtr<IDBIndexBackendInterface> IDBObjectStoreBackendImpl::createIndex(const String& name, const IDBKeyPath& keyPath, bool unique, bool multiEntry, IDBTransactionBackendInterface* transaction, ExceptionCode& ec) > { >- if (name.isNull()) { >- ec = IDBDatabaseException::IDB_TYPE_ERR; >- return 0; >- } >- if (m_indexes.contains(name)) { >- ec = IDBDatabaseException::CONSTRAINT_ERR; >- return 0; >- } >- if (transaction->mode() != IDBTransaction::VERSION_CHANGE) { >- ec = IDBDatabaseException::IDB_INVALID_STATE_ERR; >- return 0; >- } >+ ASSERT(transaction->mode() == IDBTransaction::VERSION_CHANGE); >+ ASSERT(!m_indexes.contains(name)); > > RefPtr<IDBIndexBackendImpl> index = IDBIndexBackendImpl::create(m_database, this, name, keyPath, unique, multiEntry); > ASSERT(index->name() == name); >@@ -520,18 +463,11 @@ PassRefPtr<IDBIndexBackendInterface> IDBObjectStoreBackendImpl::index(const Stri > > void IDBObjectStoreBackendImpl::deleteIndex(const String& name, IDBTransactionBackendInterface* transaction, ExceptionCode& ec) > { >- if (transaction->mode() != IDBTransaction::VERSION_CHANGE) { >- ec = IDBDatabaseException::IDB_INVALID_STATE_ERR; >- return; >- } >- >- RefPtr<IDBIndexBackendImpl> index = m_indexes.get(name); >- if (!index) { >- ec = IDBDatabaseException::IDB_NOT_FOUND_ERR; >- return; >- } >+ ASSERT(transaction->mode() == IDBTransaction::VERSION_CHANGE); >+ ASSERT(m_indexes.contains(name)); > > RefPtr<IDBObjectStoreBackendImpl> objectStore = this; >+ RefPtr<IDBIndexBackendImpl> index = m_indexes.get(name); > RefPtr<IDBTransactionBackendInterface> transactionPtr = transaction; > if (!transaction->scheduleTask( > createCallbackTask(&IDBObjectStoreBackendImpl::deleteIndexInternal, >diff --git a/Source/WebCore/Modules/indexeddb/IDBTransaction.cpp b/Source/WebCore/Modules/indexeddb/IDBTransaction.cpp >index 7087c657e06686c17d15b36d88c69249d23e9b59..6ad3007238ef36f658f6c22b5eb9c6a7367745a5 100644 >--- a/Source/WebCore/Modules/indexeddb/IDBTransaction.cpp >+++ b/Source/WebCore/Modules/indexeddb/IDBTransaction.cpp >@@ -84,6 +84,7 @@ IDBTransaction::IDBTransaction(ScriptExecutionContext* context, PassRefPtr<IDBTr > , m_backend(backend) > , m_database(db) > , m_mode(mode) >+ , m_active(true) > , m_transactionFinished(false) > , m_contextStopped(false) > { >@@ -193,6 +194,7 @@ void IDBTransaction::abort() > { > if (m_transactionFinished) > return; >+ m_active = false; > RefPtr<IDBTransaction> selfRef = this; > if (m_backend) > m_backend->abort(); >@@ -242,6 +244,7 @@ void IDBTransaction::unregisterRequest(IDBRequest* request) > void IDBTransaction::onAbort() > { > ASSERT(!m_transactionFinished); >+ m_active = false; > while (!m_childRequests.isEmpty()) { > IDBRequest* request = *m_childRequests.begin(); > m_childRequests.remove(request); >@@ -265,6 +268,7 @@ void IDBTransaction::onAbort() > void IDBTransaction::onComplete() > { > ASSERT(!m_transactionFinished); >+ m_active = false; > m_objectStoreCleanupMap.clear(); > closeOpenCursors(); > m_database->transactionFinished(this); >diff --git a/Source/WebCore/Modules/indexeddb/IDBTransaction.h b/Source/WebCore/Modules/indexeddb/IDBTransaction.h >index 0b2dec6ec08f1d1e2b960edb0116fcf89d1cf96d..2ce82b1cf77aaf20fd2240da1b8f68c1b91d22ec 100644 >--- a/Source/WebCore/Modules/indexeddb/IDBTransaction.h >+++ b/Source/WebCore/Modules/indexeddb/IDBTransaction.h >@@ -68,12 +68,13 @@ public: > static const AtomicString& modeToString(Mode, ExceptionCode&); > > IDBTransactionBackendInterface* backend() const; >+ bool isActive() const { return m_active; } > bool isFinished() const; >+ bool isReadOnly() const { return m_mode == READ_ONLY; } > bool isVersionChange() const { return m_mode == VERSION_CHANGE; } > > // Implement the IDBTransaction IDL > const String& mode() const; >- bool isReadOnly() const { return m_mode == READ_ONLY; } > IDBDatabase* db() const; > PassRefPtr<DOMError> error(ExceptionCode&) const; > void setError(PassRefPtr<DOMError>); >@@ -135,6 +136,7 @@ private: > RefPtr<IDBTransactionBackendInterface> m_backend; > RefPtr<IDBDatabase> m_database; > const Mode m_mode; >+ bool m_active; > bool m_transactionFinished; // Is it possible that we'll fire any more events or allow any new requests? If not, we're finished. > bool m_contextStopped; > RefPtr<DOMError> m_error;
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Formatted Diff
|
Diff
Attachments on
bug 89377
:
148887
|
149139
|
149394
| 149549