OLD | NEW |
1 /* | 1 /* |
2 * Copyright (C) 2007, 2008, 2013 Apple Inc. All rights reserved. | 2 * Copyright (C) 2007, 2008, 2013 Apple Inc. All rights reserved. |
3 * | 3 * |
4 * Redistribution and use in source and binary forms, with or without | 4 * Redistribution and use in source and binary forms, with or without |
5 * modification, are permitted provided that the following conditions | 5 * modification, are permitted provided that the following conditions |
6 * are met: | 6 * are met: |
7 * | 7 * |
8 * 1. Redistributions of source code must retain the above copyright | 8 * 1. Redistributions of source code must retain the above copyright |
9 * notice, this list of conditions and the following disclaimer. | 9 * notice, this list of conditions and the following disclaimer. |
10 * 2. Redistributions in binary form must reproduce the above copyright | 10 * 2. Redistributions in binary form must reproduce the above copyright |
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
64 VoidCallback* success_callback, | 64 VoidCallback* success_callback, |
65 SQLTransactionErrorCallback* error_callback, | 65 SQLTransactionErrorCallback* error_callback, |
66 bool read_only) | 66 bool read_only) |
67 : database_(db), | 67 : database_(db), |
68 callback_(callback), | 68 callback_(callback), |
69 success_callback_(success_callback), | 69 success_callback_(success_callback), |
70 error_callback_(error_callback), | 70 error_callback_(error_callback), |
71 execute_sql_allowed_(false), | 71 execute_sql_allowed_(false), |
72 read_only_(read_only) { | 72 read_only_(read_only) { |
73 DCHECK(IsMainThread()); | 73 DCHECK(IsMainThread()); |
74 ASSERT(database_); | 74 DCHECK(database_); |
75 probe::AsyncTaskScheduled(db->GetExecutionContext(), "SQLTransaction", this); | 75 probe::AsyncTaskScheduled(db->GetExecutionContext(), "SQLTransaction", this); |
76 } | 76 } |
77 | 77 |
78 SQLTransaction::~SQLTransaction() {} | 78 SQLTransaction::~SQLTransaction() {} |
79 | 79 |
80 DEFINE_TRACE(SQLTransaction) { | 80 DEFINE_TRACE(SQLTransaction) { |
81 visitor->Trace(database_); | 81 visitor->Trace(database_); |
82 visitor->Trace(backend_); | 82 visitor->Trace(backend_); |
83 visitor->Trace(callback_); | 83 visitor->Trace(callback_); |
84 visitor->Trace(success_callback_); | 84 visitor->Trace(success_callback_); |
85 visitor->Trace(error_callback_); | 85 visitor->Trace(error_callback_); |
86 } | 86 } |
87 | 87 |
88 bool SQLTransaction::HasCallback() const { | 88 bool SQLTransaction::HasCallback() const { |
89 return callback_; | 89 return callback_; |
90 } | 90 } |
91 | 91 |
92 bool SQLTransaction::HasSuccessCallback() const { | 92 bool SQLTransaction::HasSuccessCallback() const { |
93 return success_callback_; | 93 return success_callback_; |
94 } | 94 } |
95 | 95 |
96 bool SQLTransaction::HasErrorCallback() const { | 96 bool SQLTransaction::HasErrorCallback() const { |
97 return error_callback_; | 97 return error_callback_; |
98 } | 98 } |
99 | 99 |
100 void SQLTransaction::SetBackend(SQLTransactionBackend* backend) { | 100 void SQLTransaction::SetBackend(SQLTransactionBackend* backend) { |
101 ASSERT(!backend_); | 101 DCHECK(!backend_); |
102 backend_ = backend; | 102 backend_ = backend; |
103 } | 103 } |
104 | 104 |
105 SQLTransaction::StateFunction SQLTransaction::StateFunctionFor( | 105 SQLTransaction::StateFunction SQLTransaction::StateFunctionFor( |
106 SQLTransactionState state) { | 106 SQLTransactionState state) { |
107 static const StateFunction kStateFunctions[] = { | 107 static const StateFunction kStateFunctions[] = { |
108 &SQLTransaction::UnreachableState, // 0. illegal | 108 &SQLTransaction::UnreachableState, // 0. illegal |
109 &SQLTransaction::UnreachableState, // 1. idle | 109 &SQLTransaction::UnreachableState, // 1. idle |
110 &SQLTransaction::UnreachableState, // 2. acquireLock | 110 &SQLTransaction::UnreachableState, // 2. acquireLock |
111 &SQLTransaction::UnreachableState, // 3. openTransactionAndPreflight | 111 &SQLTransaction::UnreachableState, // 3. openTransactionAndPreflight |
112 &SQLTransaction::SendToBackendState, // 4. runStatements | 112 &SQLTransaction::SendToBackendState, // 4. runStatements |
113 &SQLTransaction::UnreachableState, // 5. postflightAndCommit | 113 &SQLTransaction::UnreachableState, // 5. postflightAndCommit |
114 &SQLTransaction::SendToBackendState, // 6. cleanupAndTerminate | 114 &SQLTransaction::SendToBackendState, // 6. cleanupAndTerminate |
115 &SQLTransaction:: | 115 &SQLTransaction:: |
116 SendToBackendState, // 7. cleanupAfterTransactionErrorCallback | 116 SendToBackendState, // 7. cleanupAfterTransactionErrorCallback |
117 &SQLTransaction::DeliverTransactionCallback, // 8. | 117 &SQLTransaction::DeliverTransactionCallback, // 8. |
118 &SQLTransaction::DeliverTransactionErrorCallback, // 9. | 118 &SQLTransaction::DeliverTransactionErrorCallback, // 9. |
119 &SQLTransaction::DeliverStatementCallback, // 10. | 119 &SQLTransaction::DeliverStatementCallback, // 10. |
120 &SQLTransaction::DeliverQuotaIncreaseCallback, // 11. | 120 &SQLTransaction::DeliverQuotaIncreaseCallback, // 11. |
121 &SQLTransaction::DeliverSuccessCallback // 12. | 121 &SQLTransaction::DeliverSuccessCallback // 12. |
122 }; | 122 }; |
123 | 123 |
124 ASSERT(WTF_ARRAY_LENGTH(kStateFunctions) == | 124 DCHECK(WTF_ARRAY_LENGTH(kStateFunctions) == |
125 static_cast<int>(SQLTransactionState::kNumberOfStates)); | 125 static_cast<int>(SQLTransactionState::kNumberOfStates)); |
126 ASSERT(state < SQLTransactionState::kNumberOfStates); | 126 DCHECK(state < SQLTransactionState::kNumberOfStates); |
127 | 127 |
128 return kStateFunctions[static_cast<int>(state)]; | 128 return kStateFunctions[static_cast<int>(state)]; |
129 } | 129 } |
130 | 130 |
131 // requestTransitToState() can be called from the backend. Hence, it should | 131 // requestTransitToState() can be called from the backend. Hence, it should |
132 // NOT be modifying SQLTransactionBackend in general. The only safe field to | 132 // NOT be modifying SQLTransactionBackend in general. The only safe field to |
133 // modify is m_requestedState which is meant for this purpose. | 133 // modify is m_requestedState which is meant for this purpose. |
134 void SQLTransaction::RequestTransitToState(SQLTransactionState next_state) { | 134 void SQLTransaction::RequestTransitToState(SQLTransactionState next_state) { |
135 #if DCHECK_IS_ON() | 135 #if DCHECK_IS_ON() |
136 STORAGE_DVLOG(1) << "Scheduling " << NameForSQLTransactionState(next_state) | 136 STORAGE_DVLOG(1) << "Scheduling " << NameForSQLTransactionState(next_state) |
137 << " for transaction " << this; | 137 << " for transaction " << this; |
138 #endif | 138 #endif |
139 requested_state_ = next_state; | 139 requested_state_ = next_state; |
140 database_->ScheduleTransactionCallback(this); | 140 database_->ScheduleTransactionCallback(this); |
141 } | 141 } |
142 | 142 |
143 SQLTransactionState SQLTransaction::NextStateForTransactionError() { | 143 SQLTransactionState SQLTransaction::NextStateForTransactionError() { |
144 ASSERT(transaction_error_); | 144 DCHECK(transaction_error_); |
145 if (HasErrorCallback()) | 145 if (HasErrorCallback()) |
146 return SQLTransactionState::kDeliverTransactionErrorCallback; | 146 return SQLTransactionState::kDeliverTransactionErrorCallback; |
147 | 147 |
148 // No error callback, so fast-forward to: | 148 // No error callback, so fast-forward to: |
149 // Transaction Step 11 - Rollback the transaction. | 149 // Transaction Step 11 - Rollback the transaction. |
150 return SQLTransactionState::kCleanupAfterTransactionErrorCallback; | 150 return SQLTransactionState::kCleanupAfterTransactionErrorCallback; |
151 } | 151 } |
152 | 152 |
153 SQLTransactionState SQLTransaction::DeliverTransactionCallback() { | 153 SQLTransactionState SQLTransaction::DeliverTransactionCallback() { |
154 bool should_deliver_error_callback = false; | 154 bool should_deliver_error_callback = false; |
(...skipping 26 matching lines...) Expand all Loading... |
181 probe::AsyncTask async_task(database_->GetExecutionContext(), this); | 181 probe::AsyncTask async_task(database_->GetExecutionContext(), this); |
182 | 182 |
183 // Spec 4.3.2.10: If exists, invoke error callback with the last | 183 // Spec 4.3.2.10: If exists, invoke error callback with the last |
184 // error to have occurred in this transaction. | 184 // error to have occurred in this transaction. |
185 if (SQLTransactionErrorCallback* error_callback = error_callback_.Release()) { | 185 if (SQLTransactionErrorCallback* error_callback = error_callback_.Release()) { |
186 // If we get here with an empty m_transactionError, then the backend | 186 // If we get here with an empty m_transactionError, then the backend |
187 // must be waiting in the idle state waiting for this state to finish. | 187 // must be waiting in the idle state waiting for this state to finish. |
188 // Hence, it's thread safe to fetch the backend transactionError without | 188 // Hence, it's thread safe to fetch the backend transactionError without |
189 // a lock. | 189 // a lock. |
190 if (!transaction_error_) { | 190 if (!transaction_error_) { |
191 ASSERT(backend_->TransactionError()); | 191 DCHECK(backend_->TransactionError()); |
192 transaction_error_ = SQLErrorData::Create(*backend_->TransactionError()); | 192 transaction_error_ = SQLErrorData::Create(*backend_->TransactionError()); |
193 } | 193 } |
194 ASSERT(transaction_error_); | 194 DCHECK(transaction_error_); |
195 error_callback->handleEvent(SQLError::Create(*transaction_error_)); | 195 error_callback->handleEvent(SQLError::Create(*transaction_error_)); |
196 | 196 |
197 transaction_error_ = nullptr; | 197 transaction_error_ = nullptr; |
198 } | 198 } |
199 | 199 |
200 ClearCallbacks(); | 200 ClearCallbacks(); |
201 | 201 |
202 // Spec 4.3.2.10: Rollback the transaction. | 202 // Spec 4.3.2.10: Rollback the transaction. |
203 return SQLTransactionState::kCleanupAfterTransactionErrorCallback; | 203 return SQLTransactionState::kCleanupAfterTransactionErrorCallback; |
204 } | 204 } |
205 | 205 |
206 SQLTransactionState SQLTransaction::DeliverStatementCallback() { | 206 SQLTransactionState SQLTransaction::DeliverStatementCallback() { |
207 DCHECK(IsMainThread()); | 207 DCHECK(IsMainThread()); |
208 // Spec 4.3.2.6.6 and 4.3.2.6.3: If the statement callback went wrong, jump to | 208 // Spec 4.3.2.6.6 and 4.3.2.6.3: If the statement callback went wrong, jump to |
209 // the transaction error callback. Otherwise, continue to loop through the | 209 // the transaction error callback. Otherwise, continue to loop through the |
210 // statement queue. | 210 // statement queue. |
211 execute_sql_allowed_ = true; | 211 execute_sql_allowed_ = true; |
212 | 212 |
213 SQLStatement* current_statement = backend_->CurrentStatement(); | 213 SQLStatement* current_statement = backend_->CurrentStatement(); |
214 ASSERT(current_statement); | 214 DCHECK(current_statement); |
215 | 215 |
216 bool result = current_statement->PerformCallback(this); | 216 bool result = current_statement->PerformCallback(this); |
217 | 217 |
218 execute_sql_allowed_ = false; | 218 execute_sql_allowed_ = false; |
219 | 219 |
220 if (result) { | 220 if (result) { |
221 database_->ReportCommitTransactionResult(2, SQLError::kUnknownErr, 0); | 221 database_->ReportCommitTransactionResult(2, SQLError::kUnknownErr, 0); |
222 transaction_error_ = | 222 transaction_error_ = |
223 SQLErrorData::Create(SQLError::kUnknownErr, | 223 SQLErrorData::Create(SQLError::kUnknownErr, |
224 "the statement callback raised an exception or " | 224 "the statement callback raised an exception or " |
225 "statement error callback did not return false"); | 225 "statement error callback did not return false"); |
226 return NextStateForTransactionError(); | 226 return NextStateForTransactionError(); |
227 } | 227 } |
228 return SQLTransactionState::kRunStatements; | 228 return SQLTransactionState::kRunStatements; |
229 } | 229 } |
230 | 230 |
231 SQLTransactionState SQLTransaction::DeliverQuotaIncreaseCallback() { | 231 SQLTransactionState SQLTransaction::DeliverQuotaIncreaseCallback() { |
232 DCHECK(IsMainThread()); | 232 DCHECK(IsMainThread()); |
233 ASSERT(backend_->CurrentStatement()); | 233 DCHECK(backend_->CurrentStatement()); |
234 | 234 |
235 bool should_retry_current_statement = | 235 bool should_retry_current_statement = |
236 database_->TransactionClient()->DidExceedQuota(GetDatabase()); | 236 database_->TransactionClient()->DidExceedQuota(GetDatabase()); |
237 backend_->SetShouldRetryCurrentStatement(should_retry_current_statement); | 237 backend_->SetShouldRetryCurrentStatement(should_retry_current_statement); |
238 | 238 |
239 return SQLTransactionState::kRunStatements; | 239 return SQLTransactionState::kRunStatements; |
240 } | 240 } |
241 | 241 |
242 SQLTransactionState SQLTransaction::DeliverSuccessCallback() { | 242 SQLTransactionState SQLTransaction::DeliverSuccessCallback() { |
243 DCHECK(IsMainThread()); | 243 DCHECK(IsMainThread()); |
244 probe::AsyncTask async_task(database_->GetExecutionContext(), this); | 244 probe::AsyncTask async_task(database_->GetExecutionContext(), this); |
245 | 245 |
246 // Spec 4.3.2.8: Deliver success callback. | 246 // Spec 4.3.2.8: Deliver success callback. |
247 if (VoidCallback* success_callback = success_callback_.Release()) | 247 if (VoidCallback* success_callback = success_callback_.Release()) |
248 success_callback->handleEvent(); | 248 success_callback->handleEvent(); |
249 | 249 |
250 ClearCallbacks(); | 250 ClearCallbacks(); |
251 | 251 |
252 // Schedule a "post-success callback" step to return control to the database | 252 // Schedule a "post-success callback" step to return control to the database |
253 // thread in case there are further transactions queued up for this Database. | 253 // thread in case there are further transactions queued up for this Database. |
254 return SQLTransactionState::kCleanupAndTerminate; | 254 return SQLTransactionState::kCleanupAndTerminate; |
255 } | 255 } |
256 | 256 |
257 // This state function is used as a stub function to plug unimplemented states | 257 // This state function is used as a stub function to plug unimplemented states |
258 // in the state dispatch table. They are unimplemented because they should | 258 // in the state dispatch table. They are unimplemented because they should |
259 // never be reached in the course of correct execution. | 259 // never be reached in the course of correct execution. |
260 SQLTransactionState SQLTransaction::UnreachableState() { | 260 SQLTransactionState SQLTransaction::UnreachableState() { |
261 ASSERT_NOT_REACHED(); | 261 NOTREACHED(); |
262 return SQLTransactionState::kEnd; | 262 return SQLTransactionState::kEnd; |
263 } | 263 } |
264 | 264 |
265 SQLTransactionState SQLTransaction::SendToBackendState() { | 265 SQLTransactionState SQLTransaction::SendToBackendState() { |
266 ASSERT(next_state_ != SQLTransactionState::kIdle); | 266 DCHECK_NE(next_state_, SQLTransactionState::kIdle); |
267 backend_->RequestTransitToState(next_state_); | 267 backend_->RequestTransitToState(next_state_); |
268 return SQLTransactionState::kIdle; | 268 return SQLTransactionState::kIdle; |
269 } | 269 } |
270 | 270 |
271 void SQLTransaction::PerformPendingCallback() { | 271 void SQLTransaction::PerformPendingCallback() { |
272 DCHECK(IsMainThread()); | 272 DCHECK(IsMainThread()); |
273 ComputeNextStateAndCleanupIfNeeded(); | 273 ComputeNextStateAndCleanupIfNeeded(); |
274 RunStateMachine(); | 274 RunStateMachine(); |
275 } | 275 } |
276 | 276 |
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
322 arguments.Get(), script_state->GetIsolate(), exception_state); | 322 arguments.Get(), script_state->GetIsolate(), exception_state); |
323 ExecuteSQL(sql_statement, sql_values, callback, callback_error, | 323 ExecuteSQL(sql_statement, sql_values, callback, callback_error, |
324 exception_state); | 324 exception_state); |
325 } | 325 } |
326 | 326 |
327 bool SQLTransaction::ComputeNextStateAndCleanupIfNeeded() { | 327 bool SQLTransaction::ComputeNextStateAndCleanupIfNeeded() { |
328 // Only honor the requested state transition if we're not supposed to be | 328 // Only honor the requested state transition if we're not supposed to be |
329 // cleaning up and shutting down: | 329 // cleaning up and shutting down: |
330 if (database_->Opened()) { | 330 if (database_->Opened()) { |
331 SetStateToRequestedState(); | 331 SetStateToRequestedState(); |
332 ASSERT(next_state_ == SQLTransactionState::kEnd || | 332 DCHECK(next_state_ == SQLTransactionState::kEnd || |
333 next_state_ == SQLTransactionState::kDeliverTransactionCallback || | 333 next_state_ == SQLTransactionState::kDeliverTransactionCallback || |
334 next_state_ == | 334 next_state_ == |
335 SQLTransactionState::kDeliverTransactionErrorCallback || | 335 SQLTransactionState::kDeliverTransactionErrorCallback || |
336 next_state_ == SQLTransactionState::kDeliverStatementCallback || | 336 next_state_ == SQLTransactionState::kDeliverStatementCallback || |
337 next_state_ == SQLTransactionState::kDeliverQuotaIncreaseCallback || | 337 next_state_ == SQLTransactionState::kDeliverQuotaIncreaseCallback || |
338 next_state_ == SQLTransactionState::kDeliverSuccessCallback); | 338 next_state_ == SQLTransactionState::kDeliverSuccessCallback); |
339 #if DCHECK_IS_ON() | 339 #if DCHECK_IS_ON() |
340 STORAGE_DVLOG(1) << "Callback " << NameForSQLTransactionState(next_state_); | 340 STORAGE_DVLOG(1) << "Callback " << NameForSQLTransactionState(next_state_); |
341 #endif | 341 #endif |
342 return false; | 342 return false; |
343 } | 343 } |
344 | 344 |
345 ClearCallbacks(); | 345 ClearCallbacks(); |
346 next_state_ = SQLTransactionState::kCleanupAndTerminate; | 346 next_state_ = SQLTransactionState::kCleanupAndTerminate; |
347 | 347 |
348 return true; | 348 return true; |
349 } | 349 } |
350 | 350 |
351 void SQLTransaction::ClearCallbacks() { | 351 void SQLTransaction::ClearCallbacks() { |
352 callback_.Clear(); | 352 callback_.Clear(); |
353 success_callback_.Clear(); | 353 success_callback_.Clear(); |
354 error_callback_.Clear(); | 354 error_callback_.Clear(); |
355 } | 355 } |
356 | 356 |
357 SQLTransactionErrorCallback* SQLTransaction::ReleaseErrorCallback() { | 357 SQLTransactionErrorCallback* SQLTransaction::ReleaseErrorCallback() { |
358 return error_callback_.Release(); | 358 return error_callback_.Release(); |
359 } | 359 } |
360 | 360 |
361 } // namespace blink | 361 } // namespace blink |
OLD | NEW |