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