OLD | NEW |
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 Loading... |
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 Loading... |
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 } |
OLD | NEW |