blob: a93488706411c3c6d57a3924ad744a0d664e25c4 [file] [log] [blame]
[email protected]eaee4df2014-07-04 05:00:121// Copyright 2014 The Chromium Authors. All rights reserved.
[email protected]23e152e92011-03-30 15:52:342// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
[email protected]bf5c532d2014-07-05 00:29:535#include "components/search_engines/keyword_table.h"
[email protected]23e152e92011-03-30 15:52:346
avif57136c12015-12-25 23:27:457#include <stddef.h>
8
dchengd967d9502016-04-21 22:36:519#include <memory>
[email protected]4e40f59bb2012-04-19 01:07:0810#include <set>
11
[email protected]5b3078752012-10-09 18:54:1612#include "base/json/json_reader.h"
13#include "base/json/json_writer.h"
[email protected]23e152e92011-03-30 15:52:3414#include "base/logging.h"
[email protected]3ea1b182013-02-08 22:38:4115#include "base/strings/string_number_conversions.h"
mgiuca30f75882017-03-28 02:07:1916#include "base/strings/string_piece.h"
[email protected]1988e1c2013-02-28 20:27:4217#include "base/strings/string_split.h"
[email protected]9f0abdb2013-06-10 21:49:3418#include "base/strings/string_util.h"
[email protected]e309f312013-06-07 21:50:0819#include "base/strings/utf_string_conversions.h"
[email protected]5b3078752012-10-09 18:54:1620#include "base/values.h"
[email protected]bf5c532d2014-07-05 00:29:5321#include "components/history/core/browser/url_database.h"
[email protected]eb7c2e22014-06-12 16:26:0722#include "components/search_engines/search_terms_data.h"
[email protected]d550cb02014-06-25 06:48:1123#include "components/search_engines/template_url.h"
[email protected]06d548412013-04-03 21:24:0824#include "components/webdata/common/web_database.h"
[email protected]f0a54b22011-07-19 18:40:2125#include "sql/statement.h"
[email protected]67bb2742011-12-03 08:45:2426#include "sql/transaction.h"
[email protected]761fa4702013-07-02 15:25:1527#include "url/gurl.h"
[email protected]23e152e92011-03-30 15:52:3428
29using base::Time;
30
[email protected]e5f908e12012-03-13 21:10:1431// static
32const char KeywordTable::kDefaultSearchProviderKey[] =
33 "Default Search Provider ID";
[email protected]e5f908e12012-03-13 21:10:1434
[email protected]23e152e92011-03-30 15:52:3435namespace {
36
[email protected]23e152e92011-03-30 15:52:3437// Keys used in the meta table.
[email protected]432761572011-10-19 05:19:2638const char kBuiltinKeywordVersion[] = "Builtin Keyword Version";
39
[email protected]5b3078752012-10-09 18:54:1640const std::string ColumnsForVersion(int version, bool concatenated) {
mgiuca30f75882017-03-28 02:07:1941 std::vector<base::StringPiece> columns;
[email protected]7b596f62012-05-08 01:34:2542
[email protected]5b3078752012-10-09 18:54:1643 columns.push_back("id");
44 columns.push_back("short_name");
45 columns.push_back("keyword");
46 columns.push_back("favicon_url");
47 columns.push_back("url");
48 columns.push_back("safe_for_autoreplace");
49 columns.push_back("originating_url");
50 columns.push_back("date_created");
51 columns.push_back("usage_count");
52 columns.push_back("input_encodings");
ltiancf06dd012016-11-18 08:49:1253 if (version <= 67) {
54 // Column removed after version 67.
55 columns.push_back("show_in_default_list");
56 }
[email protected]5b3078752012-10-09 18:54:1657 columns.push_back("suggest_url");
58 columns.push_back("prepopulate_id");
59 if (version <= 44) {
60 // Columns removed after version 44.
61 columns.push_back("autogenerate_keyword");
62 columns.push_back("logo_id");
63 }
64 columns.push_back("created_by_policy");
65 columns.push_back("instant_url");
66 columns.push_back("last_modified");
67 columns.push_back("sync_guid");
68 if (version >= 47) {
69 // Column added in version 47.
70 columns.push_back("alternate_urls");
71 }
[email protected]008987b02013-01-03 21:22:4372 if (version >= 49) {
73 // Column added in version 49.
74 columns.push_back("search_terms_replacement_key");
75 }
[email protected]39682d12013-07-31 23:02:0576 if (version >= 52) {
77 // Column added in version 52.
78 columns.push_back("image_url");
79 columns.push_back("search_url_post_params");
80 columns.push_back("suggest_url_post_params");
81 columns.push_back("instant_url_post_params");
82 columns.push_back("image_url_post_params");
83 }
[email protected]041238dd2013-08-19 21:05:1284 if (version >= 53) {
85 // Column added in version 53.
86 columns.push_back("new_tab_url");
87 }
ltian8b5fc832016-12-02 23:43:3588 if (version >= 69) {
89 // Column added in version 69.
90 columns.push_back("last_visited");
91 }
[email protected]5b3078752012-10-09 18:54:1692
brettwd94a22142015-07-15 05:19:2693 return base::JoinString(columns, std::string(concatenated ? " || " : ", "));
[email protected]5b3078752012-10-09 18:54:1694}
95
[email protected]764d0b8b2011-12-14 13:26:2296
[email protected]573889f22012-04-07 01:31:5497// Inserts the data from |data| into |s|. |s| is assumed to have slots for all
[email protected]e5f908e12012-03-13 21:10:1498// the columns in the keyword table. |id_column| is the slot number to bind
[email protected]7b596f62012-05-08 01:34:2599// |data|'s |id| to; |starting_column| is the slot number of the first of a
[email protected]e5f908e12012-03-13 21:10:14100// contiguous set of slots to bind all the other fields to.
[email protected]7b596f62012-05-08 01:34:25101void BindURLToStatement(const TemplateURLData& data,
[email protected]e5f908e12012-03-13 21:10:14102 sql::Statement* s,
103 int id_column,
104 int starting_column) {
[email protected]5b3078752012-10-09 18:54:16105 // Serialize |alternate_urls| to JSON.
106 // TODO(beaudoin): Check what it would take to use a new table to store
107 // alternate_urls while keeping backups and table signature in a good state.
108 // See: crbug.com/153520
[email protected]e53a7f292013-12-23 21:43:38109 base::ListValue alternate_urls_value;
[email protected]5b3078752012-10-09 18:54:16110 for (size_t i = 0; i < data.alternate_urls.size(); ++i)
111 alternate_urls_value.AppendString(data.alternate_urls[i]);
112 std::string alternate_urls;
estade8d046462015-05-16 01:02:34113 base::JSONWriter::Write(alternate_urls_value, &alternate_urls);
[email protected]5b3078752012-10-09 18:54:16114
[email protected]573889f22012-04-07 01:31:54115 s->BindInt64(id_column, data.id);
mpearson3c6d7af2015-05-13 23:59:53116 s->BindString16(starting_column, data.short_name());
[email protected]7b596f62012-05-08 01:34:25117 s->BindString16(starting_column + 1, data.keyword());
[email protected]573889f22012-04-07 01:31:54118 s->BindString(starting_column + 2, data.favicon_url.is_valid() ?
[email protected]bf5c532d2014-07-05 00:29:53119 history::URLDatabase::GURLToDatabaseURL(data.favicon_url) :
[email protected]e5f908e12012-03-13 21:10:14120 std::string());
[email protected]573889f22012-04-07 01:31:54121 s->BindString(starting_column + 3, data.url());
122 s->BindBool(starting_column + 4, data.safe_for_autoreplace);
123 s->BindString(starting_column + 5, data.originating_url.is_valid() ?
[email protected]bf5c532d2014-07-05 00:29:53124 history::URLDatabase::GURLToDatabaseURL(data.originating_url) :
[email protected]e5f908e12012-03-13 21:10:14125 std::string());
[email protected]573889f22012-04-07 01:31:54126 s->BindInt64(starting_column + 6, data.date_created.ToTimeT());
127 s->BindInt(starting_column + 7, data.usage_count);
brettwd94a22142015-07-15 05:19:26128 s->BindString(starting_column + 8,
129 base::JoinString(data.input_encodings, ";"));
ltiancf06dd012016-11-18 08:49:12130 s->BindString(starting_column + 9, data.suggestions_url);
131 s->BindInt(starting_column + 10, data.prepopulate_id);
132 s->BindBool(starting_column + 11, data.created_by_policy);
133 s->BindString(starting_column + 12, data.instant_url);
134 s->BindInt64(starting_column + 13, data.last_modified.ToTimeT());
135 s->BindString(starting_column + 14, data.sync_guid);
136 s->BindString(starting_column + 15, alternate_urls);
137 s->BindString(starting_column + 16, data.search_terms_replacement_key);
138 s->BindString(starting_column + 17, data.image_url);
139 s->BindString(starting_column + 18, data.search_url_post_params);
140 s->BindString(starting_column + 19, data.suggestions_url_post_params);
141 s->BindString(starting_column + 20, data.instant_url_post_params);
142 s->BindString(starting_column + 21, data.image_url_post_params);
143 s->BindString(starting_column + 22, data.new_tab_url);
ltian8b5fc832016-12-02 23:43:35144 s->BindInt64(starting_column + 23, data.last_visited.ToTimeT());
[email protected]23e152e92011-03-30 15:52:34145}
[email protected]432761572011-10-19 05:19:26146
[email protected]3e95f4d2013-03-20 23:21:01147WebDatabaseTable::TypeKey GetKey() {
[email protected]56be8f52013-04-10 19:43:30148 // We just need a unique constant. Use the address of a static that
149 // COMDAT folding won't touch in an optimizing linker.
150 static int table_key = 0;
[email protected]3e95f4d2013-03-20 23:21:01151 return reinterpret_cast<void*>(&table_key);
152}
153
154} // namespace
155
156KeywordTable::KeywordTable() {
[email protected]2adf7df2012-07-14 19:16:55157}
158
[email protected]23e152e92011-03-30 15:52:34159KeywordTable::~KeywordTable() {}
160
[email protected]3e95f4d2013-03-20 23:21:01161KeywordTable* KeywordTable::FromWebDatabase(WebDatabase* db) {
162 return static_cast<KeywordTable*>(db->GetTable(GetKey()));
163}
164
165WebDatabaseTable::TypeKey KeywordTable::GetTypeKey() const {
166 return GetKey();
167}
168
[email protected]942cd282014-03-25 06:38:47169bool KeywordTable::CreateTablesIfNecessary() {
[email protected]e5f908e12012-03-13 21:10:14170 return db_->DoesTableExist("keywords") ||
[email protected]102253f2012-12-14 17:00:58171 db_->Execute("CREATE TABLE keywords ("
ltian8b5fc832016-12-02 23:43:35172 "id INTEGER PRIMARY KEY,"
173 "short_name VARCHAR NOT NULL,"
174 "keyword VARCHAR NOT NULL,"
175 "favicon_url VARCHAR NOT NULL,"
176 "url VARCHAR NOT NULL,"
177 "safe_for_autoreplace INTEGER,"
178 "originating_url VARCHAR,"
179 "date_created INTEGER DEFAULT 0,"
180 "usage_count INTEGER DEFAULT 0,"
181 "input_encodings VARCHAR,"
182 "suggest_url VARCHAR,"
183 "prepopulate_id INTEGER DEFAULT 0,"
184 "created_by_policy INTEGER DEFAULT 0,"
185 "instant_url VARCHAR,"
186 "last_modified INTEGER DEFAULT 0,"
187 "sync_guid VARCHAR,"
188 "alternate_urls VARCHAR,"
189 "search_terms_replacement_key VARCHAR,"
190 "image_url VARCHAR,"
191 "search_url_post_params VARCHAR,"
192 "suggest_url_post_params VARCHAR,"
193 "instant_url_post_params VARCHAR,"
194 "image_url_post_params VARCHAR,"
195 "new_tab_url VARCHAR,"
196 " last_visited INTEGER DEFAULT 0)");
[email protected]23e152e92011-03-30 15:52:34197}
198
[email protected]4db2dd8d2011-03-30 16:11:26199bool KeywordTable::IsSyncable() {
200 return true;
201}
202
[email protected]ad52b772013-03-12 22:24:08203bool KeywordTable::MigrateToVersion(int version,
[email protected]ad52b772013-03-12 22:24:08204 bool* update_compatible_version) {
205 // Migrate if necessary.
206 switch (version) {
[email protected]041238dd2013-08-19 21:05:12207 case 53:
208 *update_compatible_version = true;
209 return MigrateToVersion53AddNewTabURLColumn();
vasilii1fb84252014-11-06 11:59:09210 case 59:
211 *update_compatible_version = true;
212 return MigrateToVersion59RemoveExtensionKeywords();
ltiancf06dd012016-11-18 08:49:12213 case 68:
214 *update_compatible_version = true;
215 return MigrateToVersion68RemoveShowInDefaultListColumn();
ltian8b5fc832016-12-02 23:43:35216 case 69:
217 return MigrateToVersion69AddLastVisitedColumn();
[email protected]ad52b772013-03-12 22:24:08218 }
219
220 return true;
221}
222
[email protected]ad94ea32014-04-02 01:40:47223bool KeywordTable::PerformOperations(const Operations& operations) {
224 sql::Transaction transaction(db_);
225 if (!transaction.Begin())
226 return false;
[email protected]bed29d942011-12-22 19:25:51227
[email protected]ad94ea32014-04-02 01:40:47228 for (Operations::const_iterator i(operations.begin()); i != operations.end();
229 ++i) {
230 switch (i->first) {
231 case ADD:
232 if (!AddKeyword(i->second))
233 return false;
234 break;
[email protected]23e152e92011-03-30 15:52:34235
[email protected]ad94ea32014-04-02 01:40:47236 case REMOVE:
237 if (!RemoveKeyword(i->second.id))
238 return false;
239 break;
[email protected]bed29d942011-12-22 19:25:51240
[email protected]ad94ea32014-04-02 01:40:47241 case UPDATE:
242 if (!UpdateKeyword(i->second))
243 return false;
244 break;
245 }
246 }
247
248 return transaction.Commit();
[email protected]23e152e92011-03-30 15:52:34249}
250
[email protected]e5f908e12012-03-13 21:10:14251bool KeywordTable::GetKeywords(Keywords* keywords) {
[email protected]5b3078752012-10-09 18:54:16252 std::string query("SELECT " + GetKeywordColumns() +
[email protected]e5f908e12012-03-13 21:10:14253 " FROM keywords ORDER BY id ASC");
254 sql::Statement s(db_->GetUniqueStatement(query.c_str()));
[email protected]bed29d942011-12-22 19:25:51255
[email protected]4e40f59bb2012-04-19 01:07:08256 std::set<TemplateURLID> bad_entries;
[email protected]573889f22012-04-07 01:31:54257 while (s.Step()) {
258 keywords->push_back(TemplateURLData());
[email protected]4e40f59bb2012-04-19 01:07:08259 if (!GetKeywordDataFromStatement(s, &keywords->back())) {
260 bad_entries.insert(s.ColumnInt64(0));
261 keywords->pop_back();
262 }
[email protected]573889f22012-04-07 01:31:54263 }
[email protected]4e40f59bb2012-04-19 01:07:08264 bool succeeded = s.Succeeded();
265 for (std::set<TemplateURLID>::const_iterator i(bad_entries.begin());
266 i != bad_entries.end(); ++i)
267 succeeded &= RemoveKeyword(*i);
268 return succeeded;
[email protected]23e152e92011-03-30 15:52:34269}
270
avif57136c12015-12-25 23:27:45271bool KeywordTable::SetDefaultSearchProviderID(int64_t id) {
[email protected]102253f2012-12-14 17:00:58272 return meta_table_->SetValue(kDefaultSearchProviderKey, id);
[email protected]23e152e92011-03-30 15:52:34273}
274
avif57136c12015-12-25 23:27:45275int64_t KeywordTable::GetDefaultSearchProviderID() {
276 int64_t value = kInvalidTemplateURLID;
[email protected]23e152e92011-03-30 15:52:34277 meta_table_->GetValue(kDefaultSearchProviderKey, &value);
[email protected]75a4eca2011-10-26 20:40:09278 return value;
279}
280
[email protected]432761572011-10-19 05:19:26281bool KeywordTable::SetBuiltinKeywordVersion(int version) {
[email protected]23e152e92011-03-30 15:52:34282 return meta_table_->SetValue(kBuiltinKeywordVersion, version);
283}
284
[email protected]432761572011-10-19 05:19:26285int KeywordTable::GetBuiltinKeywordVersion() {
[email protected]23e152e92011-03-30 15:52:34286 int version = 0;
[email protected]e5f908e12012-03-13 21:10:14287 return meta_table_->GetValue(kBuiltinKeywordVersion, &version) ? version : 0;
[email protected]23e152e92011-03-30 15:52:34288}
[email protected]d8a99432011-04-05 15:48:34289
[email protected]5b3078752012-10-09 18:54:16290// static
291std::string KeywordTable::GetKeywordColumns() {
292 return ColumnsForVersion(WebDatabase::kCurrentVersionNumber, false);
293}
294
[email protected]041238dd2013-08-19 21:05:12295bool KeywordTable::MigrateToVersion53AddNewTabURLColumn() {
[email protected]6aa2df5c2014-04-02 01:39:15296 return db_->Execute("ALTER TABLE keywords ADD COLUMN new_tab_url "
297 "VARCHAR DEFAULT ''");
[email protected]39682d12013-07-31 23:02:05298}
299
vasilii1fb84252014-11-06 11:59:09300bool KeywordTable::MigrateToVersion59RemoveExtensionKeywords() {
301 return db_->Execute("DELETE FROM keywords "
302 "WHERE url LIKE 'chrome-extension://%'");
303}
304
ltiancf06dd012016-11-18 08:49:12305// SQLite does not support DROP COLUMN operation. So A new table is created
306// without the show_in_default_list column. Data from all but the dropped column
307// of the old table is copied into it. After that, the old table is dropped and
308// the new table is renamed to it.
309bool KeywordTable::MigrateToVersion68RemoveShowInDefaultListColumn() {
310 sql::Transaction transaction(db_);
311 std::string query_str =
312 std::string("INSERT INTO temp_keywords SELECT " +
313 ColumnsForVersion(68, false) + " FROM keywords");
314 const char* clone_query = query_str.c_str();
315 return transaction.Begin() &&
316 db_->Execute(
317 "CREATE TABLE temp_keywords ("
318 "id INTEGER PRIMARY KEY,"
319 "short_name VARCHAR NOT NULL,"
320 "keyword VARCHAR NOT NULL,"
321 "favicon_url VARCHAR NOT NULL,"
322 "url VARCHAR NOT NULL,"
323 "safe_for_autoreplace INTEGER,"
324 "originating_url VARCHAR,"
325 "date_created INTEGER DEFAULT 0,"
326 "usage_count INTEGER DEFAULT 0,"
327 "input_encodings VARCHAR,"
328 "suggest_url VARCHAR,"
329 "prepopulate_id INTEGER DEFAULT 0,"
330 "created_by_policy INTEGER DEFAULT 0,"
331 "instant_url VARCHAR,"
332 "last_modified INTEGER DEFAULT 0,"
333 "sync_guid VARCHAR,"
334 "alternate_urls VARCHAR,"
335 "search_terms_replacement_key VARCHAR,"
336 "image_url VARCHAR,"
337 "search_url_post_params VARCHAR,"
338 "suggest_url_post_params VARCHAR,"
339 "instant_url_post_params VARCHAR,"
340 "image_url_post_params VARCHAR,"
341 "new_tab_url VARCHAR)") &&
342 db_->Execute(clone_query) && db_->Execute("DROP TABLE keywords") &&
343 db_->Execute("ALTER TABLE temp_keywords RENAME TO keywords") &&
344 transaction.Commit();
345}
346
ltian8b5fc832016-12-02 23:43:35347bool KeywordTable::MigrateToVersion69AddLastVisitedColumn() {
348 return db_->Execute("ALTER TABLE keywords ADD COLUMN last_visited "
349 "INTEGER DEFAULT 0");
350}
351
[email protected]e5f908e12012-03-13 21:10:14352// static
[email protected]4e40f59bb2012-04-19 01:07:08353bool KeywordTable::GetKeywordDataFromStatement(const sql::Statement& s,
[email protected]573889f22012-04-07 01:31:54354 TemplateURLData* data) {
355 DCHECK(data);
[email protected]5b3078752012-10-09 18:54:16356
mpearson3c6d7af2015-05-13 23:59:53357 data->SetShortName(s.ColumnString16(1));
[email protected]573889f22012-04-07 01:31:54358 data->SetKeyword(s.ColumnString16(2));
[email protected]4e40f59bb2012-04-19 01:07:08359 // Due to past bugs, we might have persisted entries with empty URLs. Avoid
360 // reading these out. (GetKeywords() will delete these entries on return.)
361 // NOTE: This code should only be needed as long as we might be reading such
362 // potentially-old data and can be removed afterward.
363 if (s.ColumnString(4).empty())
364 return false;
[email protected]573889f22012-04-07 01:31:54365 data->SetURL(s.ColumnString(4));
ltiancf06dd012016-11-18 08:49:12366 data->suggestions_url = s.ColumnString(10);
367 data->instant_url = s.ColumnString(13);
368 data->image_url = s.ColumnString(18);
369 data->new_tab_url = s.ColumnString(23);
370 data->search_url_post_params = s.ColumnString(19);
371 data->suggestions_url_post_params = s.ColumnString(20);
372 data->instant_url_post_params = s.ColumnString(21);
373 data->image_url_post_params = s.ColumnString(22);
[email protected]573889f22012-04-07 01:31:54374 data->favicon_url = GURL(s.ColumnString(3));
375 data->originating_url = GURL(s.ColumnString(6));
[email protected]573889f22012-04-07 01:31:54376 data->safe_for_autoreplace = s.ColumnBool(5);
brettw8be197d12015-07-23 23:23:31377 data->input_encodings = base::SplitString(
378 s.ColumnString(9), ";", base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL);
[email protected]573889f22012-04-07 01:31:54379 data->id = s.ColumnInt64(0);
380 data->date_created = Time::FromTimeT(s.ColumnInt64(7));
ltiancf06dd012016-11-18 08:49:12381 data->last_modified = Time::FromTimeT(s.ColumnInt64(14));
382 data->created_by_policy = s.ColumnBool(12);
[email protected]573889f22012-04-07 01:31:54383 data->usage_count = s.ColumnInt(8);
ltiancf06dd012016-11-18 08:49:12384 data->prepopulate_id = s.ColumnInt(11);
385 data->sync_guid = s.ColumnString(15);
[email protected]5b3078752012-10-09 18:54:16386
387 data->alternate_urls.clear();
388 base::JSONReader json_reader;
dchengd967d9502016-04-21 22:36:51389 std::unique_ptr<base::Value> value(
ltiancf06dd012016-11-18 08:49:12390 json_reader.ReadToValue(s.ColumnString(16)));
[email protected]e53a7f292013-12-23 21:43:38391 base::ListValue* alternate_urls_value;
[email protected]5b3078752012-10-09 18:54:16392 if (value.get() && value->GetAsList(&alternate_urls_value)) {
393 std::string alternate_url;
394 for (size_t i = 0; i < alternate_urls_value->GetSize(); ++i) {
395 if (alternate_urls_value->GetString(i, &alternate_url))
396 data->alternate_urls.push_back(alternate_url);
397 }
398 }
399
ltiancf06dd012016-11-18 08:49:12400 data->search_terms_replacement_key = s.ColumnString(17);
ltian8b5fc832016-12-02 23:43:35401 data->last_visited = Time::FromTimeT(s.ColumnInt64(24));
[email protected]008987b02013-01-03 21:22:43402
[email protected]4e40f59bb2012-04-19 01:07:08403 return true;
[email protected]fbfc3722012-01-16 11:58:38404}
405
[email protected]ad94ea32014-04-02 01:40:47406bool KeywordTable::AddKeyword(const TemplateURLData& data) {
407 DCHECK(data.id);
408 std::string query("INSERT INTO keywords (" + GetKeywordColumns() + ") "
ltiancf06dd012016-11-18 08:49:12409 "VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,"
ltian8b5fc832016-12-02 23:43:35410 " ?,?)");
[email protected]ad94ea32014-04-02 01:40:47411 sql::Statement s(db_->GetCachedStatement(SQL_FROM_HERE, query.c_str()));
412 BindURLToStatement(data, &s, 0, 1);
413
414 return s.Run();
415}
416
417bool KeywordTable::RemoveKeyword(TemplateURLID id) {
418 DCHECK(id);
419 sql::Statement s(db_->GetCachedStatement(
420 SQL_FROM_HERE, "DELETE FROM keywords WHERE id = ?"));
421 s.BindInt64(0, id);
422
423 return s.Run();
424}
425
426bool KeywordTable::UpdateKeyword(const TemplateURLData& data) {
427 DCHECK(data.id);
428 sql::Statement s(db_->GetCachedStatement(
429 SQL_FROM_HERE,
430 "UPDATE keywords SET short_name=?, keyword=?, favicon_url=?, url=?, "
431 "safe_for_autoreplace=?, originating_url=?, date_created=?, "
ltiancf06dd012016-11-18 08:49:12432 "usage_count=?, input_encodings=?, suggest_url=?, "
433 "prepopulate_id=?, created_by_policy=?, instant_url=?, "
[email protected]ad94ea32014-04-02 01:40:47434 "last_modified=?, sync_guid=?, alternate_urls=?, "
435 "search_terms_replacement_key=?, image_url=?, search_url_post_params=?, "
436 "suggest_url_post_params=?, instant_url_post_params=?, "
ltian8b5fc832016-12-02 23:43:35437 "image_url_post_params=?, new_tab_url=?, last_visited=? WHERE id=?"));
438 BindURLToStatement(data, &s, 24, 0); // "24" binds id() as the last item.
[email protected]ad94ea32014-04-02 01:40:47439
440 return s.Run();
441}
442
[email protected]764d0b8b2011-12-14 13:26:22443bool KeywordTable::GetKeywordAsString(TemplateURLID id,
444 const std::string& table_name,
445 std::string* result) {
[email protected]5b3078752012-10-09 18:54:16446 std::string query("SELECT " +
447 ColumnsForVersion(WebDatabase::kCurrentVersionNumber, true) +
[email protected]e5f908e12012-03-13 21:10:14448 " FROM " + table_name + " WHERE id=?");
[email protected]764d0b8b2011-12-14 13:26:22449 sql::Statement s(db_->GetUniqueStatement(query.c_str()));
[email protected]67bb2742011-12-03 08:45:24450 s.BindInt64(0, id);
[email protected]ae6c59c2012-01-18 23:43:25451
[email protected]67bb2742011-12-03 08:45:24452 if (!s.Step()) {
[email protected]e5f908e12012-03-13 21:10:14453 LOG_IF(WARNING, s.Succeeded()) << "No keyword with id: " << id
454 << ", ignoring.";
[email protected]67bb2742011-12-03 08:45:24455 return true;
456 }
457
[email protected]ae6c59c2012-01-18 23:43:25458 if (!s.Succeeded())
[email protected]67bb2742011-12-03 08:45:24459 return false;
[email protected]67bb2742011-12-03 08:45:24460
461 *result = s.ColumnString(0);
462 return true;
463}