| Index: components/offline_pages/background/request_queue_store_sql.cc
|
| diff --git a/components/offline_pages/background/request_queue_store_sql.cc b/components/offline_pages/background/request_queue_store_sql.cc
|
| index ad007dc6ea90c5e748bec71e3d1115ebc1bbaea5..8f3ad762e62d1dd0401596dab456b8b454c5f406 100644
|
| --- a/components/offline_pages/background/request_queue_store_sql.cc
|
| +++ b/components/offline_pages/background/request_queue_store_sql.cc
|
| @@ -58,6 +58,62 @@ bool CreateSchema(sql::Connection* db) {
|
| return true;
|
| }
|
|
|
| +// Create a save page request from a SQL result. Expects complete rows with
|
| +// all columns present. Columns are in order they are defined in select query
|
| +// in |RequestQueueStore::RequestSync| method.
|
| +SavePageRequest MakeSavePageRequest(const sql::Statement& statement) {
|
| + const int64_t id = statement.ColumnInt64(0);
|
| + const base::Time creation_time =
|
| + base::Time::FromInternalValue(statement.ColumnInt64(1));
|
| + const base::Time activation_time =
|
| + base::Time::FromInternalValue(statement.ColumnInt64(2));
|
| + const base::Time last_attempt_time =
|
| + base::Time::FromInternalValue(statement.ColumnInt64(3));
|
| + const int64_t started_attempt_count = statement.ColumnInt64(4);
|
| + const int64_t completed_attempt_count = statement.ColumnInt64(5);
|
| + const SavePageRequest::RequestState state =
|
| + static_cast<SavePageRequest::RequestState>(statement.ColumnInt64(6));
|
| + const GURL url(statement.ColumnString(7));
|
| + const ClientId client_id(statement.ColumnString(8),
|
| + statement.ColumnString(9));
|
| +
|
| + DVLOG(2) << "making save page request - id " << id << " url " << url
|
| + << " client_id " << client_id.name_space << "-" << client_id.id
|
| + << " creation time " << creation_time << " user requested "
|
| + << kUserRequested;
|
| +
|
| + SavePageRequest request(id, url, client_id, creation_time, activation_time,
|
| + kUserRequested);
|
| + request.set_last_attempt_time(last_attempt_time);
|
| + request.set_started_attempt_count(started_attempt_count);
|
| + request.set_completed_attempt_count(completed_attempt_count);
|
| + request.set_request_state(state);
|
| + return request;
|
| +}
|
| +
|
| +// Get a request for a specific id.
|
| +SavePageRequest GetOneRequest(sql::Connection* db, const int64_t request_id) {
|
| + const char kSql[] =
|
| + "SELECT request_id, creation_time, activation_time,"
|
| + " last_attempt_time, started_attempt_count, completed_attempt_count,"
|
| + " state, url, client_namespace, client_id"
|
| + " FROM " REQUEST_QUEUE_TABLE_NAME " WHERE request_id=?";
|
| +
|
| + sql::Statement statement(db->GetCachedStatement(SQL_FROM_HERE, kSql));
|
| + statement.BindInt64(0, request_id);
|
| +
|
| + statement.Run();
|
| + return MakeSavePageRequest(statement);
|
| +}
|
| +
|
| +void BuildFailedResultList(const std::vector<int64_t>& request_ids,
|
| + RequestQueue::UpdateMultipleRequestResults results) {
|
| + results.clear();
|
| + for (int64_t request_id : request_ids)
|
| + results.push_back(std::make_pair(
|
| + request_id, RequestQueue::UpdateRequestResult::STORE_FAILURE));
|
| +}
|
| +
|
| bool DeleteRequestById(sql::Connection* db, int64_t request_id) {
|
| const char kSql[] =
|
| "DELETE FROM " REQUEST_QUEUE_TABLE_NAME " WHERE request_id=?";
|
| @@ -80,88 +136,74 @@ bool ChangeRequestState(sql::Connection* db,
|
|
|
| bool DeleteRequestsByIds(sql::Connection* db,
|
| const std::vector<int64_t>& request_ids,
|
| - RequestQueue::UpdateMultipleRequestResults& results) {
|
| + RequestQueue::UpdateMultipleRequestResults& results,
|
| + std::vector<SavePageRequest>& requests) {
|
| // If you create a transaction but don't Commit() it is automatically
|
| // rolled back by its destructor when it falls out of scope.
|
| sql::Transaction transaction(db);
|
| if (!transaction.Begin()) {
|
| - for (int64_t request_id : request_ids)
|
| - results.push_back(std::make_pair(
|
| - request_id, RequestQueue::UpdateRequestResult::STORE_FAILURE));
|
| + BuildFailedResultList(request_ids, results);
|
| return false;
|
| }
|
|
|
| - for (auto request_id : request_ids) {
|
| + // Read the request before we delete it, and if the delete worked, put it on
|
| + // the queue of requests that got deleted.
|
| + for (int64_t request_id : request_ids) {
|
| + SavePageRequest request = GetOneRequest(db, request_id);
|
| RequestQueue::UpdateRequestResult result;
|
| - if (DeleteRequestById(db, request_id))
|
| + if (DeleteRequestById(db, request_id)) {
|
| result = RequestQueue::UpdateRequestResult::SUCCESS;
|
| - else
|
| + requests.push_back(request);
|
| + } else {
|
| result = RequestQueue::UpdateRequestResult::REQUEST_DOES_NOT_EXIST;
|
| + }
|
| results.push_back(std::make_pair(request_id, result));
|
| + requests.push_back(request);
|
| }
|
|
|
| if (!transaction.Commit()) {
|
| - results.clear();
|
| - for (int64_t request_id : request_ids)
|
| - results.push_back(std::make_pair(
|
| - request_id, RequestQueue::UpdateRequestResult::STORE_FAILURE));
|
| + requests.clear();
|
| + BuildFailedResultList(request_ids, results);
|
| return false;
|
| }
|
|
|
| return true;
|
| }
|
|
|
| -RequestQueueStore::UpdateStatus ChangeRequestsState(
|
| - sql::Connection* db,
|
| - const std::vector<int64_t>& request_ids,
|
| - SavePageRequest::RequestState new_state) {
|
| +bool ChangeRequestsState(sql::Connection* db,
|
| + const std::vector<int64_t>& request_ids,
|
| + SavePageRequest::RequestState new_state,
|
| + RequestQueue::UpdateMultipleRequestResults& results,
|
| + std::vector<SavePageRequest>& requests) {
|
| // If you create a transaction but don't Commit() it is automatically
|
| // rolled back by its destructor when it falls out of scope.
|
| sql::Transaction transaction(db);
|
| - if (!transaction.Begin())
|
| - return RequestQueueStore::UpdateStatus::FAILED;
|
| - for (const auto& request_id : request_ids) {
|
| - if (!ChangeRequestState(db, request_id, new_state))
|
| - return RequestQueueStore::UpdateStatus::FAILED;
|
| + if (!transaction.Begin()) {
|
| + BuildFailedResultList(request_ids, results);
|
| + return false;
|
| }
|
|
|
| - if (!transaction.Commit())
|
| - return RequestQueueStore::UpdateStatus::FAILED;
|
| -
|
| - return RequestQueueStore::UpdateStatus::UPDATED;
|
| -}
|
| + // Update a request, then get it, and put the item we got on the output list.
|
| + for (const auto& request_id : request_ids) {
|
| + RequestQueue::UpdateRequestResult status;
|
| + if (!ChangeRequestState(db, request_id, new_state))
|
| + status = RequestQueue::UpdateRequestResult::REQUEST_DOES_NOT_EXIST;
|
| + else
|
| + status = RequestQueue::UpdateRequestResult::SUCCESS;
|
|
|
| -// Create a save page request from a SQL result. Expects complete rows with
|
| -// all columns present. Columns are in order they are defined in select query
|
| -// in |RequestQueueStore::RequestSync| method.
|
| -SavePageRequest MakeSavePageRequest(const sql::Statement& statement) {
|
| - const int64_t id = statement.ColumnInt64(0);
|
| - const base::Time creation_time =
|
| - base::Time::FromInternalValue(statement.ColumnInt64(1));
|
| - const base::Time activation_time =
|
| - base::Time::FromInternalValue(statement.ColumnInt64(2));
|
| - const base::Time last_attempt_time =
|
| - base::Time::FromInternalValue(statement.ColumnInt64(3));
|
| - const int64_t started_attempt_count = statement.ColumnInt64(4);
|
| - const int64_t completed_attempt_count = statement.ColumnInt64(5);
|
| - const SavePageRequest::RequestState state =
|
| - static_cast<SavePageRequest::RequestState>(statement.ColumnInt64(6));
|
| - const GURL url(statement.ColumnString(7));
|
| - const ClientId client_id(statement.ColumnString(8),
|
| - statement.ColumnString(9));
|
| + // Make output request_id/status pair, and put a copy of the updated request
|
| + // on output list.
|
| + results.push_back(std::make_pair(request_id, status));
|
| + requests.push_back(GetOneRequest(db, request_id));
|
| + }
|
|
|
| - DVLOG(2) << "making save page request - id " << id << " url " << url
|
| - << " client_id " << client_id.name_space << "-" << client_id.id
|
| - << " creation time " << creation_time << " user requested "
|
| - << kUserRequested;
|
| + if (!transaction.Commit()) {
|
| + requests.clear();
|
| + BuildFailedResultList(request_ids, results);
|
| + return false;
|
| + }
|
|
|
| - SavePageRequest request(
|
| - id, url, client_id, creation_time, activation_time, kUserRequested);
|
| - request.set_last_attempt_time(last_attempt_time);
|
| - request.set_started_attempt_count(started_attempt_count);
|
| - request.set_completed_attempt_count(completed_attempt_count);
|
| - request.set_request_state(state);
|
| - return request;
|
| + return true;
|
| }
|
|
|
| RequestQueueStore::UpdateStatus InsertOrReplace(
|
| @@ -276,9 +318,10 @@ void RequestQueueStoreSQL::RemoveRequestsSync(
|
| const std::vector<int64_t>& request_ids,
|
| const RemoveCallback& callback) {
|
| RequestQueue::UpdateMultipleRequestResults results;
|
| + std::vector<SavePageRequest> requests;
|
| // TODO(fgorski): add UMA metrics here.
|
| - DeleteRequestsByIds(db, request_ids, results);
|
| - runner->PostTask(FROM_HERE, base::Bind(callback, results));
|
| + DeleteRequestsByIds(db, request_ids, results, requests);
|
| + runner->PostTask(FROM_HERE, base::Bind(callback, results, requests));
|
| }
|
|
|
| // static
|
| @@ -287,11 +330,13 @@ void RequestQueueStoreSQL::ChangeRequestsStateSync(
|
| scoped_refptr<base::SingleThreadTaskRunner> runner,
|
| const std::vector<int64_t>& request_ids,
|
| const SavePageRequest::RequestState new_state,
|
| - const UpdateCallback& callback) {
|
| + const UpdateMultipleRequestsCallback& callback) {
|
| + RequestQueue::UpdateMultipleRequestResults results;
|
| + std::vector<SavePageRequest> requests;
|
| // TODO(fgorski): add UMA metrics here.
|
| - RequestQueueStore::UpdateStatus status =
|
| - offline_pages::ChangeRequestsState(db, request_ids, new_state);
|
| - runner->PostTask(FROM_HERE, base::Bind(callback, status));
|
| + offline_pages::ChangeRequestsState(db, request_ids, new_state, results,
|
| + requests);
|
| + runner->PostTask(FROM_HERE, base::Bind(callback, results, requests));
|
| }
|
|
|
| // static
|
| @@ -348,11 +393,12 @@ void RequestQueueStoreSQL::RemoveRequests(
|
| const RemoveCallback& callback) {
|
| // Set up a failed set of results in case we fail the DB check.
|
| RequestQueue::UpdateMultipleRequestResults results;
|
| - for (int64_t request_id : request_ids)
|
| - results.push_back(std::make_pair(
|
| - request_id, RequestQueue::UpdateRequestResult::STORE_FAILURE));
|
| + std::vector<SavePageRequest> requests;
|
| + for (int64_t request_id : request_ids)
|
| + results.push_back(std::make_pair(
|
| + request_id, RequestQueue::UpdateRequestResult::STORE_FAILURE));
|
|
|
| - if (!CheckDb(base::Bind(callback, results)))
|
| + if (!CheckDb(base::Bind(callback, results, requests)))
|
| return;
|
|
|
| background_task_runner_->PostTask(
|
| @@ -364,8 +410,10 @@ void RequestQueueStoreSQL::RemoveRequests(
|
| void RequestQueueStoreSQL::ChangeRequestsState(
|
| const std::vector<int64_t>& request_ids,
|
| const SavePageRequest::RequestState new_state,
|
| - const UpdateCallback& callback) {
|
| - if (!CheckDb(base::Bind(callback, UpdateStatus::FAILED)))
|
| + const UpdateMultipleRequestsCallback& callback) {
|
| + RequestQueue::UpdateMultipleRequestResults results;
|
| + std::vector<SavePageRequest> requests;
|
| + if (!CheckDb(base::Bind(callback, results, requests)))
|
| return;
|
|
|
| background_task_runner_->PostTask(
|
|
|