Diff
Modified: trunk/Source/WebCore/ChangeLog (121290 => 121291)
--- trunk/Source/WebCore/ChangeLog 2012-06-26 21:46:34 UTC (rev 121290)
+++ trunk/Source/WebCore/ChangeLog 2012-06-26 22:04:09 UTC (rev 121291)
@@ -1,3 +1,77 @@
+2012-06-26 Joshua Bell <jsb...@chromium.org>
+
+ IndexedDB: Move method precondition checks to front end objects
+ https://bugs.webkit.org/show_bug.cgi?id=89377
+
+ Reviewed by Tony Chang.
+
+ 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-26 Sheriff Bot <webkit.review....@gmail.com>
Unreviewed, rolling out r121285.
Modified: trunk/Source/WebCore/Modules/indexeddb/IDBCursor.cpp (121290 => 121291)
--- trunk/Source/WebCore/Modules/indexeddb/IDBCursor.cpp 2012-06-26 21:46:34 UTC (rev 121290)
+++ trunk/Source/WebCore/Modules/indexeddb/IDBCursor.cpp 2012-06-26 22:04:09 UTC (rev 121291)
@@ -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 @@
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 @@
return;
}
- if (!m_request) {
+ if (!m_transaction->isActive()) {
ec = IDBDatabaseException::TRANSACTION_INACTIVE_ERR;
return;
}
@@ -188,7 +203,7 @@
return;
}
- if (!m_request) {
+ if (!m_transaction->isActive()) {
ec = IDBDatabaseException::TRANSACTION_INACTIVE_ERR;
return;
}
@@ -213,6 +228,10 @@
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 @@
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())
Modified: trunk/Source/WebCore/Modules/indexeddb/IDBCursor.h (121290 => 121291)
--- trunk/Source/WebCore/Modules/indexeddb/IDBCursor.h 2012-06-26 21:46:34 UTC (rev 121290)
+++ trunk/Source/WebCore/Modules/indexeddb/IDBCursor.h 2012-06-26 22:04:09 UTC (rev 121291)
@@ -91,8 +91,11 @@
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;
Modified: trunk/Source/WebCore/Modules/indexeddb/IDBCursorBackendImpl.cpp (121290 => 121291)
--- trunk/Source/WebCore/Modules/indexeddb/IDBCursorBackendImpl.cpp 2012-06-26 21:46:34 UTC (rev 121290)
+++ trunk/Source/WebCore/Modules/indexeddb/IDBCursorBackendImpl.cpp 2012-06-26 22:04:09 UTC (rev 121291)
@@ -93,11 +93,10 @@
{
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);
}
Modified: trunk/Source/WebCore/Modules/indexeddb/IDBCursorWithValue.h (121290 => 121291)
--- trunk/Source/WebCore/Modules/indexeddb/IDBCursorWithValue.h 2012-06-26 21:46:34 UTC (rev 121290)
+++ trunk/Source/WebCore/Modules/indexeddb/IDBCursorWithValue.h 2012-06-26 22:04:09 UTC (rev 121291)
@@ -41,6 +41,9 @@
// 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*);
};
Modified: trunk/Source/WebCore/Modules/indexeddb/IDBDatabase.cpp (121290 => 121291)
--- trunk/Source/WebCore/Modules/indexeddb/IDBDatabase.cpp 2012-06-26 21:46:34 UTC (rev 121290)
+++ trunk/Source/WebCore/Modules/indexeddb/IDBDatabase.cpp 2012-06-26 22:04:09 UTC (rev 121291)
@@ -117,6 +117,10 @@
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 @@
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 @@
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) {
Modified: trunk/Source/WebCore/Modules/indexeddb/IDBDatabaseBackendImpl.cpp (121290 => 121291)
--- trunk/Source/WebCore/Modules/indexeddb/IDBDatabaseBackendImpl.cpp 2012-06-26 21:46:34 UTC (rev 121290)
+++ trunk/Source/WebCore/Modules/indexeddb/IDBDatabaseBackendImpl.cpp 2012-06-26 22:04:09 UTC (rev 121291)
@@ -145,10 +145,7 @@
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 @@
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))) {
Modified: trunk/Source/WebCore/Modules/indexeddb/IDBIndex.cpp (121290 => 121291)
--- trunk/Source/WebCore/Modules/indexeddb/IDBIndex.cpp 2012-06-26 21:46:34 UTC (rev 121290)
+++ trunk/Source/WebCore/Modules/indexeddb/IDBIndex.cpp 2012-06-26 22:04:09 UTC (rev 121291)
@@ -65,6 +65,10 @@
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 @@
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 @@
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 @@
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 @@
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;
Modified: trunk/Source/WebCore/Modules/indexeddb/IDBObjectStore.cpp (121290 => 121291)
--- trunk/Source/WebCore/Modules/indexeddb/IDBObjectStore.cpp 2012-06-26 21:46:34 UTC (rev 121290)
+++ trunk/Source/WebCore/Modules/indexeddb/IDBObjectStore.cpp 2012-06-26 22:04:09 UTC (rev 121291)
@@ -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 @@
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 @@
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->isActive()) {
+ ec = IDBDatabaseException::TRANSACTION_INACTIVE_ERR;
+ return 0;
+ }
if (m_transaction->isReadOnly()) {
ec = IDBDatabaseException::READ_ONLY_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::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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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) {
Modified: trunk/Source/WebCore/Modules/indexeddb/IDBObjectStore.h (121290 => 121291)
--- trunk/Source/WebCore/Modules/indexeddb/IDBObjectStore.h 2012-06-26 21:46:34 UTC (rev 121290)
+++ trunk/Source/WebCore/Modules/indexeddb/IDBObjectStore.h 2012-06-26 22:04:09 UTC (rev 121291)
@@ -95,6 +95,7 @@
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 @@
private:
IDBObjectStore(const IDBObjectStoreMetadata&, PassRefPtr<IDBObjectStoreBackendInterface>, IDBTransaction*);
- void removeTransactionFromPendingList();
IDBObjectStoreMetadata m_metadata;
RefPtr<IDBObjectStoreBackendInterface> m_backend;
Modified: trunk/Source/WebCore/Modules/indexeddb/IDBObjectStoreBackendImpl.cpp (121290 => 121291)
--- trunk/Source/WebCore/Modules/indexeddb/IDBObjectStoreBackendImpl.cpp 2012-06-26 21:46:34 UTC (rev 121290)
+++ trunk/Source/WebCore/Modules/indexeddb/IDBObjectStoreBackendImpl.cpp 2012-06-26 22:04:09 UTC (rev 121291)
@@ -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::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 @@
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 @@
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 @@
void IDBObjectStoreBackendImpl::deleteIndex(const String& name, IDBTransactionBackendInterface* transaction, ExceptionCode& ec)
{
- if (transaction->mode() != IDBTransaction::VERSION_CHANGE) {
- ec = IDBDatabaseException::IDB_INVALID_STATE_ERR;
- return;
- }
+ ASSERT(transaction->mode() == IDBTransaction::VERSION_CHANGE);
+ ASSERT(m_indexes.contains(name));
- RefPtr<IDBIndexBackendImpl> index = m_indexes.get(name);
- if (!index) {
- ec = IDBDatabaseException::IDB_NOT_FOUND_ERR;
- return;
- }
-
RefPtr<IDBObjectStoreBackendImpl> objectStore = this;
+ RefPtr<IDBIndexBackendImpl> index = m_indexes.get(name);
RefPtr<IDBTransactionBackendInterface> transactionPtr = transaction;
if (!transaction->scheduleTask(
createCallbackTask(&IDBObjectStoreBackendImpl::deleteIndexInternal,
Modified: trunk/Source/WebCore/Modules/indexeddb/IDBTransaction.cpp (121290 => 121291)
--- trunk/Source/WebCore/Modules/indexeddb/IDBTransaction.cpp 2012-06-26 21:46:34 UTC (rev 121290)
+++ trunk/Source/WebCore/Modules/indexeddb/IDBTransaction.cpp 2012-06-26 22:04:09 UTC (rev 121291)
@@ -84,6 +84,7 @@
, m_backend(backend)
, m_database(db)
, m_mode(mode)
+ , m_active(true)
, m_transactionFinished(false)
, m_contextStopped(false)
{
@@ -193,6 +194,7 @@
{
if (m_transactionFinished)
return;
+ m_active = false;
RefPtr<IDBTransaction> selfRef = this;
if (m_backend)
m_backend->abort();
@@ -242,6 +244,7 @@
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::onComplete()
{
ASSERT(!m_transactionFinished);
+ m_active = false;
m_objectStoreCleanupMap.clear();
closeOpenCursors();
m_database->transactionFinished(this);
Modified: trunk/Source/WebCore/Modules/indexeddb/IDBTransaction.h (121290 => 121291)
--- trunk/Source/WebCore/Modules/indexeddb/IDBTransaction.h 2012-06-26 21:46:34 UTC (rev 121290)
+++ trunk/Source/WebCore/Modules/indexeddb/IDBTransaction.h 2012-06-26 22:04:09 UTC (rev 121291)
@@ -68,12 +68,13 @@
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 @@
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;