| 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 <unordered_set> |
| 8 |
| 7 #include "base/bind.h" | 9 #include "base/bind.h" |
| 8 #include "base/files/file_path.h" | 10 #include "base/files/file_path.h" |
| 9 #include "base/files/file_util.h" | 11 #include "base/files/file_util.h" |
| 10 #include "base/location.h" | 12 #include "base/location.h" |
| 11 #include "base/logging.h" | 13 #include "base/logging.h" |
| 12 #include "base/sequenced_task_runner.h" | 14 #include "base/sequenced_task_runner.h" |
| 13 #include "base/threading/thread_task_runner_handle.h" | 15 #include "base/threading/thread_task_runner_handle.h" |
| 14 #include "components/offline_pages/background/save_page_request.h" | 16 #include "components/offline_pages/background/save_page_request.h" |
| 15 #include "sql/connection.h" | 17 #include "sql/connection.h" |
| 16 #include "sql/statement.h" | 18 #include "sql/statement.h" |
| 17 #include "sql/transaction.h" | 19 #include "sql/transaction.h" |
| 18 | 20 |
| 19 namespace offline_pages { | 21 namespace offline_pages { |
| 20 | 22 |
| 21 template class StoreUpdateResult<SavePageRequest>; | 23 template class StoreUpdateResult<SavePageRequest>; |
| 22 | 24 |
| 23 namespace { | 25 namespace { |
| 24 | 26 |
| 25 using UpdateStatus = RequestQueueStore::UpdateStatus; | |
| 26 using StoreStateCallback = base::Callback<void(StoreState)>; | 27 using StoreStateCallback = base::Callback<void(StoreState)>; |
| 27 | 28 |
| 28 // This is a macro instead of a const so that | 29 // This is a macro instead of a const so that |
| 29 // it can be used inline in other SQL statements below. | 30 // it can be used inline in other SQL statements below. |
| 30 #define REQUEST_QUEUE_TABLE_NAME "request_queue_v1" | 31 #define REQUEST_QUEUE_TABLE_NAME "request_queue_v1" |
| 31 const bool kUserRequested = true; | 32 const bool kUserRequested = true; |
| 32 | 33 |
| 33 bool CreateRequestQueueTable(sql::Connection* db) { | 34 bool CreateRequestQueueTable(sql::Connection* db) { |
| 34 const char kSql[] = "CREATE TABLE IF NOT EXISTS " REQUEST_QUEUE_TABLE_NAME | 35 const char kSql[] = "CREATE TABLE IF NOT EXISTS " REQUEST_QUEUE_TABLE_NAME |
| 35 " (request_id INTEGER PRIMARY KEY NOT NULL," | 36 " (request_id INTEGER PRIMARY KEY NOT NULL," |
| (...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 102 const int64_t request_id) { | 103 const int64_t request_id) { |
| 103 const char kSql[] = | 104 const char kSql[] = |
| 104 "SELECT request_id, creation_time, activation_time," | 105 "SELECT request_id, creation_time, activation_time," |
| 105 " last_attempt_time, started_attempt_count, completed_attempt_count," | 106 " last_attempt_time, started_attempt_count, completed_attempt_count," |
| 106 " state, url, client_namespace, client_id" | 107 " state, url, client_namespace, client_id" |
| 107 " FROM " REQUEST_QUEUE_TABLE_NAME " WHERE request_id=?"; | 108 " FROM " REQUEST_QUEUE_TABLE_NAME " WHERE request_id=?"; |
| 108 | 109 |
| 109 sql::Statement statement(db->GetCachedStatement(SQL_FROM_HERE, kSql)); | 110 sql::Statement statement(db->GetCachedStatement(SQL_FROM_HERE, kSql)); |
| 110 statement.BindInt64(0, request_id); | 111 statement.BindInt64(0, request_id); |
| 111 | 112 |
| 112 statement.Run(); | 113 if (statement.Step()) |
| 113 return MakeSavePageRequest(statement); | 114 return MakeSavePageRequest(statement); |
| 115 return std::unique_ptr<SavePageRequest>(nullptr); |
| 114 } | 116 } |
| 115 | 117 |
| 116 ItemActionStatus DeleteRequestById(sql::Connection* db, int64_t request_id) { | 118 ItemActionStatus DeleteRequestById(sql::Connection* db, int64_t request_id) { |
| 117 const char kSql[] = | 119 const char kSql[] = |
| 118 "DELETE FROM " REQUEST_QUEUE_TABLE_NAME " WHERE request_id=?"; | 120 "DELETE FROM " REQUEST_QUEUE_TABLE_NAME " WHERE request_id=?"; |
| 119 sql::Statement statement(db->GetCachedStatement(SQL_FROM_HERE, kSql)); | 121 sql::Statement statement(db->GetCachedStatement(SQL_FROM_HERE, kSql)); |
| 120 statement.BindInt64(0, request_id); | 122 statement.BindInt64(0, request_id); |
| 121 if (!statement.Run()) | 123 if (!statement.Run()) |
| 122 return ItemActionStatus::STORE_ERROR; | 124 return ItemActionStatus::STORE_ERROR; |
| 123 else if (db->GetLastChangeCount() == 0) | 125 else if (db->GetLastChangeCount() == 0) |
| (...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 240 sql::Statement statement(db->GetCachedStatement(SQL_FROM_HERE, kSql)); | 242 sql::Statement statement(db->GetCachedStatement(SQL_FROM_HERE, kSql)); |
| 241 | 243 |
| 242 std::vector<std::unique_ptr<SavePageRequest>> requests; | 244 std::vector<std::unique_ptr<SavePageRequest>> requests; |
| 243 while (statement.Step()) | 245 while (statement.Step()) |
| 244 requests.push_back(MakeSavePageRequest(statement)); | 246 requests.push_back(MakeSavePageRequest(statement)); |
| 245 | 247 |
| 246 runner->PostTask(FROM_HERE, base::Bind(callback, statement.Succeeded(), | 248 runner->PostTask(FROM_HERE, base::Bind(callback, statement.Succeeded(), |
| 247 base::Passed(&requests))); | 249 base::Passed(&requests))); |
| 248 } | 250 } |
| 249 | 251 |
| 252 void GetRequestsByIdsSync(sql::Connection* db, |
| 253 scoped_refptr<base::SingleThreadTaskRunner> runner, |
| 254 const std::vector<int64_t>& request_ids, |
| 255 const RequestQueueStore::UpdateCallback& callback) { |
| 256 // TODO(fgorski): Perhaps add metrics here. |
| 257 std::unique_ptr<UpdateRequestsResult> result( |
| 258 new UpdateRequestsResult(StoreState::LOADED)); |
| 259 |
| 260 // If you create a transaction but don't Commit() it is automatically |
| 261 // rolled back by its destructor when it falls out of scope. |
| 262 sql::Transaction transaction(db); |
| 263 if (!transaction.Begin()) { |
| 264 PostStoreErrorForAllIds(runner, request_ids, callback); |
| 265 return; |
| 266 } |
| 267 |
| 268 // Make sure not to include the same request multiple times, preserving the |
| 269 // order of non-duplicated IDs in the result. |
| 270 std::unordered_set<int64_t> processed_ids; |
| 271 for (int64_t request_id : request_ids) { |
| 272 if (!processed_ids.insert(request_id).second) |
| 273 continue; |
| 274 std::unique_ptr<SavePageRequest> request = GetOneRequest(db, request_id); |
| 275 if (request.get()) |
| 276 result->updated_items.push_back(*request); |
| 277 ItemActionStatus status = |
| 278 request.get() ? ItemActionStatus::SUCCESS : ItemActionStatus::NOT_FOUND; |
| 279 result->item_statuses.push_back(std::make_pair(request_id, status)); |
| 280 } |
| 281 |
| 282 if (!transaction.Commit()) { |
| 283 PostStoreErrorForAllIds(runner, request_ids, callback); |
| 284 return; |
| 285 } |
| 286 |
| 287 runner->PostTask(FROM_HERE, base::Bind(callback, base::Passed(&result))); |
| 288 } |
| 289 |
| 250 void AddRequestSync(sql::Connection* db, | 290 void AddRequestSync(sql::Connection* db, |
| 251 scoped_refptr<base::SingleThreadTaskRunner> runner, | 291 scoped_refptr<base::SingleThreadTaskRunner> runner, |
| 252 const SavePageRequest& request, | 292 const SavePageRequest& request, |
| 253 const RequestQueueStore::AddCallback& callback) { | 293 const RequestQueueStore::AddCallback& callback) { |
| 254 // TODO(fgorski): add UMA metrics here. | 294 // TODO(fgorski): add UMA metrics here. |
| 255 ItemActionStatus status = Insert(db, request); | 295 ItemActionStatus status = Insert(db, request); |
| 256 runner->PostTask(FROM_HERE, base::Bind(callback, status)); | 296 runner->PostTask(FROM_HERE, base::Bind(callback, status)); |
| 257 } | 297 } |
| 258 | 298 |
| 259 void UpdateRequestsSync(sql::Connection* db, | 299 void UpdateRequestsSync(sql::Connection* db, |
| (...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 378 DCHECK(db_.get()); | 418 DCHECK(db_.get()); |
| 379 std::vector<std::unique_ptr<SavePageRequest>> requests; | 419 std::vector<std::unique_ptr<SavePageRequest>> requests; |
| 380 if (!CheckDb(base::Bind(callback, false, base::Passed(&requests)))) | 420 if (!CheckDb(base::Bind(callback, false, base::Passed(&requests)))) |
| 381 return; | 421 return; |
| 382 | 422 |
| 383 background_task_runner_->PostTask( | 423 background_task_runner_->PostTask( |
| 384 FROM_HERE, base::Bind(&GetRequestsSync, db_.get(), | 424 FROM_HERE, base::Bind(&GetRequestsSync, db_.get(), |
| 385 base::ThreadTaskRunnerHandle::Get(), callback)); | 425 base::ThreadTaskRunnerHandle::Get(), callback)); |
| 386 } | 426 } |
| 387 | 427 |
| 428 void RequestQueueStoreSQL::GetRequestsByIds( |
| 429 const std::vector<int64_t>& request_ids, |
| 430 const UpdateCallback& callback) { |
| 431 if (!db_.get()) { |
| 432 PostStoreErrorForAllIds(base::ThreadTaskRunnerHandle::Get(), request_ids, |
| 433 callback); |
| 434 return; |
| 435 } |
| 436 |
| 437 background_task_runner_->PostTask( |
| 438 FROM_HERE, |
| 439 base::Bind(&GetRequestsByIdsSync, db_.get(), |
| 440 base::ThreadTaskRunnerHandle::Get(), request_ids, callback)); |
| 441 } |
| 442 |
| 388 void RequestQueueStoreSQL::AddRequest(const SavePageRequest& request, | 443 void RequestQueueStoreSQL::AddRequest(const SavePageRequest& request, |
| 389 const AddCallback& callback) { | 444 const AddCallback& callback) { |
| 390 if (!CheckDb(base::Bind(callback, ItemActionStatus::STORE_ERROR))) | 445 if (!CheckDb(base::Bind(callback, ItemActionStatus::STORE_ERROR))) |
| 391 return; | 446 return; |
| 392 | 447 |
| 393 background_task_runner_->PostTask( | 448 background_task_runner_->PostTask( |
| 394 FROM_HERE, | 449 FROM_HERE, |
| 395 base::Bind(&AddRequestSync, db_.get(), | 450 base::Bind(&AddRequestSync, db_.get(), |
| 396 base::ThreadTaskRunnerHandle::Get(), request, callback)); | 451 base::ThreadTaskRunnerHandle::Get(), request, callback)); |
| 397 } | 452 } |
| (...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 465 // Complete connection initialization post reset. | 520 // Complete connection initialization post reset. |
| 466 OnOpenConnectionDone(state); | 521 OnOpenConnectionDone(state); |
| 467 callback.Run(state == StoreState::LOADED); | 522 callback.Run(state == StoreState::LOADED); |
| 468 } | 523 } |
| 469 | 524 |
| 470 StoreState RequestQueueStoreSQL::state() const { | 525 StoreState RequestQueueStoreSQL::state() const { |
| 471 return state_; | 526 return state_; |
| 472 } | 527 } |
| 473 | 528 |
| 474 } // namespace offline_pages | 529 } // namespace offline_pages |
| OLD | NEW |