IndexedDB: Passing empty array to IDBDatabase.transaction should raise exception
authorcommit-queue@webkit.org <commit-queue@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 27 Oct 2011 13:35:51 +0000 (13:35 +0000)
committercommit-queue@webkit.org <commit-queue@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 27 Oct 2011 13:35:51 +0000 (13:35 +0000)
https://bugs.webkit.org/show_bug.cgi?id=70251

Patch by Joshua Bell <jsbell@chromium.org> on 2011-10-27
Reviewed by Adam Barth.

Source/WebCore:

IDBDatabase.transaction() supported being called with an empty array to
lock all object stores. Support for this was rejected from inclusion in
the IDB spec due to performance concerns. This patch removes that
functionality.

A special case in the spec (passing a string instead of an array) worked
in WebKit accidentally, by resolving the string to an empty array. This
needed explicit support. Support for DOMString[] is added to the binding
code generators (reliant on DOMStringList) to ensure JS arrays are not
coerced to DOMStrings. This matches the proposed IDL.

* bindings/scripts/CodeGeneratorV8.pm:
(GenerateParametersCheckExpression):
(GetNativeType):
(JSValueToNative):
(IsArrayType):
* bindings/scripts/IDLStructure.pm:
* storage/IDBDatabase.cpp:
(WebCore::IDBDatabase::transaction):
* storage/IDBDatabase.h:
(WebCore::IDBDatabase::transaction):
* storage/IDBDatabase.idl:
* storage/IDBTransactionBackendImpl.cpp:
(WebCore::IDBTransactionBackendImpl::IDBTransactionBackendImpl):
(WebCore::IDBTransactionBackendImpl::objectStore):

LayoutTests:

Many tests relied on the non-specified behavior of passing an empty
array into IDBDatabase.transaction() to include all object stores in
scopes. Worse, non-arrays would be treated as empty arrays, and hence
"just worked".

* storage/indexeddb/create-and-remove-object-store-expected.txt:
* storage/indexeddb/create-and-remove-object-store.html:
* storage/indexeddb/create-object-store-options-expected.txt:
* storage/indexeddb/create-object-store-options.html:
* storage/indexeddb/cursor-inconsistency-expected.txt:
* storage/indexeddb/cursor-inconsistency.html:
* storage/indexeddb/cursor-skip-deleted-expected.txt:
* storage/indexeddb/cursor-skip-deleted.html:
* storage/indexeddb/cursor-update-expected.txt:
* storage/indexeddb/cursor-update.html:
* storage/indexeddb/data-corruption-expected.txt:
* storage/indexeddb/data-corruption.html:
* storage/indexeddb/database-quota.html:
* storage/indexeddb/error-causes-abort-by-default-expected.txt:
* storage/indexeddb/error-causes-abort-by-default.html:
* storage/indexeddb/exception-in-event-aborts-expected.txt:
* storage/indexeddb/exception-in-event-aborts.html:
* storage/indexeddb/index-unique-expected.txt:
* storage/indexeddb/index-unique.html:
* storage/indexeddb/mutating-cursor-expected.txt:
* storage/indexeddb/mutating-cursor.html:
* storage/indexeddb/objectstore-autoincrement-expected.txt:
* storage/indexeddb/objectstore-autoincrement.html:
* storage/indexeddb/objectstore-basics-expected.txt:
* storage/indexeddb/objectstore-basics.html:
* storage/indexeddb/objectstore-clear-expected.txt:
* storage/indexeddb/objectstore-clear.html:
* storage/indexeddb/objectstore-removeobjectstore-expected.txt:
* storage/indexeddb/objectstore-removeobjectstore.html:
* storage/indexeddb/request-event-propagation-expected.txt:
* storage/indexeddb/request-event-propagation.html:
* storage/indexeddb/transaction-abort-expected.txt:
* storage/indexeddb/transaction-abort-with-js-recursion-expected.txt:
* storage/indexeddb/transaction-abort-with-js-recursion.html:
* storage/indexeddb/transaction-abort.html:
* storage/indexeddb/transaction-after-close-expected.txt:
* storage/indexeddb/transaction-after-close.html:
* storage/indexeddb/transaction-and-objectstore-calls-expected.txt:
* storage/indexeddb/transaction-and-objectstore-calls.html:
* storage/indexeddb/transaction-basics-expected.txt:
* storage/indexeddb/transaction-basics.html:
* storage/indexeddb/transaction-crash-on-abort-expected.txt:
* storage/indexeddb/transaction-crash-on-abort.html:
* storage/indexeddb/transaction-event-propagation-expected.txt:
* storage/indexeddb/transaction-event-propagation.html:
* storage/indexeddb/transaction-read-only-expected.txt:
* storage/indexeddb/transaction-read-only.html:
* storage/indexeddb/transaction-storeNames-required-expected.txt:
* storage/indexeddb/tutorial.html:

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

59 files changed:
LayoutTests/ChangeLog
LayoutTests/storage/indexeddb/create-and-remove-object-store-expected.txt
LayoutTests/storage/indexeddb/create-and-remove-object-store.html
LayoutTests/storage/indexeddb/create-object-store-options-expected.txt
LayoutTests/storage/indexeddb/create-object-store-options.html
LayoutTests/storage/indexeddb/cursor-inconsistency-expected.txt
LayoutTests/storage/indexeddb/cursor-inconsistency.html
LayoutTests/storage/indexeddb/cursor-skip-deleted-expected.txt
LayoutTests/storage/indexeddb/cursor-skip-deleted.html
LayoutTests/storage/indexeddb/cursor-update-expected.txt
LayoutTests/storage/indexeddb/cursor-update.html
LayoutTests/storage/indexeddb/data-corruption-expected.txt
LayoutTests/storage/indexeddb/data-corruption.html
LayoutTests/storage/indexeddb/database-quota.html
LayoutTests/storage/indexeddb/error-causes-abort-by-default-expected.txt
LayoutTests/storage/indexeddb/error-causes-abort-by-default.html
LayoutTests/storage/indexeddb/exception-in-event-aborts-expected.txt
LayoutTests/storage/indexeddb/exception-in-event-aborts.html
LayoutTests/storage/indexeddb/index-unique-expected.txt
LayoutTests/storage/indexeddb/index-unique.html
LayoutTests/storage/indexeddb/mutating-cursor-expected.txt
LayoutTests/storage/indexeddb/mutating-cursor.html
LayoutTests/storage/indexeddb/objectstore-autoincrement-expected.txt
LayoutTests/storage/indexeddb/objectstore-autoincrement.html
LayoutTests/storage/indexeddb/objectstore-basics-expected.txt
LayoutTests/storage/indexeddb/objectstore-basics.html
LayoutTests/storage/indexeddb/objectstore-clear-expected.txt
LayoutTests/storage/indexeddb/objectstore-clear.html
LayoutTests/storage/indexeddb/objectstore-removeobjectstore-expected.txt
LayoutTests/storage/indexeddb/objectstore-removeobjectstore.html
LayoutTests/storage/indexeddb/request-event-propagation-expected.txt
LayoutTests/storage/indexeddb/request-event-propagation.html
LayoutTests/storage/indexeddb/transaction-abort-expected.txt
LayoutTests/storage/indexeddb/transaction-abort-with-js-recursion-expected.txt
LayoutTests/storage/indexeddb/transaction-abort-with-js-recursion.html
LayoutTests/storage/indexeddb/transaction-abort.html
LayoutTests/storage/indexeddb/transaction-after-close-expected.txt
LayoutTests/storage/indexeddb/transaction-after-close.html
LayoutTests/storage/indexeddb/transaction-and-objectstore-calls-expected.txt
LayoutTests/storage/indexeddb/transaction-and-objectstore-calls.html
LayoutTests/storage/indexeddb/transaction-basics-expected.txt
LayoutTests/storage/indexeddb/transaction-basics.html
LayoutTests/storage/indexeddb/transaction-crash-on-abort-expected.txt
LayoutTests/storage/indexeddb/transaction-crash-on-abort.html
LayoutTests/storage/indexeddb/transaction-event-propagation-expected.txt
LayoutTests/storage/indexeddb/transaction-event-propagation.html
LayoutTests/storage/indexeddb/transaction-storeNames-required-expected.txt
LayoutTests/storage/indexeddb/tutorial.html
Source/WebCore/ChangeLog
Source/WebCore/bindings/scripts/CodeGeneratorJS.pm
Source/WebCore/bindings/scripts/CodeGeneratorV8.pm
Source/WebCore/bindings/scripts/IDLStructure.pm
Source/WebCore/bindings/scripts/test/JS/JSTestObj.cpp
Source/WebCore/bindings/scripts/test/TestObj.idl
Source/WebCore/bindings/scripts/test/V8/V8TestObj.cpp
Source/WebCore/storage/IDBDatabase.cpp
Source/WebCore/storage/IDBDatabase.h
Source/WebCore/storage/IDBDatabase.idl
Source/WebCore/storage/IDBTransactionBackendImpl.cpp

