IndexedDB: Methods should throw TRANSACTION_INACTIVE_ERR when transaction is complete...
authorcommit-queue@webkit.org <commit-queue@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 12 Jan 2012 01:02:49 +0000 (01:02 +0000)
committercommit-queue@webkit.org <commit-queue@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 12 Jan 2012 01:02:49 +0000 (01:02 +0000)
https://bugs.webkit.org/show_bug.cgi?id=76108

Source/WebCore:

Updated IDBDatabaseException error codes to match spec (the pre-DOM4 version),
including updated description strings, and changed relevant store and index
methods to raise the expected exception type now that it is detailed in the spec.

Patch by Joshua Bell <jsbell@chromium.org> on 2012-01-11
Reviewed by Tony Chang.

Tests: storage/indexeddb/transaction-basics.html

* storage/IDBCursorBackendImpl.cpp:
(WebCore::IDBCursorBackendImpl::continueFunction):
(WebCore::IDBCursorBackendImpl::prefetchContinue):
* storage/IDBDatabaseException.cpp:
* storage/IDBDatabaseException.h:
* storage/IDBDatabaseException.idl:
* storage/IDBIndexBackendImpl.cpp:
(WebCore::IDBIndexBackendImpl::openCursor):
(WebCore::IDBIndexBackendImpl::openKeyCursor):
(WebCore::IDBIndexBackendImpl::count):
(WebCore::IDBIndexBackendImpl::get):
(WebCore::IDBIndexBackendImpl::getKey):
* storage/IDBObjectStoreBackendImpl.cpp:
(WebCore::IDBObjectStoreBackendImpl::get):
(WebCore::IDBObjectStoreBackendImpl::put):
(WebCore::IDBObjectStoreBackendImpl::deleteFunction):
(WebCore::IDBObjectStoreBackendImpl::clear):
(WebCore::IDBObjectStoreBackendImpl::createIndex):
(WebCore::IDBObjectStoreBackendImpl::deleteIndex):
(WebCore::IDBObjectStoreBackendImpl::openCursor):
(WebCore::IDBObjectStoreBackendImpl::count):

LayoutTests:

Patch by Joshua Bell <jsbell@chromium.org> on 2012-01-11
Reviewed by Tony Chang.

* storage/indexeddb/constants-expected.txt:
* storage/indexeddb/constants.html:
* storage/indexeddb/deleteIndex-expected.txt:
* storage/indexeddb/deleteIndex.html:
* storage/indexeddb/set_version_queue-expected.txt:
* storage/indexeddb/set_version_queue.html:
* storage/indexeddb/transaction-abort-expected.txt:
* storage/indexeddb/transaction-abort.html:
* storage/indexeddb/transaction-basics-expected.txt:
* storage/indexeddb/transaction-basics.html:

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@104771 268f45cc-cd09-0410-ab3c-d52691b4dbfc

18 files changed:
LayoutTests/ChangeLog
LayoutTests/storage/indexeddb/constants-expected.txt
LayoutTests/storage/indexeddb/constants.html
LayoutTests/storage/indexeddb/deleteIndex-expected.txt
LayoutTests/storage/indexeddb/deleteIndex.html
LayoutTests/storage/indexeddb/set_version_queue-expected.txt
LayoutTests/storage/indexeddb/set_version_queue.html
LayoutTests/storage/indexeddb/transaction-abort-expected.txt
LayoutTests/storage/indexeddb/transaction-abort.html
LayoutTests/storage/indexeddb/transaction-basics-expected.txt
LayoutTests/storage/indexeddb/transaction-basics.html
Source/WebCore/ChangeLog
Source/WebCore/storage/IDBCursorBackendImpl.cpp
Source/WebCore/storage/IDBDatabaseException.cpp
Source/WebCore/storage/IDBDatabaseException.h
Source/WebCore/storage/IDBDatabaseException.idl
Source/WebCore/storage/IDBIndexBackendImpl.cpp
Source/WebCore/storage/IDBObjectStoreBackendImpl.cpp

index f72adf5..7d1a81b 100644 (file)
@@ -1,3 +1,21 @@
+2012-01-11  Joshua Bell  <jsbell@chromium.org>
+
+        IndexedDB: Methods should throw TRANSACTION_INACTIVE_ERR when transaction is completed/aborted
+        https://bugs.webkit.org/show_bug.cgi?id=76108
+
+        Reviewed by Tony Chang.
+
+        * storage/indexeddb/constants-expected.txt:
+        * storage/indexeddb/constants.html:
+        * storage/indexeddb/deleteIndex-expected.txt:
+        * storage/indexeddb/deleteIndex.html:
+        * storage/indexeddb/set_version_queue-expected.txt:
+        * storage/indexeddb/set_version_queue.html:
+        * storage/indexeddb/transaction-abort-expected.txt:
+        * storage/indexeddb/transaction-abort.html:
+        * storage/indexeddb/transaction-basics-expected.txt:
+        * storage/indexeddb/transaction-basics.html:
+
 2012-01-11  Wei Jia  <wjia@chromium.org>
 
         implement layout tests for <video> with media stream
index 4516f7e..2b86df9 100644 (file)
@@ -9,11 +9,12 @@ PASS webkitIDBDatabaseException.NOT_FOUND_ERR is 3
 PASS webkitIDBDatabaseException.CONSTRAINT_ERR is 4
 PASS webkitIDBDatabaseException.DATA_ERR is 5
 PASS webkitIDBDatabaseException.NOT_ALLOWED_ERR is 6
-PASS webkitIDBDatabaseException.SERIAL_ERR is 7
-PASS webkitIDBDatabaseException.RECOVERABLE_ERR is 8
-PASS webkitIDBDatabaseException.TRANSIENT_ERR is 9
+PASS webkitIDBDatabaseException.TRANSACTION_INACTIVE_ERR is 7
+PASS webkitIDBDatabaseException.ABORT_ERR is 8
+PASS webkitIDBDatabaseException.READ_ONLY_ERR is 9
 PASS webkitIDBDatabaseException.TIMEOUT_ERR is 10
