Title: [121488] trunk
Revision
121488
Author
[email protected]
Date
2012-06-28 16:48:31 -0700 (Thu, 28 Jun 2012)

Log Message

IndexedDB: IDBDatabase should have a close pending field.
https://bugs.webkit.org/show_bug.cgi?id=71129

Reviewed by Tony Chang.

Source/WebCore:

Handle the IDB spec case that "versionchange" events should not be fired
against connections that have the internal "closePending" flag set but
are not yet closed due to running transactions.

Test: storage/indexeddb/database-closepending-flag.html

* Modules/indexeddb/IDBDatabase.cpp:
(WebCore::IDBDatabase::onVersionChange):

LayoutTests:

* storage/indexeddb/database-closepending-flag-expected.txt: Added.
* storage/indexeddb/database-closepending-flag.html: Added.
* storage/indexeddb/resources/database-closepending-flag.js: Added.
(test):
(openConnection.request.onsuccess.request.onsuccess):
(openConnection.request.onsuccess):
(openConnection):
(testIDBDatabaseName):
(testIDBDatabaseObjectStoreNames.request.onsuccess.request.onsuccess.transaction.oncomplete):
(testIDBDatabaseObjectStoreNames.request.onsuccess.request.onsuccess):
(testIDBDatabaseObjectStoreNames.request.onsuccess):
(testIDBDatabaseObjectStoreNames):
(testIDBDatabaseTransaction):
(testVersionChangeTransactionSteps.request.onsuccess.request.onsuccess.request.onblocked):
(testVersionChangeTransactionSteps.request.onsuccess.request.onsuccess.request.onsuccess.transaction.oncomplete):
(testVersionChangeTransactionSteps.request.onsuccess.request.onsuccess.request.onsuccess):
(testVersionChangeTransactionSteps.request.onsuccess.request.onsuccess):
(testDatabaseDeletion.request.onsuccess.request.onblocked):
(testDatabaseDeletion.request.onsuccess.request.onsuccess):

Modified Paths

Added Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (121487 => 121488)


--- trunk/LayoutTests/ChangeLog	2012-06-28 23:38:59 UTC (rev 121487)
+++ trunk/LayoutTests/ChangeLog	2012-06-28 23:48:31 UTC (rev 121488)
@@ -1,3 +1,30 @@
+2012-06-28  Joshua Bell  <[email protected]>
+
+        IndexedDB: IDBDatabase should have a close pending field.
+        https://bugs.webkit.org/show_bug.cgi?id=71129
+
+        Reviewed by Tony Chang.
+
+        * storage/indexeddb/database-closepending-flag-expected.txt: Added.
+        * storage/indexeddb/database-closepending-flag.html: Added.
+        * storage/indexeddb/resources/database-closepending-flag.js: Added.
+        (test):
+        (openConnection.request.onsuccess.request.onsuccess):
+        (openConnection.request.onsuccess):
+        (openConnection):
+        (testIDBDatabaseName):
+        (testIDBDatabaseObjectStoreNames.request.onsuccess.request.onsuccess.transaction.oncomplete):
+        (testIDBDatabaseObjectStoreNames.request.onsuccess.request.onsuccess):
+        (testIDBDatabaseObjectStoreNames.request.onsuccess):
+        (testIDBDatabaseObjectStoreNames):
+        (testIDBDatabaseTransaction):
+        (testVersionChangeTransactionSteps.request.onsuccess.request.onsuccess.request.onblocked):
+        (testVersionChangeTransactionSteps.request.onsuccess.request.onsuccess.request.onsuccess.transaction.oncomplete):
+        (testVersionChangeTransactionSteps.request.onsuccess.request.onsuccess.request.onsuccess):
+        (testVersionChangeTransactionSteps.request.onsuccess.request.onsuccess):
+        (testDatabaseDeletion.request.onsuccess.request.onblocked):
+        (testDatabaseDeletion.request.onsuccess.request.onsuccess):
+
 2012-06-28  Ojan Vafai  <[email protected]>
 
         Replace a BUG_OJAN with a proper tracking bug and unskip two

Added: trunk/LayoutTests/storage/indexeddb/database-closepending-flag-expected.txt (0 => 121488)


