Skip to content
Permalink
Browse files
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.

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:


Canonical link: https://commits.webkit.org/169682@main
git-svn-id: https://svn.webkit.org/repository/webkit/trunk@192720 268f45cc-cd09-0410-ab3c-d52691b4dbfc
  • Loading branch information
beidson committed Nov 21, 2015
1 parent 8199012 commit fc5f432cf05c76634328564fa4911346e313814d
Showing 18 changed files with 163 additions and 20 deletions.
@@ -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.
@@ -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
@@ -22,8 +22,7 @@
var request = window.indexedDB.open("DeleteDatabase1TestDatabase");
request.onsuccess = function()
{
log("Unexpected success");
done();
log("open db success");
}
request.onerror = function(e)
{
@@ -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
@@ -25,8 +25,7 @@
var request = window.indexedDB.open("DeleteDatabase2TestDatabase");
request.onsuccess = function()
{
log("Unexpected success");
done();
log("open db success");
}
request.onerror = function(e)
{
@@ -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

@@ -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>
@@ -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.
@@ -18,8 +18,7 @@

request.onsuccess = function()
{
alert("Unexpected success (firstPhase)");
done();
alert("First version change successful");
}
request.onerror = function(e)
{
@@ -78,8 +77,7 @@
alert(request + " (thirdPhase)");
request.onsuccess = function()
{
alert("Unexpected success (thirdPhase)");
done();
alert("Version change to version 2 successful");
}
request.onerror = function(e)
{
@@ -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)
@@ -26,8 +26,7 @@

request.onsuccess = function()
{
alert("Unexpected success (firstPhase)");
done();
alert("First version change successful");
}
request.onerror = function(e)
{
@@ -95,8 +94,7 @@
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)
{
@@ -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
@@ -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());
@@ -72,7 +72,7 @@ class IDBDatabase : public WebCore::IDBDatabase {
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&);
@@ -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);

@@ -51,6 +51,7 @@ class IDBOpenDBRequest : public IDBRequest {
uint64_t version() const { return m_version; }

void requestCompleted(const IDBResultData&);
void fireSuccessAfterVersionChangeCommit();

private:
IDBOpenDBRequest(IDBConnectionToServer&, ScriptExecutionContext*, const IDBDatabaseIdentifier&, uint64_t version);
@@ -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)
@@ -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 @@ class IDBTransaction : public WebCore::IDBTransaction {
void operationDidComplete(TransactionOperation&);

private:
IDBTransaction(IDBDatabase&, const IDBTransactionInfo&);
IDBTransaction(IDBDatabase&, const IDBTransactionInfo&, IDBOpenDBRequest*);

bool isFinishedOrFinishing() const;

@@ -194,6 +196,8 @@ class IDBTransaction : public WebCore::IDBTransaction {
Timer m_operationTimer;
std::unique_ptr<Timer> m_activationTimer;

RefPtr<IDBOpenDBRequest> m_openDBRequest;

Deque<RefPtr<TransactionOperation>> m_transactionOperationQueue;
HashMap<IDBResourceIdentifier, RefPtr<TransactionOperation>> m_transactionOperationMap;

0 comments on commit fc5f432

Please sign in to comment.