-PASS webkitIDBDatabaseException.DEADLOCK_ERR is 11
+PASS webkitIDBDatabaseException.QUOTA_ERR is 11
+PASS webkitIDBDatabaseException.VER_ERR is 12
 PASS webkitIDBRequest.LOADING is 1
 PASS webkitIDBRequest.DONE is 2
 PASS webkitIDBCursor.NEXT is 0
index d0e032a..a161e9e 100644 (file)
@@ -9,7 +9,7 @@
 <script>
 
 description("Test IndexedDB's constants.");
-if (window.layoutTestController) 
+if (window.layoutTestController)
     layoutTestController.waitUntilDone();
 
 function test()
@@ -20,11 +20,12 @@ function test()
     shouldBe("webkitIDBDatabaseException.CONSTRAINT_ERR", "4");
     shouldBe("webkitIDBDatabaseException.DATA_ERR", "5");
     shouldBe("webkitIDBDatabaseException.NOT_ALLOWED_ERR", "6");
-    shouldBe("webkitIDBDatabaseException.SERIAL_ERR", "7");
-    shouldBe("webkitIDBDatabaseException.RECOVERABLE_ERR", "8");
-    shouldBe("webkitIDBDatabaseException.TRANSIENT_ERR", "9");
+    shouldBe("webkitIDBDatabaseException.TRANSACTION_INACTIVE_ERR", "7");
+    shouldBe("webkitIDBDatabaseException.ABORT_ERR", "8");
+    shouldBe("webkitIDBDatabaseException.READ_ONLY_ERR", "9");
     shouldBe("webkitIDBDatabaseException.TIMEOUT_ERR", "10");
-    shouldBe("webkitIDBDatabaseException.DEADLOCK_ERR", "11");
+    shouldBe("webkitIDBDatabaseException.QUOTA_ERR", "11");
+    shouldBe("webkitIDBDatabaseException.VER_ERR", "12");
 
     shouldBe("webkitIDBRequest.LOADING", "1");
     shouldBe("webkitIDBRequest.DONE", "2");
index c3d1e55..106b2ff 100644 (file)
@@ -29,7 +29,7 @@ PASS Exception was thrown.
 PASS code is IDBDatabaseException.NOT_ALLOWED_ERR
 Expecting exception from objectStore.deleteIndex('second')
 PASS Exception was thrown.
-PASS code is IDBDatabaseException.NOT_ALLOWED_ERR
+PASS code is IDBDatabaseException.TRANSACTION_INACTIVE_ERR
 PASS successfullyParsed is true
 
 TEST COMPLETE
index c67e8e1..4a70743 100644 (file)
@@ -56,7 +56,7 @@ function twiddleIndexes()
 function postTwiddling()
 {
     evalAndExpectException("db.createObjectStore('bar');", "IDBDatabaseException.NOT_ALLOWED_ERR");
-    evalAndExpectException("objectStore.deleteIndex('second')", "IDBDatabaseException.NOT_ALLOWED_ERR");
+    evalAndExpectException("objectStore.deleteIndex('second')", "IDBDatabaseException.TRANSACTION_INACTIVE_ERR");
     done();
 }
 
index 4130bf2..edaa022 100644 (file)
@@ -3,11 +3,14 @@
 On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
 
 
-PASS IndexedDB == null is false
-IndexedDB.open('set-version-queue')
-IndexedDB.open('set-version-queue')
-IndexedDB.open('set-version-queue')
-IndexedDB.open('set-version-queue')
+window.indexedDB = window.indexedDB || window.webkitIndexedDB
+PASS indexedDB != null is true
+IDBDatabaseException = window.IDBDatabaseException || window.webkitIDBDatabaseException
+PASS IDBDatabaseException != null is true
+indexedDB.open('set-version-queue')
+indexedDB.open('set-version-queue')
+indexedDB.open('set-version-queue')
+indexedDB.open('set-version-queue')
 connections[0].setVersion('version 0')
 connections[1].setVersion('version 1')
 connections[2].setVersion('version 2')
@@ -52,17 +55,17 @@ Note: This means that a connection can receive a blocked event after its close()
 PASS event.version is "version 3"
 
 PASS connection[0] got error event
-PASS event.target.errorCode is 13
+PASS event.target.errorCode is IDBDatabaseException.ABORT_ERR
 PASS event.target.webkitErrorMessage.length > 0 is true
 Connection was closed before set version transaction was created
 
 PASS connection[2] got error event
-PASS event.target.errorCode is 13
+PASS event.target.errorCode is IDBDatabaseException.ABORT_ERR
 PASS event.target.webkitErrorMessage.length > 0 is true
 Connection was closed before set version transaction was created
 
 PASS connection[3] got error event
-PASS event.target.errorCode is 13
+PASS event.target.errorCode is IDBDatabaseException.ABORT_ERR
 PASS event.target.webkitErrorMessage.length > 0 is true
 Connection was closed before set version transaction was created
 
index 16a94d0..7975709 100644 (file)
@@ -15,17 +15,17 @@ if (window.layoutTestController)
 connections = []\r
 function test()\r
 {\r
-    if ('webkitIndexedDB' in window)\r
-        IndexedDB = webkitIndexedDB;\r
-    else if ('mozIndexedDB' in window)\r
-        IndexedDB = mozIndexedDB;\r
-    shouldBeFalse("IndexedDB == null");\r
+    evalAndLog("window.indexedDB = window.indexedDB || window.webkitIndexedDB");\r
+    shouldBeTrue("indexedDB != null");\r
+    evalAndLog("IDBDatabaseException = window.IDBDatabaseException || window.webkitIDBDatabaseException");\r
+    shouldBeTrue("IDBDatabaseException != null");\r
+\r
     openDBConnection();\r
 }\r
 \r
 function openDBConnection()\r
 {\r
-    result = evalAndLog("IndexedDB.open('set-version-queue')");\r
+    result = evalAndLog("indexedDB.open('set-version-queue')");\r
     result.onsuccess = openSuccess;\r
     result.onerror = unexpectedErrorCallback;\r
 }\r