--- trunk/LayoutTests/storage/indexeddb/database-closepending-flag-expected.txt	                        (rev 0)
+++ trunk/LayoutTests/storage/indexeddb/database-closepending-flag-expected.txt	2012-06-28 23:48:31 UTC (rev 121488)
@@ -0,0 +1,82 @@
+Test IndexedDB IDBDatabase internal closePending 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 = self.location.pathname
+indexedDB.deleteDatabase(dbname)
+
+openConnection():
+request = indexedDB.open(dbname)
+connection = request.result
+request = connection.setVersion('1')
+store = connection.createObjectStore('store')
+
+First, verify that the database connection is not closed:
+PASS transaction = connection.transaction('store') did not throw exception.
+
+Database closing steps
+"1. Set the internal closePending flag of connection to true."
+connection.close()
+Expecting exception from connection.transaction('store')
+PASS Exception was thrown.
+PASS code is DOMException.INVALID_STATE_ERR
+PASS ename is 'InvalidStateError'
+"2. Wait for all transactions created using connection to complete. Once they are complete, connection is closed."
+transaction._oncomplete_ = testIDBDatabaseName
+
+IDBDatabase.name:
+"The function must return this name even if the closePending flag is set on the connection."
+PASS connection.name is dbname
+
+IDBDatabase.objectStoreNames:
+"Once the closePending flag is set on the connection, this function must return a snapshot of the list of names of the object stores taken at the time when the close method was called."
+request = indexedDB.open(dbname)
+version_change_connection = request.result
+version_change_connection.setVersion('2')
+version_change_connection.createObjectStore('new_store')
+PASS version_change_connection.objectStoreNames.contains('new_store') is true
+PASS connection.objectStoreNames.contains('new_store') is false
+version_change_connection.close()
+
+IDBDatabase.transaction():
+"...if this method is called on a IDBDatabase instance where the closePending flag is set, a InvalidStateError exception must be thrown."
+Expecting exception from connection.transaction('store')
+PASS Exception was thrown.
+PASS code is DOMException.INVALID_STATE_ERR
+PASS ename is 'InvalidStateError'
+
+"versionchange" transaction steps:
+"Fire a versionchange event at each object in openDatabases that is open. The event must not be fired on objects which has the closePending flag set."
+request = indexedDB.open(dbname)
+connection = request.result
+versionChangeWasFired = false
+connection._onversionchange_ = function () { versionChangeWasFired = true; }
+transaction = connection.transaction('store')
+connection.close()
+closePending is set, but active transaction will keep connection from closing
+request = indexedDB.open(dbname)
+version_change_connection = request.result
+version_change_connection.setVersion('3')
+'blocked' event fired, letting transaction complete and connection close
+PASS versionChangeWasFired is false
+version_change_connection.close()
+
+Database deletion steps:
+"Fire a versionchange event at each object in openDatabases that is open. The event must not be fired on objects which has the closePending flag set."
+request = indexedDB.open(dbname)
+connection = request.result
+versionChangeWasFired = false
+connection._onversionchange_ = function () { versionChangeWasFired = true; }
+transaction = connection.transaction('store')
+connection.close()
+closePending is set, but active transaction will keep connection from closing
+request = indexedDB.deleteDatabase(dbname)
+'blocked' event fired, letting transaction complete and connection close
+PASS versionChangeWasFired is false
+PASS successfullyParsed is true
+
+TEST COMPLETE
+

Added: trunk/LayoutTests/storage/indexeddb/database-closepending-flag.html (0 => 121488)


--- trunk/LayoutTests/storage/indexeddb/database-closepending-flag.html	                        (rev 0)
+++ trunk/LayoutTests/storage/indexeddb/database-closepending-flag.html	2012-06-28 23:48:31 UTC (rev 121488)
@@ -0,0 +1,10 @@
+<html>
+<head>
+<script src=""
+<script src=""
+</head>
+<body>
+<script src=""
+<script src=""
+</body>
+</html>

Added: trunk/LayoutTests/storage/indexeddb/resources/database-closepending-flag.js (0 => 121488)


