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