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

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 comment 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 // We store at most 2 time stamps. If we remove both of them we should
428 if (!AddToCountOfFormElement(itr->a, -how_many, &was_removed)) 429 // delete the corresponding data. If we delete only one it could still be
429 return false; 430 // the last timestamp for the data, so check how many timestamps do remain.
431 bool should_remove = (CountTimestampsData(itr->a) == 0);
432 if (should_remove) {
433 if (!RemoveFormElementForID(itr->a))
434 return false;
435 } else {
436 if (!AddToCountOfFormElement(itr->a, -how_many))
437 return false;
438 }
430 AutofillChange::Type change_type = 439 AutofillChange::Type change_type =
431 was_removed ? AutofillChange::REMOVE : AutofillChange::UPDATE; 440 should_remove ? AutofillChange::REMOVE : AutofillChange::UPDATE;
432 changes->push_back(AutofillChange(change_type, 441 changes->push_back(AutofillChange(change_type,
433 AutofillKey(itr->b, itr->c))); 442 AutofillKey(itr->b, itr->c)));
434 } 443 }
435 444
436 return true; 445 return true;
437 } 446 }
438 447
448 bool AutofillTable::RemoveExpiredFormElements(
449 std::vector<AutofillChange>* changes) {
450 DCHECK(changes);
451
452 base::Time delete_end = AutofillEntry::ExpirationTime();
453 // Query for the pair_id, name, and value of all form elements that
454 // were last used before the |delete_end|.
455 sql::Statement select_for_delete(db_->GetUniqueStatement(
456 "SELECT DISTINCT pair_id, name, value "
457 "FROM autofill WHERE pair_id NOT IN "
458 "(SELECT DISTINCT pair_id "
459 "FROM autofill_dates WHERE date_created >= ?)"));
460 select_for_delete.BindInt64(0, delete_end.ToTimeT());
461 AutofillElementList entries_to_delete;
462 while (select_for_delete.Step()) {
463 entries_to_delete.push_back(MakeTuple(select_for_delete.ColumnInt64(0),
464 select_for_delete.ColumnString16(1),
465 select_for_delete.ColumnString16(2)));
466 }
467
468 if (!select_for_delete.Succeeded())
469 return false;
470
471 sql::Statement delete_data_statement(db_->GetUniqueStatement(
472 "DELETE FROM autofill WHERE pair_id NOT IN ("
473 "SELECT pair_id FROM autofill_dates WHERE date_created >= ?)"));
474 delete_data_statement.BindInt64(0, delete_end.ToTimeT());
475 if (!delete_data_statement.Run())
476 return false;
477
478 sql::Statement delete_times_statement(db_->GetUniqueStatement(
479 "DELETE FROM autofill_dates WHERE pair_id NOT IN ("
480 "SELECT pair_id FROM autofill_dates WHERE date_created >= ?)"));
481 delete_times_statement.BindInt64(0, delete_end.ToTimeT());
482 if (!delete_times_statement.Run())
483 return false;
484
485 // Cull remaining entries' timestamps.
486 std::vector<AutofillEntry> entries;
487 if (!GetAllAutofillEntries(&entries))
488 return false;
489 sql::Statement cull_date_entry(db_->GetUniqueStatement(
490 "DELETE FROM autofill_dates "
491 "WHERE pair_id == (SELECT pair_id FROM autofill "
492 "WHERE name = ? and value = ?)"
493 "AND date_created != ? AND date_created != ?"));
494 for (size_t i = 0; i < entries.size(); ++i) {
495 cull_date_entry.BindString16(0, entries[i].key().name());
496 cull_date_entry.BindString16(1, entries[i].key().value());
497 cull_date_entry.BindInt64(2,
498 entries[i].timestamps().empty() ? 0 :
499 entries[i].timestamps().front().ToTimeT());
500 cull_date_entry.BindInt64(3,
501 entries[i].timestamps().empty() ? 0 :
502 entries[i].timestamps().back().ToTimeT());
503 if (!cull_date_entry.Run())
504 return false;
505 cull_date_entry.Reset();
506 }
507
508 changes->clear();
509 changes->reserve(entries_to_delete.size());
510
511 for (AutofillElementList::iterator it = entries_to_delete.begin();
512 it != entries_to_delete.end(); ++it) {
513 changes->push_back(AutofillChange(
514 AutofillChange::REMOVE, AutofillKey(it->b, it->c)));
515 }
516 return true;
517 }
518
439 bool AutofillTable::RemoveFormElementForTimeRange(int64 pair_id, 519 bool AutofillTable::RemoveFormElementForTimeRange(int64 pair_id,
440 const Time& delete_begin, 520 const Time& delete_begin,
441 const Time& delete_end, 521 const Time& delete_end,
442 int* how_many) { 522 int* how_many) {
443 sql::Statement s(db_->GetUniqueStatement( 523 sql::Statement s(db_->GetUniqueStatement(
444 "DELETE FROM autofill_dates WHERE pair_id = ? AND " 524 "DELETE FROM autofill_dates WHERE pair_id = ? AND "
445 "date_created >= ? AND date_created < ?")); 525 "date_created >= ? AND date_created < ?"));
446 s.BindInt64(0, pair_id); 526 s.BindInt64(0, pair_id);
447 s.BindInt64(1, delete_begin.is_null() ? 0 : delete_begin.ToTimeT()); 527 s.BindInt64(1, delete_begin.is_null() ? 0 : delete_begin.ToTimeT());
448 s.BindInt64(2, delete_end.is_null() ? std::numeric_limits<int64>::max() : 528 s.BindInt64(2, delete_end.is_null() ? std::numeric_limits<int64>::max() :
449 delete_end.ToTimeT()); 529 delete_end.ToTimeT());
450 530
451 bool result = s.Run(); 531 bool result = s.Run();
452 if (how_many) 532 if (how_many)
453 *how_many = db_->GetLastChangeCount(); 533 *how_many = db_->GetLastChangeCount();
454 534
455 return result; 535 return result;
456 } 536 }
457 537
538 int AutofillTable::CountTimestampsData(int64 pair_id) {
539 sql::Statement s(db_->GetUniqueStatement(
540 "SELECT COUNT(*) FROM autofill_dates WHERE pair_id = ?"));
541 s.BindInt64(0, pair_id);
542 if (!s.Step()) {
543 NOTREACHED();
544 return 0;
545 } else {
546 return s.ColumnInt(0);
547 }
548 }
549
458 bool AutofillTable::AddToCountOfFormElement(int64 pair_id, 550 bool AutofillTable::AddToCountOfFormElement(int64 pair_id,
459 int delta, 551 int delta) {
460 bool* was_removed) {
461 DCHECK(was_removed);
462 int count = 0; 552 int count = 0;
463 *was_removed = false;
464 553
465 if (!GetCountOfFormElement(pair_id, &count)) 554 if (!GetCountOfFormElement(pair_id, &count))
466 return false; 555 return false;
467 556
468 if (count + delta == 0) { 557 if (count + delta == 0) {
469 if (!RemoveFormElementForID(pair_id)) 558 // Should remove the element earlier in the code.
470 return false; 559 NOTREACHED();
471 *was_removed = true; 560 return false;
472 } else { 561 } else {
473 if (!SetCountOfFormElement(pair_id, count + delta)) 562 if (!SetCountOfFormElement(pair_id, count + delta))
474 return false; 563 return false;
475 } 564 }
476 return true; 565 return true;
477 } 566 }
478 567
479 bool AutofillTable::GetIDAndCountOfFormElement( 568 bool AutofillTable::GetIDAndCountOfFormElement(
480 const FormField& element, 569 const FormField& element,
481 int64* pair_id, 570 int64* pair_id,
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after
545 const Time& date_created) { 634 const Time& date_created) {
546 sql::Statement s(db_->GetUniqueStatement( 635 sql::Statement s(db_->GetUniqueStatement(
547 "INSERT INTO autofill_dates " 636 "INSERT INTO autofill_dates "
548 "(pair_id, date_created) VALUES (?, ?)")); 637 "(pair_id, date_created) VALUES (?, ?)"));
549 s.BindInt64(0, pair_id); 638 s.BindInt64(0, pair_id);
550 s.BindInt64(1, date_created.ToTimeT()); 639 s.BindInt64(1, date_created.ToTimeT());
551 640
552 return s.Run(); 641 return s.Run();
553 } 642 }
554 643
644 bool AutofillTable::DeleteLastAccess(int64 pair_id) {
645 // Inner SELECT selects the newest |date_created| for a given |pair_id|.
646 // DELETE deletes only that entry.
647 sql::Statement s(db_->GetUniqueStatement(
648 "DELETE FROM autofill_dates WHERE pair_id = ? and date_created IN "
649 "(SELECT date_created FROM autofill_dates WHERE pair_id = ? "
650 "ORDER BY date_created DESC LIMIT 1)"));
651 s.BindInt64(0, pair_id);
652 s.BindInt64(1, pair_id);
653
654 return s.Run();
655 }
656
555 bool AutofillTable::AddFormFieldValuesTime( 657 bool AutofillTable::AddFormFieldValuesTime(
556 const std::vector<FormField>& elements, 658 const std::vector<FormField>& elements,
557 std::vector<AutofillChange>* changes, 659 std::vector<AutofillChange>* changes,
558 Time time) { 660 Time time) {
559 // Only add one new entry for each unique element name. Use |seen_names| to 661 // 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. 662 // track this. Add up to |kMaximumUniqueNames| unique entries per form.
561 const size_t kMaximumUniqueNames = 256; 663 const size_t kMaximumUniqueNames = 256;
562 std::set<string16> seen_names; 664 std::set<string16> seen_names;
563 bool result = true; 665 bool result = true;
564 for (std::vector<FormField>::const_iterator 666 for (std::vector<FormField>::const_iterator itr = elements.begin();
565 itr = elements.begin(); 667 itr != elements.end(); ++itr) {
566 itr != elements.end();
567 itr++) {
568 if (seen_names.size() >= kMaximumUniqueNames) 668 if (seen_names.size() >= kMaximumUniqueNames)
569 break; 669 break;
570 if (seen_names.find(itr->name) != seen_names.end()) 670 if (seen_names.find(itr->name) != seen_names.end())
571 continue; 671 continue;
572 result = result && AddFormFieldValueTime(*itr, changes, time); 672 result = result && AddFormFieldValueTime(*itr, changes, time);
573 seen_names.insert(itr->name); 673 seen_names.insert(itr->name);
574 } 674 }
575 return result; 675 return result;
576 } 676 }
577 677
(...skipping 148 matching lines...) Expand 10 before | Expand all | Expand 10 after
726 826
727 if (!GetIDAndCountOfFormElement(element, &pair_id, &count)) 827 if (!GetIDAndCountOfFormElement(element, &pair_id, &count))
728 return false; 828 return false;
729 829
730 if (count == 0 && !InsertFormElement(element, &pair_id)) 830 if (count == 0 && !InsertFormElement(element, &pair_id))
731 return false; 831 return false;
732 832
733 if (!SetCountOfFormElement(pair_id, count + 1)) 833 if (!SetCountOfFormElement(pair_id, count + 1))
734 return false; 834 return false;
735 835
836 // If we already have more than 2 times delete last one, before adding new
837 // one.
838 if (count >= 2 && !DeleteLastAccess(pair_id))
839 return false;
840
736 if (!InsertPairIDAndDate(pair_id, time)) 841 if (!InsertPairIDAndDate(pair_id, time))
737 return false; 842 return false;
738 843
739 AutofillChange::Type change_type = 844 AutofillChange::Type change_type =
740 count == 0 ? AutofillChange::ADD : AutofillChange::UPDATE; 845 count == 0 ? AutofillChange::ADD : AutofillChange::UPDATE;
741 changes->push_back( 846 changes->push_back(
742 AutofillChange(change_type, 847 AutofillChange(change_type,
743 AutofillKey(element.name, element.value))); 848 AutofillKey(element.name, element.value)));
744 return true; 849 return true;
745 } 850 }
(...skipping 1127 matching lines...) Expand 10 before | Expand all | Expand 10 after
1873 "WHERE guid=?")); 1978 "WHERE guid=?"));
1874 s_date.BindInt64(0, date_item->second); 1979 s_date.BindInt64(0, date_item->second);
1875 s_date.BindString(1, iter->guid()); 1980 s_date.BindString(1, iter->guid());
1876 1981
1877 if (!s_date.Run()) 1982 if (!s_date.Run())
1878 return false; 1983 return false;
1879 } 1984 }
1880 1985
1881 return true; 1986 return true;
1882 } 1987 }
OLDNEW
« no previous file with comments | « chrome/browser/webdata/autofill_table.h ('k') | chrome/browser/webdata/autofill_table_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698