Include all dupe types (event when value is zero) in scan stats.
[chromium-blink-merge.git] / components / autofill / core / browser / webdata / autofill_table.cc
blob3f5a4c21dbd5e776edb5a05cffa4266887fe0107
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
3 // found in the LICENSE file.
5 #include "components/autofill/core/browser/webdata/autofill_table.h"
7 #include <algorithm>
8 #include <cmath>
9 #include <limits>
10 #include <map>
11 #include <set>
12 #include <string>
13 #include <vector>
15 #include "base/command_line.h"
16 #include "base/guid.h"
17 #include "base/i18n/case_conversion.h"
18 #include "base/logging.h"
19 #include "base/numerics/safe_conversions.h"
20 #include "base/strings/string_number_conversions.h"
21 #include "base/strings/utf_string_conversions.h"
22 #include "base/time/time.h"
23 #include "components/autofill/core/browser/autofill_country.h"
24 #include "components/autofill/core/browser/autofill_profile.h"
25 #include "components/autofill/core/browser/autofill_type.h"
26 #include "components/autofill/core/browser/credit_card.h"
27 #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_entry.h"
30 #include "components/autofill/core/common/autofill_switches.h"
31 #include "components/autofill/core/common/form_field_data.h"
32 #include "components/os_crypt/os_crypt.h"
33 #include "components/webdata/common/web_database.h"
34 #include "sql/statement.h"
35 #include "sql/transaction.h"
36 #include "ui/base/l10n/l10n_util.h"
37 #include "url/gurl.h"
39 using base::ASCIIToUTF16;
40 using base::Time;
42 namespace autofill {
43 namespace {
45 // The period after which autocomplete entries should expire in days.
46 const int64 kExpirationPeriodInDays = 60;
48 template<typename T>
49 T* address_of(T& v) {
50 return &v;
53 // Helper struct for AutofillTable::RemoveFormElementsAddedBetween().
54 // Contains all the necessary fields to update a row in the 'autofill' table.
55 struct AutofillUpdate {
56 base::string16 name;
57 base::string16 value;
58 time_t date_created;
59 time_t date_last_used;
60 int count;
63 // Rounds a positive floating point number to the nearest integer.
64 int Round(float f) {
65 DCHECK_GE(f, 0.f);
66 return base::checked_cast<int>(std::floor(f + 0.5f));
69 // Returns the |data_model|'s value corresponding to the |type|, trimmed to the
70 // maximum length that can be stored in a column of the Autofill database.
71 base::string16 GetInfo(const AutofillDataModel& data_model,
72 ServerFieldType type) {
73 base::string16 data = data_model.GetRawInfo(type);
74 if (data.size() > AutofillTable::kMaxDataLength)
75 return data.substr(0, AutofillTable::kMaxDataLength);
77 return data;
80 void BindAutofillProfileToStatement(const AutofillProfile& profile,
81 const base::Time& modification_date,
82 sql::Statement* s) {
83 DCHECK(base::IsValidGUID(profile.guid()));
84 int index = 0;
85 s->BindString(index++, profile.guid());
87 s->BindString16(index++, GetInfo(profile, COMPANY_NAME));
88 s->BindString16(index++, GetInfo(profile, ADDRESS_HOME_STREET_ADDRESS));
89 s->BindString16(index++, GetInfo(profile, ADDRESS_HOME_DEPENDENT_LOCALITY));
90 s->BindString16(index++, GetInfo(profile, ADDRESS_HOME_CITY));
91 s->BindString16(index++, GetInfo(profile, ADDRESS_HOME_STATE));
92 s->BindString16(index++, GetInfo(profile, ADDRESS_HOME_ZIP));
93 s->BindString16(index++, GetInfo(profile, ADDRESS_HOME_SORTING_CODE));
94 s->BindString16(index++, GetInfo(profile, ADDRESS_HOME_COUNTRY));
95 s->BindInt64(index++, profile.use_count());
96 s->BindInt64(index++, profile.use_date().ToTimeT());
97 s->BindInt64(index++, modification_date.ToTimeT());
98 s->BindString(index++, profile.origin());
99 s->BindString(index++, profile.language_code());
102 scoped_ptr<AutofillProfile> AutofillProfileFromStatement(
103 const sql::Statement& s) {
104 scoped_ptr<AutofillProfile> profile(new AutofillProfile);
105 int index = 0;
106 profile->set_guid(s.ColumnString(index++));
107 DCHECK(base::IsValidGUID(profile->guid()));
109 profile->SetRawInfo(COMPANY_NAME, s.ColumnString16(index++));
110 profile->SetRawInfo(ADDRESS_HOME_STREET_ADDRESS, s.ColumnString16(index++));
111 profile->SetRawInfo(ADDRESS_HOME_DEPENDENT_LOCALITY,
112 s.ColumnString16(index++));
113 profile->SetRawInfo(ADDRESS_HOME_CITY, s.ColumnString16(index++));
114 profile->SetRawInfo(ADDRESS_HOME_STATE, s.ColumnString16(index++));
115 profile->SetRawInfo(ADDRESS_HOME_ZIP, s.ColumnString16(index++));
116 profile->SetRawInfo(ADDRESS_HOME_SORTING_CODE, s.ColumnString16(index++));
117 profile->SetRawInfo(ADDRESS_HOME_COUNTRY, s.ColumnString16(index++));
118 profile->set_use_count(s.ColumnInt64(index++));
119 profile->set_use_date(base::Time::FromTimeT(s.ColumnInt64(index++)));
120 profile->set_modification_date(base::Time::FromTimeT(s.ColumnInt64(index++)));
121 profile->set_origin(s.ColumnString(index++));
122 profile->set_language_code(s.ColumnString(index++));
124 return profile.Pass();
127 void BindEncryptedCardToColumn(sql::Statement* s,
128 int column_index,
129 const base::string16& number) {
130 std::string encrypted_data;
131 OSCrypt::EncryptString16(number, &encrypted_data);
132 s->BindBlob(column_index, encrypted_data.data(),
133 static_cast<int>(encrypted_data.length()));
137 void BindCreditCardToStatement(const CreditCard& credit_card,
138 const base::Time& modification_date,
139 sql::Statement* s) {
140 DCHECK(base::IsValidGUID(credit_card.guid()));
141 int index = 0;
142 s->BindString(index++, credit_card.guid());
144 s->BindString16(index++, GetInfo(credit_card, CREDIT_CARD_NAME));
145 s->BindString16(index++, GetInfo(credit_card, CREDIT_CARD_EXP_MONTH));
146 s->BindString16(index++, GetInfo(credit_card, CREDIT_CARD_EXP_4_DIGIT_YEAR));
147 BindEncryptedCardToColumn(s, index++,
148 credit_card.GetRawInfo(CREDIT_CARD_NUMBER));
150 s->BindInt64(index++, credit_card.use_count());
151 s->BindInt64(index++, credit_card.use_date().ToTimeT());
152 s->BindInt64(index++, modification_date.ToTimeT());
153 s->BindString(index++, credit_card.origin());
156 base::string16 UnencryptedCardFromColumn(const sql::Statement& s,
157 int column_index) {
158 base::string16 credit_card_number;
159 int encrypted_number_len = s.ColumnByteLength(column_index);
160 if (encrypted_number_len) {
161 std::string encrypted_number;
162 encrypted_number.resize(encrypted_number_len);
163 memcpy(&encrypted_number[0], s.ColumnBlob(column_index),
164 encrypted_number_len);
165 OSCrypt::DecryptString16(encrypted_number, &credit_card_number);
167 return credit_card_number;
170 scoped_ptr<CreditCard> CreditCardFromStatement(const sql::Statement& s) {
171 scoped_ptr<CreditCard> credit_card(new CreditCard);
173 int index = 0;
174 credit_card->set_guid(s.ColumnString(index++));
175 DCHECK(base::IsValidGUID(credit_card->guid()));
177 credit_card->SetRawInfo(CREDIT_CARD_NAME, s.ColumnString16(index++));
178 credit_card->SetRawInfo(CREDIT_CARD_EXP_MONTH, s.ColumnString16(index++));
179 credit_card->SetRawInfo(CREDIT_CARD_EXP_4_DIGIT_YEAR,
180 s.ColumnString16(index++));
181 credit_card->SetRawInfo(CREDIT_CARD_NUMBER,
182 UnencryptedCardFromColumn(s, index++));
183 credit_card->set_use_count(s.ColumnInt64(index++));
184 credit_card->set_use_date(base::Time::FromTimeT(s.ColumnInt64(index++)));
185 credit_card->set_modification_date(
186 base::Time::FromTimeT(s.ColumnInt64(index++)));
187 credit_card->set_origin(s.ColumnString(index++));
189 return credit_card.Pass();
192 bool AddAutofillProfileNamesToProfile(sql::Connection* db,
193 AutofillProfile* profile) {
194 sql::Statement s(db->GetUniqueStatement(
195 "SELECT guid, first_name, middle_name, last_name, full_name "
196 "FROM autofill_profile_names "
197 "WHERE guid=?"));
198 s.BindString(0, profile->guid());
200 if (!s.is_valid())
201 return false;
203 std::vector<base::string16> first_names;
204 std::vector<base::string16> middle_names;
205 std::vector<base::string16> last_names;
206 std::vector<base::string16> full_names;
207 while (s.Step()) {
208 DCHECK_EQ(profile->guid(), s.ColumnString(0));
209 first_names.push_back(s.ColumnString16(1));
210 middle_names.push_back(s.ColumnString16(2));
211 last_names.push_back(s.ColumnString16(3));
212 full_names.push_back(s.ColumnString16(4));
214 if (!s.Succeeded())
215 return false;
217 profile->SetRawMultiInfo(NAME_FIRST, first_names);
218 profile->SetRawMultiInfo(NAME_MIDDLE, middle_names);
219 profile->SetRawMultiInfo(NAME_LAST, last_names);
220 profile->SetRawMultiInfo(NAME_FULL, full_names);
221 return true;
224 bool AddAutofillProfileEmailsToProfile(sql::Connection* db,
225 AutofillProfile* profile) {
226 sql::Statement s(db->GetUniqueStatement(
227 "SELECT guid, email "
228 "FROM autofill_profile_emails "
229 "WHERE guid=?"));
230 s.BindString(0, profile->guid());
232 if (!s.is_valid())
233 return false;
235 std::vector<base::string16> emails;
236 while (s.Step()) {
237 DCHECK_EQ(profile->guid(), s.ColumnString(0));
238 emails.push_back(s.ColumnString16(1));
240 if (!s.Succeeded())
241 return false;
243 profile->SetRawMultiInfo(EMAIL_ADDRESS, emails);
244 return true;
247 bool AddAutofillProfilePhonesToProfile(sql::Connection* db,
248 AutofillProfile* profile) {
249 sql::Statement s(db->GetUniqueStatement(
250 "SELECT guid, number "
251 "FROM autofill_profile_phones "
252 "WHERE guid=?"));
253 s.BindString(0, profile->guid());
255 if (!s.is_valid())
256 return false;
258 std::vector<base::string16> numbers;
259 while (s.Step()) {
260 DCHECK_EQ(profile->guid(), s.ColumnString(0));
261 numbers.push_back(s.ColumnString16(1));
263 if (!s.Succeeded())
264 return false;
266 profile->SetRawMultiInfo(PHONE_HOME_WHOLE_NUMBER, numbers);
267 return true;
270 bool AddAutofillProfileNames(const AutofillProfile& profile,
271 sql::Connection* db) {
272 std::vector<base::string16> first_names;
273 profile.GetRawMultiInfo(NAME_FIRST, &first_names);
274 std::vector<base::string16> middle_names;
275 profile.GetRawMultiInfo(NAME_MIDDLE, &middle_names);
276 std::vector<base::string16> last_names;
277 profile.GetRawMultiInfo(NAME_LAST, &last_names);
278 std::vector<base::string16> full_names;
279 profile.GetRawMultiInfo(NAME_FULL, &full_names);
280 DCHECK_EQ(first_names.size(), middle_names.size());
281 DCHECK_EQ(first_names.size(), last_names.size());
282 DCHECK_EQ(first_names.size(), full_names.size());
284 for (size_t i = 0; i < first_names.size(); ++i) {
285 // Add the new name.
286 sql::Statement s(db->GetUniqueStatement(
287 "INSERT INTO autofill_profile_names"
288 " (guid, first_name, middle_name, last_name, full_name) "
289 "VALUES (?,?,?,?,?)"));
290 s.BindString(0, profile.guid());
291 s.BindString16(1, first_names[i]);
292 s.BindString16(2, middle_names[i]);
293 s.BindString16(3, last_names[i]);
294 s.BindString16(4, full_names[i]);
296 if (!s.Run())
297 return false;
299 return true;
302 bool AddAutofillProfileEmails(const AutofillProfile& profile,
303 sql::Connection* db) {
304 std::vector<base::string16> emails;
305 profile.GetRawMultiInfo(EMAIL_ADDRESS, &emails);
307 for (size_t i = 0; i < emails.size(); ++i) {
308 // Add the new email.
309 sql::Statement s(db->GetUniqueStatement(
310 "INSERT INTO autofill_profile_emails"
311 " (guid, email) "
312 "VALUES (?,?)"));
313 s.BindString(0, profile.guid());
314 s.BindString16(1, emails[i]);
316 if (!s.Run())
317 return false;
320 return true;
323 bool AddAutofillProfilePhones(const AutofillProfile& profile,
324 sql::Connection* db) {
325 std::vector<base::string16> numbers;
326 profile.GetRawMultiInfo(PHONE_HOME_WHOLE_NUMBER, &numbers);
328 for (size_t i = 0; i < numbers.size(); ++i) {
329 // Add the new number.
330 sql::Statement s(db->GetUniqueStatement(
331 "INSERT INTO autofill_profile_phones"
332 " (guid, number) "
333 "VALUES (?,?)"));
334 s.BindString(0, profile.guid());
335 s.BindString16(1, numbers[i]);
337 if (!s.Run())
338 return false;
341 return true;
344 bool AddAutofillProfilePieces(const AutofillProfile& profile,
345 sql::Connection* db) {
346 if (!AddAutofillProfileNames(profile, db))
347 return false;
349 if (!AddAutofillProfileEmails(profile, db))
350 return false;
352 if (!AddAutofillProfilePhones(profile, db))
353 return false;
355 return true;
358 bool RemoveAutofillProfilePieces(const std::string& guid, sql::Connection* db) {
359 sql::Statement s1(db->GetUniqueStatement(
360 "DELETE FROM autofill_profile_names WHERE guid = ?"));
361 s1.BindString(0, guid);
363 if (!s1.Run())
364 return false;
366 sql::Statement s2(db->GetUniqueStatement(
367 "DELETE FROM autofill_profile_emails WHERE guid = ?"));
368 s2.BindString(0, guid);
370 if (!s2.Run())
371 return false;
373 sql::Statement s3(db->GetUniqueStatement(
374 "DELETE FROM autofill_profile_phones WHERE guid = ?"));
375 s3.BindString(0, guid);
377 return s3.Run();
380 WebDatabaseTable::TypeKey GetKey() {
381 // We just need a unique constant. Use the address of a static that
382 // COMDAT folding won't touch in an optimizing linker.
383 static int table_key = 0;
384 return reinterpret_cast<void*>(&table_key);
387 time_t GetEndTime(const base::Time& end) {
388 if (end.is_null() || end == base::Time::Max())
389 return std::numeric_limits<time_t>::max();
391 return end.ToTimeT();
394 std::string ServerStatusEnumToString(CreditCard::ServerStatus status) {
395 switch (status) {
396 case CreditCard::EXPIRED:
397 return "EXPIRED";
399 case CreditCard::OK:
400 return "OK";
403 NOTREACHED();
404 return "OK";
407 CreditCard::ServerStatus ServerStatusStringToEnum(const std::string& status) {
408 if (status == "EXPIRED")
409 return CreditCard::EXPIRED;
411 DCHECK_EQ("OK", status);
412 return CreditCard::OK;
415 } // namespace
417 // The maximum length allowed for form data.
418 const size_t AutofillTable::kMaxDataLength = 1024;
420 AutofillTable::AutofillTable(const std::string& app_locale)
421 : app_locale_(app_locale) {
424 AutofillTable::~AutofillTable() {
427 AutofillTable* AutofillTable::FromWebDatabase(WebDatabase* db) {
428 return static_cast<AutofillTable*>(db->GetTable(GetKey()));
431 WebDatabaseTable::TypeKey AutofillTable::GetTypeKey() const {
432 return GetKey();
435 bool AutofillTable::CreateTablesIfNecessary() {
436 return (InitMainTable() && InitCreditCardsTable() && InitProfilesTable() &&
437 InitProfileNamesTable() && InitProfileEmailsTable() &&
438 InitProfilePhonesTable() && InitProfileTrashTable() &&
439 InitMaskedCreditCardsTable() && InitUnmaskedCreditCardsTable() &&
440 InitServerCardMetadataTable() && InitServerAddressesTable() &&
441 InitServerAddressMetadataTable());
444 bool AutofillTable::IsSyncable() {
445 return true;
448 bool AutofillTable::MigrateToVersion(int version,
449 bool* update_compatible_version) {
450 // Migrate if necessary.
451 switch (version) {
452 case 54:
453 *update_compatible_version = true;
454 return MigrateToVersion54AddI18nFieldsAndRemoveDeprecatedFields();
455 case 55:
456 *update_compatible_version = true;
457 return MigrateToVersion55MergeAutofillDatesTable();
458 case 56:
459 *update_compatible_version = true;
460 return MigrateToVersion56AddProfileLanguageCodeForFormatting();
461 case 57:
462 *update_compatible_version = true;
463 return MigrateToVersion57AddFullNameField();
464 case 60:
465 *update_compatible_version = false;
466 return MigrateToVersion60AddServerCards();
467 case 61:
468 *update_compatible_version = false;
469 return MigrateToVersion61AddUsageStats();
470 case 62:
471 *update_compatible_version = false;
472 return MigrateToVersion62AddUsageStatsForUnmaskedCards();
473 case 63:
474 *update_compatible_version = false;
475 return MigrateToVersion63AddServerRecipientName();
476 case 64:
477 *update_compatible_version = false;
478 return MigrateToVersion64AddUnmaskDate();
479 case 65:
480 *update_compatible_version = false;
481 return MigrateToVersion65AddServerMetadataTables();
483 return true;
486 bool AutofillTable::AddFormFieldValues(
487 const std::vector<FormFieldData>& elements,
488 std::vector<AutofillChange>* changes) {
489 return AddFormFieldValuesTime(elements, changes, Time::Now());
492 bool AutofillTable::AddFormFieldValue(const FormFieldData& element,
493 std::vector<AutofillChange>* changes) {
494 return AddFormFieldValueTime(element, changes, Time::Now());
497 bool AutofillTable::GetFormValuesForElementName(
498 const base::string16& name,
499 const base::string16& prefix,
500 std::vector<base::string16>* values,
501 int limit) {
502 DCHECK(values);
503 sql::Statement s;
505 if (prefix.empty()) {
506 s.Assign(db_->GetUniqueStatement(
507 "SELECT value FROM autofill "
508 "WHERE name = ? "
509 "ORDER BY count DESC "
510 "LIMIT ?"));
511 s.BindString16(0, name);
512 s.BindInt(1, limit);
513 } else {
514 base::string16 prefix_lower = base::i18n::ToLower(prefix);
515 base::string16 next_prefix = prefix_lower;
516 next_prefix[next_prefix.length() - 1]++;
518 s.Assign(db_->GetUniqueStatement(
519 "SELECT value FROM autofill "
520 "WHERE name = ? AND "
521 "value_lower >= ? AND "
522 "value_lower < ? "
523 "ORDER BY count DESC "
524 "LIMIT ?"));
525 s.BindString16(0, name);
526 s.BindString16(1, prefix_lower);
527 s.BindString16(2, next_prefix);
528 s.BindInt(3, limit);
531 values->clear();
532 while (s.Step())
533 values->push_back(s.ColumnString16(0));
534 return s.Succeeded();
537 bool AutofillTable::HasFormElements() {
538 sql::Statement s(db_->GetUniqueStatement("SELECT COUNT(*) FROM autofill"));
539 if (!s.Step()) {
540 NOTREACHED();
541 return false;
543 return s.ColumnInt(0) > 0;
546 bool AutofillTable::RemoveFormElementsAddedBetween(
547 const Time& delete_begin,
548 const Time& delete_end,
549 std::vector<AutofillChange>* changes) {
550 const time_t delete_begin_time_t = delete_begin.ToTimeT();
551 const time_t delete_end_time_t = GetEndTime(delete_end);
553 // Query for the name, value, count, and access dates of all form elements
554 // that were used between the given times.
555 sql::Statement s(db_->GetUniqueStatement(
556 "SELECT name, value, count, date_created, date_last_used FROM autofill "
557 "WHERE (date_created >= ? AND date_created < ?) OR "
558 " (date_last_used >= ? AND date_last_used < ?)"));
559 s.BindInt64(0, delete_begin_time_t);
560 s.BindInt64(1, delete_end_time_t);
561 s.BindInt64(2, delete_begin_time_t);
562 s.BindInt64(3, delete_end_time_t);
564 std::vector<AutofillUpdate> updates;
565 std::vector<AutofillChange> tentative_changes;
566 while (s.Step()) {
567 base::string16 name = s.ColumnString16(0);
568 base::string16 value = s.ColumnString16(1);
569 int count = s.ColumnInt(2);
570 time_t date_created_time_t = s.ColumnInt64(3);
571 time_t date_last_used_time_t = s.ColumnInt64(4);
573 // If *all* uses of the element were between |delete_begin| and
574 // |delete_end|, then delete the element. Otherwise, update the use
575 // timestamps and use count.
576 AutofillChange::Type change_type;
577 if (date_created_time_t >= delete_begin_time_t &&
578 date_last_used_time_t < delete_end_time_t) {
579 change_type = AutofillChange::REMOVE;
580 } else {
581 change_type = AutofillChange::UPDATE;
583 // For all updated elements, set either date_created or date_last_used so
584 // that the range [date_created, date_last_used] no longer overlaps with
585 // [delete_begin, delete_end). Update the count by interpolating.
586 // Precisely, compute the average amount of time between increments to the
587 // count in the original range [date_created, date_last_used]:
588 // avg_delta = (date_last_used_orig - date_created_orig) / (count - 1)
589 // The count can be expressed as
590 // count = 1 + (date_last_used - date_created) / avg_delta
591 // Hence, update the count to
592 // count_new = 1 + (date_last_used_new - date_created_new) / avg_delta
593 // = 1 + ((count - 1) *
594 // (date_last_used_new - date_created_new) /
595 // (date_last_used_orig - date_created_orig))
596 // Interpolating might not give a result that completely accurately
597 // reflects the user's history, but it's the best that can be done given
598 // the information in the database.
599 AutofillUpdate updated_entry;
600 updated_entry.name = name;
601 updated_entry.value = value;
602 updated_entry.date_created =
603 date_created_time_t < delete_begin_time_t ?
604 date_created_time_t :
605 delete_end_time_t;
606 updated_entry.date_last_used =
607 date_last_used_time_t >= delete_end_time_t ?
608 date_last_used_time_t :
609 delete_begin_time_t - 1;
610 updated_entry.count =
612 Round(1.0 * (count - 1) *
613 (updated_entry.date_last_used - updated_entry.date_created) /
614 (date_last_used_time_t - date_created_time_t));
615 updates.push_back(updated_entry);
618 tentative_changes.push_back(
619 AutofillChange(change_type, AutofillKey(name, value)));
621 if (!s.Succeeded())
622 return false;
624 // As a single transaction, remove or update the elements appropriately.
625 sql::Statement s_delete(db_->GetUniqueStatement(
626 "DELETE FROM autofill WHERE date_created >= ? AND date_last_used < ?"));
627 s_delete.BindInt64(0, delete_begin_time_t);
628 s_delete.BindInt64(1, delete_end_time_t);
629 sql::Transaction transaction(db_);
630 if (!transaction.Begin())
631 return false;
632 if (!s_delete.Run())
633 return false;
634 for (size_t i = 0; i < updates.size(); ++i) {
635 sql::Statement s_update(db_->GetUniqueStatement(
636 "UPDATE autofill SET date_created = ?, date_last_used = ?, count = ?"
637 "WHERE name = ? AND value = ?"));
638 s_update.BindInt64(0, updates[i].date_created);
639 s_update.BindInt64(1, updates[i].date_last_used);
640 s_update.BindInt(2, updates[i].count);
641 s_update.BindString16(3, updates[i].name);
642 s_update.BindString16(4, updates[i].value);
643 if (!s_update.Run())
644 return false;
646 if (!transaction.Commit())
647 return false;
649 *changes = tentative_changes;
650 return true;
653 bool AutofillTable::RemoveExpiredFormElements(
654 std::vector<AutofillChange>* changes) {
655 base::Time expiration_time =
656 base::Time::Now() - base::TimeDelta::FromDays(kExpirationPeriodInDays);
658 // Query for the name and value of all form elements that were last used
659 // before the |expiration_time|.
660 sql::Statement select_for_delete(db_->GetUniqueStatement(
661 "SELECT name, value FROM autofill WHERE date_last_used < ?"));
662 select_for_delete.BindInt64(0, expiration_time.ToTimeT());
663 std::vector<AutofillChange> tentative_changes;
664 while (select_for_delete.Step()) {
665 base::string16 name = select_for_delete.ColumnString16(0);
666 base::string16 value = select_for_delete.ColumnString16(1);
667 tentative_changes.push_back(
668 AutofillChange(AutofillChange::REMOVE, AutofillKey(name, value)));
671 if (!select_for_delete.Succeeded())
672 return false;
674 sql::Statement delete_data_statement(db_->GetUniqueStatement(
675 "DELETE FROM autofill WHERE date_last_used < ?"));
676 delete_data_statement.BindInt64(0, expiration_time.ToTimeT());
677 if (!delete_data_statement.Run())
678 return false;
680 *changes = tentative_changes;
681 return true;
684 bool AutofillTable::AddFormFieldValuesTime(
685 const std::vector<FormFieldData>& elements,
686 std::vector<AutofillChange>* changes,
687 Time time) {
688 // Only add one new entry for each unique element name. Use |seen_names| to
689 // track this. Add up to |kMaximumUniqueNames| unique entries per form.
690 const size_t kMaximumUniqueNames = 256;
691 std::set<base::string16> seen_names;
692 bool result = true;
693 for (std::vector<FormFieldData>::const_iterator itr = elements.begin();
694 itr != elements.end(); ++itr) {
695 if (seen_names.size() >= kMaximumUniqueNames)
696 break;
697 if (seen_names.find(itr->name) != seen_names.end())
698 continue;
699 result = result && AddFormFieldValueTime(*itr, changes, time);
700 seen_names.insert(itr->name);
702 return result;
705 bool AutofillTable::GetAllAutofillEntries(std::vector<AutofillEntry>* entries) {
706 sql::Statement s(db_->GetUniqueStatement(
707 "SELECT name, value, date_created, date_last_used FROM autofill"));
709 while (s.Step()) {
710 base::string16 name = s.ColumnString16(0);
711 base::string16 value = s.ColumnString16(1);
712 Time date_created = Time::FromTimeT(s.ColumnInt64(2));
713 Time date_last_used = Time::FromTimeT(s.ColumnInt64(3));
714 entries->push_back(
715 AutofillEntry(AutofillKey(name, value), date_created, date_last_used));
718 return s.Succeeded();
721 bool AutofillTable::GetAutofillTimestamps(const base::string16& name,
722 const base::string16& value,
723 Time* date_created,
724 Time* date_last_used) {
725 sql::Statement s(db_->GetUniqueStatement(
726 "SELECT date_created, date_last_used FROM autofill "
727 "WHERE name = ? AND value = ?"));
728 s.BindString16(0, name);
729 s.BindString16(1, value);
730 if (!s.Step())
731 return false;
733 *date_created = Time::FromTimeT(s.ColumnInt64(0));
734 *date_last_used = Time::FromTimeT(s.ColumnInt64(1));
736 DCHECK(!s.Step());
737 return true;
740 bool AutofillTable::UpdateAutofillEntries(
741 const std::vector<AutofillEntry>& entries) {
742 if (entries.empty())
743 return true;
745 // Remove all existing entries.
746 for (size_t i = 0; i < entries.size(); ++i) {
747 sql::Statement s(db_->GetUniqueStatement(
748 "DELETE FROM autofill WHERE name = ? AND value = ?"));
749 s.BindString16(0, entries[i].key().name());
750 s.BindString16(1, entries[i].key().value());
751 if (!s.Run())
752 return false;
755 // Insert all the supplied autofill entries.
756 for (size_t i = 0; i < entries.size(); ++i) {
757 if (!InsertAutofillEntry(entries[i]))
758 return false;
761 return true;
764 bool AutofillTable::InsertAutofillEntry(const AutofillEntry& entry) {
765 std::string sql =
766 "INSERT INTO autofill "
767 "(name, value, value_lower, date_created, date_last_used, count) "
768 "VALUES (?, ?, ?, ?, ?, ?)";
769 sql::Statement s(db_->GetUniqueStatement(sql.c_str()));
770 s.BindString16(0, entry.key().name());
771 s.BindString16(1, entry.key().value());
772 s.BindString16(2, base::i18n::ToLower(entry.key().value()));
773 s.BindInt64(3, entry.date_created().ToTimeT());
774 s.BindInt64(4, entry.date_last_used().ToTimeT());
775 // TODO(isherman): The counts column is currently synced implicitly as the
776 // number of timestamps. Sync the value explicitly instead, since the DB now
777 // only saves the first and last timestamp, which makes counting timestamps
778 // completely meaningless as a way to track frequency of usage.
779 s.BindInt(5, entry.date_last_used() == entry.date_created() ? 1 : 2);
780 return s.Run();
783 bool AutofillTable::AddFormFieldValueTime(const FormFieldData& element,
784 std::vector<AutofillChange>* changes,
785 Time time) {
786 sql::Statement s_exists(db_->GetUniqueStatement(
787 "SELECT COUNT(*) FROM autofill WHERE name = ? AND value = ?"));
788 s_exists.BindString16(0, element.name);
789 s_exists.BindString16(1, element.value);
790 if (!s_exists.Step())
791 return false;
793 bool already_exists = s_exists.ColumnInt(0) > 0;
794 if (already_exists) {
795 sql::Statement s(db_->GetUniqueStatement(
796 "UPDATE autofill SET date_last_used = ?, count = count + 1 "
797 "WHERE name = ? AND value = ?"));
798 s.BindInt64(0, time.ToTimeT());
799 s.BindString16(1, element.name);
800 s.BindString16(2, element.value);
801 if (!s.Run())
802 return false;
803 } else {
804 time_t time_as_time_t = time.ToTimeT();
805 sql::Statement s(db_->GetUniqueStatement(
806 "INSERT INTO autofill "
807 "(name, value, value_lower, date_created, date_last_used, count) "
808 "VALUES (?, ?, ?, ?, ?, ?)"));
809 s.BindString16(0, element.name);
810 s.BindString16(1, element.value);
811 s.BindString16(2, base::i18n::ToLower(element.value));
812 s.BindInt64(3, time_as_time_t);
813 s.BindInt64(4, time_as_time_t);
814 s.BindInt(5, 1);
815 if (!s.Run())
816 return false;
819 AutofillChange::Type change_type =
820 already_exists ? AutofillChange::UPDATE : AutofillChange::ADD;
821 changes->push_back(
822 AutofillChange(change_type, AutofillKey(element.name, element.value)));
823 return true;
827 bool AutofillTable::RemoveFormElement(const base::string16& name,
828 const base::string16& value) {
829 sql::Statement s(db_->GetUniqueStatement(
830 "DELETE FROM autofill WHERE name = ? AND value= ?"));
831 s.BindString16(0, name);
832 s.BindString16(1, value);
833 return s.Run();
836 bool AutofillTable::AddAutofillProfile(const AutofillProfile& profile) {
837 if (IsAutofillGUIDInTrash(profile.guid()))
838 return true;
840 sql::Statement s(db_->GetUniqueStatement(
841 "INSERT INTO autofill_profiles"
842 "(guid, company_name, street_address, dependent_locality, city, state,"
843 " zipcode, sorting_code, country_code, use_count, use_date, "
844 " date_modified, origin, language_code)"
845 "VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?)"));
846 BindAutofillProfileToStatement(profile, base::Time::Now(), &s);
848 if (!s.Run())
849 return false;
851 return AddAutofillProfilePieces(profile, db_);
854 bool AutofillTable::GetAutofillProfile(const std::string& guid,
855 AutofillProfile** profile) {
856 DCHECK(base::IsValidGUID(guid));
857 DCHECK(profile);
858 sql::Statement s(db_->GetUniqueStatement(
859 "SELECT guid, company_name, street_address, dependent_locality, city,"
860 " state, zipcode, sorting_code, country_code, use_count, use_date,"
861 " date_modified, origin, language_code "
862 "FROM autofill_profiles "
863 "WHERE guid=?"));
864 s.BindString(0, guid);
866 if (!s.Step())
867 return false;
869 scoped_ptr<AutofillProfile> p = AutofillProfileFromStatement(s);
871 // Get associated name info.
872 AddAutofillProfileNamesToProfile(db_, p.get());
874 // Get associated email info.
875 AddAutofillProfileEmailsToProfile(db_, p.get());
877 // Get associated phone info.
878 AddAutofillProfilePhonesToProfile(db_, p.get());
880 *profile = p.release();
881 return true;
884 bool AutofillTable::GetAutofillProfiles(
885 std::vector<AutofillProfile*>* profiles) {
886 DCHECK(profiles);
887 profiles->clear();
889 sql::Statement s(db_->GetUniqueStatement(
890 "SELECT guid "
891 "FROM autofill_profiles "
892 "ORDER BY date_modified DESC, guid"));
894 while (s.Step()) {
895 std::string guid = s.ColumnString(0);
896 AutofillProfile* profile = NULL;
897 if (!GetAutofillProfile(guid, &profile))
898 return false;
899 profiles->push_back(profile);
902 return s.Succeeded();
905 bool AutofillTable::GetServerProfiles(std::vector<AutofillProfile*>* profiles) {
906 profiles->clear();
908 sql::Statement s(db_->GetUniqueStatement(
909 "SELECT "
910 "id,"
911 "use_count,"
912 "use_date,"
913 "recipient_name,"
914 "company_name,"
915 "street_address,"
916 "address_1," // ADDRESS_HOME_STATE
917 "address_2," // ADDRESS_HOME_CITY
918 "address_3," // ADDRESS_HOME_DEPENDENT_LOCALITY
919 "address_4," // Not supported in AutofillProfile yet.
920 "postal_code," // ADDRESS_HOME_ZIP
921 "sorting_code," // ADDRESS_HOME_SORTING_CODE
922 "country_code," // ADDRESS_HOME_COUNTRY
923 "phone_number," // PHONE_HOME_WHOLE_NUMBER
924 "language_code "
925 "FROM server_addresses addresses "
926 "LEFT OUTER JOIN server_address_metadata USING (id)"));
928 while (s.Step()) {
929 int index = 0;
930 scoped_ptr<AutofillProfile> profile(new AutofillProfile(
931 AutofillProfile::SERVER_PROFILE, s.ColumnString(index++)));
932 profile->set_use_count(s.ColumnInt64(index++));
933 profile->set_use_date(
934 base::Time::FromInternalValue(s.ColumnInt64(index++)));
936 base::string16 recipient_name = s.ColumnString16(index++);
937 profile->SetRawInfo(COMPANY_NAME, s.ColumnString16(index++));
938 profile->SetRawInfo(ADDRESS_HOME_STREET_ADDRESS, s.ColumnString16(index++));
939 profile->SetRawInfo(ADDRESS_HOME_STATE, s.ColumnString16(index++));
940 profile->SetRawInfo(ADDRESS_HOME_CITY, s.ColumnString16(index++));
941 profile->SetRawInfo(ADDRESS_HOME_DEPENDENT_LOCALITY,
942 s.ColumnString16(index++));
943 index++; // Skip address_4 which we haven't added to AutofillProfile yet.
944 profile->SetRawInfo(ADDRESS_HOME_ZIP, s.ColumnString16(index++));
945 profile->SetRawInfo(ADDRESS_HOME_SORTING_CODE, s.ColumnString16(index++));
946 profile->SetRawInfo(ADDRESS_HOME_COUNTRY, s.ColumnString16(index++));
947 base::string16 phone_number = s.ColumnString16(index++);
948 profile->set_language_code(s.ColumnString(index++));
950 // SetInfo instead of SetRawInfo so the constituent pieces will be parsed
951 // for these data types.
952 profile->SetInfo(AutofillType(NAME_FULL), recipient_name,
953 profile->language_code());
954 profile->SetInfo(AutofillType(PHONE_HOME_WHOLE_NUMBER), phone_number,
955 profile->language_code());
957 profiles->push_back(profile.release());
960 return s.Succeeded();
963 void AutofillTable::SetServerProfiles(
964 const std::vector<AutofillProfile>& profiles) {
965 sql::Transaction transaction(db_);
966 if (!transaction.Begin())
967 return;
969 // Delete all old ones first.
970 sql::Statement delete_old(db_->GetUniqueStatement(
971 "DELETE FROM server_addresses"));
972 delete_old.Run();
974 sql::Statement insert(db_->GetUniqueStatement(
975 "INSERT INTO server_addresses("
976 "id,"
977 "recipient_name,"
978 "company_name,"
979 "street_address,"
980 "address_1," // ADDRESS_HOME_STATE
981 "address_2," // ADDRESS_HOME_CITY
982 "address_3," // ADDRESS_HOME_DEPENDENT_LOCALITY
983 "address_4," // Not supported in AutofillProfile yet.
984 "postal_code," // ADDRESS_HOME_ZIP
985 "sorting_code," // ADDRESS_HOME_SORTING_CODE
986 "country_code," // ADDRESS_HOME_COUNTRY
987 "phone_number," // PHONE_HOME_WHOLE_NUMBER
988 "language_code) "
989 "VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?)"));
990 for (const auto& profile : profiles) {
991 DCHECK(profile.record_type() == AutofillProfile::SERVER_PROFILE);
993 int index = 0;
994 insert.BindString(index++, profile.server_id());
995 insert.BindString16(index++, profile.GetRawInfo(NAME_FULL));
996 insert.BindString16(index++, profile.GetRawInfo(COMPANY_NAME));
997 insert.BindString16(index++,
998 profile.GetRawInfo(ADDRESS_HOME_STREET_ADDRESS));
999 insert.BindString16(index++, profile.GetRawInfo(ADDRESS_HOME_STATE));
1000 insert.BindString16(index++, profile.GetRawInfo(ADDRESS_HOME_CITY));
1001 insert.BindString16(index++,
1002 profile.GetRawInfo(ADDRESS_HOME_DEPENDENT_LOCALITY));
1003 index++; // SKip address_4 which we haven't added to AutofillProfile yet.
1004 insert.BindString16(index++, profile.GetRawInfo(ADDRESS_HOME_ZIP));
1005 insert.BindString16(index++, profile.GetRawInfo(ADDRESS_HOME_SORTING_CODE));
1006 insert.BindString16(index++, profile.GetRawInfo(ADDRESS_HOME_COUNTRY));
1007 insert.BindString16(index++, profile.GetRawInfo(PHONE_HOME_WHOLE_NUMBER));
1008 insert.BindString(index++, profile.language_code());
1010 insert.Run();
1011 insert.Reset(true);
1014 // Delete metadata that's no longer relevant.
1015 sql::Statement metadata_delete(db_->GetUniqueStatement(
1016 "DELETE FROM server_address_metadata WHERE id NOT IN "
1017 "(SELECT id FROM server_addresses)"));
1018 metadata_delete.Run();
1020 transaction.Commit();
1023 bool AutofillTable::UpdateAutofillProfile(const AutofillProfile& profile) {
1024 DCHECK(base::IsValidGUID(profile.guid()));
1026 // Don't update anything until the trash has been emptied. There may be
1027 // pending modifications to process.
1028 if (!IsAutofillProfilesTrashEmpty())
1029 return true;
1031 AutofillProfile* tmp_profile = NULL;
1032 if (!GetAutofillProfile(profile.guid(), &tmp_profile))
1033 return false;
1035 scoped_ptr<AutofillProfile> old_profile(tmp_profile);
1036 bool update_modification_date = *old_profile != profile;
1038 sql::Statement s(db_->GetUniqueStatement(
1039 "UPDATE autofill_profiles "
1040 "SET guid=?, company_name=?, street_address=?, dependent_locality=?, "
1041 " city=?, state=?, zipcode=?, sorting_code=?, country_code=?, "
1042 " use_count=?, use_date=?, date_modified=?, origin=?, language_code=? "
1043 "WHERE guid=?"));
1044 BindAutofillProfileToStatement(
1045 profile,
1046 update_modification_date ? base::Time::Now() :
1047 old_profile->modification_date(),
1048 &s);
1049 s.BindString(14, profile.guid());
1051 bool result = s.Run();
1052 DCHECK_GT(db_->GetLastChangeCount(), 0);
1053 if (!result)
1054 return result;
1056 // Remove the old names, emails, and phone numbers.
1057 if (!RemoveAutofillProfilePieces(profile.guid(), db_))
1058 return false;
1060 return AddAutofillProfilePieces(profile, db_);
1063 bool AutofillTable::RemoveAutofillProfile(const std::string& guid) {
1064 DCHECK(base::IsValidGUID(guid));
1066 if (IsAutofillGUIDInTrash(guid)) {
1067 sql::Statement s_trash(db_->GetUniqueStatement(
1068 "DELETE FROM autofill_profiles_trash WHERE guid = ?"));
1069 s_trash.BindString(0, guid);
1071 bool success = s_trash.Run();
1072 DCHECK_GT(db_->GetLastChangeCount(), 0) << "Expected item in trash";
1073 return success;
1076 sql::Statement s(db_->GetUniqueStatement(
1077 "DELETE FROM autofill_profiles WHERE guid = ?"));
1078 s.BindString(0, guid);
1080 if (!s.Run())
1081 return false;
1083 return RemoveAutofillProfilePieces(guid, db_);
1086 bool AutofillTable::ClearAutofillProfiles() {
1087 sql::Statement s1(db_->GetUniqueStatement(
1088 "DELETE FROM autofill_profiles"));
1090 if (!s1.Run())
1091 return false;
1093 sql::Statement s2(db_->GetUniqueStatement(
1094 "DELETE FROM autofill_profile_names"));
1096 if (!s2.Run())
1097 return false;
1099 sql::Statement s3(db_->GetUniqueStatement(
1100 "DELETE FROM autofill_profile_emails"));
1102 if (!s3.Run())
1103 return false;
1105 sql::Statement s4(db_->GetUniqueStatement(
1106 "DELETE FROM autofill_profile_phones"));
1108 return s4.Run();
1111 bool AutofillTable::AddCreditCard(const CreditCard& credit_card) {
1112 sql::Statement s(db_->GetUniqueStatement(
1113 "INSERT INTO credit_cards"
1114 "(guid, name_on_card, expiration_month, expiration_year, "
1115 " card_number_encrypted, use_count, use_date, date_modified, origin)"
1116 "VALUES (?,?,?,?,?,?,?,?,?)"));
1117 BindCreditCardToStatement(credit_card, base::Time::Now(), &s);
1119 if (!s.Run())
1120 return false;
1122 DCHECK_GT(db_->GetLastChangeCount(), 0);
1123 return true;
1126 bool AutofillTable::GetCreditCard(const std::string& guid,
1127 CreditCard** credit_card) {
1128 DCHECK(base::IsValidGUID(guid));
1129 sql::Statement s(db_->GetUniqueStatement(
1130 "SELECT guid, name_on_card, expiration_month, expiration_year, "
1131 "card_number_encrypted, use_count, use_date, date_modified, "
1132 "origin "
1133 "FROM credit_cards "
1134 "WHERE guid = ?"));
1135 s.BindString(0, guid);
1137 if (!s.Step())
1138 return false;
1140 *credit_card = CreditCardFromStatement(s).release();
1141 return true;
1144 bool AutofillTable::GetCreditCards(
1145 std::vector<CreditCard*>* credit_cards) {
1146 DCHECK(credit_cards);
1147 credit_cards->clear();
1149 sql::Statement s(db_->GetUniqueStatement(
1150 "SELECT guid "
1151 "FROM credit_cards "
1152 "ORDER BY date_modified DESC, guid"));
1154 while (s.Step()) {
1155 std::string guid = s.ColumnString(0);
1156 CreditCard* credit_card = NULL;
1157 if (!GetCreditCard(guid, &credit_card))
1158 return false;
1159 credit_cards->push_back(credit_card);
1162 return s.Succeeded();
1165 bool AutofillTable::GetServerCreditCards(
1166 std::vector<CreditCard*>* credit_cards) {
1167 credit_cards->clear();
1169 sql::Statement s(db_->GetUniqueStatement(
1170 "SELECT "
1171 "card_number_encrypted, " // 0
1172 "last_four," // 1
1173 "masked.id," // 2
1174 "metadata.use_count," // 3
1175 "metadata.use_date," // 4
1176 "type," // 5
1177 "status," // 6
1178 "name_on_card," // 7
1179 "exp_month," // 8
1180 "exp_year " // 9
1181 "FROM masked_credit_cards masked "
1182 "LEFT OUTER JOIN unmasked_credit_cards USING (id) "
1183 "LEFT OUTER JOIN server_card_metadata metadata USING (id)"));
1184 while (s.Step()) {
1185 int index = 0;
1187 // If the card_number_encrypted field is nonempty, we can assume this card
1188 // is a full card, otherwise it's masked.
1189 base::string16 full_card_number = UnencryptedCardFromColumn(s, index++);
1190 base::string16 last_four = s.ColumnString16(index++);
1191 CreditCard::RecordType record_type = full_card_number.empty() ?
1192 CreditCard::MASKED_SERVER_CARD :
1193 CreditCard::FULL_SERVER_CARD;
1194 std::string server_id = s.ColumnString(index++);
1196 CreditCard* card = new CreditCard(record_type, server_id);
1197 card->SetRawInfo(
1198 CREDIT_CARD_NUMBER,
1199 record_type == CreditCard::MASKED_SERVER_CARD ? last_four
1200 : full_card_number);
1201 card->set_use_count(s.ColumnInt64(index++));
1202 card->set_use_date(base::Time::FromInternalValue(s.ColumnInt64(index++)));
1204 std::string card_type = s.ColumnString(index++);
1205 if (record_type == CreditCard::MASKED_SERVER_CARD) {
1206 // The type must be set after setting the number to override the
1207 // autodectected type.
1208 card->SetTypeForMaskedCard(card_type.c_str());
1209 } else {
1210 DCHECK_EQ(CreditCard::GetCreditCardType(full_card_number), card_type);
1213 card->SetServerStatus(ServerStatusStringToEnum(s.ColumnString(index++)));
1214 card->SetRawInfo(CREDIT_CARD_NAME, s.ColumnString16(index++));
1215 card->SetRawInfo(CREDIT_CARD_EXP_MONTH, s.ColumnString16(index++));
1216 card->SetRawInfo(CREDIT_CARD_EXP_4_DIGIT_YEAR, s.ColumnString16(index++));
1217 credit_cards->push_back(card);
1220 return s.Succeeded();
1223 void AutofillTable::SetServerCreditCards(
1224 const std::vector<CreditCard>& credit_cards) {
1225 sql::Transaction transaction(db_);
1226 if (!transaction.Begin())
1227 return;
1229 // Delete all old values.
1230 sql::Statement masked_delete(db_->GetUniqueStatement(
1231 "DELETE FROM masked_credit_cards"));
1232 masked_delete.Run();
1234 sql::Statement masked_insert(db_->GetUniqueStatement(
1235 "INSERT INTO masked_credit_cards("
1236 "id," // 0
1237 "type," // 1
1238 "status," // 2
1239 "name_on_card," // 3
1240 "last_four," // 4
1241 "exp_month," // 4
1242 "exp_year) " // 5
1243 "VALUES (?,?,?,?,?,?,?)"));
1244 for (const CreditCard& card : credit_cards) {
1245 DCHECK_EQ(CreditCard::MASKED_SERVER_CARD, card.record_type());
1247 masked_insert.BindString(0, card.server_id());
1248 masked_insert.BindString(1, card.type());
1249 masked_insert.BindString(2,
1250 ServerStatusEnumToString(card.GetServerStatus()));
1251 masked_insert.BindString16(3, card.GetRawInfo(CREDIT_CARD_NAME));
1252 masked_insert.BindString16(4, card.LastFourDigits());
1253 masked_insert.BindString16(5, card.GetRawInfo(CREDIT_CARD_EXP_MONTH));
1254 masked_insert.BindString16(6,
1255 card.GetRawInfo(CREDIT_CARD_EXP_4_DIGIT_YEAR));
1257 masked_insert.Run();
1258 masked_insert.Reset(true);
1261 // Delete all items in the unmasked table that aren't in the new set.
1262 sql::Statement unmasked_delete(db_->GetUniqueStatement(
1263 "DELETE FROM unmasked_credit_cards WHERE id NOT IN "
1264 "(SELECT id FROM masked_credit_cards)"));
1265 unmasked_delete.Run();
1266 // Do the same for metadata.
1267 sql::Statement metadata_delete(db_->GetUniqueStatement(
1268 "DELETE FROM server_card_metadata WHERE id NOT IN "
1269 "(SELECT id FROM masked_credit_cards)"));
1270 metadata_delete.Run();
1272 transaction.Commit();
1275 bool AutofillTable::UnmaskServerCreditCard(const CreditCard& masked,
1276 const base::string16& full_number) {
1277 // Make sure there aren't duplicates for this card.
1278 MaskServerCreditCard(masked.server_id());
1279 sql::Statement s(db_->GetUniqueStatement(
1280 "INSERT INTO unmasked_credit_cards("
1281 "id,"
1282 "card_number_encrypted,"
1283 "unmask_date)"
1284 "VALUES (?,?,?)"));
1285 s.BindString(0, masked.server_id());
1287 std::string encrypted_data;
1288 OSCrypt::EncryptString16(full_number, &encrypted_data);
1289 s.BindBlob(1, encrypted_data.data(),
1290 static_cast<int>(encrypted_data.length()));
1291 s.BindInt64(2, base::Time::Now().ToInternalValue()); // unmask_date
1293 s.Run();
1295 CreditCard unmasked = masked;
1296 unmasked.set_record_type(CreditCard::FULL_SERVER_CARD);
1297 unmasked.SetNumber(full_number);
1298 unmasked.RecordUse();
1299 UpdateServerCardUsageStats(unmasked);
1301 return db_->GetLastChangeCount() > 0;
1304 bool AutofillTable::MaskServerCreditCard(const std::string& id) {
1305 sql::Statement s(db_->GetUniqueStatement(
1306 "DELETE FROM unmasked_credit_cards WHERE id = ?"));
1307 s.BindString(0, id);
1308 s.Run();
1309 return db_->GetLastChangeCount() > 0;
1312 bool AutofillTable::UpdateServerCardUsageStats(
1313 const CreditCard& credit_card) {
1314 DCHECK_NE(CreditCard::LOCAL_CARD, credit_card.record_type());
1315 sql::Transaction transaction(db_);
1316 if (!transaction.Begin())
1317 return false;
1319 sql::Statement remove(db_->GetUniqueStatement(
1320 "DELETE FROM server_card_metadata WHERE id = ?"));
1321 remove.BindString(0, credit_card.server_id());
1322 remove.Run();
1324 sql::Statement s(db_->GetUniqueStatement(
1325 "INSERT INTO server_card_metadata(use_count, use_date, id)"
1326 "VALUES (?,?,?)"));
1327 s.BindInt64(0, credit_card.use_count());
1328 s.BindInt64(1, credit_card.use_date().ToInternalValue());
1329 s.BindString(2, credit_card.server_id());
1330 s.Run();
1332 transaction.Commit();
1334 return db_->GetLastChangeCount() > 0;
1337 bool AutofillTable::UpdateServerAddressUsageStats(
1338 const AutofillProfile& profile) {
1339 DCHECK_EQ(AutofillProfile::SERVER_PROFILE, profile.record_type());
1341 sql::Transaction transaction(db_);
1342 if (!transaction.Begin())
1343 return false;
1345 sql::Statement remove(db_->GetUniqueStatement(
1346 "DELETE FROM server_address_metadata WHERE id = ?"));
1347 remove.BindString(0, profile.server_id());
1348 remove.Run();
1350 sql::Statement s(db_->GetUniqueStatement(
1351 "INSERT INTO server_address_metadata(use_count, use_date, id)"
1352 "VALUES (?,?,?)"));
1353 s.BindInt64(0, profile.use_count());
1354 s.BindInt64(1, profile.use_date().ToInternalValue());
1355 s.BindString(2, profile.server_id());
1356 s.Run();
1358 transaction.Commit();
1360 return db_->GetLastChangeCount() > 0;
1363 bool AutofillTable::ClearAllServerData() {
1364 sql::Transaction transaction(db_);
1365 if (!transaction.Begin())
1366 return false; // Some error, nothing was changed.
1368 sql::Statement masked(db_->GetUniqueStatement(
1369 "DELETE FROM masked_credit_cards"));
1370 masked.Run();
1371 bool changed = db_->GetLastChangeCount() > 0;
1373 sql::Statement unmasked(db_->GetUniqueStatement(
1374 "DELETE FROM unmasked_credit_cards"));
1375 unmasked.Run();
1376 changed |= db_->GetLastChangeCount() > 0;
1378 sql::Statement addresses(db_->GetUniqueStatement(
1379 "DELETE FROM server_addresses"));
1380 addresses.Run();
1381 changed |= db_->GetLastChangeCount() > 0;
1383 sql::Statement card_metadata(db_->GetUniqueStatement(
1384 "DELETE FROM server_card_metadata"));
1385 card_metadata.Run();
1386 changed |= db_->GetLastChangeCount() > 0;
1388 sql::Statement address_metadata(db_->GetUniqueStatement(
1389 "DELETE FROM server_address_metadata"));
1390 address_metadata.Run();
1391 changed |= db_->GetLastChangeCount() > 0;
1393 transaction.Commit();
1394 return changed;
1397 bool AutofillTable::UpdateCreditCard(const CreditCard& credit_card) {
1398 DCHECK(base::IsValidGUID(credit_card.guid()));
1400 CreditCard* tmp_credit_card = NULL;
1401 if (!GetCreditCard(credit_card.guid(), &tmp_credit_card))
1402 return false;
1404 scoped_ptr<CreditCard> old_credit_card(tmp_credit_card);
1405 bool update_modification_date = *old_credit_card != credit_card;
1407 sql::Statement s(db_->GetUniqueStatement(
1408 "UPDATE credit_cards "
1409 "SET guid=?, name_on_card=?, expiration_month=?,"
1410 "expiration_year=?, card_number_encrypted=?, use_count=?, use_date=?,"
1411 "date_modified=?, origin=?"
1412 "WHERE guid=?"));
1413 BindCreditCardToStatement(
1414 credit_card,
1415 update_modification_date ? base::Time::Now() :
1416 old_credit_card->modification_date(),
1417 &s);
1418 s.BindString(9, credit_card.guid());
1420 bool result = s.Run();
1421 DCHECK_GT(db_->GetLastChangeCount(), 0);
1422 return result;
1425 bool AutofillTable::RemoveCreditCard(const std::string& guid) {
1426 DCHECK(base::IsValidGUID(guid));
1427 sql::Statement s(db_->GetUniqueStatement(
1428 "DELETE FROM credit_cards WHERE guid = ?"));
1429 s.BindString(0, guid);
1431 return s.Run();
1434 bool AutofillTable::RemoveAutofillDataModifiedBetween(
1435 const Time& delete_begin,
1436 const Time& delete_end,
1437 std::vector<std::string>* profile_guids,
1438 std::vector<std::string>* credit_card_guids) {
1439 DCHECK(delete_end.is_null() || delete_begin < delete_end);
1441 time_t delete_begin_t = delete_begin.ToTimeT();
1442 time_t delete_end_t = GetEndTime(delete_end);
1444 // Remember Autofill profiles in the time range.
1445 sql::Statement s_profiles_get(db_->GetUniqueStatement(
1446 "SELECT guid FROM autofill_profiles "
1447 "WHERE date_modified >= ? AND date_modified < ?"));
1448 s_profiles_get.BindInt64(0, delete_begin_t);
1449 s_profiles_get.BindInt64(1, delete_end_t);
1451 profile_guids->clear();
1452 while (s_profiles_get.Step()) {
1453 std::string guid = s_profiles_get.ColumnString(0);
1454 profile_guids->push_back(guid);
1456 if (!s_profiles_get.Succeeded())
1457 return false;
1459 // Remove Autofill profiles in the time range.
1460 sql::Statement s_profiles(db_->GetUniqueStatement(
1461 "DELETE FROM autofill_profiles "
1462 "WHERE date_modified >= ? AND date_modified < ?"));
1463 s_profiles.BindInt64(0, delete_begin_t);
1464 s_profiles.BindInt64(1, delete_end_t);
1466 if (!s_profiles.Run())
1467 return false;
1469 // Remember Autofill credit cards in the time range.
1470 sql::Statement s_credit_cards_get(db_->GetUniqueStatement(
1471 "SELECT guid FROM credit_cards "
1472 "WHERE date_modified >= ? AND date_modified < ?"));
1473 s_credit_cards_get.BindInt64(0, delete_begin_t);
1474 s_credit_cards_get.BindInt64(1, delete_end_t);
1476 credit_card_guids->clear();
1477 while (s_credit_cards_get.Step()) {
1478 std::string guid = s_credit_cards_get.ColumnString(0);
1479 credit_card_guids->push_back(guid);
1481 if (!s_credit_cards_get.Succeeded())
1482 return false;
1484 // Remove Autofill credit cards in the time range.
1485 sql::Statement s_credit_cards(db_->GetUniqueStatement(
1486 "DELETE FROM credit_cards "
1487 "WHERE date_modified >= ? AND date_modified < ?"));
1488 s_credit_cards.BindInt64(0, delete_begin_t);
1489 s_credit_cards.BindInt64(1, delete_end_t);
1490 if (!s_credit_cards.Run())
1491 return false;
1493 // Remove unmasked credit cards in the time range.
1494 sql::Statement s_unmasked_cards(db_->GetUniqueStatement(
1495 "DELETE FROM unmasked_credit_cards "
1496 "WHERE unmask_date >= ? AND unmask_date < ?"));
1497 s_unmasked_cards.BindInt64(0, delete_begin.ToInternalValue());
1498 s_unmasked_cards.BindInt64(1, delete_end.ToInternalValue());
1499 return s_unmasked_cards.Run();
1502 bool AutofillTable::RemoveOriginURLsModifiedBetween(
1503 const Time& delete_begin,
1504 const Time& delete_end,
1505 ScopedVector<AutofillProfile>* profiles) {
1506 DCHECK(delete_end.is_null() || delete_begin < delete_end);
1508 time_t delete_begin_t = delete_begin.ToTimeT();
1509 time_t delete_end_t = GetEndTime(delete_end);
1511 // Remember Autofill profiles with URL origins in the time range.
1512 sql::Statement s_profiles_get(db_->GetUniqueStatement(
1513 "SELECT guid, origin FROM autofill_profiles "
1514 "WHERE date_modified >= ? AND date_modified < ?"));
1515 s_profiles_get.BindInt64(0, delete_begin_t);
1516 s_profiles_get.BindInt64(1, delete_end_t);
1518 std::vector<std::string> profile_guids;
1519 while (s_profiles_get.Step()) {
1520 std::string guid = s_profiles_get.ColumnString(0);
1521 std::string origin = s_profiles_get.ColumnString(1);
1522 if (GURL(origin).is_valid())
1523 profile_guids.push_back(guid);
1525 if (!s_profiles_get.Succeeded())
1526 return false;
1528 // Clear out the origins for the found Autofill profiles.
1529 for (std::vector<std::string>::const_iterator it = profile_guids.begin();
1530 it != profile_guids.end(); ++it) {
1531 sql::Statement s_profile(db_->GetUniqueStatement(
1532 "UPDATE autofill_profiles SET origin='' WHERE guid=?"));
1533 s_profile.BindString(0, *it);
1534 if (!s_profile.Run())
1535 return false;
1537 AutofillProfile* profile;
1538 if (!GetAutofillProfile(*it, &profile))
1539 return false;
1541 profiles->push_back(profile);
1544 // Remember Autofill credit cards with URL origins in the time range.
1545 sql::Statement s_credit_cards_get(db_->GetUniqueStatement(
1546 "SELECT guid, origin FROM credit_cards "
1547 "WHERE date_modified >= ? AND date_modified < ?"));
1548 s_credit_cards_get.BindInt64(0, delete_begin_t);
1549 s_credit_cards_get.BindInt64(1, delete_end_t);
1551 std::vector<std::string> credit_card_guids;
1552 while (s_credit_cards_get.Step()) {
1553 std::string guid = s_credit_cards_get.ColumnString(0);
1554 std::string origin = s_credit_cards_get.ColumnString(1);
1555 if (GURL(origin).is_valid())
1556 credit_card_guids.push_back(guid);
1558 if (!s_credit_cards_get.Succeeded())
1559 return false;
1561 // Clear out the origins for the found credit cards.
1562 for (std::vector<std::string>::const_iterator it = credit_card_guids.begin();
1563 it != credit_card_guids.end(); ++it) {
1564 sql::Statement s_credit_card(db_->GetUniqueStatement(
1565 "UPDATE credit_cards SET origin='' WHERE guid=?"));
1566 s_credit_card.BindString(0, *it);
1567 if (!s_credit_card.Run())
1568 return false;
1571 return true;
1574 bool AutofillTable::GetAutofillProfilesInTrash(
1575 std::vector<std::string>* guids) {
1576 guids->clear();
1578 sql::Statement s(db_->GetUniqueStatement(
1579 "SELECT guid "
1580 "FROM autofill_profiles_trash"));
1582 while (s.Step()) {
1583 std::string guid = s.ColumnString(0);
1584 guids->push_back(guid);
1587 return s.Succeeded();
1590 bool AutofillTable::EmptyAutofillProfilesTrash() {
1591 sql::Statement s(db_->GetUniqueStatement(
1592 "DELETE FROM autofill_profiles_trash"));
1594 return s.Run();
1598 bool AutofillTable::AddAutofillGUIDToTrash(const std::string& guid) {
1599 sql::Statement s(db_->GetUniqueStatement(
1600 "INSERT INTO autofill_profiles_trash"
1601 " (guid) "
1602 "VALUES (?)"));
1603 s.BindString(0, guid);
1605 return s.Run();
1608 bool AutofillTable::IsAutofillProfilesTrashEmpty() {
1609 sql::Statement s(db_->GetUniqueStatement(
1610 "SELECT guid "
1611 "FROM autofill_profiles_trash"));
1613 return !s.Step();
1616 bool AutofillTable::IsAutofillGUIDInTrash(const std::string& guid) {
1617 sql::Statement s(db_->GetUniqueStatement(
1618 "SELECT guid "
1619 "FROM autofill_profiles_trash "
1620 "WHERE guid = ?"));
1621 s.BindString(0, guid);
1623 return s.Step();
1626 bool AutofillTable::InitMainTable() {
1627 if (!db_->DoesTableExist("autofill")) {
1628 if (!db_->Execute("CREATE TABLE autofill ("
1629 "name VARCHAR, "
1630 "value VARCHAR, "
1631 "value_lower VARCHAR, "
1632 "date_created INTEGER DEFAULT 0, "
1633 "date_last_used INTEGER DEFAULT 0, "
1634 "count INTEGER DEFAULT 1, "
1635 "PRIMARY KEY (name, value))") ||
1636 !db_->Execute("CREATE INDEX autofill_name ON autofill (name)") ||
1637 !db_->Execute("CREATE INDEX autofill_name_value_lower ON "
1638 "autofill (name, value_lower)")) {
1639 NOTREACHED();
1640 return false;
1643 return true;
1646 bool AutofillTable::InitCreditCardsTable() {
1647 if (!db_->DoesTableExist("credit_cards")) {
1648 if (!db_->Execute("CREATE TABLE credit_cards ( "
1649 "guid VARCHAR PRIMARY KEY, "
1650 "name_on_card VARCHAR, "
1651 "expiration_month INTEGER, "
1652 "expiration_year INTEGER, "
1653 "card_number_encrypted BLOB, "
1654 "date_modified INTEGER NOT NULL DEFAULT 0, "
1655 "origin VARCHAR DEFAULT '', "
1656 "use_count INTEGER NOT NULL DEFAULT 0, "
1657 "use_date INTEGER NOT NULL DEFAULT 0) ")) {
1658 NOTREACHED();
1659 return false;
1663 return true;
1666 bool AutofillTable::InitProfilesTable() {
1667 if (!db_->DoesTableExist("autofill_profiles")) {
1668 if (!db_->Execute("CREATE TABLE autofill_profiles ( "
1669 "guid VARCHAR PRIMARY KEY, "
1670 "company_name VARCHAR, "
1671 "street_address VARCHAR, "
1672 "dependent_locality VARCHAR, "
1673 "city VARCHAR, "
1674 "state VARCHAR, "
1675 "zipcode VARCHAR, "
1676 "sorting_code VARCHAR, "
1677 "country_code VARCHAR, "
1678 "date_modified INTEGER NOT NULL DEFAULT 0, "
1679 "origin VARCHAR DEFAULT '', "
1680 "language_code VARCHAR, "
1681 "use_count INTEGER NOT NULL DEFAULT 0, "
1682 "use_date INTEGER NOT NULL DEFAULT 0) ")) {
1683 NOTREACHED();
1684 return false;
1687 return true;
1690 bool AutofillTable::InitProfileNamesTable() {
1691 if (!db_->DoesTableExist("autofill_profile_names")) {
1692 if (!db_->Execute("CREATE TABLE autofill_profile_names ( "
1693 "guid VARCHAR, "
1694 "first_name VARCHAR, "
1695 "middle_name VARCHAR, "
1696 "last_name VARCHAR, "
1697 "full_name VARCHAR)")) {
1698 NOTREACHED();
1699 return false;
1702 return true;
1705 bool AutofillTable::InitProfileEmailsTable() {
1706 if (!db_->DoesTableExist("autofill_profile_emails")) {
1707 if (!db_->Execute("CREATE TABLE autofill_profile_emails ( "
1708 "guid VARCHAR, "
1709 "email VARCHAR)")) {
1710 NOTREACHED();
1711 return false;
1714 return true;
1717 bool AutofillTable::InitProfilePhonesTable() {
1718 if (!db_->DoesTableExist("autofill_profile_phones")) {
1719 if (!db_->Execute("CREATE TABLE autofill_profile_phones ( "
1720 "guid VARCHAR, "
1721 "number VARCHAR)")) {
1722 NOTREACHED();
1723 return false;
1726 return true;
1729 bool AutofillTable::InitProfileTrashTable() {
1730 if (!db_->DoesTableExist("autofill_profiles_trash")) {
1731 if (!db_->Execute("CREATE TABLE autofill_profiles_trash ( "
1732 "guid VARCHAR)")) {
1733 NOTREACHED();
1734 return false;
1737 return true;
1740 bool AutofillTable::InitMaskedCreditCardsTable() {
1741 if (!db_->DoesTableExist("masked_credit_cards")) {
1742 if (!db_->Execute("CREATE TABLE masked_credit_cards ("
1743 "id VARCHAR,"
1744 "status VARCHAR,"
1745 "name_on_card VARCHAR,"
1746 "type VARCHAR,"
1747 "last_four VARCHAR,"
1748 "exp_month INTEGER DEFAULT 0,"
1749 "exp_year INTEGER DEFAULT 0)")) {
1750 NOTREACHED();
1751 return false;
1754 return true;
1757 bool AutofillTable::InitUnmaskedCreditCardsTable() {
1758 if (!db_->DoesTableExist("unmasked_credit_cards")) {
1759 if (!db_->Execute("CREATE TABLE unmasked_credit_cards ("
1760 "id VARCHAR,"
1761 "card_number_encrypted VARCHAR, "
1762 "use_count INTEGER NOT NULL DEFAULT 0, "
1763 "use_date INTEGER NOT NULL DEFAULT 0, "
1764 "unmask_date INTEGER NOT NULL DEFAULT 0)")) {
1765 NOTREACHED();
1766 return false;
1769 return true;
1772 bool AutofillTable::InitServerCardMetadataTable() {
1773 if (!db_->DoesTableExist("server_card_metadata")) {
1774 if (!db_->Execute("CREATE TABLE server_card_metadata ("
1775 "id VARCHAR NOT NULL,"
1776 "use_count INTEGER NOT NULL DEFAULT 0, "
1777 "use_date INTEGER NOT NULL DEFAULT 0)")) {
1778 NOTREACHED();
1779 return false;
1782 return true;
1785 bool AutofillTable::InitServerAddressesTable() {
1786 if (!db_->DoesTableExist("server_addresses")) {
1787 // The space after language_code is necessary to match what sqlite does
1788 // when it appends the column in migration.
1789 if (!db_->Execute("CREATE TABLE server_addresses ("
1790 "id VARCHAR,"
1791 "company_name VARCHAR,"
1792 "street_address VARCHAR,"
1793 "address_1 VARCHAR,"
1794 "address_2 VARCHAR,"
1795 "address_3 VARCHAR,"
1796 "address_4 VARCHAR,"
1797 "postal_code VARCHAR,"
1798 "sorting_code VARCHAR,"
1799 "country_code VARCHAR,"
1800 "language_code VARCHAR, " // Space required.
1801 "recipient_name VARCHAR, " // Ditto.
1802 "phone_number VARCHAR)")) {
1803 NOTREACHED();
1804 return false;
1807 return true;
1810 bool AutofillTable::InitServerAddressMetadataTable() {
1811 if (!db_->DoesTableExist("server_address_metadata")) {
1812 if (!db_->Execute("CREATE TABLE server_address_metadata ("
1813 "id VARCHAR NOT NULL,"
1814 "use_count INTEGER NOT NULL DEFAULT 0, "
1815 "use_date INTEGER NOT NULL DEFAULT 0)")) {
1816 NOTREACHED();
1817 return false;
1820 return true;
1823 bool AutofillTable::MigrateToVersion54AddI18nFieldsAndRemoveDeprecatedFields() {
1824 sql::Transaction transaction(db_);
1825 if (!transaction.Begin())
1826 return false;
1828 // Test the existence of the |address_line_1| column as an indication that a
1829 // migration is needed. It is possible that the new |autofill_profile_phones|
1830 // schema is in place because the table was newly created when migrating from
1831 // a pre-version-23 database.
1832 if (db_->DoesColumnExist("autofill_profiles", "address_line_1")) {
1833 // Create a temporary copy of the autofill_profiles table in the (newer)
1834 // version 54 format. This table
1835 // (a) adds columns for street_address, dependent_locality, and
1836 // sorting_code,
1837 // (b) removes the address_line_1 and address_line_2 columns, which are
1838 // replaced by the street_address column, and
1839 // (c) removes the country column, which was long deprecated.
1840 if (db_->DoesTableExist("autofill_profiles_temp") ||
1841 !db_->Execute("CREATE TABLE autofill_profiles_temp ( "
1842 "guid VARCHAR PRIMARY KEY, "
1843 "company_name VARCHAR, "
1844 "street_address VARCHAR, "
1845 "dependent_locality VARCHAR, "
1846 "city VARCHAR, "
1847 "state VARCHAR, "
1848 "zipcode VARCHAR, "
1849 "sorting_code VARCHAR, "
1850 "country_code VARCHAR, "
1851 "date_modified INTEGER NOT NULL DEFAULT 0, "
1852 "origin VARCHAR DEFAULT '')")) {
1853 return false;
1856 // Copy over the data from the autofill_profiles table, taking care to merge
1857 // the address lines 1 and 2 into the new street_address column.
1858 if (!db_->Execute("INSERT INTO autofill_profiles_temp "
1859 "SELECT guid, company_name, '', '', city, state, zipcode,"
1860 " '', country_code, date_modified, origin "
1861 "FROM autofill_profiles")) {
1862 return false;
1864 sql::Statement s(db_->GetUniqueStatement(
1865 "SELECT guid, address_line_1, address_line_2 FROM autofill_profiles"));
1866 while (s.Step()) {
1867 std::string guid = s.ColumnString(0);
1868 base::string16 line1 = s.ColumnString16(1);
1869 base::string16 line2 = s.ColumnString16(2);
1870 base::string16 street_address = line1;
1871 if (!line2.empty())
1872 street_address += base::ASCIIToUTF16("\n") + line2;
1874 sql::Statement s_update(db_->GetUniqueStatement(
1875 "UPDATE autofill_profiles_temp SET street_address=? WHERE guid=?"));
1876 s_update.BindString16(0, street_address);
1877 s_update.BindString(1, guid);
1878 if (!s_update.Run())
1879 return false;
1881 if (!s.Succeeded())
1882 return false;
1884 // Delete the existing (version 53) table and replace it with the contents
1885 // of the temporary table.
1886 if (!db_->Execute("DROP TABLE autofill_profiles") ||
1887 !db_->Execute("ALTER TABLE autofill_profiles_temp "
1888 "RENAME TO autofill_profiles")) {
1889 return false;
1893 // Test the existence of the |type| column as an indication that a migration
1894 // is needed. It is possible that the new |autofill_profile_phones| schema is
1895 // in place because the table was newly created when migrating from a
1896 // pre-version-23 database.
1897 if (db_->DoesColumnExist("autofill_profile_phones", "type")) {
1898 // Create a temporary copy of the autofill_profile_phones table in the
1899 // (newer) version 54 format. This table removes the deprecated |type|
1900 // column.
1901 if (db_->DoesTableExist("autofill_profile_phones_temp") ||
1902 !db_->Execute("CREATE TABLE autofill_profile_phones_temp ( "
1903 "guid VARCHAR, "
1904 "number VARCHAR)")) {
1905 return false;
1908 // Copy over the data from the autofill_profile_phones table.
1909 if (!db_->Execute("INSERT INTO autofill_profile_phones_temp "
1910 "SELECT guid, number FROM autofill_profile_phones")) {
1911 return false;
1914 // Delete the existing (version 53) table and replace it with the contents
1915 // of the temporary table.
1916 if (!db_->Execute("DROP TABLE autofill_profile_phones"))
1917 return false;
1918 if (!db_->Execute("ALTER TABLE autofill_profile_phones_temp "
1919 "RENAME TO autofill_profile_phones")) {
1920 return false;
1924 return transaction.Commit();
1927 bool AutofillTable::MigrateToVersion55MergeAutofillDatesTable() {
1928 sql::Transaction transaction(db_);
1929 if (!transaction.Begin())
1930 return false;
1932 if (db_->DoesTableExist("autofill_temp") ||
1933 !db_->Execute("CREATE TABLE autofill_temp ("
1934 "name VARCHAR, "
1935 "value VARCHAR, "
1936 "value_lower VARCHAR, "
1937 "date_created INTEGER DEFAULT 0, "
1938 "date_last_used INTEGER DEFAULT 0, "
1939 "count INTEGER DEFAULT 1, "
1940 "PRIMARY KEY (name, value))")) {
1941 return false;
1944 // Slurp up the data from the existing table and write it to the new table.
1945 sql::Statement s(db_->GetUniqueStatement(
1946 "SELECT name, value, value_lower, count, MIN(date_created),"
1947 " MAX(date_created) "
1948 "FROM autofill a JOIN autofill_dates ad ON a.pair_id=ad.pair_id "
1949 "GROUP BY name, value, value_lower, count"));
1950 while (s.Step()) {
1951 sql::Statement s_insert(db_->GetUniqueStatement(
1952 "INSERT INTO autofill_temp "
1953 "(name, value, value_lower, count, date_created, date_last_used) "
1954 "VALUES (?, ?, ?, ?, ?, ?)"));
1955 s_insert.BindString16(0, s.ColumnString16(0));
1956 s_insert.BindString16(1, s.ColumnString16(1));
1957 s_insert.BindString16(2, s.ColumnString16(2));
1958 s_insert.BindInt(3, s.ColumnInt(3));
1959 s_insert.BindInt64(4, s.ColumnInt64(4));
1960 s_insert.BindInt64(5, s.ColumnInt64(5));
1961 if (!s_insert.Run())
1962 return false;
1965 if (!s.Succeeded())
1966 return false;
1968 // Delete the existing (version 54) tables and replace them with the contents
1969 // of the temporary table.
1970 if (!db_->Execute("DROP TABLE autofill") ||
1971 !db_->Execute("DROP TABLE autofill_dates") ||
1972 !db_->Execute("ALTER TABLE autofill_temp "
1973 "RENAME TO autofill")) {
1974 return false;
1977 // Create indices on the new table, for fast lookups.
1978 if (!db_->Execute("CREATE INDEX autofill_name ON autofill (name)") ||
1979 !db_->Execute("CREATE INDEX autofill_name_value_lower ON "
1980 "autofill (name, value_lower)")) {
1981 return false;
1985 return transaction.Commit();
1988 bool AutofillTable::MigrateToVersion56AddProfileLanguageCodeForFormatting() {
1989 return db_->Execute("ALTER TABLE autofill_profiles "
1990 "ADD COLUMN language_code VARCHAR");
1993 bool AutofillTable::MigrateToVersion57AddFullNameField() {
1994 return db_->Execute("ALTER TABLE autofill_profile_names "
1995 "ADD COLUMN full_name VARCHAR");
1998 bool AutofillTable::MigrateToVersion60AddServerCards() {
1999 sql::Transaction transaction(db_);
2000 if (!transaction.Begin())
2001 return false;
2003 if (!db_->DoesTableExist("masked_credit_cards") &&
2004 !db_->Execute("CREATE TABLE masked_credit_cards ("
2005 "id VARCHAR,"
2006 "status VARCHAR,"
2007 "name_on_card VARCHAR,"
2008 "type VARCHAR,"
2009 "last_four VARCHAR,"
2010 "exp_month INTEGER DEFAULT 0,"
2011 "exp_year INTEGER DEFAULT 0)")) {
2012 return false;
2015 if (!db_->DoesTableExist("unmasked_credit_cards") &&
2016 !db_->Execute("CREATE TABLE unmasked_credit_cards ("
2017 "id VARCHAR,"
2018 "card_number_encrypted VARCHAR)")) {
2019 return false;
2022 if (!db_->DoesTableExist("server_addresses") &&
2023 !db_->Execute("CREATE TABLE server_addresses ("
2024 "id VARCHAR,"
2025 "company_name VARCHAR,"
2026 "street_address VARCHAR,"
2027 "address_1 VARCHAR,"
2028 "address_2 VARCHAR,"
2029 "address_3 VARCHAR,"
2030 "address_4 VARCHAR,"
2031 "postal_code VARCHAR,"
2032 "sorting_code VARCHAR,"
2033 "country_code VARCHAR,"
2034 "language_code VARCHAR)")) {
2035 return false;
2038 return transaction.Commit();
2041 bool AutofillTable::MigrateToVersion61AddUsageStats() {
2042 sql::Transaction transaction(db_);
2043 if (!transaction.Begin())
2044 return false;
2046 // Add use_count to autofill_profiles.
2047 if (!db_->DoesColumnExist("autofill_profiles", "use_count") &&
2048 !db_->Execute("ALTER TABLE autofill_profiles ADD COLUMN "
2049 "use_count INTEGER NOT NULL DEFAULT 0")) {
2050 return false;
2053 // Add use_date to autofill_profiles.
2054 if (!db_->DoesColumnExist("autofill_profiles", "use_date") &&
2055 !db_->Execute("ALTER TABLE autofill_profiles ADD COLUMN "
2056 "use_date INTEGER NOT NULL DEFAULT 0")) {
2057 return false;
2060 // Add use_count to credit_cards.
2061 if (!db_->DoesColumnExist("credit_cards", "use_count") &&
2062 !db_->Execute("ALTER TABLE credit_cards ADD COLUMN "
2063 "use_count INTEGER NOT NULL DEFAULT 0")) {
2064 return false;
2067 // Add use_date to credit_cards.
2068 if (!db_->DoesColumnExist("credit_cards", "use_date") &&
2069 !db_->Execute("ALTER TABLE credit_cards ADD COLUMN "
2070 "use_date INTEGER NOT NULL DEFAULT 0")) {
2071 return false;
2074 return transaction.Commit();
2077 bool AutofillTable::MigrateToVersion62AddUsageStatsForUnmaskedCards() {
2078 sql::Transaction transaction(db_);
2079 if (!transaction.Begin())
2080 return false;
2082 // Add use_count to unmasked_credit_cards.
2083 if (!db_->DoesColumnExist("unmasked_credit_cards", "use_count") &&
2084 !db_->Execute("ALTER TABLE unmasked_credit_cards ADD COLUMN "
2085 "use_count INTEGER NOT NULL DEFAULT 0")) {
2086 return false;
2089 // Add use_date to unmasked_credit_cards.
2090 if (!db_->DoesColumnExist("unmasked_credit_cards", "use_date") &&
2091 !db_->Execute("ALTER TABLE unmasked_credit_cards ADD COLUMN "
2092 "use_date INTEGER NOT NULL DEFAULT 0")) {
2093 return false;
2096 return transaction.Commit();
2099 bool AutofillTable::MigrateToVersion63AddServerRecipientName() {
2100 if (!db_->DoesColumnExist("server_addresses", "recipient_name") &&
2101 !db_->Execute("ALTER TABLE server_addresses ADD COLUMN "
2102 "recipient_name VARCHAR")) {
2103 return false;
2105 return true;
2108 bool AutofillTable::MigrateToVersion64AddUnmaskDate() {
2109 sql::Transaction transaction(db_);
2110 if (!transaction.Begin())
2111 return false;
2113 if (!db_->DoesColumnExist("unmasked_credit_cards", "unmask_date") &&
2114 !db_->Execute("ALTER TABLE unmasked_credit_cards ADD COLUMN "
2115 "unmask_date INTEGER NOT NULL DEFAULT 0")) {
2116 return false;
2118 if (!db_->DoesColumnExist("server_addresses", "phone_number") &&
2119 !db_->Execute("ALTER TABLE server_addresses ADD COLUMN "
2120 "phone_number VARCHAR")) {
2121 return false;
2124 return transaction.Commit();
2127 bool AutofillTable::MigrateToVersion65AddServerMetadataTables() {
2128 sql::Transaction transaction(db_);
2129 if (!transaction.Begin())
2130 return false;
2132 if (!db_->DoesTableExist("server_card_metadata") &&
2133 !db_->Execute("CREATE TABLE server_card_metadata ("
2134 "id VARCHAR NOT NULL,"
2135 "use_count INTEGER NOT NULL DEFAULT 0, "
2136 "use_date INTEGER NOT NULL DEFAULT 0)")) {
2137 return false;
2140 // This clobbers existing usage metadata, which is not synced and only
2141 // applies to unmasked cards. Trying to migrate the usage metadata would be
2142 // tricky as multiple devices for the same user get DB upgrades.
2143 if (!db_->Execute("UPDATE unmasked_credit_cards "
2144 "SET use_count=0, use_date=0")) {
2145 return false;
2148 if (!db_->DoesTableExist("server_address_metadata") &&
2149 !db_->Execute("CREATE TABLE server_address_metadata ("
2150 "id VARCHAR NOT NULL,"
2151 "use_count INTEGER NOT NULL DEFAULT 0, "
2152 "use_date INTEGER NOT NULL DEFAULT 0)")) {
2153 return false;
2156 // Get existing server addresses and generate IDs for them.
2157 sql::Statement s(db_->GetUniqueStatement(
2158 "SELECT "
2159 "id,"
2160 "recipient_name,"
2161 "company_name,"
2162 "street_address,"
2163 "address_1," // ADDRESS_HOME_STATE
2164 "address_2," // ADDRESS_HOME_CITY
2165 "address_3," // ADDRESS_HOME_DEPENDENT_LOCALITY
2166 "address_4," // Not supported in AutofillProfile yet.
2167 "postal_code," // ADDRESS_HOME_ZIP
2168 "sorting_code," // ADDRESS_HOME_SORTING_CODE
2169 "country_code," // ADDRESS_HOME_COUNTRY
2170 "phone_number," // PHONE_HOME_WHOLE_NUMBER
2171 "language_code "
2172 "FROM server_addresses addresses"));
2173 std::vector<AutofillProfile> profiles;
2174 while (s.Step()) {
2175 int index = 0;
2176 AutofillProfile profile(
2177 AutofillProfile::SERVER_PROFILE, s.ColumnString(index++));
2179 base::string16 recipient_name = s.ColumnString16(index++);
2180 profile.SetRawInfo(COMPANY_NAME, s.ColumnString16(index++));
2181 profile.SetRawInfo(ADDRESS_HOME_STREET_ADDRESS, s.ColumnString16(index++));
2182 profile.SetRawInfo(ADDRESS_HOME_STATE, s.ColumnString16(index++));
2183 profile.SetRawInfo(ADDRESS_HOME_CITY, s.ColumnString16(index++));
2184 profile.SetRawInfo(ADDRESS_HOME_DEPENDENT_LOCALITY,
2185 s.ColumnString16(index++));
2186 index++; // Skip address_4 which we haven't added to AutofillProfile yet.
2187 profile.SetRawInfo(ADDRESS_HOME_ZIP, s.ColumnString16(index++));
2188 profile.SetRawInfo(ADDRESS_HOME_SORTING_CODE, s.ColumnString16(index++));
2189 profile.SetRawInfo(ADDRESS_HOME_COUNTRY, s.ColumnString16(index++));
2190 base::string16 phone_number = s.ColumnString16(index++);
2191 profile.set_language_code(s.ColumnString(index++));
2192 profile.SetInfo(AutofillType(NAME_FULL), recipient_name,
2193 profile.language_code());
2194 profile.SetInfo(AutofillType(PHONE_HOME_WHOLE_NUMBER), phone_number,
2195 profile.language_code());
2196 profile.GenerateServerProfileIdentifier();
2197 profiles.push_back(profile);
2200 // Reinsert with the generated IDs.
2201 sql::Statement delete_old(db_->GetUniqueStatement(
2202 "DELETE FROM server_addresses"));
2203 delete_old.Run();
2205 sql::Statement insert(db_->GetUniqueStatement(
2206 "INSERT INTO server_addresses("
2207 "id,"
2208 "recipient_name,"
2209 "company_name,"
2210 "street_address,"
2211 "address_1," // ADDRESS_HOME_STATE
2212 "address_2," // ADDRESS_HOME_CITY
2213 "address_3," // ADDRESS_HOME_DEPENDENT_LOCALITY
2214 "address_4," // Not supported in AutofillProfile yet.
2215 "postal_code," // ADDRESS_HOME_ZIP
2216 "sorting_code," // ADDRESS_HOME_SORTING_CODE
2217 "country_code," // ADDRESS_HOME_COUNTRY
2218 "phone_number," // PHONE_HOME_WHOLE_NUMBER
2219 "language_code) "
2220 "VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?)"));
2221 for (const AutofillProfile& profile : profiles) {
2222 int index = 0;
2223 insert.BindString(index++, profile.server_id());
2224 insert.BindString16(index++, profile.GetRawInfo(NAME_FULL));
2225 insert.BindString16(index++, profile.GetRawInfo(COMPANY_NAME));
2226 insert.BindString16(index++,
2227 profile.GetRawInfo(ADDRESS_HOME_STREET_ADDRESS));
2228 insert.BindString16(index++, profile.GetRawInfo(ADDRESS_HOME_STATE));
2229 insert.BindString16(index++, profile.GetRawInfo(ADDRESS_HOME_CITY));
2230 insert.BindString16(index++,
2231 profile.GetRawInfo(ADDRESS_HOME_DEPENDENT_LOCALITY));
2232 index++; // SKip address_4 which we haven't added to AutofillProfile yet.
2233 insert.BindString16(index++, profile.GetRawInfo(ADDRESS_HOME_ZIP));
2234 insert.BindString16(index++, profile.GetRawInfo(ADDRESS_HOME_SORTING_CODE));
2235 insert.BindString16(index++, profile.GetRawInfo(ADDRESS_HOME_COUNTRY));
2236 insert.BindString16(index++, profile.GetRawInfo(PHONE_HOME_WHOLE_NUMBER));
2237 insert.BindString(index++, profile.language_code());
2238 insert.Run();
2239 insert.Reset(true);
2242 return transaction.Commit();
2245 } // namespace autofill