Chromium Code Reviews| 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" | |
| 10 #include "base/json/json_writer.h" | |
| 9 #include "base/logging.h" | 11 #include "base/logging.h" |
| 10 #include "base/memory/scoped_ptr.h" | 12 #include "base/memory/scoped_ptr.h" |
| 11 #include "base/metrics/histogram.h" | 13 #include "base/metrics/histogram.h" |
| 12 #include "base/metrics/stats_counters.h" | 14 #include "base/metrics/stats_counters.h" |
| 13 #include "base/string_number_conversions.h" | 15 #include "base/string_number_conversions.h" |
| 14 #include "base/string_split.h" | 16 #include "base/string_split.h" |
| 15 #include "base/string_util.h" | 17 #include "base/string_util.h" |
| 16 #include "base/stringprintf.h" | 18 #include "base/stringprintf.h" |
| 17 #include "base/utf_string_conversions.h" | 19 #include "base/utf_string_conversions.h" |
| 20 #include "base/values.h" | |
| 18 #include "chrome/browser/history/history_database.h" | 21 #include "chrome/browser/history/history_database.h" |
| 19 #include "chrome/browser/protector/histograms.h" | 22 #include "chrome/browser/protector/histograms.h" |
| 20 #include "chrome/browser/protector/protector_utils.h" | 23 #include "chrome/browser/protector/protector_utils.h" |
| 21 #include "chrome/browser/search_engines/search_terms_data.h" | 24 #include "chrome/browser/search_engines/search_terms_data.h" |
| 22 #include "chrome/browser/search_engines/template_url.h" | 25 #include "chrome/browser/search_engines/template_url.h" |
| 23 #include "chrome/browser/search_engines/template_url_service.h" | 26 #include "chrome/browser/search_engines/template_url_service.h" |
| 24 #include "chrome/browser/webdata/web_database.h" | 27 #include "chrome/browser/webdata/web_database.h" |
| 25 #include "googleurl/src/gurl.h" | 28 #include "googleurl/src/gurl.h" |
| 26 #include "sql/statement.h" | 29 #include "sql/statement.h" |
| 27 #include "sql/transaction.h" | 30 #include "sql/transaction.h" |
| 28 | 31 |
| 29 using base::Time; | 32 using base::Time; |
| 30 | 33 |
| 31 // static | 34 // static |
| 32 const char KeywordTable::kDefaultSearchProviderKey[] = | 35 const char KeywordTable::kDefaultSearchProviderKey[] = |
| 33 "Default Search Provider ID"; | 36 "Default Search Provider ID"; |
| 34 const char KeywordTable::kDefaultSearchIDBackupKey[] = | 37 const char KeywordTable::kDefaultSearchIDBackupKey[] = |
| 35 "Default Search Provider ID Backup"; | 38 "Default Search Provider ID Backup"; |
| 36 const char KeywordTable::kBackupSignatureKey[] = | 39 const char KeywordTable::kBackupSignatureKey[] = |
| 37 "Default Search Provider ID Backup Signature"; | 40 "Default Search Provider ID Backup Signature"; |
| 38 const char KeywordTable::kKeywordColumns[] = "id, short_name, keyword, " | 41 const char KeywordTable::kKeywordColumns[] = "id, short_name, keyword, " |
| 39 "favicon_url, url, safe_for_autoreplace, originating_url, date_created, " | 42 "favicon_url, url, safe_for_autoreplace, originating_url, date_created, " |
| 40 "usage_count, input_encodings, show_in_default_list, suggest_url, " | 43 "usage_count, input_encodings, show_in_default_list, suggest_url, " |
| 41 "prepopulate_id, created_by_policy, instant_url, last_modified, sync_guid"; | 44 "prepopulate_id, created_by_policy, instant_url, last_modified, sync_guid, " |
| 45 "alternate_urls"; | |
| 42 | 46 |
| 43 namespace { | 47 namespace { |
| 44 | 48 |
| 45 // Keys used in the meta table. | 49 // Keys used in the meta table. |
| 46 const char kBuiltinKeywordVersion[] = "Builtin Keyword Version"; | 50 const char kBuiltinKeywordVersion[] = "Builtin Keyword Version"; |
| 47 | 51 |
| 48 // The set of columns up through version 44. (There were different columns | 52 // The set of columns up through version 44. (There were different columns |
| 49 // below version 29 but none of the code below needs to worry about that case.) | 53 // below version 29 but none of the code below needs to worry about that case.) |
| 50 const char kKeywordColumnsVersion44Concatenated[] = "id || short_name || " | 54 const char kKeywordColumnsVersion44Concatenated[] = "id || short_name || " |
| 51 "keyword || favicon_url || url || safe_for_autoreplace || " | 55 "keyword || favicon_url || url || safe_for_autoreplace || " |
| 52 "originating_url || date_created || usage_count || input_encodings || " | 56 "originating_url || date_created || usage_count || input_encodings || " |
| 53 "show_in_default_list || suggest_url || prepopulate_id || " | 57 "show_in_default_list || suggest_url || prepopulate_id || " |
| 54 "autogenerate_keyword || logo_id || created_by_policy || instant_url || " | 58 "autogenerate_keyword || logo_id || created_by_policy || instant_url || " |
| 55 "last_modified || sync_guid"; | 59 "last_modified || sync_guid"; |
| 56 const char kKeywordColumnsVersion44[] = "id, short_name, keyword, favicon_url, " | 60 const char kKeywordColumnsVersion44[] = "id, short_name, keyword, favicon_url, " |
| 57 "url, safe_for_autoreplace, originating_url, date_created, usage_count, " | 61 "url, safe_for_autoreplace, originating_url, date_created, usage_count, " |
| 58 "input_encodings, show_in_default_list, suggest_url, prepopulate_id, " | 62 "input_encodings, show_in_default_list, suggest_url, prepopulate_id, " |
| 59 "autogenerate_keyword, logo_id, created_by_policy, instant_url, " | 63 "autogenerate_keyword, logo_id, created_by_policy, instant_url, " |
| 60 "last_modified, sync_guid"; | 64 "last_modified, sync_guid"; |
| 61 // NOTE: Remember to change what |kKeywordColumnsVersion45| says if the column | 65 // The set of columns from version 45 through version 46 (inclusively). |
| 62 // set in |kKeywordColumns| changes, and update any code that needs to switch | 66 const char kKeywordColumnsVersion46Concatenated[] = "id || short_name || " |
| 63 // column sets based on a version number! | 67 "keyword || favicon_url || url || safe_for_autoreplace || " |
| 64 const char* const kKeywordColumnsVersion45 = KeywordTable::kKeywordColumns; | 68 "originating_url || date_created || usage_count || input_encodings || " |
| 69 "show_in_default_list || suggest_url || prepopulate_id || " | |
| 70 "created_by_policy || instant_url || last_modified || sync_guid"; | |
| 71 const char kKeywordColumnsVersion46[] = "id, short_name, keyword, " | |
| 72 "favicon_url, url, safe_for_autoreplace, originating_url, date_created, " | |
| 73 "usage_count, input_encodings, show_in_default_list, suggest_url, " | |
| 74 "prepopulate_id, created_by_policy, instant_url, last_modified, sync_guid"; | |
| 65 | 75 |
| 66 // The current columns. | 76 // The current columns. |
| 67 const char kKeywordColumnsConcatenated[] = "id || short_name || keyword || " | 77 const char kKeywordColumnsConcatenated[] = "id || short_name || " |
|
Peter Kasting
2012/10/02 21:47:59
Nit: Why rewrap this value (and all the subsequent
beaudoin
2012/10/03 22:46:52
Done.
| |
| 68 "favicon_url || url || safe_for_autoreplace || originating_url || " | 78 "keyword || favicon_url || url || safe_for_autoreplace || " |
| 69 "date_created || usage_count || input_encodings || show_in_default_list || " | 79 "originating_url || date_created || usage_count || input_encodings || " |
| 70 "suggest_url || prepopulate_id || created_by_policy || instant_url || " | 80 "show_in_default_list || suggest_url || prepopulate_id || " |
| 71 "last_modified || sync_guid"; | 81 "created_by_policy || instant_url || last_modified || sync_guid || " |
| 82 "alternate_urls"; | |
| 72 | 83 |
| 73 // Inserts the data from |data| into |s|. |s| is assumed to have slots for all | 84 // Inserts the data from |data| into |s|. |s| is assumed to have slots for all |
| 74 // the columns in the keyword table. |id_column| is the slot number to bind | 85 // the columns in the keyword table. |id_column| is the slot number to bind |
| 75 // |data|'s |id| to; |starting_column| is the slot number of the first of a | 86 // |data|'s |id| to; |starting_column| is the slot number of the first of a |
| 76 // contiguous set of slots to bind all the other fields to. | 87 // contiguous set of slots to bind all the other fields to. |
| 77 void BindURLToStatement(const TemplateURLData& data, | 88 void BindURLToStatement(const TemplateURLData& data, |
| 78 sql::Statement* s, | 89 sql::Statement* s, |
| 79 int id_column, | 90 int id_column, |
| 80 int starting_column) { | 91 int starting_column) { |
| 92 // Serialize |alternate_urls| to JSON. | |
| 93 // TODO(beaudoin): Check what it would take to use a new table to store | |
| 94 // alternate_urls while keeping backups and table signature in a good state. | |
| 95 // See: crbug.com/153520 | |
| 96 ListValue alternate_urls_value; | |
| 97 for (size_t i = 0; i < data.alternate_urls.size(); ++i) | |
| 98 alternate_urls_value.AppendString(data.alternate_urls[i]); | |
| 99 std::string alternate_urls; | |
| 100 base::JSONWriter::Write(&alternate_urls_value, &alternate_urls); | |
| 101 | |
| 81 s->BindInt64(id_column, data.id); | 102 s->BindInt64(id_column, data.id); |
| 82 s->BindString16(starting_column, data.short_name); | 103 s->BindString16(starting_column, data.short_name); |
| 83 s->BindString16(starting_column + 1, data.keyword()); | 104 s->BindString16(starting_column + 1, data.keyword()); |
| 84 s->BindString(starting_column + 2, data.favicon_url.is_valid() ? | 105 s->BindString(starting_column + 2, data.favicon_url.is_valid() ? |
| 85 history::HistoryDatabase::GURLToDatabaseURL(data.favicon_url) : | 106 history::HistoryDatabase::GURLToDatabaseURL(data.favicon_url) : |
| 86 std::string()); | 107 std::string()); |
| 87 s->BindString(starting_column + 3, data.url()); | 108 s->BindString(starting_column + 3, data.url()); |
| 88 s->BindBool(starting_column + 4, data.safe_for_autoreplace); | 109 s->BindBool(starting_column + 4, data.safe_for_autoreplace); |
| 89 s->BindString(starting_column + 5, data.originating_url.is_valid() ? | 110 s->BindString(starting_column + 5, data.originating_url.is_valid() ? |
| 90 history::HistoryDatabase::GURLToDatabaseURL(data.originating_url) : | 111 history::HistoryDatabase::GURLToDatabaseURL(data.originating_url) : |
| 91 std::string()); | 112 std::string()); |
| 92 s->BindInt64(starting_column + 6, data.date_created.ToTimeT()); | 113 s->BindInt64(starting_column + 6, data.date_created.ToTimeT()); |
| 93 s->BindInt(starting_column + 7, data.usage_count); | 114 s->BindInt(starting_column + 7, data.usage_count); |
| 94 s->BindString(starting_column + 8, JoinString(data.input_encodings, ';')); | 115 s->BindString(starting_column + 8, JoinString(data.input_encodings, ';')); |
| 95 s->BindBool(starting_column + 9, data.show_in_default_list); | 116 s->BindBool(starting_column + 9, data.show_in_default_list); |
| 96 s->BindString(starting_column + 10, data.suggestions_url); | 117 s->BindString(starting_column + 10, data.suggestions_url); |
| 97 s->BindInt(starting_column + 11, data.prepopulate_id); | 118 s->BindInt(starting_column + 11, data.prepopulate_id); |
| 98 s->BindBool(starting_column + 12, data.created_by_policy); | 119 s->BindBool(starting_column + 12, data.created_by_policy); |
| 99 s->BindString(starting_column + 13, data.instant_url); | 120 s->BindString(starting_column + 13, data.instant_url); |
| 100 s->BindInt64(starting_column + 14, data.last_modified.ToTimeT()); | 121 s->BindInt64(starting_column + 14, data.last_modified.ToTimeT()); |
| 101 s->BindString(starting_column + 15, data.sync_guid); | 122 s->BindString(starting_column + 15, data.sync_guid); |
| 123 s->BindString(starting_column + 16, alternate_urls); | |
| 102 } | 124 } |
| 103 | 125 |
| 104 } // anonymous namespace | 126 } // anonymous namespace |
| 105 | 127 |
| 106 KeywordTable::KeywordTable(sql::Connection* db, sql::MetaTable* meta_table) | 128 KeywordTable::KeywordTable(sql::Connection* db, sql::MetaTable* meta_table) |
| 107 : WebDatabaseTable(db, meta_table), | 129 : WebDatabaseTable(db, meta_table), |
| 108 backup_overwritten_(false) { | 130 backup_overwritten_(false) { |
| 109 } | 131 } |
| 110 | 132 |
| 111 KeywordTable::~KeywordTable() {} | 133 KeywordTable::~KeywordTable() {} |
| (...skipping 10 matching lines...) Expand all Loading... | |
| 122 "originating_url VARCHAR," | 144 "originating_url VARCHAR," |
| 123 "date_created INTEGER DEFAULT 0," | 145 "date_created INTEGER DEFAULT 0," |
| 124 "usage_count INTEGER DEFAULT 0," | 146 "usage_count INTEGER DEFAULT 0," |
| 125 "input_encodings VARCHAR," | 147 "input_encodings VARCHAR," |
| 126 "show_in_default_list INTEGER," | 148 "show_in_default_list INTEGER," |
| 127 "suggest_url VARCHAR," | 149 "suggest_url VARCHAR," |
| 128 "prepopulate_id INTEGER DEFAULT 0," | 150 "prepopulate_id INTEGER DEFAULT 0," |
| 129 "created_by_policy INTEGER DEFAULT 0," | 151 "created_by_policy INTEGER DEFAULT 0," |
| 130 "instant_url VARCHAR," | 152 "instant_url VARCHAR," |
| 131 "last_modified INTEGER DEFAULT 0," | 153 "last_modified INTEGER DEFAULT 0," |
| 132 "sync_guid VARCHAR)") && | 154 "sync_guid VARCHAR," |
| 155 "alternate_urls VARCHAR)") && | |
| 133 UpdateBackupSignature(WebDatabase::kCurrentVersionNumber)); | 156 UpdateBackupSignature(WebDatabase::kCurrentVersionNumber)); |
| 134 } | 157 } |
| 135 | 158 |
| 136 bool KeywordTable::IsSyncable() { | 159 bool KeywordTable::IsSyncable() { |
| 137 return true; | 160 return true; |
| 138 } | 161 } |
| 139 | 162 |
| 140 bool KeywordTable::AddKeyword(const TemplateURLData& data) { | 163 bool KeywordTable::AddKeyword(const TemplateURLData& data) { |
| 141 DCHECK(data.id); | 164 DCHECK(data.id); |
| 142 std::string query("INSERT INTO keywords (" + std::string(kKeywordColumns) + | 165 std::string query("INSERT INTO keywords (" + std::string(kKeywordColumns) + |
| 143 ") VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)"); | 166 ") VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)"); |
| 144 sql::Statement s(db_->GetUniqueStatement(query.c_str())); | 167 sql::Statement s(db_->GetUniqueStatement(query.c_str())); |
| 145 BindURLToStatement(data, &s, 0, 1); | 168 BindURLToStatement(data, &s, 0, 1); |
| 146 | 169 |
| 147 return s.Run() && UpdateBackupSignature(WebDatabase::kCurrentVersionNumber); | 170 return s.Run() && UpdateBackupSignature(WebDatabase::kCurrentVersionNumber); |
| 148 } | 171 } |
| 149 | 172 |
| 150 bool KeywordTable::RemoveKeyword(TemplateURLID id) { | 173 bool KeywordTable::RemoveKeyword(TemplateURLID id) { |
| 151 DCHECK(id); | 174 DCHECK(id); |
| 152 sql::Statement s( | 175 sql::Statement s( |
| 153 db_->GetUniqueStatement("DELETE FROM keywords WHERE id = ?")); | 176 db_->GetUniqueStatement("DELETE FROM keywords WHERE id = ?")); |
| (...skipping 21 matching lines...) Expand all Loading... | |
| 175 succeeded &= RemoveKeyword(*i); | 198 succeeded &= RemoveKeyword(*i); |
| 176 return succeeded; | 199 return succeeded; |
| 177 } | 200 } |
| 178 | 201 |
| 179 bool KeywordTable::UpdateKeyword(const TemplateURLData& data) { | 202 bool KeywordTable::UpdateKeyword(const TemplateURLData& data) { |
| 180 DCHECK(data.id); | 203 DCHECK(data.id); |
| 181 sql::Statement s(db_->GetUniqueStatement("UPDATE keywords SET short_name=?, " | 204 sql::Statement s(db_->GetUniqueStatement("UPDATE keywords SET short_name=?, " |
| 182 "keyword=?, favicon_url=?, url=?, safe_for_autoreplace=?, " | 205 "keyword=?, favicon_url=?, url=?, safe_for_autoreplace=?, " |
| 183 "originating_url=?, date_created=?, usage_count=?, input_encodings=?, " | 206 "originating_url=?, date_created=?, usage_count=?, input_encodings=?, " |
| 184 "show_in_default_list=?, suggest_url=?, prepopulate_id=?, " | 207 "show_in_default_list=?, suggest_url=?, prepopulate_id=?, " |
| 185 "created_by_policy=?, instant_url=?, last_modified=?, sync_guid=? WHERE " | 208 "created_by_policy=?, instant_url=?, last_modified=?, sync_guid=?, " |
| 186 "id=?")); | 209 "alternate_urls=? WHERE id=?")); |
| 187 BindURLToStatement(data, &s, 16, 0); // "16" binds id() as the last item. | 210 BindURLToStatement(data, &s, 17, 0); // "17" binds id() as the last item. |
| 188 | 211 |
| 189 return s.Run() && UpdateBackupSignature(WebDatabase::kCurrentVersionNumber); | 212 return s.Run() && UpdateBackupSignature(WebDatabase::kCurrentVersionNumber); |
| 190 } | 213 } |
| 191 | 214 |
| 192 bool KeywordTable::SetDefaultSearchProviderID(int64 id) { | 215 bool KeywordTable::SetDefaultSearchProviderID(int64 id) { |
| 193 // Added for http://crbug.com/116952. | 216 // Added for http://crbug.com/116952. |
| 194 UMA_HISTOGRAM_COUNTS_100("Search.DefaultSearchProviderID", | 217 UMA_HISTOGRAM_COUNTS_100("Search.DefaultSearchProviderID", |
| 195 static_cast<int32>(id)); | 218 static_cast<int32>(id)); |
| 196 return meta_table_->SetValue(kDefaultSearchProviderKey, id) && | 219 return meta_table_->SetValue(kDefaultSearchProviderKey, id) && |
| 197 UpdateBackupSignature(WebDatabase::kCurrentVersionNumber); | 220 UpdateBackupSignature(WebDatabase::kCurrentVersionNumber); |
| (...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 302 bool KeywordTable::MigrateToVersion26AddCreatedByPolicyColumn() { | 325 bool KeywordTable::MigrateToVersion26AddCreatedByPolicyColumn() { |
| 303 return db_->Execute("ALTER TABLE keywords ADD COLUMN created_by_policy " | 326 return db_->Execute("ALTER TABLE keywords ADD COLUMN created_by_policy " |
| 304 "INTEGER DEFAULT 0"); | 327 "INTEGER DEFAULT 0"); |
| 305 } | 328 } |
| 306 | 329 |
| 307 bool KeywordTable::MigrateToVersion28SupportsInstantColumn() { | 330 bool KeywordTable::MigrateToVersion28SupportsInstantColumn() { |
| 308 return db_->Execute("ALTER TABLE keywords ADD COLUMN supports_instant " | 331 return db_->Execute("ALTER TABLE keywords ADD COLUMN supports_instant " |
| 309 "INTEGER DEFAULT 0"); | 332 "INTEGER DEFAULT 0"); |
| 310 } | 333 } |
| 311 | 334 |
| 312 bool KeywordTable::MigrateToVersion29InstantUrlToSupportsInstant() { | 335 bool KeywordTable::MigrateToVersion29InstantURLToSupportsInstant() { |
| 313 sql::Transaction transaction(db_); | 336 sql::Transaction transaction(db_); |
| 314 return transaction.Begin() && | 337 return transaction.Begin() && |
| 315 db_->Execute("ALTER TABLE keywords ADD COLUMN instant_url VARCHAR") && | 338 db_->Execute("ALTER TABLE keywords ADD COLUMN instant_url VARCHAR") && |
| 316 db_->Execute("CREATE TABLE keywords_temp (" | 339 db_->Execute("CREATE TABLE keywords_temp (" |
| 317 "id INTEGER PRIMARY KEY," | 340 "id INTEGER PRIMARY KEY," |
| 318 "short_name VARCHAR NOT NULL," | 341 "short_name VARCHAR NOT NULL," |
| 319 "keyword VARCHAR NOT NULL," | 342 "keyword VARCHAR NOT NULL," |
| 320 "favicon_url VARCHAR NOT NULL," | 343 "favicon_url VARCHAR NOT NULL," |
| 321 "url VARCHAR NOT NULL," | 344 "url VARCHAR NOT NULL," |
| 322 "safe_for_autoreplace INTEGER," | 345 "safe_for_autoreplace INTEGER," |
| (...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 379 // Old backup was invalid; drop the table entirely, which will trigger the | 402 // Old backup was invalid; drop the table entirely, which will trigger the |
| 380 // protector code to prompt the user and recreate the table. | 403 // protector code to prompt the user and recreate the table. |
| 381 if (db_->DoesTableExist("keywords_backup") && | 404 if (db_->DoesTableExist("keywords_backup") && |
| 382 !db_->Execute("DROP TABLE keywords_backup")) | 405 !db_->Execute("DROP TABLE keywords_backup")) |
| 383 return false; | 406 return false; |
| 384 } | 407 } |
| 385 | 408 |
| 386 return transaction.Commit(); | 409 return transaction.Commit(); |
| 387 } | 410 } |
| 388 | 411 |
| 412 bool KeywordTable::MigrateToVersion47AddAlternateURLsColumn() { | |
| 413 sql::Transaction transaction(db_); | |
| 414 | |
| 415 // Fill the |alternate_urls| column with empty strings, otherwise it breaks | |
| 416 // code relying on |kKeywordColumnsConcatenated|. | |
|
Peter Kasting
2012/10/02 21:47:59
Why? We have other VARCHAR columns that don't def
beaudoin
2012/10/03 22:46:52
It's needed for the migration. When adding the col
Peter Kasting
2012/10/03 22:59:33
So doesn't that mean that all our other VARCHARs s
beaudoin
2012/10/04 00:03:58
I think the fact that any update to the table (sav
| |
| 417 if (!transaction.Begin() || | |
| 418 !db_->Execute("ALTER TABLE keywords ADD COLUMN " | |
| 419 "alternate_urls VARCHAR DEFAULT ''")) | |
| 420 return false; | |
| 421 | |
| 422 if (db_->DoesTableExist("keywords_backup")) { | |
| 423 if (!db_->Execute("ALTER TABLE keywords_backup ADD COLUMN " | |
| 424 "alternate_urls VARCHAR DEFAULT ''") || | |
| 425 !SignBackup(47)) | |
|
Peter Kasting
2012/10/02 21:47:59
We should only migrate and sign the backup if it w
beaudoin
2012/10/03 22:46:52
Done.
| |
| 426 return false; | |
| 427 } | |
| 428 | |
| 429 return transaction.Commit(); | |
| 430 } | |
| 431 | |
| 389 // static | 432 // static |
| 390 bool KeywordTable::GetKeywordDataFromStatement(const sql::Statement& s, | 433 bool KeywordTable::GetKeywordDataFromStatement(const sql::Statement& s, |
| 391 TemplateURLData* data) { | 434 TemplateURLData* data) { |
| 392 DCHECK(data); | 435 DCHECK(data); |
| 436 | |
| 393 data->short_name = s.ColumnString16(1); | 437 data->short_name = s.ColumnString16(1); |
| 394 data->SetKeyword(s.ColumnString16(2)); | 438 data->SetKeyword(s.ColumnString16(2)); |
| 395 // Due to past bugs, we might have persisted entries with empty URLs. Avoid | 439 // Due to past bugs, we might have persisted entries with empty URLs. Avoid |
| 396 // reading these out. (GetKeywords() will delete these entries on return.) | 440 // reading these out. (GetKeywords() will delete these entries on return.) |
| 397 // NOTE: This code should only be needed as long as we might be reading such | 441 // NOTE: This code should only be needed as long as we might be reading such |
| 398 // potentially-old data and can be removed afterward. | 442 // potentially-old data and can be removed afterward. |
| 399 if (s.ColumnString(4).empty()) | 443 if (s.ColumnString(4).empty()) |
| 400 return false; | 444 return false; |
| 401 data->SetURL(s.ColumnString(4)); | 445 data->SetURL(s.ColumnString(4)); |
| 402 data->suggestions_url = s.ColumnString(11); | 446 data->suggestions_url = s.ColumnString(11); |
| 403 data->instant_url = s.ColumnString(14); | 447 data->instant_url = s.ColumnString(14); |
| 404 data->favicon_url = GURL(s.ColumnString(3)); | 448 data->favicon_url = GURL(s.ColumnString(3)); |
| 405 data->originating_url = GURL(s.ColumnString(6)); | 449 data->originating_url = GURL(s.ColumnString(6)); |
| 406 data->show_in_default_list = s.ColumnBool(10); | 450 data->show_in_default_list = s.ColumnBool(10); |
| 407 data->safe_for_autoreplace = s.ColumnBool(5); | 451 data->safe_for_autoreplace = s.ColumnBool(5); |
| 408 base::SplitString(s.ColumnString(9), ';', &data->input_encodings); | 452 base::SplitString(s.ColumnString(9), ';', &data->input_encodings); |
| 409 data->id = s.ColumnInt64(0); | 453 data->id = s.ColumnInt64(0); |
| 410 data->date_created = Time::FromTimeT(s.ColumnInt64(7)); | 454 data->date_created = Time::FromTimeT(s.ColumnInt64(7)); |
| 411 data->last_modified = Time::FromTimeT(s.ColumnInt64(15)); | 455 data->last_modified = Time::FromTimeT(s.ColumnInt64(15)); |
| 412 data->created_by_policy = s.ColumnBool(13); | 456 data->created_by_policy = s.ColumnBool(13); |
| 413 data->usage_count = s.ColumnInt(8); | 457 data->usage_count = s.ColumnInt(8); |
| 414 data->prepopulate_id = s.ColumnInt(12); | 458 data->prepopulate_id = s.ColumnInt(12); |
| 415 data->sync_guid = s.ColumnString(16); | 459 data->sync_guid = s.ColumnString(16); |
| 460 | |
| 461 data->alternate_urls.clear(); | |
| 462 base::JSONReader json_reader; | |
| 463 scoped_ptr<Value> value(json_reader.ReadToValue(s.ColumnString(17))); | |
| 464 ListValue* alternate_urls_value; | |
| 465 if (value.get() && value->GetAsList(&alternate_urls_value)) { | |
| 466 std::string alternate_url; | |
| 467 for (size_t i = 0; i < alternate_urls_value->GetSize(); ++i) { | |
| 468 if (alternate_urls_value->GetString(i, &alternate_url)) | |
| 469 data->alternate_urls.push_back(alternate_url); | |
| 470 } | |
| 471 } | |
| 472 | |
| 416 return true; | 473 return true; |
| 417 } | 474 } |
| 418 | 475 |
| 419 bool KeywordTable::GetSignatureData(int table_version, std::string* backup) { | 476 bool KeywordTable::GetSignatureData(int table_version, std::string* backup) { |
| 420 DCHECK(backup); | 477 DCHECK(backup); |
| 421 | 478 |
| 422 int64 backup_value = kInvalidTemplateURLID; | 479 int64 backup_value = kInvalidTemplateURLID; |
| 423 if (!meta_table_->GetValue(kDefaultSearchIDBackupKey, &backup_value)) { | 480 if (!meta_table_->GetValue(kDefaultSearchIDBackupKey, &backup_value)) { |
| 424 LOG(ERROR) << "No backup id for signing."; | 481 LOG(ERROR) << "No backup id for signing."; |
| 425 return false; | 482 return false; |
| (...skipping 11 matching lines...) Expand all Loading... | |
| 437 | 494 |
| 438 bool KeywordTable::GetTableContents(const char* table_name, | 495 bool KeywordTable::GetTableContents(const char* table_name, |
| 439 int table_version, | 496 int table_version, |
| 440 std::string* contents) { | 497 std::string* contents) { |
| 441 DCHECK(contents); | 498 DCHECK(contents); |
| 442 | 499 |
| 443 if (!db_->DoesTableExist(table_name)) | 500 if (!db_->DoesTableExist(table_name)) |
| 444 return false; | 501 return false; |
| 445 | 502 |
| 446 contents->clear(); | 503 contents->clear(); |
| 447 std::string query("SELECT " + | 504 const char* keywords_columns_concatenated = kKeywordColumnsConcatenated; |
|
Peter Kasting
2012/10/02 21:47:59
Nit: Probably makes sense to have helper functions
beaudoin
2012/10/03 22:46:52
Refactored this in a major way, got rid of all the
| |
| 448 std::string((table_version <= 44) ? | 505 if (table_version <= 44) |
| 449 kKeywordColumnsVersion44Concatenated : kKeywordColumnsConcatenated) + | 506 keywords_columns_concatenated = kKeywordColumnsVersion44Concatenated; |
| 507 else if (table_version <= 46) | |
| 508 keywords_columns_concatenated = kKeywordColumnsVersion46Concatenated; | |
| 509 std::string query("SELECT " + std::string(keywords_columns_concatenated) + | |
| 450 " FROM " + std::string(table_name) + " ORDER BY id ASC"); | 510 " FROM " + std::string(table_name) + " ORDER BY id ASC"); |
| 451 sql::Statement s((table_version == WebDatabase::kCurrentVersionNumber) ? | 511 sql::Statement s((table_version == WebDatabase::kCurrentVersionNumber) ? |
| 452 db_->GetCachedStatement(sql::StatementID(table_name), query.c_str()) : | 512 db_->GetCachedStatement(sql::StatementID(table_name), query.c_str()) : |
| 453 db_->GetUniqueStatement(query.c_str())); | 513 db_->GetUniqueStatement(query.c_str())); |
| 454 while (s.Step()) | 514 while (s.Step()) |
| 455 *contents += s.ColumnString(0); | 515 *contents += s.ColumnString(0); |
| 456 return s.Succeeded(); | 516 return s.Succeeded(); |
| 457 } | 517 } |
| 458 | 518 |
| 459 bool KeywordTable::UpdateBackupSignature(int table_version) { | 519 bool KeywordTable::UpdateBackupSignature(int table_version) { |
| 460 sql::Transaction transaction(db_); | 520 sql::Transaction transaction(db_); |
| 461 if (!transaction.Begin()) | 521 if (!transaction.Begin()) |
| 462 return false; | 522 return false; |
| 463 | 523 |
| 464 int64 id = kInvalidTemplateURLID; | 524 int64 id = kInvalidTemplateURLID; |
| 465 if (!UpdateDefaultSearchProviderIDBackup(&id)) { | 525 if (!UpdateDefaultSearchProviderIDBackup(&id)) { |
| 466 LOG(ERROR) << "Failed to update default search id backup."; | 526 LOG(ERROR) << "Failed to update default search id backup."; |
| 467 return false; | 527 return false; |
| 468 } | 528 } |
| 469 | 529 |
| 470 // Backup of all keywords. | 530 // Backup of all keywords. |
| 471 if (db_->DoesTableExist("keywords_backup") && | 531 if (db_->DoesTableExist("keywords_backup") && |
| 472 !db_->Execute("DROP TABLE keywords_backup")) | 532 !db_->Execute("DROP TABLE keywords_backup")) |
| 473 return false; | 533 return false; |
| 474 | 534 |
| 535 const char* keywords_columns = kKeywordColumns; | |
| 536 if (table_version <= 44) | |
| 537 keywords_columns = kKeywordColumnsVersion44; | |
| 538 else if (table_version <= 46) | |
| 539 keywords_columns = kKeywordColumnsVersion46; | |
| 475 std::string query("CREATE TABLE keywords_backup AS SELECT " + | 540 std::string query("CREATE TABLE keywords_backup AS SELECT " + |
| 476 std::string((table_version <= 44) ? | 541 std::string(keywords_columns) + " FROM keywords ORDER BY id ASC"); |
| 477 kKeywordColumnsVersion44 : kKeywordColumns) + | |
| 478 " FROM keywords ORDER BY id ASC"); | |
| 479 if (!db_->Execute(query.c_str())) { | 542 if (!db_->Execute(query.c_str())) { |
| 480 LOG(ERROR) << "Failed to create keywords_backup table."; | 543 LOG(ERROR) << "Failed to create keywords_backup table."; |
| 481 return false; | 544 return false; |
| 482 } | 545 } |
| 483 | 546 |
| 484 return SignBackup(table_version) && transaction.Commit(); | 547 return SignBackup(table_version) && transaction.Commit(); |
| 485 } | 548 } |
| 486 | 549 |
| 487 bool KeywordTable::SignBackup(int table_version) { | 550 bool KeywordTable::SignBackup(int table_version) { |
| 488 std::string data_to_sign; | 551 std::string data_to_sign; |
| (...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 557 "input_encodings VARCHAR," | 620 "input_encodings VARCHAR," |
| 558 "show_in_default_list INTEGER," | 621 "show_in_default_list INTEGER," |
| 559 "suggest_url VARCHAR," | 622 "suggest_url VARCHAR," |
| 560 "prepopulate_id INTEGER DEFAULT 0," | 623 "prepopulate_id INTEGER DEFAULT 0," |
| 561 "created_by_policy INTEGER DEFAULT 0," | 624 "created_by_policy INTEGER DEFAULT 0," |
| 562 "instant_url VARCHAR," | 625 "instant_url VARCHAR," |
| 563 "last_modified INTEGER DEFAULT 0," | 626 "last_modified INTEGER DEFAULT 0," |
| 564 "sync_guid VARCHAR)")) | 627 "sync_guid VARCHAR)")) |
| 565 return false; | 628 return false; |
| 566 std::string sql("INSERT INTO keywords_temp SELECT " + | 629 std::string sql("INSERT INTO keywords_temp SELECT " + |
| 567 std::string(kKeywordColumnsVersion45) + " FROM " + name); | 630 std::string(kKeywordColumnsVersion46) + " FROM " + name); |
| 568 if (!db_->Execute(sql.c_str())) | 631 if (!db_->Execute(sql.c_str())) |
| 569 return false; | 632 return false; |
| 570 | 633 |
| 571 // NOTE: The ORDER BY here ensures that the uniquing process for keywords will | 634 // NOTE: The ORDER BY here ensures that the uniquing process for keywords will |
| 572 // happen identically on both the normal and backup tables. | 635 // happen identically on both the normal and backup tables. |
| 573 sql = "SELECT id, keyword, url, autogenerate_keyword FROM " + name + | 636 sql = "SELECT id, keyword, url, autogenerate_keyword FROM " + name + |
| 574 " ORDER BY id ASC"; | 637 " ORDER BY id ASC"; |
| 575 sql::Statement s(db_->GetUniqueStatement(sql.c_str())); | 638 sql::Statement s(db_->GetUniqueStatement(sql.c_str())); |
| 576 string16 placeholder_keyword(ASCIIToUTF16("dummy")); | 639 string16 placeholder_keyword(ASCIIToUTF16("dummy")); |
| 577 std::set<string16> keywords; | 640 std::set<string16> keywords; |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 619 } | 682 } |
| 620 } | 683 } |
| 621 | 684 |
| 622 // Replace the old table with the new one. | 685 // Replace the old table with the new one. |
| 623 sql = "DROP TABLE " + name; | 686 sql = "DROP TABLE " + name; |
| 624 if (!db_->Execute(sql.c_str())) | 687 if (!db_->Execute(sql.c_str())) |
| 625 return false; | 688 return false; |
| 626 sql = "ALTER TABLE keywords_temp RENAME TO " + name; | 689 sql = "ALTER TABLE keywords_temp RENAME TO " + name; |
| 627 return db_->Execute(sql.c_str()); | 690 return db_->Execute(sql.c_str()); |
| 628 } | 691 } |
| OLD | NEW |