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"
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"
39 using base::ASCIIToUTF16
;
45 // The period after which autocomplete entries should expire in days.
46 const int64 kExpirationPeriodInDays
= 60;
53 // Helper struct for AutofillTable::RemoveFormElementsAddedBetween().
54 // Contains all the necessary fields to update a row in the 'autofill' table.
55 struct AutofillUpdate
{
59 time_t date_last_used
;
63 // Rounds a positive floating point number to the nearest integer.
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
);
80 void BindAutofillProfileToStatement(const AutofillProfile
& profile
,
81 const base::Time
& modification_date
,
83 DCHECK(base::IsValidGUID(profile
.guid()));
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
);
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
,
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
,
140 DCHECK(base::IsValidGUID(credit_card
.guid()));
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
,
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
);
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 "
198 s
.BindString(0, profile
->guid());
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
;
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));
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
);
224 bool AddAutofillProfileEmailsToProfile(sql::Connection
* db
,
225 AutofillProfile
* profile
) {
226 sql::Statement
s(db
->GetUniqueStatement(
227 "SELECT guid, email "
228 "FROM autofill_profile_emails "
230 s
.BindString(0, profile
->guid());
235 std::vector
<base::string16
> emails
;
237 DCHECK_EQ(profile
->guid(), s
.ColumnString(0));
238 emails
.push_back(s
.ColumnString16(1));
243 profile
->SetRawMultiInfo(EMAIL_ADDRESS
, emails
);
247 bool AddAutofillProfilePhonesToProfile(sql::Connection
* db
,
248 AutofillProfile
* profile
) {
249 sql::Statement
s(db
->GetUniqueStatement(
250 "SELECT guid, number "
251 "FROM autofill_profile_phones "
253 s
.BindString(0, profile
->guid());
258 std::vector
<base::string16
> numbers
;
260 DCHECK_EQ(profile
->guid(), s
.ColumnString(0));
261 numbers
.push_back(s
.ColumnString16(1));
266 profile
->SetRawMultiInfo(PHONE_HOME_WHOLE_NUMBER
, numbers
);
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
) {
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
]);
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"
313 s
.BindString(0, profile
.guid());
314 s
.BindString16(1, emails
[i
]);
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"
334 s
.BindString(0, profile
.guid());
335 s
.BindString16(1, numbers
[i
]);
344 bool AddAutofillProfilePieces(const AutofillProfile
& profile
,
345 sql::Connection
* db
) {
346 if (!AddAutofillProfileNames(profile
, db
))
349 if (!AddAutofillProfileEmails(profile
, db
))
352 if (!AddAutofillProfilePhones(profile
, db
))
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
);
366 sql::Statement
s2(db
->GetUniqueStatement(
367 "DELETE FROM autofill_profile_emails WHERE guid = ?"));
368 s2
.BindString(0, guid
);
373 sql::Statement
s3(db
->GetUniqueStatement(
374 "DELETE FROM autofill_profile_phones WHERE guid = ?"));
375 s3
.BindString(0, guid
);
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
) {
396 case CreditCard::EXPIRED
:
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
;
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 {
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() {
448 bool AutofillTable::MigrateToVersion(int version
,
449 bool* update_compatible_version
) {
450 // Migrate if necessary.
453 *update_compatible_version
= true;
454 return MigrateToVersion54AddI18nFieldsAndRemoveDeprecatedFields();
456 *update_compatible_version
= true;
457 return MigrateToVersion55MergeAutofillDatesTable();
459 *update_compatible_version
= true;
460 return MigrateToVersion56AddProfileLanguageCodeForFormatting();
462 *update_compatible_version
= true;
463 return MigrateToVersion57AddFullNameField();
465 *update_compatible_version
= false;
466 return MigrateToVersion60AddServerCards();
468 *update_compatible_version
= false;
469 return MigrateToVersion61AddUsageStats();
471 *update_compatible_version
= false;
472 return MigrateToVersion62AddUsageStatsForUnmaskedCards();
474 *update_compatible_version
= false;
475 return MigrateToVersion63AddServerRecipientName();
477 *update_compatible_version
= false;
478 return MigrateToVersion64AddUnmaskDate();
480 *update_compatible_version
= false;
481 return MigrateToVersion65AddServerMetadataTables();
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
,
505 if (prefix
.empty()) {
506 s
.Assign(db_
->GetUniqueStatement(
507 "SELECT value FROM autofill "
509 "ORDER BY count DESC "
511 s
.BindString16(0, name
);
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 "
523 "ORDER BY count DESC "
525 s
.BindString16(0, name
);
526 s
.BindString16(1, prefix_lower
);
527 s
.BindString16(2, next_prefix
);
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"));
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
;
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
;
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
:
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
)));
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())
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
);
646 if (!transaction
.Commit())
649 *changes
= tentative_changes
;
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())
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())
680 *changes
= tentative_changes
;
684 bool AutofillTable::AddFormFieldValuesTime(
685 const std::vector
<FormFieldData
>& elements
,
686 std::vector
<AutofillChange
>* changes
,
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
;
693 for (std::vector
<FormFieldData
>::const_iterator itr
= elements
.begin();
694 itr
!= elements
.end(); ++itr
) {
695 if (seen_names
.size() >= kMaximumUniqueNames
)
697 if (seen_names
.find(itr
->name
) != seen_names
.end())
699 result
= result
&& AddFormFieldValueTime(*itr
, changes
, time
);
700 seen_names
.insert(itr
->name
);
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"));
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));
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
,
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
);
733 *date_created
= Time::FromTimeT(s
.ColumnInt64(0));
734 *date_last_used
= Time::FromTimeT(s
.ColumnInt64(1));
740 bool AutofillTable::UpdateAutofillEntries(
741 const std::vector
<AutofillEntry
>& entries
) {
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());
755 // Insert all the supplied autofill entries.
756 for (size_t i
= 0; i
< entries
.size(); ++i
) {
757 if (!InsertAutofillEntry(entries
[i
]))
764 bool AutofillTable::InsertAutofillEntry(const AutofillEntry
& entry
) {
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);
783 bool AutofillTable::AddFormFieldValueTime(const FormFieldData
& element
,
784 std::vector
<AutofillChange
>* changes
,
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())
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
);
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
);
819 AutofillChange::Type change_type
=
820 already_exists
? AutofillChange::UPDATE
: AutofillChange::ADD
;
822 AutofillChange(change_type
, AutofillKey(element
.name
, element
.value
)));
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
);
836 bool AutofillTable::AddAutofillProfile(const AutofillProfile
& profile
) {
837 if (IsAutofillGUIDInTrash(profile
.guid()))
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
);
851 return AddAutofillProfilePieces(profile
, db_
);
854 bool AutofillTable::GetAutofillProfile(const std::string
& guid
,
855 AutofillProfile
** profile
) {
856 DCHECK(base::IsValidGUID(guid
));
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 "
864 s
.BindString(0, guid
);
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();
884 bool AutofillTable::GetAutofillProfiles(
885 std::vector
<AutofillProfile
*>* profiles
) {
889 sql::Statement
s(db_
->GetUniqueStatement(
891 "FROM autofill_profiles "
892 "ORDER BY date_modified DESC, guid"));
895 std::string guid
= s
.ColumnString(0);
896 AutofillProfile
* profile
= NULL
;
897 if (!GetAutofillProfile(guid
, &profile
))
899 profiles
->push_back(profile
);
902 return s
.Succeeded();
905 bool AutofillTable::GetServerProfiles(std::vector
<AutofillProfile
*>* profiles
) {
908 sql::Statement
s(db_
->GetUniqueStatement(
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
925 "FROM server_addresses addresses "
926 "LEFT OUTER JOIN server_address_metadata USING (id)"));
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())
969 // Delete all old ones first.
970 sql::Statement
delete_old(db_
->GetUniqueStatement(
971 "DELETE FROM server_addresses"));
974 sql::Statement
insert(db_
->GetUniqueStatement(
975 "INSERT INTO server_addresses("
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
989 "VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?)"));
990 for (const auto& profile
: profiles
) {
991 DCHECK(profile
.record_type() == AutofillProfile::SERVER_PROFILE
);
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());
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())
1031 AutofillProfile
* tmp_profile
= NULL
;
1032 if (!GetAutofillProfile(profile
.guid(), &tmp_profile
))
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=? "
1044 BindAutofillProfileToStatement(
1046 update_modification_date
? base::Time::Now() :
1047 old_profile
->modification_date(),
1049 s
.BindString(14, profile
.guid());
1051 bool result
= s
.Run();
1052 DCHECK_GT(db_
->GetLastChangeCount(), 0);
1056 // Remove the old names, emails, and phone numbers.
1057 if (!RemoveAutofillProfilePieces(profile
.guid(), db_
))
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";
1076 sql::Statement
s(db_
->GetUniqueStatement(
1077 "DELETE FROM autofill_profiles WHERE guid = ?"));
1078 s
.BindString(0, guid
);
1083 return RemoveAutofillProfilePieces(guid
, db_
);
1086 bool AutofillTable::ClearAutofillProfiles() {
1087 sql::Statement
s1(db_
->GetUniqueStatement(
1088 "DELETE FROM autofill_profiles"));
1093 sql::Statement
s2(db_
->GetUniqueStatement(
1094 "DELETE FROM autofill_profile_names"));
1099 sql::Statement
s3(db_
->GetUniqueStatement(
1100 "DELETE FROM autofill_profile_emails"));
1105 sql::Statement
s4(db_
->GetUniqueStatement(
1106 "DELETE FROM autofill_profile_phones"));
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
);
1122 DCHECK_GT(db_
->GetLastChangeCount(), 0);
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, "
1133 "FROM credit_cards "
1135 s
.BindString(0, guid
);
1140 *credit_card
= CreditCardFromStatement(s
).release();
1144 bool AutofillTable::GetCreditCards(
1145 std::vector
<CreditCard
*>* credit_cards
) {
1146 DCHECK(credit_cards
);
1147 credit_cards
->clear();
1149 sql::Statement
s(db_
->GetUniqueStatement(
1151 "FROM credit_cards "
1152 "ORDER BY date_modified DESC, guid"));
1155 std::string guid
= s
.ColumnString(0);
1156 CreditCard
* credit_card
= NULL
;
1157 if (!GetCreditCard(guid
, &credit_card
))
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(
1171 "card_number_encrypted, " // 0
1174 "metadata.use_count," // 3
1175 "metadata.use_date," // 4
1178 "name_on_card," // 7
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)"));
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
);
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());
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())
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("
1239 "name_on_card," // 3
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("
1282 "card_number_encrypted,"
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
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
);
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())
1319 sql::Statement
remove(db_
->GetUniqueStatement(
1320 "DELETE FROM server_card_metadata WHERE id = ?"));
1321 remove
.BindString(0, credit_card
.server_id());
1324 sql::Statement
s(db_
->GetUniqueStatement(
1325 "INSERT INTO server_card_metadata(use_count, use_date, id)"
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());
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())
1345 sql::Statement
remove(db_
->GetUniqueStatement(
1346 "DELETE FROM server_address_metadata WHERE id = ?"));
1347 remove
.BindString(0, profile
.server_id());
1350 sql::Statement
s(db_
->GetUniqueStatement(
1351 "INSERT INTO server_address_metadata(use_count, use_date, id)"
1353 s
.BindInt64(0, profile
.use_count());
1354 s
.BindInt64(1, profile
.use_date().ToInternalValue());
1355 s
.BindString(2, profile
.server_id());
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"));
1371 bool changed
= db_
->GetLastChangeCount() > 0;
1373 sql::Statement
unmasked(db_
->GetUniqueStatement(
1374 "DELETE FROM unmasked_credit_cards"));
1376 changed
|= db_
->GetLastChangeCount() > 0;
1378 sql::Statement
addresses(db_
->GetUniqueStatement(
1379 "DELETE FROM server_addresses"));
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();
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
))
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=?"
1413 BindCreditCardToStatement(
1415 update_modification_date
? base::Time::Now() :
1416 old_credit_card
->modification_date(),
1418 s
.BindString(9, credit_card
.guid());
1420 bool result
= s
.Run();
1421 DCHECK_GT(db_
->GetLastChangeCount(), 0);
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
);
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())
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())
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())
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())
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())
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())
1537 AutofillProfile
* profile
;
1538 if (!GetAutofillProfile(*it
, &profile
))
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())
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())
1574 bool AutofillTable::GetAutofillProfilesInTrash(
1575 std::vector
<std::string
>* guids
) {
1578 sql::Statement
s(db_
->GetUniqueStatement(
1580 "FROM autofill_profiles_trash"));
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"));
1598 bool AutofillTable::AddAutofillGUIDToTrash(const std::string
& guid
) {
1599 sql::Statement
s(db_
->GetUniqueStatement(
1600 "INSERT INTO autofill_profiles_trash"
1603 s
.BindString(0, guid
);
1608 bool AutofillTable::IsAutofillProfilesTrashEmpty() {
1609 sql::Statement
s(db_
->GetUniqueStatement(
1611 "FROM autofill_profiles_trash"));
1616 bool AutofillTable::IsAutofillGUIDInTrash(const std::string
& guid
) {
1617 sql::Statement
s(db_
->GetUniqueStatement(
1619 "FROM autofill_profiles_trash "
1621 s
.BindString(0, guid
);
1626 bool AutofillTable::InitMainTable() {
1627 if (!db_
->DoesTableExist("autofill")) {
1628 if (!db_
->Execute("CREATE TABLE autofill ("
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)")) {
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) ")) {
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, "
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) ")) {
1690 bool AutofillTable::InitProfileNamesTable() {
1691 if (!db_
->DoesTableExist("autofill_profile_names")) {
1692 if (!db_
->Execute("CREATE TABLE autofill_profile_names ( "
1694 "first_name VARCHAR, "
1695 "middle_name VARCHAR, "
1696 "last_name VARCHAR, "
1697 "full_name VARCHAR)")) {
1705 bool AutofillTable::InitProfileEmailsTable() {
1706 if (!db_
->DoesTableExist("autofill_profile_emails")) {
1707 if (!db_
->Execute("CREATE TABLE autofill_profile_emails ( "
1709 "email VARCHAR)")) {
1717 bool AutofillTable::InitProfilePhonesTable() {
1718 if (!db_
->DoesTableExist("autofill_profile_phones")) {
1719 if (!db_
->Execute("CREATE TABLE autofill_profile_phones ( "
1721 "number VARCHAR)")) {
1729 bool AutofillTable::InitProfileTrashTable() {
1730 if (!db_
->DoesTableExist("autofill_profiles_trash")) {
1731 if (!db_
->Execute("CREATE TABLE autofill_profiles_trash ( "
1740 bool AutofillTable::InitMaskedCreditCardsTable() {
1741 if (!db_
->DoesTableExist("masked_credit_cards")) {
1742 if (!db_
->Execute("CREATE TABLE masked_credit_cards ("
1745 "name_on_card VARCHAR,"
1747 "last_four VARCHAR,"
1748 "exp_month INTEGER DEFAULT 0,"
1749 "exp_year INTEGER DEFAULT 0)")) {
1757 bool AutofillTable::InitUnmaskedCreditCardsTable() {
1758 if (!db_
->DoesTableExist("unmasked_credit_cards")) {
1759 if (!db_
->Execute("CREATE TABLE unmasked_credit_cards ("
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)")) {
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)")) {
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 ("
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)")) {
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)")) {
1823 bool AutofillTable::MigrateToVersion54AddI18nFieldsAndRemoveDeprecatedFields() {
1824 sql::Transaction
transaction(db_
);
1825 if (!transaction
.Begin())
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
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, "
1849 "sorting_code VARCHAR, "
1850 "country_code VARCHAR, "
1851 "date_modified INTEGER NOT NULL DEFAULT 0, "
1852 "origin VARCHAR DEFAULT '')")) {
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")) {
1864 sql::Statement
s(db_
->GetUniqueStatement(
1865 "SELECT guid, address_line_1, address_line_2 FROM autofill_profiles"));
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
;
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())
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")) {
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|
1901 if (db_
->DoesTableExist("autofill_profile_phones_temp") ||
1902 !db_
->Execute("CREATE TABLE autofill_profile_phones_temp ( "
1904 "number VARCHAR)")) {
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")) {
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"))
1918 if (!db_
->Execute("ALTER TABLE autofill_profile_phones_temp "
1919 "RENAME TO autofill_profile_phones")) {
1924 return transaction
.Commit();
1927 bool AutofillTable::MigrateToVersion55MergeAutofillDatesTable() {
1928 sql::Transaction
transaction(db_
);
1929 if (!transaction
.Begin())
1932 if (db_
->DoesTableExist("autofill_temp") ||
1933 !db_
->Execute("CREATE TABLE autofill_temp ("
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))")) {
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"));
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())
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")) {
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)")) {
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())
2003 if (!db_
->DoesTableExist("masked_credit_cards") &&
2004 !db_
->Execute("CREATE TABLE masked_credit_cards ("
2007 "name_on_card VARCHAR,"
2009 "last_four VARCHAR,"
2010 "exp_month INTEGER DEFAULT 0,"
2011 "exp_year INTEGER DEFAULT 0)")) {
2015 if (!db_
->DoesTableExist("unmasked_credit_cards") &&
2016 !db_
->Execute("CREATE TABLE unmasked_credit_cards ("
2018 "card_number_encrypted VARCHAR)")) {
2022 if (!db_
->DoesTableExist("server_addresses") &&
2023 !db_
->Execute("CREATE TABLE server_addresses ("
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)")) {
2038 return transaction
.Commit();
2041 bool AutofillTable::MigrateToVersion61AddUsageStats() {
2042 sql::Transaction
transaction(db_
);
2043 if (!transaction
.Begin())
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")) {
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")) {
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")) {
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")) {
2074 return transaction
.Commit();
2077 bool AutofillTable::MigrateToVersion62AddUsageStatsForUnmaskedCards() {
2078 sql::Transaction
transaction(db_
);
2079 if (!transaction
.Begin())
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")) {
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")) {
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")) {
2108 bool AutofillTable::MigrateToVersion64AddUnmaskDate() {
2109 sql::Transaction
transaction(db_
);
2110 if (!transaction
.Begin())
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")) {
2118 if (!db_
->DoesColumnExist("server_addresses", "phone_number") &&
2119 !db_
->Execute("ALTER TABLE server_addresses ADD COLUMN "
2120 "phone_number VARCHAR")) {
2124 return transaction
.Commit();
2127 bool AutofillTable::MigrateToVersion65AddServerMetadataTables() {
2128 sql::Transaction
transaction(db_
);
2129 if (!transaction
.Begin())
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)")) {
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")) {
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)")) {
2156 // Get existing server addresses and generate IDs for them.
2157 sql::Statement
s(db_
->GetUniqueStatement(
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
2172 "FROM server_addresses addresses"));
2173 std::vector
<AutofillProfile
> profiles
;
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"));
2205 sql::Statement
insert(db_
->GetUniqueStatement(
2206 "INSERT INTO server_addresses("
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
2220 "VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?)"));
2221 for (const AutofillProfile
& profile
: profiles
) {
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());
2242 return transaction
.Commit();
2245 } // namespace autofill