Title: [191198] trunk
Revision
191198
Author
beid...@apple.com
Date
2015-10-16 13:04:13 -0700 (Fri, 16 Oct 2015)

Log Message

Source/WebCore:
Modern IDB: Handle versionchange events.
https://bugs.webkit.org/show_bug.cgi?id=150149

Reviewed by Alex Christensen.

Test: storage/indexeddb/modern/versionchange-event.html

- IDBVersionChangeEvents are now dispatched to open connections when a
  version upgrade request comes in.
- Once all of those open connections have closed, the version upgrade
  request is handled.

* Modules/indexeddb/client/IDBConnectionToServer.cpp:
(WebCore::IDBClient::IDBConnectionToServer::fireVersionChangeEvent):
(WebCore::IDBClient::IDBConnectionToServer::registerDatabaseConnection):
(WebCore::IDBClient::IDBConnectionToServer::unregisterDatabaseConnection):
* Modules/indexeddb/client/IDBConnectionToServer.h:

* Modules/indexeddb/client/IDBDatabaseImpl.cpp:
(WebCore::IDBClient::IDBDatabase::fireVersionChangeEvent):
* Modules/indexeddb/client/IDBDatabaseImpl.h:

* Modules/indexeddb/server/UniqueIDBDatabase.cpp:
(WebCore::IDBServer::UniqueIDBDatabase::UniqueIDBDatabase):
(WebCore::IDBServer::UniqueIDBDatabase::connectionClosedFromClient):
(WebCore::IDBServer::UniqueIDBDatabase::invokeTransactionScheduler):
(WebCore::IDBServer::UniqueIDBDatabase::transactionSchedulingTimerFired):
* Modules/indexeddb/server/UniqueIDBDatabase.h:

LayoutTests:
Modern IDB: Add versionchange events.
https://bugs.webkit.org/show_bug.cgi?id=150149

Reviewed by Alex Christensen.

* storage/indexeddb/modern/versionchange-event-expected.txt: Added.
* storage/indexeddb/modern/versionchange-event.html: Added.

Modified Paths

Added Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (191197 => 191198)


--- trunk/LayoutTests/ChangeLog	2015-10-16 20:02:21 UTC (rev 191197)
+++ trunk/LayoutTests/ChangeLog	2015-10-16 20:04:13 UTC (rev 191198)
@@ -1,3 +1,13 @@
+2015-10-16  Brady Eidson  <beid...@apple.com>
+
+        Modern IDB: Add versionchange events.
+        https://bugs.webkit.org/show_bug.cgi?id=150149
+
+        Reviewed by Alex Christensen.
+
+        * storage/indexeddb/modern/versionchange-event-expected.txt: Added.
+        * storage/indexeddb/modern/versionchange-event.html: Added.
+
 2015-10-16  Zalan Bujtas  <za...@apple.com>
 
         First line box in paragraph using initial-letter overflows.

Added: trunk/LayoutTests/storage/indexeddb/modern/versionchange-event-expected.txt (0 => 191198)


--- trunk/LayoutTests/storage/indexeddb/modern/versionchange-event-expected.txt	                        (rev 0)
+++ trunk/LayoutTests/storage/indexeddb/modern/versionchange-event-expected.txt	2015-10-16 20:04:13 UTC (rev 191198)
@@ -0,0 +1,17 @@
+ALERT: upgradeneeded (firstPhase): old version - 0 new version - 1
+ALERT: Version change complete (firstPhase). Database version is now - 1
+ALERT: Open success (secondPhase)
+ALERT: thirdPhase - Requested database connection with version 2
+ALERT: secondPhase connection versionchange event - old version: 1, new version: 2
+ALERT: firstPhase connection versionchange event - old version: 1, new version: 2
+ALERT: Expected upgrade needed (thirdPhase)
+ALERT: Done
+This test:
+-Opens a connection to a database at version 1, creating the database
+-Commits the version change transaction for that database
+-Opens a second connection to that database, requesting version 1
+-Opens a third connection to that database, requesting version 2
+-Makes sure the first and second connections get the versionchange event
+-Closes the first and second connections
+-Makes sure the versionchange transaction for the second connection starts successfully
+