@@ -115,8 +115,8 @@ function connectionError(event, connectionId)
 {\r
     debug("")\r
     testPassed("connection[" + connectionId + "] got error event");\r
-    shouldBe("event.target.errorCode", "13")\r
-    if ('webkitIndexedDB' in window) {\r
+    shouldBe("event.target.errorCode", "IDBDatabaseException.ABORT_ERR")\r
+    if ('webkitErrorMessage' in event.target) {\r
         shouldBe("event.target.webkitErrorMessage.length > 0", "true");\r
         debug(event.target.webkitErrorMessage);\r
     }\r
index b2089e0..7bd3b6e 100644 (file)
@@ -3,7 +3,13 @@ Test transaction aborts send the proper onabort messages..
 On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
 
 
-webkitIndexedDB.open('name')
+window.indexedDB = window.indexedDB || window.webkitIndexedDB
+PASS indexedDB != null is true
+IDBTransaction = window.IDBTransaction || window.webkitIDBTransaction
+PASS IDBTransaction != null is true
+IDBDatabaseException = window.IDBDatabaseException || window.webkitIDBDatabaseException
+PASS IDBDatabaseException != null is true
+indexedDB.open('name')
 db = event.target.result
 db.setVersion('new version')
 setVersionSuccess():
@@ -13,20 +19,20 @@ trans.oncomplete = startTest
 Deleted all object stores.
 store = db.createObjectStore('storeName', null)
 store.add({x: 'value', y: 'zzz'}, 'key')
-trans = db.transaction(['storeName'], webkitIDBTransaction.READ_WRITE)
+trans = db.transaction(['storeName'], IDBTransaction.READ_WRITE)
 trans.onabort = transactionAborted
 trans.oncomplete = unexpectedCompleteCallback
 store = trans.objectStore('storeName')
 store.add({x: 'value2', y: 'zzz2'}, 'key2')
 store.add({x: 'value3', y: 'zzz3'}, 'key3')
-PASS event.target.errorCode is webkitIDBDatabaseException.ABORT_ERR
+PASS event.target.errorCode is IDBDatabaseException.ABORT_ERR
 PASS firstError is false
 PASS secondError is false
 PASS abortFired is false
 Expecting exception from store.add({x: 'value4', y: 'zzz4'}, 'key4')
 PASS Exception was thrown.
-PASS code is webkitIDBDatabaseException.NOT_ALLOWED_ERR
-PASS event.target.errorCode is webkitIDBDatabaseException.ABORT_ERR
+PASS code is IDBDatabaseException.TRANSACTION_INACTIVE_ERR
+PASS event.target.errorCode is IDBDatabaseException.ABORT_ERR
 PASS firstError is true
 PASS secondError is false
 PASS abortFired is false
@@ -35,7 +41,7 @@ PASS secondError is true
 PASS abortFired is false
 Expecting exception from store.add({x: 'value5', y: 'zzz5'}, 'key5')
 PASS Exception was thrown.
-PASS code is webkitIDBDatabaseException.NOT_ALLOWED_ERR
+PASS code is IDBDatabaseException.TRANSACTION_INACTIVE_ERR
 PASS successfullyParsed is true
 
 TEST COMPLETE
index 1b4a563..debba62 100644 (file)
@@ -14,7 +14,14 @@ if (window.layoutTestController)
 
 function test()
 {
-    request = evalAndLog("webkitIndexedDB.open('name')");
+    evalAndLog("window.indexedDB = window.indexedDB || window.webkitIndexedDB");
+    shouldBeTrue("indexedDB != null");
+    evalAndLog("IDBTransaction = window.IDBTransaction || window.webkitIDBTransaction");
+    shouldBeTrue("IDBTransaction != null");
+    evalAndLog("IDBDatabaseException = window.IDBDatabaseException || window.webkitIDBDatabaseException");
+    shouldBeTrue("IDBDatabaseException != null");
+
+    request = evalAndLog("indexedDB.open('name')");
     request.onsuccess = setVersion;
     request.onerror = unexpectedErrorCallback;
 }
@@ -45,7 +52,7 @@ function deleteExisting()
 
 function startTest()
 {
-    trans = evalAndLog("trans = db.transaction(['storeName'], webkitIDBTransaction.READ_WRITE)");
+    trans = evalAndLog("trans = db.transaction(['storeName'], IDBTransaction.READ_WRITE)");
     evalAndLog("trans.onabort = transactionAborted");
     evalAndLog("trans.oncomplete = unexpectedCompleteCallback");
     store = evalAndLog("store = trans.objectStore('storeName')");
@@ -63,18 +70,18 @@ function startTest()
 
 function firstAdd()
 {
-    shouldBe("event.target.errorCode", "webkitIDBDatabaseException.ABORT_ERR");
+    shouldBe("event.target.errorCode", "IDBDatabaseException.ABORT_ERR");
     shouldBeFalse("firstError");
     shouldBeFalse("secondError");
     shouldBeFalse("abortFired");
     firstError = true;
 
-    evalAndExpectException("store.add({x: 'value4', y: 'zzz4'}, 'key4')", "webkitIDBDatabaseException.NOT_ALLOWED_ERR");
+    evalAndExpectException("store.add({x: 'value4', y: 'zzz4'}, 'key4')", "IDBDatabaseException.TRANSACTION_INACTIVE_ERR");
 }
 
 function secondAdd()
 {
-    shouldBe("event.target.errorCode", "webkitIDBDatabaseException.ABORT_ERR");
+    shouldBe("event.target.errorCode", "IDBDatabaseException.ABORT_ERR");
     shouldBeTrue("firstError");
     shouldBeFalse("secondError");
     shouldBeFalse("abortFired");
@@ -88,7 +95,7 @@ function transactionAborted()
     shouldBeFalse("abortFired");
     abortFired = true;
 
-    evalAndExpectException("store.add({x: 'value5', y: 'zzz5'}, 'key5')", "webkitIDBDatabaseException.NOT_ALLOWED_ERR");
+    evalAndExpectException("store.add({x: 'value5', y: 'zzz5'}, 'key5')", "IDBDatabaseException.TRANSACTION_INACTIVE_ERR");
     done();
 }
 
index 5921c3d..1b612f8 100644 (file)
@@ -3,9 +3,12 @@ Test IndexedDB transaction basics.
 On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
 
 
-PASS 'webkitIndexedDB' in window is true
-PASS webkitIndexedDB == null is false
-webkitIndexedDB.open('transaction-basics')
+indexedDB = window.indexedDB || window.webkitIndexedDB || window.mozIndexedDB;
+PASS indexedDB == null is false
+IDBDatabaseException = window.IDBDatabaseException || window.webkitIDBDatabaseException;
+PASS IDBDatabaseException == null is false
+
+indexedDB.open('transaction-basics')
 openSuccess():
 db = event.target.result
 request = db.setVersion('version 1')
@@ -50,6 +53,41 @@ PASS trans !== null is true
 store = db.createObjectStore('storeFail', null)
 index = store.createIndex('indexFail', 'x', false)
 
+testInactiveAbortedTransaction():
+Expecting exception from index.openCursor()
+PASS Exception was thrown.
+PASS code is IDBDatabaseException.TRANSACTION_INACTIVE_ERR
+Expecting exception from index.openKeyCursor()
+PASS Exception was thrown.
+PASS code is IDBDatabaseException.TRANSACTION_INACTIVE_ERR
+Expecting exception from index.get(0)
+PASS Exception was thrown.
+PASS code is IDBDatabaseException.TRANSACTION_INACTIVE_ERR
+Expecting exception from index.getKey(0)
+PASS Exception was thrown.
+PASS code is IDBDatabaseException.TRANSACTION_INACTIVE_ERR
+Expecting exception from index.count()
+PASS Exception was thrown.
+PASS code is IDBDatabaseException.TRANSACTION_INACTIVE_ERR
+Expecting exception from store.put(0, 0)
+PASS Exception was thrown.
+PASS code is IDBDatabaseException.TRANSACTION_INACTIVE_ERR
+Expecting exception from store.add(0, 0)
+PASS Exception was thrown.
+PASS code is IDBDatabaseException.TRANSACTION_INACTIVE_ERR
+Expecting exception from store.delete(0)
+PASS Exception was thrown.
+PASS code is IDBDatabaseException.TRANSACTION_INACTIVE_ERR
+Expecting exception from store.clear()
+PASS Exception was thrown.
+PASS code is IDBDatabaseException.TRANSACTION_INACTIVE_ERR
+Expecting exception from store.get(0)
+PASS Exception was thrown.
+PASS code is IDBDatabaseException.TRANSACTION_INACTIVE_ERR
+Expecting exception from store.openCursor()
+PASS Exception was thrown.
+PASS code is IDBDatabaseException.TRANSACTION_INACTIVE_ERR
+
 testSetVersionAbort4():
 PASS window.db.objectStoreNames is []
 PASS window.db.objectStoreNames.length is 0
@@ -61,6 +99,41 @@ PASS trans !== null is true
 store = db.createObjectStore('storeFail', null)
 index = store.createIndex('indexFail', 'x', false)
 
+testInactiveCompletedTransaction():
+Expecting exception from index.openCursor()
+PASS Exception was thrown.
+PASS code is IDBDatabaseException.TRANSACTION_INACTIVE_ERR
+Expecting exception from index.openKeyCursor()
+PASS Exception was thrown.
+PASS code is IDBDatabaseException.TRANSACTION_INACTIVE_ERR
+Expecting exception from index.get(0)
+PASS Exception was thrown.
+PASS code is IDBDatabaseException.TRANSACTION_INACTIVE_ERR
+Expecting exception from index.getKey(0)
+PASS Exception was thrown.
+PASS code is IDBDatabaseException.TRANSACTION_INACTIVE_ERR
+Expecting exception from index.count()
+PASS Exception was thrown.
+PASS code is IDBDatabaseException.TRANSACTION_INACTIVE_ERR
+Expecting exception from store.put(0, 0)
+PASS Exception was thrown.
+PASS code is IDBDatabaseException.TRANSACTION_INACTIVE_ERR
+Expecting exception from store.add(0, 0)
+PASS Exception was thrown.
+PASS code is IDBDatabaseException.TRANSACTION_INACTIVE_ERR
+Expecting exception from store.delete(0)
+PASS Exception was thrown.
+PASS code is IDBDatabaseException.TRANSACTION_INACTIVE_ERR
+Expecting exception from store.clear()
+PASS Exception was thrown.
+PASS code is IDBDatabaseException.TRANSACTION_INACTIVE_ERR
+Expecting exception from store.get(0)
+PASS Exception was thrown.
+PASS code is IDBDatabaseException.TRANSACTION_INACTIVE_ERR
+Expecting exception from store.openCursor()
+PASS Exception was thrown.
+PASS code is IDBDatabaseException.TRANSACTION_INACTIVE_ERR
+
 testSetVersionAbort5():
 PASS db.objectStoreNames is ['storeFail']
 PASS db.objectStoreNames.length is 1
index e1f0b72..7fa1916 100644 (file)
@@ -12,10 +12,13 @@ description("Test IndexedDB transaction basics.");
 \r
 function test()\r
 {\r
-    shouldBeTrue("'webkitIndexedDB' in window");\r
-    shouldBeFalse("webkitIndexedDB == null");\r
+    indexedDB = evalAndLog("indexedDB = window.indexedDB || window.webkitIndexedDB || window.mozIndexedDB;");\r
+    shouldBeFalse("indexedDB == null");\r
+    IDBDatabaseException = evalAndLog("IDBDatabaseException = window.IDBDatabaseException || window.webkitIDBDatabaseException;");\r
+    shouldBeFalse("IDBDatabaseException == null");\r
+    debug("");\r
 \r
-    request = evalAndLog("webkitIndexedDB.open('transaction-basics')");\r
+    request = evalAndLog("indexedDB.open('transaction-basics')");\r
     request.onsuccess = openSuccess;\r
     request.onerror = unexpectedErrorCallback;\r
 }\r
@@ -104,15 +107,35 @@ function addIDBObjects()
     shouldBeFalse("event.cancelable");\r
     var trans = evalAndLog("trans = event.target.result");\r
     shouldBeTrue("trans !== null");\r
-    trans.onabort = testSetVersionAbort4;\r
+    trans.onabort = testInactiveAbortedTransaction;\r
     trans.oncomplete = unexpectedCompleteCallback;\r
 \r
-    var store = evalAndLog("store = db.createObjectStore('storeFail', null)");\r
-    var index = evalAndLog("index = store.createIndex('indexFail', 'x', false)");\r
+    store = evalAndLog("store = db.createObjectStore('storeFail', null)");\r
+    index = evalAndLog("index = store.createIndex('indexFail', 'x', false)");\r
 \r
     trans.abort();\r
 }\r
 \r
+function testInactiveAbortedTransaction()\r
+{\r
+    debug("");\r
+    debug("testInactiveAbortedTransaction():");\r
+    evalAndExpectException("index.openCursor()", "IDBDatabaseException.TRANSACTION_INACTIVE_ERR");\r
+    evalAndExpectException("index.openKeyCursor()", "IDBDatabaseException.TRANSACTION_INACTIVE_ERR");\r
+    evalAndExpectException("index.get(0)", "IDBDatabaseException.TRANSACTION_INACTIVE_ERR");\r
+    evalAndExpectException("index.getKey(0)", "IDBDatabaseException.TRANSACTION_INACTIVE_ERR");\r
+    evalAndExpectException("index.count()", "IDBDatabaseException.TRANSACTION_INACTIVE_ERR");\r
+\r
+    evalAndExpectException("store.put(0, 0)", "IDBDatabaseException.TRANSACTION_INACTIVE_ERR");\r
+    evalAndExpectException("store.add(0, 0)", "IDBDatabaseException.TRANSACTION_INACTIVE_ERR");\r
+    evalAndExpectException("store.delete(0)", "IDBDatabaseException.TRANSACTION_INACTIVE_ERR");\r
+    evalAndExpectException("store.clear()", "IDBDatabaseException.TRANSACTION_INACTIVE_ERR");\r
+    evalAndExpectException("store.get(0)", "IDBDatabaseException.TRANSACTION_INACTIVE_ERR");\r
+    evalAndExpectException("store.openCursor()", "IDBDatabaseException.TRANSACTION_INACTIVE_ERR");\r
+\r
+    testSetVersionAbort4();\r
+}\r
+\r
 function testSetVersionAbort4()\r
 {\r
     debug("");\r
@@ -129,10 +152,30 @@ function addIDBObjectsAndCommit()
     shouldBeTrue("trans !== null");\r
     trans.onabort = unexpectedAbortCallback;\r
 \r
-    var store = evalAndLog("store = db.createObjectStore('storeFail', null)");\r
-    var index = evalAndLog("index = store.createIndex('indexFail', 'x', false)");\r
+    store = evalAndLog("store = db.createObjectStore('storeFail', null)");\r
+    index = evalAndLog("index = store.createIndex('indexFail', 'x', false)");\r
+\r
+    trans.oncomplete = testInactiveCompletedTransaction;\r
+}\r
 \r
-    trans.oncomplete = testSetVersionAbort5;\r
+function testInactiveCompletedTransaction()\r
+{\r
+    debug("");\r
+    debug("testInactiveCompletedTransaction():");\r
+    evalAndExpectException("index.openCursor()", "IDBDatabaseException.TRANSACTION_INACTIVE_ERR");\r
+    evalAndExpectException("index.openKeyCursor()", "IDBDatabaseException.TRANSACTION_INACTIVE_ERR");\r
+    evalAndExpectException("index.get(0)", "IDBDatabaseException.TRANSACTION_INACTIVE_ERR");\r
+    evalAndExpectException("index.getKey(0)", "IDBDatabaseException.TRANSACTION_INACTIVE_ERR");\r
+    evalAndExpectException("index.count()", "IDBDatabaseException.TRANSACTION_INACTIVE_ERR");\r
+\r
+    evalAndExpectException("store.put(0, 0)", "IDBDatabaseException.TRANSACTION_INACTIVE_ERR");\r
+    evalAndExpectException("store.add(0, 0)", "IDBDatabaseException.TRANSACTION_INACTIVE_ERR");\r
+    evalAndExpectException("store.delete(0)", "IDBDatabaseException.TRANSACTION_INACTIVE_ERR");\r
+    evalAndExpectException("store.clear()", "IDBDatabaseException.TRANSACTION_INACTIVE_ERR");\r
+    evalAndExpectException("store.get(0)", "IDBDatabaseException.TRANSACTION_INACTIVE_ERR");\r
+    evalAndExpectException("store.openCursor()", "IDBDatabaseException.TRANSACTION_INACTIVE_ERR");\r
+\r
+    testSetVersionAbort5();\r
 }\r
 \r
 function testSetVersionAbort5()\r
index f9245ee..f075e48 100644 (file)
@@ -1,3 +1,38 @@
+2012-01-11  Joshua Bell  <jsbell@chromium.org>
+
+        IndexedDB: Methods should throw TRANSACTION_INACTIVE_ERR when transaction is completed/aborted
+        https://bugs.webkit.org/show_bug.cgi?id=76108
+
+        Updated IDBDatabaseException error codes to match spec (the pre-DOM4 version),
+        including updated description strings, and changed relevant store and index 
+        methods to raise the expected exception type now that it is detailed in the spec.
+
+        Reviewed by Tony Chang.
+
+        Tests: storage/indexeddb/transaction-basics.html
+
+        * storage/IDBCursorBackendImpl.cpp:
+        (WebCore::IDBCursorBackendImpl::continueFunction):
+        (WebCore::IDBCursorBackendImpl::prefetchContinue):
+        * storage/IDBDatabaseException.cpp:
+        * storage/IDBDatabaseException.h:
+        * storage/IDBDatabaseException.idl:
+        * storage/IDBIndexBackendImpl.cpp:
+        (WebCore::IDBIndexBackendImpl::openCursor):
+        (WebCore::IDBIndexBackendImpl::openKeyCursor):
+        (WebCore::IDBIndexBackendImpl::count):
+        (WebCore::IDBIndexBackendImpl::get):
+        (WebCore::IDBIndexBackendImpl::getKey):
+        * storage/IDBObjectStoreBackendImpl.cpp:
+        (WebCore::IDBObjectStoreBackendImpl::get):
+        (WebCore::IDBObjectStoreBackendImpl::put):
+        (WebCore::IDBObjectStoreBackendImpl::deleteFunction):
+        (WebCore::IDBObjectStoreBackendImpl::clear):
+        (WebCore::IDBObjectStoreBackendImpl::createIndex):
+        (WebCore::IDBObjectStoreBackendImpl::deleteIndex):
+        (WebCore::IDBObjectStoreBackendImpl::openCursor):
+        (WebCore::IDBObjectStoreBackendImpl::count):
+
 2012-01-11  Kentaro Hara  <haraken@chromium.org>
 
         Implement the [Supplemental] IDL for custom methods
index 2351f67..7f99463 100644 (file)
@@ -114,7 +114,7 @@ void IDBCursorBackendImpl::continueFunction(PassRefPtr<IDBKey> prpKey, PassRefPt
     }
 
     if (!m_transaction->scheduleTask(createCallbackTask(&IDBCursorBackendImpl::continueFunctionInternal, this, key, prpCallbacks)))
-        ec = IDBDatabaseException::NOT_ALLOWED_ERR;
+        ec = IDBDatabaseException::TRANSACTION_INACTIVE_ERR;
 }
 
 // IMPORTANT: If this ever 1) fires an 'error' event and 2) it's possible to fire another event afterwards,
@@ -146,7 +146,7 @@ void IDBCursorBackendImpl::deleteFunction(PassRefPtr<IDBCallbacks> prpCallbacks,
 void IDBCursorBackendImpl::prefetchContinue(int numberToFetch, PassRefPtr<IDBCallbacks> prpCallbacks, ExceptionCode& ec)
 {
     if (!m_transaction->scheduleTask(createCallbackTask(&IDBCursorBackendImpl::prefetchContinueInternal, this, numberToFetch, prpCallbacks)))
-        ec = IDBDatabaseException::NOT_ALLOWED_ERR;
+        ec = IDBDatabaseException::TRANSACTION_INACTIVE_ERR;
 }
 
 void IDBCursorBackendImpl::prefetchContinueInternal(ScriptExecutionContext*, PassRefPtr<IDBCursorBackendImpl> prpCursor, int numberToFetch, PassRefPtr<IDBCallbacks> callbacks)
index f5c3edc..4fc681e 100644 (file)
@@ -42,13 +42,12 @@ static const char* const exceptionNames[] = {
     "CONSTRAINT_ERR",
     "DATA_ERR",
     "NOT_ALLOWED_ERR",
-    "SERIAL_ERR",
-    "RECOVERABLE_ERR",
-    "TRANSIENT_ERR",
-    "TIMEOUT_ERR",
-    "DEADLOCK_ERR",
+    "TRANSACTION_INACTIVE_ERR",
+    "ABORT_ERR",
     "READ_ONLY_ERR",
-    "ABORT_ERR"
+    "TIMEOUT_ERR",
+    "QUOTA_ERR",
+    "VER_ERR"
 };
 
 static const char* const exceptionDescriptions[] = {
@@ -58,13 +57,12 @@ static const char* const exceptionDescriptions[] = {
     "The request cannot be completed due to a failed constraint.",
     "The data provided does not meet the requirements of the function.",
     "This function is not allowed to be called in such a context.",
-    "The data supplied cannot be serialized according to the structured cloning algorithm.",
-    "RECOVERABLE_ERR", // FIXME: This isn't even used.
-    "TRANSIENT_ERR", // FIXME: This isn't even used.
-    "TIMEOUT_ERR", // This can't be thrown.
-    "DEADLOCK_ERR", // This can't be thrown.
-    "Write operations cannot be preformed on a read-only transaction.",
-    "The transaction was aborted, so the request cannot be fulfilled."
+    "A request was placed against a transaction which is either currently not active, or which is finished.",
+    "The transaction was aborted, so the request cannot be fulfilled.",
+    "A write operation was attempted in a read-only transaction.",
+    "A lock for the transaction could not be obtained in a reasonable time.", // FIXME: This isn't used yet.
+    "The operation failed because there was not enough remaining storage space, or the storage quota was reached and the user declined to give more space to the database.", // FIXME: This isn't used yet
+    "An attempt was made to open a database using a lower version than the existing version.", // FIXME: This isn't used yet
 };
 
 COMPILE_ASSERT(WTF_ARRAY_LENGTH(exceptionNames) == WTF_ARRAY_LENGTH(exceptionDescriptions), IDBDatabaseExceptionTablesMustMatch);
index f606036..570a2fc 100644 (file)
@@ -43,20 +43,19 @@ public:
     static const int IDBDatabaseExceptionMax = 1299;
 
     enum IDBDatabaseExceptionCode {
-        NO_ERR = IDBDatabaseExceptionOffset + 0,
-        UNKNOWN_ERR = IDBDatabaseExceptionOffset + 1,
-        NON_TRANSIENT_ERR = IDBDatabaseExceptionOffset + 2,
-        NOT_FOUND_ERR = IDBDatabaseExceptionOffset + 3,
-        CONSTRAINT_ERR = IDBDatabaseExceptionOffset + 4,
-        DATA_ERR = IDBDatabaseExceptionOffset + 5,
-        NOT_ALLOWED_ERR = IDBDatabaseExceptionOffset + 6,
-        SERIAL_ERR = IDBDatabaseExceptionOffset + 7,
-        RECOVERABLE_ERR = IDBDatabaseExceptionOffset + 8,
-        TRANSIENT_ERR = IDBDatabaseExceptionOffset + 9,
-        TIMEOUT_ERR = IDBDatabaseExceptionOffset + 10,
-        DEADLOCK_ERR = IDBDatabaseExceptionOffset + 11,
-        READ_ONLY_ERR = IDBDatabaseExceptionOffset + 12,
-        ABORT_ERR = IDBDatabaseExceptionOffset + 13
+        NO_ERR = IDBDatabaseExceptionOffset,
+        UNKNOWN_ERR,
+        NON_TRANSIENT_ERR,
+        NOT_FOUND_ERR,
+        CONSTRAINT_ERR,
+        DATA_ERR,
+        NOT_ALLOWED_ERR,
+        TRANSACTION_INACTIVE_ERR,
+        ABORT_ERR,
+        READ_ONLY_ERR,
+        TIMEOUT_ERR,
+        QUOTA_ERR,
+        VER_ERR
     };
 
     static int ErrorCodeToExceptionCode(int errorCode)
index d603057..1ade37d 100644 (file)
@@ -46,13 +46,12 @@ module storage {
         const unsigned short CONSTRAINT_ERR = 4;
         const unsigned short DATA_ERR = 5;
         const unsigned short NOT_ALLOWED_ERR = 6;
-        const unsigned short SERIAL_ERR = 7;
-        const unsigned short RECOVERABLE_ERR = 8;
-        const unsigned short TRANSIENT_ERR = 9;
+        const unsigned short TRANSACTION_INACTIVE_ERR = 7;
+        const unsigned short ABORT_ERR = 8;
+        const unsigned short READ_ONLY_ERR = 9;
         const unsigned short TIMEOUT_ERR = 10;
-        const unsigned short DEADLOCK_ERR = 11;
-        const unsigned short READ_ONLY_ERR = 12;
-        const unsigned short ABORT_ERR = 13;
+        const unsigned short QUOTA_ERR = 11;
+        const unsigned short VER_ERR = 12;
     };
 
 }
index e4c3c7c..a41d1d9 100644 (file)
@@ -109,7 +109,7 @@ void IDBIndexBackendImpl::openCursor(PassRefPtr<IDBKeyRange> prpKeyRange, unsign
     RefPtr<IDBCallbacks> callbacks = prpCallbacks;
     RefPtr<IDBTransactionBackendInterface> transaction = transactionPtr;
     if (!transaction->scheduleTask(createCallbackTask(&openCursorInternal, index, keyRange, direction, IDBCursorBackendInterface::IndexCursor, callbacks, transaction)))
-        ec = IDBDatabaseException::NOT_ALLOWED_ERR;
+        ec = IDBDatabaseException::TRANSACTION_INACTIVE_ERR;
 }
 
 void IDBIndexBackendImpl::openKeyCursor(PassRefPtr<IDBKeyRange> prpKeyRange, unsigned short direction, PassRefPtr<IDBCallbacks> prpCallbacks, IDBTransactionBackendInterface* transactionPtr, ExceptionCode& ec)
@@ -119,7 +119,7 @@ void IDBIndexBackendImpl::openKeyCursor(PassRefPtr<IDBKeyRange> prpKeyRange, uns
     RefPtr<IDBCallbacks> callbacks = prpCallbacks;
     RefPtr<IDBTransactionBackendInterface> transaction = transactionPtr;
     if (!transaction->scheduleTask(createCallbackTask(&openCursorInternal, index, keyRange, direction, IDBCursorBackendInterface::IndexKeyCursor, callbacks, transaction)))
-        ec = IDBDatabaseException::NOT_ALLOWED_ERR;
+        ec = IDBDatabaseException::TRANSACTION_INACTIVE_ERR;
 }
 
 void IDBIndexBackendImpl::countInternal(ScriptExecutionContext*, PassRefPtr<IDBIndexBackendImpl> index, PassRefPtr<IDBKeyRange> range, PassRefPtr<IDBCallbacks> callbacks, PassRefPtr<IDBTransactionBackendInterface> transaction)
@@ -142,7 +142,7 @@ void IDBIndexBackendImpl::countInternal(ScriptExecutionContext*, PassRefPtr<IDBI
 void IDBIndexBackendImpl::count(PassRefPtr<IDBKeyRange> range, PassRefPtr<IDBCallbacks> callbacks, IDBTransactionBackendInterface* transaction, ExceptionCode& ec)
 {
     if (!transaction->scheduleTask(createCallbackTask(&countInternal, this, range, callbacks, transaction)))
-        ec = IDBDatabaseException::NOT_ALLOWED_ERR;
+        ec = IDBDatabaseException::TRANSACTION_INACTIVE_ERR;
 }
 
 void IDBIndexBackendImpl::getInternal(ScriptExecutionContext*, PassRefPtr<IDBIndexBackendImpl> index, PassRefPtr<IDBKey> key, bool getObject, PassRefPtr<IDBCallbacks> callbacks)
@@ -171,7 +171,7 @@ void IDBIndexBackendImpl::get(PassRefPtr<IDBKey> prpKey, PassRefPtr<IDBCallbacks
     RefPtr<IDBKey> key = prpKey;
     RefPtr<IDBCallbacks> callbacks = prpCallbacks;
     if (!transaction->scheduleTask(createCallbackTask(&getInternal, index, key, true, callbacks)))
-        ec = IDBDatabaseException::NOT_ALLOWED_ERR;
+        ec = IDBDatabaseException::TRANSACTION_INACTIVE_ERR;
 }
 
 void IDBIndexBackendImpl::getKey(PassRefPtr<IDBKey> prpKey, PassRefPtr<IDBCallbacks> prpCallbacks, IDBTransactionBackendInterface* transaction, ExceptionCode& ec)
@@ -180,7 +180,7 @@ void IDBIndexBackendImpl::getKey(PassRefPtr<IDBKey> prpKey, PassRefPtr<IDBCallba
     RefPtr<IDBKey> key = prpKey;
     RefPtr<IDBCallbacks> callbacks = prpCallbacks;
     if (!transaction->scheduleTask(createCallbackTask(&getInternal, index, key, false, callbacks)))
-        ec = IDBDatabaseException::NOT_ALLOWED_ERR;
+        ec = IDBDatabaseException::TRANSACTION_INACTIVE_ERR;
 }
 
 bool IDBIndexBackendImpl::addingKeyAllowed(const IDBKey* indexKey, const IDBKey* primaryKey)
index 5e34385..08334c4 100644 (file)
@@ -87,7 +87,7 @@ void IDBObjectStoreBackendImpl::get(PassRefPtr<IDBKey> prpKey, PassRefPtr<IDBCal
     RefPtr<IDBKey> key = prpKey;
     RefPtr<IDBCallbacks> callbacks = prpCallbacks;
     if (!transaction->scheduleTask(createCallbackTask(&IDBObjectStoreBackendImpl::getInternal, objectStore, key, callbacks)))
-        ec = IDBDatabaseException::NOT_ALLOWED_ERR;
+        ec = IDBDatabaseException::TRANSACTION_INACTIVE_ERR;
 }
 
 void IDBObjectStoreBackendImpl::getInternal(ScriptExecutionContext*, PassRefPtr<IDBObjectStoreBackendImpl> objectStore, PassRefPtr<IDBKey> key, PassRefPtr<IDBCallbacks> callbacks)
@@ -151,7 +151,7 @@ void IDBObjectStoreBackendImpl::put(PassRefPtr<SerializedScriptValue> prpValue,
     // FIXME: This should throw a SERIAL_ERR on structured clone problems.
     // FIXME: This should throw a DATA_ERR when the wrong key/keyPath data is supplied.
     if (!transaction->scheduleTask(createCallbackTask(&IDBObjectStoreBackendImpl::putInternal, objectStore, value, key, putMode, callbacks, transaction)))
-        ec = IDBDatabaseException::NOT_ALLOWED_ERR;
+        ec = IDBDatabaseException::TRANSACTION_INACTIVE_ERR;
 }
 
 PassRefPtr<IDBKey> IDBObjectStoreBackendImpl::selectKeyForPut(IDBObjectStoreBackendImpl* objectStore, IDBKey* key, PutMode putMode, IDBCallbacks* callbacks, RefPtr<SerializedScriptValue>& value)
@@ -334,7 +334,7 @@ void IDBObjectStoreBackendImpl::deleteFunction(PassRefPtr<IDBKey> prpKey, PassRe
     }
 
     if (!transaction->scheduleTask(createCallbackTask(&IDBObjectStoreBackendImpl::deleteInternal, objectStore, key, callbacks)))
-        ec = IDBDatabaseException::NOT_ALLOWED_ERR;
+        ec = IDBDatabaseException::TRANSACTION_INACTIVE_ERR;
 }
 
 void IDBObjectStoreBackendImpl::deleteInternal(ScriptExecutionContext*, PassRefPtr<IDBObjectStoreBackendImpl> objectStore, PassRefPtr<IDBKey> key, PassRefPtr<IDBCallbacks> callbacks)
@@ -368,7 +368,7 @@ void IDBObjectStoreBackendImpl::clear(PassRefPtr<IDBCallbacks> prpCallbacks, IDB
     RefPtr<IDBCallbacks> callbacks = prpCallbacks;
 
     if (!transaction->scheduleTask(createCallbackTask(&IDBObjectStoreBackendImpl::clearInternal, objectStore, callbacks)))
-        ec = IDBDatabaseException::NOT_ALLOWED_ERR;
+        ec = IDBDatabaseException::TRANSACTION_INACTIVE_ERR;
 }
 
 void IDBObjectStoreBackendImpl::clearInternal(ScriptExecutionContext*, PassRefPtr<IDBObjectStoreBackendImpl> objectStore, PassRefPtr<IDBCallbacks> callbacks)
@@ -455,7 +455,7 @@ PassRefPtr<IDBIndexBackendInterface> IDBObjectStoreBackendImpl::createIndex(cons
                                  objectStore, index, transactionPtr),
               createCallbackTask(&IDBObjectStoreBackendImpl::removeIndexFromMap,
                                  objectStore, index))) {
-        ec = IDBDatabaseException::NOT_ALLOWED_ERR;
+        ec = IDBDatabaseException::TRANSACTION_INACTIVE_ERR;
         return 0;
     }
 
