Diff
Modified: trunk/LayoutTests/ChangeLog (120503 => 120504)
--- trunk/LayoutTests/ChangeLog 2012-06-15 22:30:43 UTC (rev 120503)
+++ trunk/LayoutTests/ChangeLog 2012-06-15 22:49:04 UTC (rev 120504)
@@ -1,3 +1,23 @@
+2012-06-15 Joshua Bell <[email protected]>
+
+ IndexedDB: Raise exceptions when methods are called on deleted objects
+ https://bugs.webkit.org/show_bug.cgi?id=89243
+
+ Reviewed by Tony Chang.
+
+ * storage/indexeddb/deleted-objects-expected.txt: Added.
+ * storage/indexeddb/deleted-objects.html: Added.
+ * storage/indexeddb/resources/deleted-objects.js: Added.
+ (test):
+ (openDatabase.request.onsuccess.request.onsuccess):
+ (openDatabase.request.onsuccess):
+ (openDatabase):
+ * storage/indexeddb/resources/transaction-basics.js: Fix test that relied on
+ non-compliant behavior.
+ (addRemoveIDBObjects):
+ (addRemoveAddIDBObjects):
+ * storage/indexeddb/transaction-basics-expected.txt:
+
2012-06-15 Abhishek Arya <[email protected]>
Unreviewed. Forgot a rebaseline for r120477.
Added: trunk/LayoutTests/storage/indexeddb/deleted-objects-expected.txt (0 => 120504)
--- trunk/LayoutTests/storage/indexeddb/deleted-objects-expected.txt (rev 0)
+++ trunk/LayoutTests/storage/indexeddb/deleted-objects-expected.txt 2012-06-15 22:49:04 UTC (rev 120504)
@@ -0,0 +1,87 @@
+Test that IndexedDB objects that have been deleted throw exceptions
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+indexedDB = self.indexedDB || self.webkitIndexedDB || self.mozIndexedDB || self.msIndexedDB || self.OIndexedDB;
+
+dbname = self.location.pathname
+request = indexedDB.deleteDatabase(dbname)
+
+openDatabase():
+request = indexedDB.open(dbname)
+connection = request.result
+request = connection.setVersion('1')
+
+deletedStore = connection.createObjectStore('deletedStore')
+store = connection.createObjectStore('store')
+deletedIndex = store.createIndex('deletedIndex', 'path')
+
+connection.deleteObjectStore('deletedStore')
+store.deleteIndex('deletedIndex')
+
+Expecting exception from deletedStore.put(0, 0)
+PASS Exception was thrown.
+PASS code is DOMException.INVALID_STATE_ERR
+PASS ename is 'InvalidStateError'
+Expecting exception from deletedStore.add(0, 0)
+PASS Exception was thrown.
+PASS code is DOMException.INVALID_STATE_ERR
+PASS ename is 'InvalidStateError'
+Expecting exception from deletedStore.delete(0)
+PASS Exception was thrown.
+PASS code is DOMException.INVALID_STATE_ERR
+PASS ename is 'InvalidStateError'
+Expecting exception from deletedStore.get(0)
+PASS Exception was thrown.
+PASS code is DOMException.INVALID_STATE_ERR
+PASS ename is 'InvalidStateError'
+Expecting exception from deletedStore.clear()
+PASS Exception was thrown.
+PASS code is DOMException.INVALID_STATE_ERR
+PASS ename is 'InvalidStateError'
+Expecting exception from deletedStore.openCursor()
+PASS Exception was thrown.
+PASS code is DOMException.INVALID_STATE_ERR
+PASS ename is 'InvalidStateError'
+Expecting exception from deletedStore.createIndex('name', 'path')
+PASS Exception was thrown.
+PASS code is DOMException.INVALID_STATE_ERR
+PASS ename is 'InvalidStateError'
+Expecting exception from deletedStore.index('name')
+PASS Exception was thrown.
+PASS code is DOMException.INVALID_STATE_ERR
+PASS ename is 'InvalidStateError'
+Expecting exception from deletedStore.deleteIndex('name')
+PASS Exception was thrown.
+PASS code is DOMException.INVALID_STATE_ERR
+PASS ename is 'InvalidStateError'
+Expecting exception from deletedStore.count()
+PASS Exception was thrown.
+PASS code is DOMException.INVALID_STATE_ERR
+PASS ename is 'InvalidStateError'
+
+Expecting exception from deletedIndex.openCursor()
+PASS Exception was thrown.
+PASS code is DOMException.INVALID_STATE_ERR
+PASS ename is 'InvalidStateError'
+Expecting exception from deletedIndex.openKeyCursor()
+PASS Exception was thrown.
+PASS code is DOMException.INVALID_STATE_ERR
+PASS ename is 'InvalidStateError'
+Expecting exception from deletedIndex.get(0)
+PASS Exception was thrown.
+PASS code is DOMException.INVALID_STATE_ERR
+PASS ename is 'InvalidStateError'
+Expecting exception from deletedIndex.getKey(0)
+PASS Exception was thrown.
+PASS code is DOMException.INVALID_STATE_ERR
+PASS ename is 'InvalidStateError'
+Expecting exception from deletedIndex.count()
+PASS Exception was thrown.
+PASS code is DOMException.INVALID_STATE_ERR
+PASS ename is 'InvalidStateError'
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
Added: trunk/LayoutTests/storage/indexeddb/deleted-objects.html (0 => 120504)
--- trunk/LayoutTests/storage/indexeddb/deleted-objects.html (rev 0)
+++ trunk/LayoutTests/storage/indexeddb/deleted-objects.html 2012-06-15 22:49:04 UTC (rev 120504)
@@ -0,0 +1,10 @@
+<html>
+<head>
+<script src=""
+<script src=""
+</head>
+<body>
+<script src=""
+<script src=""
+</body>
+</html>
Added: trunk/LayoutTests/storage/indexeddb/resources/deleted-objects.js (0 => 120504)
--- trunk/LayoutTests/storage/indexeddb/resources/deleted-objects.js (rev 0)
+++ trunk/LayoutTests/storage/indexeddb/resources/deleted-objects.js 2012-06-15 22:49:04 UTC (rev 120504)
@@ -0,0 +1,64 @@
+if (this.importScripts) {
+ importScripts('../../../fast/js/resources/js-test-pre.js');
+ importScripts('shared.js');
+}
+
+description("Test that IndexedDB objects that have been deleted throw exceptions");
+
+function test()
+{
+ removeVendorPrefixes();
+ evalAndLog("dbname = self.location.pathname");
+ evalAndLog("request = indexedDB.deleteDatabase(dbname)");
+ request._onerror_ = unexpectedErrorCallback;
+ request._onsuccess_ = openDatabase;
+}
+
+function openDatabase()
+{
+ debug("");
+ debug("openDatabase():");
+ evalAndLog("request = indexedDB.open(dbname)");
+ request._onerror_ = unexpectedErrorCallback;
+ request._onsuccess_ = function() {
+ evalAndLog("connection = request.result");
+ evalAndLog("request = connection.setVersion('1')");
+ request._onerror_ = unexpectedErrorCallback;
+ request._onsuccess_ = function() {
+ trans = request.result;
+
+ debug("");
+ evalAndLog("deletedStore = connection.createObjectStore('deletedStore')");
+ evalAndLog("store = connection.createObjectStore('store')");
+ evalAndLog("deletedIndex = store.createIndex('deletedIndex', 'path')");
+
+ debug("");
+ evalAndLog("connection.deleteObjectStore('deletedStore')");
+ evalAndLog("store.deleteIndex('deletedIndex')");
+
+ debug("");
+ evalAndExpectException("deletedStore.put(0, 0)", "DOMException.INVALID_STATE_ERR", "'InvalidStateError'");
+ evalAndExpectException("deletedStore.add(0, 0)", "DOMException.INVALID_STATE_ERR", "'InvalidStateError'");
+ evalAndExpectException("deletedStore.delete(0)", "DOMException.INVALID_STATE_ERR", "'InvalidStateError'");
+ evalAndExpectException("deletedStore.get(0)", "DOMException.INVALID_STATE_ERR", "'InvalidStateError'");
+ evalAndExpectException("deletedStore.clear()", "DOMException.INVALID_STATE_ERR", "'InvalidStateError'");
+ evalAndExpectException("deletedStore.openCursor()", "DOMException.INVALID_STATE_ERR", "'InvalidStateError'");
+ evalAndExpectException("deletedStore.createIndex('name', 'path')", "DOMException.INVALID_STATE_ERR", "'InvalidStateError'");
+ evalAndExpectException("deletedStore.index('name')", "DOMException.INVALID_STATE_ERR", "'InvalidStateError'");
+ evalAndExpectException("deletedStore.deleteIndex('name')", "DOMException.INVALID_STATE_ERR", "'InvalidStateError'");
+ evalAndExpectException("deletedStore.count()", "DOMException.INVALID_STATE_ERR", "'InvalidStateError'");
+
+ debug("");
+ evalAndExpectException("deletedIndex.openCursor()", "DOMException.INVALID_STATE_ERR", "'InvalidStateError'");
+ evalAndExpectException("deletedIndex.openKeyCursor()", "DOMException.INVALID_STATE_ERR", "'InvalidStateError'");
+ evalAndExpectException("deletedIndex.get(0)", "DOMException.INVALID_STATE_ERR", "'InvalidStateError'");
+ evalAndExpectException("deletedIndex.getKey(0)", "DOMException.INVALID_STATE_ERR", "'InvalidStateError'");
+ evalAndExpectException("deletedIndex.count()", "DOMException.INVALID_STATE_ERR", "'InvalidStateError'");
+
+ trans._onabort_ = unexpectedAbortCallback;
+ trans._oncomplete_ = finishJSTest;
+ };
+ };
+}
+
+test();
Modified: trunk/LayoutTests/storage/indexeddb/resources/transaction-basics.js (120503 => 120504)
--- trunk/LayoutTests/storage/indexeddb/resources/transaction-basics.js 2012-06-15 22:30:43 UTC (rev 120503)
+++ trunk/LayoutTests/storage/indexeddb/resources/transaction-basics.js 2012-06-15 22:49:04 UTC (rev 120504)
@@ -48,7 +48,7 @@
var index = evalAndLog("index = store.createIndex('indexFail', 'x')");
evalAndLog("db.deleteObjectStore('storeFail')");
- evalAndLog("store.deleteIndex('indexFail')");
+ evalAndExpectException("store.deleteIndex('indexFail')", "DOMException.INVALID_STATE_ERR", "'InvalidStateError'");
trans.abort();
}
@@ -74,7 +74,7 @@
var index = evalAndLog("index = store.createIndex('indexFail', 'x')");
evalAndLog("db.deleteObjectStore('storeFail')");
- evalAndLog("store.deleteIndex('indexFail')");
+ evalAndExpectException("store.deleteIndex('indexFail')", "DOMException.INVALID_STATE_ERR", "'InvalidStateError'");
var store = evalAndLog("store = db.createObjectStore('storeFail', null)");
var index = evalAndLog("index = store.createIndex('indexFail', 'x')");
Modified: trunk/LayoutTests/storage/indexeddb/transaction-basics-expected.txt (120503 => 120504)
--- trunk/LayoutTests/storage/indexeddb/transaction-basics-expected.txt 2012-06-15 22:30:43 UTC (rev 120503)
+++ trunk/LayoutTests/storage/indexeddb/transaction-basics-expected.txt 2012-06-15 22:49:04 UTC (rev 120504)
@@ -20,7 +20,10 @@
store = db.createObjectStore('storeFail', null)
index = store.createIndex('indexFail', 'x')
db.deleteObjectStore('storeFail')
-store.deleteIndex('indexFail')
+Expecting exception from store.deleteIndex('indexFail')
+PASS Exception was thrown.
+PASS code is DOMException.INVALID_STATE_ERR
+PASS ename is 'InvalidStateError'
testSetVersionAbort2():
PASS self.db.objectStoreNames is []
@@ -33,7 +36,10 @@
store = db.createObjectStore('storeFail', null)
index = store.createIndex('indexFail', 'x')
db.deleteObjectStore('storeFail')
-store.deleteIndex('indexFail')
+Expecting exception from store.deleteIndex('indexFail')
+PASS Exception was thrown.
+PASS code is DOMException.INVALID_STATE_ERR
+PASS ename is 'InvalidStateError'
store = db.createObjectStore('storeFail', null)
index = store.createIndex('indexFail', 'x')
Modified: trunk/Source/WebCore/ChangeLog (120503 => 120504)
--- trunk/Source/WebCore/ChangeLog 2012-06-15 22:30:43 UTC (rev 120503)
+++ trunk/Source/WebCore/ChangeLog 2012-06-15 22:49:04 UTC (rev 120504)
@@ -1,3 +1,49 @@
+2012-06-15 Joshua Bell <[email protected]>
+
+ IndexedDB: Raise exceptions when methods are called on deleted objects
+ https://bugs.webkit.org/show_bug.cgi?id=89243
+
+ Reviewed by Tony Chang.
+
+ Implement the IDB spec requirement that InvalidStateError exceptions are
+ thrown when methods are called on objects (i.e. object stores and indexes)
+ that have been deleted within a version change transaction.
+
+ Test: storage/indexeddb/deleted-objects.html
+
+ * Modules/indexeddb/IDBDatabase.cpp:
+ (WebCore::IDBDatabase::deleteObjectStore): Don't relay to transaction if back-end failed.
+ * Modules/indexeddb/IDBIndex.cpp: Check deleted state in methods, raise if set.
+ (WebCore::IDBIndex::IDBIndex):
+ (WebCore::IDBIndex::openCursor):
+ (WebCore::IDBIndex::count):
+ (WebCore::IDBIndex::openKeyCursor):
+ (WebCore::IDBIndex::get):
+ (WebCore::IDBIndex::getKey):
+ * Modules/indexeddb/IDBIndex.h: Add flag to track deleted state, method to mark it.
+ (WebCore::IDBIndex::markDeleted):
+ (IDBIndex):
+ * Modules/indexeddb/IDBObjectStore.cpp: Check deleted state in methods, raise if set.
+ (WebCore::IDBObjectStore::IDBObjectStore):
+ (WebCore::IDBObjectStore::get):
+ (WebCore::IDBObjectStore::add):
+ (WebCore::IDBObjectStore::put):
+ (WebCore::IDBObjectStore::deleteFunction):
+ (WebCore::IDBObjectStore::clear):
+ (WebCore::IDBObjectStore::createIndex):
+ (WebCore::IDBObjectStore::index):
+ (WebCore::IDBObjectStore::deleteIndex): If the index being deleted has been instantiated,
+ mark it as deleted.
+ (WebCore::IDBObjectStore::openCursor):
+ (WebCore::IDBObjectStore::count):
+ * Modules/indexeddb/IDBObjectStore.h: Add flag to track deleted state, method to mark it.
+ (WebCore::IDBObjectStore::markDeleted):
+ (IDBObjectStore):
+ * Modules/indexeddb/IDBTransaction.cpp:
+ (WebCore::IDBTransaction::objectStore):
+ (WebCore::IDBTransaction::objectStoreDeleted): If the store being deleted has been instantiated,
+ mark it as deleted.
+
2012-06-15 James Robinson <[email protected]>
[chromium] Fix LayoutTests/platform/chromium/compositing/accelerated-drawing/svg-filters.html
Modified: trunk/Source/WebCore/Modules/indexeddb/IDBDatabase.cpp (120503 => 120504)
--- trunk/Source/WebCore/Modules/indexeddb/IDBDatabase.cpp 2012-06-15 22:30:43 UTC (rev 120503)
+++ trunk/Source/WebCore/Modules/indexeddb/IDBDatabase.cpp 2012-06-15 22:49:04 UTC (rev 120504)
@@ -149,7 +149,8 @@
}
m_backend->deleteObjectStore(name, m_versionChangeTransaction->backend(), ec);
- m_versionChangeTransaction->objectStoreDeleted(name);
+ if (!ec)
+ m_versionChangeTransaction->objectStoreDeleted(name);
}
PassRefPtr<IDBVersionChangeRequest> IDBDatabase::setVersion(ScriptExecutionContext* context, const String& version, ExceptionCode& ec)
Modified: trunk/Source/WebCore/Modules/indexeddb/IDBIndex.cpp (120503 => 120504)
--- trunk/Source/WebCore/Modules/indexeddb/IDBIndex.cpp 2012-06-15 22:30:43 UTC (rev 120503)
+++ trunk/Source/WebCore/Modules/indexeddb/IDBIndex.cpp 2012-06-15 22:49:04 UTC (rev 120504)
@@ -46,6 +46,7 @@
: m_backend(backend)
, m_objectStore(objectStore)
, m_transaction(transaction)
+ , m_deleted(false)
{
ASSERT(m_backend);
ASSERT(m_objectStore);
@@ -59,6 +60,10 @@
PassRefPtr<IDBRequest> IDBIndex::openCursor(ScriptExecutionContext* context, PassRefPtr<IDBKeyRange> keyRange, const String& directionString, ExceptionCode& ec)
{
IDB_TRACE("IDBIndex::openCursor");
+ if (m_deleted) {
+ ec = IDBDatabaseException::IDB_INVALID_STATE_ERR;
+ return 0;
+ }
unsigned short direction = IDBCursor::stringToDirection(directionString, ec);
if (ec)
return 0;
@@ -105,6 +110,10 @@
PassRefPtr<IDBRequest> IDBIndex::count(ScriptExecutionContext* context, PassRefPtr<IDBKeyRange> keyRange, ExceptionCode& ec)
{
IDB_TRACE("IDBIndex::count");
+ if (m_deleted) {
+ ec = IDBDatabaseException::IDB_INVALID_STATE_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) {
@@ -126,6 +135,10 @@
PassRefPtr<IDBRequest> IDBIndex::openKeyCursor(ScriptExecutionContext* context, PassRefPtr<IDBKeyRange> keyRange, const String& directionString, ExceptionCode& ec)
{
IDB_TRACE("IDBIndex::openKeyCursor");
+ if (m_deleted) {
+ ec = IDBDatabaseException::IDB_INVALID_STATE_ERR;
+ return 0;
+ }
unsigned short direction = IDBCursor::stringToDirection(directionString, ec);
if (ec)
@@ -173,6 +186,10 @@
PassRefPtr<IDBRequest> IDBIndex::get(ScriptExecutionContext* context, PassRefPtr<IDBKey> key, ExceptionCode& ec)
{
IDB_TRACE("IDBIndex::get");
+ if (m_deleted) {
+ ec = IDBDatabaseException::IDB_INVALID_STATE_ERR;
+ return 0;
+ }
if (key && (key->type() == IDBKey::InvalidType)) {
ec = IDBDatabaseException::DATA_ERR;
return 0;
@@ -188,6 +205,10 @@
PassRefPtr<IDBRequest> IDBIndex::get(ScriptExecutionContext* context, PassRefPtr<IDBKeyRange> keyRange, ExceptionCode& ec)
{
IDB_TRACE("IDBIndex::get");
+ if (m_deleted) {
+ ec = IDBDatabaseException::IDB_INVALID_STATE_ERR;
+ return 0;
+ }
if (!keyRange) {
ec = IDBDatabaseException::DATA_ERR;
return 0;
@@ -205,6 +226,10 @@
PassRefPtr<IDBRequest> IDBIndex::getKey(ScriptExecutionContext* context, PassRefPtr<IDBKey> key, ExceptionCode& ec)
{
IDB_TRACE("IDBIndex::getKey");
+ if (m_deleted) {
+ ec = IDBDatabaseException::IDB_INVALID_STATE_ERR;
+ return 0;
+ }
if (key && (key->type() == IDBKey::InvalidType)) {
ec = IDBDatabaseException::DATA_ERR;
return 0;
@@ -220,6 +245,10 @@
PassRefPtr<IDBRequest> IDBIndex::getKey(ScriptExecutionContext* context, PassRefPtr<IDBKeyRange> keyRange, ExceptionCode& ec)
{
IDB_TRACE("IDBIndex::getKey");
+ if (m_deleted) {
+ ec = IDBDatabaseException::IDB_INVALID_STATE_ERR;
+ return 0;
+ }
if (!keyRange) {
ec = IDBDatabaseException::DATA_ERR;
return 0;
Modified: trunk/Source/WebCore/Modules/indexeddb/IDBIndex.h (120503 => 120504)
--- trunk/Source/WebCore/Modules/indexeddb/IDBIndex.h 2012-06-15 22:30:43 UTC (rev 120503)
+++ trunk/Source/WebCore/Modules/indexeddb/IDBIndex.h 2012-06-15 22:49:04 UTC (rev 120504)
@@ -80,12 +80,15 @@
PassRefPtr<IDBRequest> getKey(ScriptExecutionContext*, PassRefPtr<IDBKeyRange>, ExceptionCode&);
PassRefPtr<IDBRequest> getKey(ScriptExecutionContext*, PassRefPtr<IDBKey>, ExceptionCode&);
+ void markDeleted() { m_deleted = true; }
+
private:
IDBIndex(PassRefPtr<IDBIndexBackendInterface>, IDBObjectStore*, IDBTransaction*);
RefPtr<IDBIndexBackendInterface> m_backend;
RefPtr<IDBObjectStore> m_objectStore;
RefPtr<IDBTransaction> m_transaction;
+ bool m_deleted;
};
} // namespace WebCore
Modified: trunk/Source/WebCore/Modules/indexeddb/IDBObjectStore.cpp (120503 => 120504)
--- trunk/Source/WebCore/Modules/indexeddb/IDBObjectStore.cpp 2012-06-15 22:30:43 UTC (rev 120503)
+++ trunk/Source/WebCore/Modules/indexeddb/IDBObjectStore.cpp 2012-06-15 22:49:04 UTC (rev 120504)
@@ -47,6 +47,7 @@
IDBObjectStore::IDBObjectStore(PassRefPtr<IDBObjectStoreBackendInterface> idbObjectStore, IDBTransaction* transaction)
: m_backend(idbObjectStore)
, m_transaction(transaction)
+ , m_deleted(false)
{
ASSERT(m_backend);
ASSERT(m_transaction);
@@ -104,6 +105,11 @@
PassRefPtr<IDBRequest> IDBObjectStore::get(ScriptExecutionContext* context, PassRefPtr<IDBKey> key, ExceptionCode& ec)
{
IDB_TRACE("IDBObjectStore::get");
+ if (m_deleted) {
+ ec = IDBDatabaseException::IDB_INVALID_STATE_ERR;
+ return 0;
+ }
+
if (!key || (key->type() == IDBKey::InvalidType)) {
ec = IDBDatabaseException::DATA_ERR;
return 0;
@@ -118,6 +124,10 @@
PassRefPtr<IDBRequest> IDBObjectStore::add(ScriptExecutionContext* context, PassRefPtr<SerializedScriptValue> prpValue, PassRefPtr<IDBKey> key, ExceptionCode& ec)
{
IDB_TRACE("IDBObjectStore::add");
+ if (m_deleted) {
+ ec = IDBDatabaseException::IDB_INVALID_STATE_ERR;
+ return 0;
+ }
if (m_transaction->isReadOnly()) {
ec = IDBDatabaseException::READ_ONLY_ERR;
return 0;
@@ -147,6 +157,10 @@
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;
+ return 0;
+ }
if (m_transaction->isReadOnly()) {
ec = IDBDatabaseException::READ_ONLY_ERR;
return 0;
@@ -176,6 +190,10 @@
PassRefPtr<IDBRequest> IDBObjectStore::deleteFunction(ScriptExecutionContext* context, PassRefPtr<IDBKeyRange> keyRange, ExceptionCode& ec)
{
IDB_TRACE("IDBObjectStore::delete");
+ if (m_deleted) {
+ ec = IDBDatabaseException::IDB_INVALID_STATE_ERR;
+ return 0;
+ }
if (m_transaction->isReadOnly()) {
ec = IDBDatabaseException::READ_ONLY_ERR;
return 0;
@@ -198,6 +216,10 @@
PassRefPtr<IDBRequest> IDBObjectStore::deleteFunction(ScriptExecutionContext* context, PassRefPtr<IDBKey> key, ExceptionCode& ec)
{
IDB_TRACE("IDBObjectStore::delete");
+ if (m_deleted) {
+ ec = IDBDatabaseException::IDB_INVALID_STATE_ERR;
+ return 0;
+ }
if (m_transaction->isReadOnly()) {
ec = IDBDatabaseException::READ_ONLY_ERR;
return 0;
@@ -220,6 +242,10 @@
PassRefPtr<IDBRequest> IDBObjectStore::clear(ScriptExecutionContext* context, ExceptionCode& ec)
{
IDB_TRACE("IDBObjectStore::clear");
+ if (m_deleted) {
+ ec = IDBDatabaseException::IDB_INVALID_STATE_ERR;
+ return 0;
+ }
if (m_transaction->isReadOnly()) {
ec = IDBDatabaseException::READ_ONLY_ERR;
return 0;
@@ -251,6 +277,11 @@
PassRefPtr<IDBIndex> IDBObjectStore::createIndex(const String& name, const IDBKeyPath& keyPath, const Dictionary& options, ExceptionCode& ec)
{
IDB_TRACE("IDBObjectStore::createIndex");
+ if (!m_transaction->isVersionChange() || m_deleted) {
+ ec = IDBDatabaseException::IDB_INVALID_STATE_ERR;
+ return 0;
+ }
+
if (!keyPath.isValid()) {
ec = IDBDatabaseException::IDB_SYNTAX_ERR;
return 0;
@@ -269,16 +300,22 @@
RefPtr<IDBIndexBackendInterface> indexBackend = m_backend->createIndex(name, keyPath, unique, multiEntry, m_transaction->backend(), ec);
ASSERT(!indexBackend != !ec); // If we didn't get an index, we should have gotten an exception code. And vice versa.
- if (!indexBackend)
+ if (ec)
return 0;
+
RefPtr<IDBIndex> index = IDBIndex::create(indexBackend.release(), this, m_transaction.get());
m_indexMap.set(name, index);
+
return index.release();
}
PassRefPtr<IDBIndex> IDBObjectStore::index(const String& name, ExceptionCode& ec)
{
IDB_TRACE("IDBObjectStore::index");
+ if (m_deleted) {
+ ec = IDBDatabaseException::IDB_INVALID_STATE_ERR;
+ return 0;
+ }
if (m_transaction->isFinished()) {
ec = IDBDatabaseException::IDB_INVALID_STATE_ERR;
return 0;
@@ -290,7 +327,7 @@
RefPtr<IDBIndexBackendInterface> indexBackend = m_backend->index(name, ec);
ASSERT(!indexBackend != !ec); // If we didn't get an index, we should have gotten an exception code. And vice versa.
- if (!indexBackend)
+ if (ec)
return 0;
RefPtr<IDBIndex> index = IDBIndex::create(indexBackend.release(), this, m_transaction.get());
@@ -300,12 +337,28 @@
void IDBObjectStore::deleteIndex(const String& name, ExceptionCode& ec)
{
+ if (!m_transaction->isVersionChange() || m_deleted) {
+ ec = IDBDatabaseException::IDB_INVALID_STATE_ERR;
+ return;
+ }
+
m_backend->deleteIndex(name, m_transaction->backend(), ec);
+ if (!ec) {
+ IDBIndexMap::iterator it = m_indexMap.find(name);
+ if (it != m_indexMap.end()) {
+ it->second->markDeleted();
+ m_indexMap.remove(name);
+ }
+ }
}
PassRefPtr<IDBRequest> IDBObjectStore::openCursor(ScriptExecutionContext* context, PassRefPtr<IDBKeyRange> range, const String& directionString, ExceptionCode& ec)
{
IDB_TRACE("IDBObjectStore::openCursor");
+ if (m_deleted) {
+ ec = IDBDatabaseException::IDB_INVALID_STATE_ERR;
+ return 0;
+ }
unsigned short direction = IDBCursor::stringToDirection(directionString, ec);
if (ec)
return 0;
@@ -352,6 +405,10 @@
PassRefPtr<IDBRequest> IDBObjectStore::count(ScriptExecutionContext* context, PassRefPtr<IDBKeyRange> range, ExceptionCode& ec)
{
IDB_TRACE("IDBObjectStore::count");
+ if (m_deleted) {
+ ec = IDBDatabaseException::IDB_INVALID_STATE_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 (120503 => 120504)
--- trunk/Source/WebCore/Modules/indexeddb/IDBObjectStore.h 2012-06-15 22:30:43 UTC (rev 120503)
+++ trunk/Source/WebCore/Modules/indexeddb/IDBObjectStore.h 2012-06-15 22:49:04 UTC (rev 120504)
@@ -94,6 +94,7 @@
PassRefPtr<IDBRequest> count(ScriptExecutionContext*, PassRefPtr<IDBKeyRange>, ExceptionCode&);
PassRefPtr<IDBRequest> count(ScriptExecutionContext*, PassRefPtr<IDBKey>, ExceptionCode&);
+ void markDeleted() { m_deleted = true; }
void transactionFinished();
private:
@@ -102,6 +103,7 @@
RefPtr<IDBObjectStoreBackendInterface> m_backend;
RefPtr<IDBTransaction> m_transaction;
+ bool m_deleted;
typedef HashMap<String, RefPtr<IDBIndex> > IDBIndexMap;
IDBIndexMap m_indexMap;
Modified: trunk/Source/WebCore/Modules/indexeddb/IDBTransaction.cpp (120503 => 120504)
--- trunk/Source/WebCore/Modules/indexeddb/IDBTransaction.cpp 2012-06-15 22:30:43 UTC (rev 120503)
+++ trunk/Source/WebCore/Modules/indexeddb/IDBTransaction.cpp 2012-06-15 22:49:04 UTC (rev 120504)
@@ -154,10 +154,10 @@
return it->second;
RefPtr<IDBObjectStoreBackendInterface> objectStoreBackend = m_backend->objectStore(name, ec);
- if (!objectStoreBackend) {
- ASSERT(ec);
+ ASSERT(!objectStoreBackend != !ec); // If we didn't get a store, we should have gotten an exception code. And vice versa.
+ if (ec)
return 0;
- }
+
RefPtr<IDBObjectStore> objectStore = IDBObjectStore::create(objectStoreBackend, this);
objectStoreCreated(name, objectStore);
return objectStore.release();
@@ -172,7 +172,12 @@
void IDBTransaction::objectStoreDeleted(const String& name)
{
ASSERT(!m_transactionFinished);
- m_objectStoreMap.remove(name);
+ IDBObjectStoreMap::iterator it = m_objectStoreMap.find(name);
+ if (it != m_objectStoreMap.end()) {
+ RefPtr<IDBObjectStore> objectStore = it->second;
+ m_objectStoreMap.remove(name);
+ objectStore->markDeleted();
+ }
}
void IDBTransaction::abort()