index 16d2457..d2d746e 100755 (executable)
@@ -1,3 +1,65 @@
+2011-10-27  Joshua Bell  <jsbell@chromium.org>
+
+        IndexedDB: Passing empty array to IDBDatabase.transaction should raise exception
+        https://bugs.webkit.org/show_bug.cgi?id=70251
+
+        Reviewed by Adam Barth.
+
+        Many tests relied on the non-specified behavior of passing an empty
+        array into IDBDatabase.transaction() to include all object stores in
+        scopes. Worse, non-arrays would be treated as empty arrays, and hence
+        "just worked".
+
+        * storage/indexeddb/create-and-remove-object-store-expected.txt:
+        * storage/indexeddb/create-and-remove-object-store.html:
+        * storage/indexeddb/create-object-store-options-expected.txt:
+        * storage/indexeddb/create-object-store-options.html:
+        * storage/indexeddb/cursor-inconsistency-expected.txt:
+        * storage/indexeddb/cursor-inconsistency.html:
+        * storage/indexeddb/cursor-skip-deleted-expected.txt:
+        * storage/indexeddb/cursor-skip-deleted.html:
+        * storage/indexeddb/cursor-update-expected.txt:
+        * storage/indexeddb/cursor-update.html:
+        * storage/indexeddb/data-corruption-expected.txt:
+        * storage/indexeddb/data-corruption.html:
+        * storage/indexeddb/database-quota.html:
+        * storage/indexeddb/error-causes-abort-by-default-expected.txt:
+        * storage/indexeddb/error-causes-abort-by-default.html:
+        * storage/indexeddb/exception-in-event-aborts-expected.txt:
+        * storage/indexeddb/exception-in-event-aborts.html:
+        * storage/indexeddb/index-unique-expected.txt:
+        * storage/indexeddb/index-unique.html:
+        * storage/indexeddb/mutating-cursor-expected.txt:
+        * storage/indexeddb/mutating-cursor.html:
+        * storage/indexeddb/objectstore-autoincrement-expected.txt:
+        * storage/indexeddb/objectstore-autoincrement.html:
+        * storage/indexeddb/objectstore-basics-expected.txt:
+        * storage/indexeddb/objectstore-basics.html:
+        * storage/indexeddb/objectstore-clear-expected.txt:
+        * storage/indexeddb/objectstore-clear.html:
+        * storage/indexeddb/objectstore-removeobjectstore-expected.txt:
+        * storage/indexeddb/objectstore-removeobjectstore.html:
+        * storage/indexeddb/request-event-propagation-expected.txt:
+        * storage/indexeddb/request-event-propagation.html:
+        * storage/indexeddb/transaction-abort-expected.txt:
+        * storage/indexeddb/transaction-abort-with-js-recursion-expected.txt:
+        * storage/indexeddb/transaction-abort-with-js-recursion.html:
+        * storage/indexeddb/transaction-abort.html:
+        * storage/indexeddb/transaction-after-close-expected.txt:
+        * storage/indexeddb/transaction-after-close.html:
+        * storage/indexeddb/transaction-and-objectstore-calls-expected.txt:
+        * storage/indexeddb/transaction-and-objectstore-calls.html:
+        * storage/indexeddb/transaction-basics-expected.txt:
+        * storage/indexeddb/transaction-basics.html:
+        * storage/indexeddb/transaction-crash-on-abort-expected.txt:
+        * storage/indexeddb/transaction-crash-on-abort.html:
+        * storage/indexeddb/transaction-event-propagation-expected.txt:
+        * storage/indexeddb/transaction-event-propagation.html:
+        * storage/indexeddb/transaction-read-only-expected.txt:
+        * storage/indexeddb/transaction-read-only.html:
+        * storage/indexeddb/transaction-storeNames-required-expected.txt:
+        * storage/indexeddb/tutorial.html:
+
 2011-10-27  Ken Buchanan <kenrb@chromium.org>
 
         Crash due to nested first-letter selectors
index 528ba89..c3411ac 100644 (file)
@@ -28,7 +28,7 @@ db.createObjectStore('tmp')
 Expecting exception from db.createObjectStore('tmp')
 PASS Exception was thrown.
 PASS code is webkitIDBDatabaseException.CONSTRAINT_ERR
-trans = db.transaction({mode: webkitIDBTransaction.READ_WRITE})
+trans = db.transaction(['tmp'])
 trans.objectStore('tmp').get(0)
 PASS event.target.result is undefined.
 Trying create
index 43c1fe1..04dff65 100644 (file)
@@ -47,7 +47,7 @@ function cleanDatabase()
     os = evalAndLog("db.createObjectStore('tmp')");
     evalAndExpectException("db.createObjectStore('tmp')", "webkitIDBDatabaseException.CONSTRAINT_ERR");
 
-    trans = evalAndLog("trans = db.transaction({mode: webkitIDBTransaction.READ_WRITE})");
+    trans = evalAndLog("trans = db.transaction(['tmp'])");
     request = evalAndLog("trans.objectStore('tmp').get(0)");
     request.onsuccess = tryOnceMore;
     request.onerror = unexpectedErrorCallback;
index 5f0e94d..165c89f 100644 (file)
@@ -12,7 +12,7 @@ Deleted all object stores.
 db.createObjectStore('a', {keyPath: 'a'})
 db.createObjectStore('b')
 db.createObjectStore('c', {autoIncrement: true});
-trans = db.transaction([], webkitIDBTransaction.READ_WRITE)
+trans = db.transaction(['a', 'b'], webkitIDBTransaction.READ_WRITE)
 PASS trans.mode is webkitIDBTransaction.READ_WRITE
 trans.objectStore('a').put({'a': 0})
 trans.objectStore('b').put({'a': 0}, 0)
index bf600d7..b9becf3 100644 (file)
@@ -43,7 +43,7 @@ function cleanDatabase()
     debug("db.createObjectStore('c', {autoIncrement: true});");
     db.createObjectStore('c', {autoIncrement: true});
 
-    trans = evalAndLog("trans = db.transaction([], webkitIDBTransaction.READ_WRITE)");
+    trans = evalAndLog("trans = db.transaction(['a', 'b'], webkitIDBTransaction.READ_WRITE)");
     shouldBe("trans.mode", "webkitIDBTransaction.READ_WRITE");
 
     req = evalAndLog("trans.objectStore('a').put({'a': 0})");
index 11cc292..bacd41d 100644 (file)
@@ -16,7 +16,7 @@ objectStore.add('someValue2', 'someKey2').onerror = unexpectedErrorCallback
 objectStore.add('someValue3', 'someKey3').onerror = unexpectedErrorCallback
 objectStore.add('someValue4', 'someKey4').onerror = unexpectedErrorCallback
 openBasicCursor()
-trans = db.transaction([], webkitIDBTransaction.READ_WRITE)
+trans = db.transaction(['basicStore'], webkitIDBTransaction.READ_WRITE)
 trans.objectStore('basicStore')
 objectStore.openCursor(keyRange)
 