Added: trunk/LayoutTests/storage/indexeddb/modern/versionchange-event.html (0 => 191198)


--- trunk/LayoutTests/storage/indexeddb/modern/versionchange-event.html	                        (rev 0)
+++ trunk/LayoutTests/storage/indexeddb/modern/versionchange-event.html	2015-10-16 20:04:13 UTC (rev 191198)
@@ -0,0 +1,110 @@
+This test:<br>
+-Opens a connection to a database at version 1, creating the database<br>
+-Commits the version change transaction for that database<br>
+-Opens a second connection to that database, requesting version 1<br>
+-Opens a third connection to that database, requesting version 2<br>
+-Makes sure the first and second connections get the versionchange event<br>
+-Closes the first and second connections<br>
+-Makes sure the versionchange transaction for the second connection starts successfully<br>
+<script>
+
+if (window.testRunner) {
+    testRunner.waitUntilDone();
+    testRunner.dumpAsText();
+}
+
+function done()
+{
+    alert("Done");
+    if (window.testRunner)
+        testRunner.notifyDone();
+}
+
+var request = window.indexedDB.open("VersionChangeTestDatabase");
+var connection1;
+var connection2;
+
+request._onsuccess_ = function()
+{
+    alert("Unexpected success (firstPhase)");
+	done();
+}
+request._onerror_ = function(e)
+{
+    alert("Unexpected error (firstPhase)");
+	done();
+}
+
+request._onupgradeneeded_ = function(e)
+{
+    alert("upgradeneeded (firstPhase): old version - " + e.oldVersion + " new version - " + e.newVersion);
+    request.transaction._oncomplete_ = function()
+    {
+        alert("Version change complete (firstPhase). Database version is now - " + request.transaction.db.version);
+        connection1 = request.transaction.db;
+        connection1._onversionchange_ = function(e)
+        {
+            alert("firstPhase connection versionchange event - old version: " + e.oldVersion + ", new version: " + e.newVersion);
+            connection1.close();
+        }
+        secondPhase();
+    }
+    request.transaction._onabort_ = function()
+    {
+        alert("Version change transaction unexpected abort (firstPhase)");
+        done();
+    }
+    request.transaction._onerror_ = function()
+    {
+        alert("Version change transaction unexpected error (firstPhase)");
+        done();
+    }
+}
+
+function secondPhase()
+{
+    var request = window.indexedDB.open("VersionChangeTestDatabase", 1);
+    request._onsuccess_ = function()
+    {
+        alert("Open success (secondPhase)");
+        connection2 = request.result;
+        connection2._onversionchange_ = function(e)
+        {
+            alert("secondPhase connection versionchange event - old version: " + e.oldVersion + ", new version: " + e.newVersion);
+            connection2.close();
+        }
+        thirdPhase();
+    }
+    request._onerror_ = function(e)
+    {
+        alert("Unexpected open error (secondPhase)" + e);
+        done();
+    }
+    request._onupgradeneeded_ = function(e)
+    {
+    	alert("Unexpected upgrade needed (secondPhase)");
+    	done();
+    }
+}
+
+function thirdPhase()
+{
+    var request = window.indexedDB.open("VersionChangeTestDatabase", 2);
+    alert("thirdPhase - Requested database connection with version 2");
+    request._onsuccess_ = function()
+    {
+        alert("Unexpected open success (thirdPhase)");
+        done();
+    }
+    request._onerror_ = function(e)
+    {
+        alert("Unexpected open error (thirdPhase)" + e);
+        done();
+    }
+    request._onupgradeneeded_ = function(e)
+    {
+    	alert("Expected upgrade needed (thirdPhase)");
+    	done();
+    }
+}
+</script>

