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

Side by Side Diff: components/offline_pages/offline_page_metadata_store_sql.cc

Issue 2384423003: [Offline pages] Resetting offline page metadata store if initial load fails (Closed)
Patch Set: Rebased and comments addressed Created 4 years, 2 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/offline_page_metadata_store_sql.h" 5 #include "components/offline_pages/offline_page_metadata_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 236 matching lines...) Expand 10 before | Expand all | Expand 10 after
247 } 247 }
248 if (!db->Open(path)) { 248 if (!db->Open(path)) {
249 LOG(ERROR) << "Failed to open database"; 249 LOG(ERROR) << "Failed to open database";
250 return false; 250 return false;
251 } 251 }
252 db->Preload(); 252 db->Preload();
253 253
254 return CreateSchema(db); 254 return CreateSchema(db);
255 } 255 }
256 256
257 void NotifyLoadResult(scoped_refptr<base::SingleThreadTaskRunner> runner,
258 const OfflinePageMetadataStore::LoadCallback& callback,
259 OfflinePageMetadataStore::LoadStatus status,
260 const std::vector<OfflinePageItem>& result) {
261 // TODO(bburns): Switch to SQL specific UMA metrics.
262 UMA_HISTOGRAM_ENUMERATION("OfflinePages.LoadStatus", status,
263 OfflinePageMetadataStore::LOAD_STATUS_COUNT);
264 if (status == OfflinePageMetadataStore::LOAD_SUCCEEDED) {
265 UMA_HISTOGRAM_COUNTS("OfflinePages.SavedPageCount",
266 static_cast<int32_t>(result.size()));
267 } else {
268 DVLOG(1) << "Offline pages database loading failed: " << status;
269 }
270 runner->PostTask(FROM_HERE, base::Bind(callback, status, result));
271 }
272
273 void OpenConnectionSync(sql::Connection* db, 257 void OpenConnectionSync(sql::Connection* db,
274 scoped_refptr<base::SingleThreadTaskRunner> runner, 258 scoped_refptr<base::SingleThreadTaskRunner> runner,
275 const base::FilePath& path, 259 const base::FilePath& path,
276 const base::Callback<void(StoreState)>& callback) { 260 const base::Callback<void(StoreState)>& callback) {
277 StoreState state = 261 StoreState state =
278 InitDatabase(db, path) ? StoreState::LOADED : StoreState::FAILED_LOADING; 262 InitDatabase(db, path) ? StoreState::LOADED : StoreState::FAILED_LOADING;
279 runner->PostTask(FROM_HERE, base::Bind(callback, state)); 263 runner->PostTask(FROM_HERE, base::Bind(callback, state));
280 } 264 }
281 265
282 bool GetPageByOfflineIdSync(sql::Connection* db, 266 bool GetPageByOfflineIdSync(sql::Connection* db,
283 int64_t offline_id, 267 int64_t offline_id,
284 OfflinePageItem* item) { 268 OfflinePageItem* item) {
285 const char kSql[] = 269 const char kSql[] =
286 "SELECT * FROM " OFFLINE_PAGES_TABLE_NAME " WHERE offline_id = ?"; 270 "SELECT * FROM " OFFLINE_PAGES_TABLE_NAME " WHERE offline_id = ?";
287 sql::Statement statement(db->GetCachedStatement(SQL_FROM_HERE, kSql)); 271 sql::Statement statement(db->GetCachedStatement(SQL_FROM_HERE, kSql));
288 statement.BindInt64(0, offline_id); 272 statement.BindInt64(0, offline_id);
289 273
290 if (statement.Step()) { 274 if (statement.Step()) {
291 *item = MakeOfflinePageItem(&statement); 275 *item = MakeOfflinePageItem(&statement);
292 return true; 276 return true;
293 } 277 }
294 278
295 return false; 279 return false;
296 } 280 }
297 281
298 void GetOfflinePagesSync( 282 void GetOfflinePagesSync(
299 sql::Connection* db, 283 sql::Connection* db,
300 scoped_refptr<base::SingleThreadTaskRunner> runner, 284 scoped_refptr<base::SingleThreadTaskRunner> runner,
301 const OfflinePageMetadataStore::LoadCallback& callback) { 285 const OfflinePageMetadataStore::GetOfflinePagesCallback& callback) {
302 const char kSql[] = "SELECT * FROM " OFFLINE_PAGES_TABLE_NAME; 286 const char kSql[] = "SELECT * FROM " OFFLINE_PAGES_TABLE_NAME;
303 287
304 sql::Statement statement(db->GetCachedStatement(SQL_FROM_HERE, kSql)); 288 sql::Statement statement(db->GetCachedStatement(SQL_FROM_HERE, kSql));
305 289
306 std::vector<OfflinePageItem> result; 290 std::vector<OfflinePageItem> result;
307 while (statement.Step()) 291 while (statement.Step())
308 result.push_back(MakeOfflinePageItem(&statement)); 292 result.push_back(MakeOfflinePageItem(&statement));
309 293
310 if (statement.Succeeded()) { 294 StoreState store_state =
311 NotifyLoadResult(runner, callback, OfflinePageMetadataStore::LOAD_SUCCEEDED, 295 statement.Succeeded() ? StoreState::LOADED : StoreState::FAILED_OPERATION;
312 result); 296 if (!statement.Succeeded())
313 } else {
314 result.clear(); 297 result.clear();
315 NotifyLoadResult(runner, callback, 298
316 OfflinePageMetadataStore::STORE_LOAD_FAILED, result); 299 runner->PostTask(FROM_HERE, base::Bind(callback, store_state, result));
317 }
318 } 300 }
319 301
320 void AddOfflinePageSync(sql::Connection* db, 302 void AddOfflinePageSync(sql::Connection* db,
321 scoped_refptr<base::SingleThreadTaskRunner> runner, 303 scoped_refptr<base::SingleThreadTaskRunner> runner,
322 const OfflinePageItem& offline_page, 304 const OfflinePageItem& offline_page,
323 const OfflinePageMetadataStore::AddCallback& callback) { 305 const OfflinePageMetadataStore::AddCallback& callback) {
324 ItemActionStatus status = Insert(db, offline_page); 306 ItemActionStatus status = Insert(db, offline_page);
325 runner->PostTask(FROM_HERE, base::Bind(callback, status)); 307 runner->PostTask(FROM_HERE, base::Bind(callback, status));
326 } 308 }
327 309
(...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after
430 } 412 }
431 413
432 void ResetSync(sql::Connection* db, 414 void ResetSync(sql::Connection* db,
433 const base::FilePath& db_file_path, 415 const base::FilePath& db_file_path,
434 scoped_refptr<base::SingleThreadTaskRunner> runner, 416 scoped_refptr<base::SingleThreadTaskRunner> runner,
435 const base::Callback<void(StoreState)>& callback) { 417 const base::Callback<void(StoreState)>& callback) {
436 // This method deletes the content of the whole store and reinitializes it. 418 // This method deletes the content of the whole store and reinitializes it.
437 bool success = db->Raze(); 419 bool success = db->Raze();
438 db->Close(); 420 db->Close();
439 StoreState state; 421 StoreState state;
440 if (success) { 422 if (!success)
441 state = InitDatabase(db, db_file_path) ? StoreState::LOADED
442 : StoreState::FAILED_LOADING;
443 } else {
444 state = StoreState::FAILED_RESET; 423 state = StoreState::FAILED_RESET;
445 } 424 else if (InitDatabase(db, db_file_path))
425 state = StoreState::LOADED;
426 else
427 state = StoreState::FAILED_RESET;
428
446 runner->PostTask(FROM_HERE, base::Bind(callback, state)); 429 runner->PostTask(FROM_HERE, base::Bind(callback, state));
447 } 430 }
448 431
449 } // anonymous namespace 432 } // anonymous namespace
450 433
451 OfflinePageMetadataStoreSQL::OfflinePageMetadataStoreSQL( 434 OfflinePageMetadataStoreSQL::OfflinePageMetadataStoreSQL(
452 scoped_refptr<base::SequencedTaskRunner> background_task_runner, 435 scoped_refptr<base::SequencedTaskRunner> background_task_runner,
453 const base::FilePath& path) 436 const base::FilePath& path)
454 : background_task_runner_(std::move(background_task_runner)), 437 : background_task_runner_(std::move(background_task_runner)),
455 db_file_path_(path.AppendASCII("OfflinePages.db")), 438 db_file_path_(path.AppendASCII("OfflinePages.db")),
456 state_(StoreState::NOT_LOADED), 439 state_(StoreState::NOT_LOADED),
457 weak_ptr_factory_(this) { 440 weak_ptr_factory_(this) {
458 OpenConnection(); 441 OpenConnection();
459 } 442 }
460 443
461 OfflinePageMetadataStoreSQL::~OfflinePageMetadataStoreSQL() { 444 OfflinePageMetadataStoreSQL::~OfflinePageMetadataStoreSQL() {
462 if (db_.get() && 445 if (db_.get() &&
463 !background_task_runner_->DeleteSoon(FROM_HERE, db_.release())) { 446 !background_task_runner_->DeleteSoon(FROM_HERE, db_.release())) {
464 DLOG(WARNING) << "SQL database will not be deleted."; 447 DLOG(WARNING) << "SQL database will not be deleted.";
465 } 448 }
466 } 449 }
467 450
468 void OfflinePageMetadataStoreSQL::GetOfflinePages( 451 void OfflinePageMetadataStoreSQL::GetOfflinePages(
469 const LoadCallback& callback) { 452 const GetOfflinePagesCallback& callback) {
470 if (!CheckDb(base::Bind( 453 if (!CheckStoreState()) {
471 callback, STORE_INIT_FAILED, std::vector<OfflinePageItem>()))) { 454 base::ThreadTaskRunnerHandle::Get()->PostTask(
455 FROM_HERE,
456 base::Bind(callback, state(), std::vector<OfflinePageItem>()));
472 return; 457 return;
473 } 458 }
474 459
475 background_task_runner_->PostTask( 460 background_task_runner_->PostTask(
476 FROM_HERE, base::Bind(&GetOfflinePagesSync, db_.get(), 461 FROM_HERE, base::Bind(&GetOfflinePagesSync, db_.get(),
477 base::ThreadTaskRunnerHandle::Get(), callback)); 462 base::ThreadTaskRunnerHandle::Get(), callback));
478 } 463 }
479 464
480 void OfflinePageMetadataStoreSQL::AddOfflinePage( 465 void OfflinePageMetadataStoreSQL::AddOfflinePage(
481 const OfflinePageItem& offline_page, 466 const OfflinePageItem& offline_page,
482 const AddCallback& callback) { 467 const AddCallback& callback) {
483 if (!CheckDb(base::Bind(callback, ItemActionStatus::STORE_ERROR))) 468 if (!CheckStoreState()) {
469 base::ThreadTaskRunnerHandle::Get()->PostTask(
470 FROM_HERE, base::Bind(callback, ItemActionStatus::STORE_ERROR));
484 return; 471 return;
472 }
485 473
486 background_task_runner_->PostTask( 474 background_task_runner_->PostTask(
487 FROM_HERE, 475 FROM_HERE,
488 base::Bind(&AddOfflinePageSync, db_.get(), 476 base::Bind(&AddOfflinePageSync, db_.get(),
489 base::ThreadTaskRunnerHandle::Get(), offline_page, callback)); 477 base::ThreadTaskRunnerHandle::Get(), offline_page, callback));
490 } 478 }
491 479
492 void OfflinePageMetadataStoreSQL::UpdateOfflinePages( 480 void OfflinePageMetadataStoreSQL::UpdateOfflinePages(
493 const std::vector<OfflinePageItem>& pages, 481 const std::vector<OfflinePageItem>& pages,
494 const UpdateCallback& callback) { 482 const UpdateCallback& callback) {
(...skipping 22 matching lines...) Expand all
517 ItemActionStatus::NOT_FOUND /* will be ignored */, callback); 505 ItemActionStatus::NOT_FOUND /* will be ignored */, callback);
518 return; 506 return;
519 } 507 }
520 508
521 background_task_runner_->PostTask( 509 background_task_runner_->PostTask(
522 FROM_HERE, base::Bind(&RemoveOfflinePagesSync, offline_ids, db_.get(), 510 FROM_HERE, base::Bind(&RemoveOfflinePagesSync, offline_ids, db_.get(),
523 base::ThreadTaskRunnerHandle::Get(), callback)); 511 base::ThreadTaskRunnerHandle::Get(), callback));
524 } 512 }
525 513
526 void OfflinePageMetadataStoreSQL::Reset(const ResetCallback& callback) { 514 void OfflinePageMetadataStoreSQL::Reset(const ResetCallback& callback) {
527 if (!CheckDb(base::Bind(callback, false))) 515 if (!CheckStoreState()) {
516 base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE,
517 base::Bind(callback, false));
528 return; 518 return;
519 }
529 520
530 background_task_runner_->PostTask( 521 background_task_runner_->PostTask(
531 FROM_HERE, 522 FROM_HERE,
532 base::Bind(&ResetSync, db_.get(), db_file_path_, 523 base::Bind(&ResetSync, db_.get(), db_file_path_,
533 base::ThreadTaskRunnerHandle::Get(), 524 base::ThreadTaskRunnerHandle::Get(),
534 base::Bind(&OfflinePageMetadataStoreSQL::OnResetDone, 525 base::Bind(&OfflinePageMetadataStoreSQL::OnResetDone,
535 weak_ptr_factory_.GetWeakPtr(), callback))); 526 weak_ptr_factory_.GetWeakPtr(), callback)));
536 } 527 }
537 528
538 StoreState OfflinePageMetadataStoreSQL::state() const {
539 return state_;
540 }
541
542 void OfflinePageMetadataStoreSQL::SetStateForTesting(StoreState state,
543 bool reset_db) {
544 state_ = state;
545 if (reset_db)
546 db_.reset(nullptr);
547 }
548
549 void OfflinePageMetadataStoreSQL::OpenConnection() { 529 void OfflinePageMetadataStoreSQL::OpenConnection() {
550 DCHECK(!db_); 530 DCHECK(!db_);
551 db_.reset(new sql::Connection()); 531 db_.reset(new sql::Connection());
552 background_task_runner_->PostTask( 532 background_task_runner_->PostTask(
553 FROM_HERE, 533 FROM_HERE,
554 base::Bind(&OpenConnectionSync, db_.get(), 534 base::Bind(&OpenConnectionSync, db_.get(),
555 base::ThreadTaskRunnerHandle::Get(), db_file_path_, 535 base::ThreadTaskRunnerHandle::Get(), db_file_path_,
556 base::Bind(&OfflinePageMetadataStoreSQL::OnOpenConnectionDone, 536 base::Bind(&OfflinePageMetadataStoreSQL::OnOpenConnectionDone,
557 weak_ptr_factory_.GetWeakPtr()))); 537 weak_ptr_factory_.GetWeakPtr())));
558 } 538 }
559 539
560 void OfflinePageMetadataStoreSQL::OnOpenConnectionDone(StoreState state) { 540 void OfflinePageMetadataStoreSQL::OnOpenConnectionDone(StoreState state) {
561 DCHECK(db_.get()); 541 DCHECK(db_.get());
562 542
563 state_ = state; 543 state_ = state;
564 544
565 // Unfortunately we were not able to open DB connection. 545 // Unfortunately we were not able to open DB connection.
566 if (state != StoreState::LOADED) 546 if (state != StoreState::LOADED)
567 db_.reset(); 547 db_.reset();
568
569 // TODO(fgorski): This might be a place to start store recovery. Alternatively
570 // that can be attempted in the OfflinePageModel.
571 } 548 }
572 549
573 void OfflinePageMetadataStoreSQL::OnResetDone(const ResetCallback& callback, 550 void OfflinePageMetadataStoreSQL::OnResetDone(const ResetCallback& callback,
574 StoreState state) { 551 StoreState state) {
575 OnOpenConnectionDone(state); 552 OnOpenConnectionDone(state);
576 callback.Run(state == StoreState::LOADED); 553 callback.Run(state == StoreState::LOADED);
577 } 554 }
578 555
579 bool OfflinePageMetadataStoreSQL::CheckDb(const base::Closure& callback) { 556 bool OfflinePageMetadataStoreSQL::CheckStoreState() {
580 if (!db_.get() || state_ != StoreState::LOADED) { 557 // If db is null, store cannot be loaded.
581 base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE, callback); 558 DCHECK(db_.get() || state_ != StoreState::LOADED);
582 return false; 559 return db_.get() && state_ == StoreState::LOADED;
583 } 560 }
584 return true; 561
562 StoreState OfflinePageMetadataStoreSQL::state() const {
563 return state_;
564 }
565
566 void OfflinePageMetadataStoreSQL::SetStateForTesting(StoreState state,
567 bool reset_db) {
568 state_ = state;
569 if (reset_db)
570 db_.reset(nullptr);
585 } 571 }
586 572
587 } // namespace offline_pages 573 } // namespace offline_pages
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698