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

Side by Side Diff: chrome/browser/webdata/keyword_table.cc

Issue 10381016: Remove the "autogenerate keyword" bit on TemplateURL. (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: Created 8 years, 7 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 | Annotate | Revision Log
OLDNEW
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/logging.h" 9 #include "base/logging.h"
10 #include "base/memory/scoped_ptr.h" 10 #include "base/memory/scoped_ptr.h"
11 #include "base/metrics/histogram.h" 11 #include "base/metrics/histogram.h"
12 #include "base/metrics/stats_counters.h" 12 #include "base/metrics/stats_counters.h"
13 #include "base/string_number_conversions.h" 13 #include "base/string_number_conversions.h"
14 #include "base/string_split.h" 14 #include "base/string_split.h"
15 #include "base/string_util.h" 15 #include "base/string_util.h"
16 #include "base/stringprintf.h" 16 #include "base/stringprintf.h"
17 #include "base/utf_string_conversions.h" 17 #include "base/utf_string_conversions.h"
18 #include "chrome/browser/history/history_database.h" 18 #include "chrome/browser/history/history_database.h"
19 #include "chrome/browser/protector/histograms.h" 19 #include "chrome/browser/protector/histograms.h"
20 #include "chrome/browser/protector/protector_utils.h" 20 #include "chrome/browser/protector/protector_utils.h"
21 #include "chrome/browser/search_engines/search_terms_data.h"
21 #include "chrome/browser/search_engines/template_url.h" 22 #include "chrome/browser/search_engines/template_url.h"
23 #include "chrome/browser/search_engines/template_url_service.h"
24 #include "chrome/browser/webdata/web_database.h"
22 #include "googleurl/src/gurl.h" 25 #include "googleurl/src/gurl.h"
23 #include "sql/statement.h" 26 #include "sql/statement.h"
24 #include "sql/transaction.h" 27 #include "sql/transaction.h"
25 28
26 using base::Time; 29 using base::Time;
27 30
28 // static 31 // static
29 const char KeywordTable::kDefaultSearchProviderKey[] = 32 const char KeywordTable::kDefaultSearchProviderKey[] =
30 "Default Search Provider ID"; 33 "Default Search Provider ID";
31 const char KeywordTable::kDefaultSearchIDBackupKey[] = 34 const char KeywordTable::kDefaultSearchIDBackupKey[] =
32 "Default Search Provider ID Backup"; 35 "Default Search Provider ID Backup";
33 const char KeywordTable::kBackupSignatureKey[] = 36 const char KeywordTable::kBackupSignatureKey[] =
34 "Default Search Provider ID Backup Signature"; 37 "Default Search Provider ID Backup Signature";
35 const char KeywordTable::kKeywordColumns[] = "id, short_name, keyword, " 38 const char KeywordTable::kKeywordColumns[] = "id, short_name, keyword, "
36 "favicon_url, url, safe_for_autoreplace, originating_url, date_created, " 39 "favicon_url, url, safe_for_autoreplace, originating_url, date_created, "
37 "usage_count, input_encodings, show_in_default_list, suggest_url, " 40 "usage_count, input_encodings, show_in_default_list, suggest_url, "
38 "prepopulate_id, autogenerate_keyword, logo_id, created_by_policy, " 41 "prepopulate_id, created_by_policy, instant_url, last_modified, sync_guid";
39 "instant_url, last_modified, sync_guid";
40 42
41 namespace { 43 namespace {
42 44
43 // Keys used in the meta table. 45 // Keys used in the meta table.
44 const char kBuiltinKeywordVersion[] = "Builtin Keyword Version"; 46 const char kBuiltinKeywordVersion[] = "Builtin Keyword Version";
45 47
48 // 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.)
50 const char kKeywordColumnsVersion44Concatenated[] = "id || short_name || "
51 "keyword || favicon_url || url || safe_for_autoreplace || "
52 "originating_url || date_created || usage_count || input_encodings || "
53 "show_in_default_list || suggest_url || prepopulate_id || "
54 "autogenerate_keyword || logo_id || created_by_policy || instant_url || "
55 "last_modified || sync_guid";
56 const char kKeywordColumnsVersion44[] = "id, short_name, keyword, favicon_url, "
57 "url, safe_for_autoreplace, originating_url, date_created, usage_count, "
58 "input_encodings, show_in_default_list, suggest_url, prepopulate_id, "
59 "autogenerate_keyword, logo_id, created_by_policy, instant_url, "
60 "last_modified, sync_guid";
61 // NOTE: Remember to change what |kKeywordColumnsVersion45| says if the column
62 // set in |kKeywordColumns| changes, and update any code that needs to switch
63 // column sets based on a version number!
64 const char* const kKeywordColumnsVersion45 = KeywordTable::kKeywordColumns;
65
66 // The current columns.
46 const char kKeywordColumnsConcatenated[] = "id || short_name || keyword || " 67 const char kKeywordColumnsConcatenated[] = "id || short_name || keyword || "
47 "favicon_url || url || safe_for_autoreplace || originating_url || " 68 "favicon_url || url || safe_for_autoreplace || originating_url || "
48 "date_created || usage_count || input_encodings || show_in_default_list || " 69 "date_created || usage_count || input_encodings || show_in_default_list || "
49 "suggest_url || prepopulate_id || autogenerate_keyword || logo_id || " 70 "suggest_url || prepopulate_id || created_by_policy || instant_url || "
50 "created_by_policy || instant_url || last_modified || sync_guid"; 71 "last_modified || sync_guid";
51 72
52 // Inserts the data from |data| into |s|. |s| is assumed to have slots for all 73 // Inserts the data from |data| into |s|. |s| is assumed to have slots for all
53 // the columns in the keyword table. |id_column| is the slot number to bind 74 // the columns in the keyword table. |id_column| is the slot number to bind
54 // |data|'s id() to; |starting_column| is the slot number of the first of a 75 // |data|'s |id| to; |starting_column| is the slot number of the first of a
55 // contiguous set of slots to bind all the other fields to. 76 // contiguous set of slots to bind all the other fields to.
56 void BindURLToStatement(const TemplateURL& url, 77 void BindURLToStatement(const TemplateURLData& data,
57 sql::Statement* s, 78 sql::Statement* s,
58 int id_column, 79 int id_column,
59 int starting_column) { 80 int starting_column) {
60 const TemplateURLData& data = url.data();
61 s->BindInt64(id_column, data.id); 81 s->BindInt64(id_column, data.id);
62 s->BindString16(starting_column, data.short_name); 82 s->BindString16(starting_column, data.short_name);
63 // TODO(pkasting): See comment on TempalteURL::EnsureKeyword(). 83 s->BindString16(starting_column + 1, data.keyword());
64 s->BindString16(starting_column + 1,
65 data.keyword(const_cast<TemplateURL*>(&url)));
66 s->BindString(starting_column + 2, data.favicon_url.is_valid() ? 84 s->BindString(starting_column + 2, data.favicon_url.is_valid() ?
67 history::HistoryDatabase::GURLToDatabaseURL(data.favicon_url) : 85 history::HistoryDatabase::GURLToDatabaseURL(data.favicon_url) :
68 std::string()); 86 std::string());
69 s->BindString(starting_column + 3, data.url()); 87 s->BindString(starting_column + 3, data.url());
70 s->BindBool(starting_column + 4, data.safe_for_autoreplace); 88 s->BindBool(starting_column + 4, data.safe_for_autoreplace);
71 s->BindString(starting_column + 5, data.originating_url.is_valid() ? 89 s->BindString(starting_column + 5, data.originating_url.is_valid() ?
72 history::HistoryDatabase::GURLToDatabaseURL(data.originating_url) : 90 history::HistoryDatabase::GURLToDatabaseURL(data.originating_url) :
73 std::string()); 91 std::string());
74 s->BindInt64(starting_column + 6, data.date_created.ToTimeT()); 92 s->BindInt64(starting_column + 6, data.date_created.ToTimeT());
75 s->BindInt(starting_column + 7, data.usage_count); 93 s->BindInt(starting_column + 7, data.usage_count);
76 s->BindString(starting_column + 8, JoinString(data.input_encodings, ';')); 94 s->BindString(starting_column + 8, JoinString(data.input_encodings, ';'));
77 s->BindBool(starting_column + 9, data.show_in_default_list); 95 s->BindBool(starting_column + 9, data.show_in_default_list);
78 s->BindString(starting_column + 10, data.suggestions_url); 96 s->BindString(starting_column + 10, data.suggestions_url);
79 s->BindInt(starting_column + 11, data.prepopulate_id); 97 s->BindInt(starting_column + 11, data.prepopulate_id);
80 s->BindBool(starting_column + 12, data.autogenerate_keyword()); 98 s->BindBool(starting_column + 12, data.created_by_policy);
81 s->BindInt(starting_column + 13, 0); 99 s->BindString(starting_column + 13, data.instant_url);
82 s->BindBool(starting_column + 14, data.created_by_policy); 100 s->BindInt64(starting_column + 14, data.last_modified.ToTimeT());
83 s->BindString(starting_column + 15, data.instant_url); 101 s->BindString(starting_column + 15, data.sync_guid);
84 s->BindInt64(starting_column + 16, data.last_modified.ToTimeT());
85 s->BindString(starting_column + 17, data.sync_guid);
86 } 102 }
87 103
88 // Signs search provider id and returns its signature. 104 // Signs search provider id and returns its signature.
89 std::string GetSearchProviderIDSignature(int64 id) { 105 std::string GetSearchProviderIDSignature(int64 id) {
90 return protector::SignSetting(base::Int64ToString(id)); 106 return protector::SignSetting(base::Int64ToString(id));
91 } 107 }
92 108
93 // Checks if signature for search provider id is correct and returns the 109 // Checks if signature for search provider id is correct and returns the
94 // result. 110 // result.
95 bool IsSearchProviderIDValid(int64 id, const std::string& signature) { 111 bool IsSearchProviderIDValid(int64 id, const std::string& signature) {
(...skipping 13 matching lines...) Expand all
109 "favicon_url VARCHAR NOT NULL," 125 "favicon_url VARCHAR NOT NULL,"
110 "url VARCHAR NOT NULL," 126 "url VARCHAR NOT NULL,"
111 "safe_for_autoreplace INTEGER," 127 "safe_for_autoreplace INTEGER,"
112 "originating_url VARCHAR," 128 "originating_url VARCHAR,"
113 "date_created INTEGER DEFAULT 0," 129 "date_created INTEGER DEFAULT 0,"
114 "usage_count INTEGER DEFAULT 0," 130 "usage_count INTEGER DEFAULT 0,"
115 "input_encodings VARCHAR," 131 "input_encodings VARCHAR,"
116 "show_in_default_list INTEGER," 132 "show_in_default_list INTEGER,"
117 "suggest_url VARCHAR," 133 "suggest_url VARCHAR,"
118 "prepopulate_id INTEGER DEFAULT 0," 134 "prepopulate_id INTEGER DEFAULT 0,"
119 "autogenerate_keyword INTEGER DEFAULT 0,"
120 "logo_id INTEGER DEFAULT 0,"
121 "created_by_policy INTEGER DEFAULT 0," 135 "created_by_policy INTEGER DEFAULT 0,"
122 "instant_url VARCHAR," 136 "instant_url VARCHAR,"
123 "last_modified INTEGER DEFAULT 0," 137 "last_modified INTEGER DEFAULT 0,"
124 "sync_guid VARCHAR)") && 138 "sync_guid VARCHAR)") &&
125 UpdateBackupSignature()); 139 UpdateBackupSignature(WebDatabase::kCurrentVersionNumber));
126 } 140 }
127 141
128 bool KeywordTable::IsSyncable() { 142 bool KeywordTable::IsSyncable() {
129 return true; 143 return true;
130 } 144 }
131 145
132 bool KeywordTable::AddKeyword(const TemplateURL& url) { 146 bool KeywordTable::AddKeyword(const TemplateURLData& data) {
133 DCHECK(url.id()); 147 DCHECK(data.id);
134 std::string query("INSERT INTO keywords (" + std::string(kKeywordColumns) + 148 std::string query("INSERT INTO keywords (" + std::string(kKeywordColumns) +
135 ") VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)"); 149 ") VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)");
136 sql::Statement s(db_->GetUniqueStatement(query.c_str())); 150 sql::Statement s(db_->GetUniqueStatement(query.c_str()));
137 BindURLToStatement(url, &s, 0, 1); 151 BindURLToStatement(data, &s, 0, 1);
138 152
139 return s.Run() && UpdateBackupSignature(); 153 return s.Run() && UpdateBackupSignature(WebDatabase::kCurrentVersionNumber);
140 } 154 }
141 155
142 bool KeywordTable::RemoveKeyword(TemplateURLID id) { 156 bool KeywordTable::RemoveKeyword(TemplateURLID id) {
143 DCHECK(id); 157 DCHECK(id);
144 sql::Statement s( 158 sql::Statement s(
145 db_->GetUniqueStatement("DELETE FROM keywords WHERE id = ?")); 159 db_->GetUniqueStatement("DELETE FROM keywords WHERE id = ?"));
146 s.BindInt64(0, id); 160 s.BindInt64(0, id);
147 161
148 return s.Run() && UpdateBackupSignature(); 162 return s.Run() && UpdateBackupSignature(WebDatabase::kCurrentVersionNumber);
149 } 163 }
150 164
151 bool KeywordTable::GetKeywords(Keywords* keywords) { 165 bool KeywordTable::GetKeywords(Keywords* keywords) {
152 std::string query("SELECT " + std::string(kKeywordColumns) + 166 std::string query("SELECT " + std::string(kKeywordColumns) +
153 " FROM keywords ORDER BY id ASC"); 167 " FROM keywords ORDER BY id ASC");
154 sql::Statement s(db_->GetUniqueStatement(query.c_str())); 168 sql::Statement s(db_->GetUniqueStatement(query.c_str()));
155 169
156 std::set<TemplateURLID> bad_entries; 170 std::set<TemplateURLID> bad_entries;
157 while (s.Step()) { 171 while (s.Step()) {
158 keywords->push_back(TemplateURLData()); 172 keywords->push_back(TemplateURLData());
159 if (!GetKeywordDataFromStatement(s, &keywords->back())) { 173 if (!GetKeywordDataFromStatement(s, &keywords->back())) {
160 bad_entries.insert(s.ColumnInt64(0)); 174 bad_entries.insert(s.ColumnInt64(0));
161 keywords->pop_back(); 175 keywords->pop_back();
162 } 176 }
163 } 177 }
164 bool succeeded = s.Succeeded(); 178 bool succeeded = s.Succeeded();
165 for (std::set<TemplateURLID>::const_iterator i(bad_entries.begin()); 179 for (std::set<TemplateURLID>::const_iterator i(bad_entries.begin());
166 i != bad_entries.end(); ++i) 180 i != bad_entries.end(); ++i)
167 succeeded &= RemoveKeyword(*i); 181 succeeded &= RemoveKeyword(*i);
168 return succeeded; 182 return succeeded;
169 } 183 }
170 184
171 bool KeywordTable::UpdateKeyword(const TemplateURL& url) { 185 bool KeywordTable::UpdateKeyword(const TemplateURLData& data) {
172 DCHECK(url.id()); 186 DCHECK(data.id);
173 sql::Statement s(db_->GetUniqueStatement("UPDATE keywords SET short_name=?, " 187 sql::Statement s(db_->GetUniqueStatement("UPDATE keywords SET short_name=?, "
174 "keyword=?, favicon_url=?, url=?, safe_for_autoreplace=?, " 188 "keyword=?, favicon_url=?, url=?, safe_for_autoreplace=?, "
175 "originating_url=?, date_created=?, usage_count=?, input_encodings=?, " 189 "originating_url=?, date_created=?, usage_count=?, input_encodings=?, "
176 "show_in_default_list=?, suggest_url=?, prepopulate_id=?, " 190 "show_in_default_list=?, suggest_url=?, prepopulate_id=?, "
177 "autogenerate_keyword=?, logo_id=?, created_by_policy=?, instant_url=?, " 191 "created_by_policy=?, instant_url=?, last_modified=?, sync_guid=? WHERE "
178 "last_modified=?, sync_guid=? WHERE id=?")); 192 "id=?"));
179 BindURLToStatement(url, &s, 18, 0); // "18" binds id() as the last item. 193 BindURLToStatement(data, &s, 16, 0); // "16" binds id() as the last item.
180 194
181 return s.Run() && UpdateBackupSignature(); 195 return s.Run() && UpdateBackupSignature(WebDatabase::kCurrentVersionNumber);
182 } 196 }
183 197
184 bool KeywordTable::SetDefaultSearchProviderID(int64 id) { 198 bool KeywordTable::SetDefaultSearchProviderID(int64 id) {
185 // Added for http://crbug.com/116952. 199 // Added for http://crbug.com/116952.
186 UMA_HISTOGRAM_COUNTS_100("Search.DefaultSearchProviderID", 200 UMA_HISTOGRAM_COUNTS_100("Search.DefaultSearchProviderID",
187 static_cast<int32>(id)); 201 static_cast<int32>(id));
188 return meta_table_->SetValue(kDefaultSearchProviderKey, id) && 202 return meta_table_->SetValue(kDefaultSearchProviderKey, id) &&
189 UpdateBackupSignature(); 203 UpdateBackupSignature(WebDatabase::kCurrentVersionNumber);
190 } 204 }
191 205
192 int64 KeywordTable::GetDefaultSearchProviderID() { 206 int64 KeywordTable::GetDefaultSearchProviderID() {
193 int64 value = kInvalidTemplateURLID; 207 int64 value = kInvalidTemplateURLID;
194 meta_table_->GetValue(kDefaultSearchProviderKey, &value); 208 meta_table_->GetValue(kDefaultSearchProviderKey, &value);
195 return value; 209 return value;
196 } 210 }
197 211
198 bool KeywordTable::GetDefaultSearchProviderBackup(TemplateURLData* backup) { 212 bool KeywordTable::GetDefaultSearchProviderBackup(TemplateURLData* backup) {
199 if (!IsBackupSignatureValid()) 213 if (!IsBackupSignatureValid(WebDatabase::kCurrentVersionNumber))
200 return false; 214 return false;
201 215
202 int64 backup_id = kInvalidTemplateURLID; 216 int64 backup_id = kInvalidTemplateURLID;
203 if (!meta_table_->GetValue(kDefaultSearchIDBackupKey, &backup_id)) { 217 if (!meta_table_->GetValue(kDefaultSearchIDBackupKey, &backup_id)) {
204 LOG(ERROR) << "No default search id backup found."; 218 LOG(ERROR) << "No default search id backup found.";
205 return false; 219 return false;
206 } 220 }
207 std::string query("SELECT " + std::string(kKeywordColumns) + 221 std::string query("SELECT " + std::string(kKeywordColumns) +
208 " FROM keywords_backup WHERE id=?"); 222 " FROM keywords_backup WHERE id=?");
209 sql::Statement s(db_->GetUniqueStatement(query.c_str())); 223 sql::Statement s(db_->GetUniqueStatement(query.c_str()));
210 s.BindInt64(0, backup_id); 224 s.BindInt64(0, backup_id);
211 225
212 if (!s.Step()) { 226 if (!s.Step()) {
213 LOG_IF(ERROR, s.Succeeded()) 227 LOG_IF(ERROR, s.Succeeded())
214 << "No default search provider with backup id."; 228 << "No default search provider with backup id.";
215 return NULL; 229 return false;
216 } 230 }
217 231
218 if (!GetKeywordDataFromStatement(s, backup)) 232 if (!GetKeywordDataFromStatement(s, backup))
219 return false; 233 return false;
220 234
221 // ID has no meaning for the backup and should be kInvalidTemplateURLID in 235 // ID has no meaning for the backup and should be kInvalidTemplateURLID in
222 // case the TemplateURL will be added to keywords if missing. 236 // case the TemplateURL will be added to keywords if missing.
223 backup->id = kInvalidTemplateURLID; 237 backup->id = kInvalidTemplateURLID;
224 return true; 238 return true;
225 } 239 }
226 240
227 bool KeywordTable::DidDefaultSearchProviderChange() { 241 bool KeywordTable::DidDefaultSearchProviderChange() {
228 if (!IsBackupSignatureValid()) { 242 if (!IsBackupSignatureValid(WebDatabase::kCurrentVersionNumber)) {
229 UMA_HISTOGRAM_ENUMERATION( 243 UMA_HISTOGRAM_ENUMERATION(
230 protector::kProtectorHistogramDefaultSearchProvider, 244 protector::kProtectorHistogramDefaultSearchProvider,
231 protector::kProtectorErrorBackupInvalid, 245 protector::kProtectorErrorBackupInvalid,
232 protector::kProtectorErrorCount); 246 protector::kProtectorErrorCount);
233 LOG(ERROR) << "Backup signature is invalid."; 247 LOG(ERROR) << "Backup signature is invalid.";
234 return true; 248 return true;
235 } 249 }
236 250
237 int64 backup_id = kInvalidTemplateURLID; 251 int64 backup_id = kInvalidTemplateURLID;
238 meta_table_->GetValue(kDefaultSearchIDBackupKey, &backup_id); 252 meta_table_->GetValue(kDefaultSearchIDBackupKey, &backup_id);
(...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after
333 bool KeywordTable::MigrateToVersion38AddLastModifiedColumn() { 347 bool KeywordTable::MigrateToVersion38AddLastModifiedColumn() {
334 return db_->Execute( 348 return db_->Execute(
335 "ALTER TABLE keywords ADD COLUMN last_modified INTEGER DEFAULT 0"); 349 "ALTER TABLE keywords ADD COLUMN last_modified INTEGER DEFAULT 0");
336 } 350 }
337 351
338 bool KeywordTable::MigrateToVersion39AddSyncGUIDColumn() { 352 bool KeywordTable::MigrateToVersion39AddSyncGUIDColumn() {
339 return db_->Execute("ALTER TABLE keywords ADD COLUMN sync_guid VARCHAR"); 353 return db_->Execute("ALTER TABLE keywords ADD COLUMN sync_guid VARCHAR");
340 } 354 }
341 355
342 bool KeywordTable::MigrateToVersion44AddDefaultSearchProviderBackup() { 356 bool KeywordTable::MigrateToVersion44AddDefaultSearchProviderBackup() {
343 return IsBackupSignatureValid() || UpdateBackupSignature(); 357 return IsBackupSignatureValid(44) || UpdateBackupSignature(44);
358 }
359
360 bool KeywordTable::MigrateToVersion45RemoveLogoIDAndAutogenerateColumns() {
361 sql::Transaction transaction(db_);
362 if (!transaction.Begin())
363 return false;
364
365 // The version 43 migration should have been written to do this, but since it
366 // wasn't, we'll do it now. Unfortunately a previous change deleted this for
367 // some users, so we can't be sure this will succeed (so don't bail on error).
368 meta_table_->DeleteKey("Default Search Provider Backup");
369
370 if (!MigrateKeywordsTableForVersion45("keywords"))
371 return false;
372
373 if (IsBackupSignatureValid(44)) {
374 // Migrate the keywords backup table as well.
375 if (!MigrateKeywordsTableForVersion45("keywords_backup") || !SignBackup(45))
376 return false;
377 } else {
378 // Old backup was invalid; drop the table entirely, which will trigger the
379 // protector code to prompt the user and recreate the table.
380 if (db_->DoesTableExist("keywords_backup") &&
381 !db_->Execute("DROP TABLE keywords_backup"))
382 return false;
383 }
384
385 return transaction.Commit();
344 } 386 }
345 387
346 // static 388 // static
347 bool KeywordTable::GetKeywordDataFromStatement(const sql::Statement& s, 389 bool KeywordTable::GetKeywordDataFromStatement(const sql::Statement& s,
348 TemplateURLData* data) { 390 TemplateURLData* data) {
349 DCHECK(data); 391 DCHECK(data);
350 data->short_name = s.ColumnString16(1); 392 data->short_name = s.ColumnString16(1);
351 data->SetKeyword(s.ColumnString16(2)); 393 data->SetKeyword(s.ColumnString16(2));
352 data->SetAutogenerateKeyword(s.ColumnBool(13));
353 // Due to past bugs, we might have persisted entries with empty URLs. Avoid 394 // Due to past bugs, we might have persisted entries with empty URLs. Avoid
354 // reading these out. (GetKeywords() will delete these entries on return.) 395 // reading these out. (GetKeywords() will delete these entries on return.)
355 // NOTE: This code should only be needed as long as we might be reading such 396 // NOTE: This code should only be needed as long as we might be reading such
356 // potentially-old data and can be removed afterward. 397 // potentially-old data and can be removed afterward.
357 if (s.ColumnString(4).empty()) 398 if (s.ColumnString(4).empty())
358 return false; 399 return false;
359 data->SetURL(s.ColumnString(4)); 400 data->SetURL(s.ColumnString(4));
360 data->suggestions_url = s.ColumnString(11); 401 data->suggestions_url = s.ColumnString(11);
361 data->instant_url = s.ColumnString(16); 402 data->instant_url = s.ColumnString(14);
362 data->favicon_url = GURL(s.ColumnString(3)); 403 data->favicon_url = GURL(s.ColumnString(3));
363 data->originating_url = GURL(s.ColumnString(6)); 404 data->originating_url = GURL(s.ColumnString(6));
364 data->show_in_default_list = s.ColumnBool(10); 405 data->show_in_default_list = s.ColumnBool(10);
365 data->safe_for_autoreplace = s.ColumnBool(5); 406 data->safe_for_autoreplace = s.ColumnBool(5);
366 base::SplitString(s.ColumnString(9), ';', &data->input_encodings); 407 base::SplitString(s.ColumnString(9), ';', &data->input_encodings);
367 data->id = s.ColumnInt64(0); 408 data->id = s.ColumnInt64(0);
368 data->date_created = Time::FromTimeT(s.ColumnInt64(7)); 409 data->date_created = Time::FromTimeT(s.ColumnInt64(7));
369 data->last_modified = Time::FromTimeT(s.ColumnInt64(17)); 410 data->last_modified = Time::FromTimeT(s.ColumnInt64(15));
370 data->created_by_policy = s.ColumnBool(15); 411 data->created_by_policy = s.ColumnBool(13);
371 data->usage_count = s.ColumnInt(8); 412 data->usage_count = s.ColumnInt(8);
372 data->prepopulate_id = s.ColumnInt(12); 413 data->prepopulate_id = s.ColumnInt(12);
373 data->sync_guid = s.ColumnString(18); 414 data->sync_guid = s.ColumnString(16);
374 return true; 415 return true;
375 } 416 }
376 417
377 bool KeywordTable::GetSignatureData(std::string* backup) { 418 bool KeywordTable::GetSignatureData(int table_version, std::string* backup) {
378 DCHECK(backup); 419 DCHECK(backup);
379 420
380 int64 backup_value = kInvalidTemplateURLID; 421 int64 backup_value = kInvalidTemplateURLID;
381 if (!meta_table_->GetValue(kDefaultSearchIDBackupKey, &backup_value)) { 422 if (!meta_table_->GetValue(kDefaultSearchIDBackupKey, &backup_value)) {
382 LOG(ERROR) << "No backup id for signing."; 423 LOG(ERROR) << "No backup id for signing.";
383 return false; 424 return false;
384 } 425 }
385 426
386 std::string keywords_backup_data; 427 std::string keywords_backup_data;
387 if (!GetTableContents("keywords_backup", &keywords_backup_data)) { 428 if (!GetTableContents("keywords_backup", table_version,
429 &keywords_backup_data)) {
388 LOG(ERROR) << "Can't get keywords backup data"; 430 LOG(ERROR) << "Can't get keywords backup data";
389 return false; 431 return false;
390 } 432 }
391 *backup = base::Int64ToString(backup_value) + keywords_backup_data; 433 *backup = base::Int64ToString(backup_value) + keywords_backup_data;
392 return true; 434 return true;
393 } 435 }
394 436
395 bool KeywordTable::GetTableContents(const char* table_name, 437 bool KeywordTable::GetTableContents(const char* table_name,
438 int table_version,
396 std::string* contents) { 439 std::string* contents) {
397 DCHECK(contents); 440 DCHECK(contents);
398 441
399 if (!db_->DoesTableExist(table_name)) 442 if (!db_->DoesTableExist(table_name))
400 return false; 443 return false;
401 444
402 contents->clear(); 445 contents->clear();
403 std::string query("SELECT " + std::string(kKeywordColumnsConcatenated) + 446 std::string query("SELECT " +
447 std::string((table_version <= 44) ?
448 kKeywordColumnsVersion44Concatenated : kKeywordColumnsConcatenated) +
404 " FROM " + std::string(table_name) + " ORDER BY id ASC"); 449 " FROM " + std::string(table_name) + " ORDER BY id ASC");
405 sql::Statement s(db_->GetCachedStatement(sql::StatementID(table_name), 450 sql::Statement s((table_version == WebDatabase::kCurrentVersionNumber) ?
406 query.c_str())); 451 db_->GetCachedStatement(sql::StatementID(table_name), query.c_str()) :
452 db_->GetUniqueStatement(query.c_str()));
407 while (s.Step()) 453 while (s.Step())
408 *contents += s.ColumnString(0); 454 *contents += s.ColumnString(0);
409 return s.Succeeded(); 455 return s.Succeeded();
410 } 456 }
411 457
412 bool KeywordTable::UpdateBackupSignature() { 458 bool KeywordTable::UpdateBackupSignature(int table_version) {
413 sql::Transaction transaction(db_); 459 sql::Transaction transaction(db_);
414 if (!transaction.Begin()) 460 if (!transaction.Begin())
415 return false; 461 return false;
416 462
417 int64 id = kInvalidTemplateURLID; 463 int64 id = kInvalidTemplateURLID;
418 if (!UpdateDefaultSearchProviderIDBackup(&id)) { 464 if (!UpdateDefaultSearchProviderIDBackup(&id)) {
419 LOG(ERROR) << "Failed to update default search id backup."; 465 LOG(ERROR) << "Failed to update default search id backup.";
420 return false; 466 return false;
421 } 467 }
422 468
423 // Backup of all keywords. 469 // Backup of all keywords.
424 if (db_->DoesTableExist("keywords_backup") && 470 if (db_->DoesTableExist("keywords_backup") &&
425 !db_->Execute("DROP TABLE keywords_backup")) 471 !db_->Execute("DROP TABLE keywords_backup"))
426 return false; 472 return false;
427 473
428 std::string query("CREATE TABLE keywords_backup AS SELECT " + 474 std::string query("CREATE TABLE keywords_backup AS SELECT " +
429 std::string(kKeywordColumns) + " FROM keywords ORDER BY id ASC"); 475 std::string((table_version <= 44) ?
476 kKeywordColumnsVersion44 : kKeywordColumns) +
477 " FROM keywords ORDER BY id ASC");
430 if (!db_->Execute(query.c_str())) { 478 if (!db_->Execute(query.c_str())) {
431 LOG(ERROR) << "Failed to create keywords_backup table."; 479 LOG(ERROR) << "Failed to create keywords_backup table.";
432 return false; 480 return false;
433 } 481 }
434 482
483 return SignBackup(table_version) && transaction.Commit();
484 }
485
486 bool KeywordTable::SignBackup(int table_version) {
435 std::string data_to_sign; 487 std::string data_to_sign;
436 if (!GetSignatureData(&data_to_sign)) { 488 if (!GetSignatureData(table_version, &data_to_sign)) {
437 LOG(ERROR) << "No data to sign."; 489 LOG(ERROR) << "No data to sign.";
438 return false; 490 return false;
439 } 491 }
440 492
441 std::string signature = protector::SignSetting(data_to_sign); 493 std::string signature = protector::SignSetting(data_to_sign);
442 if (signature.empty()) { 494 if (signature.empty()) {
443 LOG(ERROR) << "Signature is empty"; 495 LOG(ERROR) << "Signature is empty";
444 return false; 496 return false;
445 } 497 }
446 498
447 return meta_table_->SetValue(kBackupSignatureKey, signature) && 499 return meta_table_->SetValue(kBackupSignatureKey, signature);
448 transaction.Commit();
449 } 500 }
450 501
451 bool KeywordTable::IsBackupSignatureValid() { 502 bool KeywordTable::IsBackupSignatureValid(int table_version) {
452 std::string signature; 503 std::string signature;
453 std::string signature_data; 504 std::string signature_data;
454 return meta_table_->GetValue(kBackupSignatureKey, &signature) && 505 return meta_table_->GetValue(kBackupSignatureKey, &signature) &&
455 GetSignatureData(&signature_data) && 506 GetSignatureData(table_version, &signature_data) &&
456 protector::IsSettingValid(signature_data, signature); 507 protector::IsSettingValid(signature_data, signature);
457 } 508 }
458 509
459 bool KeywordTable::GetKeywordAsString(TemplateURLID id, 510 bool KeywordTable::GetKeywordAsString(TemplateURLID id,
460 const std::string& table_name, 511 const std::string& table_name,
461 std::string* result) { 512 std::string* result) {
462 std::string query("SELECT " + std::string(kKeywordColumnsConcatenated) + 513 std::string query("SELECT " + std::string(kKeywordColumnsConcatenated) +
463 " FROM " + table_name + " WHERE id=?"); 514 " FROM " + table_name + " WHERE id=?");
464 sql::Statement s(db_->GetUniqueStatement(query.c_str())); 515 sql::Statement s(db_->GetUniqueStatement(query.c_str()));
465 s.BindInt64(0, id); 516 s.BindInt64(0, id);
(...skipping 16 matching lines...) Expand all
482 int64 default_search_id = GetDefaultSearchProviderID(); 533 int64 default_search_id = GetDefaultSearchProviderID();
483 if (!meta_table_->SetValue(kDefaultSearchIDBackupKey, 534 if (!meta_table_->SetValue(kDefaultSearchIDBackupKey,
484 default_search_id)) { 535 default_search_id)) {
485 LOG(ERROR) << "Can't write default search id backup."; 536 LOG(ERROR) << "Can't write default search id backup.";
486 return false; 537 return false;
487 } 538 }
488 539
489 *id = default_search_id; 540 *id = default_search_id;
490 return true; 541 return true;
491 } 542 }
543
544 bool KeywordTable::MigrateKeywordsTableForVersion45(const std::string& name) {
545 // Create a new table without the columns we're dropping.
546 if (!db_->Execute("CREATE TABLE keywords_temp ("
547 "id INTEGER PRIMARY KEY,"
548 "short_name VARCHAR NOT NULL,"
549 "keyword VARCHAR NOT NULL,"
550 "favicon_url VARCHAR NOT NULL,"
551 "url VARCHAR NOT NULL,"
552 "safe_for_autoreplace INTEGER,"
553 "originating_url VARCHAR,"
554 "date_created INTEGER DEFAULT 0,"
555 "usage_count INTEGER DEFAULT 0,"
556 "input_encodings VARCHAR,"
557 "show_in_default_list INTEGER,"
558 "suggest_url VARCHAR,"
559 "prepopulate_id INTEGER DEFAULT 0,"
560 "created_by_policy INTEGER DEFAULT 0,"
561 "instant_url VARCHAR,"
562 "last_modified INTEGER DEFAULT 0,"
563 "sync_guid VARCHAR)"))
564 return false;
565 std::string sql("INSERT INTO keywords_temp SELECT " +
566 std::string(kKeywordColumnsVersion45) + " FROM " + name);
567 if (!db_->Execute(sql.c_str()))
568 return false;
569
570 // NOTE: The ORDER BY here ensures that the uniquing process for keywords will
571 // happen identically on both the normal and backup tables.
572 sql = "SELECT id, keyword, url, autogenerate_keyword FROM " + name +
573 " ORDER BY id ASC";
574 sql::Statement s(db_->GetUniqueStatement(sql.c_str()));
575 string16 placeholder_keyword(ASCIIToUTF16("dummy"));
576 std::set<string16> keywords;
577 while (s.Step()) {
578 string16 keyword(s.ColumnString16(1));
579 bool generate_keyword = keyword.empty() || s.ColumnBool(3);
580 if (generate_keyword)
581 keyword = placeholder_keyword;
582 TemplateURLData data;
583 data.SetKeyword(keyword);
584 data.SetURL(s.ColumnString(2));
585 TemplateURL turl(NULL, data);
586 // Don't persist extension keywords to disk. These will get added to the
587 // TemplateURLService as the extensions are loaded.
588 bool delete_entry = turl.IsExtensionKeyword();
589 if (!delete_entry && generate_keyword) {
590 // Explicitly generate keywords for all rows with the autogenerate bit set
591 // or where the keyword is empty.
592 SearchTermsData terms_data;
593 GURL url(TemplateURLService::GenerateSearchURLUsingTermsData(&turl,
594 terms_data));
595 if (!url.is_valid()) {
596 delete_entry = true;
597 } else {
598 // Ensure autogenerated keywords are unique.
599 keyword = TemplateURLService::GenerateKeyword(url);
600 while (keywords.count(keyword))
601 keyword.append(ASCIIToUTF16("_"));
602 sql::Statement u(db_->GetUniqueStatement(
603 "UPDATE keywords_temp SET keyword=? WHERE id=?"));
604 u.BindString16(0, keyword);
605 u.BindInt64(1, s.ColumnInt64(0));
606 if (!u.Run())
607 return false;
608 }
609 }
610 if (delete_entry) {
611 sql::Statement u(db_->GetUniqueStatement(
612 "DELETE FROM keywords_temp WHERE id=?"));
613 u.BindInt64(0, s.ColumnInt64(0));
614 if (!u.Run())
615 return false;
616 } else {
617 keywords.insert(keyword);
618 }
619 }
620
621 // Replace the old table with the new one.
622 sql = "DROP TABLE " + name;
623 if (!db_->Execute(sql.c_str()))
624 return false;
625 sql = "ALTER TABLE keywords_temp RENAME TO " + name;
626 return db_->Execute(sql.c_str());
627 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698