OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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/omnibox/browser/shortcuts_database.h" | 5 #include "components/omnibox/browser/shortcuts_database.h" |
6 | 6 |
7 #include <string> | 7 #include <string> |
8 | 8 |
| 9 #include "base/bind.h" |
9 #include "base/guid.h" | 10 #include "base/guid.h" |
10 #include "base/logging.h" | 11 #include "base/logging.h" |
11 #include "base/strings/stringprintf.h" | 12 #include "base/strings/stringprintf.h" |
12 #include "base/time/time.h" | 13 #include "base/time/time.h" |
13 #include "components/omnibox/browser/autocomplete_match_type.h" | 14 #include "components/omnibox/browser/autocomplete_match_type.h" |
14 #include "sql/meta_table.h" | 15 #include "sql/meta_table.h" |
| 16 #include "sql/recovery.h" |
15 #include "sql/statement.h" | 17 #include "sql/statement.h" |
16 #include "sql/transaction.h" | 18 #include "sql/transaction.h" |
17 #include "ui/base/page_transition_types.h" | 19 #include "ui/base/page_transition_types.h" |
18 | 20 |
19 | 21 |
20 // Helpers -------------------------------------------------------------------- | 22 // Helpers -------------------------------------------------------------------- |
21 | 23 |
22 namespace { | 24 namespace { |
23 | 25 |
24 // Current version number. We write databases at the "current" version number, | 26 // Current version number. We write databases at the "current" version number, |
(...skipping 23 matching lines...) Expand all Loading... |
48 bool DeleteShortcut(const char* field_name, | 50 bool DeleteShortcut(const char* field_name, |
49 const std::string& id, | 51 const std::string& id, |
50 sql::Connection& db) { | 52 sql::Connection& db) { |
51 sql::Statement s(db.GetUniqueStatement( | 53 sql::Statement s(db.GetUniqueStatement( |
52 base::StringPrintf("DELETE FROM omni_box_shortcuts WHERE %s = ?", | 54 base::StringPrintf("DELETE FROM omni_box_shortcuts WHERE %s = ?", |
53 field_name).c_str())); | 55 field_name).c_str())); |
54 s.BindString(0, id); | 56 s.BindString(0, id); |
55 return s.Run(); | 57 return s.Run(); |
56 } | 58 } |
57 | 59 |
| 60 void DatabaseErrorCallback(sql::Connection* db, |
| 61 const base::FilePath& db_path, |
| 62 int extended_error, |
| 63 sql::Statement* stmt) { |
| 64 if (sql::Recovery::ShouldRecover(extended_error)) { |
| 65 // Prevent reentrant calls. |
| 66 db->reset_error_callback(); |
| 67 |
| 68 // After this call, the |db| handle is poisoned so that future calls will |
| 69 // return errors until the handle is re-opened. |
| 70 sql::Recovery::RecoverDatabase(db, db_path); |
| 71 |
| 72 // The DLOG(FATAL) below is intended to draw immediate attention to errors |
| 73 // in newly-written code. Database corruption is generally a result of OS |
| 74 // or hardware issues, not coding errors at the client level, so displaying |
| 75 // the error would probably lead to confusion. The ignored call signals the |
| 76 // test-expectation framework that the error was handled. |
| 77 ignore_result(sql::Connection::IsExpectedSqliteError(extended_error)); |
| 78 return; |
| 79 } |
| 80 |
| 81 // The default handling is to assert on debug and to ignore on release. |
| 82 if (!sql::Connection::IsExpectedSqliteError(extended_error)) |
| 83 DLOG(FATAL) << db->GetErrorMessage(); |
| 84 } |
| 85 |
58 } // namespace | 86 } // namespace |
59 | 87 |
60 // ShortcutsDatabase::Shortcut::MatchCore ------------------------------------- | 88 // ShortcutsDatabase::Shortcut::MatchCore ------------------------------------- |
61 | 89 |
62 ShortcutsDatabase::Shortcut::MatchCore::MatchCore( | 90 ShortcutsDatabase::Shortcut::MatchCore::MatchCore( |
63 const base::string16& fill_into_edit, | 91 const base::string16& fill_into_edit, |
64 const GURL& destination_url, | 92 const GURL& destination_url, |
65 const base::string16& contents, | 93 const base::string16& contents, |
66 const std::string& contents_class, | 94 const std::string& contents_class, |
67 const base::string16& description, | 95 const base::string16& description, |
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
116 | 144 |
117 // ShortcutsDatabase ---------------------------------------------------------- | 145 // ShortcutsDatabase ---------------------------------------------------------- |
118 | 146 |
119 ShortcutsDatabase::ShortcutsDatabase(const base::FilePath& database_path) | 147 ShortcutsDatabase::ShortcutsDatabase(const base::FilePath& database_path) |
120 : database_path_(database_path) { | 148 : database_path_(database_path) { |
121 } | 149 } |
122 | 150 |
123 bool ShortcutsDatabase::Init() { | 151 bool ShortcutsDatabase::Init() { |
124 db_.set_histogram_tag("Shortcuts"); | 152 db_.set_histogram_tag("Shortcuts"); |
125 | 153 |
| 154 // To recover from corruption. |
| 155 db_.set_error_callback( |
| 156 base::Bind(&DatabaseErrorCallback, &db_, database_path_)); |
| 157 |
126 // Set the database page size to something a little larger to give us | 158 // Set the database page size to something a little larger to give us |
127 // better performance (we're typically seek rather than bandwidth limited). | 159 // better performance (we're typically seek rather than bandwidth limited). |
128 // This only has an effect before any tables have been created, otherwise | 160 // This only has an effect before any tables have been created, otherwise |
129 // this is a NOP. Must be a power of 2 and a max of 8192. | 161 // this is a NOP. Must be a power of 2 and a max of 8192. |
130 db_.set_page_size(4096); | 162 db_.set_page_size(4096); |
131 | 163 |
132 // Run the database in exclusive mode. Nobody else should be accessing the | 164 // Run the database in exclusive mode. Nobody else should be accessing the |
133 // database while we're running, and this will give somewhat improved perf. | 165 // database while we're running, and this will give somewhat improved perf. |
134 db_.set_exclusive_locking(); | 166 db_.set_exclusive_locking(); |
135 | 167 |
(...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
250 "UPDATE omni_box_shortcuts SET type = %d", | 282 "UPDATE omni_box_shortcuts SET type = %d", |
251 static_cast<int>(AutocompleteMatchType::HISTORY_TITLE)).c_str()) && | 283 static_cast<int>(AutocompleteMatchType::HISTORY_TITLE)).c_str()) && |
252 db_.Execute("ALTER TABLE omni_box_shortcuts " | 284 db_.Execute("ALTER TABLE omni_box_shortcuts " |
253 "ADD COLUMN keyword VARCHAR") && | 285 "ADD COLUMN keyword VARCHAR") && |
254 transaction.Commit())) { | 286 transaction.Commit())) { |
255 return false; | 287 return false; |
256 } | 288 } |
257 } | 289 } |
258 | 290 |
259 if (!sql::MetaTable::DoesTableExist(&db_)) { | 291 if (!sql::MetaTable::DoesTableExist(&db_)) { |
260 meta_table_.Init(&db_, kCurrentVersionNumber, kCompatibleVersionNumber); | |
261 sql::Transaction transaction(&db_); | 292 sql::Transaction transaction(&db_); |
262 if (!(transaction.Begin() && | 293 if (!(transaction.Begin() && |
263 // Migrate old SEARCH_OTHER_ENGINE values to the new type value. | 294 meta_table_.Init( |
264 db_.Execute(base::StringPrintf("UPDATE omni_box_shortcuts " | 295 &db_, kCurrentVersionNumber, kCompatibleVersionNumber) && |
265 "SET type = 13 WHERE type = 9").c_str()) && | 296 // Migrate old SEARCH_OTHER_ENGINE values to the new type value. |
266 // Migrate old EXTENSION_APP values to the new type value. | 297 db_.Execute( |
267 db_.Execute(base::StringPrintf("UPDATE omni_box_shortcuts " | 298 "UPDATE omni_box_shortcuts SET type = 13 WHERE type = 9") && |
268 "SET type = 14 WHERE type = 10").c_str()) && | 299 // Migrate old EXTENSION_APP values to the new type value. |
269 // Migrate old CONTACT values to the new type value. | 300 db_.Execute( |
270 db_.Execute(base::StringPrintf("UPDATE omni_box_shortcuts " | 301 "UPDATE omni_box_shortcuts SET type = 14 WHERE type = 10") && |
271 "SET type = 15 WHERE type = 11").c_str()) && | 302 // Migrate old CONTACT values to the new type value. |
272 // Migrate old BOOKMARK_TITLE values to the new type value. | 303 db_.Execute( |
273 db_.Execute(base::StringPrintf("UPDATE omni_box_shortcuts " | 304 "UPDATE omni_box_shortcuts SET type = 15 WHERE type = 11") && |
274 "SET type = 16 WHERE type = 12").c_str()) && | 305 // Migrate old BOOKMARK_TITLE values to the new type value. |
275 transaction.Commit())) { | 306 db_.Execute( |
| 307 "UPDATE omni_box_shortcuts SET type = 16 WHERE type = 12") && |
| 308 transaction.Commit())) { |
276 return false; | 309 return false; |
277 } | 310 } |
278 } | 311 } |
279 return true; | 312 return true; |
280 } | 313 } |
OLD | NEW |