/*
 * Copyright (C) 2007, 2008, 2013 Apple Inc. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1.  Redistributions of source code must retain the above copyright
 *     notice, this list of conditions and the following disclaimer.
 * 2.  Redistributions in binary form must reproduce the above copyright
 *     notice, this list of conditions and the following disclaimer in the
 *     documentation and/or other materials provided with the distribution.
 * 3.  Neither the name of Apple Computer, Inc. ("Apple") nor the names of
 *     its contributors may be used to endorse or promote products derived
 *     from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#include "modules/webdatabase/SQLTransactionBackend.h"

#include <memory>
#include "modules/webdatabase/Database.h"
#include "modules/webdatabase/DatabaseAuthorizer.h"
#include "modules/webdatabase/DatabaseContext.h"
#include "modules/webdatabase/DatabaseThread.h"
#include "modules/webdatabase/DatabaseTracker.h"
#include "modules/webdatabase/SQLError.h"
#include "modules/webdatabase/SQLStatementBackend.h"
#include "modules/webdatabase/SQLTransaction.h"
#include "modules/webdatabase/SQLTransactionClient.h"
#include "modules/webdatabase/SQLTransactionCoordinator.h"
#include "modules/webdatabase/StorageLog.h"
#include "modules/webdatabase/sqlite/SQLValue.h"
#include "modules/webdatabase/sqlite/SQLiteTransaction.h"
#include "platform/wtf/StdLibExtras.h"

// How does a SQLTransaction work?
// ==============================
// The SQLTransaction is a state machine that executes a series of states /
// steps.
//
// The work of the transaction states are defined in section of 4.3.2 of the
// webdatabase spec: http://dev.w3.org/html5/webdatabase/#processing-model
//
// the State Transition Graph at a glance:
// ======================================
//
//     Backend                        .   Frontend
//     (works with SQLiteDatabase)    .   (works with Script)
//     ===========================    .   ===================
//                                    .
//     1. Idle                        .
//         v                          .
//     2. AcquireLock                 .
//         v                          .
//     3. OpenTransactionAndPreflight -----------------------------------.
//         |                        .                                    |
//         `-------------------------> 8. DeliverTransactionCallback --. |
//                                  .     |                           v v
//         ,------------------------------' 9. DeliverTransactionErrorCallback +
//         |                        .                                  ^ ^ ^   |
//         v                        .                                  | | |   |
//     4. RunStatements -----------------------------------------------' | |   |
//         |        ^  ^ |  ^ |     .                                    | |   |
//         |--------'  | |  | `------> 10. DeliverStatementCallback +----' |   |
//         |           | |  `---------------------------------------'      |   |
//         |           | `-----------> 11. DeliverQuotaIncreaseCallback +  |   |
//         |            `-----------------------------------------------'  |   |
//         v                        .                                      |   |
//     5. PostflightAndCommit --+------------------------------------------'   |
//                              |----> 12. DeliverSuccessCallback +            |
//         ,--------------------'   .                             |            |
//         v                        .                             |            |
//     6. CleanupAndTerminate <-----------------------------------'            |
//         v           ^            .                                          |
//     0. End          |            .                                          |
//                     |            .                                          |
//                7: CleanupAfterTransactionErrorCallback <--------------------'
//                                  .
//
// the States and State Transitions:
// ================================
//     0. SQLTransactionState::End
//         - the end state.
//
//     1. SQLTransactionState::Idle
//         - placeholder state while waiting on frontend/backend, etc. See
//           comment on "State transitions between SQLTransaction and
//           SQLTransactionBackend" below.
//
//     2. SQLTransactionState::AcquireLock (runs in backend)
//         - this is the start state.
//         - acquire the "lock".
//         - on "lock" acquisition, goto
//           SQLTransactionState::OpenTransactionAndPreflight.
//
//     3. SQLTransactionState::openTransactionAndPreflight (runs in backend)
//         - Sets up an SQLiteTransaction.
//         - begin the SQLiteTransaction.
//         - call the SQLTransactionWrapper preflight if available.
//         - schedule script callback.
//         - on error, goto
//           SQLTransactionState::DeliverTransactionErrorCallback.
//         - goto SQLTransactionState::DeliverTransactionCallback.
//
//     4. SQLTransactionState::DeliverTransactionCallback (runs in frontend)
//         - invoke the script function callback() if available.
//         - on error, goto
//           SQLTransactionState::DeliverTransactionErrorCallback.
//         - goto SQLTransactionState::RunStatements.
//
//     5. SQLTransactionState::DeliverTransactionErrorCallback (runs in
//        frontend)
//         - invoke the script function errorCallback if available.
//         - goto SQLTransactionState::CleanupAfterTransactionErrorCallback.
//
//     6. SQLTransactionState::RunStatements (runs in backend)
//         - while there are statements {
//             - run a statement.
//             - if statementCallback is available, goto
//               SQLTransactionState::DeliverStatementCallback.
//             - on error,
//               goto SQLTransactionState::DeliverQuotaIncreaseCallback, or
//               goto SQLTransactionState::DeliverStatementCallback, or
//               goto SQLTransactionState::deliverTransactionErrorCallback.
//           }
//         - goto SQLTransactionState::PostflightAndCommit.
//
//     7. SQLTransactionState::DeliverStatementCallback (runs in frontend)
//         - invoke script statement callback (assume available).
//         - on error, goto
//           SQLTransactionState::DeliverTransactionErrorCallback.
//         - goto SQLTransactionState::RunStatements.
//
//     8. SQLTransactionState::DeliverQuotaIncreaseCallback (runs in frontend)
//         - give client a chance to increase the quota.
//         - goto SQLTransactionState::RunStatements.
//
//     9. SQLTransactionState::PostflightAndCommit (runs in backend)
//         - call the SQLTransactionWrapper postflight if available.
//         - commit the SQLiteTansaction.
//         - on error, goto
//           SQLTransactionState::DeliverTransactionErrorCallback.
//         - if successCallback is available, goto
//           SQLTransactionState::DeliverSuccessCallback.
//           else goto SQLTransactionState::CleanupAndTerminate.
//
//     10. SQLTransactionState::DeliverSuccessCallback (runs in frontend)
//         - invoke the script function successCallback() if available.
//         - goto SQLTransactionState::CleanupAndTerminate.
//
//     11. SQLTransactionState::CleanupAndTerminate (runs in backend)
//         - stop and clear the SQLiteTransaction.
//         - release the "lock".
//         - goto SQLTransactionState::End.
//
//     12. SQLTransactionState::CleanupAfterTransactionErrorCallback (runs in
//         backend)
//         - rollback the SQLiteTransaction.
//         - goto SQLTransactionState::CleanupAndTerminate.
//
// State transitions between SQLTransaction and SQLTransactionBackend
// ==================================================================
// As shown above, there are state transitions that crosses the boundary between
// the frontend and backend. For example,
//
//     OpenTransactionAndPreflight (state 3 in the backend)
//     transitions to DeliverTransactionCallback (state 8 in the frontend),
//     which in turn transitions to RunStatements (state 4 in the backend).
//
// This cross boundary transition is done by posting transition requests to the
// other side and letting the other side's state machine execute the state
// transition in the appropriate thread (i.e. the script thread for the
// frontend, and the database thread for the backend).
//
// Logically, the state transitions work as shown in the graph above. But
// physically, the transition mechanism uses the Idle state (both in the
// frontend and backend) as a waiting state for further activity. For example,
// taking a closer look at the 3 state transition example above, what actually
// happens is as follows:
//
//     Step 1:
//     ======
//     In the frontend thread:
//     - waiting quietly is Idle. Not doing any work.
//
//     In the backend:
//     - is in OpenTransactionAndPreflight, and doing its work.
//     - when done, it transits to the backend DeliverTransactionCallback.
//     - the backend DeliverTransactionCallback sends a request to the frontend
//       to transit to DeliverTransactionCallback, and then itself transits to
//       Idle.
//
//     Step 2:
//     ======
//     In the frontend thread:
//     - transits to DeliverTransactionCallback and does its work.
//     - when done, it transits to the frontend RunStatements.
//     - the frontend RunStatements sends a request to the backend to transit
//       to RunStatements, and then itself transits to Idle.
//
//     In the backend:
//     - waiting quietly in Idle.
//
//     Step 3:
//     ======
//     In the frontend thread:
//     - waiting quietly is Idle. Not doing any work.
//
//     In the backend:
//     - transits to RunStatements, and does its work.
//        ...
//
// So, when the frontend or backend are not active, they will park themselves in
// their Idle states. This means their m_nextState is set to Idle, but they
// never actually run the corresponding state function. Note: for both the
// frontend and backend, the state function for Idle is unreachableState().
//
// The states that send a request to their peer across the front/back boundary
// are implemented with just 2 functions: SQLTransaction::sendToBackendState()
// and SQLTransactionBackend::sendToFrontendState(). These state functions do
// nothing but sends a request to the other side to transit to the current
// state (indicated by m_nextState), and then transits itself to the Idle state
// to wait for further action.

// The Life-Cycle of a SQLTransaction i.e. Who's keeping the SQLTransaction
// alive?
// ==============================================================================
// The RefPtr chain goes something like this:
//
//     At birth (in Database::runTransaction()):
//     ====================================================
//     Database
//         // HeapDeque<Member<SQLTransactionBackend>> m_transactionQueue
//         // points to ...
//     --> SQLTransactionBackend
//         // Member<SQLTransaction> m_frontend points to ...
//     --> SQLTransaction
//         // Member<SQLTransactionBackend> m_backend points to ...
//     --> SQLTransactionBackend  // which is a circular reference.
//
//     Note: there's a circular reference between the SQLTransaction front-end
//     and back-end. This circular reference is established in the constructor
//     of the SQLTransactionBackend. The circular reference will be broken by
//     calling doCleanup() to nullify m_frontend. This is done at the end of the
//     transaction's clean up state (i.e. when the transaction should no longer
//     be in use thereafter), or if the database was interrupted. See comments
//     on "What happens if a transaction is interrupted?" below for details.
//
//     After scheduling the transaction with the DatabaseThread
//     (Database::scheduleTransaction()):
//     ======================================================================================================
//     DatabaseThread
//         // MessageQueue<DatabaseTask> m_queue points to ...
//     --> DatabaseTransactionTask
//         // Member<SQLTransactionBackend> m_transaction points to ...
//     --> SQLTransactionBackend
//         // Member<SQLTransaction> m_frontend points to ...
//     --> SQLTransaction
//         // Member<SQLTransactionBackend> m_backend points to ...
//     --> SQLTransactionBackend  // which is a circular reference.
//
//     When executing the transaction (in DatabaseThread::databaseThread()):
//     ====================================================================
//     std::unique_ptr<DatabaseTask> task;
//         // points to ...
//     --> DatabaseTransactionTask
//         // Member<SQLTransactionBackend> m_transaction points to ...
//     --> SQLTransactionBackend
//         // Member<SQLTransaction> m_frontend;
//     --> SQLTransaction
//         // Member<SQLTransactionBackend> m_backend points to ...
//     --> SQLTransactionBackend  // which is a circular reference.
//
//     At the end of cleanupAndTerminate():
//     ===================================
//     At the end of the cleanup state, the SQLTransactionBackend::m_frontend is
//     nullified.  If by then, a JSObject wrapper is referring to the
//     SQLTransaction, then the reference chain looks like this:
//
//     JSObjectWrapper
//     --> SQLTransaction
//         // in Member<SQLTransactionBackend> m_backend points to ...
//     --> SQLTransactionBackend
//         // which no longer points back to its SQLTransaction.
//
//     When the GC collects the corresponding JSObject, the above chain will be
//     cleaned up and deleted.
//
//     If there is no JSObject wrapper referring to the SQLTransaction when the
//     cleanup states nullify SQLTransactionBackend::m_frontend, the
//     SQLTransaction will deleted then.  However, there will still be a
//     DatabaseTask pointing to the SQLTransactionBackend (see the "When
//     executing the transaction" chain above). This will keep the
//     SQLTransactionBackend alive until DatabaseThread::databaseThread()
//     releases its task std::unique_ptr.
//
//     What happens if a transaction is interrupted?
//     ============================================
//     If the transaction is interrupted half way, it won't get to run to state
//     CleanupAndTerminate, and hence, would not have called
//     SQLTransactionBackend's doCleanup(). doCleanup() is where we nullify
//     SQLTransactionBackend::m_frontend to break the reference cycle between
//     the frontend and backend. Hence, we need to cleanup the transaction by
//     other means.
//
//     Note: calling SQLTransactionBackend::notifyDatabaseThreadIsShuttingDown()
//     is effectively the same as calling SQLTransactionBackend::doClean().
//
//     In terms of who needs to call doCleanup(), there are 5 phases in the
//     SQLTransactionBackend life-cycle. These are the phases and how the clean
//     up is done:
//
//     Phase 1. After Birth, before scheduling
//
//     - To clean up, DatabaseThread::databaseThread() will call
//       Database::close() during its shutdown.
//     - Database::close() will iterate
//       Database::m_transactionQueue and call
//       notifyDatabaseThreadIsShuttingDown() on each transaction there.
//
//     Phase 2. After scheduling, before state AcquireLock
//
//     - If the interruption occures before the DatabaseTransactionTask is
//       scheduled in DatabaseThread::m_queue but hasn't gotten to execute
//       (i.e. DatabaseTransactionTask::performTask() has not been called),
//       then the DatabaseTransactionTask may get destructed before it ever
//       gets to execute.
//     - To clean up, the destructor will check if the task's m_wasExecuted is
//       set. If not, it will call notifyDatabaseThreadIsShuttingDown() on
//       the task's transaction.
//
//     Phase 3. After state AcquireLock, before "lockAcquired"
//
//     - In this phase, the transaction would have been added to the
//       SQLTransactionCoordinator's CoordinationInfo's pendingTransactions.
//     - To clean up, during shutdown, DatabaseThread::databaseThread() calls
//       SQLTransactionCoordinator::shutdown(), which calls
//       notifyDatabaseThreadIsShuttingDown().
//
//     Phase 4: After "lockAcquired", before state CleanupAndTerminate
//
//     - In this phase, the transaction would have been added either to the
//       SQLTransactionCoordinator's CoordinationInfo's activeWriteTransaction
//       or activeReadTransactions.
//     - To clean up, during shutdown, DatabaseThread::databaseThread() calls
//       SQLTransactionCoordinator::shutdown(), which calls
//       notifyDatabaseThreadIsShuttingDown().
//
//     Phase 5: After state CleanupAndTerminate
//
//     - This is how a transaction ends normally.
//     - state CleanupAndTerminate calls doCleanup().

namespace blink {

SQLTransactionBackend* SQLTransactionBackend::Create(
    Database* db,
    SQLTransaction* frontend,
    SQLTransactionWrapper* wrapper,
    bool read_only) {
  return new SQLTransactionBackend(db, frontend, wrapper, read_only);
}

SQLTransactionBackend::SQLTransactionBackend(Database* db,
                                             SQLTransaction* frontend,
                                             SQLTransactionWrapper* wrapper,
                                             bool read_only)
    : frontend_(frontend),
      database_(db),
      wrapper_(wrapper),
      has_callback_(frontend_->HasCallback()),
      has_success_callback_(frontend_->HasSuccessCallback()),
      has_error_callback_(frontend_->HasErrorCallback()),
      should_retry_current_statement_(false),
      modified_database_(false),
      lock_acquired_(false),
      read_only_(read_only),
      has_version_mismatch_(false) {
  DCHECK(IsMainThread());
  DCHECK(database_);
  frontend_->SetBackend(this);
  requested_state_ = SQLTransactionState::kAcquireLock;
}

SQLTransactionBackend::~SQLTransactionBackend() {
  DCHECK(!sqlite_transaction_);
}

void SQLTransactionBackend::Trace(blink::Visitor* visitor) {
  visitor->Trace(database_);
  visitor->Trace(wrapper_);
}

void SQLTransactionBackend::DoCleanup() {
  if (!frontend_)
    return;
  // Break the reference cycle. See comment about the life-cycle above.
  frontend_ = nullptr;

  DCHECK(GetDatabase()
             ->GetDatabaseContext()
             ->GetDatabaseThread()
             ->IsDatabaseThread());

  MutexLocker locker(statement_mutex_);
  statement_queue_.clear();

  if (sqlite_transaction_) {
    // In the event we got here because of an interruption or error (i.e. if
    // the transaction is in progress), we should roll it back here. Clearing
    // m_sqliteTransaction invokes SQLiteTransaction's destructor which does
    // just that. We might as well do this unconditionally and free up its
    // resources because we're already terminating.
    sqlite_transaction_.reset();
  }

  // Release the lock on this database
  if (lock_acquired_)
    database_->TransactionCoordinator()->ReleaseLock(this);

  // Do some aggresive clean up here except for m_database.
  //
  // We can't clear m_database here because the frontend may asynchronously
  // invoke SQLTransactionBackend::requestTransitToState(), and that function
  // uses m_database to schedule a state transition. This may occur because
  // the frontend (being in another thread) may already be on the way to
  // requesting our next state before it detects an interruption.
  //
  // There is no harm in letting it finish making the request. It'll set
  // m_requestedState, but we won't execute a transition to that state because
  // we've already shut down the transaction.
  //
  // We also can't clear m_currentStatementBackend and m_transactionError.
  // m_currentStatementBackend may be accessed asynchronously by the
  // frontend's deliverStatementCallback() state. Similarly,
  // m_transactionError may be accessed by deliverTransactionErrorCallback().
  // This occurs if requests for transition to those states have already been
  // registered with the frontend just prior to a clean up request arriving.
  //
  // So instead, let our destructor handle their clean up since this
  // SQLTransactionBackend is guaranteed to not destruct until the frontend
  // is also destructing.

  wrapper_ = nullptr;
}

SQLStatement* SQLTransactionBackend::CurrentStatement() {
  return current_statement_backend_->GetFrontend();
}

SQLErrorData* SQLTransactionBackend::TransactionError() {
  return transaction_error_.get();
}

void SQLTransactionBackend::SetShouldRetryCurrentStatement(bool should_retry) {
  DCHECK(!should_retry_current_statement_);
  should_retry_current_statement_ = should_retry;
}

SQLTransactionBackend::StateFunction SQLTransactionBackend::StateFunctionFor(
    SQLTransactionState state) {
  static const StateFunction kStateFunctions[] = {
      &SQLTransactionBackend::UnreachableState,                      // 0. end
      &SQLTransactionBackend::UnreachableState,                      // 1. idle
      &SQLTransactionBackend::AcquireLock,                           // 2.
      &SQLTransactionBackend::OpenTransactionAndPreflight,           // 3.
      &SQLTransactionBackend::RunStatements,                         // 4.
      &SQLTransactionBackend::PostflightAndCommit,                   // 5.
      &SQLTransactionBackend::CleanupAndTerminate,                   // 6.
      &SQLTransactionBackend::CleanupAfterTransactionErrorCallback,  // 7.
      // 8. deliverTransactionCallback
      &SQLTransactionBackend::SendToFrontendState,
      // 9. deliverTransactionErrorCallback
      &SQLTransactionBackend::SendToFrontendState,
      // 10.  deliverStatementCallback
      &SQLTransactionBackend::SendToFrontendState,
      // 11. deliverQuotaIncreaseCallback
      &SQLTransactionBackend::SendToFrontendState,
      // 12. deliverSuccessCallback
      &SQLTransactionBackend::SendToFrontendState,
  };

  DCHECK(WTF_ARRAY_LENGTH(kStateFunctions) ==
         static_cast<int>(SQLTransactionState::kNumberOfStates));
  DCHECK_LT(state, SQLTransactionState::kNumberOfStates);

  return kStateFunctions[static_cast<int>(state)];
}

void SQLTransactionBackend::EnqueueStatementBackend(
    SQLStatementBackend* statement_backend) {
  DCHECK(IsMainThread());
  MutexLocker locker(statement_mutex_);
  statement_queue_.push_back(statement_backend);
}

void SQLTransactionBackend::ComputeNextStateAndCleanupIfNeeded() {
  DCHECK(GetDatabase()
             ->GetDatabaseContext()
             ->GetDatabaseThread()
             ->IsDatabaseThread());
  // Only honor the requested state transition if we're not supposed to be
  // cleaning up and shutting down:
  if (database_->Opened()) {
    SetStateToRequestedState();
    DCHECK(next_state_ == SQLTransactionState::kAcquireLock ||
           next_state_ == SQLTransactionState::kOpenTransactionAndPreflight ||
           next_state_ == SQLTransactionState::kRunStatements ||
           next_state_ == SQLTransactionState::kPostflightAndCommit ||
           next_state_ == SQLTransactionState::kCleanupAndTerminate ||
           next_state_ ==
               SQLTransactionState::kCleanupAfterTransactionErrorCallback);
#if DCHECK_IS_ON()
    STORAGE_DVLOG(1) << "State " << NameForSQLTransactionState(next_state_);
#endif
    return;
  }

  // If we get here, then we should be shutting down. Do clean up if needed:
  if (next_state_ == SQLTransactionState::kEnd)
    return;
  next_state_ = SQLTransactionState::kEnd;

  // If the database was stopped, don't do anything and cancel queued work
  STORAGE_DVLOG(1) << "Database was stopped or interrupted - cancelling work "
                      "for this transaction";

  // The current SQLite transaction should be stopped, as well
  if (sqlite_transaction_) {
    sqlite_transaction_->Stop();
    sqlite_transaction_.reset();
  }

  // Terminate the frontend state machine. This also gets the frontend to
  // call computeNextStateAndCleanupIfNeeded() and clear its wrappers
  // if needed.
  frontend_->RequestTransitToState(SQLTransactionState::kEnd);

  // Redirect to the end state to abort, clean up, and end the transaction.
  DoCleanup();
}

void SQLTransactionBackend::PerformNextStep() {
  ComputeNextStateAndCleanupIfNeeded();
  RunStateMachine();
}

void SQLTransactionBackend::ExecuteSQL(SQLStatement* statement,
                                       const String& sql_statement,
                                       const Vector<SQLValue>& arguments,
                                       int permissions) {
  DCHECK(IsMainThread());
  EnqueueStatementBackend(SQLStatementBackend::Create(statement, sql_statement,
                                                      arguments, permissions));
}

void SQLTransactionBackend::NotifyDatabaseThreadIsShuttingDown() {
  DCHECK(GetDatabase()
             ->GetDatabaseContext()
             ->GetDatabaseThread()
             ->IsDatabaseThread());

  // If the transaction is in progress, we should roll it back here, since this
  // is our last opportunity to do something related to this transaction on the
  // DB thread. Amongst other work, doCleanup() will clear m_sqliteTransaction
  // which invokes SQLiteTransaction's destructor, which will do the roll back
  // if necessary.
  DoCleanup();
}

SQLTransactionState SQLTransactionBackend::AcquireLock() {
  database_->TransactionCoordinator()->AcquireLock(this);
  return SQLTransactionState::kIdle;
}

void SQLTransactionBackend::LockAcquired() {
  lock_acquired_ = true;
  RequestTransitToState(SQLTransactionState::kOpenTransactionAndPreflight);
}

SQLTransactionState SQLTransactionBackend::OpenTransactionAndPreflight() {
  DCHECK(GetDatabase()
             ->GetDatabaseContext()
             ->GetDatabaseThread()
             ->IsDatabaseThread());
  DCHECK(!database_->SqliteDatabase().TransactionInProgress());
  DCHECK(lock_acquired_);

  STORAGE_DVLOG(1) << "Opening and preflighting transaction " << this;

  // Set the maximum usage for this transaction if this transactions is not
  // read-only.
  if (!read_only_)
    database_->SqliteDatabase().SetMaximumSize(database_->MaximumSize());

  DCHECK(!sqlite_transaction_);
  sqlite_transaction_ = std::make_unique<SQLiteTransaction>(
      database_->SqliteDatabase(), read_only_);

  database_->ResetDeletes();
  database_->DisableAuthorizer();
  sqlite_transaction_->begin();
  database_->EnableAuthorizer();

  // Spec 4.3.2.1+2: Open a transaction to the database, jumping to the error
  // callback if that fails.
  if (!sqlite_transaction_->InProgress()) {
    DCHECK(!database_->SqliteDatabase().TransactionInProgress());
    database_->ReportStartTransactionResult(
        2, SQLError::kDatabaseErr, database_->SqliteDatabase().LastError());
    transaction_error_ = SQLErrorData::Create(
        SQLError::kDatabaseErr, "unable to begin transaction",
        database_->SqliteDatabase().LastError(),
        database_->SqliteDatabase().LastErrorMsg());
    sqlite_transaction_.reset();
    return NextStateForTransactionError();
  }

  // Note: We intentionally retrieve the actual version even with an empty
  // expected version.  In multi-process browsers, we take this opportunity to
  // update the cached value for the actual version. In single-process browsers,
  // this is just a map lookup.
  String actual_version;
  if (!database_->GetActualVersionForTransaction(actual_version)) {
    database_->ReportStartTransactionResult(
        3, SQLError::kDatabaseErr, database_->SqliteDatabase().LastError());
    transaction_error_ =
        SQLErrorData::Create(SQLError::kDatabaseErr, "unable to read version",
                             database_->SqliteDatabase().LastError(),
                             database_->SqliteDatabase().LastErrorMsg());
    database_->DisableAuthorizer();
    sqlite_transaction_.reset();
    database_->EnableAuthorizer();
    return NextStateForTransactionError();
  }
  has_version_mismatch_ = !database_->ExpectedVersion().IsEmpty() &&
                          (database_->ExpectedVersion() != actual_version);

  // Spec 4.3.2.3: Perform preflight steps, jumping to the error callback if
  // they fail.
  if (wrapper_ && !wrapper_->PerformPreflight(this)) {
    database_->DisableAuthorizer();
    sqlite_transaction_.reset();
    database_->EnableAuthorizer();
    if (wrapper_->SqlError()) {
      transaction_error_ = SQLErrorData::Create(*wrapper_->SqlError());
    } else {
      database_->ReportStartTransactionResult(4, SQLError::kUnknownErr, 0);
      transaction_error_ = SQLErrorData::Create(
          SQLError::kUnknownErr,
          "unknown error occurred during transaction preflight");
    }
    return NextStateForTransactionError();
  }

  // Spec 4.3.2.4: Invoke the transaction callback with the new SQLTransaction
  // object.
  if (has_callback_)
    return SQLTransactionState::kDeliverTransactionCallback;

  // If we have no callback to make, skip pass to the state after:
  return SQLTransactionState::kRunStatements;
}

SQLTransactionState SQLTransactionBackend::RunStatements() {
  DCHECK(GetDatabase()
             ->GetDatabaseContext()
             ->GetDatabaseThread()
             ->IsDatabaseThread());
  DCHECK(lock_acquired_);
  SQLTransactionState next_state;

  // If there is a series of statements queued up that are all successful and
  // have no associated SQLStatementCallback objects, then we can burn through
  // the queue.
  do {
    if (should_retry_current_statement_ &&
        !sqlite_transaction_->WasRolledBackBySqlite()) {
      should_retry_current_statement_ = false;
      // FIXME - Another place that needs fixing up after
      // <rdar://problem/5628468> is addressed.
      // See ::openTransactionAndPreflight() for discussion

      // Reset the maximum size here, as it was increased to allow us to retry
      // this statement.  m_shouldRetryCurrentStatement is set to true only when
      // a statement exceeds the quota, which can happen only in a read-write
      // transaction.  Therefore, there is no need to check here if the
      // transaction is read-write.
      database_->SqliteDatabase().SetMaximumSize(database_->MaximumSize());
    } else {
      // If the current statement has already been run, failed due to quota
      // constraints, and we're not retrying it, that means it ended in an
      // error. Handle it now.
      if (current_statement_backend_ &&
          current_statement_backend_->LastExecutionFailedDueToQuota()) {
        return NextStateForCurrentStatementError();
      }

      // Otherwise, advance to the next statement
      GetNextStatement();
    }
    next_state = RunCurrentStatementAndGetNextState();
  } while (next_state == SQLTransactionState::kRunStatements);

  return next_state;
}

void SQLTransactionBackend::GetNextStatement() {
  DCHECK(GetDatabase()
             ->GetDatabaseContext()
             ->GetDatabaseThread()
             ->IsDatabaseThread());
  current_statement_backend_ = nullptr;

  MutexLocker locker(statement_mutex_);
  if (!statement_queue_.IsEmpty())
    current_statement_backend_ = statement_queue_.TakeFirst();
}

SQLTransactionState
SQLTransactionBackend::RunCurrentStatementAndGetNextState() {
  if (!current_statement_backend_) {
    // No more statements to run. So move on to the next state.
    return SQLTransactionState::kPostflightAndCommit;
  }

  database_->ResetAuthorizer();

  if (has_version_mismatch_)
    current_statement_backend_->SetVersionMismatchedError(database_.Get());

  if (current_statement_backend_->Execute(database_.Get())) {
    if (database_->LastActionChangedDatabase()) {
      // Flag this transaction as having changed the database for later delegate
      // notification.
      modified_database_ = true;
    }

    if (current_statement_backend_->HasStatementCallback()) {
      return SQLTransactionState::kDeliverStatementCallback;
    }

    // If we get here, then the statement doesn't have a callback to invoke.
    // We can move on to the next statement. Hence, stay in this state.
    return SQLTransactionState::kRunStatements;
  }

  if (current_statement_backend_->LastExecutionFailedDueToQuota()) {
    return SQLTransactionState::kDeliverQuotaIncreaseCallback;
  }

  return NextStateForCurrentStatementError();
}

SQLTransactionState SQLTransactionBackend::NextStateForCurrentStatementError() {
  // Spec 4.3.2.6.6: error - Call the statement's error callback, but if there
  // was no error callback, or the transaction was rolled back, jump to the
  // transaction error callback.
  if (current_statement_backend_->HasStatementErrorCallback() &&
      !sqlite_transaction_->WasRolledBackBySqlite())
    return SQLTransactionState::kDeliverStatementCallback;

  if (current_statement_backend_->SqlError()) {
    transaction_error_ =
        SQLErrorData::Create(*current_statement_backend_->SqlError());
  } else {
    database_->ReportCommitTransactionResult(1, SQLError::kDatabaseErr, 0);
    transaction_error_ = SQLErrorData::Create(
        SQLError::kDatabaseErr, "the statement failed to execute");
  }
  return NextStateForTransactionError();
}

SQLTransactionState SQLTransactionBackend::PostflightAndCommit() {
  DCHECK(lock_acquired_);

  // Spec 4.3.2.7: Perform postflight steps, jumping to the error callback if
  // they fail.
  if (wrapper_ && !wrapper_->PerformPostflight(this)) {
    if (wrapper_->SqlError()) {
      transaction_error_ = SQLErrorData::Create(*wrapper_->SqlError());
    } else {
      database_->ReportCommitTransactionResult(3, SQLError::kUnknownErr, 0);
      transaction_error_ = SQLErrorData::Create(
          SQLError::kUnknownErr,
          "unknown error occurred during transaction postflight");
    }
    return NextStateForTransactionError();
  }

  // Spec 4.3.2.7: Commit the transaction, jumping to the error callback if that
  // fails.
  DCHECK(sqlite_transaction_);

  database_->DisableAuthorizer();
  sqlite_transaction_->Commit();
  database_->EnableAuthorizer();

  // If the commit failed, the transaction will still be marked as "in progress"
  if (sqlite_transaction_->InProgress()) {
    if (wrapper_)
      wrapper_->HandleCommitFailedAfterPostflight(this);
    database_->ReportCommitTransactionResult(
        4, SQLError::kDatabaseErr, database_->SqliteDatabase().LastError());
    transaction_error_ = SQLErrorData::Create(
        SQLError::kDatabaseErr, "unable to commit transaction",
        database_->SqliteDatabase().LastError(),
        database_->SqliteDatabase().LastErrorMsg());
    return NextStateForTransactionError();
  }

  database_->ReportCommitTransactionResult(0, -1, 0);  // OK

  // Vacuum the database if anything was deleted.
  if (database_->HadDeletes())
    database_->IncrementalVacuumIfNeeded();

  // The commit was successful. If the transaction modified this database,
  // notify the delegates.
  if (modified_database_)
    database_->TransactionClient()->DidCommitWriteTransaction(GetDatabase());

  // Spec 4.3.2.8: Deliver success callback, if there is one.
  return SQLTransactionState::kDeliverSuccessCallback;
}

SQLTransactionState SQLTransactionBackend::CleanupAndTerminate() {
  DCHECK(lock_acquired_);

  // Spec 4.3.2.9: End transaction steps. There is no next step.
  STORAGE_DVLOG(1) << "Transaction " << this << " is complete";
  DCHECK(!database_->SqliteDatabase().TransactionInProgress());

  // Phase 5 cleanup. See comment on the SQLTransaction life-cycle above.
  DoCleanup();
  database_->InProgressTransactionCompleted();
  return SQLTransactionState::kEnd;
}

SQLTransactionState SQLTransactionBackend::NextStateForTransactionError() {
  DCHECK(transaction_error_);
  if (has_error_callback_)
    return SQLTransactionState::kDeliverTransactionErrorCallback;

  // No error callback, so fast-forward to the next state and rollback the
  // transaction.
  return SQLTransactionState::kCleanupAfterTransactionErrorCallback;
}

SQLTransactionState
SQLTransactionBackend::CleanupAfterTransactionErrorCallback() {
  DCHECK(lock_acquired_);

  STORAGE_DVLOG(1) << "Transaction " << this << " is complete with an error";
  database_->DisableAuthorizer();
  if (sqlite_transaction_) {
    // Spec 4.3.2.10: Rollback the transaction.
    sqlite_transaction_->Rollback();

    DCHECK(!database_->SqliteDatabase().TransactionInProgress());
    sqlite_transaction_.reset();
  }
  database_->EnableAuthorizer();

  DCHECK(!database_->SqliteDatabase().TransactionInProgress());

  return SQLTransactionState::kCleanupAndTerminate;
}

// requestTransitToState() can be called from the frontend. Hence, it should
// NOT be modifying SQLTransactionBackend in general. The only safe field to
// modify is m_requestedState which is meant for this purpose.
void SQLTransactionBackend::RequestTransitToState(
    SQLTransactionState next_state) {
#if DCHECK_IS_ON()
  STORAGE_DVLOG(1) << "Scheduling " << NameForSQLTransactionState(next_state)
                   << " for transaction " << this;
#endif
  requested_state_ = next_state;
  DCHECK_NE(requested_state_, SQLTransactionState::kEnd);
  database_->ScheduleTransactionStep(this);
}

// This state function is used as a stub function to plug unimplemented states
// in the state dispatch table. They are unimplemented because they should
// never be reached in the course of correct execution.
SQLTransactionState SQLTransactionBackend::UnreachableState() {
  NOTREACHED();
  return SQLTransactionState::kEnd;
}

SQLTransactionState SQLTransactionBackend::SendToFrontendState() {
  DCHECK_NE(next_state_, SQLTransactionState::kIdle);
  frontend_->RequestTransitToState(next_state_);
  return SQLTransactionState::kIdle;
}

}  // namespace blink
