Modern IDB: After versionchange transactions complete, fire onsuccess on the original...
authorbeidson@apple.com <beidson@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Sat, 21 Nov 2015 03:57:19 +0000 (03:57 +0000)
committerbeidson@apple.com <beidson@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Sat, 21 Nov 2015 03:57:19 +0000 (03:57 +0000)
https://bugs.webkit.org/show_bug.cgi?id=151522

Reviewed by Alex Christensen.

Source/WebCore:

Test: storage/indexeddb/modern/opendatabase-success-after-versionchange.html (And changes to other existing tests)

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

* Modules/indexeddb/client/IDBOpenDBRequestImpl.cpp:
(WebCore::IDBClient::IDBOpenDBRequest::fireSuccessAfterVersionChangeCommit):
(WebCore::IDBClient::IDBOpenDBRequest::onUpgradeNeeded):
* Modules/indexeddb/client/IDBOpenDBRequestImpl.h:

* Modules/indexeddb/client/IDBTransactionImpl.cpp:
(WebCore::IDBClient::IDBTransaction::create):
(WebCore::IDBClient::IDBTransaction::IDBTransaction):
(WebCore::IDBClient::IDBTransaction::dispatchEvent):
* Modules/indexeddb/client/IDBTransactionImpl.h:

LayoutTests:

* storage/indexeddb/modern/deletedatabase-1-expected.txt:
* storage/indexeddb/modern/deletedatabase-1.html:
* storage/indexeddb/modern/deletedatabase-2-expected.txt:
* storage/indexeddb/modern/deletedatabase-2.html:
* storage/indexeddb/modern/opendatabase-success-after-versionchange-expected.txt: Added.
* storage/indexeddb/modern/opendatabase-success-after-versionchange.html: Added.
* storage/indexeddb/modern/opendatabase-versions-expected.txt:
* storage/indexeddb/modern/opendatabase-versions.html:
* storage/indexeddb/modern/versionchange-event-expected.txt:
* storage/indexeddb/modern/versionchange-event.html:

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

18 files changed:
LayoutTests/ChangeLog
LayoutTests/storage/indexeddb/modern/deletedatabase-1-expected.txt
LayoutTests/storage/indexeddb/modern/deletedatabase-1.html
LayoutTests/storage/indexeddb/modern/deletedatabase-2-expected.txt
LayoutTests/storage/indexeddb/modern/deletedatabase-2.html
LayoutTests/storage/indexeddb/modern/opendatabase-success-after-versionchange-expected.txt [new file with mode: 0644]
LayoutTests/storage/indexeddb/modern/opendatabase-success-after-versionchange.html [new file with mode: 0644]
LayoutTests/storage/indexeddb/modern/opendatabase-versions-expected.txt
LayoutTests/storage/indexeddb/modern/opendatabase-versions.html
LayoutTests/storage/indexeddb/modern/versionchange-event-expected.txt
LayoutTests/storage/indexeddb/modern/versionchange-event.html
Source/WebCore/ChangeLog
Source/WebCore/Modules/indexeddb/client/IDBDatabaseImpl.cpp
Source/WebCore/Modules/indexeddb/client/IDBDatabaseImpl.h
Source/WebCore/Modules/indexeddb/client/IDBOpenDBRequestImpl.cpp
Source/WebCore/Modules/indexeddb/client/IDBOpenDBRequestImpl.h
Source/WebCore/Modules/indexeddb/client/IDBTransactionImpl.cpp
Source/WebCore/Modules/indexeddb/client/IDBTransactionImpl.h

index c3a366b92927d167db93761bcde9665d3e676c14..946cf47caeae920f45c67172098f3468fbcced68 100644 (file)
@@ -1,3 +1,21 @@
+2015-11-20  Brady Eidson  <beidson@apple.com>
+
+        Modern IDB: After versionchange transactions complete, fire onsuccess on the original IDBOpenDBRequest
+        https://bugs.webkit.org/show_bug.cgi?id=151522
+
+        Reviewed by Alex Christensen.
+
+        * storage/indexeddb/modern/deletedatabase-1-expected.txt:
+        * storage/indexeddb/modern/deletedatabase-1.html:
+        * storage/indexeddb/modern/deletedatabase-2-expected.txt:
+        * storage/indexeddb/modern/deletedatabase-2.html:
+        * storage/indexeddb/modern/opendatabase-success-after-versionchange-expected.txt: Added.
+        * storage/indexeddb/modern/opendatabase-success-after-versionchange.html: Added.
+        * storage/indexeddb/modern/opendatabase-versions-expected.txt:
+        * storage/indexeddb/modern/opendatabase-versions.html:
+        * storage/indexeddb/modern/versionchange-event-expected.txt:
+        * storage/indexeddb/modern/versionchange-event.html:
+
 2015-11-20  Chris Dumez  <cdumez@apple.com>
 
         Unreviewed, mark fast/replaced/replaced-breaking.html as failing on ElCapitan-wk1.