index b9ccb58..0d8583a 100644 (file)
@@ -53,7 +53,7 @@ function setVersionSuccess()
 function openBasicCursor()
 {
     debug("openBasicCursor()");
-    evalAndLog("trans = db.transaction([], webkitIDBTransaction.READ_WRITE)");
+    evalAndLog("trans = db.transaction(['basicStore'], webkitIDBTransaction.READ_WRITE)");
     trans.onabort = unexpectedAbortCallback;
     trans.oncomplete = transactionComplete;
 
index 317c925..e129ad9 100644 (file)
@@ -16,7 +16,7 @@ objectStore.createIndex('nameIndex', 'name')
 resetObjectStore():
 
 basicCursorTest()
-trans = db.transaction([], webkitIDBTransaction.READ_WRITE)
+trans = db.transaction(['store'], webkitIDBTransaction.READ_WRITE)
 
 testCursor():
 trans.objectStore('store').openCursor(webkitIDBKeyRange.lowerBound(0))
index a3bb0d9..04130fe 100644 (file)
@@ -146,7 +146,7 @@ function basicCursorTest()
 {
     debug("basicCursorTest()");
 
-    evalAndLog("trans = db.transaction([], webkitIDBTransaction.READ_WRITE)");
+    evalAndLog("trans = db.transaction(['store'], webkitIDBTransaction.READ_WRITE)");
     trans.onabort = unexpectedAbortCallback;
     trans.oncomplete = transactionComplete;
 
index 955bcf9..4aebd54 100644 (file)
@@ -27,7 +27,7 @@ objectStore.add({number: 2, id: 2}).onerror = unexpectedErrorCallback
 objectStore.add({number: 3, id: 3}).onerror = unexpectedErrorCallback
 objectStore.add({number: 4, id: 4}).onerror = unexpectedErrorCallback
 openBasicCursor()
-trans = db.transaction([], webkitIDBTransaction.READ_WRITE)
+trans = db.transaction(['basicStore', 'autoIncrementStore', 'keyPathStore'], webkitIDBTransaction.READ_WRITE)
 trans.objectStore('basicStore')
 objectStore.openCursor(keyRange)
 basicUpdateCursor()
index 783a88c..fd97294 100644 (file)
@@ -65,7 +65,7 @@ function setVersionSuccess()
 function openBasicCursor()
 {
     debug("openBasicCursor()");
-    evalAndLog("trans = db.transaction([], webkitIDBTransaction.READ_WRITE)");
+    evalAndLog("trans = db.transaction(['basicStore', 'autoIncrementStore', 'keyPathStore'], webkitIDBTransaction.READ_WRITE)");
     trans.onabort = unexpectedAbortCallback;
     trans.oncomplete = transactionComplete;
 
index a02b54c..31b14a8 100644 (file)
@@ -13,10 +13,10 @@ PASS trans !== null is true
 Deleted all object stores.
 db.createObjectStore('storeName')
 addData():
-transaction = db.transaction([], webkitIDBTransaction.READ_WRITE)
+transaction = db.transaction(['storeName'], webkitIDBTransaction.READ_WRITE)
 request = transaction.objectStore('storeName').add({x: testDate}, 'key')
 addData():
-transaction = db.transaction([], webkitIDBTransaction.READ_ONLY)
+transaction = db.transaction(['storeName'], webkitIDBTransaction.READ_ONLY)
 request = transaction.objectStore('storeName').get('key')
 PASS event.target.result.x.toString() == testDate.toString() is true
 PASS successfullyParsed is true
index ea7928b..0adb235 100644 (file)
@@ -49,7 +49,7 @@ var testDate = new Date('February 24, 1955 12:00:08');
 function addData()
 {
     debug("addData():");
-    var transaction = evalAndLog("transaction = db.transaction([], webkitIDBTransaction.READ_WRITE)");
+    var transaction = evalAndLog("transaction = db.transaction(['storeName'], webkitIDBTransaction.READ_WRITE)");
     var request = evalAndLog("request = transaction.objectStore('storeName').add({x: testDate}, 'key')");
     request.onerror = unexpectedErrorCallback;
     transaction.oncomplete = getData;
@@ -58,7 +58,7 @@ function addData()
 function getData()
 {
     debug("addData():");
-    var transaction = evalAndLog("transaction = db.transaction([], webkitIDBTransaction.READ_ONLY)");
+    var transaction = evalAndLog("transaction = db.transaction(['storeName'], webkitIDBTransaction.READ_ONLY)");
     var request = evalAndLog("request = transaction.objectStore('storeName').get('key')");
     request.onerror = unexpectedErrorCallback;
     request.onsuccess = doCheck;
index 2e622f0..7ad0c48 100644 (file)
@@ -61,7 +61,7 @@ function checkObjectStore()
 
 function checkQuotaEnforcing()
 {
-    var trans = evalAndLog("trans = db.transaction([], webkitIDBTransaction.READ_WRITE)");
+    var trans = evalAndLog("trans = db.transaction(['test123'], webkitIDBTransaction.READ_WRITE)");
     trans.onabort = testComplete;
     trans.oncomplete = unexpectedCompleteCallback;
     debug("Creating 'data' which contains 64K of data");
index 96f4b65..8a55d9f 100644 (file)
@@ -12,7 +12,7 @@ PASS trans !== null is true
 trans.oncomplete = addData
 Deleted all object stores.
 db.createObjectStore('storeName', null)
-trans = db.transaction([], webkitIDBTransaction.READ_WRITE)
+trans = db.transaction(['storeName'], webkitIDBTransaction.READ_WRITE)
 trans.onabort = unexpectedAbortCallback
 trans.oncomplete = transactionCompleted
 store = trans.objectStore('storeName')
@@ -22,7 +22,7 @@ event.preventDefault()
 PASS Transaction completed
 
 
-trans = db.transaction([], webkitIDBTransaction.READ_WRITE)
+trans = db.transaction(['storeName'], webkitIDBTransaction.READ_WRITE)
 trans.onabort = transactionAborted1
 trans.oncomplete = unexpectedCompleteCallback
 store = trans.objectStore('storeName')
@@ -31,7 +31,7 @@ Doing nothing to prevent the default action...
 PASS Transaction aborted
 
 
-trans = db.transaction([], webkitIDBTransaction.READ_WRITE)
+trans = db.transaction(['storeName'], webkitIDBTransaction.READ_WRITE)
 trans.onabort = transactionAborted2
 trans.oncomplete = unexpectedCompleteCallback
 store = trans.objectStore('storeName')
index 8ce6d07..d198b0a 100644 (file)
@@ -45,7 +45,7 @@ function deleteExisting()
 
 function addData()
 {
-    trans = evalAndLog("trans = db.transaction([], webkitIDBTransaction.READ_WRITE)");
+    trans = evalAndLog("trans = db.transaction(['storeName'], webkitIDBTransaction.READ_WRITE)");
     evalAndLog("trans.onabort = unexpectedAbortCallback");
     evalAndLog("trans.oncomplete = transactionCompleted");
     store = evalAndLog("store = trans.objectStore('storeName')");
@@ -72,7 +72,7 @@ function transactionCompleted()
     testPassed("Transaction completed");
     debug("");
     debug("");
-    trans = evalAndLog("trans = db.transaction([], webkitIDBTransaction.READ_WRITE)");
+    trans = evalAndLog("trans = db.transaction(['storeName'], webkitIDBTransaction.READ_WRITE)");
     evalAndLog("trans.onabort = transactionAborted1");
     evalAndLog("trans.oncomplete = unexpectedCompleteCallback");
     store = evalAndLog("store = trans.objectStore('storeName')");
@@ -91,7 +91,7 @@ function transactionAborted1()
     testPassed("Transaction aborted");
     debug("");
     debug("");
-    trans = evalAndLog("trans = db.transaction([], webkitIDBTransaction.READ_WRITE)");
+    trans = evalAndLog("trans = db.transaction(['storeName'], webkitIDBTransaction.READ_WRITE)");
     evalAndLog("trans.onabort = transactionAborted2");
     evalAndLog("trans.oncomplete = unexpectedCompleteCallback");
     store = evalAndLog("store = trans.objectStore('storeName')");
index d4b74fa..e9785cb 100644 (file)
@@ -16,7 +16,7 @@ Deleted all object stores.
 store = db.createObjectStore('storeName', null)
 store.add({x: 'value', y: 'zzz'}, 'key')
 
-trans = db.transaction([], webkitIDBTransaction.READ_WRITE)
+trans = db.transaction(['storeName'], webkitIDBTransaction.READ_WRITE)
 trans.onabort = transactionAborted1
 trans.oncomplete = unexpectedCompleteCallback
 store = trans.objectStore('storeName')
@@ -26,7 +26,7 @@ event.preventDefault()
 Throwing
 
 PASS The transaction was aborted.
-trans = db.transaction([], webkitIDBTransaction.READ_WRITE)
+trans = db.transaction(['storeName'], webkitIDBTransaction.READ_WRITE)
 trans.onabort = transactionAborted2
 trans.oncomplete = unexpectedCompleteCallback
 store = trans.objectStore('storeName')
@@ -36,7 +36,7 @@ event.preventDefault()
 Throwing
 
 PASS The transaction was aborted.
-trans = db.transaction([], webkitIDBTransaction.READ_WRITE)
+trans = db.transaction(['storeName'], webkitIDBTransaction.READ_WRITE)
 trans.onabort = unexpectedAbortCallback
 trans.oncomplete = transactionCompleted1
 store = trans.objectStore('storeName')
@@ -46,7 +46,7 @@ event.preventDefault()
 Throwing within a try block
 
 PASS The transaction completed.
-trans = db.transaction([], webkitIDBTransaction.READ_WRITE)
+trans = db.transaction(['storeName'], webkitIDBTransaction.READ_WRITE)
 trans.onabort = unexpectedAbortCallback
 trans.oncomplete = transactionCompleted2
 store = trans.objectStore('storeName')
index 89e27ef..9f522be 100644 (file)
@@ -48,7 +48,7 @@ function deleteExisting()
 function startTest()
 {
     debug("");
-    trans = evalAndLog("trans = db.transaction([], webkitIDBTransaction.READ_WRITE)");
+    trans = evalAndLog("trans = db.transaction(['storeName'], webkitIDBTransaction.READ_WRITE)");
     evalAndLog("trans.onabort = transactionAborted1");
     evalAndLog("trans.oncomplete = unexpectedCompleteCallback");
     store = evalAndLog("store = trans.objectStore('storeName')");
@@ -69,7 +69,7 @@ function transactionAborted1()
 {
     debug("");
     testPassed("The transaction was aborted.");
-    trans = evalAndLog("trans = db.transaction([], webkitIDBTransaction.READ_WRITE)");
+    trans = evalAndLog("trans = db.transaction(['storeName'], webkitIDBTransaction.READ_WRITE)");
     evalAndLog("trans.onabort = transactionAborted2");
     evalAndLog("trans.oncomplete = unexpectedCompleteCallback");
     store = evalAndLog("store = trans.objectStore('storeName')");
@@ -82,7 +82,7 @@ function transactionAborted2()
 {
     debug("");
     testPassed("The transaction was aborted.");
-    trans = evalAndLog("trans = db.transaction([], webkitIDBTransaction.READ_WRITE)");
+    trans = evalAndLog("trans = db.transaction(['storeName'], webkitIDBTransaction.READ_WRITE)");
     evalAndLog("trans.onabort = unexpectedAbortCallback");
     evalAndLog("trans.oncomplete = transactionCompleted1");
     store = evalAndLog("store = trans.objectStore('storeName')");
@@ -107,7 +107,7 @@ function transactionCompleted1()
 {
     debug("");
     testPassed("The transaction completed.");
-    trans = evalAndLog("trans = db.transaction([], webkitIDBTransaction.READ_WRITE)");
+    trans = evalAndLog("trans = db.transaction(['storeName'], webkitIDBTransaction.READ_WRITE)");
     evalAndLog("trans.onabort = unexpectedAbortCallback");
     evalAndLog("trans.oncomplete = transactionCompleted2");
     store = evalAndLog("store = trans.objectStore('storeName')");
index 9f10f41..b1a0273 100644 (file)
@@ -13,7 +13,7 @@ Deleted all object stores.
 db.createObjectStore('store')
 store.createIndex('index', 'x', {unique: true})
 setVersionCompleted():
-transaction = db.transaction([], webkitIDBTransaction.READ_WRITE)
+transaction = db.transaction(['store'], webkitIDBTransaction.READ_WRITE)
 transaction.objectStore('store').put({x: 1}, 'foo')
 addMoreData():
 transaction.objectStore('store').put({x: 1}, 'bar')
index 50b639b..b07e184 100644 (file)
@@ -49,7 +49,7 @@ function deleteExisting()
 function setVersionCompleted()
 {
     debug("setVersionCompleted():");
-    window.transaction = evalAndLog("transaction = db.transaction([], webkitIDBTransaction.READ_WRITE)");
+    window.transaction = evalAndLog("transaction = db.transaction(['store'], webkitIDBTransaction.READ_WRITE)");
 
     request = evalAndLog("transaction.objectStore('store').put({x: 1}, 'foo')");
     request.onerror = unexpectedErrorCallback;
index 270b24f..2b89b61 100644 (file)
@@ -16,7 +16,7 @@ objectStore.add(2, 2).onerror = unexpectedErrorCallback
 objectStore.add(3, 3).onerror = unexpectedErrorCallback
 objectStore.add(4, 4).onerror = unexpectedErrorCallback
 openForwardCursor()
-trans = db.transaction([], webkitIDBTransaction.READ_WRITE)
+trans = db.transaction(['store'], webkitIDBTransaction.READ_WRITE)
 trans.objectStore('store')
 objectStore.openCursor()
 forwardCursor()
@@ -49,7 +49,7 @@ forwardCursor()
 PASS cursorSteps is 5
 forwardCursorComplete()
 openReverseCursor()
-trans = db.transaction([], webkitIDBTransaction.READ_WRITE)
+trans = db.transaction(['store'], webkitIDBTransaction.READ_WRITE)
 trans.objectStore('store')
 objectStore.openCursor(null, webkitIDBCursor.PREV)
 reverseCursor()
index 5808db7..cf191bb 100644 (file)
@@ -52,7 +52,7 @@ function setVersionSuccess()
 function openForwardCursor()
 {
     debug("openForwardCursor()");
-    evalAndLog("trans = db.transaction([], webkitIDBTransaction.READ_WRITE)");
+    evalAndLog("trans = db.transaction(['store'], webkitIDBTransaction.READ_WRITE)");
     trans.onabort = unexpectedAbortCallback;
     trans.oncomplete = forwardCursorComplete;
 
@@ -97,7 +97,7 @@ function forwardCursorComplete()
 function openReverseCursor()
 {
     debug("openReverseCursor()");
-    evalAndLog("trans = db.transaction([], webkitIDBTransaction.READ_WRITE)");
+    evalAndLog("trans = db.transaction(['store'], webkitIDBTransaction.READ_WRITE)");
     trans.onabort = unexpectedAbortCallback;
     trans.oncomplete = reverseCursorComplete;
 
index 87e477b..48b11bb 100644 (file)
@@ -23,7 +23,7 @@ PASS storeNames.contains('StoreWithAutoIncrement') is true
 PASS storeNames.contains('PlainOldStore') is true
 PASS storeNames.length is 3
 setVersionCompleted():
-trans = db.transaction([], webkitIDBTransaction.READ_WRITE)
+trans = db.transaction(['StoreWithKeyPath', 'StoreWithAutoIncrement', 'PlainOldStore'], webkitIDBTransaction.READ_WRITE)
 store = trans.objectStore('StoreWithKeyPath')
 Insert into object store with auto increment and key path, with key in the object.
 store.add({name: 'Jeffersson', number: '7010', id: 3})
index 0945c84..cf3e568 100644 (file)
@@ -61,7 +61,7 @@ function setVersionCompleted()
 {
     debug("setVersionCompleted():");
 
-    window.trans = evalAndLog("trans = db.transaction([], webkitIDBTransaction.READ_WRITE)");
+    window.trans = evalAndLog("trans = db.transaction(['StoreWithKeyPath', 'StoreWithAutoIncrement', 'PlainOldStore'], webkitIDBTransaction.READ_WRITE)");
     trans.onabort = unexpectedAbortCallback;
     trans.oncomplete = done;
 
index 1a108ce..6ecc430 100644 (file)
@@ -50,7 +50,7 @@ PASS store.indexNames[1] is null
 PASS store.indexNames[100] is null
 PASS store.indexNames.item(1) is null
 PASS store.indexNames.item(100) is null
-transaction = db.transaction([], webkitIDBTransaction.READ_WRITE)
+transaction = db.transaction(['storeName'], webkitIDBTransaction.READ_WRITE)
 store = transaction.objectStore('storeName')
 Try to insert data with a Date key:
 store.add({x: 'foo'}, testDate)
@@ -66,20 +66,20 @@ event.target.source.add({x: 'foo'}, 'zzz')
 addAgainFailure():
 PASS event.target.errorCode is webkitIDBDatabaseException.CONSTRAINT_ERR
 event.preventDefault()
-db.transaction([], webkitIDBTransaction.READ_WRITE)
+db.transaction(['storeName'], webkitIDBTransaction.READ_WRITE)
 store = transaction.objectStore('storeName')
 store.add({x: 'somevalue'}, 'somekey')
 Expecting exception from store.add({x: 'othervalue'}, null)
 PASS Exception was thrown.
 PASS code is webkitIDBDatabaseException.DATA_ERR
-db.transaction([], webkitIDBTransaction.READ_WRITE)
+db.transaction(['storeName'], webkitIDBTransaction.READ_WRITE)
 store = transaction.objectStore('storeName')
 store.add({x: null}, 'validkey')
 PASS event.cancelable is true
 addWithNullIndexFailure():
 PASS event.target.errorCode is webkitIDBDatabaseException.DATA_ERR
 event.preventDefault()
-db.transaction([], webkitIDBTransaction.READ_WRITE)
+db.transaction(['storeName'], webkitIDBTransaction.READ_WRITE)
 store = transaction.objectStore('storeName')
 store.get('key')
 getSuccess():
index 8e45169..1b5d384 100644 (file)
@@ -135,7 +135,7 @@ var testDateB = new Date("Wed Jan 05 2011 15:54:49");
 
 function addData()
 {
-    var transaction = evalAndLog("transaction = db.transaction([], webkitIDBTransaction.READ_WRITE)");
+    var transaction = evalAndLog("transaction = db.transaction(['storeName'], webkitIDBTransaction.READ_WRITE)");
     transaction.onabort = unexpectedAbortCallback;
     window.store = evalAndLog("store = transaction.objectStore('storeName')");
 
@@ -181,14 +181,14 @@ function addAgainFailure()
 
     evalAndLog("event.preventDefault()");
 
-    transaction = evalAndLog("db.transaction([], webkitIDBTransaction.READ_WRITE)");
+    transaction = evalAndLog("db.transaction(['storeName'], webkitIDBTransaction.READ_WRITE)");
     transaction.onabort = unexpectedErrorCallback;
     var store = evalAndLog("store = transaction.objectStore('storeName')");
 
     evalAndLog("store.add({x: 'somevalue'}, 'somekey')");
     evalAndExpectException("store.add({x: 'othervalue'}, null)", "webkitIDBDatabaseException.DATA_ERR");
 
-    transaction = evalAndLog("db.transaction([], webkitIDBTransaction.READ_WRITE)");
+    transaction = evalAndLog("db.transaction(['storeName'], webkitIDBTransaction.READ_WRITE)");
     transaction.onabort = unexpectedErrorCallback;
     var store = evalAndLog("store = transaction.objectStore('storeName')");
 
@@ -205,7 +205,7 @@ function addWithNullIndexFailure()
 
     evalAndLog("event.preventDefault()");
 
-    transaction = evalAndLog("db.transaction([], webkitIDBTransaction.READ_WRITE)");
+    transaction = evalAndLog("db.transaction(['storeName'], webkitIDBTransaction.READ_WRITE)");
     transaction.onabort = unexpectedErrorCallback;
     var store = evalAndLog("store = transaction.objectStore('storeName')");
 
index 2875fd6..4a82493 100644 (file)
@@ -23,7 +23,7 @@ index = store.index('indexName')
 index.openKeyCursor()
 openKeyCursorSuccess():
 PASS event.target.result is null
-db.transaction({mode: webkitIDBTransaction.READ_WRITE})
+db.transaction(['otherStoreName'])
 otherStore = transaction.objectStore('otherStoreName')
 otherStore.get('key')
 PASS event.target.result is "value"
index f18848b..03dd5dd 100644 (file)
@@ -87,7 +87,7 @@ function openKeyCursorSuccess()
     debug("openKeyCursorSuccess():");
     shouldBeNull("event.target.result");
 
-    transaction = evalAndLog("db.transaction({mode: webkitIDBTransaction.READ_WRITE})");
+    transaction = evalAndLog("db.transaction(['otherStoreName'])");
     transaction.onabort = unexpectedErrorCallback;
     var otherStore = evalAndLog("otherStore = transaction.objectStore('otherStoreName')");
 
index 77ed01f..407d36f 100644 (file)
@@ -13,7 +13,7 @@ store = db.createObjectStore('storeName', null)
 store.createIndex('indexName', '')
 PASS store.indexNames.contains('indexName') is true
 store.add('value', 'key')
-db.transaction({mode: webkitIDBTransaction.READ_WRITE})
+db.transaction(['storeName'])
 store = transaction.objectStore('storeName')
 store.get('key')
 PASS event.target.result is "value"
@@ -22,7 +22,7 @@ trans = event.target.result
 PASS trans !== null is true
 db.deleteObjectStore('storeName')
 db.createObjectStore('storeName', null)
-db.transaction({mode: webkitIDBTransaction.READ_WRITE})
+db.transaction(['storeName'])
 store = transaction.objectStore('storeName')
 store.get('key')
 PASS event.target.result is undefined
index f44b27e..51fdecb 100644 (file)
@@ -49,7 +49,7 @@ function deleteExisting()
 
 function getValue()
 {
-    transaction = evalAndLog("db.transaction({mode: webkitIDBTransaction.READ_WRITE})");
+    transaction = evalAndLog("db.transaction(['storeName'])");
     transaction.onabort = unexpectedErrorCallback;
     var store = evalAndLog("store = transaction.objectStore('storeName')");
 
@@ -85,7 +85,7 @@ function createObjectStoreAgain()
 
 function getValueAgain()
 {
-    transaction = evalAndLog("db.transaction({mode: webkitIDBTransaction.READ_WRITE})");
+    transaction = evalAndLog("db.transaction(['storeName'])");
     transaction.onabort = unexpectedErrorCallback;
     var store = evalAndLog("store = transaction.objectStore('storeName')");
 
index f71f781..f8c6df7 100644 (file)
@@ -14,7 +14,7 @@ Deleted all object stores.
 store = db.createObjectStore('storeName', null)
 store.add({x: 'value', y: 'zzz'}, 'key')
 Verify that handler fires and that not preventing default will result in an abort
-trans = db.transaction([], webkitIDBTransaction.READ_WRITE)
+trans = db.transaction(['storeName'], webkitIDBTransaction.READ_WRITE)
 trans.onabort = transactionAborted
 trans.oncomplete = unexpectedCompleteCallback
 trans.onerror = allowDefault
@@ -25,7 +25,7 @@ Doing nothing to prevent the default action...
 PASS handlerFired is true
 
 Verifing error
-trans = db.transaction([], webkitIDBTransaction.READ_WRITE)
+trans = db.transaction(['storeName'], webkitIDBTransaction.READ_WRITE)
 trans.onabort = transactionAborted2
 trans.oncomplete = unexpectedAbortCallback
 trans.addEventListener('error', errorCaptureCallback, true)
@@ -92,7 +92,7 @@ PASS bubbleFired is true
 PASS dbBubbleFired is true
 
 Verifing success.
-trans = db.transaction([], webkitIDBTransaction.READ_WRITE)
+trans = db.transaction(['storeName'], webkitIDBTransaction.READ_WRITE)
 trans.oncomplete = transactionComplete
 trans.onabort = unexpectedAbortCallback
 trans.addEventListener('success', successCaptureCallback, true)
index 3b1da3b..d7fbee2 100644 (file)
@@ -48,7 +48,7 @@ function deleteExisting()
 function startTest()
 {
     debug("Verify that handler fires and that not preventing default will result in an abort");
-    trans = evalAndLog("trans = db.transaction([], webkitIDBTransaction.READ_WRITE)");
+    trans = evalAndLog("trans = db.transaction(['storeName'], webkitIDBTransaction.READ_WRITE)");
     evalAndLog("trans.onabort = transactionAborted");
     evalAndLog("trans.oncomplete = unexpectedCompleteCallback");
     evalAndLog("trans.onerror = allowDefault");
@@ -70,7 +70,7 @@ function transactionAborted()
     shouldBeTrue("handlerFired");
     debug("");
     debug("Verifing error");
-    trans = evalAndLog("trans = db.transaction([], webkitIDBTransaction.READ_WRITE)");
+    trans = evalAndLog("trans = db.transaction(['storeName'], webkitIDBTransaction.READ_WRITE)");
     evalAndLog("trans.onabort = transactionAborted2");
     evalAndLog("trans.oncomplete = unexpectedAbortCallback");
     evalAndLog("trans.addEventListener('error', errorCaptureCallback, true)");
@@ -173,7 +173,7 @@ function transactionAborted2()
     shouldBeTrue("dbBubbleFired");
     debug("");
     debug("Verifing success.");
-    trans = evalAndLog("trans = db.transaction([], webkitIDBTransaction.READ_WRITE)");
+    trans = evalAndLog("trans = db.transaction(['storeName'], webkitIDBTransaction.READ_WRITE)");
     evalAndLog("trans.oncomplete = transactionComplete");
     evalAndLog("trans.onabort = unexpectedAbortCallback");
     evalAndLog("trans.addEventListener('success', successCaptureCallback, true)");
index c3bcb70..b2089e0 100644 (file)
@@ -13,7 +13,7 @@ trans.oncomplete = startTest
 Deleted all object stores.
 store = db.createObjectStore('storeName', null)
 store.add({x: 'value', y: 'zzz'}, 'key')
-trans = db.transaction([], webkitIDBTransaction.READ_WRITE)
+trans = db.transaction(['storeName'], webkitIDBTransaction.READ_WRITE)
 trans.onabort = transactionAborted
 trans.oncomplete = unexpectedCompleteCallback
 store = trans.objectStore('storeName')
index 9a216e9..7a1ffaf 100644 (file)
@@ -8,9 +8,9 @@ PASS webkitIndexedDB == null is false
 webkitIndexedDB.open('transaction-abort-with-js-recursion')
 db = event.target.result
 db.setVersion('new version')
-pendingTransaction = db.transaction([], webkitIDBTransaction.READ_WRITE)
+pendingTransaction = db.transaction(['objectStore'], webkitIDBTransaction.READ_WRITE)
 Start re-entrant JS
-transaction = db.transaction([], webkitIDBTransaction.READ_WRITE)
+transaction = db.transaction(['objectStore'], webkitIDBTransaction.READ_WRITE)
 End re-entrant JS
 store = pendingTransaction.objectStore('objectStore')
 PASS store !== undefined is true
index d0cde03..ced6ec3 100644 (file)
@@ -36,8 +36,9 @@ function setVersion() {
 }\r
 \r
 function click() {\r
+    store = db.createObjectStore('objectStore', null);\r
     body.onclick = test;\r
-    var pendingTransaction = evalAndLog("pendingTransaction = db.transaction([], webkitIDBTransaction.READ_WRITE)");\r
+    var pendingTransaction = evalAndLog("pendingTransaction = db.transaction(['objectStore'], webkitIDBTransaction.READ_WRITE)");\r
     pendingTransaction.onsuccess = unexpectedErrorCallback;\r
     pendingTransaction.onerror = unexpectedErrorCallback;\r
     pendingTransaction.onabort = abortCallback;\r
@@ -52,8 +53,7 @@ function click() {
 function test()\r
 {\r
     debug("Start re-entrant JS");\r
-    store = db.createObjectStore('objectStore', null);\r
-    transaction = evalAndLog("transaction = db.transaction([], webkitIDBTransaction.READ_WRITE)");\r
+    transaction = evalAndLog("transaction = db.transaction(['objectStore'], webkitIDBTransaction.READ_WRITE)");\r
     debug("End re-entrant JS");\r
 }\r
 \r
index 6bd0c00..1d28027 100644 (file)
@@ -47,7 +47,7 @@ function deleteExisting()
 
 function startTest()
 {
-    trans = evalAndLog("trans = db.transaction([], webkitIDBTransaction.READ_WRITE)");
+    trans = evalAndLog("trans = db.transaction(['storeName'], webkitIDBTransaction.READ_WRITE)");
     evalAndLog("trans.onabort = transactionAborted");
     evalAndLog("trans.oncomplete = unexpectedCompleteCallback");
     store = evalAndLog("store = trans.objectStore('storeName')");
index 6be5795..238e159 100644 (file)
@@ -14,17 +14,17 @@ store = db.createObjectStore('store')
 request = store.put('x', 'y')
 PASS Put success
 running first transaction
-currentTransaction = db.transaction([], webkitIDBTransaction.READ_WRITE)
+currentTransaction = db.transaction(['store'], webkitIDBTransaction.READ_WRITE)
 objectStore.put('a', 'b')
 db.close()
-Expecting exception from db.transaction([], webkitIDBTransaction.READ_WRITE)
+Expecting exception from db.transaction(['store'], webkitIDBTransaction.READ_WRITE)
 PASS Exception was thrown.
 PASS code is webkitIDBDatabaseException.NOT_ALLOWED_ERR
 
 verify that we can reopen the db after calling close
 webkitIndexedDB.open('transaction-after-close')
 second_db = event.target.result
-currentTransaction = second_db.transaction([], webkitIDBTransaction.READ_WRITE)
+currentTransaction = second_db.transaction(['store'], webkitIDBTransaction.READ_WRITE)
 request = store.put('1', '2')
 PASS final put success
 PASS successfullyParsed is true
index 13aee60..20359b1 100644 (file)
@@ -53,7 +53,7 @@ function onPutSuccess()
 function runFirstRegularTransaction()\r
 {\r
     debug("running first transaction")\r
-    currentTransaction = evalAndLog("currentTransaction = db.transaction([], webkitIDBTransaction.READ_WRITE)");\r
+    currentTransaction = evalAndLog("currentTransaction = db.transaction(['store'], webkitIDBTransaction.READ_WRITE)");\r
     currentTransaction.onabort = unexpectedAbortCallback;\r
     currentTransaction.oncomplete = firstTransactionComplete;\r
     objectStore = currentTransaction.objectStore('store');\r
@@ -64,7 +64,7 @@ function runFirstRegularTransaction()
 function firstTransactionComplete()\r
 {\r
     evalAndLog("db.close()");\r
-    evalAndExpectException("db.transaction([], webkitIDBTransaction.READ_WRITE)", "webkitIDBDatabaseException.NOT_ALLOWED_ERR");\r
+    evalAndExpectException("db.transaction(['store'], webkitIDBTransaction.READ_WRITE)", "webkitIDBDatabaseException.NOT_ALLOWED_ERR");\r
 \r
     debug("")\r
     debug("verify that we can reopen the db after calling close")\r
@@ -75,7 +75,7 @@ function firstTransactionComplete()
 \r
 function onSecondOpen() {\r
     second_db = evalAndLog("second_db = event.target.result");\r
-    currentTransaction = evalAndLog("currentTransaction = second_db.transaction([], webkitIDBTransaction.READ_WRITE)");\r
+    currentTransaction = evalAndLog("currentTransaction = second_db.transaction(['store'], webkitIDBTransaction.READ_WRITE)");\r
     store = currentTransaction.objectStore('store');\r
     request = evalAndLog("request = store.put('1', '2')");\r
     request.onsuccess = onFinalPutSuccess;\r
index 313c1a1..e9211da 100644 (file)
@@ -55,14 +55,17 @@ Expecting exception from trans.objectStore('x')
 PASS Exception was thrown.
 PASS code is webkitIDBDatabaseException.NOT_FOUND_ERR
 
-trans = db.transaction([])
+Passing a string as the first argument is a shortcut for just one object store:
+trans = db.transaction('a')
 trans.objectStore('a')
-trans.objectStore('b')
+Expecting exception from trans.objectStore('b')
+PASS Exception was thrown.
+PASS code is webkitIDBDatabaseException.NOT_FOUND_ERR
 Expecting exception from trans.objectStore('x')
 PASS Exception was thrown.
 PASS code is webkitIDBDatabaseException.NOT_FOUND_ERR
 
-PASS trans = db.transaction() threw exception TypeError: Not enough arguments.
+PASS trans = db.transaction() threw exception TypeError: Type error.
 
 Expecting exception from db.transaction(['x'])
 PASS Exception was thrown.
@@ -80,6 +83,30 @@ Expecting exception from db.transaction(['a', 'x', 'b'])
 PASS Exception was thrown.
 PASS code is webkitIDBDatabaseException.NOT_FOUND_ERR
 
+Exception thrown when no stores specified:
+Expecting exception from db.transaction([])
+PASS Exception was thrown.
+PASS code is DOMException.INVALID_ACCESS_ERR
+
+{} coerces to a string - so no match, but not a type error:
+Expecting exception from db.transaction({})
+PASS Exception was thrown.
+PASS code is webkitIDBDatabaseException.NOT_FOUND_ERR
+Expecting exception from db.transaction({mode:0})
+PASS Exception was thrown.
+PASS code is webkitIDBDatabaseException.NOT_FOUND_ERR
+
+Overriding the default string coercion makes these work:
+db.transaction({toString:function(){return 'a';}})
+db.transaction([{toString:function(){return 'a';}}])
+... but you still need to specify a real store:
+Expecting exception from db.transaction([{toString:function(){return 'x';}}])
+PASS Exception was thrown.
+PASS code is webkitIDBDatabaseException.NOT_FOUND_ERR
+Expecting exception from db.transaction([{toString:function(){return 'x';}}])
+PASS Exception was thrown.
+PASS code is webkitIDBDatabaseException.NOT_FOUND_ERR
+
 PASS successfullyParsed is true
 
 TEST COMPLETE
index 0935ef9..fbba1db 100644 (file)
@@ -75,9 +75,10 @@ function created()
     evalAndExpectException("trans.objectStore('x')", "webkitIDBDatabaseException.NOT_FOUND_ERR");
     debug("");
 
-    trans = evalAndLog("trans = db.transaction([])");
+    debug("Passing a string as the first argument is a shortcut for just one object store:");
+    trans = evalAndLog("trans = db.transaction('a')");
     evalAndLog("trans.objectStore('a')");
-    evalAndLog("trans.objectStore('b')");
+    evalAndExpectException("trans.objectStore('b')", "webkitIDBDatabaseException.NOT_FOUND_ERR");
     evalAndExpectException("trans.objectStore('x')", "webkitIDBDatabaseException.NOT_FOUND_ERR");
     debug("");
 
@@ -91,6 +92,23 @@ function created()
     evalAndExpectException("db.transaction(['a', 'x', 'b'])", "webkitIDBDatabaseException.NOT_FOUND_ERR");
     debug("");
 
+    debug("Exception thrown when no stores specified:");
+    evalAndExpectException("db.transaction([])", "DOMException.INVALID_ACCESS_ERR");
+    debug("");
+
+    debug("{} coerces to a string - so no match, but not a type error:");
+    evalAndExpectException("db.transaction({})", "webkitIDBDatabaseException.NOT_FOUND_ERR");
+    evalAndExpectException("db.transaction({mode:0})", "webkitIDBDatabaseException.NOT_FOUND_ERR");
+    debug("");
+
+    debug("Overriding the default string coercion makes these work:");
+    evalAndLog("db.transaction({toString:function(){return 'a';}})");
+    evalAndLog("db.transaction([{toString:function(){return 'a';}}])");
+    debug("... but you still need to specify a real store:");
+    evalAndExpectException("db.transaction([{toString:function(){return 'x';}}])", "webkitIDBDatabaseException.NOT_FOUND_ERR");
+    evalAndExpectException("db.transaction([{toString:function(){return 'x';}}])", "webkitIDBDatabaseException.NOT_FOUND_ERR");
+
+    debug("");
     done();
 }
 
index 527c553..3171a86 100644 (file)
@@ -63,7 +63,7 @@ trans = event.target.result
 PASS trans !== null is true
 Deleted all object stores.
 db.createObjectStore('storeName', null)
-db.transaction({mode: webkitIDBTransaction.READ_WRITE})
+db.transaction(['storeName'])
 store = transaction.objectStore('storeName')
 PASS store.name is "storeName"
 PASS complete event fired
index 0e49da1..f3b3efa 100644 (file)
@@ -206,7 +206,7 @@ function setVersionSuccess()
     deleteAllObjectStores(db);\r
 \r
     evalAndLog("db.createObjectStore('storeName', null)");\r
-    transaction = evalAndLog("db.transaction({mode: webkitIDBTransaction.READ_WRITE})");\r
+    transaction = evalAndLog("db.transaction(['storeName'])");\r
     transaction.onabort = abortCallback;\r
     var store = evalAndLog("store = transaction.objectStore('storeName')");\r
     shouldBeEqualToString("store.name", "storeName");\r
index f60eaa2..6d33820 100644 (file)
@@ -8,6 +8,8 @@ PASS webkitIndexedDB == null is false
 webkitIndexedDB.open('transaction-crash-on-abort')
 openSuccess():
 db = event.target.result
+db.setVersion('1.0')
+db.createObjectStore('foo')
 db.transaction('foo')
 window.gc()
 PASS successfullyParsed is true
index 75d122b..6f9ca15 100644 (file)
@@ -28,6 +28,14 @@ function openSuccess()
 {
     debug("openSuccess():");
     db = evalAndLog("db = event.target.result");
+    request = evalAndLog("db.setVersion('1.0')");
+    request.onsuccess = setVersionSuccess;
+    request.onerror = unexpectedErrorCallback;
+}
+
+function setVersionSuccess()
+{
+    evalAndLog("db.createObjectStore('foo')");
     evalAndLog("db.transaction('foo')");
     evalAndLog("window.gc()");
     done();
index 5f85c81..d42061a 100644 (file)
@@ -13,7 +13,7 @@ Deleted all object stores.
 store = db.createObjectStore('storeName', null)
 store.add({x: 'value', y: 'zzz'}, 'key')
 Verifing abort
-trans = db.transaction([], webkitIDBTransaction.READ_WRITE)
+trans = db.transaction(['storeName'], webkitIDBTransaction.READ_WRITE)
 trans.onabort = abortFiredCallback
 trans.oncomplete = unexpectedAbortCallback
 db.addEventListener('abort', dbAbortCaptureCallback, true)
@@ -45,7 +45,7 @@ PASS event.target is trans
 PASS event.currentTarget is db
 
 Verifing success.
-trans = db.transaction([], webkitIDBTransaction.READ_WRITE)
+trans = db.transaction(['storeName'], webkitIDBTransaction.READ_WRITE)
 trans.oncomplete = completeFiredCallback
 trans.onabort = unexpectedAbortCallback
 db.removeEventListener('abort', dbAbortCaptureCallback, true)
index 15c275c..941ac52 100644 (file)
@@ -47,7 +47,7 @@ function deleteExisting()
 function startTest()
 {
     debug("Verifing abort");
-    trans = evalAndLog("trans = db.transaction([], webkitIDBTransaction.READ_WRITE)");
+    trans = evalAndLog("trans = db.transaction(['storeName'], webkitIDBTransaction.READ_WRITE)");
     evalAndLog("trans.onabort = abortFiredCallback");
     evalAndLog("trans.oncomplete = unexpectedAbortCallback");
     evalAndLog("db.addEventListener('abort', dbAbortCaptureCallback, true)");
@@ -97,7 +97,7 @@ function dbAbortBubbleCallback()
     dbBubbleFired1 = true;
     debug("");
     debug("Verifing success.");
-    trans = evalAndLog("trans = db.transaction([], webkitIDBTransaction.READ_WRITE)");
+    trans = evalAndLog("trans = db.transaction(['storeName'], webkitIDBTransaction.READ_WRITE)");
     evalAndLog("trans.oncomplete = completeFiredCallback");
     evalAndLog("trans.onabort = unexpectedAbortCallback");
     evalAndLog("db.removeEventListener('abort', dbAbortCaptureCallback, true)");
index a5fe5eb..8727794 100644 (file)
@@ -15,7 +15,7 @@ indexedDB.open(name, description)
 db = event.target.result
 request = db.setVersion('1')
 Deleted all object stores.
-PASS db.transaction(); threw exception TypeError: Not enough arguments.
+PASS db.transaction(); threw exception TypeError: Type error.
 PASS successfullyParsed is true
 
 TEST COMPLETE
index 8b28987..3c04852 100644 (file)
@@ -211,15 +211,14 @@ function onSetVersionComplete()
     // createObjectStore, transaction optionally takes in various optional parameters.
     //
     // First of all is the parameter "objectStoreNames". If you pass in a string, we lock just that
-    // objectStore.  If you pass in an array, we lock those. Otherwise (for example, if you omit it
-    // or pass in null/undefined) we lock the whole database. By specifying locks over fewer
+    // objectStore.  If you pass in an array, we lock those. By specifying locks over fewer
     // objectStores you make it possible for browsers to run transactions concurrently. That said,
     // Chromium/WebKit does not support this yet.
     //
     // Next is "mode" which specifies the locking mode. The default is READ_ONLY (i.e. a shared lock).
     // That's fine for this case, but later we'll ask for IDBTransaction.READ_WRITE. At the moment,
     // Chromium/WebKit pretends every transaction is READ_WRITE, which is kind of bad.
-    window.currentTransaction = db.transaction([], IDBTransaction.READ_WRITE);
+    window.currentTransaction = db.transaction("people", IDBTransaction.READ_WRITE);
     currentTransaction.oncomplete = unexpectedComplete;
     currentTransaction.onabort = onTransactionAborted;
 
@@ -266,10 +265,8 @@ function unexpectedComplete()
 
 function onTransactionAborted()
 {
-    // Now let's make a real transaction and a person to our objectStore. Just to show it's possible,
-    // we'll omit the objectStoreNames parameter which means we'll lock everything even though we only
-    // ever access "people".
-    window.currentTransaction = db.transaction([], IDBTransaction.READ_WRITE);
+    // Now let's make a real transaction and a person to our objectStore.
+    window.currentTransaction = db.transaction("people", IDBTransaction.READ_WRITE);
     currentTransaction.onabort = unexpectedAbort;
 
     var people = currentTransaction.objectStore("people");
@@ -307,7 +304,7 @@ function onPutTransactionComplete()
     // OK, now let's query the people objectStore in a couple different ways. First up, let's try get.
     // It simply takes in a key and returns a request whose result will be the value. Note that here
     // we're passing in an array for objectStoreNames rather than a simple string.
-    window.currentTransaction = db.transaction(["people"], IDBTransaction.READ_WRITE, 0);
+    window.currentTransaction = db.transaction(["people"], IDBTransaction.READ_WRITE);
     currentTransaction.onabort = unexpectedAbort;
 
     var people = currentTransaction.objectStore("people");
index ec16474..5446a22 100755 (executable)
@@ -1,3 +1,36 @@
+2011-10-27  Joshua Bell  <jsbell@chromium.org>
+
+        IndexedDB: Passing empty array to IDBDatabase.transaction should raise exception
+        https://bugs.webkit.org/show_bug.cgi?id=70251
+
+        Reviewed by Adam Barth.
+
+        IDBDatabase.transaction() supported being called with an empty array to
+        lock all object stores. Support for this was rejected from inclusion in
+        the IDB spec due to performance concerns. This patch removes that
+        functionality.
+
+        A special case in the spec (passing a string instead of an array) worked
+        in WebKit accidentally, by resolving the string to an empty array. This
+        needed explicit support. Support for DOMString[] is added to the binding
+        code generators (reliant on DOMStringList) to ensure JS arrays are not
+        coerced to DOMStrings. This matches the proposed IDL.
+
+        * bindings/scripts/CodeGeneratorV8.pm:
+        (GenerateParametersCheckExpression):
+        (GetNativeType):
+        (JSValueToNative):
+        (IsArrayType):
+        * bindings/scripts/IDLStructure.pm:
+        * storage/IDBDatabase.cpp:
+        (WebCore::IDBDatabase::transaction):
+        * storage/IDBDatabase.h:
+        (WebCore::IDBDatabase::transaction):
+        * storage/IDBDatabase.idl:
+        * storage/IDBTransactionBackendImpl.cpp:
+        (WebCore::IDBTransactionBackendImpl::IDBTransactionBackendImpl):
+        (WebCore::IDBTransactionBackendImpl::objectStore):
+
 2011-10-27  Ken Buchanan <kenrb@chromium.org>
 
         Crash due to nested first-letter selectors
index 7286659..e85e0ac 100644 (file)
@@ -291,6 +291,9 @@ sub AddIncludesForType
     } elsif ($type eq "XPathNSResolver") {
         $includesRef->{"JSXPathNSResolver.h"} = 1;
         $includesRef->{"JSCustomXPathNSResolver.h"} = 1;
+    } elsif ($type eq "DOMString[]") {
+        # FIXME: Add proper support for T[], T[]?, sequence<T>
+        $includesRef->{"JSDOMStringList.h"} = 1;
     } elsif ($isCallback) {
         $includesRef->{"JS${type}.h"} = 1;
     } else {
@@ -1223,6 +1226,10 @@ sub GenerateParametersCheckExpression
             # For Callbacks only checks if the value is null or object.
             push(@andExpression, "(${value}.isNull() || ${value}.isObject())");
             $usedArguments{$parameterIndex} = 1;
+        } elsif (IsArrayType($type)) {
+            # FIXME: Add proper support for T[], T[]?, sequence<T>
+            push(@andExpression, "(${value}.isNull() || (${value}.isObject() && asObject(${value})->inherits(&JSArray::s_info)))");
+            $usedArguments{$parameterIndex} = 1;
         } elsif (!IsNativeType($type)) {
             push(@andExpression, "(${value}.isNull() || (${value}.isObject() && asObject(${value})->inherits(&JS${type}::s_info)))");
             $usedArguments{$parameterIndex} = 1;
@@ -2627,6 +2634,8 @@ sub GetNativeTypeFromSignature
 my %nativeType = (
     "CompareHow" => "Range::CompareHow",
     "DOMString" => "const String&",
+    # FIXME: Add proper support for T[], T[]?, sequence<T>
+    "DOMString[]" => "DOMStringList*",
     "DOMObject" => "ScriptValue",
     "NodeFilter" => "RefPtr<NodeFilter>",
     "SerializedScriptValue" => "RefPtr<SerializedScriptValue>",
@@ -2702,6 +2711,13 @@ sub IsNativeType
     return exists $nativeType{$type};
 }
 
+sub IsArrayType
+{
+    my $type = shift;
+    # FIXME: Add proper support for T[], T[]?, sequence<T>.
+    return $type =~ m/\[\]$/;
+}
+
 sub JSValueToNative
 {
     my $signature = shift;
@@ -2751,6 +2767,11 @@ sub JSValueToNative
         return "createIDBKeyFromValue(exec, $value)";
     }
 
+    if ($type eq "DOMString[]") {
+        AddToImplIncludes("JSDOMStringList.h", $conditional);
+        return "toDOMStringList($value)";
+    }
+
     AddToImplIncludes("HTMLOptionElement.h", $conditional) if $type eq "HTMLOptionElement";
     AddToImplIncludes("JSCustomVoidCallback.h", $conditional) if $type eq "VoidCallback";
     AddToImplIncludes("Event.h", $conditional) if $type eq "Event";
index 6803fc1..9fb27c5 100644 (file)
@@ -1197,6 +1197,9 @@ sub GenerateParametersCheckExpression
         } elsif ($parameter->extendedAttributes->{"Callback"}) {
             # For Callbacks only checks if the value is null or object.
             push(@andExpression, "(${value}->IsNull() || ${value}->IsObject())");
+        } elsif (IsArrayType($type)) {
+            # FIXME: Add proper support for T[], T[]?, sequence<T>.
+            push(@andExpression, "(${value}->IsNull() || ${value}->IsArray())");
         } elsif (IsWrapperType($type)) {
             push(@andExpression, "(${value}->IsNull() || V8${type}::HasInstance($value))");
         }
@@ -3127,6 +3130,8 @@ sub GetNativeType
     return "RefPtr<MediaQueryListListener>" if $type eq "MediaQueryListListener";
 
     return "RefPtr<DOMStringList>" if $type eq "DOMStringList";
+    # FIXME: Add proper support for T[], T[]?, sequence<T>.
+    return "RefPtr<DOMStringList>" if $type eq "DOMString[]";
 
     # Default, assume native type is a pointer with same type name as idl type
     return "${type}*";
@@ -3180,6 +3185,8 @@ sub JSValueToNative
     return "static_cast<Range::CompareHow>($value->Int32Value())" if $type eq "CompareHow";
     return "toWebCoreDate($value)" if $type eq "Date";
     return "v8ValueToWebCoreDOMStringList($value)" if $type eq "DOMStringList";
+    # FIXME: Add proper support for T[], T[]? and sequence<T>.
+    return "v8ValueToWebCoreDOMStringList($value)" if $type eq "DOMString[]";
 
     if ($type eq "DOMString" or $type eq "DOMUserData") {
         return $value;
@@ -3249,6 +3256,7 @@ sub GetV8HeaderName
     return "EventTarget.h" if $type eq "EventTarget";
     return "SerializedScriptValue.h" if $type eq "SerializedScriptValue";
     return "ScriptValue.h" if $type eq "DOMObject";
+    return "V8DOMStringList.h" if $type eq "DOMString[]";
     return "V8${type}.h";
 }
 
@@ -3351,6 +3359,13 @@ sub IsWrapperType
     return !($non_wrapper_types{$type});
 }
 
+sub IsArrayType
+{
+    my $type = $codeGenerator->StripModule(shift);
+    # FIXME: Add proper support for T[], T[]?, sequence<T>.
+    return $type =~ m/\[\]$/;
+}
+
 sub IsDOMNodeType
 {
     my $type = shift;
index 3400e0c..6ba0e6f 100644 (file)
@@ -87,7 +87,7 @@ our $constValue = '("[^"\r\n]*")|(0[xX][a-fA-F0-9]+)|(-?[0-9]*)';
 our $idlDataType = '[a-zA-Z0-9\ ]';   # Generic data type identifier
 
 # Magic IDL parsing regular expressions
-my $supportedTypes = "((?:unsigned )?(?:int|short|(?:long )?long)|(?:$idlIdNs*))";
+my $supportedTypes = "((?:(?:unsigned )?(?:int|short|(?:long )?long)|(?:$idlIdNs*))(?:\\[\\])?)";
 
 # Special IDL notations. This regular expression extracts the string between the first [ and its corresponding ].
 our $extendedAttributeSyntax = qr/\[[^\[\]]*(?:(??{$IDLStructure::extendedAttributeSyntax})[^\[\]]*)*\]/x; # Used for extended attributes
index 7c50d66..c4985ae 100644 (file)
@@ -26,6 +26,7 @@
 #include "IDBBindingUtilities.h"
 #include "IDBKey.h"
 #include "JSDOMBinding.h"
+#include "JSDOMStringList.h"
 #include "JSEventListener.h"
 #include "JSOptionsObject.h"
 #include "JSTestCallback.h"
@@ -1755,6 +1756,36 @@ static EncodedJSValue JSC_HOST_CALL jsTestObjPrototypeFunctionOverloadedMethod5(
     return JSValue::encode(jsUndefined());
 }
 
+static EncodedJSValue JSC_HOST_CALL jsTestObjPrototypeFunctionOverloadedMethod6(ExecState* exec)
+{
+    JSValue thisValue = exec->hostThisValue();
+    if (!thisValue.inherits(&JSTestObj::s_info))
+        return throwVMTypeError(exec);
+    JSTestObj* castedThis = static_cast<JSTestObj*>(asObject(thisValue));
+    ASSERT_GC_OBJECT_INHERITS(castedThis, &JSTestObj::s_info);
+    TestObj* imp = static_cast<TestObj*>(castedThis->impl());
+    DOMStringList* listArg(toDOMStringList(exec->argument(0)));
+    if (exec->hadException())
+        return JSValue::encode(jsUndefined());
+    imp->overloadedMethod(listArg);
+    return JSValue::encode(jsUndefined());
+}
+
+static EncodedJSValue JSC_HOST_CALL jsTestObjPrototypeFunctionOverloadedMethod7(ExecState* exec)
+{
+    JSValue thisValue = exec->hostThisValue();
+    if (!thisValue.inherits(&JSTestObj::s_info))
+        return throwVMTypeError(exec);
+    JSTestObj* castedThis = static_cast<JSTestObj*>(asObject(thisValue));
+    ASSERT_GC_OBJECT_INHERITS(castedThis, &JSTestObj::s_info);
+    TestObj* imp = static_cast<TestObj*>(castedThis->impl());
+    DOMStringList* arrayArg(toDOMStringList(exec->argument(0)));
+    if (exec->hadException())
+        return JSValue::encode(jsUndefined());
+    imp->overloadedMethod(arrayArg);
+    return JSValue::encode(jsUndefined());
+}
+
 EncodedJSValue JSC_HOST_CALL jsTestObjPrototypeFunctionOverloadedMethod(ExecState* exec)
 {
     size_t argsCount = exec->argumentCount();
@@ -1770,6 +1801,10 @@ EncodedJSValue JSC_HOST_CALL jsTestObjPrototypeFunctionOverloadedMethod(ExecStat
         return jsTestObjPrototypeFunctionOverloadedMethod4(exec);
     if ((argsCount == 1 && (arg0.isNull() || arg0.isObject())))
         return jsTestObjPrototypeFunctionOverloadedMethod5(exec);
+    if ((argsCount == 1 && (arg0.isNull() || (arg0.isObject() && asObject(arg0)->inherits(&JSDOMStringList::s_info)))))
+        return jsTestObjPrototypeFunctionOverloadedMethod6(exec);
+    if ((argsCount == 1 && (arg0.isNull() || (arg0.isObject() && asObject(arg0)->inherits(&JSArray::s_info)))))
+        return jsTestObjPrototypeFunctionOverloadedMethod7(exec);
     return throwVMTypeError(exec);
 }
 
index 75b49ab..2242dee 100644 (file)
@@ -157,6 +157,8 @@ module test {
         void    overloadedMethod(in DOMString strArg);
         void    overloadedMethod(in long intArg);
         void    overloadedMethod(in [Callback] TestCallback callback);
+        void    overloadedMethod(in DOMStringList listArg);
+        void    overloadedMethod(in DOMString[] arrayArg);
 #endif
 
         // Class methods within JavaScript (like what's used for IDBKeyRange).
index 83a478c..0123917 100644 (file)
@@ -1160,6 +1160,24 @@ static v8::Handle<v8::Value> overloadedMethod5Callback(const v8::Arguments& args
     return v8::Handle<v8::Value>();
 }
 
+static v8::Handle<v8::Value> overloadedMethod6Callback(const v8::Arguments& args)
+{
+    INC_STATS("DOM.TestObj.overloadedMethod6");
+    TestObj* imp = V8TestObj::toNative(args.Holder());
+    EXCEPTION_BLOCK(RefPtr<DOMStringList>, listArg, v8ValueToWebCoreDOMStringList(MAYBE_MISSING_PARAMETER(args, 0, MissingIsUndefined)));
+    imp->overloadedMethod(listArg);
+    return v8::Handle<v8::Value>();
+}
+
+static v8::Handle<v8::Value> overloadedMethod7Callback(const v8::Arguments& args)
+{
+    INC_STATS("DOM.TestObj.overloadedMethod7");
+    TestObj* imp = V8TestObj::toNative(args.Holder());
+    EXCEPTION_BLOCK(RefPtr<DOMStringList>, arrayArg, v8ValueToWebCoreDOMStringList(MAYBE_MISSING_PARAMETER(args, 0, MissingIsUndefined)));
+    imp->overloadedMethod(arrayArg);
+    return v8::Handle<v8::Value>();
+}
+
 static v8::Handle<v8::Value> overloadedMethodCallback(const v8::Arguments& args)
 {
     INC_STATS("DOM.TestObj.overloadedMethod");
@@ -1173,6 +1191,10 @@ static v8::Handle<v8::Value> overloadedMethodCallback(const v8::Arguments& args)
         return overloadedMethod4Callback(args);
     if ((args.Length() == 1 && (args[0]->IsNull() || args[0]->IsObject())))
         return overloadedMethod5Callback(args);
+    if ((args.Length() == 1 && (args[0]->IsNull() || V8DOMStringList::HasInstance(args[0]))))
+        return overloadedMethod6Callback(args);
+    if ((args.Length() == 1 && (args[0]->IsNull() || args[0]->IsArray())))
+        return overloadedMethod7Callback(args);
     V8Proxy::throwTypeError();
     return notHandledByInterceptor();
 }
index 7cbaf5b..a801443 100644 (file)
@@ -27,6 +27,7 @@
 #include "IDBDatabase.h"
 
 #include "Document.h"
+#include "ExceptionCode.h"
 #include "EventQueue.h"
 #include "IDBAny.h"
 #include "IDBDatabaseCallbacksImpl.h"
@@ -121,11 +122,20 @@ PassRefPtr<IDBVersionChangeRequest> IDBDatabase::setVersion(ScriptExecutionConte
     return request;
 }
 
+PassRefPtr<IDBTransaction> IDBDatabase::transaction(ScriptExecutionContext* context, const String& storeName, unsigned short mode, ExceptionCode& ec)
+{
+    RefPtr<DOMStringList> storeNames = DOMStringList::create();
+    storeNames->append(storeName);
+    return transaction(context, storeNames, mode, ec);
+}
+
 PassRefPtr<IDBTransaction> IDBDatabase::transaction(ScriptExecutionContext* context, PassRefPtr<DOMStringList> prpStoreNames, unsigned short mode, ExceptionCode& ec)
 {
     RefPtr<DOMStringList> storeNames = prpStoreNames;
-    if (!storeNames)
-        storeNames = DOMStringList::create();
+    if (!storeNames || storeNames->isEmpty()) {
+        ec = INVALID_ACCESS_ERR;
+        return 0;
+    }
 
     if (mode != IDBTransaction::READ_WRITE && mode != IDBTransaction::READ_ONLY) {
         // FIXME: May need to change when specced: http://www.w3.org/Bugs/Public/show_bug.cgi?id=11406
index 4f2fc4b..6fe4590 100644 (file)
@@ -61,11 +61,9 @@ public:
 
     // FIXME: Try to modify the code generator so this is unneeded.
     PassRefPtr<IDBObjectStore> createObjectStore(const String& name, ExceptionCode& ec) { return createObjectStore(name, OptionsObject(), ec); }
-    PassRefPtr<IDBTransaction> transaction(ScriptExecutionContext* context, ExceptionCode& ec) { return transaction(context, 0, ec); }
-    PassRefPtr<IDBTransaction> transaction(ScriptExecutionContext* context, PassRefPtr<DOMStringList> storeNames, ExceptionCode& ec) { return transaction(context, storeNames, IDBTransaction::READ_ONLY, ec); }
-    PassRefPtr<IDBTransaction> transaction(ScriptExecutionContext*, PassRefPtr<DOMStringList>, unsigned short mode, ExceptionCode&);
-
     PassRefPtr<IDBObjectStore> createObjectStore(const String& name, const OptionsObject&, ExceptionCode&);
+    PassRefPtr<IDBTransaction> transaction(ScriptExecutionContext*, PassRefPtr<DOMStringList>, unsigned short mode, ExceptionCode&);
+    PassRefPtr<IDBTransaction> transaction(ScriptExecutionContext*, const String&, unsigned short mode, ExceptionCode&);
     void deleteObjectStore(const String& name, ExceptionCode&);
     PassRefPtr<IDBVersionChangeRequest> setVersion(ScriptExecutionContext*, const String& version, ExceptionCode&);
     void close();
index 82f6435..f0b1d0c 100644 (file)
@@ -45,7 +45,11 @@ module storage {
             raises (IDBDatabaseException);
         [CallWith=ScriptExecutionContext] IDBVersionChangeRequest setVersion(in DOMString version)
             raises (IDBDatabaseException);
-        [CallWith=ScriptExecutionContext] IDBTransaction transaction(in DOMStringList storeNames, in [Optional] unsigned short mode)
+        [CallWith=ScriptExecutionContext] IDBTransaction transaction(in DOMStringList storeNames, in [Optional=CallWithDefaultValue] unsigned short mode)
+            raises (IDBDatabaseException);
+        [CallWith=ScriptExecutionContext] IDBTransaction transaction(in DOMString[] storeNames, in [Optional=CallWithDefaultValue] unsigned short mode)
+            raises (IDBDatabaseException);
+        [CallWith=ScriptExecutionContext] IDBTransaction transaction(in DOMString storeName, in [Optional=CallWithDefaultValue] unsigned short mode)
             raises (IDBDatabaseException);
         void close();
 
index 015da18..8a12264 100644 (file)
@@ -52,6 +52,7 @@ IDBTransactionBackendImpl::IDBTransactionBackendImpl(DOMStringList* objectStores
     , m_pendingEvents(0)
 {
     ASSERT(m_objectStoreNames);
+    ASSERT(m_mode == IDBTransaction::VERSION_CHANGE || !m_objectStoreNames->isEmpty());
     m_database->transactionCoordinator()->didCreateTransaction(this);
 }
 
@@ -69,7 +70,7 @@ PassRefPtr<IDBObjectStoreBackendInterface> IDBTransactionBackendImpl::objectStor
     }
 
     // Does a linear search, but it really shouldn't be that slow in practice.
-    if (!m_objectStoreNames->isEmpty() && !m_objectStoreNames->contains(name)) {
+    if (m_mode != IDBTransaction::VERSION_CHANGE && !m_objectStoreNames->contains(name)) {
         ec = IDBDatabaseException::NOT_FOUND_ERR;
         return 0;
     }