Modified: trunk/Source/WebCore/ChangeLog (191197 => 191198)


--- trunk/Source/WebCore/ChangeLog	2015-10-16 20:02:21 UTC (rev 191197)
+++ trunk/Source/WebCore/ChangeLog	2015-10-16 20:04:13 UTC (rev 191198)
@@ -1,3 +1,34 @@
+2015-10-16  Brady Eidson  <beid...@apple.com>
+
+        Modern IDB: Handle versionchange events.
+        https://bugs.webkit.org/show_bug.cgi?id=150149
+
+        Reviewed by Alex Christensen.
+
+        Test: storage/indexeddb/modern/versionchange-event.html
+        
+        - IDBVersionChangeEvents are now dispatched to open connections when a
+          version upgrade request comes in.
+        - Once all of those open connections have closed, the version upgrade 
+          request is handled.
+
+        * Modules/indexeddb/client/IDBConnectionToServer.cpp:
+        (WebCore::IDBClient::IDBConnectionToServer::fireVersionChangeEvent):
+        (WebCore::IDBClient::IDBConnectionToServer::registerDatabaseConnection):
+        (WebCore::IDBClient::IDBConnectionToServer::unregisterDatabaseConnection):
+        * Modules/indexeddb/client/IDBConnectionToServer.h:
+
+        * Modules/indexeddb/client/IDBDatabaseImpl.cpp:
+        (WebCore::IDBClient::IDBDatabase::fireVersionChangeEvent):
+        * Modules/indexeddb/client/IDBDatabaseImpl.h:
+
+        * Modules/indexeddb/server/UniqueIDBDatabase.cpp:
+        (WebCore::IDBServer::UniqueIDBDatabase::UniqueIDBDatabase):
+        (WebCore::IDBServer::UniqueIDBDatabase::connectionClosedFromClient):
+        (WebCore::IDBServer::UniqueIDBDatabase::invokeTransactionScheduler):
+        (WebCore::IDBServer::UniqueIDBDatabase::transactionSchedulingTimerFired):
+        * Modules/indexeddb/server/UniqueIDBDatabase.h:
+
 2015-10-16  Zalan Bujtas  <za...@apple.com>
 
         First line box in paragraph using initial-letter overflows.

Modified: trunk/Source/WebCore/Modules/indexeddb/client/IDBConnectionToServer.cpp (191197 => 191198)


--- trunk/Source/WebCore/Modules/indexeddb/client/IDBConnectionToServer.cpp	2015-10-16 20:02:21 UTC (rev 191197)
+++ trunk/Source/WebCore/Modules/indexeddb/client/IDBConnectionToServer.cpp	2015-10-16 20:04:13 UTC (rev 191198)
@@ -113,11 +113,15 @@
     transaction->didCommit(error);
 }
 
-void IDBConnectionToServer::fireVersionChangeEvent(uint64_t /*databaseConnectionIdentifier*/ , uint64_t /*requestedVersion*/)
+void IDBConnectionToServer::fireVersionChangeEvent(uint64_t databaseConnectionIdentifier, uint64_t requestedVersion)
 {
     LOG(IndexedDB, "IDBConnectionToServer::fireVersionChangeEvent");
 
-    // FIXME: Implement versionchange events firing on already-open transactions.
+    auto connection = m_databaseConnectionMap.get(databaseConnectionIdentifier);
+    if (!connection)
+        return;
+
+    connection->fireVersionChangeEvent(requestedVersion);
 }
 
 void IDBConnectionToServer::databaseConnectionClosed(IDBDatabase& database)