index 3ef7a35943d8170fa932226906f5724c61d1088c..8b1590e0fee320c1bad06e64513b6ab7de534bc0 100644 (file)
@@ -2,6 +2,7 @@ This tests that if deleteDatabase is called while there is already an open conne
 Initial upgrade old version - 0 new version - 1
 Version change complete
 Requesting deleteDatabase
+open db success
 First connection received versionchange event: oldVersion 1, newVersion null
 Delete database success: oldVersion 1, newVersion null
 Recreating database to make sure it's new and empty
index a0941cdb1bc7f3286f62298710f255bd48526551..a0aa0ffd6bd63a52867b695bcea3a4b611a7b22f 100644 (file)
@@ -22,8 +22,7 @@ function log(message)
 var request = window.indexedDB.open("DeleteDatabase1TestDatabase");
 request.onsuccess = function()
 {
-    log("Unexpected success");
-       done();
+    log("open db success");
 }
 request.onerror = function(e)
 {
index f4e1025d73e909a7c81f476bf40f2b4309fa9592..3d94546bcba25ccdc158ddbf8d2686cedc262660 100644 (file)
@@ -4,6 +4,7 @@ Initial upgrade old version - 0 new version - 1
 Requesting deleteDatabase
 First connection received versionchange event: oldVersion 0, newVersion null
 First version change complete
+open db success
 Delete database success: oldVersion 1, newVersion null
 Recreating database to make sure it's new and empty
 Second upgrade old version - 0 new version - 1
index 4a3dac151edef654eb495bd0df9eba0c0675c734..dd817877eea3da0c1a833166211ea4ca3bc84d2f 100644 (file)
@@ -25,8 +25,7 @@ var stopSpinning = false;
 var request = window.indexedDB.open("DeleteDatabase2TestDatabase");
 request.onsuccess = function()
 {
-    log("Unexpected success");
-       done();
+    log("open db success");
 }
 request.onerror = function(e)
 {
diff --git a/LayoutTests/storage/indexeddb/modern/opendatabase-success-after-versionchange-expected.txt b/LayoutTests/storage/indexeddb/modern/opendatabase-success-after-versionchange-expected.txt
new file mode 100644 (file)
index 0000000..b1d684b
--- /dev/null
@@ -0,0 +1,10 @@
+This test verifies that:
+- Opening a new database results in the onupgradeneeded handler being called on the IDBOpenDBRequest.
+- The versionchange transaction representing the upgrade commits successfully.
+- After that transaction commits, the onsuccess handler on the original IDBOpenDBRequest is called.
+upgradeneeded: old version - 0 new version - 1
+[object IDBTransaction]
+Version change complete
+Got the onsuccess handler as expected.
+Done
+
diff --git a/LayoutTests/storage/indexeddb/modern/opendatabase-success-after-versionchange.html b/LayoutTests/storage/indexeddb/modern/opendatabase-success-after-versionchange.html
new file mode 100644 (file)
index 0000000..a13ddf9
--- /dev/null
@@ -0,0 +1,61 @@
+This test verifies that:<br>
+    - Opening a new database results in the onupgradeneeded handler being called on the IDBOpenDBRequest.<br>
+    - The versionchange transaction representing the upgrade commits successfully.<br>
+    - After that transaction commits, the onsuccess handler on the original IDBOpenDBRequest is called.<br>
+<div id="logger"></div>
+<script>
+
+if (window.testRunner) {
+    testRunner.waitUntilDone();
+    testRunner.dumpAsText();
+}
+
+function done()
+{
+    log("Done");
+    if (window.testRunner)
+        testRunner.notifyDone();
+}
+
+function log(message)
+{
+    document.getElementById("logger").innerHTML += message + "<br>";
+}
+
+var request = window.indexedDB.open("OpenDatabaseSuccessAfterVersionChangeDatabase");
+
+request.onsuccess = function()
+{
+    log("Got the onsuccess handler as expected.");
+       done();
+}
+request.onerror = function(e)
+{
+    log("Unexpected onerror handler called");
+       done();
+}
+
+request.onupgradeneeded = function(e)
+{
+    log("upgradeneeded: old version - " + e.oldVersion + " new version - " + e.newVersion);
+    log(request.transaction);
+    
+    request.transaction.oncomplete = function()
+    {
+        log("Version change complete");
+    }
+    
+    request.transaction.onabort = function()
+    {
+        log("Version change unexpected abort");
+        done();
+    }
+    
+    request.transaction.onerror = function()
+    {
+        log("Version change unexpected error");
+        done();
+    }
+}
+
+</script>
index 09678f66a3cf65f47ca69cfbc9feb6044b8c7970..caa11d0501babf7a3931b91ff79cc261707abfbd 100644 (file)
@@ -3,12 +3,14 @@ ALERT: upgradeneeded (firstPhase): old version - 0 new version - 1
 ALERT: [object IDBTransaction]
 ALERT: Version change complete (firstPhase). Database version is now - 1
 ALERT: [object IDBOpenDBRequest] (secondPhase)
+ALERT: First version change successful
 ALERT: Successfully opened database at version 1 (secondPhase)
 ALERT: [object IDBOpenDBRequest] (thirdPhase)
 ALERT: upgradeneeded (thirdPhase): old version - 1 new version - 2
 ALERT: [object IDBTransaction]
 ALERT: Version change complete (thirdPhase). Database version is now - 2
 ALERT: [object IDBOpenDBRequest] (fourthPhase)
+ALERT: Version change to version 2 successful
 ALERT: Expected error (fourthPhase) - VersionError
 ALERT: Done
 This test creates a new database with the default version, commits that versionchange transaction, and then reopens it at different versions to make sure the IDBOpenDBRequests behave appropriately.
index 8c575c868c7e4e69a8aef0a772a30a53ac9e7632..321b217f80703ea1c9181444f2228e57b22a7fe4 100644 (file)
@@ -18,8 +18,7 @@ alert(request + " (firstPhase)");
 
 request.onsuccess = function()
 {
-    alert("Unexpected success (firstPhase)");
-       done();
+    alert("First version change successful");
 }
 request.onerror = function(e)
 {
@@ -78,8 +77,7 @@ function thirdPhase()
     alert(request + " (thirdPhase)");
     request.onsuccess = function()
     {
-        alert("Unexpected success (thirdPhase)");
-        done();
+        alert("Version change to version 2 successful");
     }
     request.onerror = function(e)
     {
index 3cf2da06f25b07aaf35de311a31ec18b75b6647e..5981b24f8c0b079e135aa4e7d7f069a27af09cd6 100644 (file)
@@ -1,5 +1,6 @@
 ALERT: upgradeneeded (firstPhase): old version - 0 new version - 1
 ALERT: Version change complete (firstPhase). Database version is now - 1
+ALERT: First version change successful
 ALERT: Open success (secondPhase)
 ALERT: thirdPhase - Requested database connection with version 2
 ALERT: Expected upgrade needed (thirdPhase)
index 5b1af7eed154ebe56756065a5406d37ba0623b70..5db4d3448421c31e32ac735c5ab437916038f654 100644 (file)
@@ -26,8 +26,7 @@ var connection2;
 
 request.onsuccess = function()
 {
-    alert("Unexpected success (firstPhase)");
-       done();
+    alert("First version change successful");
 }
 request.onerror = function(e)
 {
@@ -95,8 +94,7 @@ function thirdPhase()
     alert("thirdPhase - Requested database connection with version 2");
     request.onsuccess = function()
     {
-        alert("Unexpected open success (thirdPhase)");
-        done();
+        alert("Version change to version 2 successful");
     }
     request.onerror = function(e)
     {
index da87eb6c652c12abd560997515454697ccd78702..5a0ba9cd0a8e649e5ffa87b21fd0bbcd7cfc0382 100644 (file)
@@ -1,3 +1,27 @@
+2015-11-20  Brady Eidson  <beidson@apple.com>
+
+        Modern IDB: After versionchange transactions complete, fire onsuccess on the original IDBOpenDBRequest
+        https://bugs.webkit.org/show_bug.cgi?id=151522
+
+        Reviewed by Alex Christensen.
+
+        Test: storage/indexeddb/modern/opendatabase-success-after-versionchange.html (And changes to other existing tests)
+
+        * Modules/indexeddb/client/IDBDatabaseImpl.cpp:
+        (WebCore::IDBClient::IDBDatabase::startVersionChangeTransaction):
+        * Modules/indexeddb/client/IDBDatabaseImpl.h:
+        
+        * Modules/indexeddb/client/IDBOpenDBRequestImpl.cpp:
+        (WebCore::IDBClient::IDBOpenDBRequest::fireSuccessAfterVersionChangeCommit):
+        (WebCore::IDBClient::IDBOpenDBRequest::onUpgradeNeeded):
+        * Modules/indexeddb/client/IDBOpenDBRequestImpl.h:
+        
+        * Modules/indexeddb/client/IDBTransactionImpl.cpp:
+        (WebCore::IDBClient::IDBTransaction::create):
+        (WebCore::IDBClient::IDBTransaction::IDBTransaction):
+        (WebCore::IDBClient::IDBTransaction::dispatchEvent):
+        * Modules/indexeddb/client/IDBTransactionImpl.h:
+
 2015-11-20  Simon Fraser  <simon.fraser@apple.com>
 
         More deviceRGB color cleanup
index 89560c885952694d60f558d0ae39aa88b9e51797..02c4853543a6306abeb048805aba0f1417607273 100644 (file)
@@ -239,14 +239,14 @@ bool IDBDatabase::canSuspendForPageCache() const
     return true;
 }
 
-Ref<IDBTransaction> IDBDatabase::startVersionChangeTransaction(const IDBTransactionInfo& info)
+Ref<IDBTransaction> IDBDatabase::startVersionChangeTransaction(const IDBTransactionInfo& info, IDBOpenDBRequest& request)
 {
     LOG(IndexedDB, "IDBDatabase::startVersionChangeTransaction");
 
     ASSERT(!m_versionChangeTransaction);
     ASSERT(info.mode() == IndexedDB::TransactionMode::VersionChange);
 
-    Ref<IDBTransaction> transaction = IDBTransaction::create(*this, info);
+    Ref<IDBTransaction> transaction = IDBTransaction::create(*this, info, request);
     m_versionChangeTransaction = &transaction.get();
 
     m_activeTransactions.set(transaction->info().identifier(), &transaction.get());
index df80b8c7e4332ef1a23534ca9f6d2719058fe251..fdc0bf8b44593e41a70b126d0576f1c645eaa79f 100644 (file)
@@ -72,7 +72,7 @@ public:
     const IDBDatabaseInfo& info() const { return m_info; }
     uint64_t databaseConnectionIdentifier() const { return m_databaseConnectionIdentifier; }
 
-    Ref<IDBTransaction> startVersionChangeTransaction(const IDBTransactionInfo&);
+    Ref<IDBTransaction> startVersionChangeTransaction(const IDBTransactionInfo&, IDBOpenDBRequest&);
     void didStartTransaction(IDBTransaction&);
 
     void willCommitTransaction(IDBTransaction&);
index 76badfcb284d0de629a09f1d75a7dfc70441e4b3..15a8cd75e11b1c3617cf1ffecfd9d81c8aa1f977 100644 (file)
@@ -67,6 +67,17 @@ void IDBOpenDBRequest::onError(const IDBResultData& data)
     enqueueEvent(Event::create(eventNames().errorEvent, true, true));
 }
 
+void IDBOpenDBRequest::fireSuccessAfterVersionChangeCommit()
+{
+    LOG(IndexedDB, "IDBOpenDBRequest::fireSuccessAfterVersionChangeCommit()");
+
+    ASSERT(m_result);
+    ASSERT(m_result->type() == IDBAny::Type::IDBDatabase);
+    m_transaction->addRequest(*this);
+
+    enqueueEvent(Event::create(eventNames().successEvent, false, false));
+}
+
 void IDBOpenDBRequest::onSuccess(const IDBResultData& resultData)
 {
     LOG(IndexedDB, "IDBOpenDBRequest::onSuccess()");
@@ -84,7 +95,7 @@ void IDBOpenDBRequest::onSuccess(const IDBResultData& resultData)
 void IDBOpenDBRequest::onUpgradeNeeded(const IDBResultData& resultData)
 {
     Ref<IDBDatabase> database = IDBDatabase::create(*scriptExecutionContext(), connection(), resultData);
-    Ref<IDBTransaction> transaction = database->startVersionChangeTransaction(resultData.transactionInfo());
+    Ref<IDBTransaction> transaction = database->startVersionChangeTransaction(resultData.transactionInfo(), *this);
 
     ASSERT(transaction->info().mode() == IndexedDB::TransactionMode::VersionChange);
 
index d93d7030a1419b9d5116cd215a6edcbb154c6018..0363cc51fd360e488bf815e54d56be444ad531ee 100644 (file)
@@ -51,6 +51,7 @@ public:
     uint64_t version() const { return m_version; }
 
     void requestCompleted(const IDBResultData&);
+    void fireSuccessAfterVersionChangeCommit();
 
 private:
     IDBOpenDBRequest(IDBConnectionToServer&, ScriptExecutionContext*, const IDBDatabaseIdentifier&, uint64_t version);
index 15d212f65778e119bc783d42472b51aa5fba6e1f..e17bacab52c486824a7fe65f5376ccc499aeb325 100644 (file)
@@ -37,6 +37,7 @@
 #include "IDBKeyData.h"
 #include "IDBKeyRangeData.h"
 #include "IDBObjectStore.h"
+#include "IDBOpenDBRequestImpl.h"
 #include "IDBRequestImpl.h"
 #include "IDBResultData.h"
 #include "JSDOMWindowBase.h"
@@ -49,19 +50,26 @@ namespace IDBClient {
 
 Ref<IDBTransaction> IDBTransaction::create(IDBDatabase& database, const IDBTransactionInfo& info)
 {
-    return adoptRef(*new IDBTransaction(database, info));
+    return adoptRef(*new IDBTransaction(database, info, nullptr));
 }
 
-IDBTransaction::IDBTransaction(IDBDatabase& database, const IDBTransactionInfo& info)
+Ref<IDBTransaction> IDBTransaction::create(IDBDatabase& database, const IDBTransactionInfo& info, IDBOpenDBRequest& request)
+{
+    return adoptRef(*new IDBTransaction(database, info, &request));
+}
+
+IDBTransaction::IDBTransaction(IDBDatabase& database, const IDBTransactionInfo& info, IDBOpenDBRequest* request)
     : WebCore::IDBTransaction(database.scriptExecutionContext())
     , m_database(database)
     , m_info(info)
     , m_operationTimer(*this, &IDBTransaction::operationTimerFired)
+    , m_openDBRequest(request)
 
 {
     relaxAdoptionRequirement();
 
     if (m_info.mode() == IndexedDB::TransactionMode::VersionChange) {
+        ASSERT(m_openDBRequest);
         m_originalDatabaseInfo = std::make_unique<IDBDatabaseInfo>(m_database->info());
         m_startedOnServer = true;
     } else {
@@ -381,7 +389,14 @@ bool IDBTransaction::dispatchEvent(Event& event)
     targets.append(this);
     targets.append(db());
 
-    return IDBEventDispatcher::dispatch(event, targets);
+    bool result = IDBEventDispatcher::dispatch(event, targets);
+
+    if (isVersionChange() && event.type() == eventNames().completeEvent) {
+        ASSERT(m_openDBRequest);
+        m_openDBRequest->fireSuccessAfterVersionChangeCommit();
+    }
+
+    return result;
 }
 
 Ref<IDBObjectStore> IDBTransaction::createObjectStore(const IDBObjectStoreInfo& info)
index 379a39bdaa7cb44069b198d18cc54bc41e2f3ee2..d3704806052f11907a6a14f01d79757562d6cf90 100644 (file)
@@ -54,11 +54,13 @@ namespace IDBClient {
 class IDBCursor;
 class IDBDatabase;
 class IDBIndex;
+class IDBOpenDBRequest;
 class TransactionOperation;
 
 class IDBTransaction : public WebCore::IDBTransaction {
 public:
     static Ref<IDBTransaction> create(IDBDatabase&, const IDBTransactionInfo&);
+    static Ref<IDBTransaction> create(IDBDatabase&, const IDBTransactionInfo&, IDBOpenDBRequest&);
 
     virtual ~IDBTransaction() override final;
 
@@ -122,7 +124,7 @@ public:
     void operationDidComplete(TransactionOperation&);
 
 private:
-    IDBTransaction(IDBDatabase&, const IDBTransactionInfo&);
+    IDBTransaction(IDBDatabase&, const IDBTransactionInfo&, IDBOpenDBRequest*);
 
     bool isFinishedOrFinishing() const;
 
@@ -194,6 +196,8 @@ private:
     Timer m_operationTimer;
     std::unique_ptr<Timer> m_activationTimer;
 
+    RefPtr<IDBOpenDBRequest> m_openDBRequest;
+
     Deque<RefPtr<TransactionOperation>> m_transactionOperationQueue;
     HashMap<IDBResourceIdentifier, RefPtr<TransactionOperation>> m_transactionOperationMap;