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

Side by Side Diff: chrome/browser/history/url_database.cc

Issue 9071014: Database usage adjustment for .../history (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 8 years, 11 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) 2011 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2011 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/history/url_database.h" 5 #include "chrome/browser/history/url_database.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 #include <limits> 8 #include <limits>
9 #include <string> 9 #include <string>
10 #include <vector> 10 #include <vector>
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after
83 i->hidden_ = s.ColumnInt(6) != 0; 83 i->hidden_ = s.ColumnInt(6) != 0;
84 } 84 }
85 85
86 bool URLDatabase::GetURLRow(URLID url_id, URLRow* info) { 86 bool URLDatabase::GetURLRow(URLID url_id, URLRow* info) {
87 // TODO(brettw) We need check for empty URLs to handle the case where 87 // TODO(brettw) We need check for empty URLs to handle the case where
88 // there are old URLs in the database that are empty that got in before 88 // there are old URLs in the database that are empty that got in before
89 // we added any checks. We should eventually be able to remove it 89 // we added any checks. We should eventually be able to remove it
90 // when all inputs are using GURL (which prohibit empty input). 90 // when all inputs are using GURL (which prohibit empty input).
91 sql::Statement statement(GetDB().GetCachedStatement(SQL_FROM_HERE, 91 sql::Statement statement(GetDB().GetCachedStatement(SQL_FROM_HERE,
92 "SELECT" HISTORY_URL_ROW_FIELDS "FROM urls WHERE id=?")); 92 "SELECT" HISTORY_URL_ROW_FIELDS "FROM urls WHERE id=?"));
93 if (!statement) 93 statement.BindInt64(0, url_id);
94 return false;
95 94
96 statement.BindInt64(0, url_id);
97 if (statement.Step()) { 95 if (statement.Step()) {
98 FillURLRow(statement, info); 96 FillURLRow(statement, info);
99 return true; 97 return true;
100 } 98 }
101 return false; 99 return false;
102 } 100 }
103 101
104 bool URLDatabase::GetAllTypedUrls(std::vector<history::URLRow>* urls) { 102 bool URLDatabase::GetAllTypedUrls(std::vector<history::URLRow>* urls) {
105 sql::Statement statement(GetDB().GetCachedStatement(SQL_FROM_HERE, 103 sql::Statement statement(GetDB().GetCachedStatement(SQL_FROM_HERE,
106 "SELECT" HISTORY_URL_ROW_FIELDS "FROM urls WHERE typed_count > 0")); 104 "SELECT" HISTORY_URL_ROW_FIELDS "FROM urls WHERE typed_count > 0"));
107 if (!statement)
108 return false;
Scott Hess - ex-Googler 2012/01/03 23:41:57 This can now return true in case of empty results.
Greg Billock 2012/01/04 19:20:20 I think that's what this did before. The above sho
Scott Hess - ex-Googler 2012/01/10 22:04:56 As it stands, it's always returning true, so if it
109 105
110 while (statement.Step()) { 106 while (statement.Step()) {
111 URLRow info; 107 URLRow info;
112 FillURLRow(statement, &info); 108 FillURLRow(statement, &info);
113 urls->push_back(info); 109 urls->push_back(info);
114 } 110 }
115 return true; 111 return true;
116 } 112 }
117 113
118 URLID URLDatabase::GetRowForURL(const GURL& url, history::URLRow* info) { 114 URLID URLDatabase::GetRowForURL(const GURL& url, history::URLRow* info) {
119 sql::Statement statement(GetDB().GetCachedStatement(SQL_FROM_HERE, 115 sql::Statement statement(GetDB().GetCachedStatement(SQL_FROM_HERE,
120 "SELECT" HISTORY_URL_ROW_FIELDS "FROM urls WHERE url=?")); 116 "SELECT" HISTORY_URL_ROW_FIELDS "FROM urls WHERE url=?"));
121 if (!statement)
122 return 0;
123
124 std::string url_string = GURLToDatabaseURL(url); 117 std::string url_string = GURLToDatabaseURL(url);
125 statement.BindString(0, url_string); 118 statement.BindString(0, url_string);
119
126 if (!statement.Step()) 120 if (!statement.Step())
127 return 0; // no data 121 return 0; // no data
128 122
129 if (info) 123 if (info)
130 FillURLRow(statement, info); 124 FillURLRow(statement, info);
131 return statement.ColumnInt64(0); 125 return statement.ColumnInt64(0);
132 } 126 }
133 127
134 bool URLDatabase::UpdateURLRow(URLID url_id, 128 bool URLDatabase::UpdateURLRow(URLID url_id,
135 const history::URLRow& info) { 129 const history::URLRow& info) {
136 sql::Statement statement(GetDB().GetCachedStatement(SQL_FROM_HERE, 130 sql::Statement statement(GetDB().GetCachedStatement(SQL_FROM_HERE,
137 "UPDATE urls SET title=?,visit_count=?,typed_count=?,last_visit_time=?," 131 "UPDATE urls SET title=?,visit_count=?,typed_count=?,last_visit_time=?,"
138 "hidden=?" 132 "hidden=?"
139 "WHERE id=?")); 133 "WHERE id=?"));
140 if (!statement)
141 return false;
142
143 statement.BindString16(0, info.title()); 134 statement.BindString16(0, info.title());
144 statement.BindInt(1, info.visit_count()); 135 statement.BindInt(1, info.visit_count());
145 statement.BindInt(2, info.typed_count()); 136 statement.BindInt(2, info.typed_count());
146 statement.BindInt64(3, info.last_visit().ToInternalValue()); 137 statement.BindInt64(3, info.last_visit().ToInternalValue());
147 statement.BindInt(4, info.hidden() ? 1 : 0); 138 statement.BindInt(4, info.hidden() ? 1 : 0);
148 statement.BindInt64(5, url_id); 139 statement.BindInt64(5, url_id);
140
149 return statement.Run(); 141 return statement.Run();
150 } 142 }
151 143
152 URLID URLDatabase::AddURLInternal(const history::URLRow& info, 144 URLID URLDatabase::AddURLInternal(const history::URLRow& info,
153 bool is_temporary) { 145 bool is_temporary) {
154 // This function is used to insert into two different tables, so we have to 146 // This function is used to insert into two different tables, so we have to
155 // do some shuffling. Unfortinately, we can't use the macro 147 // do some shuffling. Unfortinately, we can't use the macro
156 // HISTORY_URL_ROW_FIELDS because that specifies the table name which is 148 // HISTORY_URL_ROW_FIELDS because that specifies the table name which is
157 // invalid in the insert syntax. 149 // invalid in the insert syntax.
158 #define ADDURL_COMMON_SUFFIX \ 150 #define ADDURL_COMMON_SUFFIX \
159 " (url, title, visit_count, typed_count, "\ 151 " (url, title, visit_count, typed_count, "\
160 "last_visit_time, hidden) "\ 152 "last_visit_time, hidden) "\
161 "VALUES (?,?,?,?,?,?)" 153 "VALUES (?,?,?,?,?,?)"
162 const char* statement_name; 154 const char* statement_name;
163 const char* statement_sql; 155 const char* statement_sql;
164 if (is_temporary) { 156 if (is_temporary) {
165 statement_name = "AddURLTemporary"; 157 statement_name = "AddURLTemporary";
166 statement_sql = "INSERT INTO temp_urls" ADDURL_COMMON_SUFFIX; 158 statement_sql = "INSERT INTO temp_urls" ADDURL_COMMON_SUFFIX;
167 } else { 159 } else {
168 statement_name = "AddURL"; 160 statement_name = "AddURL";
169 statement_sql = "INSERT INTO urls" ADDURL_COMMON_SUFFIX; 161 statement_sql = "INSERT INTO urls" ADDURL_COMMON_SUFFIX;
170 } 162 }
171 #undef ADDURL_COMMON_SUFFIX 163 #undef ADDURL_COMMON_SUFFIX
172 164
173 sql::Statement statement(GetDB().GetCachedStatement( 165 sql::Statement statement(GetDB().GetCachedStatement(
174 sql::StatementID(statement_name), statement_sql)); 166 sql::StatementID(statement_name), statement_sql));
175 if (!statement) {
176 NOTREACHED() << GetDB().GetErrorMessage();
177 return 0;
178 }
179
180 statement.BindString(0, GURLToDatabaseURL(info.url())); 167 statement.BindString(0, GURLToDatabaseURL(info.url()));
181 statement.BindString16(1, info.title()); 168 statement.BindString16(1, info.title());
182 statement.BindInt(2, info.visit_count()); 169 statement.BindInt(2, info.visit_count());
183 statement.BindInt(3, info.typed_count()); 170 statement.BindInt(3, info.typed_count());
184 statement.BindInt64(4, info.last_visit().ToInternalValue()); 171 statement.BindInt64(4, info.last_visit().ToInternalValue());
185 statement.BindInt(5, info.hidden() ? 1 : 0); 172 statement.BindInt(5, info.hidden() ? 1 : 0);
186 173
187 if (!statement.Run()) { 174 if (!statement.Run()) {
188 VLOG(0) << "Failed to add url " << info.url().possibly_invalid_spec() 175 VLOG(0) << "Failed to add url " << info.url().possibly_invalid_spec()
189 << " to table history.urls."; 176 << " to table history.urls.";
190 return 0; 177 return 0;
191 } 178 }
192 return GetDB().GetLastInsertRowId(); 179 return GetDB().GetLastInsertRowId();
193 } 180 }
194 181
195 bool URLDatabase::DeleteURLRow(URLID id) { 182 bool URLDatabase::DeleteURLRow(URLID id) {
196 sql::Statement statement(GetDB().GetCachedStatement(SQL_FROM_HERE, 183 sql::Statement statement(GetDB().GetCachedStatement(SQL_FROM_HERE,
197 "DELETE FROM urls WHERE id = ?")); 184 "DELETE FROM urls WHERE id = ?"));
198 if (!statement) 185 statement.BindInt64(0, id);
199 return false;
200 186
201 statement.BindInt64(0, id);
202 if (!statement.Run()) 187 if (!statement.Run())
203 return false; 188 return false;
204 189
205 // And delete any keyword visits. 190 // And delete any keyword visits.
206 if (!has_keyword_search_terms_) 191 if (!has_keyword_search_terms_)
207 return true; 192 return true;
208 193
209 sql::Statement del_keyword_visit(GetDB().GetCachedStatement(SQL_FROM_HERE, 194 sql::Statement del_keyword_visit(GetDB().GetCachedStatement(SQL_FROM_HERE,
210 "DELETE FROM keyword_search_terms WHERE url_id=?")); 195 "DELETE FROM keyword_search_terms WHERE url_id=?"));
211 if (!del_keyword_visit)
212 return false;
213 del_keyword_visit.BindInt64(0, id); 196 del_keyword_visit.BindInt64(0, id);
197
214 return del_keyword_visit.Run(); 198 return del_keyword_visit.Run();
215 } 199 }
216 200
217 bool URLDatabase::CreateTemporaryURLTable() { 201 bool URLDatabase::CreateTemporaryURLTable() {
218 return CreateURLTable(true); 202 return CreateURLTable(true);
219 } 203 }
220 204
221 bool URLDatabase::CommitTemporaryURLTable() { 205 bool URLDatabase::CommitTemporaryURLTable() {
222 // See the comments in the header file as well as 206 // See the comments in the header file as well as
223 // HistoryBackend::DeleteAllHistory() for more information on how this works 207 // HistoryBackend::DeleteAllHistory() for more information on how this works
(...skipping 20 matching lines...) Expand all
244 228
245 return true; 229 return true;
246 } 230 }
247 231
248 bool URLDatabase::InitURLEnumeratorForEverything(URLEnumerator* enumerator) { 232 bool URLDatabase::InitURLEnumeratorForEverything(URLEnumerator* enumerator) {
249 DCHECK(!enumerator->initialized_); 233 DCHECK(!enumerator->initialized_);
250 std::string sql("SELECT "); 234 std::string sql("SELECT ");
251 sql.append(kURLRowFields); 235 sql.append(kURLRowFields);
252 sql.append(" FROM urls"); 236 sql.append(" FROM urls");
253 enumerator->statement_.Assign(GetDB().GetUniqueStatement(sql.c_str())); 237 enumerator->statement_.Assign(GetDB().GetUniqueStatement(sql.c_str()));
254 if (!enumerator->statement_) {
255 NOTREACHED() << GetDB().GetErrorMessage();
256 return false;
257 }
Scott Hess - ex-Googler 2012/01/03 23:41:57 I'm not entirely convinced that removing these is
Greg Billock 2012/01/04 19:20:20 OK. Is the above build-up of a query manually kosh
Scott Hess - ex-Googler 2012/01/10 22:04:56 In general I hate dynamically-generated queries, p
258 enumerator->initialized_ = true; 238 enumerator->initialized_ = true;
259 return true; 239 return true;
260 } 240 }
261 241
262 bool URLDatabase::InitURLEnumeratorForSignificant(URLEnumerator* enumerator) { 242 bool URLDatabase::InitURLEnumeratorForSignificant(URLEnumerator* enumerator) {
263 DCHECK(!enumerator->initialized_); 243 DCHECK(!enumerator->initialized_);
264 std::string sql("SELECT "); 244 std::string sql("SELECT ");
265 sql.append(kURLRowFields); 245 sql.append(kURLRowFields);
266 sql.append(" FROM urls WHERE last_visit_time >= ? OR visit_count >= ? OR " 246 sql.append(" FROM urls WHERE last_visit_time >= ? OR visit_count >= ? OR "
267 "typed_count >= ?"); 247 "typed_count >= ?");
268 enumerator->statement_.Assign(GetDB().GetUniqueStatement(sql.c_str())); 248 enumerator->statement_.Assign(GetDB().GetUniqueStatement(sql.c_str()));
269 if (!enumerator->statement_) {
270 NOTREACHED() << GetDB().GetErrorMessage();
271 return false;
272 }
273 enumerator->statement_.BindInt64( 249 enumerator->statement_.BindInt64(
274 0, AutocompleteAgeThreshold().ToInternalValue()); 250 0, AutocompleteAgeThreshold().ToInternalValue());
275 enumerator->statement_.BindInt(1, kLowQualityMatchVisitLimit); 251 enumerator->statement_.BindInt(1, kLowQualityMatchVisitLimit);
276 enumerator->statement_.BindInt(2, kLowQualityMatchTypedLimit); 252 enumerator->statement_.BindInt(2, kLowQualityMatchTypedLimit);
277 enumerator->initialized_ = true; 253 enumerator->initialized_ = true;
278 return true; 254 return true;
279 } 255 }
280 256
281 bool URLDatabase::InitIconMappingEnumeratorForEverything( 257 bool URLDatabase::InitIconMappingEnumeratorForEverything(
282 IconMappingEnumerator* enumerator) { 258 IconMappingEnumerator* enumerator) {
283 DCHECK(!enumerator->initialized_); 259 DCHECK(!enumerator->initialized_);
284 enumerator->statement_.Assign(GetDB().GetUniqueStatement( 260 enumerator->statement_.Assign(GetDB().GetUniqueStatement(
285 "SELECT url, favicon_id FROM urls WHERE favicon_id <> 0")); 261 "SELECT url, favicon_id FROM urls WHERE favicon_id <> 0"));
286 if (!enumerator->statement_) {
287 NOTREACHED() << GetDB().GetErrorMessage();
288 return false;
289 }
290 enumerator->initialized_ = true; 262 enumerator->initialized_ = true;
291 return true; 263 return true;
292 } 264 }
293 265
294 bool URLDatabase::AutocompleteForPrefix(const std::string& prefix, 266 bool URLDatabase::AutocompleteForPrefix(const std::string& prefix,
295 size_t max_results, 267 size_t max_results,
296 bool typed_only, 268 bool typed_only,
297 std::vector<history::URLRow>* results) { 269 std::vector<history::URLRow>* results) {
298 // NOTE: this query originally sorted by starred as the second parameter. But 270 // NOTE: this query originally sorted by starred as the second parameter. But
299 // as bookmarks is no longer part of the db we no longer include the order 271 // as bookmarks is no longer part of the db we no longer include the order
300 // by clause. 272 // by clause.
301 results->clear(); 273 results->clear();
302 const char* sql; 274 const char* sql;
303 int line; 275 int line;
304 if (typed_only) { 276 if (typed_only) {
305 sql = "SELECT" HISTORY_URL_ROW_FIELDS "FROM urls " 277 sql = "SELECT" HISTORY_URL_ROW_FIELDS "FROM urls "
306 "WHERE url >= ? AND url < ? AND hidden = 0 AND typed_count > 0 " 278 "WHERE url >= ? AND url < ? AND hidden = 0 AND typed_count > 0 "
307 "ORDER BY typed_count DESC, visit_count DESC, last_visit_time DESC " 279 "ORDER BY typed_count DESC, visit_count DESC, last_visit_time DESC "
308 "LIMIT ?"; 280 "LIMIT ?";
309 line = __LINE__; 281 line = __LINE__;
310 } else { 282 } else {
311 sql = "SELECT" HISTORY_URL_ROW_FIELDS "FROM urls " 283 sql = "SELECT" HISTORY_URL_ROW_FIELDS "FROM urls "
312 "WHERE url >= ? AND url < ? AND hidden = 0 " 284 "WHERE url >= ? AND url < ? AND hidden = 0 "
313 "ORDER BY typed_count DESC, visit_count DESC, last_visit_time DESC " 285 "ORDER BY typed_count DESC, visit_count DESC, last_visit_time DESC "
314 "LIMIT ?"; 286 "LIMIT ?";
315 line = __LINE__; 287 line = __LINE__;
316 } 288 }
317 sql::Statement statement( 289 sql::Statement statement(
318 GetDB().GetCachedStatement(sql::StatementID(__FILE__, line), sql)); 290 GetDB().GetCachedStatement(sql::StatementID(__FILE__, line), sql));
319 if (!statement)
320 return false;
321 291
322 // We will find all strings between "prefix" and this string, which is prefix 292 // We will find all strings between "prefix" and this string, which is prefix
323 // followed by the maximum character size. Use 8-bit strings for everything 293 // followed by the maximum character size. Use 8-bit strings for everything
324 // so we can be sure sqlite is comparing everything in 8-bit mode. Otherwise, 294 // so we can be sure sqlite is comparing everything in 8-bit mode. Otherwise,
325 // it will have to convert strings either to UTF-8 or UTF-16 for comparison. 295 // it will have to convert strings either to UTF-8 or UTF-16 for comparison.
326 std::string end_query(prefix); 296 std::string end_query(prefix);
327 end_query.push_back(std::numeric_limits<unsigned char>::max()); 297 end_query.push_back(std::numeric_limits<unsigned char>::max());
328 298
329 statement.BindString(0, prefix); 299 statement.BindString(0, prefix);
330 statement.BindString(1, end_query); 300 statement.BindString(1, end_query);
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
368 // those wouldn't use the index, and would run into problems with "wildcard" 338 // those wouldn't use the index, and would run into problems with "wildcard"
369 // characters that appear in URLs (% for LIKE, or *, ? for GLOB). 339 // characters that appear in URLs (% for LIKE, or *, ? for GLOB).
370 std::string sql("SELECT "); 340 std::string sql("SELECT ");
371 sql.append(kURLRowFields); 341 sql.append(kURLRowFields);
372 sql.append(" FROM urls WHERE url "); 342 sql.append(" FROM urls WHERE url ");
373 sql.append(allow_base ? ">=" : ">"); 343 sql.append(allow_base ? ">=" : ">");
374 sql.append(" ? AND url < :end AND url = substr(:end, 1, length(url)) " 344 sql.append(" ? AND url < :end AND url = substr(:end, 1, length(url)) "
375 "AND hidden = 0 AND visit_count >= ? AND typed_count >= ? " 345 "AND hidden = 0 AND visit_count >= ? AND typed_count >= ? "
376 "ORDER BY url LIMIT 1"); 346 "ORDER BY url LIMIT 1");
377 sql::Statement statement(GetDB().GetUniqueStatement(sql.c_str())); 347 sql::Statement statement(GetDB().GetUniqueStatement(sql.c_str()));
378 if (!statement) {
379 NOTREACHED() << GetDB().GetErrorMessage();
380 return false;
381 }
382
383 statement.BindString(0, base); 348 statement.BindString(0, base);
384 statement.BindString(1, url); // :end 349 statement.BindString(1, url); // :end
385 statement.BindInt(2, min_visits); 350 statement.BindInt(2, min_visits);
386 statement.BindInt(3, min_typed); 351 statement.BindInt(3, min_typed);
387 352
388 if (!statement.Step()) 353 if (!statement.Step())
389 return false; 354 return false;
390 355
391 DCHECK(info); 356 DCHECK(info);
392 FillURLRow(statement, info); 357 FillURLRow(statement, info);
(...skipping 20 matching lines...) Expand all
413 "keyword_search_terms (keyword_id, lower_term)")) { 378 "keyword_search_terms (keyword_id, lower_term)")) {
414 return false; 379 return false;
415 } 380 }
416 381
417 // For deletion. 382 // For deletion.
418 if (!GetDB().Execute( 383 if (!GetDB().Execute(
419 "CREATE INDEX IF NOT EXISTS keyword_search_terms_index2 ON " 384 "CREATE INDEX IF NOT EXISTS keyword_search_terms_index2 ON "
420 "keyword_search_terms (url_id)")) { 385 "keyword_search_terms (url_id)")) {
421 return false; 386 return false;
422 } 387 }
388
423 return true; 389 return true;
424 } 390 }
425 391
426 bool URLDatabase::DropKeywordSearchTermsTable() { 392 bool URLDatabase::DropKeywordSearchTermsTable() {
427 // This will implicitly delete the indices over the table. 393 // This will implicitly delete the indices over the table.
428 return GetDB().Execute("DROP TABLE keyword_search_terms"); 394 return GetDB().Execute("DROP TABLE keyword_search_terms");
429 } 395 }
430 396
431 bool URLDatabase::SetKeywordSearchTermsForURL(URLID url_id, 397 bool URLDatabase::SetKeywordSearchTermsForURL(URLID url_id,
432 TemplateURLID keyword_id, 398 TemplateURLID keyword_id,
433 const string16& term) { 399 const string16& term) {
434 DCHECK(url_id && keyword_id && !term.empty()); 400 DCHECK(url_id && keyword_id && !term.empty());
435 401
436 sql::Statement exist_statement(GetDB().GetCachedStatement(SQL_FROM_HERE, 402 sql::Statement exist_statement(GetDB().GetCachedStatement(SQL_FROM_HERE,
437 "SELECT term FROM keyword_search_terms " 403 "SELECT term FROM keyword_search_terms "
438 "WHERE keyword_id = ? AND url_id = ?")); 404 "WHERE keyword_id = ? AND url_id = ?"));
439 if (!exist_statement)
440 return false;
441 exist_statement.BindInt64(0, keyword_id); 405 exist_statement.BindInt64(0, keyword_id);
442 exist_statement.BindInt64(1, url_id); 406 exist_statement.BindInt64(1, url_id);
407
443 if (exist_statement.Step()) 408 if (exist_statement.Step())
444 return true; // Term already exists, no need to add it. 409 return true; // Term already exists, no need to add it.
445 410
446 sql::Statement statement(GetDB().GetCachedStatement(SQL_FROM_HERE, 411 sql::Statement statement(GetDB().GetCachedStatement(SQL_FROM_HERE,
447 "INSERT INTO keyword_search_terms (keyword_id, url_id, lower_term, term) " 412 "INSERT INTO keyword_search_terms (keyword_id, url_id, lower_term, term) "
448 "VALUES (?,?,?,?)")); 413 "VALUES (?,?,?,?)"));
449 if (!statement)
450 return false;
451
452 statement.BindInt64(0, keyword_id); 414 statement.BindInt64(0, keyword_id);
453 statement.BindInt64(1, url_id); 415 statement.BindInt64(1, url_id);
454 statement.BindString16(2, base::i18n::ToLower(term)); 416 statement.BindString16(2, base::i18n::ToLower(term));
455 statement.BindString16(3, term); 417 statement.BindString16(3, term);
456 return statement.Run(); 418 return statement.Run();
457 } 419 }
458 420
459 bool URLDatabase::GetKeywordSearchTermRow(URLID url_id, 421 bool URLDatabase::GetKeywordSearchTermRow(URLID url_id,
460 KeywordSearchTermRow* row) { 422 KeywordSearchTermRow* row) {
461 DCHECK(url_id); 423 DCHECK(url_id);
462 sql::Statement statement(GetDB().GetCachedStatement(SQL_FROM_HERE, 424 sql::Statement statement(GetDB().GetCachedStatement(SQL_FROM_HERE,
463 "SELECT keyword_id, term FROM keyword_search_terms WHERE url_id=?")); 425 "SELECT keyword_id, term FROM keyword_search_terms WHERE url_id=?"));
464 if (!statement) 426 statement.BindInt64(0, url_id);
465 return false;
466 427
467 statement.BindInt64(0, url_id);
468 if (!statement.Step()) 428 if (!statement.Step())
469 return false; 429 return false;
470 430
471 if (row) { 431 if (row) {
472 row->url_id = url_id; 432 row->url_id = url_id;
473 row->keyword_id = statement.ColumnInt64(0); 433 row->keyword_id = statement.ColumnInt64(0);
474 row->term = statement.ColumnString16(1); 434 row->term = statement.ColumnString16(1);
475 } 435 }
476 return true; 436 return true;
477 } 437 }
478 438
479 void URLDatabase::DeleteAllSearchTermsForKeyword( 439 void URLDatabase::DeleteAllSearchTermsForKeyword(
480 TemplateURLID keyword_id) { 440 TemplateURLID keyword_id) {
481 DCHECK(keyword_id); 441 DCHECK(keyword_id);
482 sql::Statement statement(GetDB().GetCachedStatement(SQL_FROM_HERE, 442 sql::Statement statement(GetDB().GetCachedStatement(SQL_FROM_HERE,
483 "DELETE FROM keyword_search_terms WHERE keyword_id=?")); 443 "DELETE FROM keyword_search_terms WHERE keyword_id=?"));
484 if (!statement) 444 statement.BindInt64(0, keyword_id);
485 return;
486 445
487 statement.BindInt64(0, keyword_id);
488 statement.Run(); 446 statement.Run();
489 } 447 }
490 448
491 void URLDatabase::GetMostRecentKeywordSearchTerms( 449 void URLDatabase::GetMostRecentKeywordSearchTerms(
492 TemplateURLID keyword_id, 450 TemplateURLID keyword_id,
493 const string16& prefix, 451 const string16& prefix,
494 int max_count, 452 int max_count,
495 std::vector<KeywordSearchTermVisit>* matches) { 453 std::vector<KeywordSearchTermVisit>* matches) {
496 // NOTE: the keyword_id can be zero if on first run the user does a query 454 // NOTE: the keyword_id can be zero if on first run the user does a query
497 // before the TemplateURLService has finished loading. As the chances of this 455 // before the TemplateURLService has finished loading. As the chances of this
498 // occurring are small, we ignore it. 456 // occurring are small, we ignore it.
499 if (!keyword_id) 457 if (!keyword_id)
500 return; 458 return;
501 459
502 DCHECK(!prefix.empty()); 460 DCHECK(!prefix.empty());
503 sql::Statement statement(GetDB().GetCachedStatement(SQL_FROM_HERE, 461 sql::Statement statement(GetDB().GetCachedStatement(SQL_FROM_HERE,
504 "SELECT DISTINCT kv.term, u.visit_count, u.last_visit_time " 462 "SELECT DISTINCT kv.term, u.visit_count, u.last_visit_time "
505 "FROM keyword_search_terms kv " 463 "FROM keyword_search_terms kv "
506 "JOIN urls u ON kv.url_id = u.id " 464 "JOIN urls u ON kv.url_id = u.id "
507 "WHERE kv.keyword_id = ? AND kv.lower_term >= ? AND kv.lower_term < ? " 465 "WHERE kv.keyword_id = ? AND kv.lower_term >= ? AND kv.lower_term < ? "
508 "ORDER BY u.last_visit_time DESC LIMIT ?")); 466 "ORDER BY u.last_visit_time DESC LIMIT ?"));
509 if (!statement)
510 return;
511 467
512 // NOTE: Keep this ToLower() call in sync with search_provider.cc. 468 // NOTE: Keep this ToLower() call in sync with search_provider.cc.
513 string16 lower_prefix = base::i18n::ToLower(prefix); 469 string16 lower_prefix = base::i18n::ToLower(prefix);
514 // This magic gives us a prefix search. 470 // This magic gives us a prefix search.
515 string16 next_prefix = lower_prefix; 471 string16 next_prefix = lower_prefix;
516 next_prefix[next_prefix.size() - 1] = 472 next_prefix[next_prefix.size() - 1] =
517 next_prefix[next_prefix.size() - 1] + 1; 473 next_prefix[next_prefix.size() - 1] + 1;
518 statement.BindInt64(0, keyword_id); 474 statement.BindInt64(0, keyword_id);
519 statement.BindString16(1, lower_prefix); 475 statement.BindString16(1, lower_prefix);
520 statement.BindString16(2, next_prefix); 476 statement.BindString16(2, next_prefix);
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
576 return GetDB().Execute(sql.c_str()); 532 return GetDB().Execute(sql.c_str());
577 } 533 }
578 534
579 bool URLDatabase::CreateMainURLIndex() { 535 bool URLDatabase::CreateMainURLIndex() {
580 // Index over URLs so we can quickly look up based on URL. 536 // Index over URLs so we can quickly look up based on URL.
581 return GetDB().Execute( 537 return GetDB().Execute(
582 "CREATE INDEX IF NOT EXISTS urls_url_index ON urls (url)"); 538 "CREATE INDEX IF NOT EXISTS urls_url_index ON urls (url)");
583 } 539 }
584 540
585 } // namespace history 541 } // namespace history
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698