Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(120)

Side by Side Diff: components/offline_pages/background/request_queue_store_sql.cc

Issue 2221323003: Add an API to Pause and Resume background offlining requests. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Adding a check function to reduce common code. Created 4 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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 59 matching lines...) Expand 10 before | Expand all | Expand 10 after
70 const char kSql[] = "DELETE FROM " REQUEST_QUEUE_TABLE_NAME 70 const char kSql[] = "DELETE FROM " REQUEST_QUEUE_TABLE_NAME
71 " WHERE client_namespace=? AND client_id=?"; 71 " WHERE client_namespace=? AND client_id=?";
72 sql::Statement statement(db->GetCachedStatement(SQL_FROM_HERE, kSql)); 72 sql::Statement statement(db->GetCachedStatement(SQL_FROM_HERE, kSql));
73 statement.BindString(0, client_id.name_space); 73 statement.BindString(0, client_id.name_space);
74 statement.BindString(1, client_id.id); 74 statement.BindString(1, client_id.id);
75 DVLOG(2) << kSql << " client_namespace " << client_id.name_space 75 DVLOG(2) << kSql << " client_namespace " << client_id.name_space
76 << " client_id " << client_id.id; 76 << " client_id " << client_id.id;
77 return statement.Run(); 77 return statement.Run();
78 } 78 }
79 79
80 bool PauseRequest(sql::Connection* db, const int64_t request_id) {
81 const char kSql[] = "UPDATE " REQUEST_QUEUE_TABLE_NAME
82 " SET state=?"
83 " WHERE request_id=?";
84 sql::Statement statement(db->GetCachedStatement(SQL_FROM_HERE, kSql));
85 statement.BindInt64(
86 0, static_cast<long>(SavePageRequest::RequestState::PAUSED));
87 statement.BindInt64(1, request_id);
88 return statement.Run();
89 }
90
91 bool ResumeRequest(sql::Connection* db, const int64_t request_id) {
92 const char kSql[] = "UPDATE " REQUEST_QUEUE_TABLE_NAME
93 " SET state=?"
94 " WHERE request_id=?";
95 sql::Statement statement(db->GetCachedStatement(SQL_FROM_HERE, kSql));
96 statement.BindInt64(
97 0, static_cast<long>(SavePageRequest::RequestState::AVAILABLE));
98 statement.BindInt64(1, request_id);
99 return statement.Run();
100 }
101
80 bool DeleteRequestsByIds(sql::Connection* db, 102 bool DeleteRequestsByIds(sql::Connection* db,
81 const std::vector<int64_t>& request_ids, 103 const std::vector<int64_t>& request_ids,
82 int* count) { 104 int* count) {
83 DCHECK(count); 105 DCHECK(count);
84 // If you create a transaction but don't Commit() it is automatically 106 // If you create a transaction but don't Commit() it is automatically
85 // rolled back by its destructor when it falls out of scope. 107 // rolled back by its destructor when it falls out of scope.
86 sql::Transaction transaction(db); 108 sql::Transaction transaction(db);
87 if (!transaction.Begin()) 109 if (!transaction.Begin())
88 return false; 110 return false;
89 111
(...skipping 26 matching lines...) Expand all
116 return false; 138 return false;
117 *count += db->GetLastChangeCount(); 139 *count += db->GetLastChangeCount();
118 } 140 }
119 141
120 if (!transaction.Commit()) 142 if (!transaction.Commit())
121 return false; 143 return false;
122 144
123 return true; 145 return true;
124 } 146 }
125 147
148 RequestQueueStore::UpdateStatus PauseRequests(
149 sql::Connection* db, const std::vector<int64_t>& request_ids) {
150 // If you create a transaction but don't Commit() it is automatically
151 // rolled back by its destructor when it falls out of scope.
152 sql::Transaction transaction(db);
153 if (!transaction.Begin())
154 return RequestQueueStore::UpdateStatus::FAILED;
155 for (const auto& request_id : request_ids) {
156 if (!PauseRequest(db, request_id))
157 return RequestQueueStore::UpdateStatus::FAILED;
158 }
159
160 if (!transaction.Commit())
161 return RequestQueueStore::UpdateStatus::FAILED;
162
163 return RequestQueueStore::UpdateStatus::UPDATED;
164 }
165
166 RequestQueueStore::UpdateStatus ResumeRequests(
167 sql::Connection* db, const std::vector<int64_t>& request_ids) {
168 // If you create a transaction but don't Commit() it is automatically
169 // rolled back by its destructor when it falls out of scope.
170 sql::Transaction transaction(db);
171 if (!transaction.Begin())
172 return RequestQueueStore::UpdateStatus::FAILED;
173
174 for (const auto& request_id : request_ids) {
175 if (!ResumeRequest(db, request_id))
176 return RequestQueueStore::UpdateStatus::FAILED;
177 }
178
179 if (!transaction.Commit())
180 return RequestQueueStore::UpdateStatus::FAILED;
181
182 return RequestQueueStore::UpdateStatus::UPDATED;
183 }
184
126 // Create a save page request from a SQL result. Expects complete rows with 185 // 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 186 // all columns present. Columns are in order they are defined in select query
128 // in |RequestQueueStore::RequestSync| method. 187 // in |RequestQueueStore::RequestSync| method.
129 SavePageRequest MakeSavePageRequest(const sql::Statement& statement) { 188 SavePageRequest MakeSavePageRequest(const sql::Statement& statement) {
130 const int64_t id = statement.ColumnInt64(0); 189 const int64_t id = statement.ColumnInt64(0);
131 const base::Time creation_time = 190 const base::Time creation_time =
132 base::Time::FromInternalValue(statement.ColumnInt64(1)); 191 base::Time::FromInternalValue(statement.ColumnInt64(1));
133 const base::Time activation_time = 192 const base::Time activation_time =
134 base::Time::FromInternalValue(statement.ColumnInt64(2)); 193 base::Time::FromInternalValue(statement.ColumnInt64(2));
135 const base::Time last_attempt_time = 194 const base::Time last_attempt_time =
(...skipping 147 matching lines...) Expand 10 before | Expand all | Expand 10 after
283 const RemoveCallback& callback) { 342 const RemoveCallback& callback) {
284 // TODO(fgorski): add UMA metrics here. 343 // TODO(fgorski): add UMA metrics here.
285 int count = 0; 344 int count = 0;
286 if (DeleteRequestsByClientIds(db, client_ids, &count)) 345 if (DeleteRequestsByClientIds(db, client_ids, &count))
287 runner->PostTask(FROM_HERE, base::Bind(callback, true, count)); 346 runner->PostTask(FROM_HERE, base::Bind(callback, true, count));
288 else 347 else
289 runner->PostTask(FROM_HERE, base::Bind(callback, false, 0)); 348 runner->PostTask(FROM_HERE, base::Bind(callback, false, 0));
290 } 349 }
291 350
292 // static 351 // static
352 void RequestQueueStoreSQL::PauseRequestsSync(
Dmitry Titov 2016/08/09 23:46:33 I am not sure the store must have methods like Pau
Pete Williamson 2016/08/10 01:34:10 Done.
353 sql::Connection* db,
354 scoped_refptr<base::SingleThreadTaskRunner> runner,
355 const std::vector<int64_t>& request_ids,
356 const UpdateCallback& callback) {
357 // TODO(fgorski): add UMA metrics here.
358 RequestQueueStore::UpdateStatus status =
359 offline_pages::PauseRequests(db, request_ids);
360 runner->PostTask(FROM_HERE, base::Bind(callback, status));
361 }
362
363 // static
364 void RequestQueueStoreSQL::ResumeRequestsSync(
365 sql::Connection* db,
366 scoped_refptr<base::SingleThreadTaskRunner> runner,
367 const std::vector<int64_t>& request_ids,
368 const UpdateCallback& callback) {
369 // TODO(fgorski): add UMA metrics here.
370 RequestQueueStore::UpdateStatus status =
371 offline_pages::ResumeRequests(db, request_ids);
372 runner->PostTask(FROM_HERE, base::Bind(callback, status));
373 }
374
375 // static
293 void RequestQueueStoreSQL::ResetSync( 376 void RequestQueueStoreSQL::ResetSync(
294 sql::Connection* db, 377 sql::Connection* db,
295 const base::FilePath& db_file_path, 378 const base::FilePath& db_file_path,
296 scoped_refptr<base::SingleThreadTaskRunner> runner, 379 scoped_refptr<base::SingleThreadTaskRunner> runner,
297 const ResetCallback& callback) { 380 const ResetCallback& callback) {
298 // This method deletes the content of the whole store and reinitializes it. 381 // This method deletes the content of the whole store and reinitializes it.
299 bool success = db->Raze(); 382 bool success = db->Raze();
300 db->Close(); 383 db->Close();
301 if (success) 384 if (success)
302 success = InitDatabase(db, db_file_path); 385 success = InitDatabase(db, db_file_path);
303 runner->PostTask(FROM_HERE, base::Bind(callback, success)); 386 runner->PostTask(FROM_HERE, base::Bind(callback, success));
304 } 387 }
305 388
306 void RequestQueueStoreSQL::GetRequests(const GetRequestsCallback& callback) { 389 bool RequestQueueStoreSQL::CheckDb(const RemoveCallback& callback) {
390 DCHECK(db_.get());
391 if (!db_.get()) {
392 // Nothing to do, but post a callback instead of calling directly
393 // to preserve the async style behavior to prevent bugs.
394 base::ThreadTaskRunnerHandle::Get()->PostTask(
395 FROM_HERE, base::Bind(callback, false, 0));
396 return false;
397 }
398 return true;
399 }
400
401 bool RequestQueueStoreSQL::CheckDb(const GetRequestsCallback& callback) {
307 DCHECK(db_.get()); 402 DCHECK(db_.get());
308 if (!db_.get()) { 403 if (!db_.get()) {
309 // Nothing to do, but post a callback instead of calling directly 404 // Nothing to do, but post a callback instead of calling directly
310 // to preserve the async style behavior to prevent bugs. 405 // to preserve the async style behavior to prevent bugs.
311 base::ThreadTaskRunnerHandle::Get()->PostTask( 406 base::ThreadTaskRunnerHandle::Get()->PostTask(
312 FROM_HERE, base::Bind(callback, false, std::vector<SavePageRequest>())); 407 FROM_HERE, base::Bind(callback, false, std::vector<SavePageRequest>()));
408 return false;
409 }
410 return true;
411 }
412
413 bool RequestQueueStoreSQL::CheckDb(const UpdateCallback& callback) {
Dmitry Titov 2016/08/09 23:46:33 The answer to multiple CheckDB functions is to pas
Pete Williamson 2016/08/10 01:34:10 Done.
414 DCHECK(db_.get());
415 if (!db_.get()) {
416 // Nothing to do, but post a callback instead of calling directly
417 // to preserve the async style behavior to prevent bugs.
418 base::ThreadTaskRunnerHandle::Get()->PostTask(
419 FROM_HERE, base::Bind(callback, UpdateStatus::FAILED));
420 return false;
421 }
422
423 return true;
424 }
425
426 bool RequestQueueStoreSQL::CheckDb(const ResetCallback& callback) {
427 DCHECK(db_.get());
428 if (!db_.get()) {
429 // Nothing to do, but post a callback instead of calling directly
430 // to preserve the async style behavior to prevent bugs.
431 base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE,
432 base::Bind(callback, false));
433 return false;
434 }
435
436 return true;
437 }
438
439 void RequestQueueStoreSQL::GetRequests(const GetRequestsCallback& callback) {
440 DCHECK(db_.get());
441 if (!CheckDb(callback))
313 return; 442 return;
314 }
315 443
316 background_task_runner_->PostTask( 444 background_task_runner_->PostTask(
317 FROM_HERE, base::Bind(&RequestQueueStoreSQL::GetRequestsSync, db_.get(), 445 FROM_HERE, base::Bind(&RequestQueueStoreSQL::GetRequestsSync, db_.get(),
318 base::ThreadTaskRunnerHandle::Get(), callback)); 446 base::ThreadTaskRunnerHandle::Get(), callback));
319 } 447 }
320 448
321 void RequestQueueStoreSQL::AddOrUpdateRequest(const SavePageRequest& request, 449 void RequestQueueStoreSQL::AddOrUpdateRequest(const SavePageRequest& request,
322 const UpdateCallback& callback) { 450 const UpdateCallback& callback) {
323 DCHECK(db_.get()); 451 DCHECK(db_.get());
324 if (!db_.get()) { 452 if (!CheckDb(callback))
325 // Nothing to do, but post a callback instead of calling directly
326 // to preserve the async style behavior to prevent bugs.
327 base::ThreadTaskRunnerHandle::Get()->PostTask(
328 FROM_HERE, base::Bind(callback, UpdateStatus::FAILED));
329 return; 453 return;
330 }
331 454
332 background_task_runner_->PostTask( 455 background_task_runner_->PostTask(
333 FROM_HERE, 456 FROM_HERE,
334 base::Bind(&RequestQueueStoreSQL::AddOrUpdateRequestSync, db_.get(), 457 base::Bind(&RequestQueueStoreSQL::AddOrUpdateRequestSync, db_.get(),
335 base::ThreadTaskRunnerHandle::Get(), request, callback)); 458 base::ThreadTaskRunnerHandle::Get(), request, callback));
336 } 459 }
337 460
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.
342 void RequestQueueStoreSQL::RemoveRequests( 461 void RequestQueueStoreSQL::RemoveRequests(
343 const std::vector<int64_t>& request_ids, 462 const std::vector<int64_t>& request_ids,
344 const RemoveCallback& callback) { 463 const RemoveCallback& callback) {
345 DCHECK(db_.get()); 464 if (!CheckDb(callback))
346 if (!db_.get()) {
347 // Nothing to do, but post a callback instead of calling directly
348 // to preserve the async style behavior to prevent bugs.
349 base::ThreadTaskRunnerHandle::Get()->PostTask(
350 FROM_HERE, base::Bind(callback, false, 0));
351 return; 465 return;
352 }
353 466
354 background_task_runner_->PostTask( 467 background_task_runner_->PostTask(
355 FROM_HERE, 468 FROM_HERE,
356 base::Bind(&RequestQueueStoreSQL::RemoveRequestsSync, db_.get(), 469 base::Bind(&RequestQueueStoreSQL::RemoveRequestsSync, db_.get(),
357 base::ThreadTaskRunnerHandle::Get(), request_ids, callback)); 470 base::ThreadTaskRunnerHandle::Get(), request_ids, callback));
358 } 471 }
359 472
360 void RequestQueueStoreSQL::RemoveRequestsByClientId( 473 void RequestQueueStoreSQL::RemoveRequestsByClientId(
361 const std::vector<ClientId>& client_ids, 474 const std::vector<ClientId>& client_ids,
362 const RemoveCallback& callback) { 475 const RemoveCallback& callback) {
363 DCHECK(db_.get()); 476 DCHECK(db_.get());
364 if (!db_.get()) { 477 if (!db_.get()) {
365 // Nothing to do, but post a callback instead of calling directly 478 // Nothing to do, but post a callback instead of calling directly
366 // to preserve the async style behavior to prevent bugs. 479 // to preserve the async style behavior to prevent bugs.
367 base::ThreadTaskRunnerHandle::Get()->PostTask( 480 base::ThreadTaskRunnerHandle::Get()->PostTask(
368 FROM_HERE, base::Bind(callback, false, 0)); 481 FROM_HERE, base::Bind(callback, false, 0));
369 return; 482 return;
370 } 483 }
371 484
372 background_task_runner_->PostTask( 485 background_task_runner_->PostTask(
373 FROM_HERE, 486 FROM_HERE,
374 base::Bind(&RequestQueueStoreSQL::RemoveRequestsByClientIdSync, db_.get(), 487 base::Bind(&RequestQueueStoreSQL::RemoveRequestsByClientIdSync, db_.get(),
375 base::ThreadTaskRunnerHandle::Get(), client_ids, callback)); 488 base::ThreadTaskRunnerHandle::Get(), client_ids, callback));
376 } 489 }
377 490
378 void RequestQueueStoreSQL::Reset(const ResetCallback& callback) { 491 void RequestQueueStoreSQL::PauseRequests(
379 DCHECK(db_.get()); 492 const std::vector<int64_t>& request_ids,
380 if (!db_.get()) { 493 const UpdateCallback& callback) {
381 // Nothing to do, but post a callback instead of calling directly 494 if (!CheckDb(callback))
382 // to preserve the async style behavior to prevent bugs. 495 return;
383 base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE, 496
384 base::Bind(callback, false)); 497 background_task_runner_->PostTask(
498 FROM_HERE,
499 base::Bind(&RequestQueueStoreSQL::PauseRequestsSync, db_.get(),
500 base::ThreadTaskRunnerHandle::Get(), request_ids, callback));
501 }
502
503 void RequestQueueStoreSQL::ResumeRequests(
504 const std::vector<int64_t>& request_ids,
505 const UpdateCallback& callback) {
506 if (!CheckDb(callback)) {
385 return; 507 return;
386 } 508 }
387 509
510 background_task_runner_->PostTask(
511 FROM_HERE,
512 base::Bind(&RequestQueueStoreSQL::ResumeRequestsSync, db_.get(),
513 base::ThreadTaskRunnerHandle::Get(), request_ids, callback));
514 }
515
516
517 void RequestQueueStoreSQL::Reset(const ResetCallback& callback) {
518 DCHECK(db_.get());
519 if (!CheckDb(callback)) {
520 return;
521 }
522
388 background_task_runner_->PostTask( 523 background_task_runner_->PostTask(
389 FROM_HERE, 524 FROM_HERE,
390 base::Bind(&RequestQueueStoreSQL::ResetSync, db_.get(), db_file_path_, 525 base::Bind(&RequestQueueStoreSQL::ResetSync, db_.get(), db_file_path_,
391 base::ThreadTaskRunnerHandle::Get(), 526 base::ThreadTaskRunnerHandle::Get(),
392 base::Bind(&RequestQueueStoreSQL::OnResetDone, 527 base::Bind(&RequestQueueStoreSQL::OnResetDone,
393 weak_ptr_factory_.GetWeakPtr(), callback))); 528 weak_ptr_factory_.GetWeakPtr(), callback)));
394 } 529 }
395 530
396 void RequestQueueStoreSQL::OpenConnection() { 531 void RequestQueueStoreSQL::OpenConnection() {
397 DCHECK(!db_); 532 DCHECK(!db_);
(...skipping 15 matching lines...) Expand all
413 } 548 }
414 549
415 void RequestQueueStoreSQL::OnResetDone(const ResetCallback& callback, 550 void RequestQueueStoreSQL::OnResetDone(const ResetCallback& callback,
416 bool success) { 551 bool success) {
417 // Complete connection initialization post reset. 552 // Complete connection initialization post reset.
418 OnOpenConnectionDone(success); 553 OnOpenConnectionDone(success);
419 callback.Run(success); 554 callback.Run(success);
420 } 555 }
421 556
422 } // namespace offline_pages 557 } // namespace offline_pages
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698