1926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)/* 2926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) * Copyright (C) 2007, 2008, 2013 Apple Inc. All rights reserved. 3926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) * 4926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) * Redistribution and use in source and binary forms, with or without 5926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) * modification, are permitted provided that the following conditions 6926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) * are met: 7926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) * 8926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) * 1. Redistributions of source code must retain the above copyright 9926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) * notice, this list of conditions and the following disclaimer. 10926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) * 2. Redistributions in binary form must reproduce the above copyright 11926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) * notice, this list of conditions and the following disclaimer in the 12926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) * documentation and/or other materials provided with the distribution. 13926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of 14926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) * its contributors may be used to endorse or promote products derived 15926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) * from this software without specific prior written permission. 16926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) * 17926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY 18926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 19926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 20926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY 21926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 22926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 23926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 24926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 26926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) */ 28926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) 29926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)#include "config.h" 3053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "modules/webdatabase/SQLTransactionBackend.h" 3153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) 327242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci#include "modules/webdatabase/Database.h" 3353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "modules/webdatabase/DatabaseAuthorizer.h" 34bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles)#include "modules/webdatabase/DatabaseContext.h" 3553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "modules/webdatabase/DatabaseThread.h" 3653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "modules/webdatabase/DatabaseTracker.h" 3753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "modules/webdatabase/SQLError.h" 3853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "modules/webdatabase/SQLStatementBackend.h" 397242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci#include "modules/webdatabase/SQLTransaction.h" 4053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "modules/webdatabase/SQLTransactionClient.h" 4153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "modules/webdatabase/SQLTransactionCoordinator.h" 427242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci#include "modules/webdatabase/sqlite/SQLValue.h" 437242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci#include "modules/webdatabase/sqlite/SQLiteTransaction.h" 447242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci#include "platform/Logging.h" 4553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "wtf/StdLibExtras.h" 46926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) 47926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) 48926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)// How does a SQLTransaction work? 49926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)// ============================== 50926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)// The SQLTransaction is a state machine that executes a series of states / steps. 51926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)// 52926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)// The work of the transaction states are defined in section of 4.3.2 of the 53926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)// webdatabase spec: http://dev.w3.org/html5/webdatabase/#processing-model 54926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)// 55926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)// the State Transition Graph at a glance: 56926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)// ====================================== 57926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)// 58926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)// Backend . Frontend 59926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)// (works with SQLiteDatabase) . (works with Script) 60926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)// =========================== . =================== 61926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)// . 62926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)// 1. Idle . 63926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)// v . 64926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)// 2. AcquireLock . 65926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)// v . 66926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)// 3. OpenTransactionAndPreflight ------------------------------------------. 67926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)// | . | 68926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)// `-------------------------------> 8. DeliverTransactionCallback --. | 69926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)// . | v v 70926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)// ,-------------------------------------' 9. DeliverTransactionErrorCallback + 71926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)// | . ^ ^ ^ | 72926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)// v . | | | | 73926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)// 4. RunStatements -----------------------------------------------------' | | | 74926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)// | ^ ^ | ^ | . | | | 75926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)// |--------' | | | `------------> 10. DeliverStatementCallback +-----' | | 76926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)// | | | `---------------------------------------------' | | 77926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)// | | `-----------------> 11. DeliverQuotaIncreaseCallback + | | 78926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)// | `-----------------------------------------------------' | | 79926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)// v . | | 80926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)// 5. PostflightAndCommit --+--------------------------------------------------' | 81926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)// |----------> 12. DeliverSuccessCallback + | 82926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)// ,--------------------' . | | 83926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)// v . | | 84926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)// 6. CleanupAndTerminate <-----------------------------------------' | 85926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)// v ^ . | 86926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)// 0. End | . | 87926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)// | . | 88926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)// 7: CleanupAfterTransactionErrorCallback <----------------------------' 89926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)// . 90926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)// 91926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)// the States and State Transitions: 92926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)// ================================ 93926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)// 0. SQLTransactionState::End 94926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)// - the end state. 95926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)// 96926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)// 1. SQLTransactionState::Idle 97926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)// - placeholder state while waiting on frontend/backend, etc. See comment on 98926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)// "State transitions between SQLTransaction and SQLTransactionBackend" 99926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)// below. 100926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)// 101926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)// 2. SQLTransactionState::AcquireLock (runs in backend) 102926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)// - this is the start state. 103926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)// - acquire the "lock". 104926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)// - on "lock" acquisition, goto SQLTransactionState::OpenTransactionAndPreflight. 105926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)// 106926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)// 3. SQLTransactionState::openTransactionAndPreflight (runs in backend) 107926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)// - Sets up an SQLiteTransaction. 108926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)// - begin the SQLiteTransaction. 109926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)// - call the SQLTransactionWrapper preflight if available. 110926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)// - schedule script callback. 111926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)// - on error, goto SQLTransactionState::DeliverTransactionErrorCallback. 112926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)// - goto SQLTransactionState::DeliverTransactionCallback. 113926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)// 114926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)// 4. SQLTransactionState::DeliverTransactionCallback (runs in frontend) 115926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)// - invoke the script function callback() if available. 116926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)// - on error, goto SQLTransactionState::DeliverTransactionErrorCallback. 117926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)// - goto SQLTransactionState::RunStatements. 118926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)// 119926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)// 5. SQLTransactionState::DeliverTransactionErrorCallback (runs in frontend) 120926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)// - invoke the script function errorCallback if available. 121926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)// - goto SQLTransactionState::CleanupAfterTransactionErrorCallback. 122926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)// 123926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)// 6. SQLTransactionState::RunStatements (runs in backend) 124926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)// - while there are statements { 125926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)// - run a statement. 126926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)// - if statementCallback is available, goto SQLTransactionState::DeliverStatementCallback. 127926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)// - on error, 128926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)// goto SQLTransactionState::DeliverQuotaIncreaseCallback, or 129926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)// goto SQLTransactionState::DeliverStatementCallback, or 130926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)// goto SQLTransactionState::deliverTransactionErrorCallback. 131926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)// } 132926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)// - goto SQLTransactionState::PostflightAndCommit. 133926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)// 134926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)// 7. SQLTransactionState::DeliverStatementCallback (runs in frontend) 135926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)// - invoke script statement callback (assume available). 136926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)// - on error, goto SQLTransactionState::DeliverTransactionErrorCallback. 137926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)// - goto SQLTransactionState::RunStatements. 138926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)// 139926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)// 8. SQLTransactionState::DeliverQuotaIncreaseCallback (runs in frontend) 140926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)// - give client a chance to increase the quota. 141926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)// - goto SQLTransactionState::RunStatements. 142926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)// 143926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)// 9. SQLTransactionState::PostflightAndCommit (runs in backend) 144926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)// - call the SQLTransactionWrapper postflight if available. 145926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)// - commit the SQLiteTansaction. 146926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)// - on error, goto SQLTransactionState::DeliverTransactionErrorCallback. 147926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)// - if successCallback is available, goto SQLTransactionState::DeliverSuccessCallback. 148926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)// else goto SQLTransactionState::CleanupAndTerminate. 149926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)// 150926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)// 10. SQLTransactionState::DeliverSuccessCallback (runs in frontend) 151926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)// - invoke the script function successCallback() if available. 152926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)// - goto SQLTransactionState::CleanupAndTerminate. 153926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)// 154926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)// 11. SQLTransactionState::CleanupAndTerminate (runs in backend) 155926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)// - stop and clear the SQLiteTransaction. 156926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)// - release the "lock". 157926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)// - goto SQLTransactionState::End. 158926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)// 159926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)// 12. SQLTransactionState::CleanupAfterTransactionErrorCallback (runs in backend) 160926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)// - rollback the SQLiteTransaction. 161926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)// - goto SQLTransactionState::CleanupAndTerminate. 162926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)// 163926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)// State transitions between SQLTransaction and SQLTransactionBackend 164926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)// ================================================================== 165926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)// As shown above, there are state transitions that crosses the boundary between 166926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)// the frontend and backend. For example, 167926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)// 168926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)// OpenTransactionAndPreflight (state 3 in the backend) 169926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)// transitions to DeliverTransactionCallback (state 8 in the frontend), 170926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)// which in turn transitions to RunStatements (state 4 in the backend). 171926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)// 172926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)// This cross boundary transition is done by posting transition requests to the 173926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)// other side and letting the other side's state machine execute the state 174926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)// transition in the appropriate thread (i.e. the script thread for the frontend, 175926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)// and the database thread for the backend). 176926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)// 177926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)// Logically, the state transitions work as shown in the graph above. But 178926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)// physically, the transition mechanism uses the Idle state (both in the frontend 179926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)// and backend) as a waiting state for further activity. For example, taking a 180926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)// closer look at the 3 state transition example above, what actually happens 181926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)// is as follows: 182926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)// 183926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)// Step 1: 184926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)// ====== 185926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)// In the frontend thread: 186926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)// - waiting quietly is Idle. Not doing any work. 187926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)// 188926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)// In the backend: 189926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)// - is in OpenTransactionAndPreflight, and doing its work. 190926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)// - when done, it transits to the backend DeliverTransactionCallback. 191926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)// - the backend DeliverTransactionCallback sends a request to the frontend 192926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)// to transit to DeliverTransactionCallback, and then itself transits to 193926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)// Idle. 194926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)// 195926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)// Step 2: 196926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)// ====== 197926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)// In the frontend thread: 198926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)// - transits to DeliverTransactionCallback and does its work. 199926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)// - when done, it transits to the frontend RunStatements. 200926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)// - the frontend RunStatements sends a request to the backend to transit 201926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)// to RunStatements, and then itself transits to Idle. 202926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)// 203926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)// In the backend: 204926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)// - waiting quietly in Idle. 205926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)// 206926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)// Step 3: 207926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)// ====== 208926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)// In the frontend thread: 209926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)// - waiting quietly is Idle. Not doing any work. 210926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)// 211926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)// In the backend: 212926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)// - transits to RunStatements, and does its work. 213926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)// ... 214926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)// 215926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)// So, when the frontend or backend are not active, they will park themselves in 216926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)// their Idle states. This means their m_nextState is set to Idle, but they never 217926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)// actually run the corresponding state function. Note: for both the frontend and 218926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)// backend, the state function for Idle is unreachableState(). 219926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)// 220926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)// The states that send a request to their peer across the front/back boundary 221926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)// are implemented with just 2 functions: SQLTransaction::sendToBackendState() 222926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)// and SQLTransactionBackend::sendToFrontendState(). These state functions do 223926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)// nothing but sends a request to the other side to transit to the current 224926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)// state (indicated by m_nextState), and then transits itself to the Idle state 225926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)// to wait for further action. 226926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) 227926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) 22802772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch// The Life-Cycle of a SQLTransaction i.e. Who's keeping the SQLTransaction alive? 229926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)// ============================================================================== 230926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)// The RefPtr chain goes something like this: 231926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)// 2327242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci// At birth (in Database::runTransaction()): 233926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)// ==================================================== 2347242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci// Database // Deque<RefPtr<SQLTransactionBackend> > m_transactionQueue points to ... 235926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)// --> SQLTransactionBackend // RefPtr<SQLTransaction> m_frontend points to ... 236926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)// --> SQLTransaction // RefPtr<SQLTransactionBackend> m_backend points to ... 237926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)// --> SQLTransactionBackend // which is a circular reference. 238926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)// 239926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)// Note: there's a circular reference between the SQLTransaction front-end and 240926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)// back-end. This circular reference is established in the constructor of the 241926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)// SQLTransactionBackend. The circular reference will be broken by calling 242926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)// doCleanup() to nullify m_frontend. This is done at the end of the transaction's 243926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)// clean up state (i.e. when the transaction should no longer be in use thereafter), 244926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)// or if the database was interrupted. See comments on "What happens if a transaction 245926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)// is interrupted?" below for details. 246926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)// 2477242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci// After scheduling the transaction with the DatabaseThread (Database::scheduleTransaction()): 248926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)// ====================================================================================================== 249926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)// DatabaseThread // MessageQueue<DatabaseTask> m_queue points to ... 250926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)// --> DatabaseTransactionTask // RefPtr<SQLTransactionBackend> m_transaction points to ... 251926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)// --> SQLTransactionBackend // RefPtr<SQLTransaction> m_frontend points to ... 252926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)// --> SQLTransaction // RefPtr<SQLTransactionBackend> m_backend points to ... 253926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)// --> SQLTransactionBackend // which is a circular reference. 254926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)// 255926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)// When executing the transaction (in DatabaseThread::databaseThread()): 256926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)// ==================================================================== 257926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)// OwnPtr<DatabaseTask> task; // points to ... 258926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)// --> DatabaseTransactionTask // RefPtr<SQLTransactionBackend> m_transaction points to ... 259926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)// --> SQLTransactionBackend // RefPtr<SQLTransaction> m_frontend; 260926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)// --> SQLTransaction // RefPtr<SQLTransactionBackend> m_backend points to ... 261926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)// --> SQLTransactionBackend // which is a circular reference. 262926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)// 263926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)// At the end of cleanupAndTerminate(): 264926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)// =================================== 265926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)// At the end of the cleanup state, the SQLTransactionBackend::m_frontend is nullified. 266926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)// If by then, a JSObject wrapper is referring to the SQLTransaction, then the reference 267926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)// chain looks like this: 268926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)// 269926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)// JSObjectWrapper 270926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)// --> SQLTransaction // in RefPtr<SQLTransactionBackend> m_backend points to ... 271926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)// --> SQLTransactionBackend // which no longer points back to its SQLTransaction. 272926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)// 273926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)// When the GC collects the corresponding JSObject, the above chain will be cleaned up 274926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)// and deleted. 275926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)// 276926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)// If there is no JSObject wrapper referring to the SQLTransaction when the cleanup 277926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)// states nullify SQLTransactionBackend::m_frontend, the SQLTransaction will deleted then. 278926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)// However, there will still be a DatabaseTask pointing to the SQLTransactionBackend (see 279926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)// the "When executing the transaction" chain above). This will keep the 280926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)// SQLTransactionBackend alive until DatabaseThread::databaseThread() releases its 281926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)// task OwnPtr. 282926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)// 283926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)// What happens if a transaction is interrupted? 284926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)// ============================================ 285926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)// If the transaction is interrupted half way, it won't get to run to state 286926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)// CleanupAndTerminate, and hence, would not have called SQLTransactionBackend's 287926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)// doCleanup(). doCleanup() is where we nullify SQLTransactionBackend::m_frontend 288926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)// to break the reference cycle between the frontend and backend. Hence, we need 289926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)// to cleanup the transaction by other means. 290926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)// 291926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)// Note: calling SQLTransactionBackend::notifyDatabaseThreadIsShuttingDown() 292926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)// is effectively the same as calling SQLTransactionBackend::doClean(). 293926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)// 294926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)// In terms of who needs to call doCleanup(), there are 5 phases in the 295926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)// SQLTransactionBackend life-cycle. These are the phases and how the clean 296926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)// up is done: 297926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)// 298926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)// Phase 1. After Birth, before scheduling 299926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)// 300926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)// - To clean up, DatabaseThread::databaseThread() will call 3017242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci// Database::close() during its shutdown. 3027242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci// - Database::close() will iterate 3037242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci// Database::m_transactionQueue and call 304926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)// notifyDatabaseThreadIsShuttingDown() on each transaction there. 30502772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch// 306926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)// Phase 2. After scheduling, before state AcquireLock 307926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)// 308926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)// - If the interruption occures before the DatabaseTransactionTask is 309926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)// scheduled in DatabaseThread::m_queue but hasn't gotten to execute 310926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)// (i.e. DatabaseTransactionTask::performTask() has not been called), 311926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)// then the DatabaseTransactionTask may get destructed before it ever 312926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)// gets to execute. 313926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)// - To clean up, the destructor will check if the task's m_wasExecuted is 314926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)// set. If not, it will call notifyDatabaseThreadIsShuttingDown() on 315926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)// the task's transaction. 316926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)// 317926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)// Phase 3. After state AcquireLock, before "lockAcquired" 318926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)// 319926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)// - In this phase, the transaction would have been added to the 320926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)// SQLTransactionCoordinator's CoordinationInfo's pendingTransactions. 321926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)// - To clean up, during shutdown, DatabaseThread::databaseThread() calls 322926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)// SQLTransactionCoordinator::shutdown(), which calls 323926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)// notifyDatabaseThreadIsShuttingDown(). 324926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)// 325926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)// Phase 4: After "lockAcquired", before state CleanupAndTerminate 326926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)// 327926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)// - In this phase, the transaction would have been added either to the 328926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)// SQLTransactionCoordinator's CoordinationInfo's activeWriteTransaction 329926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)// or activeReadTransactions. 330926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)// - To clean up, during shutdown, DatabaseThread::databaseThread() calls 331926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)// SQLTransactionCoordinator::shutdown(), which calls 332926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)// notifyDatabaseThreadIsShuttingDown(). 333926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)// 334926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)// Phase 5: After state CleanupAndTerminate 335926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)// 336926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)// - This is how a transaction ends normally. 337926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)// - state CleanupAndTerminate calls doCleanup(). 338926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) 339926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) 340c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)namespace blink { 341926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) 3427242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano TucciPassRefPtrWillBeRawPtr<SQLTransactionBackend> SQLTransactionBackend::create(Database* db, 3437242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci PassRefPtrWillBeRawPtr<SQLTransaction> frontend, 34407a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch PassRefPtrWillBeRawPtr<SQLTransactionWrapper> wrapper, 34507a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch bool readOnly) 346926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles){ 34743e7502580f146aa5b3db8267ba6dbb5c733a489Torne (Richard Coles) return adoptRefWillBeNoop(new SQLTransactionBackend(db, frontend, wrapper, readOnly)); 348926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)} 349926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) 3507242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano TucciSQLTransactionBackend::SQLTransactionBackend(Database* db, 3517242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci PassRefPtrWillBeRawPtr<SQLTransaction> frontend, 35207a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch PassRefPtrWillBeRawPtr<SQLTransactionWrapper> wrapper, 35307a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch bool readOnly) 354926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) : m_frontend(frontend) 355926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) , m_database(db) 356926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) , m_wrapper(wrapper) 357926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) , m_hasCallback(m_frontend->hasCallback()) 358926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) , m_hasSuccessCallback(m_frontend->hasSuccessCallback()) 359926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) , m_hasErrorCallback(m_frontend->hasErrorCallback()) 360926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) , m_shouldRetryCurrentStatement(false) 361926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) , m_modifiedDatabase(false) 362926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) , m_lockAcquired(false) 363926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) , m_readOnly(readOnly) 364926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) , m_hasVersionMismatch(false) 365926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles){ 366926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) ASSERT(m_database); 367926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) m_frontend->setBackend(this); 368926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) m_requestedState = SQLTransactionState::AcquireLock; 369926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)} 370926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) 371926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)SQLTransactionBackend::~SQLTransactionBackend() 372926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles){ 373926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) ASSERT(!m_sqliteTransaction); 374926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)} 375926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) 37643e7502580f146aa5b3db8267ba6dbb5c733a489Torne (Richard Coles)void SQLTransactionBackend::trace(Visitor* visitor) 37743e7502580f146aa5b3db8267ba6dbb5c733a489Torne (Richard Coles){ 37843e7502580f146aa5b3db8267ba6dbb5c733a489Torne (Richard Coles) visitor->trace(m_frontend); 37943e7502580f146aa5b3db8267ba6dbb5c733a489Torne (Richard Coles) visitor->trace(m_currentStatementBackend); 38043e7502580f146aa5b3db8267ba6dbb5c733a489Torne (Richard Coles) visitor->trace(m_database); 38107a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch visitor->trace(m_wrapper); 38243e7502580f146aa5b3db8267ba6dbb5c733a489Torne (Richard Coles) visitor->trace(m_statementQueue); 38343e7502580f146aa5b3db8267ba6dbb5c733a489Torne (Richard Coles)} 38443e7502580f146aa5b3db8267ba6dbb5c733a489Torne (Richard Coles) 385926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)void SQLTransactionBackend::doCleanup() 386926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles){ 387926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) if (!m_frontend) 388926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) return; 389d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) m_frontend = nullptr; // Break the reference cycle. See comment about the life-cycle above. 390926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) 39151b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles) ASSERT(database()->databaseContext()->databaseThread()->isDatabaseThread()); 392926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) 393926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) MutexLocker locker(m_statementMutex); 394926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) m_statementQueue.clear(); 395926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) 396926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) if (m_sqliteTransaction) { 397926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) // In the event we got here because of an interruption or error (i.e. if 398926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) // the transaction is in progress), we should roll it back here. Clearing 399926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) // m_sqliteTransaction invokes SQLiteTransaction's destructor which does 400926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) // just that. We might as well do this unconditionally and free up its 401926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) // resources because we're already terminating. 402926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) m_sqliteTransaction.clear(); 403926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) } 404926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) 405926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) // Release the lock on this database 406926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) if (m_lockAcquired) 407926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) m_database->transactionCoordinator()->releaseLock(this); 408926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) 409926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) // Do some aggresive clean up here except for m_database. 410926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) // 411926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) // We can't clear m_database here because the frontend may asynchronously 412926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) // invoke SQLTransactionBackend::requestTransitToState(), and that function 413926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) // uses m_database to schedule a state transition. This may occur because 414926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) // the frontend (being in another thread) may already be on the way to 415926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) // requesting our next state before it detects an interruption. 416926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) // 417926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) // There is no harm in letting it finish making the request. It'll set 418926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) // m_requestedState, but we won't execute a transition to that state because 419926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) // we've already shut down the transaction. 420926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) // 421926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) // We also can't clear m_currentStatementBackend and m_transactionError. 422926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) // m_currentStatementBackend may be accessed asynchronously by the 423926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) // frontend's deliverStatementCallback() state. Similarly, 424926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) // m_transactionError may be accessed by deliverTransactionErrorCallback(). 425926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) // This occurs if requests for transition to those states have already been 426926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) // registered with the frontend just prior to a clean up request arriving. 427926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) // 428926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) // So instead, let our destructor handle their clean up since this 429926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) // SQLTransactionBackend is guaranteed to not destruct until the frontend 430926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) // is also destructing. 431926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) 432d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) m_wrapper = nullptr; 433926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)} 434926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) 4357242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano TucciSQLStatement* SQLTransactionBackend::currentStatement() 436926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles){ 437926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) return m_currentStatementBackend->frontend(); 438926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)} 439926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) 44007a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben MurdochSQLErrorData* SQLTransactionBackend::transactionError() 441926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles){ 44207a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch return m_transactionError.get(); 443926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)} 444926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) 445926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)void SQLTransactionBackend::setShouldRetryCurrentStatement(bool shouldRetry) 446926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles){ 447926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) ASSERT(!m_shouldRetryCurrentStatement); 448926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) m_shouldRetryCurrentStatement = shouldRetry; 449926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)} 450926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) 451926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)SQLTransactionBackend::StateFunction SQLTransactionBackend::stateFunctionFor(SQLTransactionState state) 452926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles){ 453926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) static const StateFunction stateFunctions[] = { 454926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) &SQLTransactionBackend::unreachableState, // 0. end 455926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) &SQLTransactionBackend::unreachableState, // 1. idle 456926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) &SQLTransactionBackend::acquireLock, // 2. 457926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) &SQLTransactionBackend::openTransactionAndPreflight, // 3. 458926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) &SQLTransactionBackend::runStatements, // 4. 459926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) &SQLTransactionBackend::postflightAndCommit, // 5. 460926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) &SQLTransactionBackend::cleanupAndTerminate, // 6. 461926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) &SQLTransactionBackend::cleanupAfterTransactionErrorCallback, // 7. 462926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) &SQLTransactionBackend::sendToFrontendState, // 8. deliverTransactionCallback 463926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) &SQLTransactionBackend::sendToFrontendState, // 9. deliverTransactionErrorCallback 464926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) &SQLTransactionBackend::sendToFrontendState, // 10. deliverStatementCallback 465926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) &SQLTransactionBackend::sendToFrontendState, // 11. deliverQuotaIncreaseCallback 466926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) &SQLTransactionBackend::sendToFrontendState // 12. deliverSuccessCallback 467926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) }; 468926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) 469926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) ASSERT(WTF_ARRAY_LENGTH(stateFunctions) == static_cast<int>(SQLTransactionState::NumberOfStates)); 470926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) ASSERT(state < SQLTransactionState::NumberOfStates); 471926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) 472926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) return stateFunctions[static_cast<int>(state)]; 473926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)} 474926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) 47543e7502580f146aa5b3db8267ba6dbb5c733a489Torne (Richard Coles)void SQLTransactionBackend::enqueueStatementBackend(PassRefPtrWillBeRawPtr<SQLStatementBackend> statementBackend) 476926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles){ 477926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) MutexLocker locker(m_statementMutex); 478926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) m_statementQueue.append(statementBackend); 479926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)} 480926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) 481926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)void SQLTransactionBackend::computeNextStateAndCleanupIfNeeded() 482926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles){ 483926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) // Only honor the requested state transition if we're not supposed to be 484926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) // cleaning up and shutting down: 4857242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci if (m_database->opened()) { 486926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) setStateToRequestedState(); 487926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) ASSERT(m_nextState == SQLTransactionState::AcquireLock 488926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) || m_nextState == SQLTransactionState::OpenTransactionAndPreflight 489926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) || m_nextState == SQLTransactionState::RunStatements 490926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) || m_nextState == SQLTransactionState::PostflightAndCommit 491926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) || m_nextState == SQLTransactionState::CleanupAndTerminate 492926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) || m_nextState == SQLTransactionState::CleanupAfterTransactionErrorCallback); 493926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) 494a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) WTF_LOG(StorageAPI, "State %s\n", nameForSQLTransactionState(m_nextState)); 495926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) return; 496926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) } 497926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) 498926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) // If we get here, then we should be shutting down. Do clean up if needed: 499926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) if (m_nextState == SQLTransactionState::End) 500926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) return; 501926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) m_nextState = SQLTransactionState::End; 502926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) 503926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) // If the database was stopped, don't do anything and cancel queued work 504a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) WTF_LOG(StorageAPI, "Database was stopped or interrupted - cancelling work for this transaction"); 505926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) 506926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) // The current SQLite transaction should be stopped, as well 507926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) if (m_sqliteTransaction) { 508926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) m_sqliteTransaction->stop(); 509926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) m_sqliteTransaction.clear(); 510926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) } 511926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) 512926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) // Terminate the frontend state machine. This also gets the frontend to 513926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) // call computeNextStateAndCleanupIfNeeded() and clear its wrappers 514926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) // if needed. 515926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) m_frontend->requestTransitToState(SQLTransactionState::End); 516926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) 517926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) // Redirect to the end state to abort, clean up, and end the transaction. 518926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) doCleanup(); 519926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)} 520926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) 521926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)void SQLTransactionBackend::performNextStep() 522926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles){ 523926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) computeNextStateAndCleanupIfNeeded(); 524926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) runStateMachine(); 525926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)} 526926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) 5277242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tuccivoid SQLTransactionBackend::executeSQL(PassOwnPtrWillBeRawPtr<SQLStatement> statement, 528926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) const String& sqlStatement, const Vector<SQLValue>& arguments, int permissions) 529926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles){ 53043e7502580f146aa5b3db8267ba6dbb5c733a489Torne (Richard Coles) enqueueStatementBackend(SQLStatementBackend::create(statement, sqlStatement, arguments, permissions)); 531926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)} 532926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) 533926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)void SQLTransactionBackend::notifyDatabaseThreadIsShuttingDown() 534926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles){ 53551b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles) ASSERT(database()->databaseContext()->databaseThread()->isDatabaseThread()); 536926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) 537926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) // If the transaction is in progress, we should roll it back here, since this 538926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) // is our last opportunity to do something related to this transaction on the 539926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) // DB thread. Amongst other work, doCleanup() will clear m_sqliteTransaction 540926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) // which invokes SQLiteTransaction's destructor, which will do the roll back 541926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) // if necessary. 542926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) doCleanup(); 543926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)} 544926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) 545926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)SQLTransactionState SQLTransactionBackend::acquireLock() 546926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles){ 547926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) m_database->transactionCoordinator()->acquireLock(this); 548926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) return SQLTransactionState::Idle; 549926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)} 550926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) 551926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)void SQLTransactionBackend::lockAcquired() 552926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles){ 553926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) m_lockAcquired = true; 554926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) requestTransitToState(SQLTransactionState::OpenTransactionAndPreflight); 555926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)} 556926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) 557926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)SQLTransactionState SQLTransactionBackend::openTransactionAndPreflight() 558926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles){ 559926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) ASSERT(!m_database->sqliteDatabase().transactionInProgress()); 560926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) ASSERT(m_lockAcquired); 561926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) 562a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) WTF_LOG(StorageAPI, "Opening and preflighting transaction %p", this); 563926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) 564926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) // Set the maximum usage for this transaction if this transactions is not read-only 56553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) if (!m_readOnly) 566926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) m_database->sqliteDatabase().setMaximumSize(m_database->maximumSize()); 567926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) 568926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) ASSERT(!m_sqliteTransaction); 569926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) m_sqliteTransaction = adoptPtr(new SQLiteTransaction(m_database->sqliteDatabase(), m_readOnly)); 570926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) 571926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) m_database->resetDeletes(); 572926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) m_database->disableAuthorizer(); 573926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) m_sqliteTransaction->begin(); 574926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) m_database->enableAuthorizer(); 575926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) 576926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) // Spec 4.3.2.1+2: Open a transaction to the database, jumping to the error callback if that fails 577926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) if (!m_sqliteTransaction->inProgress()) { 578926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) ASSERT(!m_database->sqliteDatabase().transactionInProgress()); 579926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) m_database->reportStartTransactionResult(2, SQLError::DATABASE_ERR, m_database->sqliteDatabase().lastError()); 58007a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch m_transactionError = SQLErrorData::create(SQLError::DATABASE_ERR, "unable to begin transaction", 581926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) m_database->sqliteDatabase().lastError(), m_database->sqliteDatabase().lastErrorMsg()); 582926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) m_sqliteTransaction.clear(); 583926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) return nextStateForTransactionError(); 584926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) } 585926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) 586926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) // Note: We intentionally retrieve the actual version even with an empty expected version. 587926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) // In multi-process browsers, we take this opportinutiy to update the cached value for 588926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) // the actual version. In single-process browsers, this is just a map lookup. 589926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) String actualVersion; 590926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) if (!m_database->getActualVersionForTransaction(actualVersion)) { 591926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) m_database->reportStartTransactionResult(3, SQLError::DATABASE_ERR, m_database->sqliteDatabase().lastError()); 59207a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch m_transactionError = SQLErrorData::create(SQLError::DATABASE_ERR, "unable to read version", 593926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) m_database->sqliteDatabase().lastError(), m_database->sqliteDatabase().lastErrorMsg()); 594926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) m_database->disableAuthorizer(); 595926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) m_sqliteTransaction.clear(); 596926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) m_database->enableAuthorizer(); 597926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) return nextStateForTransactionError(); 598926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) } 599926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) m_hasVersionMismatch = !m_database->expectedVersion().isEmpty() && (m_database->expectedVersion() != actualVersion); 600926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) 601926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) // Spec 4.3.2.3: Perform preflight steps, jumping to the error callback if they fail 602926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) if (m_wrapper && !m_wrapper->performPreflight(this)) { 603926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) m_database->disableAuthorizer(); 604926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) m_sqliteTransaction.clear(); 605926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) m_database->enableAuthorizer(); 60607a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch if (m_wrapper->sqlError()) { 60707a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch m_transactionError = SQLErrorData::create(*m_wrapper->sqlError()); 60807a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch } else { 609926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) m_database->reportStartTransactionResult(4, SQLError::UNKNOWN_ERR, 0); 61007a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch m_transactionError = SQLErrorData::create(SQLError::UNKNOWN_ERR, "unknown error occurred during transaction preflight"); 611926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) } 612926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) return nextStateForTransactionError(); 613926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) } 614926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) 615926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) // Spec 4.3.2.4: Invoke the transaction callback with the new SQLTransaction object 616926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) if (m_hasCallback) 617926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) return SQLTransactionState::DeliverTransactionCallback; 618926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) 619926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) // If we have no callback to make, skip pass to the state after: 620926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) return SQLTransactionState::RunStatements; 621926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)} 622926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) 623926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)SQLTransactionState SQLTransactionBackend::runStatements() 624926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles){ 625926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) ASSERT(m_lockAcquired); 626926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) SQLTransactionState nextState; 627926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) 628926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) // If there is a series of statements queued up that are all successful and have no associated 629926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) // SQLStatementCallback objects, then we can burn through the queue 630926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) do { 631926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) if (m_shouldRetryCurrentStatement && !m_sqliteTransaction->wasRolledBackBySqlite()) { 632926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) m_shouldRetryCurrentStatement = false; 633926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) // FIXME - Another place that needs fixing up after <rdar://problem/5628468> is addressed. 634926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) // See ::openTransactionAndPreflight() for discussion 635926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) 636926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) // Reset the maximum size here, as it was increased to allow us to retry this statement. 637926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) // m_shouldRetryCurrentStatement is set to true only when a statement exceeds 638926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) // the quota, which can happen only in a read-write transaction. Therefore, there 639926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) // is no need to check here if the transaction is read-write. 640926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) m_database->sqliteDatabase().setMaximumSize(m_database->maximumSize()); 641926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) } else { 642926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) // If the current statement has already been run, failed due to quota constraints, and we're not retrying it, 643926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) // that means it ended in an error. Handle it now 644926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) if (m_currentStatementBackend && m_currentStatementBackend->lastExecutionFailedDueToQuota()) { 645926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) return nextStateForCurrentStatementError(); 646926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) } 647926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) 648926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) // Otherwise, advance to the next statement 649926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) getNextStatement(); 650926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) } 651926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) nextState = runCurrentStatementAndGetNextState(); 652926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) } while (nextState == SQLTransactionState::RunStatements); 653926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) 654926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) return nextState; 655926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)} 656926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) 657926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)void SQLTransactionBackend::getNextStatement() 658926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles){ 659d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) m_currentStatementBackend = nullptr; 660926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) 661926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) MutexLocker locker(m_statementMutex); 662926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) if (!m_statementQueue.isEmpty()) 663926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) m_currentStatementBackend = m_statementQueue.takeFirst(); 664926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)} 665926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) 666926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)SQLTransactionState SQLTransactionBackend::runCurrentStatementAndGetNextState() 667926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles){ 668926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) if (!m_currentStatementBackend) { 669926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) // No more statements to run. So move on to the next state. 670926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) return SQLTransactionState::PostflightAndCommit; 671926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) } 672926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) 673926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) m_database->resetAuthorizer(); 674926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) 675926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) if (m_hasVersionMismatch) 6767242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci m_currentStatementBackend->setVersionMismatchedError(m_database.get()); 677926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) 678926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) if (m_currentStatementBackend->execute(m_database.get())) { 679926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) if (m_database->lastActionChangedDatabase()) { 680926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) // Flag this transaction as having changed the database for later delegate notification 681926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) m_modifiedDatabase = true; 682926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) } 683926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) 684926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) if (m_currentStatementBackend->hasStatementCallback()) { 685926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) return SQLTransactionState::DeliverStatementCallback; 686926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) } 687926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) 688926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) // If we get here, then the statement doesn't have a callback to invoke. 689926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) // We can move on to the next statement. Hence, stay in this state. 690926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) return SQLTransactionState::RunStatements; 691926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) } 692926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) 693926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) if (m_currentStatementBackend->lastExecutionFailedDueToQuota()) { 694926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) return SQLTransactionState::DeliverQuotaIncreaseCallback; 695926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) } 696926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) 697926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) return nextStateForCurrentStatementError(); 698926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)} 699926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) 700926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)SQLTransactionState SQLTransactionBackend::nextStateForCurrentStatementError() 701926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles){ 702926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) // Spec 4.3.2.6.6: error - Call the statement's error callback, but if there was no error callback, 703926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) // or the transaction was rolled back, jump to the transaction error callback 704926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) if (m_currentStatementBackend->hasStatementErrorCallback() && !m_sqliteTransaction->wasRolledBackBySqlite()) 705926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) return SQLTransactionState::DeliverStatementCallback; 706926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) 70707a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch if (m_currentStatementBackend->sqlError()) { 70807a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch m_transactionError = SQLErrorData::create(*m_currentStatementBackend->sqlError()); 70907a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch } else { 710926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) m_database->reportCommitTransactionResult(1, SQLError::DATABASE_ERR, 0); 71107a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch m_transactionError = SQLErrorData::create(SQLError::DATABASE_ERR, "the statement failed to execute"); 712926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) } 713926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) return nextStateForTransactionError(); 714926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)} 715926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) 716926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)SQLTransactionState SQLTransactionBackend::postflightAndCommit() 717926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles){ 718926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) ASSERT(m_lockAcquired); 719926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) 720926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) // Spec 4.3.2.7: Perform postflight steps, jumping to the error callback if they fail. 721926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) if (m_wrapper && !m_wrapper->performPostflight(this)) { 72207a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch if (m_wrapper->sqlError()) { 72307a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch m_transactionError = SQLErrorData::create(*m_wrapper->sqlError()); 72407a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch } else { 725926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) m_database->reportCommitTransactionResult(3, SQLError::UNKNOWN_ERR, 0); 72607a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch m_transactionError = SQLErrorData::create(SQLError::UNKNOWN_ERR, "unknown error occurred during transaction postflight"); 727926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) } 728926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) return nextStateForTransactionError(); 729926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) } 730926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) 731926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) // Spec 4.3.2.7: Commit the transaction, jumping to the error callback if that fails. 732926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) ASSERT(m_sqliteTransaction); 733926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) 734926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) m_database->disableAuthorizer(); 735926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) m_sqliteTransaction->commit(); 736926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) m_database->enableAuthorizer(); 737926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) 738926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) // If the commit failed, the transaction will still be marked as "in progress" 739926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) if (m_sqliteTransaction->inProgress()) { 740926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) if (m_wrapper) 741926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) m_wrapper->handleCommitFailedAfterPostflight(this); 742926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) m_database->reportCommitTransactionResult(4, SQLError::DATABASE_ERR, m_database->sqliteDatabase().lastError()); 74307a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch m_transactionError = SQLErrorData::create(SQLError::DATABASE_ERR, "unable to commit transaction", 744926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) m_database->sqliteDatabase().lastError(), m_database->sqliteDatabase().lastErrorMsg()); 745926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) return nextStateForTransactionError(); 746926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) } 747926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) 748926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) m_database->reportCommitTransactionResult(0, -1, 0); // OK 749926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) 750926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) // Vacuum the database if anything was deleted. 751926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) if (m_database->hadDeletes()) 752926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) m_database->incrementalVacuumIfNeeded(); 753926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) 754926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) // The commit was successful. If the transaction modified this database, notify the delegates. 755926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) if (m_modifiedDatabase) 756926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) m_database->transactionClient()->didCommitWriteTransaction(database()); 757926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) 758926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) // Spec 4.3.2.8: Deliver success callback, if there is one. 759926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) return SQLTransactionState::DeliverSuccessCallback; 760926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)} 761926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) 762926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)SQLTransactionState SQLTransactionBackend::cleanupAndTerminate() 763926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles){ 764926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) ASSERT(m_lockAcquired); 765926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) 766926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) // Spec 4.3.2.9: End transaction steps. There is no next step. 767a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) WTF_LOG(StorageAPI, "Transaction %p is complete\n", this); 768926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) ASSERT(!m_database->sqliteDatabase().transactionInProgress()); 769926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) 770926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) // Phase 5 cleanup. See comment on the SQLTransaction life-cycle above. 771926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) doCleanup(); 772926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) m_database->inProgressTransactionCompleted(); 773926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) return SQLTransactionState::End; 774926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)} 775926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) 776926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)SQLTransactionState SQLTransactionBackend::nextStateForTransactionError() 777926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles){ 778926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) ASSERT(m_transactionError); 779926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) if (m_hasErrorCallback) 780926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) return SQLTransactionState::DeliverTransactionErrorCallback; 781926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) 782926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) // No error callback, so fast-forward to the next state and rollback the 783926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) // transaction. 784926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) return SQLTransactionState::CleanupAfterTransactionErrorCallback; 785926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)} 786926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) 787926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)SQLTransactionState SQLTransactionBackend::cleanupAfterTransactionErrorCallback() 788926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles){ 789926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) ASSERT(m_lockAcquired); 790926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) 791a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) WTF_LOG(StorageAPI, "Transaction %p is complete with an error\n", this); 792926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) m_database->disableAuthorizer(); 793926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) if (m_sqliteTransaction) { 794926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) // Spec 4.3.2.10: Rollback the transaction. 795926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) m_sqliteTransaction->rollback(); 796926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) 797926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) ASSERT(!m_database->sqliteDatabase().transactionInProgress()); 798926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) m_sqliteTransaction.clear(); 799926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) } 800926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) m_database->enableAuthorizer(); 801926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) 802926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) ASSERT(!m_database->sqliteDatabase().transactionInProgress()); 803926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) 804926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) return SQLTransactionState::CleanupAndTerminate; 805926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)} 806926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) 807926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)// requestTransitToState() can be called from the frontend. Hence, it should 808926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)// NOT be modifying SQLTransactionBackend in general. The only safe field to 809926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)// modify is m_requestedState which is meant for this purpose. 810926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)void SQLTransactionBackend::requestTransitToState(SQLTransactionState nextState) 811926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles){ 812a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) WTF_LOG(StorageAPI, "Scheduling %s for transaction %p\n", nameForSQLTransactionState(nextState), this); 813926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) m_requestedState = nextState; 814926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) ASSERT(m_requestedState != SQLTransactionState::End); 815926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) m_database->scheduleTransactionStep(this); 816926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)} 817926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) 818926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)// This state function is used as a stub function to plug unimplemented states 819926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)// in the state dispatch table. They are unimplemented because they should 820926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)// never be reached in the course of correct execution. 821926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)SQLTransactionState SQLTransactionBackend::unreachableState() 822926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles){ 823926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) ASSERT_NOT_REACHED(); 824926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) return SQLTransactionState::End; 825926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)} 826926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) 827926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)SQLTransactionState SQLTransactionBackend::sendToFrontendState() 828926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles){ 829926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) ASSERT(m_nextState != SQLTransactionState::Idle); 830926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) m_frontend->requestTransitToState(m_nextState); 831926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) return SQLTransactionState::Idle; 832926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)} 833926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) 834c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)} // namespace blink 835