| OLD | NEW |
| 1 // Copyright 2016 The Chromium Authors. All rights reserved. | 1 // Copyright 2016 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "components/offline_pages/background/request_queue_store_sql.h" | 5 #include "components/offline_pages/background/request_queue_store_sql.h" |
| 6 | 6 |
| 7 #include "base/bind.h" | 7 #include "base/bind.h" |
| 8 #include "base/files/file_path.h" | 8 #include "base/files/file_path.h" |
| 9 #include "base/files/file_util.h" | 9 #include "base/files/file_util.h" |
| 10 #include "base/location.h" | 10 #include "base/location.h" |
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 59 } | 59 } |
| 60 | 60 |
| 61 bool DeleteRequestById(sql::Connection* db, int64_t request_id) { | 61 bool DeleteRequestById(sql::Connection* db, int64_t request_id) { |
| 62 const char kSql[] = | 62 const char kSql[] = |
| 63 "DELETE FROM " REQUEST_QUEUE_TABLE_NAME " WHERE request_id=?"; | 63 "DELETE FROM " REQUEST_QUEUE_TABLE_NAME " WHERE request_id=?"; |
| 64 sql::Statement statement(db->GetCachedStatement(SQL_FROM_HERE, kSql)); | 64 sql::Statement statement(db->GetCachedStatement(SQL_FROM_HERE, kSql)); |
| 65 statement.BindInt64(0, request_id); | 65 statement.BindInt64(0, request_id); |
| 66 return statement.Run(); | 66 return statement.Run(); |
| 67 } | 67 } |
| 68 | 68 |
| 69 bool ChangeRequestState(sql::Connection* db, |
| 70 const int64_t request_id, |
| 71 const SavePageRequest::RequestState new_state) { |
| 72 const char kSql[] = "UPDATE " REQUEST_QUEUE_TABLE_NAME |
| 73 " SET state=?" |
| 74 " WHERE request_id=?"; |
| 75 sql::Statement statement(db->GetCachedStatement(SQL_FROM_HERE, kSql)); |
| 76 statement.BindInt64(0, static_cast<int64_t>(new_state)); |
| 77 statement.BindInt64(1, request_id); |
| 78 return statement.Run(); |
| 79 } |
| 80 |
| 69 bool DeleteRequestsByIds(sql::Connection* db, | 81 bool DeleteRequestsByIds(sql::Connection* db, |
| 70 const std::vector<int64_t>& request_ids, | 82 const std::vector<int64_t>& request_ids, |
| 71 RequestQueue::UpdateMultipleRequestResults& results) { | 83 RequestQueue::UpdateMultipleRequestResults& results) { |
| 72 // If you create a transaction but don't Commit() it is automatically | 84 // If you create a transaction but don't Commit() it is automatically |
| 73 // rolled back by its destructor when it falls out of scope. | 85 // rolled back by its destructor when it falls out of scope. |
| 74 sql::Transaction transaction(db); | 86 sql::Transaction transaction(db); |
| 75 if (!transaction.Begin()) { | 87 if (!transaction.Begin()) { |
| 76 for (int64_t request_id : request_ids) | 88 for (int64_t request_id : request_ids) |
| 77 results.push_back(std::make_pair( | 89 results.push_back(std::make_pair( |
| 78 request_id, RequestQueue::UpdateRequestResult::STORE_FAILURE)); | 90 request_id, RequestQueue::UpdateRequestResult::STORE_FAILURE)); |
| (...skipping 13 matching lines...) Expand all Loading... |
| 92 results.clear(); | 104 results.clear(); |
| 93 for (int64_t request_id : request_ids) | 105 for (int64_t request_id : request_ids) |
| 94 results.push_back(std::make_pair( | 106 results.push_back(std::make_pair( |
| 95 request_id, RequestQueue::UpdateRequestResult::STORE_FAILURE)); | 107 request_id, RequestQueue::UpdateRequestResult::STORE_FAILURE)); |
| 96 return false; | 108 return false; |
| 97 } | 109 } |
| 98 | 110 |
| 99 return true; | 111 return true; |
| 100 } | 112 } |
| 101 | 113 |
| 114 RequestQueueStore::UpdateStatus ChangeRequestsState( |
| 115 sql::Connection* db, |
| 116 const std::vector<int64_t>& request_ids, |
| 117 SavePageRequest::RequestState new_state) { |
| 118 // If you create a transaction but don't Commit() it is automatically |
| 119 // rolled back by its destructor when it falls out of scope. |
| 120 sql::Transaction transaction(db); |
| 121 if (!transaction.Begin()) |
| 122 return RequestQueueStore::UpdateStatus::FAILED; |
| 123 for (const auto& request_id : request_ids) { |
| 124 if (!ChangeRequestState(db, request_id, new_state)) |
| 125 return RequestQueueStore::UpdateStatus::FAILED; |
| 126 } |
| 127 |
| 128 if (!transaction.Commit()) |
| 129 return RequestQueueStore::UpdateStatus::FAILED; |
| 130 |
| 131 return RequestQueueStore::UpdateStatus::UPDATED; |
| 132 } |
| 133 |
| 102 // Create a save page request from a SQL result. Expects complete rows with | 134 // Create a save page request from a SQL result. Expects complete rows with |
| 103 // all columns present. Columns are in order they are defined in select query | 135 // all columns present. Columns are in order they are defined in select query |
| 104 // in |RequestQueueStore::RequestSync| method. | 136 // in |RequestQueueStore::RequestSync| method. |
| 105 SavePageRequest MakeSavePageRequest(const sql::Statement& statement) { | 137 SavePageRequest MakeSavePageRequest(const sql::Statement& statement) { |
| 106 const int64_t id = statement.ColumnInt64(0); | 138 const int64_t id = statement.ColumnInt64(0); |
| 107 const base::Time creation_time = | 139 const base::Time creation_time = |
| 108 base::Time::FromInternalValue(statement.ColumnInt64(1)); | 140 base::Time::FromInternalValue(statement.ColumnInt64(1)); |
| 109 const base::Time activation_time = | 141 const base::Time activation_time = |
| 110 base::Time::FromInternalValue(statement.ColumnInt64(2)); | 142 base::Time::FromInternalValue(statement.ColumnInt64(2)); |
| 111 const base::Time last_attempt_time = | 143 const base::Time last_attempt_time = |
| (...skipping 131 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 243 scoped_refptr<base::SingleThreadTaskRunner> runner, | 275 scoped_refptr<base::SingleThreadTaskRunner> runner, |
| 244 const std::vector<int64_t>& request_ids, | 276 const std::vector<int64_t>& request_ids, |
| 245 const RemoveCallback& callback) { | 277 const RemoveCallback& callback) { |
| 246 RequestQueue::UpdateMultipleRequestResults results; | 278 RequestQueue::UpdateMultipleRequestResults results; |
| 247 // TODO(fgorski): add UMA metrics here. | 279 // TODO(fgorski): add UMA metrics here. |
| 248 DeleteRequestsByIds(db, request_ids, results); | 280 DeleteRequestsByIds(db, request_ids, results); |
| 249 runner->PostTask(FROM_HERE, base::Bind(callback, results)); | 281 runner->PostTask(FROM_HERE, base::Bind(callback, results)); |
| 250 } | 282 } |
| 251 | 283 |
| 252 // static | 284 // static |
| 285 void RequestQueueStoreSQL::ChangeRequestsStateSync( |
| 286 sql::Connection* db, |
| 287 scoped_refptr<base::SingleThreadTaskRunner> runner, |
| 288 const std::vector<int64_t>& request_ids, |
| 289 const SavePageRequest::RequestState new_state, |
| 290 const UpdateCallback& callback) { |
| 291 // TODO(fgorski): add UMA metrics here. |
| 292 RequestQueueStore::UpdateStatus status = |
| 293 offline_pages::ChangeRequestsState(db, request_ids, new_state); |
| 294 runner->PostTask(FROM_HERE, base::Bind(callback, status)); |
| 295 } |
| 296 |
| 297 // static |
| 253 void RequestQueueStoreSQL::ResetSync( | 298 void RequestQueueStoreSQL::ResetSync( |
| 254 sql::Connection* db, | 299 sql::Connection* db, |
| 255 const base::FilePath& db_file_path, | 300 const base::FilePath& db_file_path, |
| 256 scoped_refptr<base::SingleThreadTaskRunner> runner, | 301 scoped_refptr<base::SingleThreadTaskRunner> runner, |
| 257 const ResetCallback& callback) { | 302 const ResetCallback& callback) { |
| 258 // This method deletes the content of the whole store and reinitializes it. | 303 // This method deletes the content of the whole store and reinitializes it. |
| 259 bool success = db->Raze(); | 304 bool success = db->Raze(); |
| 260 db->Close(); | 305 db->Close(); |
| 261 if (success) | 306 if (success) |
| 262 success = InitDatabase(db, db_file_path); | 307 success = InitDatabase(db, db_file_path); |
| 263 runner->PostTask(FROM_HERE, base::Bind(callback, success)); | 308 runner->PostTask(FROM_HERE, base::Bind(callback, success)); |
| 264 } | 309 } |
| 265 | 310 |
| 311 bool RequestQueueStoreSQL::CheckDb(const base::Closure& callback) { |
| 312 DCHECK(db_.get()); |
| 313 if (!db_.get()) { |
| 314 // Nothing to do, but post a callback instead of calling directly |
| 315 // to preserve the async style behavior to prevent bugs. |
| 316 base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE, |
| 317 base::Bind(callback)); |
| 318 return false; |
| 319 } |
| 320 return true; |
| 321 } |
| 322 |
| 266 void RequestQueueStoreSQL::GetRequests(const GetRequestsCallback& callback) { | 323 void RequestQueueStoreSQL::GetRequests(const GetRequestsCallback& callback) { |
| 267 DCHECK(db_.get()); | 324 DCHECK(db_.get()); |
| 268 if (!db_.get()) { | 325 if (!CheckDb(base::Bind(callback, false, std::vector<SavePageRequest>()))) |
| 269 // Nothing to do, but post a callback instead of calling directly | |
| 270 // to preserve the async style behavior to prevent bugs. | |
| 271 base::ThreadTaskRunnerHandle::Get()->PostTask( | |
| 272 FROM_HERE, base::Bind(callback, false, std::vector<SavePageRequest>())); | |
| 273 return; | 326 return; |
| 274 } | |
| 275 | 327 |
| 276 background_task_runner_->PostTask( | 328 background_task_runner_->PostTask( |
| 277 FROM_HERE, base::Bind(&RequestQueueStoreSQL::GetRequestsSync, db_.get(), | 329 FROM_HERE, base::Bind(&RequestQueueStoreSQL::GetRequestsSync, db_.get(), |
| 278 base::ThreadTaskRunnerHandle::Get(), callback)); | 330 base::ThreadTaskRunnerHandle::Get(), callback)); |
| 279 } | 331 } |
| 280 | 332 |
| 281 void RequestQueueStoreSQL::AddOrUpdateRequest(const SavePageRequest& request, | 333 void RequestQueueStoreSQL::AddOrUpdateRequest(const SavePageRequest& request, |
| 282 const UpdateCallback& callback) { | 334 const UpdateCallback& callback) { |
| 283 DCHECK(db_.get()); | 335 DCHECK(db_.get()); |
| 284 if (!db_.get()) { | 336 if (!CheckDb(base::Bind(callback, UpdateStatus::FAILED))) |
| 285 // Nothing to do, but post a callback instead of calling directly | |
| 286 // to preserve the async style behavior to prevent bugs. | |
| 287 base::ThreadTaskRunnerHandle::Get()->PostTask( | |
| 288 FROM_HERE, base::Bind(callback, UpdateStatus::FAILED)); | |
| 289 return; | 337 return; |
| 290 } | |
| 291 | 338 |
| 292 background_task_runner_->PostTask( | 339 background_task_runner_->PostTask( |
| 293 FROM_HERE, | 340 FROM_HERE, |
| 294 base::Bind(&RequestQueueStoreSQL::AddOrUpdateRequestSync, db_.get(), | 341 base::Bind(&RequestQueueStoreSQL::AddOrUpdateRequestSync, db_.get(), |
| 295 base::ThreadTaskRunnerHandle::Get(), request, callback)); | 342 base::ThreadTaskRunnerHandle::Get(), request, callback)); |
| 296 } | 343 } |
| 297 | 344 |
| 298 // RemoveRequestsByRequestId to be more parallell with RemoveRequestsByClientId. | 345 // RemoveRequestsByRequestId to be more parallell with RemoveRequestsByClientId. |
| 299 void RequestQueueStoreSQL::RemoveRequests( | 346 void RequestQueueStoreSQL::RemoveRequests( |
| 300 const std::vector<int64_t>& request_ids, | 347 const std::vector<int64_t>& request_ids, |
| 301 const RemoveCallback& callback) { | 348 const RemoveCallback& callback) { |
| 302 DCHECK(db_.get()); | 349 // Set up a failed set of results in case we fail the DB check. |
| 303 if (!db_.get()) { | 350 RequestQueue::UpdateMultipleRequestResults results; |
| 304 RequestQueue::UpdateMultipleRequestResults results; | |
| 305 for (int64_t request_id : request_ids) | 351 for (int64_t request_id : request_ids) |
| 306 results.push_back(std::make_pair( | 352 results.push_back(std::make_pair( |
| 307 request_id, RequestQueue::UpdateRequestResult::STORE_FAILURE)); | 353 request_id, RequestQueue::UpdateRequestResult::STORE_FAILURE)); |
| 308 // Nothing to do, but post a callback instead of calling directly | 354 |
| 309 // to preserve the async style behavior to prevent bugs. | 355 if (!CheckDb(base::Bind(callback, results))) |
| 310 base::ThreadTaskRunnerHandle::Get()->PostTask( | |
| 311 FROM_HERE, base::Bind(callback, results)); | |
| 312 return; | 356 return; |
| 313 } | |
| 314 | 357 |
| 315 background_task_runner_->PostTask( | 358 background_task_runner_->PostTask( |
| 316 FROM_HERE, | 359 FROM_HERE, |
| 317 base::Bind(&RequestQueueStoreSQL::RemoveRequestsSync, db_.get(), | 360 base::Bind(&RequestQueueStoreSQL::RemoveRequestsSync, db_.get(), |
| 318 base::ThreadTaskRunnerHandle::Get(), request_ids, callback)); | 361 base::ThreadTaskRunnerHandle::Get(), request_ids, callback)); |
| 319 } | 362 } |
| 320 | 363 |
| 364 void RequestQueueStoreSQL::ChangeRequestsState( |
| 365 const std::vector<int64_t>& request_ids, |
| 366 const SavePageRequest::RequestState new_state, |
| 367 const UpdateCallback& callback) { |
| 368 if (!CheckDb(base::Bind(callback, UpdateStatus::FAILED))) |
| 369 return; |
| 370 |
| 371 background_task_runner_->PostTask( |
| 372 FROM_HERE, base::Bind(&RequestQueueStoreSQL::ChangeRequestsStateSync, |
| 373 db_.get(), base::ThreadTaskRunnerHandle::Get(), |
| 374 request_ids, new_state, callback)); |
| 375 } |
| 376 |
| 321 void RequestQueueStoreSQL::Reset(const ResetCallback& callback) { | 377 void RequestQueueStoreSQL::Reset(const ResetCallback& callback) { |
| 322 DCHECK(db_.get()); | 378 DCHECK(db_.get()); |
| 323 if (!db_.get()) { | 379 if (!CheckDb(base::Bind(callback, false))) |
| 324 // Nothing to do, but post a callback instead of calling directly | |
| 325 // to preserve the async style behavior to prevent bugs. | |
| 326 base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE, | |
| 327 base::Bind(callback, false)); | |
| 328 return; | 380 return; |
| 329 } | |
| 330 | 381 |
| 331 background_task_runner_->PostTask( | 382 background_task_runner_->PostTask( |
| 332 FROM_HERE, | 383 FROM_HERE, |
| 333 base::Bind(&RequestQueueStoreSQL::ResetSync, db_.get(), db_file_path_, | 384 base::Bind(&RequestQueueStoreSQL::ResetSync, db_.get(), db_file_path_, |
| 334 base::ThreadTaskRunnerHandle::Get(), | 385 base::ThreadTaskRunnerHandle::Get(), |
| 335 base::Bind(&RequestQueueStoreSQL::OnResetDone, | 386 base::Bind(&RequestQueueStoreSQL::OnResetDone, |
| 336 weak_ptr_factory_.GetWeakPtr(), callback))); | 387 weak_ptr_factory_.GetWeakPtr(), callback))); |
| 337 } | 388 } |
| 338 | 389 |
| 339 void RequestQueueStoreSQL::OpenConnection() { | 390 void RequestQueueStoreSQL::OpenConnection() { |
| (...skipping 16 matching lines...) Expand all Loading... |
| 356 } | 407 } |
| 357 | 408 |
| 358 void RequestQueueStoreSQL::OnResetDone(const ResetCallback& callback, | 409 void RequestQueueStoreSQL::OnResetDone(const ResetCallback& callback, |
| 359 bool success) { | 410 bool success) { |
| 360 // Complete connection initialization post reset. | 411 // Complete connection initialization post reset. |
| 361 OnOpenConnectionDone(success); | 412 OnOpenConnectionDone(success); |
| 362 callback.Run(success); | 413 callback.Run(success); |
| 363 } | 414 } |
| 364 | 415 |
| 365 } // namespace offline_pages | 416 } // namespace offline_pages |
| OLD | NEW |