--- trunk/LayoutTests/storage/indexeddb/resources/database-closepending-flag.js	                        (rev 0)
+++ trunk/LayoutTests/storage/indexeddb/resources/database-closepending-flag.js	2012-06-28 23:48:31 UTC (rev 121488)
@@ -0,0 +1,183 @@
+if (this.importScripts) {
+    importScripts('../../../fast/js/resources/js-test-pre.js');
+    importScripts('shared.js');
+}
+
+description("Test IndexedDB IDBDatabase internal closePending flag");
+
+function test()
+{
+    removeVendorPrefixes();
+
+    evalAndLog("dbname = self.location.pathname");
+    request = evalAndLog("indexedDB.deleteDatabase(dbname)");
+    request._onerror_ = unexpectedErrorCallback;
+    request._onsuccess_ = openConnection;
+}
+
+function openConnection()
+{
+    debug("");
+    debug("openConnection():");
+    evalAndLog("request = indexedDB.open(dbname)");
+    request._onerror_ = unexpectedErrorCallback;
+    request._onsuccess_ = function() {
+        evalAndLog("connection = request.result");
+        evalAndLog("request = connection.setVersion('1')");
+        request._onerror_ = unexpectedErrorCallback;
+        request._onsuccess_ = function() {
+            trans = request.result;
+            evalAndLog("store = connection.createObjectStore('store')");
+            trans._onabort_ = unexpectedAbortCallback;
+            trans._oncomplete_ = testDatabaseClosingSteps;
+        };
+    };
+}
+
+function testDatabaseClosingSteps()
+{
+    debug("");
+    debug("First, verify that the database connection is not closed:");
+    shouldNotThrow("transaction = connection.transaction('store')");
+    transaction.objectStore('store').get(0); // FIXME: Can remove this line when WK89379 lands
+
+    debug("");
+    debug("Database closing steps");
+    debug("\"1. Set the internal closePending flag of connection to true.\"");
+    evalAndLog("connection.close()");
+    evalAndExpectException("connection.transaction('store')", "DOMException.INVALID_STATE_ERR", "'InvalidStateError'");
+    debug("\"2. Wait for all transactions created using connection to complete. Once they are complete, connection is closed.\"");
+
+    evalAndLog("transaction._oncomplete_ = testIDBDatabaseName");
+}
+
+function testIDBDatabaseName()
+{
+    debug("");
+    debug("IDBDatabase.name:");
+    debug("\"The function must return this name even if the closePending flag is set on the connection.\"");
+    shouldBe("connection.name", "dbname");
+
+    testIDBDatabaseObjectStoreNames();
+}
+
+function testIDBDatabaseObjectStoreNames()
+{
+    debug("");
+    debug("IDBDatabase.objectStoreNames:");
+    debug("\"Once the closePending flag is set on the connection, this function must return a snapshot of the list of names of the object stores taken at the time when the close method was called.\"");
+
+    evalAndLog("request = indexedDB.open(dbname)");
+    request._onerror_ = unexpectedErrorCallback;
+    request._onsuccess_ = function() {
+        evalAndLog("version_change_connection = request.result");
+        request = evalAndLog("version_change_connection.setVersion('2')");
+        // FIXME: Should verify 'blocked' not fired. http://webkit.org/b/71130
+        request._onerror_ = unexpectedErrorCallback;
+        request._onsuccess_ = function () {
+            var transaction = request.result;
+            evalAndLog("version_change_connection.createObjectStore('new_store')");
+            transaction._oncomplete_ = function () {
+                shouldBeTrue("version_change_connection.objectStoreNames.contains('new_store')");
+                shouldBeFalse("connection.objectStoreNames.contains('new_store')");
+                evalAndLog("version_change_connection.close()");
+
+                testIDBDatabaseTransaction();
+            };
+        };
+    };
+}
+
+function testIDBDatabaseTransaction()
+{
+    debug("");
+    debug("IDBDatabase.transaction():");
+    debug("\"...if this method is called on a IDBDatabase instance where the closePending flag is set, a InvalidStateError exception must be thrown.\"");
+    evalAndExpectException("connection.transaction('store')", "DOMException.INVALID_STATE_ERR", "'InvalidStateError'");
+
+    testVersionChangeTransactionSteps();
+}
+
+function testVersionChangeTransactionSteps()
+{
+    debug("");
+    debug("\"versionchange\" transaction steps:");
+    debug("\"Fire a versionchange event at each object in openDatabases that is open. The event must not be fired on objects which has the closePending flag set.\"");
+
+    evalAndLog("request = indexedDB.open(dbname)");
+    request._onerror_ = unexpectedErrorCallback;
+    request._onsuccess_ = function() {
+        evalAndLog("connection = request.result");
+        evalAndLog("versionChangeWasFired = false");
+        evalAndLog("connection._onversionchange_ = function () { versionChangeWasFired = true; }");
+        evalAndLog("transaction = connection.transaction('store')");
+        evalAndLog("connection.close()");
+        debug("closePending is set, but active transaction will keep connection from closing");
+
+        keepTransactionBusy = true;
+        function busy() {
+            if (keepTransactionBusy)
+                transaction.objectStore('store').get(0)._onsuccess_ = busy;
+        }
+        busy();
+
+        evalAndLog("request = indexedDB.open(dbname)");
+        request._onerror_ = unexpectedErrorCallback;
+        request._onsuccess_ = function() {
+            evalAndLog("version_change_connection = request.result");
+            request = evalAndLog("version_change_connection.setVersion('3')");
+            request._onblocked_ = function () {
+                debug("'blocked' event fired, letting transaction complete and connection close");
+                keepTransactionBusy = false;
+            };
+            request._onerror_ = unexpectedErrorCallback;
+            request._onsuccess_ = function () {
+                shouldBeFalse("versionChangeWasFired");
+                var transaction = request.result;
+                transaction._oncomplete_ = function () {
+                    request = evalAndLog("version_change_connection.close()");
+
+                    testDatabaseDeletion();
+                };
+            };
+        };
+    };
+}
+
+function testDatabaseDeletion()
+{
+    debug("");
+    debug("Database deletion steps:");
+    debug("\"Fire a versionchange event at each object in openDatabases that is open. The event must not be fired on objects which has the closePending flag set.\"");
+
+    evalAndLog("request = indexedDB.open(dbname)");
+    request._onerror_ = unexpectedErrorCallback;
+    request._onsuccess_ = function() {
+        evalAndLog("connection = request.result");
+        evalAndLog("versionChangeWasFired = false");
+        evalAndLog("connection._onversionchange_ = function () { versionChangeWasFired = true; }");
+        evalAndLog("transaction = connection.transaction('store')");
+        evalAndLog("connection.close()");
+        debug("closePending is set, but active transaction will keep connection from closing");
+
+        keepTransactionBusy = true;
+        function busy() {
+            if (keepTransactionBusy)
+                transaction.objectStore('store').get(0)._onsuccess_ = busy;
+        }
+        busy();
+
+        evalAndLog("request = indexedDB.deleteDatabase(dbname)");
+        request._onblocked_ = function () {
+            debug("'blocked' event fired, letting transaction complete and connection close");
+            keepTransactionBusy = false;
+        };
+        request._onerror_ = unexpectedErrorCallback;
+        request._onsuccess_ = function () {
+            shouldBeFalse("versionChangeWasFired");
+            finishJSTest();
+        };
+    };
+}
+
+test();