@@ -511,7 +511,7 @@ void IDBObjectStoreBackendImpl::deleteIndex(const String& name, IDBTransactionBa
                                  objectStore, index, transactionPtr),
               createCallbackTask(&IDBObjectStoreBackendImpl::addIndexToMap,
                                  objectStore, index))) {
-        ec = IDBDatabaseException::NOT_ALLOWED_ERR;
+        ec = IDBDatabaseException::TRANSACTION_INACTIVE_ERR;
         return;
     }
     m_indexes.remove(name);
@@ -532,7 +532,7 @@ void IDBObjectStoreBackendImpl::openCursor(PassRefPtr<IDBKeyRange> prpRange, uns
     if (!transaction->scheduleTask(
             createCallbackTask(&IDBObjectStoreBackendImpl::openCursorInternal,
                                objectStore, range, direction, callbacks, transactionPtr))) {
-        ec = IDBDatabaseException::NOT_ALLOWED_ERR;
+        ec = IDBDatabaseException::TRANSACTION_INACTIVE_ERR;
     }
 }
 
@@ -553,7 +553,7 @@ void IDBObjectStoreBackendImpl::openCursorInternal(ScriptExecutionContext*, Pass
 void IDBObjectStoreBackendImpl::count(PassRefPtr<IDBKeyRange> range, PassRefPtr<IDBCallbacks> callbacks, IDBTransactionBackendInterface* transaction, ExceptionCode& ec)
 {
     if (!transaction->scheduleTask(createCallbackTask(&IDBObjectStoreBackendImpl::countInternal, this, range, callbacks, transaction)))
-        ec = IDBDatabaseException::NOT_ALLOWED_ERR;
+        ec = IDBDatabaseException::TRANSACTION_INACTIVE_ERR;
 }
 
 void IDBObjectStoreBackendImpl::countInternal(ScriptExecutionContext*, PassRefPtr<IDBObjectStoreBackendImpl> objectStore, PassRefPtr<IDBKeyRange> range, PassRefPtr<IDBCallbacks> callbacks, PassRefPtr<IDBTransactionBackendInterface> transaction)