• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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.
4 
5 #include "components/autofill/core/browser/webdata/autofill_table.h"
6 
7 #include <algorithm>
8 #include <cmath>
9 #include <limits>
10 #include <map>
11 #include <set>
12 #include <string>
13 #include <vector>
14 
15 #include "base/guid.h"
16 #include "base/i18n/case_conversion.h"
17 #include "base/logging.h"
18 #include "base/numerics/safe_conversions.h"
19 #include "base/strings/string_number_conversions.h"
20 #include "base/strings/utf_string_conversions.h"
21 #include "base/time/time.h"
22 #include "base/tuple.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/form_field_data.h"
31 #include "components/os_crypt/os_crypt.h"
32 #include "components/webdata/common/web_database.h"
33 #include "sql/statement.h"
34 #include "sql/transaction.h"
35 #include "ui/base/l10n/l10n_util.h"
36 #include "url/gurl.h"
37 
38 using base::Time;
39 
40 namespace autofill {
41 namespace {
42 
43 // The period after which Autofill entries should expire in days.
44 const int64 kExpirationPeriodInDays = 60;
45 
46 template<typename T>
address_of(T & v)47 T* address_of(T& v) {
48   return &v;
49 }
50 
51 // Helper struct for AutofillTable::RemoveFormElementsAddedBetween().
52 // Contains all the necessary fields to update a row in the 'autofill' table.
53 struct AutofillUpdate {
54   base::string16 name;
55   base::string16 value;
56   time_t date_created;
57   time_t date_last_used;
58   int count;
59 };
60 
61 // Rounds a positive floating point number to the nearest integer.
Round(float f)62 int Round(float f) {
63   DCHECK_GE(f, 0.f);
64   return base::checked_cast<int>(std::floor(f + 0.5f));
65 }
66 
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.
GetInfo(const AutofillDataModel & data_model,ServerFieldType type)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);
74 
75   return data;
76 }
77 
BindAutofillProfileToStatement(const AutofillProfile & profile,sql::Statement * s)78 void BindAutofillProfileToStatement(const AutofillProfile& profile,
79                                     sql::Statement* s) {
80   DCHECK(base::IsValidGUID(profile.guid()));
81   int index = 0;
82   s->BindString(index++, profile.guid());
83 
84   s->BindString16(index++, GetInfo(profile, COMPANY_NAME));
85   s->BindString16(index++, GetInfo(profile, ADDRESS_HOME_STREET_ADDRESS));
86   s->BindString16(index++, GetInfo(profile, ADDRESS_HOME_DEPENDENT_LOCALITY));
87   s->BindString16(index++, GetInfo(profile, ADDRESS_HOME_CITY));
88   s->BindString16(index++, GetInfo(profile, ADDRESS_HOME_STATE));
89   s->BindString16(index++, GetInfo(profile, ADDRESS_HOME_ZIP));
90   s->BindString16(index++, GetInfo(profile, ADDRESS_HOME_SORTING_CODE));
91   s->BindString16(index++, GetInfo(profile, ADDRESS_HOME_COUNTRY));
92   s->BindInt64(index++, Time::Now().ToTimeT());
93   s->BindString(index++, profile.origin());
94   s->BindString(index++, profile.language_code());
95 }
96 
AutofillProfileFromStatement(const sql::Statement & s)97 scoped_ptr<AutofillProfile> AutofillProfileFromStatement(
98     const sql::Statement& s) {
99   scoped_ptr<AutofillProfile> profile(new AutofillProfile);
100   int index = 0;
101   profile->set_guid(s.ColumnString(index++));
102   DCHECK(base::IsValidGUID(profile->guid()));
103 
104   profile->SetRawInfo(COMPANY_NAME, s.ColumnString16(index++));
105   profile->SetRawInfo(ADDRESS_HOME_STREET_ADDRESS, s.ColumnString16(index++));
106   profile->SetRawInfo(ADDRESS_HOME_DEPENDENT_LOCALITY,
107                       s.ColumnString16(index++));
108   profile->SetRawInfo(ADDRESS_HOME_CITY, s.ColumnString16(index++));
109   profile->SetRawInfo(ADDRESS_HOME_STATE, s.ColumnString16(index++));
110   profile->SetRawInfo(ADDRESS_HOME_ZIP, s.ColumnString16(index++));
111   profile->SetRawInfo(ADDRESS_HOME_SORTING_CODE, s.ColumnString16(index++));
112   profile->SetRawInfo(ADDRESS_HOME_COUNTRY, s.ColumnString16(index++));
113   // Intentionally skip column 9, which stores the profile's modification date.
114   index++;
115   profile->set_origin(s.ColumnString(index++));
116   profile->set_language_code(s.ColumnString(index++));
117 
118   return profile.Pass();
119 }
120 
BindCreditCardToStatement(const CreditCard & credit_card,sql::Statement * s)121 void BindCreditCardToStatement(const CreditCard& credit_card,
122                                sql::Statement* s) {
123   DCHECK(base::IsValidGUID(credit_card.guid()));
124   int index = 0;
125   s->BindString(index++, credit_card.guid());
126 
127   s->BindString16(index++, GetInfo(credit_card, CREDIT_CARD_NAME));
128   s->BindString16(index++, GetInfo(credit_card, CREDIT_CARD_EXP_MONTH));
129   s->BindString16(index++, GetInfo(credit_card, CREDIT_CARD_EXP_4_DIGIT_YEAR));
130 
131   std::string encrypted_data;
132   OSCrypt::EncryptString16(credit_card.GetRawInfo(CREDIT_CARD_NUMBER),
133                            &encrypted_data);
134   s->BindBlob(index++, encrypted_data.data(),
135               static_cast<int>(encrypted_data.length()));
136 
137   s->BindInt64(index++, Time::Now().ToTimeT());
138   s->BindString(index++, credit_card.origin());
139 }
140 
CreditCardFromStatement(const sql::Statement & s)141 scoped_ptr<CreditCard> CreditCardFromStatement(const sql::Statement& s) {
142   scoped_ptr<CreditCard> credit_card(new CreditCard);
143 
144   int index = 0;
145   credit_card->set_guid(s.ColumnString(index++));
146   DCHECK(base::IsValidGUID(credit_card->guid()));
147 
148   credit_card->SetRawInfo(CREDIT_CARD_NAME, s.ColumnString16(index++));
149   credit_card->SetRawInfo(CREDIT_CARD_EXP_MONTH, s.ColumnString16(index++));
150   credit_card->SetRawInfo(CREDIT_CARD_EXP_4_DIGIT_YEAR,
151                           s.ColumnString16(index++));
152   int encrypted_number_len = s.ColumnByteLength(index);
153   base::string16 credit_card_number;
154   if (encrypted_number_len) {
155     std::string encrypted_number;
156     encrypted_number.resize(encrypted_number_len);
157     memcpy(&encrypted_number[0], s.ColumnBlob(index++), encrypted_number_len);
158     OSCrypt::DecryptString16(encrypted_number, &credit_card_number);
159   } else {
160     index++;
161   }
162   credit_card->SetRawInfo(CREDIT_CARD_NUMBER, credit_card_number);
163   // Intentionally skip column 5, which stores the modification date.
164   index++;
165   credit_card->set_origin(s.ColumnString(index++));
166 
167   return credit_card.Pass();
168 }
169 
170 // Obsolete version of AddAutofillProfileNamesToProfile, but still needed
171 // for MigrateToVersion37MergeAndCullOlderProfiles().
AddAutofillProfileNamesToProfileForVersion37(sql::Connection * db,AutofillProfile * profile)172 bool AddAutofillProfileNamesToProfileForVersion37(sql::Connection* db,
173                                                   AutofillProfile* profile) {
174   sql::Statement s(db->GetUniqueStatement(
175       "SELECT guid, first_name, middle_name, last_name "
176       "FROM autofill_profile_names "
177       "WHERE guid=?"));
178   s.BindString(0, profile->guid());
179 
180   if (!s.is_valid())
181     return false;
182 
183   std::vector<base::string16> first_names;
184   std::vector<base::string16> middle_names;
185   std::vector<base::string16> last_names;
186   while (s.Step()) {
187     DCHECK_EQ(profile->guid(), s.ColumnString(0));
188     first_names.push_back(s.ColumnString16(1));
189     middle_names.push_back(s.ColumnString16(2));
190     last_names.push_back(s.ColumnString16(3));
191   }
192   if (!s.Succeeded())
193     return false;
194 
195   profile->SetRawMultiInfo(NAME_FIRST, first_names);
196   profile->SetRawMultiInfo(NAME_MIDDLE, middle_names);
197   profile->SetRawMultiInfo(NAME_LAST, last_names);
198   return true;
199 }
200 
AddAutofillProfileNamesToProfile(sql::Connection * db,AutofillProfile * profile)201 bool AddAutofillProfileNamesToProfile(sql::Connection* db,
202                                       AutofillProfile* profile) {
203   sql::Statement s(db->GetUniqueStatement(
204       "SELECT guid, first_name, middle_name, last_name, full_name "
205       "FROM autofill_profile_names "
206       "WHERE guid=?"));
207   s.BindString(0, profile->guid());
208 
209   if (!s.is_valid())
210     return false;
211 
212   std::vector<base::string16> first_names;
213   std::vector<base::string16> middle_names;
214   std::vector<base::string16> last_names;
215   std::vector<base::string16> full_names;
216   while (s.Step()) {
217     DCHECK_EQ(profile->guid(), s.ColumnString(0));
218     first_names.push_back(s.ColumnString16(1));
219     middle_names.push_back(s.ColumnString16(2));
220     last_names.push_back(s.ColumnString16(3));
221     full_names.push_back(s.ColumnString16(4));
222   }
223   if (!s.Succeeded())
224     return false;
225 
226   profile->SetRawMultiInfo(NAME_FIRST, first_names);
227   profile->SetRawMultiInfo(NAME_MIDDLE, middle_names);
228   profile->SetRawMultiInfo(NAME_LAST, last_names);
229   profile->SetRawMultiInfo(NAME_FULL, full_names);
230   return true;
231 }
232 
AddAutofillProfileEmailsToProfile(sql::Connection * db,AutofillProfile * profile)233 bool AddAutofillProfileEmailsToProfile(sql::Connection* db,
234                                        AutofillProfile* profile) {
235   sql::Statement s(db->GetUniqueStatement(
236       "SELECT guid, email "
237       "FROM autofill_profile_emails "
238       "WHERE guid=?"));
239   s.BindString(0, profile->guid());
240 
241   if (!s.is_valid())
242     return false;
243 
244   std::vector<base::string16> emails;
245   while (s.Step()) {
246     DCHECK_EQ(profile->guid(), s.ColumnString(0));
247     emails.push_back(s.ColumnString16(1));
248   }
249   if (!s.Succeeded())
250     return false;
251 
252   profile->SetRawMultiInfo(EMAIL_ADDRESS, emails);
253   return true;
254 }
255 
AddAutofillProfilePhonesToProfile(sql::Connection * db,AutofillProfile * profile)256 bool AddAutofillProfilePhonesToProfile(sql::Connection* db,
257                                        AutofillProfile* profile) {
258   sql::Statement s(db->GetUniqueStatement(
259       "SELECT guid, number "
260       "FROM autofill_profile_phones "
261       "WHERE guid=?"));
262   s.BindString(0, profile->guid());
263 
264   if (!s.is_valid())
265     return false;
266 
267   std::vector<base::string16> numbers;
268   while (s.Step()) {
269     DCHECK_EQ(profile->guid(), s.ColumnString(0));
270     numbers.push_back(s.ColumnString16(1));
271   }
272   if (!s.Succeeded())
273     return false;
274 
275   profile->SetRawMultiInfo(PHONE_HOME_WHOLE_NUMBER, numbers);
276   return true;
277 }
278 
279 // Obsolete version of AddAutofillProfileNames needed for
280 // MigrateToVersion33ProfilesBasedOnFirstName() and
281 // MigrateToVersion37MergeAndCullOlderProfiles().
AddAutofillProfileNamesForVersion3x(const AutofillProfile & profile,sql::Connection * db)282 bool AddAutofillProfileNamesForVersion3x(
283     const AutofillProfile& profile,
284     sql::Connection* db) {
285   std::vector<base::string16> first_names;
286   profile.GetRawMultiInfo(NAME_FIRST, &first_names);
287   std::vector<base::string16> middle_names;
288   profile.GetRawMultiInfo(NAME_MIDDLE, &middle_names);
289   std::vector<base::string16> last_names;
290   profile.GetRawMultiInfo(NAME_LAST, &last_names);
291   DCHECK_EQ(first_names.size(), middle_names.size());
292   DCHECK_EQ(first_names.size(), last_names.size());
293 
294   for (size_t i = 0; i < first_names.size(); ++i) {
295     // Add the new name.
296     sql::Statement s(db->GetUniqueStatement(
297         "INSERT INTO autofill_profile_names"
298         " (guid, first_name, middle_name, last_name) "
299         "VALUES (?,?,?,?)"));
300     s.BindString(0, profile.guid());
301     s.BindString16(1, first_names[i]);
302     s.BindString16(2, middle_names[i]);
303     s.BindString16(3, last_names[i]);
304 
305     if (!s.Run())
306       return false;
307   }
308   return true;
309 }
310 
AddAutofillProfileNames(const AutofillProfile & profile,sql::Connection * db)311 bool AddAutofillProfileNames(const AutofillProfile& profile,
312                              sql::Connection* db) {
313   std::vector<base::string16> first_names;
314   profile.GetRawMultiInfo(NAME_FIRST, &first_names);
315   std::vector<base::string16> middle_names;
316   profile.GetRawMultiInfo(NAME_MIDDLE, &middle_names);
317   std::vector<base::string16> last_names;
318   profile.GetRawMultiInfo(NAME_LAST, &last_names);
319   std::vector<base::string16> full_names;
320   profile.GetRawMultiInfo(NAME_FULL, &full_names);
321   DCHECK_EQ(first_names.size(), middle_names.size());
322   DCHECK_EQ(first_names.size(), last_names.size());
323   DCHECK_EQ(first_names.size(), full_names.size());
324 
325   for (size_t i = 0; i < first_names.size(); ++i) {
326     // Add the new name.
327     sql::Statement s(db->GetUniqueStatement(
328         "INSERT INTO autofill_profile_names"
329         " (guid, first_name, middle_name, last_name, full_name) "
330         "VALUES (?,?,?,?,?)"));
331     s.BindString(0, profile.guid());
332     s.BindString16(1, first_names[i]);
333     s.BindString16(2, middle_names[i]);
334     s.BindString16(3, last_names[i]);
335     s.BindString16(4, full_names[i]);
336 
337     if (!s.Run())
338       return false;
339   }
340   return true;
341 }
342 
AddAutofillProfileEmails(const AutofillProfile & profile,sql::Connection * db)343 bool AddAutofillProfileEmails(const AutofillProfile& profile,
344                               sql::Connection* db) {
345   std::vector<base::string16> emails;
346   profile.GetRawMultiInfo(EMAIL_ADDRESS, &emails);
347 
348   for (size_t i = 0; i < emails.size(); ++i) {
349     // Add the new email.
350     sql::Statement s(db->GetUniqueStatement(
351       "INSERT INTO autofill_profile_emails"
352       " (guid, email) "
353       "VALUES (?,?)"));
354     s.BindString(0, profile.guid());
355     s.BindString16(1, emails[i]);
356 
357     if (!s.Run())
358       return false;
359   }
360 
361   return true;
362 }
363 
AddAutofillProfilePhones(const AutofillProfile & profile,sql::Connection * db)364 bool AddAutofillProfilePhones(const AutofillProfile& profile,
365                               sql::Connection* db) {
366   std::vector<base::string16> numbers;
367   profile.GetRawMultiInfo(PHONE_HOME_WHOLE_NUMBER, &numbers);
368 
369   for (size_t i = 0; i < numbers.size(); ++i) {
370     // Add the new number.
371     sql::Statement s(db->GetUniqueStatement(
372       "INSERT INTO autofill_profile_phones"
373       " (guid, number) "
374       "VALUES (?,?)"));
375     s.BindString(0, profile.guid());
376     s.BindString16(1, numbers[i]);
377 
378     if (!s.Run())
379       return false;
380   }
381 
382   return true;
383 }
384 
AddAutofillProfilePieces(const AutofillProfile & profile,sql::Connection * db)385 bool AddAutofillProfilePieces(const AutofillProfile& profile,
386                               sql::Connection* db) {
387   if (!AddAutofillProfileNames(profile, db))
388     return false;
389 
390   if (!AddAutofillProfileEmails(profile, db))
391     return false;
392 
393   if (!AddAutofillProfilePhones(profile, db))
394     return false;
395 
396   return true;
397 }
398 
RemoveAutofillProfilePieces(const std::string & guid,sql::Connection * db)399 bool RemoveAutofillProfilePieces(const std::string& guid, sql::Connection* db) {
400   sql::Statement s1(db->GetUniqueStatement(
401       "DELETE FROM autofill_profile_names WHERE guid = ?"));
402   s1.BindString(0, guid);
403 
404   if (!s1.Run())
405     return false;
406 
407   sql::Statement s2(db->GetUniqueStatement(
408       "DELETE FROM autofill_profile_emails WHERE guid = ?"));
409   s2.BindString(0, guid);
410 
411   if (!s2.Run())
412     return false;
413 
414   sql::Statement s3(db->GetUniqueStatement(
415       "DELETE FROM autofill_profile_phones WHERE guid = ?"));
416   s3.BindString(0, guid);
417 
418   return s3.Run();
419 }
420 
GetKey()421 WebDatabaseTable::TypeKey GetKey() {
422   // We just need a unique constant. Use the address of a static that
423   // COMDAT folding won't touch in an optimizing linker.
424   static int table_key = 0;
425   return reinterpret_cast<void*>(&table_key);
426 }
427 
GetEndTime(const base::Time & end)428 time_t GetEndTime(const base::Time& end) {
429   if (end.is_null() || end == base::Time::Max())
430     return std::numeric_limits<time_t>::max();
431 
432   return end.ToTimeT();
433 }
434 
435 }  // namespace
436 
437 // The maximum length allowed for form data.
438 const size_t AutofillTable::kMaxDataLength = 1024;
439 
AutofillTable(const std::string & app_locale)440 AutofillTable::AutofillTable(const std::string& app_locale)
441     : app_locale_(app_locale) {
442 }
443 
~AutofillTable()444 AutofillTable::~AutofillTable() {
445 }
446 
FromWebDatabase(WebDatabase * db)447 AutofillTable* AutofillTable::FromWebDatabase(WebDatabase* db) {
448   return static_cast<AutofillTable*>(db->GetTable(GetKey()));
449 }
450 
GetTypeKey() const451 WebDatabaseTable::TypeKey AutofillTable::GetTypeKey() const {
452   return GetKey();
453 }
454 
CreateTablesIfNecessary()455 bool AutofillTable::CreateTablesIfNecessary() {
456   return (InitMainTable() && InitCreditCardsTable() && InitProfilesTable() &&
457           InitProfileNamesTable() && InitProfileEmailsTable() &&
458           InitProfilePhonesTable() && InitProfileTrashTable());
459 }
460 
IsSyncable()461 bool AutofillTable::IsSyncable() {
462   return true;
463 }
464 
MigrateToVersion(int version,bool * update_compatible_version)465 bool AutofillTable::MigrateToVersion(int version,
466                                      bool* update_compatible_version) {
467   // Migrate if necessary.
468   switch (version) {
469     case 22:
470       return MigrateToVersion22ClearAutofillEmptyValueElements();
471     case 23:
472       return MigrateToVersion23AddCardNumberEncryptedColumn();
473     case 24:
474       return MigrateToVersion24CleanupOversizedStringFields();
475     case 27:
476       *update_compatible_version = true;
477       return MigrateToVersion27UpdateLegacyCreditCards();
478     case 30:
479       *update_compatible_version = true;
480       return MigrateToVersion30AddDateModifed();
481     case 31:
482       *update_compatible_version = true;
483       return MigrateToVersion31AddGUIDToCreditCardsAndProfiles();
484     case 32:
485       *update_compatible_version = true;
486       return MigrateToVersion32UpdateProfilesAndCreditCards();
487     case 33:
488       *update_compatible_version = true;
489       return MigrateToVersion33ProfilesBasedOnFirstName();
490     case 34:
491       *update_compatible_version = true;
492       return MigrateToVersion34ProfilesBasedOnCountryCode();
493     case 35:
494       *update_compatible_version = true;
495       return MigrateToVersion35GreatBritainCountryCodes();
496     // Combine migrations 36 and 37.  This is due to enhancements to the merge
497     // step when migrating profiles.  The original migration from 35 to 36 did
498     // not merge profiles with identical addresses, but the migration from 36 to
499     // 37 does.  The step from 35 to 36 should only happen on the Chrome 12 dev
500     // channel.  Chrome 12 beta and release users will jump from 35 to 37
501     // directly getting the full benefits of the multi-valued merge as well as
502     // the culling of bad data.
503     case 37:
504       *update_compatible_version = true;
505       return MigrateToVersion37MergeAndCullOlderProfiles();
506     case 51:
507       // Combine migrations 50 and 51.  The migration code from version 49 to 50
508       // worked correctly for users with existing 'origin' columns, but failed
509       // to create these columns for new users.
510       return MigrateToVersion51AddOriginColumn();
511     case 54:
512       *update_compatible_version = true;
513       return MigrateToVersion54AddI18nFieldsAndRemoveDeprecatedFields();
514     case 55:
515       *update_compatible_version = true;
516       return MigrateToVersion55MergeAutofillDatesTable();
517     case 56:
518       *update_compatible_version = true;
519       return MigrateToVersion56AddProfileLanguageCodeForFormatting();
520     case 57:
521       *update_compatible_version = true;
522       return MigrateToVersion57AddFullNameField();
523   }
524   return true;
525 }
526 
AddFormFieldValues(const std::vector<FormFieldData> & elements,std::vector<AutofillChange> * changes)527 bool AutofillTable::AddFormFieldValues(
528     const std::vector<FormFieldData>& elements,
529     std::vector<AutofillChange>* changes) {
530   return AddFormFieldValuesTime(elements, changes, Time::Now());
531 }
532 
AddFormFieldValue(const FormFieldData & element,std::vector<AutofillChange> * changes)533 bool AutofillTable::AddFormFieldValue(const FormFieldData& element,
534                                       std::vector<AutofillChange>* changes) {
535   return AddFormFieldValueTime(element, changes, Time::Now());
536 }
537 
GetFormValuesForElementName(const base::string16 & name,const base::string16 & prefix,std::vector<base::string16> * values,int limit)538 bool AutofillTable::GetFormValuesForElementName(
539     const base::string16& name,
540     const base::string16& prefix,
541     std::vector<base::string16>* values,
542     int limit) {
543   DCHECK(values);
544   sql::Statement s;
545 
546   if (prefix.empty()) {
547     s.Assign(db_->GetUniqueStatement(
548         "SELECT value FROM autofill "
549         "WHERE name = ? "
550         "ORDER BY count DESC "
551         "LIMIT ?"));
552     s.BindString16(0, name);
553     s.BindInt(1, limit);
554   } else {
555     base::string16 prefix_lower = base::i18n::ToLower(prefix);
556     base::string16 next_prefix = prefix_lower;
557     next_prefix[next_prefix.length() - 1]++;
558 
559     s.Assign(db_->GetUniqueStatement(
560         "SELECT value FROM autofill "
561         "WHERE name = ? AND "
562         "value_lower >= ? AND "
563         "value_lower < ? "
564         "ORDER BY count DESC "
565         "LIMIT ?"));
566     s.BindString16(0, name);
567     s.BindString16(1, prefix_lower);
568     s.BindString16(2, next_prefix);
569     s.BindInt(3, limit);
570   }
571 
572   values->clear();
573   while (s.Step())
574     values->push_back(s.ColumnString16(0));
575   return s.Succeeded();
576 }
577 
HasFormElements()578 bool AutofillTable::HasFormElements() {
579   sql::Statement s(db_->GetUniqueStatement("SELECT COUNT(*) FROM autofill"));
580   if (!s.Step()) {
581     NOTREACHED();
582     return false;
583   }
584   return s.ColumnInt(0) > 0;
585 }
586 
RemoveFormElementsAddedBetween(const Time & delete_begin,const Time & delete_end,std::vector<AutofillChange> * changes)587 bool AutofillTable::RemoveFormElementsAddedBetween(
588     const Time& delete_begin,
589     const Time& delete_end,
590     std::vector<AutofillChange>* changes) {
591   const time_t delete_begin_time_t = delete_begin.ToTimeT();
592   const time_t delete_end_time_t = GetEndTime(delete_end);
593 
594   // Query for the name, value, count, and access dates of all form elements
595   // that were used between the given times.
596   sql::Statement s(db_->GetUniqueStatement(
597       "SELECT name, value, count, date_created, date_last_used FROM autofill "
598       "WHERE (date_created >= ? AND date_created < ?) OR "
599       "      (date_last_used >= ? AND date_last_used < ?)"));
600   s.BindInt64(0, delete_begin_time_t);
601   s.BindInt64(1, delete_end_time_t);
602   s.BindInt64(2, delete_begin_time_t);
603   s.BindInt64(3, delete_end_time_t);
604 
605   std::vector<AutofillUpdate> updates;
606   std::vector<AutofillChange> tentative_changes;
607   while (s.Step()) {
608     base::string16 name = s.ColumnString16(0);
609     base::string16 value = s.ColumnString16(1);
610     int count = s.ColumnInt(2);
611     time_t date_created_time_t = s.ColumnInt64(3);
612     time_t date_last_used_time_t = s.ColumnInt64(4);
613 
614     // If *all* uses of the element were between |delete_begin| and
615     // |delete_end|, then delete the element.  Otherwise, update the use
616     // timestamps and use count.
617     AutofillChange::Type change_type;
618     if (date_created_time_t >= delete_begin_time_t &&
619         date_last_used_time_t < delete_end_time_t) {
620       change_type = AutofillChange::REMOVE;
621     } else {
622       change_type = AutofillChange::UPDATE;
623 
624       // For all updated elements, set either date_created or date_last_used so
625       // that the range [date_created, date_last_used] no longer overlaps with
626       // [delete_begin, delete_end). Update the count by interpolating.
627       // Precisely, compute the average amount of time between increments to the
628       // count in the original range [date_created, date_last_used]:
629       //   avg_delta = (date_last_used_orig - date_created_orig) / (count - 1)
630       // The count can be expressed as
631       //   count = 1 + (date_last_used - date_created) / avg_delta
632       // Hence, update the count to
633       //   count_new = 1 + (date_last_used_new - date_created_new) / avg_delta
634       //             = 1 + ((count - 1) *
635       //                    (date_last_used_new - date_created_new) /
636       //                    (date_last_used_orig - date_created_orig))
637       // Interpolating might not give a result that completely accurately
638       // reflects the user's history, but it's the best that can be done given
639       // the information in the database.
640       AutofillUpdate updated_entry;
641       updated_entry.name = name;
642       updated_entry.value = value;
643       updated_entry.date_created =
644           date_created_time_t < delete_begin_time_t ?
645           date_created_time_t :
646           delete_end_time_t;
647       updated_entry.date_last_used =
648           date_last_used_time_t >= delete_end_time_t ?
649           date_last_used_time_t :
650           delete_begin_time_t - 1;
651       updated_entry.count =
652           1 +
653           Round(1.0 * (count - 1) *
654                 (updated_entry.date_last_used - updated_entry.date_created) /
655                 (date_last_used_time_t - date_created_time_t));
656       updates.push_back(updated_entry);
657     }
658 
659     tentative_changes.push_back(
660         AutofillChange(change_type, AutofillKey(name, value)));
661   }
662   if (!s.Succeeded())
663     return false;
664 
665   // As a single transaction, remove or update the elements appropriately.
666   sql::Statement s_delete(db_->GetUniqueStatement(
667       "DELETE FROM autofill WHERE date_created >= ? AND date_last_used < ?"));
668   s_delete.BindInt64(0, delete_begin_time_t);
669   s_delete.BindInt64(1, delete_end_time_t);
670   sql::Transaction transaction(db_);
671   if (!transaction.Begin())
672     return false;
673   if (!s_delete.Run())
674     return false;
675   for (size_t i = 0; i < updates.size(); ++i) {
676     sql::Statement s_update(db_->GetUniqueStatement(
677       "UPDATE autofill SET date_created = ?, date_last_used = ?, count = ?"
678       "WHERE name = ? AND value = ?"));
679     s_update.BindInt64(0, updates[i].date_created);
680     s_update.BindInt64(1, updates[i].date_last_used);
681     s_update.BindInt(2, updates[i].count);
682     s_update.BindString16(3, updates[i].name);
683     s_update.BindString16(4, updates[i].value);
684     if (!s_update.Run())
685       return false;
686   }
687   if (!transaction.Commit())
688     return false;
689 
690   *changes = tentative_changes;
691   return true;
692 }
693 
RemoveExpiredFormElements(std::vector<AutofillChange> * changes)694 bool AutofillTable::RemoveExpiredFormElements(
695     std::vector<AutofillChange>* changes) {
696   base::Time expiration_time =
697       base::Time::Now() - base::TimeDelta::FromDays(kExpirationPeriodInDays);
698 
699   // Query for the name and value of all form elements that were last used
700   // before the |expiration_time|.
701   sql::Statement select_for_delete(db_->GetUniqueStatement(
702       "SELECT name, value FROM autofill WHERE date_last_used < ?"));
703   select_for_delete.BindInt64(0, expiration_time.ToTimeT());
704   std::vector<AutofillChange> tentative_changes;
705   while (select_for_delete.Step()) {
706     base::string16 name = select_for_delete.ColumnString16(0);
707     base::string16 value = select_for_delete.ColumnString16(1);
708     tentative_changes.push_back(
709         AutofillChange(AutofillChange::REMOVE, AutofillKey(name, value)));
710   }
711 
712   if (!select_for_delete.Succeeded())
713     return false;
714 
715   sql::Statement delete_data_statement(db_->GetUniqueStatement(
716       "DELETE FROM autofill WHERE date_last_used < ?"));
717   delete_data_statement.BindInt64(0, expiration_time.ToTimeT());
718   if (!delete_data_statement.Run())
719     return false;
720 
721   *changes = tentative_changes;
722   return true;
723 }
724 
AddFormFieldValuesTime(const std::vector<FormFieldData> & elements,std::vector<AutofillChange> * changes,Time time)725 bool AutofillTable::AddFormFieldValuesTime(
726     const std::vector<FormFieldData>& elements,
727     std::vector<AutofillChange>* changes,
728     Time time) {
729   // Only add one new entry for each unique element name.  Use |seen_names| to
730   // track this.  Add up to |kMaximumUniqueNames| unique entries per form.
731   const size_t kMaximumUniqueNames = 256;
732   std::set<base::string16> seen_names;
733   bool result = true;
734   for (std::vector<FormFieldData>::const_iterator itr = elements.begin();
735        itr != elements.end(); ++itr) {
736     if (seen_names.size() >= kMaximumUniqueNames)
737       break;
738     if (seen_names.find(itr->name) != seen_names.end())
739       continue;
740     result = result && AddFormFieldValueTime(*itr, changes, time);
741     seen_names.insert(itr->name);
742   }
743   return result;
744 }
745 
GetAllAutofillEntries(std::vector<AutofillEntry> * entries)746 bool AutofillTable::GetAllAutofillEntries(std::vector<AutofillEntry>* entries) {
747   sql::Statement s(db_->GetUniqueStatement(
748       "SELECT name, value, date_created, date_last_used FROM autofill"));
749 
750   while (s.Step()) {
751     base::string16 name = s.ColumnString16(0);
752     base::string16 value = s.ColumnString16(1);
753     Time date_created = Time::FromTimeT(s.ColumnInt64(2));
754     Time date_last_used = Time::FromTimeT(s.ColumnInt64(3));
755     entries->push_back(
756         AutofillEntry(AutofillKey(name, value), date_created, date_last_used));
757   }
758 
759   return s.Succeeded();
760 }
761 
GetAutofillTimestamps(const base::string16 & name,const base::string16 & value,Time * date_created,Time * date_last_used)762 bool AutofillTable::GetAutofillTimestamps(const base::string16& name,
763                                           const base::string16& value,
764                                           Time* date_created,
765                                           Time* date_last_used) {
766   sql::Statement s(db_->GetUniqueStatement(
767       "SELECT date_created, date_last_used FROM autofill "
768       "WHERE name = ? AND value = ?"));
769   s.BindString16(0, name);
770   s.BindString16(1, value);
771   if (!s.Step())
772     return false;
773 
774   *date_created = Time::FromTimeT(s.ColumnInt64(0));
775   *date_last_used = Time::FromTimeT(s.ColumnInt64(1));
776 
777   DCHECK(!s.Step());
778   return true;
779 }
780 
UpdateAutofillEntries(const std::vector<AutofillEntry> & entries)781 bool AutofillTable::UpdateAutofillEntries(
782     const std::vector<AutofillEntry>& entries) {
783   if (entries.empty())
784     return true;
785 
786   // Remove all existing entries.
787   for (size_t i = 0; i < entries.size(); ++i) {
788     sql::Statement s(db_->GetUniqueStatement(
789         "DELETE FROM autofill WHERE name = ? AND value = ?"));
790     s.BindString16(0, entries[i].key().name());
791     s.BindString16(1, entries[i].key().value());
792     if (!s.Run())
793       return false;
794   }
795 
796   // Insert all the supplied autofill entries.
797   for (size_t i = 0; i < entries.size(); ++i) {
798     if (!InsertAutofillEntry(entries[i]))
799       return false;
800   }
801 
802   return true;
803 }
804 
InsertAutofillEntry(const AutofillEntry & entry)805 bool AutofillTable::InsertAutofillEntry(const AutofillEntry& entry) {
806   std::string sql =
807       "INSERT INTO autofill "
808       "(name, value, value_lower, date_created, date_last_used, count) "
809       "VALUES (?, ?, ?, ?, ?, ?)";
810   sql::Statement s(db_->GetUniqueStatement(sql.c_str()));
811   s.BindString16(0, entry.key().name());
812   s.BindString16(1, entry.key().value());
813   s.BindString16(2, base::i18n::ToLower(entry.key().value()));
814   s.BindInt64(3, entry.date_created().ToTimeT());
815   s.BindInt64(4, entry.date_last_used().ToTimeT());
816   // TODO(isherman): The counts column is currently synced implicitly as the
817   // number of timestamps.  Sync the value explicitly instead, since the DB now
818   // only saves the first and last timestamp, which makes counting timestamps
819   // completely meaningless as a way to track frequency of usage.
820   s.BindInt(5, entry.date_last_used() == entry.date_created() ? 1 : 2);
821   return s.Run();
822 }
823 
AddFormFieldValueTime(const FormFieldData & element,std::vector<AutofillChange> * changes,Time time)824 bool AutofillTable::AddFormFieldValueTime(const FormFieldData& element,
825                                           std::vector<AutofillChange>* changes,
826                                           Time time) {
827   sql::Statement s_exists(db_->GetUniqueStatement(
828       "SELECT COUNT(*) FROM autofill WHERE name = ? AND value = ?"));
829   s_exists.BindString16(0, element.name);
830   s_exists.BindString16(1, element.value);
831   if (!s_exists.Step())
832     return false;
833 
834   bool already_exists = s_exists.ColumnInt(0) > 0;
835   if (already_exists) {
836     sql::Statement s(db_->GetUniqueStatement(
837         "UPDATE autofill SET date_last_used = ?, count = count + 1 "
838         "WHERE name = ? AND value = ?"));
839     s.BindInt64(0, time.ToTimeT());
840     s.BindString16(1, element.name);
841     s.BindString16(2, element.value);
842     if (!s.Run())
843       return false;
844   } else {
845     time_t time_as_time_t = time.ToTimeT();
846     sql::Statement s(db_->GetUniqueStatement(
847         "INSERT INTO autofill "
848         "(name, value, value_lower, date_created, date_last_used, count) "
849         "VALUES (?, ?, ?, ?, ?, ?)"));
850     s.BindString16(0, element.name);
851     s.BindString16(1, element.value);
852     s.BindString16(2, base::i18n::ToLower(element.value));
853     s.BindInt64(3, time_as_time_t);
854     s.BindInt64(4, time_as_time_t);
855     s.BindInt(5, 1);
856     if (!s.Run())
857       return false;
858   }
859 
860   AutofillChange::Type change_type =
861       already_exists ? AutofillChange::UPDATE : AutofillChange::ADD;
862   changes->push_back(
863       AutofillChange(change_type, AutofillKey(element.name, element.value)));
864   return true;
865 }
866 
867 
RemoveFormElement(const base::string16 & name,const base::string16 & value)868 bool AutofillTable::RemoveFormElement(const base::string16& name,
869                                       const base::string16& value) {
870   sql::Statement s(db_->GetUniqueStatement(
871       "DELETE FROM autofill WHERE name = ? AND value= ?"));
872   s.BindString16(0, name);
873   s.BindString16(1, value);
874   return s.Run();
875 }
876 
AddAutofillProfile(const AutofillProfile & profile)877 bool AutofillTable::AddAutofillProfile(const AutofillProfile& profile) {
878   if (IsAutofillGUIDInTrash(profile.guid()))
879     return true;
880 
881   sql::Statement s(db_->GetUniqueStatement(
882       "INSERT INTO autofill_profiles"
883       "(guid, company_name, street_address, dependent_locality, city, state,"
884       " zipcode, sorting_code, country_code, date_modified, origin,"
885       " language_code)"
886       "VALUES (?,?,?,?,?,?,?,?,?,?,?,?)"));
887   BindAutofillProfileToStatement(profile, &s);
888 
889   if (!s.Run())
890     return false;
891 
892   return AddAutofillProfilePieces(profile, db_);
893 }
894 
GetAutofillProfile(const std::string & guid,AutofillProfile ** profile)895 bool AutofillTable::GetAutofillProfile(const std::string& guid,
896                                        AutofillProfile** profile) {
897   DCHECK(base::IsValidGUID(guid));
898   DCHECK(profile);
899   sql::Statement s(db_->GetUniqueStatement(
900       "SELECT guid, company_name, street_address, dependent_locality, city,"
901       " state, zipcode, sorting_code, country_code, date_modified, origin,"
902       " language_code "
903       "FROM autofill_profiles "
904       "WHERE guid=?"));
905   s.BindString(0, guid);
906 
907   if (!s.Step())
908     return false;
909 
910   scoped_ptr<AutofillProfile> p = AutofillProfileFromStatement(s);
911 
912   // Get associated name info.
913   AddAutofillProfileNamesToProfile(db_, p.get());
914 
915   // Get associated email info.
916   AddAutofillProfileEmailsToProfile(db_, p.get());
917 
918   // Get associated phone info.
919   AddAutofillProfilePhonesToProfile(db_, p.get());
920 
921   *profile = p.release();
922   return true;
923 }
924 
GetAutofillProfiles(std::vector<AutofillProfile * > * profiles)925 bool AutofillTable::GetAutofillProfiles(
926     std::vector<AutofillProfile*>* profiles) {
927   DCHECK(profiles);
928   profiles->clear();
929 
930   sql::Statement s(db_->GetUniqueStatement(
931       "SELECT guid "
932       "FROM autofill_profiles "
933       "ORDER BY date_modified DESC, guid"));
934 
935   while (s.Step()) {
936     std::string guid = s.ColumnString(0);
937     AutofillProfile* profile = NULL;
938     if (!GetAutofillProfile(guid, &profile))
939       return false;
940     profiles->push_back(profile);
941   }
942 
943   return s.Succeeded();
944 }
945 
UpdateAutofillProfile(const AutofillProfile & profile)946 bool AutofillTable::UpdateAutofillProfile(const AutofillProfile& profile) {
947   DCHECK(base::IsValidGUID(profile.guid()));
948 
949   // Don't update anything until the trash has been emptied.  There may be
950   // pending modifications to process.
951   if (!IsAutofillProfilesTrashEmpty())
952     return true;
953 
954   AutofillProfile* tmp_profile = NULL;
955   if (!GetAutofillProfile(profile.guid(), &tmp_profile))
956     return false;
957 
958   // Preserve appropriate modification dates by not updating unchanged profiles.
959   scoped_ptr<AutofillProfile> old_profile(tmp_profile);
960   if (*old_profile == profile)
961     return true;
962 
963   sql::Statement s(db_->GetUniqueStatement(
964       "UPDATE autofill_profiles "
965       "SET guid=?, company_name=?, street_address=?, dependent_locality=?, "
966       "    city=?, state=?, zipcode=?, sorting_code=?, country_code=?, "
967       "    date_modified=?, origin=?, language_code=? "
968       "WHERE guid=?"));
969   BindAutofillProfileToStatement(profile, &s);
970   s.BindString(12, profile.guid());
971 
972   bool result = s.Run();
973   DCHECK_GT(db_->GetLastChangeCount(), 0);
974   if (!result)
975     return result;
976 
977   // Remove the old names, emails, and phone numbers.
978   if (!RemoveAutofillProfilePieces(profile.guid(), db_))
979     return false;
980 
981   return AddAutofillProfilePieces(profile, db_);
982 }
983 
RemoveAutofillProfile(const std::string & guid)984 bool AutofillTable::RemoveAutofillProfile(const std::string& guid) {
985   DCHECK(base::IsValidGUID(guid));
986 
987   if (IsAutofillGUIDInTrash(guid)) {
988     sql::Statement s_trash(db_->GetUniqueStatement(
989         "DELETE FROM autofill_profiles_trash WHERE guid = ?"));
990     s_trash.BindString(0, guid);
991 
992     bool success = s_trash.Run();
993     DCHECK_GT(db_->GetLastChangeCount(), 0) << "Expected item in trash";
994     return success;
995   }
996 
997   sql::Statement s(db_->GetUniqueStatement(
998       "DELETE FROM autofill_profiles WHERE guid = ?"));
999   s.BindString(0, guid);
1000 
1001   if (!s.Run())
1002     return false;
1003 
1004   return RemoveAutofillProfilePieces(guid, db_);
1005 }
1006 
ClearAutofillProfiles()1007 bool AutofillTable::ClearAutofillProfiles() {
1008   sql::Statement s1(db_->GetUniqueStatement(
1009       "DELETE FROM autofill_profiles"));
1010 
1011   if (!s1.Run())
1012     return false;
1013 
1014   sql::Statement s2(db_->GetUniqueStatement(
1015       "DELETE FROM autofill_profile_names"));
1016 
1017   if (!s2.Run())
1018     return false;
1019 
1020   sql::Statement s3(db_->GetUniqueStatement(
1021       "DELETE FROM autofill_profile_emails"));
1022 
1023   if (!s3.Run())
1024     return false;
1025 
1026   sql::Statement s4(db_->GetUniqueStatement(
1027       "DELETE FROM autofill_profile_phones"));
1028 
1029   return s4.Run();
1030 }
1031 
AddCreditCard(const CreditCard & credit_card)1032 bool AutofillTable::AddCreditCard(const CreditCard& credit_card) {
1033   sql::Statement s(db_->GetUniqueStatement(
1034       "INSERT INTO credit_cards"
1035       "(guid, name_on_card, expiration_month, expiration_year, "
1036       " card_number_encrypted, date_modified, origin)"
1037       "VALUES (?,?,?,?,?,?,?)"));
1038   BindCreditCardToStatement(credit_card, &s);
1039 
1040   if (!s.Run())
1041     return false;
1042 
1043   DCHECK_GT(db_->GetLastChangeCount(), 0);
1044   return true;
1045 }
1046 
GetCreditCard(const std::string & guid,CreditCard ** credit_card)1047 bool AutofillTable::GetCreditCard(const std::string& guid,
1048                                   CreditCard** credit_card) {
1049   DCHECK(base::IsValidGUID(guid));
1050   sql::Statement s(db_->GetUniqueStatement(
1051       "SELECT guid, name_on_card, expiration_month, expiration_year, "
1052       "       card_number_encrypted, date_modified, origin "
1053       "FROM credit_cards "
1054       "WHERE guid = ?"));
1055   s.BindString(0, guid);
1056 
1057   if (!s.Step())
1058     return false;
1059 
1060   *credit_card = CreditCardFromStatement(s).release();
1061   return true;
1062 }
1063 
GetCreditCards(std::vector<CreditCard * > * credit_cards)1064 bool AutofillTable::GetCreditCards(
1065     std::vector<CreditCard*>* credit_cards) {
1066   DCHECK(credit_cards);
1067   credit_cards->clear();
1068 
1069   sql::Statement s(db_->GetUniqueStatement(
1070       "SELECT guid "
1071       "FROM credit_cards "
1072       "ORDER BY date_modified DESC, guid"));
1073 
1074   while (s.Step()) {
1075     std::string guid = s.ColumnString(0);
1076     CreditCard* credit_card = NULL;
1077     if (!GetCreditCard(guid, &credit_card))
1078       return false;
1079     credit_cards->push_back(credit_card);
1080   }
1081 
1082   return s.Succeeded();
1083 }
1084 
UpdateCreditCard(const CreditCard & credit_card)1085 bool AutofillTable::UpdateCreditCard(const CreditCard& credit_card) {
1086   DCHECK(base::IsValidGUID(credit_card.guid()));
1087 
1088   CreditCard* tmp_credit_card = NULL;
1089   if (!GetCreditCard(credit_card.guid(), &tmp_credit_card))
1090     return false;
1091 
1092   // Preserve appropriate modification dates by not updating unchanged cards.
1093   scoped_ptr<CreditCard> old_credit_card(tmp_credit_card);
1094   if (*old_credit_card == credit_card)
1095     return true;
1096 
1097   sql::Statement s(db_->GetUniqueStatement(
1098       "UPDATE credit_cards "
1099       "SET guid=?, name_on_card=?, expiration_month=?, "
1100       "    expiration_year=?, card_number_encrypted=?, date_modified=?, "
1101       "    origin=? "
1102       "WHERE guid=?"));
1103   BindCreditCardToStatement(credit_card, &s);
1104   s.BindString(7, credit_card.guid());
1105 
1106   bool result = s.Run();
1107   DCHECK_GT(db_->GetLastChangeCount(), 0);
1108   return result;
1109 }
1110 
RemoveCreditCard(const std::string & guid)1111 bool AutofillTable::RemoveCreditCard(const std::string& guid) {
1112   DCHECK(base::IsValidGUID(guid));
1113   sql::Statement s(db_->GetUniqueStatement(
1114       "DELETE FROM credit_cards WHERE guid = ?"));
1115   s.BindString(0, guid);
1116 
1117   return s.Run();
1118 }
1119 
RemoveAutofillDataModifiedBetween(const Time & delete_begin,const Time & delete_end,std::vector<std::string> * profile_guids,std::vector<std::string> * credit_card_guids)1120 bool AutofillTable::RemoveAutofillDataModifiedBetween(
1121     const Time& delete_begin,
1122     const Time& delete_end,
1123     std::vector<std::string>* profile_guids,
1124     std::vector<std::string>* credit_card_guids) {
1125   DCHECK(delete_end.is_null() || delete_begin < delete_end);
1126 
1127   time_t delete_begin_t = delete_begin.ToTimeT();
1128   time_t delete_end_t = GetEndTime(delete_end);
1129 
1130   // Remember Autofill profiles in the time range.
1131   sql::Statement s_profiles_get(db_->GetUniqueStatement(
1132       "SELECT guid FROM autofill_profiles "
1133       "WHERE date_modified >= ? AND date_modified < ?"));
1134   s_profiles_get.BindInt64(0, delete_begin_t);
1135   s_profiles_get.BindInt64(1, delete_end_t);
1136 
1137   profile_guids->clear();
1138   while (s_profiles_get.Step()) {
1139     std::string guid = s_profiles_get.ColumnString(0);
1140     profile_guids->push_back(guid);
1141   }
1142   if (!s_profiles_get.Succeeded())
1143     return false;
1144 
1145   // Remove Autofill profiles in the time range.
1146   sql::Statement s_profiles(db_->GetUniqueStatement(
1147       "DELETE FROM autofill_profiles "
1148       "WHERE date_modified >= ? AND date_modified < ?"));
1149   s_profiles.BindInt64(0, delete_begin_t);
1150   s_profiles.BindInt64(1, delete_end_t);
1151 
1152   if (!s_profiles.Run())
1153     return false;
1154 
1155   // Remember Autofill credit cards in the time range.
1156   sql::Statement s_credit_cards_get(db_->GetUniqueStatement(
1157       "SELECT guid FROM credit_cards "
1158       "WHERE date_modified >= ? AND date_modified < ?"));
1159   s_credit_cards_get.BindInt64(0, delete_begin_t);
1160   s_credit_cards_get.BindInt64(1, delete_end_t);
1161 
1162   credit_card_guids->clear();
1163   while (s_credit_cards_get.Step()) {
1164     std::string guid = s_credit_cards_get.ColumnString(0);
1165     credit_card_guids->push_back(guid);
1166   }
1167   if (!s_credit_cards_get.Succeeded())
1168     return false;
1169 
1170   // Remove Autofill credit cards in the time range.
1171   sql::Statement s_credit_cards(db_->GetUniqueStatement(
1172       "DELETE FROM credit_cards "
1173       "WHERE date_modified >= ? AND date_modified < ?"));
1174   s_credit_cards.BindInt64(0, delete_begin_t);
1175   s_credit_cards.BindInt64(1, delete_end_t);
1176 
1177   return s_credit_cards.Run();
1178 }
1179 
RemoveOriginURLsModifiedBetween(const Time & delete_begin,const Time & delete_end,ScopedVector<AutofillProfile> * profiles)1180 bool AutofillTable::RemoveOriginURLsModifiedBetween(
1181     const Time& delete_begin,
1182     const Time& delete_end,
1183     ScopedVector<AutofillProfile>* profiles) {
1184   DCHECK(delete_end.is_null() || delete_begin < delete_end);
1185 
1186   time_t delete_begin_t = delete_begin.ToTimeT();
1187   time_t delete_end_t = GetEndTime(delete_end);
1188 
1189   // Remember Autofill profiles with URL origins in the time range.
1190   sql::Statement s_profiles_get(db_->GetUniqueStatement(
1191       "SELECT guid, origin FROM autofill_profiles "
1192       "WHERE date_modified >= ? AND date_modified < ?"));
1193   s_profiles_get.BindInt64(0, delete_begin_t);
1194   s_profiles_get.BindInt64(1, delete_end_t);
1195 
1196   std::vector<std::string> profile_guids;
1197   while (s_profiles_get.Step()) {
1198     std::string guid = s_profiles_get.ColumnString(0);
1199     std::string origin = s_profiles_get.ColumnString(1);
1200     if (GURL(origin).is_valid())
1201       profile_guids.push_back(guid);
1202   }
1203   if (!s_profiles_get.Succeeded())
1204     return false;
1205 
1206   // Clear out the origins for the found Autofill profiles.
1207   for (std::vector<std::string>::const_iterator it = profile_guids.begin();
1208        it != profile_guids.end(); ++it) {
1209     sql::Statement s_profile(db_->GetUniqueStatement(
1210         "UPDATE autofill_profiles SET origin='' WHERE guid=?"));
1211     s_profile.BindString(0, *it);
1212     if (!s_profile.Run())
1213       return false;
1214 
1215     AutofillProfile* profile;
1216     if (!GetAutofillProfile(*it, &profile))
1217       return false;
1218 
1219     profiles->push_back(profile);
1220   }
1221 
1222   // Remember Autofill credit cards with URL origins in the time range.
1223   sql::Statement s_credit_cards_get(db_->GetUniqueStatement(
1224       "SELECT guid, origin FROM credit_cards "
1225       "WHERE date_modified >= ? AND date_modified < ?"));
1226   s_credit_cards_get.BindInt64(0, delete_begin_t);
1227   s_credit_cards_get.BindInt64(1, delete_end_t);
1228 
1229   std::vector<std::string> credit_card_guids;
1230   while (s_credit_cards_get.Step()) {
1231     std::string guid = s_credit_cards_get.ColumnString(0);
1232     std::string origin = s_credit_cards_get.ColumnString(1);
1233     if (GURL(origin).is_valid())
1234       credit_card_guids.push_back(guid);
1235   }
1236   if (!s_credit_cards_get.Succeeded())
1237     return false;
1238 
1239   // Clear out the origins for the found credit cards.
1240   for (std::vector<std::string>::const_iterator it = credit_card_guids.begin();
1241        it != credit_card_guids.end(); ++it) {
1242     sql::Statement s_credit_card(db_->GetUniqueStatement(
1243         "UPDATE credit_cards SET origin='' WHERE guid=?"));
1244     s_credit_card.BindString(0, *it);
1245     if (!s_credit_card.Run())
1246       return false;
1247   }
1248 
1249   return true;
1250 }
1251 
GetAutofillProfilesInTrash(std::vector<std::string> * guids)1252 bool AutofillTable::GetAutofillProfilesInTrash(
1253     std::vector<std::string>* guids) {
1254   guids->clear();
1255 
1256   sql::Statement s(db_->GetUniqueStatement(
1257       "SELECT guid "
1258       "FROM autofill_profiles_trash"));
1259 
1260   while (s.Step()) {
1261     std::string guid = s.ColumnString(0);
1262     guids->push_back(guid);
1263   }
1264 
1265   return s.Succeeded();
1266 }
1267 
EmptyAutofillProfilesTrash()1268 bool AutofillTable::EmptyAutofillProfilesTrash() {
1269   sql::Statement s(db_->GetUniqueStatement(
1270       "DELETE FROM autofill_profiles_trash"));
1271 
1272   return s.Run();
1273 }
1274 
1275 
AddAutofillGUIDToTrash(const std::string & guid)1276 bool AutofillTable::AddAutofillGUIDToTrash(const std::string& guid) {
1277   sql::Statement s(db_->GetUniqueStatement(
1278     "INSERT INTO autofill_profiles_trash"
1279     " (guid) "
1280     "VALUES (?)"));
1281   s.BindString(0, guid);
1282 
1283   return s.Run();
1284 }
1285 
IsAutofillProfilesTrashEmpty()1286 bool AutofillTable::IsAutofillProfilesTrashEmpty() {
1287   sql::Statement s(db_->GetUniqueStatement(
1288       "SELECT guid "
1289       "FROM autofill_profiles_trash"));
1290 
1291   return !s.Step();
1292 }
1293 
IsAutofillGUIDInTrash(const std::string & guid)1294 bool AutofillTable::IsAutofillGUIDInTrash(const std::string& guid) {
1295   sql::Statement s(db_->GetUniqueStatement(
1296       "SELECT guid "
1297       "FROM autofill_profiles_trash "
1298       "WHERE guid = ?"));
1299   s.BindString(0, guid);
1300 
1301   return s.Step();
1302 }
1303 
InitMainTable()1304 bool AutofillTable::InitMainTable() {
1305   if (!db_->DoesTableExist("autofill")) {
1306     if (!db_->Execute("CREATE TABLE autofill ("
1307                       "name VARCHAR, "
1308                       "value VARCHAR, "
1309                       "value_lower VARCHAR, "
1310                       "date_created INTEGER DEFAULT 0, "
1311                       "date_last_used INTEGER DEFAULT 0, "
1312                       "count INTEGER DEFAULT 1, "
1313                       "PRIMARY KEY (name, value))") ||
1314         !db_->Execute("CREATE INDEX autofill_name ON autofill (name)") ||
1315         !db_->Execute("CREATE INDEX autofill_name_value_lower ON "
1316                       "autofill (name, value_lower)")) {
1317        NOTREACHED();
1318        return false;
1319     }
1320   }
1321   return true;
1322 }
1323 
InitCreditCardsTable()1324 bool AutofillTable::InitCreditCardsTable() {
1325   if (!db_->DoesTableExist("credit_cards")) {
1326     if (!db_->Execute("CREATE TABLE credit_cards ( "
1327                       "guid VARCHAR PRIMARY KEY, "
1328                       "name_on_card VARCHAR, "
1329                       "expiration_month INTEGER, "
1330                       "expiration_year INTEGER, "
1331                       "card_number_encrypted BLOB, "
1332                       "date_modified INTEGER NOT NULL DEFAULT 0, "
1333                       "origin VARCHAR DEFAULT '')")) {
1334       NOTREACHED();
1335       return false;
1336     }
1337   }
1338 
1339   return true;
1340 }
1341 
InitProfilesTable()1342 bool AutofillTable::InitProfilesTable() {
1343   if (!db_->DoesTableExist("autofill_profiles")) {
1344     if (!db_->Execute("CREATE TABLE autofill_profiles ( "
1345                       "guid VARCHAR PRIMARY KEY, "
1346                       "company_name VARCHAR, "
1347                       "street_address VARCHAR, "
1348                       "dependent_locality VARCHAR, "
1349                       "city VARCHAR, "
1350                       "state VARCHAR, "
1351                       "zipcode VARCHAR, "
1352                       "sorting_code VARCHAR, "
1353                       "country_code VARCHAR, "
1354                       "date_modified INTEGER NOT NULL DEFAULT 0, "
1355                       "origin VARCHAR DEFAULT '', "
1356                       "language_code VARCHAR)")) {
1357       NOTREACHED();
1358       return false;
1359     }
1360   }
1361   return true;
1362 }
1363 
InitProfileNamesTable()1364 bool AutofillTable::InitProfileNamesTable() {
1365   if (!db_->DoesTableExist("autofill_profile_names")) {
1366     if (!db_->Execute("CREATE TABLE autofill_profile_names ( "
1367                       "guid VARCHAR, "
1368                       "first_name VARCHAR, "
1369                       "middle_name VARCHAR, "
1370                       "last_name VARCHAR, "
1371                       "full_name VARCHAR)")) {
1372       NOTREACHED();
1373       return false;
1374     }
1375   }
1376   return true;
1377 }
1378 
InitProfileEmailsTable()1379 bool AutofillTable::InitProfileEmailsTable() {
1380   if (!db_->DoesTableExist("autofill_profile_emails")) {
1381     if (!db_->Execute("CREATE TABLE autofill_profile_emails ( "
1382                       "guid VARCHAR, "
1383                       "email VARCHAR)")) {
1384       NOTREACHED();
1385       return false;
1386     }
1387   }
1388   return true;
1389 }
1390 
InitProfilePhonesTable()1391 bool AutofillTable::InitProfilePhonesTable() {
1392   if (!db_->DoesTableExist("autofill_profile_phones")) {
1393     if (!db_->Execute("CREATE TABLE autofill_profile_phones ( "
1394                       "guid VARCHAR, "
1395                       "number VARCHAR)")) {
1396       NOTREACHED();
1397       return false;
1398     }
1399   }
1400   return true;
1401 }
1402 
InitProfileTrashTable()1403 bool AutofillTable::InitProfileTrashTable() {
1404   if (!db_->DoesTableExist("autofill_profiles_trash")) {
1405     if (!db_->Execute("CREATE TABLE autofill_profiles_trash ( "
1406                       "guid VARCHAR)")) {
1407       NOTREACHED();
1408       return false;
1409     }
1410   }
1411   return true;
1412 }
1413 
MigrateToVersion22ClearAutofillEmptyValueElements()1414 bool AutofillTable::MigrateToVersion22ClearAutofillEmptyValueElements() {
1415   if (!db_->DoesTableExist("autofill") &&
1416       (!db_->Execute("CREATE TABLE autofill ("
1417                      "  name VARCHAR,"
1418                      "  value VARCHAR,"
1419                      "  value_lower VARCHAR,"
1420                      "  pair_id INTEGER PRIMARY KEY,"
1421                      "  count INTEGER DEFAULT 1)") ||
1422        !db_->Execute("CREATE INDEX autofill_name ON autofill (name)") ||
1423        !db_->Execute("CREATE INDEX autofill_name_value_lower ON"
1424                      "  autofill (name, value_lower)") ||
1425        !db_->Execute("CREATE TABLE autofill_dates ("
1426                      "  pair_id INTEGER DEFAULT 0,"
1427                      "  date_created INTEGER DEFAULT 0)") ||
1428        !db_->Execute("CREATE INDEX autofill_dates_pair_id ON"
1429                      "  autofill (pair_id)")))
1430     return false;
1431 
1432 
1433   sql::Statement s(db_->GetUniqueStatement(
1434       "SELECT pair_id FROM autofill WHERE TRIM(value) = \"\""));
1435   if (!s.is_valid())
1436     return false;
1437 
1438   std::set<int64> ids;
1439   while (s.Step())
1440     ids.insert(s.ColumnInt64(0));
1441   if (!s.Succeeded())
1442     return false;
1443 
1444   if (!db_->Execute("DELETE FROM autofill WHERE TRIM(value) = \"\""))
1445     return false;
1446 
1447   for (std::set<int64>::const_iterator it = ids.begin(); it != ids.end();
1448        ++it) {
1449     sql::Statement s(db_->GetUniqueStatement(
1450         "DELETE FROM autofill_dates WHERE pair_id = ?"));
1451     s.BindInt64(0, *it);
1452     if (!s.Run())
1453       return false;
1454   }
1455 
1456   return true;
1457 }
1458 
1459 // Add the card_number_encrypted column if credit card table was not
1460 // created in this build (otherwise the column already exists).
1461 // WARNING: Do not change the order of the execution of the SQL
1462 // statements in this case!  Profile corruption and data migration
1463 // issues WILL OCCUR. See http://crbug.com/10913
1464 //
1465 // The problem is that if a user has a profile which was created before
1466 // r37036, when the credit_cards table was added, and then failed to
1467 // update this profile between the credit card addition and the addition
1468 // of the "encrypted" columns (44963), the next data migration will put
1469 // the user's profile in an incoherent state: The user will update from
1470 // a data profile set to be earlier than 22, and therefore pass through
1471 // this update case.  But because the user did not have a credit_cards
1472 // table before starting Chrome, it will have just been initialized
1473 // above, and so already have these columns -- and thus this data
1474 // update step will have failed.
1475 //
1476 // The false assumption in this case is that at this step in the
1477 // migration, the user has a credit card table, and that this
1478 // table does not include encrypted columns!
1479 // Because this case does not roll back the complete set of SQL
1480 // transactions properly in case of failure (that is, it does not
1481 // roll back the table initialization done above), the incoherent
1482 // profile will now see itself as being at version 22 -- but include a
1483 // fully initialized credit_cards table.  Every time Chrome runs, it
1484 // will try to update the web database and fail at this step, unless
1485 // we allow for the faulty assumption described above by checking for
1486 // the existence of the columns only AFTER we've executed the commands
1487 // to add them.
MigrateToVersion23AddCardNumberEncryptedColumn()1488 bool AutofillTable::MigrateToVersion23AddCardNumberEncryptedColumn() {
1489   if (!db_->DoesTableExist("autofill_profiles") &&
1490       (!db_->Execute("CREATE TABLE autofill_profiles ( "
1491                      "label VARCHAR, "
1492                      "unique_id INTEGER PRIMARY KEY, "
1493                      "first_name VARCHAR, "
1494                      "middle_name VARCHAR, "
1495                      "last_name VARCHAR, "
1496                      "email VARCHAR, "
1497                      "company_name VARCHAR, "
1498                      "address_line_1 VARCHAR, "
1499                      "address_line_2 VARCHAR, "
1500                      "city VARCHAR, "
1501                      "state VARCHAR, "
1502                      "zipcode VARCHAR, "
1503                      "country VARCHAR, "
1504                      "phone VARCHAR, "
1505                      "fax VARCHAR)") ||
1506        !db_->Execute("CREATE INDEX autofill_profiles_label_index"
1507                      "  ON autofill_profiles (label)")))
1508     return false;
1509 
1510   if (!db_->DoesTableExist("credit_cards") &&
1511       (!db_->Execute("CREATE TABLE credit_cards ( "
1512                      "label VARCHAR, "
1513                      "unique_id INTEGER PRIMARY KEY, "
1514                      "name_on_card VARCHAR, "
1515                      "type VARCHAR, "
1516                      "card_number VARCHAR, "
1517                      "expiration_month INTEGER, "
1518                      "expiration_year INTEGER, "
1519                      "verification_code VARCHAR, "
1520                      "billing_address VARCHAR, "
1521                      "shipping_address VARCHAR)") ||
1522        !db_->Execute("CREATE INDEX credit_cards_label_index"
1523                      "  ON credit_cards (label)")))
1524     return false;
1525 
1526   if (!db_->DoesColumnExist("credit_cards", "card_number_encrypted")) {
1527     if (!db_->Execute("ALTER TABLE credit_cards ADD COLUMN "
1528                       "card_number_encrypted BLOB DEFAULT NULL")) {
1529       return false;
1530     }
1531   }
1532 
1533   if (!db_->DoesColumnExist("credit_cards", "verification_code_encrypted")) {
1534     if (!db_->Execute("ALTER TABLE credit_cards ADD COLUMN "
1535                       "verification_code_encrypted BLOB DEFAULT NULL")) {
1536       return false;
1537     }
1538   }
1539 
1540   return true;
1541 }
1542 
1543 // One-time cleanup for http://crbug.com/38364 - In the presence of
1544 // multi-byte UTF-8 characters, that bug could cause Autofill strings
1545 // to grow larger and more corrupt with each save.  The cleanup removes
1546 // any row with a string field larger than a reasonable size.  The string
1547 // fields examined here are precisely the ones that were subject to
1548 // corruption by the original bug.
MigrateToVersion24CleanupOversizedStringFields()1549 bool AutofillTable::MigrateToVersion24CleanupOversizedStringFields() {
1550   const std::string autofill_is_too_big =
1551       "max(length(name), length(value)) > 500";
1552 
1553   const std::string credit_cards_is_too_big =
1554       "max(length(label), length(name_on_card), length(type), "
1555       "    length(expiration_month), length(expiration_year), "
1556       "    length(billing_address), length(shipping_address) "
1557       ") > 500";
1558 
1559   const std::string autofill_profiles_is_too_big =
1560       "max(length(label), length(first_name), "
1561       "    length(middle_name), length(last_name), length(email), "
1562       "    length(company_name), length(address_line_1), "
1563       "    length(address_line_2), length(city), length(state), "
1564       "    length(zipcode), length(country), length(phone)) > 500";
1565 
1566   std::string query = "DELETE FROM autofill_dates WHERE pair_id IN ("
1567       "SELECT pair_id FROM autofill WHERE " + autofill_is_too_big + ")";
1568 
1569   if (!db_->Execute(query.c_str()))
1570     return false;
1571 
1572   query = "DELETE FROM autofill WHERE " + autofill_is_too_big;
1573 
1574   if (!db_->Execute(query.c_str()))
1575     return false;
1576 
1577   // Only delete from legacy credit card tables where specific columns exist.
1578   if (db_->DoesColumnExist("credit_cards", "label") &&
1579       db_->DoesColumnExist("credit_cards", "name_on_card") &&
1580       db_->DoesColumnExist("credit_cards", "type") &&
1581       db_->DoesColumnExist("credit_cards", "expiration_month") &&
1582       db_->DoesColumnExist("credit_cards", "expiration_year") &&
1583       db_->DoesColumnExist("credit_cards", "billing_address") &&
1584       db_->DoesColumnExist("credit_cards", "shipping_address") &&
1585       db_->DoesColumnExist("autofill_profiles", "label")) {
1586     query = "DELETE FROM credit_cards WHERE (" + credit_cards_is_too_big +
1587         ") OR label IN (SELECT label FROM autofill_profiles WHERE " +
1588         autofill_profiles_is_too_big + ")";
1589 
1590     if (!db_->Execute(query.c_str()))
1591       return false;
1592   }
1593 
1594   if (db_->DoesColumnExist("autofill_profiles", "label")) {
1595     query = "DELETE FROM autofill_profiles WHERE " +
1596         autofill_profiles_is_too_big;
1597 
1598     if (!db_->Execute(query.c_str()))
1599       return false;
1600   }
1601 
1602   return true;
1603 }
1604 
1605 // Change the credit_cards.billing_address column from a string to an
1606 // int.  The stored string is the label of an address, so we have to
1607 // select the unique ID of this address using the label as a foreign
1608 // key into the |autofill_profiles| table.
MigrateToVersion27UpdateLegacyCreditCards()1609 bool AutofillTable::MigrateToVersion27UpdateLegacyCreditCards() {
1610   // Only migrate from legacy credit card tables where specific columns
1611   // exist.
1612   if (!(db_->DoesColumnExist("credit_cards", "unique_id") &&
1613         db_->DoesColumnExist("credit_cards", "billing_address") &&
1614         db_->DoesColumnExist("autofill_profiles", "unique_id"))) {
1615     return true;
1616   }
1617 
1618   std::string stmt =
1619       "SELECT credit_cards.unique_id, autofill_profiles.unique_id "
1620       "FROM autofill_profiles, credit_cards "
1621       "WHERE credit_cards.billing_address = autofill_profiles.label";
1622   sql::Statement s(db_->GetUniqueStatement(stmt.c_str()));
1623 
1624   std::map<int, int> cc_billing_map;
1625   while (s.Step())
1626     cc_billing_map[s.ColumnInt(0)] = s.ColumnInt(1);
1627   if (!s.Succeeded())
1628     return false;
1629 
1630   // Windows already stores the IDs as strings in |billing_address|. Try
1631   // to convert those.
1632   if (cc_billing_map.empty()) {
1633     std::string stmt = "SELECT unique_id,billing_address FROM credit_cards";
1634     sql::Statement s(db_->GetUniqueStatement(stmt.c_str()));
1635 
1636     while (s.Step()) {
1637       int id = 0;
1638       if (base::StringToInt(s.ColumnString(1), &id))
1639         cc_billing_map[s.ColumnInt(0)] = id;
1640     }
1641     if (!s.Succeeded())
1642       return false;
1643   }
1644 
1645   if (!db_->Execute("CREATE TABLE credit_cards_temp ( "
1646                     "label VARCHAR, "
1647                     "unique_id INTEGER PRIMARY KEY, "
1648                     "name_on_card VARCHAR, "
1649                     "type VARCHAR, "
1650                     "card_number VARCHAR, "
1651                     "expiration_month INTEGER, "
1652                     "expiration_year INTEGER, "
1653                     "verification_code VARCHAR, "
1654                     "billing_address INTEGER, "
1655                     "shipping_address VARCHAR, "
1656                     "card_number_encrypted BLOB, "
1657                     "verification_code_encrypted BLOB)")) {
1658     return false;
1659   }
1660 
1661   if (!db_->Execute(
1662       "INSERT INTO credit_cards_temp "
1663       "SELECT label,unique_id,name_on_card,type,card_number,"
1664       "expiration_month,expiration_year,verification_code,0,"
1665       "shipping_address,card_number_encrypted,"
1666       "verification_code_encrypted FROM credit_cards")) {
1667     return false;
1668   }
1669 
1670   if (!db_->Execute("DROP TABLE credit_cards"))
1671     return false;
1672 
1673   if (!db_->Execute("ALTER TABLE credit_cards_temp RENAME TO credit_cards"))
1674     return false;
1675 
1676   for (std::map<int, int>::const_iterator iter = cc_billing_map.begin();
1677        iter != cc_billing_map.end(); ++iter) {
1678     sql::Statement s(db_->GetCachedStatement(
1679         SQL_FROM_HERE,
1680         "UPDATE credit_cards SET billing_address=? WHERE unique_id=?"));
1681     s.BindInt(0, (*iter).second);
1682     s.BindInt(1, (*iter).first);
1683 
1684     if (!s.Run())
1685       return false;
1686   }
1687 
1688   return true;
1689 }
1690 
MigrateToVersion30AddDateModifed()1691 bool AutofillTable::MigrateToVersion30AddDateModifed() {
1692   // Add date_modified to autofill_profiles.
1693   if (!db_->DoesColumnExist("autofill_profiles", "date_modified")) {
1694     if (!db_->Execute("ALTER TABLE autofill_profiles ADD COLUMN "
1695                       "date_modified INTEGER NON NULL DEFAULT 0")) {
1696       return false;
1697     }
1698 
1699     sql::Statement s(db_->GetUniqueStatement(
1700         "UPDATE autofill_profiles SET date_modified=?"));
1701     s.BindInt64(0, Time::Now().ToTimeT());
1702 
1703     if (!s.Run())
1704       return false;
1705   }
1706 
1707   // Add date_modified to credit_cards.
1708   if (!db_->DoesColumnExist("credit_cards", "date_modified")) {
1709     if (!db_->Execute("ALTER TABLE credit_cards ADD COLUMN "
1710                       "date_modified INTEGER NON NULL DEFAULT 0")) {
1711       return false;
1712     }
1713 
1714     sql::Statement s(db_->GetUniqueStatement(
1715         "UPDATE credit_cards SET date_modified=?"));
1716     s.BindInt64(0, Time::Now().ToTimeT());
1717 
1718     if (!s.Run())
1719       return false;
1720   }
1721 
1722   return true;
1723 }
1724 
MigrateToVersion31AddGUIDToCreditCardsAndProfiles()1725 bool AutofillTable::MigrateToVersion31AddGUIDToCreditCardsAndProfiles() {
1726   // Note that we need to check for the guid column's existence due to the
1727   // fact that for a version 22 database the |autofill_profiles| table
1728   // gets created fresh with |InitAutofillProfilesTable|.
1729   if (!db_->DoesColumnExist("autofill_profiles", "guid")) {
1730     if (!db_->Execute("ALTER TABLE autofill_profiles ADD COLUMN "
1731                       "guid VARCHAR NOT NULL DEFAULT \"\"")) {
1732       return false;
1733     }
1734 
1735     // Set all the |guid| fields to valid values.
1736 
1737     sql::Statement s(db_->GetUniqueStatement("SELECT unique_id "
1738                                              "FROM autofill_profiles"));
1739 
1740     while (s.Step()) {
1741       sql::Statement update_s(
1742           db_->GetUniqueStatement("UPDATE autofill_profiles "
1743                                   "SET guid=? WHERE unique_id=?"));
1744       update_s.BindString(0, base::GenerateGUID());
1745       update_s.BindInt(1, s.ColumnInt(0));
1746 
1747       if (!update_s.Run())
1748         return false;
1749     }
1750     if (!s.Succeeded())
1751       return false;
1752   }
1753 
1754   // Note that we need to check for the guid column's existence due to the
1755   // fact that for a version 22 database the |autofill_profiles| table
1756   // gets created fresh with |InitAutofillProfilesTable|.
1757   if (!db_->DoesColumnExist("credit_cards", "guid")) {
1758     if (!db_->Execute("ALTER TABLE credit_cards ADD COLUMN "
1759                       "guid VARCHAR NOT NULL DEFAULT \"\"")) {
1760       return false;
1761     }
1762 
1763     // Set all the |guid| fields to valid values.
1764 
1765     sql::Statement s(db_->GetUniqueStatement("SELECT unique_id "
1766                                              "FROM credit_cards"));
1767 
1768     while (s.Step()) {
1769       sql::Statement update_s(
1770           db_->GetUniqueStatement("UPDATE credit_cards "
1771                                   "set guid=? WHERE unique_id=?"));
1772       update_s.BindString(0, base::GenerateGUID());
1773       update_s.BindInt(1, s.ColumnInt(0));
1774 
1775       if (!update_s.Run())
1776         return false;
1777     }
1778     if (!s.Succeeded())
1779       return false;
1780   }
1781 
1782   return true;
1783 }
1784 
MigrateToVersion32UpdateProfilesAndCreditCards()1785 bool AutofillTable::MigrateToVersion32UpdateProfilesAndCreditCards() {
1786   if (db_->DoesColumnExist("autofill_profiles", "unique_id")) {
1787     if (!db_->Execute("CREATE TABLE autofill_profiles_temp ( "
1788                       "guid VARCHAR PRIMARY KEY, "
1789                       "label VARCHAR, "
1790                       "first_name VARCHAR, "
1791                       "middle_name VARCHAR, "
1792                       "last_name VARCHAR, "
1793                       "email VARCHAR, "
1794                       "company_name VARCHAR, "
1795                       "address_line_1 VARCHAR, "
1796                       "address_line_2 VARCHAR, "
1797                       "city VARCHAR, "
1798                       "state VARCHAR, "
1799                       "zipcode VARCHAR, "
1800                       "country VARCHAR, "
1801                       "phone VARCHAR, "
1802                       "date_modified INTEGER NOT NULL DEFAULT 0)")) {
1803       return false;
1804     }
1805 
1806     if (!db_->Execute(
1807         "INSERT INTO autofill_profiles_temp "
1808         "SELECT guid, label, first_name, middle_name, last_name, email, "
1809         "company_name, address_line_1, address_line_2, city, state, "
1810         "zipcode, country, phone, date_modified "
1811         "FROM autofill_profiles")) {
1812       return false;
1813     }
1814 
1815     if (!db_->Execute("DROP TABLE autofill_profiles"))
1816       return false;
1817 
1818     if (!db_->Execute(
1819         "ALTER TABLE autofill_profiles_temp RENAME TO autofill_profiles")) {
1820       return false;
1821     }
1822   }
1823 
1824   if (db_->DoesColumnExist("credit_cards", "unique_id")) {
1825     if (!db_->Execute("CREATE TABLE credit_cards_temp ( "
1826                       "guid VARCHAR PRIMARY KEY, "
1827                       "label VARCHAR, "
1828                       "name_on_card VARCHAR, "
1829                       "expiration_month INTEGER, "
1830                       "expiration_year INTEGER, "
1831                       "card_number_encrypted BLOB, "
1832                       "date_modified INTEGER NOT NULL DEFAULT 0)")) {
1833       return false;
1834     }
1835 
1836     if (!db_->Execute(
1837         "INSERT INTO credit_cards_temp "
1838         "SELECT guid, label, name_on_card, expiration_month, "
1839         "expiration_year, card_number_encrypted, date_modified "
1840         "FROM credit_cards")) {
1841       return false;
1842     }
1843 
1844     if (!db_->Execute("DROP TABLE credit_cards"))
1845       return false;
1846 
1847     if (!db_->Execute("ALTER TABLE credit_cards_temp RENAME TO credit_cards"))
1848       return false;
1849   }
1850 
1851   return true;
1852 }
1853 
1854 // Test the existence of the |first_name| column as an indication that
1855 // we need a migration.  It is possible that the new |autofill_profiles|
1856 // schema is in place because the table was newly created when migrating
1857 // from a pre-version-22 database.
MigrateToVersion33ProfilesBasedOnFirstName()1858 bool AutofillTable::MigrateToVersion33ProfilesBasedOnFirstName() {
1859   if (!db_->DoesTableExist("autofill_profile_names") &&
1860       !db_->Execute("CREATE TABLE autofill_profile_names ( "
1861                     "guid VARCHAR, "
1862                     "first_name VARCHAR, "
1863                     "middle_name VARCHAR, "
1864                     "last_name VARCHAR)"))
1865     return false;
1866 
1867   if (!db_->DoesTableExist("autofill_profile_emails") &&
1868       !db_->Execute("CREATE TABLE autofill_profile_emails ( "
1869                     "guid VARCHAR, "
1870                     "email VARCHAR)"))
1871     return false;
1872 
1873   if (!db_->DoesTableExist("autofill_profile_phones") &&
1874       !db_->Execute("CREATE TABLE autofill_profile_phones ( "
1875                     "guid VARCHAR, "
1876                     "type INTEGER DEFAULT 0, "
1877                     "number VARCHAR)"))
1878     return false;
1879 
1880   if (db_->DoesColumnExist("autofill_profiles", "first_name")) {
1881     // Create autofill_profiles_temp table that will receive the data.
1882     if (!db_->DoesTableExist("autofill_profiles_temp")) {
1883       if (!db_->Execute("CREATE TABLE autofill_profiles_temp ( "
1884                         "guid VARCHAR PRIMARY KEY, "
1885                         "company_name VARCHAR, "
1886                         "address_line_1 VARCHAR, "
1887                         "address_line_2 VARCHAR, "
1888                         "city VARCHAR, "
1889                         "state VARCHAR, "
1890                         "zipcode VARCHAR, "
1891                         "country VARCHAR, "
1892                         "date_modified INTEGER NOT NULL DEFAULT 0)")) {
1893         return false;
1894       }
1895     }
1896 
1897     sql::Statement s(db_->GetUniqueStatement(
1898         "SELECT guid, first_name, middle_name, last_name, email, "
1899         "company_name, address_line_1, address_line_2, city, state, "
1900         "zipcode, country, phone, date_modified "
1901         "FROM autofill_profiles"));
1902 
1903     while (s.Step()) {
1904       AutofillProfile profile;
1905       int index = 0;
1906       profile.set_guid(s.ColumnString(index++));
1907       DCHECK(base::IsValidGUID(profile.guid()));
1908 
1909       profile.SetRawInfo(NAME_FIRST, s.ColumnString16(index++));
1910       profile.SetRawInfo(NAME_MIDDLE, s.ColumnString16(index++));
1911       profile.SetRawInfo(NAME_LAST, s.ColumnString16(index++));
1912       profile.SetRawInfo(EMAIL_ADDRESS, s.ColumnString16(index++));
1913       profile.SetRawInfo(COMPANY_NAME, s.ColumnString16(index++));
1914       profile.SetRawInfo(ADDRESS_HOME_LINE1, s.ColumnString16(index++));
1915       profile.SetRawInfo(ADDRESS_HOME_LINE2, s.ColumnString16(index++));
1916       profile.SetRawInfo(ADDRESS_HOME_CITY, s.ColumnString16(index++));
1917       profile.SetRawInfo(ADDRESS_HOME_STATE, s.ColumnString16(index++));
1918       profile.SetRawInfo(ADDRESS_HOME_ZIP, s.ColumnString16(index++));
1919       profile.SetInfo(AutofillType(ADDRESS_HOME_COUNTRY),
1920                       s.ColumnString16(index++), app_locale_);
1921       profile.SetRawInfo(PHONE_HOME_WHOLE_NUMBER, s.ColumnString16(index++));
1922       int64 date_modified = s.ColumnInt64(index++);
1923 
1924       sql::Statement s_insert(db_->GetUniqueStatement(
1925           "INSERT INTO autofill_profiles_temp"
1926           "(guid, company_name, address_line_1, address_line_2, city,"
1927           " state, zipcode, country, date_modified)"
1928           "VALUES (?,?,?,?,?,?,?,?,?)"));
1929       index = 0;
1930       s_insert.BindString(index++, profile.guid());
1931       s_insert.BindString16(index++, profile.GetRawInfo(COMPANY_NAME));
1932       s_insert.BindString16(index++, profile.GetRawInfo(ADDRESS_HOME_LINE1));
1933       s_insert.BindString16(index++, profile.GetRawInfo(ADDRESS_HOME_LINE2));
1934       s_insert.BindString16(index++, profile.GetRawInfo(ADDRESS_HOME_CITY));
1935       s_insert.BindString16(index++, profile.GetRawInfo(ADDRESS_HOME_STATE));
1936       s_insert.BindString16(index++, profile.GetRawInfo(ADDRESS_HOME_ZIP));
1937       s_insert.BindString16(index++, profile.GetRawInfo(ADDRESS_HOME_COUNTRY));
1938       s_insert.BindInt64(index++, date_modified);
1939 
1940       if (!s_insert.Run())
1941         return false;
1942 
1943       // Add the other bits: names, emails, and phone numbers.
1944       if (!AddAutofillProfileNamesForVersion3x(profile, db_) ||
1945           !AddAutofillProfileEmails(profile, db_) ||
1946           !AddAutofillProfilePhones(profile, db_)) {
1947         return false;
1948       }
1949     }  // endwhile
1950     if (!s.Succeeded())
1951       return false;
1952 
1953     if (!db_->Execute("DROP TABLE autofill_profiles"))
1954       return false;
1955 
1956     if (!db_->Execute(
1957         "ALTER TABLE autofill_profiles_temp RENAME TO autofill_profiles")) {
1958       return false;
1959     }
1960   }
1961 
1962   // Remove the labels column from the credit_cards table.
1963   if (db_->DoesColumnExist("credit_cards", "label")) {
1964     if (!db_->Execute("CREATE TABLE credit_cards_temp ( "
1965                       "guid VARCHAR PRIMARY KEY, "
1966                       "name_on_card VARCHAR, "
1967                       "expiration_month INTEGER, "
1968                       "expiration_year INTEGER, "
1969                       "card_number_encrypted BLOB, "
1970                       "date_modified INTEGER NOT NULL DEFAULT 0)")) {
1971       return false;
1972     }
1973 
1974     if (!db_->Execute(
1975         "INSERT INTO credit_cards_temp "
1976         "SELECT guid, name_on_card, expiration_month, "
1977         "expiration_year, card_number_encrypted, date_modified "
1978         "FROM credit_cards")) {
1979       return false;
1980     }
1981 
1982     if (!db_->Execute("DROP TABLE credit_cards"))
1983       return false;
1984 
1985     if (!db_->Execute("ALTER TABLE credit_cards_temp RENAME TO credit_cards"))
1986       return false;
1987   }
1988 
1989   return true;
1990 }
1991 
1992 // Test the existence of the |country_code| column as an indication that
1993 // we need a migration.  It is possible that the new |autofill_profiles|
1994 // schema is in place because the table was newly created when migrating
1995 // from a pre-version-22 database.
MigrateToVersion34ProfilesBasedOnCountryCode()1996 bool AutofillTable::MigrateToVersion34ProfilesBasedOnCountryCode() {
1997   if (!db_->DoesColumnExist("autofill_profiles", "country_code")) {
1998     if (!db_->Execute("ALTER TABLE autofill_profiles ADD COLUMN "
1999                       "country_code VARCHAR")) {
2000       return false;
2001     }
2002 
2003     // Set all the |country_code| fields to match existing |country| values.
2004     sql::Statement s(db_->GetUniqueStatement("SELECT guid, country "
2005                                              "FROM autofill_profiles"));
2006 
2007     while (s.Step()) {
2008       sql::Statement update_s(
2009           db_->GetUniqueStatement("UPDATE autofill_profiles "
2010                                   "SET country_code=? WHERE guid=?"));
2011 
2012       base::string16 country = s.ColumnString16(1);
2013       update_s.BindString(0, AutofillCountry::GetCountryCode(country,
2014                                                              app_locale_));
2015       update_s.BindString(1, s.ColumnString(0));
2016 
2017       if (!update_s.Run())
2018         return false;
2019     }
2020     if (!s.Succeeded())
2021       return false;
2022   }
2023 
2024   return true;
2025 }
2026 
2027 // Correct all country codes with value "UK" to be "GB".  This data
2028 // was mistakenly introduced in build 686.0.  This migration is to clean
2029 // it up.  See http://crbug.com/74511 for details.
MigrateToVersion35GreatBritainCountryCodes()2030 bool AutofillTable::MigrateToVersion35GreatBritainCountryCodes() {
2031   sql::Statement s(db_->GetUniqueStatement(
2032       "UPDATE autofill_profiles SET country_code=\"GB\" "
2033       "WHERE country_code=\"UK\""));
2034 
2035   return s.Run();
2036 }
2037 
2038 // Merge and cull older profiles where possible.
MigrateToVersion37MergeAndCullOlderProfiles()2039 bool AutofillTable::MigrateToVersion37MergeAndCullOlderProfiles() {
2040   if (!db_->DoesTableExist("autofill_profiles_trash") &&
2041       !db_->Execute("CREATE TABLE autofill_profiles_trash (guid VARCHAR)"))
2042     return false;
2043 
2044   sql::Statement s(db_->GetUniqueStatement(
2045       "SELECT guid, date_modified FROM autofill_profiles"));
2046 
2047   // Accumulate the good profiles.
2048   std::vector<AutofillProfile> accumulated_profiles;
2049   std::vector<AutofillProfile*> accumulated_profiles_p;
2050   std::map<std::string, int64> modification_map;
2051   while (s.Step()) {
2052     std::string guid = s.ColumnString(0);
2053     int64 date_modified = s.ColumnInt64(1);
2054     modification_map.insert(
2055         std::pair<std::string, int64>(guid, date_modified));
2056 
2057     sql::Statement s(db_->GetUniqueStatement(
2058         "SELECT guid, company_name, address_line_1, address_line_2, city, "
2059         " state, zipcode, country, country_code, date_modified "
2060         "FROM autofill_profiles "
2061         "WHERE guid=?"));
2062     s.BindString(0, guid);
2063 
2064     if (!s.Step())
2065       return false;
2066 
2067     scoped_ptr<AutofillProfile> profile(new AutofillProfile);
2068     int index = 0;
2069     profile->set_guid(s.ColumnString(index++));
2070     DCHECK(base::IsValidGUID(profile->guid()));
2071 
2072     profile->SetRawInfo(COMPANY_NAME, s.ColumnString16(index++));
2073     profile->SetRawInfo(ADDRESS_HOME_LINE1, s.ColumnString16(index++));
2074     profile->SetRawInfo(ADDRESS_HOME_LINE2, s.ColumnString16(index++));
2075     profile->SetRawInfo(ADDRESS_HOME_CITY, s.ColumnString16(index++));
2076     profile->SetRawInfo(ADDRESS_HOME_STATE, s.ColumnString16(index++));
2077     profile->SetRawInfo(ADDRESS_HOME_ZIP, s.ColumnString16(index++));
2078     // Intentionally skip column 7, which stores the localized country name.
2079     index++;
2080     profile->SetRawInfo(ADDRESS_HOME_COUNTRY, s.ColumnString16(index++));
2081     // Intentionally skip column 9, which stores the profile's modification
2082     // date.
2083     index++;
2084     profile->set_origin(s.ColumnString(index++));
2085 
2086     // Get associated name info.
2087     AddAutofillProfileNamesToProfileForVersion37(db_, profile.get());
2088 
2089     // Get associated email info.
2090     AddAutofillProfileEmailsToProfile(db_, profile.get());
2091 
2092     // Get associated phone info.
2093     AddAutofillProfilePhonesToProfile(db_, profile.get());
2094 
2095     if (PersonalDataManager::IsValidLearnableProfile(*profile, app_locale_)) {
2096       std::vector<AutofillProfile> merged_profiles;
2097       std::string merged_guid = PersonalDataManager::MergeProfile(
2098           *profile, accumulated_profiles_p, app_locale_, &merged_profiles);
2099 
2100       std::swap(accumulated_profiles, merged_profiles);
2101 
2102       accumulated_profiles_p.clear();
2103       accumulated_profiles_p.resize(accumulated_profiles.size());
2104       std::transform(accumulated_profiles.begin(),
2105                      accumulated_profiles.end(),
2106                      accumulated_profiles_p.begin(),
2107                      address_of<AutofillProfile>);
2108 
2109       // If the profile got merged trash the original.
2110       if (merged_guid != profile->guid())
2111         AddAutofillGUIDToTrash(profile->guid());
2112     } else {
2113       // An invalid profile, so trash it.
2114       AddAutofillGUIDToTrash(profile->guid());
2115     }
2116   }  // endwhile
2117   if (!s.Succeeded())
2118     return false;
2119 
2120   // Drop the current profiles.
2121   if (!ClearAutofillProfiles())
2122     return false;
2123 
2124   // Add the newly merged profiles back in.
2125   for (std::vector<AutofillProfile>::const_iterator
2126           iter = accumulated_profiles.begin();
2127        iter != accumulated_profiles.end();
2128        ++iter) {
2129     // Save the profile with its original modification date.
2130     std::map<std::string, int64>::const_iterator date_item =
2131         modification_map.find(iter->guid());
2132     if (date_item == modification_map.end())
2133       return false;
2134 
2135     sql::Statement s(db_->GetUniqueStatement(
2136         "INSERT INTO autofill_profiles"
2137         "(guid, company_name, address_line_1, address_line_2, city, state,"
2138         " zipcode, country, country_code, date_modified)"
2139         "VALUES (?,?,?,?,?,?,?,?,?,?)"));
2140     int index = 0;
2141     s.BindString(index++, iter->guid());
2142     s.BindString16(index++, GetInfo(*iter, COMPANY_NAME));
2143     s.BindString16(index++, GetInfo(*iter, ADDRESS_HOME_LINE1));
2144     s.BindString16(index++, GetInfo(*iter, ADDRESS_HOME_LINE2));
2145     s.BindString16(index++, GetInfo(*iter, ADDRESS_HOME_CITY));
2146     s.BindString16(index++, GetInfo(*iter, ADDRESS_HOME_STATE));
2147     s.BindString16(index++, GetInfo(*iter, ADDRESS_HOME_ZIP));
2148     s.BindString16(index++, base::string16());  // This column is deprecated.
2149     s.BindString16(index++, GetInfo(*iter, ADDRESS_HOME_COUNTRY));
2150     s.BindInt64(index++, date_item->second);
2151 
2152     if (!s.Run())
2153       return false;
2154 
2155     if (!AddAutofillProfileNamesForVersion3x(*iter, db_) ||
2156         !AddAutofillProfileEmails(*iter, db_) ||
2157         !AddAutofillProfilePhones(*iter, db_)) {
2158       return false;
2159     }
2160   }
2161 
2162   return true;
2163 }
2164 
MigrateToVersion51AddOriginColumn()2165 bool AutofillTable::MigrateToVersion51AddOriginColumn() {
2166   sql::Transaction transaction(db_);
2167   if (!transaction.Begin())
2168     return false;
2169 
2170   // Add origin to autofill_profiles.
2171   if (!db_->DoesColumnExist("autofill_profiles", "origin") &&
2172       !db_->Execute("ALTER TABLE autofill_profiles "
2173                     "ADD COLUMN origin VARCHAR DEFAULT ''")) {
2174     return false;
2175   }
2176 
2177   // Add origin to credit_cards.
2178   if (!db_->DoesColumnExist("credit_cards", "origin") &&
2179       !db_->Execute("ALTER TABLE credit_cards "
2180                     "ADD COLUMN origin VARCHAR DEFAULT ''")) {
2181       return false;
2182   }
2183 
2184   return transaction.Commit();
2185 }
2186 
MigrateToVersion54AddI18nFieldsAndRemoveDeprecatedFields()2187 bool AutofillTable::MigrateToVersion54AddI18nFieldsAndRemoveDeprecatedFields() {
2188   sql::Transaction transaction(db_);
2189   if (!transaction.Begin())
2190     return false;
2191 
2192   // Test the existence of the |address_line_1| column as an indication that a
2193   // migration is needed.  It is possible that the new |autofill_profile_phones|
2194   // schema is in place because the table was newly created when migrating from
2195   // a pre-version-23 database.
2196   if (db_->DoesColumnExist("autofill_profiles", "address_line_1")) {
2197     // Create a temporary copy of the autofill_profiles table in the (newer)
2198     // version 54 format.  This table
2199     //   (a) adds columns for street_address, dependent_locality, and
2200     //       sorting_code,
2201     //   (b) removes the address_line_1 and address_line_2 columns, which are
2202     //       replaced by the street_address column, and
2203     //   (c) removes the country column, which was long deprecated.
2204     if (db_->DoesTableExist("autofill_profiles_temp") ||
2205         !db_->Execute("CREATE TABLE autofill_profiles_temp ( "
2206                       "guid VARCHAR PRIMARY KEY, "
2207                       "company_name VARCHAR, "
2208                       "street_address VARCHAR, "
2209                       "dependent_locality VARCHAR, "
2210                       "city VARCHAR, "
2211                       "state VARCHAR, "
2212                       "zipcode VARCHAR, "
2213                       "sorting_code VARCHAR, "
2214                       "country_code VARCHAR, "
2215                       "date_modified INTEGER NOT NULL DEFAULT 0, "
2216                       "origin VARCHAR DEFAULT '')")) {
2217       return false;
2218     }
2219 
2220     // Copy over the data from the autofill_profiles table, taking care to merge
2221     // the address lines 1 and 2 into the new street_address column.
2222     if (!db_->Execute("INSERT INTO autofill_profiles_temp "
2223                       "SELECT guid, company_name, '', '', city, state, zipcode,"
2224                       " '', country_code, date_modified, origin "
2225                       "FROM autofill_profiles")) {
2226       return false;
2227     }
2228     sql::Statement s(db_->GetUniqueStatement(
2229         "SELECT guid, address_line_1, address_line_2 FROM autofill_profiles"));
2230     while (s.Step()) {
2231       std::string guid = s.ColumnString(0);
2232       base::string16 line1 = s.ColumnString16(1);
2233       base::string16 line2 = s.ColumnString16(2);
2234       base::string16 street_address = line1;
2235       if (!line2.empty())
2236         street_address += base::ASCIIToUTF16("\n") + line2;
2237 
2238       sql::Statement s_update(db_->GetUniqueStatement(
2239           "UPDATE autofill_profiles_temp SET street_address=? WHERE guid=?"));
2240       s_update.BindString16(0, street_address);
2241       s_update.BindString(1, guid);
2242       if (!s_update.Run())
2243         return false;
2244     }
2245     if (!s.Succeeded())
2246       return false;
2247 
2248     // Delete the existing (version 53) table and replace it with the contents
2249     // of the temporary table.
2250     if (!db_->Execute("DROP TABLE autofill_profiles") ||
2251         !db_->Execute("ALTER TABLE autofill_profiles_temp "
2252                       "RENAME TO autofill_profiles")) {
2253       return false;
2254     }
2255   }
2256 
2257   // Test the existence of the |type| column as an indication that a migration
2258   // is needed.  It is possible that the new |autofill_profile_phones| schema is
2259   // in place because the table was newly created when migrating from a
2260   // pre-version-23 database.
2261   if (db_->DoesColumnExist("autofill_profile_phones", "type")) {
2262     // Create a temporary copy of the autofill_profile_phones table in the
2263     // (newer) version 54 format.  This table removes the deprecated |type|
2264     // column.
2265     if (db_->DoesTableExist("autofill_profile_phones_temp") ||
2266         !db_->Execute("CREATE TABLE autofill_profile_phones_temp ( "
2267                       "guid VARCHAR, "
2268                       "number VARCHAR)")) {
2269       return false;
2270     }
2271 
2272     // Copy over the data from the autofill_profile_phones table.
2273     if (!db_->Execute("INSERT INTO autofill_profile_phones_temp "
2274                       "SELECT guid, number FROM autofill_profile_phones")) {
2275       return false;
2276     }
2277 
2278     // Delete the existing (version 53) table and replace it with the contents
2279     // of the temporary table.
2280     if (!db_->Execute("DROP TABLE autofill_profile_phones"))
2281       return false;
2282     if (!db_->Execute("ALTER TABLE autofill_profile_phones_temp "
2283                       "RENAME TO autofill_profile_phones")) {
2284       return false;
2285     }
2286   }
2287 
2288   return transaction.Commit();
2289 }
2290 
MigrateToVersion55MergeAutofillDatesTable()2291 bool AutofillTable::MigrateToVersion55MergeAutofillDatesTable() {
2292   sql::Transaction transaction(db_);
2293   if (!transaction.Begin())
2294     return false;
2295 
2296   if (db_->DoesTableExist("autofill_temp") ||
2297       !db_->Execute("CREATE TABLE autofill_temp ("
2298                     "name VARCHAR, "
2299                     "value VARCHAR, "
2300                     "value_lower VARCHAR, "
2301                     "date_created INTEGER DEFAULT 0, "
2302                     "date_last_used INTEGER DEFAULT 0, "
2303                     "count INTEGER DEFAULT 1, "
2304                     "PRIMARY KEY (name, value))")) {
2305     return false;
2306   }
2307 
2308   // Slurp up the data from the existing table and write it to the new table.
2309   sql::Statement s(db_->GetUniqueStatement(
2310       "SELECT name, value, value_lower, count, MIN(date_created),"
2311       " MAX(date_created) "
2312       "FROM autofill a JOIN autofill_dates ad ON a.pair_id=ad.pair_id "
2313       "GROUP BY name, value, value_lower, count"));
2314   while (s.Step()) {
2315     sql::Statement s_insert(db_->GetUniqueStatement(
2316         "INSERT INTO autofill_temp "
2317         "(name, value, value_lower, count, date_created, date_last_used) "
2318         "VALUES (?, ?, ?, ?, ?, ?)"));
2319     s_insert.BindString16(0, s.ColumnString16(0));
2320     s_insert.BindString16(1, s.ColumnString16(1));
2321     s_insert.BindString16(2, s.ColumnString16(2));
2322     s_insert.BindInt(3, s.ColumnInt(3));
2323     s_insert.BindInt64(4, s.ColumnInt64(4));
2324     s_insert.BindInt64(5, s.ColumnInt64(5));
2325     if (!s_insert.Run())
2326       return false;
2327   }
2328 
2329   if (!s.Succeeded())
2330     return false;
2331 
2332   // Delete the existing (version 54) tables and replace them with the contents
2333   // of the temporary table.
2334   if (!db_->Execute("DROP TABLE autofill") ||
2335       !db_->Execute("DROP TABLE autofill_dates") ||
2336       !db_->Execute("ALTER TABLE autofill_temp "
2337                     "RENAME TO autofill")) {
2338     return false;
2339   }
2340 
2341   // Create indices on the new table, for fast lookups.
2342   if (!db_->Execute("CREATE INDEX autofill_name ON autofill (name)") ||
2343       !db_->Execute("CREATE INDEX autofill_name_value_lower ON "
2344                     "autofill (name, value_lower)")) {
2345     return false;
2346   }
2347 
2348 
2349   return transaction.Commit();
2350 }
2351 
MigrateToVersion56AddProfileLanguageCodeForFormatting()2352 bool AutofillTable::MigrateToVersion56AddProfileLanguageCodeForFormatting() {
2353   return db_->Execute("ALTER TABLE autofill_profiles "
2354                       "ADD COLUMN language_code VARCHAR");
2355 }
2356 
MigrateToVersion57AddFullNameField()2357 bool AutofillTable::MigrateToVersion57AddFullNameField() {
2358   return db_->Execute("ALTER TABLE autofill_profile_names "
2359                       "ADD COLUMN full_name VARCHAR");
2360 }
2361 
2362 }  // namespace autofill
2363