| 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 |