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