| Index: components/autofill/core/browser/webdata/autofill_table.cc
|
| diff --git a/components/autofill/core/browser/webdata/autofill_table.cc b/components/autofill/core/browser/webdata/autofill_table.cc
|
| index 14fd62e5fc099f059b61d819e7c474acd167f4a4..9e960cfa957c37a5428e0caaa721837b5f61be89 100644
|
| --- a/components/autofill/core/browser/webdata/autofill_table.cc
|
| +++ b/components/autofill/core/browser/webdata/autofill_table.cc
|
| @@ -189,37 +189,6 @@ scoped_ptr<CreditCard> CreditCardFromStatement(const sql::Statement& s) {
|
| return credit_card.Pass();
|
| }
|
|
|
| -// Obsolete version of AddAutofillProfileNamesToProfile, but still needed
|
| -// for MigrateToVersion37MergeAndCullOlderProfiles().
|
| -bool AddAutofillProfileNamesToProfileForVersion37(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 AddAutofillProfileNamesToProfile(sql::Connection* db,
|
| AutofillProfile* profile) {
|
| sql::Statement s(db->GetUniqueStatement(
|
| @@ -298,38 +267,6 @@ bool AddAutofillProfilePhonesToProfile(sql::Connection* db,
|
| return true;
|
| }
|
|
|
| -// Obsolete version of AddAutofillProfileNames needed for
|
| -// MigrateToVersion33ProfilesBasedOnFirstName() and
|
| -// MigrateToVersion37MergeAndCullOlderProfiles().
|
| -bool AddAutofillProfileNamesForVersion3x(
|
| - 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(first_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 AddAutofillProfileNames(const AutofillProfile& profile,
|
| sql::Connection* db) {
|
| std::vector<base::string16> first_names;
|
| @@ -511,48 +448,6 @@ bool AutofillTable::MigrateToVersion(int version,
|
| bool* update_compatible_version) {
|
| // Migrate if necessary.
|
| switch (version) {
|
| - case 22:
|
| - return MigrateToVersion22ClearAutofillEmptyValueElements();
|
| - 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();
|
| case 54:
|
| *update_compatible_version = true;
|
| return MigrateToVersion54AddI18nFieldsAndRemoveDeprecatedFields();
|
| @@ -1795,778 +1690,6 @@ bool AutofillTable::InitServerAddressesTable() {
|
| return true;
|
| }
|
|
|
| -bool AutofillTable::MigrateToVersion22ClearAutofillEmptyValueElements() {
|
| - if (!db_->DoesTableExist("autofill") &&
|
| - (!db_->Execute("CREATE TABLE autofill ("
|
| - " name VARCHAR,"
|
| - " value VARCHAR,"
|
| - " value_lower VARCHAR,"
|
| - " pair_id INTEGER PRIMARY KEY,"
|
| - " count INTEGER DEFAULT 1)") ||
|
| - !db_->Execute("CREATE INDEX autofill_name ON autofill (name)") ||
|
| - !db_->Execute("CREATE INDEX autofill_name_value_lower ON"
|
| - " autofill (name, value_lower)") ||
|
| - !db_->Execute("CREATE TABLE autofill_dates ("
|
| - " pair_id INTEGER DEFAULT 0,"
|
| - " date_created INTEGER DEFAULT 0)") ||
|
| - !db_->Execute("CREATE INDEX autofill_dates_pair_id ON"
|
| - " autofill (pair_id)")))
|
| - return false;
|
| -
|
| -
|
| - 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;
|
| -
|
| - if (!db_->Execute("DELETE FROM autofill WHERE TRIM(value) = \"\""))
|
| - return false;
|
| -
|
| - for (std::set<int64>::const_iterator it = ids.begin(); it != ids.end();
|
| - ++it) {
|
| - sql::Statement s(db_->GetUniqueStatement(
|
| - "DELETE FROM autofill_dates WHERE pair_id = ?"));
|
| - s.BindInt64(0, *it);
|
| - if (!s.Run())
|
| - 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_->DoesTableExist("autofill_profiles") &&
|
| - (!db_->Execute("CREATE TABLE autofill_profiles ( "
|
| - "label VARCHAR, "
|
| - "unique_id INTEGER PRIMARY KEY, "
|
| - "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, "
|
| - "fax VARCHAR)") ||
|
| - !db_->Execute("CREATE INDEX autofill_profiles_label_index"
|
| - " ON autofill_profiles (label)")))
|
| - return false;
|
| -
|
| - if (!db_->DoesTableExist("credit_cards") &&
|
| - (!db_->Execute("CREATE TABLE credit_cards ( "
|
| - "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 VARCHAR, "
|
| - "shipping_address VARCHAR)") ||
|
| - !db_->Execute("CREATE INDEX credit_cards_label_index"
|
| - " ON credit_cards (label)")))
|
| - return false;
|
| -
|
| - if (!db_->DoesColumnExist("credit_cards", "card_number_encrypted")) {
|
| - if (!db_->Execute("ALTER TABLE credit_cards ADD COLUMN "
|
| - "card_number_encrypted BLOB DEFAULT NULL")) {
|
| - 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")) {
|
| - 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_->DoesTableExist("autofill_profile_names") &&
|
| - !db_->Execute("CREATE TABLE autofill_profile_names ( "
|
| - "guid VARCHAR, "
|
| - "first_name VARCHAR, "
|
| - "middle_name VARCHAR, "
|
| - "last_name VARCHAR)"))
|
| - return false;
|
| -
|
| - if (!db_->DoesTableExist("autofill_profile_emails") &&
|
| - !db_->Execute("CREATE TABLE autofill_profile_emails ( "
|
| - "guid VARCHAR, "
|
| - "email VARCHAR)"))
|
| - return false;
|
| -
|
| - if (!db_->DoesTableExist("autofill_profile_phones") &&
|
| - !db_->Execute("CREATE TABLE autofill_profile_phones ( "
|
| - "guid VARCHAR, "
|
| - "type INTEGER DEFAULT 0, "
|
| - "number VARCHAR)"))
|
| - return false;
|
| -
|
| - 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;
|
| - int index = 0;
|
| - profile.set_guid(s.ColumnString(index++));
|
| - DCHECK(base::IsValidGUID(profile.guid()));
|
| -
|
| - profile.SetRawInfo(NAME_FIRST, s.ColumnString16(index++));
|
| - profile.SetRawInfo(NAME_MIDDLE, s.ColumnString16(index++));
|
| - profile.SetRawInfo(NAME_LAST, s.ColumnString16(index++));
|
| - profile.SetRawInfo(EMAIL_ADDRESS, s.ColumnString16(index++));
|
| - profile.SetRawInfo(COMPANY_NAME, s.ColumnString16(index++));
|
| - profile.SetRawInfo(ADDRESS_HOME_LINE1, s.ColumnString16(index++));
|
| - profile.SetRawInfo(ADDRESS_HOME_LINE2, s.ColumnString16(index++));
|
| - profile.SetRawInfo(ADDRESS_HOME_CITY, s.ColumnString16(index++));
|
| - profile.SetRawInfo(ADDRESS_HOME_STATE, s.ColumnString16(index++));
|
| - profile.SetRawInfo(ADDRESS_HOME_ZIP, s.ColumnString16(index++));
|
| - profile.SetInfo(AutofillType(ADDRESS_HOME_COUNTRY),
|
| - s.ColumnString16(index++), app_locale_);
|
| - profile.SetRawInfo(PHONE_HOME_WHOLE_NUMBER, s.ColumnString16(index++));
|
| - int64 date_modified = s.ColumnInt64(index++);
|
| -
|
| - 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 (?,?,?,?,?,?,?,?,?)"));
|
| - index = 0;
|
| - s_insert.BindString(index++, profile.guid());
|
| - s_insert.BindString16(index++, profile.GetRawInfo(COMPANY_NAME));
|
| - s_insert.BindString16(index++, profile.GetRawInfo(ADDRESS_HOME_LINE1));
|
| - s_insert.BindString16(index++, profile.GetRawInfo(ADDRESS_HOME_LINE2));
|
| - s_insert.BindString16(index++, profile.GetRawInfo(ADDRESS_HOME_CITY));
|
| - s_insert.BindString16(index++, profile.GetRawInfo(ADDRESS_HOME_STATE));
|
| - s_insert.BindString16(index++, profile.GetRawInfo(ADDRESS_HOME_ZIP));
|
| - s_insert.BindString16(index++, profile.GetRawInfo(ADDRESS_HOME_COUNTRY));
|
| - s_insert.BindInt64(index++, date_modified);
|
| -
|
| - if (!s_insert.Run())
|
| - return false;
|
| -
|
| - // Add the other bits: names, emails, and phone numbers.
|
| - if (!AddAutofillProfileNamesForVersion3x(profile, db_) ||
|
| - !AddAutofillProfileEmails(profile, db_) ||
|
| - !AddAutofillProfilePhones(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() {
|
| - if (!db_->DoesTableExist("autofill_profiles_trash") &&
|
| - !db_->Execute("CREATE TABLE autofill_profiles_trash (guid VARCHAR)"))
|
| - return false;
|
| -
|
| - 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);
|
| - int index = 0;
|
| - profile->set_guid(s.ColumnString(index++));
|
| - DCHECK(base::IsValidGUID(profile->guid()));
|
| -
|
| - profile->SetRawInfo(COMPANY_NAME, s.ColumnString16(index++));
|
| - profile->SetRawInfo(ADDRESS_HOME_LINE1, s.ColumnString16(index++));
|
| - profile->SetRawInfo(ADDRESS_HOME_LINE2, s.ColumnString16(index++));
|
| - profile->SetRawInfo(ADDRESS_HOME_CITY, s.ColumnString16(index++));
|
| - profile->SetRawInfo(ADDRESS_HOME_STATE, s.ColumnString16(index++));
|
| - profile->SetRawInfo(ADDRESS_HOME_ZIP, s.ColumnString16(index++));
|
| - // Intentionally skip column 7, which stores the localized country name.
|
| - index++;
|
| - profile->SetRawInfo(ADDRESS_HOME_COUNTRY, s.ColumnString16(index++));
|
| - profile->set_modification_date(
|
| - base::Time::FromTimeT(s.ColumnInt64(index++)));
|
| - profile->set_origin(s.ColumnString(index++));
|
| -
|
| - // Get associated name info.
|
| - AddAutofillProfileNamesToProfileForVersion37(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;
|
| - std::string merged_guid = 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_guid != profile->guid())
|
| - 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 (?,?,?,?,?,?,?,?,?,?)"));
|
| - int index = 0;
|
| - s.BindString(index++, iter->guid());
|
| - s.BindString16(index++, GetInfo(*iter, COMPANY_NAME));
|
| - s.BindString16(index++, GetInfo(*iter, ADDRESS_HOME_LINE1));
|
| - s.BindString16(index++, GetInfo(*iter, ADDRESS_HOME_LINE2));
|
| - s.BindString16(index++, GetInfo(*iter, ADDRESS_HOME_CITY));
|
| - s.BindString16(index++, GetInfo(*iter, ADDRESS_HOME_STATE));
|
| - s.BindString16(index++, GetInfo(*iter, ADDRESS_HOME_ZIP));
|
| - s.BindString16(index++, base::string16()); // This column is deprecated.
|
| - s.BindString16(index++, GetInfo(*iter, ADDRESS_HOME_COUNTRY));
|
| - s.BindInt64(index++, date_item->second);
|
| -
|
| - if (!s.Run())
|
| - return false;
|
| -
|
| - if (!AddAutofillProfileNamesForVersion3x(*iter, db_) ||
|
| - !AddAutofillProfileEmails(*iter, db_) ||
|
| - !AddAutofillProfilePhones(*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();
|
| -}
|
| -
|
| bool AutofillTable::MigrateToVersion54AddI18nFieldsAndRemoveDeprecatedFields() {
|
| sql::Transaction transaction(db_);
|
| if (!transaction.Begin())
|
|
|