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

Side by Side Diff: components/autofill/core/browser/webdata/autofill_table.cc

Issue 962673004: [Autofill/Autocomplete Feature] Substring matching instead of prefix matching. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 5 years, 5 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
OLDNEW
1 // Copyright 2013 The Chromium Authors. All rights reserved. 1 // Copyright 2013 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 "components/autofill/core/browser/webdata/autofill_table.h" 5 #include "components/autofill/core/browser/webdata/autofill_table.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 #include <cmath> 8 #include <cmath>
9 #include <limits> 9 #include <limits>
10 #include <map> 10 #include <map>
11 #include <set> 11 #include <set>
12 #include <string> 12 #include <string>
13 #include <vector> 13 #include <vector>
14 14
15 #include "base/command_line.h" 15 #include "base/command_line.h"
16 #include "base/guid.h" 16 #include "base/guid.h"
17 #include "base/i18n/case_conversion.h" 17 #include "base/i18n/case_conversion.h"
18 #include "base/logging.h" 18 #include "base/logging.h"
19 #include "base/numerics/safe_conversions.h" 19 #include "base/numerics/safe_conversions.h"
20 #include "base/strings/string_number_conversions.h" 20 #include "base/strings/string_number_conversions.h"
21 #include "base/strings/string_util.h"
21 #include "base/strings/utf_string_conversions.h" 22 #include "base/strings/utf_string_conversions.h"
22 #include "base/time/time.h" 23 #include "base/time/time.h"
23 #include "components/autofill/core/browser/autofill_country.h" 24 #include "components/autofill/core/browser/autofill_country.h"
24 #include "components/autofill/core/browser/autofill_profile.h" 25 #include "components/autofill/core/browser/autofill_profile.h"
25 #include "components/autofill/core/browser/autofill_type.h" 26 #include "components/autofill/core/browser/autofill_type.h"
26 #include "components/autofill/core/browser/credit_card.h" 27 #include "components/autofill/core/browser/credit_card.h"
27 #include "components/autofill/core/browser/personal_data_manager.h" 28 #include "components/autofill/core/browser/personal_data_manager.h"
28 #include "components/autofill/core/browser/webdata/autofill_change.h" 29 #include "components/autofill/core/browser/webdata/autofill_change.h"
29 #include "components/autofill/core/browser/webdata/autofill_entry.h" 30 #include "components/autofill/core/browser/webdata/autofill_entry.h"
30 #include "components/autofill/core/common/autofill_switches.h" 31 #include "components/autofill/core/common/autofill_switches.h"
32 #include "components/autofill/core/common/autofill_util.h"
31 #include "components/autofill/core/common/form_field_data.h" 33 #include "components/autofill/core/common/form_field_data.h"
32 #include "components/os_crypt/os_crypt.h" 34 #include "components/os_crypt/os_crypt.h"
33 #include "components/webdata/common/web_database.h" 35 #include "components/webdata/common/web_database.h"
34 #include "sql/statement.h" 36 #include "sql/statement.h"
35 #include "sql/transaction.h" 37 #include "sql/transaction.h"
36 #include "ui/base/l10n/l10n_util.h" 38 #include "ui/base/l10n/l10n_util.h"
37 #include "url/gurl.h" 39 #include "url/gurl.h"
38 40
39 using base::ASCIIToUTF16; 41 using base::ASCIIToUTF16;
40 using base::Time; 42 using base::Time;
(...skipping 320 matching lines...) Expand 10 before | Expand all | Expand 10 after
361 } 363 }
362 364
363 CreditCard::ServerStatus ServerStatusStringToEnum(const std::string& status) { 365 CreditCard::ServerStatus ServerStatusStringToEnum(const std::string& status) {
364 if (status == "EXPIRED") 366 if (status == "EXPIRED")
365 return CreditCard::EXPIRED; 367 return CreditCard::EXPIRED;
366 368
367 DCHECK_EQ("OK", status); 369 DCHECK_EQ("OK", status);
368 return CreditCard::OK; 370 return CreditCard::OK;
369 } 371 }
370 372
373 // Returns |s| with |escaper| in front of each of occurrence of a character from
374 // |special_chars|. Any occurrence of |escaper| in |s| is doubled. For example,
375 // Substitute("hello_world!", "_%", '!'') returns "hello!_world!!".
376 base::string16 Substitute(const base::string16& s,
377 const base::string16& special_chars,
378 const base::char16& escaper) {
379 // Prepend |escaper| to the list of |special_chars|.
380 base::string16 escape_wildcards(special_chars);
381 escape_wildcards.insert(escape_wildcards.begin(), escaper);
382
383 // Prepend the |escaper| just before |special_chars| in |s|.
384 base::string16 result(s);
385 for (base::string16::const_iterator it = escape_wildcards.begin();
please use gerrit instead 2015/07/06 20:15:17 Please use a c++11 loop, like this: for (base::ch
Pritam Nikam 2015/07/07 16:18:31 Done.
386 it != escape_wildcards.end(); ++it) {
387 size_t pos = 0;
388 while ((pos = result.find(*it, pos)) != base::string16::npos) {
389 result.insert(result.begin() + pos, escaper);
390 pos += 2;
391 }
please use gerrit instead 2015/07/06 20:15:17 Lines 387-391 are a for loop in disguise. Let's us
Pritam Nikam 2015/07/07 16:18:31 Done.
392 }
393
394 return result;
395 }
396
371 } // namespace 397 } // namespace
372 398
373 // The maximum length allowed for form data. 399 // The maximum length allowed for form data.
374 const size_t AutofillTable::kMaxDataLength = 1024; 400 const size_t AutofillTable::kMaxDataLength = 1024;
375 401
376 AutofillTable::AutofillTable(const std::string& app_locale) 402 AutofillTable::AutofillTable(const std::string& app_locale)
377 : app_locale_(app_locale) { 403 : app_locale_(app_locale) {
378 } 404 }
379 405
380 AutofillTable::~AutofillTable() { 406 AutofillTable::~AutofillTable() {
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after
449 std::vector<AutofillChange>* changes) { 475 std::vector<AutofillChange>* changes) {
450 return AddFormFieldValueTime(element, changes, Time::Now()); 476 return AddFormFieldValueTime(element, changes, Time::Now());
451 } 477 }
452 478
453 bool AutofillTable::GetFormValuesForElementName( 479 bool AutofillTable::GetFormValuesForElementName(
454 const base::string16& name, 480 const base::string16& name,
455 const base::string16& prefix, 481 const base::string16& prefix,
456 std::vector<base::string16>* values, 482 std::vector<base::string16>* values,
457 int limit) { 483 int limit) {
458 DCHECK(values); 484 DCHECK(values);
459 sql::Statement s; 485 bool succeeded = false;
460 486
461 if (prefix.empty()) { 487 if (prefix.empty()) {
488 sql::Statement s;
462 s.Assign(db_->GetUniqueStatement( 489 s.Assign(db_->GetUniqueStatement(
463 "SELECT value FROM autofill " 490 "SELECT value FROM autofill "
464 "WHERE name = ? " 491 "WHERE name = ? "
465 "ORDER BY count DESC " 492 "ORDER BY count DESC "
466 "LIMIT ?")); 493 "LIMIT ?"));
467 s.BindString16(0, name); 494 s.BindString16(0, name);
468 s.BindInt(1, limit); 495 s.BindInt(1, limit);
496
497 values->clear();
498 while (s.Step())
499 values->push_back(s.ColumnString16(0));
500
501 succeeded = s.Succeeded();
469 } else { 502 } else {
470 base::string16 prefix_lower = base::i18n::ToLower(prefix); 503 base::string16 prefix_lower = base::i18n::ToLower(prefix);
471 base::string16 next_prefix = prefix_lower; 504 base::string16 next_prefix = prefix_lower;
472 next_prefix[next_prefix.length() - 1]++; 505 next_prefix[next_prefix.length() - 1]++;
473 506
474 s.Assign(db_->GetUniqueStatement( 507 sql::Statement s1;
508 s1.Assign(db_->GetUniqueStatement(
475 "SELECT value FROM autofill " 509 "SELECT value FROM autofill "
476 "WHERE name = ? AND " 510 "WHERE name = ? AND "
477 "value_lower >= ? AND " 511 "value_lower >= ? AND "
478 "value_lower < ? " 512 "value_lower < ? "
479 "ORDER BY count DESC " 513 "ORDER BY count DESC "
480 "LIMIT ?")); 514 "LIMIT ?"));
481 s.BindString16(0, name); 515 s1.BindString16(0, name);
482 s.BindString16(1, prefix_lower); 516 s1.BindString16(1, prefix_lower);
483 s.BindString16(2, next_prefix); 517 s1.BindString16(2, next_prefix);
484 s.BindInt(3, limit); 518 s1.BindInt(3, limit);
519
520 values->clear();
521 while (s1.Step())
522 values->push_back(s1.ColumnString16(0));
523
524 succeeded = s1.Succeeded();
525
526 if (IsFeatureSubstringMatchEnabled()) {
527 sql::Statement s2;
528 s2.Assign(db_->GetUniqueStatement(
529 "SELECT value FROM autofill "
530 "WHERE name = ? AND ("
531 " value LIKE '% ' || :prefix || '%' ESCAPE '!' OR "
532 " value LIKE '%.' || :prefix || '%' ESCAPE '!' OR "
533 " value LIKE '%,' || :prefix || '%' ESCAPE '!' OR "
534 " value LIKE '%-' || :prefix || '%' ESCAPE '!' OR "
535 " value LIKE '%@' || :prefix || '%' ESCAPE '!' OR "
536 " value LIKE '%!_' || :prefix || '%'ESCAPE '!' ) "
please use gerrit instead 2015/07/06 20:15:17 Please add a space between '%' and ESCAPE.
Pritam Nikam 2015/07/07 16:18:31 Done.
537 "ORDER BY count DESC "
538 "LIMIT ?"));
539
540 s2.BindString16(0, name);
541 s2.BindString16(1, Substitute(prefix_lower, ASCIIToUTF16("_%"), L'!'));
please use gerrit instead 2015/07/06 20:15:17 Please use 0x21, which is a base::char16, instead
Pritam Nikam 2015/07/07 16:18:31 Done.
542 s2.BindInt(2, limit);
543
544 // Append substring matched suggestions.
please use gerrit instead 2015/07/06 20:15:17 It's clear what's going on without this comment.
Pritam Nikam 2015/07/07 16:18:31 Done.
545 while (s2.Step())
546 values->push_back(s2.ColumnString16(0));
547
548 succeeded &= s2.Succeeded();
549 }
485 } 550 }
486 551
487 values->clear(); 552 return succeeded;
488 while (s.Step())
489 values->push_back(s.ColumnString16(0));
490 return s.Succeeded();
491 } 553 }
492 554
493 bool AutofillTable::HasFormElements() { 555 bool AutofillTable::HasFormElements() {
494 sql::Statement s(db_->GetUniqueStatement("SELECT COUNT(*) FROM autofill")); 556 sql::Statement s(db_->GetUniqueStatement("SELECT COUNT(*) FROM autofill"));
495 if (!s.Step()) { 557 if (!s.Step()) {
496 NOTREACHED(); 558 NOTREACHED();
497 return false; 559 return false;
498 } 560 }
499 return s.ColumnInt(0) > 0; 561 return s.ColumnInt(0) > 0;
500 } 562 }
(...skipping 1691 matching lines...) Expand 10 before | Expand all | Expand 10 after
2192 insert.BindString16(index++, profile.GetRawInfo(PHONE_HOME_WHOLE_NUMBER)); 2254 insert.BindString16(index++, profile.GetRawInfo(PHONE_HOME_WHOLE_NUMBER));
2193 insert.BindString(index++, profile.language_code()); 2255 insert.BindString(index++, profile.language_code());
2194 insert.Run(); 2256 insert.Run();
2195 insert.Reset(true); 2257 insert.Reset(true);
2196 } 2258 }
2197 2259
2198 return transaction.Commit(); 2260 return transaction.Commit();
2199 } 2261 }
2200 2262
2201 } // namespace autofill 2263 } // namespace autofill
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698