Modified: trunk/Source/WebCore/ChangeLog (121487 => 121488)


--- trunk/Source/WebCore/ChangeLog	2012-06-28 23:38:59 UTC (rev 121487)
+++ trunk/Source/WebCore/ChangeLog	2012-06-28 23:48:31 UTC (rev 121488)
@@ -1,3 +1,19 @@
+2012-06-28  Joshua Bell  <[email protected]>
+
+        IndexedDB: IDBDatabase should have a close pending field.
+        https://bugs.webkit.org/show_bug.cgi?id=71129
+
+        Reviewed by Tony Chang.
+
+        Handle the IDB spec case that "versionchange" events should not be fired 
+        against connections that have the internal "closePending" flag set but 
+        are not yet closed due to running transactions.
+
+        Test: storage/indexeddb/database-closepending-flag.html
+
+        * Modules/indexeddb/IDBDatabase.cpp:
+        (WebCore::IDBDatabase::onVersionChange):
+
 2012-06-28  Adrienne Walker  <[email protected]>
 
         [chromium] Split WebScrollbar into WebPluginScrollbar and WebScrollbar

Modified: trunk/Source/WebCore/Modules/indexeddb/IDBDatabase.cpp (121487 => 121488)


--- trunk/Source/WebCore/Modules/indexeddb/IDBDatabase.cpp	2012-06-28 23:38:59 UTC (rev 121487)
+++ trunk/Source/WebCore/Modules/indexeddb/IDBDatabase.cpp	2012-06-28 23:48:31 UTC (rev 121488)
@@ -297,6 +297,9 @@
     if (m_contextStopped || !scriptExecutionContext())
         return;
 
+    if (m_closePending)
+        return;
+
     enqueueEvent(IDBVersionChangeEvent::create(version, eventNames().versionchangeEvent));
 }
 
_______________________________________________
webkit-changes mailing list
[email protected]
http://lists.webkit.org/mailman/listinfo.cgi/webkit-changes

Reply via email to