Modern IDB: storage/indexeddb/exceptions.html fails.
authorbeidson@apple.com <beidson@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 4 Dec 2015 19:07:19 +0000 (19:07 +0000)
committerbeidson@apple.com <beidson@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 4 Dec 2015 19:07:19 +0000 (19:07 +0000)
https://bugs.webkit.org/show_bug.cgi?id=151732

Reviewed by Alex Christensen.

Source/WebCore:

No new tests (At least one failing test now passes).

- Lots of customized exception messages for IDB code to match the text expectations.
- Updates to the test expectations where we can't/won't match them exactly.
- And a couple of little required behavior changes exposed by the test

* Modules/indexeddb/IDBCursor.h:
* Modules/indexeddb/IDBCursor.idl:
* Modules/indexeddb/IDBDatabase.h:
* Modules/indexeddb/IDBDatabase.idl:
* Modules/indexeddb/IDBDatabaseException.cpp:
(WebCore::IDBDatabaseException::initializeDescription):
* Modules/indexeddb/IDBFactory.h:
* Modules/indexeddb/IDBFactory.idl:
* Modules/indexeddb/IDBIndex.h:
* Modules/indexeddb/IDBIndex.idl:
* Modules/indexeddb/IDBObjectStore.h:
* Modules/indexeddb/IDBObjectStore.idl:
* Modules/indexeddb/IDBRequest.h:
* Modules/indexeddb/IDBRequest.idl:
* Modules/indexeddb/IDBTransaction.h:
* Modules/indexeddb/IDBTransaction.idl:

* Modules/indexeddb/client/IDBCursorImpl.cpp:
(WebCore::IDBClient::IDBCursor::update):
(WebCore::IDBClient::IDBCursor::advance):
(WebCore::IDBClient::IDBCursor::continueFunction):
(WebCore::IDBClient::IDBCursor::deleteFunction):
* Modules/indexeddb/client/IDBCursorImpl.h:

* Modules/indexeddb/client/IDBDatabaseImpl.cpp:
(WebCore::IDBClient::IDBDatabase::createObjectStore):
(WebCore::IDBClient::IDBDatabase::transaction):
(WebCore::IDBClient::IDBDatabase::deleteObjectStore):
* Modules/indexeddb/client/IDBDatabaseImpl.h:

* Modules/indexeddb/client/IDBFactoryImpl.cpp:
(WebCore::IDBClient::IDBFactory::cmp):
* Modules/indexeddb/client/IDBFactoryImpl.h:

* Modules/indexeddb/client/IDBIndexImpl.cpp:
(WebCore::IDBClient::IDBIndex::openCursor):
(WebCore::IDBClient::IDBIndex::count):
(WebCore::IDBClient::IDBIndex::doCount):
(WebCore::IDBClient::IDBIndex::openKeyCursor):
(WebCore::IDBClient::IDBIndex::get):
(WebCore::IDBClient::IDBIndex::doGet):
(WebCore::IDBClient::IDBIndex::getKey):
(WebCore::IDBClient::IDBIndex::doGetKey):
* Modules/indexeddb/client/IDBIndexImpl.h:

* Modules/indexeddb/client/IDBObjectStoreImpl.cpp:
(WebCore::IDBClient::IDBObjectStore::openCursor):
(WebCore::IDBClient::IDBObjectStore::get):
(WebCore::IDBClient::IDBObjectStore::add):
(WebCore::IDBClient::IDBObjectStore::put):
(WebCore::IDBClient::IDBObjectStore::putForCursorUpdate):
(WebCore::IDBClient::IDBObjectStore::putOrAdd):
(WebCore::IDBClient::IDBObjectStore::deleteFunction):
(WebCore::IDBClient::IDBObjectStore::clear):
(WebCore::IDBClient::IDBObjectStore::createIndex):
(WebCore::IDBClient::IDBObjectStore::index):
(WebCore::IDBClient::IDBObjectStore::deleteIndex):
(WebCore::IDBClient::IDBObjectStore::count):
(WebCore::IDBClient::IDBObjectStore::doCount):
* Modules/indexeddb/client/IDBObjectStoreImpl.h:

* Modules/indexeddb/client/IDBRequestImpl.cpp:
(WebCore::IDBClient::IDBRequest::result):
(WebCore::IDBClient::IDBRequest::error):
* Modules/indexeddb/client/IDBRequestImpl.h:

* Modules/indexeddb/client/IDBTransactionImpl.cpp:
(WebCore::IDBClient::IDBTransaction::objectStore):
(WebCore::IDBClient::IDBTransaction::abortDueToFailedRequest):
(WebCore::IDBClient::IDBTransaction::abort):
* Modules/indexeddb/client/IDBTransactionImpl.h:

* Modules/indexeddb/legacy/LegacyCursor.cpp:
(WebCore::LegacyCursor::update):
(WebCore::LegacyCursor::continueFunction):
(WebCore::LegacyCursor::deleteFunction):
* Modules/indexeddb/legacy/LegacyCursor.h:

* Modules/indexeddb/legacy/LegacyDatabase.cpp:
(WebCore::LegacyDatabase::createObjectStore):
(WebCore::LegacyDatabase::deleteObjectStore):
(WebCore::LegacyDatabase::transaction):
(WebCore::LegacyDatabase::forceClose):
* Modules/indexeddb/legacy/LegacyDatabase.h:

* Modules/indexeddb/legacy/LegacyFactory.cpp:
(WebCore::LegacyFactory::cmp):
* Modules/indexeddb/legacy/LegacyFactory.h:

* Modules/indexeddb/legacy/LegacyIndex.cpp:
(WebCore::LegacyIndex::openCursor):
(WebCore::LegacyIndex::count):
(WebCore::LegacyIndex::openKeyCursor):
(WebCore::LegacyIndex::get):
(WebCore::LegacyIndex::getKey):
* Modules/indexeddb/legacy/LegacyIndex.h:

* Modules/indexeddb/legacy/LegacyObjectStore.cpp:
(WebCore::LegacyObjectStore::get):
(WebCore::LegacyObjectStore::add):
(WebCore::LegacyObjectStore::put):
(WebCore::LegacyObjectStore::deleteFunction):
(WebCore::LegacyObjectStore::clear):
(WebCore::LegacyObjectStore::createIndex):
(WebCore::LegacyObjectStore::index):
(WebCore::LegacyObjectStore::deleteIndex):
(WebCore::LegacyObjectStore::openCursor):
(WebCore::LegacyObjectStore::count):
* Modules/indexeddb/legacy/LegacyObjectStore.h:
(WebCore::LegacyObjectStore::createIndex):
(WebCore::LegacyObjectStore::count):

* Modules/indexeddb/legacy/LegacyRequest.cpp:
(WebCore::LegacyRequest::result):
(WebCore::LegacyRequest::error):
(WebCore::LegacyRequest::dispatchEvent):
(WebCore::LegacyRequest::uncaughtExceptionInEventHandler):
* Modules/indexeddb/legacy/LegacyRequest.h:

* Modules/indexeddb/legacy/LegacyTransaction.cpp:
(WebCore::LegacyTransaction::objectStore):
(WebCore::LegacyTransaction::abort):
(WebCore::LegacyTransaction::stop):
* Modules/indexeddb/legacy/LegacyTransaction.h:

* bindings/js/JSDOMBinding.cpp:
(WebCore::createDOMException): For IDBDatabase exceptions, use createWithDescriptionAsMessage

* bindings/js/JSIDBDatabaseCustom.cpp:
(WebCore::JSIDBDatabase::createObjectStore):
(WebCore::JSIDBDatabase::transaction):

* bindings/js/JSIDBObjectStoreCustom.cpp:
(WebCore::putOrAdd):
(WebCore::JSIDBObjectStore::createIndex):

* dom/DOMCoreException.h:
(WebCore::DOMCoreException::createWithDescriptionAsMessage): Create an exception whose message
  is the description.
(WebCore::DOMCoreException::DOMCoreException):

* dom/ExceptionBase.cpp:
(WebCore::ExceptionBase::ExceptionBase): Add a flag to determine where the message comes from
* dom/ExceptionBase.h:

* dom/make_dom_exceptions.pl:
(generateHeader): Add an IDBDatabaseException type

* inspector/InspectorIndexedDBAgent.cpp:

LayoutTests:

Lots of new wk2-specific expectations to keep Legacy IDB passing for now.

* platform/mac-wk1/TestExpectations:
* platform/wk2/imported/w3c/indexeddb/idbcursor_continue_index5-expected.txt: Added.
* platform/wk2/imported/w3c/indexeddb/idbcursor_continue_index6-expected.txt: Added.
* platform/wk2/imported/w3c/indexeddb/idbcursor_continue_invalid-expected.txt: Added.
* platform/wk2/imported/w3c/indexeddb/idbindex_get7-expected.txt: Added.
* platform/wk2/imported/w3c/indexeddb/idbindex_getKey7-expected.txt: Added.
* platform/wk2/imported/w3c/indexeddb/idbindex_openCursor2-expected.txt: Added.
* platform/wk2/imported/w3c/indexeddb/idbindex_openKeyCursor3-expected.txt: Added.
* platform/wk2/imported/w3c/indexeddb/keypath-expected.txt: Added.
* platform/wk2/storage/indexeddb/aborted-versionchange-closes-expected.txt: Copied from LayoutTests/storage/indexeddb/aborted-versionchange-closes-expected.txt.
* platform/wk2/storage/indexeddb/bad-keypath-expected.txt: Copied from LayoutTests/storage/indexeddb/mozilla/bad-keypath-expected.txt.
* platform/wk2/storage/indexeddb/basics-expected.txt: Copied from LayoutTests/storage/indexeddb/basics-expected.txt.
* platform/wk2/storage/indexeddb/clear-expected.txt: Copied from LayoutTests/storage/indexeddb/mozilla/clear-expected.txt.
* platform/wk2/storage/indexeddb/create-and-remove-object-store-expected.txt: Copied from LayoutTests/storage/indexeddb/create-and-remove-object-store-expected.txt.
* platform/wk2/storage/indexeddb/create-objectstore-basics-expected.txt: Copied from LayoutTests/storage/indexeddb/mozilla/create-objectstore-basics-expected.txt.
* platform/wk2/storage/indexeddb/cursor-continue-dir-expected.txt: Added.
* platform/wk2/storage/indexeddb/cursor-continue-expected.txt: Added.
* platform/wk2/storage/indexeddb/cursor-finished-expected.txt: Copied from LayoutTests/storage/indexeddb/cursor-finished-expected.txt.
* platform/wk2/storage/indexeddb/cursors-expected.txt: Copied from LayoutTests/storage/indexeddb/mozilla/cursors-expected.txt.
* platform/wk2/storage/indexeddb/database-basics-expected.txt: Added.
* platform/wk2/storage/indexeddb/deleteIndex-bug110792-expected.txt: Added.
* platform/wk2/storage/indexeddb/index-count-expected.txt: Added.
* platform/wk2/storage/indexeddb/intversion-close-in-oncomplete-expected.txt: Added.
* platform/wk2/storage/indexeddb/intversion-close-in-upgradeneeded-expected.txt: Added.
* platform/wk2/storage/indexeddb/invalid-keys-expected.txt: Added.
* platform/wk2/storage/indexeddb/key-requirements-delete-null-key-expected.txt: Copied from LayoutTests/storage/indexeddb/mozilla/key-requirements-delete-null-key-expected.txt.
* platform/wk2/storage/indexeddb/key-requirements-inline-and-passed-expected.txt: Copied from LayoutTests/storage/indexeddb/mozilla/key-requirements-inline-and-passed-expected.txt.
* platform/wk2/storage/indexeddb/key-requirements-put-no-key-expected.txt: Copied from LayoutTests/storage/indexeddb/mozilla/key-requirements-put-no-key-expected.txt.
* platform/wk2/storage/indexeddb/key-requirements-put-null-key-expected.txt: Copied from LayoutTests/storage/indexeddb/mozilla/key-requirements-put-null-key-expected.txt.
* platform/wk2/storage/indexeddb/key-type-array-expected.txt: Added.
* platform/wk2/storage/indexeddb/keypath-arrays-expected.txt: Added.
* platform/wk2/storage/indexeddb/keypath-edges-expected.txt: Added.
* platform/wk2/storage/indexeddb/keyrange-expected.txt: Added.
* platform/wk2/storage/indexeddb/mozilla/clear-expected.txt: Copied from LayoutTests/storage/indexeddb/mozilla/clear-expected.txt.
* platform/wk2/storage/indexeddb/mozilla/create-objectstore-basics-expected.txt: Copied from LayoutTests/storage/indexeddb/mozilla/create-objectstore-basics-expected.txt.
* platform/wk2/storage/indexeddb/mozilla/cursors-expected.txt: Copied from LayoutTests/storage/indexeddb/mozilla/cursors-expected.txt.
* platform/wk2/storage/indexeddb/mozilla/key-requirements-delete-null-key-expected.txt: Copied from LayoutTests/storage/indexeddb/mozilla/key-requirements-delete-null-key-expected.txt.
* platform/wk2/storage/indexeddb/mozilla/readonly-transactions-expected.txt: Copied from LayoutTests/storage/indexeddb/mozilla/readonly-transactions-expected.txt.
* platform/wk2/storage/indexeddb/object-lookups-in-versionchange-expected.txt: Added.
* platform/wk2/storage/indexeddb/objectstore-count-expected.txt: Added.
* platform/wk2/storage/indexeddb/open-cursor-expected.txt: Added.
* platform/wk2/storage/indexeddb/readonly-transactions-expected.txt: Copied from LayoutTests/storage/indexeddb/mozilla/readonly-transactions-expected.txt.
* platform/wk2/storage/indexeddb/removed-expected.txt: Added.
* platform/wk2/storage/indexeddb/request-result-cache-expected.txt: Added.
* platform/wk2/storage/indexeddb/transaction-abort-expected.txt: Copied from LayoutTests/storage/indexeddb/transaction-abort-expected.txt.
* platform/wk2/storage/indexeddb/transaction-active-flag-expected.txt: Added.
* platform/wk2/storage/indexeddb/transaction-after-close-expected.txt: Added.
* platform/wk2/storage/indexeddb/transaction-read-only-expected.txt: Added.
* platform/wk2/storage/indexeddb/version-change-exclusive-expected.txt: Added.
* storage/indexeddb/aborted-versionchange-closes-expected.txt:
* storage/indexeddb/basics-expected.txt:
* storage/indexeddb/create-and-remove-object-store-expected.txt:
* storage/indexeddb/cursor-finished-expected.txt:
* storage/indexeddb/exceptions-expected.txt:
* storage/indexeddb/modern/createobjectstore-failures-expected.txt:
* storage/indexeddb/modern/double-abort-expected.txt:
* storage/indexeddb/modern/idbdatabase-deleteobjectstore-failures-expected.txt:
* storage/indexeddb/modern/idbdatabase-transaction-failures-expected.txt:
* storage/indexeddb/mozilla/bad-keypath-expected.txt:
* storage/indexeddb/mozilla/clear-expected.txt:
* storage/indexeddb/mozilla/create-objectstore-basics-expected.txt:
* storage/indexeddb/mozilla/cursors-expected.txt:
* storage/indexeddb/mozilla/key-requirements-delete-null-key-expected.txt:
* storage/indexeddb/mozilla/key-requirements-inline-and-passed-expected.txt:
* storage/indexeddb/mozilla/key-requirements-put-no-key-expected.txt:
* storage/indexeddb/mozilla/key-requirements-put-null-key-expected.txt:
* storage/indexeddb/mozilla/readonly-transactions-expected.txt:
* storage/indexeddb/resources/exceptions.js:
(testObjectStore):
* storage/indexeddb/transaction-abort-expected.txt:

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

122 files changed:
LayoutTests/ChangeLog
LayoutTests/platform/mac-wk1/TestExpectations
LayoutTests/platform/wk2/imported/w3c/indexeddb/idbcursor_continue_index5-expected.txt [new file with mode: 0644]
LayoutTests/platform/wk2/imported/w3c/indexeddb/idbcursor_continue_index6-expected.txt [new file with mode: 0644]
LayoutTests/platform/wk2/imported/w3c/indexeddb/idbcursor_continue_invalid-expected.txt [new file with mode: 0644]
LayoutTests/platform/wk2/imported/w3c/indexeddb/idbindex_get7-expected.txt [new file with mode: 0644]
LayoutTests/platform/wk2/imported/w3c/indexeddb/idbindex_getKey7-expected.txt [new file with mode: 0644]
LayoutTests/platform/wk2/imported/w3c/indexeddb/idbindex_openCursor2-expected.txt [new file with mode: 0644]
LayoutTests/platform/wk2/imported/w3c/indexeddb/idbindex_openKeyCursor3-expected.txt [new file with mode: 0644]
LayoutTests/platform/wk2/imported/w3c/indexeddb/keypath-expected.txt [new file with mode: 0644]
LayoutTests/platform/wk2/storage/indexeddb/aborted-versionchange-closes-expected.txt [new file with mode: 0644]
LayoutTests/platform/wk2/storage/indexeddb/bad-keypath-expected.txt [new file with mode: 0644]
LayoutTests/platform/wk2/storage/indexeddb/basics-expected.txt [new file with mode: 0644]
LayoutTests/platform/wk2/storage/indexeddb/clear-expected.txt [new file with mode: 0644]
LayoutTests/platform/wk2/storage/indexeddb/create-and-remove-object-store-expected.txt [new file with mode: 0644]
LayoutTests/platform/wk2/storage/indexeddb/create-objectstore-basics-expected.txt [new file with mode: 0644]
LayoutTests/platform/wk2/storage/indexeddb/cursor-continue-dir-expected.txt [new file with mode: 0644]
LayoutTests/platform/wk2/storage/indexeddb/cursor-continue-expected.txt [new file with mode: 0644]
LayoutTests/platform/wk2/storage/indexeddb/cursor-finished-expected.txt [new file with mode: 0644]
LayoutTests/platform/wk2/storage/indexeddb/cursors-expected.txt [new file with mode: 0644]
LayoutTests/platform/wk2/storage/indexeddb/database-basics-expected.txt [new file with mode: 0644]
LayoutTests/platform/wk2/storage/indexeddb/deleteIndex-bug110792-expected.txt [new file with mode: 0644]
LayoutTests/platform/wk2/storage/indexeddb/index-count-expected.txt [new file with mode: 0644]
LayoutTests/platform/wk2/storage/indexeddb/intversion-close-in-oncomplete-expected.txt [new file with mode: 0644]
LayoutTests/platform/wk2/storage/indexeddb/intversion-close-in-upgradeneeded-expected.txt [new file with mode: 0644]
LayoutTests/platform/wk2/storage/indexeddb/invalid-keys-expected.txt [new file with mode: 0644]
LayoutTests/platform/wk2/storage/indexeddb/key-requirements-delete-null-key-expected.txt [new file with mode: 0644]
LayoutTests/platform/wk2/storage/indexeddb/key-requirements-inline-and-passed-expected.txt [new file with mode: 0644]
LayoutTests/platform/wk2/storage/indexeddb/key-requirements-put-no-key-expected.txt [new file with mode: 0644]
LayoutTests/platform/wk2/storage/indexeddb/key-requirements-put-null-key-expected.txt [new file with mode: 0644]
LayoutTests/platform/wk2/storage/indexeddb/key-type-array-expected.txt [new file with mode: 0644]
LayoutTests/platform/wk2/storage/indexeddb/keypath-arrays-expected.txt [new file with mode: 0644]
LayoutTests/platform/wk2/storage/indexeddb/keypath-edges-expected.txt [new file with mode: 0644]
LayoutTests/platform/wk2/storage/indexeddb/keyrange-expected.txt [new file with mode: 0644]
LayoutTests/platform/wk2/storage/indexeddb/mozilla/clear-expected.txt [new file with mode: 0644]
LayoutTests/platform/wk2/storage/indexeddb/mozilla/create-objectstore-basics-expected.txt [new file with mode: 0644]
LayoutTests/platform/wk2/storage/indexeddb/mozilla/cursors-expected.txt [new file with mode: 0644]
LayoutTests/platform/wk2/storage/indexeddb/mozilla/key-requirements-delete-null-key-expected.txt [new file with mode: 0644]
LayoutTests/platform/wk2/storage/indexeddb/mozilla/readonly-transactions-expected.txt [new file with mode: 0644]
LayoutTests/platform/wk2/storage/indexeddb/object-lookups-in-versionchange-expected.txt [new file with mode: 0644]
LayoutTests/platform/wk2/storage/indexeddb/objectstore-count-expected.txt [new file with mode: 0644]
LayoutTests/platform/wk2/storage/indexeddb/open-cursor-expected.txt [new file with mode: 0644]
LayoutTests/platform/wk2/storage/indexeddb/readonly-transactions-expected.txt [new file with mode: 0644]
LayoutTests/platform/wk2/storage/indexeddb/removed-expected.txt [new file with mode: 0644]
LayoutTests/platform/wk2/storage/indexeddb/request-result-cache-expected.txt [new file with mode: 0644]
LayoutTests/platform/wk2/storage/indexeddb/transaction-abort-expected.txt [new file with mode: 0644]
LayoutTests/platform/wk2/storage/indexeddb/transaction-active-flag-expected.txt [new file with mode: 0644]
LayoutTests/platform/wk2/storage/indexeddb/transaction-after-close-expected.txt [new file with mode: 0644]
LayoutTests/platform/wk2/storage/indexeddb/transaction-read-only-expected.txt [new file with mode: 0644]
LayoutTests/platform/wk2/storage/indexeddb/version-change-exclusive-expected.txt [new file with mode: 0644]
LayoutTests/storage/indexeddb/aborted-versionchange-closes-expected.txt
LayoutTests/storage/indexeddb/basics-expected.txt
LayoutTests/storage/indexeddb/create-and-remove-object-store-expected.txt
LayoutTests/storage/indexeddb/cursor-finished-expected.txt
LayoutTests/storage/indexeddb/exceptions-expected.txt
LayoutTests/storage/indexeddb/modern/createobjectstore-failures-expected.txt
LayoutTests/storage/indexeddb/modern/double-abort-expected.txt
LayoutTests/storage/indexeddb/modern/idbdatabase-deleteobjectstore-failures-expected.txt
LayoutTests/storage/indexeddb/modern/idbdatabase-transaction-failures-expected.txt
LayoutTests/storage/indexeddb/mozilla/bad-keypath-expected.txt
LayoutTests/storage/indexeddb/mozilla/clear-expected.txt
LayoutTests/storage/indexeddb/mozilla/create-objectstore-basics-expected.txt
LayoutTests/storage/indexeddb/mozilla/cursors-expected.txt
LayoutTests/storage/indexeddb/mozilla/key-requirements-delete-null-key-expected.txt
LayoutTests/storage/indexeddb/mozilla/key-requirements-inline-and-passed-expected.txt
LayoutTests/storage/indexeddb/mozilla/key-requirements-put-no-key-expected.txt
LayoutTests/storage/indexeddb/mozilla/key-requirements-put-null-key-expected.txt
LayoutTests/storage/indexeddb/mozilla/readonly-transactions-expected.txt
LayoutTests/storage/indexeddb/resources/exceptions.js
LayoutTests/storage/indexeddb/transaction-abort-expected.txt
Source/WebCore/ChangeLog
Source/WebCore/Modules/indexeddb/IDBCursor.h
Source/WebCore/Modules/indexeddb/IDBCursor.idl
Source/WebCore/Modules/indexeddb/IDBDatabase.h
Source/WebCore/Modules/indexeddb/IDBDatabase.idl
Source/WebCore/Modules/indexeddb/IDBDatabaseException.cpp
Source/WebCore/Modules/indexeddb/IDBFactory.h
Source/WebCore/Modules/indexeddb/IDBFactory.idl
Source/WebCore/Modules/indexeddb/IDBIndex.h
Source/WebCore/Modules/indexeddb/IDBIndex.idl
Source/WebCore/Modules/indexeddb/IDBObjectStore.h
Source/WebCore/Modules/indexeddb/IDBObjectStore.idl
Source/WebCore/Modules/indexeddb/IDBRequest.h
Source/WebCore/Modules/indexeddb/IDBRequest.idl
Source/WebCore/Modules/indexeddb/IDBTransaction.h
Source/WebCore/Modules/indexeddb/IDBTransaction.idl
Source/WebCore/Modules/indexeddb/client/IDBCursorImpl.cpp
Source/WebCore/Modules/indexeddb/client/IDBCursorImpl.h
Source/WebCore/Modules/indexeddb/client/IDBDatabaseImpl.cpp
Source/WebCore/Modules/indexeddb/client/IDBDatabaseImpl.h
Source/WebCore/Modules/indexeddb/client/IDBFactoryImpl.cpp
Source/WebCore/Modules/indexeddb/client/IDBFactoryImpl.h
Source/WebCore/Modules/indexeddb/client/IDBIndexImpl.cpp
Source/WebCore/Modules/indexeddb/client/IDBIndexImpl.h
Source/WebCore/Modules/indexeddb/client/IDBObjectStoreImpl.cpp
Source/WebCore/Modules/indexeddb/client/IDBObjectStoreImpl.h
Source/WebCore/Modules/indexeddb/client/IDBRequestImpl.cpp
Source/WebCore/Modules/indexeddb/client/IDBRequestImpl.h
Source/WebCore/Modules/indexeddb/client/IDBTransactionImpl.cpp
Source/WebCore/Modules/indexeddb/client/IDBTransactionImpl.h
Source/WebCore/Modules/indexeddb/legacy/LegacyCursor.cpp
Source/WebCore/Modules/indexeddb/legacy/LegacyCursor.h
Source/WebCore/Modules/indexeddb/legacy/LegacyDatabase.cpp
Source/WebCore/Modules/indexeddb/legacy/LegacyDatabase.h
Source/WebCore/Modules/indexeddb/legacy/LegacyFactory.cpp
Source/WebCore/Modules/indexeddb/legacy/LegacyFactory.h
Source/WebCore/Modules/indexeddb/legacy/LegacyIndex.cpp
Source/WebCore/Modules/indexeddb/legacy/LegacyIndex.h
Source/WebCore/Modules/indexeddb/legacy/LegacyObjectStore.cpp
Source/WebCore/Modules/indexeddb/legacy/LegacyObjectStore.h
Source/WebCore/Modules/indexeddb/legacy/LegacyRequest.cpp
Source/WebCore/Modules/indexeddb/legacy/LegacyRequest.h
Source/WebCore/Modules/indexeddb/legacy/LegacyTransaction.cpp
Source/WebCore/Modules/indexeddb/legacy/LegacyTransaction.h
Source/WebCore/bindings/js/JSDOMBinding.cpp
Source/WebCore/bindings/js/JSIDBDatabaseCustom.cpp
Source/WebCore/bindings/js/JSIDBObjectStoreCustom.cpp
Source/WebCore/dom/DOMCoreException.h
Source/WebCore/dom/ExceptionBase.cpp
Source/WebCore/dom/ExceptionBase.h
Source/WebCore/dom/make_dom_exceptions.pl
Source/WebCore/inspector/InspectorIndexedDBAgent.cpp

index 265b069..5722041 100644 (file)
@@ -1,3 +1,83 @@
+2015-12-04  Brady Eidson  <beidson@apple.com>
+
+        Modern IDB: storage/indexeddb/exceptions.html fails.
+        https://bugs.webkit.org/show_bug.cgi?id=151732
+
+        Reviewed by Alex Christensen.
+
+        Lots of new wk2-specific expectations to keep Legacy IDB passing for now.
+        
+        * platform/mac-wk1/TestExpectations:
+        * platform/wk2/imported/w3c/indexeddb/idbcursor_continue_index5-expected.txt: Added.
+        * platform/wk2/imported/w3c/indexeddb/idbcursor_continue_index6-expected.txt: Added.
+        * platform/wk2/imported/w3c/indexeddb/idbcursor_continue_invalid-expected.txt: Added.
+        * platform/wk2/imported/w3c/indexeddb/idbindex_get7-expected.txt: Added.
+        * platform/wk2/imported/w3c/indexeddb/idbindex_getKey7-expected.txt: Added.
+        * platform/wk2/imported/w3c/indexeddb/idbindex_openCursor2-expected.txt: Added.
+        * platform/wk2/imported/w3c/indexeddb/idbindex_openKeyCursor3-expected.txt: Added.
+        * platform/wk2/imported/w3c/indexeddb/keypath-expected.txt: Added.
+        * platform/wk2/storage/indexeddb/aborted-versionchange-closes-expected.txt: Copied from LayoutTests/storage/indexeddb/aborted-versionchange-closes-expected.txt.
+        * platform/wk2/storage/indexeddb/bad-keypath-expected.txt: Copied from LayoutTests/storage/indexeddb/mozilla/bad-keypath-expected.txt.
+        * platform/wk2/storage/indexeddb/basics-expected.txt: Copied from LayoutTests/storage/indexeddb/basics-expected.txt.
+        * platform/wk2/storage/indexeddb/clear-expected.txt: Copied from LayoutTests/storage/indexeddb/mozilla/clear-expected.txt.
+        * platform/wk2/storage/indexeddb/create-and-remove-object-store-expected.txt: Copied from LayoutTests/storage/indexeddb/create-and-remove-object-store-expected.txt.
+        * platform/wk2/storage/indexeddb/create-objectstore-basics-expected.txt: Copied from LayoutTests/storage/indexeddb/mozilla/create-objectstore-basics-expected.txt.
+        * platform/wk2/storage/indexeddb/cursor-continue-dir-expected.txt: Added.
+        * platform/wk2/storage/indexeddb/cursor-continue-expected.txt: Added.
+        * platform/wk2/storage/indexeddb/cursor-finished-expected.txt: Copied from LayoutTests/storage/indexeddb/cursor-finished-expected.txt.
+        * platform/wk2/storage/indexeddb/cursors-expected.txt: Copied from LayoutTests/storage/indexeddb/mozilla/cursors-expected.txt.
+        * platform/wk2/storage/indexeddb/database-basics-expected.txt: Added.
+        * platform/wk2/storage/indexeddb/deleteIndex-bug110792-expected.txt: Added.
+        * platform/wk2/storage/indexeddb/index-count-expected.txt: Added.
+        * platform/wk2/storage/indexeddb/intversion-close-in-oncomplete-expected.txt: Added.
+        * platform/wk2/storage/indexeddb/intversion-close-in-upgradeneeded-expected.txt: Added.
+        * platform/wk2/storage/indexeddb/invalid-keys-expected.txt: Added.
+        * platform/wk2/storage/indexeddb/key-requirements-delete-null-key-expected.txt: Copied from LayoutTests/storage/indexeddb/mozilla/key-requirements-delete-null-key-expected.txt.
+        * platform/wk2/storage/indexeddb/key-requirements-inline-and-passed-expected.txt: Copied from LayoutTests/storage/indexeddb/mozilla/key-requirements-inline-and-passed-expected.txt.
+        * platform/wk2/storage/indexeddb/key-requirements-put-no-key-expected.txt: Copied from LayoutTests/storage/indexeddb/mozilla/key-requirements-put-no-key-expected.txt.
+        * platform/wk2/storage/indexeddb/key-requirements-put-null-key-expected.txt: Copied from LayoutTests/storage/indexeddb/mozilla/key-requirements-put-null-key-expected.txt.
+        * platform/wk2/storage/indexeddb/key-type-array-expected.txt: Added.
+        * platform/wk2/storage/indexeddb/keypath-arrays-expected.txt: Added.
+        * platform/wk2/storage/indexeddb/keypath-edges-expected.txt: Added.
+        * platform/wk2/storage/indexeddb/keyrange-expected.txt: Added.
+        * platform/wk2/storage/indexeddb/mozilla/clear-expected.txt: Copied from LayoutTests/storage/indexeddb/mozilla/clear-expected.txt.
+        * platform/wk2/storage/indexeddb/mozilla/create-objectstore-basics-expected.txt: Copied from LayoutTests/storage/indexeddb/mozilla/create-objectstore-basics-expected.txt.
+        * platform/wk2/storage/indexeddb/mozilla/cursors-expected.txt: Copied from LayoutTests/storage/indexeddb/mozilla/cursors-expected.txt.
+        * platform/wk2/storage/indexeddb/mozilla/key-requirements-delete-null-key-expected.txt: Copied from LayoutTests/storage/indexeddb/mozilla/key-requirements-delete-null-key-expected.txt.
+        * platform/wk2/storage/indexeddb/mozilla/readonly-transactions-expected.txt: Copied from LayoutTests/storage/indexeddb/mozilla/readonly-transactions-expected.txt.
+        * platform/wk2/storage/indexeddb/object-lookups-in-versionchange-expected.txt: Added.
+        * platform/wk2/storage/indexeddb/objectstore-count-expected.txt: Added.
+        * platform/wk2/storage/indexeddb/open-cursor-expected.txt: Added.
+        * platform/wk2/storage/indexeddb/readonly-transactions-expected.txt: Copied from LayoutTests/storage/indexeddb/mozilla/readonly-transactions-expected.txt.
+        * platform/wk2/storage/indexeddb/removed-expected.txt: Added.
+        * platform/wk2/storage/indexeddb/request-result-cache-expected.txt: Added.
+        * platform/wk2/storage/indexeddb/transaction-abort-expected.txt: Copied from LayoutTests/storage/indexeddb/transaction-abort-expected.txt.
+        * platform/wk2/storage/indexeddb/transaction-active-flag-expected.txt: Added.
+        * platform/wk2/storage/indexeddb/transaction-after-close-expected.txt: Added.
+        * platform/wk2/storage/indexeddb/transaction-read-only-expected.txt: Added.
+        * platform/wk2/storage/indexeddb/version-change-exclusive-expected.txt: Added.
+        * storage/indexeddb/aborted-versionchange-closes-expected.txt:
+        * storage/indexeddb/basics-expected.txt:
+        * storage/indexeddb/create-and-remove-object-store-expected.txt:
+        * storage/indexeddb/cursor-finished-expected.txt:
+        * storage/indexeddb/exceptions-expected.txt:
+        * storage/indexeddb/modern/createobjectstore-failures-expected.txt:
+        * storage/indexeddb/modern/double-abort-expected.txt:
+        * storage/indexeddb/modern/idbdatabase-deleteobjectstore-failures-expected.txt:
+        * storage/indexeddb/modern/idbdatabase-transaction-failures-expected.txt:
+        * storage/indexeddb/mozilla/bad-keypath-expected.txt:
+        * storage/indexeddb/mozilla/clear-expected.txt:
+        * storage/indexeddb/mozilla/create-objectstore-basics-expected.txt:
+        * storage/indexeddb/mozilla/cursors-expected.txt:
+        * storage/indexeddb/mozilla/key-requirements-delete-null-key-expected.txt:
+        * storage/indexeddb/mozilla/key-requirements-inline-and-passed-expected.txt:
+        * storage/indexeddb/mozilla/key-requirements-put-no-key-expected.txt:
+        * storage/indexeddb/mozilla/key-requirements-put-null-key-expected.txt:
+        * storage/indexeddb/mozilla/readonly-transactions-expected.txt:
+        * storage/indexeddb/resources/exceptions.js:
+        (testObjectStore):
+        * storage/indexeddb/transaction-abort-expected.txt:
+
 2015-12-04  Joseph Pecoraro  <pecoraro@apple.com>
 
         Web Inspector: Unskip many inspector/debugger tests
index da880e4..9eb6f19 100644 (file)
@@ -83,6 +83,7 @@ storage/indexeddb/cursor-index-delete.html [ Pass ]
 storage/indexeddb/cursor-overloads.html [ Pass ]
 storage/indexeddb/cursor-skip-deleted.html [ Pass ]
 storage/indexeddb/events.html [ Pass ]
+storage/indexeddb/exceptions.html [ Pass ]
 storage/indexeddb/modern [ Pass ]
 storage/indexeddb/mozilla [ Pass ]
 storage/indexeddb/transaction-abort.html [ Pass ]
diff --git a/LayoutTests/platform/wk2/imported/w3c/indexeddb/idbcursor_continue_index5-expected.txt b/LayoutTests/platform/wk2/imported/w3c/indexeddb/idbcursor_continue_index5-expected.txt
new file mode 100644 (file)
index 0000000..696e03e
--- /dev/null
@@ -0,0 +1,3 @@
+
+FAIL IDBCursor.continue() - index - iterate using 'prevunique' The data provided does not meet requirements.
+
diff --git a/LayoutTests/platform/wk2/imported/w3c/indexeddb/idbcursor_continue_index6-expected.txt b/LayoutTests/platform/wk2/imported/w3c/indexeddb/idbcursor_continue_index6-expected.txt
new file mode 100644 (file)
index 0000000..96faa12
--- /dev/null
@@ -0,0 +1,3 @@
+
+FAIL IDBCursor.continue() - index - iterate using nextunique The data provided does not meet requirements.
+
diff --git a/LayoutTests/platform/wk2/imported/w3c/indexeddb/idbcursor_continue_invalid-expected.txt b/LayoutTests/platform/wk2/imported/w3c/indexeddb/idbcursor_continue_invalid-expected.txt
new file mode 100644 (file)
index 0000000..1471907
--- /dev/null
@@ -0,0 +1,3 @@
+
+FAIL IDBCursor.continue() - attempt to call continue two times The data provided does not meet requirements.
+
diff --git a/LayoutTests/platform/wk2/imported/w3c/indexeddb/idbindex_get7-expected.txt b/LayoutTests/platform/wk2/imported/w3c/indexeddb/idbindex_get7-expected.txt
new file mode 100644 (file)
index 0000000..7b8016f
--- /dev/null
@@ -0,0 +1,5 @@
+
+FAIL IDBIndex.get() - throw TransactionInactiveError on aborted transaction assert_throws: function "function (){
+            index.get("data");
+        }" threw object "Error: A request was placed against a transaction which i..." that is not a DOMException InvalidStateError: property "code" is equal to 0, expected 11
+
diff --git a/LayoutTests/platform/wk2/imported/w3c/indexeddb/idbindex_getKey7-expected.txt b/LayoutTests/platform/wk2/imported/w3c/indexeddb/idbindex_getKey7-expected.txt
new file mode 100644 (file)
index 0000000..5669f4c
--- /dev/null
@@ -0,0 +1,5 @@
+
+FAIL IDBIndex.getKey() - throw TransactionInactiveError on aborted transaction assert_throws: function "function (){
+            index.getKey("data");
+        }" threw object "Error: A request was placed against a transaction which i..." that is not a DOMException InvalidStateError: property "code" is equal to 0, expected 11
+
diff --git a/LayoutTests/platform/wk2/imported/w3c/indexeddb/idbindex_openCursor2-expected.txt b/LayoutTests/platform/wk2/imported/w3c/indexeddb/idbindex_openCursor2-expected.txt
new file mode 100644 (file)
index 0000000..7f05ad9
--- /dev/null
@@ -0,0 +1,5 @@
+
+FAIL IDBIndex.openCursor() - throw TransactionInactiveError on aborted transaction assert_throws: function "function (){
+            index.openCursor();
+        }" threw object "Error: A request was placed against a transaction which i..." that is not a DOMException InvalidStateError: property "code" is equal to 0, expected 11
+
diff --git a/LayoutTests/platform/wk2/imported/w3c/indexeddb/idbindex_openKeyCursor3-expected.txt b/LayoutTests/platform/wk2/imported/w3c/indexeddb/idbindex_openKeyCursor3-expected.txt
new file mode 100644 (file)
index 0000000..f489005
--- /dev/null
@@ -0,0 +1,5 @@
+
+FAIL IDBIndex.openKeyCursor() - throw TransactionInactiveError on aborted transaction assert_throws: function "function (){
+            index.openKeyCursor();
+        }" threw object "Error: A request was placed against a transaction which i..." that is not a DOMException InvalidStateError: property "code" is equal to 0, expected 11
+
diff --git a/LayoutTests/platform/wk2/imported/w3c/indexeddb/keypath-expected.txt b/LayoutTests/platform/wk2/imported/w3c/indexeddb/keypath-expected.txt
new file mode 100644 (file)
index 0000000..0215523
--- /dev/null
@@ -0,0 +1,21 @@
+
+PASS Keypath - my.key 
+FAIL Keypath - my.køi The data provided does not meet requirements.
+PASS Keypath - my.key_ya 
+PASS Keypath - public.key$ya 
+PASS Keypath - true.$ 
+PASS Keypath - my._ 
+PASS Keypath - delete.a7 
+PASS Keypath - p.p.p.p.p.p.p.p.p.p.p.p.p.p 
+PASS Keypath - str.length 
+PASS Keypath - arr.length 
+PASS Keypath - length 
+PASS Keypath - '' uses value as key 
+PASS Keypath - [''] uses value as [key] 
+PASS Keypath - ['x', 'y'] 
+PASS Keypath - [['x'], 'y'] (stringifies) 
+PASS Keypath - ['x', {toString->'y'}] (stringifies) 
+PASS Keypath - name,type 
+PASS Keypath - name,type.name 
+PASS Keypath - array loop -> stringify becomes [''] 
+
diff --git a/LayoutTests/platform/wk2/storage/indexeddb/aborted-versionchange-closes-expected.txt b/LayoutTests/platform/wk2/storage/indexeddb/aborted-versionchange-closes-expected.txt
new file mode 100644 (file)
index 0000000..093304a
--- /dev/null
@@ -0,0 +1,48 @@
+Test that an aborted 'versionchange' transaction closes the connection.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+indexedDB = self.indexedDB || self.webkitIndexedDB || self.mozIndexedDB || self.msIndexedDB || self.OIndexedDB;
+
+dbname = "aborted-versionchange-closes.html"
+indexedDB.deleteDatabase(dbname)
+indexedDB.open(dbname, 1)
+
+prepareDatabase():
+db = event.target.result
+db.createObjectStore('store')
+
+onOpen():
+db = event.target.result
+db.close()
+
+openAgain():
+request = indexedDB.open(dbname, 2)
+
+onUpgradeNeeded():
+db = event.target.result
+transaction = event.target.transaction
+sawTransactionAbort = false
+
+onTransactionAbort():
+sawTransactionAbort = true
+creating a transaction should fail because connection is closed:
+Expecting exception from db.transaction('store')
+PASS Exception was thrown.
+PASS code is DOMException.INVALID_STATE_ERR
+PASS ename is 'InvalidStateError'
+Exception message: An operation was called on an object on which it is not allowed or at a time when it is not allowed.
+
+onOpenError():
+PASS sawTransactionAbort is true
+creating a transaction should fail because connection is closed:
+Expecting exception from db.transaction('store')
+PASS Exception was thrown.
+PASS code is DOMException.INVALID_STATE_ERR
+PASS ename is 'InvalidStateError'
+Exception message: An operation was called on an object on which it is not allowed or at a time when it is not allowed.
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
diff --git a/LayoutTests/platform/wk2/storage/indexeddb/bad-keypath-expected.txt b/LayoutTests/platform/wk2/storage/indexeddb/bad-keypath-expected.txt
new file mode 100644 (file)
index 0000000..5449adf
--- /dev/null
@@ -0,0 +1,21 @@
+Test IndexedDB adding property with invalid keypath
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+indexedDB = self.indexedDB || self.webkitIndexedDB || self.mozIndexedDB || self.msIndexedDB || self.OIndexedDB;
+
+dbname = "bad-keypath.html"
+indexedDB.deleteDatabase(dbname)
+indexedDB.open(dbname)
+objectStore = db.createObjectStore('foo', { keyPath: 'keyPath' });
+request = objectStore.add({ keyPath: 'foo' });
+Expecting exception from request = objectStore.add({});
+PASS Exception was thrown.
+PASS code is 0
+PASS ename is 'DataError'
+Exception message: The data provided does not meet requirements.
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
diff --git a/LayoutTests/platform/wk2/storage/indexeddb/basics-expected.txt b/LayoutTests/platform/wk2/storage/indexeddb/basics-expected.txt
new file mode 100644 (file)
index 0000000..ff61f14
--- /dev/null
@@ -0,0 +1,46 @@
+Test IndexedDB's basics.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+indexedDB = self.indexedDB || self.webkitIndexedDB || self.mozIndexedDB || self.msIndexedDB || self.OIndexedDB;
+
+indexedDB.open('basics')
+PASS 'result' in request is true
+Expecting exception from request.result
+PASS Exception was thrown.
+PASS code is DOMException.INVALID_STATE_ERR
+PASS ename is 'InvalidStateError'
+Exception message: An operation was called on an object on which it is not allowed or at a time when it is not allowed.
+PASS 'error' in request is true
+Expecting exception from request.error
+PASS Exception was thrown.
+PASS code is DOMException.INVALID_STATE_ERR
+PASS ename is 'InvalidStateError'
+Exception message: An operation was called on an object on which it is not allowed or at a time when it is not allowed.
+PASS 'source' in request is true
+PASS request.source is null
+PASS 'transaction' in request is true
+PASS request.transaction is null
+PASS 'readyState' in request is true
+PASS request.readyState is "pending"
+PASS 'onsuccess' in request is true
+PASS request.onsuccess is null
+PASS 'onerror' in request is true
+PASS request.onerror is null
+PASS 'result' in event.target is true
+PASS !!event.target.result is true
+PASS 'error' in event.target is true
+PASS event.target.error is null
+PASS 'source' in event.target is true
+PASS request.source is null
+PASS 'transaction' in event.target is true
+PASS event.target.transaction is null
+PASS 'readyState' in request is true
+PASS event.target.readyState is "done"
+PASS 'onsuccess' in event.target is true
+PASS 'onerror' in event.target is true
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
diff --git a/LayoutTests/platform/wk2/storage/indexeddb/clear-expected.txt b/LayoutTests/platform/wk2/storage/indexeddb/clear-expected.txt
new file mode 100644 (file)
index 0000000..60bba5f
--- /dev/null
@@ -0,0 +1,26 @@
+Test IndexedDB's clearing an object store
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+indexedDB = self.indexedDB || self.webkitIndexedDB || self.mozIndexedDB || self.msIndexedDB || self.OIndexedDB;
+
+dbname = "clear.html"
+indexedDB.deleteDatabase(dbname)
+indexedDB.open(dbname)
+objectStore = db.createObjectStore('foo', { autoIncrement: true });
+request = objectStore.add({});
+Expecting exception from db.transaction('foo').objectStore('foo').clear();
+PASS Exception was thrown.
+PASS code is 0
+PASS ename is 'ReadOnlyError'
+Exception message: A write operation was attempted in a read-only transaction.
+db.transaction('foo', 'readwrite')
+transaction.objectStore('foo').clear();
+request = db.transaction('foo').objectStore('foo').openCursor();
+cursor = request.result;
+PASS cursor is null
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
diff --git a/LayoutTests/platform/wk2/storage/indexeddb/create-and-remove-object-store-expected.txt b/LayoutTests/platform/wk2/storage/indexeddb/create-and-remove-object-store-expected.txt
new file mode 100644 (file)
index 0000000..e77033e
--- /dev/null
@@ -0,0 +1,47 @@
+Test IndexedDB's create and removeObjectStore
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+indexedDB = self.indexedDB || self.webkitIndexedDB || self.mozIndexedDB || self.msIndexedDB || self.OIndexedDB;
+
+dbname = "create-and-remove-object-store.html"
+indexedDB.deleteDatabase(dbname)
+indexedDB.open(dbname)
+db.createObjectStore('tmp')
+Expecting exception from db.createObjectStore('tmp')
+PASS Exception was thrown.
+PASS code is 0
+PASS ename is 'ConstraintError'
+Exception message: A mutation operation in the transaction failed because a constraint was not satisfied.
+trans = db.transaction(['tmp'])
+trans.objectStore('tmp').get(0)
+PASS event.target.result is undefined.
+Trying create
+Expecting exception from db.createObjectStore("some os")
+PASS Exception was thrown.
+PASS code is DOMException.INVALID_STATE_ERR
+PASS ename is 'InvalidStateError'
+Exception message: An operation was called on an object on which it is not allowed or at a time when it is not allowed.
+Trying remove
+Expecting exception from db.deleteObjectStore("some os")
+PASS Exception was thrown.
+PASS code is DOMException.INVALID_STATE_ERR
+PASS ename is 'InvalidStateError'
+Exception message: An operation was called on an object on which it is not allowed or at a time when it is not allowed.
+Trying create with store that already exists
+Expecting exception from db.createObjectStore('tmp')
+PASS Exception was thrown.
+PASS code is DOMException.INVALID_STATE_ERR
+PASS ename is 'InvalidStateError'
+Exception message: An operation was called on an object on which it is not allowed or at a time when it is not allowed.
+Trying remove with store that already exists
+Expecting exception from db.deleteObjectStore('tmp')
+PASS Exception was thrown.
+PASS code is DOMException.INVALID_STATE_ERR
+PASS ename is 'InvalidStateError'
+Exception message: An operation was called on an object on which it is not allowed or at a time when it is not allowed.
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
diff --git a/LayoutTests/platform/wk2/storage/indexeddb/create-objectstore-basics-expected.txt b/LayoutTests/platform/wk2/storage/indexeddb/create-objectstore-basics-expected.txt
new file mode 100644 (file)
index 0000000..f9c5c80
--- /dev/null
@@ -0,0 +1,56 @@
+Test IndexedDB's creating object store and updating properties
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+indexedDB = self.indexedDB || self.webkitIndexedDB || self.mozIndexedDB || self.msIndexedDB || self.OIndexedDB;
+
+dbname = "create-objectstore-basics.html"
+indexedDB.deleteDatabase(dbname)
+indexedDB.open(dbname)
+objectStore = db.createObjectStore(info.name, info.options);
+PASS objectStore.name is info.name
+PASS objectStore.indexNames.length is 0
+PASS event.target.transaction.db is db
+PASS event.target.transaction.mode is "versionchange"
+objectStore = db.createObjectStore(info.name, info.options);
+PASS objectStore.name is info.name
+PASS objectStore.indexNames.length is 0
+PASS event.target.transaction.db is db
+PASS event.target.transaction.mode is "versionchange"
+objectStore = db.createObjectStore(info.name, info.options);
+PASS objectStore.name is info.name
+PASS objectStore.indexNames.length is 0
+PASS event.target.transaction.db is db
+PASS event.target.transaction.mode is "versionchange"
+Expecting exception from objectStore = db.createObjectStore(info.name, info.options)
+PASS Exception was thrown.
+PASS code is DOMException.INVALID_ACCESS_ERR
+Exception message: An invalid operation was performed on an object.
+objectStore = db.createObjectStore(info.name, info.options);
+PASS objectStore.name is info.name
+PASS objectStore.indexNames.length is 0
+PASS event.target.transaction.db is db
+PASS event.target.transaction.mode is "versionchange"
+objectStore = db.createObjectStore(info.name, info.options);
+PASS objectStore.name is info.name
+PASS objectStore.keyPath is info.options.keyPath
+PASS objectStore.indexNames.length is 0
+PASS event.target.transaction.db is db
+PASS event.target.transaction.mode is "versionchange"
+objectStore = db.createObjectStore(info.name, info.options);
+PASS objectStore.name is info.name
+PASS objectStore.keyPath is info.options.keyPath
+PASS objectStore.indexNames.length is 0
+PASS event.target.transaction.db is db
+PASS event.target.transaction.mode is "versionchange"
+objectStore = db.createObjectStore(info.name, info.options);
+PASS objectStore.name is info.name
+PASS objectStore.keyPath is info.options.keyPath
+PASS objectStore.indexNames.length is 0
+PASS event.target.transaction.db is db
+PASS event.target.transaction.mode is "versionchange"
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
diff --git a/LayoutTests/platform/wk2/storage/indexeddb/cursor-continue-dir-expected.txt b/LayoutTests/platform/wk2/storage/indexeddb/cursor-continue-dir-expected.txt
new file mode 100644 (file)
index 0000000..67c8638
--- /dev/null
@@ -0,0 +1,47 @@
+Test that continue() calls against cursors are validated by direction.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+indexedDB = self.indexedDB || self.webkitIndexedDB || self.mozIndexedDB || self.msIndexedDB || self.OIndexedDB;
+
+dbname = "cursor-continue-dir.html"
+indexedDB.deleteDatabase(dbname)
+indexedDB.open(dbname)
+store = db.createObjectStore('store')
+store.put(1,1)
+store.put(2,2)
+store.put(3,3)
+store.put(4,4)
+store.put(5,5)
+store.put(6,6)
+store.put(7,7)
+store.put(8,8)
+store.put(9,9)
+store.put(10,10)
+trans = db.transaction('store')
+store = trans.objectStore('store')
+request = store.openCursor(IDBKeyRange.bound(-Infinity, Infinity), 'next')
+cursor = request.result
+PASS cursor is non-null.
+Expect DataError if: The parameter is less than or equal to this cursor's position and this cursor's direction is "next" or "nextunique".
+PASS cursor.key is 1
+Expecting exception from cursor.continue(-1)
+PASS Exception was thrown.
+PASS code is 0
+PASS ename is 'DataError'
+Exception message: The data provided does not meet requirements.
+request = store.openCursor(IDBKeyRange.bound(-Infinity, Infinity), 'prev')
+cursor = request.result
+PASS cursor is non-null.
+Expect DataError if: The parameter is greater than or equal to this cursor's position and this cursor's direction is "prev" or "prevunique".
+PASS cursor.key is 10
+Expecting exception from cursor.continue(11)
+PASS Exception was thrown.
+PASS code is 0
+PASS ename is 'DataError'
+Exception message: The data provided does not meet requirements.
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
diff --git a/LayoutTests/platform/wk2/storage/indexeddb/cursor-continue-expected.txt b/LayoutTests/platform/wk2/storage/indexeddb/cursor-continue-expected.txt
new file mode 100644 (file)
index 0000000..5defd6b
--- /dev/null
@@ -0,0 +1,124 @@
+Test IndexedDB's IDBCursor.continue() with a key parameter.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+indexedDB = self.indexedDB || self.webkitIndexedDB || self.mozIndexedDB || self.msIndexedDB || self.OIndexedDB;
+
+dbname = "cursor-continue.html"
+indexedDB.deleteDatabase(dbname)
+indexedDB.open(dbname)
+db.createObjectStore('someObjectStore')
+objectStore.createIndex('someIndex', 'x')
+objectStore.add({'x': testData[nextToAdd]}, nextToAdd)
+objectStore.add({'x': testData[nextToAdd]}, nextToAdd)
+objectStore.add({'x': testData[nextToAdd]}, nextToAdd)
+objectStore.add({'x': testData[nextToAdd]}, nextToAdd)
+objectStore.add({'x': testData[nextToAdd]}, nextToAdd)
+objectStore.add({'x': testData[nextToAdd]}, nextToAdd)
+objectStore.add({'x': testData[nextToAdd]}, nextToAdd)
+objectStore.add({'x': testData[nextToAdd]}, nextToAdd)
+objectStore.add({'x': testData[nextToAdd]}, nextToAdd)
+objectStore.add({'x': testData[nextToAdd]}, nextToAdd)
+objectStore.add({'x': testData[nextToAdd]}, nextToAdd)
+objectStore.add({'x': testData[nextToAdd]}, nextToAdd)
+objectStore.add({'x': testData[nextToAdd]}, nextToAdd)
+objectStore.add({'x': testData[nextToAdd]}, nextToAdd)
+objectStore.add({'x': testData[nextToAdd]}, nextToAdd)
+objectStore.add({'x': testData[nextToAdd]}, nextToAdd)
+objectStore.add({'x': testData[nextToAdd]}, nextToAdd)
+objectStore.add({'x': testData[nextToAdd]}, nextToAdd)
+
+indexObject.openKeyCursor(null, 'next')
+PASS event.target.result.primaryKey is 0
+event.target.result.continue(3.14159)
+PASS event.target.result.primaryKey is 3
+event.target.result.continue()
+PASS event.target.result.primaryKey is 4
+event.target.result.continue()
+PASS event.target.result.primaryKey is 5
+event.target.result.continue(12)
+PASS event.target.result.primaryKey is 7
+event.target.result.continue(date)
+PASS event.target.result.primaryKey is 9
+event.target.result.continue()
+PASS event.target.result.primaryKey is 10
+event.target.result.continue()
+PASS event.target.result.primaryKey is 11
+event.target.result.continue('A bit1')
+PASS event.target.result.primaryKey is 14
+event.target.result.continue('A bit3')
+PASS event.target.result.primaryKey is 16
+event.target.result.continue('the BIGGEST string')
+PASS event.target.result.primaryKey is 17
+event.target.result.continue()
+PASS event.target.result is null
+
+indexObject.openKeyCursor(null, 'prev')
+PASS event.target.result.primaryKey is 17
+event.target.result.continue('A bit2')
+PASS event.target.result.primaryKey is 15
+event.target.result.continue()
+PASS event.target.result.primaryKey is 14
+event.target.result.continue(date)
+PASS event.target.result.primaryKey is 10
+event.target.result.continue()
+PASS event.target.result.primaryKey is 9
+event.target.result.continue(1)
+PASS event.target.result.primaryKey is 2
+event.target.result.continue()
+PASS event.target.result.primaryKey is 1
+event.target.result.continue()
+PASS event.target.result.primaryKey is 0
+event.target.result.continue()
+PASS event.target.result is null
+
+indexObject.openKeyCursor(null, 'next')
+PASS event.target.result.primaryKey is 0
+event.target.result.continue(3.14159)
+PASS event.target.result.primaryKey is 3
+Expecting exception from event.target.result.continue(1)
+PASS Exception was thrown.
+PASS code is 0
+PASS ename is 'DataError'
+Exception message: The data provided does not meet requirements.
+
+indexObject.openKeyCursor(null, 'next')
+PASS event.target.result.primaryKey is 0
+event.target.result.continue(3.14159)
+PASS event.target.result.primaryKey is 3
+Expecting exception from event.target.result.continue(3.14159)
+PASS Exception was thrown.
+PASS code is 0
+PASS ename is 'DataError'
+Exception message: The data provided does not meet requirements.
+
+indexObject.openKeyCursor(null, 'prev')
+PASS event.target.result.primaryKey is 17
+event.target.result.continue('A bit2')
+PASS event.target.result.primaryKey is 15
+Expecting exception from event.target.result.continue('A bit3')
+PASS Exception was thrown.
+PASS code is 0
+PASS ename is 'DataError'
+Exception message: The data provided does not meet requirements.
+
+indexObject.openKeyCursor(null, 'prev')
+PASS event.target.result.primaryKey is 17
+event.target.result.continue('A bit2')
+PASS event.target.result.primaryKey is 15
+cursor = event.target.result
+Expecting exception from event.target.result.continue('A bit2')
+PASS Exception was thrown.
+PASS code is 0
+PASS ename is 'DataError'
+Exception message: The data provided does not meet requirements.
+Expecting exception from cursor.continue()
+PASS Exception was thrown.
+PASS code is 0
+PASS ename is 'TransactionInactiveError'
+Exception message: A request was placed against a transaction which is either currently not active, or which is finished.
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
diff --git a/LayoutTests/platform/wk2/storage/indexeddb/cursor-finished-expected.txt b/LayoutTests/platform/wk2/storage/indexeddb/cursor-finished-expected.txt
new file mode 100644 (file)
index 0000000..dc15954
--- /dev/null
@@ -0,0 +1,77 @@
+Ensure cursor calls behave as expected after cursor has run to the end.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+indexedDB = self.indexedDB || self.webkitIndexedDB || self.mozIndexedDB || self.msIndexedDB || self.OIndexedDB;
+
+dbname = "cursor-finished.html"
+
+prepareDatabase():
+indexedDB.deleteDatabase(dbname)
+
+onDeleteSuccess():
+indexedDB.open(dbname, 1)
+
+onUpgradeNeeded():
+db = event.target.result
+store = db.createObjectStore('store')
+store.put(1, 1)
+store.put(2, 2)
+
+onOpenSuccess():
+db = event.target.result
+transaction = db.transaction('store', 'readwrite')
+store = transaction.objectStore('store')
+count = 0
+cursorRequest = store.openCursor()
+
+onCursorSuccess():
+cursor = event.target.result
+PASS cursor is non-null.
+count++
+savedCursor = cursor
+cursor.continue()
+
+onCursorSuccess():
+cursor = event.target.result
+PASS cursor is non-null.
+count++
+savedCursor = cursor
+cursor.continue()
+
+onCursorSuccess():
+cursor = event.target.result
+PASS cursor is null
+PASS savedCursor is non-null.
+
+Expecting exception from savedCursor.update('value')
+PASS Exception was thrown.
+PASS code is DOMException.INVALID_STATE_ERR
+PASS ename is 'InvalidStateError'
+Exception message: An operation was called on an object on which it is not allowed or at a time when it is not allowed.
+Expecting exception from savedCursor.advance(1)
+PASS Exception was thrown.
+PASS code is DOMException.INVALID_STATE_ERR
+PASS ename is 'InvalidStateError'
+Exception message: An operation was called on an object on which it is not allowed or at a time when it is not allowed.
+Expecting exception from savedCursor.continue()
+PASS Exception was thrown.
+PASS code is DOMException.INVALID_STATE_ERR
+PASS ename is 'InvalidStateError'
+Exception message: An operation was called on an object on which it is not allowed or at a time when it is not allowed.
+Expecting exception from savedCursor.continue('key')
+PASS Exception was thrown.
+PASS code is DOMException.INVALID_STATE_ERR
+PASS ename is 'InvalidStateError'
+Exception message: An operation was called on an object on which it is not allowed or at a time when it is not allowed.
+Expecting exception from savedCursor.delete()
+PASS Exception was thrown.
+PASS code is DOMException.INVALID_STATE_ERR
+PASS ename is 'InvalidStateError'
+Exception message: An operation was called on an object on which it is not allowed or at a time when it is not allowed.
+
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
diff --git a/LayoutTests/platform/wk2/storage/indexeddb/cursors-expected.txt b/LayoutTests/platform/wk2/storage/indexeddb/cursors-expected.txt
new file mode 100644 (file)
index 0000000..5380b09
--- /dev/null
@@ -0,0 +1,609 @@
+Test IndexedDB cursor behavior
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+indexedDB = self.indexedDB || self.webkitIndexedDB || self.mozIndexedDB || self.msIndexedDB || self.OIndexedDB;
+
+dbname = "cursors.html"
+indexedDB.deleteDatabase(dbname)
+indexedDB.open(dbname)
+db.createObjectStore('autoIncrement', { autoIncrement: true });
+request = objectStore.openCursor();
+PASS event.target.result is null
+db.createObjectStore('autoIncrementKeyPath', { keyPath: 'foo', autoIncrement: true });
+request = objectStore.openCursor();
+PASS event.target.result is null
+db.createObjectStore('keyPath', { keyPath: 'foo' });
+request = objectStore.openCursor();
+PASS event.target.result is null
+db.createObjectStore('foo');
+request = objectStore.openCursor();
+PASS event.target.result is null
+keys = [1, -1, 0, 10, 2000, 'q', 'z', 'two', 'b', 'a'];
+sortedKeys = [-1, 0, 1, 10, 2000, 'a', 'b', 'q', 'two', 'z'];
+keyIndex = 0;
+request = objectStore.add('foo', keys[i]);
+request = objectStore.add('foo', keys[i]);
+request = objectStore.add('foo', keys[i]);
+request = objectStore.add('foo', keys[i]);
+request = objectStore.add('foo', keys[i]);
+request = objectStore.add('foo', keys[i]);
+request = objectStore.add('foo', keys[i]);
+request = objectStore.add('foo', keys[i]);
+request = objectStore.add('foo', keys[i]);
+request = objectStore.add('foo', keys[i]);
+request = objectStore.openCursor();
+cursor = event.target.result;
+PASS cursor.key is sortedKeys[keyIndex]
+PASS cursor.primaryKey is sortedKeys[keyIndex]
+PASS cursor.value is 'foo'
+cursor.continue();
+Expecting exception from cursor.continue();
+PASS Exception was thrown.
+PASS code is DOMException.INVALID_STATE_ERR
+Exception message: An operation was called on an object on which it is not allowed or at a time when it is not allowed.
+PASS cursor.key is sortedKeys[keyIndex]
+PASS cursor.primaryKey is sortedKeys[keyIndex]
+PASS cursor.value is 'foo'
+keyIndex++;
+cursor = event.target.result;
+PASS cursor.key is sortedKeys[keyIndex]
+PASS cursor.primaryKey is sortedKeys[keyIndex]
+PASS cursor.value is 'foo'
+cursor.continue();
+Expecting exception from cursor.continue();
+PASS Exception was thrown.
+PASS code is DOMException.INVALID_STATE_ERR
+Exception message: An operation was called on an object on which it is not allowed or at a time when it is not allowed.
+PASS cursor.key is sortedKeys[keyIndex]
+PASS cursor.primaryKey is sortedKeys[keyIndex]
+PASS cursor.value is 'foo'
+keyIndex++;
+cursor = event.target.result;
+PASS cursor.key is sortedKeys[keyIndex]
+PASS cursor.primaryKey is sortedKeys[keyIndex]
+PASS cursor.value is 'foo'
+cursor.continue();
+Expecting exception from cursor.continue();
+PASS Exception was thrown.
+PASS code is DOMException.INVALID_STATE_ERR
+Exception message: An operation was called on an object on which it is not allowed or at a time when it is not allowed.
+PASS cursor.key is sortedKeys[keyIndex]
+PASS cursor.primaryKey is sortedKeys[keyIndex]
+PASS cursor.value is 'foo'
+keyIndex++;
+cursor = event.target.result;
+PASS cursor.key is sortedKeys[keyIndex]
+PASS cursor.primaryKey is sortedKeys[keyIndex]
+PASS cursor.value is 'foo'
+cursor.continue();
+Expecting exception from cursor.continue();
+PASS Exception was thrown.
+PASS code is DOMException.INVALID_STATE_ERR
+Exception message: An operation was called on an object on which it is not allowed or at a time when it is not allowed.
+PASS cursor.key is sortedKeys[keyIndex]
+PASS cursor.primaryKey is sortedKeys[keyIndex]
+PASS cursor.value is 'foo'
+keyIndex++;
+cursor = event.target.result;
+PASS cursor.key is sortedKeys[keyIndex]
+PASS cursor.primaryKey is sortedKeys[keyIndex]
+PASS cursor.value is 'foo'
+cursor.continue();
+Expecting exception from cursor.continue();
+PASS Exception was thrown.
+PASS code is DOMException.INVALID_STATE_ERR
+Exception message: An operation was called on an object on which it is not allowed or at a time when it is not allowed.
+PASS cursor.key is sortedKeys[keyIndex]
+PASS cursor.primaryKey is sortedKeys[keyIndex]
+PASS cursor.value is 'foo'
+keyIndex++;
+cursor = event.target.result;
+PASS cursor.key is sortedKeys[keyIndex]
+PASS cursor.primaryKey is sortedKeys[keyIndex]
+PASS cursor.value is 'foo'
+cursor.continue();
+Expecting exception from cursor.continue();
+PASS Exception was thrown.
+PASS code is DOMException.INVALID_STATE_ERR
+Exception message: An operation was called on an object on which it is not allowed or at a time when it is not allowed.
+PASS cursor.key is sortedKeys[keyIndex]
+PASS cursor.primaryKey is sortedKeys[keyIndex]
+PASS cursor.value is 'foo'
+keyIndex++;
+cursor = event.target.result;
+PASS cursor.key is sortedKeys[keyIndex]
+PASS cursor.primaryKey is sortedKeys[keyIndex]
+PASS cursor.value is 'foo'
+cursor.continue();
+Expecting exception from cursor.continue();
+PASS Exception was thrown.
+PASS code is DOMException.INVALID_STATE_ERR
+Exception message: An operation was called on an object on which it is not allowed or at a time when it is not allowed.
+PASS cursor.key is sortedKeys[keyIndex]
+PASS cursor.primaryKey is sortedKeys[keyIndex]
+PASS cursor.value is 'foo'
+keyIndex++;
+cursor = event.target.result;
+PASS cursor.key is sortedKeys[keyIndex]
+PASS cursor.primaryKey is sortedKeys[keyIndex]
+PASS cursor.value is 'foo'
+cursor.continue();
+Expecting exception from cursor.continue();
+PASS Exception was thrown.
+PASS code is DOMException.INVALID_STATE_ERR
+Exception message: An operation was called on an object on which it is not allowed or at a time when it is not allowed.
+PASS cursor.key is sortedKeys[keyIndex]
+PASS cursor.primaryKey is sortedKeys[keyIndex]
+PASS cursor.value is 'foo'
+keyIndex++;
+cursor = event.target.result;
+PASS cursor.key is sortedKeys[keyIndex]
+PASS cursor.primaryKey is sortedKeys[keyIndex]
+PASS cursor.value is 'foo'
+cursor.continue();
+Expecting exception from cursor.continue();
+PASS Exception was thrown.
+PASS code is DOMException.INVALID_STATE_ERR
+Exception message: An operation was called on an object on which it is not allowed or at a time when it is not allowed.
+PASS cursor.key is sortedKeys[keyIndex]
+PASS cursor.primaryKey is sortedKeys[keyIndex]
+PASS cursor.value is 'foo'
+keyIndex++;
+cursor = event.target.result;
+PASS cursor.key is sortedKeys[keyIndex]
+PASS cursor.primaryKey is sortedKeys[keyIndex]
+PASS cursor.value is 'foo'
+cursor.continue();
+Expecting exception from cursor.continue();
+PASS Exception was thrown.
+PASS code is DOMException.INVALID_STATE_ERR
+Exception message: An operation was called on an object on which it is not allowed or at a time when it is not allowed.
+PASS cursor.key is sortedKeys[keyIndex]
+PASS cursor.primaryKey is sortedKeys[keyIndex]
+PASS cursor.value is 'foo'
+keyIndex++;
+cursor = event.target.result;
+PASS keyIndex is keys.length
+keyIndex = 4;
+range = IDBKeyRange.bound(2000, 'q');
+request = objectStore.openCursor(range);
+cursor = event.target.result;
+PASS cursor.key is sortedKeys[keyIndex]
+PASS cursor.primaryKey is sortedKeys[keyIndex]
+PASS cursor.value is 'foo'
+cursor.continue();
+PASS cursor.key is sortedKeys[keyIndex]
+PASS cursor.primaryKey is sortedKeys[keyIndex]
+PASS cursor.value is 'foo'
+keyIndex++;
+cursor = event.target.result;
+PASS cursor.key is sortedKeys[keyIndex]
+PASS cursor.primaryKey is sortedKeys[keyIndex]
+PASS cursor.value is 'foo'
+cursor.continue();
+PASS cursor.key is sortedKeys[keyIndex]
+PASS cursor.primaryKey is sortedKeys[keyIndex]
+PASS cursor.value is 'foo'
+keyIndex++;
+cursor = event.target.result;
+PASS cursor.key is sortedKeys[keyIndex]
+PASS cursor.primaryKey is sortedKeys[keyIndex]
+PASS cursor.value is 'foo'
+cursor.continue();
+PASS cursor.key is sortedKeys[keyIndex]
+PASS cursor.primaryKey is sortedKeys[keyIndex]
+PASS cursor.value is 'foo'
+keyIndex++;
+cursor = event.target.result;
+PASS cursor.key is sortedKeys[keyIndex]
+PASS cursor.primaryKey is sortedKeys[keyIndex]
+PASS cursor.value is 'foo'
+cursor.continue();
+PASS cursor.key is sortedKeys[keyIndex]
+PASS cursor.primaryKey is sortedKeys[keyIndex]
+PASS cursor.value is 'foo'
+keyIndex++;
+cursor = event.target.result;
+PASS keyIndex is 8
+request = objectStore.openCursor();
+cursor = event.target.result;
+PASS cursor.key is sortedKeys[keyIndex]
+PASS cursor.primaryKey is sortedKeys[keyIndex]
+PASS cursor.value is 'foo'
+cursor.continue('b');
+PASS cursor.key is sortedKeys[keyIndex]
+PASS cursor.primaryKey is sortedKeys[keyIndex]
+PASS cursor.value is 'foo'
+keyIndex += keyIndex ? 1: 6;
+cursor = event.target.result;
+PASS cursor.key is sortedKeys[keyIndex]
+PASS cursor.primaryKey is sortedKeys[keyIndex]
+PASS cursor.value is 'foo'
+cursor.continue();
+PASS cursor.key is sortedKeys[keyIndex]
+PASS cursor.primaryKey is sortedKeys[keyIndex]
+PASS cursor.value is 'foo'
+keyIndex += keyIndex ? 1: 6;
+cursor = event.target.result;
+PASS cursor.key is sortedKeys[keyIndex]
+PASS cursor.primaryKey is sortedKeys[keyIndex]
+PASS cursor.value is 'foo'
+cursor.continue();
+PASS cursor.key is sortedKeys[keyIndex]
+PASS cursor.primaryKey is sortedKeys[keyIndex]
+PASS cursor.value is 'foo'
+keyIndex += keyIndex ? 1: 6;
+cursor = event.target.result;
+PASS cursor.key is sortedKeys[keyIndex]
+PASS cursor.primaryKey is sortedKeys[keyIndex]
+PASS cursor.value is 'foo'
+cursor.continue();
+PASS cursor.key is sortedKeys[keyIndex]
+PASS cursor.primaryKey is sortedKeys[keyIndex]
+PASS cursor.value is 'foo'
+keyIndex += keyIndex ? 1: 6;
+cursor = event.target.result;
+PASS cursor.key is sortedKeys[keyIndex]
+PASS cursor.primaryKey is sortedKeys[keyIndex]
+PASS cursor.value is 'foo'
+cursor.continue();
+PASS cursor.key is sortedKeys[keyIndex]
+PASS cursor.primaryKey is sortedKeys[keyIndex]
+PASS cursor.value is 'foo'
+keyIndex += keyIndex ? 1: 6;
+cursor = event.target.result;
+PASS keyIndex is keys.length
+keyIndex = 0;
+request = objectStore.openCursor();
+cursor = event.target.result;
+PASS cursor.key is sortedKeys[keyIndex]
+PASS cursor.primaryKey is sortedKeys[keyIndex]
+PASS cursor.value is 'foo'
+cursor.continue(10);
+PASS cursor.key is sortedKeys[keyIndex]
+PASS cursor.primaryKey is sortedKeys[keyIndex]
+PASS cursor.value is 'foo'
+keyIndex += keyIndex ? 1: 3;
+cursor = event.target.result;
+PASS cursor.key is sortedKeys[keyIndex]
+PASS cursor.primaryKey is sortedKeys[keyIndex]
+PASS cursor.value is 'foo'
+cursor.continue();
+PASS cursor.key is sortedKeys[keyIndex]
+PASS cursor.primaryKey is sortedKeys[keyIndex]
+PASS cursor.value is 'foo'
+keyIndex += keyIndex ? 1: 3;
+cursor = event.target.result;
+PASS cursor.key is sortedKeys[keyIndex]
+PASS cursor.primaryKey is sortedKeys[keyIndex]
+PASS cursor.value is 'foo'
+cursor.continue();
+PASS cursor.key is sortedKeys[keyIndex]
+PASS cursor.primaryKey is sortedKeys[keyIndex]
+PASS cursor.value is 'foo'
+keyIndex += keyIndex ? 1: 3;
+cursor = event.target.result;
+PASS cursor.key is sortedKeys[keyIndex]
+PASS cursor.primaryKey is sortedKeys[keyIndex]
+PASS cursor.value is 'foo'
+cursor.continue();
+PASS cursor.key is sortedKeys[keyIndex]
+PASS cursor.primaryKey is sortedKeys[keyIndex]
+PASS cursor.value is 'foo'
+keyIndex += keyIndex ? 1: 3;
+cursor = event.target.result;
+PASS cursor.key is sortedKeys[keyIndex]
+PASS cursor.primaryKey is sortedKeys[keyIndex]
+PASS cursor.value is 'foo'
+cursor.continue();
+PASS cursor.key is sortedKeys[keyIndex]
+PASS cursor.primaryKey is sortedKeys[keyIndex]
+PASS cursor.value is 'foo'
+keyIndex += keyIndex ? 1: 3;
+cursor = event.target.result;
+PASS cursor.key is sortedKeys[keyIndex]
+PASS cursor.primaryKey is sortedKeys[keyIndex]
+PASS cursor.value is 'foo'
+cursor.continue();
+PASS cursor.key is sortedKeys[keyIndex]
+PASS cursor.primaryKey is sortedKeys[keyIndex]
+PASS cursor.value is 'foo'
+keyIndex += keyIndex ? 1: 3;
+cursor = event.target.result;
+PASS cursor.key is sortedKeys[keyIndex]
+PASS cursor.primaryKey is sortedKeys[keyIndex]
+PASS cursor.value is 'foo'
+cursor.continue();
+PASS cursor.key is sortedKeys[keyIndex]
+PASS cursor.primaryKey is sortedKeys[keyIndex]
+PASS cursor.value is 'foo'
+keyIndex += keyIndex ? 1: 3;
+cursor = event.target.result;
+PASS cursor.key is sortedKeys[keyIndex]
+PASS cursor.primaryKey is sortedKeys[keyIndex]
+PASS cursor.value is 'foo'
+cursor.continue();
+PASS cursor.key is sortedKeys[keyIndex]
+PASS cursor.primaryKey is sortedKeys[keyIndex]
+PASS cursor.value is 'foo'
+keyIndex += keyIndex ? 1: 3;
+cursor = event.target.result;
+PASS keyIndex is keys.length
+keyIndex = 0;
+request = objectStore.openCursor();
+cursor = event.target.result;
+PASS cursor.key is sortedKeys[keyIndex]
+PASS cursor.primaryKey is sortedKeys[keyIndex]
+PASS cursor.value is 'foo'
+cursor.continue('c');
+PASS cursor.key is sortedKeys[keyIndex]
+PASS cursor.primaryKey is sortedKeys[keyIndex]
+PASS cursor.value is 'foo'
+keyIndex += keyIndex ? 1 : 7;
+cursor = event.target.result;
+PASS cursor.key is sortedKeys[keyIndex]
+PASS cursor.primaryKey is sortedKeys[keyIndex]
+PASS cursor.value is 'foo'
+cursor.continue();
+PASS cursor.key is sortedKeys[keyIndex]
+PASS cursor.primaryKey is sortedKeys[keyIndex]
+PASS cursor.value is 'foo'
+keyIndex += keyIndex ? 1 : 7;
+cursor = event.target.result;
+PASS cursor.key is sortedKeys[keyIndex]
+PASS cursor.primaryKey is sortedKeys[keyIndex]
+PASS cursor.value is 'foo'
+cursor.continue();
+PASS cursor.key is sortedKeys[keyIndex]
+PASS cursor.primaryKey is sortedKeys[keyIndex]
+PASS cursor.value is 'foo'
+keyIndex += keyIndex ? 1 : 7;
+cursor = event.target.result;
+PASS cursor.key is sortedKeys[keyIndex]
+PASS cursor.primaryKey is sortedKeys[keyIndex]
+PASS cursor.value is 'foo'
+cursor.continue();
+PASS cursor.key is sortedKeys[keyIndex]
+PASS cursor.primaryKey is sortedKeys[keyIndex]
+PASS cursor.value is 'foo'
+keyIndex += keyIndex ? 1 : 7;
+cursor = event.target.result;
+PASS keyIndex is keys.length
+keyIndex = 0;
+request = objectStore.openCursor();
+cursor = event.target.result;
+PASS cursor.key is sortedKeys[keyIndex]
+PASS cursor.primaryKey is sortedKeys[keyIndex]
+PASS cursor.value is 'foo'
+keyIndex++;
+cursor.continue();
+cursor = event.target.result;
+PASS cursor.key is sortedKeys[keyIndex]
+PASS cursor.primaryKey is sortedKeys[keyIndex]
+PASS cursor.value is 'foo'
+keyIndex++;
+cursor.continue();
+cursor = event.target.result;
+PASS cursor.key is sortedKeys[keyIndex]
+PASS cursor.primaryKey is sortedKeys[keyIndex]
+PASS cursor.value is 'foo'
+keyIndex++;
+cursor.continue();
+cursor = event.target.result;
+PASS cursor.key is sortedKeys[keyIndex]
+PASS cursor.primaryKey is sortedKeys[keyIndex]
+PASS cursor.value is 'foo'
+keyIndex++;
+cursor.continue();
+cursor = event.target.result;
+PASS cursor.key is sortedKeys[keyIndex]
+PASS cursor.primaryKey is sortedKeys[keyIndex]
+PASS cursor.value is 'foo'
+request = cursor.update('bar');
+keyIndex++;
+cursor.continue();
+cursor = event.target.result;
+PASS cursor.key is sortedKeys[keyIndex]
+PASS cursor.primaryKey is sortedKeys[keyIndex]
+PASS cursor.value is 'foo'
+keyIndex++;
+cursor.continue();
+cursor = event.target.result;
+PASS cursor.key is sortedKeys[keyIndex]
+PASS cursor.primaryKey is sortedKeys[keyIndex]
+PASS cursor.value is 'foo'
+keyIndex++;
+cursor.continue();
+cursor = event.target.result;
+PASS cursor.key is sortedKeys[keyIndex]
+PASS cursor.primaryKey is sortedKeys[keyIndex]
+PASS cursor.value is 'foo'
+keyIndex++;
+cursor.continue();
+cursor = event.target.result;
+PASS cursor.key is sortedKeys[keyIndex]
+PASS cursor.primaryKey is sortedKeys[keyIndex]
+PASS cursor.value is 'foo'
+keyIndex++;
+cursor.continue();
+cursor = event.target.result;
+PASS cursor.key is sortedKeys[keyIndex]
+PASS cursor.primaryKey is sortedKeys[keyIndex]
+PASS cursor.value is 'foo'
+keyIndex++;
+cursor.continue();
+cursor = event.target.result;
+PASS keyIndex is keys.length
+request = objectStore.get(sortedKeys[4]);
+PASS event.target.result is 'bar'
+request = objectStore.put('foo', sortedKeys[4]);
+keyIndex = 0;
+request = objectStore.openCursor(null, 'next');
+cursor = event.target.result;
+PASS cursor.key is sortedKeys[keyIndex]
+PASS cursor.primaryKey is sortedKeys[keyIndex]
+PASS cursor.value is 'foo'
+keyIndex++;
+cursor.continue();
+cursor = event.target.result;
+PASS cursor.key is sortedKeys[keyIndex]
+PASS cursor.primaryKey is sortedKeys[keyIndex]
+PASS cursor.value is 'foo'
+keyIndex++;
+cursor.continue();
+cursor = event.target.result;
+PASS cursor.key is sortedKeys[keyIndex]
+PASS cursor.primaryKey is sortedKeys[keyIndex]
+PASS cursor.value is 'foo'
+keyIndex++;
+cursor.continue();
+cursor = event.target.result;
+PASS cursor.key is sortedKeys[keyIndex]
+PASS cursor.primaryKey is sortedKeys[keyIndex]
+PASS cursor.value is 'foo'
+keyIndex++;
+cursor.continue();
+cursor = event.target.result;
+PASS cursor.key is sortedKeys[keyIndex]
+PASS cursor.primaryKey is sortedKeys[keyIndex]
+PASS cursor.value is 'foo'
+request = cursor.delete();
+keyIndex++;
+cursor.continue();
+PASS keyIndex is 5
+gotRemoveEvent = true;
+cursor = event.target.result;
+PASS cursor.key is sortedKeys[keyIndex]
+PASS cursor.primaryKey is sortedKeys[keyIndex]
+PASS cursor.value is 'foo'
+keyIndex++;
+cursor.continue();
+cursor = event.target.result;
+PASS cursor.key is sortedKeys[keyIndex]
+PASS cursor.primaryKey is sortedKeys[keyIndex]
+PASS cursor.value is 'foo'
+keyIndex++;
+cursor.continue();
+cursor = event.target.result;
+PASS cursor.key is sortedKeys[keyIndex]
+PASS cursor.primaryKey is sortedKeys[keyIndex]
+PASS cursor.value is 'foo'
+keyIndex++;
+cursor.continue();
+cursor = event.target.result;
+PASS cursor.key is sortedKeys[keyIndex]
+PASS cursor.primaryKey is sortedKeys[keyIndex]
+PASS cursor.value is 'foo'
+keyIndex++;
+cursor.continue();
+cursor = event.target.result;
+PASS cursor.key is sortedKeys[keyIndex]
+PASS cursor.primaryKey is sortedKeys[keyIndex]
+PASS cursor.value is 'foo'
+keyIndex++;
+cursor.continue();
+cursor = event.target.result;
+PASS keyIndex is keys.length
+PASS gotRemoveEvent is true
+request = objectStore.get(sortedKeys[4]);
+PASS event.target.result is undefined
+request = objectStore.add('foo', sortedKeys[4]);
+request = objectStore.openCursor(null, 'prev');
+cursor = event.target.result;
+PASS cursor.key is sortedKeys[keyIndex]
+PASS cursor.primaryKey is sortedKeys[keyIndex]
+PASS cursor.value is 'foo'
+cursor.continue();
+PASS cursor.key is sortedKeys[keyIndex]
+PASS cursor.primaryKey is sortedKeys[keyIndex]
+PASS cursor.value is 'foo'
+keyIndex--;
+cursor = event.target.result;
+PASS cursor.key is sortedKeys[keyIndex]
+PASS cursor.primaryKey is sortedKeys[keyIndex]
+PASS cursor.value is 'foo'
+cursor.continue();
+PASS cursor.key is sortedKeys[keyIndex]
+PASS cursor.primaryKey is sortedKeys[keyIndex]
+PASS cursor.value is 'foo'
+keyIndex--;
+cursor = event.target.result;
+PASS cursor.key is sortedKeys[keyIndex]
+PASS cursor.primaryKey is sortedKeys[keyIndex]
+PASS cursor.value is 'foo'
+cursor.continue();
+PASS cursor.key is sortedKeys[keyIndex]
+PASS cursor.primaryKey is sortedKeys[keyIndex]
+PASS cursor.value is 'foo'
+keyIndex--;
+cursor = event.target.result;
+PASS cursor.key is sortedKeys[keyIndex]
+PASS cursor.primaryKey is sortedKeys[keyIndex]
+PASS cursor.value is 'foo'
+cursor.continue();
+PASS cursor.key is sortedKeys[keyIndex]
+PASS cursor.primaryKey is sortedKeys[keyIndex]
+PASS cursor.value is 'foo'
+keyIndex--;
+cursor = event.target.result;
+PASS cursor.key is sortedKeys[keyIndex]
+PASS cursor.primaryKey is sortedKeys[keyIndex]
+PASS cursor.value is 'foo'
+cursor.continue();
+PASS cursor.key is sortedKeys[keyIndex]
+PASS cursor.primaryKey is sortedKeys[keyIndex]
+PASS cursor.value is 'foo'
+keyIndex--;
+cursor = event.target.result;
+PASS cursor.key is sortedKeys[keyIndex]
+PASS cursor.primaryKey is sortedKeys[keyIndex]
+PASS cursor.value is 'foo'
+cursor.continue();
+PASS cursor.key is sortedKeys[keyIndex]
+PASS cursor.primaryKey is sortedKeys[keyIndex]
+PASS cursor.value is 'foo'
+keyIndex--;
+cursor = event.target.result;
+PASS cursor.key is sortedKeys[keyIndex]
+PASS cursor.primaryKey is sortedKeys[keyIndex]
+PASS cursor.value is 'foo'
+cursor.continue();
+PASS cursor.key is sortedKeys[keyIndex]
+PASS cursor.primaryKey is sortedKeys[keyIndex]
+PASS cursor.value is 'foo'
+keyIndex--;
+cursor = event.target.result;
+PASS cursor.key is sortedKeys[keyIndex]
+PASS cursor.primaryKey is sortedKeys[keyIndex]
+PASS cursor.value is 'foo'
+cursor.continue();
+PASS cursor.key is sortedKeys[keyIndex]
+PASS cursor.primaryKey is sortedKeys[keyIndex]
+PASS cursor.value is 'foo'
+keyIndex--;
+cursor = event.target.result;
+PASS cursor.key is sortedKeys[keyIndex]
+PASS cursor.primaryKey is sortedKeys[keyIndex]
+PASS cursor.value is 'foo'
+cursor.continue();
+PASS cursor.key is sortedKeys[keyIndex]
+PASS cursor.primaryKey is sortedKeys[keyIndex]
+PASS cursor.value is 'foo'
+keyIndex--;
+cursor = event.target.result;
+PASS cursor.key is sortedKeys[keyIndex]
+PASS cursor.primaryKey is sortedKeys[keyIndex]
+PASS cursor.value is 'foo'
+cursor.continue();
+PASS cursor.key is sortedKeys[keyIndex]
+PASS cursor.primaryKey is sortedKeys[keyIndex]
+PASS cursor.value is 'foo'
+keyIndex--;
+cursor = event.target.result;
+PASS keyIndex is -1
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
diff --git a/LayoutTests/platform/wk2/storage/indexeddb/database-basics-expected.txt b/LayoutTests/platform/wk2/storage/indexeddb/database-basics-expected.txt
new file mode 100644 (file)
index 0000000..fdc55e0
--- /dev/null
@@ -0,0 +1,62 @@
+Test the basics of IndexedDB's IDBDatabase.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+indexedDB = self.indexedDB || self.webkitIndexedDB || self.mozIndexedDB || self.msIndexedDB || self.OIndexedDB;
+
+dbname = "database-basics.html"
+indexedDB.deleteDatabase(dbname)
+indexedDB.open(dbname)
+Test that you can't open a transaction while in a versionchange transaction
+Expecting exception from db.transaction("doesntExist")
+PASS Exception was thrown.
+PASS code is DOMException.INVALID_STATE_ERR
+PASS ename is 'InvalidStateError'
+Exception message: An operation was called on an object on which it is not allowed or at a time when it is not allowed.
+PASS db.version is 1
+PASS db.name is "database-basics.html"
+PASS db.objectStoreNames is []
+PASS db.objectStoreNames.length is 0
+PASS db.objectStoreNames.contains('') is false
+PASS db.objectStoreNames[0] is undefined.
+PASS db.objectStoreNames.item(0) is null
+db.createObjectStore("test123")
+PASS db.objectStoreNames is ['test123']
+PASS db.objectStoreNames.length is 1
+PASS db.objectStoreNames.contains('') is false
+PASS db.objectStoreNames.contains('test456') is false
+PASS db.objectStoreNames.contains('test123') is true
+db.close()
+request = indexedDB.open(dbname, 2)
+db = event.target.result
+PASS db.version is 2
+PASS db.name is "database-basics.html"
+PASS db.objectStoreNames is ['test123']
+PASS db.objectStoreNames.length is 1
+PASS db.objectStoreNames.contains('') is false
+PASS db.objectStoreNames.contains('test456') is false
+PASS db.objectStoreNames.contains('test123') is true
+db.createObjectStore("test456")
+setVersionTrans = event.target.transaction
+PASS setVersionTrans is non-null.
+setVersionTrans.abort()
+PASS db.version is 1
+PASS db.objectStoreNames is ['test123']
+PASS db.objectStoreNames.length is 1
+PASS db.objectStoreNames.contains('') is false
+PASS db.objectStoreNames.contains('test456') is false
+PASS db.objectStoreNames.contains('test123') is true
+db.close()
+Now that the connection is closed, transaction creation should fail
+Expecting exception from db.transaction('test123')
+PASS Exception was thrown.
+PASS code is DOMException.INVALID_STATE_ERR
+PASS ename is 'InvalidStateError'
+Exception message: An operation was called on an object on which it is not allowed or at a time when it is not allowed.
+Call twice, make sure it's harmless
+db.close()
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
diff --git a/LayoutTests/platform/wk2/storage/indexeddb/deleteIndex-bug110792-expected.txt b/LayoutTests/platform/wk2/storage/indexeddb/deleteIndex-bug110792-expected.txt
new file mode 100644 (file)
index 0000000..86717ed
--- /dev/null
@@ -0,0 +1,34 @@
+Ensure IndexedDB's IDBObjectStore.deleteIndex() works if IDBIndex object has not been fetched - regression test for bug 110792.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+indexedDB = self.indexedDB || self.webkitIndexedDB || self.mozIndexedDB || self.msIndexedDB || self.OIndexedDB;
+
+dbname = "deleteIndex-bug110792.html"
+indexedDB.deleteDatabase(dbname)
+indexedDB.open(dbname, 1)
+
+onFirstUpgradeNeeded():
+db = event.target.result
+store = db.createObjectStore('store')
+store.createIndex('index', 'keyPath')
+
+closeAndReOpen():
+db.close()
+
+indexedDB.open(dbname, 2)
+
+onSecondUpgradeNeeded():
+db = event.target.result
+store = event.target.transaction.objectStore('store')
+store.deleteIndex('index')
+Expecting exception from store.index('index')
+PASS Exception was thrown.
+PASS code is DOMException.NOT_FOUND_ERR
+PASS ename is 'NotFoundError'
+Exception message: An operation failed because the requested database object could not be found.
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
diff --git a/LayoutTests/platform/wk2/storage/indexeddb/index-count-expected.txt b/LayoutTests/platform/wk2/storage/indexeddb/index-count-expected.txt
new file mode 100644 (file)
index 0000000..712951e
--- /dev/null
@@ -0,0 +1,120 @@
+Test IndexedDB's IDBIndex.count().
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+indexedDB = self.indexedDB || self.webkitIndexedDB || self.mozIndexedDB || self.msIndexedDB || self.OIndexedDB;
+
+dbname = "index-count.html"
+indexedDB.deleteDatabase(dbname)
+indexedDB.open(dbname)
+store = db.createObjectStore('storeName', null)
+store.createIndex('indexName', '')
+PASS store.indexNames.contains('indexName') is true
+adding 0 ... 99
+
+verifying count without range
+trans = db.transaction('storeName', 'readonly')
+PASS trans is non-null.
+store = trans.objectStore('storeName')
+PASS store is non-null.
+index = store.index('indexName')
+PASS index is non-null.
+request = index.count()
+PASS typeof request.result is "number"
+PASS request.result is 100
+
+verifying count with range
+trans = db.transaction('storeName', 'readonly')
+PASS trans is non-null.
+store = trans.objectStore('storeName')
+PASS store is non-null.
+index = trans.objectStore('storeName').index('indexName')
+PASS index is non-null.
+
+test = {"lower":0,"lowerOpen":false,"upper":99,"upperOpen":false,"expected":100}
+request = index.count(IDBKeyRange.bound(test.lower, test.upper, test.lowerOpen, test.upperOpen))
+PASS typeof request.result is "number"
+PASS request.result is 100
+
+test = {"lower":0,"lowerOpen":true,"upper":99,"upperOpen":false,"expected":99}
+request = index.count(IDBKeyRange.bound(test.lower, test.upper, test.lowerOpen, test.upperOpen))
+PASS typeof request.result is "number"
+PASS request.result is 99
+
+test = {"lower":0,"lowerOpen":false,"upper":99,"upperOpen":true,"expected":99}
+request = index.count(IDBKeyRange.bound(test.lower, test.upper, test.lowerOpen, test.upperOpen))
+PASS typeof request.result is "number"
+PASS request.result is 99
+
+test = {"lower":0,"lowerOpen":true,"upper":99,"upperOpen":true,"expected":98}
+request = index.count(IDBKeyRange.bound(test.lower, test.upper, test.lowerOpen, test.upperOpen))
+PASS typeof request.result is "number"
+PASS request.result is 98
+
+test = {"lower":0,"lowerOpen":false,"upper":100,"upperOpen":false,"expected":100}
+request = index.count(IDBKeyRange.bound(test.lower, test.upper, test.lowerOpen, test.upperOpen))
+PASS typeof request.result is "number"
+PASS request.result is 100
+
+test = {"lower":0,"lowerOpen":false,"upper":100,"upperOpen":false,"expected":100}
+request = index.count(IDBKeyRange.bound(test.lower, test.upper, test.lowerOpen, test.upperOpen))
+PASS typeof request.result is "number"
+PASS request.result is 100
+
+test = {"lower":10,"lowerOpen":false,"upper":100,"upperOpen":false,"expected":90}
+request = index.count(IDBKeyRange.bound(test.lower, test.upper, test.lowerOpen, test.upperOpen))
+PASS typeof request.result is "number"
+PASS request.result is 90
+
+test = {"lower":0,"lowerOpen":false,"upper":0,"upperOpen":false,"expected":1}
+request = index.count(IDBKeyRange.bound(test.lower, test.upper, test.lowerOpen, test.upperOpen))
+PASS typeof request.result is "number"
+PASS request.result is 1
+
+test = {"lower":500,"lowerOpen":false,"upper":500,"upperOpen":false,"expected":0}
+request = index.count(IDBKeyRange.bound(test.lower, test.upper, test.lowerOpen, test.upperOpen))
+PASS typeof request.result is "number"
+PASS request.result is 0
+
+verifying count with key
+trans = db.transaction('storeName', 'readonly')
+PASS trans is non-null.
+store = trans.objectStore('storeName')
+PASS store is non-null.
+index = trans.objectStore('storeName').index('indexName')
+PASS index is non-null.
+Expecting exception from index.count(NaN)
+PASS Exception was thrown.
+PASS code is 0
+PASS ename is 'DataError'
+Exception message: The data provided does not meet requirements.
+Expecting exception from index.count({})
+PASS Exception was thrown.
+PASS code is 0
+PASS ename is 'DataError'
+Exception message: The data provided does not meet requirements.
+Expecting exception from index.count(/regex/)
+PASS Exception was thrown.
+PASS code is 0
+PASS ename is 'DataError'
+Exception message: The data provided does not meet requirements.
+
+test = {"key":0,"expected":1}
+request = index.count(test.key)
+PASS typeof request.result is "number"
+PASS request.result is 1
+
+test = {"key":100,"expected":0}
+request = index.count(test.key)
+PASS typeof request.result is "number"
+PASS request.result is 0
+
+test = {"key":null,"expected":100}
+request = index.count(test.key)
+PASS typeof request.result is "number"
+PASS request.result is 100
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
diff --git a/LayoutTests/platform/wk2/storage/indexeddb/intversion-close-in-oncomplete-expected.txt b/LayoutTests/platform/wk2/storage/indexeddb/intversion-close-in-oncomplete-expected.txt
new file mode 100644 (file)
index 0000000..8f8d7a0
--- /dev/null
@@ -0,0 +1,34 @@
+Call db.close() in the complete handler for a version change transaction, before the success event associated with the open call fires
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+indexedDB = self.indexedDB || self.webkitIndexedDB || self.mozIndexedDB || self.msIndexedDB || self.OIndexedDB;
+
+dbname = "intversion-close-in-oncomplete.html"
+indexedDB.deleteDatabase(dbname)
+request = indexedDB.open(dbname, 7)
+
+upgradeNeeded():
+db = event.target.result
+PASS event.newVersion is 7
+db.createObjectStore('os')
+transaction = event.target.transaction
+
+transaction.oncomplete:
+sawTransactionComplete = true
+db.close()
+
+openError():
+PASS sawTransactionComplete is true
+PASS event.target.result is null
+PASS event.target.error.name is "AbortError"
+Expecting exception from transaction = db.transaction('os', 'readwrite')
+PASS Exception was thrown.
+PASS code is DOMException.INVALID_STATE_ERR
+PASS ename is 'InvalidStateError'
+Exception message: An operation was called on an object on which it is not allowed or at a time when it is not allowed.
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
diff --git a/LayoutTests/platform/wk2/storage/indexeddb/intversion-close-in-upgradeneeded-expected.txt b/LayoutTests/platform/wk2/storage/indexeddb/intversion-close-in-upgradeneeded-expected.txt
new file mode 100644 (file)
index 0000000..71fc793
--- /dev/null
@@ -0,0 +1,39 @@
+Test that when db.close is called in upgradeneeded, the db is cleaned up on refresh.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+indexedDB = self.indexedDB || self.webkitIndexedDB || self.mozIndexedDB || self.msIndexedDB || self.OIndexedDB;
+
+dbname = "intversion-close-in-upgradeneeded.html"
+indexedDB.deleteDatabase(dbname)
+request = indexedDB.open(dbname, 7)
+
+
+upgradeNeeded():
+db = event.target.result
+PASS event.newVersion is 7
+transaction = event.target.transaction
+db.createObjectStore('os')
+db.close()
+
+transaction.oncomplete:
+sawTransactionComplete = true
+
+openError():
+PASS sawTransactionComplete is true
+PASS event.target.error.name is 'AbortError'
+PASS event.result is undefined
+
+Verify that the old connection is unchanged and was closed:
+PASS db is non-null.
+PASS db.version is 7
+Expecting exception from db.transaction('os')
+PASS Exception was thrown.
+PASS code is DOMException.INVALID_STATE_ERR
+PASS ename is 'InvalidStateError'
+Exception message: An operation was called on an object on which it is not allowed or at a time when it is not allowed.
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
diff --git a/LayoutTests/platform/wk2/storage/indexeddb/invalid-keys-expected.txt b/LayoutTests/platform/wk2/storage/indexeddb/invalid-keys-expected.txt
new file mode 100644 (file)
index 0000000..846f76c
--- /dev/null
@@ -0,0 +1,95 @@
+Test IndexedDB invalid keys
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+indexedDB = self.indexedDB || self.webkitIndexedDB || self.mozIndexedDB || self.msIndexedDB || self.OIndexedDB;
+
+dbname = "invalid-keys.html"
+indexedDB.deleteDatabase(dbname)
+indexedDB.open(dbname)
+db.createObjectStore('foo');
+Expecting exception from request = objectStore.put('value', void 0)
+PASS Exception was thrown.
+PASS code is 0
+PASS ename is 'DataError'
+Exception message: The data provided does not meet requirements.
+Expecting exception from request = objectStore.put('value', null)
+PASS Exception was thrown.
+PASS code is 0
+PASS ename is 'DataError'
+Exception message: The data provided does not meet requirements.
+Expecting exception from request = objectStore.put('value', (function() { return arguments; }()))
+PASS Exception was thrown.
+PASS code is 0
+PASS ename is 'DataError'
+Exception message: The data provided does not meet requirements.
+Expecting exception from request = objectStore.put('value', true)
+PASS Exception was thrown.
+PASS code is 0
+PASS ename is 'DataError'
+Exception message: The data provided does not meet requirements.
+Expecting exception from request = objectStore.put('value', false)
+PASS Exception was thrown.
+PASS code is 0
+PASS ename is 'DataError'
+Exception message: The data provided does not meet requirements.
+Expecting exception from request = objectStore.put('value', new Error)
+PASS Exception was thrown.
+PASS code is 0
+PASS ename is 'DataError'
+Exception message: The data provided does not meet requirements.
+Expecting exception from request = objectStore.put('value', function () {})
+PASS Exception was thrown.
+PASS code is 0
+PASS ename is 'DataError'
+Exception message: The data provided does not meet requirements.
+Expecting exception from request = objectStore.put('value', JSON)
+PASS Exception was thrown.
+PASS code is 0
+PASS ename is 'DataError'
+Exception message: The data provided does not meet requirements.
+Expecting exception from request = objectStore.put('value', Math)
+PASS Exception was thrown.
+PASS code is 0
+PASS ename is 'DataError'
+Exception message: The data provided does not meet requirements.
+Expecting exception from request = objectStore.put('value', NaN)
+PASS Exception was thrown.
+PASS code is 0
+PASS ename is 'DataError'
+Exception message: The data provided does not meet requirements.
+Expecting exception from request = objectStore.put('value', new Date(NaN))
+PASS Exception was thrown.
+PASS code is 0
+PASS ename is 'DataError'
+Exception message: The data provided does not meet requirements.
+Expecting exception from request = objectStore.put('value', {})
+PASS Exception was thrown.
+PASS code is 0
+PASS ename is 'DataError'
+Exception message: The data provided does not meet requirements.
+Expecting exception from request = objectStore.put('value', /regex/)
+PASS Exception was thrown.
+PASS code is 0
+PASS ename is 'DataError'
+Exception message: The data provided does not meet requirements.
+Expecting exception from request = objectStore.put('value', self)
+PASS Exception was thrown.
+PASS code is 0
+PASS ename is 'DataError'
+Exception message: The data provided does not meet requirements.
+Expecting exception from request = objectStore.put('value', self.document)
+PASS Exception was thrown.
+PASS code is 0
+PASS ename is 'DataError'
+Exception message: The data provided does not meet requirements.
+Expecting exception from request = objectStore.put('value', self.document.body)
+PASS Exception was thrown.
+PASS code is 0
+PASS ename is 'DataError'
+Exception message: The data provided does not meet requirements.
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
diff --git a/LayoutTests/platform/wk2/storage/indexeddb/key-requirements-delete-null-key-expected.txt b/LayoutTests/platform/wk2/storage/indexeddb/key-requirements-delete-null-key-expected.txt
new file mode 100644 (file)
index 0000000..56f891e
--- /dev/null
@@ -0,0 +1,20 @@
+Test IndexedDB's behavior deleting entry with no key
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+indexedDB = self.indexedDB || self.webkitIndexedDB || self.mozIndexedDB || self.msIndexedDB || self.OIndexedDB;
+
+dbname = "key-requirements-delete-null-key.html"
+indexedDB.deleteDatabase(dbname)
+indexedDB.open(dbname)
+objectStore = db.createObjectStore('bar');
+Expecting exception from objectStore.delete(null);
+PASS Exception was thrown.
+PASS code is 0
+PASS ename is 'DataError'
+Exception message: The data provided does not meet requirements.
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
diff --git a/LayoutTests/platform/wk2/storage/indexeddb/key-requirements-inline-and-passed-expected.txt b/LayoutTests/platform/wk2/storage/indexeddb/key-requirements-inline-and-passed-expected.txt
new file mode 100644 (file)
index 0000000..f09c61b
--- /dev/null
@@ -0,0 +1,20 @@
+Test IndexedDB's behavior adding inline and passed key simultaneously
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+indexedDB = self.indexedDB || self.webkitIndexedDB || self.mozIndexedDB || self.msIndexedDB || self.OIndexedDB;
+
+dbname = "key-requirements-inline-and-passed.html"
+indexedDB.deleteDatabase(dbname)
+indexedDB.open(dbname)
+objectStore = db.createObjectStore('baz', { keyPath: 'id' });
+Expecting exception from objectStore.add({id: 5}, 5);
+PASS Exception was thrown.
+PASS code is 0
+PASS ename is 'DataError'
+Exception message: The data provided does not meet requirements.
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
diff --git a/LayoutTests/platform/wk2/storage/indexeddb/key-requirements-put-no-key-expected.txt b/LayoutTests/platform/wk2/storage/indexeddb/key-requirements-put-no-key-expected.txt
new file mode 100644 (file)
index 0000000..4a15a9f
--- /dev/null
@@ -0,0 +1,20 @@
+Test IndexedDB's behavior puting without key
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+indexedDB = self.indexedDB || self.webkitIndexedDB || self.mozIndexedDB || self.msIndexedDB || self.OIndexedDB;
+
+dbname = "key-requirements-put-no-key.html"
+indexedDB.deleteDatabase(dbname)
+indexedDB.open(dbname)
+objectStore = db.createObjectStore('bar');
+Expecting exception from objectStore.put({});
+PASS Exception was thrown.
+PASS code is 0
+PASS ename is 'DataError'
+Exception message: The data provided does not meet requirements.
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
diff --git a/LayoutTests/platform/wk2/storage/indexeddb/key-requirements-put-null-key-expected.txt b/LayoutTests/platform/wk2/storage/indexeddb/key-requirements-put-null-key-expected.txt
new file mode 100644 (file)
index 0000000..59dc35a
--- /dev/null
@@ -0,0 +1,20 @@
+Test IndexedDB's behavior put()ing with null key
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+indexedDB = self.indexedDB || self.webkitIndexedDB || self.mozIndexedDB || self.msIndexedDB || self.OIndexedDB;
+
+dbname = "key-requirements-put-null-key.html"
+indexedDB.deleteDatabase(dbname)
+indexedDB.open(dbname)
+objectStore = db.createObjectStore('bar');
+Expecting exception from objectStore.put({}, null);
+PASS Exception was thrown.
+PASS code is 0
+PASS ename is 'DataError'
+Exception message: The data provided does not meet requirements.
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
diff --git a/LayoutTests/platform/wk2/storage/indexeddb/key-type-array-expected.txt b/LayoutTests/platform/wk2/storage/indexeddb/key-type-array-expected.txt
new file mode 100644 (file)
index 0000000..177c0c2
--- /dev/null
@@ -0,0 +1,291 @@
+Test IndexedDB key types
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+indexedDB = self.indexedDB || self.webkitIndexedDB || self.mozIndexedDB || self.msIndexedDB || self.OIndexedDB;
+
+dbname = "key-type-array.html"
+indexedDB.deleteDatabase(dbname)
+indexedDB.open(dbname)
+db.createObjectStore('store');
+
+trans = db.transaction('store', 'readwrite')
+store = trans.objectStore('store')
+
+long_array = []; for (i = 0; i < 1000; ++i) { long_array.push('abc', 123, new Date(0), []); }
+
+array that contains non-numeric self-reference
+self_referrential_array = []; self_referrential_array.self = self_referrential_array;
+
+testing array key: []
+store.put('value1', []);
+store.get([]);
+PASS getreq.result is "value1"
+
+testing array key: [-Infinity]
+store.put('value2', [-Infinity]);
+store.get([-Infinity]);
+PASS getreq.result is "value2"
+
+testing array key: [-Number.MAX_VALUE]
+store.put('value3', [-Number.MAX_VALUE]);
+store.get([-Number.MAX_VALUE]);
+PASS getreq.result is "value3"
+
+testing array key: [-1]
+store.put('value4', [-1]);
+store.get([-1]);
+PASS getreq.result is "value4"
+
+testing array key: [-Number.MIN_VALUE]
+store.put('value5', [-Number.MIN_VALUE]);
+store.get([-Number.MIN_VALUE]);
+PASS getreq.result is "value5"
+
+testing array key: [0]
+store.put('value6', [0]);
+store.get([0]);
+PASS getreq.result is "value6"
+
+testing array key: [Number.MIN_VALUE]
+store.put('value7', [Number.MIN_VALUE]);
+store.get([Number.MIN_VALUE]);
+PASS getreq.result is "value7"
+
+testing array key: [1]
+store.put('value8', [1]);
+store.get([1]);
+PASS getreq.result is "value8"
+
+testing array key: [Number.MAX_VALUE]
+store.put('value9', [Number.MAX_VALUE]);
+store.get([Number.MAX_VALUE]);
+PASS getreq.result is "value9"
+
+testing array key: [Infinity]
+store.put('value10', [Infinity]);
+store.get([Infinity]);
+PASS getreq.result is "value10"
+
+testing array key: [1,2,3]
+store.put('value11', [1,2,3]);
+store.get([1,2,3]);
+PASS getreq.result is "value11"
+
+testing array key: [new Date(0)]
+store.put('value12', [new Date(0)]);
+store.get([new Date(0)]);
+PASS getreq.result is "value12"
+
+testing array key: [new Date('2525-01-01T00:00:00Z')]
+store.put('value13', [new Date('2525-01-01T00:00:00Z')]);
+store.get([new Date('2525-01-01T00:00:00Z')]);
+PASS getreq.result is "value13"
+
+testing array key: [new Date(0), new Date('2525-01-01T00:00:00Z')]
+store.put('value14', [new Date(0), new Date('2525-01-01T00:00:00Z')]);
+store.get([new Date(0), new Date('2525-01-01T00:00:00Z')]);
+PASS getreq.result is "value14"
+
+testing array key: ['']
+store.put('value15', ['']);
+store.get(['']);
+PASS getreq.result is "value15"
+
+testing array key: ['']
+store.put('value16', ['']);
+store.get(['']);
+PASS getreq.result is "value16"
+
+testing array key: ['abc123']
+store.put('value17', ['abc123']);
+store.get(['abc123']);
+PASS getreq.result is "value17"
+
+testing array key: ['abc', 123]
+store.put('value18', ['abc', 123]);
+store.get(['abc', 123]);
+PASS getreq.result is "value18"
+
+testing array key: [[]]
+store.put('value19', [[]]);
+store.get([[]]);
+PASS getreq.result is "value19"
+
+testing array key: [[], []]
+store.put('value20', [[], []]);
+store.get([[], []]);
+PASS getreq.result is "value20"
+
+testing array key: [[], [], []]
+store.put('value21', [[], [], []]);
+store.get([[], [], []]);
+PASS getreq.result is "value21"
+
+testing array key: [[[]]]
+store.put('value22', [[[]]]);
+store.get([[[]]]);
+PASS getreq.result is "value22"
+
+testing array key: [[[[]]]]
+store.put('value23', [[[[]]]]);
+store.get([[[[]]]]);
+PASS getreq.result is "value23"
+
+testing array key: [123, 'abc', new Date(0), []]
+store.put('value24', [123, 'abc', new Date(0), []]);
+store.get([123, 'abc', new Date(0), []]);
+PASS getreq.result is "value24"
+
+testing array key: [[123, 'abc', new Date(0), []], [456, 'def', new Date(999), [[]]]]
+store.put('value25', [[123, 'abc', new Date(0), []], [456, 'def', new Date(999), [[]]]]);
+store.get([[123, 'abc', new Date(0), []], [456, 'def', new Date(999), [[]]]]);
+PASS getreq.result is "value25"
+
+testing array key: long_array
+store.put('value26', long_array);
+store.get(long_array);
+PASS getreq.result is "value26"
+
+testing array key: self_referrential_array
+store.put('value27', self_referrential_array);
+store.get(self_referrential_array);
+PASS getreq.result is "value27"
+
+trans = db.transaction('store', 'readwrite')
+store = trans.objectStore('store')
+
+array that contains itself: array = [ array ]
+cyclic_array = []; cyclic_array.push(cyclic_array)
+array that contains itself, one level down: array = [ [ array ] ]
+cyclic_array2 = []; cyclic_array2.push([cyclic_array2])
+array that contains itself, not as first element: array = [1, 'b', [], array]
+cyclic_array3 = [1, 'b', []]; cyclic_array3.push(cyclic_array3)
+array that contains array that contains itself
+cyclic_array4 = [cyclic_array];
+
+testing invalid array key: [ void 0 ]
+Expecting exception from store.put('value', [ void 0 ]);
+PASS Exception was thrown.
+PASS code is 0
+PASS ename is 'DataError'
+Exception message: The data provided does not meet requirements.
+
+testing invalid array key: [ true ]
+Expecting exception from store.put('value', [ true ]);
+PASS Exception was thrown.
+PASS code is 0
+PASS ename is 'DataError'
+Exception message: The data provided does not meet requirements.
+
+testing invalid array key: [ false ]
+Expecting exception from store.put('value', [ false ]);
+PASS Exception was thrown.
+PASS code is 0
+PASS ename is 'DataError'
+Exception message: The data provided does not meet requirements.
+
+testing invalid array key: [ NaN ]
+Expecting exception from store.put('value', [ NaN ]);
+PASS Exception was thrown.
+PASS code is 0
+PASS ename is 'DataError'
+Exception message: The data provided does not meet requirements.
+
+testing invalid array key: [ null ]
+Expecting exception from store.put('value', [ null ]);
+PASS Exception was thrown.
+PASS code is 0
+PASS ename is 'DataError'
+Exception message: The data provided does not meet requirements.
+
+testing invalid array key: [ {} ]
+Expecting exception from store.put('value', [ {} ]);
+PASS Exception was thrown.
+PASS code is 0
+PASS ename is 'DataError'
+Exception message: The data provided does not meet requirements.
+
+testing invalid array key: [ function () {} ]
+Expecting exception from store.put('value', [ function () {} ]);
+PASS Exception was thrown.
+PASS code is 0
+PASS ename is 'DataError'
+Exception message: The data provided does not meet requirements.
+
+testing invalid array key: [ /regex/ ]
+Expecting exception from store.put('value', [ /regex/ ]);
+PASS Exception was thrown.
+PASS code is 0
+PASS ename is 'DataError'
+Exception message: The data provided does not meet requirements.
+
+testing invalid array key: [ self ]
+Expecting exception from store.put('value', [ self ]);
+PASS Exception was thrown.
+PASS code is 0
+PASS ename is 'DataError'
+Exception message: The data provided does not meet requirements.
+
+testing invalid array key: [ self.document ]
+Expecting exception from store.put('value', [ self.document ]);
+PASS Exception was thrown.
+PASS code is 0
+PASS ename is 'DataError'
+Exception message: The data provided does not meet requirements.
+
+testing invalid array key: [ self.document.body ]
+Expecting exception from store.put('value', [ self.document.body ]);
+PASS Exception was thrown.
+PASS code is 0
+PASS ename is 'DataError'
+Exception message: The data provided does not meet requirements.
+
+testing invalid array key: cyclic_array
+Expecting exception from store.put('value', cyclic_array);
+PASS Exception was thrown.
+PASS code is 0
+PASS ename is 'DataError'
+Exception message: The data provided does not meet requirements.
+
+testing invalid array key: cyclic_array2
+Expecting exception from store.put('value', cyclic_array2);
+PASS Exception was thrown.
+PASS code is 0
+PASS ename is 'DataError'
+Exception message: The data provided does not meet requirements.
+
+testing invalid array key: cyclic_array3
+Expecting exception from store.put('value', cyclic_array3);
+PASS Exception was thrown.
+PASS code is 0
+PASS ename is 'DataError'
+Exception message: The data provided does not meet requirements.
+
+testing invalid array key: cyclic_array4
+Expecting exception from store.put('value', cyclic_array4);
+PASS Exception was thrown.
+PASS code is 0
+PASS ename is 'DataError'
+Exception message: The data provided does not meet requirements.
+
+testing invalid array key: Array(1000)
+Expecting exception from store.put('value', Array(1000));
+PASS Exception was thrown.
+PASS code is 0
+PASS ename is 'DataError'
+Exception message: The data provided does not meet requirements.
+
+PASS indexedDB.cmp(makeArrayOfDepth(25), 0) is 1
+PASS indexedDB.cmp(makeArrayOfDepth(250), 0) is 1
+Expecting exception from indexedDB.cmp(makeArrayOfDepth(2500), 0)
+PASS Exception was thrown.
+PASS code is 0
+PASS ename is 'DataError'
+Exception message: The data provided does not meet requirements.
+
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
diff --git a/LayoutTests/platform/wk2/storage/indexeddb/keypath-arrays-expected.txt b/LayoutTests/platform/wk2/storage/indexeddb/keypath-arrays-expected.txt
new file mode 100644 (file)
index 0000000..76e83e1
--- /dev/null
@@ -0,0 +1,58 @@
+Test IndexedDB Array-type keyPaths
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+indexedDB = self.indexedDB || self.webkitIndexedDB || self.mozIndexedDB || self.msIndexedDB || self.OIndexedDB;
+
+dbname = "keypath-arrays.html"
+indexedDB.deleteDatabase(dbname)
+indexedDB.open(dbname)
+store = db.createObjectStore('store', {keyPath: ['a', 'b']})
+store.createIndex('index', ['c', 'd'])
+Expecting exception from db.createObjectStore('store-with-generator', {keyPath: ['a', 'b'], autoIncrement: true})
+PASS Exception was thrown.
+PASS code is DOMException.INVALID_ACCESS_ERR
+Exception message: An invalid operation was performed on an object.
+Expecting exception from store.createIndex('index-multientry', ['e', 'f'], {multiEntry: true})
+PASS Exception was thrown.
+PASS code is DOMException.INVALID_ACCESS_ERR
+Exception message: An invalid operation was performed on an object.
+
+Empty arrays are not valid key paths:
+Expecting exception from db.createObjectStore('store-keypath-empty-array', {keyPath: []})
+PASS Exception was thrown.
+PASS code is DOMException.SYNTAX_ERR
+Exception message: The keypath argument contains an invalid key path.
+Expecting exception from store.createIndex('index-keypath-empty-array', [])
+PASS Exception was thrown.
+PASS code is DOMException.SYNTAX_ERR
+Exception message: The keypath argument contains an invalid key path.
+
+testKeyPaths():
+transaction = db.transaction(['store'], 'readwrite')
+store = transaction.objectStore('store')
+index = store.index('index')
+
+request = store.put({a: 1, b: 2, c: 3, d: 4})
+request = store.put({a: 5, b: 6, c: 7, d: 8})
+request = store.openCursor()
+cursor = request.result
+PASS cursor is non-null.
+PASS JSON.stringify(cursor.key) is "[1,2]"
+cursor = request.result
+PASS cursor is non-null.
+PASS JSON.stringify(cursor.key) is "[5,6]"
+request = index.openCursor()
+cursor = request.result
+PASS cursor is non-null.
+PASS JSON.stringify(cursor.primaryKey) is "[1,2]"
+PASS JSON.stringify(cursor.key) is "[3,4]"
+cursor = request.result
+PASS cursor is non-null.
+PASS JSON.stringify(cursor.primaryKey) is "[5,6]"
+PASS JSON.stringify(cursor.key) is "[7,8]"
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
diff --git a/LayoutTests/platform/wk2/storage/indexeddb/keypath-edges-expected.txt b/LayoutTests/platform/wk2/storage/indexeddb/keypath-edges-expected.txt
new file mode 100644 (file)
index 0000000..114a545
--- /dev/null
@@ -0,0 +1,78 @@
+Test IndexedDB keyPath edge cases
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+indexedDB = self.indexedDB || self.webkitIndexedDB || self.mozIndexedDB || self.msIndexedDB || self.OIndexedDB;
+
+dbname = "keypath-edges.html"
+indexedDB.deleteDatabase(dbname)
+indexedDB.open(dbname)
+db.createObjectStore('store-with-path', {keyPath: 'foo'})
+db.createObjectStore('store-with-path-and-generator', {keyPath: 'foo', autoIncrement: true})
+
+testKeyPaths():
+transaction = db.transaction(['store-with-path'], 'readwrite')
+store = transaction.objectStore('store-with-path')
+
+Key path doesn't resolve to a value; should yield null, should throw DATA_ERR
+Expecting exception from store.put(null)
+PASS Exception was thrown.
+PASS code is 0
+PASS ename is 'DataError'
+Exception message: The data provided does not meet requirements.
+
+Key path doesn't resolve to a value; should yield null, should throw DATA_ERR
+Expecting exception from store.put({})
+PASS Exception was thrown.
+PASS code is 0
+PASS ename is 'DataError'
+Exception message: The data provided does not meet requirements.
+
+Key path resolves to a value that is invalid key; should yield 'invalid' key, should throw DATA_ERR
+Expecting exception from store.put({foo: null})
+PASS Exception was thrown.
+PASS code is 0
+PASS ename is 'DataError'
+Exception message: The data provided does not meet requirements.
+
+Key path resolves to a value that is valid key; should yield 'string' key, should succeed
+store.put({foo: 'zoo'})
+PASS store.put succeeded
+
+testKeyPathsAndGenerator():
+transaction = db.transaction(['store-with-path-and-generator'], 'readwrite')
+store = transaction.objectStore('store-with-path-and-generator')
+
+Key path doesn't resolve to a value; should yield null but insertion would fail, so put request should raise exception
+Expecting exception from store.put(null)
+PASS Exception was thrown.
+PASS code is 0
+PASS ename is 'DataError'
+Exception message: The data provided does not meet requirements.
+
+Key path doesn't resolve to a value; should yield null but insertion would fail, so put request should raise exception
+Expecting exception from store.put('string')
+PASS Exception was thrown.
+PASS code is 0
+PASS ename is 'DataError'
+Exception message: The data provided does not meet requirements.
+
+Key path doesn't resolve to a value; should yield null, key should be generated, put request should succeed
+store.put({})
+PASS store.put succeeded
+
+Key path resolves to a value that is invalid key; should yield 'invalid' key, should throw DATA_ERR
+Expecting exception from store.put({foo: null})
+PASS Exception was thrown.
+PASS code is 0
+PASS ename is 'DataError'
+Exception message: The data provided does not meet requirements.
+
+Key path resolves to a value that is valid key; should yield 'string' key, should succeed
+store.put({foo: 'zoo'})
+PASS store.put succeeded
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
diff --git a/LayoutTests/platform/wk2/storage/indexeddb/keyrange-expected.txt b/LayoutTests/platform/wk2/storage/indexeddb/keyrange-expected.txt
new file mode 100644 (file)
index 0000000..437bd84
--- /dev/null
@@ -0,0 +1,276 @@
+Test IndexedDB's KeyRange.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+indexedDB = self.indexedDB || self.webkitIndexedDB || self.mozIndexedDB || self.msIndexedDB || self.OIndexedDB;
+
+PASS 'lower' in IDBKeyRange is false
+PASS 'upper' in IDBKeyRange is false
+PASS 'lowerOpen' in IDBKeyRange is false
+PASS 'upperOpen' in IDBKeyRange is false
+PASS 'only' in IDBKeyRange is true
+PASS 'lowerBound' in IDBKeyRange is true
+PASS 'upperBound' in IDBKeyRange is true
+PASS 'bound' in IDBKeyRange is true
+
+instance = IDBKeyRange.only(1)
+PASS 'lower' in instance is true
+PASS 'upper' in instance is true
+PASS 'lowerOpen' in instance is true
+PASS 'upperOpen' in instance is true
+PASS 'only' in instance is false
+PASS 'lowerBound' in instance is false
+PASS 'upperBound' in instance is false
+PASS 'bound' in instance is false
+
+IDBKeyRange.only(1)
+PASS keyRange.lower is 1
+PASS keyRange.upper is 1
+PASS keyRange.lowerOpen is false
+PASS keyRange.upperOpen is false
+IDBKeyRange.only(3.14)
+PASS keyRange.lower is 3.14
+PASS keyRange.upper is 3.14
+PASS keyRange.lowerOpen is false
+PASS keyRange.upperOpen is false
+IDBKeyRange.only('a')
+PASS keyRange.lower is 'a'
+PASS keyRange.upper is 'a'
+PASS keyRange.lowerOpen is false
+PASS keyRange.upperOpen is false
+IDBKeyRange.lowerBound(10,true)
+PASS keyRange.lower is 10
+PASS keyRange.lowerOpen is true
+PASS keyRange.upper is undefined.
+PASS keyRange.upperOpen is true
+IDBKeyRange.lowerBound(11,false)
+PASS keyRange.lower is 11
+PASS keyRange.lowerOpen is false
+PASS keyRange.upper is undefined.
+PASS keyRange.upperOpen is true
+IDBKeyRange.lowerBound(12,undefined)
+PASS keyRange.lower is 12
+PASS keyRange.lowerOpen is false
+PASS keyRange.upper is undefined.
+PASS keyRange.upperOpen is true
+IDBKeyRange.lowerBound(10.1,true)
+PASS keyRange.lower is 10.1
+PASS keyRange.lowerOpen is true
+PASS keyRange.upper is undefined.
+PASS keyRange.upperOpen is true
+IDBKeyRange.lowerBound(11.2,false)
+PASS keyRange.lower is 11.2
+PASS keyRange.lowerOpen is false
+PASS keyRange.upper is undefined.
+PASS keyRange.upperOpen is true
+IDBKeyRange.lowerBound(12.3,undefined)
+PASS keyRange.lower is 12.3
+PASS keyRange.lowerOpen is false
+PASS keyRange.upper is undefined.
+PASS keyRange.upperOpen is true
+IDBKeyRange.lowerBound('aa',true)
+PASS keyRange.lower is 'aa'
+PASS keyRange.lowerOpen is true
+PASS keyRange.upper is undefined.
+PASS keyRange.upperOpen is true
+IDBKeyRange.lowerBound('ab',false)
+PASS keyRange.lower is 'ab'
+PASS keyRange.lowerOpen is false
+PASS keyRange.upper is undefined.
+PASS keyRange.upperOpen is true
+IDBKeyRange.lowerBound('ac',undefined)
+PASS keyRange.lower is 'ac'
+PASS keyRange.lowerOpen is false
+PASS keyRange.upper is undefined.
+PASS keyRange.upperOpen is true
+IDBKeyRange.upperBound(20,true)
+PASS keyRange.upper is 20
+PASS keyRange.upperOpen is true
+PASS keyRange.lower is undefined.
+PASS keyRange.lowerOpen is true
+IDBKeyRange.upperBound(21,false)
+PASS keyRange.upper is 21
+PASS keyRange.upperOpen is false
+PASS keyRange.lower is undefined.
+PASS keyRange.lowerOpen is true
+IDBKeyRange.upperBound(22,undefined)
+PASS keyRange.upper is 22
+PASS keyRange.upperOpen is false
+PASS keyRange.lower is undefined.
+PASS keyRange.lowerOpen is true
+IDBKeyRange.upperBound(20.2,true)
+PASS keyRange.upper is 20.2
+PASS keyRange.upperOpen is true
+PASS keyRange.lower is undefined.
+PASS keyRange.lowerOpen is true
+IDBKeyRange.upperBound(21.3,false)
+PASS keyRange.upper is 21.3
+PASS keyRange.upperOpen is false
+PASS keyRange.lower is undefined.
+PASS keyRange.lowerOpen is true
+IDBKeyRange.upperBound(22.4,undefined)
+PASS keyRange.upper is 22.4
+PASS keyRange.upperOpen is false
+PASS keyRange.lower is undefined.
+PASS keyRange.lowerOpen is true
+IDBKeyRange.upperBound('ba',true)
+PASS keyRange.upper is 'ba'
+PASS keyRange.upperOpen is true
+PASS keyRange.lower is undefined.
+PASS keyRange.lowerOpen is true
+IDBKeyRange.upperBound('bb',false)
+PASS keyRange.upper is 'bb'
+PASS keyRange.upperOpen is false
+PASS keyRange.lower is undefined.
+PASS keyRange.lowerOpen is true
+IDBKeyRange.upperBound('bc',undefined)
+PASS keyRange.upper is 'bc'
+PASS keyRange.upperOpen is false
+PASS keyRange.lower is undefined.
+PASS keyRange.lowerOpen is true
+IDBKeyRange.bound(30,40, undefined, undefined)
+PASS keyRange.lower is 30
+PASS keyRange.upper is 40
+PASS keyRange.lowerOpen is false
+PASS keyRange.upperOpen is false
+IDBKeyRange.bound(31,41, false, false)
+PASS keyRange.lower is 31
+PASS keyRange.upper is 41
+PASS keyRange.lowerOpen is false
+PASS keyRange.upperOpen is false
+IDBKeyRange.bound(32,42, false, true)
+PASS keyRange.lower is 32
+PASS keyRange.upper is 42
+PASS keyRange.lowerOpen is false
+PASS keyRange.upperOpen is true
+IDBKeyRange.bound(33,43, true, false)
+PASS keyRange.lower is 33
+PASS keyRange.upper is 43
+PASS keyRange.lowerOpen is true
+PASS keyRange.upperOpen is false
+IDBKeyRange.bound(34,44, true, true)
+PASS keyRange.lower is 34
+PASS keyRange.upper is 44
+PASS keyRange.lowerOpen is true
+PASS keyRange.upperOpen is true
+IDBKeyRange.bound(30.1,40.2, undefined, undefined)
+PASS keyRange.lower is 30.1
+PASS keyRange.upper is 40.2
+PASS keyRange.lowerOpen is false
+PASS keyRange.upperOpen is false
+IDBKeyRange.bound(31.3,41.4, false, false)
+PASS keyRange.lower is 31.3
+PASS keyRange.upper is 41.4
+PASS keyRange.lowerOpen is false
+PASS keyRange.upperOpen is false
+IDBKeyRange.bound(32.5,42.6, false, true)
+PASS keyRange.lower is 32.5
+PASS keyRange.upper is 42.6
+PASS keyRange.lowerOpen is false
+PASS keyRange.upperOpen is true
+IDBKeyRange.bound(33.7,43.8, true, false)
+PASS keyRange.lower is 33.7
+PASS keyRange.upper is 43.8
+PASS keyRange.lowerOpen is true
+PASS keyRange.upperOpen is false
+IDBKeyRange.bound(34.9,44, true, true)
+PASS keyRange.lower is 34.9
+PASS keyRange.upper is 44
+PASS keyRange.lowerOpen is true
+PASS keyRange.upperOpen is true
+IDBKeyRange.bound('aaa','aba', false, false)
+PASS keyRange.lower is 'aaa'
+PASS keyRange.upper is 'aba'
+PASS keyRange.lowerOpen is false
+PASS keyRange.upperOpen is false
+IDBKeyRange.bound('aab','abb', undefined, undefined)
+PASS keyRange.lower is 'aab'
+PASS keyRange.upper is 'abb'
+PASS keyRange.lowerOpen is false
+PASS keyRange.upperOpen is false
+IDBKeyRange.bound('aac','abc', false, false)
+PASS keyRange.lower is 'aac'
+PASS keyRange.upper is 'abc'
+PASS keyRange.lowerOpen is false
+PASS keyRange.upperOpen is false
+IDBKeyRange.bound('aad','abd', false, true)
+PASS keyRange.lower is 'aad'
+PASS keyRange.upper is 'abd'
+PASS keyRange.lowerOpen is false
+PASS keyRange.upperOpen is true
+IDBKeyRange.bound('aae','abe', true, false)
+PASS keyRange.lower is 'aae'
+PASS keyRange.upper is 'abe'
+PASS keyRange.lowerOpen is true
+PASS keyRange.upperOpen is false
+IDBKeyRange.bound('aaf','abf', true, true)
+PASS keyRange.lower is 'aaf'
+PASS keyRange.upper is 'abf'
+PASS keyRange.lowerOpen is true
+PASS keyRange.upperOpen is true
+Passing an invalid key into only({})
+Expecting exception from IDBKeyRange.only({})
+PASS Exception was thrown.
+PASS code is 0
+PASS ename is 'DataError'
+Exception message: The data provided does not meet requirements.
+Passing an invalid key into upperBound({})
+Expecting exception from IDBKeyRange.upperBound({})
+PASS Exception was thrown.
+PASS code is 0
+PASS ename is 'DataError'
+Exception message: The data provided does not meet requirements.
+Passing an invalid key into lowerBound({})
+Expecting exception from IDBKeyRange.lowerBound({})
+PASS Exception was thrown.
+PASS code is 0
+PASS ename is 'DataError'
+Exception message: The data provided does not meet requirements.
+Passing an invalid key into bound(null, {})
+Expecting exception from IDBKeyRange.bound(null, {})
+PASS Exception was thrown.
+PASS code is 0
+PASS ename is 'DataError'
+Exception message: The data provided does not meet requirements.
+Passing an invalid key into bound({},null)
+Expecting exception from IDBKeyRange.bound({}, null)
+PASS Exception was thrown.
+PASS code is 0
+PASS ename is 'DataError'
+Exception message: The data provided does not meet requirements.
+Passing an invalid key into bound({}, {})
+Expecting exception from IDBKeyRange.bound({}, {})
+PASS Exception was thrown.
+PASS code is 0
+PASS ename is 'DataError'
+Exception message: The data provided does not meet requirements.
+Lower key greater than higher key, bound(4, 3)
+Expecting exception from IDBKeyRange.bound(4, 3)
+PASS Exception was thrown.
+PASS code is 0
+PASS ename is 'DataError'
+Exception message: The data provided does not meet requirements.
+Equal keys, either of the bounds is open, bound(4, 4, true, false)
+Expecting exception from IDBKeyRange.bound(4, 4, true, false)
+PASS Exception was thrown.
+PASS code is 0
+PASS ename is 'DataError'
+Exception message: The data provided does not meet requirements.
+Equal keys, either of the bounds is open, bound(4, 4, false, true)
+Expecting exception from IDBKeyRange.bound(4, 4, false, true)
+PASS Exception was thrown.
+PASS code is 0
+PASS ename is 'DataError'
+Exception message: The data provided does not meet requirements.
+Equal keys, either of the bounds is open, bound(4, 4, true, true)
+Expecting exception from IDBKeyRange.bound(4, 4, true, true)
+PASS Exception was thrown.
+PASS code is 0
+PASS ename is 'DataError'
+Exception message: The data provided does not meet requirements.
+Equal keys, none of the bounds is open, bound(4, 4, false, false)
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
diff --git a/LayoutTests/platform/wk2/storage/indexeddb/mozilla/clear-expected.txt b/LayoutTests/platform/wk2/storage/indexeddb/mozilla/clear-expected.txt
new file mode 100644 (file)
index 0000000..60bba5f
--- /dev/null
@@ -0,0 +1,26 @@
+Test IndexedDB's clearing an object store
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+indexedDB = self.indexedDB || self.webkitIndexedDB || self.mozIndexedDB || self.msIndexedDB || self.OIndexedDB;
+
+dbname = "clear.html"
+indexedDB.deleteDatabase(dbname)
+indexedDB.open(dbname)
+objectStore = db.createObjectStore('foo', { autoIncrement: true });
+request = objectStore.add({});
+Expecting exception from db.transaction('foo').objectStore('foo').clear();
+PASS Exception was thrown.
+PASS code is 0
+PASS ename is 'ReadOnlyError'
+Exception message: A write operation was attempted in a read-only transaction.
+db.transaction('foo', 'readwrite')
+transaction.objectStore('foo').clear();
+request = db.transaction('foo').objectStore('foo').openCursor();
+cursor = request.result;
+PASS cursor is null
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
diff --git a/LayoutTests/platform/wk2/storage/indexeddb/mozilla/create-objectstore-basics-expected.txt b/LayoutTests/platform/wk2/storage/indexeddb/mozilla/create-objectstore-basics-expected.txt
new file mode 100644 (file)
index 0000000..f9c5c80
--- /dev/null
@@ -0,0 +1,56 @@
+Test IndexedDB's creating object store and updating properties
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+indexedDB = self.indexedDB || self.webkitIndexedDB || self.mozIndexedDB || self.msIndexedDB || self.OIndexedDB;
+
+dbname = "create-objectstore-basics.html"
+indexedDB.deleteDatabase(dbname)
+indexedDB.open(dbname)
+objectStore = db.createObjectStore(info.name, info.options);
+PASS objectStore.name is info.name
+PASS objectStore.indexNames.length is 0
+PASS event.target.transaction.db is db
+PASS event.target.transaction.mode is "versionchange"
+objectStore = db.createObjectStore(info.name, info.options);
+PASS objectStore.name is info.name
+PASS objectStore.indexNames.length is 0
+PASS event.target.transaction.db is db
+PASS event.target.transaction.mode is "versionchange"
+objectStore = db.createObjectStore(info.name, info.options);
+PASS objectStore.name is info.name
+PASS objectStore.indexNames.length is 0
+PASS event.target.transaction.db is db
+PASS event.target.transaction.mode is "versionchange"
+Expecting exception from objectStore = db.createObjectStore(info.name, info.options)
+PASS Exception was thrown.
+PASS code is DOMException.INVALID_ACCESS_ERR
+Exception message: An invalid operation was performed on an object.
+objectStore = db.createObjectStore(info.name, info.options);
+PASS objectStore.name is info.name
+PASS objectStore.indexNames.length is 0
+PASS event.target.transaction.db is db
+PASS event.target.transaction.mode is "versionchange"
+objectStore = db.createObjectStore(info.name, info.options);
+PASS objectStore.name is info.name
+PASS objectStore.keyPath is info.options.keyPath
+PASS objectStore.indexNames.length is 0
+PASS event.target.transaction.db is db
+PASS event.target.transaction.mode is "versionchange"
+objectStore = db.createObjectStore(info.name, info.options);
+PASS objectStore.name is info.name
+PASS objectStore.keyPath is info.options.keyPath
+PASS objectStore.indexNames.length is 0
+PASS event.target.transaction.db is db
+PASS event.target.transaction.mode is "versionchange"
+objectStore = db.createObjectStore(info.name, info.options);
+PASS objectStore.name is info.name
+PASS objectStore.keyPath is info.options.keyPath
+PASS objectStore.indexNames.length is 0
+PASS event.target.transaction.db is db
+PASS event.target.transaction.mode is "versionchange"
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
diff --git a/LayoutTests/platform/wk2/storage/indexeddb/mozilla/cursors-expected.txt b/LayoutTests/platform/wk2/storage/indexeddb/mozilla/cursors-expected.txt
new file mode 100644 (file)
index 0000000..5380b09
--- /dev/null
@@ -0,0 +1,609 @@
+Test IndexedDB cursor behavior
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+indexedDB = self.indexedDB || self.webkitIndexedDB || self.mozIndexedDB || self.msIndexedDB || self.OIndexedDB;
+
+dbname = "cursors.html"
+indexedDB.deleteDatabase(dbname)
+indexedDB.open(dbname)
+db.createObjectStore('autoIncrement', { autoIncrement: true });
+request = objectStore.openCursor();
+PASS event.target.result is null
+db.createObjectStore('autoIncrementKeyPath', { keyPath: 'foo', autoIncrement: true });
+request = objectStore.openCursor();
+PASS event.target.result is null
+db.createObjectStore('keyPath', { keyPath: 'foo' });
+request = objectStore.openCursor();
+PASS event.target.result is null
+db.createObjectStore('foo');
+request = objectStore.openCursor();
+PASS event.target.result is null
+keys = [1, -1, 0, 10, 2000, 'q', 'z', 'two', 'b', 'a'];
+sortedKeys = [-1, 0, 1, 10, 2000, 'a', 'b', 'q', 'two', 'z'];
+keyIndex = 0;
+request = objectStore.add('foo', keys[i]);
+request = objectStore.add('foo', keys[i]);
+request = objectStore.add('foo', keys[i]);
+request = objectStore.add('foo', keys[i]);
+request = objectStore.add('foo', keys[i]);
+request = objectStore.add('foo', keys[i]);
+request = objectStore.add('foo', keys[i]);
+request = objectStore.add('foo', keys[i]);
+request = objectStore.add('foo', keys[i]);
+request = objectStore.add('foo', keys[i]);
+request = objectStore.openCursor();
+cursor = event.target.result;
+PASS cursor.key is sortedKeys[keyIndex]
+PASS cursor.primaryKey is sortedKeys[keyIndex]
+PASS cursor.value is 'foo'
+cursor.continue();
+Expecting exception from cursor.continue();
+PASS Exception was thrown.
+PASS code is DOMException.INVALID_STATE_ERR
+Exception message: An operation was called on an object on which it is not allowed or at a time when it is not allowed.
+PASS cursor.key is sortedKeys[keyIndex]
+PASS cursor.primaryKey is sortedKeys[keyIndex]
+PASS cursor.value is 'foo'
+keyIndex++;
+cursor = event.target.result;
+PASS cursor.key is sortedKeys[keyIndex]
+PASS cursor.primaryKey is sortedKeys[keyIndex]
+PASS cursor.value is 'foo'
+cursor.continue();
+Expecting exception from cursor.continue();
+PASS Exception was thrown.
+PASS code is DOMException.INVALID_STATE_ERR
+Exception message: An operation was called on an object on which it is not allowed or at a time when it is not allowed.
+PASS cursor.key is sortedKeys[keyIndex]
+PASS cursor.primaryKey is sortedKeys[keyIndex]
+PASS cursor.value is 'foo'
+keyIndex++;
+cursor = event.target.result;
+PASS cursor.key is sortedKeys[keyIndex]
+PASS cursor.primaryKey is sortedKeys[keyIndex]
+PASS cursor.value is 'foo'
+cursor.continue();
+Expecting exception from cursor.continue();
+PASS Exception was thrown.
+PASS code is DOMException.INVALID_STATE_ERR
+Exception message: An operation was called on an object on which it is not allowed or at a time when it is not allowed.
+PASS cursor.key is sortedKeys[keyIndex]
+PASS cursor.primaryKey is sortedKeys[keyIndex]
+PASS cursor.value is 'foo'
+keyIndex++;
+cursor = event.target.result;
+PASS cursor.key is sortedKeys[keyIndex]
+PASS cursor.primaryKey is sortedKeys[keyIndex]
+PASS cursor.value is 'foo'
+cursor.continue();
+Expecting exception from cursor.continue();
+PASS Exception was thrown.
+PASS code is DOMException.INVALID_STATE_ERR
+Exception message: An operation was called on an object on which it is not allowed or at a time when it is not allowed.
+PASS cursor.key is sortedKeys[keyIndex]
+PASS cursor.primaryKey is sortedKeys[keyIndex]
+PASS cursor.value is 'foo'
+keyIndex++;
+cursor = event.target.result;
+PASS cursor.key is sortedKeys[keyIndex]
+PASS cursor.primaryKey is sortedKeys[keyIndex]
+PASS cursor.value is 'foo'
+cursor.continue();
+Expecting exception from cursor.continue();
+PASS Exception was thrown.
+PASS code is DOMException.INVALID_STATE_ERR
+Exception message: An operation was called on an object on which it is not allowed or at a time when it is not allowed.
+PASS cursor.key is sortedKeys[keyIndex]
+PASS cursor.primaryKey is sortedKeys[keyIndex]
+PASS cursor.value is 'foo'
+keyIndex++;
+cursor = event.target.result;
+PASS cursor.key is sortedKeys[keyIndex]
+PASS cursor.primaryKey is sortedKeys[keyIndex]
+PASS cursor.value is 'foo'
+cursor.continue();
+Expecting exception from cursor.continue();
+PASS Exception was thrown.
+PASS code is DOMException.INVALID_STATE_ERR
+Exception message: An operation was called on an object on which it is not allowed or at a time when it is not allowed.
+PASS cursor.key is sortedKeys[keyIndex]
+PASS cursor.primaryKey is sortedKeys[keyIndex]
+PASS cursor.value is 'foo'
+keyIndex++;
+cursor = event.target.result;
+PASS cursor.key is sortedKeys[keyIndex]
+PASS cursor.primaryKey is sortedKeys[keyIndex]
+PASS cursor.value is 'foo'
+cursor.continue();
+Expecting exception from cursor.continue();
+PASS Exception was thrown.
+PASS code is DOMException.INVALID_STATE_ERR
+Exception message: An operation was called on an object on which it is not allowed or at a time when it is not allowed.
+PASS cursor.key is sortedKeys[keyIndex]
+PASS cursor.primaryKey is sortedKeys[keyIndex]
+PASS cursor.value is 'foo'
+keyIndex++;
+cursor = event.target.result;
+PASS cursor.key is sortedKeys[keyIndex]
+PASS cursor.primaryKey is sortedKeys[keyIndex]
+PASS cursor.value is 'foo'
+cursor.continue();
+Expecting exception from cursor.continue();
+PASS Exception was thrown.
+PASS code is DOMException.INVALID_STATE_ERR
+Exception message: An operation was called on an object on which it is not allowed or at a time when it is not allowed.
+PASS cursor.key is sortedKeys[keyIndex]
+PASS cursor.primaryKey is sortedKeys[keyIndex]
+PASS cursor.value is 'foo'
+keyIndex++;
+cursor = event.target.result;
+PASS cursor.key is sortedKeys[keyIndex]
+PASS cursor.primaryKey is sortedKeys[keyIndex]
+PASS cursor.value is 'foo'
+cursor.continue();
+Expecting exception from cursor.continue();
+PASS Exception was thrown.
+PASS code is DOMException.INVALID_STATE_ERR
+Exception message: An operation was called on an object on which it is not allowed or at a time when it is not allowed.
+PASS cursor.key is sortedKeys[keyIndex]
+PASS cursor.primaryKey is sortedKeys[keyIndex]
+PASS cursor.value is 'foo'
+keyIndex++;
+cursor = event.target.result;
+PASS cursor.key is sortedKeys[keyIndex]
+PASS cursor.primaryKey is sortedKeys[keyIndex]
+PASS cursor.value is 'foo'
+cursor.continue();
+Expecting exception from cursor.continue();
+PASS Exception was thrown.
+PASS code is DOMException.INVALID_STATE_ERR
+Exception message: An operation was called on an object on which it is not allowed or at a time when it is not allowed.
+PASS cursor.key is sortedKeys[keyIndex]
+PASS cursor.primaryKey is sortedKeys[keyIndex]
+PASS cursor.value is 'foo'
+keyIndex++;
+cursor = event.target.result;
+PASS keyIndex is keys.length
+keyIndex = 4;
+range = IDBKeyRange.bound(2000, 'q');
+request = objectStore.openCursor(range);
+cursor = event.target.result;
+PASS cursor.key is sortedKeys[keyIndex]
+PASS cursor.primaryKey is sortedKeys[keyIndex]
+PASS cursor.value is 'foo'
+cursor.continue();
+PASS cursor.key is sortedKeys[keyIndex]
+PASS cursor.primaryKey is sortedKeys[keyIndex]
+PASS cursor.value is 'foo'
+keyIndex++;
+cursor = event.target.result;
+PASS cursor.key is sortedKeys[keyIndex]
+PASS cursor.primaryKey is sortedKeys[keyIndex]
+PASS cursor.value is 'foo'
+cursor.continue();
+PASS cursor.key is sortedKeys[keyIndex]
+PASS cursor.primaryKey is sortedKeys[keyIndex]
+PASS cursor.value is 'foo'
+keyIndex++;
+cursor = event.target.result;
+PASS cursor.key is sortedKeys[keyIndex]
+PASS cursor.primaryKey is sortedKeys[keyIndex]
+PASS cursor.value is 'foo'
+cursor.continue();
+PASS cursor.key is sortedKeys[keyIndex]
+PASS cursor.primaryKey is sortedKeys[keyIndex]
+PASS cursor.value is 'foo'
+keyIndex++;
+cursor = event.target.result;
+PASS cursor.key is sortedKeys[keyIndex]
+PASS cursor.primaryKey is sortedKeys[keyIndex]
+PASS cursor.value is 'foo'
+cursor.continue();
+PASS cursor.key is sortedKeys[keyIndex]
+PASS cursor.primaryKey is sortedKeys[keyIndex]
+PASS cursor.value is 'foo'
+keyIndex++;
+cursor = event.target.result;
+PASS keyIndex is 8
+request = objectStore.openCursor();
+cursor = event.target.result;
+PASS cursor.key is sortedKeys[keyIndex]
+PASS cursor.primaryKey is sortedKeys[keyIndex]
+PASS cursor.value is 'foo'
+cursor.continue('b');
+PASS cursor.key is sortedKeys[keyIndex]
+PASS cursor.primaryKey is sortedKeys[keyIndex]
+PASS cursor.value is 'foo'
+keyIndex += keyIndex ? 1: 6;
+cursor = event.target.result;
+PASS cursor.key is sortedKeys[keyIndex]
+PASS cursor.primaryKey is sortedKeys[keyIndex]
+PASS cursor.value is 'foo'
+cursor.continue();
+PASS cursor.key is sortedKeys[keyIndex]
+PASS cursor.primaryKey is sortedKeys[keyIndex]
+PASS cursor.value is 'foo'
+keyIndex += keyIndex ? 1: 6;
+cursor = event.target.result;
+PASS cursor.key is sortedKeys[keyIndex]
+PASS cursor.primaryKey is sortedKeys[keyIndex]
+PASS cursor.value is 'foo'
+cursor.continue();
+PASS cursor.key is sortedKeys[keyIndex]
+PASS cursor.primaryKey is sortedKeys[keyIndex]
+PASS cursor.value is 'foo'
+keyIndex += keyIndex ? 1: 6;
+cursor = event.target.result;
+PASS cursor.key is sortedKeys[keyIndex]
+PASS cursor.primaryKey is sortedKeys[keyIndex]
+PASS cursor.value is 'foo'
+cursor.continue();
+PASS cursor.key is sortedKeys[keyIndex]
+PASS cursor.primaryKey is sortedKeys[keyIndex]
+PASS cursor.value is 'foo'
+keyIndex += keyIndex ? 1: 6;
+cursor = event.target.result;
+PASS cursor.key is sortedKeys[keyIndex]
+PASS cursor.primaryKey is sortedKeys[keyIndex]
+PASS cursor.value is 'foo'
+cursor.continue();
+PASS cursor.key is sortedKeys[keyIndex]
+PASS cursor.primaryKey is sortedKeys[keyIndex]
+PASS cursor.value is 'foo'
+keyIndex += keyIndex ? 1: 6;
+cursor = event.target.result;
+PASS keyIndex is keys.length
+keyIndex = 0;
+request = objectStore.openCursor();
+cursor = event.target.result;
+PASS cursor.key is sortedKeys[keyIndex]
+PASS cursor.primaryKey is sortedKeys[keyIndex]
+PASS cursor.value is 'foo'
+cursor.continue(10);
+PASS cursor.key is sortedKeys[keyIndex]
+PASS cursor.primaryKey is sortedKeys[keyIndex]
+PASS cursor.value is 'foo'
+keyIndex += keyIndex ? 1: 3;
+cursor = event.target.result;
+PASS cursor.key is sortedKeys[keyIndex]
+PASS cursor.primaryKey is sortedKeys[keyIndex]
+PASS cursor.value is 'foo'
+cursor.continue();
+PASS cursor.key is sortedKeys[keyIndex]
+PASS cursor.primaryKey is sortedKeys[keyIndex]
+PASS cursor.value is 'foo'
+keyIndex += keyIndex ? 1: 3;
+cursor = event.target.result;
+PASS cursor.key is sortedKeys[keyIndex]
+PASS cursor.primaryKey is sortedKeys[keyIndex]
+PASS cursor.value is 'foo'
+cursor.continue();
+PASS cursor.key is sortedKeys[keyIndex]
+PASS cursor.primaryKey is sortedKeys[keyIndex]
+PASS cursor.value is 'foo'
+keyIndex += keyIndex ? 1: 3;
+cursor = event.target.result;
+PASS cursor.key is sortedKeys[keyIndex]
+PASS cursor.primaryKey is sortedKeys[keyIndex]
+PASS cursor.value is 'foo'
+cursor.continue();
+PASS cursor.key is sortedKeys[keyIndex]
+PASS cursor.primaryKey is sortedKeys[keyIndex]
+PASS cursor.value is 'foo'
+keyIndex += keyIndex ? 1: 3;
+cursor = event.target.result;
+PASS cursor.key is sortedKeys[keyIndex]
+PASS cursor.primaryKey is sortedKeys[keyIndex]
+PASS cursor.value is 'foo'
+cursor.continue();
+PASS cursor.key is sortedKeys[keyIndex]
+PASS cursor.primaryKey is sortedKeys[keyIndex]
+PASS cursor.value is 'foo'
+keyIndex += keyIndex ? 1: 3;
+cursor = event.target.result;
+PASS cursor.key is sortedKeys[keyIndex]
+PASS cursor.primaryKey is sortedKeys[keyIndex]
+PASS cursor.value is 'foo'
+cursor.continue();
+PASS cursor.key is sortedKeys[keyIndex]
+PASS cursor.primaryKey is sortedKeys[keyIndex]
+PASS cursor.value is 'foo'
+keyIndex += keyIndex ? 1: 3;
+cursor = event.target.result;
+PASS cursor.key is sortedKeys[keyIndex]
+PASS cursor.primaryKey is sortedKeys[keyIndex]
+PASS cursor.value is 'foo'
+cursor.continue();
+PASS cursor.key is sortedKeys[keyIndex]
+PASS cursor.primaryKey is sortedKeys[keyIndex]
+PASS cursor.value is 'foo'
+keyIndex += keyIndex ? 1: 3;
+cursor = event.target.result;
+PASS cursor.key is sortedKeys[keyIndex]
+PASS cursor.primaryKey is sortedKeys[keyIndex]
+PASS cursor.value is 'foo'
+cursor.continue();
+PASS cursor.key is sortedKeys[keyIndex]
+PASS cursor.primaryKey is sortedKeys[keyIndex]
+PASS cursor.value is 'foo'
+keyIndex += keyIndex ? 1: 3;
+cursor = event.target.result;
+PASS keyIndex is keys.length
+keyIndex = 0;
+request = objectStore.openCursor();
+cursor = event.target.result;
+PASS cursor.key is sortedKeys[keyIndex]
+PASS cursor.primaryKey is sortedKeys[keyIndex]
+PASS cursor.value is 'foo'
+cursor.continue('c');
+PASS cursor.key is sortedKeys[keyIndex]
+PASS cursor.primaryKey is sortedKeys[keyIndex]
+PASS cursor.value is 'foo'
+keyIndex += keyIndex ? 1 : 7;
+cursor = event.target.result;
+PASS cursor.key is sortedKeys[keyIndex]
+PASS cursor.primaryKey is sortedKeys[keyIndex]
+PASS cursor.value is 'foo'
+cursor.continue();
+PASS cursor.key is sortedKeys[keyIndex]
+PASS cursor.primaryKey is sortedKeys[keyIndex]
+PASS cursor.value is 'foo'
+keyIndex += keyIndex ? 1 : 7;
+cursor = event.target.result;
+PASS cursor.key is sortedKeys[keyIndex]
+PASS cursor.primaryKey is sortedKeys[keyIndex]
+PASS cursor.value is 'foo'
+cursor.continue();
+PASS cursor.key is sortedKeys[keyIndex]
+PASS cursor.primaryKey is sortedKeys[keyIndex]
+PASS cursor.value is 'foo'
+keyIndex += keyIndex ? 1 : 7;
+cursor = event.target.result;
+PASS cursor.key is sortedKeys[keyIndex]
+PASS cursor.primaryKey is sortedKeys[keyIndex]
+PASS cursor.value is 'foo'
+cursor.continue();
+PASS cursor.key is sortedKeys[keyIndex]
+PASS cursor.primaryKey is sortedKeys[keyIndex]
+PASS cursor.value is 'foo'
+keyIndex += keyIndex ? 1 : 7;
+cursor = event.target.result;
+PASS keyIndex is keys.length
+keyIndex = 0;
+request = objectStore.openCursor();
+cursor = event.target.result;
+PASS cursor.key is sortedKeys[keyIndex]
+PASS cursor.primaryKey is sortedKeys[keyIndex]
+PASS cursor.value is 'foo'
+keyIndex++;
+cursor.continue();
+cursor = event.target.result;
+PASS cursor.key is sortedKeys[keyIndex]
+PASS cursor.primaryKey is sortedKeys[keyIndex]
+PASS cursor.value is 'foo'
+keyIndex++;
+cursor.continue();
+cursor = event.target.result;
+PASS cursor.key is sortedKeys[keyIndex]
+PASS cursor.primaryKey is sortedKeys[keyIndex]
+PASS cursor.value is 'foo'
+keyIndex++;
+cursor.continue();
+cursor = event.target.result;
+PASS cursor.key is sortedKeys[keyIndex]
+PASS cursor.primaryKey is sortedKeys[keyIndex]
+PASS cursor.value is 'foo'
+keyIndex++;
+cursor.continue();
+cursor = event.target.result;
+PASS cursor.key is sortedKeys[keyIndex]
+PASS cursor.primaryKey is sortedKeys[keyIndex]
+PASS cursor.value is 'foo'
+request = cursor.update('bar');
+keyIndex++;
+cursor.continue();
+cursor = event.target.result;
+PASS cursor.key is sortedKeys[keyIndex]
+PASS cursor.primaryKey is sortedKeys[keyIndex]
+PASS cursor.value is 'foo'
+keyIndex++;
+cursor.continue();
+cursor = event.target.result;
+PASS cursor.key is sortedKeys[keyIndex]
+PASS cursor.primaryKey is sortedKeys[keyIndex]
+PASS cursor.value is 'foo'
+keyIndex++;
+cursor.continue();
+cursor = event.target.result;
+PASS cursor.key is sortedKeys[keyIndex]
+PASS cursor.primaryKey is sortedKeys[keyIndex]
+PASS cursor.value is 'foo'
+keyIndex++;
+cursor.continue();
+cursor = event.target.result;
+PASS cursor.key is sortedKeys[keyIndex]
+PASS cursor.primaryKey is sortedKeys[keyIndex]
+PASS cursor.value is 'foo'
+keyIndex++;
+cursor.continue();
+cursor = event.target.result;
+PASS cursor.key is sortedKeys[keyIndex]
+PASS cursor.primaryKey is sortedKeys[keyIndex]
+PASS cursor.value is 'foo'
+keyIndex++;
+cursor.continue();
+cursor = event.target.result;
+PASS keyIndex is keys.length
+request = objectStore.get(sortedKeys[4]);
+PASS event.target.result is 'bar'
+request = objectStore.put('foo', sortedKeys[4]);
+keyIndex = 0;
+request = objectStore.openCursor(null, 'next');
+cursor = event.target.result;
+PASS cursor.key is sortedKeys[keyIndex]
+PASS cursor.primaryKey is sortedKeys[keyIndex]
+PASS cursor.value is 'foo'
+keyIndex++;
+cursor.continue();
+cursor = event.target.result;
+PASS cursor.key is sortedKeys[keyIndex]
+PASS cursor.primaryKey is sortedKeys[keyIndex]
+PASS cursor.value is 'foo'
+keyIndex++;
+cursor.continue();
+cursor = event.target.result;
+PASS cursor.key is sortedKeys[keyIndex]
+PASS cursor.primaryKey is sortedKeys[keyIndex]
+PASS cursor.value is 'foo'
+keyIndex++;
+cursor.continue();
+cursor = event.target.result;
+PASS cursor.key is sortedKeys[keyIndex]
+PASS cursor.primaryKey is sortedKeys[keyIndex]
+PASS cursor.value is 'foo'
+keyIndex++;
+cursor.continue();
+cursor = event.target.result;
+PASS cursor.key is sortedKeys[keyIndex]
+PASS cursor.primaryKey is sortedKeys[keyIndex]
+PASS cursor.value is 'foo'
+request = cursor.delete();
+keyIndex++;
+cursor.continue();
+PASS keyIndex is 5
+gotRemoveEvent = true;
+cursor = event.target.result;
+PASS cursor.key is sortedKeys[keyIndex]
+PASS cursor.primaryKey is sortedKeys[keyIndex]
+PASS cursor.value is 'foo'
+keyIndex++;
+cursor.continue();
+cursor = event.target.result;
+PASS cursor.key is sortedKeys[keyIndex]
+PASS cursor.primaryKey is sortedKeys[keyIndex]
+PASS cursor.value is 'foo'
+keyIndex++;
+cursor.continue();
+cursor = event.target.result;
+PASS cursor.key is sortedKeys[keyIndex]
+PASS cursor.primaryKey is sortedKeys[keyIndex]
+PASS cursor.value is 'foo'
+keyIndex++;
+cursor.continue();
+cursor = event.target.result;
+PASS cursor.key is sortedKeys[keyIndex]
+PASS cursor.primaryKey is sortedKeys[keyIndex]
+PASS cursor.value is 'foo'
+keyIndex++;
+cursor.continue();
+cursor = event.target.result;
+PASS cursor.key is sortedKeys[keyIndex]
+PASS cursor.primaryKey is sortedKeys[keyIndex]
+PASS cursor.value is 'foo'
+keyIndex++;
+cursor.continue();
+cursor = event.target.result;
+PASS keyIndex is keys.length
+PASS gotRemoveEvent is true
+request = objectStore.get(sortedKeys[4]);
+PASS event.target.result is undefined
+request = objectStore.add('foo', sortedKeys[4]);
+request = objectStore.openCursor(null, 'prev');
+cursor = event.target.result;
+PASS cursor.key is sortedKeys[keyIndex]
+PASS cursor.primaryKey is sortedKeys[keyIndex]
+PASS cursor.value is 'foo'
+cursor.continue();
+PASS cursor.key is sortedKeys[keyIndex]
+PASS cursor.primaryKey is sortedKeys[keyIndex]
+PASS cursor.value is 'foo'
+keyIndex--;
+cursor = event.target.result;
+PASS cursor.key is sortedKeys[keyIndex]
+PASS cursor.primaryKey is sortedKeys[keyIndex]
+PASS cursor.value is 'foo'
+cursor.continue();
+PASS cursor.key is sortedKeys[keyIndex]
+PASS cursor.primaryKey is sortedKeys[keyIndex]
+PASS cursor.value is 'foo'
+keyIndex--;
+cursor = event.target.result;
+PASS cursor.key is sortedKeys[keyIndex]
+PASS cursor.primaryKey is sortedKeys[keyIndex]
+PASS cursor.value is 'foo'
+cursor.continue();
+PASS cursor.key is sortedKeys[keyIndex]
+PASS cursor.primaryKey is sortedKeys[keyIndex]
+PASS cursor.value is 'foo'
+keyIndex--;
+cursor = event.target.result;
+PASS cursor.key is sortedKeys[keyIndex]
+PASS cursor.primaryKey is sortedKeys[keyIndex]
+PASS cursor.value is 'foo'
+cursor.continue();
+PASS cursor.key is sortedKeys[keyIndex]
+PASS cursor.primaryKey is sortedKeys[keyIndex]
+PASS cursor.value is 'foo'
+keyIndex--;
+cursor = event.target.result;
+PASS cursor.key is sortedKeys[keyIndex]
+PASS cursor.primaryKey is sortedKeys[keyIndex]
+PASS cursor.value is 'foo'
+cursor.continue();
+PASS cursor.key is sortedKeys[keyIndex]
+PASS cursor.primaryKey is sortedKeys[keyIndex]
+PASS cursor.value is 'foo'
+keyIndex--;
+cursor = event.target.result;
+PASS cursor.key is sortedKeys[keyIndex]
+PASS cursor.primaryKey is sortedKeys[keyIndex]
+PASS cursor.value is 'foo'
+cursor.continue();
+PASS cursor.key is sortedKeys[keyIndex]
+PASS cursor.primaryKey is sortedKeys[keyIndex]
+PASS cursor.value is 'foo'
+keyIndex--;
+cursor = event.target.result;
+PASS cursor.key is sortedKeys[keyIndex]
+PASS cursor.primaryKey is sortedKeys[keyIndex]
+PASS cursor.value is 'foo'
+cursor.continue();
+PASS cursor.key is sortedKeys[keyIndex]
+PASS cursor.primaryKey is sortedKeys[keyIndex]
+PASS cursor.value is 'foo'
+keyIndex--;
+cursor = event.target.result;
+PASS cursor.key is sortedKeys[keyIndex]
+PASS cursor.primaryKey is sortedKeys[keyIndex]
+PASS cursor.value is 'foo'
+cursor.continue();
+PASS cursor.key is sortedKeys[keyIndex]
+PASS cursor.primaryKey is sortedKeys[keyIndex]
+PASS cursor.value is 'foo'
+keyIndex--;
+cursor = event.target.result;
+PASS cursor.key is sortedKeys[keyIndex]
+PASS cursor.primaryKey is sortedKeys[keyIndex]
+PASS cursor.value is 'foo'
+cursor.continue();
+PASS cursor.key is sortedKeys[keyIndex]
+PASS cursor.primaryKey is sortedKeys[keyIndex]
+PASS cursor.value is 'foo'
+keyIndex--;
+cursor = event.target.result;
+PASS cursor.key is sortedKeys[keyIndex]
+PASS cursor.primaryKey is sortedKeys[keyIndex]
+PASS cursor.value is 'foo'
+cursor.continue();
+PASS cursor.key is sortedKeys[keyIndex]
+PASS cursor.primaryKey is sortedKeys[keyIndex]
+PASS cursor.value is 'foo'
+keyIndex--;
+cursor = event.target.result;
+PASS keyIndex is -1
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
diff --git a/LayoutTests/platform/wk2/storage/indexeddb/mozilla/key-requirements-delete-null-key-expected.txt b/LayoutTests/platform/wk2/storage/indexeddb/mozilla/key-requirements-delete-null-key-expected.txt
new file mode 100644 (file)
index 0000000..56f891e
--- /dev/null
@@ -0,0 +1,20 @@
+Test IndexedDB's behavior deleting entry with no key
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+indexedDB = self.indexedDB || self.webkitIndexedDB || self.mozIndexedDB || self.msIndexedDB || self.OIndexedDB;
+
+dbname = "key-requirements-delete-null-key.html"
+indexedDB.deleteDatabase(dbname)
+indexedDB.open(dbname)
+objectStore = db.createObjectStore('bar');
+Expecting exception from objectStore.delete(null);
+PASS Exception was thrown.
+PASS code is 0
+PASS ename is 'DataError'
+Exception message: The data provided does not meet requirements.
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
diff --git a/LayoutTests/platform/wk2/storage/indexeddb/mozilla/readonly-transactions-expected.txt b/LayoutTests/platform/wk2/storage/indexeddb/mozilla/readonly-transactions-expected.txt
new file mode 100644 (file)
index 0000000..3ac3d4d
--- /dev/null
@@ -0,0 +1,57 @@
+Test IndexedDB's readonly transactions
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+indexedDB = self.indexedDB || self.webkitIndexedDB || self.mozIndexedDB || self.msIndexedDB || self.OIndexedDB;
+
+dbname = "readonly-transactions.html"
+indexedDB.deleteDatabase(dbname)
+indexedDB.open(dbname)
+objectStore = db.createObjectStore(osName, { autoIncrement: true });
+Expecting exception from db.transaction([osName]).objectStore(osName).add({});
+PASS Exception was thrown.
+PASS code is 0
+PASS ename is 'ReadOnlyError'
+Exception message: A write operation was attempted in a read-only transaction.
+Expecting exception from db.transaction(osName).objectStore(osName).add({});
+PASS Exception was thrown.
+PASS code is 0
+PASS ename is 'ReadOnlyError'
+Exception message: A write operation was attempted in a read-only transaction.
+key1 = 1;
+key2 = 2;
+Expecting exception from db.transaction([osName]).objectStore(osName).put({}, key1);
+PASS Exception was thrown.
+PASS code is 0
+PASS ename is 'ReadOnlyError'
+Exception message: A write operation was attempted in a read-only transaction.
+Expecting exception from db.transaction(osName).objectStore(osName).put({}, key2);
+PASS Exception was thrown.
+PASS code is 0
+PASS ename is 'ReadOnlyError'
+Exception message: A write operation was attempted in a read-only transaction.
+Expecting exception from db.transaction([osName]).objectStore(osName).put({}, key1);
+PASS Exception was thrown.
+PASS code is 0
+PASS ename is 'ReadOnlyError'
+Exception message: A write operation was attempted in a read-only transaction.
+Expecting exception from db.transaction(osName).objectStore(osName).put({}, key1);
+PASS Exception was thrown.
+PASS code is 0
+PASS ename is 'ReadOnlyError'
+Exception message: A write operation was attempted in a read-only transaction.
+Expecting exception from db.transaction([osName]).objectStore(osName).delete(key1);
+PASS Exception was thrown.
+PASS code is 0
+PASS ename is 'ReadOnlyError'
+Exception message: A write operation was attempted in a read-only transaction.
+Expecting exception from db.transaction(osName).objectStore(osName).delete(key2);
+PASS Exception was thrown.
+PASS code is 0
+PASS ename is 'ReadOnlyError'
+Exception message: A write operation was attempted in a read-only transaction.
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
diff --git a/LayoutTests/platform/wk2/storage/indexeddb/object-lookups-in-versionchange-expected.txt b/LayoutTests/platform/wk2/storage/indexeddb/object-lookups-in-versionchange-expected.txt
new file mode 100644 (file)
index 0000000..919a0c5
--- /dev/null
@@ -0,0 +1,29 @@
+Regression test for http://webkit.org/b/102547
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+indexedDB = self.indexedDB || self.webkitIndexedDB || self.mozIndexedDB || self.msIndexedDB || self.OIndexedDB;
+
+dbname = "object-lookups-in-versionchange.html"
+indexedDB.deleteDatabase(dbname)
+indexedDB.open(dbname)
+db = event.target.result
+transaction = event.target.transaction
+store = db.createObjectStore('store')
+
+Expecting exception from transaction.objectStore('no-such-store')
+PASS Exception was thrown.
+PASS code is DOMException.NOT_FOUND_ERR
+PASS ename is 'NotFoundError'
+Exception message: An operation failed because the requested database object could not be found.
+
+Expecting exception from store.index('no-such-index')
+PASS Exception was thrown.
+PASS code is DOMException.NOT_FOUND_ERR
+PASS ename is 'NotFoundError'
+Exception message: An operation failed because the requested database object could not be found.
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
diff --git a/LayoutTests/platform/wk2/storage/indexeddb/objectstore-count-expected.txt b/LayoutTests/platform/wk2/storage/indexeddb/objectstore-count-expected.txt
new file mode 100644 (file)
index 0000000..677653e
--- /dev/null
@@ -0,0 +1,112 @@
+Test IndexedDB's IDBObjectStore.count().
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+indexedDB = self.indexedDB || self.webkitIndexedDB || self.mozIndexedDB || self.msIndexedDB || self.OIndexedDB;
+
+dbname = "objectstore-count.html"
+indexedDB.deleteDatabase(dbname)
+indexedDB.open(dbname)
+store = db.createObjectStore('storeName', null)
+adding 0 ... 99
+
+verifying count without range
+trans = db.transaction('storeName', 'readonly')
+PASS trans is non-null.
+store = trans.objectStore('storeName')
+PASS store is non-null.
+request = store.count()
+PASS typeof request.result is "number"
+PASS request.result is 100
+
+verifying count with range
+trans = db.transaction('storeName', 'readonly')
+PASS trans is non-null.
+store = trans.objectStore('storeName')
+PASS store is non-null.
+
+test = {"lower":0,"lowerOpen":false,"upper":99,"upperOpen":false,"expected":100}
+request = store.count(IDBKeyRange.bound(test.lower, test.upper, test.lowerOpen, test.upperOpen))
+PASS typeof request.result is "number"
+PASS request.result is 100
+
+test = {"lower":0,"lowerOpen":true,"upper":99,"upperOpen":false,"expected":99}
+request = store.count(IDBKeyRange.bound(test.lower, test.upper, test.lowerOpen, test.upperOpen))
+PASS typeof request.result is "number"
+PASS request.result is 99
+
+test = {"lower":0,"lowerOpen":false,"upper":99,"upperOpen":true,"expected":99}
+request = store.count(IDBKeyRange.bound(test.lower, test.upper, test.lowerOpen, test.upperOpen))
+PASS typeof request.result is "number"
+PASS request.result is 99
+
+test = {"lower":0,"lowerOpen":true,"upper":99,"upperOpen":true,"expected":98}
+request = store.count(IDBKeyRange.bound(test.lower, test.upper, test.lowerOpen, test.upperOpen))
+PASS typeof request.result is "number"
+PASS request.result is 98
+
+test = {"lower":0,"lowerOpen":false,"upper":100,"upperOpen":false,"expected":100}
+request = store.count(IDBKeyRange.bound(test.lower, test.upper, test.lowerOpen, test.upperOpen))
+PASS typeof request.result is "number"
+PASS request.result is 100
+
+test = {"lower":0,"lowerOpen":false,"upper":100,"upperOpen":false,"expected":100}
+request = store.count(IDBKeyRange.bound(test.lower, test.upper, test.lowerOpen, test.upperOpen))
+PASS typeof request.result is "number"
+PASS request.result is 100
+
+test = {"lower":10,"lowerOpen":false,"upper":100,"upperOpen":false,"expected":90}
+request = store.count(IDBKeyRange.bound(test.lower, test.upper, test.lowerOpen, test.upperOpen))
+PASS typeof request.result is "number"
+PASS request.result is 90
+
+test = {"lower":0,"lowerOpen":false,"upper":0,"upperOpen":false,"expected":1}
+request = store.count(IDBKeyRange.bound(test.lower, test.upper, test.lowerOpen, test.upperOpen))
+PASS typeof request.result is "number"
+PASS request.result is 1
+
+test = {"lower":500,"lowerOpen":false,"upper":500,"upperOpen":false,"expected":0}
+request = store.count(IDBKeyRange.bound(test.lower, test.upper, test.lowerOpen, test.upperOpen))
+PASS typeof request.result is "number"
+PASS request.result is 0
+
+verifying count with key
+trans = db.transaction('storeName', 'readonly')
+PASS trans is non-null.
+store = trans.objectStore('storeName')
+PASS store is non-null.
+Expecting exception from store.count(NaN)
+PASS Exception was thrown.
+PASS code is 0
+PASS ename is 'DataError'
+Exception message: The data provided does not meet requirements.
+Expecting exception from store.count({})
+PASS Exception was thrown.
+PASS code is 0
+PASS ename is 'DataError'
+Exception message: The data provided does not meet requirements.
+Expecting exception from store.count(/regex/)
+PASS Exception was thrown.
+PASS code is 0
+PASS ename is 'DataError'
+Exception message: The data provided does not meet requirements.
+
+test = {"key":0,"expected":1}
+request = store.count(test.key)
+PASS typeof request.result is "number"
+PASS request.result is 1
+
+test = {"key":100,"expected":0}
+request = store.count(test.key)
+PASS typeof request.result is "number"
+PASS request.result is 0
+
+test = {"key":null,"expected":100}
+request = store.count(test.key)
+PASS typeof request.result is "number"
+PASS request.result is 100
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
diff --git a/LayoutTests/platform/wk2/storage/indexeddb/open-cursor-expected.txt b/LayoutTests/platform/wk2/storage/indexeddb/open-cursor-expected.txt
new file mode 100644 (file)
index 0000000..5ae6551
--- /dev/null
@@ -0,0 +1,52 @@
+Test IndexedDB's openCursor.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+indexedDB = self.indexedDB || self.webkitIndexedDB || self.mozIndexedDB || self.msIndexedDB || self.OIndexedDB;
+
+dbname = "open-cursor.html"
+indexedDB.deleteDatabase(dbname)
+indexedDB.open(dbname)
+objectStore = db.createObjectStore('test')
+objectStore.add('myValue', 'myKey')
+Opening cursor
+event.target.source.openCursor(keyRange)
+Cursor opened successfully.
+PASS cursor.direction is "next"
+PASS cursor.key is "myKey"
+PASS cursor.value is "myValue"
+
+Passing an invalid key into .continue({}).
+Expecting exception from event.target.result.continue({})
+PASS Exception was thrown.
+PASS code is 0
+PASS ename is 'DataError'
+Exception message: The data provided does not meet requirements.
+
+Opening an empty cursor.
+objectStore.openCursor(keyRange)
+Empty cursor opened successfully.
+PASS cursor is null
+Opening cursor
+event.target.source.openCursor("myKey")
+Cursor opened successfully.
+PASS cursor.direction is "next"
+PASS cursor.key is "myKey"
+PASS cursor.value is "myValue"
+
+Passing an invalid key into .continue({}).
+Expecting exception from cursor.continue({})
+PASS Exception was thrown.
+PASS code is 0
+PASS ename is 'DataError'
+Exception message: The data provided does not meet requirements.
+
+Opening an empty cursor.
+objectStore.openCursor("InexistentKey")
+Empty cursor opened successfully.
+PASS cursor is null
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
diff --git a/LayoutTests/platform/wk2/storage/indexeddb/readonly-transactions-expected.txt b/LayoutTests/platform/wk2/storage/indexeddb/readonly-transactions-expected.txt
new file mode 100644 (file)
index 0000000..3ac3d4d
--- /dev/null
@@ -0,0 +1,57 @@
+Test IndexedDB's readonly transactions
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+indexedDB = self.indexedDB || self.webkitIndexedDB || self.mozIndexedDB || self.msIndexedDB || self.OIndexedDB;
+
+dbname = "readonly-transactions.html"
+indexedDB.deleteDatabase(dbname)
+indexedDB.open(dbname)
+objectStore = db.createObjectStore(osName, { autoIncrement: true });
+Expecting exception from db.transaction([osName]).objectStore(osName).add({});
+PASS Exception was thrown.
+PASS code is 0
+PASS ename is 'ReadOnlyError'
+Exception message: A write operation was attempted in a read-only transaction.
+Expecting exception from db.transaction(osName).objectStore(osName).add({});
+PASS Exception was thrown.
+PASS code is 0
+PASS ename is 'ReadOnlyError'
+Exception message: A write operation was attempted in a read-only transaction.
+key1 = 1;
+key2 = 2;
+Expecting exception from db.transaction([osName]).objectStore(osName).put({}, key1);
+PASS Exception was thrown.
+PASS code is 0
+PASS ename is 'ReadOnlyError'
+Exception message: A write operation was attempted in a read-only transaction.
+Expecting exception from db.transaction(osName).objectStore(osName).put({}, key2);
+PASS Exception was thrown.
+PASS code is 0
+PASS ename is 'ReadOnlyError'
+Exception message: A write operation was attempted in a read-only transaction.
+Expecting exception from db.transaction([osName]).objectStore(osName).put({}, key1);
+PASS Exception was thrown.
+PASS code is 0
+PASS ename is 'ReadOnlyError'
+Exception message: A write operation was attempted in a read-only transaction.
+Expecting exception from db.transaction(osName).objectStore(osName).put({}, key1);
+PASS Exception was thrown.
+PASS code is 0
+PASS ename is 'ReadOnlyError'
+Exception message: A write operation was attempted in a read-only transaction.
+Expecting exception from db.transaction([osName]).objectStore(osName).delete(key1);
+PASS Exception was thrown.
+PASS code is 0
+PASS ename is 'ReadOnlyError'
+Exception message: A write operation was attempted in a read-only transaction.
+Expecting exception from db.transaction(osName).objectStore(osName).delete(key2);
+PASS Exception was thrown.
+PASS code is 0
+PASS ename is 'ReadOnlyError'
+Exception message: A write operation was attempted in a read-only transaction.
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
diff --git a/LayoutTests/platform/wk2/storage/indexeddb/removed-expected.txt b/LayoutTests/platform/wk2/storage/indexeddb/removed-expected.txt
new file mode 100644 (file)
index 0000000..081b938
--- /dev/null
@@ -0,0 +1,18 @@
+Ensure that some obsolete IndexedDB features are gone.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+indexedDB = self.indexedDB || self.webkitIndexedDB || self.mozIndexedDB || self.msIndexedDB || self.OIndexedDB;
+
+dbname = "removed.html"
+PASS self.webkitIDBDatabaseError is undefined.
+PASS 'IDBDatabaseException' in self is false
+PASS 'errorCode' in indexedDB.open(dbname) is false
+PASS 'setVersion' in IDBDatabase.prototype is false
+PASS document.createEvent('IDBUpgradeNeededEvent') threw exception Error: NotSupportedError: DOM Exception 9.
+PASS 'version' in document.createEvent('IDBVersionChangeEvent') is false
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
diff --git a/LayoutTests/platform/wk2/storage/indexeddb/request-result-cache-expected.txt b/LayoutTests/platform/wk2/storage/indexeddb/request-result-cache-expected.txt
new file mode 100644 (file)
index 0000000..e351975
--- /dev/null
@@ -0,0 +1,35 @@
+Verify that a request's result is dirtied when a cursor is continued
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+indexedDB = self.indexedDB || self.webkitIndexedDB || self.mozIndexedDB || self.msIndexedDB || self.OIndexedDB;
+
+dbname = "request-result-cache.html"
+indexedDB.deleteDatabase(dbname)
+indexedDB.open(dbname)
+
+prepareDatabase():
+db = event.target.result
+store = db.createObjectStore('store')
+
+onOpen():
+db = event.target.result
+tx = db.transaction('store')
+store = tx.objectStore('store')
+cursorRequest = store.openCursor()
+
+cursorRequestSuccess():
+cursor = cursorRequest.result
+cursor.continue()
+Expecting exception from cursorRequest.result
+PASS Exception was thrown.
+PASS code is DOMException.INVALID_STATE_ERR
+PASS ename is 'InvalidStateError'
+Exception message: An operation was called on an object on which it is not allowed or at a time when it is not allowed.
+
+cursorRequestSuccess():
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
diff --git a/LayoutTests/platform/wk2/storage/indexeddb/transaction-abort-expected.txt b/LayoutTests/platform/wk2/storage/indexeddb/transaction-abort-expected.txt
new file mode 100644 (file)
index 0000000..b23ea8d
--- /dev/null
@@ -0,0 +1,51 @@
+Test transaction aborts send the proper onabort messages..
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+indexedDB = self.indexedDB || self.webkitIndexedDB || self.mozIndexedDB || self.msIndexedDB || self.OIndexedDB;
+
+dbname = "transaction-abort.html"
+indexedDB.deleteDatabase(dbname)
+indexedDB.open(dbname)
+store = db.createObjectStore('storeName', null)
+store.add({x: 'value', y: 'zzz'}, 'key')
+trans = db.transaction(['storeName'], 'readwrite')
+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.error.name is 'AbortError'
+PASS trans.error is null
+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 0
+PASS ename is 'TransactionInactiveError'
+Exception message: A request was placed against a transaction which is either currently not active, or which is finished.
+PASS event.target.error.name is 'AbortError'
+PASS trans.error is null
+PASS firstError is true
+PASS secondError is false
+PASS abortFired is false
+PASS firstError is true
+PASS secondError is true
+PASS abortFired is false
+PASS trans.error is null
+Expecting exception from store.add({x: 'value5', y: 'zzz5'}, 'key5')
+PASS Exception was thrown.
+PASS code is 0
+PASS ename is 'TransactionInactiveError'
+Exception message: A request was placed against a transaction which is either currently not active, or which is finished.
+Expecting exception from trans.abort()
+PASS Exception was thrown.
+PASS code is DOMException.INVALID_STATE_ERR
+PASS ename is 'InvalidStateError'
+Exception message: An operation was called on an object on which it is not allowed or at a time when it is not allowed.
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
diff --git a/LayoutTests/platform/wk2/storage/indexeddb/transaction-active-flag-expected.txt b/LayoutTests/platform/wk2/storage/indexeddb/transaction-active-flag-expected.txt
new file mode 100644 (file)
index 0000000..7962546
--- /dev/null
@@ -0,0 +1,266 @@
+Test IndexedDB transaction internal active flag.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+indexedDB = self.indexedDB || self.webkitIndexedDB || self.mozIndexedDB || self.msIndexedDB || self.OIndexedDB;
+
+dbname = "transaction-active-flag.html"
+indexedDB.deleteDatabase(dbname)
+indexedDB.open(dbname)
+store = db.createObjectStore('store')
+store.createIndex('index', 'keypath')
+
+runTransaction():
+transaction = db.transaction('store', 'readwrite')
+
+Verify that transactions are created with |active| flag set:
+store = transaction.objectStore('store')
+index = store.index('index')
+PASS store.add(0, 0) did not throw exception.
+PASS store.put(0, 0) did not throw exception.
+PASS store.get(0) did not throw exception.
+PASS store.get(IDBKeyRange.only(0)) did not throw exception.
+PASS store.delete(0) did not throw exception.
+PASS store.delete(IDBKeyRange.only(0)) did not throw exception.
+PASS store.count() did not throw exception.
+PASS store.count(0) did not throw exception.
+PASS store.count(IDBKeyRange.only(0)) did not throw exception.
+PASS store.clear() did not throw exception.
+PASS store.openCursor() did not throw exception.
+PASS store.openCursor(0) did not throw exception.
+PASS store.openCursor(0, 'next') did not throw exception.
+PASS store.openCursor(IDBKeyRange.only(0)) did not throw exception.
+PASS store.openCursor(IDBKeyRange.only(0), 'next') did not throw exception.
+PASS index.get(0) did not throw exception.
+PASS index.get(IDBKeyRange.only(0)) did not throw exception.
+PASS index.getKey(0) did not throw exception.
+PASS index.getKey(IDBKeyRange.only(0)) did not throw exception.
+PASS index.count() did not throw exception.
+PASS index.count(0) did not throw exception.
+PASS index.count(IDBKeyRange.only(0)) did not throw exception.
+PASS index.openCursor() did not throw exception.
+PASS index.openCursor(0) did not throw exception.
+PASS index.openCursor(0, 'next') did not throw exception.
+PASS index.openCursor(IDBKeyRange.only(0)) did not throw exception.
+PASS index.openCursor(IDBKeyRange.only(0), 'next') did not throw exception.
+PASS index.openKeyCursor() did not throw exception.
+PASS index.openKeyCursor(0) did not throw exception.
+PASS index.openKeyCursor(0, 'next') did not throw exception.
+PASS index.openKeyCursor(IDBKeyRange.only(0)) did not throw exception.
+PASS index.openKeyCursor(IDBKeyRange.only(0), 'next') did not throw exception.
+
+Transaction shouldn't be active inside a non-IDB-event callback
+setTimeout(testTimeout, 0)
+
+testTimeout():
+store = transaction.objectStore('store')
+index = store.index('index')
+Expecting exception from store.add(0, 0)
+PASS Exception was thrown.
+PASS code is 0
+PASS ename is 'TransactionInactiveError'
+Exception message: A request was placed against a transaction which is either currently not active, or which is finished.
+Expecting exception from store.put(0, 0)
+PASS Exception was thrown.
+PASS code is 0
+PASS ename is 'TransactionInactiveError'
+Exception message: A request was placed against a transaction which is either currently not active, or which is finished.
+Expecting exception from store.get(0)
+PASS Exception was thrown.
+PASS code is 0
+PASS ename is 'TransactionInactiveError'
+Exception message: A request was placed against a transaction which is either currently not active, or which is finished.
+Expecting exception from store.get(IDBKeyRange.only(0))
+PASS Exception was thrown.
+PASS code is 0
+PASS ename is 'TransactionInactiveError'
+Exception message: A request was placed against a transaction which is either currently not active, or which is finished.
+Expecting exception from store.delete(0)
+PASS Exception was thrown.
+PASS code is 0
+PASS ename is 'TransactionInactiveError'
+Exception message: A request was placed against a transaction which is either currently not active, or which is finished.
+Expecting exception from store.delete(IDBKeyRange.only(0))
+PASS Exception was thrown.
+PASS code is 0
+PASS ename is 'TransactionInactiveError'
+Exception message: A request was placed against a transaction which is either currently not active, or which is finished.
+Expecting exception from store.count()
+PASS Exception was thrown.
+PASS code is 0
+PASS ename is 'TransactionInactiveError'
+Exception message: A request was placed against a transaction which is either currently not active, or which is finished.
+Expecting exception from store.count(0)
+PASS Exception was thrown.
+PASS code is 0
+PASS ename is 'TransactionInactiveError'
+Exception message: A request was placed against a transaction which is either currently not active, or which is finished.
+Expecting exception from store.count(IDBKeyRange.only(0))
+PASS Exception was thrown.
+PASS code is 0
+PASS ename is 'TransactionInactiveError'
+Exception message: A request was placed against a transaction which is either currently not active, or which is finished.
+Expecting exception from store.clear()
+PASS Exception was thrown.
+PASS code is 0
+PASS ename is 'TransactionInactiveError'
+Exception message: A request was placed against a transaction which is either currently not active, or which is finished.
+Expecting exception from store.openCursor()
+PASS Exception was thrown.
+PASS code is 0
+PASS ename is 'TransactionInactiveError'
+Exception message: A request was placed against a transaction which is either currently not active, or which is finished.
+Expecting exception from store.openCursor(0)
+PASS Exception was thrown.
+PASS code is 0
+PASS ename is 'TransactionInactiveError'
+Exception message: A request was placed against a transaction which is either currently not active, or which is finished.
+Expecting exception from store.openCursor(0, 'next')
+PASS Exception was thrown.
+PASS code is 0
+PASS ename is 'TransactionInactiveError'
+Exception message: A request was placed against a transaction which is either currently not active, or which is finished.
+Expecting exception from store.openCursor(IDBKeyRange.only(0))
+PASS Exception was thrown.
+PASS code is 0
+PASS ename is 'TransactionInactiveError'
+Exception message: A request was placed against a transaction which is either currently not active, or which is finished.
+Expecting exception from store.openCursor(IDBKeyRange.only(0), 'next')
+PASS Exception was thrown.
+PASS code is 0
+PASS ename is 'TransactionInactiveError'
+Exception message: A request was placed against a transaction which is either currently not active, or which is finished.
+Expecting exception from index.get(0)
+PASS Exception was thrown.
+PASS code is 0
+PASS ename is 'TransactionInactiveError'
+Exception message: A request was placed against a transaction which is either currently not active, or which is finished.
+Expecting exception from index.get(IDBKeyRange.only(0))
+PASS Exception was thrown.
+PASS code is 0
+PASS ename is 'TransactionInactiveError'
+Exception message: A request was placed against a transaction which is either currently not active, or which is finished.
+Expecting exception from index.getKey(0)
+PASS Exception was thrown.
+PASS code is 0
+PASS ename is 'TransactionInactiveError'
+Exception message: A request was placed against a transaction which is either currently not active, or which is finished.
+Expecting exception from index.getKey(IDBKeyRange.only(0))
+PASS Exception was thrown.
+PASS code is 0
+PASS ename is 'TransactionInactiveError'
+Exception message: A request was placed against a transaction which is either currently not active, or which is finished.
+Expecting exception from index.count()
+PASS Exception was thrown.
+PASS code is 0
+PASS ename is 'TransactionInactiveError'
+Exception message: A request was placed against a transaction which is either currently not active, or which is finished.
+Expecting exception from index.count(0)
+PASS Exception was thrown.
+PASS code is 0
+PASS ename is 'TransactionInactiveError'
+Exception message: A request was placed against a transaction which is either currently not active, or which is finished.
+Expecting exception from index.count(IDBKeyRange.only(0))
+PASS Exception was thrown.
+PASS code is 0
+PASS ename is 'TransactionInactiveError'
+Exception message: A request was placed against a transaction which is either currently not active, or which is finished.
+Expecting exception from index.openCursor()
+PASS Exception was thrown.
+PASS code is 0
+PASS ename is 'TransactionInactiveError'
+Exception message: A request was placed against a transaction which is either currently not active, or which is finished.
+Expecting exception from index.openCursor(0)
+PASS Exception was thrown.
+PASS code is 0
+PASS ename is 'TransactionInactiveError'
+Exception message: A request was placed against a transaction which is either currently not active, or which is finished.
+Expecting exception from index.openCursor(0, 'next')
+PASS Exception was thrown.
+PASS code is 0
+PASS ename is 'TransactionInactiveError'
+Exception message: A request was placed against a transaction which is either currently not active, or which is finished.
+Expecting exception from index.openCursor(IDBKeyRange.only(0))
+PASS Exception was thrown.
+PASS code is 0
+PASS ename is 'TransactionInactiveError'
+Exception message: A request was placed against a transaction which is either currently not active, or which is finished.
+Expecting exception from index.openCursor(IDBKeyRange.only(0), 'next')
+PASS Exception was thrown.
+PASS code is 0
+PASS ename is 'TransactionInactiveError'
+Exception message: A request was placed against a transaction which is either currently not active, or which is finished.
+Expecting exception from index.openKeyCursor()
+PASS Exception was thrown.
+PASS code is 0
+PASS ename is 'TransactionInactiveError'
+Exception message: A request was placed against a transaction which is either currently not active, or which is finished.
+Expecting exception from index.openKeyCursor(0)
+PASS Exception was thrown.
+PASS code is 0
+PASS ename is 'TransactionInactiveError'
+Exception message: A request was placed against a transaction which is either currently not active, or which is finished.
+Expecting exception from index.openKeyCursor(0, 'next')
+PASS Exception was thrown.
+PASS code is 0
+PASS ename is 'TransactionInactiveError'
+Exception message: A request was placed against a transaction which is either currently not active, or which is finished.
+Expecting exception from index.openKeyCursor(IDBKeyRange.only(0))
+PASS Exception was thrown.
+PASS code is 0
+PASS ename is 'TransactionInactiveError'
+Exception message: A request was placed against a transaction which is either currently not active, or which is finished.
+Expecting exception from index.openKeyCursor(IDBKeyRange.only(0), 'next')
+PASS Exception was thrown.
+PASS code is 0
+PASS ename is 'TransactionInactiveError'
+Exception message: A request was placed against a transaction which is either currently not active, or which is finished.
+
+testEventCallback():
+Transaction should be active inside a non-IDB-event callback
+store = transaction.objectStore('store')
+index = store.index('index')
+PASS store.add(0, 0) did not throw exception.
+PASS store.put(0, 0) did not throw exception.
+PASS store.get(0) did not throw exception.
+PASS store.get(IDBKeyRange.only(0)) did not throw exception.
+PASS store.delete(0) did not throw exception.
+PASS store.delete(IDBKeyRange.only(0)) did not throw exception.
+PASS store.count() did not throw exception.
+PASS store.count(0) did not throw exception.
+PASS store.count(IDBKeyRange.only(0)) did not throw exception.
+PASS store.clear() did not throw exception.
+PASS store.openCursor() did not throw exception.
+PASS store.openCursor(0) did not throw exception.
+PASS store.openCursor(0, 'next') did not throw exception.
+PASS store.openCursor(IDBKeyRange.only(0)) did not throw exception.
+PASS store.openCursor(IDBKeyRange.only(0), 'next') did not throw exception.
+PASS index.get(0) did not throw exception.
+PASS index.get(IDBKeyRange.only(0)) did not throw exception.
+PASS index.getKey(0) did not throw exception.
+PASS index.getKey(IDBKeyRange.only(0)) did not throw exception.
+PASS index.count() did not throw exception.
+PASS index.count(0) did not throw exception.
+PASS index.count(IDBKeyRange.only(0)) did not throw exception.
+PASS index.openCursor() did not throw exception.
+PASS index.openCursor(0) did not throw exception.
+PASS index.openCursor(0, 'next') did not throw exception.
+PASS index.openCursor(IDBKeyRange.only(0)) did not throw exception.
+PASS index.openCursor(IDBKeyRange.only(0), 'next') did not throw exception.
+PASS index.openKeyCursor() did not throw exception.
+PASS index.openKeyCursor(0) did not throw exception.
+PASS index.openKeyCursor(0, 'next') did not throw exception.
+PASS index.openKeyCursor(IDBKeyRange.only(0)) did not throw exception.
+PASS index.openKeyCursor(IDBKeyRange.only(0), 'next') did not throw exception.
+
+transactionComplete():
+Expecting exception from store = transaction.objectStore('store')
+PASS Exception was thrown.
+PASS code is DOMException.INVALID_STATE_ERR
+PASS ename is 'InvalidStateError'
+Exception message: An operation was called on an object on which it is not allowed or at a time when it is not allowed.
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
diff --git a/LayoutTests/platform/wk2/storage/indexeddb/transaction-after-close-expected.txt b/LayoutTests/platform/wk2/storage/indexeddb/transaction-after-close-expected.txt
new file mode 100644 (file)
index 0000000..214845d
--- /dev/null
@@ -0,0 +1,33 @@
+Test closing a database connection in IndexedDB.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+indexedDB = self.indexedDB || self.webkitIndexedDB || self.mozIndexedDB || self.msIndexedDB || self.OIndexedDB;
+
+dbname = "transaction-after-close.html"
+indexedDB.deleteDatabase(dbname)
+indexedDB.open(dbname)
+store = db.createObjectStore('store')
+request = store.put('x', 'y')
+PASS Put success
+running first transaction
+currentTransaction = db.transaction(['store'], 'readwrite')
+objectStore.put('a', 'b')
+db.close()
+Expecting exception from db.transaction(['store'], 'readwrite')
+PASS Exception was thrown.
+PASS code is DOMException.INVALID_STATE_ERR
+PASS ename is 'InvalidStateError'
+Exception message: An operation was called on an object on which it is not allowed or at a time when it is not allowed.
+
+verify that we can reopen the db after calling close
+indexedDB.open(dbname)
+second_db = event.target.result
+currentTransaction = second_db.transaction(['store'], 'readwrite')
+request = store.put('1', '2')
+PASS final put success
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
diff --git a/LayoutTests/platform/wk2/storage/indexeddb/transaction-read-only-expected.txt b/LayoutTests/platform/wk2/storage/indexeddb/transaction-read-only-expected.txt
new file mode 100644 (file)
index 0000000..08552e5
--- /dev/null
@@ -0,0 +1,36 @@
+Test read-only transactions in IndexedDB.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+indexedDB = self.indexedDB || self.webkitIndexedDB || self.mozIndexedDB || self.msIndexedDB || self.OIndexedDB;
+
+dbname = "transaction-read-only.html"
+indexedDB.deleteDatabase(dbname)
+indexedDB.open(dbname)
+store = db.createObjectStore('store')
+store.put('x', 'y')
+trans = db.transaction('store')
+Expecting exception from trans.objectStore('store').put('a', 'b')
+PASS Exception was thrown.
+PASS code is 0
+PASS ename is 'ReadOnlyError'
+Exception message: A write operation was attempted in a read-only transaction.
+trans = db.transaction('store')
+Expecting exception from trans.objectStore('store').delete('x')
+PASS Exception was thrown.
+PASS code is 0
+PASS ename is 'ReadOnlyError'
+Exception message: A write operation was attempted in a read-only transaction.
+trans = db.transaction('store')
+cur = trans.objectStore('store').openCursor()
+PASS !event.target.result is false
+Expecting exception from event.target.result.delete()
+PASS Exception was thrown.
+PASS code is 0
+PASS ename is 'ReadOnlyError'
+Exception message: A write operation was attempted in a read-only transaction.
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
diff --git a/LayoutTests/platform/wk2/storage/indexeddb/version-change-exclusive-expected.txt b/LayoutTests/platform/wk2/storage/indexeddb/version-change-exclusive-expected.txt
new file mode 100644 (file)
index 0000000..ca1b3ed
--- /dev/null
@@ -0,0 +1,49 @@
+Ensure pending open waits for version change transaction to complete.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+indexedDB = self.indexedDB || self.webkitIndexedDB || self.mozIndexedDB || self.msIndexedDB || self.OIndexedDB;
+
+dbname = "version-change-exclusive.html"
+indexedDB.deleteDatabase(dbname)
+indexedDB.open(dbname)
+calling open() - callback should wait until VERSION_CHANGE transaction is complete
+indexedDB.open(dbname)
+setVersion() callback
+starting work in VERSION_CHANGE transaction
+self.state = 'VERSION_CHANGE started'
+store = db.createObjectStore('test-store')
+Expecting exception from db.transaction('test-store')
+PASS Exception was thrown.
+PASS code is DOMException.INVALID_STATE_ERR
+PASS ename is 'InvalidStateError'
+Exception message: An operation was called on an object on which it is not allowed or at a time when it is not allowed.
+store.put(0, 0)
+in put's onsuccess
+store.put(1, 1)
+in put's onsuccess
+store.put(2, 2)
+in put's onsuccess
+store.put(3, 3)
+in put's onsuccess
+store.put(4, 4)
+in put's onsuccess
+store.put(5, 5)
+in put's onsuccess
+store.put(6, 6)
+in put's onsuccess
+store.put(7, 7)
+in put's onsuccess
+store.put(8, 8)
+in put's onsuccess
+store.put(9, 9)
+in put's onsuccess
+ending work in VERSION_CHANGE transaction
+self.state = 'VERSION_CHANGE finished'
+open() callback - this should appear after VERSION_CHANGE transaction ends
+PASS self.state is "VERSION_CHANGE finished"
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
index 4b3325c..093304a 100644 (file)
@@ -32,7 +32,7 @@ Expecting exception from db.transaction('store')
 PASS Exception was thrown.
 PASS code is DOMException.INVALID_STATE_ERR
 PASS ename is 'InvalidStateError'
-Exception message: InvalidStateError: DOM IDBDatabase Exception 11
+Exception message: An operation was called on an object on which it is not allowed or at a time when it is not allowed.
 
 onOpenError():
 PASS sawTransactionAbort is true
@@ -41,7 +41,7 @@ Expecting exception from db.transaction('store')
 PASS Exception was thrown.
 PASS code is DOMException.INVALID_STATE_ERR
 PASS ename is 'InvalidStateError'
-Exception message: InvalidStateError: DOM IDBDatabase Exception 11
+Exception message: An operation was called on an object on which it is not allowed or at a time when it is not allowed.
 PASS successfullyParsed is true
 
 TEST COMPLETE
index e76c4cb..bf9efb8 100644 (file)
@@ -11,13 +11,13 @@ Expecting exception from request.result
 PASS Exception was thrown.
 PASS code is DOMException.INVALID_STATE_ERR
 PASS ename is 'InvalidStateError'
-Exception message: InvalidStateError: DOM IDBDatabase Exception 11
+Exception message: Failed to read the 'result' property from 'IDBRequest': The request has not finished.
 PASS 'error' in request is true
 Expecting exception from request.error
 PASS Exception was thrown.
 PASS code is DOMException.INVALID_STATE_ERR
 PASS ename is 'InvalidStateError'
-Exception message: InvalidStateError: DOM IDBDatabase Exception 11
+Exception message: Failed to read the 'error' property from 'IDBRequest': The request has not finished.
 PASS 'source' in request is true
 PASS request.source is null
 PASS 'transaction' in request is true
index 34ce3b3..b244c8f 100644 (file)
@@ -13,7 +13,7 @@ Expecting exception from db.createObjectStore('tmp')
 PASS Exception was thrown.
 PASS code is 0
 PASS ename is 'ConstraintError'
-Exception message: ConstraintError: DOM IDBDatabase Exception 0
+Exception message: Failed to execute 'createObjectStore' on 'IDBDatabase': An object store with the specified name already exists.
 trans = db.transaction(['tmp'])
 trans.objectStore('tmp').get(0)
 PASS event.target.result is undefined.
@@ -22,25 +22,25 @@ Expecting exception from db.createObjectStore("some os")
 PASS Exception was thrown.
 PASS code is DOMException.INVALID_STATE_ERR
 PASS ename is 'InvalidStateError'
-Exception message: InvalidStateError: DOM IDBDatabase Exception 11
+Exception message: Failed to execute 'createObjectStore' on 'IDBDatabase': The database is not running a version change transaction.
 Trying remove
 Expecting exception from db.deleteObjectStore("some os")
 PASS Exception was thrown.
 PASS code is DOMException.INVALID_STATE_ERR
 PASS ename is 'InvalidStateError'
-Exception message: InvalidStateError: DOM IDBDatabase Exception 11
+Exception message: Failed to execute 'deleteObjectStore' on 'IDBDatabase': The database is not running a version change transaction.
 Trying create with store that already exists
 Expecting exception from db.createObjectStore('tmp')
 PASS Exception was thrown.
 PASS code is DOMException.INVALID_STATE_ERR
 PASS ename is 'InvalidStateError'
-Exception message: InvalidStateError: DOM IDBDatabase Exception 11
+Exception message: Failed to execute 'createObjectStore' on 'IDBDatabase': The database is not running a version change transaction.
 Trying remove with store that already exists
 Expecting exception from db.deleteObjectStore('tmp')
 PASS Exception was thrown.
 PASS code is DOMException.INVALID_STATE_ERR
 PASS ename is 'InvalidStateError'
-Exception message: InvalidStateError: DOM IDBDatabase Exception 11
+Exception message: Failed to execute 'deleteObjectStore' on 'IDBDatabase': The database is not running a version change transaction.
 PASS successfullyParsed is true
 
 TEST COMPLETE
index 979b98f..082c103 100644 (file)
@@ -49,27 +49,27 @@ Expecting exception from savedCursor.update('value')
 PASS Exception was thrown.
 PASS code is DOMException.INVALID_STATE_ERR
 PASS ename is 'InvalidStateError'
-Exception message: InvalidStateError: DOM IDBDatabase Exception 11
+Exception message: An operation was called on an object on which it is not allowed or at a time when it is not allowed.
 Expecting exception from savedCursor.advance(1)
 PASS Exception was thrown.
 PASS code is DOMException.INVALID_STATE_ERR
 PASS ename is 'InvalidStateError'
-Exception message: InvalidStateError: DOM IDBDatabase Exception 11
+Exception message: Failed to execute 'advance' on 'IDBCursor': The cursor is being iterated or has iterated past its end.
 Expecting exception from savedCursor.continue()
 PASS Exception was thrown.
 PASS code is DOMException.INVALID_STATE_ERR
 PASS ename is 'InvalidStateError'
-Exception message: InvalidStateError: DOM IDBDatabase Exception 11
+Exception message: Failed to execute 'continue' on 'IDBCursor': The cursor is being iterated or has iterated past its end.
 Expecting exception from savedCursor.continue('key')
 PASS Exception was thrown.
 PASS code is DOMException.INVALID_STATE_ERR
 PASS ename is 'InvalidStateError'
-Exception message: InvalidStateError: DOM IDBDatabase Exception 11
+Exception message: Failed to execute 'continue' on 'IDBCursor': The cursor is being iterated or has iterated past its end.
 Expecting exception from savedCursor.delete()
 PASS Exception was thrown.
 PASS code is DOMException.INVALID_STATE_ERR
 PASS ename is 'InvalidStateError'
-Exception message: InvalidStateError: DOM IDBDatabase Exception 11
+Exception message: An operation was called on an object on which it is not allowed or at a time when it is not allowed.
 
 PASS successfullyParsed is true
 
index 4893f9e..8ff52dd 100644 (file)
@@ -149,18 +149,18 @@ Expecting exception from storeFromReadOnlyTransaction.add(0, 0)
 PASS Exception was thrown.
 PASS code is 0
 PASS ename is 'ReadOnlyError'
-Exception message: Failed to execute 'add' on 'IDBObjectStore': The transaction is read-only.
+Exception message: Failed to store record in an IDBObjectStore: The transaction is read-only.
 The transaction this IDBObjectStore belongs to is not active.
 Expecting exception from storeFromInactiveTransaction.add(0, 0)
 PASS Exception was thrown.
 PASS code is 0
 PASS ename is 'TransactionInactiveError'
-Exception message: Failed to execute 'add' on 'IDBObjectStore': The transaction has finished.
+Exception message: Failed to store record in an IDBObjectStore: The transaction is inactive or finished.
 The data being stored could not be cloned by the internal structured cloning algorithm.
 Expecting exception from store.add(self, 0)
 PASS Exception was thrown.
 PASS code is DOMException.DATA_CLONE_ERR
-Exception message: Failed to execute 'add' on 'IDBObjectStore': An object could not be cloned.
+Exception message: DataCloneError: DOM Exception 25
 
 IDBObjectStore.clear()
 This method throws a DOMException of type ReadOnlyError if the transaction which this IDBObjectStore belongs to is has its mode set to "readonly".
@@ -174,7 +174,7 @@ Expecting exception from storeFromInactiveTransaction.clear()
 PASS Exception was thrown.
 PASS code is 0
 PASS ename is 'TransactionInactiveError'
-Exception message: Failed to execute 'clear' on 'IDBObjectStore': The transaction has finished.
+Exception message: Failed to execute 'clear' on 'IDBObjectStore': The transaction is inactive or finished.
 
 IDBObjectStore.count()
 If the optional key parameter is not a valid key or a key range, this method throws a DOMException of type DataError.
@@ -188,7 +188,7 @@ Expecting exception from storeFromInactiveTransaction.count()
 PASS Exception was thrown.
 PASS code is 0
 PASS ename is 'TransactionInactiveError'
-Exception message: Failed to execute 'count' on 'IDBObjectStore': The transaction has finished.
+Exception message: Failed to execute 'count' on 'IDBObjectStore': The transaction is inactive or finished.
 
 IDBObjectStore.delete()
 This method throws a DOMException of type ReadOnlyError if the transaction which this IDBObjectStore belongs to is has its mode set to "readonly".
@@ -208,7 +208,7 @@ Expecting exception from storeFromInactiveTransaction.add(0, 0)
 PASS Exception was thrown.
 PASS code is 0
 PASS ename is 'TransactionInactiveError'
-Exception message: Failed to execute 'add' on 'IDBObjectStore': The transaction has finished.
+Exception message: Failed to store record in an IDBObjectStore: The transaction is inactive or finished.
 
 IDBObjectStore.get()
 If the key parameter is not a valid key or a key range, this method throws a DOMException of type DataError.
@@ -222,7 +222,7 @@ Expecting exception from storeFromInactiveTransaction.get(0)
 PASS Exception was thrown.
 PASS code is 0
 PASS ename is 'TransactionInactiveError'
-Exception message: Failed to execute 'get' on 'IDBObjectStore': The transaction has finished.
+Exception message: Failed to execute 'get' on 'IDBObjectStore': The transaction is inactive or finished.
 
 IDBObjectStore.index()
 There is no index with the given name, compared in a case-sensitive manner, in the connected database.
@@ -234,9 +234,9 @@ Exception message: Failed to execute 'index' on 'IDBObjectStore': The specified
 Occurs if a request is made on a source object that has been deleted or removed, or if the transaction the object store belongs to has finished.
 Expecting exception from storeFromInactiveTransaction.index('index')
 PASS Exception was thrown.
-PASS code is DOMException.INVALID_STATE_ERR
-PASS ename is 'InvalidStateError'
-Exception message: Failed to execute 'index' on 'IDBObjectStore': The transaction has finished.
+PASS code is 0
+PASS ename is 'TransactionInactiveError'
+Exception message: Failed to execute 'index' on 'IDBObjectStore': The transaction is inactive or finished.
 
 IDBObjectStore.openCursor()
 If the range parameter is specified but is not a valid key or a key range, this method throws a DOMException of type DataError.
@@ -250,29 +250,11 @@ Expecting exception from storeFromInactiveTransaction.openCursor()
 PASS Exception was thrown.
 PASS code is 0
 PASS ename is 'TransactionInactiveError'
-Exception message: Failed to execute 'openCursor' on 'IDBObjectStore': The transaction has finished.
+Exception message: Failed to execute 'openCursor' on 'IDBObjectStore': The transaction is inactive or finished.
 The value for the direction parameter is invalid.
 Expecting TypeError exception from store.openCursor(0, 'invalid-direction')
 PASS Exception was thrown.
-PASS store.openCursor(0, 'invalid-direction') threw TypeError: Failed to execute 'openCursor' on 'IDBObjectStore': The direction provided ('invalid-direction') is not one of 'next', 'nextunique', 'prev', or 'prevunique'.
-
-IDBObjectStore.openKeyCursor()
-If the range parameter is specified but is not a valid key or a key range, this method throws a DOMException of type DataError.
-Expecting exception from store.openKeyCursor({})
-PASS Exception was thrown.
-PASS code is 0
-PASS ename is 'DataError'
-Exception message: Failed to execute 'openKeyCursor' on 'IDBObjectStore': The parameter is not a valid key.
-The transaction this IDBObjectStore belongs to is not active.
-Expecting exception from storeFromInactiveTransaction.openKeyCursor()
-PASS Exception was thrown.
-PASS code is 0
-PASS ename is 'TransactionInactiveError'
-Exception message: Failed to execute 'openKeyCursor' on 'IDBObjectStore': The transaction has finished.
-The value for the direction parameter is invalid.
-Expecting TypeError exception from store.openKeyCursor(0, 'invalid-direction')
-PASS Exception was thrown.
-PASS store.openKeyCursor(0, 'invalid-direction') threw TypeError: Failed to execute 'openKeyCursor' on 'IDBObjectStore': The direction provided ('invalid-direction') is not one of 'next', 'nextunique', 'prev', or 'prevunique'.
+PASS store.openCursor(0, 'invalid-direction') threw TypeError: Type error
 
 IDBObjectStore.put()
 This method throws a DOMException of type ReadOnlyError if the transaction which this IDBObjectStore belongs to is has its mode set to "readonly".
@@ -280,18 +262,18 @@ Expecting exception from storeFromReadOnlyTransaction.put(0, 0)
 PASS Exception was thrown.
 PASS code is 0
 PASS ename is 'ReadOnlyError'
-Exception message: Failed to execute 'put' on 'IDBObjectStore': The transaction is read-only.
+Exception message: Failed to store record in an IDBObjectStore: The transaction is read-only.
 The transaction this IDBObjectStore belongs to is not active.
 Expecting exception from storeFromInactiveTransaction.put(0, 0)
 PASS Exception was thrown.
 PASS code is 0
 PASS ename is 'TransactionInactiveError'
-Exception message: Failed to execute 'put' on 'IDBObjectStore': The transaction has finished.
+Exception message: Failed to store record in an IDBObjectStore: The transaction is inactive or finished.
 The data being stored could not be cloned by the internal structured cloning algorithm.
 Expecting exception from store.put(self, 0)
 PASS Exception was thrown.
 PASS code is DOMException.DATA_CLONE_ERR
-Exception message: Failed to execute 'put' on 'IDBObjectStore': An object could not be cloned.
+Exception message: DataCloneError: DOM Exception 25
 db.close()
 ro_transaction.oncomplete = transactionComplete
 rw_transaction.oncomplete = transactionComplete
@@ -363,7 +345,7 @@ Expecting exception from indexFromInactiveTransaction.count()
 PASS Exception was thrown.
 PASS code is 0
 PASS ename is 'TransactionInactiveError'
-Exception message: Failed to execute 'count' on 'IDBIndex': The transaction has finished.
+Exception message: Failed to execute 'count' on 'IDBIndex': The transaction is inactive or finished.
 
 IDBIndex.get()
 If the key parameter is not a valid key or a key range, this method throws a DOMException of type DataError.
@@ -377,7 +359,7 @@ Expecting exception from indexFromInactiveTransaction.get(0)
 PASS Exception was thrown.
 PASS code is 0
 PASS ename is 'TransactionInactiveError'
-Exception message: Failed to execute 'get' on 'IDBIndex': The transaction has finished.
+Exception message: Failed to execute 'get' on 'IDBIndex': The transaction is inactive or finished.
 
 IDBIndex.getKey()
 If the key parameter is not a valid key or a key range, this method throws a DOMException of type DataError.
@@ -391,7 +373,7 @@ Expecting exception from indexFromInactiveTransaction.getKey(0)
 PASS Exception was thrown.
 PASS code is 0
 PASS ename is 'TransactionInactiveError'
-Exception message: Failed to execute 'getKey' on 'IDBIndex': The transaction has finished.
+Exception message: Failed to execute 'getKey' on 'IDBIndex': The transaction is inactive or finished.
 
 IDBIndex.openCursor()
 If the range parameter is specified but is not a valid key or a key range, this method throws a DOMException of type DataError.
@@ -405,7 +387,7 @@ Expecting exception from indexFromInactiveTransaction.openCursor()
 PASS Exception was thrown.
 PASS code is 0
 PASS ename is 'TransactionInactiveError'
-Exception message: Failed to execute 'openCursor' on 'IDBIndex': The transaction has finished.
+Exception message: Failed to execute 'openCursor' on 'IDBIndex': The transaction is inactive or finished.
 The value for the direction parameter is invalid.
 Expecting TypeError exception from index.openCursor(0, 'invalid-direction')
 PASS Exception was thrown.
@@ -423,7 +405,7 @@ Expecting exception from indexFromInactiveTransaction.openKeyCursor()
 PASS Exception was thrown.
 PASS code is 0
 PASS ename is 'TransactionInactiveError'
-Exception message: Failed to execute 'openKeyCursor' on 'IDBIndex': The transaction has finished.
+Exception message: Failed to execute 'openKeyCursor' on 'IDBIndex': The transaction is inactive or finished.
 The value for the direction parameter is invalid.
 Expecting TypeError exception from index.openKeyCursor(0, 'invalid-direction')
 PASS Exception was thrown.
@@ -457,7 +439,7 @@ Expecting exception from cursorFromInactiveTransaction.advance(1)
 PASS Exception was thrown.
 PASS code is 0
 PASS ename is 'TransactionInactiveError'
-Exception message: Failed to execute 'advance' on 'IDBCursor': The transaction has finished.
+Exception message: Failed to execute 'advance' on 'IDBCursor': The transaction is inactive or finished.
 
 IDBCursor.continue()
 The parameter is not a valid key.
@@ -490,7 +472,7 @@ Expecting exception from cursorFromInactiveTransaction.continue()
 PASS Exception was thrown.
 PASS code is 0
 PASS ename is 'TransactionInactiveError'
-Exception message: Failed to execute 'continue' on 'IDBCursor': The transaction has finished.
+Exception message: Failed to execute 'continue' on 'IDBCursor': The transaction is inactive or finished.
 
 IDBCursor.delete()
 If this cursor's got value flag is false, or if this cursor was created using openKeyCursor a DOMException of type InvalidStateError is thrown.
@@ -504,7 +486,7 @@ Expecting exception from cursorFromInactiveTransaction.delete()
 PASS Exception was thrown.
 PASS code is 0
 PASS ename is 'TransactionInactiveError'
-Exception message: Failed to execute 'delete' on 'IDBCursor': The transaction has finished.
+Exception message: Failed to execute 'delete' on 'IDBCursor': The transaction is inactive or finished.
 
 IDBCursor.update()
 If this cursor's got value flag is false or if this cursor was created using openKeyCursor. This method throws a DOMException of type InvalidStateError.
@@ -523,13 +505,13 @@ If the structured clone algorithm throws an exception, that exception is rethrow
 Expecting exception from cursor.update(self)
 PASS Exception was thrown.
 PASS code is DOMException.DATA_CLONE_ERR
-Exception message: Failed to execute 'update' on 'IDBCursor': An object could not be cloned.
+Exception message: DataCloneError: DOM Exception 25
 The transaction this IDBCursor belongs to is not active.
 Expecting exception from cursorFromInactiveTransaction.update({})
 PASS Exception was thrown.
 PASS code is 0
 PASS ename is 'TransactionInactiveError'
-Exception message: Failed to execute 'update' on 'IDBCursor': The transaction has finished.
+Exception message: Failed to execute 'update' on 'IDBCursor': The transaction is inactive or finished.
 readOnlyTransaction = db.transaction('store', 'readonly')
 request = readOnlyTransaction.objectStore('store').openCursor()
 cursorFromReadOnlyTransaction = request.result
@@ -558,7 +540,7 @@ Expecting exception from finishedTransaction.abort()
 PASS Exception was thrown.
 PASS code is DOMException.INVALID_STATE_ERR
 PASS ename is 'InvalidStateError'
-Exception message: Failed to execute 'abort' on 'IDBTransaction': The transaction has finished.
+Exception message: Failed to execute 'abort' on 'IDBTransaction': The transaction is inactive or finished.
 If the requested object store is not in this transaction's scope.
 Expecting exception from db.transaction('store').objectStore('otherStore')
 PASS Exception was thrown.
index 0e18f88..1386b18 100644 (file)
@@ -1,23 +1,23 @@
 ALERT: Initial upgrade needed: Old version - 0 New version - 1
-ALERT: Failed to create object store with both autoincrement and an empty keypath: Error: InvalidAccessError: DOM IDBDatabase Exception 15
+ALERT: Failed to create object store with both autoincrement and an empty keypath: Error: Failed to execute 'createObjectStore' on 'IDBDatabase': The autoIncrement option was set but the keyPath option was empty or an array.
 ALERT: Object store names:
-ALERT: Failed to create object store with both autoincrement and a sequence keypath: Error: InvalidAccessError: DOM IDBDatabase Exception 15
+ALERT: Failed to create object store with both autoincrement and a sequence keypath: Error: Failed to execute 'createObjectStore' on 'IDBDatabase': The autoIncrement option was set but the keyPath option was empty or an array.
 ALERT: Object store names:
-ALERT: Failed to create object store with invalid keyPath: Error: SyntaxError: DOM IDBDatabase Exception 12
+ALERT: Failed to create object store with invalid keyPath: Error: Failed to execute 'createObjectStore' on 'IDBDatabase': The keyPath option is not a valid key path.
 ALERT: Object store names:
 ALERT: Actually created an object store
 ALERT: Object store names:
 ALERT: TestObjectStore1
-ALERT: Failed to create TestObjectStore a second time: Error: ConstraintError: DOM IDBDatabase Exception 0
+ALERT: Failed to create TestObjectStore a second time: Error: Failed to execute 'createObjectStore' on 'IDBDatabase': An object store with the specified name already exists.
 ALERT: Object store names:
 ALERT: TestObjectStore1
 ALERT: Initial upgrade versionchange transaction complete
 ALERT: Object store names:
 ALERT: TestObjectStore1
-ALERT: Failed to create object store while there is no version change transaction: Error: InvalidStateError: DOM IDBDatabase Exception 11
+ALERT: Failed to create object store while there is no version change transaction: Error: Failed to execute 'createObjectStore' on 'IDBDatabase': The database is not running a version change transaction.
 ALERT: Object store names:
 ALERT: TestObjectStore1
-ALERT: Failed to create object store outside of onupgradeneeded: Error: InvalidStateError: DOM IDBDatabase Exception 11
+ALERT: Failed to create object store outside of onupgradeneeded: Error: Failed to execute 'createObjectStore' on 'IDBDatabase': The database is not running a version change transaction.
 ALERT: Object store names:
 ALERT: TestObjectStore1
 ALERT: Done
index 4ef22cf..df5f010 100644 (file)
@@ -1,5 +1,5 @@
 ALERT: Initial upgrade needed: Old version - 0 New version - 1
-ALERT: Second abort failed: Error: InvalidStateError: DOM IDBDatabase Exception 11
+ALERT: Second abort failed: Error: Failed to execute 'abort' on 'IDBTransaction': The transaction is inactive or finished.
 ALERT: Initial upgrade versionchange transaction aborted
 ALERT: Done
 This test aborts the same transaction twice, making the appropriate exception is thrown.
index ac05859..2d24af4 100644 (file)
@@ -1,11 +1,11 @@
 ALERT: Initial upgrade needed: Old version - 0 New version - 1
 ALERT: Initial upgrade versionchange transaction complete
 ALERT: readwrite put success - about to try to delete an objectstore
-ALERT: Failed to deleteObjectStore without a versionchange transaction - Error: InvalidStateError: DOM IDBDatabase Exception 11
+ALERT: Failed to deleteObjectStore without a versionchange transaction - Error: Failed to execute 'deleteObjectStore' on 'IDBDatabase': The database is not running a version change transaction.
 ALERT: readwrite transaction complete
 ALERT: Second upgrade needed: Old version - 1 New version - 2
-ALERT: Failed to deleteObjectStore with a non-existent objectstore - Error: NotFoundError: DOM IDBDatabase Exception 8
-ALERT: Failed to deleteObjectStore with an in-progress versionchange transaction that is inactive - Error: TransactionInactiveError: DOM IDBDatabase Exception 0
+ALERT: Failed to deleteObjectStore with a non-existent objectstore - Error: Failed to execute 'deleteObjectStore' on 'IDBDatabase': The specified object store was not found.
+ALERT: Failed to deleteObjectStore with an in-progress versionchange transaction that is inactive - Error: A request was placed against a transaction which is either currently not active, or which is finished.
 ALERT: Second version change transaction complete
 ALERT: Done
 This tests some obvious failures that can happen while calling IDBDatabase.deleteObjectStore()
index 35b9095..4b553b0 100644 (file)
@@ -1,10 +1,10 @@
 ALERT: Upgrade needed: Old version - 0 New version - 1
-ALERT: Failed to start a transaction while a versionChange transaction was in progress - Error: InvalidStateError: DOM IDBDatabase Exception 11
+ALERT: Failed to start a transaction while a versionChange transaction was in progress - Error: Failed to execute 'transaction' on 'IDBDatabase': A version change transaction is running.
 ALERT: versionchange transaction completed
-ALERT: Failed to start a transaction with an empty set of object stores - Error: InvalidAccessError: DOM IDBDatabase Exception 15
-ALERT: Failed to start a transaction to a nonexistent object store - Error: NotFoundError: DOM IDBDatabase Exception 8
-ALERT: Failed to start a transaction with an invalid mode - TypeError: Type error
-ALERT: Failed to explicitly start a versionchange transaction - TypeError: Type error
-ALERT: Failed to explicitly start a transaction with the close pending flag set - Error: InvalidStateError: DOM IDBDatabase Exception 11
+ALERT: Failed to start a transaction with an empty set of object stores - Error: Failed to execute 'transaction' on 'IDBDatabase': The storeNames parameter was empty.
+ALERT: Failed to start a transaction to a nonexistent object store - Error: Failed to execute 'transaction' on 'IDBDatabase': One of the specified object stores was not found.
+ALERT: Failed to start a transaction with an invalid mode - TypeError: Failed to execute 'transaction' on 'IDBDatabase': The mode provided ('invalid-mode') is not one of 'readonly' or 'readwrite'.
+ALERT: Failed to explicitly start a versionchange transaction - TypeError: Failed to execute 'transaction' on 'IDBDatabase': The mode provided ('invalid-mode') is not one of 'readonly' or 'readwrite'.
+ALERT: Failed to explicitly start a transaction with the close pending flag set - Error: An operation was called on an object on which it is not allowed or at a time when it is not allowed.
 ALERT: Done
 This tests some obvious failures that can happen while calling IDBDatabase.transaction()
index 4713bb3..5449adf 100644 (file)
@@ -14,7 +14,7 @@ Expecting exception from request = objectStore.add({});
 PASS Exception was thrown.
 PASS code is 0
 PASS ename is 'DataError'
-Exception message: DataError: DOM IDBDatabase Exception 0
+Exception message: The data provided does not meet requirements.
 PASS successfullyParsed is true
 
 TEST COMPLETE
index e1568c8..f6fb4d0 100644 (file)
@@ -14,7 +14,7 @@ Expecting exception from db.transaction('foo').objectStore('foo').clear();
 PASS Exception was thrown.
 PASS code is 0
 PASS ename is 'ReadOnlyError'
-Exception message: ReadOnlyError: DOM IDBDatabase Exception 0
+Exception message: Failed to execute 'clear' on 'IDBObjectStore': The transaction is read-only.
 db.transaction('foo', 'readwrite')
 transaction.objectStore('foo').clear();
 request = db.transaction('foo').objectStore('foo').openCursor();
index 4c4a362..ad877a9 100644 (file)
@@ -26,7 +26,7 @@ PASS event.target.transaction.mode is "versionchange"
 Expecting exception from objectStore = db.createObjectStore(info.name, info.options)
 PASS Exception was thrown.
 PASS code is DOMException.INVALID_ACCESS_ERR
-Exception message: InvalidAccessError: DOM IDBDatabase Exception 15
+Exception message: Failed to execute 'createObjectStore' on 'IDBDatabase': The autoIncrement option was set but the keyPath option was empty or an array.
 objectStore = db.createObjectStore(info.name, info.options);
 PASS objectStore.name is info.name
 PASS objectStore.indexNames.length is 0
index ceb0ae6..551c15e 100644 (file)
@@ -42,7 +42,7 @@ cursor.continue();
 Expecting exception from cursor.continue();
 PASS Exception was thrown.
 PASS code is DOMException.INVALID_STATE_ERR
-Exception message: InvalidStateError: DOM IDBDatabase Exception 11
+Exception message: Failed to execute 'continue' on 'IDBCursor': The cursor is being iterated or has iterated past its end.
 PASS cursor.key is sortedKeys[keyIndex]
 PASS cursor.primaryKey is sortedKeys[keyIndex]
 PASS cursor.value is 'foo'
@@ -55,7 +55,7 @@ cursor.continue();
 Expecting exception from cursor.continue();
 PASS Exception was thrown.
 PASS code is DOMException.INVALID_STATE_ERR
-Exception message: InvalidStateError: DOM IDBDatabase Exception 11
+Exception message: Failed to execute 'continue' on 'IDBCursor': The cursor is being iterated or has iterated past its end.
 PASS cursor.key is sortedKeys[keyIndex]
 PASS cursor.primaryKey is sortedKeys[keyIndex]
 PASS cursor.value is 'foo'
@@ -68,7 +68,7 @@ cursor.continue();
 Expecting exception from cursor.continue();
 PASS Exception was thrown.
 PASS code is DOMException.INVALID_STATE_ERR
-Exception message: InvalidStateError: DOM IDBDatabase Exception 11
+Exception message: Failed to execute 'continue' on 'IDBCursor': The cursor is being iterated or has iterated past its end.
 PASS cursor.key is sortedKeys[keyIndex]
 PASS cursor.primaryKey is sortedKeys[keyIndex]
 PASS cursor.value is 'foo'
@@ -81,7 +81,7 @@ cursor.continue();
 Expecting exception from cursor.continue();
 PASS Exception was thrown.
 PASS code is DOMException.INVALID_STATE_ERR
-Exception message: InvalidStateError: DOM IDBDatabase Exception 11
+Exception message: Failed to execute 'continue' on 'IDBCursor': The cursor is being iterated or has iterated past its end.
 PASS cursor.key is sortedKeys[keyIndex]
 PASS cursor.primaryKey is sortedKeys[keyIndex]
 PASS cursor.value is 'foo'
@@ -94,7 +94,7 @@ cursor.continue();
 Expecting exception from cursor.continue();
 PASS Exception was thrown.
 PASS code is DOMException.INVALID_STATE_ERR
-Exception message: InvalidStateError: DOM IDBDatabase Exception 11
+Exception message: Failed to execute 'continue' on 'IDBCursor': The cursor is being iterated or has iterated past its end.
 PASS cursor.key is sortedKeys[keyIndex]
 PASS cursor.primaryKey is sortedKeys[keyIndex]
 PASS cursor.value is 'foo'
@@ -107,7 +107,7 @@ cursor.continue();
 Expecting exception from cursor.continue();
 PASS Exception was thrown.
 PASS code is DOMException.INVALID_STATE_ERR
-Exception message: InvalidStateError: DOM IDBDatabase Exception 11
+Exception message: Failed to execute 'continue' on 'IDBCursor': The cursor is being iterated or has iterated past its end.
 PASS cursor.key is sortedKeys[keyIndex]
 PASS cursor.primaryKey is sortedKeys[keyIndex]
 PASS cursor.value is 'foo'
@@ -120,7 +120,7 @@ cursor.continue();
 Expecting exception from cursor.continue();
 PASS Exception was thrown.
 PASS code is DOMException.INVALID_STATE_ERR
-Exception message: InvalidStateError: DOM IDBDatabase Exception 11
+Exception message: Failed to execute 'continue' on 'IDBCursor': The cursor is being iterated or has iterated past its end.
 PASS cursor.key is sortedKeys[keyIndex]
 PASS cursor.primaryKey is sortedKeys[keyIndex]
 PASS cursor.value is 'foo'
@@ -133,7 +133,7 @@ cursor.continue();
 Expecting exception from cursor.continue();
 PASS Exception was thrown.
 PASS code is DOMException.INVALID_STATE_ERR
-Exception message: InvalidStateError: DOM IDBDatabase Exception 11
+Exception message: Failed to execute 'continue' on 'IDBCursor': The cursor is being iterated or has iterated past its end.
 PASS cursor.key is sortedKeys[keyIndex]
 PASS cursor.primaryKey is sortedKeys[keyIndex]
 PASS cursor.value is 'foo'
@@ -146,7 +146,7 @@ cursor.continue();
 Expecting exception from cursor.continue();
 PASS Exception was thrown.
 PASS code is DOMException.INVALID_STATE_ERR
-Exception message: InvalidStateError: DOM IDBDatabase Exception 11
+Exception message: Failed to execute 'continue' on 'IDBCursor': The cursor is being iterated or has iterated past its end.
 PASS cursor.key is sortedKeys[keyIndex]
 PASS cursor.primaryKey is sortedKeys[keyIndex]
 PASS cursor.value is 'foo'
@@ -159,7 +159,7 @@ cursor.continue();
 Expecting exception from cursor.continue();
 PASS Exception was thrown.
 PASS code is DOMException.INVALID_STATE_ERR
-Exception message: InvalidStateError: DOM IDBDatabase Exception 11
+Exception message: Failed to execute 'continue' on 'IDBCursor': The cursor is being iterated or has iterated past its end.
 PASS cursor.key is sortedKeys[keyIndex]
 PASS cursor.primaryKey is sortedKeys[keyIndex]
 PASS cursor.value is 'foo'
index daf50ef..ad19247 100644 (file)
@@ -13,7 +13,7 @@ Expecting exception from objectStore.delete(null);
 PASS Exception was thrown.
 PASS code is 0
 PASS ename is 'DataError'
-Exception message: DataError: DOM IDBDatabase Exception 0
+Exception message: Failed to execute 'delete' on 'IDBObjectStore': The parameter is not a valid key range.
 PASS successfullyParsed is true
 
 TEST COMPLETE
index ed78cd9..f09c61b 100644 (file)
@@ -13,7 +13,7 @@ Expecting exception from objectStore.add({id: 5}, 5);
 PASS Exception was thrown.
 PASS code is 0
 PASS ename is 'DataError'
-Exception message: DataError: DOM IDBDatabase Exception 0
+Exception message: The data provided does not meet requirements.
 PASS successfullyParsed is true
 
 TEST COMPLETE
index 7ecac7a..4a15a9f 100644 (file)
@@ -13,7 +13,7 @@ Expecting exception from objectStore.put({});
 PASS Exception was thrown.
 PASS code is 0
 PASS ename is 'DataError'
-Exception message: DataError: DOM IDBDatabase Exception 0
+Exception message: The data provided does not meet requirements.
 PASS successfullyParsed is true
 
 TEST COMPLETE
index 3aa5455..59dc35a 100644 (file)
@@ -13,7 +13,7 @@ Expecting exception from objectStore.put({}, null);
 PASS Exception was thrown.
 PASS code is 0
 PASS ename is 'DataError'
-Exception message: DataError: DOM IDBDatabase Exception 0
+Exception message: The data provided does not meet requirements.
 PASS successfullyParsed is true
 
 TEST COMPLETE
index 861c19b..ae37349 100644 (file)
@@ -13,44 +13,44 @@ Expecting exception from db.transaction([osName]).objectStore(osName).add({});
 PASS Exception was thrown.
 PASS code is 0
 PASS ename is 'ReadOnlyError'
-Exception message: ReadOnlyError: DOM IDBDatabase Exception 0
+Exception message: Failed to store record in an IDBObjectStore: The transaction is read-only.
 Expecting exception from db.transaction(osName).objectStore(osName).add({});
 PASS Exception was thrown.
 PASS code is 0
 PASS ename is 'ReadOnlyError'
-Exception message: ReadOnlyError: DOM IDBDatabase Exception 0
+Exception message: Failed to store record in an IDBObjectStore: The transaction is read-only.
 key1 = 1;
 key2 = 2;
 Expecting exception from db.transaction([osName]).objectStore(osName).put({}, key1);
 PASS Exception was thrown.
 PASS code is 0
 PASS ename is 'ReadOnlyError'
-Exception message: ReadOnlyError: DOM IDBDatabase Exception 0
+Exception message: Failed to store record in an IDBObjectStore: The transaction is read-only.
 Expecting exception from db.transaction(osName).objectStore(osName).put({}, key2);
 PASS Exception was thrown.
 PASS code is 0
 PASS ename is 'ReadOnlyError'
-Exception message: ReadOnlyError: DOM IDBDatabase Exception 0
+Exception message: Failed to store record in an IDBObjectStore: The transaction is read-only.
 Expecting exception from db.transaction([osName]).objectStore(osName).put({}, key1);
 PASS Exception was thrown.
 PASS code is 0
 PASS ename is 'ReadOnlyError'
-Exception message: ReadOnlyError: DOM IDBDatabase Exception 0
+Exception message: Failed to store record in an IDBObjectStore: The transaction is read-only.
 Expecting exception from db.transaction(osName).objectStore(osName).put({}, key1);
 PASS Exception was thrown.
 PASS code is 0
 PASS ename is 'ReadOnlyError'
-Exception message: ReadOnlyError: DOM IDBDatabase Exception 0
+Exception message: Failed to store record in an IDBObjectStore: The transaction is read-only.
 Expecting exception from db.transaction([osName]).objectStore(osName).delete(key1);
 PASS Exception was thrown.
 PASS code is 0
 PASS ename is 'ReadOnlyError'
-Exception message: ReadOnlyError: DOM IDBDatabase Exception 0
+Exception message: Failed to execute 'delete' on 'IDBObjectStore': The transaction is read-only.
 Expecting exception from db.transaction(osName).objectStore(osName).delete(key2);
 PASS Exception was thrown.
 PASS code is 0
 PASS ename is 'ReadOnlyError'
-Exception message: ReadOnlyError: DOM IDBDatabase Exception 0
+Exception message: Failed to execute 'delete' on 'IDBObjectStore': The transaction is read-only.
 PASS successfullyParsed is true
 
 TEST COMPLETE
index 8ba845e..470199b 100644 (file)
@@ -185,7 +185,7 @@ function testObjectStore()
     debug("There is no index with the given name, compared in a case-sensitive manner, in the connected database.");
     evalAndExpectException("store.index('no-such-index')", "DOMException.NOT_FOUND_ERR", "'NotFoundError'");
     debug("Occurs if a request is made on a source object that has been deleted or removed, or if the transaction the object store belongs to has finished.");
-    evalAndExpectException("storeFromInactiveTransaction.index('index')", "DOMException.INVALID_STATE_ERR", "'InvalidStateError'");
+    evalAndExpectException("storeFromInactiveTransaction.index('index')", "0", "'TransactionInactiveError'");
     // "Occurs if a request is made on a source object that has been deleted or removed." - covered in deleted-objects.html
 
     debug("");
index b2dcdb1..b1b7a99 100644 (file)
@@ -25,7 +25,7 @@ Expecting exception from store.add({x: 'value4', y: 'zzz4'}, 'key4')
 PASS Exception was thrown.
 PASS code is 0
 PASS ename is 'TransactionInactiveError'
-Exception message: TransactionInactiveError: DOM IDBDatabase Exception 0
+Exception message: Failed to store record in an IDBObjectStore: The transaction is inactive or finished.
 PASS event.target.error.name is 'AbortError'
 PASS trans.error is null
 PASS firstError is true
@@ -39,12 +39,12 @@ Expecting exception from store.add({x: 'value5', y: 'zzz5'}, 'key5')
 PASS Exception was thrown.
 PASS code is 0
 PASS ename is 'TransactionInactiveError'
-Exception message: TransactionInactiveError: DOM IDBDatabase Exception 0
+Exception message: Failed to store record in an IDBObjectStore: The transaction is inactive or finished.
 Expecting exception from trans.abort()
 PASS Exception was thrown.
 PASS code is DOMException.INVALID_STATE_ERR
 PASS ename is 'InvalidStateError'
-Exception message: InvalidStateError: DOM IDBDatabase Exception 11
+Exception message: Failed to execute 'abort' on 'IDBTransaction': The transaction is inactive or finished.
 PASS successfullyParsed is true
 
 TEST COMPLETE
index 9fadc24..cdb5401 100644 (file)
@@ -1,3 +1,166 @@
+2015-12-04  Brady Eidson  <beidson@apple.com>
+
+        Modern IDB: storage/indexeddb/exceptions.html fails.
+        https://bugs.webkit.org/show_bug.cgi?id=151732
+
+        Reviewed by Alex Christensen.
+
+        No new tests (At least one failing test now passes).
+
+        - Lots of customized exception messages for IDB code to match the text expectations.
+        - Updates to the test expectations where we can't/won't match them exactly.
+        - And a couple of little required behavior changes exposed by the test
+
+        * Modules/indexeddb/IDBCursor.h:
+        * Modules/indexeddb/IDBCursor.idl:
+        * Modules/indexeddb/IDBDatabase.h:
+        * Modules/indexeddb/IDBDatabase.idl:
+        * Modules/indexeddb/IDBDatabaseException.cpp:
+        (WebCore::IDBDatabaseException::initializeDescription):
+        * Modules/indexeddb/IDBFactory.h:
+        * Modules/indexeddb/IDBFactory.idl:
+        * Modules/indexeddb/IDBIndex.h:
+        * Modules/indexeddb/IDBIndex.idl:
+        * Modules/indexeddb/IDBObjectStore.h:
+        * Modules/indexeddb/IDBObjectStore.idl:
+        * Modules/indexeddb/IDBRequest.h:
+        * Modules/indexeddb/IDBRequest.idl:
+        * Modules/indexeddb/IDBTransaction.h:
+        * Modules/indexeddb/IDBTransaction.idl:
+        
+        * Modules/indexeddb/client/IDBCursorImpl.cpp:
+        (WebCore::IDBClient::IDBCursor::update):
+        (WebCore::IDBClient::IDBCursor::advance):
+        (WebCore::IDBClient::IDBCursor::continueFunction):
+        (WebCore::IDBClient::IDBCursor::deleteFunction):
+        * Modules/indexeddb/client/IDBCursorImpl.h:
+        
+        * Modules/indexeddb/client/IDBDatabaseImpl.cpp:
+        (WebCore::IDBClient::IDBDatabase::createObjectStore):
+        (WebCore::IDBClient::IDBDatabase::transaction):
+        (WebCore::IDBClient::IDBDatabase::deleteObjectStore):
+        * Modules/indexeddb/client/IDBDatabaseImpl.h:
+        
+        * Modules/indexeddb/client/IDBFactoryImpl.cpp:
+        (WebCore::IDBClient::IDBFactory::cmp):
+        * Modules/indexeddb/client/IDBFactoryImpl.h:
+        
+        * Modules/indexeddb/client/IDBIndexImpl.cpp:
+        (WebCore::IDBClient::IDBIndex::openCursor):
+        (WebCore::IDBClient::IDBIndex::count):
+        (WebCore::IDBClient::IDBIndex::doCount):
+        (WebCore::IDBClient::IDBIndex::openKeyCursor):
+        (WebCore::IDBClient::IDBIndex::get):
+        (WebCore::IDBClient::IDBIndex::doGet):
+        (WebCore::IDBClient::IDBIndex::getKey):
+        (WebCore::IDBClient::IDBIndex::doGetKey):
+        * Modules/indexeddb/client/IDBIndexImpl.h:
+        
+        * Modules/indexeddb/client/IDBObjectStoreImpl.cpp:
+        (WebCore::IDBClient::IDBObjectStore::openCursor):
+        (WebCore::IDBClient::IDBObjectStore::get):
+        (WebCore::IDBClient::IDBObjectStore::add):
+        (WebCore::IDBClient::IDBObjectStore::put):
+        (WebCore::IDBClient::IDBObjectStore::putForCursorUpdate):
+        (WebCore::IDBClient::IDBObjectStore::putOrAdd):
+        (WebCore::IDBClient::IDBObjectStore::deleteFunction):
+        (WebCore::IDBClient::IDBObjectStore::clear):
+        (WebCore::IDBClient::IDBObjectStore::createIndex):
+        (WebCore::IDBClient::IDBObjectStore::index):
+        (WebCore::IDBClient::IDBObjectStore::deleteIndex):
+        (WebCore::IDBClient::IDBObjectStore::count):
+        (WebCore::IDBClient::IDBObjectStore::doCount):
+        * Modules/indexeddb/client/IDBObjectStoreImpl.h:
+
+        * Modules/indexeddb/client/IDBRequestImpl.cpp:
+        (WebCore::IDBClient::IDBRequest::result):
+        (WebCore::IDBClient::IDBRequest::error):
+        * Modules/indexeddb/client/IDBRequestImpl.h:
+
+        * Modules/indexeddb/client/IDBTransactionImpl.cpp:
+        (WebCore::IDBClient::IDBTransaction::objectStore):
+        (WebCore::IDBClient::IDBTransaction::abortDueToFailedRequest):
+        (WebCore::IDBClient::IDBTransaction::abort):
+        * Modules/indexeddb/client/IDBTransactionImpl.h:
+
+        * Modules/indexeddb/legacy/LegacyCursor.cpp:
+        (WebCore::LegacyCursor::update):
+        (WebCore::LegacyCursor::continueFunction):
+        (WebCore::LegacyCursor::deleteFunction):
+        * Modules/indexeddb/legacy/LegacyCursor.h:
+
+        * Modules/indexeddb/legacy/LegacyDatabase.cpp:
+        (WebCore::LegacyDatabase::createObjectStore):
+        (WebCore::LegacyDatabase::deleteObjectStore):
+        (WebCore::LegacyDatabase::transaction):
+        (WebCore::LegacyDatabase::forceClose):
+        * Modules/indexeddb/legacy/LegacyDatabase.h:
+
+        * Modules/indexeddb/legacy/LegacyFactory.cpp:
+        (WebCore::LegacyFactory::cmp):
+        * Modules/indexeddb/legacy/LegacyFactory.h:
+
+        * Modules/indexeddb/legacy/LegacyIndex.cpp:
+        (WebCore::LegacyIndex::openCursor):
+        (WebCore::LegacyIndex::count):
+        (WebCore::LegacyIndex::openKeyCursor):
+        (WebCore::LegacyIndex::get):
+        (WebCore::LegacyIndex::getKey):
+        * Modules/indexeddb/legacy/LegacyIndex.h:
+
+        * Modules/indexeddb/legacy/LegacyObjectStore.cpp:
+        (WebCore::LegacyObjectStore::get):
+        (WebCore::LegacyObjectStore::add):
+        (WebCore::LegacyObjectStore::put):
+        (WebCore::LegacyObjectStore::deleteFunction):
+        (WebCore::LegacyObjectStore::clear):
+        (WebCore::LegacyObjectStore::createIndex):
+        (WebCore::LegacyObjectStore::index):
+        (WebCore::LegacyObjectStore::deleteIndex):
+        (WebCore::LegacyObjectStore::openCursor):
+        (WebCore::LegacyObjectStore::count):
+        * Modules/indexeddb/legacy/LegacyObjectStore.h:
+        (WebCore::LegacyObjectStore::createIndex):
+        (WebCore::LegacyObjectStore::count):
+
+        * Modules/indexeddb/legacy/LegacyRequest.cpp:
+        (WebCore::LegacyRequest::result):
+        (WebCore::LegacyRequest::error):
+        (WebCore::LegacyRequest::dispatchEvent):
+        (WebCore::LegacyRequest::uncaughtExceptionInEventHandler):
+        * Modules/indexeddb/legacy/LegacyRequest.h:
+
+        * Modules/indexeddb/legacy/LegacyTransaction.cpp:
+        (WebCore::LegacyTransaction::objectStore):
+        (WebCore::LegacyTransaction::abort):
+        (WebCore::LegacyTransaction::stop):
+        * Modules/indexeddb/legacy/LegacyTransaction.h:
+
+        * bindings/js/JSDOMBinding.cpp:
+        (WebCore::createDOMException): For IDBDatabase exceptions, use createWithDescriptionAsMessage
+
+        * bindings/js/JSIDBDatabaseCustom.cpp:
+        (WebCore::JSIDBDatabase::createObjectStore):
+        (WebCore::JSIDBDatabase::transaction):
+
+        * bindings/js/JSIDBObjectStoreCustom.cpp:
+        (WebCore::putOrAdd):
+        (WebCore::JSIDBObjectStore::createIndex):
+
+        * dom/DOMCoreException.h:
+        (WebCore::DOMCoreException::createWithDescriptionAsMessage): Create an exception whose message
+          is the description.
+        (WebCore::DOMCoreException::DOMCoreException):
+
+        * dom/ExceptionBase.cpp:
+        (WebCore::ExceptionBase::ExceptionBase): Add a flag to determine where the message comes from
+        * dom/ExceptionBase.h:
+
+        * dom/make_dom_exceptions.pl:
+        (generateHeader): Add an IDBDatabaseException type
+
+        * inspector/InspectorIndexedDBAgent.cpp:
+
 2015-12-04  Joseph Pecoraro  <pecoraro@apple.com>
 
         Web Inspector: Remove untested and unused Worker inspection
index 4077244..bb24ea3 100644 (file)
@@ -65,12 +65,12 @@ public:
     virtual const Deprecated::ScriptValue& value() const = 0;
     virtual IDBAny* source() = 0;
 
-    virtual RefPtr<IDBRequest> update(JSC::ExecState&, Deprecated::ScriptValue&, ExceptionCode&) = 0;
+    virtual RefPtr<IDBRequest> update(JSC::ExecState&, Deprecated::ScriptValue&, ExceptionCodeWithMessage&) = 0;
     virtual void advance(unsigned long, ExceptionCodeWithMessage&) = 0;
     // FIXME: Try to modify the code generator so this overload is unneeded.
-    virtual void continueFunction(ScriptExecutionContext*, ExceptionCode&) = 0;
-    virtual void continueFunction(ScriptExecutionContext*, const Deprecated::ScriptValue& key, ExceptionCode&) = 0;
-    virtual RefPtr<IDBRequest> deleteFunction(ScriptExecutionContext*, ExceptionCode&) = 0;
+    virtual void continueFunction(ScriptExecutionContext*, ExceptionCodeWithMessage&) = 0;
+    virtual void continueFunction(ScriptExecutionContext*, const Deprecated::ScriptValue& key, ExceptionCodeWithMessage&) = 0;
+    virtual RefPtr<IDBRequest> deleteFunction(ScriptExecutionContext*, ExceptionCodeWithMessage&) = 0;
 
     virtual bool isKeyCursor() const = 0;
 
index 26c51bd..9edd017 100644 (file)
@@ -33,8 +33,8 @@
     readonly attribute any key;
     readonly attribute any primaryKey;
 
-    [CallWith=ScriptState, RaisesException] IDBRequest update(any value);
+    [CallWith=ScriptState, RaisesExceptionWithMessage] IDBRequest update(any value);
     [RaisesExceptionWithMessage] void advance([EnforceRange] unsigned long count);
-    [CallWith=ScriptExecutionContext, ImplementedAs=continueFunction, RaisesException] void continue(optional any key);
-    [CallWith=ScriptExecutionContext, ImplementedAs=deleteFunction, RaisesException] IDBRequest delete();
+    [CallWith=ScriptExecutionContext, ImplementedAs=continueFunction, RaisesExceptionWithMessage] void continue(optional any key);
+    [CallWith=ScriptExecutionContext, ImplementedAs=deleteFunction, RaisesExceptionWithMessage] IDBRequest delete();
 };
index 5d2b3cc..e96ecef 100644 (file)
@@ -44,7 +44,7 @@ namespace WebCore {
 
 class ScriptExecutionContext;
 
-typedef int ExceptionCode;
+struct ExceptionCodeWithMessage;
 
 class IDBDatabase : public RefCounted<IDBDatabase>, public ScriptWrappable, public EventTargetWithInlineData, public ActiveDOMObject {
 public:
@@ -55,11 +55,11 @@ public:
     virtual uint64_t version() const = 0;
     virtual RefPtr<DOMStringList> objectStoreNames() const = 0;
 
-    virtual RefPtr<IDBObjectStore> createObjectStore(const String& name, const Dictionary&, ExceptionCode&) = 0;
-    virtual RefPtr<IDBObjectStore> createObjectStore(const String& name, const IDBKeyPath&, bool autoIncrement, ExceptionCode&) = 0;
-    virtual RefPtr<IDBTransaction> transaction(ScriptExecutionContext*, const Vector<String>&, const String& mode, ExceptionCode&) = 0;
-    virtual RefPtr<IDBTransaction> transaction(ScriptExecutionContext*, const String&, const String& mode, ExceptionCode&) = 0;
-    virtual void deleteObjectStore(const String& name, ExceptionCode&) = 0;
+    virtual RefPtr<IDBObjectStore> createObjectStore(const String& name, const Dictionary&, ExceptionCodeWithMessage&) = 0;
+    virtual RefPtr<IDBObjectStore> createObjectStore(const String& name, const IDBKeyPath&, bool autoIncrement, ExceptionCodeWithMessage&) = 0;
+    virtual RefPtr<IDBTransaction> transaction(ScriptExecutionContext*, const Vector<String>&, const String& mode, ExceptionCodeWithMessage&) = 0;
+    virtual RefPtr<IDBTransaction> transaction(ScriptExecutionContext*, const String&, const String& mode, ExceptionCodeWithMessage&) = 0;
+    virtual void deleteObjectStore(const String& name, ExceptionCodeWithMessage&) = 0;
     virtual void close() = 0;
 
     using RefCounted<IDBDatabase>::ref;
index fc7dea6..cf3d9d4 100644 (file)
     readonly attribute unsigned long long version;
     readonly attribute DOMStringList objectStoreNames;
 
-    [Custom, RaisesException] IDBObjectStore createObjectStore(DOMString name, optional Dictionary options);
-    [RaisesException] void deleteObjectStore(DOMString name);
-    [Custom, CallWith=ScriptExecutionContext, RaisesException] IDBTransaction transaction(DOMString storeName, [Default=NullString] optional DOMString mode);
-    [Custom, CallWith=ScriptExecutionContext, RaisesException] IDBTransaction transaction(sequence<DOMString> storeNames, [Default=NullString] optional DOMString mode);
+    [Custom, RaisesExceptionWithMessage] IDBObjectStore createObjectStore(DOMString name, optional Dictionary options);
+    [RaisesExceptionWithMessage] void deleteObjectStore(DOMString name);
+    [Custom, CallWith=ScriptExecutionContext, RaisesExceptionWithMessage] IDBTransaction transaction(DOMString storeName, [Default=NullString] optional DOMString mode);
+    [Custom, CallWith=ScriptExecutionContext, RaisesExceptionWithMessage] IDBTransaction transaction(sequence<DOMString> storeNames, [Default=NullString] optional DOMString mode);
     void close();
 
     attribute EventHandler onabort;
index 287ccfe..5deb01f 100644 (file)
@@ -78,7 +78,7 @@ bool IDBDatabaseException::initializeDescription(ExceptionCode ec, ExceptionCode
 
     description->typeName = "DOM IDBDatabase";
     description->code = entry->code;
-    description->type = DOMCoreExceptionType;
+    description->type = IDBDatabaseExceptionType;
 
     description->name = entry ? entry->name : 0;
     description->description = entry ? entry->description : 0;
index ab274f9..3afc4ee 100644 (file)
@@ -41,6 +41,8 @@ class IDBKeyRange;
 class IDBFactoryBackendInterface;
 class ScriptExecutionContext;
 
+struct ExceptionCodeWithMessage;
+
 typedef int ExceptionCode;
 
 class IDBFactory : public RefCounted<IDBFactory> {
@@ -56,7 +58,7 @@ public:
     virtual RefPtr<IDBOpenDBRequest> open(ScriptExecutionContext*, const String& name, unsigned long long version, ExceptionCode&) = 0;
     virtual RefPtr<IDBOpenDBRequest> deleteDatabase(ScriptExecutionContext*, const String& name, ExceptionCode&) = 0;
 
-    virtual short cmp(ScriptExecutionContext*, const Deprecated::ScriptValue& first, const Deprecated::ScriptValue& second, ExceptionCode&) = 0;
+    virtual short cmp(ScriptExecutionContext*, const Deprecated::ScriptValue& first, const Deprecated::ScriptValue& second, ExceptionCodeWithMessage&) = 0;
 
 protected:
     IDBFactory();
index c87ce19..6c550da 100644 (file)
@@ -30,6 +30,6 @@
 ] interface IDBFactory {
     [CallWith=ScriptExecutionContext, RaisesException] IDBOpenDBRequest open(DOMString name, [EnforceRange] optional unsigned long long version);
     [CallWith=ScriptExecutionContext, RaisesException] IDBOpenDBRequest deleteDatabase(DOMString name);
-    [CallWith=ScriptExecutionContext, RaisesException] short cmp(any first, any second);
+    [CallWith=ScriptExecutionContext, RaisesExceptionWithMessage] short cmp(any first, any second);
 };
 
index 30e93e4..4c51d40 100644 (file)
@@ -55,27 +55,27 @@ public:
     virtual bool unique() const = 0;
     virtual bool multiEntry() const = 0;
 
-    virtual RefPtr<IDBRequest> openCursor(ScriptExecutionContext*, ExceptionCode&) = 0;
-    virtual RefPtr<IDBRequest> openCursor(ScriptExecutionContext*, IDBKeyRange*, ExceptionCode&) = 0;
-    virtual RefPtr<IDBRequest> openCursor(ScriptExecutionContext*, const Deprecated::ScriptValue& key, ExceptionCode&) = 0;
-    virtual RefPtr<IDBRequest> openCursor(ScriptExecutionContext*, IDBKeyRange*, const String& direction, ExceptionCode&) = 0;
-    virtual RefPtr<IDBRequest> openCursor(ScriptExecutionContext*, const Deprecated::ScriptValue& key, const String& direction, ExceptionCode&) = 0;
-
-    virtual RefPtr<IDBRequest> count(ScriptExecutionContext*, ExceptionCode&) = 0;
-    virtual RefPtr<IDBRequest> count(ScriptExecutionContext*, IDBKeyRange*, ExceptionCode&) = 0;
-    virtual RefPtr<IDBRequest> count(ScriptExecutionContext*, const Deprecated::ScriptValue& key, ExceptionCode&) = 0;
-
-    virtual RefPtr<IDBRequest> openKeyCursor(ScriptExecutionContext*, ExceptionCode&) = 0;
-    virtual RefPtr<IDBRequest> openKeyCursor(ScriptExecutionContext*, IDBKeyRange*, ExceptionCode&) = 0;
-    virtual RefPtr<IDBRequest> openKeyCursor(ScriptExecutionContext*, const Deprecated::ScriptValue& key, ExceptionCode&) = 0;
-    virtual RefPtr<IDBRequest> openKeyCursor(ScriptExecutionContext*, IDBKeyRange*, const String& direction, ExceptionCode&) = 0;
-    virtual RefPtr<IDBRequest> openKeyCursor(ScriptExecutionContext*, const Deprecated::ScriptValue& key, const String& direction, ExceptionCode&) = 0;
-
-    virtual RefPtr<IDBRequest> get(ScriptExecutionContext*, IDBKeyRange*, ExceptionCode&) = 0;
-    virtual RefPtr<IDBRequest> get(ScriptExecutionContext*, const Deprecated::ScriptValue& key, ExceptionCode&) = 0;
-
-    virtual RefPtr<IDBRequest> getKey(ScriptExecutionContext*, IDBKeyRange*, ExceptionCode&) = 0;
-    virtual RefPtr<IDBRequest> getKey(ScriptExecutionContext*, const Deprecated::ScriptValue& key, ExceptionCode&) = 0;
+    virtual RefPtr<IDBRequest> openCursor(ScriptExecutionContext*, ExceptionCodeWithMessage&) = 0;
+    virtual RefPtr<IDBRequest> openCursor(ScriptExecutionContext*, IDBKeyRange*, ExceptionCodeWithMessage&) = 0;
+    virtual RefPtr<IDBRequest> openCursor(ScriptExecutionContext*, const Deprecated::ScriptValue& key, ExceptionCodeWithMessage&) = 0;
+    virtual RefPtr<IDBRequest> openCursor(ScriptExecutionContext*, IDBKeyRange*, const String& direction, ExceptionCodeWithMessage&) = 0;
+    virtual RefPtr<IDBRequest> openCursor(ScriptExecutionContext*, const Deprecated::ScriptValue& key, const String& direction, ExceptionCodeWithMessage&) = 0;
+
+    virtual RefPtr<IDBRequest> count(ScriptExecutionContext*, ExceptionCodeWithMessage&) = 0;
+    virtual RefPtr<IDBRequest> count(ScriptExecutionContext*, IDBKeyRange*, ExceptionCodeWithMessage&) = 0;
+    virtual RefPtr<IDBRequest> count(ScriptExecutionContext*, const Deprecated::ScriptValue& key, ExceptionCodeWithMessage&) = 0;
+
+    virtual RefPtr<IDBRequest> openKeyCursor(ScriptExecutionContext*, ExceptionCodeWithMessage&) = 0;
+    virtual RefPtr<IDBRequest> openKeyCursor(ScriptExecutionContext*, IDBKeyRange*, ExceptionCodeWithMessage&) = 0;
+    virtual RefPtr<IDBRequest> openKeyCursor(ScriptExecutionContext*, const Deprecated::ScriptValue& key, ExceptionCodeWithMessage&) = 0;
+    virtual RefPtr<IDBRequest> openKeyCursor(ScriptExecutionContext*, IDBKeyRange*, const String& direction, ExceptionCodeWithMessage&) = 0;
+    virtual RefPtr<IDBRequest> openKeyCursor(ScriptExecutionContext*, const Deprecated::ScriptValue& key, const String& direction, ExceptionCodeWithMessage&) = 0;
+
+    virtual RefPtr<IDBRequest> get(ScriptExecutionContext*, IDBKeyRange*, ExceptionCodeWithMessage&) = 0;
+    virtual RefPtr<IDBRequest> get(ScriptExecutionContext*, const Deprecated::ScriptValue& key, ExceptionCodeWithMessage&) = 0;
+
+    virtual RefPtr<IDBRequest> getKey(ScriptExecutionContext*, IDBKeyRange*, ExceptionCodeWithMessage&) = 0;
+    virtual RefPtr<IDBRequest> getKey(ScriptExecutionContext*, const Deprecated::ScriptValue& key, ExceptionCodeWithMessage&) = 0;
 
 protected:
     IDBIndex();
index 95a106d..0e60ff6 100644 (file)
     readonly attribute boolean multiEntry;
     readonly attribute boolean unique;
 
-    [CallWith=ScriptExecutionContext, RaisesException] IDBRequest openCursor(optional IDBKeyRange? range, optional DOMString direction);
-    [CallWith=ScriptExecutionContext, RaisesException] IDBRequest openCursor(any key, optional DOMString direction);
+    [CallWith=ScriptExecutionContext, RaisesExceptionWithMessage] IDBRequest openCursor(optional IDBKeyRange? range, optional DOMString direction);
+    [CallWith=ScriptExecutionContext, RaisesExceptionWithMessage] IDBRequest openCursor(any key, optional DOMString direction);
 
-    [CallWith=ScriptExecutionContext, RaisesException] IDBRequest openKeyCursor(optional IDBKeyRange? range, optional DOMString  direction);
-    [CallWith=ScriptExecutionContext, RaisesException] IDBRequest openKeyCursor(any key, optional DOMString direction);
+    [CallWith=ScriptExecutionContext, RaisesExceptionWithMessage] IDBRequest openKeyCursor(optional IDBKeyRange? range, optional DOMString  direction);
+    [CallWith=ScriptExecutionContext, RaisesExceptionWithMessage] IDBRequest openKeyCursor(any key, optional DOMString direction);
 
-    [CallWith=ScriptExecutionContext, RaisesException] IDBRequest get(IDBKeyRange? key);
-    [CallWith=ScriptExecutionContext, RaisesException] IDBRequest get(any key);
-    [CallWith=ScriptExecutionContext, RaisesException] IDBRequest getKey(IDBKeyRange? key);
-    [CallWith=ScriptExecutionContext, RaisesException] IDBRequest getKey(any key);
-    [CallWith=ScriptExecutionContext, RaisesException] IDBRequest count(optional IDBKeyRange? range);
-    [CallWith=ScriptExecutionContext, RaisesException] IDBRequest count(any key);
+    [CallWith=ScriptExecutionContext, RaisesExceptionWithMessage] IDBRequest get(IDBKeyRange? key);
+    [CallWith=ScriptExecutionContext, RaisesExceptionWithMessage] IDBRequest get(any key);
+    [CallWith=ScriptExecutionContext, RaisesExceptionWithMessage] IDBRequest getKey(IDBKeyRange? key);
+    [CallWith=ScriptExecutionContext, RaisesExceptionWithMessage] IDBRequest getKey(any key);
+    [CallWith=ScriptExecutionContext, RaisesExceptionWithMessage] IDBRequest count(optional IDBKeyRange? range);
+    [CallWith=ScriptExecutionContext, RaisesExceptionWithMessage] IDBRequest count(any key);
 };
 
index 8113ede..4dbd725 100644 (file)
@@ -67,30 +67,30 @@ public:
     virtual RefPtr<IDBTransaction> transaction() = 0;
     virtual bool autoIncrement() const = 0;
 
-    virtual RefPtr<IDBRequest> add(JSC::ExecState&, JSC::JSValue, ExceptionCode&) = 0;
-    virtual RefPtr<IDBRequest> put(JSC::ExecState&, JSC::JSValue, ExceptionCode&) = 0;
-    virtual RefPtr<IDBRequest> openCursor(ScriptExecutionContext*, ExceptionCode&) = 0;
-    virtual RefPtr<IDBRequest> openCursor(ScriptExecutionContext*, IDBKeyRange*, ExceptionCode&) = 0;
-    virtual RefPtr<IDBRequest> openCursor(ScriptExecutionContext*, const Deprecated::ScriptValue& key, ExceptionCode&) = 0;
-    virtual RefPtr<IDBRequest> openCursor(ScriptExecutionContext*, IDBKeyRange*, const String& direction, ExceptionCode&) = 0;
-    virtual RefPtr<IDBRequest> openCursor(ScriptExecutionContext*, const Deprecated::ScriptValue& key, const String& direction, ExceptionCode&) = 0;
-
-    virtual RefPtr<IDBRequest> get(ScriptExecutionContext*, const Deprecated::ScriptValue& key, ExceptionCode&) = 0;
-    virtual RefPtr<IDBRequest> get(ScriptExecutionContext*, IDBKeyRange*, ExceptionCode&) = 0;
-    virtual RefPtr<IDBRequest> add(JSC::ExecState&, JSC::JSValue, JSC::JSValue key, ExceptionCode&) = 0;
-    virtual RefPtr<IDBRequest> put(JSC::ExecState&, JSC::JSValue, JSC::JSValue key, ExceptionCode&) = 0;
-    virtual RefPtr<IDBRequest> deleteFunction(ScriptExecutionContext*, IDBKeyRange*, ExceptionCode&) = 0;
-    virtual RefPtr<IDBRequest> deleteFunction(ScriptExecutionContext*, const Deprecated::ScriptValue& key, ExceptionCode&) = 0;
-    virtual RefPtr<IDBRequest> clear(ScriptExecutionContext*, ExceptionCode&) = 0;
-
-    virtual RefPtr<IDBIndex> createIndex(ScriptExecutionContext*, const String& name, const IDBKeyPath&, bool unique, bool multiEntry, ExceptionCode&) = 0;
-
-    virtual RefPtr<IDBIndex> index(const String& name, ExceptionCode&) = 0;
-    virtual void deleteIndex(const String& name, ExceptionCode&) = 0;
-
-    virtual RefPtr<IDBRequest> count(ScriptExecutionContext*, ExceptionCode&) = 0;
-    virtual RefPtr<IDBRequest> count(ScriptExecutionContext*, IDBKeyRange*, ExceptionCode&) = 0;
-    virtual RefPtr<IDBRequest> count(ScriptExecutionContext*, const Deprecated::ScriptValue& key, ExceptionCode&) = 0;
+    virtual RefPtr<IDBRequest> add(JSC::ExecState&, JSC::JSValue, ExceptionCodeWithMessage&) = 0;
+    virtual RefPtr<IDBRequest> put(JSC::ExecState&, JSC::JSValue, ExceptionCodeWithMessage&) = 0;
+    virtual RefPtr<IDBRequest> openCursor(ScriptExecutionContext*, ExceptionCodeWithMessage&) = 0;
+    virtual RefPtr<IDBRequest> openCursor(ScriptExecutionContext*, IDBKeyRange*, ExceptionCodeWithMessage&) = 0;
+    virtual RefPtr<IDBRequest> openCursor(ScriptExecutionContext*, const Deprecated::ScriptValue& key, ExceptionCodeWithMessage&) = 0;
+    virtual RefPtr<IDBRequest> openCursor(ScriptExecutionContext*, IDBKeyRange*, const String& direction, ExceptionCodeWithMessage&) = 0;
+    virtual RefPtr<IDBRequest> openCursor(ScriptExecutionContext*, const Deprecated::ScriptValue& key, const String& direction, ExceptionCodeWithMessage&) = 0;
+
+    virtual RefPtr<IDBRequest> get(ScriptExecutionContext*, const Deprecated::ScriptValue& key, ExceptionCodeWithMessage&) = 0;
+    virtual RefPtr<IDBRequest> get(ScriptExecutionContext*, IDBKeyRange*, ExceptionCodeWithMessage&) = 0;
+    virtual RefPtr<IDBRequest> add(JSC::ExecState&, JSC::JSValue, JSC::JSValue key, ExceptionCodeWithMessage&) = 0;
+    virtual RefPtr<IDBRequest> put(JSC::ExecState&, JSC::JSValue, JSC::JSValue key, ExceptionCodeWithMessage&) = 0;
+    virtual RefPtr<IDBRequest> deleteFunction(ScriptExecutionContext*, IDBKeyRange*, ExceptionCodeWithMessage&) = 0;
+    virtual RefPtr<IDBRequest> deleteFunction(ScriptExecutionContext*, const Deprecated::ScriptValue& key, ExceptionCodeWithMessage&) = 0;
+    virtual RefPtr<IDBRequest> clear(ScriptExecutionContext*, ExceptionCodeWithMessage&) = 0;
+
+    virtual RefPtr<IDBIndex> createIndex(ScriptExecutionContext*, const String& name, const IDBKeyPath&, bool unique, bool multiEntry, ExceptionCodeWithMessage&) = 0;
+
+    virtual RefPtr<IDBIndex> index(const String& name, ExceptionCodeWithMessage&) = 0;
+    virtual void deleteIndex(const String& name, ExceptionCodeWithMessage&) = 0;
+
+    virtual RefPtr<IDBRequest> count(ScriptExecutionContext*, ExceptionCodeWithMessage&) = 0;
+    virtual RefPtr<IDBRequest> count(ScriptExecutionContext*, IDBKeyRange*, ExceptionCodeWithMessage&) = 0;
+    virtual RefPtr<IDBRequest> count(ScriptExecutionContext*, const Deprecated::ScriptValue& key, ExceptionCodeWithMessage&) = 0;
 
 protected:
     IDBObjectStore();
index 13ccc0c..93ccb71 100644 (file)
     readonly attribute IDBTransaction transaction;
     readonly attribute boolean autoIncrement;
 
-    [CallWith=ScriptExecutionContext, Custom, ImplementedAs=putFunction, RaisesException] IDBRequest put(any value, optional any key);
-    [CallWith=ScriptExecutionContext, Custom, RaisesException] IDBRequest add(any value, optional any key);
-    [CallWith=ScriptExecutionContext, ImplementedAs=deleteFunction, RaisesException] IDBRequest delete(IDBKeyRange? keyRange);
-    [CallWith=ScriptExecutionContext, ImplementedAs=deleteFunction, RaisesException] IDBRequest delete(any key);
-    [CallWith=ScriptExecutionContext, RaisesException] IDBRequest get(IDBKeyRange? key);
-    [CallWith=ScriptExecutionContext, RaisesException] IDBRequest get(any key);
-    [CallWith=ScriptExecutionContext, RaisesException] IDBRequest clear();
-    [CallWith=ScriptExecutionContext, RaisesException] IDBRequest openCursor(optional IDBKeyRange? range, optional DOMString direction);
-    [CallWith=ScriptExecutionContext, RaisesException] IDBRequest openCursor(any key, optional DOMString direction);
-    [CallWith=ScriptExecutionContext, Custom, RaisesException] IDBIndex createIndex(DOMString name, sequence<DOMString> keyPath, optional Dictionary options);
-    [CallWith=ScriptExecutionContext, Custom, RaisesException] IDBIndex createIndex(DOMString name, DOMString keyPath, optional Dictionary options);
-    [RaisesException] IDBIndex index(DOMString name);
-    [RaisesException] void deleteIndex(DOMString name);
-    [CallWith=ScriptExecutionContext, RaisesException] IDBRequest count(optional IDBKeyRange? range);
-    [CallWith=ScriptExecutionContext, RaisesException] IDBRequest count(any key);
+    [CallWith=ScriptExecutionContext, Custom, ImplementedAs=putFunction, RaisesExceptionWithMessage] IDBRequest put(any value, optional any key);
+    [CallWith=ScriptExecutionContext, Custom, RaisesExceptionWithMessage] IDBRequest add(any value, optional any key);
+    [CallWith=ScriptExecutionContext, ImplementedAs=deleteFunction, RaisesExceptionWithMessage] IDBRequest delete(IDBKeyRange? keyRange);
+    [CallWith=ScriptExecutionContext, ImplementedAs=deleteFunction, RaisesExceptionWithMessage] IDBRequest delete(any key);
+    [CallWith=ScriptExecutionContext, RaisesExceptionWithMessage] IDBRequest get(IDBKeyRange? key);
+    [CallWith=ScriptExecutionContext, RaisesExceptionWithMessage] IDBRequest get(any key);
+    [CallWith=ScriptExecutionContext, RaisesExceptionWithMessage] IDBRequest clear();
+    [CallWith=ScriptExecutionContext, RaisesExceptionWithMessage] IDBRequest openCursor(optional IDBKeyRange? range, optional DOMString direction);
+    [CallWith=ScriptExecutionContext, RaisesExceptionWithMessage] IDBRequest openCursor(any key, optional DOMString direction);
+    [CallWith=ScriptExecutionContext, Custom, RaisesExceptionWithMessage] IDBIndex createIndex(DOMString name, sequence<DOMString> keyPath, optional Dictionary options);
+    [CallWith=ScriptExecutionContext, Custom, RaisesExceptionWithMessage] IDBIndex createIndex(DOMString name, DOMString keyPath, optional Dictionary options);
+    [RaisesExceptionWithMessage] IDBIndex index(DOMString name);
+    [RaisesExceptionWithMessage] void deleteIndex(DOMString name);
+    [CallWith=ScriptExecutionContext, RaisesExceptionWithMessage] IDBRequest count(optional IDBKeyRange? range);
+    [CallWith=ScriptExecutionContext, RaisesExceptionWithMessage] IDBRequest count(any key);
 };
index f3109c1..f41b174 100644 (file)
@@ -42,6 +42,8 @@ namespace WebCore {
 
 class IDBTransaction;
 
+struct ExceptionCodeWithMessage;
+
 typedef int ExceptionCode;
 
 // Defined in the IDL
@@ -55,9 +57,9 @@ class IDBRequest : public ScriptWrappable, public EventTargetWithInlineData, pub
 public:
     virtual ~IDBRequest() { }
 
-    virtual RefPtr<IDBAny> result(ExceptionCode&) const = 0;
+    virtual RefPtr<IDBAny> result(ExceptionCodeWithMessage&) const = 0;
     virtual unsigned short errorCode(ExceptionCode&) const = 0;
-    virtual RefPtr<DOMError> error(ExceptionCode&) const = 0;
+    virtual RefPtr<DOMError> error(ExceptionCodeWithMessage&) const = 0;
     virtual RefPtr<IDBAny> source() const = 0;
     virtual RefPtr<IDBTransaction> transaction() const = 0;
 
index 3dbdf8d..fea8ebe 100644 (file)
@@ -36,8 +36,8 @@
     JSGenerateToNativeObject,
     SkipVTableValidation,
 ] interface IDBRequest : EventTarget {
-    [GetterRaisesException] readonly attribute IDBAny result;
-    [GetterRaisesException] readonly attribute DOMError error;
+    [GetterRaisesExceptionWithMessage] readonly attribute IDBAny result;
+    [GetterRaisesExceptionWithMessage] readonly attribute DOMError error;
     readonly attribute IDBAny source;
     readonly attribute IDBTransaction transaction;
     readonly attribute DOMString readyState;
index ed9774f..0043e00 100644 (file)
@@ -44,6 +44,8 @@ class IDBDatabaseBackend;
 class IDBDatabaseError;
 class IDBObjectStore;
 class IDBOpenDBRequest;
+
+struct ExceptionCodeWithMessage;
 struct IDBObjectStoreMetadata;
 
 class IDBTransaction : public ScriptWrappable, public RefCounted<IDBTransaction>, public EventTargetWithInlineData, public ActiveDOMObject {
@@ -63,8 +65,8 @@ public:
     virtual const String& mode() const = 0;
     virtual IDBDatabase* db() = 0;
     virtual RefPtr<DOMError> error() const = 0;
-    virtual RefPtr<IDBObjectStore> objectStore(const String& name, ExceptionCode&) = 0;
-    virtual void abort(ExceptionCode&) = 0;
+    virtual RefPtr<IDBObjectStore> objectStore(const String& name, ExceptionCodeWithMessage&) = 0;
+    virtual void abort(ExceptionCodeWithMessage&) = 0;
 
     using RefCounted<IDBTransaction>::ref;
     using RefCounted<IDBTransaction>::deref;
index cc89c50..da27b28 100644 (file)
@@ -37,8 +37,8 @@
     readonly attribute IDBDatabase db;
     readonly attribute DOMError error;
 
-    [RaisesException] IDBObjectStore objectStore (DOMString name);
-    [RaisesException] void abort ();
+    [RaisesExceptionWithMessage] IDBObjectStore objectStore (DOMString name);
+    [RaisesExceptionWithMessage] void abort ();
 
     attribute EventHandler onabort;
     attribute EventHandler oncomplete;
index 59b67f9..bb2be9e 100644 (file)
@@ -110,36 +110,56 @@ IDBAny* IDBCursor::source()
     return &m_source.get();
 }
 
-RefPtr<WebCore::IDBRequest> IDBCursor::update(JSC::ExecState& exec, Deprecated::ScriptValue& value, ExceptionCode& ec)
+RefPtr<WebCore::IDBRequest> IDBCursor::update(JSC::ExecState& exec, Deprecated::ScriptValue& value, ExceptionCodeWithMessage& ec)
 {
     LOG(IndexedDB, "IDBCursor::update");
 
     if (sourcesDeleted()) {
-        ec = IDBDatabaseException::InvalidStateError;
+        ec.code = IDBDatabaseException::InvalidStateError;
         return nullptr;
     }
 
     if (!transaction().isActive()) {
-        ec = IDBDatabaseException::TransactionInactiveError;
+        ec.code = IDBDatabaseException::TransactionInactiveError;
+        ec.message = ASCIILiteral("Failed to execute 'update' on 'IDBCursor': The transaction is inactive or finished.");
         return nullptr;
     }
 
     if (transaction().isReadOnly()) {
-        ec = IDBDatabaseException::ReadOnlyError;
+        ec.code = IDBDatabaseException::ReadOnlyError;
+        ec.message = ASCIILiteral("Failed to execute 'update' on 'IDBCursor': The record may not be updated inside a read-only transaction.");
         return nullptr;
     }
 
     if (!m_gotValue) {
-        ec = IDBDatabaseException::InvalidStateError;
+        ec.code = IDBDatabaseException::InvalidStateError;
         return nullptr;
     }
 
     if (isKeyCursor()) {
-        ec = IDBDatabaseException::InvalidStateError;
+        ec.code = IDBDatabaseException::InvalidStateError;
+        ec.message = ASCIILiteral("Failed to execute 'update' on 'IDBCursor': The cursor is a key cursor.");
         return nullptr;
     }
 
+    auto& objectStore = effectiveObjectStore();
+    auto& keyPath = objectStore.info().keyPath();
+    const bool usesInLineKeys = !keyPath.isNull();
+    if (usesInLineKeys) {
+        RefPtr<IDBKey> keyPathKey = maybeCreateIDBKeyFromScriptValueAndKeyPath(exec, value, keyPath);
+        IDBKeyData keyPathKeyData(keyPathKey.get());
+        if (!keyPathKey || keyPathKeyData != m_currentPrimaryKeyData) {
+            ec.code = IDBDatabaseException::DataError;
+            ec.message = ASCIILiteral("Failed to execute 'update' on 'IDBCursor': The effective object store of this cursor uses in-line keys and evaluating the key path of the value parameter results in a different value than the cursor's effective key.");
+            return nullptr;
+        }
+    }
+
     auto request = effectiveObjectStore().putForCursorUpdate(exec, value.jsValue(), m_deprecatedCurrentPrimaryKey.jsValue(), ec);
+    if (ec.code)
+        return nullptr;
+
+    ASSERT(request);
     request->setSource(*this);
     return request;
 }
@@ -166,11 +186,13 @@ void IDBCursor::advance(unsigned long count, ExceptionCodeWithMessage& ec)
 
     if (!transaction().isActive()) {
         ec.code = IDBDatabaseException::TransactionInactiveError;
+        ec.message = ASCIILiteral("Failed to execute 'advance' on 'IDBCursor': The transaction is inactive or finished.");
         return;
     }
 
     if (!m_gotValue) {
         ec.code = IDBDatabaseException::InvalidStateError;
+        ec.message = ASCIILiteral("Failed to execute 'advance' on 'IDBCursor': The cursor is being iterated or has iterated past its end.");
         return;
     }
 
@@ -179,20 +201,20 @@ void IDBCursor::advance(unsigned long count, ExceptionCodeWithMessage& ec)
     uncheckedIteratorCursor(IDBKeyData(), count);
 }
 
-void IDBCursor::continueFunction(ScriptExecutionContext* context, ExceptionCode& ec)
+void IDBCursor::continueFunction(ScriptExecutionContext* context, ExceptionCodeWithMessage& ec)
 {
     if (!context) {
-        ec = IDBDatabaseException::InvalidStateError;
+        ec.code = IDBDatabaseException::InvalidStateError;
         return;
     }
 
     continueFunction(IDBKeyData(), ec);
 }
 
-void IDBCursor::continueFunction(ScriptExecutionContext* context, const Deprecated::ScriptValue& keyValue, ExceptionCode& ec)
+void IDBCursor::continueFunction(ScriptExecutionContext* context, const Deprecated::ScriptValue& keyValue, ExceptionCodeWithMessage& ec)
 {
     if (!context) {
-        ec = IDBDatabaseException::InvalidStateError;
+        ec.code = IDBDatabaseException::InvalidStateError;
         return;
     }
 
@@ -201,42 +223,47 @@ void IDBCursor::continueFunction(ScriptExecutionContext* context, const Deprecat
     continueFunction(key.get(), ec);
 }
 
-void IDBCursor::continueFunction(const IDBKeyData& key, ExceptionCode& ec)
+void IDBCursor::continueFunction(const IDBKeyData& key, ExceptionCodeWithMessage& ec)
 {
     LOG(IndexedDB, "IDBCursor::continueFunction");
 
     if (!m_request) {
-        ec = IDBDatabaseException::InvalidStateError;
+        ec.code = IDBDatabaseException::InvalidStateError;
         return;
     }
 
     if (sourcesDeleted()) {
-        ec = IDBDatabaseException::InvalidStateError;
+        ec.code = IDBDatabaseException::InvalidStateError;
         return;
     }
 
     if (!transaction().isActive()) {
-        ec = IDBDatabaseException::TransactionInactiveError;
+        ec.code = IDBDatabaseException::TransactionInactiveError;
+        ec.message = ASCIILiteral("Failed to execute 'continue' on 'IDBCursor': The transaction is inactive or finished.");
         return;
     }
 
     if (!m_gotValue) {
-        ec = IDBDatabaseException::InvalidStateError;
+        ec.code = IDBDatabaseException::InvalidStateError;
+        ec.message = ASCIILiteral("Failed to execute 'continue' on 'IDBCursor': The cursor is being iterated or has iterated past its end.");
         return;
     }
 
     if (!key.isNull() && !key.isValid()) {
-        ec = IDBDatabaseException::DataError;
+        ec.code = IDBDatabaseException::DataError;
+        ec.message = ASCIILiteral("Failed to execute 'continue' on 'IDBCursor': The parameter is not a valid key.");
         return;
     }
 
     if (m_info.isDirectionForward()) {
         if (!key.isNull() && key.compare(m_currentPrimaryKeyData) <= 0) {
-            ec = IDBDatabaseException::DataError;
+            ec.code = IDBDatabaseException::DataError;
+            ec.message = ASCIILiteral("Failed to execute 'continue' on 'IDBCursor': The parameter is less than or equal to this cursor's position.");
             return;
         }
     } else if (!key.isNull() && key.compare(m_currentPrimaryKeyData) >= 0) {
-        ec = IDBDatabaseException::DataError;
+        ec.code = IDBDatabaseException::DataError;
+        ec.message = ASCIILiteral("Failed to execute 'continue' on 'IDBCursor': The parameter is greater than or equal to this cursor's position.");
         return;
     }
 
@@ -251,32 +278,40 @@ void IDBCursor::uncheckedIteratorCursor(const IDBKeyData& key, unsigned long cou
     transaction().iterateCursor(*this, key, count);
 }
 
-RefPtr<WebCore::IDBRequest> IDBCursor::deleteFunction(ScriptExecutionContext* context, ExceptionCode& ec)
+RefPtr<WebCore::IDBRequest> IDBCursor::deleteFunction(ScriptExecutionContext* context, ExceptionCodeWithMessage& ec)
 {
     LOG(IndexedDB, "IDBCursor::deleteFunction");
 
     if (!context) {
-        ec = IDBDatabaseException::InvalidStateError;
+        ec.code = IDBDatabaseException::InvalidStateError;
         return nullptr;
     }
 
     if (sourcesDeleted()) {
-        ec = IDBDatabaseException::InvalidStateError;
+        ec.code = IDBDatabaseException::InvalidStateError;
         return nullptr;
     }
 
     if (!transaction().isActive()) {
-        ec = IDBDatabaseException::TransactionInactiveError;
+        ec.code = IDBDatabaseException::TransactionInactiveError;
+        ec.message = ASCIILiteral("Failed to execute 'delete' on 'IDBCursor': The transaction is inactive or finished.");
         return nullptr;
     }
 
     if (transaction().isReadOnly()) {
-        ec = IDBDatabaseException::ReadOnlyError;
+        ec.code = IDBDatabaseException::ReadOnlyError;
+        ec.message = ASCIILiteral("Failed to execute 'delete' on 'IDBCursor': The record may not be deleted inside a read-only transaction.");
         return nullptr;
     }
 
     if (!m_gotValue) {
-        ec = IDBDatabaseException::InvalidStateError;
+        ec.code = IDBDatabaseException::InvalidStateError;
+        return nullptr;
+    }
+
+    if (isKeyCursor()) {
+        ec.code = IDBDatabaseException::InvalidStateError;
+        ec.message = ASCIILiteral("Failed to execute 'delete' on 'IDBCursor': The cursor is a key cursor.");
         return nullptr;
     }
 
index 3e37040..bc88f1d 100644 (file)
@@ -55,13 +55,13 @@ public:
     virtual const Deprecated::ScriptValue& value() const override final;
     virtual IDBAny* source() override final;
 
-    virtual RefPtr<WebCore::IDBRequest> update(JSC::ExecState&, Deprecated::ScriptValue&, ExceptionCode&) override final;
+    virtual RefPtr<WebCore::IDBRequest> update(JSC::ExecState&, Deprecated::ScriptValue&, ExceptionCodeWithMessage&) override final;
     virtual void advance(unsigned long, ExceptionCodeWithMessage&) override final;
-    virtual void continueFunction(ScriptExecutionContext*, ExceptionCode&) override final;
-    virtual void continueFunction(ScriptExecutionContext*, const Deprecated::ScriptValue& key, ExceptionCode&) override final;
-    virtual RefPtr<WebCore::IDBRequest> deleteFunction(ScriptExecutionContext*, ExceptionCode&) override final;
+    virtual void continueFunction(ScriptExecutionContext*, ExceptionCodeWithMessage&) override final;
+    virtual void continueFunction(ScriptExecutionContext*, const Deprecated::ScriptValue& key, ExceptionCodeWithMessage&) override final;
+    virtual RefPtr<WebCore::IDBRequest> deleteFunction(ScriptExecutionContext*, ExceptionCodeWithMessage&) override final;
 
-    void continueFunction(const IDBKeyData&, ExceptionCode&);
+    void continueFunction(const IDBKeyData&, ExceptionCodeWithMessage&);
 
     const IDBCursorInfo& info() const { return m_info; }
 
index 5303a6b..e825cdf 100644 (file)
@@ -86,41 +86,45 @@ RefPtr<DOMStringList> IDBDatabase::objectStoreNames() const
     return WTF::move(objectStoreNames);
 }
 
-RefPtr<WebCore::IDBObjectStore> IDBDatabase::createObjectStore(const String&, const Dictionary&, ExceptionCode&)
+RefPtr<WebCore::IDBObjectStore> IDBDatabase::createObjectStore(const String&, const Dictionary&, ExceptionCodeWithMessage&)
 {
     ASSERT_NOT_REACHED();
     return nullptr;
 }
 
-RefPtr<WebCore::IDBObjectStore> IDBDatabase::createObjectStore(const String& name, const IDBKeyPath& keyPath, bool autoIncrement, ExceptionCode& ec)
+RefPtr<WebCore::IDBObjectStore> IDBDatabase::createObjectStore(const String& name, const IDBKeyPath& keyPath, bool autoIncrement, ExceptionCodeWithMessage& ec)
 {
     LOG(IndexedDB, "IDBDatabase::createObjectStore");
 
     ASSERT(!m_versionChangeTransaction || m_versionChangeTransaction->isVersionChange());
 
     if (!m_versionChangeTransaction) {
-        ec = IDBDatabaseException::InvalidStateError;
+        ec.code = IDBDatabaseException::InvalidStateError;
+        ec.message = ASCIILiteral("Failed to execute 'createObjectStore' on 'IDBDatabase': The database is not running a version change transaction.");
         return nullptr;
     }
 
     if (!m_versionChangeTransaction->isActive()) {
-        ec = IDBDatabaseException::TransactionInactiveError;
+        ec.code = IDBDatabaseException::TransactionInactiveError;
         return nullptr;
     }
 
     if (m_info.hasObjectStore(name)) {
-        ec = IDBDatabaseException::ConstraintError;
+        ec.code = IDBDatabaseException::ConstraintError;
+        ec.message = ASCIILiteral("Failed to execute 'createObjectStore' on 'IDBDatabase': An object store with the specified name already exists.");
         return nullptr;
     }
 
     if (!keyPath.isNull() && !keyPath.isValid()) {
-        ec = IDBDatabaseException::SyntaxError;
+        ec.code = IDBDatabaseException::SyntaxError;
+        ec.message = ASCIILiteral("Failed to execute 'createObjectStore' on 'IDBDatabase': The keyPath option is not a valid key path.");
         return nullptr;
     }
 
     if (autoIncrement && !keyPath.isNull()) {
         if ((keyPath.type() == IndexedDB::KeyPathType::String && keyPath.string().isEmpty()) || keyPath.type() == IndexedDB::KeyPathType::Array) {
-            ec = IDBDatabaseException::InvalidAccessError;
+            ec.code = IDBDatabaseException::InvalidAccessError;
+            ec.message = ASCIILiteral("Failed to execute 'createObjectStore' on 'IDBDatabase': The autoIncrement option was set but the keyPath option was empty or an array.");
             return nullptr;
         }
     }
@@ -133,38 +137,43 @@ RefPtr<WebCore::IDBObjectStore> IDBDatabase::createObjectStore(const String& nam
     return adoptRef(&objectStore.leakRef());
 }
 
-RefPtr<WebCore::IDBTransaction> IDBDatabase::transaction(ScriptExecutionContext*, const Vector<String>& objectStores, const String& modeString, ExceptionCode& ec)
+RefPtr<WebCore::IDBTransaction> IDBDatabase::transaction(ScriptExecutionContext*, const Vector<String>& objectStores, const String& modeString, ExceptionCodeWithMessage& ec)
 {
     LOG(IndexedDB, "IDBDatabase::transaction");
 
     if (m_closePending) {
-        ec = IDBDatabaseException::InvalidStateError;
+        ec.code = IDBDatabaseException::InvalidStateError;
         return nullptr;
     }
 
     if (objectStores.isEmpty()) {
-        ec = IDBDatabaseException::InvalidAccessError;
+        ec.code = IDBDatabaseException::InvalidAccessError;
+        ec.message = ASCIILiteral("Failed to execute 'transaction' on 'IDBDatabase': The storeNames parameter was empty.");
         return nullptr;
     }
 
-    IndexedDB::TransactionMode mode = IDBTransaction::stringToMode(modeString, ec);
-    if (ec)
+    IndexedDB::TransactionMode mode = IDBTransaction::stringToMode(modeString, ec.code);
+    if (ec.code) {
+        ec.message = ASCIILiteral("Failed to execute 'transaction' on 'IDBDatabase': The mode provided ('invalid-mode') is not one of 'readonly' or 'readwrite'.");
         return nullptr;
+    }
 
     if (mode != IndexedDB::TransactionMode::ReadOnly && mode != IndexedDB::TransactionMode::ReadWrite) {
-        ec = TypeError;
+        ec.code = TypeError;
         return nullptr;
     }
 
     if (m_versionChangeTransaction && !m_versionChangeTransaction->isFinishedOrFinishing()) {
-        ec = IDBDatabaseException::InvalidStateError;
+        ec.code = IDBDatabaseException::InvalidStateError;
+        ec.message = ASCIILiteral("Failed to execute 'transaction' on 'IDBDatabase': A version change transaction is running.");
         return nullptr;
     }
 
     for (auto& objectStoreName : objectStores) {
         if (m_info.hasObjectStore(objectStoreName))
             continue;
-        ec = IDBDatabaseException::NotFoundError;
+        ec.code = IDBDatabaseException::NotFoundError;
+        ec.message = ASCIILiteral("Failed to execute 'transaction' on 'IDBDatabase': One of the specified object stores was not found.");
         return nullptr;
     }
 
@@ -178,29 +187,31 @@ RefPtr<WebCore::IDBTransaction> IDBDatabase::transaction(ScriptExecutionContext*
     return adoptRef(&transaction.leakRef());
 }
 
-RefPtr<WebCore::IDBTransaction> IDBDatabase::transaction(ScriptExecutionContext* context, const String& objectStore, const String& mode, ExceptionCode& ec)
+RefPtr<WebCore::IDBTransaction> IDBDatabase::transaction(ScriptExecutionContext* context, const String& objectStore, const String& mode, ExceptionCodeWithMessage& ec)
 {
     Vector<String> objectStores(1);
     objectStores[0] = objectStore;
     return transaction(context, objectStores, mode, ec);
 }
 
-void IDBDatabase::deleteObjectStore(const String& objectStoreName, ExceptionCode& ec)
+void IDBDatabase::deleteObjectStore(const String& objectStoreName, ExceptionCodeWithMessage& ec)
 {
     LOG(IndexedDB, "IDBDatabase::deleteObjectStore");
 
     if (!m_versionChangeTransaction) {
-        ec = IDBDatabaseException::InvalidStateError;
+        ec.code = IDBDatabaseException::InvalidStateError;
+        ec.message = ASCIILiteral("Failed to execute 'deleteObjectStore' on 'IDBDatabase': The database is not running a version change transaction.");
         return;
     }
 
     if (!m_versionChangeTransaction->isActive()) {
-        ec = IDBDatabaseException::TransactionInactiveError;
+        ec.code = IDBDatabaseException::TransactionInactiveError;
         return;
     }
 
     if (!m_info.hasObjectStore(objectStoreName)) {
-        ec = IDBDatabaseException::NotFoundError;
+        ec.code = IDBDatabaseException::NotFoundError;
+        ec.message = ASCIILiteral("Failed to execute 'deleteObjectStore' on 'IDBDatabase': The specified object store was not found.");
         return;
     }
 
index b13f60a..241a26e 100644 (file)
@@ -53,11 +53,11 @@ public:
     virtual uint64_t version() const override final;
     virtual RefPtr<DOMStringList> objectStoreNames() const override final;
 
-    virtual RefPtr<WebCore::IDBObjectStore> createObjectStore(const String& name, const Dictionary&, ExceptionCode&) override final;
-    virtual RefPtr<WebCore::IDBObjectStore> createObjectStore(const String& name, const IDBKeyPath&, bool autoIncrement, ExceptionCode&) override final;
-    virtual RefPtr<WebCore::IDBTransaction> transaction(ScriptExecutionContext*, const Vector<String>&, const String& mode, ExceptionCode&) override final;
-    virtual RefPtr<WebCore::IDBTransaction> transaction(ScriptExecutionContext*, const String&, const String& mode, ExceptionCode&) override final;
-    virtual void deleteObjectStore(const String& name, ExceptionCode&) override final;
+    virtual RefPtr<WebCore::IDBObjectStore> createObjectStore(const String& name, const Dictionary&, ExceptionCodeWithMessage&) override final;
+    virtual RefPtr<WebCore::IDBObjectStore> createObjectStore(const String& name, const IDBKeyPath&, bool autoIncrement, ExceptionCodeWithMessage&) override final;
+    virtual RefPtr<WebCore::IDBTransaction> transaction(ScriptExecutionContext*, const Vector<String>&, const String& mode, ExceptionCodeWithMessage&) override final;
+    virtual RefPtr<WebCore::IDBTransaction> transaction(ScriptExecutionContext*, const String&, const String& mode, ExceptionCodeWithMessage&) override final;
+    virtual void deleteObjectStore(const String& name, ExceptionCodeWithMessage&) override final;
     virtual void close() override final;
 
     // EventTarget
index ffe67f3..fda69b5 100644 (file)
 
 #if ENABLE(INDEXED_DATABASE)
 
+#include "DOMRequestState.h"
 #include "Document.h"
 #include "ExceptionCode.h"
+#include "IDBBindingUtilities.h"
 #include "IDBDatabaseIdentifier.h"
 #include "IDBOpenDBRequestImpl.h"
 #include "Logging.h"
@@ -148,9 +150,22 @@ RefPtr<WebCore::IDBOpenDBRequest> IDBFactory::deleteDatabase(ScriptExecutionCont
     return adoptRef(&request.leakRef());
 }
 
-short IDBFactory::cmp(ScriptExecutionContext*, const Deprecated::ScriptValue&, const Deprecated::ScriptValue&, ExceptionCode&)
+short IDBFactory::cmp(ScriptExecutionContext* context, const Deprecated::ScriptValue& firstValue, const Deprecated::ScriptValue& secondValue, ExceptionCodeWithMessage& ec)
 {
-    return 0;
+    DOMRequestState requestState(context);
+    RefPtr<IDBKey> first = scriptValueToIDBKey(&requestState, firstValue);
+    RefPtr<IDBKey> second = scriptValueToIDBKey(&requestState, secondValue);
+
+    ASSERT(first);
+    ASSERT(second);
+
+    if (!first->isValid() || !second->isValid()) {
+        ec.code = IDBDatabaseException::DataError;
+        ec.message = ASCIILiteral("Failed to execute 'cmp' on 'IDBFactory': The parameter is not a valid key.");
+        return 0;
+    }
+
+    return static_cast<short>(first->compare(second.get()));
 }
 
 } // namespace IDBClient
index 8047376..6859be1 100644 (file)
@@ -46,7 +46,7 @@ public:
     virtual RefPtr<WebCore::IDBOpenDBRequest> open(ScriptExecutionContext*, const String& name, unsigned long long version, ExceptionCode&) override final;
     virtual RefPtr<WebCore::IDBOpenDBRequest> deleteDatabase(ScriptExecutionContext*, const String& name, ExceptionCode&) override final;
 
-    virtual short cmp(ScriptExecutionContext*, const Deprecated::ScriptValue& first, const Deprecated::ScriptValue& second, ExceptionCode&) override final;
+    virtual short cmp(ScriptExecutionContext*, const Deprecated::ScriptValue& first, const Deprecated::ScriptValue& second, ExceptionCodeWithMessage&) override final;
 
 private:
     IDBFactory(IDBConnectionToServer&);
index 2f6dcd3..7f427d0 100644 (file)
@@ -86,23 +86,26 @@ bool IDBIndex::multiEntry() const
     return m_info.multiEntry();
 }
 
-RefPtr<WebCore::IDBRequest> IDBIndex::openCursor(ScriptExecutionContext* context, IDBKeyRange* range, const String& directionString, ExceptionCode& ec)
+RefPtr<WebCore::IDBRequest> IDBIndex::openCursor(ScriptExecutionContext* context, IDBKeyRange* range, const String& directionString, ExceptionCodeWithMessage& ec)
 {
     LOG(IndexedDB, "IDBIndex::openCursor");
 
     if (m_deleted || m_objectStore->isDeleted()) {
-        ec = IDBDatabaseException::InvalidStateError;
+        ec.code = IDBDatabaseException::InvalidStateError;
         return nullptr;
     }
 
     if (!m_objectStore->modernTransaction().isActive()) {
-        ec = IDBDatabaseException::TransactionInactiveError;
+        ec.code = IDBDatabaseException::TransactionInactiveError;
+        ec.message = ASCIILiteral("Failed to execute 'openCursor' on 'IDBIndex': The transaction is inactive or finished.");
         return nullptr;
     }
 
-    IndexedDB::CursorDirection direction = IDBCursor::stringToDirection(directionString, ec);
-    if (ec)
+    IndexedDB::CursorDirection direction = IDBCursor::stringToDirection(directionString, ec.code);
+    if (ec.code) {
+        ec.message = ASCIILiteral("Failed to execute 'openCursor' on 'IDBIndex': The direction provided ('invalid-direction') is not one of 'next', 'nextunique', 'prev', or 'prevunique'.");
         return nullptr;
+    }
 
     IDBKeyRangeData rangeData = range;
     if (rangeData.lowerKey.isNull())
@@ -115,22 +118,24 @@ RefPtr<WebCore::IDBRequest> IDBIndex::openCursor(ScriptExecutionContext* context
     return WTF::move(request);
 }
 
-RefPtr<WebCore::IDBRequest> IDBIndex::openCursor(ScriptExecutionContext* context, const Deprecated::ScriptValue& key, const String& direction, ExceptionCode& ec)
+RefPtr<WebCore::IDBRequest> IDBIndex::openCursor(ScriptExecutionContext* context, const Deprecated::ScriptValue& key, const String& direction, ExceptionCodeWithMessage& ec)
 {
     LOG(IndexedDB, "IDBIndex::openCursor");
-    RefPtr<IDBKeyRange> keyRange = IDBKeyRange::only(context, key, ec);
-    if (ec)
+    RefPtr<IDBKeyRange> keyRange = IDBKeyRange::only(context, key, ec.code);
+    if (ec.code) {
+        ec.message = ASCIILiteral("Failed to execute 'openCursor' on 'IDBIndex': The parameter is not a valid key.");
         return nullptr;
+    }
 
     return openCursor(context, keyRange.get(), direction, ec);
 }
 
-RefPtr<WebCore::IDBRequest> IDBIndex::count(ScriptExecutionContext* context, ExceptionCode& ec)
+RefPtr<WebCore::IDBRequest> IDBIndex::count(ScriptExecutionContext* context, ExceptionCodeWithMessage& ec)
 {
     LOG(IndexedDB, "IDBIndex::count");
 
     if (!context) {
-        ec = INVALID_STATE_ERR;
+        ec.code = IDBDatabaseException::InvalidStateError;
         return nullptr;
     }
 
@@ -138,189 +143,199 @@ RefPtr<WebCore::IDBRequest> IDBIndex::count(ScriptExecutionContext* context, Exc
     range.isNull = false;
     return doCount(*context, range, ec);}
 
-RefPtr<WebCore::IDBRequest> IDBIndex::count(ScriptExecutionContext* context, IDBKeyRange* range, ExceptionCode& ec)
+RefPtr<WebCore::IDBRequest> IDBIndex::count(ScriptExecutionContext* context, IDBKeyRange* range, ExceptionCodeWithMessage& ec)
 {
     LOG(IndexedDB, "IDBIndex::count");
 
     if (!context) {
-        ec = INVALID_STATE_ERR;
+        ec.code = IDBDatabaseException::InvalidStateError;
         return nullptr;
     }
 
     return doCount(*context, IDBKeyRangeData(range), ec);
 }
 
-RefPtr<WebCore::IDBRequest> IDBIndex::count(ScriptExecutionContext* context, const Deprecated::ScriptValue& key, ExceptionCode& ec)
+RefPtr<WebCore::IDBRequest> IDBIndex::count(ScriptExecutionContext* context, const Deprecated::ScriptValue& key, ExceptionCodeWithMessage& ec)
 {
     LOG(IndexedDB, "IDBIndex::count");
 
     if (!context) {
-        ec = INVALID_STATE_ERR;
+        ec.code = IDBDatabaseException::InvalidStateError;
         return nullptr;
     }
 
     DOMRequestState requestState(context);
     RefPtr<IDBKey> idbKey = scriptValueToIDBKey(&requestState, key);
     if (!idbKey || idbKey->type() == KeyType::Invalid) {
-        ec = static_cast<ExceptionCode>(IDBDatabaseException::DataError);
+        ec.code = IDBDatabaseException::DataError;
+        ec.message = ASCIILiteral("Failed to execute 'count' on 'IDBIndex': The parameter is not a valid key.");
         return nullptr;
     }
 
     return doCount(*context, IDBKeyRangeData(idbKey.get()), ec);
 }
 
-RefPtr<WebCore::IDBRequest> IDBIndex::doCount(ScriptExecutionContext& context, const IDBKeyRangeData& range, ExceptionCode& ec)
+RefPtr<WebCore::IDBRequest> IDBIndex::doCount(ScriptExecutionContext& context, const IDBKeyRangeData& range, ExceptionCodeWithMessage& ec)
 {
     if (m_deleted || m_objectStore->isDeleted()) {
-        ec = INVALID_STATE_ERR;
+        ec.code = IDBDatabaseException::InvalidStateError;
         return nullptr;
     }
 
     if (range.isNull) {
-        ec = static_cast<ExceptionCode>(IDBDatabaseException::DataError);
+        ec.code = IDBDatabaseException::DataError;
         return nullptr;
     }
 
     auto& transaction = m_objectStore->modernTransaction();
     if (!transaction.isActive()) {
-        ec = static_cast<ExceptionCode>(IDBDatabaseException::TransactionInactiveError);
+        ec.code = IDBDatabaseException::TransactionInactiveError;
+        ec.message = ASCIILiteral("Failed to execute 'count' on 'IDBIndex': The transaction is inactive or finished.");
         return nullptr;
     }
 
     return transaction.requestCount(context, *this, range);
 }
 
-RefPtr<WebCore::IDBRequest> IDBIndex::openKeyCursor(ScriptExecutionContext* context, IDBKeyRange* range, const String& directionString, ExceptionCode& ec)
+RefPtr<WebCore::IDBRequest> IDBIndex::openKeyCursor(ScriptExecutionContext* context, IDBKeyRange* range, const String& directionString, ExceptionCodeWithMessage& ec)
 {
     LOG(IndexedDB, "IDBIndex::openKeyCursor");
 
     if (m_deleted || m_objectStore->isDeleted()) {
-        ec = IDBDatabaseException::InvalidStateError;
+        ec.code = IDBDatabaseException::InvalidStateError;
         return nullptr;
     }
 
     if (!m_objectStore->modernTransaction().isActive()) {
-        ec = IDBDatabaseException::TransactionInactiveError;
+        ec.code = IDBDatabaseException::TransactionInactiveError;
+        ec.message = ASCIILiteral("Failed to execute 'openKeyCursor' on 'IDBIndex': The transaction is inactive or finished.");
         return nullptr;
     }
 
-    IndexedDB::CursorDirection direction = IDBCursor::stringToDirection(directionString, ec);
-    if (ec)
+    IndexedDB::CursorDirection direction = IDBCursor::stringToDirection(directionString, ec.code);
+    if (ec.code) {
+        ec.message = ASCIILiteral("Failed to execute 'openKeyCursor' on 'IDBIndex': The direction provided ('invalid-direction') is not one of 'next', 'nextunique', 'prev', or 'prevunique'.");
         return nullptr;
+    }
 
     auto info = IDBCursorInfo::indexCursor(m_objectStore->modernTransaction(), m_objectStore->info().identifier(), m_info.identifier(), range, direction, IndexedDB::CursorType::KeyOnly);
     Ref<IDBRequest> request = m_objectStore->modernTransaction().requestOpenCursor(*context, *this, info);
     return WTF::move(request);
 }
 
-RefPtr<WebCore::IDBRequest> IDBIndex::openKeyCursor(ScriptExecutionContext* context, const Deprecated::ScriptValue& key, const String& direction, ExceptionCode& ec)
+RefPtr<WebCore::IDBRequest> IDBIndex::openKeyCursor(ScriptExecutionContext* context, const Deprecated::ScriptValue& key, const String& direction, ExceptionCodeWithMessage& ec)
 {
     LOG(IndexedDB, "IDBIndex::openKeyCursor");
-    RefPtr<IDBKeyRange> keyRange = IDBKeyRange::only(context, key, ec);
-    if (ec)
+    RefPtr<IDBKeyRange> keyRange = IDBKeyRange::only(context, key, ec.code);
+    if (ec.code) {
+        ec.message = ASCIILiteral("Failed to execute 'openKeyCursor' on 'IDBIndex': The parameter is not a valid key.");
         return nullptr;
-
+    }
     return openKeyCursor(context, keyRange.get(), direction, ec);
 }
 
-RefPtr<WebCore::IDBRequest> IDBIndex::get(ScriptExecutionContext* context, IDBKeyRange* range, ExceptionCode& ec)
+RefPtr<WebCore::IDBRequest> IDBIndex::get(ScriptExecutionContext* context, IDBKeyRange* range, ExceptionCodeWithMessage& ec)
 {
     LOG(IndexedDB, "IDBIndex::get");
 
     if (!context) {
-        ec = INVALID_STATE_ERR;
+        ec.code = IDBDatabaseException::InvalidStateError;
         return nullptr;
     }
 
     return doGet(*context, IDBKeyRangeData(range), ec);
 }
 
-RefPtr<WebCore::IDBRequest> IDBIndex::get(ScriptExecutionContext* context, const Deprecated::ScriptValue& key, ExceptionCode& ec)
+RefPtr<WebCore::IDBRequest> IDBIndex::get(ScriptExecutionContext* context, const Deprecated::ScriptValue& key, ExceptionCodeWithMessage& ec)
 {
     LOG(IndexedDB, "IDBIndex::get");
 
     if (!context) {
-        ec = INVALID_STATE_ERR;
+        ec.code = IDBDatabaseException::InvalidStateError;
         return nullptr;
     }
 
     DOMRequestState requestState(context);
     RefPtr<IDBKey> idbKey = scriptValueToIDBKey(&requestState, key);
     if (!idbKey || idbKey->type() == KeyType::Invalid) {
-        ec = static_cast<ExceptionCode>(IDBDatabaseException::DataError);
+        ec.code = IDBDatabaseException::DataError;
+        ec.message = ASCIILiteral("Failed to execute 'get' on 'IDBIndex': The parameter is not a valid key.");
         return nullptr;
     }
 
     return doGet(*context, IDBKeyRangeData(idbKey.get()), ec);
 }
 
-RefPtr<WebCore::IDBRequest> IDBIndex::doGet(ScriptExecutionContext& context, const IDBKeyRangeData& range, ExceptionCode& ec)
+RefPtr<WebCore::IDBRequest> IDBIndex::doGet(ScriptExecutionContext& context, const IDBKeyRangeData& range, ExceptionCodeWithMessage& ec)
 {
     if (m_deleted || m_objectStore->isDeleted()) {
-        ec = INVALID_STATE_ERR;
+        ec.code = IDBDatabaseException::InvalidStateError;
         return nullptr;
     }
 
     if (range.isNull) {
-        ec = static_cast<ExceptionCode>(IDBDatabaseException::DataError);
+        ec.code = IDBDatabaseException::DataError;
         return nullptr;
     }
 
     auto& transaction = m_objectStore->modernTransaction();
     if (!transaction.isActive()) {
-        ec = static_cast<ExceptionCode>(IDBDatabaseException::TransactionInactiveError);
+        ec.code = IDBDatabaseException::TransactionInactiveError;
+        ec.message = ASCIILiteral("Failed to execute 'get' on 'IDBIndex': The transaction is inactive or finished.");
         return nullptr;
     }
 
     return transaction.requestGetValue(context, *this, range);
 }
 
-RefPtr<WebCore::IDBRequest> IDBIndex::getKey(ScriptExecutionContext* context, IDBKeyRange* range, ExceptionCode& ec)
+RefPtr<WebCore::IDBRequest> IDBIndex::getKey(ScriptExecutionContext* context, IDBKeyRange* range, ExceptionCodeWithMessage& ec)
 {
     LOG(IndexedDB, "IDBIndex::getKey");
 
     if (!context) {
-        ec = INVALID_STATE_ERR;
+        ec.code = IDBDatabaseException::InvalidStateError;
         return nullptr;
     }
 
     return doGetKey(*context, IDBKeyRangeData(range), ec);
 }
 
-RefPtr<WebCore::IDBRequest> IDBIndex::getKey(ScriptExecutionContext* context, const Deprecated::ScriptValue& key, ExceptionCode& ec)
+RefPtr<WebCore::IDBRequest> IDBIndex::getKey(ScriptExecutionContext* context, const Deprecated::ScriptValue& key, ExceptionCodeWithMessage& ec)
 {
     LOG(IndexedDB, "IDBIndex::getKey");
 
     if (!context) {
-        ec = INVALID_STATE_ERR;
+        ec.code = IDBDatabaseException::InvalidStateError;
         return nullptr;
     }
 
     DOMRequestState requestState(context);
     RefPtr<IDBKey> idbKey = scriptValueToIDBKey(&requestState, key);
     if (!idbKey || idbKey->type() == KeyType::Invalid) {
-        ec = static_cast<ExceptionCode>(IDBDatabaseException::DataError);
+        ec.code = IDBDatabaseException::DataError;
+        ec.message = ASCIILiteral("Failed to execute 'getKey' on 'IDBIndex': The parameter is not a valid key.");
         return nullptr;
     }
 
     return doGetKey(*context, IDBKeyRangeData(idbKey.get()), ec);
 }
 
-RefPtr<WebCore::IDBRequest> IDBIndex::doGetKey(ScriptExecutionContext& context, const IDBKeyRangeData& range, ExceptionCode& ec)
+RefPtr<WebCore::IDBRequest> IDBIndex::doGetKey(ScriptExecutionContext& context, const IDBKeyRangeData& range, ExceptionCodeWithMessage& ec)
 {
     if (m_deleted || m_objectStore->isDeleted()) {
-        ec = INVALID_STATE_ERR;
+        ec.code = IDBDatabaseException::InvalidStateError;
         return nullptr;
     }
 
     if (range.isNull) {
-        ec = static_cast<ExceptionCode>(IDBDatabaseException::DataError);
+        ec.code = IDBDatabaseException::DataError;
         return nullptr;
     }
 
     auto& transaction = m_objectStore->modernTransaction();
     if (!transaction.isActive()) {
-        ec = static_cast<ExceptionCode>(IDBDatabaseException::TransactionInactiveError);
+        ec.code = IDBDatabaseException::TransactionInactiveError;
+        ec.message = ASCIILiteral("Failed to execute 'getKey' on 'IDBIndex': The transaction is inactive or finished.");
         return nullptr;
     }
 
index 47f8f84..b180a64 100644 (file)
@@ -54,26 +54,26 @@ public:
     virtual bool unique() const override final;
     virtual bool multiEntry() const override final;
 
-    virtual RefPtr<WebCore::IDBRequest> openCursor(ScriptExecutionContext* context, ExceptionCode& ec) override final { return openCursor(context, static_cast<IDBKeyRange*>(nullptr), ec); }
-    virtual RefPtr<WebCore::IDBRequest> openCursor(ScriptExecutionContext* context, IDBKeyRange* keyRange, ExceptionCode& ec) override final { return openCursor(context, keyRange, IDBCursor::directionNext(), ec); }
-    virtual RefPtr<WebCore::IDBRequest> openCursor(ScriptExecutionContext* context, const Deprecated::ScriptValue& key, ExceptionCode& ec) override final { return openCursor(context, key, IDBCursor::directionNext(), ec); }
-    virtual RefPtr<WebCore::IDBRequest> openCursor(ScriptExecutionContext*, IDBKeyRange*, const String& direction, ExceptionCode&) override final;
-    virtual RefPtr<WebCore::IDBRequest> openCursor(ScriptExecutionContext*, const Deprecated::ScriptValue& key, const String& direction, ExceptionCode&) override final;
-
-    virtual RefPtr<WebCore::IDBRequest> count(ScriptExecutionContext*, ExceptionCode&) override final;
-    virtual RefPtr<WebCore::IDBRequest> count(ScriptExecutionContext*, IDBKeyRange*, ExceptionCode&) override final;
-    virtual RefPtr<WebCore::IDBRequest> count(ScriptExecutionContext*, const Deprecated::ScriptValue& key, ExceptionCode&) override final;
-
-    virtual RefPtr<WebCore::IDBRequest> openKeyCursor(ScriptExecutionContext* context, ExceptionCode& ec) override final { return openKeyCursor(context, static_cast<IDBKeyRange*>(nullptr), ec); }
-    virtual RefPtr<WebCore::IDBRequest> openKeyCursor(ScriptExecutionContext* context, IDBKeyRange* keyRange, ExceptionCode& ec) override final { return openKeyCursor(context, keyRange, IDBCursor::directionNext(), ec); }
-    virtual RefPtr<WebCore::IDBRequest> openKeyCursor(ScriptExecutionContext* context, const Deprecated::ScriptValue& key, ExceptionCode& ec) override final { return openKeyCursor(context, key, IDBCursor::directionNext(), ec); }
-    virtual RefPtr<WebCore::IDBRequest> openKeyCursor(ScriptExecutionContext*, IDBKeyRange*, const String& direction, ExceptionCode&) override final;
-    virtual RefPtr<WebCore::IDBRequest> openKeyCursor(ScriptExecutionContext*, const Deprecated::ScriptValue& key, const String& direction, ExceptionCode&) override final;
-
-    virtual RefPtr<WebCore::IDBRequest> get(ScriptExecutionContext*, IDBKeyRange*, ExceptionCode&) override final;
-    virtual RefPtr<WebCore::IDBRequest> get(ScriptExecutionContext*, const Deprecated::ScriptValue& key, ExceptionCode&) override final;
-    virtual RefPtr<WebCore::IDBRequest> getKey(ScriptExecutionContext*, IDBKeyRange*, ExceptionCode&) override final;
-    virtual RefPtr<WebCore::IDBRequest> getKey(ScriptExecutionContext*, const Deprecated::ScriptValue& key, ExceptionCode&) override final;
+    virtual RefPtr<WebCore::IDBRequest> openCursor(ScriptExecutionContext* context, ExceptionCodeWithMessage& ec) override final { return openCursor(context, static_cast<IDBKeyRange*>(nullptr), ec); }
+    virtual RefPtr<WebCore::IDBRequest> openCursor(ScriptExecutionContext* context, IDBKeyRange* keyRange, ExceptionCodeWithMessage& ec) override final { return openCursor(context, keyRange, IDBCursor::directionNext(), ec); }
+    virtual RefPtr<WebCore::IDBRequest> openCursor(ScriptExecutionContext* context, const Deprecated::ScriptValue& key, ExceptionCodeWithMessage& ec) override final { return openCursor(context, key, IDBCursor::directionNext(), ec); }
+    virtual RefPtr<WebCore::IDBRequest> openCursor(ScriptExecutionContext*, IDBKeyRange*, const String& direction, ExceptionCodeWithMessage&) override final;
+    virtual RefPtr<WebCore::IDBRequest> openCursor(ScriptExecutionContext*, const Deprecated::ScriptValue& key, const String& direction, ExceptionCodeWithMessage&) override final;
+
+    virtual RefPtr<WebCore::IDBRequest> count(ScriptExecutionContext*, ExceptionCodeWithMessage&) override final;
+    virtual RefPtr<WebCore::IDBRequest> count(ScriptExecutionContext*, IDBKeyRange*, ExceptionCodeWithMessage&) override final;
+    virtual RefPtr<WebCore::IDBRequest> count(ScriptExecutionContext*, const Deprecated::ScriptValue& key, ExceptionCodeWithMessage&) override final;
+
+    virtual RefPtr<WebCore::IDBRequest> openKeyCursor(ScriptExecutionContext* context, ExceptionCodeWithMessage& ec) override final { return openKeyCursor(context, static_cast<IDBKeyRange*>(nullptr), ec); }
+    virtual RefPtr<WebCore::IDBRequest> openKeyCursor(ScriptExecutionContext* context, IDBKeyRange* keyRange, ExceptionCodeWithMessage& ec) override final { return openKeyCursor(context, keyRange, IDBCursor::directionNext(), ec); }
+    virtual RefPtr<WebCore::IDBRequest> openKeyCursor(ScriptExecutionContext* context, const Deprecated::ScriptValue& key, ExceptionCodeWithMessage& ec) override final { return openKeyCursor(context, key, IDBCursor::directionNext(), ec); }
+    virtual RefPtr<WebCore::IDBRequest> openKeyCursor(ScriptExecutionContext*, IDBKeyRange*, const String& direction, ExceptionCodeWithMessage&) override final;
+    virtual RefPtr<WebCore::IDBRequest> openKeyCursor(ScriptExecutionContext*, const Deprecated::ScriptValue& key, const String& direction, ExceptionCodeWithMessage&) override final;
+
+    virtual RefPtr<WebCore::IDBRequest> get(ScriptExecutionContext*, IDBKeyRange*, ExceptionCodeWithMessage&) override final;
+    virtual RefPtr<WebCore::IDBRequest> get(ScriptExecutionContext*, const Deprecated::ScriptValue& key, ExceptionCodeWithMessage&) override final;
+    virtual RefPtr<WebCore::IDBRequest> getKey(ScriptExecutionContext*, IDBKeyRange*, ExceptionCodeWithMessage&) override final;
+    virtual RefPtr<WebCore::IDBRequest> getKey(ScriptExecutionContext*, const Deprecated::ScriptValue& key, ExceptionCodeWithMessage&) override final;
 
     const IDBIndexInfo& info() const { return m_info; }
 
@@ -85,9 +85,9 @@ public:
 private:
     IDBIndex(const IDBIndexInfo&, IDBObjectStore&);
 
-    RefPtr<WebCore::IDBRequest> doCount(ScriptExecutionContext&, const IDBKeyRangeData&, ExceptionCode&);
-    RefPtr<WebCore::IDBRequest> doGet(ScriptExecutionContext&, const IDBKeyRangeData&, ExceptionCode&);
-    RefPtr<WebCore::IDBRequest> doGetKey(ScriptExecutionContext&, const IDBKeyRangeData&, ExceptionCode&);
+    RefPtr<WebCore::IDBRequest> doCount(ScriptExecutionContext&, const IDBKeyRangeData&, ExceptionCodeWithMessage&);
+    RefPtr<WebCore::IDBRequest> doGet(ScriptExecutionContext&, const IDBKeyRangeData&, ExceptionCodeWithMessage&);
+    RefPtr<WebCore::IDBRequest> doGetKey(ScriptExecutionContext&, const IDBKeyRangeData&, ExceptionCodeWithMessage&);
 
     IDBIndexInfo m_info;
     Ref<IDBObjectStore> m_objectStore;
index 60bae4f..488391f 100644 (file)
@@ -95,37 +95,38 @@ bool IDBObjectStore::autoIncrement() const
     return m_info.autoIncrement();
 }
 
-RefPtr<WebCore::IDBRequest> IDBObjectStore::openCursor(ScriptExecutionContext* context, ExceptionCode& ec)
+RefPtr<WebCore::IDBRequest> IDBObjectStore::openCursor(ScriptExecutionContext* context, ExceptionCodeWithMessage& ec)
 {
     return openCursor(context, static_cast<IDBKeyRange*>(nullptr), ec);
 }
 
-RefPtr<WebCore::IDBRequest> IDBObjectStore::openCursor(ScriptExecutionContext* context, IDBKeyRange* keyRange, ExceptionCode& ec)
+RefPtr<WebCore::IDBRequest> IDBObjectStore::openCursor(ScriptExecutionContext* context, IDBKeyRange* keyRange, ExceptionCodeWithMessage& ec)
 {
     return openCursor(context, keyRange, IDBCursor::directionNext(), ec);
 }
 
-RefPtr<WebCore::IDBRequest> IDBObjectStore::openCursor(ScriptExecutionContext* context, const Deprecated::ScriptValue& key, ExceptionCode& ec)
+RefPtr<WebCore::IDBRequest> IDBObjectStore::openCursor(ScriptExecutionContext* context, const Deprecated::ScriptValue& key, ExceptionCodeWithMessage& ec)
 {
     return openCursor(context, key, IDBCursor::directionNext(), ec);
 }
 
-RefPtr<WebCore::IDBRequest> IDBObjectStore::openCursor(ScriptExecutionContext* context, IDBKeyRange* range, const String& directionString, ExceptionCode& ec)
+RefPtr<WebCore::IDBRequest> IDBObjectStore::openCursor(ScriptExecutionContext* context, IDBKeyRange* range, const String& directionString, ExceptionCodeWithMessage& ec)
 {
     LOG(IndexedDB, "IDBObjectStore::openCursor");
 
     if (m_deleted) {
-        ec = IDBDatabaseException::InvalidStateError;
+        ec.code = IDBDatabaseException::InvalidStateError;
         return nullptr;
     }
 
     if (!m_transaction->isActive()) {
-        ec = IDBDatabaseException::TransactionInactiveError;
+        ec.code = IDBDatabaseException::TransactionInactiveError;
+        ec.message = ASCIILiteral("Failed to execute 'openCursor' on 'IDBObjectStore': The transaction is inactive or finished.");
         return nullptr;
     }
 
-    IndexedDB::CursorDirection direction = IDBCursor::stringToDirection(directionString, ec);
-    if (ec)
+    IndexedDB::CursorDirection direction = IDBCursor::stringToDirection(directionString, ec.code);
+    if (ec.code)
         return nullptr;
 
     auto info = IDBCursorInfo::objectStoreCursor(m_transaction.get(), m_info.identifier(), range, direction);
@@ -133,38 +134,42 @@ RefPtr<WebCore::IDBRequest> IDBObjectStore::openCursor(ScriptExecutionContext* c
     return WTF::move(request);
 }
 
-RefPtr<WebCore::IDBRequest> IDBObjectStore::openCursor(ScriptExecutionContext* context, const Deprecated::ScriptValue& key, const String& direction, ExceptionCode& ec)
+RefPtr<WebCore::IDBRequest> IDBObjectStore::openCursor(ScriptExecutionContext* context, const Deprecated::ScriptValue& key, const String& direction, ExceptionCodeWithMessage& ec)
 {
-    RefPtr<IDBKeyRange> keyRange = IDBKeyRange::only(context, key, ec);
-    if (ec)
+    RefPtr<IDBKeyRange> keyRange = IDBKeyRange::only(context, key, ec.code);
+    if (ec.code) {
+        ec.message = ASCIILiteral("Failed to execute 'openCursor' on 'IDBObjectStore': The parameter is not a valid key.");
         return 0;
+    }
 
     return openCursor(context, keyRange.get(), direction, ec);
 }
 
-RefPtr<WebCore::IDBRequest> IDBObjectStore::get(ScriptExecutionContext* context, const Deprecated::ScriptValue& key, ExceptionCode& ec)
+RefPtr<WebCore::IDBRequest> IDBObjectStore::get(ScriptExecutionContext* context, const Deprecated::ScriptValue& key, ExceptionCodeWithMessage& ec)
 {
     LOG(IndexedDB, "IDBObjectStore::get");
 
     if (!context) {
-        ec = INVALID_STATE_ERR;
+        ec.code = IDBDatabaseException::InvalidStateError;
         return nullptr;
     }
 
     if (!m_transaction->isActive()) {
-        ec = static_cast<ExceptionCode>(IDBDatabaseException::TransactionInactiveError);
+        ec.code = IDBDatabaseException::TransactionInactiveError;
+        ec.message = ASCIILiteral("Failed to execute 'get' on 'IDBObjectStore': The transaction is inactive or finished.");
         return nullptr;
     }
 
     if (m_deleted) {
-        ec = INVALID_STATE_ERR;
+        ec.code = IDBDatabaseException::InvalidStateError;
         return nullptr;
     }
 
     DOMRequestState requestState(context);
     RefPtr<IDBKey> idbKey = scriptValueToIDBKey(&requestState, key);
     if (!idbKey || idbKey->type() == KeyType::Invalid) {
-        ec = static_cast<ExceptionCode>(IDBDatabaseException::DataError);
+        ec.code = IDBDatabaseException::DataError;
+        ec.message = ASCIILiteral("Failed to execute 'get' on 'IDBObjectStore': The parameter is not a valid key.");
         return nullptr;
     }
 
@@ -172,28 +177,28 @@ RefPtr<WebCore::IDBRequest> IDBObjectStore::get(ScriptExecutionContext* context,
     return WTF::move(request);
 }
 
-RefPtr<WebCore::IDBRequest> IDBObjectStore::get(ScriptExecutionContext* context, IDBKeyRange* keyRange, ExceptionCode& ec)
+RefPtr<WebCore::IDBRequest> IDBObjectStore::get(ScriptExecutionContext* context, IDBKeyRange* keyRange, ExceptionCodeWithMessage& ec)
 {
     LOG(IndexedDB, "IDBObjectStore::get");
 
     if (!context) {
-        ec = INVALID_STATE_ERR;
+        ec.code = IDBDatabaseException::InvalidStateError;
         return nullptr;
     }
 
     if (!m_transaction->isActive()) {
-        ec = static_cast<ExceptionCode>(IDBDatabaseException::TransactionInactiveError);
+        ec.code = IDBDatabaseException::TransactionInactiveError;
         return nullptr;
     }
 
     if (m_deleted) {
-        ec = INVALID_STATE_ERR;
+        ec.code = IDBDatabaseException::InvalidStateError;
         return nullptr;
     }
 
     IDBKeyRangeData keyRangeData(keyRange);
     if (!keyRangeData.isValid()) {
-        ec = static_cast<ExceptionCode>(IDBDatabaseException::DataError);
+        ec.code = IDBDatabaseException::DataError;
         return nullptr;
     }
 
@@ -201,66 +206,70 @@ RefPtr<WebCore::IDBRequest> IDBObjectStore::get(ScriptExecutionContext* context,
     return WTF::move(request);
 }
 
-RefPtr<WebCore::IDBRequest> IDBObjectStore::add(JSC::ExecState& state, JSC::JSValue value, ExceptionCode& ec)
+RefPtr<WebCore::IDBRequest> IDBObjectStore::add(JSC::ExecState& state, JSC::JSValue value, ExceptionCodeWithMessage& ec)
 {
     return putOrAdd(state, value, nullptr, IndexedDB::ObjectStoreOverwriteMode::NoOverwrite, InlineKeyCheck::Perform, ec);
 }
 
-RefPtr<WebCore::IDBRequest> IDBObjectStore::add(JSC::ExecState& execState, JSC::JSValue value, JSC::JSValue key, ExceptionCode& ec)
+RefPtr<WebCore::IDBRequest> IDBObjectStore::add(JSC::ExecState& execState, JSC::JSValue value, JSC::JSValue key, ExceptionCodeWithMessage& ec)
 {
     auto idbKey = scriptValueToIDBKey(execState, key);
     return putOrAdd(execState, value, idbKey, IndexedDB::ObjectStoreOverwriteMode::NoOverwrite, InlineKeyCheck::Perform, ec);
 }
 
-RefPtr<WebCore::IDBRequest> IDBObjectStore::put(JSC::ExecState& execState, JSC::JSValue value, JSC::JSValue key, ExceptionCode& ec)
+RefPtr<WebCore::IDBRequest> IDBObjectStore::put(JSC::ExecState& execState, JSC::JSValue value, JSC::JSValue key, ExceptionCodeWithMessage& ec)
 {
     auto idbKey = scriptValueToIDBKey(execState, key);
     return putOrAdd(execState, value, idbKey, IndexedDB::ObjectStoreOverwriteMode::Overwrite, InlineKeyCheck::Perform, ec);
 }
 
-RefPtr<WebCore::IDBRequest> IDBObjectStore::put(JSC::ExecState& state, JSC::JSValue value, ExceptionCode& ec)
+RefPtr<WebCore::IDBRequest> IDBObjectStore::put(JSC::ExecState& state, JSC::JSValue value, ExceptionCodeWithMessage& ec)
 {
     return putOrAdd(state, value, nullptr, IndexedDB::ObjectStoreOverwriteMode::Overwrite, InlineKeyCheck::Perform, ec);
 }
 
-RefPtr<IDBRequest> IDBObjectStore::putForCursorUpdate(JSC::ExecState& state, JSC::JSValue value, JSC::JSValue key, ExceptionCode& ec)
+RefPtr<IDBRequest> IDBObjectStore::putForCursorUpdate(JSC::ExecState& state, JSC::JSValue value, JSC::JSValue key, ExceptionCodeWithMessage& ec)
 {
     return putOrAdd(state, value, scriptValueToIDBKey(state, key), IndexedDB::ObjectStoreOverwriteMode::Overwrite, InlineKeyCheck::DoNotPerform, ec);
 }
 
-RefPtr<IDBRequest> IDBObjectStore::putOrAdd(JSC::ExecState& state, JSC::JSValue value, RefPtr<IDBKey> key, IndexedDB::ObjectStoreOverwriteMode overwriteMode, InlineKeyCheck inlineKeyCheck, ExceptionCode& ec)
+RefPtr<IDBRequest> IDBObjectStore::putOrAdd(JSC::ExecState& state, JSC::JSValue value, RefPtr<IDBKey> key, IndexedDB::ObjectStoreOverwriteMode overwriteMode, InlineKeyCheck inlineKeyCheck, ExceptionCodeWithMessage& ec)
 {
     LOG(IndexedDB, "IDBObjectStore::putOrAdd");
 
-    if (m_transaction->isReadOnly()) {
-        ec = IDBDatabaseException::ReadOnlyError;
+    if (!m_transaction->isActive()) {
+        ec.code = IDBDatabaseException::TransactionInactiveError;
+        ec.message = ASCIILiteral("Failed to store record in an IDBObjectStore: The transaction is inactive or finished.");
         return nullptr;
     }
 
-    if (!m_transaction->isActive()) {
-        ec = IDBDatabaseException::TransactionInactiveError;
+    if (m_transaction->isReadOnly()) {
+        ec.code = IDBDatabaseException::ReadOnlyError;
+        ec.message = ASCIILiteral("Failed to store record in an IDBObjectStore: The transaction is read-only.");
         return nullptr;
     }
 
     if (m_deleted) {
-        ec = IDBDatabaseException::InvalidStateError;
+        ec.code = IDBDatabaseException::InvalidStateError;
         return nullptr;
     }
 
     RefPtr<SerializedScriptValue> serializedValue = SerializedScriptValue::create(&state, value, nullptr, nullptr);
     if (state.hadException()) {
-        ec = IDBDatabaseException::DataCloneError;
+        ec.code = IDBDatabaseException::DataCloneError;
+        ec.message = ASCIILiteral("Failed to store record in an IDBObjectStore: An object could not be cloned.");
         return nullptr;
     }
 
     if (serializedValue->hasBlobURLs()) {
         // FIXME: Add Blob/File/FileList support
-        ec = IDBDatabaseException::DataCloneError;
+        ec.code = IDBDatabaseException::DataCloneError;
+        ec.message = ASCIILiteral("Failed to store record in an IDBObjectStore: BlobURLs are not yet supported.");
         return nullptr;
     }
 
     if (key && key->type() == KeyType::Invalid) {
-        ec = IDBDatabaseException::DataError;
+        ec.code = IDBDatabaseException::DataError;
         return nullptr;
     }
 
@@ -268,24 +277,24 @@ RefPtr<IDBRequest> IDBObjectStore::putOrAdd(JSC::ExecState& state, JSC::JSValue
     bool usesKeyGenerator = autoIncrement();
     if (usesInlineKeys && inlineKeyCheck == InlineKeyCheck::Perform) {
         if (key) {
-            ec = IDBDatabaseException::DataError;
+            ec.code = IDBDatabaseException::DataError;
             return nullptr;
         }
 
         RefPtr<IDBKey> keyPathKey = maybeCreateIDBKeyFromScriptValueAndKeyPath(state, value, m_info.keyPath());
         if (keyPathKey && !keyPathKey->isValid()) {
-            ec = IDBDatabaseException::DataError;
+            ec.code = IDBDatabaseException::DataError;
             return nullptr;
         }
 
         if (!keyPathKey) {
             if (usesKeyGenerator) {
                 if (!canInjectIDBKeyIntoScriptValue(state, value, m_info.keyPath())) {
-                    ec = IDBDatabaseException::DataError;
+                    ec.code = IDBDatabaseException::DataError;
                     return nullptr;
                 }
             } else {
-                ec = IDBDatabaseException::DataError;
+                ec.code = IDBDatabaseException::DataError;
                 return nullptr;
             }
         }
@@ -295,13 +304,13 @@ RefPtr<IDBRequest> IDBObjectStore::putOrAdd(JSC::ExecState& state, JSC::JSValue
             key = keyPathKey;
         }
     } else if (!usesKeyGenerator && !key) {
-        ec = IDBDatabaseException::DataError;
+        ec.code = IDBDatabaseException::DataError;
         return nullptr;
     }
 
     auto context = scriptExecutionContextFromExecState(&state);
     if (!context) {
-        ec = IDBDatabaseException::UnknownError;
+        ec.code = IDBDatabaseException::UnknownError;
         return nullptr;
     }
 
@@ -310,28 +319,31 @@ RefPtr<IDBRequest> IDBObjectStore::putOrAdd(JSC::ExecState& state, JSC::JSValue
 }
 
 
-RefPtr<WebCore::IDBRequest> IDBObjectStore::deleteFunction(ScriptExecutionContext* context, IDBKeyRange* keyRange, ExceptionCode& ec)
+RefPtr<WebCore::IDBRequest> IDBObjectStore::deleteFunction(ScriptExecutionContext* context, IDBKeyRange* keyRange, ExceptionCodeWithMessage& ec)
 {
     LOG(IndexedDB, "IDBObjectStore::deleteFunction");
 
-    if (m_transaction->isReadOnly()) {
-        ec = static_cast<ExceptionCode>(IDBDatabaseException::ReadOnlyError);
+    if (!m_transaction->isActive()) {
+        ec.code = IDBDatabaseException::TransactionInactiveError;
+        ec.message = ASCIILiteral("Failed to execute 'delete' on 'IDBObjectStore': The transaction is inactive or finished.");
         return nullptr;
     }
 
-    if (!m_transaction->isActive()) {
-        ec = static_cast<ExceptionCode>(IDBDatabaseException::TransactionInactiveError);
+    if (m_transaction->isReadOnly()) {
+        ec.code = IDBDatabaseException::ReadOnlyError;
+        ec.message = ASCIILiteral("Failed to execute 'delete' on 'IDBObjectStore': The transaction is read-only.");
         return nullptr;
     }
 
     if (m_deleted) {
-        ec = INVALID_STATE_ERR;
+        ec.code = IDBDatabaseException::InvalidStateError;
         return nullptr;
     }
 
     IDBKeyRangeData keyRangeData(keyRange);
     if (!keyRangeData.isValid()) {
-        ec = static_cast<ExceptionCode>(IDBDatabaseException::DataError);
+        ec.code = IDBDatabaseException::DataError;
+        ec.message = ASCIILiteral("Failed to execute 'delete' on 'IDBObjectStore': The parameter is not a valid key range.");
         return nullptr;
     }
 
@@ -339,39 +351,42 @@ RefPtr<WebCore::IDBRequest> IDBObjectStore::deleteFunction(ScriptExecutionContex
     return WTF::move(request);
 }
 
-RefPtr<WebCore::IDBRequest> IDBObjectStore::deleteFunction(ScriptExecutionContext* context, const Deprecated::ScriptValue& key, ExceptionCode& ec)
+RefPtr<WebCore::IDBRequest> IDBObjectStore::deleteFunction(ScriptExecutionContext* context, const Deprecated::ScriptValue& key, ExceptionCodeWithMessage& ec)
 {
     return deleteFunction(context, key.jsValue(), ec);
 }
 
-RefPtr<WebCore::IDBRequest> IDBObjectStore::deleteFunction(ScriptExecutionContext* context, JSC::JSValue key, ExceptionCode& ec)
+RefPtr<WebCore::IDBRequest> IDBObjectStore::deleteFunction(ScriptExecutionContext* context, JSC::JSValue key, ExceptionCodeWithMessage& ec)
 {
     DOMRequestState requestState(context);
     RefPtr<IDBKey> idbKey = scriptValueToIDBKey(&requestState, key);
     if (!idbKey || idbKey->type() == KeyType::Invalid) {
-        ec = static_cast<ExceptionCode>(IDBDatabaseException::DataError);
+        ec.code = IDBDatabaseException::DataError;
+        ec.message = ASCIILiteral("Failed to execute 'delete' on 'IDBObjectStore': The parameter is not a valid key.");
         return nullptr;
     }
 
     return deleteFunction(context, &IDBKeyRange::create(idbKey.get()).get(), ec);
 }
 
-RefPtr<WebCore::IDBRequest> IDBObjectStore::clear(ScriptExecutionContext* context, ExceptionCode& ec)
+RefPtr<WebCore::IDBRequest> IDBObjectStore::clear(ScriptExecutionContext* context, ExceptionCodeWithMessage& ec)
 {
     LOG(IndexedDB, "IDBObjectStore::clear");
 
-    if (m_transaction->isReadOnly()) {
-        ec = static_cast<ExceptionCode>(IDBDatabaseException::ReadOnlyError);
+    if (!m_transaction->isActive()) {
+        ec.code = IDBDatabaseException::TransactionInactiveError;
+        ec.message = ASCIILiteral("Failed to execute 'clear' on 'IDBObjectStore': The transaction is inactive or finished.");
         return nullptr;
     }
 
-    if (!m_transaction->isActive()) {
-        ec = static_cast<ExceptionCode>(IDBDatabaseException::TransactionInactiveError);
+    if (m_transaction->isReadOnly()) {
+        ec.code = IDBDatabaseException::ReadOnlyError;
+        ec.message = ASCIILiteral("Failed to execute 'clear' on 'IDBObjectStore': The transaction is read-only.");
         return nullptr;
     }
 
     if (m_deleted) {
-        ec = static_cast<ExceptionCode>(IDBDatabaseException::InvalidStateError);
+        ec.code = IDBDatabaseException::InvalidStateError;
         return nullptr;
     }
 
@@ -379,47 +394,51 @@ RefPtr<WebCore::IDBRequest> IDBObjectStore::clear(ScriptExecutionContext* contex
     return adoptRef(request.leakRef());
 }
 
-RefPtr<WebCore::IDBIndex> IDBObjectStore::createIndex(ScriptExecutionContext* context, const String& name, const IDBKeyPath& keyPath, bool unique, bool multiEntry, ExceptionCode& ec)
+RefPtr<WebCore::IDBIndex> IDBObjectStore::createIndex(ScriptExecutionContext* context, const String& name, const IDBKeyPath& keyPath, bool unique, bool multiEntry, ExceptionCodeWithMessage& ec)
 {
     LOG(IndexedDB, "IDBObjectStore::createIndex %s", name.utf8().data());
 
     if (!context) {
-        ec = INVALID_STATE_ERR;
+        ec.code = IDBDatabaseException::InvalidStateError;
         return nullptr;
     }
 
     if (m_deleted) {
-        ec = static_cast<ExceptionCode>(IDBDatabaseException::InvalidStateError);
+        ec.code = IDBDatabaseException::InvalidStateError;
         return nullptr;
     }
 
     if (!m_transaction->isVersionChange()) {
-        ec = static_cast<ExceptionCode>(IDBDatabaseException::InvalidStateError);
+        ec.code = IDBDatabaseException::InvalidStateError;
+        ec.message = ASCIILiteral("Failed to execute 'createIndex' on 'IDBObjectStore': The database is not running a version change transaction.");
         return nullptr;
     }
 
     if (!m_transaction->isActive()) {
-        ec = static_cast<ExceptionCode>(IDBDatabaseException::TransactionInactiveError);
+        ec.code = IDBDatabaseException::TransactionInactiveError;
         return nullptr;
     }
 
     if (!keyPath.isValid()) {
-        ec = IDBDatabaseException::SyntaxError;
+        ec.code = IDBDatabaseException::SyntaxError;
+        ec.message = ASCIILiteral("Failed to execute 'createIndex' on 'IDBObjectStore': The keyPath argument contains an invalid key path.");
         return nullptr;
     }
 
     if (name.isNull()) {
-        ec = TypeError;
+        ec.code = TypeError;
         return nullptr;
     }
 
     if (m_info.hasIndex(name)) {
-        ec = IDBDatabaseException::ConstraintError;
+        ec.code = IDBDatabaseException::ConstraintError;
+        ec.message = ASCIILiteral("Failed to execute 'createIndex' on 'IDBObjectStore': An index with the specified name already exists.");
         return nullptr;
     }
 
     if (keyPath.type() == IndexedDB::KeyPathType::Array && multiEntry) {
-        ec = IDBDatabaseException::InvalidAccessError;
+        ec.code = IDBDatabaseException::InvalidAccessError;
+        ec.message = ASCIILiteral("Failed to execute 'createIndex' on 'IDBObjectStore': The keyPath argument was an array and the multiEntry option is true.");
         return nullptr;
     }
 
@@ -434,22 +453,18 @@ RefPtr<WebCore::IDBIndex> IDBObjectStore::createIndex(ScriptExecutionContext* co
     return WTF::move(index);
 }
 
-RefPtr<WebCore::IDBIndex> IDBObjectStore::index(const String& indexName, ExceptionCode& ec)
+RefPtr<WebCore::IDBIndex> IDBObjectStore::index(const String& indexName, ExceptionCodeWithMessage& ec)
 {
     LOG(IndexedDB, "IDBObjectStore::index");
 
-    if (indexName.isEmpty()) {
-        ec = NOT_FOUND_ERR;
-        return nullptr;
-    }
-
     if (m_deleted) {
-        ec = INVALID_STATE_ERR;
+        ec.code = IDBDatabaseException::InvalidStateError;
         return nullptr;
     }
 
     if (!m_transaction->isActive()) {
-        ec = static_cast<ExceptionCode>(IDBDatabaseException::TransactionInactiveError);
+        ec.code = IDBDatabaseException::TransactionInactiveError;
+        ec.message = ASCIILiteral("Failed to execute 'index' on 'IDBObjectStore': The transaction is inactive or finished.");
         return nullptr;
     }
 
@@ -459,7 +474,8 @@ RefPtr<WebCore::IDBIndex> IDBObjectStore::index(const String& indexName, Excepti
 
     auto* info = m_info.infoForExistingIndex(indexName);
     if (!info) {
-        ec = NOT_FOUND_ERR;
+        ec.code = IDBDatabaseException::NotFoundError;
+        ec.message = ASCIILiteral("Failed to execute 'index' on 'IDBObjectStore': The specified index was not found.");
         return nullptr;
     }
 
@@ -469,27 +485,29 @@ RefPtr<WebCore::IDBIndex> IDBObjectStore::index(const String& indexName, Excepti
     return WTF::move(index);
 }
 
-void IDBObjectStore::deleteIndex(const String& name, ExceptionCode& ec)
+void IDBObjectStore::deleteIndex(const String& name, ExceptionCodeWithMessage& ec)
 {
     LOG(IndexedDB, "IDBObjectStore::deleteIndex %s", name.utf8().data());
 
     if (m_deleted) {
-        ec = static_cast<ExceptionCode>(IDBDatabaseException::InvalidStateError);
+        ec.code = IDBDatabaseException::InvalidStateError;
         return;
     }
 
     if (!m_transaction->isVersionChange()) {
-        ec = static_cast<ExceptionCode>(IDBDatabaseException::InvalidStateError);
+        ec.code = IDBDatabaseException::InvalidStateError;
+        ec.message = ASCIILiteral("Failed to execute 'deleteIndex' on 'IDBObjectStore': The database is not running a version change transaction.");
         return;
     }
 
     if (!m_transaction->isActive()) {
-        ec = static_cast<ExceptionCode>(IDBDatabaseException::TransactionInactiveError);
+        ec.code = IDBDatabaseException::TransactionInactiveError;
         return;
     }
 
     if (!m_info.hasIndex(name)) {
-        ec = IDBDatabaseException::NotFoundError;
+        ec.code = IDBDatabaseException::NotFoundError;
+        ec.message = ASCIILiteral("Failed to execute 'deleteIndex' on 'IDBObjectStore': The specified index was not found.");
         return;
     }
 
@@ -505,12 +523,12 @@ void IDBObjectStore::deleteIndex(const String& name, ExceptionCode& ec)
     m_transaction->deleteIndex(m_info.identifier(), name);
 }
 
-RefPtr<WebCore::IDBRequest> IDBObjectStore::count(ScriptExecutionContext* context, ExceptionCode& ec)
+RefPtr<WebCore::IDBRequest> IDBObjectStore::count(ScriptExecutionContext* context, ExceptionCodeWithMessage& ec)
 {
     LOG(IndexedDB, "IDBObjectStore::count");
 
     if (!context) {
-        ec = INVALID_STATE_ERR;
+        ec.code = IDBDatabaseException::InvalidStateError;
         return nullptr;
     }
 
@@ -519,51 +537,53 @@ RefPtr<WebCore::IDBRequest> IDBObjectStore::count(ScriptExecutionContext* contex
     return doCount(*context, range, ec);
 }
 
-RefPtr<WebCore::IDBRequest> IDBObjectStore::count(ScriptExecutionContext* context, const Deprecated::ScriptValue& key, ExceptionCode& ec)
+RefPtr<WebCore::IDBRequest> IDBObjectStore::count(ScriptExecutionContext* context, const Deprecated::ScriptValue& key, ExceptionCodeWithMessage& ec)
 {
     LOG(IndexedDB, "IDBObjectStore::count");
 
     if (!context) {
-        ec = INVALID_STATE_ERR;
+        ec.code = IDBDatabaseException::InvalidStateError;
         return nullptr;
     }
 
     DOMRequestState requestState(context);
     RefPtr<IDBKey> idbKey = scriptValueToIDBKey(&requestState, key);
     if (!idbKey || idbKey->type() == KeyType::Invalid) {
-        ec = static_cast<ExceptionCode>(IDBDatabaseException::DataError);
+        ec.code = IDBDatabaseException::DataError;
+        ec.message = ASCIILiteral("Failed to execute 'count' on 'IDBObjectStore': The parameter is not a valid key.");
         return nullptr;
     }
 
     return doCount(*context, IDBKeyRangeData(idbKey.get()), ec);
 }
 
-RefPtr<WebCore::IDBRequest> IDBObjectStore::count(ScriptExecutionContext* context, IDBKeyRange* range, ExceptionCode& ec)
+RefPtr<WebCore::IDBRequest> IDBObjectStore::count(ScriptExecutionContext* context, IDBKeyRange* range, ExceptionCodeWithMessage& ec)
 {
     LOG(IndexedDB, "IDBObjectStore::count");
 
     if (!context) {
-        ec = INVALID_STATE_ERR;
+        ec.code = IDBDatabaseException::InvalidStateError;
         return nullptr;
     }
 
     return doCount(*context, IDBKeyRangeData(range), ec);
 }
 
-RefPtr<WebCore::IDBRequest> IDBObjectStore::doCount(ScriptExecutionContext& context, const IDBKeyRangeData& range, ExceptionCode& ec)
+RefPtr<WebCore::IDBRequest> IDBObjectStore::doCount(ScriptExecutionContext& context, const IDBKeyRangeData& range, ExceptionCodeWithMessage& ec)
 {
     if (!m_transaction->isActive()) {
-        ec = static_cast<ExceptionCode>(IDBDatabaseException::TransactionInactiveError);
+        ec.code = IDBDatabaseException::TransactionInactiveError;
+        ec.message = ASCIILiteral("Failed to execute 'count' on 'IDBObjectStore': The transaction is inactive or finished.");
         return nullptr;
     }
 
     if (m_deleted) {
-        ec = INVALID_STATE_ERR;
+        ec.code = IDBDatabaseException::InvalidStateError;
         return nullptr;
     }
 
     if (range.isNull) {
-        ec = static_cast<ExceptionCode>(IDBDatabaseException::DataError);
+        ec.code = IDBDatabaseException::DataError;
         return nullptr;
     }
 
index a5c3fbe..da9487e 100644 (file)
@@ -58,30 +58,30 @@ public:
     virtual RefPtr<WebCore::IDBTransaction> transaction() override final;
     virtual bool autoIncrement() const override final;
 
-    virtual RefPtr<WebCore::IDBRequest> add(JSC::ExecState&, JSC::JSValue, ExceptionCode&) override final;
-    virtual RefPtr<WebCore::IDBRequest> put(JSC::ExecState&, JSC::JSValue, ExceptionCode&) override final;
-    virtual RefPtr<WebCore::IDBRequest> openCursor(ScriptExecutionContext*, ExceptionCode&) override final;
-    virtual RefPtr<WebCore::IDBRequest> openCursor(ScriptExecutionContext*, IDBKeyRange*, ExceptionCode&) override final;
-    virtual RefPtr<WebCore::IDBRequest> openCursor(ScriptExecutionContext*, const Deprecated::ScriptValue& key, ExceptionCode&) override final;
-    virtual RefPtr<WebCore::IDBRequest> openCursor(ScriptExecutionContext*, IDBKeyRange*, const String& direction, ExceptionCode&) override final;
-    virtual RefPtr<WebCore::IDBRequest> openCursor(ScriptExecutionContext*, const Deprecated::ScriptValue& key, const String& direction, ExceptionCode&) override final;
-    virtual RefPtr<WebCore::IDBRequest> get(ScriptExecutionContext*, const Deprecated::ScriptValue& key, ExceptionCode&) override final;
-    virtual RefPtr<WebCore::IDBRequest> get(ScriptExecutionContext*, IDBKeyRange*, ExceptionCode&) override final;
-    virtual RefPtr<WebCore::IDBRequest> add(JSC::ExecState&, JSC::JSValue, JSC::JSValue key, ExceptionCode&) override final;
-    virtual RefPtr<WebCore::IDBRequest> put(JSC::ExecState&, JSC::JSValue, JSC::JSValue key, ExceptionCode&) override final;
-    virtual RefPtr<WebCore::IDBRequest> deleteFunction(ScriptExecutionContext*, IDBKeyRange*, ExceptionCode&) override final;
-    virtual RefPtr<WebCore::IDBRequest> deleteFunction(ScriptExecutionContext*, const Deprecated::ScriptValue& key, ExceptionCode&) override final;
-    virtual RefPtr<WebCore::IDBRequest> clear(ScriptExecutionContext*, ExceptionCode&) override final;
-    virtual RefPtr<WebCore::IDBIndex> createIndex(ScriptExecutionContext*, const String& name, const IDBKeyPath&, bool unique, bool multiEntry, ExceptionCode&) override final;
-    virtual RefPtr<WebCore::IDBIndex> index(const String& name, ExceptionCode&) override final;
-    virtual void deleteIndex(const String& name, ExceptionCode&) override final;
-    virtual RefPtr<WebCore::IDBRequest> count(ScriptExecutionContext*, ExceptionCode&) override final;
-    virtual RefPtr<WebCore::IDBRequest> count(ScriptExecutionContext*, IDBKeyRange*, ExceptionCode&) override final;
-    virtual RefPtr<WebCore::IDBRequest> count(ScriptExecutionContext*, const Deprecated::ScriptValue& key, ExceptionCode&) override final;
-
-    RefPtr<IDBRequest> putForCursorUpdate(JSC::ExecState&, JSC::JSValue, JSC::JSValue key, ExceptionCode&);
-
-    RefPtr<WebCore::IDBRequest> deleteFunction(ScriptExecutionContext*, JSC::JSValue key, ExceptionCode&);
+    virtual RefPtr<WebCore::IDBRequest> add(JSC::ExecState&, JSC::JSValue, ExceptionCodeWithMessage&) override final;
+    virtual RefPtr<WebCore::IDBRequest> put(JSC::ExecState&, JSC::JSValue, ExceptionCodeWithMessage&) override final;
+    virtual RefPtr<WebCore::IDBRequest> openCursor(ScriptExecutionContext*, ExceptionCodeWithMessage&) override final;
+    virtual RefPtr<WebCore::IDBRequest> openCursor(ScriptExecutionContext*, IDBKeyRange*, ExceptionCodeWithMessage&) override final;
+    virtual RefPtr<WebCore::IDBRequest> openCursor(ScriptExecutionContext*, const Deprecated::ScriptValue& key, ExceptionCodeWithMessage&) override final;
+    virtual RefPtr<WebCore::IDBRequest> openCursor(ScriptExecutionContext*, IDBKeyRange*, const String& direction, ExceptionCodeWithMessage&) override final;
+    virtual RefPtr<WebCore::IDBRequest> openCursor(ScriptExecutionContext*, const Deprecated::ScriptValue& key, const String& direction, ExceptionCodeWithMessage&) override final;
+    virtual RefPtr<WebCore::IDBRequest> get(ScriptExecutionContext*, const Deprecated::ScriptValue& key, ExceptionCodeWithMessage&) override final;
+    virtual RefPtr<WebCore::IDBRequest> get(ScriptExecutionContext*, IDBKeyRange*, ExceptionCodeWithMessage&) override final;
+    virtual RefPtr<WebCore::IDBRequest> add(JSC::ExecState&, JSC::JSValue, JSC::JSValue key, ExceptionCodeWithMessage&) override final;
+    virtual RefPtr<WebCore::IDBRequest> put(JSC::ExecState&, JSC::JSValue, JSC::JSValue key, ExceptionCodeWithMessage&) override final;
+    virtual RefPtr<WebCore::IDBRequest> deleteFunction(ScriptExecutionContext*, IDBKeyRange*, ExceptionCodeWithMessage&) override final;
+    virtual RefPtr<WebCore::IDBRequest> deleteFunction(ScriptExecutionContext*, const Deprecated::ScriptValue& key, ExceptionCodeWithMessage&) override final;
+    virtual RefPtr<WebCore::IDBRequest> clear(ScriptExecutionContext*, ExceptionCodeWithMessage&) override final;
+    virtual RefPtr<WebCore::IDBIndex> createIndex(ScriptExecutionContext*, const String& name, const IDBKeyPath&, bool unique, bool multiEntry, ExceptionCodeWithMessage&) override final;
+    virtual RefPtr<WebCore::IDBIndex> index(const String& name, ExceptionCodeWithMessage&) override final;
+    virtual void deleteIndex(const String& name, ExceptionCodeWithMessage&) override final;
+    virtual RefPtr<WebCore::IDBRequest> count(ScriptExecutionContext*, ExceptionCodeWithMessage&) override final;
+    virtual RefPtr<WebCore::IDBRequest> count(ScriptExecutionContext*, IDBKeyRange*, ExceptionCodeWithMessage&) override final;
+    virtual RefPtr<WebCore::IDBRequest> count(ScriptExecutionContext*, const Deprecated::ScriptValue& key, ExceptionCodeWithMessage&) override final;
+
+    RefPtr<IDBRequest> putForCursorUpdate(JSC::ExecState&, JSC::JSValue, JSC::JSValue key, ExceptionCodeWithMessage&);
+
+    RefPtr<WebCore::IDBRequest> deleteFunction(ScriptExecutionContext*, JSC::JSValue key, ExceptionCodeWithMessage&);
 
     void markAsDeleted();
     bool isDeleted() const { return m_deleted; }
@@ -100,8 +100,8 @@ private:
         DoNotPerform,
     };
 
-    RefPtr<IDBRequest> putOrAdd(JSC::ExecState&, JSC::JSValue, RefPtr<IDBKey>, IndexedDB::ObjectStoreOverwriteMode, InlineKeyCheck, ExceptionCode&);
-    RefPtr<WebCore::IDBRequest> doCount(ScriptExecutionContext&, const IDBKeyRangeData&, ExceptionCode&);
+    RefPtr<IDBRequest> putOrAdd(JSC::ExecState&, JSC::JSValue, RefPtr<IDBKey>, IndexedDB::ObjectStoreOverwriteMode, InlineKeyCheck, ExceptionCodeWithMessage&);
+    RefPtr<WebCore::IDBRequest> doCount(ScriptExecutionContext&, const IDBKeyRangeData&, ExceptionCodeWithMessage&);
 
     IDBObjectStoreInfo m_info;
     Ref<IDBTransaction> m_transaction;
index b950908..0a222fb 100644 (file)
@@ -120,12 +120,13 @@ IDBRequest::~IDBRequest()
     }
 }
 
-RefPtr<WebCore::IDBAny> IDBRequest::result(ExceptionCode& ec) const
+RefPtr<WebCore::IDBAny> IDBRequest::result(ExceptionCodeWithMessage& ec) const
 {
     if (m_readyState == IDBRequestReadyState::Done)
         return m_result;
 
-    ec = IDBDatabaseException::InvalidStateError;
+    ec.code = IDBDatabaseException::InvalidStateError;
+    ec.message = ASCIILiteral("Failed to read the 'result' property from 'IDBRequest': The request has not finished.");
     return nullptr;
 }
 
@@ -134,12 +135,13 @@ unsigned short IDBRequest::errorCode(ExceptionCode&) const
     return 0;
 }
 
-RefPtr<DOMError> IDBRequest::error(ExceptionCode& ec) const
+RefPtr<DOMError> IDBRequest::error(ExceptionCodeWithMessage& ec) const
 {
     if (m_readyState == IDBRequestReadyState::Done)
         return m_domError;
 
-    ec = IDBDatabaseException::InvalidStateError;
+    ec.code = IDBDatabaseException::InvalidStateError;
+    ec.message = ASCIILiteral("Failed to read the 'error' property from 'IDBRequest': The request has not finished.");
     return nullptr;
 }
 
index 6f7bdf2..a43e779 100644 (file)
@@ -60,9 +60,9 @@ public:
 
     virtual ~IDBRequest() override;
 
-    virtual RefPtr<WebCore::IDBAny> result(ExceptionCode&) const override;
+    virtual RefPtr<WebCore::IDBAny> result(ExceptionCodeWithMessage&) const override;
     virtual unsigned short errorCode(ExceptionCode&) const override;
-    virtual RefPtr<DOMError> error(ExceptionCode&) const override;
+    virtual RefPtr<DOMError> error(ExceptionCodeWithMessage&) const override;
     virtual RefPtr<WebCore::IDBAny> source() const override;
     virtual RefPtr<WebCore::IDBTransaction> transaction() const override;
     virtual const String& readyState() const override;
index 2930003..ec8e540 100644 (file)
@@ -121,17 +121,12 @@ RefPtr<DOMError> IDBTransaction::error() const
     return m_domError;
 }
 
-RefPtr<WebCore::IDBObjectStore> IDBTransaction::objectStore(const String& objectStoreName, ExceptionCode& ec)
+RefPtr<WebCore::IDBObjectStore> IDBTransaction::objectStore(const String& objectStoreName, ExceptionCodeWithMessage& ec)
 {
     LOG(IndexedDB, "IDBTransaction::objectStore");
 
-    if (objectStoreName.isEmpty()) {
-        ec = NOT_FOUND_ERR;
-        return nullptr;
-    }
-
     if (isFinishedOrFinishing()) {
-        ec = INVALID_STATE_ERR;
+        ec.code = IDBDatabaseException::InvalidStateError;
         return nullptr;
     }
 
@@ -149,13 +144,15 @@ RefPtr<WebCore::IDBObjectStore> IDBTransaction::objectStore(const String& object
 
     auto* info = m_database->info().infoForExistingObjectStore(objectStoreName);
     if (!info) {
-        ec = NOT_FOUND_ERR;
+        ec.code = IDBDatabaseException::NotFoundError;
+        ec.message = ASCIILiteral("Failed to execute 'objectStore' on 'IDBTransaction': The specified object store was not found.");
         return nullptr;
     }
 
     // Version change transactions are scoped to every object store in the database.
-    if (!found && !isVersionChange()) {
-        ec = NOT_FOUND_ERR;
+    if (!info || (!found && !isVersionChange())) {
+        ec.code = IDBDatabaseException::NotFoundError;
+        ec.message = ASCIILiteral("Failed to execute 'objectStore' on 'IDBTransaction': The specified object store was not found.");
         return nullptr;
     }
 
@@ -172,16 +169,17 @@ void IDBTransaction::abortDueToFailedRequest(DOMError& error)
     ASSERT(!isFinishedOrFinishing());
 
     m_domError = &error;
-    ExceptionCode ec;
+    ExceptionCodeWithMessage ec;
     abort(ec);
 }
 
-void IDBTransaction::abort(ExceptionCode& ec)
+void IDBTransaction::abort(ExceptionCodeWithMessage& ec)
 {
     LOG(IndexedDB, "IDBTransaction::abort");
 
     if (isFinishedOrFinishing()) {
-        ec = IDBDatabaseException::InvalidStateError;
+        ec.code = IDBDatabaseException::InvalidStateError;
+        ec.message = ASCIILiteral("Failed to execute 'abort' on 'IDBTransaction': The transaction is inactive or finished.");
         return;
     }
 
index a8e45eb..0757f8a 100644 (file)
@@ -68,8 +68,8 @@ public:
     virtual const String& mode() const override final;
     virtual WebCore::IDBDatabase* db() override final;
     virtual RefPtr<DOMError> error() const override final;
-    virtual RefPtr<WebCore::IDBObjectStore> objectStore(const String& name, ExceptionCode&) override final;
-    virtual void abort(ExceptionCode&) override final;
+    virtual RefPtr<WebCore::IDBObjectStore> objectStore(const String& name, ExceptionCodeWithMessage&) override final;
+    virtual void abort(ExceptionCodeWithMessage&) override final;
 
     virtual EventTargetInterface eventTargetInterface() const override final { return IDBTransactionEventTargetInterfaceType; }
     virtual ScriptExecutionContext* scriptExecutionContext() const override final { return ActiveDOMObject::scriptExecutionContext(); }
index b57a470..93399d1 100644 (file)
@@ -96,20 +96,20 @@ IDBAny* LegacyCursor::source()
     return m_source.get();
 }
 
-RefPtr<IDBRequest> LegacyCursor::update(JSC::ExecState& state, Deprecated::ScriptValue& value, ExceptionCode& ec)
+RefPtr<IDBRequest> LegacyCursor::update(JSC::ExecState& state, Deprecated::ScriptValue& value, ExceptionCodeWithMessage& ec)
 {
     LOG(StorageAPI, "LegacyCursor::update");
 
     if (!m_gotValue || isKeyCursor()) {
-        ec = IDBDatabaseException::InvalidStateError;
+        ec.code = IDBDatabaseException::InvalidStateError;
         return 0;
     }
     if (!m_transaction->isActive()) {
-        ec = IDBDatabaseException::TransactionInactiveError;
+        ec.code = IDBDatabaseException::TransactionInactiveError;
         return 0;
     }
     if (m_transaction->isReadOnly()) {
-        ec = IDBDatabaseException::ReadOnlyError;
+        ec.code = IDBDatabaseException::ReadOnlyError;
         return 0;
     }
 
@@ -119,7 +119,7 @@ RefPtr<IDBRequest> LegacyCursor::update(JSC::ExecState& state, Deprecated::Scrip
     if (usesInLineKeys) {
         RefPtr<IDBKey> keyPathKey = createIDBKeyFromScriptValueAndKeyPath(m_request->requestState()->exec(), value, keyPath);
         if (!keyPathKey || !keyPathKey->isEqual(m_currentPrimaryKey.get())) {
-            ec = IDBDatabaseException::DataError;
+            ec.code = IDBDatabaseException::DataError;
             return 0;
         }
     }
@@ -152,29 +152,29 @@ void LegacyCursor::advance(unsigned long count, ExceptionCodeWithMessage& ec)
     ASSERT(!ec.code);
 }
 
-void LegacyCursor::continueFunction(ScriptExecutionContext* context, const Deprecated::ScriptValue& keyValue, ExceptionCode& ec)
+void LegacyCursor::continueFunction(ScriptExecutionContext* context, const Deprecated::ScriptValue& keyValue, ExceptionCodeWithMessage& ec)
 {
     DOMRequestState requestState(context);
     RefPtr<IDBKey> key = scriptValueToIDBKey(&requestState, keyValue);
     continueFunction(key.release(), ec);
 }
 
-void LegacyCursor::continueFunction(PassRefPtr<IDBKey> key, ExceptionCode& ec)
+void LegacyCursor::continueFunction(PassRefPtr<IDBKey> key, ExceptionCodeWithMessage& ec)
 {
-    ec = 0;
+    ec.code = 0;
     LOG(StorageAPI, "LegacyCursor::continue");
     if (key && !key->isValid()) {
-        ec = IDBDatabaseException::DataError;
+        ec.code = IDBDatabaseException::DataError;
         return;
     }
 
     if (!m_transaction->isActive()) {
-        ec = IDBDatabaseException::TransactionInactiveError;
+        ec.code = IDBDatabaseException::TransactionInactiveError;
         return;
     }
 
     if (!m_gotValue) {
-        ec = IDBDatabaseException::InvalidStateError;
+        ec.code = IDBDatabaseException::InvalidStateError;
         return;
     }
 
@@ -182,12 +182,12 @@ void LegacyCursor::continueFunction(PassRefPtr<IDBKey> key, ExceptionCode& ec)
         ASSERT(m_currentKey);
         if (m_direction == IndexedDB::CursorDirection::Next || m_direction == IndexedDB::CursorDirection::NextNoDuplicate) {
             if (!m_currentKey->isLessThan(key.get())) {
-                ec = IDBDatabaseException::DataError;
+                ec.code = IDBDatabaseException::DataError;
                 return;
             }
         } else {
             if (!key->isLessThan(m_currentKey.get())) {
-                ec = IDBDatabaseException::DataError;
+                ec.code = IDBDatabaseException::DataError;
                 return;
             }
         }
@@ -197,30 +197,30 @@ void LegacyCursor::continueFunction(PassRefPtr<IDBKey> key, ExceptionCode& ec)
     //        will be on the original context openCursor was called on. Is this right?
     m_request->setPendingCursor(this);
     m_gotValue = false;
-    m_backend->continueFunction(key, m_request, ec);
-    ASSERT(!ec);
+    m_backend->continueFunction(key, m_request, ec.code);
+    ASSERT(!ec.code);
 }
 
-RefPtr<IDBRequest> LegacyCursor::deleteFunction(ScriptExecutionContext* context, ExceptionCode& ec)
+RefPtr<IDBRequest> LegacyCursor::deleteFunction(ScriptExecutionContext* context, ExceptionCodeWithMessage& ec)
 {
-    ec = 0;
+    ec.code = 0;
     LOG(StorageAPI, "LegacyCursor::delete");
     if (!m_transaction->isActive()) {
-        ec = IDBDatabaseException::TransactionInactiveError;
+        ec.code = IDBDatabaseException::TransactionInactiveError;
         return 0;
     }
     if (m_transaction->isReadOnly()) {
-        ec = IDBDatabaseException::ReadOnlyError;
+        ec.code = IDBDatabaseException::ReadOnlyError;
         return 0;
     }
 
     if (!m_gotValue || isKeyCursor()) {
-        ec = IDBDatabaseException::InvalidStateError;
+        ec.code = IDBDatabaseException::InvalidStateError;
         return 0;
     }
     RefPtr<LegacyRequest> request = LegacyRequest::create(context, LegacyAny::create(this), m_transaction.get());
-    m_backend->deleteFunction(request, ec);
-    ASSERT(!ec);
+    m_backend->deleteFunction(request, ec.code);
+    ASSERT(!ec.code);
     return request.release();
 }
 
index 53e9994..46e0b42 100644 (file)
@@ -61,14 +61,14 @@ public:
     const Deprecated::ScriptValue& value() const override;
     IDBAny* source() override;
 
-    RefPtr<IDBRequest> update(JSC::ExecState&, Deprecated::ScriptValue&, ExceptionCode&) override;
+    RefPtr<IDBRequest> update(JSC::ExecState&, Deprecated::ScriptValue&, ExceptionCodeWithMessage&) override;
     void advance(unsigned long, ExceptionCodeWithMessage&) override;
     // FIXME: Try to modify the code generator so this overload is unneeded.
-    void continueFunction(ScriptExecutionContext*, ExceptionCode& ec) override { continueFunction(static_cast<IDBKey*>(nullptr), ec); }
-    void continueFunction(ScriptExecutionContext*, const Deprecated::ScriptValue& key, ExceptionCode&) override;
-    RefPtr<IDBRequest> deleteFunction(ScriptExecutionContext*, ExceptionCode&) override;
+    void continueFunction(ScriptExecutionContext*, ExceptionCodeWithMessage& ec) override { continueFunction(static_cast<IDBKey*>(nullptr), ec); }
+    void continueFunction(ScriptExecutionContext*, const Deprecated::ScriptValue& key, ExceptionCodeWithMessage&) override;
+    RefPtr<IDBRequest> deleteFunction(ScriptExecutionContext*, ExceptionCodeWithMessage&) override;
 
-    void continueFunction(PassRefPtr<IDBKey>, ExceptionCode&);
+    void continueFunction(PassRefPtr<IDBKey>, ExceptionCodeWithMessage&);
     void postSuccessHandlerCallback();
     void close();
     void setValueReady(DOMRequestState*, PassRefPtr<IDBKey>, PassRefPtr<IDBKey> primaryKey, Deprecated::ScriptValue&);
index 865c9f2..c068cdb 100644 (file)
@@ -161,7 +161,7 @@ uint64_t LegacyDatabase::version() const
     return m_metadata.version != IDBDatabaseMetadata::NoIntVersion ? m_metadata.version : static_cast<uint64_t>(IDBDatabaseMetadata::DefaultIntVersion);
 }
 
-RefPtr<IDBObjectStore> LegacyDatabase::createObjectStore(const String& name, const Dictionary& options, ExceptionCode& ec)
+RefPtr<IDBObjectStore> LegacyDatabase::createObjectStore(const String& name, const Dictionary& options, ExceptionCodeWithMessage& ec)
 {
     IDBKeyPath keyPath;
     bool autoIncrement = false;
@@ -179,30 +179,30 @@ RefPtr<IDBObjectStore> LegacyDatabase::createObjectStore(const String& name, con
     return createObjectStore(name, keyPath, autoIncrement, ec);
 }
 
-RefPtr<IDBObjectStore> LegacyDatabase::createObjectStore(const String& name, const IDBKeyPath& keyPath, bool autoIncrement, ExceptionCode& ec)
+RefPtr<IDBObjectStore> LegacyDatabase::createObjectStore(const String& name, const IDBKeyPath& keyPath, bool autoIncrement, ExceptionCodeWithMessage& ec)
 {
     LOG(StorageAPI, "LegacyDatabase::createObjectStore");
     if (!m_versionChangeTransaction) {
-        ec = IDBDatabaseException::InvalidStateError;
+        ec.code = IDBDatabaseException::InvalidStateError;
         return 0;
     }
     if (!m_versionChangeTransaction->isActive()) {
-        ec = IDBDatabaseException::TransactionInactiveError;
+        ec.code = IDBDatabaseException::TransactionInactiveError;
         return 0;
     }
 
     if (containsObjectStore(name)) {
-        ec = IDBDatabaseException::ConstraintError;
+        ec.code = IDBDatabaseException::ConstraintError;
         return 0;
     }
 
     if (!keyPath.isNull() && !keyPath.isValid()) {
-        ec = IDBDatabaseException::SyntaxError;
+        ec.code = IDBDatabaseException::SyntaxError;
         return 0;
     }
 
     if (autoIncrement && ((keyPath.type() == IndexedDB::KeyPathType::String && keyPath.string().isEmpty()) || keyPath.type() == IndexedDB::KeyPathType::Array)) {
-        ec = IDBDatabaseException::InvalidAccessError;
+        ec.code = IDBDatabaseException::InvalidAccessError;
         return 0;
     }
 
@@ -218,21 +218,21 @@ RefPtr<IDBObjectStore> LegacyDatabase::createObjectStore(const String& name, con
     return objectStore.release();
 }
 
-void LegacyDatabase::deleteObjectStore(const String& name, ExceptionCode& ec)
+void LegacyDatabase::deleteObjectStore(const String& name, ExceptionCodeWithMessage& ec)
 {
     LOG(StorageAPI, "LegacyDatabase::deleteObjectStore");
     if (!m_versionChangeTransaction) {
-        ec = IDBDatabaseException::InvalidStateError;
+        ec.code = IDBDatabaseException::InvalidStateError;
         return;
     }
     if (!m_versionChangeTransaction->isActive()) {
-        ec = IDBDatabaseException::TransactionInactiveError;
+        ec.code = IDBDatabaseException::TransactionInactiveError;
         return;
     }
 
     int64_t objectStoreId = findObjectStoreId(name);
     if (objectStoreId == IDBObjectStoreMetadata::InvalidId) {
-        ec = IDBDatabaseException::NotFoundError;
+        ec.code = IDBDatabaseException::NotFoundError;
         return;
     }
 
@@ -241,20 +241,20 @@ void LegacyDatabase::deleteObjectStore(const String& name, ExceptionCode& ec)
     m_metadata.objectStores.remove(objectStoreId);
 }
 
-RefPtr<IDBTransaction> LegacyDatabase::transaction(ScriptExecutionContext* context, const Vector<String>& scope, const String& modeString, ExceptionCode& ec)
+RefPtr<IDBTransaction> LegacyDatabase::transaction(ScriptExecutionContext* context, const Vector<String>& scope, const String& modeString, ExceptionCodeWithMessage& ec)
 {
     LOG(StorageAPI, "LegacyDatabase::transaction");
     if (!scope.size()) {
-        ec = IDBDatabaseException::InvalidAccessError;
+        ec.code = IDBDatabaseException::InvalidAccessError;
         return 0;
     }
 
-    IndexedDB::TransactionMode mode = IDBTransaction::stringToMode(modeString, ec);
-    if (ec)
+    IndexedDB::TransactionMode mode = IDBTransaction::stringToMode(modeString, ec.code);
+    if (ec.code)
         return 0;
 
     if (m_versionChangeTransaction || m_closePending) {
-        ec = IDBDatabaseException::InvalidStateError;
+        ec.code = IDBDatabaseException::InvalidStateError;
         return 0;
     }
 
@@ -262,7 +262,7 @@ RefPtr<IDBTransaction> LegacyDatabase::transaction(ScriptExecutionContext* conte
     for (auto& name : scope) {
         int64_t objectStoreId = findObjectStoreId(name);
         if (objectStoreId == IDBObjectStoreMetadata::InvalidId) {
-            ec = IDBDatabaseException::NotFoundError;
+            ec.code = IDBDatabaseException::NotFoundError;
             return 0;
         }
         objectStoreIds.append(objectStoreId);
@@ -275,7 +275,7 @@ RefPtr<IDBTransaction> LegacyDatabase::transaction(ScriptExecutionContext* conte
     return transaction.release();
 }
 
-RefPtr<IDBTransaction> LegacyDatabase::transaction(ScriptExecutionContext* context, const String& storeName, const String& mode, ExceptionCode& ec)
+RefPtr<IDBTransaction> LegacyDatabase::transaction(ScriptExecutionContext* context, const String& storeName, const String& mode, ExceptionCodeWithMessage& ec)
 {
     RefPtr<DOMStringList> storeNames = DOMStringList::create();
     storeNames->append(storeName);
@@ -284,8 +284,9 @@ RefPtr<IDBTransaction> LegacyDatabase::transaction(ScriptExecutionContext* conte
 
 void LegacyDatabase::forceClose()
 {
+    ExceptionCodeWithMessage ec;
     for (auto& transaction : m_transactions.values())
-        transaction->abort(IGNORE_EXCEPTION);
+        transaction->abort(ec);
     this->close();
 }
 
index 651ecb4..a128af4 100644 (file)
@@ -65,11 +65,11 @@ public:
     virtual uint64_t version() const override final;
     virtual RefPtr<DOMStringList> objectStoreNames() const override final;
 
-    virtual RefPtr<IDBObjectStore> createObjectStore(const String& name, const Dictionary&, ExceptionCode&) override final;
-    virtual RefPtr<IDBObjectStore> createObjectStore(const String& name, const IDBKeyPath&, bool autoIncrement, ExceptionCode&) override final;
-    virtual RefPtr<IDBTransaction> transaction(ScriptExecutionContext*, const Vector<String>&, const String& mode, ExceptionCode&) override final;
-    virtual RefPtr<IDBTransaction> transaction(ScriptExecutionContext*, const String&, const String& mode, ExceptionCode&) override final;
-    virtual void deleteObjectStore(const String& name, ExceptionCode&) override final;
+    virtual RefPtr<IDBObjectStore> createObjectStore(const String& name, const Dictionary&, ExceptionCodeWithMessage&) override final;
+    virtual RefPtr<IDBObjectStore> createObjectStore(const String& name, const IDBKeyPath&, bool autoIncrement, ExceptionCodeWithMessage&) override final;
+    virtual RefPtr<IDBTransaction> transaction(ScriptExecutionContext*, const Vector<String>&, const String& mode, ExceptionCodeWithMessage&) override final;
+    virtual RefPtr<IDBTransaction> transaction(ScriptExecutionContext*, const String&, const String& mode, ExceptionCodeWithMessage&) override final;
+    virtual void deleteObjectStore(const String& name, ExceptionCodeWithMessage&) override final;
     virtual void close() override final;
 
     // IDBDatabaseCallbacks
@@ -105,7 +105,7 @@ public:
 private:
     LegacyDatabase(ScriptExecutionContext*, PassRefPtr<IDBDatabaseBackend>, PassRefPtr<IDBDatabaseCallbacks>);
 
-    PassRefPtr<IDBTransaction> transaction(ScriptExecutionContext* context, PassRefPtr<DOMStringList> scope, const String& mode, ExceptionCode& ec) { return transaction(context, *scope, mode, ec); }
+    PassRefPtr<IDBTransaction> transaction(ScriptExecutionContext* context, PassRefPtr<DOMStringList> scope, const String& mode, ExceptionCodeWithMessage& ec) { return transaction(context, *scope, mode, ec); }
 
     // ActiveDOMObject API.
     void stop() override;
index a63680e..80852ca 100644 (file)
@@ -146,7 +146,7 @@ RefPtr<IDBOpenDBRequest> LegacyFactory::deleteDatabase(ScriptExecutionContext* c
     return request;
 }
 
-short LegacyFactory::cmp(ScriptExecutionContext* context, const Deprecated::ScriptValue& firstValue, const Deprecated::ScriptValue& secondValue, ExceptionCode& ec)
+short LegacyFactory::cmp(ScriptExecutionContext* context, const Deprecated::ScriptValue& firstValue, const Deprecated::ScriptValue& secondValue, ExceptionCodeWithMessage& ec)
 {
     DOMRequestState requestState(context);
     RefPtr<IDBKey> first = scriptValueToIDBKey(&requestState, firstValue);
@@ -156,7 +156,7 @@ short LegacyFactory::cmp(ScriptExecutionContext* context, const Deprecated::Scri
     ASSERT(second);
 
     if (!first->isValid() || !second->isValid()) {
-        ec = IDBDatabaseException::DataError;
+        ec.code = IDBDatabaseException::DataError;
         return 0;
     }
 
index f591c0f..43c1e74 100644 (file)
@@ -67,7 +67,7 @@ public:
     virtual RefPtr<IDBOpenDBRequest> open(ScriptExecutionContext*, const String& name, unsigned long long version, ExceptionCode&) override;
     virtual RefPtr<IDBOpenDBRequest> deleteDatabase(ScriptExecutionContext*, const String& name, ExceptionCode&) override;
 
-    short cmp(ScriptExecutionContext*, const Deprecated::ScriptValue& first, const Deprecated::ScriptValue& second, ExceptionCode&) override;
+    short cmp(ScriptExecutionContext*, const Deprecated::ScriptValue& first, const Deprecated::ScriptValue& second, ExceptionCodeWithMessage&) override;
 
 private:
     LegacyFactory(IDBFactoryBackendInterface*);
index 183506b..529c6e3 100644 (file)
@@ -54,19 +54,19 @@ LegacyIndex::~LegacyIndex()
 {
 }
 
-RefPtr<IDBRequest> LegacyIndex::openCursor(ScriptExecutionContext* context, IDBKeyRange* keyRange, const String& directionString, ExceptionCode& ec)
+RefPtr<IDBRequest> LegacyIndex::openCursor(ScriptExecutionContext* context, IDBKeyRange* keyRange, const String& directionString, ExceptionCodeWithMessage& ec)
 {
     LOG(StorageAPI, "LegacyIndex::openCursor");
     if (m_deleted) {
-        ec = IDBDatabaseException::InvalidStateError;
+        ec.code = IDBDatabaseException::InvalidStateError;
         return 0;
     }
     if (!m_transaction->isActive()) {
-        ec = IDBDatabaseException::TransactionInactiveError;
+        ec.code = IDBDatabaseException::TransactionInactiveError;
         return 0;
     }
-    IndexedDB::CursorDirection direction = IDBCursor::stringToDirection(directionString, ec);
-    if (ec)
+    IndexedDB::CursorDirection direction = IDBCursor::stringToDirection(directionString, ec.code);
+    if (ec.code)
         return 0;
 
     RefPtr<LegacyRequest> request = LegacyRequest::create(context, LegacyAny::create(this), m_transaction.get());
@@ -75,24 +75,24 @@ RefPtr<IDBRequest> LegacyIndex::openCursor(ScriptExecutionContext* context, IDBK
     return request;
 }
 
-RefPtr<IDBRequest> LegacyIndex::openCursor(ScriptExecutionContext* context, const Deprecated::ScriptValue& key, const String& direction, ExceptionCode& ec)
+RefPtr<IDBRequest> LegacyIndex::openCursor(ScriptExecutionContext* context, const Deprecated::ScriptValue& key, const String& direction, ExceptionCodeWithMessage& ec)
 {
     LOG(StorageAPI, "LegacyIndex::openCursor");
-    RefPtr<IDBKeyRange> keyRange = IDBKeyRange::only(context, key, ec);
-    if (ec)
+    RefPtr<IDBKeyRange> keyRange = IDBKeyRange::only(context, key, ec.code);
+    if (ec.code)
         return 0;
     return openCursor(context, keyRange.get(), direction, ec);
 }
 
-RefPtr<IDBRequest> LegacyIndex::count(ScriptExecutionContext* context, IDBKeyRange* keyRange, ExceptionCode& ec)
+RefPtr<IDBRequest> LegacyIndex::count(ScriptExecutionContext* context, IDBKeyRange* keyRange, ExceptionCodeWithMessage& ec)
 {
     LOG(StorageAPI, "LegacyIndex::count");
     if (m_deleted) {
-        ec = IDBDatabaseException::InvalidStateError;
+        ec.code = IDBDatabaseException::InvalidStateError;