Chromium Code Reviews| Index: chrome/browser/webdata/autofill_table.cc |
| diff --git a/chrome/browser/webdata/autofill_table.cc b/chrome/browser/webdata/autofill_table.cc |
| index bba0b838df6c3ad84e9f2455f43bf373ae87ceed..e228185cd0e6e8867a3cdb995be15127db1bf257 100644 |
| --- a/chrome/browser/webdata/autofill_table.cc |
| +++ b/chrome/browser/webdata/autofill_table.cc |
| @@ -425,8 +425,15 @@ bool AutofillTable::RemoveFormElementsAddedBetween( |
| return false; |
| } |
| bool was_removed = false; |
| - if (!AddToCountOfFormElement(itr->a, -how_many, &was_removed)) |
| - return false; |
| + if (how_many == 2) { |
| + // We store at most 2 time stamps. |
| + was_removed = true; |
| + if (!RemoveFormElementForID(itr->a)) |
| + return false; |
| + } else { |
| + if (!AddToCountOfFormElement(itr->a, -how_many, &was_removed)) |
| + return false; |
| + } |
| AutofillChange::Type change_type = |
| was_removed ? AutofillChange::REMOVE : AutofillChange::UPDATE; |
| changes->push_back(AutofillChange(change_type, |
| @@ -436,6 +443,73 @@ bool AutofillTable::RemoveFormElementsAddedBetween( |
| return true; |
| } |
| +bool AutofillTable::RemoveFormElementsAccessedBefore( |
| + const base::Time& delete_end, std::vector<AutofillChange>* changes) { |
| + DCHECK(changes); |
| + DCHECK(!delete_end.is_null()); |
| + // Query for the pair_id, name, and value of all form elements that |
| + // were used between the given times. |
| + sql::Statement select_for_delete(db_->GetUniqueStatement( |
| + "SELECT DISTINCT pair_id, name, value " |
| + "FROM autofill WHERE pair_id NOT IN " |
| + "(SELECT DISTINCT pair_id " |
| + "FROM autofill_dates WHERE date_created >= ?)")); |
| + select_for_delete.BindInt64(0, delete_end.ToTimeT()); |
| + AutofillElementList entries_to_delete; |
| + while (select_for_delete.Step()) { |
| + entries_to_delete.push_back(MakeTuple(select_for_delete.ColumnInt64(0), |
| + select_for_delete.ColumnString16(1), |
| + select_for_delete.ColumnString16(2))); |
| + } |
| + if (!select_for_delete.Succeeded()) |
| + return false; |
| + sql::Statement delete_data_statement(db_->GetUniqueStatement( |
| + "DELETE FROM autofill WHERE pair_id NOT IN (" |
| + "SELECT pair_id FROM autofill_dates WHERE date_created >= ?)")); |
| + delete_data_statement.BindInt64(0, delete_end.ToTimeT()); |
| + if (!delete_data_statement.Run()) |
| + return false; |
| + sql::Statement delete_times_statement(db_->GetUniqueStatement( |
| + "DELETE FROM autofill_dates WHERE pair_id NOT IN (" |
| + "SELECT pair_id FROM autofill_dates WHERE date_created >= ?)")); |
| + delete_times_statement.BindInt64(0, delete_end.ToTimeT()); |
| + if (!delete_times_statement.Run()) |
| + return false; |
| + |
| + // Cull remaining entries. |
| + std::vector<AutofillEntry> entries; |
| + if (!GetAllAutofillEntries(&entries)) |
| + return false; |
| + sql::Statement cull_date_entry(db_->GetUniqueStatement( |
| + "DELETE FROM autofill_dates " |
| + "WHERE pair_id == (SELECT pair_id FROM autofill " |
| + "WHERE name = ? and value = ?)" |
| + "AND date_created != ? AND date_created != ?")); |
| + for (size_t i = 0; i < entries.size(); ++i) { |
| + cull_date_entry.BindString16(0, entries[i].key().name()); |
| + cull_date_entry.BindString16(1, entries[i].key().value()); |
| + cull_date_entry.BindInt64(2, |
| + entries[i].timestamps().empty() ? 0 : |
| + entries[i].timestamps().front().ToTimeT()); |
| + cull_date_entry.BindInt64(3, |
| + entries[i].timestamps().empty() ? 0 : |
| + entries[i].timestamps().back().ToTimeT()); |
| + if (!cull_date_entry.Run()) |
| + return false; |
| + cull_date_entry.Reset(); |
| + } |
| + |
| + changes->clear(); |
| + changes->reserve(entries_to_delete.size()); |
| + |
| + for (AutofillElementList::iterator it = entries_to_delete.begin(); |
| + it != entries_to_delete.end(); ++it) { |
| + changes->push_back(AutofillChange( |
| + AutofillChange::REMOVE, AutofillKey(it->b, it->c))); |
| + } |
| + return true; |
| +} |
| + |
| bool AutofillTable::RemoveFormElementForTimeRange(int64 pair_id, |
| const Time& delete_begin, |
| const Time& delete_end, |
| @@ -552,6 +626,17 @@ bool AutofillTable::InsertPairIDAndDate(int64 pair_id, |
| return s.Run(); |
| } |
| +bool AutofillTable::DeleteLastAccess(int64 pair_id) { |
| + sql::Statement s(db_->GetUniqueStatement( |
| + "DELETE FROM autofill_dates WHERE pair_id = ? and date_created IN " |
| + "(SELECT date_created FROM autofill_dates WHERE pair_id = ? " |
| + "ORDER BY date_created DESC LIMIT 1)")); |
|
Ilya Sherman
2012/03/15 21:00:41
The nested lookup is a little hard to follow. Did
GeorgeY
2012/03/17 00:36:16
Yes it is for efficiency reasons: doing two SQL st
|
| + s.BindInt64(0, pair_id); |
| + s.BindInt64(1, pair_id); |
| + |
| + return s.Run(); |
| +} |
| + |
| bool AutofillTable::AddFormFieldValuesTime( |
| const std::vector<FormField>& elements, |
| std::vector<AutofillChange>* changes, |
| @@ -733,6 +818,11 @@ bool AutofillTable::AddFormFieldValueTime(const FormField& element, |
| if (!SetCountOfFormElement(pair_id, count + 1)) |
| return false; |
| + // If we already have more than 2 times delete last one, before adding new |
| + // one. |
|
Ilya Sherman
2012/03/15 21:00:41
nit: Perhaps we should overwrite it rather than de
GeorgeY
2012/03/17 00:36:16
I am not 100% certain that it will be more efficie
|
| + if (count >= 2 && !DeleteLastAccess(pair_id)) |
| + return false; |
| + |
| if (!InsertPairIDAndDate(pair_id, time)) |
| return false; |