@@ -129,14 +133,15 @@
 
 void IDBConnectionToServer::registerDatabaseConnection(IDBDatabase& database)
 {
-    ASSERT(!m_databaseConnections.contains(&database));
-    m_databaseConnections.add(&database);
+    ASSERT(!m_databaseConnectionMap.contains(database.databaseConnectionIdentifier()));
+    m_databaseConnectionMap.set(database.databaseConnectionIdentifier(), &database);
 }
 
 void IDBConnectionToServer::unregisterDatabaseConnection(IDBDatabase& database)
 {
-    ASSERT(m_databaseConnections.contains(&database));
-    m_databaseConnections.remove(&database);
+    ASSERT(m_databaseConnectionMap.contains(database.databaseConnectionIdentifier()));
+    ASSERT(m_databaseConnectionMap.get(database.databaseConnectionIdentifier()) == &database);
+    m_databaseConnectionMap.remove(database.databaseConnectionIdentifier());
 }
 
 } // namespace IDBClient

Modified: trunk/Source/WebCore/Modules/indexeddb/client/IDBConnectionToServer.h (191197 => 191198)


--- trunk/Source/WebCore/Modules/indexeddb/client/IDBConnectionToServer.h	2015-10-16 20:02:21 UTC (rev 191197)
+++ trunk/Source/WebCore/Modules/indexeddb/client/IDBConnectionToServer.h	2015-10-16 20:04:13 UTC (rev 191198)
@@ -73,7 +73,7 @@
     Ref<IDBConnectionToServerDelegate> m_delegate;
 
     HashMap<IDBResourceIdentifier, RefPtr<IDBClient::IDBOpenDBRequest>> m_openDBRequestMap;
-    HashSet<RefPtr<IDBDatabase>> m_databaseConnections;
+    HashMap<uint64_t, IDBDatabase*> m_databaseConnectionMap;
     HashMap<IDBResourceIdentifier, RefPtr<IDBTransaction>> m_committingTransactions;
 };
 

Modified: trunk/Source/WebCore/Modules/indexeddb/client/IDBDatabaseImpl.cpp (191197 => 191198)


--- trunk/Source/WebCore/Modules/indexeddb/client/IDBDatabaseImpl.cpp	2015-10-16 20:02:21 UTC (rev 191197)
+++ trunk/Source/WebCore/Modules/indexeddb/client/IDBDatabaseImpl.cpp	2015-10-16 20:04:13 UTC (rev 191198)
@@ -28,11 +28,14 @@
 
 #if ENABLE(INDEXED_DATABASE)
 
+#include "EventQueue.h"
 #include "IDBConnectionToServer.h"
 #include "IDBOpenDBRequestImpl.h"
 #include "IDBResultData.h"
 #include "IDBTransactionImpl.h"
+#include "IDBVersionChangeEventImpl.h"
 #include "Logging.h"
+#include "ScriptExecutionContext.h"
 
 namespace WebCore {
 namespace IDBClient {
@@ -191,6 +194,19 @@
     m_committingTransactions.remove(transaction.info().identifier());
 }
 
+void IDBDatabase::fireVersionChangeEvent(uint64_t requestedVersion)
+{
+    uint64_t currentVersion = m_info.version();
+    LOG(IndexedDB, "IDBDatabase::fireVersionChangeEvent - current version %llu, requested version %llu", currentVersion, requestedVersion);
+
+    if (!scriptExecutionContext())
+        return;
+    
+    Ref<Event> event = IDBVersionChangeEvent::create(currentVersion, requestedVersion, eventNames().versionchangeEvent);
+    event->setTarget(this);
+    scriptExecutionContext()->eventQueue().enqueueEvent(adoptRef(&event.leakRef()));
+}
+
 } // namespace IDBClient
 } // namespace WebCore
 

Modified: trunk/Source/WebCore/Modules/indexeddb/client/IDBDatabaseImpl.h (191197 => 191198)


