Changeset 142921 in webkit


Ignore:
Timestamp:
Feb 14, 2013 2:31:20 PM (11 years ago)
Author:
mark.lam@apple.com
Message:

Split SQLTransaction work between the frontend and backend.
https://bugs.webkit.org/show_bug.cgi?id=104750.

Reviewed by Sam Weinig.

This is part of the webdatabase refactoring for webkit2.

  1. Changed how transactions are created.
  • Database::runTransaction() first creates a SQLTransaction frontend which encapsulates the 3 script callbacks. It then passes the SQLTransaction to the backend database to create the SQLTransactionBackend.
  • The SQLTransactionBackend manages all SQLiteTransaction work.
  1. Introduced SQLTransactionState and SQLTransactionStateMachine.
  • Instead of tracking the transaction phases as "steps" in m_nextStep, we now use m_nextState which is of enum class SQLTransactionState. Unlike m_nextStep which is a pointer to a "step" function, m_nextState is a state variable which is used to index into a state dispatch table.
  • Both SQLTransaction and SQLTransactionBackend now extends SQLTransactionStateMachine, and uses its dispatch mechanism based on the SQLTransactionState.
  • Instead of having 1 state machine instances, there are 2: 1 in the frontend, and 1 in the backend. The 2 have mirrored states, and transfers work to the other state machine when needed.
  • Previously, state functions can be called inline from other states. They are now only called from the state machines runStateMachine() method. This makes it possible to isolate the state transition mechanism going between the sides (frontend and backend) to 2 functions only: SQLTransaction::sendToBackendState() and SQLTransactionBackend::sendToFrontendState().
  1. Consolidated cleanup work (mostly) to a unified cleanup function.
  1. Changed the frontend Database::runTransaction() to use a ChangeVersionData* (instead of a ChangeVersionWrapper ref ptr).
  • This is necessary because ChangeVersionWrapper contains functionality used in processing a transaction (to be invoked in the backend). Instead, what we want is to simply pass the 2 old and new version strings to the backend. The new ChangeVersionData simply packages up these 2 strings.
  • This makes ChangeVersionData easy to serialize for IPC messaging later.
  1. Moved some transaction functions back to the frontend SQLTransaction because they belong there.
  1. Moved some Database functions to its DatabaseBackendAsync backend now that the transaction has been split up.
  • This is driven naturally by those functions being used exclusively in the backend for transaction work.
  • SQLTransactionClient, SQLTransactionCoordinator, and SQLTransactionWrapper are now exclusively backend data structures. SQLTransactionClient still has some frontend "pollution" that I'll fix later.
  1. Made the few database report functions used only by Chromium conditional on PLATFORM(chromium).
  • The report functions gets re-routed to Chromium's DatabaseObserver which further routes them elsewhere. It is unclear how Chromium uses these routed messages, and I am therefore not able to determine how they should work in a frontend/backend world. So, I'm #ifdef'ing them out. They still work like in the old way for Chromium.
  1. Added new files to the build / project files.
  1. Updated / added comments about how the transaction and its states work.

No new tests.

  • CMakeLists.txt:
  • GNUmakefile.list.am:
  • Modules/webdatabase/AbstractDatabaseServer.h:
  • Modules/webdatabase/ChangeVersionData.h: Added.

(ChangeVersionData):
(WebCore::ChangeVersionData::ChangeVersionData):
(WebCore::ChangeVersionData::oldVersion):
(WebCore::ChangeVersionData::newVersion):

  • Modules/webdatabase/ChangeVersionWrapper.cpp:

(WebCore::ChangeVersionWrapper::performPreflight):
(WebCore::ChangeVersionWrapper::performPostflight):
(WebCore::ChangeVersionWrapper::handleCommitFailedAfterPostflight):

  • Modules/webdatabase/ChangeVersionWrapper.h:

(ChangeVersionWrapper):

  • Modules/webdatabase/Database.cpp:

(WebCore::Database::Database):
(WebCore::Database::close):
(WebCore::Database::changeVersion):
(WebCore::Database::transaction):
(WebCore::Database::readTransaction):
(WebCore::Database::runTransaction):
(WebCore::Database::reportStartTransactionResult):
(WebCore::Database::reportCommitTransactionResult):
(WebCore::Database::reportExecuteStatementResult):

  • Modules/webdatabase/Database.h:

(WebCore::Database::databaseContext):
(Database):
(WebCore::Database::reportStartTransactionResult):
(WebCore::Database::reportCommitTransactionResult):
(WebCore::Database::reportExecuteStatementResult):

  • Modules/webdatabase/DatabaseBackend.cpp:
  • Modules/webdatabase/DatabaseBackend.h:

(DatabaseBackend):
(WebCore::DatabaseBackend::reportOpenDatabaseResult):
(WebCore::DatabaseBackend::reportChangeVersionResult):
(WebCore::DatabaseBackend::reportStartTransactionResult):
(WebCore::DatabaseBackend::reportCommitTransactionResult):
(WebCore::DatabaseBackend::reportExecuteStatementResult):
(WebCore::DatabaseBackend::reportVacuumDatabaseResult):

  • Modules/webdatabase/DatabaseBackendAsync.cpp:

(WebCore::DatabaseBackendAsync::DatabaseBackendAsync):
(WebCore::DatabaseBackendAsync::runTransaction):
(WebCore::DatabaseBackendAsync::inProgressTransactionCompleted): Moved from frontend.
(WebCore::DatabaseBackendAsync::scheduleTransaction): Moved from frontend.
(WebCore::DatabaseBackendAsync::scheduleTransactionStep): Moved from frontend.
(WebCore::DatabaseBackendAsync::transactionClient): Moved from frontend.
(WebCore::DatabaseBackendAsync::transactionCoordinator): Moved from frontend.

  • Modules/webdatabase/DatabaseBackendAsync.h:

(DatabaseBackendAsync):

  • Modules/webdatabase/DatabaseBackendContext.cpp:

(WebCore::DatabaseBackendContext::frontend):

  • Modules/webdatabase/DatabaseBackendContext.h:

(DatabaseBackendContext):

  • Modules/webdatabase/DatabaseManager.cpp:
  • Modules/webdatabase/DatabaseManager.h:

(DatabaseManager):

  • Modules/webdatabase/DatabaseServer.cpp:
  • Modules/webdatabase/DatabaseServer.h:
  • Modules/webdatabase/DatabaseTask.cpp:

(WebCore::DatabaseBackendAsync::DatabaseTransactionTask::doPerformTask):

  • Modules/webdatabase/SQLTransaction.cpp:

(WebCore::SQLTransaction::create):
(WebCore::SQLTransaction::SQLTransaction):
(WebCore::SQLTransaction::setBackend):
(WebCore::SQLTransaction::stateFunctionFor):
(WebCore::SQLTransaction::requestTransitToState):
(WebCore::SQLTransaction::nextStateForTransactionError):

  • was handleTransactionError(). There's also a backend version.

(WebCore::SQLTransaction::deliverTransactionCallback): Moved from backend.
(WebCore::SQLTransaction::deliverTransactionErrorCallback): Moved from backend.
(WebCore::SQLTransaction::deliverStatementCallback): Moved from backend.
(WebCore::SQLTransaction::deliverQuotaIncreaseCallback): Moved from backend.
(WebCore::SQLTransaction::deliverSuccessCallback): Moved from backend.
(WebCore::SQLTransaction::unreachableState):
(WebCore::SQLTransaction::sendToBackendState):
(WebCore::SQLTransaction::performPendingCallback): Moved from backend.
(WebCore::SQLTransaction::executeSQL): Moved from backend.
(WebCore::SQLTransaction::checkAndHandleClosedOrInterruptedDatabase):
(WebCore::SQLTransaction::clearCallbackWrappers):

  • Modules/webdatabase/SQLTransaction.h:

(SQLTransaction):
(WebCore::SQLTransaction::database):
(WebCore::SQLTransaction::hasCallback):
(WebCore::SQLTransaction::hasSuccessCallback):
(WebCore::SQLTransaction::hasErrorCallback):

  • Modules/webdatabase/SQLTransactionBackend.cpp:

(WebCore::SQLTransactionBackend::create):
(WebCore::SQLTransactionBackend::SQLTransactionBackend):
(WebCore::SQLTransactionBackend::doCleanup):
(WebCore::SQLTransactionBackend::transactionError):
(WebCore::SQLTransactionBackend::setShouldRetryCurrentStatement):
(WebCore::SQLTransactionBackend::stateFunctionFor):
(WebCore::SQLTransactionBackend::enqueueStatement):
(WebCore::SQLTransactionBackend::checkAndHandleClosedOrInterruptedDatabase):
(WebCore::SQLTransactionBackend::performNextStep):
(WebCore::SQLTransactionBackend::notifyDatabaseThreadIsShuttingDown):
(WebCore::SQLTransactionBackend::acquireLock):
(WebCore::SQLTransactionBackend::lockAcquired):
(WebCore::SQLTransactionBackend::openTransactionAndPreflight):
(WebCore::SQLTransactionBackend::runStatements):
(WebCore::SQLTransactionBackend::runCurrentStatementAndGetNextState):

  • was runCurrentStatement().

(WebCore::SQLTransactionBackend::nextStateForCurrentStatementError):

  • was handleCurrentStatementError().

(WebCore::SQLTransactionBackend::postflightAndCommit):
(WebCore::SQLTransactionBackend::cleanupAndTerminate):
(WebCore::SQLTransactionBackend::nextStateForTransactionError):

  • was handleTransactionError(). There's also a frontend version.

(WebCore::SQLTransactionBackend::cleanupAfterTransactionErrorCallback):
(WebCore::SQLTransactionBackend::requestTransitToState):
(WebCore::SQLTransactionBackend::unreachableState):
(WebCore::SQLTransactionBackend::sendToFrontendState):

  • Modules/webdatabase/SQLTransactionBackend.h:

(SQLTransactionWrapper):
(SQLTransactionBackend):
(WebCore::SQLTransactionBackend::database):

  • Modules/webdatabase/SQLTransactionClient.cpp:

(WebCore::SQLTransactionClient::didCommitWriteTransaction):
(WebCore::SQLTransactionClient::didExecuteStatement):

  • Modules/webdatabase/SQLTransactionCoordinator.cpp:

(WebCore::getDatabaseIdentifier):

  • Modules/webdatabase/SQLTransactionState.h: Added.
  • Modules/webdatabase/SQLTransactionStateMachine.cpp: Added.

(WebCore::nameForSQLTransactionState):

  • was debugStepName().
  • Modules/webdatabase/SQLTransactionStateMachine.h: Added.

(SQLTransactionStateMachine):
(WebCore::SQLTransactionStateMachine::~SQLTransactionStateMachine):
(WebCore::::SQLTransactionStateMachine):
(WebCore::::setStateToRequestedState):
(WebCore::::runStateMachine):

  • Target.pri:
  • WebCore.gypi:
  • WebCore.vcproj/WebCore.vcproj:
  • WebCore.vcxproj/WebCore.vcxproj:
  • WebCore.vcxproj/WebCore.vcxproj.filters:
  • WebCore.xcodeproj/project.pbxproj:
  • inspector/InspectorDatabaseAgent.cpp:
Location:
trunk/Source/WebCore
Files:
4 added
32 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebCore/CMakeLists.txt

    r142809 r142921  
    964964    Modules/webdatabase/SQLTransactionClient.cpp
    965965    Modules/webdatabase/SQLTransactionCoordinator.cpp
     966    Modules/webdatabase/SQLTransactionStateMachine.cpp
    966967    Modules/webdatabase/SQLTransactionSync.cpp
    967968
  • trunk/Source/WebCore/ChangeLog

    r142918 r142921  
     12013-02-14  Mark Lam  <mark.lam@apple.com>
     2
     3        Split SQLTransaction work between the frontend and backend.
     4        https://bugs.webkit.org/show_bug.cgi?id=104750.
     5
     6        Reviewed by Sam Weinig.
     7
     8        This is part of the webdatabase refactoring for webkit2.
     9
     10        1. Changed how transactions are created.
     11
     12           - Database::runTransaction() first creates a SQLTransaction frontend
     13             which encapsulates the 3 script callbacks. It then passes the
     14             SQLTransaction to the backend database to create the
     15             SQLTransactionBackend.
     16           - The SQLTransactionBackend manages all SQLiteTransaction work.
     17
     18        2. Introduced SQLTransactionState and SQLTransactionStateMachine.
     19
     20           - Instead of tracking the transaction phases as "steps" in m_nextStep,
     21             we now use m_nextState which is of enum class SQLTransactionState.
     22             Unlike m_nextStep which is a pointer to a "step" function,
     23             m_nextState is a state variable which is used to index into a
     24             state dispatch table.
     25
     26           - Both SQLTransaction and SQLTransactionBackend now extends
     27             SQLTransactionStateMachine, and uses its dispatch mechanism based on
     28             the SQLTransactionState.
     29
     30           - Instead of having 1 state machine instances, there are 2: 1 in the
     31             frontend, and 1 in the backend. The 2 have mirrored states, and
     32             transfers work to the other state machine when needed.
     33
     34           - Previously, state functions can be called inline from other states.
     35             They are now only called from the state machines runStateMachine()
     36             method. This makes it possible to isolate the state transition
     37             mechanism going between the sides (frontend and backend) to 2
     38             functions only: SQLTransaction::sendToBackendState() and
     39             SQLTransactionBackend::sendToFrontendState().
     40
     41        3. Consolidated cleanup work (mostly) to a unified cleanup function.
     42
     43        4. Changed the frontend Database::runTransaction() to use a
     44           ChangeVersionData* (instead of a ChangeVersionWrapper ref ptr).
     45
     46           - This is necessary because ChangeVersionWrapper contains functionality
     47             used in processing a transaction (to be invoked in the backend).
     48             Instead, what we want is to simply pass the 2 old and new version
     49             strings to the backend. The new ChangeVersionData simply packages up
     50             these 2 strings.
     51           - This makes ChangeVersionData easy to serialize for IPC messaging later.
     52
     53        5. Moved some transaction functions back to the frontend SQLTransaction
     54           because they belong there.
     55
     56        6. Moved some Database functions to its DatabaseBackendAsync backend
     57           now that the transaction has been split up.
     58
     59           - This is driven naturally by those functions being used exclusively
     60             in the backend for transaction work.
     61           - SQLTransactionClient, SQLTransactionCoordinator, and
     62             SQLTransactionWrapper are now exclusively backend data structures.
     63             SQLTransactionClient still has some frontend "pollution" that I'll
     64             fix later.
     65
     66        7. Made the few database report functions used only by Chromium conditional
     67           on PLATFORM(chromium).
     68
     69           - The report functions gets re-routed to Chromium's DatabaseObserver
     70             which further routes them elsewhere. It is unclear how Chromium uses
     71             these routed messages, and I am therefore not able to determine how
     72             they should work in a frontend/backend world. So, I'm #ifdef'ing
     73             them out. They still work like in the old way for Chromium.
     74
     75        8. Added new files to the build / project files.
     76
     77        9. Updated / added comments about how the transaction and its states work.
     78
     79        No new tests.
     80
     81        * CMakeLists.txt:
     82        * GNUmakefile.list.am:
     83        * Modules/webdatabase/AbstractDatabaseServer.h:
     84        * Modules/webdatabase/ChangeVersionData.h: Added.
     85        (ChangeVersionData):
     86        (WebCore::ChangeVersionData::ChangeVersionData):
     87        (WebCore::ChangeVersionData::oldVersion):
     88        (WebCore::ChangeVersionData::newVersion):
     89        * Modules/webdatabase/ChangeVersionWrapper.cpp:
     90        (WebCore::ChangeVersionWrapper::performPreflight):
     91        (WebCore::ChangeVersionWrapper::performPostflight):
     92        (WebCore::ChangeVersionWrapper::handleCommitFailedAfterPostflight):
     93        * Modules/webdatabase/ChangeVersionWrapper.h:
     94        (ChangeVersionWrapper):
     95        * Modules/webdatabase/Database.cpp:
     96        (WebCore::Database::Database):
     97        (WebCore::Database::close):
     98        (WebCore::Database::changeVersion):
     99        (WebCore::Database::transaction):
     100        (WebCore::Database::readTransaction):
     101        (WebCore::Database::runTransaction):
     102        (WebCore::Database::reportStartTransactionResult):
     103        (WebCore::Database::reportCommitTransactionResult):
     104        (WebCore::Database::reportExecuteStatementResult):
     105        * Modules/webdatabase/Database.h:
     106        (WebCore::Database::databaseContext):
     107        (Database):
     108        (WebCore::Database::reportStartTransactionResult):
     109        (WebCore::Database::reportCommitTransactionResult):
     110        (WebCore::Database::reportExecuteStatementResult):
     111        * Modules/webdatabase/DatabaseBackend.cpp:
     112        * Modules/webdatabase/DatabaseBackend.h:
     113        (DatabaseBackend):
     114        (WebCore::DatabaseBackend::reportOpenDatabaseResult):
     115        (WebCore::DatabaseBackend::reportChangeVersionResult):
     116        (WebCore::DatabaseBackend::reportStartTransactionResult):
     117        (WebCore::DatabaseBackend::reportCommitTransactionResult):
     118        (WebCore::DatabaseBackend::reportExecuteStatementResult):
     119        (WebCore::DatabaseBackend::reportVacuumDatabaseResult):
     120        * Modules/webdatabase/DatabaseBackendAsync.cpp:
     121        (WebCore::DatabaseBackendAsync::DatabaseBackendAsync):
     122        (WebCore::DatabaseBackendAsync::runTransaction):
     123        (WebCore::DatabaseBackendAsync::inProgressTransactionCompleted): Moved from frontend.
     124        (WebCore::DatabaseBackendAsync::scheduleTransaction): Moved from frontend.
     125        (WebCore::DatabaseBackendAsync::scheduleTransactionStep): Moved from frontend.
     126        (WebCore::DatabaseBackendAsync::transactionClient): Moved from frontend.
     127        (WebCore::DatabaseBackendAsync::transactionCoordinator): Moved from frontend.
     128        * Modules/webdatabase/DatabaseBackendAsync.h:
     129        (DatabaseBackendAsync):
     130        * Modules/webdatabase/DatabaseBackendContext.cpp:
     131        (WebCore::DatabaseBackendContext::frontend):
     132        * Modules/webdatabase/DatabaseBackendContext.h:
     133        (DatabaseBackendContext):
     134        * Modules/webdatabase/DatabaseManager.cpp:
     135        * Modules/webdatabase/DatabaseManager.h:
     136        (DatabaseManager):
     137        * Modules/webdatabase/DatabaseServer.cpp:
     138        * Modules/webdatabase/DatabaseServer.h:
     139        * Modules/webdatabase/DatabaseTask.cpp:
     140        (WebCore::DatabaseBackendAsync::DatabaseTransactionTask::doPerformTask):
     141        * Modules/webdatabase/SQLTransaction.cpp:
     142        (WebCore::SQLTransaction::create):
     143        (WebCore::SQLTransaction::SQLTransaction):
     144        (WebCore::SQLTransaction::setBackend):
     145        (WebCore::SQLTransaction::stateFunctionFor):
     146        (WebCore::SQLTransaction::requestTransitToState):
     147        (WebCore::SQLTransaction::nextStateForTransactionError):
     148            - was handleTransactionError(). There's also a backend version.
     149        (WebCore::SQLTransaction::deliverTransactionCallback): Moved from backend.
     150        (WebCore::SQLTransaction::deliverTransactionErrorCallback): Moved from backend.
     151        (WebCore::SQLTransaction::deliverStatementCallback): Moved from backend.
     152        (WebCore::SQLTransaction::deliverQuotaIncreaseCallback): Moved from backend.
     153        (WebCore::SQLTransaction::deliverSuccessCallback): Moved from backend.
     154        (WebCore::SQLTransaction::unreachableState):
     155        (WebCore::SQLTransaction::sendToBackendState):
     156        (WebCore::SQLTransaction::performPendingCallback): Moved from backend.
     157        (WebCore::SQLTransaction::executeSQL): Moved from backend.
     158        (WebCore::SQLTransaction::checkAndHandleClosedOrInterruptedDatabase):
     159        (WebCore::SQLTransaction::clearCallbackWrappers):
     160        * Modules/webdatabase/SQLTransaction.h:
     161        (SQLTransaction):
     162        (WebCore::SQLTransaction::database):
     163        (WebCore::SQLTransaction::hasCallback):
     164        (WebCore::SQLTransaction::hasSuccessCallback):
     165        (WebCore::SQLTransaction::hasErrorCallback):
     166        * Modules/webdatabase/SQLTransactionBackend.cpp:
     167        (WebCore::SQLTransactionBackend::create):
     168        (WebCore::SQLTransactionBackend::SQLTransactionBackend):
     169        (WebCore::SQLTransactionBackend::doCleanup):
     170        (WebCore::SQLTransactionBackend::transactionError):
     171        (WebCore::SQLTransactionBackend::setShouldRetryCurrentStatement):
     172        (WebCore::SQLTransactionBackend::stateFunctionFor):
     173        (WebCore::SQLTransactionBackend::enqueueStatement):
     174        (WebCore::SQLTransactionBackend::checkAndHandleClosedOrInterruptedDatabase):
     175        (WebCore::SQLTransactionBackend::performNextStep):
     176        (WebCore::SQLTransactionBackend::notifyDatabaseThreadIsShuttingDown):
     177        (WebCore::SQLTransactionBackend::acquireLock):
     178        (WebCore::SQLTransactionBackend::lockAcquired):
     179        (WebCore::SQLTransactionBackend::openTransactionAndPreflight):
     180        (WebCore::SQLTransactionBackend::runStatements):
     181        (WebCore::SQLTransactionBackend::runCurrentStatementAndGetNextState):
     182            - was runCurrentStatement().
     183        (WebCore::SQLTransactionBackend::nextStateForCurrentStatementError):
     184            - was handleCurrentStatementError().
     185        (WebCore::SQLTransactionBackend::postflightAndCommit):
     186        (WebCore::SQLTransactionBackend::cleanupAndTerminate):
     187        (WebCore::SQLTransactionBackend::nextStateForTransactionError):
     188            - was handleTransactionError(). There's also a frontend version.
     189        (WebCore::SQLTransactionBackend::cleanupAfterTransactionErrorCallback):
     190        (WebCore::SQLTransactionBackend::requestTransitToState):
     191        (WebCore::SQLTransactionBackend::unreachableState):
     192        (WebCore::SQLTransactionBackend::sendToFrontendState):
     193        * Modules/webdatabase/SQLTransactionBackend.h:
     194        (SQLTransactionWrapper):
     195        (SQLTransactionBackend):
     196        (WebCore::SQLTransactionBackend::database):
     197        * Modules/webdatabase/SQLTransactionClient.cpp:
     198        (WebCore::SQLTransactionClient::didCommitWriteTransaction):
     199        (WebCore::SQLTransactionClient::didExecuteStatement):
     200        * Modules/webdatabase/SQLTransactionCoordinator.cpp:
     201        (WebCore::getDatabaseIdentifier):
     202        * Modules/webdatabase/SQLTransactionState.h: Added.
     203        * Modules/webdatabase/SQLTransactionStateMachine.cpp: Added.
     204        (WebCore::nameForSQLTransactionState):
     205            - was debugStepName().
     206        * Modules/webdatabase/SQLTransactionStateMachine.h: Added.
     207        (SQLTransactionStateMachine):
     208        (WebCore::SQLTransactionStateMachine::~SQLTransactionStateMachine):
     209        (WebCore::::SQLTransactionStateMachine):
     210        (WebCore::::setStateToRequestedState):
     211        (WebCore::::runStateMachine):
     212        * Target.pri:
     213        * WebCore.gypi:
     214        * WebCore.vcproj/WebCore.vcproj:
     215        * WebCore.vcxproj/WebCore.vcxproj:
     216        * WebCore.vcxproj/WebCore.vcxproj.filters:
     217        * WebCore.xcodeproj/project.pbxproj:
     218        * inspector/InspectorDatabaseAgent.cpp:
     219
    12202013-02-14  Jer Noble  <jer.noble@apple.com>
    2221
  • trunk/Source/WebCore/GNUmakefile.list.am

    r142823 r142921  
    21012101        Source/WebCore/Modules/webaudio/WaveTable.h \
    21022102        Source/WebCore/Modules/webdatabase/AbstractDatabaseServer.h \
     2103        Source/WebCore/Modules/webdatabase/ChangeVersionData.h \
    21032104        Source/WebCore/Modules/webdatabase/ChangeVersionWrapper.cpp \
    21042105        Source/WebCore/Modules/webdatabase/ChangeVersionWrapper.h \
     
    21692170        Source/WebCore/Modules/webdatabase/SQLTransactionErrorCallback.h \
    21702171        Source/WebCore/Modules/webdatabase/SQLTransactionSyncCallback.h \
     2172        Source/WebCore/Modules/webdatabase/SQLTransactionState.h \
     2173        Source/WebCore/Modules/webdatabase/SQLTransactionStateMachine.cpp \
     2174        Source/WebCore/Modules/webdatabase/SQLTransactionStateMachine.h \
    21712175        Source/WebCore/Modules/webdatabase/SQLTransactionSync.cpp \
    21722176        Source/WebCore/Modules/webdatabase/SQLTransactionSync.h \
  • trunk/Source/WebCore/Modules/webdatabase/AbstractDatabaseServer.h

    r142030 r142921  
    7575    virtual bool deleteDatabase(SecurityOrigin*, const String& name) = 0;
    7676
    77     // From a secondary thread, must be thread safe with its data
    78     virtual void scheduleNotifyDatabaseChanged(SecurityOrigin*, const String& name) = 0;
    79     virtual void databaseChanged(DatabaseBackend*) = 0;
    80 
    8177#else // PLATFORM(CHROMIUM)
    8278    virtual void closeDatabasesImmediately(const String& originIdentifier, const String& name) = 0;
  • trunk/Source/WebCore/Modules/webdatabase/ChangeVersionWrapper.cpp

    r109877 r142921  
    11/*
    2  * Copyright (C) 2007 Apple Inc. All rights reserved.
     2 * Copyright (C) 2007, 2013 Apple Inc. All rights reserved.
    33 *
    44 * Redistribution and use in source and binary forms, with or without
     
    4444}
    4545
    46 bool ChangeVersionWrapper::performPreflight(SQLTransaction* transaction)
     46bool ChangeVersionWrapper::performPreflight(SQLTransactionBackend* transaction)
    4747{
    4848    ASSERT(transaction && transaction->database());
    4949
    50     Database* database = transaction->database();
     50    DatabaseBackendAsync* database = transaction->database();
    5151
    5252    String actualVersion;
     
    6868}
    6969
    70 bool ChangeVersionWrapper::performPostflight(SQLTransaction* transaction)
     70bool ChangeVersionWrapper::performPostflight(SQLTransactionBackend* transaction)
    7171{
    7272    ASSERT(transaction && transaction->database());
    7373
    74     Database* database = transaction->database();
     74    DatabaseBackendAsync* database = transaction->database();
    7575
    7676    if (!database->setVersionInDatabase(m_newVersion)) {
     
    8888}
    8989
    90 void ChangeVersionWrapper::handleCommitFailedAfterPostflight(SQLTransaction* transaction)
     90void ChangeVersionWrapper::handleCommitFailedAfterPostflight(SQLTransactionBackend* transaction)
    9191{
    9292    transaction->database()->setCachedVersion(m_oldVersion);
  • trunk/Source/WebCore/Modules/webdatabase/ChangeVersionWrapper.h

    r127757 r142921  
    11/*
    2  * Copyright (C) 2007 Apple Inc. All rights reserved.
     2 * Copyright (C) 2007, 2013 Apple Inc. All rights reserved.
    33 *
    44 * Redistribution and use in source and binary forms, with or without
     
    3131#if ENABLE(SQL_DATABASE)
    3232
    33 #include "SQLTransaction.h"
     33#include "SQLTransactionBackend.h"
    3434#include <wtf/Forward.h>
    3535
     
    4242    static PassRefPtr<ChangeVersionWrapper> create(const String& oldVersion, const String& newVersion) { return adoptRef(new ChangeVersionWrapper(oldVersion, newVersion)); }
    4343
    44     virtual bool performPreflight(SQLTransaction*);
    45     virtual bool performPostflight(SQLTransaction*);
     44    virtual bool performPreflight(SQLTransactionBackend*);
     45    virtual bool performPostflight(SQLTransactionBackend*);
    4646    virtual SQLError* sqlError() const { return m_sqlError.get(); }
    47     virtual void handleCommitFailedAfterPostflight(SQLTransaction*);
     47    virtual void handleCommitFailedAfterPostflight(SQLTransactionBackend*);
    4848
    4949private:
  • trunk/Source/WebCore/Modules/webdatabase/Database.cpp

    r142193 r142921  
    3232#if ENABLE(SQL_DATABASE)
    3333
    34 #include "ChangeVersionWrapper.h"
     34#include "ChangeVersionData.h"
    3535#include "CrossThreadTask.h"
    3636#include "DatabaseBackendContext.h"
     
    4646#include "Page.h"
    4747#include "SQLError.h"
     48#include "SQLTransaction.h"
    4849#include "SQLTransactionCallback.h"
    49 #include "SQLTransactionClient.h"
    50 #include "SQLTransactionCoordinator.h"
    5150#include "SQLTransactionErrorCallback.h"
    5251#include "SQLiteStatement.h"
     
    6968PassRefPtr<Database> Database::create(ScriptExecutionContext*, PassRefPtr<DatabaseBackend> backend)
    7069{
     70    // FIXME: Currently, we're only simulating the backend by return the
     71    // frontend database as its own the backend. When we split the 2 apart,
     72    // this create() function should be changed to be a factory method for
     73    // instantiating the backend.
    7174    return static_cast<Database*>(backend.get());
    7275}
     
    7679    : DatabaseBase(databaseContext->scriptExecutionContext())
    7780    , DatabaseBackendAsync(databaseContext, name, expectedVersion, displayName, estimatedSize)
    78     , m_transactionInProgress(false)
    79     , m_isTransactionQueueEnabled(true)
     81    , m_databaseContext(DatabaseBackendAsync::databaseContext()->frontend())
    8082    , m_deleted(false)
    8183{
     
    163165    ASSERT(currentThread() == databaseContext()->databaseThread()->getThreadID());
    164166
    165     {
    166         MutexLocker locker(m_transactionInProgressMutex);
    167         m_isTransactionQueueEnabled = false;
    168         m_transactionInProgress = false;
    169         m_transactionQueue.clear();
    170     }
    171 
    172167    closeDatabase();
    173168
     
    197192                             PassRefPtr<VoidCallback> successCallback)
    198193{
    199     runTransaction(callback, errorCallback, successCallback, ChangeVersionWrapper::create(oldVersion, newVersion), false);
     194    ChangeVersionData data(oldVersion, newVersion);
     195    runTransaction(callback, errorCallback, successCallback, false, &data);
    200196}
    201197
    202198void Database::transaction(PassRefPtr<SQLTransactionCallback> callback, PassRefPtr<SQLTransactionErrorCallback> errorCallback, PassRefPtr<VoidCallback> successCallback)
    203199{
    204     runTransaction(callback, errorCallback, successCallback, 0, false);
     200    runTransaction(callback, errorCallback, successCallback, false);
    205201}
    206202
    207203void Database::readTransaction(PassRefPtr<SQLTransactionCallback> callback, PassRefPtr<SQLTransactionErrorCallback> errorCallback, PassRefPtr<VoidCallback> successCallback)
    208204{
    209     runTransaction(callback, errorCallback, successCallback, 0, true);
     205    runTransaction(callback, errorCallback, successCallback, true);
    210206}
    211207
     
    216212
    217213void Database::runTransaction(PassRefPtr<SQLTransactionCallback> callback, PassRefPtr<SQLTransactionErrorCallback> errorCallback,
    218                               PassRefPtr<VoidCallback> successCallback, PassRefPtr<SQLTransactionWrapper> wrapper, bool readOnly)
    219 {
    220     MutexLocker locker(m_transactionInProgressMutex);
    221     if (!m_isTransactionQueueEnabled) {
    222         if (errorCallback) {
    223             RefPtr<SQLError> error = SQLError::create(SQLError::UNKNOWN_ERR, "database has been closed");
    224             scriptExecutionContext()->postTask(createCallbackTask(&callTransactionErrorCallback, errorCallback, error.release()));
    225         }
    226         return;
    227     }
    228     RefPtr<SQLTransaction> transaction = SQLTransaction::create(this, callback, errorCallback, successCallback, wrapper, readOnly);
    229     m_transactionQueue.append(transaction.release());
    230     if (!m_transactionInProgress)
    231         scheduleTransaction();
    232 }
    233 
    234 void Database::inProgressTransactionCompleted()
    235 {
    236     MutexLocker locker(m_transactionInProgressMutex);
    237     m_transactionInProgress = false;
    238     scheduleTransaction();
    239 }
    240 
    241 void Database::scheduleTransaction()
    242 {
    243     ASSERT(!m_transactionInProgressMutex.tryLock()); // Locked by caller.
    244     RefPtr<SQLTransaction> transaction;
    245 
    246     if (m_isTransactionQueueEnabled && !m_transactionQueue.isEmpty())
    247         transaction = m_transactionQueue.takeFirst();
    248 
    249     if (transaction && databaseContext()->databaseThread()) {
    250         OwnPtr<DatabaseTransactionTask> task = DatabaseTransactionTask::create(transaction);
    251         LOG(StorageAPI, "Scheduling DatabaseTransactionTask %p for transaction %p\n", task.get(), task->transaction());
    252         m_transactionInProgress = true;
    253         databaseContext()->databaseThread()->scheduleTask(task.release());
    254     } else
    255         m_transactionInProgress = false;
    256 }
    257 
    258 void Database::scheduleTransactionStep(SQLTransactionBackend* transaction, bool immediately)
    259 {
    260     if (!databaseContext()->databaseThread())
    261         return;
    262 
    263     OwnPtr<DatabaseTransactionTask> task = DatabaseTransactionTask::create(transaction);
    264     LOG(StorageAPI, "Scheduling DatabaseTransactionTask %p for the transaction step\n", task.get());
    265     if (immediately)
    266         databaseContext()->databaseThread()->scheduleImmediateTask(task.release());
    267     else
    268         databaseContext()->databaseThread()->scheduleTask(task.release());
     214    PassRefPtr<VoidCallback> successCallback, bool readOnly, const ChangeVersionData* changeVersionData)
     215{
     216    RefPtr<SQLTransactionErrorCallback> anotherRefToErrorCallback = errorCallback;
     217    RefPtr<SQLTransaction> transaction = SQLTransaction::create(this, callback, successCallback, anotherRefToErrorCallback, readOnly);
     218
     219    RefPtr<SQLTransactionBackend> transactionBackend;
     220    transactionBackend = backend()->runTransaction(transaction.release(), readOnly, changeVersionData);
     221    if (!transactionBackend && anotherRefToErrorCallback) {
     222        RefPtr<SQLError> error = SQLError::create(SQLError::UNKNOWN_ERR, "database has been closed");
     223        scriptExecutionContext()->postTask(createCallbackTask(&callTransactionErrorCallback, anotherRefToErrorCallback, error.release()));
     224    }
    269225}
    270226
     
    324280}
    325281
    326 SQLTransactionClient* Database::transactionClient() const
    327 {
    328     return databaseContext()->databaseThread()->transactionClient();
    329 }
    330 
    331 SQLTransactionCoordinator* Database::transactionCoordinator() const
    332 {
    333     return databaseContext()->databaseThread()->transactionCoordinator();
    334 }
    335 
    336282Vector<String> Database::tableNames()
    337283{
     
    359305}
    360306
     307#if PLATFORM(CHROMIUM)
     308void Database::reportStartTransactionResult(int errorSite, int webSqlErrorCode, int sqliteErrorCode)
     309{
     310    backend()->reportStartTransactionResult(errorSite, webSqlErrorCode, sqliteErrorCode);
     311}
     312
     313void Database::reportCommitTransactionResult(int errorSite, int webSqlErrorCode, int sqliteErrorCode)
     314{
     315    backend()->reportCommitTransactionResult(errorSite, webSqlErrorCode, sqliteErrorCode);
     316}
     317
     318void Database::reportExecuteStatementResult(int errorSite, int webSqlErrorCode, int sqliteErrorCode)
     319{
     320    backend()->reportExecuteStatementResult(errorSite, webSqlErrorCode, sqliteErrorCode);
     321}
     322#endif
     323
    361324} // namespace WebCore
    362325
  • trunk/Source/WebCore/Modules/webdatabase/Database.h

    r142193 r142921  
    3636#include "DatabaseBasicTypes.h"
    3737#include "DatabaseError.h"
    38 #include <wtf/Deque.h>
    39 #include <wtf/Forward.h>
    4038#include <wtf/text/WTFString.h>
    4139
    4240namespace WebCore {
    4341
     42class ChangeVersionData;
    4443class DatabaseCallback;
     44class DatabaseContext;
    4545class SecurityOrigin;
    4646class SQLTransaction;
    4747class SQLTransactionBackend;
    4848class SQLTransactionCallback;
    49 class SQLTransactionClient;
    50 class SQLTransactionCoordinator;
    5149class SQLTransactionErrorCallback;
    52 class SQLTransactionWrapper;
    5350class VoidCallback;
    5451
     
    6663    // Internal engine support
    6764    static Database* from(DatabaseBackendAsync*);
     65    DatabaseContext* databaseContext() const { return m_databaseContext.get(); }
    6866
    6967    Vector<String> tableNames();
     
    8179
    8280    void scheduleTransactionCallback(SQLTransaction*);
    83     void scheduleTransactionStep(SQLTransactionBackend*, bool immediately = false);
    84 
    85     SQLTransactionClient* transactionClient() const;
    86     SQLTransactionCoordinator* transactionCoordinator() const;
    8781
    8882private:
     
    9387
    9488    void runTransaction(PassRefPtr<SQLTransactionCallback>, PassRefPtr<SQLTransactionErrorCallback>,
    95                         PassRefPtr<VoidCallback> successCallback, PassRefPtr<SQLTransactionWrapper>, bool readOnly);
    96 
    97     void inProgressTransactionCompleted();
    98     void scheduleTransaction();
     89        PassRefPtr<VoidCallback> successCallback, bool readOnly, const ChangeVersionData* = 0);
    9990
    10091    Vector<String> performGetTableNames();
    10192
    102     Deque<RefPtr<SQLTransaction> > m_transactionQueue;
    103     Mutex m_transactionInProgressMutex;
    104     bool m_transactionInProgress;
    105     bool m_isTransactionQueueEnabled;
     93#if PLATFORM(CHROMIUM)
     94    void reportStartTransactionResult(int errorSite, int webSqlErrorCode, int sqliteErrorCode);
     95    void reportCommitTransactionResult(int errorSite, int webSqlErrorCode, int sqliteErrorCode);
     96    void reportExecuteStatementResult(int errorSite, int webSqlErrorCode, int sqliteErrorCode);
     97#else
     98    void reportStartTransactionResult(int, int, int) { }
     99    void reportCommitTransactionResult(int, int, int) { }
     100    void reportExecuteStatementResult(int, int, int) { }
     101#endif
    106102
    107103    RefPtr<SecurityOrigin> m_databaseThreadSecurityOrigin;
     104    RefPtr<DatabaseContext> m_databaseContext;
    108105
    109106    bool m_deleted;
     
    112109    friend class DatabaseServer; // FIXME: remove this when the backend has been split out.
    113110    friend class DatabaseBackendAsync; // FIXME: remove this when the backend has been split out.
     111    friend class SQLStatement;
     112    friend class SQLTransaction;
    114113};
    115114
  • trunk/Source/WebCore/Modules/webdatabase/DatabaseBackend.cpp

    r142030 r142921  
    653653}
    654654
    655 #else
    656 void DatabaseBackend::reportOpenDatabaseResult(int, int, int) { }
    657 void DatabaseBackend::reportChangeVersionResult(int, int, int) { }
    658 void DatabaseBackend::reportStartTransactionResult(int, int, int) { }
    659 void DatabaseBackend::reportCommitTransactionResult(int, int, int) { }
    660 void DatabaseBackend::reportExecuteStatementResult(int, int, int) { }
    661 void DatabaseBackend::reportVacuumDatabaseResult(int) { }
    662655#endif // PLATFORM(CHROMIUM)
    663656
  • trunk/Source/WebCore/Modules/webdatabase/DatabaseBackend.h

    r142193 r142921  
    115115    bool getActualVersionForTransaction(String& version);
    116116
     117#if PLATFORM(CHROMIUM)
    117118    void reportOpenDatabaseResult(int errorSite, int webSqlErrorCode, int sqliteErrorCode);
    118119    void reportChangeVersionResult(int errorSite, int webSqlErrorCode, int sqliteErrorCode);
     
    121122    void reportExecuteStatementResult(int errorSite, int webSqlErrorCode, int sqliteErrorCode);
    122123    void reportVacuumDatabaseResult(int sqliteErrorCode);
     124#else
     125    void reportOpenDatabaseResult(int, int, int) { }
     126    void reportChangeVersionResult(int, int, int) { }
     127    void reportStartTransactionResult(int, int, int) { }
     128    void reportCommitTransactionResult(int, int, int) { }
     129    void reportExecuteStatementResult(int, int, int) { }
     130    void reportVacuumDatabaseResult(int) { }
     131#endif
    123132
    124133    static const char* databaseInfoTableName();
  • trunk/Source/WebCore/Modules/webdatabase/DatabaseBackendAsync.cpp

    r142030 r142921  
    2929#if ENABLE(SQL_DATABASE)
    3030
     31#include "ChangeVersionData.h"
     32#include "ChangeVersionWrapper.h"
    3133#include "DatabaseBackendContext.h"
    3234#include "DatabaseTask.h"
    3335#include "DatabaseThread.h"
    3436#include "DatabaseTracker.h"
     37#include "Logging.h"
     38#include "SQLTransaction.h"
     39#include "SQLTransactionBackend.h"
     40#include "SQLTransactionClient.h"
     41#include "SQLTransactionCoordinator.h"
    3542
    3643namespace WebCore {
     
    3845DatabaseBackendAsync::DatabaseBackendAsync(PassRefPtr<DatabaseBackendContext> databaseContext, const String& name, const String& expectedVersion, const String& displayName, unsigned long estimatedSize)
    3946    : DatabaseBackend(databaseContext, name, expectedVersion, displayName, estimatedSize, DatabaseType::Async)
     47    , m_transactionInProgress(false)
     48    , m_isTransactionQueueEnabled(true)
    4049{
    4150}
     
    7079}
    7180
     81PassRefPtr<SQLTransactionBackend> DatabaseBackendAsync::runTransaction(PassRefPtr<SQLTransaction> transaction,
     82    bool readOnly, const ChangeVersionData* data)
     83{
     84    MutexLocker locker(m_transactionInProgressMutex);
     85    if (!m_isTransactionQueueEnabled)
     86        return 0;
     87
     88    RefPtr<SQLTransactionWrapper> wrapper;
     89    if (data)
     90        wrapper = ChangeVersionWrapper::create(data->oldVersion(), data->newVersion());
     91
     92    RefPtr<SQLTransactionBackend> transactionBackend = SQLTransactionBackend::create(this, transaction, wrapper, readOnly);
     93    m_transactionQueue.append(transactionBackend);
     94    if (!m_transactionInProgress)
     95        scheduleTransaction();
     96
     97    return transactionBackend;
     98}
     99
     100void DatabaseBackendAsync::inProgressTransactionCompleted()
     101{
     102    MutexLocker locker(m_transactionInProgressMutex);
     103    m_transactionInProgress = false;
     104    scheduleTransaction();
     105}
     106
     107void DatabaseBackendAsync::scheduleTransaction()
     108{
     109    ASSERT(!m_transactionInProgressMutex.tryLock()); // Locked by caller.
     110    RefPtr<SQLTransactionBackend> transaction;
     111
     112    if (m_isTransactionQueueEnabled && !m_transactionQueue.isEmpty())
     113        transaction = m_transactionQueue.takeFirst();
     114
     115    if (transaction && databaseContext()->databaseThread()) {
     116        OwnPtr<DatabaseTransactionTask> task = DatabaseTransactionTask::create(transaction);
     117        LOG(StorageAPI, "Scheduling DatabaseTransactionTask %p for transaction %p\n", task.get(), task->transaction());
     118        m_transactionInProgress = true;
     119        databaseContext()->databaseThread()->scheduleTask(task.release());
     120    } else
     121        m_transactionInProgress = false;
     122}
     123
     124void DatabaseBackendAsync::scheduleTransactionStep(SQLTransactionBackend* transaction)
     125{
     126    if (!databaseContext()->databaseThread())
     127        return;
     128
     129    OwnPtr<DatabaseTransactionTask> task = DatabaseTransactionTask::create(transaction);
     130    LOG(StorageAPI, "Scheduling DatabaseTransactionTask %p for the transaction step\n", task.get());
     131    databaseContext()->databaseThread()->scheduleTask(task.release());
     132}
     133
     134SQLTransactionClient* DatabaseBackendAsync::transactionClient() const
     135{
     136    return databaseContext()->databaseThread()->transactionClient();
     137}
     138
     139SQLTransactionCoordinator* DatabaseBackendAsync::transactionCoordinator() const
     140{
     141    return databaseContext()->databaseThread()->transactionCoordinator();
     142}
     143
    72144} // namespace WebCore
    73145
  • trunk/Source/WebCore/Modules/webdatabase/DatabaseBackendAsync.h

    r142030 r142921  
    3030
    3131#include "DatabaseBackend.h"
     32#include <wtf/Deque.h>
    3233#include <wtf/text/WTFString.h>
    3334
    3435namespace WebCore {
    3536
     37class ChangeVersionData;
    3638class Database;
    3739class DatabaseServer;
     40class SQLTransaction;
     41class SQLTransactionBackend;
     42class SQLTransactionClient;
     43class SQLTransactionCoordinator;
    3844
    3945// FIXME: This implementation of DatabaseBackendAsync is only a place holder
     
    4854
    4955    virtual bool openAndVerifyVersion(bool setVersionInNewDatabase, DatabaseError&, String& errorMessage);
    50     virtual bool performOpenAndVerify(bool setVersionInNewDatabase, DatabaseError&, String& errorMessage);
     56
     57    PassRefPtr<SQLTransactionBackend> runTransaction(PassRefPtr<SQLTransaction>, bool readOnly, const ChangeVersionData*);
     58    void scheduleTransactionStep(SQLTransactionBackend*);
     59    void inProgressTransactionCompleted();
     60
     61    SQLTransactionClient* transactionClient() const;
     62    SQLTransactionCoordinator* transactionCoordinator() const;
    5163
    5264private:
     
    5567    class DatabaseTransactionTask;
    5668    class DatabaseTableNamesTask;
     69
     70    virtual bool performOpenAndVerify(bool setVersionInNewDatabase, DatabaseError&, String& errorMessage);
     71
     72    void scheduleTransaction();
     73
     74    Deque<RefPtr<SQLTransactionBackend> > m_transactionQueue;
     75    Mutex m_transactionInProgressMutex;
     76    bool m_transactionInProgress;
     77    bool m_isTransactionQueueEnabled;
    5778
    5879    friend class Database;
  • trunk/Source/WebCore/Modules/webdatabase/DatabaseBackendContext.cpp

    r141928 r142921  
    3333namespace WebCore {
    3434
     35DatabaseContext* DatabaseBackendContext::frontend()
     36{
     37    // FIXME: Currently, we're only simulating the frontend by return the
     38    // backend context as its own the frontend. When we split the 2 apart, this
     39    // create() function should be changed to return a cached m_frontend.
     40    return static_cast<DatabaseContext*>(this);
     41}
     42
    3543SecurityOrigin* DatabaseBackendContext::securityOrigin() const
    3644{
  • trunk/Source/WebCore/Modules/webdatabase/DatabaseBackendContext.h

    r141928 r142921  
    4444class DatabaseBackendContext : public DatabaseContext {
    4545public:
     46    DatabaseContext* frontend();
     47
    4648    ScriptExecutionContext* scriptExecutionContext() const { return m_scriptExecutionContext; }
    4749    SecurityOrigin* securityOrigin() const;
  • trunk/Source/WebCore/Modules/webdatabase/DatabaseManager.cpp

    r142698 r142921  
    415415}
    416416
    417 // From a secondary thread, must be thread safe with its data
    418 void DatabaseManager::scheduleNotifyDatabaseChanged(SecurityOrigin* origin, const String& name)
    419 {
    420     m_server->scheduleNotifyDatabaseChanged(origin, name);
    421 }
    422 
    423 void DatabaseManager::databaseChanged(DatabaseBackend* database)
    424 {
    425     m_server->databaseChanged(database);
    426 }
    427 
    428417#else // PLATFORM(CHROMIUM)
    429418void DatabaseManager::closeDatabasesImmediately(const String& originIdentifier, const String& name)
  • trunk/Source/WebCore/Modules/webdatabase/DatabaseManager.h

    r142030 r142921  
    105105    bool deleteDatabase(SecurityOrigin*, const String& name);
    106106
    107     // From a secondary thread, must be thread safe with its data
    108     void scheduleNotifyDatabaseChanged(SecurityOrigin*, const String& name);
    109 
    110     void databaseChanged(DatabaseBackend*);
    111 
    112107#else // PLATFORM(CHROMIUM)
    113108    void closeDatabasesImmediately(const String& originIdentifier, const String& name);
  • trunk/Source/WebCore/Modules/webdatabase/DatabaseServer.cpp

    r142030 r142921  
    129129}
    130130
    131 // From a secondary thread, must be thread safe with its data
    132 void DatabaseServer::scheduleNotifyDatabaseChanged(SecurityOrigin* origin, const String& name)
    133 {
    134     DatabaseTracker::tracker().scheduleNotifyDatabaseChanged(origin, name);
    135 }
    136 
    137 void DatabaseServer::databaseChanged(DatabaseBackend* database)
    138 {
    139     DatabaseTracker::tracker().databaseChanged(database);
    140 }
    141 
    142131#else // PLATFORM(CHROMIUM)
    143132void DatabaseServer::closeDatabasesImmediately(const String& originIdentifier, const String& name)
  • trunk/Source/WebCore/Modules/webdatabase/DatabaseServer.h

    r142030 r142921  
    6363    virtual bool deleteDatabase(SecurityOrigin*, const String& name);
    6464
    65     // From a secondary thread, must be thread safe with its data
    66     virtual void scheduleNotifyDatabaseChanged(SecurityOrigin*, const String& name);
    67     virtual void databaseChanged(DatabaseBackend*);
    68 
    6965#else // PLATFORM(CHROMIUM)
    7066    virtual void closeDatabasesImmediately(const String& originIdentifier, const String& name);
  • trunk/Source/WebCore/Modules/webdatabase/DatabaseTask.cpp

    r142193 r142921  
    156156void DatabaseBackendAsync::DatabaseTransactionTask::doPerformTask()
    157157{
    158     if (m_transaction->performNextStep())
    159         Database::from(m_transaction->database())->inProgressTransactionCompleted();
     158    m_transaction->performNextStep();
    160159}
    161160
  • trunk/Source/WebCore/Modules/webdatabase/SQLTransaction.cpp

    r142194 r142921  
    3232#if ENABLE(SQL_DATABASE)
    3333
     34#include "Database.h"
     35#include "DatabaseAuthorizer.h"
     36#include "DatabaseContext.h"
     37#include "ExceptionCode.h"
     38#include "Logging.h"
     39#include "SQLError.h"
     40#include "SQLStatementCallback.h"
     41#include "SQLStatementErrorCallback.h"
     42#include "SQLTransactionBackend.h"
    3443#include "SQLTransactionCallback.h"
     44#include "SQLTransactionClient.h"
    3545#include "SQLTransactionErrorCallback.h"
    3646#include "VoidCallback.h"
     47#include <wtf/StdLibExtras.h>
     48#include <wtf/Vector.h>
    3749
    3850namespace WebCore {
    3951
    4052PassRefPtr<SQLTransaction> SQLTransaction::create(Database* db, PassRefPtr<SQLTransactionCallback> callback,
    41     PassRefPtr<SQLTransactionErrorCallback> errorCallback, PassRefPtr<VoidCallback> successCallback,
    42     PassRefPtr<SQLTransactionWrapper> wrapper, bool readOnly)
    43 {
    44     return adoptRef(new SQLTransaction(db, callback, errorCallback, successCallback, wrapper, readOnly));
     53    PassRefPtr<VoidCallback> successCallback, PassRefPtr<SQLTransactionErrorCallback> errorCallback,
     54    bool readOnly)
     55{
     56    return adoptRef(new SQLTransaction(db, callback, successCallback, errorCallback, readOnly));
    4557}
    4658
    4759SQLTransaction::SQLTransaction(Database* db, PassRefPtr<SQLTransactionCallback> callback,
    48     PassRefPtr<SQLTransactionErrorCallback> errorCallback, PassRefPtr<VoidCallback> successCallback,
    49     PassRefPtr<SQLTransactionWrapper> wrapper, bool readOnly)
    50     : SQLTransactionBackend(db, callback, errorCallback, successCallback, wrapper, readOnly)
    51 {
    52 }
    53 
    54 SQLTransaction* SQLTransaction::from(SQLTransactionBackend* backend)
    55 {
    56     return static_cast<SQLTransaction*>(backend);
     60    PassRefPtr<VoidCallback> successCallback, PassRefPtr<SQLTransactionErrorCallback> errorCallback,
     61    bool readOnly)
     62    : m_database(db)
     63    , m_callbackWrapper(callback, db->scriptExecutionContext())
     64    , m_successCallbackWrapper(successCallback, db->scriptExecutionContext())
     65    , m_errorCallbackWrapper(errorCallback, db->scriptExecutionContext())
     66    , m_executeSqlAllowed(false)
     67    , m_readOnly(readOnly)
     68{
     69    ASSERT(m_database);
     70}
     71
     72void SQLTransaction::setBackend(SQLTransactionBackend* backend)
     73{
     74    ASSERT(!m_backend);
     75    m_backend = backend;
     76}
     77
     78SQLTransaction::StateFunction SQLTransaction::stateFunctionFor(SQLTransactionState state)
     79{
     80    static const StateFunction stateFunctions[] = {
     81        &SQLTransaction::unreachableState,                // 0. illegal
     82        &SQLTransaction::unreachableState,                // 1. idle
     83        &SQLTransaction::unreachableState,                // 2. acquireLock
     84        &SQLTransaction::unreachableState,                // 3. openTransactionAndPreflight
     85        &SQLTransaction::sendToBackendState,              // 4. runStatements
     86        &SQLTransaction::unreachableState,                // 5. postflightAndCommit
     87        &SQLTransaction::sendToBackendState,              // 6. cleanupAndTerminate
     88        &SQLTransaction::sendToBackendState,              // 7. cleanupAfterTransactionErrorCallback
     89        &SQLTransaction::deliverTransactionCallback,      // 8.
     90        &SQLTransaction::deliverTransactionErrorCallback, // 9.
     91        &SQLTransaction::deliverStatementCallback,        // 10.
     92        &SQLTransaction::deliverQuotaIncreaseCallback,    // 11.
     93        &SQLTransaction::deliverSuccessCallback           // 12.
     94    };
     95
     96    ASSERT(WTF_ARRAY_LENGTH(stateFunctions) == static_cast<int>(SQLTransactionState::NumberOfStates));
     97    ASSERT(state < SQLTransactionState::NumberOfStates);
     98
     99    return stateFunctions[static_cast<int>(state)];
     100}
     101
     102// requestTransitToState() can be called from the backend. Hence, it should
     103// NOT be modifying SQLTransactionBackend in general. The only safe field to
     104// modify is m_requestedState which is meant for this purpose.
     105void SQLTransaction::requestTransitToState(SQLTransactionState nextState)
     106{
     107    LOG(StorageAPI, "Scheduling %s for transaction %p\n", nameForSQLTransactionState(nextState), this);
     108    m_requestedState = nextState;
     109    m_database->scheduleTransactionCallback(this);
     110}
     111
     112SQLTransactionState SQLTransaction::nextStateForTransactionError()
     113{
     114    ASSERT(m_transactionError);
     115    if (m_errorCallbackWrapper.hasCallback())
     116        return SQLTransactionState::DeliverTransactionErrorCallback;
     117
     118    // No error callback, so fast-forward to:
     119    // Transaction Step 11 - Rollback the transaction.
     120    return SQLTransactionState::CleanupAfterTransactionErrorCallback;
     121}
     122
     123SQLTransactionState SQLTransaction::deliverTransactionCallback()
     124{
     125    bool shouldDeliverErrorCallback = false;
     126
     127    // Spec 4.3.2 4: Invoke the transaction callback with the new SQLTransaction object
     128    RefPtr<SQLTransactionCallback> callback = m_callbackWrapper.unwrap();
     129    if (callback) {
     130        m_executeSqlAllowed = true;
     131        shouldDeliverErrorCallback = !callback->handleEvent(this);
     132        m_executeSqlAllowed = false;
     133    }
     134
     135    // Spec 4.3.2 5: If the transaction callback was null or raised an exception, jump to the error callback
     136    SQLTransactionState nextState = SQLTransactionState::RunStatements;
     137    if (shouldDeliverErrorCallback) {
     138        m_database->reportStartTransactionResult(5, SQLError::UNKNOWN_ERR, 0);
     139        m_transactionError = SQLError::create(SQLError::UNKNOWN_ERR, "the SQLTransactionCallback was null or threw an exception");
     140        nextState = SQLTransactionState::DeliverTransactionErrorCallback;
     141    }
     142    m_database->reportStartTransactionResult(0, -1, 0); // OK
     143    return nextState;
     144}
     145
     146SQLTransactionState SQLTransaction::deliverTransactionErrorCallback()
     147{
     148    // Spec 4.3.2.10: If exists, invoke error callback with the last
     149    // error to have occurred in this transaction.
     150    RefPtr<SQLTransactionErrorCallback> errorCallback = m_errorCallbackWrapper.unwrap();
     151    if (errorCallback) {
     152        // If we get here with an empty m_transactionError, then the backend
     153        // must be waiting in the idle state waiting for this state to finish.
     154        // Hence, it's thread safe to fetch the backend transactionError without
     155        // a lock.
     156        if (!m_transactionError)
     157            m_transactionError = m_backend->transactionError();
     158
     159        ASSERT(m_transactionError);
     160        errorCallback->handleEvent(m_transactionError.get());
     161
     162        m_transactionError = 0;
     163    }
     164
     165    clearCallbackWrappers();
     166
     167    // Spec 4.3.2.10: Rollback the transaction.
     168    return SQLTransactionState::CleanupAfterTransactionErrorCallback;
     169}
     170
     171SQLTransactionState SQLTransaction::deliverStatementCallback()
     172{
     173    ASSERT(m_backend->m_currentStatement);
     174
     175    // Spec 4.3.2.6.6 and 4.3.2.6.3: If the statement callback went wrong, jump to the transaction error callback
     176    // Otherwise, continue to loop through the statement queue
     177    m_executeSqlAllowed = true;
     178    bool result = m_backend->m_currentStatement->performCallback(this);
     179    m_executeSqlAllowed = false;
     180
     181    if (result) {
     182        m_database->reportCommitTransactionResult(2, SQLError::UNKNOWN_ERR, 0);
     183        m_transactionError = SQLError::create(SQLError::UNKNOWN_ERR, "the statement callback raised an exception or statement error callback did not return false");
     184        return nextStateForTransactionError();
     185    }
     186    return SQLTransactionState::RunStatements;
     187}
     188
     189SQLTransactionState SQLTransaction::deliverQuotaIncreaseCallback()
     190{
     191    ASSERT(m_backend->m_currentStatement);
     192
     193    bool shouldRetryCurrentStatement = m_database->transactionClient()->didExceedQuota(database());
     194    m_backend->setShouldRetryCurrentStatement(shouldRetryCurrentStatement);
     195
     196    return SQLTransactionState::RunStatements;
     197}
     198
     199SQLTransactionState SQLTransaction::deliverSuccessCallback()
     200{
     201    // Spec 4.3.2.8: Deliver success callback.
     202    RefPtr<VoidCallback> successCallback = m_successCallbackWrapper.unwrap();
     203    if (successCallback)
     204        successCallback->handleEvent();
     205
     206    clearCallbackWrappers();
     207
     208    // Schedule a "post-success callback" step to return control to the database thread in case there
     209    // are further transactions queued up for this Database
     210    return SQLTransactionState::CleanupAndTerminate;
     211}
     212
     213// This state function is used as a stub function to plug unimplemented states
     214// in the state dispatch table. They are unimplemented because they should
     215// never be reached in the course of correct execution.
     216SQLTransactionState SQLTransaction::unreachableState()
     217{
     218    ASSERT_NOT_REACHED();
     219    return SQLTransactionState::End;
     220}
     221
     222SQLTransactionState SQLTransaction::sendToBackendState()
     223{
     224    ASSERT(m_nextState != SQLTransactionState::Idle);
     225    m_backend->requestTransitToState(m_nextState);
     226    return SQLTransactionState::Idle;
     227}
     228
     229void SQLTransaction::performPendingCallback()
     230{
     231    LOG(StorageAPI, "Callback %s\n", nameForSQLTransactionState(m_nextState));
     232
     233    setStateToRequestedState();
     234    ASSERT(m_nextState == SQLTransactionState::End
     235        || m_nextState == SQLTransactionState::DeliverTransactionCallback
     236        || m_nextState == SQLTransactionState::DeliverTransactionErrorCallback
     237        || m_nextState == SQLTransactionState::DeliverStatementCallback
     238        || m_nextState == SQLTransactionState::DeliverQuotaIncreaseCallback
     239        || m_nextState == SQLTransactionState::DeliverSuccessCallback);
     240
     241    checkAndHandleClosedOrInterruptedDatabase();
     242    runStateMachine();
     243}
     244
     245void SQLTransaction::executeSQL(const String& sqlStatement, const Vector<SQLValue>& arguments, PassRefPtr<SQLStatementCallback> callback, PassRefPtr<SQLStatementErrorCallback> callbackError, ExceptionCode& e)
     246{
     247    if (!m_executeSqlAllowed || !m_database->opened()) {
     248        e = INVALID_STATE_ERR;
     249        return;
     250    }
     251
     252    int permissions = DatabaseAuthorizer::ReadWriteMask;
     253    if (!m_database->databaseContext()->allowDatabaseAccess())
     254        permissions |= DatabaseAuthorizer::NoAccessMask;
     255    else if (m_readOnly)
     256        permissions |= DatabaseAuthorizer::ReadOnlyMask;
     257
     258    RefPtr<SQLStatement> statement = SQLStatement::create(m_database.get(), sqlStatement, arguments, callback, callbackError, permissions);
     259
     260    if (m_database->deleted())
     261        statement->setDatabaseDeletedError(m_database.get());
     262
     263    m_backend->enqueueStatement(statement);
     264}
     265
     266bool SQLTransaction::checkAndHandleClosedOrInterruptedDatabase()
     267{
     268    if (m_database->opened() && !m_database->isInterrupted())
     269        return false;
     270
     271    clearCallbackWrappers();
     272    m_nextState = SQLTransactionState::CleanupAndTerminate;
     273
     274    return true;
     275}
     276
     277void SQLTransaction::clearCallbackWrappers()
     278{
     279    // Release the unneeded callbacks, to break reference cycles.
     280    m_callbackWrapper.clear();
     281    m_successCallbackWrapper.clear();
     282    m_errorCallbackWrapper.clear();
    57283}
    58284
  • trunk/Source/WebCore/Modules/webdatabase/SQLTransaction.h

    r142194 r142921  
    3232#if ENABLE(SQL_DATABASE)
    3333
    34 #include "SQLTransactionBackend.h"
     34#include "SQLCallbackWrapper.h"
     35#include "SQLStatement.h"
     36#include "SQLTransactionStateMachine.h"
     37#include <wtf/PassRefPtr.h>
     38#include <wtf/RefPtr.h>
    3539
    3640namespace WebCore {
    3741
    38 class SQLTransaction : public SQLTransactionBackend {
     42class Database;
     43class SQLError;
     44class SQLStatementCallback;
     45class SQLStatementErrorCallback;
     46class SQLTransactionBackend;
     47class SQLTransactionCallback;
     48class SQLTransactionErrorCallback;
     49class SQLValue;
     50class VoidCallback;
     51
     52class SQLTransaction : public SQLTransactionStateMachine<SQLTransaction> {
    3953public:
    40     static PassRefPtr<SQLTransaction> create(Database*, PassRefPtr<SQLTransactionCallback>, PassRefPtr<SQLTransactionErrorCallback>,
    41                                              PassRefPtr<VoidCallback>, PassRefPtr<SQLTransactionWrapper>, bool readOnly = false);
     54    static PassRefPtr<SQLTransaction> create(Database*, PassRefPtr<SQLTransactionCallback>,
     55        PassRefPtr<VoidCallback> successCallback, PassRefPtr<SQLTransactionErrorCallback>,
     56        bool readOnly);
    4257
    43     static SQLTransaction* from(SQLTransactionBackend*);
     58    void setBackend(SQLTransactionBackend*);
     59
     60    void performPendingCallback();
     61
     62    void executeSQL(const String& sqlStatement, const Vector<SQLValue>& arguments,
     63        PassRefPtr<SQLStatementCallback>, PassRefPtr<SQLStatementErrorCallback>, ExceptionCode&);
     64
     65    Database* database() { return m_database.get(); }
     66
     67    bool hasCallback() const { return m_callbackWrapper.hasCallback(); }
     68    bool hasSuccessCallback() const { return m_successCallbackWrapper.hasCallback(); }
     69    bool hasErrorCallback() const { return m_errorCallbackWrapper.hasCallback(); }
    4470
    4571private:
    46     SQLTransaction(Database*, PassRefPtr<SQLTransactionCallback>, PassRefPtr<SQLTransactionErrorCallback>,
    47                    PassRefPtr<VoidCallback>, PassRefPtr<SQLTransactionWrapper>, bool readOnly);
     72    SQLTransaction(Database*, PassRefPtr<SQLTransactionCallback>,
     73        PassRefPtr<VoidCallback> successCallback, PassRefPtr<SQLTransactionErrorCallback>,
     74        bool readOnly);
     75
     76    bool checkAndHandleClosedOrInterruptedDatabase();
     77    void clearCallbackWrappers();
     78
     79    // State Machine functions:
     80    virtual StateFunction stateFunctionFor(SQLTransactionState);
     81    void requestTransitToState(SQLTransactionState);
     82
     83    // State functions:
     84    SQLTransactionState deliverTransactionCallback();
     85    SQLTransactionState deliverTransactionErrorCallback();
     86    SQLTransactionState deliverStatementCallback();
     87    SQLTransactionState deliverQuotaIncreaseCallback();
     88    SQLTransactionState deliverSuccessCallback();
     89
     90    SQLTransactionState unreachableState();
     91    SQLTransactionState sendToBackendState();
     92
     93    SQLTransactionState nextStateForTransactionError();
     94
     95    RefPtr<Database> m_database;
     96    RefPtr<SQLTransactionBackend> m_backend;
     97    SQLCallbackWrapper<SQLTransactionCallback> m_callbackWrapper;
     98    SQLCallbackWrapper<VoidCallback> m_successCallbackWrapper;
     99    SQLCallbackWrapper<SQLTransactionErrorCallback> m_errorCallbackWrapper;
     100
     101    bool m_executeSqlAllowed;
     102    RefPtr<SQLError> m_transactionError;
     103
     104    bool m_readOnly;
     105
     106    friend class SQLTransactionBackend;
    48107};
    49108
  • trunk/Source/WebCore/Modules/webdatabase/SQLTransactionBackend.cpp

    r142213 r142921  
    4040#include "SQLError.h"
    4141#include "SQLStatement.h"
    42 #include "SQLStatementCallback.h"
    43 #include "SQLStatementErrorCallback.h"
     42#include "SQLStatementCallback.h" // FIXME: remove when SQLStatement has been refactored.
     43#include "SQLStatementErrorCallback.h" // FIXME: remove when SQLStatement has been refactored.
    4444#include "SQLTransaction.h"
    45 #include "SQLTransactionCallback.h"
    4645#include "SQLTransactionClient.h"
    4746#include "SQLTransactionCoordinator.h"
    48 #include "SQLTransactionErrorCallback.h"
    4947#include "SQLValue.h"
    5048#include "SQLiteTransaction.h"
    51 #include "ScriptExecutionContext.h"
    52 #include "VoidCallback.h"
    53 #include <wtf/OwnPtr.h>
    54 #include <wtf/PassRefPtr.h>
    55 #include <wtf/RefPtr.h>
     49#include <wtf/StdLibExtras.h>
    5650#include <wtf/text/WTFString.h>
    5751
     
    6155// The SQLTransaction is a state machine that executes a series of states / steps.
    6256//
    63 // ths State Transition Graph at a glance:
     57// The work of the transaction states are defined in section of 4.3.2 of the
     58// webdatabase spec: http://dev.w3.org/html5/webdatabase/#processing-model
     59//
     60// the State Transition Graph at a glance:
    6461// ======================================
    6562//
    66 //    Backend (works with SQLiteDatabase)          .   Frontend (works with Script)
    67 //    ===================================          .   ============================
    68 //   ,--> State 0: [initial state]                 .
    69 //   | ^     v                                     .
    70 //   | |  State 1: [acquireLock]                   .
    71 //   | |     v                                     .
    72 //   | |  State 2: [openTransactionAndPreflight] ----------------------------------------------------.
    73 //   | |     |                                     .                                                 |
    74 //   | |     `---------------------------------------> State 3: [deliverTransactionCallback] -----.  |
    75 //   | |                                           .      |                                       v  v
    76 //   | |     ,--------------------------------------------'     State 10: [deliverTransactionErrorCallback] +
    77 //   | |     |                                     .                                              ^  ^  ^   |
    78 //   | |     v                                     .                                              |  |  |   |
    79 //   | |  State 4: [runStatements] ---------------------------------------------------------------'  |  |   |
    80 //   | |     |        ^  ^ |  ^ |                  .                                                 |  |   |
    81 //   | |     |--------'  | |  | `--------------------> State 8: [deliverStatementCallback] +---------'  |   |
    82 //   | |     |           | |  `------------------------------------------------------------'            |   |
    83 //   | |     |           | `-------------------------> State 9: [deliverQuotaIncreaseCallback] +        |   |
    84 //   | |     |            `--------------------------------------------------------------------'        |   |
    85 //   | |     v                                     .                                                    |   |
    86 //   | |  State 5: [postflightAndCommit] --+------------------------------------------------------------'   |
    87 //   | |                                   |---------> State 6: [deliverSuccessCallback] +                  |
    88 //   | |     ,-----------------------------'       .                                     |                  |
    89 //   | |     v                                     .                                     |                  |
    90 //   | |  State 7: [cleanupAfterSuccessCallback] <---------------------------------------'                  |
    91 //   | `-----'                                     .                                                        |
    92 //   `------------------------------------------------------------------------------------------------------'
    93 //                                                 .
     63//     Backend                          .   Frontend
     64//     (works with SQLiteDatabase)      .   (works with Script)
     65//     ===========================      .   ===================
     66//                                      .
     67//     1. Idle                          .
     68//         v                            .
     69//     2. AcquireLock                   .
     70//         v                            .
     71//     3. OpenTransactionAndPreflight ------------------------------------------.
     72//         |                            .                                       |
     73//         `-------------------------------> 8. DeliverTransactionCallback --.  |
     74//                                      .        |                           v  v
     75//         ,-------------------------------------'   9. DeliverTransactionErrorCallback +
     76//         |                            .                                    ^  ^  ^    |
     77//         v                            .                                    |  |  |    |
     78//     4. RunStatements -----------------------------------------------------'  |  |    |
     79//         |        ^  ^ |  ^ |         .                                       |  |    |
     80//         |--------'  | |  | `------------> 10. DeliverStatementCallback +-----'  |    |
     81//         |           | |  `---------------------------------------------'        |    |
     82//         |           | `-----------------> 11. DeliverQuotaIncreaseCallback +    |    |
     83//         |            `-----------------------------------------------------'    |    |
     84//         v                            .                                          |    |
     85//     5. PostflightAndCommit --+--------------------------------------------------'    |
     86//                              |----------> 12. DeliverSuccessCallback +               |
     87//         ,--------------------'       .                               |               |
     88//         v                            .                               |               |
     89//     6. CleanupAndTerminate <-----------------------------------------'               |
     90//         v           ^                .                                               |
     91//     0. End          |                .                                               |
     92//                     |                .                                               |
     93//                7: CleanupAfterTransactionErrorCallback <----------------------------'
     94//                                      .
    9495//
    9596// the States and State Transitions:
    9697// ================================
    97 // Executed in the back-end:
    98 //     State 0: [initial state]
    99 //     - On scheduled transaction, goto [acquireLock].
    100 //
    101 //     State 1: [acquireLock]
    102 //     - acquire lock.
    103 //     - on "lock" acquisition, goto [openTransactionAndPreflight].
    104 //
    105 //     State 2: [openTransactionAndPreflight]
    106 //     - Sets up an SQLiteTransaction.
    107 //     - begin the SQLiteTransaction.
    108 //     - call the SQLTransactionWrapper preflight if available.
    109 //     - schedule script callback.
    110 //     - on error (see handleTransactionError), goto [deliverTransactionErrorCallback].
    111 //     - goto [deliverTransactionCallback].
    112 //
    113 // Executed in the front-end:
    114 //     State 3: [deliverTransactionCallback]
    115 //     - invoke the script function callback() if available.
    116 //     - on error, goto [deliverTransactionErrorCallback].
    117 //     - goto [runStatements].
    118 //
    119 // Executed in the back-end:
    120 //     State 4: [runStatements]
    121 //     - while there are statements {
    122 //         - run a statement.
    123 //         - if statementCallback is available, goto [deliverStatementCallback].
    124 //         - on error,
    125 //           goto [deliverQuotaIncreaseCallback], or
    126 //           goto [deliverStatementCallback] (see handleCurrentStatementError), or
    127 //           goto [deliverTransactionErrorCallback].
    128 //       }
    129 //     - goto [postflightAndCommit].
    130 //
    131 //     State 5: [postflightAndCommit]
    132 //     - call the SQLTransactionWrapper postflight if available.
    133 //     - commit the SQLiteTansaction.
    134 //     - on error, goto [deliverTransactionErrorCallback] (see handleTransactionError).
    135 //     - if successCallback is available, goto [deliverSuccessCallback].
    136 //       else goto [cleanupAfterSuccessCallback].
    137 //
    138 // Executed in the front-end:
    139 //     State 6: [deliverSuccessCallback]
    140 //     - invoke the script function successCallback() if available.
    141 //     - goto [cleanupAfterSuccessCallback].
    142 //
    143 // Executed in the back-end:
    144 //     State 7: [cleanupAfterSuccessCallback]
    145 //     - clean the SQLiteTransaction.
    146 //     - release lock.
    147 //     - goto [initial state].
    148 //
    149 // Other states:
    150 // Executed in the front-end:
    151 //     State 8: [deliverStatementCallback]
    152 //     - invoke script statement callback (assume available).
    153 //     - on error (see handleTransactionError),
    154 //       goto [deliverTransactionErrorCallback].
    155 //     - goto [runStatements].
    156 //
    157 //     State 9: [deliverQuotaIncreaseCallback]
    158 //     - give client a chance to increase the quota.
    159 //     - goto [runStatements].
    160 //
    161 //     State 10: [deliverTransactionErrorCallback]
    162 //     - invoke the script function errorCallback if available.
    163 //     - goto [cleanupAfterTransactionErrorCallback].
    164 //
    165 // Executed in the back-end:
    166 //     State 11: [cleanupAfterTransactionErrorCallback]
    167 //     - rollback and clear SQLiteTransaction.
    168 //     - clear statements.
    169 //     - release lock.
    170 //     - goto [initial state].
     98//     0. SQLTransactionState::End
     99//         - the end state.
     100//
     101//     1. SQLTransactionState::Idle
     102//         - placeholder state while waiting on frontend/backend, etc. See comment on
     103//           "State transitions between SQLTransaction and SQLTransactionBackend"
     104//           below.
     105//
     106//     2. SQLTransactionState::AcquireLock (runs in backend)
     107//         - this is the start state.
     108//         - acquire the "lock".
     109//         - on "lock" acquisition, goto SQLTransactionState::OpenTransactionAndPreflight.
     110//
     111//     3. SQLTransactionState::openTransactionAndPreflight (runs in backend)
     112//         - Sets up an SQLiteTransaction.
     113//         - begin the SQLiteTransaction.
     114//         - call the SQLTransactionWrapper preflight if available.
     115//         - schedule script callback.
     116//         - on error, goto SQLTransactionState::DeliverTransactionErrorCallback.
     117//         - goto SQLTransactionState::DeliverTransactionCallback.
     118//
     119//     4. SQLTransactionState::DeliverTransactionCallback (runs in frontend)
     120//         - invoke the script function callback() if available.
     121//         - on error, goto SQLTransactionState::DeliverTransactionErrorCallback.
     122//         - goto SQLTransactionState::RunStatements.
     123//
     124//     5. SQLTransactionState::DeliverTransactionErrorCallback (runs in frontend)
     125//         - invoke the script function errorCallback if available.
     126//         - goto SQLTransactionState::CleanupAfterTransactionErrorCallback.
     127//
     128//     6. SQLTransactionState::RunStatements (runs in backend)
     129//         - while there are statements {
     130//             - run a statement.
     131//             - if statementCallback is available, goto SQLTransactionState::DeliverStatementCallback.
     132//             - on error,
     133//               goto SQLTransactionState::DeliverQuotaIncreaseCallback, or
     134//               goto SQLTransactionState::DeliverStatementCallback, or
     135//               goto SQLTransactionState::deliverTransactionErrorCallback.
     136//           }
     137//         - goto SQLTransactionState::PostflightAndCommit.
     138//
     139//     7. SQLTransactionState::DeliverStatementCallback (runs in frontend)
     140//         - invoke script statement callback (assume available).
     141//         - on error, goto SQLTransactionState::DeliverTransactionErrorCallback.
     142//         - goto SQLTransactionState::RunStatements.
     143//
     144//     8. SQLTransactionState::DeliverQuotaIncreaseCallback (runs in frontend)
     145//         - give client a chance to increase the quota.
     146//         - goto SQLTransactionState::RunStatements.
     147//
     148//     9. SQLTransactionState::PostflightAndCommit (runs in backend)
     149//         - call the SQLTransactionWrapper postflight if available.
     150//         - commit the SQLiteTansaction.
     151//         - on error, goto SQLTransactionState::DeliverTransactionErrorCallback.
     152//         - if successCallback is available, goto SQLTransactionState::DeliverSuccessCallback.
     153//           else goto SQLTransactionState::CleanupAndTerminate.
     154//
     155//     10. SQLTransactionState::DeliverSuccessCallback (runs in frontend)
     156//         - invoke the script function successCallback() if available.
     157//         - goto SQLTransactionState::CleanupAndTerminate.
     158//
     159//     11. SQLTransactionState::CleanupAndTerminate (runs in backend)
     160//         - stop and clear the SQLiteTransaction.
     161//         - release the "lock".
     162//         - goto SQLTransactionState::End.
     163//
     164//     12. SQLTransactionState::CleanupAfterTransactionErrorCallback (runs in backend)
     165//         - rollback the SQLiteTransaction.
     166//         - goto SQLTransactionState::CleanupAndTerminate.
     167//
     168// State transitions between SQLTransaction and SQLTransactionBackend
     169// ==================================================================
     170// As shown above, there are state transitions that crosses the boundary between
     171// the frontend and backend. For example,
     172//
     173//     OpenTransactionAndPreflight (state 3 in the backend)
     174//     transitions to DeliverTransactionCallback (state 8 in the frontend),
     175//     which in turn transitions to RunStatements (state 4 in the backend).
     176//
     177// This cross boundary transition is done by posting transition requests to the
     178// other side and letting the other side's state machine execute the state
     179// transition in the appropriate thread (i.e. the script thread for the frontend,
     180// and the database thread for the backend).
     181//
     182// Logically, the state transitions work as shown in the graph above. But
     183// physically, the transition mechanism uses the Idle state (both in the frontend
     184// and backend) as a waiting state for further activity. For example, taking a
     185// closer look at the 3 state transition example above, what actually happens
     186// is as follows:
     187//
     188//     Step 1:
     189//     ======
     190//     In the frontend thread:
     191//     - waiting quietly is Idle. Not doing any work.
     192//
     193//     In the backend:
     194//     - is in OpenTransactionAndPreflight, and doing its work.
     195//     - when done, it transits to the backend DeliverTransactionCallback.
     196//     - the backend DeliverTransactionCallback sends a request to the frontend
     197//       to transit to DeliverTransactionCallback, and then itself transits to
     198//       Idle.
     199//
     200//     Step 2:
     201//     ======
     202//     In the frontend thread:
     203//     - transits to DeliverTransactionCallback and does its work.
     204//     - when done, it transits to the frontend RunStatements.
     205//     - the frontend RunStatements sends a request to the backend to transit
     206//       to RunStatements, and then itself transits to Idle.
     207//
     208//     In the backend:
     209//     - waiting quietly in Idle.
     210//
     211//     Step 3:
     212//     ======
     213//     In the frontend thread:
     214//     - waiting quietly is Idle. Not doing any work.
     215//
     216//     In the backend:
     217//     - transits to RunStatements, and does its work.
     218//        ...
     219//
     220// So, when the frontend or backend are not active, they will park themselves in
     221// their Idle states. This means their m_nextState is set to Idle, but they never
     222// actually run the corresponding state function. Note: for both the frontend and
     223// backend, the state function for Idle is unreachableState().
     224//
     225// The states that send a request to their peer across the front/back boundary
     226// are implemented with just 2 functions: SQLTransaction::sendToBackendState()
     227// and SQLTransactionBackend::sendToFrontendState(). These state functions do
     228// nothing but sends a request to the other side to transit to the current
     229// state (indicated by m_nextState), and then transits itself to the Idle state
     230// to wait for further action.
     231
     232
     233// The Life-Cycle of a SQLTransaction i.e. Who's keeping the SQLTransactionAlive?
     234// =============================================================================
     235// The RefPtr chain goes something like this:
     236//
     237//     At birth (in DatabaseBackendAsync::runTransaction()):
     238//     ====================================================
     239//     DatabaseBackendAsync               // in Deque<RefPtr<SQLTransactionBackend> > m_transactionQueue points to ...
     240//     --> SQLTransactionBackend          // in RefPtr<SQLTransaction> m_frontend points to ...
     241//         --> SQLTransaction             // in RefPtr<SQLTransactionBackend> m_backend points to ...
     242//             --> SQLTransactionBackend  // which is a circular reference.
     243//
     244//     Note: there's a circular reference between the SQLTransaction front-end and
     245//     back-end. This circular reference is established in the constructor of the
     246//     SQLTransactionBackend. The circular reference will only be broken at the end
     247//     of the transaction's clean up state i.e. when the transaction should no
     248//     longer be in use thereafter.
     249//
     250//     After scheduling the transaction with the DatabaseThread (DatabaseBackendAsync::scheduleTransaction()):
     251//     ======================================================================================================
     252//     DatabaseThread                         // in MessageQueue<DatabaseTask> m_queue points to ...
     253//     --> DatabaseTransactionTask            // in RefPtr<SQLTransactionBackend> m_transaction points to ...
     254//         --> SQLTransactionBackend          // in RefPtr<SQLTransaction> m_frontend points to ...
     255//             --> SQLTransaction             // in RefPtr<SQLTransactionBackend> m_backend points to ...
     256//                 --> SQLTransactionBackend  // which is a circular reference.
     257//
     258//     When executing the transaction (in DatabaseThread::databaseThread()):
     259//     ====================================================================
     260//     OwnPtr<DatabaseTask> task;             // points to ...
     261//     --> DatabaseTransactionTask            // in RefPtr<SQLTransactionBackend> m_transaction points to ...
     262//         --> SQLTransactionBackend          // in: RefPtr<SQLTransaction> m_frontend;
     263//             --> SQLTransaction             // in RefPtr<SQLTransactionBackend> m_backend points to ...
     264//                 --> SQLTransactionBackend  // which is a circular reference.
     265//
     266//     At the end of cleanupAndTerminate():
     267//     ===================================
     268//     At the end of the cleanup state, the SQLTransactionBackend::m_frontend is nullified.
     269//     If by then, a JSObject wrapper is referring to the SQLTransaction, then the reference
     270//     chain looks like this:
     271//
     272//     JSObjectWrapper
     273//     --> SQLTransaction             // in RefPtr<SQLTransactionBackend> m_backend points to ...
     274//         --> SQLTransactionBackend  // which no longer points back to its SQLTransaction.
     275//
     276//     When the GC collects the corresponding JSObject, the above chain will be cleaned up
     277//     and deleted.
     278//
     279//     If there is no JSObject wrapper referring to the SQLTransaction when the cleanup
     280//     states nullify SQLTransactionBackend::m_frontend, the SQLTransaction will deleted then.
     281//     However, there will still be a DatabaseTask pointing to the SQLTransactionBackend (see
     282//     the "When executing the transaction" chain above). This will keep the
     283//     SQLTransactionBackend alive until DatabaseThread::databaseThread() releases its
     284//     task OwnPtr.
     285//
     286//     What happens if a transaction is interrupted?
     287//     ============================================
     288//     If the transaction is interrupted half way, it won't get to run to state
     289//     CleanupAndTerminate, and hence, would not have called doCleanup(). doCleanup() is
     290//     where we nullify SQLTransactionBackend::m_frontend to break the reference cycle
     291//     between the frontend and backend. Hence, that transaction will never get cleaned
     292//     up, unless ...
     293//
     294//     ... unless we have a cleanup mechanism for interruptions. That is, during the
     295//     shutdown of the DatabaseThread, the SQLTransactionCoordinator will discover this
     296//     interrupted transaction and invoke its notifyDatabaseThreadIsShuttingDown(),
     297//     which in turn will call doCleanup(). With that, all is well again.
    171298
    172299
     
    178305namespace WebCore {
    179306
    180 SQLTransactionBackend::SQLTransactionBackend(Database* db, PassRefPtr<SQLTransactionCallback> callback,
    181     PassRefPtr<SQLTransactionErrorCallback> errorCallback, PassRefPtr<VoidCallback> successCallback,
    182     PassRefPtr<SQLTransactionWrapper> wrapper, bool readOnly)
    183     : m_nextStep(&SQLTransactionBackend::acquireLock)
    184     , m_executeSqlAllowed(false)
     307PassRefPtr<SQLTransactionBackend> SQLTransactionBackend::create(DatabaseBackendAsync* db,
     308    PassRefPtr<SQLTransaction> frontend, PassRefPtr<SQLTransactionWrapper> wrapper, bool readOnly)
     309{
     310    return adoptRef(new SQLTransactionBackend(db, frontend, wrapper, readOnly));
     311}
     312
     313SQLTransactionBackend::SQLTransactionBackend(DatabaseBackendAsync* db,
     314    PassRefPtr<SQLTransaction> frontend, PassRefPtr<SQLTransactionWrapper> wrapper, bool readOnly)
     315    : m_frontend(frontend)
    185316    , m_database(db)
    186317    , m_wrapper(wrapper)
    187     , m_callbackWrapper(callback, db->scriptExecutionContext())
    188     , m_successCallbackWrapper(successCallback, db->scriptExecutionContext())
    189     , m_errorCallbackWrapper(errorCallback, db->scriptExecutionContext())
     318    , m_hasCallback(m_frontend->hasCallback())
     319    , m_hasSuccessCallback(m_frontend->hasSuccessCallback())
     320    , m_hasErrorCallback(m_frontend->hasErrorCallback())
    190321    , m_shouldRetryCurrentStatement(false)
    191322    , m_modifiedDatabase(false)
     
    195326{
    196327    ASSERT(m_database);
     328    m_frontend->setBackend(this);
     329    m_requestedState = SQLTransactionState::AcquireLock;
    197330}
    198331
     
    202335}
    203336
    204 void SQLTransactionBackend::executeSQL(const String& sqlStatement, const Vector<SQLValue>& arguments, PassRefPtr<SQLStatementCallback> callback, PassRefPtr<SQLStatementErrorCallback> callbackError, ExceptionCode& e)
    205 {
    206     if (!m_executeSqlAllowed || !m_database->opened()) {
    207         e = INVALID_STATE_ERR;
    208         return;
    209     }
    210 
    211     int permissions = DatabaseAuthorizer::ReadWriteMask;
    212     if (!m_database->databaseContext()->allowDatabaseAccess())
    213         permissions |= DatabaseAuthorizer::NoAccessMask;
    214     else if (m_readOnly)
    215         permissions |= DatabaseAuthorizer::ReadOnlyMask;
    216 
    217     RefPtr<SQLStatement> statement = SQLStatement::create(m_database.get(), sqlStatement, arguments, callback, callbackError, permissions);
    218 
    219     if (m_database->deleted())
    220         statement->setDatabaseDeletedError(m_database.get());
    221 
    222     enqueueStatement(statement);
     337void SQLTransactionBackend::doCleanup()
     338{
     339    ASSERT(currentThread() == database()->databaseContext()->databaseThread()->getThreadID());
     340
     341    MutexLocker locker(m_statementMutex);
     342    m_statementQueue.clear();
     343
     344    if (m_sqliteTransaction) {
     345        // In the event we got here because of an interruption or error (i.e. if
     346        // the transaction is in progress), we should roll it back here. Clearing
     347        // m_sqliteTransaction invokes SQLiteTransaction's destructor which does
     348        // just that. We might as well do this unconditionally and free up its
     349        // resources because we're already terminating.
     350        m_sqliteTransaction.clear();
     351    }
     352
     353    // Release the lock on this database
     354    if (m_lockAcquired)
     355        m_database->transactionCoordinator()->releaseLock(this);
     356
     357    // Now that we're done, break the reference cycle that keeps us alive.
     358    // See comment about the life-cycle above.
     359    m_frontend = 0;
     360
     361    // Do some aggresive clean up here except for m_database.
     362    //
     363    // We can't clear m_database here because the frontend may asynchronously
     364    // invoke SQLTransactionBackend::requestTransitToState(), and that function
     365    // uses m_database to schedule a state transition. This may occur because
     366    // the frontend (being in another thread) may already be on the way to
     367    // requesting our next state before it detects an interruption.
     368    //
     369    // There is no harm in letting it finish making the request. It'll set
     370    // m_requestedState, but we won't execute a transition to that state because
     371    // we've already shut down the transaction.
     372
     373    m_currentStatement = 0;
     374    m_wrapper = 0;
     375    m_transactionError = 0;
     376}
     377
     378PassRefPtr<SQLError> SQLTransactionBackend::transactionError()
     379{
     380    return m_transactionError;
     381}
     382
     383void SQLTransactionBackend::setShouldRetryCurrentStatement(bool shouldRetry)
     384{
     385    ASSERT(!m_shouldRetryCurrentStatement);
     386    m_shouldRetryCurrentStatement = shouldRetry;
     387}
     388
     389SQLTransactionBackend::StateFunction SQLTransactionBackend::stateFunctionFor(SQLTransactionState state)
     390{
     391    static const StateFunction stateFunctions[] = {
     392        &SQLTransactionBackend::unreachableState,            // 0. end
     393        &SQLTransactionBackend::unreachableState,            // 1. idle
     394        &SQLTransactionBackend::acquireLock,                 // 2.
     395        &SQLTransactionBackend::openTransactionAndPreflight, // 3.
     396        &SQLTransactionBackend::runStatements,               // 4.
     397        &SQLTransactionBackend::postflightAndCommit,         // 5.
     398        &SQLTransactionBackend::cleanupAndTerminate,         // 6.
     399        &SQLTransactionBackend::cleanupAfterTransactionErrorCallback, // 7.
     400        &SQLTransactionBackend::sendToFrontendState,         // 8. deliverTransactionCallback
     401        &SQLTransactionBackend::sendToFrontendState,         // 9. deliverTransactionErrorCallback
     402        &SQLTransactionBackend::sendToFrontendState,         // 10. deliverStatementCallback
     403        &SQLTransactionBackend::sendToFrontendState,         // 11. deliverQuotaIncreaseCallback
     404        &SQLTransactionBackend::sendToFrontendState          // 12. deliverSuccessCallback
     405    };
     406
     407    ASSERT(WTF_ARRAY_LENGTH(stateFunctions) == static_cast<int>(SQLTransactionState::NumberOfStates));
     408    ASSERT(state < SQLTransactionState::NumberOfStates);
     409
     410    return stateFunctions[static_cast<int>(state)];
    223411}
    224412
     
    229417}
    230418
    231 #if !LOG_DISABLED
    232 const char* SQLTransactionBackend::debugStepName(SQLTransactionBackend::TransactionStepMethod step)
    233 {
    234     if (step == &SQLTransactionBackend::acquireLock)
    235         return "acquireLock";
    236     if (step == &SQLTransactionBackend::openTransactionAndPreflight)
    237         return "openTransactionAndPreflight";
    238     if (step == &SQLTransactionBackend::runStatements)
    239         return "runStatements";
    240     if (step == &SQLTransactionBackend::postflightAndCommit)
    241         return "postflightAndCommit";
    242     if (step == &SQLTransactionBackend::cleanupAfterTransactionErrorCallback)
    243         return "cleanupAfterTransactionErrorCallback";
    244     if (step == &SQLTransactionBackend::deliverTransactionCallback)
    245         return "deliverTransactionCallback";
    246     if (step == &SQLTransactionBackend::deliverTransactionErrorCallback)
    247         return "deliverTransactionErrorCallback";
    248     if (step == &SQLTransactionBackend::deliverStatementCallback)
    249         return "deliverStatementCallback";
    250     if (step == &SQLTransactionBackend::deliverQuotaIncreaseCallback)
    251         return "deliverQuotaIncreaseCallback";
    252     if (step == &SQLTransactionBackend::deliverSuccessCallback)
    253         return "deliverSuccessCallback";
    254     if (step == &SQLTransactionBackend::cleanupAfterSuccessCallback)
    255         return "cleanupAfterSuccessCallback";
    256     return "UNKNOWN";
    257 }
    258 #endif
    259 
    260419void SQLTransactionBackend::checkAndHandleClosedOrInterruptedDatabase()
    261420{
     
    265424    // If the database was stopped, don't do anything and cancel queued work
    266425    LOG(StorageAPI, "Database was stopped or interrupted - cancelling work for this transaction");
    267     MutexLocker locker(m_statementMutex);
    268     m_statementQueue.clear();
    269     m_nextStep = 0;
    270 
    271     // Release the unneeded callbacks, to break reference cycles.
    272     m_callbackWrapper.clear();
    273     m_successCallbackWrapper.clear();
    274     m_errorCallbackWrapper.clear();
    275 
    276     // The next steps should be executed only if we're on the DB thread.
    277     if (currentThread() != database()->databaseContext()->databaseThread()->getThreadID())
    278         return;
    279426
    280427    // The current SQLite transaction should be stopped, as well
     
    284431    }
    285432
    286     if (m_lockAcquired)
    287         m_database->transactionCoordinator()->releaseLock(this);
    288 }
    289 
    290 
    291 bool SQLTransactionBackend::performNextStep()
    292 {
    293     LOG(StorageAPI, "Step %s\n", debugStepName(m_nextStep));
    294 
    295     ASSERT(m_nextStep == &SQLTransactionBackend::acquireLock
    296         || m_nextStep == &SQLTransactionBackend::openTransactionAndPreflight
    297         || m_nextStep == &SQLTransactionBackend::runStatements
    298         || m_nextStep == &SQLTransactionBackend::postflightAndCommit
    299         || m_nextStep == &SQLTransactionBackend::cleanupAfterSuccessCallback
    300         || m_nextStep == &SQLTransactionBackend::cleanupAfterTransactionErrorCallback);
     433    // Terminate the frontend state machine. This also gets the frontend to
     434    // call checkAndHandleClosedOrInterruptedDatabase() and clear its wrappers
     435    // if needed.
     436    m_frontend->requestTransitToState(SQLTransactionState::End);
     437
     438    // Redirect to the end state to abort, clean up, and end the transaction.
     439    doCleanup();
     440    m_nextState = SQLTransactionState::End;
     441}
     442
     443void SQLTransactionBackend::performNextStep()
     444{
     445    LOG(StorageAPI, "State %s\n", nameForSQLTransactionState(m_nextState));
     446
     447    setStateToRequestedState();
     448    ASSERT(m_nextState == SQLTransactionState::AcquireLock
     449        || m_nextState == SQLTransactionState::OpenTransactionAndPreflight
     450        || m_nextState == SQLTransactionState::RunStatements
     451        || m_nextState == SQLTransactionState::PostflightAndCommit
     452        || m_nextState == SQLTransactionState::CleanupAndTerminate
     453        || m_nextState == SQLTransactionState::CleanupAfterTransactionErrorCallback);
    301454
    302455    checkAndHandleClosedOrInterruptedDatabase();
    303 
    304     if (m_nextStep)
    305         (this->*m_nextStep)();
    306 
    307     // If there is no nextStep after performing the above step, the transaction is complete
    308     return !m_nextStep;
    309 }
    310 
    311 void SQLTransactionBackend::performPendingCallback()
    312 {
    313     LOG(StorageAPI, "Callback %s\n", debugStepName(m_nextStep));
    314 
    315     ASSERT(m_nextStep == &SQLTransactionBackend::deliverTransactionCallback
    316         || m_nextStep == &SQLTransactionBackend::deliverTransactionErrorCallback
    317         || m_nextStep == &SQLTransactionBackend::deliverStatementCallback
    318         || m_nextStep == &SQLTransactionBackend::deliverQuotaIncreaseCallback
    319         || m_nextStep == &SQLTransactionBackend::deliverSuccessCallback);
    320 
    321     checkAndHandleClosedOrInterruptedDatabase();
    322 
    323     if (m_nextStep)
    324         (this->*m_nextStep)();
     456    runStateMachine();
    325457}
    326458
     
    329461    ASSERT(currentThread() == database()->databaseContext()->databaseThread()->getThreadID());
    330462
    331     // If the transaction is in progress, we should roll it back here, since this is our last
    332     // oportunity to do something related to this transaction on the DB thread.
    333     // Clearing m_sqliteTransaction invokes SQLiteTransaction's destructor which does just that.
    334     m_sqliteTransaction.clear();
    335 }
    336 
    337 void SQLTransactionBackend::acquireLock()
     463    // If the transaction is in progress, we should roll it back here, since this
     464    // is our last opportunity to do something related to this transaction on the
     465    // DB thread. Amongst other work, doCleanup() will clear m_sqliteTransaction
     466    // which invokes SQLiteTransaction's destructor, which will do the roll back
     467    // if necessary.
     468
     469    // Note: if doCleanup() has already been invoked, then m_frontend would have
     470    // been nullified.
     471    if (m_frontend)
     472        doCleanup();
     473}
     474
     475SQLTransactionState SQLTransactionBackend::acquireLock()
    338476{
    339477    m_database->transactionCoordinator()->acquireLock(this);
     478    return SQLTransactionState::Idle;
    340479}
    341480
     
    343482{
    344483    m_lockAcquired = true;
    345     m_nextStep = &SQLTransactionBackend::openTransactionAndPreflight;
    346     LOG(StorageAPI, "Scheduling openTransactionAndPreflight immediately for transaction %p\n", this);
    347     m_database->scheduleTransactionStep(this, true);
    348 }
    349 
    350 void SQLTransactionBackend::openTransactionAndPreflight()
     484    requestTransitToState(SQLTransactionState::OpenTransactionAndPreflight);
     485}
     486
     487SQLTransactionState SQLTransactionBackend::openTransactionAndPreflight()
    351488{
    352489    ASSERT(!m_database->sqliteDatabase().transactionInProgress());
     
    356493
    357494    // If the database was deleted, jump to the error callback
    358     if (m_database->deleted()) {
     495    if (Database::from(m_database.get())->deleted()) {
    359496        m_database->reportStartTransactionResult(1, SQLError::UNKNOWN_ERR, 0);
    360497        m_transactionError = SQLError::create(SQLError::UNKNOWN_ERR, "unable to open a transaction, because the user deleted the database");
    361         handleTransactionError(false);
    362         return;
     498        return nextStateForTransactionError();
    363499    }
    364500
     
    375511    m_database->enableAuthorizer();
    376512
    377     // Transaction Steps 1+2 - Open a transaction to the database, jumping to the error callback if that fails
     513    // Spec 4.3.2.1+2: Open a transaction to the database, jumping to the error callback if that fails
    378514    if (!m_sqliteTransaction->inProgress()) {
    379515        ASSERT(!m_database->sqliteDatabase().transactionInProgress());
     
    382518            m_database->sqliteDatabase().lastError(), m_database->sqliteDatabase().lastErrorMsg());
    383519        m_sqliteTransaction.clear();
    384         handleTransactionError(false);
    385         return;
     520        return nextStateForTransactionError();
    386521    }
    387522
     
    397532        m_sqliteTransaction.clear();
    398533        m_database->enableAuthorizer();
    399         handleTransactionError(false);
    400         return;
     534        return nextStateForTransactionError();
    401535    }
    402536    m_hasVersionMismatch = !m_database->expectedVersion().isEmpty() && (m_database->expectedVersion() != actualVersion);
    403537
    404     // Transaction Steps 3 - Peform preflight steps, jumping to the error callback if they fail
    405     if (m_wrapper && !m_wrapper->performPreflight(SQLTransaction::from(this))) {
     538    // Spec 4.3.2.3: Perform preflight steps, jumping to the error callback if they fail
     539    if (m_wrapper && !m_wrapper->performPreflight(this)) {
    406540        m_database->disableAuthorizer();
    407541        m_sqliteTransaction.clear();
     
    412546            m_transactionError = SQLError::create(SQLError::UNKNOWN_ERR, "unknown error occurred during transaction preflight");
    413547        }
    414         handleTransactionError(false);
    415         return;
    416     }
    417 
    418     // Transaction Step 4 - Invoke the transaction callback with the new SQLTransaction object
    419     m_nextStep = &SQLTransactionBackend::deliverTransactionCallback;
    420     LOG(StorageAPI, "Scheduling deliverTransactionCallback for transaction %p\n", this);
    421     m_database->scheduleTransactionCallback(SQLTransaction::from(this));
    422 }
    423 
    424 void SQLTransactionBackend::deliverTransactionCallback()
    425 {
    426     bool shouldDeliverErrorCallback = false;
    427 
    428     RefPtr<SQLTransactionCallback> callback = m_callbackWrapper.unwrap();
    429     if (callback) {
    430         m_executeSqlAllowed = true;
    431         shouldDeliverErrorCallback = !callback->handleEvent(SQLTransaction::from(this));
    432         m_executeSqlAllowed = false;
    433     }
    434 
    435     // Transaction Step 5 - If the transaction callback was null or raised an exception, jump to the error callback
    436     if (shouldDeliverErrorCallback) {
    437         m_database->reportStartTransactionResult(5, SQLError::UNKNOWN_ERR, 0);
    438         m_transactionError = SQLError::create(SQLError::UNKNOWN_ERR, "the SQLTransactionCallback was null or threw an exception");
    439         deliverTransactionErrorCallback();
    440     } else
    441         scheduleToRunStatements();
    442 
    443     m_database->reportStartTransactionResult(0, -1, 0); // OK
    444 }
    445 
    446 void SQLTransactionBackend::scheduleToRunStatements()
    447 {
    448     m_nextStep = &SQLTransactionBackend::runStatements;
    449     LOG(StorageAPI, "Scheduling runStatements for transaction %p\n", this);
    450     m_database->scheduleTransactionStep(this);
    451 }
    452 
    453 void SQLTransactionBackend::runStatements()
     548        return nextStateForTransactionError();
     549    }
     550
     551    // Spec 4.3.2.4: Invoke the transaction callback with the new SQLTransaction object
     552    if (m_hasCallback)
     553        return SQLTransactionState::DeliverTransactionCallback;
     554
     555    // If we have no callback to make, skip pass to the state after:
     556    return SQLTransactionState::RunStatements;
     557}
     558
     559SQLTransactionState SQLTransactionBackend::runStatements()
    454560{
    455561    ASSERT(m_lockAcquired);
     562    SQLTransactionState nextState;
    456563
    457564    // If there is a series of statements queued up that are all successful and have no associated
     
    472579            // that means it ended in an error. Handle it now
    473580            if (m_currentStatement && m_currentStatement->lastExecutionFailedDueToQuota()) {
    474                 handleCurrentStatementError();
    475                 break;
     581                return nextStateForCurrentStatementError();
    476582            }
    477583
     
    479585            getNextStatement();
    480586        }
    481     } while (runCurrentStatement());
    482 
    483     // If runCurrentStatement() returned false, that means either there was no current statement to run,
    484     // or the current statement requires a callback to complete. In the later case, it also scheduled
    485     // the callback or performed any other additional work so we can return
    486     if (!m_currentStatement)
    487         postflightAndCommit();
     587        nextState = runCurrentStatementAndGetNextState();
     588    } while (nextState == SQLTransactionState::RunStatements);
     589
     590    return nextState;
    488591}
    489592
     
    497600}
    498601
    499 bool SQLTransactionBackend::runCurrentStatement()
    500 {
    501     if (!m_currentStatement)
    502         return false;
     602SQLTransactionState SQLTransactionBackend::runCurrentStatementAndGetNextState()
     603{
     604    if (!m_currentStatement) {
     605        // No more statements to run. So move on to the next state.
     606        return SQLTransactionState::PostflightAndCommit;
     607    }
    503608
    504609    m_database->resetAuthorizer();
    505610
    506611    if (m_hasVersionMismatch)
    507         m_currentStatement->setVersionMismatchedError(m_database.get());
    508 
    509     if (m_currentStatement->execute(m_database.get())) {
     612        m_currentStatement->setVersionMismatchedError(Database::from(m_database.get()));
     613
     614    if (m_currentStatement->execute(Database::from(m_database.get()))) {
    510615        if (m_database->lastActionChangedDatabase()) {
    511616            // Flag this transaction as having changed the database for later delegate notification
    512617            m_modifiedDatabase = true;
    513618            // Also dirty the size of this database file for calculating quota usage
    514             m_database->transactionClient()->didExecuteStatement(database());
     619            m_database->transactionClient()->didExecuteStatement(Database::from(database()));
    515620        }
    516621
    517622        if (m_currentStatement->hasStatementCallback()) {
    518             m_nextStep = &SQLTransactionBackend::deliverStatementCallback;
    519             LOG(StorageAPI, "Scheduling deliverStatementCallback for transaction %p\n", this);
    520             m_database->scheduleTransactionCallback(SQLTransaction::from(this));
    521             return false;
     623            return SQLTransactionState::DeliverStatementCallback;
    522624        }
    523         return true;
     625
     626        // If we get here, then the statement doesn't have a callback to invoke.
     627        // We can move on to the next statement. Hence, stay in this state.
     628        return SQLTransactionState::RunStatements;
    524629    }
    525630
    526631    if (m_currentStatement->lastExecutionFailedDueToQuota()) {
    527         m_nextStep = &SQLTransactionBackend::deliverQuotaIncreaseCallback;
    528         LOG(StorageAPI, "Scheduling deliverQuotaIncreaseCallback for transaction %p\n", this);
    529         m_database->scheduleTransactionCallback(SQLTransaction::from(this));
    530         return false;
    531     }
    532 
    533     handleCurrentStatementError();
    534 
    535     return false;
    536 }
    537 
    538 void SQLTransactionBackend::handleCurrentStatementError()
    539 {
    540     // Transaction Steps 6.error - Call the statement's error callback, but if there was no error callback,
     632        return SQLTransactionState::DeliverQuotaIncreaseCallback;
     633    }
     634
     635    return nextStateForCurrentStatementError();
     636}
     637
     638SQLTransactionState SQLTransactionBackend::nextStateForCurrentStatementError()
     639{
     640    // Spec 4.3.2.6.6: error - Call the statement's error callback, but if there was no error callback,
    541641    // or the transaction was rolled back, jump to the transaction error callback
    542     if (m_currentStatement->hasStatementErrorCallback() && !m_sqliteTransaction->wasRolledBackBySqlite()) {
    543         m_nextStep = &SQLTransactionBackend::deliverStatementCallback;
    544         LOG(StorageAPI, "Scheduling deliverStatementCallback for transaction %p\n", this);
    545         m_database->scheduleTransactionCallback(SQLTransaction::from(this));
    546     } else {
    547         m_transactionError = m_currentStatement->sqlError();
    548         if (!m_transactionError) {
    549             m_database->reportCommitTransactionResult(1, SQLError::DATABASE_ERR, 0);
    550             m_transactionError = SQLError::create(SQLError::DATABASE_ERR, "the statement failed to execute");
    551         }
    552         handleTransactionError(false);
    553     }
    554 }
    555 
    556 void SQLTransactionBackend::deliverStatementCallback()
    557 {
    558     ASSERT(m_currentStatement);
    559 
    560     // Transaction Step 6.6 and 6.3(error) - If the statement callback went wrong, jump to the transaction error callback
    561     // Otherwise, continue to loop through the statement queue
    562     m_executeSqlAllowed = true;
    563     bool result = m_currentStatement->performCallback(SQLTransaction::from(this));
    564     m_executeSqlAllowed = false;
    565 
    566     if (result) {
    567         m_database->reportCommitTransactionResult(2, SQLError::UNKNOWN_ERR, 0);
    568         m_transactionError = SQLError::create(SQLError::UNKNOWN_ERR, "the statement callback raised an exception or statement error callback did not return false");
    569         handleTransactionError(true);
    570     } else
    571         scheduleToRunStatements();
    572 }
    573 
    574 void SQLTransactionBackend::deliverQuotaIncreaseCallback()
    575 {
    576     ASSERT(m_currentStatement);
    577     ASSERT(!m_shouldRetryCurrentStatement);
    578 
    579     m_shouldRetryCurrentStatement = m_database->transactionClient()->didExceedQuota(database());
    580 
    581     m_nextStep = &SQLTransactionBackend::runStatements;
    582     LOG(StorageAPI, "Scheduling runStatements for transaction %p\n", this);
    583     m_database->scheduleTransactionStep(this);
    584 }
    585 
    586 void SQLTransactionBackend::postflightAndCommit()
     642    if (m_currentStatement->hasStatementErrorCallback() && !m_sqliteTransaction->wasRolledBackBySqlite())
     643        return SQLTransactionState::DeliverStatementCallback;
     644
     645    m_transactionError = m_currentStatement->sqlError();
     646    if (!m_transactionError) {
     647        m_database->reportCommitTransactionResult(1, SQLError::DATABASE_ERR, 0);
     648        m_transactionError = SQLError::create(SQLError::DATABASE_ERR, "the statement failed to execute");
     649    }
     650    return nextStateForTransactionError();
     651}
     652
     653SQLTransactionState SQLTransactionBackend::postflightAndCommit()
    587654{
    588655    ASSERT(m_lockAcquired);
    589656
    590     // Transaction Step 7 - Peform postflight steps, jumping to the error callback if they fail
    591     if (m_wrapper && !m_wrapper->performPostflight(SQLTransaction::from(this))) {
     657    // Spec 4.3.2.7: Perform postflight steps, jumping to the error callback if they fail.
     658    if (m_wrapper && !m_wrapper->performPostflight(this)) {
    592659        m_transactionError = m_wrapper->sqlError();
    593660        if (!m_transactionError) {
     
    595662            m_transactionError = SQLError::create(SQLError::UNKNOWN_ERR, "unknown error occurred during transaction postflight");
    596663        }
    597         handleTransactionError(false);
    598         return;
    599     }
    600 
    601     // Transacton Step 8+9 - Commit the transaction, jumping to the error callback if that fails
     664        return nextStateForTransactionError();
     665    }
     666
     667    // Spec 4.3.2.7: Commit the transaction, jumping to the error callback if that fails.
    602668    ASSERT(m_sqliteTransaction);
    603669
     
    609675    if (m_sqliteTransaction->inProgress()) {
    610676        if (m_wrapper)
    611             m_wrapper->handleCommitFailedAfterPostflight(SQLTransaction::from(this));
    612         m_successCallbackWrapper.clear();
     677            m_wrapper->handleCommitFailedAfterPostflight(this);
    613678        m_database->reportCommitTransactionResult(4, SQLError::DATABASE_ERR, m_database->sqliteDatabase().lastError());
    614679        m_transactionError = SQLError::create(SQLError::DATABASE_ERR, "unable to commit transaction",
    615680            m_database->sqliteDatabase().lastError(), m_database->sqliteDatabase().lastErrorMsg());
    616         handleTransactionError(false);
    617         return;
     681        return nextStateForTransactionError();
    618682    }
    619683
     
    628692        m_database->transactionClient()->didCommitWriteTransaction(database());
    629693
    630     // Now release our unneeded callbacks, to break reference cycles.
    631     m_errorCallbackWrapper.clear();
    632 
    633     // Transaction Step 10 - Deliver success callback, if there is one
    634     if (m_successCallbackWrapper.hasCallback()) {
    635         m_nextStep = &SQLTransactionBackend::deliverSuccessCallback;
    636         LOG(StorageAPI, "Scheduling deliverSuccessCallback for transaction %p\n", this);
    637         m_database->scheduleTransactionCallback(SQLTransaction::from(this));
    638     } else
    639         cleanupAfterSuccessCallback();
    640 }
    641 
    642 void SQLTransactionBackend::deliverSuccessCallback()
    643 {
    644     // Transaction Step 10 - Deliver success callback
    645     RefPtr<VoidCallback> successCallback = m_successCallbackWrapper.unwrap();
    646     if (successCallback)
    647         successCallback->handleEvent();
    648 
    649     // Schedule a "post-success callback" step to return control to the database thread in case there
    650     // are further transactions queued up for this Database
    651     m_nextStep = &SQLTransactionBackend::cleanupAfterSuccessCallback;
    652     LOG(StorageAPI, "Scheduling cleanupAfterSuccessCallback for transaction %p\n", this);
    653     m_database->scheduleTransactionStep(this);
    654 }
    655 
    656 void SQLTransactionBackend::cleanupAfterSuccessCallback()
     694    // Spec 4.3.2.8: Deliver success callback, if there is one.
     695    return SQLTransactionState::DeliverSuccessCallback;
     696}
     697
     698SQLTransactionState SQLTransactionBackend::cleanupAndTerminate()
    657699{
    658700    ASSERT(m_lockAcquired);
    659701
    660     // Transaction Step 11 - End transaction steps
    661     // There is no next step
     702    // Spec 4.3.2.9: End transaction steps. There is no next step.
    662703    LOG(StorageAPI, "Transaction %p is complete\n", this);
    663704    ASSERT(!m_database->sqliteDatabase().transactionInProgress());
    664     m_sqliteTransaction.clear();
    665     m_nextStep = 0;
    666 
    667     // Release the lock on this database
    668     m_database->transactionCoordinator()->releaseLock(this);
    669 }
    670 
    671 void SQLTransactionBackend::handleTransactionError(bool inCallback)
    672 {
    673     if (m_errorCallbackWrapper.hasCallback()) {
    674         if (inCallback)
    675             deliverTransactionErrorCallback();
    676         else {
    677             m_nextStep = &SQLTransactionBackend::deliverTransactionErrorCallback;
    678             LOG(StorageAPI, "Scheduling deliverTransactionErrorCallback for transaction %p\n", this);
    679             m_database->scheduleTransactionCallback(SQLTransaction::from(this));
    680         }
    681         return;
    682     }
    683 
    684     // No error callback, so fast-forward to:
    685     // Transaction Step 12 - Rollback the transaction.
    686     if (inCallback) {
    687         m_nextStep = &SQLTransactionBackend::cleanupAfterTransactionErrorCallback;
    688         LOG(StorageAPI, "Scheduling cleanupAfterTransactionErrorCallback for transaction %p\n", this);
    689         m_database->scheduleTransactionStep(this);
    690     } else
    691         cleanupAfterTransactionErrorCallback();
    692 }
    693 
    694 void SQLTransactionBackend::deliverTransactionErrorCallback()
     705
     706    doCleanup();
     707    m_database->inProgressTransactionCompleted();
     708    return SQLTransactionState::End;
     709}
     710
     711SQLTransactionState SQLTransactionBackend::nextStateForTransactionError()
    695712{
    696713    ASSERT(m_transactionError);
    697 
    698     // Transaction Step 12 - If exists, invoke error callback with the last
    699     // error to have occurred in this transaction.
    700     RefPtr<SQLTransactionErrorCallback> errorCallback = m_errorCallbackWrapper.unwrap();
    701     if (errorCallback)
    702         errorCallback->handleEvent(m_transactionError.get());
    703 
    704     m_nextStep = &SQLTransactionBackend::cleanupAfterTransactionErrorCallback;
    705     LOG(StorageAPI, "Scheduling cleanupAfterTransactionErrorCallback for transaction %p\n", this);
    706     m_database->scheduleTransactionStep(this);
    707 }
    708 
    709 void SQLTransactionBackend::cleanupAfterTransactionErrorCallback()
     714    if (m_hasErrorCallback)
     715        return SQLTransactionState::DeliverTransactionErrorCallback;
     716
     717    // No error callback, so fast-forward to the next state and rollback the
     718    // transaction.
     719    return SQLTransactionState::CleanupAfterTransactionErrorCallback;
     720}
     721
     722SQLTransactionState SQLTransactionBackend::cleanupAfterTransactionErrorCallback()
    710723{
    711724    ASSERT(m_lockAcquired);
    712725
     726    LOG(StorageAPI, "Transaction %p is complete with an error\n", this);
    713727    m_database->disableAuthorizer();
    714728    if (m_sqliteTransaction) {
    715         // Transaction Step 12 - Rollback the transaction.
     729        // Spec 4.3.2.10: Rollback the transaction.
    716730        m_sqliteTransaction->rollback();
    717731
     
    721735    m_database->enableAuthorizer();
    722736
    723     // Transaction Step 12 - Any still-pending statements in the transaction are discarded.
    724     {
    725         MutexLocker locker(m_statementMutex);
    726         m_statementQueue.clear();
    727     }
    728 
    729     // Transaction is complete! There is no next step
    730     LOG(StorageAPI, "Transaction %p is complete with an error\n", this);
    731737    ASSERT(!m_database->sqliteDatabase().transactionInProgress());
    732     m_nextStep = 0;
    733 
    734     // Now release the lock on this database
    735     m_database->transactionCoordinator()->releaseLock(this);
     738
     739    return SQLTransactionState::CleanupAndTerminate;
     740}
     741
     742// requestTransitToState() can be called from the frontend. Hence, it should
     743// NOT be modifying SQLTransactionBackend in general. The only safe field to
     744// modify is m_requestedState which is meant for this purpose.
     745void SQLTransactionBackend::requestTransitToState(SQLTransactionState nextState)
     746{
     747    LOG(StorageAPI, "Scheduling %s for transaction %p\n", nameForSQLTransactionState(nextState), this);
     748    m_requestedState = nextState;
     749    ASSERT(m_requestedState != SQLTransactionState::End);
     750    m_database->scheduleTransactionStep(this);
     751}
     752
     753// This state function is used as a stub function to plug unimplemented states
     754// in the state dispatch table. They are unimplemented because they should
     755// never be reached in the course of correct execution.
     756SQLTransactionState SQLTransactionBackend::unreachableState()
     757{
     758    ASSERT_NOT_REACHED();
     759    return SQLTransactionState::End;
     760}
     761
     762SQLTransactionState SQLTransactionBackend::sendToFrontendState()
     763{
     764    ASSERT(m_nextState != SQLTransactionState::Idle);
     765    m_frontend->requestTransitToState(m_nextState);
     766    return SQLTransactionState::Idle;
    736767}
    737768
  • trunk/Source/WebCore/Modules/webdatabase/SQLTransactionBackend.h

    r142193 r142921  
    3333#include "DatabaseBasicTypes.h"
    3434#include "SQLStatement.h"
     35#include "SQLTransactionStateMachine.h"
    3536#include <wtf/Deque.h>
    3637#include <wtf/Forward.h>
    37 #include <wtf/ThreadSafeRefCounted.h>
    38 #include <wtf/Vector.h>
    3938
    4039namespace WebCore {
    4140
    42 class Database;
     41class DatabaseBackendAsync;
    4342class SQLError;
    4443class SQLiteTransaction;
    45 class SQLStatementCallback;
    46 class SQLStatementErrorCallback;
    4744class SQLTransaction;
    48 class SQLTransactionCallback;
    49 class SQLTransactionErrorCallback;
     45class SQLTransactionBackend;
    5046class SQLValue;
    51 class VoidCallback;
    5247
    5348class SQLTransactionWrapper : public ThreadSafeRefCounted<SQLTransactionWrapper> {
    5449public:
    5550    virtual ~SQLTransactionWrapper() { }
    56     virtual bool performPreflight(SQLTransaction*) = 0;
    57     virtual bool performPostflight(SQLTransaction*) = 0;
     51    virtual bool performPreflight(SQLTransactionBackend*) = 0;
     52    virtual bool performPostflight(SQLTransactionBackend*) = 0;
    5853    virtual SQLError* sqlError() const = 0;
    59     virtual void handleCommitFailedAfterPostflight(SQLTransaction*) = 0;
     54    virtual void handleCommitFailedAfterPostflight(SQLTransactionBackend*) = 0;
    6055};
    6156
    62 class SQLTransactionBackend : public ThreadSafeRefCounted<SQLTransactionBackend> {
     57class SQLTransactionBackend : public SQLTransactionStateMachine<SQLTransactionBackend> {
    6358public:
    64     ~SQLTransactionBackend();
     59    static PassRefPtr<SQLTransactionBackend> create(DatabaseBackendAsync*,
     60        PassRefPtr<SQLTransaction>, PassRefPtr<SQLTransactionWrapper>, bool readOnly);
    6561
    66     void executeSQL(const String& sqlStatement, const Vector<SQLValue>& arguments,
    67         PassRefPtr<SQLStatementCallback>, PassRefPtr<SQLStatementErrorCallback>, ExceptionCode&);
     62    virtual ~SQLTransactionBackend();
    6863
    6964    void lockAcquired();
    70     bool performNextStep();
    71     void performPendingCallback();
     65    void performNextStep();
    7266
    73     Database* database() { return m_database.get(); }
     67    DatabaseBackendAsync* database() { return m_database.get(); }
    7468    bool isReadOnly() { return m_readOnly; }
    7569    void notifyDatabaseThreadIsShuttingDown();
    7670
     71    PassRefPtr<SQLError> transactionError();
     72    void setShouldRetryCurrentStatement(bool);
     73
    7774private:
    78     SQLTransactionBackend(Database*, PassRefPtr<SQLTransactionCallback>, PassRefPtr<SQLTransactionErrorCallback>,
    79         PassRefPtr<VoidCallback>, PassRefPtr<SQLTransactionWrapper>, bool readOnly);
     75    SQLTransactionBackend(DatabaseBackendAsync*, PassRefPtr<SQLTransaction>,
     76        PassRefPtr<SQLTransactionWrapper>, bool readOnly);
    8077
    81     typedef void (SQLTransactionBackend::*TransactionStepMethod)();
    82     TransactionStepMethod m_nextStep;
     78    void doCleanup();
    8379
    8480    void enqueueStatement(PassRefPtr<SQLStatement>);
     
    8682    void checkAndHandleClosedOrInterruptedDatabase();
    8783
    88     void acquireLock();
    89     void openTransactionAndPreflight();
    90     void deliverTransactionCallback();
    91     void scheduleToRunStatements();
    92     void runStatements();
     84    // State Machine functions:
     85    virtual StateFunction stateFunctionFor(SQLTransactionState);
     86    void requestTransitToState(SQLTransactionState);
     87
     88    // State functions:
     89    SQLTransactionState acquireLock();
     90    SQLTransactionState openTransactionAndPreflight();
     91    SQLTransactionState runStatements();
     92    SQLTransactionState postflightAndCommit();
     93    SQLTransactionState cleanupAndTerminate();
     94    SQLTransactionState cleanupAfterTransactionErrorCallback();
     95
     96    SQLTransactionState unreachableState();
     97    SQLTransactionState sendToFrontendState();
     98
     99    SQLTransactionState nextStateForCurrentStatementError();
     100    SQLTransactionState nextStateForTransactionError();
     101    SQLTransactionState runCurrentStatementAndGetNextState();
     102
    93103    void getNextStatement();
    94     bool runCurrentStatement();
    95     void handleCurrentStatementError();
    96     void deliverStatementCallback();
    97     void deliverQuotaIncreaseCallback();
    98     void postflightAndCommit();
    99     void deliverSuccessCallback();
    100     void cleanupAfterSuccessCallback();
    101     void handleTransactionError(bool inCallback);
    102     void deliverTransactionErrorCallback();
    103     void cleanupAfterTransactionErrorCallback();
    104104
    105 #if !LOG_DISABLED
    106     static const char* debugStepName(TransactionStepMethod);
    107 #endif
    108 
     105    RefPtr<SQLTransaction> m_frontend;
    109106    RefPtr<SQLStatement> m_currentStatement;
    110107
    111     bool m_executeSqlAllowed;
     108    RefPtr<DatabaseBackendAsync> m_database;
     109    RefPtr<SQLTransactionWrapper> m_wrapper;
     110    RefPtr<SQLError> m_transactionError;
    112111
    113     RefPtr<Database> m_database;
    114     RefPtr<SQLTransactionWrapper> m_wrapper;
    115     SQLCallbackWrapper<SQLTransactionCallback> m_callbackWrapper;
    116     SQLCallbackWrapper<VoidCallback> m_successCallbackWrapper;
    117     SQLCallbackWrapper<SQLTransactionErrorCallback> m_errorCallbackWrapper;
    118     RefPtr<SQLError> m_transactionError;
     112    bool m_hasCallback;
     113    bool m_hasSuccessCallback;
     114    bool m_hasErrorCallback;
    119115    bool m_shouldRetryCurrentStatement;
    120116    bool m_modifiedDatabase;
     
    128124    OwnPtr<SQLiteTransaction> m_sqliteTransaction;
    129125
    130     friend class SQLTransaction; // FIXME: Remove this once the front-end has been properly isolated.
     126    friend class SQLTransaction;
    131127};
    132128
  • trunk/Source/WebCore/Modules/webdatabase/SQLTransactionClient.cpp

    r141928 r142921  
    3737#include "DatabaseBackendContext.h"
    3838#include "DatabaseManager.h"
     39#include "DatabaseTracker.h"
    3940#include "ScriptExecutionContext.h"
    4041#include "SecurityOrigin.h"
     
    4445void SQLTransactionClient::didCommitWriteTransaction(DatabaseBackend* database)
    4546{
    46     DatabaseManager::manager().scheduleNotifyDatabaseChanged(
     47    DatabaseTracker::tracker().scheduleNotifyDatabaseChanged(
    4748        database->securityOrigin(), database->stringIdentifier());
    4849}
     
    5051void SQLTransactionClient::didExecuteStatement(DatabaseBackend* database)
    5152{
    52     DatabaseManager::manager().databaseChanged(database);
     53    DatabaseTracker::tracker().databaseChanged(database);
    5354}
    5455
  • trunk/Source/WebCore/Modules/webdatabase/SQLTransactionCoordinator.cpp

    r142193 r142921  
    3535#if ENABLE(SQL_DATABASE)
    3636
    37 #include "Database.h"
     37#include "DatabaseBackendAsync.h"
    3838#include "SQLTransactionBackend.h"
    3939#include <wtf/Deque.h>
     
    4646static String getDatabaseIdentifier(SQLTransactionBackend* transaction)
    4747{
    48     Database* database = transaction->database();
     48    DatabaseBackendAsync* database = transaction->database();
    4949    ASSERT(database);
    5050    return database->stringIdentifier();
  • trunk/Source/WebCore/Target.pri

    r142823 r142921  
    14561456    \
    14571457    Modules/webdatabase/AbstractDatabaseServer.h \
     1458    Modules/webdatabase/ChangeVersionData.h \
    14581459    Modules/webdatabase/ChangeVersionWrapper.h \
    14591460    Modules/webdatabase/DOMWindowWebDatabase.h \
     
    14861487    Modules/webdatabase/SQLTransactionClient.h \
    14871488    Modules/webdatabase/SQLTransactionCoordinator.h \
     1489    Modules/webdatabase/SQLTransactionState.h \
     1490    Modules/webdatabase/SQLTransactionStateMachine.h \
    14881491    Modules/webdatabase/SQLTransactionSync.h \
    14891492    Modules/webdatabase/SQLTransactionSyncCallback.h \
     
    30753078        Modules/webdatabase/SQLTransactionClient.cpp \
    30763079        Modules/webdatabase/SQLTransactionCoordinator.cpp \
     3080        Modules/webdatabase/SQLTransactionStateMachine.cpp \
    30773081        Modules/webdatabase/SQLTransactionSync.cpp \
    30783082
  • trunk/Source/WebCore/WebCore.gypi

    r142896 r142921  
    985985            'Modules/webaudio/WaveTable.h',
    986986            'Modules/webdatabase/AbstractDatabaseServer.h',
     987            'Modules/webdatabase/ChangeVersionData.h',
    987988            'Modules/webdatabase/ChangeVersionWrapper.cpp',
    988989            'Modules/webdatabase/ChangeVersionWrapper.h',
     
    10401041            'Modules/webdatabase/SQLTransactionCoordinator.cpp',
    10411042            'Modules/webdatabase/SQLTransactionCoordinator.h',
     1043            'Modules/webdatabase/SQLTransactionState.h',
     1044            'Modules/webdatabase/SQLTransactionStateMachine.cpp',
     1045            'Modules/webdatabase/SQLTransactionStateMachine.h',
    10421046            'Modules/webdatabase/SQLTransactionSync.cpp',
    10431047            'Modules/webdatabase/SQLTransactionSync.h',
  • trunk/Source/WebCore/WebCore.vcproj/WebCore.vcproj

    r142862 r142921  
    2537925379                                </File>
    2538025380                                <File
     25381                                        RelativePath="..\Modules\webdatabase\ChangeVersionData.h"
     25382                                        >
     25383                                </File>
     25384                                <File
    2538125385                                        RelativePath="..\Modules\webdatabase\ChangeVersionWrapper.cpp"
    2538225386                                        >
     
    2563625640                                <File
    2563725641                                        RelativePath="..\Modules\webdatabase\SQLTransactionErrorCallback.h"
     25642                                        >
     25643                                </File>
     25644                                <File
     25645                                        RelativePath="..\Modules\webdatabase\SQLTransactionState.h"
     25646                                        >
     25647                                </File>
     25648                                <File
     25649                                        RelativePath="..\Modules\webdatabase\SQLTransactionStateMachine.cpp"
     25650                                        >
     25651                                </File>
     25652                                <File
     25653                                        RelativePath="..\Modules\webdatabase\SQLTransactionStateMachine.h"
    2563825654                                        >
    2563925655                                </File>
  • trunk/Source/WebCore/WebCore.vcxproj/WebCore.vcxproj

    r142809 r142921  
    18811881    <ClCompile Include="..\Modules\webdatabase\SQLTransactionClient.cpp" />
    18821882    <ClCompile Include="..\Modules\webdatabase\SQLTransactionCoordinator.cpp" />
     1883    <ClCompile Include="..\Modules\webdatabase\SQLTransactionStateMachine.cpp" />
    18831884    <ClCompile Include="..\Modules\webdatabase\SQLTransactionSync.cpp" />
    18841885    <ClCompile Include="..\Modules\webdatabase\WorkerContextWebDatabase.cpp" />
     
    64166417    <ClInclude Include="..\Modules\notifications\WorkerContextNotifications.h" />
    64176418    <ClInclude Include="..\Modules\webdatabase\AbstractDatabaseServer.h" />
     6419    <ClInclude Include="..\Modules\webdatabase\ChangeVersionData.h" />
    64186420    <ClInclude Include="..\Modules\webdatabase\ChangeVersionWrapper.h" />
    64196421    <ClInclude Include="..\Modules\webdatabase\Database.h" />
     
    64536455    <ClInclude Include="..\Modules\webdatabase\SQLTransactionCoordinator.h" />
    64546456    <ClInclude Include="..\Modules\webdatabase\SQLTransactionErrorCallback.h" />
     6457    <ClInclude Include="..\Modules\webdatabase\SQLTransactionState.h" />
     6458    <ClInclude Include="..\Modules\webdatabase\SQLTransactionStateMachine.h" />
    64556459    <ClInclude Include="..\Modules\webdatabase\SQLTransactionSync.h" />
    64566460    <ClInclude Include="..\Modules\webdatabase\SQLTransactionSyncCallback.h" />
  • trunk/Source/WebCore/WebCore.vcxproj/WebCore.vcxproj.filters

    r142641 r142921  
    19001900      <Filter>Modules\webdatabase</Filter>
    19011901    </ClCompile>
    1902     <ClCompile Include="..\Modules\webdatabase\SQLTransaction.cpp">
    1903       <Filter>Modules\webdatabase</Filter>
    1904     </ClCompile>
    19051902    <ClCompile Include="..\Modules\webdatabase\SQLTransactionBackend.cpp">
    19061903      <Filter>Modules\webdatabase</Filter>
     
    19131910    </ClCompile>
    19141911    <ClCompile Include="..\Modules\webdatabase\SQLTransactionCoordinator.cpp">
     1912      <Filter>Modules\webdatabase</Filter>
     1913    </ClCompile>
     1914    <ClCompile Include="..\Modules\webdatabase\SQLTransactionStateMachine.cpp">
    19151915      <Filter>Modules\webdatabase</Filter>
    19161916    </ClCompile>
     
    84738473      <Filter>Modules\webdatabase</Filter>
    84748474    </ClInclude>
     8475    <ClInclude Include="..\Modules\webdatabase\ChangeVersionData.h">
     8476      <Filter>Modules\webdatabase</Filter>
     8477    </ClInclude>
    84758478    <ClInclude Include="..\Modules\webdatabase\ChangeVersionWrapper.h">
    84768479      <Filter>Modules\webdatabase</Filter>
     
    85828585    </ClInclude>
    85838586    <ClInclude Include="..\Modules\webdatabase\SQLTransactionErrorCallback.h">
     8587      <Filter>Modules\webdatabase</Filter>
     8588    </ClInclude>
     8589    <ClInclude Include="..\Modules\webdatabase\SQLTransactionState.h">
     8590      <Filter>Modules\webdatabase</Filter>
     8591    </ClInclude>
     8592    <ClInclude Include="..\Modules\webdatabase\SQLTransactionStateMachine.h">
    85848593      <Filter>Modules\webdatabase</Filter>
    85858594    </ClInclude>
  • trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj

    r142823 r142921  
    37073707                97BC69DA1505F076001B74AC /* DatabaseBackend.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 97BC69D61505F076001B74AC /* DatabaseBackend.cpp */; };
    37083708                97BC69DB1505F076001B74AC /* DatabaseBackend.h in Headers */ = {isa = PBXBuildFile; fileRef = 97BC69D71505F076001B74AC /* DatabaseBackend.h */; settings = {ATTRIBUTES = (Private, ); }; };
     3709                FE36FD1516C7826500F887C1 /* ChangeVersionData.h in Headers */ = {isa = PBXBuildFile; fileRef = FE36FD1116C7826400F887C1 /* ChangeVersionData.h */; };
    37093710                97BC69DC1505F076001B74AC /* ChangeVersionWrapper.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 97BC69D81505F076001B74AC /* ChangeVersionWrapper.cpp */; };
    37103711                97BC69DD1505F076001B74AC /* ChangeVersionWrapper.h in Headers */ = {isa = PBXBuildFile; fileRef = 97BC69D91505F076001B74AC /* ChangeVersionWrapper.h */; };
     
    37463747                97BC6A4F1505F081001B74AC /* SQLTransaction.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 97BC6A0D1505F081001B74AC /* SQLTransaction.cpp */; };
    37473748                97BC6A501505F081001B74AC /* SQLTransaction.h in Headers */ = {isa = PBXBuildFile; fileRef = 97BC6A0E1505F081001B74AC /* SQLTransaction.h */; };
     3749                FEE1811316C319E800084849 /* SQLTransactionBackend.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FEE1811116C319E800084849 /* SQLTransactionBackend.cpp */; };
     3750                FEE1811416C319E800084849 /* SQLTransactionBackend.h in Headers */ = {isa = PBXBuildFile; fileRef = FEE1811216C319E800084849 /* SQLTransactionBackend.h */; };
     3751                FEAD7D8716C339EE00D4670B /* SQLTransactionBackendSync.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FEAD7D8516C339EE00D4670B /* SQLTransactionBackendSync.cpp */; };
     3752                FEAD7D8816C339EE00D4670B /* SQLTransactionBackendSync.h in Headers */ = {isa = PBXBuildFile; fileRef = FEAD7D8616C339EE00D4670B /* SQLTransactionBackendSync.h */; };
    37483753                97BC6A521505F081001B74AC /* SQLTransactionCallback.h in Headers */ = {isa = PBXBuildFile; fileRef = 97BC6A101505F081001B74AC /* SQLTransactionCallback.h */; };
    37493754                97BC6A541505F081001B74AC /* SQLTransactionClient.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 97BC6A121505F081001B74AC /* SQLTransactionClient.cpp */; };
     
    37523757                97BC6A571505F081001B74AC /* SQLTransactionCoordinator.h in Headers */ = {isa = PBXBuildFile; fileRef = 97BC6A151505F081001B74AC /* SQLTransactionCoordinator.h */; };
    37533758                97BC6A581505F081001B74AC /* SQLTransactionErrorCallback.h in Headers */ = {isa = PBXBuildFile; fileRef = 97BC6A161505F081001B74AC /* SQLTransactionErrorCallback.h */; };
     3759                FE36FD1816C7826500F887C1 /* SQLTransactionState.h in Headers */ = {isa = PBXBuildFile; fileRef = FE36FD1416C7826400F887C1 /* SQLTransactionState.h */; };
     3760                FE36FD1616C7826500F887C1 /* SQLTransactionStateMachine.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FE36FD1216C7826400F887C1 /* SQLTransactionStateMachine.cpp */; };
     3761                FE36FD1716C7826500F887C1 /* SQLTransactionStateMachine.h in Headers */ = {isa = PBXBuildFile; fileRef = FE36FD1316C7826400F887C1 /* SQLTransactionStateMachine.h */; };
    37543762                97BC6A5A1505F081001B74AC /* SQLTransactionSync.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 97BC6A181505F081001B74AC /* SQLTransactionSync.cpp */; };
    37553763                97BC6A5B1505F081001B74AC /* SQLTransactionSync.h in Headers */ = {isa = PBXBuildFile; fileRef = 97BC6A191505F081001B74AC /* SQLTransactionSync.h */; };
     
    1115811166                97BC69D61505F076001B74AC /* DatabaseBackend.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DatabaseBackend.cpp; path = Modules/webdatabase/DatabaseBackend.cpp; sourceTree = "<group>"; };
    1115911167                97BC69D71505F076001B74AC /* DatabaseBackend.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DatabaseBackend.h; path = Modules/webdatabase/DatabaseBackend.h; sourceTree = "<group>"; };
     11168                FE36FD1116C7826400F887C1 /* ChangeVersionData.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ChangeVersionData.h; path = Modules/webdatabase/ChangeVersionData.h; sourceTree = "<group>"; };
    1116011169                97BC69D81505F076001B74AC /* ChangeVersionWrapper.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = ChangeVersionWrapper.cpp; path = Modules/webdatabase/ChangeVersionWrapper.cpp; sourceTree = "<group>"; };
    1116111170                97BC69D91505F076001B74AC /* ChangeVersionWrapper.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ChangeVersionWrapper.h; path = Modules/webdatabase/ChangeVersionWrapper.h; sourceTree = "<group>"; };
     
    1120711216                97BC6A0E1505F081001B74AC /* SQLTransaction.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SQLTransaction.h; path = Modules/webdatabase/SQLTransaction.h; sourceTree = "<group>"; };
    1120811217                97BC6A0F1505F081001B74AC /* SQLTransaction.idl */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; name = SQLTransaction.idl; path = Modules/webdatabase/SQLTransaction.idl; sourceTree = "<group>"; };
     11218                FEE1811116C319E800084849 /* SQLTransactionBackend.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SQLTransactionBackend.cpp; path = Modules/webdatabase/SQLTransactionBackend.cpp; sourceTree = "<group>"; };
     11219                FEE1811216C319E800084849 /* SQLTransactionBackend.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SQLTransactionBackend.h; path = Modules/webdatabase/SQLTransactionBackend.h; sourceTree = "<group>"; };
     11220                FEAD7D8516C339EE00D4670B /* SQLTransactionBackendSync.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SQLTransactionBackendSync.cpp; path = Modules/webdatabase/SQLTransactionBackendSync.cpp; sourceTree = "<group>"; };
     11221                FEAD7D8616C339EE00D4670B /* SQLTransactionBackendSync.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SQLTransactionBackendSync.h; path = Modules/webdatabase/SQLTransactionBackendSync.h; sourceTree = "<group>"; };
    1120911222                97BC6A101505F081001B74AC /* SQLTransactionCallback.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SQLTransactionCallback.h; path = Modules/webdatabase/SQLTransactionCallback.h; sourceTree = "<group>"; };
    1121011223                97BC6A111505F081001B74AC /* SQLTransactionCallback.idl */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; name = SQLTransactionCallback.idl; path = Modules/webdatabase/SQLTransactionCallback.idl; sourceTree = "<group>"; };
     
    1121511228                97BC6A161505F081001B74AC /* SQLTransactionErrorCallback.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SQLTransactionErrorCallback.h; path = Modules/webdatabase/SQLTransactionErrorCallback.h; sourceTree = "<group>"; };
    1121611229                97BC6A171505F081001B74AC /* SQLTransactionErrorCallback.idl */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; name = SQLTransactionErrorCallback.idl; path = Modules/webdatabase/SQLTransactionErrorCallback.idl; sourceTree = "<group>"; };
     11230                FE36FD1416C7826400F887C1 /* SQLTransactionState.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SQLTransactionState.h; path = Modules/webdatabase/SQLTransactionState.h; sourceTree = "<group>"; };
     11231                FE36FD1216C7826400F887C1 /* SQLTransactionStateMachine.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SQLTransactionStateMachine.cpp; path = Modules/webdatabase/SQLTransactionStateMachine.cpp; sourceTree = "<group>"; };
     11232                FE36FD1316C7826400F887C1 /* SQLTransactionStateMachine.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SQLTransactionStateMachine.h; path = Modules/webdatabase/SQLTransactionStateMachine.h; sourceTree = "<group>"; };
    1121711233                97BC6A181505F081001B74AC /* SQLTransactionSync.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SQLTransactionSync.cpp; path = Modules/webdatabase/SQLTransactionSync.cpp; sourceTree = "<group>"; };
    1121811234                97BC6A191505F081001B74AC /* SQLTransactionSync.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SQLTransactionSync.h; path = Modules/webdatabase/SQLTransactionSync.h; sourceTree = "<group>"; };
     
    1861618632                        children = (
    1861718633                                FE115FA9167988CD00249134 /* AbstractDatabaseServer.h */,
     18634                                FE36FD1116C7826400F887C1 /* ChangeVersionData.h */,
    1861818635                                97BC69D81505F076001B74AC /* ChangeVersionWrapper.cpp */,
    1861918636                                97BC69D91505F076001B74AC /* ChangeVersionWrapper.h */,
     
    1869618713                                97BC6A161505F081001B74AC /* SQLTransactionErrorCallback.h */,
    1869718714                                97BC6A171505F081001B74AC /* SQLTransactionErrorCallback.idl */,
     18715                                FE36FD1416C7826400F887C1 /* SQLTransactionState.h */,
     18716                                FE36FD1216C7826400F887C1 /* SQLTransactionStateMachine.cpp */,
     18717                                FE36FD1316C7826400F887C1 /* SQLTransactionStateMachine.h */,
    1869818718                                97BC6A181505F081001B74AC /* SQLTransactionSync.cpp */,
    1869918719                                97BC6A191505F081001B74AC /* SQLTransactionSync.h */,
     
    2331423334                                079D086B162F21F900DB8658 /* CaptionUserPreferencesMac.h in Headers */,
    2331523335                                6550B69E099DF0270090D781 /* CDATASection.h in Headers */,
     23336                                FE36FD1516C7826500F887C1 /* ChangeVersionData.h in Headers */,
    2331623337                                97BC69DD1505F076001B74AC /* ChangeVersionWrapper.h in Headers */,
    2331723338                                FD315FFF12B0267600C1A359 /* ChannelMergerNode.h in Headers */,
     
    2592825949                                97BC6A571505F081001B74AC /* SQLTransactionCoordinator.h in Headers */,
    2592925950                                97BC6A581505F081001B74AC /* SQLTransactionErrorCallback.h in Headers */,
     25951                                FE36FD1816C7826500F887C1 /* SQLTransactionState.h in Headers */,
     25952                                FE36FD1716C7826500F887C1 /* SQLTransactionStateMachine.h in Headers */,
    2593025953                                97BC6A5B1505F081001B74AC /* SQLTransactionSync.h in Headers */,
    2593125954                                97BC6A5D1505F081001B74AC /* SQLTransactionSyncCallback.h in Headers */,
     
    2922629249                                97BC6A541505F081001B74AC /* SQLTransactionClient.cpp in Sources */,
    2922729250                                97BC6A561505F081001B74AC /* SQLTransactionCoordinator.cpp in Sources */,
     29251                                FE36FD1616C7826500F887C1 /* SQLTransactionStateMachine.cpp in Sources */,
    2922829252                                97BC6A5A1505F081001B74AC /* SQLTransactionSync.cpp in Sources */,
    2922929253                                1A2E6E590CC55213004A2062 /* SQLValue.cpp in Sources */,
  • trunk/Source/WebCore/inspector/InspectorDatabaseAgent.cpp

    r142375 r142921  
    4242#include "InstrumentingAgents.h"
    4343#include "SQLError.h"
     44#include "SQLResultSet.h"
     45#include "SQLResultSetRowList.h"
    4446#include "SQLStatementCallback.h"
    4547#include "SQLStatementErrorCallback.h"
    46 #include "SQLResultSetRowList.h"
    4748#include "SQLTransaction.h"
    4849#include "SQLTransactionCallback.h"
Note: See TracChangeset for help on using the changeset viewer.