| 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 DeleteRequestByClientId(sql::Connection* db, const ClientId& client_id) { | 69 bool DeleteRequestsByIds( |
| 70 const char kSql[] = "DELETE FROM " REQUEST_QUEUE_TABLE_NAME | 70 sql::Connection* db, |
| 71 " WHERE client_namespace=? AND client_id=?"; | 71 const std::vector<int64_t>& request_ids, |
| 72 sql::Statement statement(db->GetCachedStatement(SQL_FROM_HERE, kSql)); | 72 std::vector<std::pair<int64_t, RequestQueue::UpdateRequestResult>>& |
| 73 statement.BindString(0, client_id.name_space); | 73 results) { |
| 74 statement.BindString(1, client_id.id); | |
| 75 DVLOG(2) << kSql << " client_namespace " << client_id.name_space | |
| 76 << " client_id " << client_id.id; | |
| 77 return statement.Run(); | |
| 78 } | |
| 79 | |
| 80 bool DeleteRequestsByIds(sql::Connection* db, | |
| 81 const std::vector<int64_t>& request_ids, | |
| 82 int* count) { | |
| 83 DCHECK(count); | |
| 84 // If you create a transaction but don't Commit() it is automatically | 74 // If you create a transaction but don't Commit() it is automatically |
| 85 // rolled back by its destructor when it falls out of scope. | 75 // rolled back by its destructor when it falls out of scope. |
| 86 sql::Transaction transaction(db); | 76 sql::Transaction transaction(db); |
| 87 if (!transaction.Begin()) | 77 if (!transaction.Begin()) { |
| 78 for (int64_t request_id : request_ids) |
| 79 results.push_back(std::make_pair( |
| 80 request_id, RequestQueue::UpdateRequestResult::STORE_FAILURE)); |
| 88 return false; | 81 return false; |
| 89 | |
| 90 *count = 0; | |
| 91 for (auto request_id : request_ids) { | |
| 92 if (!DeleteRequestById(db, request_id)) | |
| 93 return false; | |
| 94 *count += db->GetLastChangeCount(); | |
| 95 } | 82 } |
| 96 | 83 |
| 97 if (!transaction.Commit()) | 84 for (auto request_id : request_ids) { |
| 85 RequestQueue::UpdateRequestResult result; |
| 86 if (DeleteRequestById(db, request_id)) |
| 87 result = RequestQueue::UpdateRequestResult::SUCCESS; |
| 88 else |
| 89 result = RequestQueue::UpdateRequestResult::REQUEST_DOES_NOT_EXIST; |
| 90 results.push_back(std::make_pair(request_id, result)); |
| 91 } |
| 92 |
| 93 if (!transaction.Commit()) { |
| 94 results.clear(); |
| 95 for (int64_t request_id : request_ids) |
| 96 results.push_back(std::make_pair( |
| 97 request_id, RequestQueue::UpdateRequestResult::STORE_FAILURE)); |
| 98 return false; | 98 return false; |
| 99 } |
| 99 | 100 |
| 100 return true; | 101 return true; |
| 101 } | 102 } |
| 102 | 103 |
| 103 bool DeleteRequestsByClientIds(sql::Connection* db, | |
| 104 const std::vector<ClientId>& client_ids, | |
| 105 int* count) { | |
| 106 DCHECK(count); | |
| 107 // If you create a transaction but don't Commit() it is automatically | |
| 108 // rolled back by its destructor when it falls out of scope. | |
| 109 sql::Transaction transaction(db); | |
| 110 if (!transaction.Begin()) | |
| 111 return false; | |
| 112 | |
| 113 *count = 0; | |
| 114 for (const auto& client_id : client_ids) { | |
| 115 if (!DeleteRequestByClientId(db, client_id)) | |
| 116 return false; | |
| 117 *count += db->GetLastChangeCount(); | |
| 118 } | |
| 119 | |
| 120 if (!transaction.Commit()) | |
| 121 return false; | |
| 122 | |
| 123 return true; | |
| 124 } | |
| 125 | |
| 126 // Create a save page request from a SQL result. Expects complete rows with | 104 // Create a save page request from a SQL result. Expects complete rows with |
| 127 // all columns present. Columns are in order they are defined in select query | 105 // all columns present. Columns are in order they are defined in select query |
| 128 // in |RequestQueueStore::RequestSync| method. | 106 // in |RequestQueueStore::RequestSync| method. |
| 129 SavePageRequest MakeSavePageRequest(const sql::Statement& statement) { | 107 SavePageRequest MakeSavePageRequest(const sql::Statement& statement) { |
| 130 const int64_t id = statement.ColumnInt64(0); | 108 const int64_t id = statement.ColumnInt64(0); |
| 131 const base::Time creation_time = | 109 const base::Time creation_time = |
| 132 base::Time::FromInternalValue(statement.ColumnInt64(1)); | 110 base::Time::FromInternalValue(statement.ColumnInt64(1)); |
| 133 const base::Time activation_time = | 111 const base::Time activation_time = |
| 134 base::Time::FromInternalValue(statement.ColumnInt64(2)); | 112 base::Time::FromInternalValue(statement.ColumnInt64(2)); |
| 135 const base::Time last_attempt_time = | 113 const base::Time last_attempt_time = |
| (...skipping 124 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 260 RequestQueueStore::UpdateStatus status = InsertOrReplace(db, request); | 238 RequestQueueStore::UpdateStatus status = InsertOrReplace(db, request); |
| 261 runner->PostTask(FROM_HERE, base::Bind(callback, status)); | 239 runner->PostTask(FROM_HERE, base::Bind(callback, status)); |
| 262 } | 240 } |
| 263 | 241 |
| 264 // static | 242 // static |
| 265 void RequestQueueStoreSQL::RemoveRequestsSync( | 243 void RequestQueueStoreSQL::RemoveRequestsSync( |
| 266 sql::Connection* db, | 244 sql::Connection* db, |
| 267 scoped_refptr<base::SingleThreadTaskRunner> runner, | 245 scoped_refptr<base::SingleThreadTaskRunner> runner, |
| 268 const std::vector<int64_t>& request_ids, | 246 const std::vector<int64_t>& request_ids, |
| 269 const RemoveCallback& callback) { | 247 const RemoveCallback& callback) { |
| 248 std::vector<std::pair<int64_t, RequestQueue::UpdateRequestResult>> results; |
| 270 // TODO(fgorski): add UMA metrics here. | 249 // TODO(fgorski): add UMA metrics here. |
| 271 int count = 0; | 250 DeleteRequestsByIds(db, request_ids, results); |
| 272 if (DeleteRequestsByIds(db, request_ids, &count)) | 251 runner->PostTask(FROM_HERE, base::Bind(callback, results)); |
| 273 runner->PostTask(FROM_HERE, base::Bind(callback, true, count)); | |
| 274 else | |
| 275 runner->PostTask(FROM_HERE, base::Bind(callback, false, 0)); | |
| 276 } | 252 } |
| 277 | 253 |
| 278 // static | 254 // static |
| 279 void RequestQueueStoreSQL::RemoveRequestsByClientIdSync( | |
| 280 sql::Connection* db, | |
| 281 scoped_refptr<base::SingleThreadTaskRunner> runner, | |
| 282 const std::vector<ClientId>& client_ids, | |
| 283 const RemoveCallback& callback) { | |
| 284 // TODO(fgorski): add UMA metrics here. | |
| 285 int count = 0; | |
| 286 if (DeleteRequestsByClientIds(db, client_ids, &count)) | |
| 287 runner->PostTask(FROM_HERE, base::Bind(callback, true, count)); | |
| 288 else | |
| 289 runner->PostTask(FROM_HERE, base::Bind(callback, false, 0)); | |
| 290 } | |
| 291 | |
| 292 // static | |
| 293 void RequestQueueStoreSQL::ResetSync( | 255 void RequestQueueStoreSQL::ResetSync( |
| 294 sql::Connection* db, | 256 sql::Connection* db, |
| 295 const base::FilePath& db_file_path, | 257 const base::FilePath& db_file_path, |
| 296 scoped_refptr<base::SingleThreadTaskRunner> runner, | 258 scoped_refptr<base::SingleThreadTaskRunner> runner, |
| 297 const ResetCallback& callback) { | 259 const ResetCallback& callback) { |
| 298 // This method deletes the content of the whole store and reinitializes it. | 260 // This method deletes the content of the whole store and reinitializes it. |
| 299 bool success = db->Raze(); | 261 bool success = db->Raze(); |
| 300 db->Close(); | 262 db->Close(); |
| 301 if (success) | 263 if (success) |
| 302 success = InitDatabase(db, db_file_path); | 264 success = InitDatabase(db, db_file_path); |
| (...skipping 25 matching lines...) Expand all Loading... |
| 328 FROM_HERE, base::Bind(callback, UpdateStatus::FAILED)); | 290 FROM_HERE, base::Bind(callback, UpdateStatus::FAILED)); |
| 329 return; | 291 return; |
| 330 } | 292 } |
| 331 | 293 |
| 332 background_task_runner_->PostTask( | 294 background_task_runner_->PostTask( |
| 333 FROM_HERE, | 295 FROM_HERE, |
| 334 base::Bind(&RequestQueueStoreSQL::AddOrUpdateRequestSync, db_.get(), | 296 base::Bind(&RequestQueueStoreSQL::AddOrUpdateRequestSync, db_.get(), |
| 335 base::ThreadTaskRunnerHandle::Get(), request, callback)); | 297 base::ThreadTaskRunnerHandle::Get(), request, callback)); |
| 336 } | 298 } |
| 337 | 299 |
| 338 // TODO(petewil): This is unused, since request_coordinator doesn't keep | |
| 339 // request_ids, and neither do clients. Plan is to remove this API in a future | |
| 340 // changelist. If we do discover a need to keep it, name it | |
| 341 // RemoveRequestsByRequestId to be more parallell with RemoveRequestsByClientId. | 300 // RemoveRequestsByRequestId to be more parallell with RemoveRequestsByClientId. |
| 342 void RequestQueueStoreSQL::RemoveRequests( | 301 void RequestQueueStoreSQL::RemoveRequests( |
| 343 const std::vector<int64_t>& request_ids, | 302 const std::vector<int64_t>& request_ids, |
| 344 const RemoveCallback& callback) { | 303 const RemoveCallback& callback) { |
| 345 DCHECK(db_.get()); | 304 DCHECK(db_.get()); |
| 346 if (!db_.get()) { | 305 if (!db_.get()) { |
| 306 std::vector<std::pair<int64_t, RequestQueue::UpdateRequestResult>> results; |
| 307 for (int64_t request_id : request_ids) |
| 308 results.push_back(std::make_pair( |
| 309 request_id, RequestQueue::UpdateRequestResult::STORE_FAILURE)); |
| 347 // Nothing to do, but post a callback instead of calling directly | 310 // Nothing to do, but post a callback instead of calling directly |
| 348 // to preserve the async style behavior to prevent bugs. | 311 // to preserve the async style behavior to prevent bugs. |
| 349 base::ThreadTaskRunnerHandle::Get()->PostTask( | 312 base::ThreadTaskRunnerHandle::Get()->PostTask( |
| 350 FROM_HERE, base::Bind(callback, false, 0)); | 313 FROM_HERE, base::Bind(callback, results)); |
| 351 return; | 314 return; |
| 352 } | 315 } |
| 353 | 316 |
| 354 background_task_runner_->PostTask( | 317 background_task_runner_->PostTask( |
| 355 FROM_HERE, | 318 FROM_HERE, |
| 356 base::Bind(&RequestQueueStoreSQL::RemoveRequestsSync, db_.get(), | 319 base::Bind(&RequestQueueStoreSQL::RemoveRequestsSync, db_.get(), |
| 357 base::ThreadTaskRunnerHandle::Get(), request_ids, callback)); | 320 base::ThreadTaskRunnerHandle::Get(), request_ids, callback)); |
| 358 } | 321 } |
| 359 | 322 |
| 360 void RequestQueueStoreSQL::RemoveRequestsByClientId( | |
| 361 const std::vector<ClientId>& client_ids, | |
| 362 const RemoveCallback& callback) { | |
| 363 DCHECK(db_.get()); | |
| 364 if (!db_.get()) { | |
| 365 // Nothing to do, but post a callback instead of calling directly | |
| 366 // to preserve the async style behavior to prevent bugs. | |
| 367 base::ThreadTaskRunnerHandle::Get()->PostTask( | |
| 368 FROM_HERE, base::Bind(callback, false, 0)); | |
| 369 return; | |
| 370 } | |
| 371 | |
| 372 background_task_runner_->PostTask( | |
| 373 FROM_HERE, | |
| 374 base::Bind(&RequestQueueStoreSQL::RemoveRequestsByClientIdSync, db_.get(), | |
| 375 base::ThreadTaskRunnerHandle::Get(), client_ids, callback)); | |
| 376 } | |
| 377 | |
| 378 void RequestQueueStoreSQL::Reset(const ResetCallback& callback) { | 323 void RequestQueueStoreSQL::Reset(const ResetCallback& callback) { |
| 379 DCHECK(db_.get()); | 324 DCHECK(db_.get()); |
| 380 if (!db_.get()) { | 325 if (!db_.get()) { |
| 381 // Nothing to do, but post a callback instead of calling directly | 326 // Nothing to do, but post a callback instead of calling directly |
| 382 // to preserve the async style behavior to prevent bugs. | 327 // to preserve the async style behavior to prevent bugs. |
| 383 base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE, | 328 base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE, |
| 384 base::Bind(callback, false)); | 329 base::Bind(callback, false)); |
| 385 return; | 330 return; |
| 386 } | 331 } |
| 387 | 332 |
| (...skipping 25 matching lines...) Expand all Loading... |
| 413 } | 358 } |
| 414 | 359 |
| 415 void RequestQueueStoreSQL::OnResetDone(const ResetCallback& callback, | 360 void RequestQueueStoreSQL::OnResetDone(const ResetCallback& callback, |
| 416 bool success) { | 361 bool success) { |
| 417 // Complete connection initialization post reset. | 362 // Complete connection initialization post reset. |
| 418 OnOpenConnectionDone(success); | 363 OnOpenConnectionDone(success); |
| 419 callback.Run(success); | 364 callback.Run(success); |
| 420 } | 365 } |
| 421 | 366 |
| 422 } // namespace offline_pages | 367 } // namespace offline_pages |
| OLD | NEW |