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

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

Issue 9585020: Cull autofill entries older than 60 days. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Addressed comments Created 8 years, 9 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/autofill_table.h" 5 #include "chrome/browser/webdata/autofill_table.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 #include <limits> 8 #include <limits>
9 #include <map> 9 #include <map>
10 #include <set> 10 #include <set>
11 #include <string> 11 #include <string>
12 #include <vector> 12 #include <vector>
13 13
14 #include "base/i18n/case_conversion.h" 14 #include "base/i18n/case_conversion.h"
15 #include "base/logging.h" 15 #include "base/logging.h"
16 #include "base/string_number_conversions.h" 16 #include "base/string_number_conversions.h"
17 #include "base/time.h" 17 #include "base/time.h"
18 #include "base/tuple.h" 18 #include "base/tuple.h"
19 #include "chrome/browser/autofill/autofill_country.h" 19 #include "chrome/browser/autofill/autofill_country.h"
20 #include "chrome/browser/autofill/autofill_profile.h" 20 #include "chrome/browser/autofill/autofill_profile.h"
21 #include "chrome/browser/autofill/autofill_type.h" 21 #include "chrome/browser/autofill/autofill_type.h"
22 #include "chrome/browser/autofill/credit_card.h" 22 #include "chrome/browser/autofill/credit_card.h"
23 #include "chrome/browser/autofill/personal_data_manager.h" 23 #include "chrome/browser/autofill/personal_data_manager.h"
24 #include "chrome/browser/password_manager/encryptor.h" 24 #include "chrome/browser/password_manager/encryptor.h"
25 #include "chrome/browser/webdata/autofill_change.h" 25 #include "chrome/browser/webdata/autofill_change.h"
26 #include "chrome/browser/webdata/autofill_entry.h"
26 #include "chrome/common/guid.h" 27 #include "chrome/common/guid.h"
27 #include "sql/statement.h" 28 #include "sql/statement.h"
28 #include "ui/base/l10n/l10n_util.h" 29 #include "ui/base/l10n/l10n_util.h"
29 #include "webkit/forms/form_field.h" 30 #include "webkit/forms/form_field.h"
30 31
31 using base::Time; 32 using base::Time;
32 using webkit::forms::FormField; 33 using webkit::forms::FormField;
33 34
34 namespace { 35 namespace {
35 36
(...skipping 375 matching lines...) Expand 10 before | Expand all | Expand 10 after
411 AutofillElementList elements; 412 AutofillElementList elements;
412 while (s.Step()) { 413 while (s.Step()) {
413 elements.push_back(MakeTuple(s.ColumnInt64(0), 414 elements.push_back(MakeTuple(s.ColumnInt64(0),
414 s.ColumnString16(1), 415 s.ColumnString16(1),
415 s.ColumnString16(2))); 416 s.ColumnString16(2)));
416 } 417 }
417 if (!s.Succeeded()) 418 if (!s.Succeeded())
418 return false; 419 return false;
419 420
420 for (AutofillElementList::iterator itr = elements.begin(); 421 for (AutofillElementList::iterator itr = elements.begin();
421 itr != elements.end(); itr++) { 422 itr != elements.end(); ++itr) {
422 int how_many = 0; 423 int how_many = 0;
423 if (!RemoveFormElementForTimeRange(itr->a, delete_begin, delete_end, 424 if (!RemoveFormElementForTimeRange(itr->a, delete_begin, delete_end,
424 &how_many)) { 425 &how_many)) {
425 return false; 426 return false;
426 } 427 }
427 bool was_removed = false; 428 bool was_removed = false;
428 if (!AddToCountOfFormElement(itr->a, -how_many, &was_removed)) 429 // We store at most 2 time stamps. If we remove both of them we should
429 return false; 430 // delete the corresponding data. if we delete only one it could still be
431 // the last timestamp for the data.
432 if (how_many == 2 || (how_many == 1 && CountTimestampsData(itr->a) == 0)) {
433 was_removed = true;
434 if (!RemoveFormElementForID(itr->a))
435 return false;
436 } else {
437 if (!AddToCountOfFormElement(itr->a, -how_many, &was_removed))
Ilya Sherman 2012/03/21 21:20:53 As we discussed offline, I don't think we want to
GeorgeY 2012/03/21 22:10:56 Done.
438 return false;
439 }
430 AutofillChange::Type change_type = 440 AutofillChange::Type change_type =
431 was_removed ? AutofillChange::REMOVE : AutofillChange::UPDATE; 441 was_removed ? AutofillChange::REMOVE : AutofillChange::UPDATE;
432 changes->push_back(AutofillChange(change_type, 442 changes->push_back(AutofillChange(change_type,
433 AutofillKey(itr->b, itr->c))); 443 AutofillKey(itr->b, itr->c)));
434 } 444 }
435 445
436 return true; 446 return true;
437 } 447 }
438 448
449 bool AutofillTable::RemoveExpiredFormElements(
450 std::vector<AutofillChange>* changes) {
451 DCHECK(changes);
452
453 base::Time delete_end = AutofillEntry::ExpirationTime();
454 // Query for the pair_id, name, and value of all form elements that
455 // were last used before the |delete_end|.
456 sql::Statement select_for_delete(db_->GetUniqueStatement(
457 "SELECT DISTINCT pair_id, name, value "
458 "FROM autofill WHERE pair_id NOT IN "
459 "(SELECT DISTINCT pair_id "
460 "FROM autofill_dates WHERE date_created >= ?)"));
461 select_for_delete.BindInt64(0, delete_end.ToTimeT());
462 AutofillElementList entries_to_delete;
463 while (select_for_delete.Step()) {
464 entries_to_delete.push_back(MakeTuple(select_for_delete.ColumnInt64(0),
465 select_for_delete.ColumnString16(1),
466 select_for_delete.ColumnString16(2)));
467 }
468
469 if (!select_for_delete.Succeeded())
470 return false;
471
472 sql::Statement delete_data_statement(db_->GetUniqueStatement(
473 "DELETE FROM autofill WHERE pair_id NOT IN ("
474 "SELECT pair_id FROM autofill_dates WHERE date_created >= ?)"));
475 delete_data_statement.BindInt64(0, delete_end.ToTimeT());
476 if (!delete_data_statement.Run())
477 return false;
478
479 sql::Statement delete_times_statement(db_->GetUniqueStatement(
480 "DELETE FROM autofill_dates WHERE pair_id NOT IN ("
481 "SELECT pair_id FROM autofill_dates WHERE date_created >= ?)"));
482 delete_times_statement.BindInt64(0, delete_end.ToTimeT());
483 if (!delete_times_statement.Run())
484 return false;
485
486 // Cull remaining entries' timestamps.
487 std::vector<AutofillEntry> entries;
488 if (!GetAllAutofillEntries(&entries))
489 return false;
490 sql::Statement cull_date_entry(db_->GetUniqueStatement(
491 "DELETE FROM autofill_dates "
492 "WHERE pair_id == (SELECT pair_id FROM autofill "
493 "WHERE name = ? and value = ?)"
494 "AND date_created != ? AND date_created != ?"));
495 for (size_t i = 0; i < entries.size(); ++i) {
496 cull_date_entry.BindString16(0, entries[i].key().name());
497 cull_date_entry.BindString16(1, entries[i].key().value());
498 cull_date_entry.BindInt64(2,
499 entries[i].timestamps().empty() ? 0 :
500 entries[i].timestamps().front().ToTimeT());
501 cull_date_entry.BindInt64(3,
502 entries[i].timestamps().empty() ? 0 :
503 entries[i].timestamps().back().ToTimeT());
504 if (!cull_date_entry.Run())
505 return false;
506 cull_date_entry.Reset();
507 }
508
509 changes->clear();
510 changes->reserve(entries_to_delete.size());
511
512 for (AutofillElementList::iterator it = entries_to_delete.begin();
513 it != entries_to_delete.end(); ++it) {
514 changes->push_back(AutofillChange(
515 AutofillChange::REMOVE, AutofillKey(it->b, it->c)));
516 }
517 return true;
518 }
519
439 bool AutofillTable::RemoveFormElementForTimeRange(int64 pair_id, 520 bool AutofillTable::RemoveFormElementForTimeRange(int64 pair_id,
440 const Time& delete_begin, 521 const Time& delete_begin,
441 const Time& delete_end, 522 const Time& delete_end,
442 int* how_many) { 523 int* how_many) {
443 sql::Statement s(db_->GetUniqueStatement( 524 sql::Statement s(db_->GetUniqueStatement(
444 "DELETE FROM autofill_dates WHERE pair_id = ? AND " 525 "DELETE FROM autofill_dates WHERE pair_id = ? AND "
445 "date_created >= ? AND date_created < ?")); 526 "date_created >= ? AND date_created < ?"));
446 s.BindInt64(0, pair_id); 527 s.BindInt64(0, pair_id);
447 s.BindInt64(1, delete_begin.is_null() ? 0 : delete_begin.ToTimeT()); 528 s.BindInt64(1, delete_begin.is_null() ? 0 : delete_begin.ToTimeT());
448 s.BindInt64(2, delete_end.is_null() ? std::numeric_limits<int64>::max() : 529 s.BindInt64(2, delete_end.is_null() ? std::numeric_limits<int64>::max() :
449 delete_end.ToTimeT()); 530 delete_end.ToTimeT());
450 531
451 bool result = s.Run(); 532 bool result = s.Run();
452 if (how_many) 533 if (how_many)
453 *how_many = db_->GetLastChangeCount(); 534 *how_many = db_->GetLastChangeCount();
454 535
455 return result; 536 return result;
456 } 537 }
457 538
539 int AutofillTable::CountTimestampsData(int64 pair_id) {
540 sql::Statement s(db_->GetUniqueStatement(
541 "SELECT COUNT(*) FROM autofill_dates WHERE pair_id = ?"));
542 s.BindInt64(0, pair_id);
543 if (!s.Step()) {
544 NOTREACHED();
545 return 0;
546 } else {
547 return s.ColumnInt(0);
548 }
549 }
550
458 bool AutofillTable::AddToCountOfFormElement(int64 pair_id, 551 bool AutofillTable::AddToCountOfFormElement(int64 pair_id,
459 int delta, 552 int delta,
460 bool* was_removed) { 553 bool* was_removed) {
461 DCHECK(was_removed); 554 DCHECK(was_removed);
462 int count = 0; 555 int count = 0;
463 *was_removed = false; 556 *was_removed = false;
464 557
465 if (!GetCountOfFormElement(pair_id, &count)) 558 if (!GetCountOfFormElement(pair_id, &count))
466 return false; 559 return false;
467 560
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after
545 const Time& date_created) { 638 const Time& date_created) {
546 sql::Statement s(db_->GetUniqueStatement( 639 sql::Statement s(db_->GetUniqueStatement(
547 "INSERT INTO autofill_dates " 640 "INSERT INTO autofill_dates "
548 "(pair_id, date_created) VALUES (?, ?)")); 641 "(pair_id, date_created) VALUES (?, ?)"));
549 s.BindInt64(0, pair_id); 642 s.BindInt64(0, pair_id);
550 s.BindInt64(1, date_created.ToTimeT()); 643 s.BindInt64(1, date_created.ToTimeT());
551 644
552 return s.Run(); 645 return s.Run();
553 } 646 }
554 647
648 bool AutofillTable::DeleteLastAccess(int64 pair_id) {
649 // Inner SELECT selects the newest |date_created| for a given |pair_id|.
650 // DELETE deletes only that entry.
651 sql::Statement s(db_->GetUniqueStatement(
652 "DELETE FROM autofill_dates WHERE pair_id = ? and date_created IN "
653 "(SELECT date_created FROM autofill_dates WHERE pair_id = ? "
654 "ORDER BY date_created DESC LIMIT 1)"));
655 s.BindInt64(0, pair_id);
656 s.BindInt64(1, pair_id);
657
658 return s.Run();
659 }
660
555 bool AutofillTable::AddFormFieldValuesTime( 661 bool AutofillTable::AddFormFieldValuesTime(
556 const std::vector<FormField>& elements, 662 const std::vector<FormField>& elements,
557 std::vector<AutofillChange>* changes, 663 std::vector<AutofillChange>* changes,
558 Time time) { 664 Time time) {
559 // Only add one new entry for each unique element name. Use |seen_names| to 665 // Only add one new entry for each unique element name. Use |seen_names| to
560 // track this. Add up to |kMaximumUniqueNames| unique entries per form. 666 // track this. Add up to |kMaximumUniqueNames| unique entries per form.
561 const size_t kMaximumUniqueNames = 256; 667 const size_t kMaximumUniqueNames = 256;
562 std::set<string16> seen_names; 668 std::set<string16> seen_names;
563 bool result = true; 669 bool result = true;
564 for (std::vector<FormField>::const_iterator 670 for (std::vector<FormField>::const_iterator itr = elements.begin();
565 itr = elements.begin(); 671 itr != elements.end(); ++itr) {
566 itr != elements.end();
567 itr++) {
568 if (seen_names.size() >= kMaximumUniqueNames) 672 if (seen_names.size() >= kMaximumUniqueNames)
569 break; 673 break;
570 if (seen_names.find(itr->name) != seen_names.end()) 674 if (seen_names.find(itr->name) != seen_names.end())
571 continue; 675 continue;
572 result = result && AddFormFieldValueTime(*itr, changes, time); 676 result = result && AddFormFieldValueTime(*itr, changes, time);
573 seen_names.insert(itr->name); 677 seen_names.insert(itr->name);
574 } 678 }
575 return result; 679 return result;
576 } 680 }
577 681
(...skipping 148 matching lines...) Expand 10 before | Expand all | Expand 10 after
726 830
727 if (!GetIDAndCountOfFormElement(element, &pair_id, &count)) 831 if (!GetIDAndCountOfFormElement(element, &pair_id, &count))
728 return false; 832 return false;
729 833
730 if (count == 0 && !InsertFormElement(element, &pair_id)) 834 if (count == 0 && !InsertFormElement(element, &pair_id))
731 return false; 835 return false;
732 836
733 if (!SetCountOfFormElement(pair_id, count + 1)) 837 if (!SetCountOfFormElement(pair_id, count + 1))
734 return false; 838 return false;
735 839
840 // If we already have more than 2 times delete last one, before adding new
841 // one.
842 if (count >= 2 && !DeleteLastAccess(pair_id))
843 return false;
844
736 if (!InsertPairIDAndDate(pair_id, time)) 845 if (!InsertPairIDAndDate(pair_id, time))
737 return false; 846 return false;
738 847
739 AutofillChange::Type change_type = 848 AutofillChange::Type change_type =
740 count == 0 ? AutofillChange::ADD : AutofillChange::UPDATE; 849 count == 0 ? AutofillChange::ADD : AutofillChange::UPDATE;
741 changes->push_back( 850 changes->push_back(
742 AutofillChange(change_type, 851 AutofillChange(change_type,
743 AutofillKey(element.name, element.value))); 852 AutofillKey(element.name, element.value)));
744 return true; 853 return true;
745 } 854 }
(...skipping 1127 matching lines...) Expand 10 before | Expand all | Expand 10 after
1873 "WHERE guid=?")); 1982 "WHERE guid=?"));
1874 s_date.BindInt64(0, date_item->second); 1983 s_date.BindInt64(0, date_item->second);
1875 s_date.BindString(1, iter->guid()); 1984 s_date.BindString(1, iter->guid());
1876 1985
1877 if (!s_date.Run()) 1986 if (!s_date.Run())
1878 return false; 1987 return false;
1879 } 1988 }
1880 1989
1881 return true; 1990 return true;
1882 } 1991 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698