Index: components/autofill/browser/webdata/autofill_table.cc |
diff --git a/components/autofill/browser/webdata/autofill_table.cc b/components/autofill/browser/webdata/autofill_table.cc |
deleted file mode 100644 |
index 50bdd629693588b0a6dfe19e861daa726f016ccb..0000000000000000000000000000000000000000 |
--- a/components/autofill/browser/webdata/autofill_table.cc |
+++ /dev/null |
@@ -1,2192 +0,0 @@ |
-// Copyright (c) 2012 The Chromium Authors. All rights reserved. |
-// Use of this source code is governed by a BSD-style license that can be |
-// found in the LICENSE file. |
- |
-#include "components/autofill/browser/webdata/autofill_table.h" |
- |
-#include <algorithm> |
-#include <limits> |
-#include <map> |
-#include <set> |
-#include <string> |
-#include <vector> |
- |
-#include "base/guid.h" |
-#include "base/i18n/case_conversion.h" |
-#include "base/logging.h" |
-#include "base/strings/string_number_conversions.h" |
-#include "base/time.h" |
-#include "base/tuple.h" |
-#include "components/autofill/browser/autofill_country.h" |
-#include "components/autofill/browser/autofill_profile.h" |
-#include "components/autofill/browser/autofill_type.h" |
-#include "components/autofill/browser/credit_card.h" |
-#include "components/autofill/browser/personal_data_manager.h" |
-#include "components/autofill/browser/webdata/autofill_change.h" |
-#include "components/autofill/browser/webdata/autofill_entry.h" |
-#include "components/autofill/core/common/form_field_data.h" |
-#include "components/webdata/common/web_database.h" |
-#include "components/webdata/encryptor/encryptor.h" |
-#include "googleurl/src/gurl.h" |
-#include "sql/statement.h" |
-#include "sql/transaction.h" |
-#include "ui/base/l10n/l10n_util.h" |
- |
-using base::Time; |
- |
-namespace autofill { |
-namespace { |
- |
-typedef std::vector<Tuple3<int64, base::string16, base::string16> > |
- AutofillElementList; |
- |
-// TODO(dhollowa): Find a common place for this. It is duplicated in |
-// personal_data_manager.cc. |
-template<typename T> |
-T* address_of(T& v) { |
- return &v; |
-} |
- |
-base::string16 LimitDataSize(const base::string16& data) { |
- if (data.size() > AutofillTable::kMaxDataLength) |
- return data.substr(0, AutofillTable::kMaxDataLength); |
- |
- return data; |
-} |
- |
-void BindAutofillProfileToStatement(const AutofillProfile& profile, |
- sql::Statement* s, |
- const std::string& app_locale) { |
- DCHECK(base::IsValidGUID(profile.guid())); |
- s->BindString(0, profile.guid()); |
- |
- base::string16 text = profile.GetRawInfo(COMPANY_NAME); |
- s->BindString16(1, LimitDataSize(text)); |
- text = profile.GetRawInfo(ADDRESS_HOME_LINE1); |
- s->BindString16(2, LimitDataSize(text)); |
- text = profile.GetRawInfo(ADDRESS_HOME_LINE2); |
- s->BindString16(3, LimitDataSize(text)); |
- text = profile.GetRawInfo(ADDRESS_HOME_CITY); |
- s->BindString16(4, LimitDataSize(text)); |
- text = profile.GetRawInfo(ADDRESS_HOME_STATE); |
- s->BindString16(5, LimitDataSize(text)); |
- text = profile.GetRawInfo(ADDRESS_HOME_ZIP); |
- s->BindString16(6, LimitDataSize(text)); |
- text = profile.GetInfo(ADDRESS_HOME_COUNTRY, app_locale); |
- s->BindString16(7, LimitDataSize(text)); |
- text = profile.GetRawInfo(ADDRESS_HOME_COUNTRY); |
- s->BindString16(8, LimitDataSize(text)); |
- s->BindInt64(9, Time::Now().ToTimeT()); |
- s->BindString(10, profile.origin()); |
-} |
- |
-AutofillProfile* AutofillProfileFromStatement(const sql::Statement& s, |
- const std::string& app_locale) { |
- AutofillProfile* profile = new AutofillProfile; |
- profile->set_guid(s.ColumnString(0)); |
- DCHECK(base::IsValidGUID(profile->guid())); |
- |
- profile->SetRawInfo(COMPANY_NAME, s.ColumnString16(1)); |
- profile->SetRawInfo(ADDRESS_HOME_LINE1, s.ColumnString16(2)); |
- profile->SetRawInfo(ADDRESS_HOME_LINE2, s.ColumnString16(3)); |
- profile->SetRawInfo(ADDRESS_HOME_CITY, s.ColumnString16(4)); |
- profile->SetRawInfo(ADDRESS_HOME_STATE, s.ColumnString16(5)); |
- profile->SetRawInfo(ADDRESS_HOME_ZIP, s.ColumnString16(6)); |
- // Intentionally skip column 7, which stores the localized country name. |
- profile->SetRawInfo(ADDRESS_HOME_COUNTRY, s.ColumnString16(8)); |
- // Intentionally skip column 9, which stores the profile's modification date. |
- profile->set_origin(s.ColumnString(10)); |
- |
- return profile; |
-} |
- |
-void BindCreditCardToStatement(const CreditCard& credit_card, |
- sql::Statement* s) { |
- DCHECK(base::IsValidGUID(credit_card.guid())); |
- s->BindString(0, credit_card.guid()); |
- |
- base::string16 text = credit_card.GetRawInfo(CREDIT_CARD_NAME); |
- s->BindString16(1, LimitDataSize(text)); |
- text = credit_card.GetRawInfo(CREDIT_CARD_EXP_MONTH); |
- s->BindString16(2, LimitDataSize(text)); |
- text = credit_card.GetRawInfo(CREDIT_CARD_EXP_4_DIGIT_YEAR); |
- s->BindString16(3, LimitDataSize(text)); |
- text = credit_card.GetRawInfo(CREDIT_CARD_NUMBER); |
- std::string encrypted_data; |
- Encryptor::EncryptString16(text, &encrypted_data); |
- s->BindBlob(4, encrypted_data.data(), |
- static_cast<int>(encrypted_data.length())); |
- s->BindInt64(5, Time::Now().ToTimeT()); |
- s->BindString(6, credit_card.origin()); |
-} |
- |
-CreditCard* CreditCardFromStatement(const sql::Statement& s) { |
- CreditCard* credit_card = new CreditCard; |
- |
- credit_card->set_guid(s.ColumnString(0)); |
- DCHECK(base::IsValidGUID(credit_card->guid())); |
- |
- credit_card->SetRawInfo(CREDIT_CARD_NAME, s.ColumnString16(1)); |
- credit_card->SetRawInfo(CREDIT_CARD_EXP_MONTH, s.ColumnString16(2)); |
- credit_card->SetRawInfo(CREDIT_CARD_EXP_4_DIGIT_YEAR, s.ColumnString16(3)); |
- int encrypted_number_len = s.ColumnByteLength(4); |
- base::string16 credit_card_number; |
- if (encrypted_number_len) { |
- std::string encrypted_number; |
- encrypted_number.resize(encrypted_number_len); |
- memcpy(&encrypted_number[0], s.ColumnBlob(4), encrypted_number_len); |
- Encryptor::DecryptString16(encrypted_number, &credit_card_number); |
- } |
- credit_card->SetRawInfo(CREDIT_CARD_NUMBER, credit_card_number); |
- // Intentionally skip column 5, which stores the modification date. |
- credit_card->set_origin(s.ColumnString(6)); |
- |
- return credit_card; |
-} |
- |
-bool AddAutofillProfileNamesToProfile(sql::Connection* db, |
- AutofillProfile* profile) { |
- sql::Statement s(db->GetUniqueStatement( |
- "SELECT guid, first_name, middle_name, last_name " |
- "FROM autofill_profile_names " |
- "WHERE guid=?")); |
- s.BindString(0, profile->guid()); |
- |
- if (!s.is_valid()) |
- return false; |
- |
- std::vector<base::string16> first_names; |
- std::vector<base::string16> middle_names; |
- std::vector<base::string16> last_names; |
- while (s.Step()) { |
- DCHECK_EQ(profile->guid(), s.ColumnString(0)); |
- first_names.push_back(s.ColumnString16(1)); |
- middle_names.push_back(s.ColumnString16(2)); |
- last_names.push_back(s.ColumnString16(3)); |
- } |
- if (!s.Succeeded()) |
- return false; |
- |
- profile->SetRawMultiInfo(NAME_FIRST, first_names); |
- profile->SetRawMultiInfo(NAME_MIDDLE, middle_names); |
- profile->SetRawMultiInfo(NAME_LAST, last_names); |
- return true; |
-} |
- |
-bool AddAutofillProfileEmailsToProfile(sql::Connection* db, |
- AutofillProfile* profile) { |
- sql::Statement s(db->GetUniqueStatement( |
- "SELECT guid, email " |
- "FROM autofill_profile_emails " |
- "WHERE guid=?")); |
- s.BindString(0, profile->guid()); |
- |
- if (!s.is_valid()) |
- return false; |
- |
- std::vector<base::string16> emails; |
- while (s.Step()) { |
- DCHECK_EQ(profile->guid(), s.ColumnString(0)); |
- emails.push_back(s.ColumnString16(1)); |
- } |
- if (!s.Succeeded()) |
- return false; |
- |
- profile->SetRawMultiInfo(EMAIL_ADDRESS, emails); |
- return true; |
-} |
- |
-bool AddAutofillProfilePhonesToProfile(sql::Connection* db, |
- AutofillProfile* profile) { |
- sql::Statement s(db->GetUniqueStatement( |
- "SELECT guid, type, number " |
- "FROM autofill_profile_phones " |
- "WHERE guid=? AND type=?")); |
- |
- // Value used to be either [(0, phone), (1, fax)] but fax has been removed. |
- s.BindString(0, profile->guid()); |
- s.BindInt(1, 0); |
- |
- if (!s.is_valid()) |
- return false; |
- |
- std::vector<base::string16> numbers; |
- while (s.Step()) { |
- DCHECK_EQ(profile->guid(), s.ColumnString(0)); |
- numbers.push_back(s.ColumnString16(2)); |
- } |
- if (!s.Succeeded()) |
- return false; |
- |
- profile->SetRawMultiInfo(PHONE_HOME_WHOLE_NUMBER, numbers); |
- return true; |
-} |
- |
-bool AddAutofillProfileNames(const AutofillProfile& profile, |
- sql::Connection* db) { |
- std::vector<base::string16> first_names; |
- profile.GetRawMultiInfo(NAME_FIRST, &first_names); |
- std::vector<base::string16> middle_names; |
- profile.GetRawMultiInfo(NAME_MIDDLE, &middle_names); |
- std::vector<base::string16> last_names; |
- profile.GetRawMultiInfo(NAME_LAST, &last_names); |
- DCHECK_EQ(first_names.size(), middle_names.size()); |
- DCHECK_EQ(middle_names.size(), last_names.size()); |
- |
- for (size_t i = 0; i < first_names.size(); ++i) { |
- // Add the new name. |
- sql::Statement s(db->GetUniqueStatement( |
- "INSERT INTO autofill_profile_names" |
- " (guid, first_name, middle_name, last_name) " |
- "VALUES (?,?,?,?)")); |
- s.BindString(0, profile.guid()); |
- s.BindString16(1, first_names[i]); |
- s.BindString16(2, middle_names[i]); |
- s.BindString16(3, last_names[i]); |
- |
- if (!s.Run()) |
- return false; |
- } |
- return true; |
-} |
- |
-bool AddAutofillProfileEmails(const AutofillProfile& profile, |
- sql::Connection* db) { |
- std::vector<base::string16> emails; |
- profile.GetRawMultiInfo(EMAIL_ADDRESS, &emails); |
- |
- for (size_t i = 0; i < emails.size(); ++i) { |
- // Add the new email. |
- sql::Statement s(db->GetUniqueStatement( |
- "INSERT INTO autofill_profile_emails" |
- " (guid, email) " |
- "VALUES (?,?)")); |
- s.BindString(0, profile.guid()); |
- s.BindString16(1, emails[i]); |
- |
- if (!s.Run()) |
- return false; |
- } |
- |
- return true; |
-} |
- |
-bool AddAutofillProfilePhones(const AutofillProfile& profile, |
- sql::Connection* db) { |
- std::vector<base::string16> numbers; |
- profile.GetRawMultiInfo(PHONE_HOME_WHOLE_NUMBER, &numbers); |
- |
- for (size_t i = 0; i < numbers.size(); ++i) { |
- // Add the new number. |
- sql::Statement s(db->GetUniqueStatement( |
- "INSERT INTO autofill_profile_phones" |
- " (guid, type, number) " |
- "VALUES (?,?,?)")); |
- s.BindString(0, profile.guid()); |
- // Value used to be either [(0, phone), (1, fax)] but fax has been removed. |
- s.BindInt(1, 0); |
- s.BindString16(2, numbers[i]); |
- |
- if (!s.Run()) |
- return false; |
- } |
- |
- return true; |
-} |
- |
-bool AddAutofillProfilePieces(const AutofillProfile& profile, |
- sql::Connection* db) { |
- if (!AddAutofillProfileNames(profile, db)) |
- return false; |
- |
- if (!AddAutofillProfileEmails(profile, db)) |
- return false; |
- |
- if (!AddAutofillProfilePhones(profile, db)) |
- return false; |
- |
- return true; |
-} |
- |
-bool RemoveAutofillProfilePieces(const std::string& guid, sql::Connection* db) { |
- sql::Statement s1(db->GetUniqueStatement( |
- "DELETE FROM autofill_profile_names WHERE guid = ?")); |
- s1.BindString(0, guid); |
- |
- if (!s1.Run()) |
- return false; |
- |
- sql::Statement s2(db->GetUniqueStatement( |
- "DELETE FROM autofill_profile_emails WHERE guid = ?")); |
- s2.BindString(0, guid); |
- |
- if (!s2.Run()) |
- return false; |
- |
- sql::Statement s3(db->GetUniqueStatement( |
- "DELETE FROM autofill_profile_phones WHERE guid = ?")); |
- s3.BindString(0, guid); |
- |
- return s3.Run(); |
-} |
- |
-WebDatabaseTable::TypeKey GetKey() { |
- // We just need a unique constant. Use the address of a static that |
- // COMDAT folding won't touch in an optimizing linker. |
- static int table_key = 0; |
- return reinterpret_cast<void*>(&table_key); |
-} |
- |
-time_t GetEndTime(const base::Time& end) { |
- if (end.is_null() || end == base::Time::Max()) |
- return std::numeric_limits<time_t>::max(); |
- |
- return end.ToTimeT(); |
-} |
- |
-} // namespace |
- |
-// The maximum length allowed for form data. |
-const size_t AutofillTable::kMaxDataLength = 1024; |
- |
-AutofillTable::AutofillTable(const std::string& app_locale) |
- : app_locale_(app_locale) { |
-} |
- |
-AutofillTable::~AutofillTable() { |
-} |
- |
-AutofillTable* AutofillTable::FromWebDatabase(WebDatabase* db) { |
- return static_cast<AutofillTable*>(db->GetTable(GetKey())); |
-} |
- |
-WebDatabaseTable::TypeKey AutofillTable::GetTypeKey() const { |
- return GetKey(); |
-} |
- |
-bool AutofillTable::Init(sql::Connection* db, sql::MetaTable* meta_table) { |
- WebDatabaseTable::Init(db, meta_table); |
- return (InitMainTable() && InitCreditCardsTable() && InitDatesTable() && |
- InitProfilesTable() && InitProfileNamesTable() && |
- InitProfileEmailsTable() && InitProfilePhonesTable() && |
- InitProfileTrashTable()); |
-} |
- |
-bool AutofillTable::IsSyncable() { |
- return true; |
-} |
- |
-bool AutofillTable::MigrateToVersion(int version, |
- bool* update_compatible_version) { |
- // Migrate if necessary. |
- switch (version) { |
- case 22: |
- return ClearAutofillEmptyValueElements(); |
- case 23: |
- return MigrateToVersion23AddCardNumberEncryptedColumn(); |
- case 24: |
- return MigrateToVersion24CleanupOversizedStringFields(); |
- case 27: |
- *update_compatible_version = true; |
- return MigrateToVersion27UpdateLegacyCreditCards(); |
- case 30: |
- *update_compatible_version = true; |
- return MigrateToVersion30AddDateModifed(); |
- case 31: |
- *update_compatible_version = true; |
- return MigrateToVersion31AddGUIDToCreditCardsAndProfiles(); |
- case 32: |
- *update_compatible_version = true; |
- return MigrateToVersion32UpdateProfilesAndCreditCards(); |
- case 33: |
- *update_compatible_version = true; |
- return MigrateToVersion33ProfilesBasedOnFirstName(); |
- case 34: |
- *update_compatible_version = true; |
- return MigrateToVersion34ProfilesBasedOnCountryCode(); |
- case 35: |
- *update_compatible_version = true; |
- return MigrateToVersion35GreatBritainCountryCodes(); |
- // Combine migrations 36 and 37. This is due to enhancements to the merge |
- // step when migrating profiles. The original migration from 35 to 36 did |
- // not merge profiles with identical addresses, but the migration from 36 to |
- // 37 does. The step from 35 to 36 should only happen on the Chrome 12 dev |
- // channel. Chrome 12 beta and release users will jump from 35 to 37 |
- // directly getting the full benefits of the multi-valued merge as well as |
- // the culling of bad data. |
- case 37: |
- *update_compatible_version = true; |
- return MigrateToVersion37MergeAndCullOlderProfiles(); |
- case 51: |
- // Combine migrations 50 and 51. The migration code from version 49 to 50 |
- // worked correctly for users with existing 'origin' columns, but failed |
- // to create these columns for new users. |
- return MigrateToVersion51AddOriginColumn(); |
- } |
- return true; |
-} |
- |
-bool AutofillTable::AddFormFieldValues( |
- const std::vector<FormFieldData>& elements, |
- std::vector<AutofillChange>* changes) { |
- return AddFormFieldValuesTime(elements, changes, Time::Now()); |
-} |
- |
-bool AutofillTable::AddFormFieldValue(const FormFieldData& element, |
- std::vector<AutofillChange>* changes) { |
- return AddFormFieldValueTime(element, changes, Time::Now()); |
-} |
- |
-bool AutofillTable::GetFormValuesForElementName( |
- const base::string16& name, |
- const base::string16& prefix, |
- std::vector<base::string16>* values, |
- int limit) { |
- DCHECK(values); |
- sql::Statement s; |
- |
- if (prefix.empty()) { |
- s.Assign(db_->GetUniqueStatement( |
- "SELECT value FROM autofill " |
- "WHERE name = ? " |
- "ORDER BY count DESC " |
- "LIMIT ?")); |
- s.BindString16(0, name); |
- s.BindInt(1, limit); |
- } else { |
- base::string16 prefix_lower = base::i18n::ToLower(prefix); |
- base::string16 next_prefix = prefix_lower; |
- next_prefix[next_prefix.length() - 1]++; |
- |
- s.Assign(db_->GetUniqueStatement( |
- "SELECT value FROM autofill " |
- "WHERE name = ? AND " |
- "value_lower >= ? AND " |
- "value_lower < ? " |
- "ORDER BY count DESC " |
- "LIMIT ?")); |
- s.BindString16(0, name); |
- s.BindString16(1, prefix_lower); |
- s.BindString16(2, next_prefix); |
- s.BindInt(3, limit); |
- } |
- |
- values->clear(); |
- while (s.Step()) |
- values->push_back(s.ColumnString16(0)); |
- return s.Succeeded(); |
-} |
- |
-bool AutofillTable::HasFormElements() { |
- sql::Statement s(db_->GetUniqueStatement( |
- "SELECT COUNT(*) FROM autofill")); |
- if (!s.Step()) { |
- NOTREACHED(); |
- return false; |
- } |
- return s.ColumnInt(0) > 0; |
-} |
- |
-bool AutofillTable::RemoveFormElementsAddedBetween( |
- const Time& delete_begin, |
- const Time& delete_end, |
- std::vector<AutofillChange>* changes) { |
- DCHECK(changes); |
- // Query for the pair_id, name, and value of all form elements that |
- // were used between the given times. |
- sql::Statement s(db_->GetUniqueStatement( |
- "SELECT DISTINCT a.pair_id, a.name, a.value " |
- "FROM autofill_dates ad JOIN autofill a ON ad.pair_id = a.pair_id " |
- "WHERE ad.date_created >= ? AND ad.date_created < ?")); |
- s.BindInt64(0, delete_begin.ToTimeT()); |
- s.BindInt64(1, |
- (delete_end.is_null() || delete_end == base::Time::Max()) ? |
- std::numeric_limits<int64>::max() : |
- delete_end.ToTimeT()); |
- |
- AutofillElementList elements; |
- while (s.Step()) { |
- elements.push_back(MakeTuple(s.ColumnInt64(0), |
- s.ColumnString16(1), |
- s.ColumnString16(2))); |
- } |
- if (!s.Succeeded()) |
- return false; |
- |
- for (AutofillElementList::iterator itr = elements.begin(); |
- itr != elements.end(); ++itr) { |
- int how_many = 0; |
- if (!RemoveFormElementForTimeRange(itr->a, delete_begin, delete_end, |
- &how_many)) { |
- return false; |
- } |
- // We store at most 2 time stamps. If we remove both of them we should |
- // delete the corresponding data. If we delete only one it could still be |
- // the last timestamp for the data, so check how many timestamps do remain. |
- bool should_remove = (CountTimestampsData(itr->a) == 0); |
- if (should_remove) { |
- if (!RemoveFormElementForID(itr->a)) |
- return false; |
- } else { |
- if (!AddToCountOfFormElement(itr->a, -how_many)) |
- return false; |
- } |
- AutofillChange::Type change_type = |
- should_remove ? AutofillChange::REMOVE : AutofillChange::UPDATE; |
- changes->push_back(AutofillChange(change_type, |
- AutofillKey(itr->b, itr->c))); |
- } |
- |
- return true; |
-} |
- |
-bool AutofillTable::RemoveExpiredFormElements( |
- std::vector<AutofillChange>* changes) { |
- DCHECK(changes); |
- |
- base::Time delete_end = AutofillEntry::ExpirationTime(); |
- // Query for the pair_id, name, and value of all form elements that |
- // were last used before the |delete_end|. |
- sql::Statement select_for_delete(db_->GetUniqueStatement( |
- "SELECT DISTINCT pair_id, name, value " |
- "FROM autofill WHERE pair_id NOT IN " |
- "(SELECT DISTINCT pair_id " |
- "FROM autofill_dates WHERE date_created >= ?)")); |
- select_for_delete.BindInt64(0, delete_end.ToTimeT()); |
- AutofillElementList entries_to_delete; |
- while (select_for_delete.Step()) { |
- entries_to_delete.push_back(MakeTuple(select_for_delete.ColumnInt64(0), |
- select_for_delete.ColumnString16(1), |
- select_for_delete.ColumnString16(2))); |
- } |
- |
- if (!select_for_delete.Succeeded()) |
- return false; |
- |
- sql::Statement delete_data_statement(db_->GetUniqueStatement( |
- "DELETE FROM autofill WHERE pair_id NOT IN (" |
- "SELECT pair_id FROM autofill_dates WHERE date_created >= ?)")); |
- delete_data_statement.BindInt64(0, delete_end.ToTimeT()); |
- if (!delete_data_statement.Run()) |
- return false; |
- |
- sql::Statement delete_times_statement(db_->GetUniqueStatement( |
- "DELETE FROM autofill_dates WHERE pair_id NOT IN (" |
- "SELECT pair_id FROM autofill_dates WHERE date_created >= ?)")); |
- delete_times_statement.BindInt64(0, delete_end.ToTimeT()); |
- if (!delete_times_statement.Run()) |
- return false; |
- |
- // Cull remaining entries' timestamps. |
- std::vector<AutofillEntry> entries; |
- if (!GetAllAutofillEntries(&entries)) |
- return false; |
- sql::Statement cull_date_entry(db_->GetUniqueStatement( |
- "DELETE FROM autofill_dates " |
- "WHERE pair_id == (SELECT pair_id FROM autofill " |
- "WHERE name = ? and value = ?)" |
- "AND date_created != ? AND date_created != ?")); |
- for (size_t i = 0; i < entries.size(); ++i) { |
- cull_date_entry.BindString16(0, entries[i].key().name()); |
- cull_date_entry.BindString16(1, entries[i].key().value()); |
- cull_date_entry.BindInt64(2, |
- entries[i].timestamps().empty() ? 0 : |
- entries[i].timestamps().front().ToTimeT()); |
- cull_date_entry.BindInt64(3, |
- entries[i].timestamps().empty() ? 0 : |
- entries[i].timestamps().back().ToTimeT()); |
- if (!cull_date_entry.Run()) |
- return false; |
- cull_date_entry.Reset(true); |
- } |
- |
- changes->clear(); |
- changes->reserve(entries_to_delete.size()); |
- |
- for (AutofillElementList::iterator it = entries_to_delete.begin(); |
- it != entries_to_delete.end(); ++it) { |
- changes->push_back(AutofillChange( |
- AutofillChange::REMOVE, AutofillKey(it->b, it->c))); |
- } |
- return true; |
-} |
- |
-bool AutofillTable::RemoveFormElementForTimeRange(int64 pair_id, |
- const Time& delete_begin, |
- const Time& delete_end, |
- int* how_many) { |
- sql::Statement s(db_->GetUniqueStatement( |
- "DELETE FROM autofill_dates WHERE pair_id = ? AND " |
- "date_created >= ? AND date_created < ?")); |
- s.BindInt64(0, pair_id); |
- s.BindInt64(1, delete_begin.is_null() ? 0 : delete_begin.ToTimeT()); |
- s.BindInt64(2, delete_end.is_null() ? std::numeric_limits<int64>::max() : |
- delete_end.ToTimeT()); |
- |
- bool result = s.Run(); |
- if (how_many) |
- *how_many = db_->GetLastChangeCount(); |
- |
- return result; |
-} |
- |
-int AutofillTable::CountTimestampsData(int64 pair_id) { |
- sql::Statement s(db_->GetUniqueStatement( |
- "SELECT COUNT(*) FROM autofill_dates WHERE pair_id = ?")); |
- s.BindInt64(0, pair_id); |
- if (!s.Step()) { |
- NOTREACHED(); |
- return 0; |
- } else { |
- return s.ColumnInt(0); |
- } |
-} |
- |
-bool AutofillTable::AddToCountOfFormElement(int64 pair_id, |
- int delta) { |
- int count = 0; |
- |
- if (!GetCountOfFormElement(pair_id, &count)) |
- return false; |
- |
- if (count + delta == 0) { |
- // Should remove the element earlier in the code. |
- NOTREACHED(); |
- return false; |
- } else { |
- if (!SetCountOfFormElement(pair_id, count + delta)) |
- return false; |
- } |
- return true; |
-} |
- |
-bool AutofillTable::GetIDAndCountOfFormElement( |
- const FormFieldData& element, |
- int64* pair_id, |
- int* count) { |
- DCHECK(pair_id); |
- DCHECK(count); |
- |
- sql::Statement s(db_->GetUniqueStatement( |
- "SELECT pair_id, count FROM autofill " |
- "WHERE name = ? AND value = ?")); |
- s.BindString16(0, element.name); |
- s.BindString16(1, element.value); |
- |
- if (!s.is_valid()) |
- return false; |
- |
- *pair_id = 0; |
- *count = 0; |
- |
- if (s.Step()) { |
- *pair_id = s.ColumnInt64(0); |
- *count = s.ColumnInt(1); |
- } |
- |
- return true; |
-} |
- |
-bool AutofillTable::GetCountOfFormElement(int64 pair_id, int* count) { |
- DCHECK(count); |
- sql::Statement s(db_->GetUniqueStatement( |
- "SELECT count FROM autofill WHERE pair_id = ?")); |
- s.BindInt64(0, pair_id); |
- |
- if (s.Step()) { |
- *count = s.ColumnInt(0); |
- return true; |
- } |
- return false; |
-} |
- |
-bool AutofillTable::SetCountOfFormElement(int64 pair_id, int count) { |
- sql::Statement s(db_->GetUniqueStatement( |
- "UPDATE autofill SET count = ? WHERE pair_id = ?")); |
- s.BindInt(0, count); |
- s.BindInt64(1, pair_id); |
- |
- return s.Run(); |
-} |
- |
-bool AutofillTable::InsertFormElement(const FormFieldData& element, |
- int64* pair_id) { |
- DCHECK(pair_id); |
- sql::Statement s(db_->GetUniqueStatement( |
- "INSERT INTO autofill (name, value, value_lower) VALUES (?,?,?)")); |
- s.BindString16(0, element.name); |
- s.BindString16(1, element.value); |
- s.BindString16(2, base::i18n::ToLower(element.value)); |
- |
- if (!s.Run()) |
- return false; |
- |
- *pair_id = db_->GetLastInsertRowId(); |
- return true; |
-} |
- |
-bool AutofillTable::InsertPairIDAndDate(int64 pair_id, |
- const Time& date_created) { |
- sql::Statement s(db_->GetUniqueStatement( |
- "INSERT INTO autofill_dates " |
- "(pair_id, date_created) VALUES (?, ?)")); |
- s.BindInt64(0, pair_id); |
- s.BindInt64(1, date_created.ToTimeT()); |
- |
- return s.Run(); |
-} |
- |
-bool AutofillTable::DeleteLastAccess(int64 pair_id) { |
- // Inner SELECT selects the newest |date_created| for a given |pair_id|. |
- // DELETE deletes only that entry. |
- sql::Statement s(db_->GetUniqueStatement( |
- "DELETE FROM autofill_dates WHERE pair_id = ? and date_created IN " |
- "(SELECT date_created FROM autofill_dates WHERE pair_id = ? " |
- "ORDER BY date_created DESC LIMIT 1)")); |
- s.BindInt64(0, pair_id); |
- s.BindInt64(1, pair_id); |
- |
- return s.Run(); |
-} |
- |
-bool AutofillTable::AddFormFieldValuesTime( |
- const std::vector<FormFieldData>& elements, |
- std::vector<AutofillChange>* changes, |
- Time time) { |
- // Only add one new entry for each unique element name. Use |seen_names| to |
- // track this. Add up to |kMaximumUniqueNames| unique entries per form. |
- const size_t kMaximumUniqueNames = 256; |
- std::set<base::string16> seen_names; |
- bool result = true; |
- for (std::vector<FormFieldData>::const_iterator itr = elements.begin(); |
- itr != elements.end(); ++itr) { |
- if (seen_names.size() >= kMaximumUniqueNames) |
- break; |
- if (seen_names.find(itr->name) != seen_names.end()) |
- continue; |
- result = result && AddFormFieldValueTime(*itr, changes, time); |
- seen_names.insert(itr->name); |
- } |
- return result; |
-} |
- |
-bool AutofillTable::ClearAutofillEmptyValueElements() { |
- sql::Statement s(db_->GetUniqueStatement( |
- "SELECT pair_id FROM autofill WHERE TRIM(value)= \"\"")); |
- if (!s.is_valid()) |
- return false; |
- |
- std::set<int64> ids; |
- while (s.Step()) |
- ids.insert(s.ColumnInt64(0)); |
- if (!s.Succeeded()) |
- return false; |
- |
- bool success = true; |
- for (std::set<int64>::const_iterator iter = ids.begin(); iter != ids.end(); |
- ++iter) { |
- if (!RemoveFormElementForID(*iter)) |
- success = false; |
- } |
- |
- return success; |
-} |
- |
-bool AutofillTable::GetAllAutofillEntries(std::vector<AutofillEntry>* entries) { |
- DCHECK(entries); |
- sql::Statement s(db_->GetUniqueStatement( |
- "SELECT name, value, date_created FROM autofill a JOIN " |
- "autofill_dates ad ON a.pair_id=ad.pair_id")); |
- |
- bool first_entry = true; |
- AutofillKey* current_key_ptr = NULL; |
- std::vector<Time>* timestamps_ptr = NULL; |
- base::string16 name, value; |
- Time time; |
- while (s.Step()) { |
- name = s.ColumnString16(0); |
- value = s.ColumnString16(1); |
- time = Time::FromTimeT(s.ColumnInt64(2)); |
- |
- if (first_entry) { |
- current_key_ptr = new AutofillKey(name, value); |
- |
- timestamps_ptr = new std::vector<Time>; |
- timestamps_ptr->push_back(time); |
- |
- first_entry = false; |
- } else { |
- // we've encountered the next entry |
- if (current_key_ptr->name().compare(name) != 0 || |
- current_key_ptr->value().compare(value) != 0) { |
- AutofillEntry entry(*current_key_ptr, *timestamps_ptr); |
- entries->push_back(entry); |
- |
- delete current_key_ptr; |
- delete timestamps_ptr; |
- |
- current_key_ptr = new AutofillKey(name, value); |
- timestamps_ptr = new std::vector<Time>; |
- } |
- timestamps_ptr->push_back(time); |
- } |
- } |
- |
- // If there is at least one result returned, first_entry will be false. |
- // For this case we need to do a final cleanup step. |
- if (!first_entry) { |
- AutofillEntry entry(*current_key_ptr, *timestamps_ptr); |
- entries->push_back(entry); |
- delete current_key_ptr; |
- delete timestamps_ptr; |
- } |
- |
- return s.Succeeded(); |
-} |
- |
-bool AutofillTable::GetAutofillTimestamps(const base::string16& name, |
- const base::string16& value, |
- std::vector<Time>* timestamps) { |
- DCHECK(timestamps); |
- sql::Statement s(db_->GetUniqueStatement( |
- "SELECT date_created FROM autofill a JOIN " |
- "autofill_dates ad ON a.pair_id=ad.pair_id " |
- "WHERE a.name = ? AND a.value = ?")); |
- s.BindString16(0, name); |
- s.BindString16(1, value); |
- |
- while (s.Step()) |
- timestamps->push_back(Time::FromTimeT(s.ColumnInt64(0))); |
- |
- return s.Succeeded(); |
-} |
- |
-bool AutofillTable::UpdateAutofillEntries( |
- const std::vector<AutofillEntry>& entries) { |
- if (!entries.size()) |
- return true; |
- |
- // Remove all existing entries. |
- for (size_t i = 0; i < entries.size(); i++) { |
- std::string sql = "SELECT pair_id FROM autofill " |
- "WHERE name = ? AND value = ?"; |
- sql::Statement s(db_->GetUniqueStatement(sql.c_str())); |
- s.BindString16(0, entries[i].key().name()); |
- s.BindString16(1, entries[i].key().value()); |
- |
- if (!s.is_valid()) |
- return false; |
- |
- if (s.Step()) { |
- if (!RemoveFormElementForID(s.ColumnInt64(0))) |
- return false; |
- } |
- } |
- |
- // Insert all the supplied autofill entries. |
- for (size_t i = 0; i < entries.size(); i++) { |
- if (!InsertAutofillEntry(entries[i])) |
- return false; |
- } |
- |
- return true; |
-} |
- |
-bool AutofillTable::InsertAutofillEntry(const AutofillEntry& entry) { |
- std::string sql = "INSERT INTO autofill (name, value, value_lower, count) " |
- "VALUES (?, ?, ?, ?)"; |
- sql::Statement s(db_->GetUniqueStatement(sql.c_str())); |
- s.BindString16(0, entry.key().name()); |
- s.BindString16(1, entry.key().value()); |
- s.BindString16(2, base::i18n::ToLower(entry.key().value())); |
- s.BindInt(3, entry.timestamps().size()); |
- |
- if (!s.Run()) |
- return false; |
- |
- int64 pair_id = db_->GetLastInsertRowId(); |
- for (size_t i = 0; i < entry.timestamps().size(); i++) { |
- if (!InsertPairIDAndDate(pair_id, entry.timestamps()[i])) |
- return false; |
- } |
- |
- return true; |
-} |
- |
-bool AutofillTable::AddFormFieldValueTime(const FormFieldData& element, |
- std::vector<AutofillChange>* changes, |
- Time time) { |
- int count = 0; |
- int64 pair_id; |
- |
- if (!GetIDAndCountOfFormElement(element, &pair_id, &count)) |
- return false; |
- |
- if (count == 0 && !InsertFormElement(element, &pair_id)) |
- return false; |
- |
- if (!SetCountOfFormElement(pair_id, count + 1)) |
- return false; |
- |
- // If we already have more than 2 times delete last one, before adding new |
- // one. |
- if (count >= 2 && !DeleteLastAccess(pair_id)) |
- return false; |
- |
- if (!InsertPairIDAndDate(pair_id, time)) |
- return false; |
- |
- AutofillChange::Type change_type = |
- count == 0 ? AutofillChange::ADD : AutofillChange::UPDATE; |
- changes->push_back( |
- AutofillChange(change_type, |
- AutofillKey(element.name, element.value))); |
- return true; |
-} |
- |
- |
-bool AutofillTable::RemoveFormElement(const base::string16& name, |
- const base::string16& value) { |
- // Find the id for that pair. |
- sql::Statement s(db_->GetUniqueStatement( |
- "SELECT pair_id FROM autofill WHERE name = ? AND value= ?")); |
- s.BindString16(0, name); |
- s.BindString16(1, value); |
- |
- if (s.Step()) |
- return RemoveFormElementForID(s.ColumnInt64(0)); |
- return false; |
-} |
- |
-bool AutofillTable::AddAutofillProfile(const AutofillProfile& profile) { |
- if (IsAutofillGUIDInTrash(profile.guid())) |
- return true; |
- |
- sql::Statement s(db_->GetUniqueStatement( |
- "INSERT INTO autofill_profiles" |
- "(guid, company_name, address_line_1, address_line_2, city, state," |
- " zipcode, country, country_code, date_modified, origin)" |
- "VALUES (?,?,?,?,?,?,?,?,?,?,?)")); |
- BindAutofillProfileToStatement(profile, &s, app_locale_); |
- |
- if (!s.Run()) |
- return false; |
- |
- return AddAutofillProfilePieces(profile, db_); |
-} |
- |
-bool AutofillTable::GetAutofillProfile(const std::string& guid, |
- AutofillProfile** profile) { |
- DCHECK(base::IsValidGUID(guid)); |
- DCHECK(profile); |
- sql::Statement s(db_->GetUniqueStatement( |
- "SELECT guid, company_name, address_line_1, address_line_2, city, state," |
- " zipcode, country, country_code, date_modified, origin " |
- "FROM autofill_profiles " |
- "WHERE guid=?")); |
- s.BindString(0, guid); |
- |
- if (!s.Step()) |
- return false; |
- |
- scoped_ptr<AutofillProfile> p(AutofillProfileFromStatement(s, app_locale_)); |
- |
- // Get associated name info. |
- AddAutofillProfileNamesToProfile(db_, p.get()); |
- |
- // Get associated email info. |
- AddAutofillProfileEmailsToProfile(db_, p.get()); |
- |
- // Get associated phone info. |
- AddAutofillProfilePhonesToProfile(db_, p.get()); |
- |
- *profile = p.release(); |
- return true; |
-} |
- |
-bool AutofillTable::GetAutofillProfiles( |
- std::vector<AutofillProfile*>* profiles) { |
- DCHECK(profiles); |
- profiles->clear(); |
- |
- sql::Statement s(db_->GetUniqueStatement( |
- "SELECT guid " |
- "FROM autofill_profiles")); |
- |
- while (s.Step()) { |
- std::string guid = s.ColumnString(0); |
- AutofillProfile* profile = NULL; |
- if (!GetAutofillProfile(guid, &profile)) |
- return false; |
- profiles->push_back(profile); |
- } |
- |
- return s.Succeeded(); |
-} |
- |
-bool AutofillTable::UpdateAutofillProfile(const AutofillProfile& profile) { |
- DCHECK(base::IsValidGUID(profile.guid())); |
- |
- // Don't update anything until the trash has been emptied. There may be |
- // pending modifications to process. |
- if (!IsAutofillProfilesTrashEmpty()) |
- return true; |
- |
- AutofillProfile* tmp_profile = NULL; |
- if (!GetAutofillProfile(profile.guid(), &tmp_profile)) |
- return false; |
- |
- // Preserve appropriate modification dates by not updating unchanged profiles. |
- scoped_ptr<AutofillProfile> old_profile(tmp_profile); |
- if (old_profile->Compare(profile) == 0 && |
- old_profile->origin() == profile.origin()) |
- return true; |
- |
- sql::Statement s(db_->GetUniqueStatement( |
- "UPDATE autofill_profiles " |
- "SET guid=?, company_name=?, address_line_1=?, address_line_2=?, " |
- " city=?, state=?, zipcode=?, country=?, country_code=?, " |
- " date_modified=?, origin=? " |
- "WHERE guid=?")); |
- BindAutofillProfileToStatement(profile, &s, app_locale_); |
- s.BindString(11, profile.guid()); |
- |
- bool result = s.Run(); |
- DCHECK_GT(db_->GetLastChangeCount(), 0); |
- if (!result) |
- return result; |
- |
- // Remove the old names, emails, and phone numbers. |
- if (!RemoveAutofillProfilePieces(profile.guid(), db_)) |
- return false; |
- |
- return AddAutofillProfilePieces(profile, db_); |
-} |
- |
-bool AutofillTable::RemoveAutofillProfile(const std::string& guid) { |
- DCHECK(base::IsValidGUID(guid)); |
- |
- if (IsAutofillGUIDInTrash(guid)) { |
- sql::Statement s_trash(db_->GetUniqueStatement( |
- "DELETE FROM autofill_profiles_trash WHERE guid = ?")); |
- s_trash.BindString(0, guid); |
- |
- bool success = s_trash.Run(); |
- DCHECK_GT(db_->GetLastChangeCount(), 0) << "Expected item in trash"; |
- return success; |
- } |
- |
- sql::Statement s(db_->GetUniqueStatement( |
- "DELETE FROM autofill_profiles WHERE guid = ?")); |
- s.BindString(0, guid); |
- |
- if (!s.Run()) |
- return false; |
- |
- return RemoveAutofillProfilePieces(guid, db_); |
-} |
- |
-bool AutofillTable::ClearAutofillProfiles() { |
- sql::Statement s1(db_->GetUniqueStatement( |
- "DELETE FROM autofill_profiles")); |
- |
- if (!s1.Run()) |
- return false; |
- |
- sql::Statement s2(db_->GetUniqueStatement( |
- "DELETE FROM autofill_profile_names")); |
- |
- if (!s2.Run()) |
- return false; |
- |
- sql::Statement s3(db_->GetUniqueStatement( |
- "DELETE FROM autofill_profile_emails")); |
- |
- if (!s3.Run()) |
- return false; |
- |
- sql::Statement s4(db_->GetUniqueStatement( |
- "DELETE FROM autofill_profile_phones")); |
- |
- return s4.Run(); |
-} |
- |
-bool AutofillTable::AddCreditCard(const CreditCard& credit_card) { |
- sql::Statement s(db_->GetUniqueStatement( |
- "INSERT INTO credit_cards" |
- "(guid, name_on_card, expiration_month, expiration_year, " |
- " card_number_encrypted, date_modified, origin)" |
- "VALUES (?,?,?,?,?,?,?)")); |
- BindCreditCardToStatement(credit_card, &s); |
- |
- if (!s.Run()) |
- return false; |
- |
- DCHECK_GT(db_->GetLastChangeCount(), 0); |
- return true; |
-} |
- |
-bool AutofillTable::GetCreditCard(const std::string& guid, |
- CreditCard** credit_card) { |
- DCHECK(base::IsValidGUID(guid)); |
- sql::Statement s(db_->GetUniqueStatement( |
- "SELECT guid, name_on_card, expiration_month, expiration_year, " |
- " card_number_encrypted, date_modified, origin " |
- "FROM credit_cards " |
- "WHERE guid = ?")); |
- s.BindString(0, guid); |
- |
- if (!s.Step()) |
- return false; |
- |
- *credit_card = CreditCardFromStatement(s); |
- return true; |
-} |
- |
-bool AutofillTable::GetCreditCards( |
- std::vector<CreditCard*>* credit_cards) { |
- DCHECK(credit_cards); |
- credit_cards->clear(); |
- |
- sql::Statement s(db_->GetUniqueStatement( |
- "SELECT guid " |
- "FROM credit_cards")); |
- |
- while (s.Step()) { |
- std::string guid = s.ColumnString(0); |
- CreditCard* credit_card = NULL; |
- if (!GetCreditCard(guid, &credit_card)) |
- return false; |
- credit_cards->push_back(credit_card); |
- } |
- |
- return s.Succeeded(); |
-} |
- |
-bool AutofillTable::UpdateCreditCard(const CreditCard& credit_card) { |
- DCHECK(base::IsValidGUID(credit_card.guid())); |
- |
- CreditCard* tmp_credit_card = NULL; |
- if (!GetCreditCard(credit_card.guid(), &tmp_credit_card)) |
- return false; |
- |
- // Preserve appropriate modification dates by not updating unchanged cards. |
- scoped_ptr<CreditCard> old_credit_card(tmp_credit_card); |
- if (*old_credit_card == credit_card) |
- return true; |
- |
- sql::Statement s(db_->GetUniqueStatement( |
- "UPDATE credit_cards " |
- "SET guid=?, name_on_card=?, expiration_month=?, " |
- " expiration_year=?, card_number_encrypted=?, date_modified=?, " |
- " origin=? " |
- "WHERE guid=?")); |
- BindCreditCardToStatement(credit_card, &s); |
- s.BindString(7, credit_card.guid()); |
- |
- bool result = s.Run(); |
- DCHECK_GT(db_->GetLastChangeCount(), 0); |
- return result; |
-} |
- |
-bool AutofillTable::RemoveCreditCard(const std::string& guid) { |
- DCHECK(base::IsValidGUID(guid)); |
- sql::Statement s(db_->GetUniqueStatement( |
- "DELETE FROM credit_cards WHERE guid = ?")); |
- s.BindString(0, guid); |
- |
- return s.Run(); |
-} |
- |
-bool AutofillTable::RemoveAutofillDataModifiedBetween( |
- const Time& delete_begin, |
- const Time& delete_end, |
- std::vector<std::string>* profile_guids, |
- std::vector<std::string>* credit_card_guids) { |
- DCHECK(delete_end.is_null() || delete_begin < delete_end); |
- |
- time_t delete_begin_t = delete_begin.ToTimeT(); |
- time_t delete_end_t = GetEndTime(delete_end); |
- |
- // Remember Autofill profiles in the time range. |
- sql::Statement s_profiles_get(db_->GetUniqueStatement( |
- "SELECT guid FROM autofill_profiles " |
- "WHERE date_modified >= ? AND date_modified < ?")); |
- s_profiles_get.BindInt64(0, delete_begin_t); |
- s_profiles_get.BindInt64(1, delete_end_t); |
- |
- profile_guids->clear(); |
- while (s_profiles_get.Step()) { |
- std::string guid = s_profiles_get.ColumnString(0); |
- profile_guids->push_back(guid); |
- } |
- if (!s_profiles_get.Succeeded()) |
- return false; |
- |
- // Remove Autofill profiles in the time range. |
- sql::Statement s_profiles(db_->GetUniqueStatement( |
- "DELETE FROM autofill_profiles " |
- "WHERE date_modified >= ? AND date_modified < ?")); |
- s_profiles.BindInt64(0, delete_begin_t); |
- s_profiles.BindInt64(1, delete_end_t); |
- |
- if (!s_profiles.Run()) |
- return false; |
- |
- // Remember Autofill credit cards in the time range. |
- sql::Statement s_credit_cards_get(db_->GetUniqueStatement( |
- "SELECT guid FROM credit_cards " |
- "WHERE date_modified >= ? AND date_modified < ?")); |
- s_credit_cards_get.BindInt64(0, delete_begin_t); |
- s_credit_cards_get.BindInt64(1, delete_end_t); |
- |
- credit_card_guids->clear(); |
- while (s_credit_cards_get.Step()) { |
- std::string guid = s_credit_cards_get.ColumnString(0); |
- credit_card_guids->push_back(guid); |
- } |
- if (!s_credit_cards_get.Succeeded()) |
- return false; |
- |
- // Remove Autofill credit cards in the time range. |
- sql::Statement s_credit_cards(db_->GetUniqueStatement( |
- "DELETE FROM credit_cards " |
- "WHERE date_modified >= ? AND date_modified < ?")); |
- s_credit_cards.BindInt64(0, delete_begin_t); |
- s_credit_cards.BindInt64(1, delete_end_t); |
- |
- return s_credit_cards.Run(); |
-} |
- |
-bool AutofillTable::RemoveOriginURLsModifiedBetween( |
- const Time& delete_begin, |
- const Time& delete_end, |
- ScopedVector<AutofillProfile>* profiles) { |
- DCHECK(delete_end.is_null() || delete_begin < delete_end); |
- |
- time_t delete_begin_t = delete_begin.ToTimeT(); |
- time_t delete_end_t = GetEndTime(delete_end); |
- |
- // Remember Autofill profiles with URL origins in the time range. |
- sql::Statement s_profiles_get(db_->GetUniqueStatement( |
- "SELECT guid, origin FROM autofill_profiles " |
- "WHERE date_modified >= ? AND date_modified < ?")); |
- s_profiles_get.BindInt64(0, delete_begin_t); |
- s_profiles_get.BindInt64(1, delete_end_t); |
- |
- std::vector<std::string> profile_guids; |
- while (s_profiles_get.Step()) { |
- std::string guid = s_profiles_get.ColumnString(0); |
- std::string origin = s_profiles_get.ColumnString(1); |
- if (GURL(origin).is_valid()) |
- profile_guids.push_back(guid); |
- } |
- if (!s_profiles_get.Succeeded()) |
- return false; |
- |
- // Clear out the origins for the found Autofill profiles. |
- for (std::vector<std::string>::const_iterator it = profile_guids.begin(); |
- it != profile_guids.end(); ++it) { |
- sql::Statement s_profile(db_->GetUniqueStatement( |
- "UPDATE autofill_profiles SET origin='' WHERE guid=?")); |
- s_profile.BindString(0, *it); |
- if (!s_profile.Run()) |
- return false; |
- |
- AutofillProfile* profile; |
- if (!GetAutofillProfile(*it, &profile)) |
- return false; |
- |
- profiles->push_back(profile); |
- } |
- |
- // Remember Autofill credit cards with URL origins in the time range. |
- sql::Statement s_credit_cards_get(db_->GetUniqueStatement( |
- "SELECT guid, origin FROM credit_cards " |
- "WHERE date_modified >= ? AND date_modified < ?")); |
- s_credit_cards_get.BindInt64(0, delete_begin_t); |
- s_credit_cards_get.BindInt64(1, delete_end_t); |
- |
- std::vector<std::string> credit_card_guids; |
- while (s_credit_cards_get.Step()) { |
- std::string guid = s_credit_cards_get.ColumnString(0); |
- std::string origin = s_credit_cards_get.ColumnString(1); |
- if (GURL(origin).is_valid()) |
- credit_card_guids.push_back(guid); |
- } |
- if (!s_credit_cards_get.Succeeded()) |
- return false; |
- |
- // Clear out the origins for the found credit cards. |
- for (std::vector<std::string>::const_iterator it = credit_card_guids.begin(); |
- it != credit_card_guids.end(); ++it) { |
- sql::Statement s_credit_card(db_->GetUniqueStatement( |
- "UPDATE credit_cards SET origin='' WHERE guid=?")); |
- s_credit_card.BindString(0, *it); |
- if (!s_credit_card.Run()) |
- return false; |
- } |
- |
- return true; |
-} |
- |
-bool AutofillTable::GetAutofillProfilesInTrash( |
- std::vector<std::string>* guids) { |
- guids->clear(); |
- |
- sql::Statement s(db_->GetUniqueStatement( |
- "SELECT guid " |
- "FROM autofill_profiles_trash")); |
- |
- while (s.Step()) { |
- std::string guid = s.ColumnString(0); |
- guids->push_back(guid); |
- } |
- |
- return s.Succeeded(); |
-} |
- |
-bool AutofillTable::EmptyAutofillProfilesTrash() { |
- sql::Statement s(db_->GetUniqueStatement( |
- "DELETE FROM autofill_profiles_trash")); |
- |
- return s.Run(); |
-} |
- |
- |
-bool AutofillTable::RemoveFormElementForID(int64 pair_id) { |
- sql::Statement s(db_->GetUniqueStatement( |
- "DELETE FROM autofill WHERE pair_id = ?")); |
- s.BindInt64(0, pair_id); |
- |
- if (s.Run()) |
- return RemoveFormElementForTimeRange(pair_id, Time(), Time(), NULL); |
- |
- return false; |
-} |
- |
-bool AutofillTable::AddAutofillGUIDToTrash(const std::string& guid) { |
- sql::Statement s(db_->GetUniqueStatement( |
- "INSERT INTO autofill_profiles_trash" |
- " (guid) " |
- "VALUES (?)")); |
- s.BindString(0, guid); |
- |
- return s.Run(); |
-} |
- |
-bool AutofillTable::IsAutofillProfilesTrashEmpty() { |
- sql::Statement s(db_->GetUniqueStatement( |
- "SELECT guid " |
- "FROM autofill_profiles_trash")); |
- |
- return !s.Step(); |
-} |
- |
-bool AutofillTable::IsAutofillGUIDInTrash(const std::string& guid) { |
- sql::Statement s(db_->GetUniqueStatement( |
- "SELECT guid " |
- "FROM autofill_profiles_trash " |
- "WHERE guid = ?")); |
- s.BindString(0, guid); |
- |
- return s.Step(); |
-} |
- |
-bool AutofillTable::InitMainTable() { |
- if (!db_->DoesTableExist("autofill")) { |
- if (!db_->Execute("CREATE TABLE autofill (" |
- "name VARCHAR, " |
- "value VARCHAR, " |
- "value_lower VARCHAR, " |
- "pair_id INTEGER PRIMARY KEY, " |
- "count INTEGER DEFAULT 1)")) { |
- NOTREACHED(); |
- return false; |
- } |
- if (!db_->Execute("CREATE INDEX autofill_name ON autofill (name)")) { |
- NOTREACHED(); |
- return false; |
- } |
- if (!db_->Execute("CREATE INDEX autofill_name_value_lower ON " |
- "autofill (name, value_lower)")) { |
- NOTREACHED(); |
- return false; |
- } |
- } |
- return true; |
-} |
- |
-bool AutofillTable::InitCreditCardsTable() { |
- if (!db_->DoesTableExist("credit_cards")) { |
- if (!db_->Execute("CREATE TABLE credit_cards ( " |
- "guid VARCHAR PRIMARY KEY, " |
- "name_on_card VARCHAR, " |
- "expiration_month INTEGER, " |
- "expiration_year INTEGER, " |
- "card_number_encrypted BLOB, " |
- "date_modified INTEGER NOT NULL DEFAULT 0, " |
- "origin VARCHAR DEFAULT '')")) { |
- NOTREACHED(); |
- return false; |
- } |
- } |
- |
- return true; |
-} |
- |
-bool AutofillTable::InitDatesTable() { |
- if (!db_->DoesTableExist("autofill_dates")) { |
- if (!db_->Execute("CREATE TABLE autofill_dates ( " |
- "pair_id INTEGER DEFAULT 0, " |
- "date_created INTEGER DEFAULT 0)")) { |
- NOTREACHED(); |
- return false; |
- } |
- if (!db_->Execute("CREATE INDEX autofill_dates_pair_id ON " |
- "autofill_dates (pair_id)")) { |
- NOTREACHED(); |
- return false; |
- } |
- } |
- return true; |
-} |
- |
-bool AutofillTable::InitProfilesTable() { |
- if (!db_->DoesTableExist("autofill_profiles")) { |
- if (!db_->Execute("CREATE TABLE autofill_profiles ( " |
- "guid VARCHAR PRIMARY KEY, " |
- "company_name VARCHAR, " |
- "address_line_1 VARCHAR, " |
- "address_line_2 VARCHAR, " |
- "city VARCHAR, " |
- "state VARCHAR, " |
- "zipcode VARCHAR, " |
- "country VARCHAR, " |
- "country_code VARCHAR, " |
- "date_modified INTEGER NOT NULL DEFAULT 0, " |
- "origin VARCHAR DEFAULT '')")) { |
- NOTREACHED(); |
- return false; |
- } |
- } |
- return true; |
-} |
- |
-bool AutofillTable::InitProfileNamesTable() { |
- if (!db_->DoesTableExist("autofill_profile_names")) { |
- if (!db_->Execute("CREATE TABLE autofill_profile_names ( " |
- "guid VARCHAR, " |
- "first_name VARCHAR, " |
- "middle_name VARCHAR, " |
- "last_name VARCHAR)")) { |
- NOTREACHED(); |
- return false; |
- } |
- } |
- return true; |
-} |
- |
-bool AutofillTable::InitProfileEmailsTable() { |
- if (!db_->DoesTableExist("autofill_profile_emails")) { |
- if (!db_->Execute("CREATE TABLE autofill_profile_emails ( " |
- "guid VARCHAR, " |
- "email VARCHAR)")) { |
- NOTREACHED(); |
- return false; |
- } |
- } |
- return true; |
-} |
- |
-bool AutofillTable::InitProfilePhonesTable() { |
- if (!db_->DoesTableExist("autofill_profile_phones")) { |
- if (!db_->Execute("CREATE TABLE autofill_profile_phones ( " |
- "guid VARCHAR, " |
- "type INTEGER DEFAULT 0, " |
- "number VARCHAR)")) { |
- NOTREACHED(); |
- return false; |
- } |
- } |
- return true; |
-} |
- |
-bool AutofillTable::InitProfileTrashTable() { |
- if (!db_->DoesTableExist("autofill_profiles_trash")) { |
- if (!db_->Execute("CREATE TABLE autofill_profiles_trash ( " |
- "guid VARCHAR)")) { |
- NOTREACHED(); |
- return false; |
- } |
- } |
- return true; |
-} |
- |
-// Add the card_number_encrypted column if credit card table was not |
-// created in this build (otherwise the column already exists). |
-// WARNING: Do not change the order of the execution of the SQL |
-// statements in this case! Profile corruption and data migration |
-// issues WILL OCCUR. See http://crbug.com/10913 |
-// |
-// The problem is that if a user has a profile which was created before |
-// r37036, when the credit_cards table was added, and then failed to |
-// update this profile between the credit card addition and the addition |
-// of the "encrypted" columns (44963), the next data migration will put |
-// the user's profile in an incoherent state: The user will update from |
-// a data profile set to be earlier than 22, and therefore pass through |
-// this update case. But because the user did not have a credit_cards |
-// table before starting Chrome, it will have just been initialized |
-// above, and so already have these columns -- and thus this data |
-// update step will have failed. |
-// |
-// The false assumption in this case is that at this step in the |
-// migration, the user has a credit card table, and that this |
-// table does not include encrypted columns! |
-// Because this case does not roll back the complete set of SQL |
-// transactions properly in case of failure (that is, it does not |
-// roll back the table initialization done above), the incoherent |
-// profile will now see itself as being at version 22 -- but include a |
-// fully initialized credit_cards table. Every time Chrome runs, it |
-// will try to update the web database and fail at this step, unless |
-// we allow for the faulty assumption described above by checking for |
-// the existence of the columns only AFTER we've executed the commands |
-// to add them. |
-bool AutofillTable::MigrateToVersion23AddCardNumberEncryptedColumn() { |
- if (!db_->DoesColumnExist("credit_cards", "card_number_encrypted")) { |
- if (!db_->Execute("ALTER TABLE credit_cards ADD COLUMN " |
- "card_number_encrypted BLOB DEFAULT NULL")) { |
- LOG(WARNING) << "Could not add card_number_encrypted to " |
- "credit_cards table."; |
- return false; |
- } |
- } |
- |
- if (!db_->DoesColumnExist("credit_cards", "verification_code_encrypted")) { |
- if (!db_->Execute("ALTER TABLE credit_cards ADD COLUMN " |
- "verification_code_encrypted BLOB DEFAULT NULL")) { |
- LOG(WARNING) << "Could not add verification_code_encrypted to " |
- "credit_cards table."; |
- return false; |
- } |
- } |
- |
- return true; |
-} |
- |
-// One-time cleanup for http://crbug.com/38364 - In the presence of |
-// multi-byte UTF-8 characters, that bug could cause Autofill strings |
-// to grow larger and more corrupt with each save. The cleanup removes |
-// any row with a string field larger than a reasonable size. The string |
-// fields examined here are precisely the ones that were subject to |
-// corruption by the original bug. |
-bool AutofillTable::MigrateToVersion24CleanupOversizedStringFields() { |
- const std::string autofill_is_too_big = |
- "max(length(name), length(value)) > 500"; |
- |
- const std::string credit_cards_is_too_big = |
- "max(length(label), length(name_on_card), length(type), " |
- " length(expiration_month), length(expiration_year), " |
- " length(billing_address), length(shipping_address) " |
- ") > 500"; |
- |
- const std::string autofill_profiles_is_too_big = |
- "max(length(label), length(first_name), " |
- " length(middle_name), length(last_name), length(email), " |
- " length(company_name), length(address_line_1), " |
- " length(address_line_2), length(city), length(state), " |
- " length(zipcode), length(country), length(phone)) > 500"; |
- |
- std::string query = "DELETE FROM autofill_dates WHERE pair_id IN (" |
- "SELECT pair_id FROM autofill WHERE " + autofill_is_too_big + ")"; |
- |
- if (!db_->Execute(query.c_str())) |
- return false; |
- |
- query = "DELETE FROM autofill WHERE " + autofill_is_too_big; |
- |
- if (!db_->Execute(query.c_str())) |
- return false; |
- |
- // Only delete from legacy credit card tables where specific columns exist. |
- if (db_->DoesColumnExist("credit_cards", "label") && |
- db_->DoesColumnExist("credit_cards", "name_on_card") && |
- db_->DoesColumnExist("credit_cards", "type") && |
- db_->DoesColumnExist("credit_cards", "expiration_month") && |
- db_->DoesColumnExist("credit_cards", "expiration_year") && |
- db_->DoesColumnExist("credit_cards", "billing_address") && |
- db_->DoesColumnExist("credit_cards", "shipping_address") && |
- db_->DoesColumnExist("autofill_profiles", "label")) { |
- query = "DELETE FROM credit_cards WHERE (" + credit_cards_is_too_big + |
- ") OR label IN (SELECT label FROM autofill_profiles WHERE " + |
- autofill_profiles_is_too_big + ")"; |
- |
- if (!db_->Execute(query.c_str())) |
- return false; |
- } |
- |
- if (db_->DoesColumnExist("autofill_profiles", "label")) { |
- query = "DELETE FROM autofill_profiles WHERE " + |
- autofill_profiles_is_too_big; |
- |
- if (!db_->Execute(query.c_str())) |
- return false; |
- } |
- |
- return true; |
-} |
- |
-// Change the credit_cards.billing_address column from a string to an |
-// int. The stored string is the label of an address, so we have to |
-// select the unique ID of this address using the label as a foreign |
-// key into the |autofill_profiles| table. |
-bool AutofillTable::MigrateToVersion27UpdateLegacyCreditCards() { |
- // Only migrate from legacy credit card tables where specific columns |
- // exist. |
- if (!(db_->DoesColumnExist("credit_cards", "unique_id") && |
- db_->DoesColumnExist("credit_cards", "billing_address") && |
- db_->DoesColumnExist("autofill_profiles", "unique_id"))) { |
- return true; |
- } |
- |
- std::string stmt = |
- "SELECT credit_cards.unique_id, autofill_profiles.unique_id " |
- "FROM autofill_profiles, credit_cards " |
- "WHERE credit_cards.billing_address = autofill_profiles.label"; |
- sql::Statement s(db_->GetUniqueStatement(stmt.c_str())); |
- |
- std::map<int, int> cc_billing_map; |
- while (s.Step()) |
- cc_billing_map[s.ColumnInt(0)] = s.ColumnInt(1); |
- if (!s.Succeeded()) |
- return false; |
- |
- // Windows already stores the IDs as strings in |billing_address|. Try |
- // to convert those. |
- if (cc_billing_map.empty()) { |
- std::string stmt = "SELECT unique_id,billing_address FROM credit_cards"; |
- sql::Statement s(db_->GetUniqueStatement(stmt.c_str())); |
- |
- while (s.Step()) { |
- int id = 0; |
- if (base::StringToInt(s.ColumnString(1), &id)) |
- cc_billing_map[s.ColumnInt(0)] = id; |
- } |
- if (!s.Succeeded()) |
- return false; |
- } |
- |
- if (!db_->Execute("CREATE TABLE credit_cards_temp ( " |
- "label VARCHAR, " |
- "unique_id INTEGER PRIMARY KEY, " |
- "name_on_card VARCHAR, " |
- "type VARCHAR, " |
- "card_number VARCHAR, " |
- "expiration_month INTEGER, " |
- "expiration_year INTEGER, " |
- "verification_code VARCHAR, " |
- "billing_address INTEGER, " |
- "shipping_address VARCHAR, " |
- "card_number_encrypted BLOB, " |
- "verification_code_encrypted BLOB)")) { |
- return false; |
- } |
- |
- if (!db_->Execute( |
- "INSERT INTO credit_cards_temp " |
- "SELECT label,unique_id,name_on_card,type,card_number," |
- "expiration_month,expiration_year,verification_code,0," |
- "shipping_address,card_number_encrypted," |
- "verification_code_encrypted FROM credit_cards")) { |
- return false; |
- } |
- |
- if (!db_->Execute("DROP TABLE credit_cards")) |
- return false; |
- |
- if (!db_->Execute("ALTER TABLE credit_cards_temp RENAME TO credit_cards")) |
- return false; |
- |
- for (std::map<int, int>::const_iterator iter = cc_billing_map.begin(); |
- iter != cc_billing_map.end(); ++iter) { |
- sql::Statement s(db_->GetCachedStatement( |
- SQL_FROM_HERE, |
- "UPDATE credit_cards SET billing_address=? WHERE unique_id=?")); |
- s.BindInt(0, (*iter).second); |
- s.BindInt(1, (*iter).first); |
- |
- if (!s.Run()) |
- return false; |
- } |
- |
- return true; |
-} |
- |
-bool AutofillTable::MigrateToVersion30AddDateModifed() { |
- // Add date_modified to autofill_profiles. |
- if (!db_->DoesColumnExist("autofill_profiles", "date_modified")) { |
- if (!db_->Execute("ALTER TABLE autofill_profiles ADD COLUMN " |
- "date_modified INTEGER NON NULL DEFAULT 0")) { |
- return false; |
- } |
- |
- sql::Statement s(db_->GetUniqueStatement( |
- "UPDATE autofill_profiles SET date_modified=?")); |
- s.BindInt64(0, Time::Now().ToTimeT()); |
- |
- if (!s.Run()) |
- return false; |
- } |
- |
- // Add date_modified to credit_cards. |
- if (!db_->DoesColumnExist("credit_cards", "date_modified")) { |
- if (!db_->Execute("ALTER TABLE credit_cards ADD COLUMN " |
- "date_modified INTEGER NON NULL DEFAULT 0")) { |
- return false; |
- } |
- |
- sql::Statement s(db_->GetUniqueStatement( |
- "UPDATE credit_cards SET date_modified=?")); |
- s.BindInt64(0, Time::Now().ToTimeT()); |
- |
- if (!s.Run()) |
- return false; |
- } |
- |
- return true; |
-} |
- |
-bool AutofillTable::MigrateToVersion31AddGUIDToCreditCardsAndProfiles() { |
- // Note that we need to check for the guid column's existence due to the |
- // fact that for a version 22 database the |autofill_profiles| table |
- // gets created fresh with |InitAutofillProfilesTable|. |
- if (!db_->DoesColumnExist("autofill_profiles", "guid")) { |
- if (!db_->Execute("ALTER TABLE autofill_profiles ADD COLUMN " |
- "guid VARCHAR NOT NULL DEFAULT \"\"")) { |
- return false; |
- } |
- |
- // Set all the |guid| fields to valid values. |
- |
- sql::Statement s(db_->GetUniqueStatement("SELECT unique_id " |
- "FROM autofill_profiles")); |
- |
- while (s.Step()) { |
- sql::Statement update_s( |
- db_->GetUniqueStatement("UPDATE autofill_profiles " |
- "SET guid=? WHERE unique_id=?")); |
- update_s.BindString(0, base::GenerateGUID()); |
- update_s.BindInt(1, s.ColumnInt(0)); |
- |
- if (!update_s.Run()) |
- return false; |
- } |
- if (!s.Succeeded()) |
- return false; |
- } |
- |
- // Note that we need to check for the guid column's existence due to the |
- // fact that for a version 22 database the |autofill_profiles| table |
- // gets created fresh with |InitAutofillProfilesTable|. |
- if (!db_->DoesColumnExist("credit_cards", "guid")) { |
- if (!db_->Execute("ALTER TABLE credit_cards ADD COLUMN " |
- "guid VARCHAR NOT NULL DEFAULT \"\"")) { |
- return false; |
- } |
- |
- // Set all the |guid| fields to valid values. |
- |
- sql::Statement s(db_->GetUniqueStatement("SELECT unique_id " |
- "FROM credit_cards")); |
- |
- while (s.Step()) { |
- sql::Statement update_s( |
- db_->GetUniqueStatement("UPDATE credit_cards " |
- "set guid=? WHERE unique_id=?")); |
- update_s.BindString(0, base::GenerateGUID()); |
- update_s.BindInt(1, s.ColumnInt(0)); |
- |
- if (!update_s.Run()) |
- return false; |
- } |
- if (!s.Succeeded()) |
- return false; |
- } |
- |
- return true; |
-} |
- |
-bool AutofillTable::MigrateToVersion32UpdateProfilesAndCreditCards() { |
- if (db_->DoesColumnExist("autofill_profiles", "unique_id")) { |
- if (!db_->Execute("CREATE TABLE autofill_profiles_temp ( " |
- "guid VARCHAR PRIMARY KEY, " |
- "label VARCHAR, " |
- "first_name VARCHAR, " |
- "middle_name VARCHAR, " |
- "last_name VARCHAR, " |
- "email VARCHAR, " |
- "company_name VARCHAR, " |
- "address_line_1 VARCHAR, " |
- "address_line_2 VARCHAR, " |
- "city VARCHAR, " |
- "state VARCHAR, " |
- "zipcode VARCHAR, " |
- "country VARCHAR, " |
- "phone VARCHAR, " |
- "date_modified INTEGER NOT NULL DEFAULT 0)")) { |
- return false; |
- } |
- |
- if (!db_->Execute( |
- "INSERT INTO autofill_profiles_temp " |
- "SELECT guid, label, first_name, middle_name, last_name, email, " |
- "company_name, address_line_1, address_line_2, city, state, " |
- "zipcode, country, phone, date_modified " |
- "FROM autofill_profiles")) { |
- return false; |
- } |
- |
- if (!db_->Execute("DROP TABLE autofill_profiles")) |
- return false; |
- |
- if (!db_->Execute( |
- "ALTER TABLE autofill_profiles_temp RENAME TO autofill_profiles")) { |
- return false; |
- } |
- } |
- |
- if (db_->DoesColumnExist("credit_cards", "unique_id")) { |
- if (!db_->Execute("CREATE TABLE credit_cards_temp ( " |
- "guid VARCHAR PRIMARY KEY, " |
- "label VARCHAR, " |
- "name_on_card VARCHAR, " |
- "expiration_month INTEGER, " |
- "expiration_year INTEGER, " |
- "card_number_encrypted BLOB, " |
- "date_modified INTEGER NOT NULL DEFAULT 0)")) { |
- return false; |
- } |
- |
- if (!db_->Execute( |
- "INSERT INTO credit_cards_temp " |
- "SELECT guid, label, name_on_card, expiration_month, " |
- "expiration_year, card_number_encrypted, date_modified " |
- "FROM credit_cards")) { |
- return false; |
- } |
- |
- if (!db_->Execute("DROP TABLE credit_cards")) |
- return false; |
- |
- if (!db_->Execute("ALTER TABLE credit_cards_temp RENAME TO credit_cards")) |
- return false; |
- } |
- |
- return true; |
-} |
- |
-// Test the existence of the |first_name| column as an indication that |
-// we need a migration. It is possible that the new |autofill_profiles| |
-// schema is in place because the table was newly created when migrating |
-// from a pre-version-22 database. |
-bool AutofillTable::MigrateToVersion33ProfilesBasedOnFirstName() { |
- if (db_->DoesColumnExist("autofill_profiles", "first_name")) { |
- // Create autofill_profiles_temp table that will receive the data. |
- if (!db_->DoesTableExist("autofill_profiles_temp")) { |
- if (!db_->Execute("CREATE TABLE autofill_profiles_temp ( " |
- "guid VARCHAR PRIMARY KEY, " |
- "company_name VARCHAR, " |
- "address_line_1 VARCHAR, " |
- "address_line_2 VARCHAR, " |
- "city VARCHAR, " |
- "state VARCHAR, " |
- "zipcode VARCHAR, " |
- "country VARCHAR, " |
- "date_modified INTEGER NOT NULL DEFAULT 0)")) { |
- return false; |
- } |
- } |
- |
- sql::Statement s(db_->GetUniqueStatement( |
- "SELECT guid, first_name, middle_name, last_name, email, " |
- "company_name, address_line_1, address_line_2, city, state, " |
- "zipcode, country, phone, date_modified " |
- "FROM autofill_profiles")); |
- |
- while (s.Step()) { |
- AutofillProfile profile; |
- profile.set_guid(s.ColumnString(0)); |
- DCHECK(base::IsValidGUID(profile.guid())); |
- |
- profile.SetRawInfo(NAME_FIRST, s.ColumnString16(1)); |
- profile.SetRawInfo(NAME_MIDDLE, s.ColumnString16(2)); |
- profile.SetRawInfo(NAME_LAST, s.ColumnString16(3)); |
- profile.SetRawInfo(EMAIL_ADDRESS, s.ColumnString16(4)); |
- profile.SetRawInfo(COMPANY_NAME, s.ColumnString16(5)); |
- profile.SetRawInfo(ADDRESS_HOME_LINE1, s.ColumnString16(6)); |
- profile.SetRawInfo(ADDRESS_HOME_LINE2, s.ColumnString16(7)); |
- profile.SetRawInfo(ADDRESS_HOME_CITY, s.ColumnString16(8)); |
- profile.SetRawInfo(ADDRESS_HOME_STATE, s.ColumnString16(9)); |
- profile.SetRawInfo(ADDRESS_HOME_ZIP, s.ColumnString16(10)); |
- profile.SetInfo(ADDRESS_HOME_COUNTRY, s.ColumnString16(11), app_locale_); |
- profile.SetRawInfo(PHONE_HOME_WHOLE_NUMBER, s.ColumnString16(12)); |
- int64 date_modified = s.ColumnInt64(13); |
- |
- sql::Statement s_insert(db_->GetUniqueStatement( |
- "INSERT INTO autofill_profiles_temp" |
- "(guid, company_name, address_line_1, address_line_2, city," |
- " state, zipcode, country, date_modified)" |
- "VALUES (?,?,?,?,?,?,?,?,?)")); |
- s_insert.BindString(0, profile.guid()); |
- s_insert.BindString16(1, profile.GetRawInfo(COMPANY_NAME)); |
- s_insert.BindString16(2, profile.GetRawInfo(ADDRESS_HOME_LINE1)); |
- s_insert.BindString16(3, profile.GetRawInfo(ADDRESS_HOME_LINE2)); |
- s_insert.BindString16(4, profile.GetRawInfo(ADDRESS_HOME_CITY)); |
- s_insert.BindString16(5, profile.GetRawInfo(ADDRESS_HOME_STATE)); |
- s_insert.BindString16(6, profile.GetRawInfo(ADDRESS_HOME_ZIP)); |
- s_insert.BindString16(7, profile.GetRawInfo(ADDRESS_HOME_COUNTRY)); |
- s_insert.BindInt64(8, date_modified); |
- |
- if (!s_insert.Run()) |
- return false; |
- |
- // Add the other bits: names, emails, and phone numbers. |
- if (!AddAutofillProfilePieces(profile, db_)) |
- return false; |
- } // endwhile |
- if (!s.Succeeded()) |
- return false; |
- |
- if (!db_->Execute("DROP TABLE autofill_profiles")) |
- return false; |
- |
- if (!db_->Execute( |
- "ALTER TABLE autofill_profiles_temp RENAME TO autofill_profiles")) { |
- return false; |
- } |
- } |
- |
- // Remove the labels column from the credit_cards table. |
- if (db_->DoesColumnExist("credit_cards", "label")) { |
- if (!db_->Execute("CREATE TABLE credit_cards_temp ( " |
- "guid VARCHAR PRIMARY KEY, " |
- "name_on_card VARCHAR, " |
- "expiration_month INTEGER, " |
- "expiration_year INTEGER, " |
- "card_number_encrypted BLOB, " |
- "date_modified INTEGER NOT NULL DEFAULT 0)")) { |
- return false; |
- } |
- |
- if (!db_->Execute( |
- "INSERT INTO credit_cards_temp " |
- "SELECT guid, name_on_card, expiration_month, " |
- "expiration_year, card_number_encrypted, date_modified " |
- "FROM credit_cards")) { |
- return false; |
- } |
- |
- if (!db_->Execute("DROP TABLE credit_cards")) |
- return false; |
- |
- if (!db_->Execute("ALTER TABLE credit_cards_temp RENAME TO credit_cards")) |
- return false; |
- } |
- |
- return true; |
-} |
- |
-// Test the existence of the |country_code| column as an indication that |
-// we need a migration. It is possible that the new |autofill_profiles| |
-// schema is in place because the table was newly created when migrating |
-// from a pre-version-22 database. |
-bool AutofillTable::MigrateToVersion34ProfilesBasedOnCountryCode() { |
- if (!db_->DoesColumnExist("autofill_profiles", "country_code")) { |
- if (!db_->Execute("ALTER TABLE autofill_profiles ADD COLUMN " |
- "country_code VARCHAR")) { |
- return false; |
- } |
- |
- // Set all the |country_code| fields to match existing |country| values. |
- sql::Statement s(db_->GetUniqueStatement("SELECT guid, country " |
- "FROM autofill_profiles")); |
- |
- while (s.Step()) { |
- sql::Statement update_s( |
- db_->GetUniqueStatement("UPDATE autofill_profiles " |
- "SET country_code=? WHERE guid=?")); |
- |
- base::string16 country = s.ColumnString16(1); |
- update_s.BindString(0, AutofillCountry::GetCountryCode(country, |
- app_locale_)); |
- update_s.BindString(1, s.ColumnString(0)); |
- |
- if (!update_s.Run()) |
- return false; |
- } |
- if (!s.Succeeded()) |
- return false; |
- } |
- |
- return true; |
-} |
- |
-// Correct all country codes with value "UK" to be "GB". This data |
-// was mistakenly introduced in build 686.0. This migration is to clean |
-// it up. See http://crbug.com/74511 for details. |
-bool AutofillTable::MigrateToVersion35GreatBritainCountryCodes() { |
- sql::Statement s(db_->GetUniqueStatement( |
- "UPDATE autofill_profiles SET country_code=\"GB\" " |
- "WHERE country_code=\"UK\"")); |
- |
- return s.Run(); |
-} |
- |
-// Merge and cull older profiles where possible. |
-bool AutofillTable::MigrateToVersion37MergeAndCullOlderProfiles() { |
- sql::Statement s(db_->GetUniqueStatement( |
- "SELECT guid, date_modified FROM autofill_profiles")); |
- |
- // Accumulate the good profiles. |
- std::vector<AutofillProfile> accumulated_profiles; |
- std::vector<AutofillProfile*> accumulated_profiles_p; |
- std::map<std::string, int64> modification_map; |
- while (s.Step()) { |
- std::string guid = s.ColumnString(0); |
- int64 date_modified = s.ColumnInt64(1); |
- modification_map.insert( |
- std::pair<std::string, int64>(guid, date_modified)); |
- |
- sql::Statement s(db_->GetUniqueStatement( |
- "SELECT guid, company_name, address_line_1, address_line_2, city, " |
- " state, zipcode, country, country_code, date_modified " |
- "FROM autofill_profiles " |
- "WHERE guid=?")); |
- s.BindString(0, guid); |
- |
- if (!s.Step()) |
- return false; |
- |
- scoped_ptr<AutofillProfile> profile(new AutofillProfile); |
- profile->set_guid(s.ColumnString(0)); |
- DCHECK(base::IsValidGUID(profile->guid())); |
- |
- profile->SetRawInfo(COMPANY_NAME, s.ColumnString16(1)); |
- profile->SetRawInfo(ADDRESS_HOME_LINE1, s.ColumnString16(2)); |
- profile->SetRawInfo(ADDRESS_HOME_LINE2, s.ColumnString16(3)); |
- profile->SetRawInfo(ADDRESS_HOME_CITY, s.ColumnString16(4)); |
- profile->SetRawInfo(ADDRESS_HOME_STATE, s.ColumnString16(5)); |
- profile->SetRawInfo(ADDRESS_HOME_ZIP, s.ColumnString16(6)); |
- // Intentionally skip column 7, which stores the localized country name. |
- profile->SetRawInfo(ADDRESS_HOME_COUNTRY, s.ColumnString16(8)); |
- // Intentionally skip column 9, which stores the profile's modification |
- // date. |
- profile->set_origin(s.ColumnString(10)); |
- |
- // Get associated name info. |
- AddAutofillProfileNamesToProfile(db_, profile.get()); |
- |
- // Get associated email info. |
- AddAutofillProfileEmailsToProfile(db_, profile.get()); |
- |
- // Get associated phone info. |
- AddAutofillProfilePhonesToProfile(db_, profile.get()); |
- |
- if (PersonalDataManager::IsValidLearnableProfile(*profile, app_locale_)) { |
- std::vector<AutofillProfile> merged_profiles; |
- bool merged = PersonalDataManager::MergeProfile( |
- *profile, accumulated_profiles_p, app_locale_, &merged_profiles); |
- |
- std::swap(accumulated_profiles, merged_profiles); |
- |
- accumulated_profiles_p.clear(); |
- accumulated_profiles_p.resize(accumulated_profiles.size()); |
- std::transform(accumulated_profiles.begin(), |
- accumulated_profiles.end(), |
- accumulated_profiles_p.begin(), |
- address_of<AutofillProfile>); |
- |
- // If the profile got merged trash the original. |
- if (merged) |
- AddAutofillGUIDToTrash(profile->guid()); |
- |
- } else { |
- // An invalid profile, so trash it. |
- AddAutofillGUIDToTrash(profile->guid()); |
- } |
- } // endwhile |
- if (!s.Succeeded()) |
- return false; |
- |
- // Drop the current profiles. |
- if (!ClearAutofillProfiles()) |
- return false; |
- |
- // Add the newly merged profiles back in. |
- for (std::vector<AutofillProfile>::const_iterator |
- iter = accumulated_profiles.begin(); |
- iter != accumulated_profiles.end(); |
- ++iter) { |
- // Save the profile with its original modification date. |
- std::map<std::string, int64>::const_iterator date_item = |
- modification_map.find(iter->guid()); |
- if (date_item == modification_map.end()) |
- return false; |
- |
- sql::Statement s(db_->GetUniqueStatement( |
- "INSERT INTO autofill_profiles" |
- "(guid, company_name, address_line_1, address_line_2, city, state," |
- " zipcode, country, country_code, date_modified)" |
- "VALUES (?,?,?,?,?,?,?,?,?,?)")); |
- s.BindString(0, iter->guid()); |
- base::string16 text = iter->GetRawInfo(COMPANY_NAME); |
- s.BindString16(1, LimitDataSize(text)); |
- text = iter->GetRawInfo(ADDRESS_HOME_LINE1); |
- s.BindString16(2, LimitDataSize(text)); |
- text = iter->GetRawInfo(ADDRESS_HOME_LINE2); |
- s.BindString16(3, LimitDataSize(text)); |
- text = iter->GetRawInfo(ADDRESS_HOME_CITY); |
- s.BindString16(4, LimitDataSize(text)); |
- text = iter->GetRawInfo(ADDRESS_HOME_STATE); |
- s.BindString16(5, LimitDataSize(text)); |
- text = iter->GetRawInfo(ADDRESS_HOME_ZIP); |
- s.BindString16(6, LimitDataSize(text)); |
- text = iter->GetInfo(ADDRESS_HOME_COUNTRY, app_locale_); |
- s.BindString16(7, LimitDataSize(text)); |
- text = iter->GetRawInfo(ADDRESS_HOME_COUNTRY); |
- s.BindString16(8, LimitDataSize(text)); |
- s.BindInt64(9, date_item->second); |
- |
- if (!s.Run()) |
- return false; |
- |
- if (!AddAutofillProfilePieces(*iter, db_)) |
- return false; |
- } |
- |
- return true; |
-} |
- |
-bool AutofillTable::MigrateToVersion51AddOriginColumn() { |
- sql::Transaction transaction(db_); |
- if (!transaction.Begin()) |
- return false; |
- |
- // Add origin to autofill_profiles. |
- if (!db_->DoesColumnExist("autofill_profiles", "origin") && |
- !db_->Execute("ALTER TABLE autofill_profiles " |
- "ADD COLUMN origin VARCHAR DEFAULT ''")) { |
- return false; |
- } |
- |
- // Add origin to credit_cards. |
- if (!db_->DoesColumnExist("credit_cards", "origin") && |
- !db_->Execute("ALTER TABLE credit_cards " |
- "ADD COLUMN origin VARCHAR DEFAULT ''")) { |
- return false; |
- } |
- |
- return transaction.Commit(); |
-} |
- |
-} // namespace autofill |