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