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/string_util.h"
22 #include "base/strings/utf_string_conversions.h"
23 #include "base/time/time.h"
24 #include "components/autofill/core/browser/autofill_country.h"
25 #include "components/autofill/core/browser/autofill_profile.h"
26 #include "components/autofill/core/browser/autofill_type.h"
27 #include "components/autofill/core/browser/credit_card.h"
28 #include "components/autofill/core/browser/personal_data_manager.h"
29 #include "components/autofill/core/browser/webdata/autofill_change.h"
30 #include "components/autofill/core/browser/webdata/autofill_entry.h"
31 #include "components/autofill/core/common/autofill_switches.h"
32 #include "components/autofill/core/common/autofill_util.h"
33 #include "components/autofill/core/common/form_field_data.h"
34 #include "components/os_crypt/os_crypt.h"
35 #include "components/webdata/common/web_database.h"
36 #include "sql/statement.h"
37 #include "sql/transaction.h"
38 #include "ui/base/l10n/l10n_util.h"
41 using base::ASCIIToUTF16
;
43 using base::TimeDelta
;
48 // The period after which autocomplete entries should expire in days.
49 const int64 kExpirationPeriodInDays
= 60;
51 // Helper struct for AutofillTable::RemoveFormElementsAddedBetween().
52 // Contains all the necessary fields to update a row in the 'autofill' table.
53 struct AutofillUpdate
{
57 time_t date_last_used
;
61 // Rounds a positive floating point number to the nearest integer.
64 return base::checked_cast
<int>(std::floor(f
+ 0.5f
));
67 // Returns the |data_model|'s value corresponding to the |type|, trimmed to the
68 // maximum length that can be stored in a column of the Autofill database.
69 base::string16
GetInfo(const AutofillDataModel
& data_model
,
70 ServerFieldType type
) {
71 base::string16 data
= data_model
.GetRawInfo(type
);
72 if (data
.size() > AutofillTable::kMaxDataLength
)
73 return data
.substr(0, AutofillTable::kMaxDataLength
);
78 void BindAutofillProfileToStatement(const AutofillProfile
& profile
,
79 const Time
& modification_date
,
81 DCHECK(base::IsValidGUID(profile
.guid()));
83 s
->BindString(index
++, profile
.guid());
85 s
->BindString16(index
++, GetInfo(profile
, COMPANY_NAME
));
86 s
->BindString16(index
++, GetInfo(profile
, ADDRESS_HOME_STREET_ADDRESS
));
87 s
->BindString16(index
++, GetInfo(profile
, ADDRESS_HOME_DEPENDENT_LOCALITY
));
88 s
->BindString16(index
++, GetInfo(profile
, ADDRESS_HOME_CITY
));
89 s
->BindString16(index
++, GetInfo(profile
, ADDRESS_HOME_STATE
));
90 s
->BindString16(index
++, GetInfo(profile
, ADDRESS_HOME_ZIP
));
91 s
->BindString16(index
++, GetInfo(profile
, ADDRESS_HOME_SORTING_CODE
));
92 s
->BindString16(index
++, GetInfo(profile
, ADDRESS_HOME_COUNTRY
));
93 s
->BindInt64(index
++, profile
.use_count());
94 s
->BindInt64(index
++, profile
.use_date().ToTimeT());
95 s
->BindInt64(index
++, modification_date
.ToTimeT());
96 s
->BindString(index
++, profile
.origin());
97 s
->BindString(index
++, profile
.language_code());
100 scoped_ptr
<AutofillProfile
> AutofillProfileFromStatement(
101 const sql::Statement
& s
) {
102 scoped_ptr
<AutofillProfile
> profile(new AutofillProfile
);
104 profile
->set_guid(s
.ColumnString(index
++));
105 DCHECK(base::IsValidGUID(profile
->guid()));
107 profile
->SetRawInfo(COMPANY_NAME
, s
.ColumnString16(index
++));
108 profile
->SetRawInfo(ADDRESS_HOME_STREET_ADDRESS
, s
.ColumnString16(index
++));
109 profile
->SetRawInfo(ADDRESS_HOME_DEPENDENT_LOCALITY
,
110 s
.ColumnString16(index
++));
111 profile
->SetRawInfo(ADDRESS_HOME_CITY
, s
.ColumnString16(index
++));
112 profile
->SetRawInfo(ADDRESS_HOME_STATE
, s
.ColumnString16(index
++));
113 profile
->SetRawInfo(ADDRESS_HOME_ZIP
, s
.ColumnString16(index
++));
114 profile
->SetRawInfo(ADDRESS_HOME_SORTING_CODE
, s
.ColumnString16(index
++));
115 profile
->SetRawInfo(ADDRESS_HOME_COUNTRY
, s
.ColumnString16(index
++));
116 profile
->set_use_count(s
.ColumnInt64(index
++));
117 profile
->set_use_date(Time::FromTimeT(s
.ColumnInt64(index
++)));
118 profile
->set_modification_date(Time::FromTimeT(s
.ColumnInt64(index
++)));
119 profile
->set_origin(s
.ColumnString(index
++));
120 profile
->set_language_code(s
.ColumnString(index
++));
122 return profile
.Pass();
125 void BindEncryptedCardToColumn(sql::Statement
* s
,
127 const base::string16
& number
) {
128 std::string encrypted_data
;
129 OSCrypt::EncryptString16(number
, &encrypted_data
);
130 s
->BindBlob(column_index
, encrypted_data
.data(),
131 static_cast<int>(encrypted_data
.length()));
134 void BindCreditCardToStatement(const CreditCard
& credit_card
,
135 const Time
& modification_date
,
137 DCHECK(base::IsValidGUID(credit_card
.guid()));
139 s
->BindString(index
++, credit_card
.guid());
141 s
->BindString16(index
++, GetInfo(credit_card
, CREDIT_CARD_NAME
));
142 s
->BindString16(index
++, GetInfo(credit_card
, CREDIT_CARD_EXP_MONTH
));
143 s
->BindString16(index
++, GetInfo(credit_card
, CREDIT_CARD_EXP_4_DIGIT_YEAR
));
144 BindEncryptedCardToColumn(s
, index
++,
145 credit_card
.GetRawInfo(CREDIT_CARD_NUMBER
));
147 s
->BindInt64(index
++, credit_card
.use_count());
148 s
->BindInt64(index
++, credit_card
.use_date().ToTimeT());
149 s
->BindInt64(index
++, modification_date
.ToTimeT());
150 s
->BindString(index
++, credit_card
.origin());
153 base::string16
UnencryptedCardFromColumn(const sql::Statement
& s
,
155 base::string16 credit_card_number
;
156 int encrypted_number_len
= s
.ColumnByteLength(column_index
);
157 if (encrypted_number_len
) {
158 std::string encrypted_number
;
159 encrypted_number
.resize(encrypted_number_len
);
160 memcpy(&encrypted_number
[0], s
.ColumnBlob(column_index
),
161 encrypted_number_len
);
162 OSCrypt::DecryptString16(encrypted_number
, &credit_card_number
);
164 return credit_card_number
;
167 scoped_ptr
<CreditCard
> CreditCardFromStatement(const sql::Statement
& s
) {
168 scoped_ptr
<CreditCard
> credit_card(new CreditCard
);
171 credit_card
->set_guid(s
.ColumnString(index
++));
172 DCHECK(base::IsValidGUID(credit_card
->guid()));
174 credit_card
->SetRawInfo(CREDIT_CARD_NAME
, s
.ColumnString16(index
++));
175 credit_card
->SetRawInfo(CREDIT_CARD_EXP_MONTH
, s
.ColumnString16(index
++));
176 credit_card
->SetRawInfo(CREDIT_CARD_EXP_4_DIGIT_YEAR
,
177 s
.ColumnString16(index
++));
178 credit_card
->SetRawInfo(CREDIT_CARD_NUMBER
,
179 UnencryptedCardFromColumn(s
, index
++));
180 credit_card
->set_use_count(s
.ColumnInt64(index
++));
181 credit_card
->set_use_date(Time::FromTimeT(s
.ColumnInt64(index
++)));
182 credit_card
->set_modification_date(Time::FromTimeT(s
.ColumnInt64(index
++)));
183 credit_card
->set_origin(s
.ColumnString(index
++));
185 return credit_card
.Pass();
188 bool AddAutofillProfileNamesToProfile(sql::Connection
* db
,
189 AutofillProfile
* profile
) {
190 // TODO(estade): update schema so that multiple names are not associated per
191 // unique profile guid. Please refer https://crbug.com/497934.
192 sql::Statement
s(db
->GetUniqueStatement(
193 "SELECT guid, first_name, middle_name, last_name, full_name "
194 "FROM autofill_profile_names "
197 s
.BindString(0, profile
->guid());
203 DCHECK_EQ(profile
->guid(), s
.ColumnString(0));
204 profile
->SetRawInfo(NAME_FIRST
, s
.ColumnString16(1));
205 profile
->SetRawInfo(NAME_MIDDLE
, s
.ColumnString16(2));
206 profile
->SetRawInfo(NAME_LAST
, s
.ColumnString16(3));
207 profile
->SetRawInfo(NAME_FULL
, s
.ColumnString16(4));
209 return s
.Succeeded();
212 bool AddAutofillProfileEmailsToProfile(sql::Connection
* db
,
213 AutofillProfile
* profile
) {
214 // TODO(estade): update schema so that multiple emails are not associated per
215 // unique profile guid. Please refer https://crbug.com/497934.
216 sql::Statement
s(db
->GetUniqueStatement(
217 "SELECT guid, email "
218 "FROM autofill_profile_emails "
221 s
.BindString(0, profile
->guid());
227 DCHECK_EQ(profile
->guid(), s
.ColumnString(0));
228 profile
->SetRawInfo(EMAIL_ADDRESS
, s
.ColumnString16(1));
230 return s
.Succeeded();
233 bool AddAutofillProfilePhonesToProfile(sql::Connection
* db
,
234 AutofillProfile
* profile
) {
235 // TODO(estade): update schema so that multiple phone numbers are not
236 // associated per unique profile guid. Please refer https://crbug.com/497934.
237 sql::Statement
s(db
->GetUniqueStatement(
238 "SELECT guid, number "
239 "FROM autofill_profile_phones "
242 s
.BindString(0, profile
->guid());
248 DCHECK_EQ(profile
->guid(), s
.ColumnString(0));
249 profile
->SetRawInfo(PHONE_HOME_WHOLE_NUMBER
, s
.ColumnString16(1));
251 return s
.Succeeded();
254 bool AddAutofillProfileNames(const AutofillProfile
& profile
,
255 sql::Connection
* db
) {
257 sql::Statement
s(db
->GetUniqueStatement(
258 "INSERT INTO autofill_profile_names"
259 " (guid, first_name, middle_name, last_name, full_name) "
260 "VALUES (?,?,?,?,?)"));
261 s
.BindString(0, profile
.guid());
262 s
.BindString16(1, profile
.GetRawInfo(NAME_FIRST
));
263 s
.BindString16(2, profile
.GetRawInfo(NAME_MIDDLE
));
264 s
.BindString16(3, profile
.GetRawInfo(NAME_LAST
));
265 s
.BindString16(4, profile
.GetRawInfo(NAME_FULL
));
270 bool AddAutofillProfileEmails(const AutofillProfile
& profile
,
271 sql::Connection
* db
) {
272 // Add the new email.
273 sql::Statement
s(db
->GetUniqueStatement(
274 "INSERT INTO autofill_profile_emails"
277 s
.BindString(0, profile
.guid());
278 s
.BindString16(1, profile
.GetRawInfo(EMAIL_ADDRESS
));
283 bool AddAutofillProfilePhones(const AutofillProfile
& profile
,
284 sql::Connection
* db
) {
285 // Add the new number.
286 sql::Statement
s(db
->GetUniqueStatement(
287 "INSERT INTO autofill_profile_phones"
290 s
.BindString(0, profile
.guid());
291 s
.BindString16(1, profile
.GetRawInfo(PHONE_HOME_WHOLE_NUMBER
));
296 bool AddAutofillProfilePieces(const AutofillProfile
& profile
,
297 sql::Connection
* db
) {
298 if (!AddAutofillProfileNames(profile
, db
))
301 if (!AddAutofillProfileEmails(profile
, db
))
304 if (!AddAutofillProfilePhones(profile
, db
))
310 bool RemoveAutofillProfilePieces(const std::string
& guid
, sql::Connection
* db
) {
311 sql::Statement
s1(db
->GetUniqueStatement(
312 "DELETE FROM autofill_profile_names WHERE guid = ?"));
313 s1
.BindString(0, guid
);
318 sql::Statement
s2(db
->GetUniqueStatement(
319 "DELETE FROM autofill_profile_emails WHERE guid = ?"));
320 s2
.BindString(0, guid
);
325 sql::Statement
s3(db
->GetUniqueStatement(
326 "DELETE FROM autofill_profile_phones WHERE guid = ?"));
327 s3
.BindString(0, guid
);
332 WebDatabaseTable::TypeKey
GetKey() {
333 // We just need a unique constant. Use the address of a static that
334 // COMDAT folding won't touch in an optimizing linker.
335 static int table_key
= 0;
336 return reinterpret_cast<void*>(&table_key
);
339 time_t GetEndTime(const Time
& end
) {
340 if (end
.is_null() || end
== Time::Max())
341 return std::numeric_limits
<time_t>::max();
343 return end
.ToTimeT();
346 std::string
ServerStatusEnumToString(CreditCard::ServerStatus status
) {
348 case CreditCard::EXPIRED
:
359 CreditCard::ServerStatus
ServerStatusStringToEnum(const std::string
& status
) {
360 if (status
== "EXPIRED")
361 return CreditCard::EXPIRED
;
363 DCHECK_EQ("OK", status
);
364 return CreditCard::OK
;
367 // Returns |s| with |escaper| in front of each of occurrence of a character from
368 // |special_chars|. Any occurrence of |escaper| in |s| is doubled. For example,
369 // Substitute("hello_world!", "_%", '!'') returns "hello!_world!!".
370 base::string16
Substitute(const base::string16
& s
,
371 const base::string16
& special_chars
,
372 const base::char16
& escaper
) {
373 // Prepend |escaper| to the list of |special_chars|.
374 base::string16
escape_wildcards(special_chars
);
375 escape_wildcards
.insert(escape_wildcards
.begin(), escaper
);
377 // Prepend the |escaper| just before |special_chars| in |s|.
378 base::string16
result(s
);
379 for (base::char16 c
: escape_wildcards
) {
380 for (size_t pos
= 0; (pos
= result
.find(c
, pos
)) != base::string16::npos
;
382 result
.insert(result
.begin() + pos
, escaper
);
392 const size_t AutofillTable::kMaxDataLength
= 1024;
394 AutofillTable::AutofillTable() {
397 AutofillTable::~AutofillTable() {
400 AutofillTable
* AutofillTable::FromWebDatabase(WebDatabase
* db
) {
401 return static_cast<AutofillTable
*>(db
->GetTable(GetKey()));
404 WebDatabaseTable::TypeKey
AutofillTable::GetTypeKey() const {
408 bool AutofillTable::CreateTablesIfNecessary() {
409 return (InitMainTable() && InitCreditCardsTable() && InitProfilesTable() &&
410 InitProfileNamesTable() && InitProfileEmailsTable() &&
411 InitProfilePhonesTable() && InitProfileTrashTable() &&
412 InitMaskedCreditCardsTable() && InitUnmaskedCreditCardsTable() &&
413 InitServerCardMetadataTable() && InitServerAddressesTable() &&
414 InitServerAddressMetadataTable());
417 bool AutofillTable::IsSyncable() {
421 bool AutofillTable::MigrateToVersion(int version
,
422 bool* update_compatible_version
) {
423 // Migrate if necessary.
426 *update_compatible_version
= true;
427 return MigrateToVersion54AddI18nFieldsAndRemoveDeprecatedFields();
429 *update_compatible_version
= true;
430 return MigrateToVersion55MergeAutofillDatesTable();
432 *update_compatible_version
= true;
433 return MigrateToVersion56AddProfileLanguageCodeForFormatting();
435 *update_compatible_version
= true;
436 return MigrateToVersion57AddFullNameField();
438 *update_compatible_version
= false;
439 return MigrateToVersion60AddServerCards();
441 *update_compatible_version
= false;
442 return MigrateToVersion61AddUsageStats();
444 *update_compatible_version
= false;
445 return MigrateToVersion62AddUsageStatsForUnmaskedCards();
447 *update_compatible_version
= false;
448 return MigrateToVersion63AddServerRecipientName();
450 *update_compatible_version
= false;
451 return MigrateToVersion64AddUnmaskDate();
453 *update_compatible_version
= false;
454 return MigrateToVersion65AddServerMetadataTables();
459 bool AutofillTable::AddFormFieldValues(
460 const std::vector
<FormFieldData
>& elements
,
461 std::vector
<AutofillChange
>* changes
) {
462 return AddFormFieldValuesTime(elements
, changes
, Time::Now());
465 bool AutofillTable::AddFormFieldValue(const FormFieldData
& element
,
466 std::vector
<AutofillChange
>* changes
) {
467 return AddFormFieldValueTime(element
, changes
, Time::Now());
470 bool AutofillTable::GetFormValuesForElementName(
471 const base::string16
& name
,
472 const base::string16
& prefix
,
473 std::vector
<base::string16
>* values
,
476 bool succeeded
= false;
478 if (prefix
.empty()) {
480 s
.Assign(db_
->GetUniqueStatement(
481 "SELECT value FROM autofill "
483 "ORDER BY count DESC "
485 s
.BindString16(0, name
);
490 values
->push_back(s
.ColumnString16(0));
492 succeeded
= s
.Succeeded();
494 base::string16 prefix_lower
= base::i18n::ToLower(prefix
);
495 base::string16 next_prefix
= prefix_lower
;
496 next_prefix
[next_prefix
.length() - 1]++;
499 s1
.Assign(db_
->GetUniqueStatement(
500 "SELECT value FROM autofill "
501 "WHERE name = ? AND "
502 "value_lower >= ? AND "
504 "ORDER BY count DESC "
506 s1
.BindString16(0, name
);
507 s1
.BindString16(1, prefix_lower
);
508 s1
.BindString16(2, next_prefix
);
509 s1
.BindInt(3, limit
);
513 values
->push_back(s1
.ColumnString16(0));
515 succeeded
= s1
.Succeeded();
517 if (IsFeatureSubstringMatchEnabled()) {
519 s2
.Assign(db_
->GetUniqueStatement(
520 "SELECT value FROM autofill "
521 "WHERE name = ? AND ("
522 " value LIKE '% ' || :prefix || '%' ESCAPE '!' OR "
523 " value LIKE '%.' || :prefix || '%' ESCAPE '!' OR "
524 " value LIKE '%,' || :prefix || '%' ESCAPE '!' OR "
525 " value LIKE '%-' || :prefix || '%' ESCAPE '!' OR "
526 " value LIKE '%@' || :prefix || '%' ESCAPE '!' OR "
527 " value LIKE '%!_' || :prefix || '%' ESCAPE '!' ) "
528 "ORDER BY count DESC "
531 s2
.BindString16(0, name
);
532 // escaper as L'!' -> 0x21.
533 s2
.BindString16(1, Substitute(prefix_lower
, ASCIIToUTF16("_%"), 0x21));
534 s2
.BindInt(2, limit
);
536 values
->push_back(s2
.ColumnString16(0));
538 succeeded
&= s2
.Succeeded();
545 bool AutofillTable::HasFormElements() {
546 sql::Statement
s(db_
->GetUniqueStatement("SELECT COUNT(*) FROM autofill"));
551 return s
.ColumnInt(0) > 0;
554 bool AutofillTable::RemoveFormElementsAddedBetween(
555 const Time
& delete_begin
,
556 const Time
& delete_end
,
557 std::vector
<AutofillChange
>* changes
) {
558 const time_t delete_begin_time_t
= delete_begin
.ToTimeT();
559 const time_t delete_end_time_t
= GetEndTime(delete_end
);
561 // Query for the name, value, count, and access dates of all form elements
562 // that were used between the given times.
563 sql::Statement
s(db_
->GetUniqueStatement(
564 "SELECT name, value, count, date_created, date_last_used FROM autofill "
565 "WHERE (date_created >= ? AND date_created < ?) OR "
566 " (date_last_used >= ? AND date_last_used < ?)"));
567 s
.BindInt64(0, delete_begin_time_t
);
568 s
.BindInt64(1, delete_end_time_t
);
569 s
.BindInt64(2, delete_begin_time_t
);
570 s
.BindInt64(3, delete_end_time_t
);
572 std::vector
<AutofillUpdate
> updates
;
573 std::vector
<AutofillChange
> tentative_changes
;
575 base::string16 name
= s
.ColumnString16(0);
576 base::string16 value
= s
.ColumnString16(1);
577 int count
= s
.ColumnInt(2);
578 time_t date_created_time_t
= s
.ColumnInt64(3);
579 time_t date_last_used_time_t
= s
.ColumnInt64(4);
581 // If *all* uses of the element were between |delete_begin| and
582 // |delete_end|, then delete the element. Otherwise, update the use
583 // timestamps and use count.
584 AutofillChange::Type change_type
;
585 if (date_created_time_t
>= delete_begin_time_t
&&
586 date_last_used_time_t
< delete_end_time_t
) {
587 change_type
= AutofillChange::REMOVE
;
589 change_type
= AutofillChange::UPDATE
;
591 // For all updated elements, set either date_created or date_last_used so
592 // that the range [date_created, date_last_used] no longer overlaps with
593 // [delete_begin, delete_end). Update the count by interpolating.
594 // Precisely, compute the average amount of time between increments to the
595 // count in the original range [date_created, date_last_used]:
596 // avg_delta = (date_last_used_orig - date_created_orig) / (count - 1)
597 // The count can be expressed as
598 // count = 1 + (date_last_used - date_created) / avg_delta
599 // Hence, update the count to
600 // count_new = 1 + (date_last_used_new - date_created_new) / avg_delta
601 // = 1 + ((count - 1) *
602 // (date_last_used_new - date_created_new) /
603 // (date_last_used_orig - date_created_orig))
604 // Interpolating might not give a result that completely accurately
605 // reflects the user's history, but it's the best that can be done given
606 // the information in the database.
607 AutofillUpdate updated_entry
;
608 updated_entry
.name
= name
;
609 updated_entry
.value
= value
;
610 updated_entry
.date_created
=
611 date_created_time_t
< delete_begin_time_t
?
612 date_created_time_t
:
614 updated_entry
.date_last_used
=
615 date_last_used_time_t
>= delete_end_time_t
?
616 date_last_used_time_t
:
617 delete_begin_time_t
- 1;
618 updated_entry
.count
=
620 Round(1.0 * (count
- 1) *
621 (updated_entry
.date_last_used
- updated_entry
.date_created
) /
622 (date_last_used_time_t
- date_created_time_t
));
623 updates
.push_back(updated_entry
);
626 tentative_changes
.push_back(
627 AutofillChange(change_type
, AutofillKey(name
, value
)));
632 // As a single transaction, remove or update the elements appropriately.
633 sql::Statement
s_delete(db_
->GetUniqueStatement(
634 "DELETE FROM autofill WHERE date_created >= ? AND date_last_used < ?"));
635 s_delete
.BindInt64(0, delete_begin_time_t
);
636 s_delete
.BindInt64(1, delete_end_time_t
);
637 sql::Transaction
transaction(db_
);
638 if (!transaction
.Begin())
642 for (size_t i
= 0; i
< updates
.size(); ++i
) {
643 sql::Statement
s_update(db_
->GetUniqueStatement(
644 "UPDATE autofill SET date_created = ?, date_last_used = ?, count = ?"
645 "WHERE name = ? AND value = ?"));
646 s_update
.BindInt64(0, updates
[i
].date_created
);
647 s_update
.BindInt64(1, updates
[i
].date_last_used
);
648 s_update
.BindInt(2, updates
[i
].count
);
649 s_update
.BindString16(3, updates
[i
].name
);
650 s_update
.BindString16(4, updates
[i
].value
);
654 if (!transaction
.Commit())
657 *changes
= tentative_changes
;
661 bool AutofillTable::RemoveExpiredFormElements(
662 std::vector
<AutofillChange
>* changes
) {
663 Time expiration_time
=
664 Time::Now() - TimeDelta::FromDays(kExpirationPeriodInDays
);
666 // Query for the name and value of all form elements that were last used
667 // before the |expiration_time|.
668 sql::Statement
select_for_delete(db_
->GetUniqueStatement(
669 "SELECT name, value FROM autofill WHERE date_last_used < ?"));
670 select_for_delete
.BindInt64(0, expiration_time
.ToTimeT());
671 std::vector
<AutofillChange
> tentative_changes
;
672 while (select_for_delete
.Step()) {
673 base::string16 name
= select_for_delete
.ColumnString16(0);
674 base::string16 value
= select_for_delete
.ColumnString16(1);
675 tentative_changes
.push_back(
676 AutofillChange(AutofillChange::REMOVE
, AutofillKey(name
, value
)));
679 if (!select_for_delete
.Succeeded())
682 sql::Statement
delete_data_statement(db_
->GetUniqueStatement(
683 "DELETE FROM autofill WHERE date_last_used < ?"));
684 delete_data_statement
.BindInt64(0, expiration_time
.ToTimeT());
685 if (!delete_data_statement
.Run())
688 *changes
= tentative_changes
;
692 bool AutofillTable::AddFormFieldValuesTime(
693 const std::vector
<FormFieldData
>& elements
,
694 std::vector
<AutofillChange
>* changes
,
696 // Only add one new entry for each unique element name. Use |seen_names| to
697 // track this. Add up to |kMaximumUniqueNames| unique entries per form.
698 const size_t kMaximumUniqueNames
= 256;
699 std::set
<base::string16
> seen_names
;
701 for (const FormFieldData
& element
: elements
) {
702 if (seen_names
.size() >= kMaximumUniqueNames
)
704 if (ContainsKey(seen_names
, element
.name
))
706 result
= result
&& AddFormFieldValueTime(element
, changes
, time
);
707 seen_names
.insert(element
.name
);
712 bool AutofillTable::GetAllAutofillEntries(std::vector
<AutofillEntry
>* entries
) {
713 sql::Statement
s(db_
->GetUniqueStatement(
714 "SELECT name, value, date_created, date_last_used FROM autofill"));
717 base::string16 name
= s
.ColumnString16(0);
718 base::string16 value
= s
.ColumnString16(1);
719 Time date_created
= Time::FromTimeT(s
.ColumnInt64(2));
720 Time date_last_used
= Time::FromTimeT(s
.ColumnInt64(3));
722 AutofillEntry(AutofillKey(name
, value
), date_created
, date_last_used
));
725 return s
.Succeeded();
728 bool AutofillTable::GetAutofillTimestamps(const base::string16
& name
,
729 const base::string16
& value
,
731 Time
* date_last_used
) {
732 sql::Statement
s(db_
->GetUniqueStatement(
733 "SELECT date_created, date_last_used FROM autofill "
734 "WHERE name = ? AND value = ?"));
735 s
.BindString16(0, name
);
736 s
.BindString16(1, value
);
740 *date_created
= Time::FromTimeT(s
.ColumnInt64(0));
741 *date_last_used
= Time::FromTimeT(s
.ColumnInt64(1));
747 bool AutofillTable::UpdateAutofillEntries(
748 const std::vector
<AutofillEntry
>& entries
) {
752 // Remove all existing entries.
753 for (size_t i
= 0; i
< entries
.size(); ++i
) {
754 sql::Statement
s(db_
->GetUniqueStatement(
755 "DELETE FROM autofill WHERE name = ? AND value = ?"));
756 s
.BindString16(0, entries
[i
].key().name());
757 s
.BindString16(1, entries
[i
].key().value());
762 // Insert all the supplied autofill entries.
763 for (size_t i
= 0; i
< entries
.size(); ++i
) {
764 if (!InsertAutofillEntry(entries
[i
]))
771 bool AutofillTable::InsertAutofillEntry(const AutofillEntry
& entry
) {
773 "INSERT INTO autofill "
774 "(name, value, value_lower, date_created, date_last_used, count) "
775 "VALUES (?, ?, ?, ?, ?, ?)";
776 sql::Statement
s(db_
->GetUniqueStatement(sql
.c_str()));
777 s
.BindString16(0, entry
.key().name());
778 s
.BindString16(1, entry
.key().value());
779 s
.BindString16(2, base::i18n::ToLower(entry
.key().value()));
780 s
.BindInt64(3, entry
.date_created().ToTimeT());
781 s
.BindInt64(4, entry
.date_last_used().ToTimeT());
782 // TODO(isherman): The counts column is currently synced implicitly as the
783 // number of timestamps. Sync the value explicitly instead, since the DB now
784 // only saves the first and last timestamp, which makes counting timestamps
785 // completely meaningless as a way to track frequency of usage.
786 s
.BindInt(5, entry
.date_last_used() == entry
.date_created() ? 1 : 2);
790 bool AutofillTable::AddFormFieldValueTime(const FormFieldData
& element
,
791 std::vector
<AutofillChange
>* changes
,
793 sql::Statement
s_exists(db_
->GetUniqueStatement(
794 "SELECT COUNT(*) FROM autofill WHERE name = ? AND value = ?"));
795 s_exists
.BindString16(0, element
.name
);
796 s_exists
.BindString16(1, element
.value
);
797 if (!s_exists
.Step())
800 bool already_exists
= s_exists
.ColumnInt(0) > 0;
801 if (already_exists
) {
802 sql::Statement
s(db_
->GetUniqueStatement(
803 "UPDATE autofill SET date_last_used = ?, count = count + 1 "
804 "WHERE name = ? AND value = ?"));
805 s
.BindInt64(0, time
.ToTimeT());
806 s
.BindString16(1, element
.name
);
807 s
.BindString16(2, element
.value
);
811 time_t time_as_time_t
= time
.ToTimeT();
812 sql::Statement
s(db_
->GetUniqueStatement(
813 "INSERT INTO autofill "
814 "(name, value, value_lower, date_created, date_last_used, count) "
815 "VALUES (?, ?, ?, ?, ?, ?)"));
816 s
.BindString16(0, element
.name
);
817 s
.BindString16(1, element
.value
);
818 s
.BindString16(2, base::i18n::ToLower(element
.value
));
819 s
.BindInt64(3, time_as_time_t
);
820 s
.BindInt64(4, time_as_time_t
);
826 AutofillChange::Type change_type
=
827 already_exists
? AutofillChange::UPDATE
: AutofillChange::ADD
;
829 AutofillChange(change_type
, AutofillKey(element
.name
, element
.value
)));
834 bool AutofillTable::RemoveFormElement(const base::string16
& name
,
835 const base::string16
& value
) {
836 sql::Statement
s(db_
->GetUniqueStatement(
837 "DELETE FROM autofill WHERE name = ? AND value= ?"));
838 s
.BindString16(0, name
);
839 s
.BindString16(1, value
);
843 bool AutofillTable::AddAutofillProfile(const AutofillProfile
& profile
) {
844 if (IsAutofillGUIDInTrash(profile
.guid()))
847 sql::Statement
s(db_
->GetUniqueStatement(
848 "INSERT INTO autofill_profiles"
849 "(guid, company_name, street_address, dependent_locality, city, state,"
850 " zipcode, sorting_code, country_code, use_count, use_date, "
851 " date_modified, origin, language_code)"
852 "VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?)"));
853 BindAutofillProfileToStatement(profile
, Time::Now(), &s
);
858 return AddAutofillProfilePieces(profile
, db_
);
861 scoped_ptr
<AutofillProfile
> AutofillTable::GetAutofillProfile(
862 const std::string
& guid
) {
863 DCHECK(base::IsValidGUID(guid
));
864 sql::Statement
s(db_
->GetUniqueStatement(
865 "SELECT guid, company_name, street_address, dependent_locality, city,"
866 " state, zipcode, sorting_code, country_code, use_count, use_date,"
867 " date_modified, origin, language_code "
868 "FROM autofill_profiles "
870 s
.BindString(0, guid
);
872 scoped_ptr
<AutofillProfile
> p
;
876 p
= AutofillProfileFromStatement(s
);
878 // Get associated name info.
879 AddAutofillProfileNamesToProfile(db_
, p
.get());
881 // Get associated email info.
882 AddAutofillProfileEmailsToProfile(db_
, p
.get());
884 // Get associated phone info.
885 AddAutofillProfilePhonesToProfile(db_
, p
.get());
890 bool AutofillTable::GetAutofillProfiles(
891 std::vector
<AutofillProfile
*>* profiles
) {
895 sql::Statement
s(db_
->GetUniqueStatement(
897 "FROM autofill_profiles "
898 "ORDER BY date_modified DESC, guid"));
901 std::string guid
= s
.ColumnString(0);
902 scoped_ptr
<AutofillProfile
> profile
= GetAutofillProfile(guid
);
905 profiles
->push_back(profile
.release());
908 return s
.Succeeded();
911 bool AutofillTable::GetServerProfiles(std::vector
<AutofillProfile
*>* profiles
) {
914 sql::Statement
s(db_
->GetUniqueStatement(
922 "address_1," // ADDRESS_HOME_STATE
923 "address_2," // ADDRESS_HOME_CITY
924 "address_3," // ADDRESS_HOME_DEPENDENT_LOCALITY
925 "address_4," // Not supported in AutofillProfile yet.
926 "postal_code," // ADDRESS_HOME_ZIP
927 "sorting_code," // ADDRESS_HOME_SORTING_CODE
928 "country_code," // ADDRESS_HOME_COUNTRY
929 "phone_number," // PHONE_HOME_WHOLE_NUMBER
931 "FROM server_addresses addresses "
932 "LEFT OUTER JOIN server_address_metadata USING (id)"));
936 scoped_ptr
<AutofillProfile
> profile(new AutofillProfile(
937 AutofillProfile::SERVER_PROFILE
, s
.ColumnString(index
++)));
938 profile
->set_use_count(s
.ColumnInt64(index
++));
939 profile
->set_use_date(Time::FromInternalValue(s
.ColumnInt64(index
++)));
941 base::string16 recipient_name
= s
.ColumnString16(index
++);
942 profile
->SetRawInfo(COMPANY_NAME
, s
.ColumnString16(index
++));
943 profile
->SetRawInfo(ADDRESS_HOME_STREET_ADDRESS
, s
.ColumnString16(index
++));
944 profile
->SetRawInfo(ADDRESS_HOME_STATE
, s
.ColumnString16(index
++));
945 profile
->SetRawInfo(ADDRESS_HOME_CITY
, s
.ColumnString16(index
++));
946 profile
->SetRawInfo(ADDRESS_HOME_DEPENDENT_LOCALITY
,
947 s
.ColumnString16(index
++));
948 index
++; // Skip address_4 which we haven't added to AutofillProfile yet.
949 profile
->SetRawInfo(ADDRESS_HOME_ZIP
, s
.ColumnString16(index
++));
950 profile
->SetRawInfo(ADDRESS_HOME_SORTING_CODE
, s
.ColumnString16(index
++));
951 profile
->SetRawInfo(ADDRESS_HOME_COUNTRY
, s
.ColumnString16(index
++));
952 base::string16 phone_number
= s
.ColumnString16(index
++);
953 profile
->set_language_code(s
.ColumnString(index
++));
955 // SetInfo instead of SetRawInfo so the constituent pieces will be parsed
956 // for these data types.
957 profile
->SetInfo(AutofillType(NAME_FULL
), recipient_name
,
958 profile
->language_code());
959 profile
->SetInfo(AutofillType(PHONE_HOME_WHOLE_NUMBER
), phone_number
,
960 profile
->language_code());
962 profiles
->push_back(profile
.release());
965 return s
.Succeeded();
968 void AutofillTable::SetServerProfiles(
969 const std::vector
<AutofillProfile
>& profiles
) {
970 sql::Transaction
transaction(db_
);
971 if (!transaction
.Begin())
974 // Delete all old ones first.
975 sql::Statement
delete_old(db_
->GetUniqueStatement(
976 "DELETE FROM server_addresses"));
979 sql::Statement
insert(db_
->GetUniqueStatement(
980 "INSERT INTO server_addresses("
985 "address_1," // ADDRESS_HOME_STATE
986 "address_2," // ADDRESS_HOME_CITY
987 "address_3," // ADDRESS_HOME_DEPENDENT_LOCALITY
988 "address_4," // Not supported in AutofillProfile yet.
989 "postal_code," // ADDRESS_HOME_ZIP
990 "sorting_code," // ADDRESS_HOME_SORTING_CODE
991 "country_code," // ADDRESS_HOME_COUNTRY
992 "phone_number," // PHONE_HOME_WHOLE_NUMBER
994 "VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?)"));
995 for (const auto& profile
: profiles
) {
996 DCHECK(profile
.record_type() == AutofillProfile::SERVER_PROFILE
);
999 insert
.BindString(index
++, profile
.server_id());
1000 insert
.BindString16(index
++, profile
.GetRawInfo(NAME_FULL
));
1001 insert
.BindString16(index
++, profile
.GetRawInfo(COMPANY_NAME
));
1002 insert
.BindString16(index
++,
1003 profile
.GetRawInfo(ADDRESS_HOME_STREET_ADDRESS
));
1004 insert
.BindString16(index
++, profile
.GetRawInfo(ADDRESS_HOME_STATE
));
1005 insert
.BindString16(index
++, profile
.GetRawInfo(ADDRESS_HOME_CITY
));
1006 insert
.BindString16(index
++,
1007 profile
.GetRawInfo(ADDRESS_HOME_DEPENDENT_LOCALITY
));
1008 index
++; // SKip address_4 which we haven't added to AutofillProfile yet.
1009 insert
.BindString16(index
++, profile
.GetRawInfo(ADDRESS_HOME_ZIP
));
1010 insert
.BindString16(index
++, profile
.GetRawInfo(ADDRESS_HOME_SORTING_CODE
));
1011 insert
.BindString16(index
++, profile
.GetRawInfo(ADDRESS_HOME_COUNTRY
));
1012 insert
.BindString16(index
++, profile
.GetRawInfo(PHONE_HOME_WHOLE_NUMBER
));
1013 insert
.BindString(index
++, profile
.language_code());
1019 // Delete metadata that's no longer relevant.
1020 sql::Statement
metadata_delete(db_
->GetUniqueStatement(
1021 "DELETE FROM server_address_metadata WHERE id NOT IN "
1022 "(SELECT id FROM server_addresses)"));
1023 metadata_delete
.Run();
1025 transaction
.Commit();
1028 bool AutofillTable::UpdateAutofillProfile(const AutofillProfile
& profile
) {
1029 DCHECK(base::IsValidGUID(profile
.guid()));
1031 // Don't update anything until the trash has been emptied. There may be
1032 // pending modifications to process.
1033 if (!IsAutofillProfilesTrashEmpty())
1036 scoped_ptr
<AutofillProfile
> old_profile
= GetAutofillProfile(profile
.guid());
1040 bool update_modification_date
= *old_profile
!= profile
;
1042 sql::Statement
s(db_
->GetUniqueStatement(
1043 "UPDATE autofill_profiles "
1044 "SET guid=?, company_name=?, street_address=?, dependent_locality=?, "
1045 " city=?, state=?, zipcode=?, sorting_code=?, country_code=?, "
1046 " use_count=?, use_date=?, date_modified=?, origin=?, language_code=? "
1048 BindAutofillProfileToStatement(
1050 update_modification_date
? Time::Now() : old_profile
->modification_date(),
1052 s
.BindString(14, profile
.guid());
1054 bool result
= s
.Run();
1055 DCHECK_GT(db_
->GetLastChangeCount(), 0);
1059 // Remove the old names, emails, and phone numbers.
1060 if (!RemoveAutofillProfilePieces(profile
.guid(), db_
))
1063 return AddAutofillProfilePieces(profile
, db_
);
1066 bool AutofillTable::RemoveAutofillProfile(const std::string
& guid
) {
1067 DCHECK(base::IsValidGUID(guid
));
1069 if (IsAutofillGUIDInTrash(guid
)) {
1070 sql::Statement
s_trash(db_
->GetUniqueStatement(
1071 "DELETE FROM autofill_profiles_trash WHERE guid = ?"));
1072 s_trash
.BindString(0, guid
);
1074 bool success
= s_trash
.Run();
1075 DCHECK_GT(db_
->GetLastChangeCount(), 0) << "Expected item in trash";
1079 sql::Statement
s(db_
->GetUniqueStatement(
1080 "DELETE FROM autofill_profiles WHERE guid = ?"));
1081 s
.BindString(0, guid
);
1086 return RemoveAutofillProfilePieces(guid
, db_
);
1089 bool AutofillTable::ClearAutofillProfiles() {
1090 sql::Statement
s1(db_
->GetUniqueStatement(
1091 "DELETE FROM autofill_profiles"));
1096 sql::Statement
s2(db_
->GetUniqueStatement(
1097 "DELETE FROM autofill_profile_names"));
1102 sql::Statement
s3(db_
->GetUniqueStatement(
1103 "DELETE FROM autofill_profile_emails"));
1108 sql::Statement
s4(db_
->GetUniqueStatement(
1109 "DELETE FROM autofill_profile_phones"));
1114 bool AutofillTable::AddCreditCard(const CreditCard
& credit_card
) {
1115 sql::Statement
s(db_
->GetUniqueStatement(
1116 "INSERT INTO credit_cards"
1117 "(guid, name_on_card, expiration_month, expiration_year, "
1118 " card_number_encrypted, use_count, use_date, date_modified, origin)"
1119 "VALUES (?,?,?,?,?,?,?,?,?)"));
1120 BindCreditCardToStatement(credit_card
, Time::Now(), &s
);
1125 DCHECK_GT(db_
->GetLastChangeCount(), 0);
1129 scoped_ptr
<CreditCard
> AutofillTable::GetCreditCard(const std::string
& guid
) {
1130 DCHECK(base::IsValidGUID(guid
));
1131 sql::Statement
s(db_
->GetUniqueStatement(
1132 "SELECT guid, name_on_card, expiration_month, expiration_year, "
1133 "card_number_encrypted, use_count, use_date, date_modified, "
1135 "FROM credit_cards "
1137 s
.BindString(0, guid
);
1140 return scoped_ptr
<CreditCard
>();
1142 return CreditCardFromStatement(s
);
1145 bool AutofillTable::GetCreditCards(
1146 std::vector
<CreditCard
*>* credit_cards
) {
1147 DCHECK(credit_cards
);
1148 credit_cards
->clear();
1150 sql::Statement
s(db_
->GetUniqueStatement(
1152 "FROM credit_cards "
1153 "ORDER BY date_modified DESC, guid"));
1156 std::string guid
= s
.ColumnString(0);
1157 scoped_ptr
<CreditCard
> credit_card
= GetCreditCard(guid
);
1160 credit_cards
->push_back(credit_card
.release());
1163 return s
.Succeeded();
1166 bool AutofillTable::GetServerCreditCards(
1167 std::vector
<CreditCard
*>* credit_cards
) {
1168 credit_cards
->clear();
1170 sql::Statement
s(db_
->GetUniqueStatement(
1172 "card_number_encrypted, " // 0
1175 "metadata.use_count," // 3
1176 "metadata.use_date," // 4
1179 "name_on_card," // 7
1182 "FROM masked_credit_cards masked "
1183 "LEFT OUTER JOIN unmasked_credit_cards USING (id) "
1184 "LEFT OUTER JOIN server_card_metadata metadata USING (id)"));
1188 // If the card_number_encrypted field is nonempty, we can assume this card
1189 // is a full card, otherwise it's masked.
1190 base::string16 full_card_number
= UnencryptedCardFromColumn(s
, index
++);
1191 base::string16 last_four
= s
.ColumnString16(index
++);
1192 CreditCard::RecordType record_type
= full_card_number
.empty() ?
1193 CreditCard::MASKED_SERVER_CARD
:
1194 CreditCard::FULL_SERVER_CARD
;
1195 std::string server_id
= s
.ColumnString(index
++);
1197 CreditCard
* card
= new CreditCard(record_type
, server_id
);
1200 record_type
== CreditCard::MASKED_SERVER_CARD
? last_four
1201 : full_card_number
);
1202 card
->set_use_count(s
.ColumnInt64(index
++));
1203 card
->set_use_date(Time::FromInternalValue(s
.ColumnInt64(index
++)));
1205 std::string card_type
= s
.ColumnString(index
++);
1206 if (record_type
== CreditCard::MASKED_SERVER_CARD
) {
1207 // The type must be set after setting the number to override the
1208 // autodectected type.
1209 card
->SetTypeForMaskedCard(card_type
.c_str());
1211 DCHECK_EQ(CreditCard::GetCreditCardType(full_card_number
), card_type
);
1214 card
->SetServerStatus(ServerStatusStringToEnum(s
.ColumnString(index
++)));
1215 card
->SetRawInfo(CREDIT_CARD_NAME
, s
.ColumnString16(index
++));
1216 card
->SetRawInfo(CREDIT_CARD_EXP_MONTH
, s
.ColumnString16(index
++));
1217 card
->SetRawInfo(CREDIT_CARD_EXP_4_DIGIT_YEAR
, s
.ColumnString16(index
++));
1218 credit_cards
->push_back(card
);
1221 return s
.Succeeded();
1224 void AutofillTable::SetServerCreditCards(
1225 const std::vector
<CreditCard
>& credit_cards
) {
1226 sql::Transaction
transaction(db_
);
1227 if (!transaction
.Begin())
1230 // Delete all old values.
1231 sql::Statement
masked_delete(db_
->GetUniqueStatement(
1232 "DELETE FROM masked_credit_cards"));
1233 masked_delete
.Run();
1235 sql::Statement
masked_insert(db_
->GetUniqueStatement(
1236 "INSERT INTO masked_credit_cards("
1240 "name_on_card," // 3
1244 "VALUES (?,?,?,?,?,?,?)"));
1245 for (const CreditCard
& card
: credit_cards
) {
1246 DCHECK_EQ(CreditCard::MASKED_SERVER_CARD
, card
.record_type());
1248 masked_insert
.BindString(0, card
.server_id());
1249 masked_insert
.BindString(1, card
.type());
1250 masked_insert
.BindString(2,
1251 ServerStatusEnumToString(card
.GetServerStatus()));
1252 masked_insert
.BindString16(3, card
.GetRawInfo(CREDIT_CARD_NAME
));
1253 masked_insert
.BindString16(4, card
.LastFourDigits());
1254 masked_insert
.BindString16(5, card
.GetRawInfo(CREDIT_CARD_EXP_MONTH
));
1255 masked_insert
.BindString16(6,
1256 card
.GetRawInfo(CREDIT_CARD_EXP_4_DIGIT_YEAR
));
1258 masked_insert
.Run();
1259 masked_insert
.Reset(true);
1262 // Delete all items in the unmasked table that aren't in the new set.
1263 sql::Statement
unmasked_delete(db_
->GetUniqueStatement(
1264 "DELETE FROM unmasked_credit_cards WHERE id NOT IN "
1265 "(SELECT id FROM masked_credit_cards)"));
1266 unmasked_delete
.Run();
1267 // Do the same for metadata.
1268 sql::Statement
metadata_delete(db_
->GetUniqueStatement(
1269 "DELETE FROM server_card_metadata WHERE id NOT IN "
1270 "(SELECT id FROM masked_credit_cards)"));
1271 metadata_delete
.Run();
1273 transaction
.Commit();
1276 bool AutofillTable::UnmaskServerCreditCard(const CreditCard
& masked
,
1277 const base::string16
& full_number
) {
1278 // Make sure there aren't duplicates for this card.
1279 MaskServerCreditCard(masked
.server_id());
1280 sql::Statement
s(db_
->GetUniqueStatement(
1281 "INSERT INTO unmasked_credit_cards("
1283 "card_number_encrypted,"
1286 s
.BindString(0, masked
.server_id());
1288 std::string encrypted_data
;
1289 OSCrypt::EncryptString16(full_number
, &encrypted_data
);
1290 s
.BindBlob(1, encrypted_data
.data(),
1291 static_cast<int>(encrypted_data
.length()));
1292 s
.BindInt64(2, Time::Now().ToInternalValue()); // unmask_date
1296 CreditCard unmasked
= masked
;
1297 unmasked
.set_record_type(CreditCard::FULL_SERVER_CARD
);
1298 unmasked
.SetNumber(full_number
);
1299 unmasked
.RecordUse();
1300 UpdateServerCardUsageStats(unmasked
);
1302 return db_
->GetLastChangeCount() > 0;
1305 bool AutofillTable::MaskServerCreditCard(const std::string
& id
) {
1306 sql::Statement
s(db_
->GetUniqueStatement(
1307 "DELETE FROM unmasked_credit_cards WHERE id = ?"));
1308 s
.BindString(0, id
);
1310 return db_
->GetLastChangeCount() > 0;
1313 bool AutofillTable::UpdateServerCardUsageStats(
1314 const CreditCard
& credit_card
) {
1315 DCHECK_NE(CreditCard::LOCAL_CARD
, credit_card
.record_type());
1316 sql::Transaction
transaction(db_
);
1317 if (!transaction
.Begin())
1320 sql::Statement
remove(db_
->GetUniqueStatement(
1321 "DELETE FROM server_card_metadata WHERE id = ?"));
1322 remove
.BindString(0, credit_card
.server_id());
1325 sql::Statement
s(db_
->GetUniqueStatement(
1326 "INSERT INTO server_card_metadata(use_count, use_date, id)"
1328 s
.BindInt64(0, credit_card
.use_count());
1329 s
.BindInt64(1, credit_card
.use_date().ToInternalValue());
1330 s
.BindString(2, credit_card
.server_id());
1333 transaction
.Commit();
1335 return db_
->GetLastChangeCount() > 0;
1338 bool AutofillTable::UpdateServerAddressUsageStats(
1339 const AutofillProfile
& profile
) {
1340 DCHECK_EQ(AutofillProfile::SERVER_PROFILE
, profile
.record_type());
1342 sql::Transaction
transaction(db_
);
1343 if (!transaction
.Begin())
1346 sql::Statement
remove(db_
->GetUniqueStatement(
1347 "DELETE FROM server_address_metadata WHERE id = ?"));
1348 remove
.BindString(0, profile
.server_id());
1351 sql::Statement
s(db_
->GetUniqueStatement(
1352 "INSERT INTO server_address_metadata(use_count, use_date, id)"
1354 s
.BindInt64(0, profile
.use_count());
1355 s
.BindInt64(1, profile
.use_date().ToInternalValue());
1356 s
.BindString(2, profile
.server_id());
1359 transaction
.Commit();
1361 return db_
->GetLastChangeCount() > 0;
1364 bool AutofillTable::ClearAllServerData() {
1365 sql::Transaction
transaction(db_
);
1366 if (!transaction
.Begin())
1367 return false; // Some error, nothing was changed.
1369 sql::Statement
masked(db_
->GetUniqueStatement(
1370 "DELETE FROM masked_credit_cards"));
1372 bool changed
= db_
->GetLastChangeCount() > 0;
1374 sql::Statement
unmasked(db_
->GetUniqueStatement(
1375 "DELETE FROM unmasked_credit_cards"));
1377 changed
|= db_
->GetLastChangeCount() > 0;
1379 sql::Statement
addresses(db_
->GetUniqueStatement(
1380 "DELETE FROM server_addresses"));
1382 changed
|= db_
->GetLastChangeCount() > 0;
1384 sql::Statement
card_metadata(db_
->GetUniqueStatement(
1385 "DELETE FROM server_card_metadata"));
1386 card_metadata
.Run();
1387 changed
|= db_
->GetLastChangeCount() > 0;
1389 sql::Statement
address_metadata(db_
->GetUniqueStatement(
1390 "DELETE FROM server_address_metadata"));
1391 address_metadata
.Run();
1392 changed
|= db_
->GetLastChangeCount() > 0;
1394 transaction
.Commit();
1398 bool AutofillTable::UpdateCreditCard(const CreditCard
& credit_card
) {
1399 DCHECK(base::IsValidGUID(credit_card
.guid()));
1401 scoped_ptr
<CreditCard
> old_credit_card
= GetCreditCard(credit_card
.guid());
1402 if (!old_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
? 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 (const std::string
& guid
: profile_guids
) {
1530 sql::Statement
s_profile(db_
->GetUniqueStatement(
1531 "UPDATE autofill_profiles SET origin='' WHERE guid=?"));
1532 s_profile
.BindString(0, guid
);
1533 if (!s_profile
.Run())
1536 scoped_ptr
<AutofillProfile
> profile
= GetAutofillProfile(guid
);
1540 profiles
->push_back(profile
.release());
1543 // Remember Autofill credit cards with URL origins in the time range.
1544 sql::Statement
s_credit_cards_get(db_
->GetUniqueStatement(
1545 "SELECT guid, origin FROM credit_cards "
1546 "WHERE date_modified >= ? AND date_modified < ?"));
1547 s_credit_cards_get
.BindInt64(0, delete_begin_t
);
1548 s_credit_cards_get
.BindInt64(1, delete_end_t
);
1550 std::vector
<std::string
> credit_card_guids
;
1551 while (s_credit_cards_get
.Step()) {
1552 std::string guid
= s_credit_cards_get
.ColumnString(0);
1553 std::string origin
= s_credit_cards_get
.ColumnString(1);
1554 if (GURL(origin
).is_valid())
1555 credit_card_guids
.push_back(guid
);
1557 if (!s_credit_cards_get
.Succeeded())
1560 // Clear out the origins for the found credit cards.
1561 for (const std::string
& guid
: credit_card_guids
) {
1562 sql::Statement
s_credit_card(db_
->GetUniqueStatement(
1563 "UPDATE credit_cards SET origin='' WHERE guid=?"));
1564 s_credit_card
.BindString(0, guid
);
1565 if (!s_credit_card
.Run())
1572 bool AutofillTable::GetAutofillProfilesInTrash(
1573 std::vector
<std::string
>* guids
) {
1576 sql::Statement
s(db_
->GetUniqueStatement(
1578 "FROM autofill_profiles_trash"));
1581 std::string guid
= s
.ColumnString(0);
1582 guids
->push_back(guid
);
1585 return s
.Succeeded();
1588 bool AutofillTable::EmptyAutofillProfilesTrash() {
1589 sql::Statement
s(db_
->GetUniqueStatement(
1590 "DELETE FROM autofill_profiles_trash"));
1596 bool AutofillTable::AddAutofillGUIDToTrash(const std::string
& guid
) {
1597 sql::Statement
s(db_
->GetUniqueStatement(
1598 "INSERT INTO autofill_profiles_trash"
1601 s
.BindString(0, guid
);
1606 bool AutofillTable::IsAutofillProfilesTrashEmpty() {
1607 sql::Statement
s(db_
->GetUniqueStatement(
1609 "FROM autofill_profiles_trash"));
1614 bool AutofillTable::IsAutofillGUIDInTrash(const std::string
& guid
) {
1615 sql::Statement
s(db_
->GetUniqueStatement(
1617 "FROM autofill_profiles_trash "
1619 s
.BindString(0, guid
);
1624 bool AutofillTable::InitMainTable() {
1625 if (!db_
->DoesTableExist("autofill")) {
1626 if (!db_
->Execute("CREATE TABLE autofill ("
1629 "value_lower VARCHAR, "
1630 "date_created INTEGER DEFAULT 0, "
1631 "date_last_used INTEGER DEFAULT 0, "
1632 "count INTEGER DEFAULT 1, "
1633 "PRIMARY KEY (name, value))") ||
1634 !db_
->Execute("CREATE INDEX autofill_name ON autofill (name)") ||
1635 !db_
->Execute("CREATE INDEX autofill_name_value_lower ON "
1636 "autofill (name, value_lower)")) {
1644 bool AutofillTable::InitCreditCardsTable() {
1645 if (!db_
->DoesTableExist("credit_cards")) {
1646 if (!db_
->Execute("CREATE TABLE credit_cards ( "
1647 "guid VARCHAR PRIMARY KEY, "
1648 "name_on_card VARCHAR, "
1649 "expiration_month INTEGER, "
1650 "expiration_year INTEGER, "
1651 "card_number_encrypted BLOB, "
1652 "date_modified INTEGER NOT NULL DEFAULT 0, "
1653 "origin VARCHAR DEFAULT '', "
1654 "use_count INTEGER NOT NULL DEFAULT 0, "
1655 "use_date INTEGER NOT NULL DEFAULT 0) ")) {
1664 bool AutofillTable::InitProfilesTable() {
1665 if (!db_
->DoesTableExist("autofill_profiles")) {
1666 if (!db_
->Execute("CREATE TABLE autofill_profiles ( "
1667 "guid VARCHAR PRIMARY KEY, "
1668 "company_name VARCHAR, "
1669 "street_address VARCHAR, "
1670 "dependent_locality VARCHAR, "
1674 "sorting_code VARCHAR, "
1675 "country_code VARCHAR, "
1676 "date_modified INTEGER NOT NULL DEFAULT 0, "
1677 "origin VARCHAR DEFAULT '', "
1678 "language_code VARCHAR, "
1679 "use_count INTEGER NOT NULL DEFAULT 0, "
1680 "use_date INTEGER NOT NULL DEFAULT 0) ")) {
1688 bool AutofillTable::InitProfileNamesTable() {
1689 if (!db_
->DoesTableExist("autofill_profile_names")) {
1690 if (!db_
->Execute("CREATE TABLE autofill_profile_names ( "
1692 "first_name VARCHAR, "
1693 "middle_name VARCHAR, "
1694 "last_name VARCHAR, "
1695 "full_name VARCHAR)")) {
1703 bool AutofillTable::InitProfileEmailsTable() {
1704 if (!db_
->DoesTableExist("autofill_profile_emails")) {
1705 if (!db_
->Execute("CREATE TABLE autofill_profile_emails ( "
1707 "email VARCHAR)")) {
1715 bool AutofillTable::InitProfilePhonesTable() {
1716 if (!db_
->DoesTableExist("autofill_profile_phones")) {
1717 if (!db_
->Execute("CREATE TABLE autofill_profile_phones ( "
1719 "number VARCHAR)")) {
1727 bool AutofillTable::InitProfileTrashTable() {
1728 if (!db_
->DoesTableExist("autofill_profiles_trash")) {
1729 if (!db_
->Execute("CREATE TABLE autofill_profiles_trash ( "
1738 bool AutofillTable::InitMaskedCreditCardsTable() {
1739 if (!db_
->DoesTableExist("masked_credit_cards")) {
1740 if (!db_
->Execute("CREATE TABLE masked_credit_cards ("
1743 "name_on_card VARCHAR,"
1745 "last_four VARCHAR,"
1746 "exp_month INTEGER DEFAULT 0,"
1747 "exp_year INTEGER DEFAULT 0)")) {
1755 bool AutofillTable::InitUnmaskedCreditCardsTable() {
1756 if (!db_
->DoesTableExist("unmasked_credit_cards")) {
1757 if (!db_
->Execute("CREATE TABLE unmasked_credit_cards ("
1759 "card_number_encrypted VARCHAR, "
1760 "use_count INTEGER NOT NULL DEFAULT 0, "
1761 "use_date INTEGER NOT NULL DEFAULT 0, "
1762 "unmask_date INTEGER NOT NULL DEFAULT 0)")) {
1770 bool AutofillTable::InitServerCardMetadataTable() {
1771 if (!db_
->DoesTableExist("server_card_metadata")) {
1772 if (!db_
->Execute("CREATE TABLE server_card_metadata ("
1773 "id VARCHAR NOT NULL,"
1774 "use_count INTEGER NOT NULL DEFAULT 0, "
1775 "use_date INTEGER NOT NULL DEFAULT 0)")) {
1783 bool AutofillTable::InitServerAddressesTable() {
1784 if (!db_
->DoesTableExist("server_addresses")) {
1785 // The space after language_code is necessary to match what sqlite does
1786 // when it appends the column in migration.
1787 if (!db_
->Execute("CREATE TABLE server_addresses ("
1789 "company_name VARCHAR,"
1790 "street_address VARCHAR,"
1791 "address_1 VARCHAR,"
1792 "address_2 VARCHAR,"
1793 "address_3 VARCHAR,"
1794 "address_4 VARCHAR,"
1795 "postal_code VARCHAR,"
1796 "sorting_code VARCHAR,"
1797 "country_code VARCHAR,"
1798 "language_code VARCHAR, " // Space required.
1799 "recipient_name VARCHAR, " // Ditto.
1800 "phone_number VARCHAR)")) {
1808 bool AutofillTable::InitServerAddressMetadataTable() {
1809 if (!db_
->DoesTableExist("server_address_metadata")) {
1810 if (!db_
->Execute("CREATE TABLE server_address_metadata ("
1811 "id VARCHAR NOT NULL,"
1812 "use_count INTEGER NOT NULL DEFAULT 0, "
1813 "use_date INTEGER NOT NULL DEFAULT 0)")) {
1821 bool AutofillTable::MigrateToVersion54AddI18nFieldsAndRemoveDeprecatedFields() {
1822 sql::Transaction
transaction(db_
);
1823 if (!transaction
.Begin())
1826 // Test the existence of the |address_line_1| column as an indication that a
1827 // migration is needed. It is possible that the new |autofill_profile_phones|
1828 // schema is in place because the table was newly created when migrating from
1829 // a pre-version-23 database.
1830 if (db_
->DoesColumnExist("autofill_profiles", "address_line_1")) {
1831 // Create a temporary copy of the autofill_profiles table in the (newer)
1832 // version 54 format. This table
1833 // (a) adds columns for street_address, dependent_locality, and
1835 // (b) removes the address_line_1 and address_line_2 columns, which are
1836 // replaced by the street_address column, and
1837 // (c) removes the country column, which was long deprecated.
1838 if (db_
->DoesTableExist("autofill_profiles_temp") ||
1839 !db_
->Execute("CREATE TABLE autofill_profiles_temp ( "
1840 "guid VARCHAR PRIMARY KEY, "
1841 "company_name VARCHAR, "
1842 "street_address VARCHAR, "
1843 "dependent_locality VARCHAR, "
1847 "sorting_code VARCHAR, "
1848 "country_code VARCHAR, "
1849 "date_modified INTEGER NOT NULL DEFAULT 0, "
1850 "origin VARCHAR DEFAULT '')")) {
1854 // Copy over the data from the autofill_profiles table, taking care to merge
1855 // the address lines 1 and 2 into the new street_address column.
1856 if (!db_
->Execute("INSERT INTO autofill_profiles_temp "
1857 "SELECT guid, company_name, '', '', city, state, zipcode,"
1858 " '', country_code, date_modified, origin "
1859 "FROM autofill_profiles")) {
1862 sql::Statement
s(db_
->GetUniqueStatement(
1863 "SELECT guid, address_line_1, address_line_2 FROM autofill_profiles"));
1865 std::string guid
= s
.ColumnString(0);
1866 base::string16 line1
= s
.ColumnString16(1);
1867 base::string16 line2
= s
.ColumnString16(2);
1868 base::string16 street_address
= line1
;
1870 street_address
+= base::ASCIIToUTF16("\n") + line2
;
1872 sql::Statement
s_update(db_
->GetUniqueStatement(
1873 "UPDATE autofill_profiles_temp SET street_address=? WHERE guid=?"));
1874 s_update
.BindString16(0, street_address
);
1875 s_update
.BindString(1, guid
);
1876 if (!s_update
.Run())
1882 // Delete the existing (version 53) table and replace it with the contents
1883 // of the temporary table.
1884 if (!db_
->Execute("DROP TABLE autofill_profiles") ||
1885 !db_
->Execute("ALTER TABLE autofill_profiles_temp "
1886 "RENAME TO autofill_profiles")) {
1891 // Test the existence of the |type| column as an indication that a migration
1892 // is needed. It is possible that the new |autofill_profile_phones| schema is
1893 // in place because the table was newly created when migrating from a
1894 // pre-version-23 database.
1895 if (db_
->DoesColumnExist("autofill_profile_phones", "type")) {
1896 // Create a temporary copy of the autofill_profile_phones table in the
1897 // (newer) version 54 format. This table removes the deprecated |type|
1899 if (db_
->DoesTableExist("autofill_profile_phones_temp") ||
1900 !db_
->Execute("CREATE TABLE autofill_profile_phones_temp ( "
1902 "number VARCHAR)")) {
1906 // Copy over the data from the autofill_profile_phones table.
1907 if (!db_
->Execute("INSERT INTO autofill_profile_phones_temp "
1908 "SELECT guid, number FROM autofill_profile_phones")) {
1912 // Delete the existing (version 53) table and replace it with the contents
1913 // of the temporary table.
1914 if (!db_
->Execute("DROP TABLE autofill_profile_phones"))
1916 if (!db_
->Execute("ALTER TABLE autofill_profile_phones_temp "
1917 "RENAME TO autofill_profile_phones")) {
1922 return transaction
.Commit();
1925 bool AutofillTable::MigrateToVersion55MergeAutofillDatesTable() {
1926 sql::Transaction
transaction(db_
);
1927 if (!transaction
.Begin())
1930 if (db_
->DoesTableExist("autofill_temp") ||
1931 !db_
->Execute("CREATE TABLE autofill_temp ("
1934 "value_lower VARCHAR, "
1935 "date_created INTEGER DEFAULT 0, "
1936 "date_last_used INTEGER DEFAULT 0, "
1937 "count INTEGER DEFAULT 1, "
1938 "PRIMARY KEY (name, value))")) {
1942 // Slurp up the data from the existing table and write it to the new table.
1943 sql::Statement
s(db_
->GetUniqueStatement(
1944 "SELECT name, value, value_lower, count, MIN(date_created),"
1945 " MAX(date_created) "
1946 "FROM autofill a JOIN autofill_dates ad ON a.pair_id=ad.pair_id "
1947 "GROUP BY name, value, value_lower, count"));
1949 sql::Statement
s_insert(db_
->GetUniqueStatement(
1950 "INSERT INTO autofill_temp "
1951 "(name, value, value_lower, count, date_created, date_last_used) "
1952 "VALUES (?, ?, ?, ?, ?, ?)"));
1953 s_insert
.BindString16(0, s
.ColumnString16(0));
1954 s_insert
.BindString16(1, s
.ColumnString16(1));
1955 s_insert
.BindString16(2, s
.ColumnString16(2));
1956 s_insert
.BindInt(3, s
.ColumnInt(3));
1957 s_insert
.BindInt64(4, s
.ColumnInt64(4));
1958 s_insert
.BindInt64(5, s
.ColumnInt64(5));
1959 if (!s_insert
.Run())
1966 // Delete the existing (version 54) tables and replace them with the contents
1967 // of the temporary table.
1968 if (!db_
->Execute("DROP TABLE autofill") ||
1969 !db_
->Execute("DROP TABLE autofill_dates") ||
1970 !db_
->Execute("ALTER TABLE autofill_temp "
1971 "RENAME TO autofill")) {
1975 // Create indices on the new table, for fast lookups.
1976 if (!db_
->Execute("CREATE INDEX autofill_name ON autofill (name)") ||
1977 !db_
->Execute("CREATE INDEX autofill_name_value_lower ON "
1978 "autofill (name, value_lower)")) {
1983 return transaction
.Commit();
1986 bool AutofillTable::MigrateToVersion56AddProfileLanguageCodeForFormatting() {
1987 return db_
->Execute("ALTER TABLE autofill_profiles "
1988 "ADD COLUMN language_code VARCHAR");
1991 bool AutofillTable::MigrateToVersion57AddFullNameField() {
1992 return db_
->Execute("ALTER TABLE autofill_profile_names "
1993 "ADD COLUMN full_name VARCHAR");
1996 bool AutofillTable::MigrateToVersion60AddServerCards() {
1997 sql::Transaction
transaction(db_
);
1998 if (!transaction
.Begin())
2001 if (!db_
->DoesTableExist("masked_credit_cards") &&
2002 !db_
->Execute("CREATE TABLE masked_credit_cards ("
2005 "name_on_card VARCHAR,"
2007 "last_four VARCHAR,"
2008 "exp_month INTEGER DEFAULT 0,"
2009 "exp_year INTEGER DEFAULT 0)")) {
2013 if (!db_
->DoesTableExist("unmasked_credit_cards") &&
2014 !db_
->Execute("CREATE TABLE unmasked_credit_cards ("
2016 "card_number_encrypted VARCHAR)")) {
2020 if (!db_
->DoesTableExist("server_addresses") &&
2021 !db_
->Execute("CREATE TABLE server_addresses ("
2023 "company_name VARCHAR,"
2024 "street_address VARCHAR,"
2025 "address_1 VARCHAR,"
2026 "address_2 VARCHAR,"
2027 "address_3 VARCHAR,"
2028 "address_4 VARCHAR,"
2029 "postal_code VARCHAR,"
2030 "sorting_code VARCHAR,"
2031 "country_code VARCHAR,"
2032 "language_code VARCHAR)")) {
2036 return transaction
.Commit();
2039 bool AutofillTable::MigrateToVersion61AddUsageStats() {
2040 sql::Transaction
transaction(db_
);
2041 if (!transaction
.Begin())
2044 // Add use_count to autofill_profiles.
2045 if (!db_
->DoesColumnExist("autofill_profiles", "use_count") &&
2046 !db_
->Execute("ALTER TABLE autofill_profiles ADD COLUMN "
2047 "use_count INTEGER NOT NULL DEFAULT 0")) {
2051 // Add use_date to autofill_profiles.
2052 if (!db_
->DoesColumnExist("autofill_profiles", "use_date") &&
2053 !db_
->Execute("ALTER TABLE autofill_profiles ADD COLUMN "
2054 "use_date INTEGER NOT NULL DEFAULT 0")) {
2058 // Add use_count to credit_cards.
2059 if (!db_
->DoesColumnExist("credit_cards", "use_count") &&
2060 !db_
->Execute("ALTER TABLE credit_cards ADD COLUMN "
2061 "use_count INTEGER NOT NULL DEFAULT 0")) {
2065 // Add use_date to credit_cards.
2066 if (!db_
->DoesColumnExist("credit_cards", "use_date") &&
2067 !db_
->Execute("ALTER TABLE credit_cards ADD COLUMN "
2068 "use_date INTEGER NOT NULL DEFAULT 0")) {
2072 return transaction
.Commit();
2075 bool AutofillTable::MigrateToVersion62AddUsageStatsForUnmaskedCards() {
2076 sql::Transaction
transaction(db_
);
2077 if (!transaction
.Begin())
2080 // Add use_count to unmasked_credit_cards.
2081 if (!db_
->DoesColumnExist("unmasked_credit_cards", "use_count") &&
2082 !db_
->Execute("ALTER TABLE unmasked_credit_cards ADD COLUMN "
2083 "use_count INTEGER NOT NULL DEFAULT 0")) {
2087 // Add use_date to unmasked_credit_cards.
2088 if (!db_
->DoesColumnExist("unmasked_credit_cards", "use_date") &&
2089 !db_
->Execute("ALTER TABLE unmasked_credit_cards ADD COLUMN "
2090 "use_date INTEGER NOT NULL DEFAULT 0")) {
2094 return transaction
.Commit();
2097 bool AutofillTable::MigrateToVersion63AddServerRecipientName() {
2098 if (!db_
->DoesColumnExist("server_addresses", "recipient_name") &&
2099 !db_
->Execute("ALTER TABLE server_addresses ADD COLUMN "
2100 "recipient_name VARCHAR")) {
2106 bool AutofillTable::MigrateToVersion64AddUnmaskDate() {
2107 sql::Transaction
transaction(db_
);
2108 if (!transaction
.Begin())
2111 if (!db_
->DoesColumnExist("unmasked_credit_cards", "unmask_date") &&
2112 !db_
->Execute("ALTER TABLE unmasked_credit_cards ADD COLUMN "
2113 "unmask_date INTEGER NOT NULL DEFAULT 0")) {
2116 if (!db_
->DoesColumnExist("server_addresses", "phone_number") &&
2117 !db_
->Execute("ALTER TABLE server_addresses ADD COLUMN "
2118 "phone_number VARCHAR")) {
2122 return transaction
.Commit();
2125 bool AutofillTable::MigrateToVersion65AddServerMetadataTables() {
2126 sql::Transaction
transaction(db_
);
2127 if (!transaction
.Begin())
2130 if (!db_
->DoesTableExist("server_card_metadata") &&
2131 !db_
->Execute("CREATE TABLE server_card_metadata ("
2132 "id VARCHAR NOT NULL,"
2133 "use_count INTEGER NOT NULL DEFAULT 0, "
2134 "use_date INTEGER NOT NULL DEFAULT 0)")) {
2138 // This clobbers existing usage metadata, which is not synced and only
2139 // applies to unmasked cards. Trying to migrate the usage metadata would be
2140 // tricky as multiple devices for the same user get DB upgrades.
2141 if (!db_
->Execute("UPDATE unmasked_credit_cards "
2142 "SET use_count=0, use_date=0")) {
2146 if (!db_
->DoesTableExist("server_address_metadata") &&
2147 !db_
->Execute("CREATE TABLE server_address_metadata ("
2148 "id VARCHAR NOT NULL,"
2149 "use_count INTEGER NOT NULL DEFAULT 0, "
2150 "use_date INTEGER NOT NULL DEFAULT 0)")) {
2154 // Get existing server addresses and generate IDs for them.
2155 sql::Statement
s(db_
->GetUniqueStatement(
2161 "address_1," // ADDRESS_HOME_STATE
2162 "address_2," // ADDRESS_HOME_CITY
2163 "address_3," // ADDRESS_HOME_DEPENDENT_LOCALITY
2164 "address_4," // Not supported in AutofillProfile yet.
2165 "postal_code," // ADDRESS_HOME_ZIP
2166 "sorting_code," // ADDRESS_HOME_SORTING_CODE
2167 "country_code," // ADDRESS_HOME_COUNTRY
2168 "phone_number," // PHONE_HOME_WHOLE_NUMBER
2170 "FROM server_addresses addresses"));
2171 std::vector
<AutofillProfile
> profiles
;
2174 AutofillProfile
profile(
2175 AutofillProfile::SERVER_PROFILE
, s
.ColumnString(index
++));
2177 base::string16 recipient_name
= s
.ColumnString16(index
++);
2178 profile
.SetRawInfo(COMPANY_NAME
, s
.ColumnString16(index
++));
2179 profile
.SetRawInfo(ADDRESS_HOME_STREET_ADDRESS
, s
.ColumnString16(index
++));
2180 profile
.SetRawInfo(ADDRESS_HOME_STATE
, s
.ColumnString16(index
++));
2181 profile
.SetRawInfo(ADDRESS_HOME_CITY
, s
.ColumnString16(index
++));
2182 profile
.SetRawInfo(ADDRESS_HOME_DEPENDENT_LOCALITY
,
2183 s
.ColumnString16(index
++));
2184 index
++; // Skip address_4 which we haven't added to AutofillProfile yet.
2185 profile
.SetRawInfo(ADDRESS_HOME_ZIP
, s
.ColumnString16(index
++));
2186 profile
.SetRawInfo(ADDRESS_HOME_SORTING_CODE
, s
.ColumnString16(index
++));
2187 profile
.SetRawInfo(ADDRESS_HOME_COUNTRY
, s
.ColumnString16(index
++));
2188 base::string16 phone_number
= s
.ColumnString16(index
++);
2189 profile
.set_language_code(s
.ColumnString(index
++));
2190 profile
.SetInfo(AutofillType(NAME_FULL
), recipient_name
,
2191 profile
.language_code());
2192 profile
.SetInfo(AutofillType(PHONE_HOME_WHOLE_NUMBER
), phone_number
,
2193 profile
.language_code());
2194 profile
.GenerateServerProfileIdentifier();
2195 profiles
.push_back(profile
);
2198 // Reinsert with the generated IDs.
2199 sql::Statement
delete_old(db_
->GetUniqueStatement(
2200 "DELETE FROM server_addresses"));
2203 sql::Statement
insert(db_
->GetUniqueStatement(
2204 "INSERT INTO server_addresses("
2209 "address_1," // ADDRESS_HOME_STATE
2210 "address_2," // ADDRESS_HOME_CITY
2211 "address_3," // ADDRESS_HOME_DEPENDENT_LOCALITY
2212 "address_4," // Not supported in AutofillProfile yet.
2213 "postal_code," // ADDRESS_HOME_ZIP
2214 "sorting_code," // ADDRESS_HOME_SORTING_CODE
2215 "country_code," // ADDRESS_HOME_COUNTRY
2216 "phone_number," // PHONE_HOME_WHOLE_NUMBER
2218 "VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?)"));
2219 for (const AutofillProfile
& profile
: profiles
) {
2221 insert
.BindString(index
++, profile
.server_id());
2222 insert
.BindString16(index
++, profile
.GetRawInfo(NAME_FULL
));
2223 insert
.BindString16(index
++, profile
.GetRawInfo(COMPANY_NAME
));
2224 insert
.BindString16(index
++,
2225 profile
.GetRawInfo(ADDRESS_HOME_STREET_ADDRESS
));
2226 insert
.BindString16(index
++, profile
.GetRawInfo(ADDRESS_HOME_STATE
));
2227 insert
.BindString16(index
++, profile
.GetRawInfo(ADDRESS_HOME_CITY
));
2228 insert
.BindString16(index
++,
2229 profile
.GetRawInfo(ADDRESS_HOME_DEPENDENT_LOCALITY
));
2230 index
++; // SKip address_4 which we haven't added to AutofillProfile yet.
2231 insert
.BindString16(index
++, profile
.GetRawInfo(ADDRESS_HOME_ZIP
));
2232 insert
.BindString16(index
++, profile
.GetRawInfo(ADDRESS_HOME_SORTING_CODE
));
2233 insert
.BindString16(index
++, profile
.GetRawInfo(ADDRESS_HOME_COUNTRY
));
2234 insert
.BindString16(index
++, profile
.GetRawInfo(PHONE_HOME_WHOLE_NUMBER
));
2235 insert
.BindString(index
++, profile
.language_code());
2240 return transaction
.Commit();
2243 } // namespace autofill