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 "chrome/browser/webdata/keyword_table.h" | 5 #include "chrome/browser/webdata/keyword_table.h" |
6 | 6 |
7 #include <set> | 7 #include <set> |
8 | 8 |
9 #include "base/json/json_reader.h" | 9 #include "base/json/json_reader.h" |
10 #include "base/json/json_writer.h" | 10 #include "base/json/json_writer.h" |
11 #include "base/logging.h" | 11 #include "base/logging.h" |
12 #include "base/memory/scoped_ptr.h" | 12 #include "base/memory/scoped_ptr.h" |
13 #include "base/metrics/histogram.h" | |
14 #include "base/metrics/stats_counters.h" | |
15 #include "base/string_number_conversions.h" | 13 #include "base/string_number_conversions.h" |
16 #include "base/string_split.h" | 14 #include "base/string_split.h" |
17 #include "base/string_util.h" | 15 #include "base/string_util.h" |
18 #include "base/stringprintf.h" | 16 // #include "base/stringprintf.h" |
sky
2012/12/10 15:46:20
If not needed, remove.
Ivan Korotkov
2012/12/10 18:25:24
Done.
| |
19 #include "base/utf_string_conversions.h" | 17 #include "base/utf_string_conversions.h" |
20 #include "base/values.h" | 18 #include "base/values.h" |
21 #include "chrome/browser/history/history_database.h" | 19 #include "chrome/browser/history/history_database.h" |
22 #include "chrome/browser/protector/histograms.h" | |
23 #include "chrome/browser/protector/protector_utils.h" | |
24 #include "chrome/browser/search_engines/search_terms_data.h" | 20 #include "chrome/browser/search_engines/search_terms_data.h" |
25 #include "chrome/browser/search_engines/template_url.h" | 21 #include "chrome/browser/search_engines/template_url.h" |
26 #include "chrome/browser/search_engines/template_url_service.h" | 22 #include "chrome/browser/search_engines/template_url_service.h" |
27 #include "chrome/browser/webdata/web_database.h" | 23 #include "chrome/browser/webdata/web_database.h" |
28 #include "googleurl/src/gurl.h" | 24 #include "googleurl/src/gurl.h" |
29 #include "sql/statement.h" | 25 #include "sql/statement.h" |
30 #include "sql/transaction.h" | 26 #include "sql/transaction.h" |
31 | 27 |
32 using base::Time; | 28 using base::Time; |
33 | 29 |
34 // static | 30 // static |
35 const char KeywordTable::kDefaultSearchProviderKey[] = | 31 const char KeywordTable::kDefaultSearchProviderKey[] = |
36 "Default Search Provider ID"; | 32 "Default Search Provider ID"; |
37 const char KeywordTable::kDefaultSearchIDBackupKey[] = | |
38 "Default Search Provider ID Backup"; | |
39 const char KeywordTable::kBackupSignatureKey[] = | |
40 "Default Search Provider ID Backup Signature"; | |
41 | 33 |
42 namespace { | 34 namespace { |
43 | 35 |
44 // Keys used in the meta table. | 36 // Keys used in the meta table. |
45 const char kBuiltinKeywordVersion[] = "Builtin Keyword Version"; | 37 const char kBuiltinKeywordVersion[] = "Builtin Keyword Version"; |
46 | 38 |
47 const std::string ColumnsForVersion(int version, bool concatenated) { | 39 const std::string ColumnsForVersion(int version, bool concatenated) { |
48 std::vector<std::string> columns; | 40 std::vector<std::string> columns; |
49 | 41 |
50 columns.push_back("id"); | 42 columns.push_back("id"); |
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
116 s->BindBool(starting_column + 12, data.created_by_policy); | 108 s->BindBool(starting_column + 12, data.created_by_policy); |
117 s->BindString(starting_column + 13, data.instant_url); | 109 s->BindString(starting_column + 13, data.instant_url); |
118 s->BindInt64(starting_column + 14, data.last_modified.ToTimeT()); | 110 s->BindInt64(starting_column + 14, data.last_modified.ToTimeT()); |
119 s->BindString(starting_column + 15, data.sync_guid); | 111 s->BindString(starting_column + 15, data.sync_guid); |
120 s->BindString(starting_column + 16, alternate_urls); | 112 s->BindString(starting_column + 16, alternate_urls); |
121 } | 113 } |
122 | 114 |
123 } // anonymous namespace | 115 } // anonymous namespace |
124 | 116 |
125 KeywordTable::KeywordTable(sql::Connection* db, sql::MetaTable* meta_table) | 117 KeywordTable::KeywordTable(sql::Connection* db, sql::MetaTable* meta_table) |
126 : WebDatabaseTable(db, meta_table), | 118 : WebDatabaseTable(db, meta_table) { |
127 backup_overwritten_(false) { | |
128 } | 119 } |
129 | 120 |
130 KeywordTable::~KeywordTable() {} | 121 KeywordTable::~KeywordTable() {} |
131 | 122 |
132 bool KeywordTable::Init() { | 123 bool KeywordTable::Init() { |
133 return db_->DoesTableExist("keywords") || | 124 return db_->DoesTableExist("keywords") || |
134 (db_->Execute("CREATE TABLE keywords (" | 125 db_->Execute("CREATE TABLE keywords (" |
135 "id INTEGER PRIMARY KEY," | 126 "id INTEGER PRIMARY KEY," |
136 "short_name VARCHAR NOT NULL," | 127 "short_name VARCHAR NOT NULL," |
137 "keyword VARCHAR NOT NULL," | 128 "keyword VARCHAR NOT NULL," |
138 "favicon_url VARCHAR NOT NULL," | 129 "favicon_url VARCHAR NOT NULL," |
139 "url VARCHAR NOT NULL," | 130 "url VARCHAR NOT NULL," |
140 "safe_for_autoreplace INTEGER," | 131 "safe_for_autoreplace INTEGER," |
141 "originating_url VARCHAR," | 132 "originating_url VARCHAR," |
142 "date_created INTEGER DEFAULT 0," | 133 "date_created INTEGER DEFAULT 0," |
143 "usage_count INTEGER DEFAULT 0," | 134 "usage_count INTEGER DEFAULT 0," |
144 "input_encodings VARCHAR," | 135 "input_encodings VARCHAR," |
145 "show_in_default_list INTEGER," | 136 "show_in_default_list INTEGER," |
146 "suggest_url VARCHAR," | 137 "suggest_url VARCHAR," |
147 "prepopulate_id INTEGER DEFAULT 0," | 138 "prepopulate_id INTEGER DEFAULT 0," |
148 "created_by_policy INTEGER DEFAULT 0," | 139 "created_by_policy INTEGER DEFAULT 0," |
149 "instant_url VARCHAR," | 140 "instant_url VARCHAR," |
150 "last_modified INTEGER DEFAULT 0," | 141 "last_modified INTEGER DEFAULT 0," |
151 "sync_guid VARCHAR," | 142 "sync_guid VARCHAR," |
152 "alternate_urls VARCHAR)") && | 143 "alternate_urls VARCHAR)"); |
153 UpdateBackupSignature(WebDatabase::kCurrentVersionNumber)); | |
154 } | 144 } |
155 | 145 |
156 bool KeywordTable::IsSyncable() { | 146 bool KeywordTable::IsSyncable() { |
157 return true; | 147 return true; |
158 } | 148 } |
159 | 149 |
160 bool KeywordTable::AddKeyword(const TemplateURLData& data) { | 150 bool KeywordTable::AddKeyword(const TemplateURLData& data) { |
161 DCHECK(data.id); | 151 DCHECK(data.id); |
162 std::string query("INSERT INTO keywords (" + GetKeywordColumns() + | 152 std::string query("INSERT INTO keywords (" + GetKeywordColumns() + |
163 ") VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)"); | 153 ") VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)"); |
164 sql::Statement s(db_->GetUniqueStatement(query.c_str())); | 154 sql::Statement s(db_->GetUniqueStatement(query.c_str())); |
165 BindURLToStatement(data, &s, 0, 1); | 155 BindURLToStatement(data, &s, 0, 1); |
166 | 156 |
167 return s.Run() && UpdateBackupSignature(WebDatabase::kCurrentVersionNumber); | 157 return s.Run(); |
168 } | 158 } |
169 | 159 |
170 bool KeywordTable::RemoveKeyword(TemplateURLID id) { | 160 bool KeywordTable::RemoveKeyword(TemplateURLID id) { |
171 DCHECK(id); | 161 DCHECK(id); |
172 sql::Statement s( | 162 sql::Statement s( |
173 db_->GetUniqueStatement("DELETE FROM keywords WHERE id = ?")); | 163 db_->GetUniqueStatement("DELETE FROM keywords WHERE id = ?")); |
174 s.BindInt64(0, id); | 164 s.BindInt64(0, id); |
175 | 165 |
176 return s.Run() && UpdateBackupSignature(WebDatabase::kCurrentVersionNumber); | 166 return s.Run(); |
177 } | 167 } |
178 | 168 |
179 bool KeywordTable::GetKeywords(Keywords* keywords) { | 169 bool KeywordTable::GetKeywords(Keywords* keywords) { |
180 std::string query("SELECT " + GetKeywordColumns() + | 170 std::string query("SELECT " + GetKeywordColumns() + |
181 " FROM keywords ORDER BY id ASC"); | 171 " FROM keywords ORDER BY id ASC"); |
182 sql::Statement s(db_->GetUniqueStatement(query.c_str())); | 172 sql::Statement s(db_->GetUniqueStatement(query.c_str())); |
183 | 173 |
184 std::set<TemplateURLID> bad_entries; | 174 std::set<TemplateURLID> bad_entries; |
185 while (s.Step()) { | 175 while (s.Step()) { |
186 keywords->push_back(TemplateURLData()); | 176 keywords->push_back(TemplateURLData()); |
(...skipping 12 matching lines...) Expand all Loading... | |
199 bool KeywordTable::UpdateKeyword(const TemplateURLData& data) { | 189 bool KeywordTable::UpdateKeyword(const TemplateURLData& data) { |
200 DCHECK(data.id); | 190 DCHECK(data.id); |
201 sql::Statement s(db_->GetUniqueStatement("UPDATE keywords SET short_name=?, " | 191 sql::Statement s(db_->GetUniqueStatement("UPDATE keywords SET short_name=?, " |
202 "keyword=?, favicon_url=?, url=?, safe_for_autoreplace=?, " | 192 "keyword=?, favicon_url=?, url=?, safe_for_autoreplace=?, " |
203 "originating_url=?, date_created=?, usage_count=?, input_encodings=?, " | 193 "originating_url=?, date_created=?, usage_count=?, input_encodings=?, " |
204 "show_in_default_list=?, suggest_url=?, prepopulate_id=?, " | 194 "show_in_default_list=?, suggest_url=?, prepopulate_id=?, " |
205 "created_by_policy=?, instant_url=?, last_modified=?, sync_guid=?, " | 195 "created_by_policy=?, instant_url=?, last_modified=?, sync_guid=?, " |
206 "alternate_urls=? WHERE id=?")); | 196 "alternate_urls=? WHERE id=?")); |
207 BindURLToStatement(data, &s, 17, 0); // "17" binds id() as the last item. | 197 BindURLToStatement(data, &s, 17, 0); // "17" binds id() as the last item. |
208 | 198 |
209 return s.Run() && UpdateBackupSignature(WebDatabase::kCurrentVersionNumber); | 199 return s.Run(); |
210 } | 200 } |
211 | 201 |
212 bool KeywordTable::SetDefaultSearchProviderID(int64 id) { | 202 bool KeywordTable::SetDefaultSearchProviderID(int64 id) { |
213 // Added for http://crbug.com/116952. | 203 return meta_table_->SetValue(kDefaultSearchProviderKey, id); |
214 UMA_HISTOGRAM_COUNTS_100("Search.DefaultSearchProviderID", | |
215 static_cast<int32>(id)); | |
216 return meta_table_->SetValue(kDefaultSearchProviderKey, id) && | |
217 UpdateBackupSignature(WebDatabase::kCurrentVersionNumber); | |
218 } | 204 } |
219 | 205 |
220 int64 KeywordTable::GetDefaultSearchProviderID() { | 206 int64 KeywordTable::GetDefaultSearchProviderID() { |
221 int64 value = kInvalidTemplateURLID; | 207 int64 value = kInvalidTemplateURLID; |
222 meta_table_->GetValue(kDefaultSearchProviderKey, &value); | 208 meta_table_->GetValue(kDefaultSearchProviderKey, &value); |
223 return value; | 209 return value; |
224 } | 210 } |
225 | 211 |
226 bool KeywordTable::GetDefaultSearchProviderBackup(TemplateURLData* backup) { | |
227 if (!IsBackupSignatureValid(WebDatabase::kCurrentVersionNumber)) | |
228 return false; | |
229 | |
230 int64 backup_id = kInvalidTemplateURLID; | |
231 if (!meta_table_->GetValue(kDefaultSearchIDBackupKey, &backup_id)) { | |
232 LOG(ERROR) << "No default search id backup found."; | |
233 return false; | |
234 } | |
235 std::string query("SELECT " + GetKeywordColumns() + | |
236 " FROM keywords_backup WHERE id=?"); | |
237 sql::Statement s(db_->GetUniqueStatement(query.c_str())); | |
238 s.BindInt64(0, backup_id); | |
239 | |
240 if (!s.Step()) { | |
241 LOG_IF(ERROR, s.Succeeded()) | |
242 << "No default search provider with backup id."; | |
243 return false; | |
244 } | |
245 | |
246 if (!GetKeywordDataFromStatement(s, backup)) | |
247 return false; | |
248 | |
249 // ID has no meaning for the backup and should be kInvalidTemplateURLID in | |
250 // case the TemplateURL will be added to keywords if missing. | |
251 backup->id = kInvalidTemplateURLID; | |
252 return true; | |
253 } | |
254 | |
255 bool KeywordTable::DidDefaultSearchProviderChange() { | |
256 if (!IsBackupSignatureValid(WebDatabase::kCurrentVersionNumber)) { | |
257 UMA_HISTOGRAM_ENUMERATION( | |
258 protector::kProtectorHistogramDefaultSearchProvider, | |
259 protector::kProtectorErrorBackupInvalid, | |
260 protector::kProtectorErrorCount); | |
261 LOG(ERROR) << "Backup signature is invalid."; | |
262 return true; | |
263 } | |
264 | |
265 int64 backup_id = kInvalidTemplateURLID; | |
266 meta_table_->GetValue(kDefaultSearchIDBackupKey, &backup_id); | |
267 int64 current_id = GetDefaultSearchProviderID(); | |
268 if (backup_id == current_id) { | |
269 // Either this is a new profile and both IDs are kInvalidTemplateURLID or | |
270 // the search engines with the ids are equal. | |
271 if (backup_id == kInvalidTemplateURLID) { | |
272 UMA_HISTOGRAM_ENUMERATION( | |
273 protector::kProtectorHistogramDefaultSearchProvider, | |
274 backup_overwritten_ ? | |
275 protector::kProtectorErrorOverwrittenByMigration : | |
276 protector::kProtectorErrorValueValidZero, | |
277 protector::kProtectorErrorCount); | |
278 return false; | |
279 } | |
280 std::string backup_url; | |
281 std::string current_url; | |
282 if (GetKeywordAsString(backup_id, "keywords_backup", &backup_url) && | |
283 GetKeywordAsString(current_id, "keywords", ¤t_url) && | |
284 current_url == backup_url) { | |
285 UMA_HISTOGRAM_ENUMERATION( | |
286 protector::kProtectorHistogramDefaultSearchProvider, | |
287 backup_overwritten_ ? | |
288 protector::kProtectorErrorOverwrittenByMigration : | |
289 protector::kProtectorErrorValueValid, | |
290 protector::kProtectorErrorCount); | |
291 return false; | |
292 } | |
293 } | |
294 | |
295 UMA_HISTOGRAM_ENUMERATION( | |
296 protector::kProtectorHistogramDefaultSearchProvider, | |
297 protector::kProtectorErrorValueChanged, | |
298 protector::kProtectorErrorCount); | |
299 LOG(WARNING) << "Default Search Provider has changed."; | |
300 return true; | |
301 } | |
302 | |
303 bool KeywordTable::SetBuiltinKeywordVersion(int version) { | 212 bool KeywordTable::SetBuiltinKeywordVersion(int version) { |
304 return meta_table_->SetValue(kBuiltinKeywordVersion, version); | 213 return meta_table_->SetValue(kBuiltinKeywordVersion, version); |
305 } | 214 } |
306 | 215 |
307 int KeywordTable::GetBuiltinKeywordVersion() { | 216 int KeywordTable::GetBuiltinKeywordVersion() { |
308 int version = 0; | 217 int version = 0; |
309 return meta_table_->GetValue(kBuiltinKeywordVersion, &version) ? version : 0; | 218 return meta_table_->GetValue(kBuiltinKeywordVersion, &version) ? version : 0; |
310 } | 219 } |
311 | 220 |
312 // static | 221 // static |
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
370 bool KeywordTable::MigrateToVersion38AddLastModifiedColumn() { | 279 bool KeywordTable::MigrateToVersion38AddLastModifiedColumn() { |
371 return db_->Execute( | 280 return db_->Execute( |
372 "ALTER TABLE keywords ADD COLUMN last_modified INTEGER DEFAULT 0"); | 281 "ALTER TABLE keywords ADD COLUMN last_modified INTEGER DEFAULT 0"); |
373 } | 282 } |
374 | 283 |
375 bool KeywordTable::MigrateToVersion39AddSyncGUIDColumn() { | 284 bool KeywordTable::MigrateToVersion39AddSyncGUIDColumn() { |
376 return db_->Execute("ALTER TABLE keywords ADD COLUMN sync_guid VARCHAR"); | 285 return db_->Execute("ALTER TABLE keywords ADD COLUMN sync_guid VARCHAR"); |
377 } | 286 } |
378 | 287 |
379 bool KeywordTable::MigrateToVersion44AddDefaultSearchProviderBackup() { | 288 bool KeywordTable::MigrateToVersion44AddDefaultSearchProviderBackup() { |
380 if (IsBackupSignatureValid(44)) | 289 sql::Transaction transaction(db_); |
381 return true; | 290 if (!transaction.Begin()) |
382 backup_overwritten_ = true; | 291 return false; |
383 return UpdateBackupSignature(44); | 292 |
293 int64 default_search_id = GetDefaultSearchProviderID(); | |
294 if (!meta_table_->SetValue("Default Search Provider ID Backup", | |
295 default_search_id)) { | |
296 return false; | |
297 } | |
298 | |
299 // Backup of all keywords. | |
300 if (db_->DoesTableExist("keywords_backup") && | |
301 !db_->Execute("DROP TABLE keywords_backup")) { | |
302 return false; | |
303 } | |
304 | |
305 std::string query("CREATE TABLE keywords_backup AS SELECT " + | |
306 ColumnsForVersion(44, false) + " FROM keywords ORDER BY id ASC"); | |
307 if (!db_->Execute(query.c_str())) | |
308 return false; | |
309 | |
310 return transaction.Commit(); | |
384 } | 311 } |
385 | 312 |
386 bool KeywordTable::MigrateToVersion45RemoveLogoIDAndAutogenerateColumns() { | 313 bool KeywordTable::MigrateToVersion45RemoveLogoIDAndAutogenerateColumns() { |
387 sql::Transaction transaction(db_); | 314 sql::Transaction transaction(db_); |
388 if (!transaction.Begin()) | 315 if (!transaction.Begin()) |
389 return false; | 316 return false; |
390 | 317 |
391 // The version 43 migration should have been written to do this, but since it | 318 // The version 43 migration should have been written to do this, but since it |
392 // wasn't, we'll do it now. Unfortunately a previous change deleted this for | 319 // wasn't, we'll do it now. Unfortunately a previous change deleted this for |
393 // some users, so we can't be sure this will succeed (so don't bail on error). | 320 // some users, so we can't be sure this will succeed (so don't bail on error). |
394 meta_table_->DeleteKey("Default Search Provider Backup"); | 321 meta_table_->DeleteKey("Default Search Provider Backup"); |
395 | 322 |
396 if (!MigrateKeywordsTableForVersion45("keywords")) | 323 if (!MigrateKeywordsTableForVersion45("keywords")) |
397 return false; | 324 return false; |
398 | 325 |
399 if (IsBackupSignatureValid(44)) { | 326 // Migrate the keywords backup table as well. |
400 // Migrate the keywords backup table as well. | 327 if (!MigrateKeywordsTableForVersion45("keywords_backup") || |
401 if (!MigrateKeywordsTableForVersion45("keywords_backup") || !SignBackup(45)) | 328 !meta_table_->SetValue("Default Search Provider ID Backup Signature", |
402 return false; | 329 "")) { |
403 } else { | 330 return false; |
404 // Old backup was invalid; drop the table entirely, which will trigger the | |
405 // protector code to prompt the user and recreate the table. | |
406 if (db_->DoesTableExist("keywords_backup") && | |
407 !db_->Execute("DROP TABLE keywords_backup")) | |
408 return false; | |
409 } | 331 } |
410 | 332 |
411 return transaction.Commit(); | 333 return transaction.Commit(); |
412 } | 334 } |
413 | 335 |
414 bool KeywordTable::MigrateToVersion47AddAlternateURLsColumn() { | 336 bool KeywordTable::MigrateToVersion47AddAlternateURLsColumn() { |
415 sql::Transaction transaction(db_); | 337 sql::Transaction transaction(db_); |
416 | 338 |
417 // Fill the |alternate_urls| column with empty strings, otherwise it breaks | 339 // Fill the |alternate_urls| column with empty strings, otherwise it breaks |
418 // code relying on GetTableContents that concatenates the strings from all | 340 // code relying on GetTableContents that concatenates the strings from all |
419 // the columns. | 341 // the columns. |
420 if (!transaction.Begin() || | 342 if (!transaction.Begin() || |
421 !db_->Execute("ALTER TABLE keywords ADD COLUMN " | 343 !db_->Execute("ALTER TABLE keywords ADD COLUMN " |
422 "alternate_urls VARCHAR DEFAULT ''")) | 344 "alternate_urls VARCHAR DEFAULT ''")) |
423 return false; | 345 return false; |
424 | 346 |
425 if (IsBackupSignatureValid(46)) { | 347 // Migrate the keywords backup table as well. |
426 // Migrate the keywords backup table as well. | 348 if (!db_->Execute("ALTER TABLE keywords_backup ADD COLUMN " |
427 if (!db_->Execute("ALTER TABLE keywords_backup ADD COLUMN " | 349 "alternate_urls VARCHAR DEFAULT ''") || |
428 "alternate_urls VARCHAR DEFAULT ''") || | 350 !meta_table_->SetValue("Default Search Provider ID Backup Signature", |
429 !SignBackup(47)) | 351 "")) { |
430 return false; | 352 return false; |
431 } else { | |
432 // Old backup was invalid; drop the table entirely, which will trigger the | |
433 // protector code to prompt the user and recreate the table. | |
434 if (db_->DoesTableExist("keywords_backup") && | |
435 !db_->Execute("DROP TABLE keywords_backup")) | |
436 return false; | |
437 } | 353 } |
438 | 354 |
439 return transaction.Commit(); | 355 return transaction.Commit(); |
440 } | 356 } |
441 | 357 |
358 bool KeywordTable::MigrateToVersion48RemoveKeywordsBackup() { | |
359 sql::Transaction transaction(db_); | |
360 if (!transaction.Begin()) | |
361 return false; | |
362 | |
363 if (!meta_table_->DeleteKey("Default Search Provider ID Backup") || | |
364 !meta_table_->DeleteKey("Default Search Provider ID Backup Signature")) { | |
365 return false; | |
366 } | |
367 | |
368 if (!db_->Execute("DROP TABLE keywords_backup")) | |
369 return false; | |
370 | |
371 return transaction.Commit(); | |
372 } | |
373 | |
442 // static | 374 // static |
443 bool KeywordTable::GetKeywordDataFromStatement(const sql::Statement& s, | 375 bool KeywordTable::GetKeywordDataFromStatement(const sql::Statement& s, |
444 TemplateURLData* data) { | 376 TemplateURLData* data) { |
445 DCHECK(data); | 377 DCHECK(data); |
446 | 378 |
447 data->short_name = s.ColumnString16(1); | 379 data->short_name = s.ColumnString16(1); |
448 data->SetKeyword(s.ColumnString16(2)); | 380 data->SetKeyword(s.ColumnString16(2)); |
449 // Due to past bugs, we might have persisted entries with empty URLs. Avoid | 381 // Due to past bugs, we might have persisted entries with empty URLs. Avoid |
450 // reading these out. (GetKeywords() will delete these entries on return.) | 382 // reading these out. (GetKeywords() will delete these entries on return.) |
451 // NOTE: This code should only be needed as long as we might be reading such | 383 // NOTE: This code should only be needed as long as we might be reading such |
(...skipping 24 matching lines...) Expand all Loading... | |
476 std::string alternate_url; | 408 std::string alternate_url; |
477 for (size_t i = 0; i < alternate_urls_value->GetSize(); ++i) { | 409 for (size_t i = 0; i < alternate_urls_value->GetSize(); ++i) { |
478 if (alternate_urls_value->GetString(i, &alternate_url)) | 410 if (alternate_urls_value->GetString(i, &alternate_url)) |
479 data->alternate_urls.push_back(alternate_url); | 411 data->alternate_urls.push_back(alternate_url); |
480 } | 412 } |
481 } | 413 } |
482 | 414 |
483 return true; | 415 return true; |
484 } | 416 } |
485 | 417 |
486 bool KeywordTable::GetSignatureData(int table_version, std::string* backup) { | |
487 DCHECK(backup); | |
488 | |
489 int64 backup_value = kInvalidTemplateURLID; | |
490 if (!meta_table_->GetValue(kDefaultSearchIDBackupKey, &backup_value)) { | |
491 LOG(ERROR) << "No backup id for signing."; | |
492 return false; | |
493 } | |
494 | |
495 std::string keywords_backup_data; | |
496 if (!GetTableContents("keywords_backup", table_version, | |
497 &keywords_backup_data)) { | |
498 LOG(ERROR) << "Can't get keywords backup data"; | |
499 return false; | |
500 } | |
501 *backup = base::Int64ToString(backup_value) + keywords_backup_data; | |
502 return true; | |
503 } | |
504 | |
505 bool KeywordTable::GetTableContents(const char* table_name, | 418 bool KeywordTable::GetTableContents(const char* table_name, |
506 int table_version, | 419 int table_version, |
507 std::string* contents) { | 420 std::string* contents) { |
508 DCHECK(contents); | 421 DCHECK(contents); |
509 | 422 |
510 if (!db_->DoesTableExist(table_name)) | 423 if (!db_->DoesTableExist(table_name)) |
511 return false; | 424 return false; |
512 | 425 |
513 contents->clear(); | 426 contents->clear(); |
514 std::string query("SELECT " + ColumnsForVersion(table_version, true) + | 427 std::string query("SELECT " + ColumnsForVersion(table_version, true) + |
515 " FROM " + std::string(table_name) + " ORDER BY id ASC"); | 428 " FROM " + std::string(table_name) + " ORDER BY id ASC"); |
516 sql::Statement s((table_version == WebDatabase::kCurrentVersionNumber) ? | 429 sql::Statement s((table_version == WebDatabase::kCurrentVersionNumber) ? |
517 db_->GetCachedStatement(sql::StatementID(table_name), query.c_str()) : | 430 db_->GetCachedStatement(sql::StatementID(table_name), query.c_str()) : |
518 db_->GetUniqueStatement(query.c_str())); | 431 db_->GetUniqueStatement(query.c_str())); |
519 while (s.Step()) | 432 while (s.Step()) |
520 *contents += s.ColumnString(0); | 433 *contents += s.ColumnString(0); |
521 return s.Succeeded(); | 434 return s.Succeeded(); |
522 } | 435 } |
523 | 436 |
524 bool KeywordTable::UpdateBackupSignature(int table_version) { | |
525 sql::Transaction transaction(db_); | |
526 if (!transaction.Begin()) | |
527 return false; | |
528 | |
529 int64 id = kInvalidTemplateURLID; | |
530 if (!UpdateDefaultSearchProviderIDBackup(&id)) { | |
531 LOG(ERROR) << "Failed to update default search id backup."; | |
532 return false; | |
533 } | |
534 | |
535 // Backup of all keywords. | |
536 if (db_->DoesTableExist("keywords_backup") && | |
537 !db_->Execute("DROP TABLE keywords_backup")) | |
538 return false; | |
539 | |
540 std::string query("CREATE TABLE keywords_backup AS SELECT " + | |
541 ColumnsForVersion(table_version, false) + | |
542 " FROM keywords ORDER BY id ASC"); | |
543 if (!db_->Execute(query.c_str())) { | |
544 LOG(ERROR) << "Failed to create keywords_backup table."; | |
545 return false; | |
546 } | |
547 | |
548 return SignBackup(table_version) && transaction.Commit(); | |
549 } | |
550 | |
551 bool KeywordTable::SignBackup(int table_version) { | |
552 std::string data_to_sign; | |
553 if (!GetSignatureData(table_version, &data_to_sign)) { | |
554 LOG(ERROR) << "No data to sign."; | |
555 return false; | |
556 } | |
557 | |
558 std::string signature = protector::SignSetting(data_to_sign); | |
559 if (signature.empty()) { | |
560 LOG(ERROR) << "Signature is empty"; | |
561 return false; | |
562 } | |
563 | |
564 return meta_table_->SetValue(kBackupSignatureKey, signature); | |
565 } | |
566 | |
567 bool KeywordTable::IsBackupSignatureValid(int table_version) { | |
568 std::string signature; | |
569 std::string signature_data; | |
570 return meta_table_->GetValue(kBackupSignatureKey, &signature) && | |
571 GetSignatureData(table_version, &signature_data) && | |
572 protector::IsSettingValid(signature_data, signature); | |
573 } | |
574 | |
575 bool KeywordTable::GetKeywordAsString(TemplateURLID id, | 437 bool KeywordTable::GetKeywordAsString(TemplateURLID id, |
576 const std::string& table_name, | 438 const std::string& table_name, |
577 std::string* result) { | 439 std::string* result) { |
578 std::string query("SELECT " + | 440 std::string query("SELECT " + |
579 ColumnsForVersion(WebDatabase::kCurrentVersionNumber, true) + | 441 ColumnsForVersion(WebDatabase::kCurrentVersionNumber, true) + |
580 " FROM " + table_name + " WHERE id=?"); | 442 " FROM " + table_name + " WHERE id=?"); |
581 sql::Statement s(db_->GetUniqueStatement(query.c_str())); | 443 sql::Statement s(db_->GetUniqueStatement(query.c_str())); |
582 s.BindInt64(0, id); | 444 s.BindInt64(0, id); |
583 | 445 |
584 if (!s.Step()) { | 446 if (!s.Step()) { |
585 LOG_IF(WARNING, s.Succeeded()) << "No keyword with id: " << id | 447 LOG_IF(WARNING, s.Succeeded()) << "No keyword with id: " << id |
586 << ", ignoring."; | 448 << ", ignoring."; |
587 return true; | 449 return true; |
588 } | 450 } |
589 | 451 |
590 if (!s.Succeeded()) | 452 if (!s.Succeeded()) |
591 return false; | 453 return false; |
592 | 454 |
593 *result = s.ColumnString(0); | 455 *result = s.ColumnString(0); |
594 return true; | 456 return true; |
595 } | 457 } |
596 | 458 |
597 bool KeywordTable::UpdateDefaultSearchProviderIDBackup(TemplateURLID* id) { | |
598 DCHECK(id); | |
599 int64 default_search_id = GetDefaultSearchProviderID(); | |
600 if (!meta_table_->SetValue(kDefaultSearchIDBackupKey, | |
601 default_search_id)) { | |
602 LOG(ERROR) << "Can't write default search id backup."; | |
603 return false; | |
604 } | |
605 | |
606 *id = default_search_id; | |
607 return true; | |
608 } | |
609 | |
610 bool KeywordTable::MigrateKeywordsTableForVersion45(const std::string& name) { | 459 bool KeywordTable::MigrateKeywordsTableForVersion45(const std::string& name) { |
611 // Create a new table without the columns we're dropping. | 460 // Create a new table without the columns we're dropping. |
612 if (!db_->Execute("CREATE TABLE keywords_temp (" | 461 if (!db_->Execute("CREATE TABLE keywords_temp (" |
613 "id INTEGER PRIMARY KEY," | 462 "id INTEGER PRIMARY KEY," |
614 "short_name VARCHAR NOT NULL," | 463 "short_name VARCHAR NOT NULL," |
615 "keyword VARCHAR NOT NULL," | 464 "keyword VARCHAR NOT NULL," |
616 "favicon_url VARCHAR NOT NULL," | 465 "favicon_url VARCHAR NOT NULL," |
617 "url VARCHAR NOT NULL," | 466 "url VARCHAR NOT NULL," |
618 "safe_for_autoreplace INTEGER," | 467 "safe_for_autoreplace INTEGER," |
619 "originating_url VARCHAR," | 468 "originating_url VARCHAR," |
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
684 } | 533 } |
685 } | 534 } |
686 | 535 |
687 // Replace the old table with the new one. | 536 // Replace the old table with the new one. |
688 sql = "DROP TABLE " + name; | 537 sql = "DROP TABLE " + name; |
689 if (!db_->Execute(sql.c_str())) | 538 if (!db_->Execute(sql.c_str())) |
690 return false; | 539 return false; |
691 sql = "ALTER TABLE keywords_temp RENAME TO " + name; | 540 sql = "ALTER TABLE keywords_temp RENAME TO " + name; |
692 return db_->Execute(sql.c_str()); | 541 return db_->Execute(sql.c_str()); |
693 } | 542 } |
OLD | NEW |