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

Side by Side Diff: components/webdata/common/web_database_backend.cc

Issue 2225333003: Recreate the WebData database on a catastrophic SQL error (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Fix typo 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 2013 The Chromium Authors. All rights reserved. 1 // Copyright 2013 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/webdata/common/web_database_backend.h" 5 #include "components/webdata/common/web_database_backend.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 #include <utility> 8 #include <utility>
9 9
10 #include "base/bind.h" 10 #include "base/bind.h"
(...skipping 23 matching lines...) Expand all
34 tables_.push_back(table.release()); 34 tables_.push_back(table.release());
35 } 35 }
36 36
37 void WebDatabaseBackend::InitDatabase() { 37 void WebDatabaseBackend::InitDatabase() {
38 LoadDatabaseIfNecessary(); 38 LoadDatabaseIfNecessary();
39 if (delegate_) { 39 if (delegate_) {
40 delegate_->DBLoaded(init_status_, diagnostics_); 40 delegate_->DBLoaded(init_status_, diagnostics_);
41 } 41 }
42 } 42 }
43 43
44 sql::InitStatus WebDatabaseBackend::LoadDatabaseIfNecessary() {
45 if (init_complete_ || db_path_.empty()) {
46 return init_status_;
47 }
48 init_complete_ = true;
49 db_.reset(new WebDatabase());
50
51 for (const auto& table : tables_)
52 db_->AddTable(table);
53
54 // Unretained to avoid a ref loop since we own |db_|.
55 db_->set_error_callback(base::Bind(&WebDatabaseBackend::DatabaseErrorCallback,
56 base::Unretained(this)));
57 diagnostics_.clear();
58 init_status_ = db_->Init(db_path_);
59 if (init_status_ != sql::INIT_OK) {
60 LOG(ERROR) << "Cannot initialize the web database: " << init_status_;
61 diagnostics_ += sql::GetCorruptFileDiagnosticsInfo(db_path_);
62 db_.reset();
63 return init_status_;
64 }
65
66 db_->BeginTransaction();
67 return init_status_;
68 }
69
70 void WebDatabaseBackend::ShutdownDatabase() { 44 void WebDatabaseBackend::ShutdownDatabase() {
71 if (db_ && init_status_ == sql::INIT_OK) 45 if (db_ && init_status_ == sql::INIT_OK)
72 db_->CommitTransaction(); 46 db_->CommitTransaction();
73 db_.reset(NULL); 47 db_.reset(NULL);
74 init_complete_ = true; // Ensures the init sequence is not re-run. 48 init_complete_ = true; // Ensures the init sequence is not re-run.
75 init_status_ = sql::INIT_FAILURE; 49 init_status_ = sql::INIT_FAILURE;
76 } 50 }
77 51
78 void WebDatabaseBackend::DBWriteTaskWrapper( 52 void WebDatabaseBackend::DBWriteTaskWrapper(
79 const WebDatabaseService::WriteTask& task, 53 const WebDatabaseService::WriteTask& task,
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
111 if (db_ && init_status_ == sql::INIT_OK) { 85 if (db_ && init_status_ == sql::INIT_OK) {
112 return task.Run(db_.get()); 86 return task.Run(db_.get());
113 } 87 }
114 return nullptr; 88 return nullptr;
115 } 89 }
116 90
117 WebDatabaseBackend::~WebDatabaseBackend() { 91 WebDatabaseBackend::~WebDatabaseBackend() {
118 ShutdownDatabase(); 92 ShutdownDatabase();
119 } 93 }
120 94
95 void WebDatabaseBackend::LoadDatabaseIfNecessary() {
96 if (init_complete_ || db_path_.empty())
97 return;
98
99 init_complete_ = true;
100 db_.reset(new WebDatabase());
101
102 for (const auto& table : tables_)
103 db_->AddTable(table);
104
105 // Unretained to avoid a ref loop since we own |db_|.
106 db_->set_error_callback(base::Bind(&WebDatabaseBackend::DatabaseErrorCallback,
107 base::Unretained(this)));
108 diagnostics_.clear();
109 catastrophic_error_occurred_ = false;
110 init_status_ = db_->Init(db_path_);
111
112 if (init_status_ != sql::INIT_OK) {
113 LOG(ERROR) << "Cannot initialize the web database: " << init_status_;
114 db_.reset();
115 return;
116 }
117
118 // A catastrophic error might have happened and recovered.
119 if (catastrophic_error_occurred_) {
120 init_status_ = sql::INIT_OK_WITH_DATA_LOSS;
121 LOG(WARNING)
122 << "Webdata recovered from a catastrophic error. Data loss possible.";
123 }
124 db_->BeginTransaction();
125 }
126
121 void WebDatabaseBackend::DatabaseErrorCallback(int error, 127 void WebDatabaseBackend::DatabaseErrorCallback(int error,
122 sql::Statement* statement) { 128 sql::Statement* statement) {
123 // We ignore any further error callbacks after the first catastrophic error. 129 // We ignore any further error callbacks after the first catastrophic error.
124 if (!catastrophic_error_occurred_ && sql::IsErrorCatastrophic(error)) { 130 if (!catastrophic_error_occurred_ && sql::IsErrorCatastrophic(error)) {
125 catastrophic_error_occurred_ = true; 131 catastrophic_error_occurred_ = true;
126 diagnostics_ = db_->GetDiagnosticInfo(error, statement); 132 diagnostics_ = db_->GetDiagnosticInfo(error, statement);
133 diagnostics_ += sql::GetCorruptFileDiagnosticsInfo(db_path_);
134
135 db_->GetSQLConnection()->RazeAndClose();
127 } 136 }
128 } 137 }
129 138
130 void WebDatabaseBackend::Commit() { 139 void WebDatabaseBackend::Commit() {
131 DCHECK(db_); 140 DCHECK(db_);
132 DCHECK_EQ(sql::INIT_OK, init_status_); 141 DCHECK_EQ(sql::INIT_OK, init_status_);
133 db_->CommitTransaction(); 142 db_->CommitTransaction();
134 db_->BeginTransaction(); 143 db_->BeginTransaction();
135 } 144 }
OLDNEW
« no previous file with comments | « components/webdata/common/web_database_backend.h ('k') | components/webdata/common/web_database_service.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698