--- trunk/Source/WebCore/Modules/indexeddb/client/IDBDatabaseImpl.h	2015-10-16 20:02:21 UTC (rev 191197)
+++ trunk/Source/WebCore/Modules/indexeddb/client/IDBDatabaseImpl.h	2015-10-16 20:04:13 UTC (rev 191198)
@@ -77,6 +77,8 @@
     void didCommitTransaction(IDBTransaction&);
     void didAbortTransaction(IDBTransaction&);
 
+    void fireVersionChangeEvent(uint64_t requestedVersion);
+
 private:
     IDBDatabase(ScriptExecutionContext&, IDBConnectionToServer&, const IDBResultData&);
 

Modified: trunk/Source/WebCore/Modules/indexeddb/server/UniqueIDBDatabase.cpp (191197 => 191198)


--- trunk/Source/WebCore/Modules/indexeddb/server/UniqueIDBDatabase.cpp	2015-10-16 20:02:21 UTC (rev 191197)
+++ trunk/Source/WebCore/Modules/indexeddb/server/UniqueIDBDatabase.cpp	2015-10-16 20:04:13 UTC (rev 191198)
@@ -41,6 +41,7 @@
 UniqueIDBDatabase::UniqueIDBDatabase(IDBServer& server, const IDBDatabaseIdentifier& identifier)
     : m_server(server)
     , m_identifier(identifier)
+    , m_transactionSchedulingTimer(*this, &UniqueIDBDatabase::transactionSchedulingTimerFired)
 {
 }
 
@@ -266,10 +267,28 @@
         return;
     }
 
-    // FIXME: Now that a database connection has closed, previously blocked transactions might be runnable.
-    // Try to run them now.
+    // Now that a database connection has closed, previously blocked transactions might be runnable.
+    invokeTransactionScheduler();
 }
 
+void UniqueIDBDatabase::invokeTransactionScheduler()
+{
+    if (!m_transactionSchedulingTimer.isActive())
+        m_transactionSchedulingTimer.startOneShot(0);
+}
+
+void UniqueIDBDatabase::transactionSchedulingTimerFired()
+{
+    LOG(IndexedDB, "(main) UniqueIDBDatabase::transactionSchedulingTimerFired");
+
+    if (!hasAnyOpenConnections() && m_versionChangeOperation) {
+        startVersionChangeTransaction();
+        return;
+    }
+
+    // FIXME: Handle starting other pending transactions here.
+}
+
 void UniqueIDBDatabase::performErrorCallback(uint64_t callbackIdentifier, const IDBError& error)
 {
     auto callback = m_errorCallbacks.take(callbackIdentifier);

Modified: trunk/Source/WebCore/Modules/indexeddb/server/UniqueIDBDatabase.h (191197 => 191198)


--- trunk/Source/WebCore/Modules/indexeddb/server/UniqueIDBDatabase.h	2015-10-16 20:02:21 UTC (rev 191197)
+++ trunk/Source/WebCore/Modules/indexeddb/server/UniqueIDBDatabase.h	2015-10-16 20:04:13 UTC (rev 191198)
@@ -32,6 +32,7 @@
 #include "IDBDatabaseIdentifier.h"
 #include "IDBDatabaseInfo.h"
 #include "IDBServerOperation.h"
+#include "Timer.h"
 #include "UniqueIDBDatabaseConnection.h"
 #include "UniqueIDBDatabaseTransaction.h"
 #include <wtf/Deque.h>
@@ -89,6 +90,9 @@
 
     void performErrorCallback(uint64_t callbackIdentifier, const IDBError&);
 
+    void invokeTransactionScheduler();
+    void transactionSchedulingTimerFired();
+
     IDBServer& m_server;
     IDBDatabaseIdentifier m_identifier;
     
@@ -105,6 +109,8 @@
     std::unique_ptr<IDBDatabaseInfo> m_databaseInfo;
 
     HashMap<uint64_t, ErrorCallback> m_errorCallbacks;
+
+    Timer m_transactionSchedulingTimer;
 };
 
 } // namespace IDBServer
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to