summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--components/autofill/core/browser/address.cc29
-rw-r--r--components/autofill/core/browser/address.h5
-rw-r--r--components/autofill/core/browser/autofill_manager.cc3
-rw-r--r--components/autofill/core/browser/autofill_profile.cc43
-rw-r--r--components/autofill/core/browser/autofill_profile_unittest.cc41
-rw-r--r--components/autofill/core/browser/personal_data_manager.cc3
-rw-r--r--components/autofill/core/browser/personal_data_manager_unittest.cc56
-rw-r--r--components/autofill/core/browser/webdata/autofill_table.cc382
-rw-r--r--components/autofill/core/browser/webdata/autofill_table.h45
-rw-r--r--components/autofill/core/browser/webdata/autofill_table_unittest.cc6
-rw-r--r--components/test/data/web_database/version_53.sql50
-rw-r--r--components/webdata/common/web_database.cc4
-rw-r--r--components/webdata/common/web_database_migration_unittest.cc268
13 files changed, 685 insertions, 250 deletions
diff --git a/components/autofill/core/browser/address.cc b/components/autofill/core/browser/address.cc
index 2d326ce..c0bb1b5 100644
--- a/components/autofill/core/browser/address.cc
+++ b/components/autofill/core/browser/address.cc
@@ -31,10 +31,12 @@ Address& Address::operator=(const Address& address) {
line1_ = address.line1_;
line2_ = address.line2_;
+ dependent_locality_ = address.dependent_locality_;
city_ = address.city_;
state_ = address.state_;
country_code_ = address.country_code_;
zip_code_ = address.zip_code_;
+ sorting_code_ = address.sorting_code_;
return *this;
}
@@ -47,6 +49,9 @@ base::string16 Address::GetRawInfo(ServerFieldType type) const {
case ADDRESS_HOME_LINE2:
return line2_;
+ case ADDRESS_HOME_DEPENDENT_LOCALITY:
+ return dependent_locality_;
+
case ADDRESS_HOME_CITY:
return city_;
@@ -56,6 +61,9 @@ base::string16 Address::GetRawInfo(ServerFieldType type) const {
case ADDRESS_HOME_ZIP:
return zip_code_;
+ case ADDRESS_HOME_SORTING_CODE:
+ return sorting_code_;
+
case ADDRESS_HOME_COUNTRY:
return ASCIIToUTF16(country_code_);
@@ -66,11 +74,6 @@ base::string16 Address::GetRawInfo(ServerFieldType type) const {
return address;
}
- // TODO(isherman): Add support for these field types in support of i18n.
- case ADDRESS_HOME_SORTING_CODE:
- case ADDRESS_HOME_DEPENDENT_LOCALITY:
- return base::string16();
-
default:
NOTREACHED();
return base::string16();
@@ -88,6 +91,10 @@ void Address::SetRawInfo(ServerFieldType type, const base::string16& value) {
line2_ = value;
break;
+ case ADDRESS_HOME_DEPENDENT_LOCALITY:
+ dependent_locality_ = value;
+ break;
+
case ADDRESS_HOME_CITY:
city_ = value;
break;
@@ -106,6 +113,10 @@ void Address::SetRawInfo(ServerFieldType type, const base::string16& value) {
zip_code_ = value;
break;
+ case ADDRESS_HOME_SORTING_CODE:
+ sorting_code_ = value;
+ break;
+
case ADDRESS_HOME_STREET_ADDRESS: {
// Clear any stale values, which might or might not get overwritten below.
line1_.clear();
@@ -122,11 +133,6 @@ void Address::SetRawInfo(ServerFieldType type, const base::string16& value) {
break;
}
- // TODO(isherman): Add support for these field types in support of i18n.
- case ADDRESS_HOME_SORTING_CODE:
- case ADDRESS_HOME_DEPENDENT_LOCALITY:
- break;
-
default:
NOTREACHED();
}
@@ -191,9 +197,12 @@ void Address::GetMatchingTypes(const base::string16& text,
void Address::GetSupportedTypes(ServerFieldTypeSet* supported_types) const {
supported_types->insert(ADDRESS_HOME_LINE1);
supported_types->insert(ADDRESS_HOME_LINE2);
+ supported_types->insert(ADDRESS_HOME_STREET_ADDRESS);
+ supported_types->insert(ADDRESS_HOME_DEPENDENT_LOCALITY);
supported_types->insert(ADDRESS_HOME_CITY);
supported_types->insert(ADDRESS_HOME_STATE);
supported_types->insert(ADDRESS_HOME_ZIP);
+ supported_types->insert(ADDRESS_HOME_SORTING_CODE);
supported_types->insert(ADDRESS_HOME_COUNTRY);
}
diff --git a/components/autofill/core/browser/address.h b/components/autofill/core/browser/address.h
index f62c32e..8ad2751 100644
--- a/components/autofill/core/browser/address.h
+++ b/components/autofill/core/browser/address.h
@@ -45,9 +45,14 @@ class Address : public FormGroup {
// The address, sans country info.
base::string16 line1_;
base::string16 line2_;
+ // A subdivision of city, e.g. inner-city district or suburb.
+ base::string16 dependent_locality_;
base::string16 city_;
base::string16 state_;
base::string16 zip_code_;
+ // Similar to a ZIP code, but used by entities that might not be
+ // geographically contiguous. The canonical example is CEDEX in France.
+ base::string16 sorting_code_;
// The ISO 3166 2-letter country code, or an empty string if there is no
// country data specified for this address.
diff --git a/components/autofill/core/browser/autofill_manager.cc b/components/autofill/core/browser/autofill_manager.cc
index e7b5547..22ec8be 100644
--- a/components/autofill/core/browser/autofill_manager.cc
+++ b/components/autofill/core/browser/autofill_manager.cc
@@ -145,7 +145,8 @@ void DeterminePossibleFieldTypesForUpload(
if (field->form_control_type == "password") {
matching_types.insert(autofill::PASSWORD);
} else {
- base::string16 value = CollapseWhitespace(field->value, false);
+ base::string16 value;
+ TrimWhitespace(field->value, TRIM_ALL, &value);
for (std::vector<AutofillProfile>::const_iterator it = profiles.begin();
it != profiles.end(); ++it) {
it->GetMatchingTypes(value, app_locale, &matching_types);
diff --git a/components/autofill/core/browser/autofill_profile.cc b/components/autofill/core/browser/autofill_profile.cc
index 29f85772..520eff9 100644
--- a/components/autofill/core/browser/autofill_profile.cc
+++ b/components/autofill/core/browser/autofill_profile.cc
@@ -135,8 +135,7 @@ void CopyValuesToItems(ServerFieldType type,
const T& prototype) {
form_group_items->resize(values.size(), prototype);
for (size_t i = 0; i < form_group_items->size(); ++i) {
- (*form_group_items)[i].SetRawInfo(type,
- CollapseWhitespace(values[i], false));
+ (*form_group_items)[i].SetRawInfo(type, values[i]);
}
// Must have at least one (possibly empty) element.
if (form_group_items->empty())
@@ -285,7 +284,7 @@ void AutofillProfile::SetRawInfo(ServerFieldType type,
const base::string16& value) {
FormGroup* form_group = MutableFormGroupForType(AutofillType(type));
if (form_group)
- form_group->SetRawInfo(type, CollapseWhitespace(value, false));
+ form_group->SetRawInfo(type, value);
}
base::string16 AutofillProfile::GetInfo(const AutofillType& type,
@@ -304,8 +303,9 @@ bool AutofillProfile::SetInfo(const AutofillType& type,
if (!form_group)
return false;
- return
- form_group->SetInfo(type, CollapseWhitespace(value, false), app_locale);
+ base::string16 trimmed_value;
+ TrimWhitespace(value, TRIM_ALL, &trimmed_value);
+ return form_group->SetInfo(type, trimmed_value, app_locale);
}
base::string16 AutofillProfile::GetInfoForVariant(
@@ -400,13 +400,17 @@ bool AutofillProfile::IsPresentButInvalid(ServerFieldType type) const {
int AutofillProfile::Compare(const AutofillProfile& profile) const {
- const ServerFieldType single_value_types[] = { COMPANY_NAME,
- ADDRESS_HOME_LINE1,
- ADDRESS_HOME_LINE2,
- ADDRESS_HOME_CITY,
- ADDRESS_HOME_STATE,
- ADDRESS_HOME_ZIP,
- ADDRESS_HOME_COUNTRY };
+ const ServerFieldType single_value_types[] = {
+ COMPANY_NAME,
+ ADDRESS_HOME_LINE1,
+ ADDRESS_HOME_LINE2,
+ ADDRESS_HOME_DEPENDENT_LOCALITY,
+ ADDRESS_HOME_CITY,
+ ADDRESS_HOME_STATE,
+ ADDRESS_HOME_ZIP,
+ ADDRESS_HOME_SORTING_CODE,
+ ADDRESS_HOME_COUNTRY,
+ };
for (size_t i = 0; i < arraysize(single_value_types); ++i) {
int comparison = GetRawInfo(single_value_types[i]).compare(
@@ -461,11 +465,12 @@ bool AutofillProfile::IsSubsetOf(const AutofillProfile& profile,
for (ServerFieldTypeSet::const_iterator it = types.begin(); it != types.end();
++it) {
- if (*it == NAME_FULL) {
+ if (*it == NAME_FULL || *it == ADDRESS_HOME_STREET_ADDRESS) {
// Ignore the compound "full name" field type. We are only interested in
// comparing the constituent parts. For example, if |this| has a middle
// name saved, but |profile| lacks one, |profile| could still be a subset
- // of |this|.
+ // of |this|. Likewise, ignore the compound "street address" type, as we
+ // are only interested in matching line-by-line.
continue;
} else if (AutofillType(*it).group() == PHONE_HOME) {
// Phone numbers should be canonicalized prior to being compared.
@@ -500,6 +505,12 @@ void AutofillProfile::OverwriteWithOrAddTo(const AutofillProfile& profile,
// first name, last name).
CollapseCompoundFieldTypes(&field_types);
+ // TODO(isherman): Revisit this decision in the context of i18n and storing
+ // full addresses rather than storing 1-to-2 lines of an address.
+ // For addresses, do the opposite: transfer individual address lines, rather
+ // than full addresses.
+ field_types.erase(ADDRESS_HOME_STREET_ADDRESS);
+
for (ServerFieldTypeSet::const_iterator iter = field_types.begin();
iter != field_types.end(); ++iter) {
if (AutofillProfile::SupportsMultiValue(*iter)) {
@@ -818,12 +829,16 @@ std::ostream& operator<<(std::ostream& os, const AutofillProfile& profile) {
<< " "
<< UTF16ToUTF8(profile.GetRawInfo(ADDRESS_HOME_LINE2))
<< " "
+ << UTF16ToUTF8(profile.GetRawInfo(ADDRESS_HOME_DEPENDENT_LOCALITY))
+ << " "
<< UTF16ToUTF8(profile.GetRawInfo(ADDRESS_HOME_CITY))
<< " "
<< UTF16ToUTF8(profile.GetRawInfo(ADDRESS_HOME_STATE))
<< " "
<< UTF16ToUTF8(profile.GetRawInfo(ADDRESS_HOME_ZIP))
<< " "
+ << UTF16ToUTF8(profile.GetRawInfo(ADDRESS_HOME_SORTING_CODE))
+ << " "
<< UTF16ToUTF8(profile.GetRawInfo(ADDRESS_HOME_COUNTRY))
<< " "
<< UTF16ToUTF8(MultiString(profile, PHONE_HOME_WHOLE_NUMBER));
diff --git a/components/autofill/core/browser/autofill_profile_unittest.cc b/components/autofill/core/browser/autofill_profile_unittest.cc
index 6ae267d..194dc3a 100644
--- a/components/autofill/core/browser/autofill_profile_unittest.cc
+++ b/components/autofill/core/browser/autofill_profile_unittest.cc
@@ -807,4 +807,45 @@ TEST(AutofillProfileTest, IsPresentButInvalid) {
EXPECT_FALSE(profile.IsPresentButInvalid(PHONE_HOME_WHOLE_NUMBER));
}
+TEST(AutofillProfileTest, SetRawInfoPreservesLineBreaks) {
+ AutofillProfile profile(base::GenerateGUID(), "https://www.example.com/");
+
+ profile.SetRawInfo(ADDRESS_HOME_STREET_ADDRESS,
+ ASCIIToUTF16("123 Super St.\n"
+ "Apt. #42"));
+ EXPECT_EQ(ASCIIToUTF16("123 Super St.\n"
+ "Apt. #42"),
+ profile.GetRawInfo(ADDRESS_HOME_STREET_ADDRESS));
+}
+
+TEST(AutofillProfileTest, SetInfoPreservesLineBreaks) {
+ AutofillProfile profile(base::GenerateGUID(), "https://www.example.com/");
+
+ profile.SetInfo(AutofillType(ADDRESS_HOME_STREET_ADDRESS),
+ ASCIIToUTF16("123 Super St.\n"
+ "Apt. #42"),
+ "en-US");
+ EXPECT_EQ(ASCIIToUTF16("123 Super St.\n"
+ "Apt. #42"),
+ profile.GetRawInfo(ADDRESS_HOME_STREET_ADDRESS));
+}
+
+TEST(AutofillProfileTest, SetRawInfoDoesntTrimWhitespace) {
+ AutofillProfile profile(base::GenerateGUID(), "https://www.example.com/");
+
+ profile.SetRawInfo(EMAIL_ADDRESS, ASCIIToUTF16("\tuser@example.com "));
+ EXPECT_EQ(ASCIIToUTF16("\tuser@example.com "),
+ profile.GetRawInfo(EMAIL_ADDRESS));
+}
+
+TEST(AutofillProfileTest, SetInfoTrimsWhitespace) {
+ AutofillProfile profile(base::GenerateGUID(), "https://www.example.com/");
+
+ profile.SetInfo(AutofillType(EMAIL_ADDRESS),
+ ASCIIToUTF16("\tuser@example.com "),
+ "en-US");
+ EXPECT_EQ(ASCIIToUTF16("user@example.com"),
+ profile.GetRawInfo(EMAIL_ADDRESS));
+}
+
} // namespace autofill
diff --git a/components/autofill/core/browser/personal_data_manager.cc b/components/autofill/core/browser/personal_data_manager.cc
index 284a09f..28d92d4 100644
--- a/components/autofill/core/browser/personal_data_manager.cc
+++ b/components/autofill/core/browser/personal_data_manager.cc
@@ -248,7 +248,8 @@ bool PersonalDataManager::ImportFormData(
for (size_t i = 0; i < form.field_count(); ++i) {
const AutofillField* field = form.field(i);
- base::string16 value = CollapseWhitespace(field->value, false);
+ base::string16 value;
+ TrimWhitespace(field->value, TRIM_ALL, &value);
// If we don't know the type of the field, or the user hasn't entered any
// information into the field, then skip it.
diff --git a/components/autofill/core/browser/personal_data_manager_unittest.cc b/components/autofill/core/browser/personal_data_manager_unittest.cc
index d45cfd8..4223b60c 100644
--- a/components/autofill/core/browser/personal_data_manager_unittest.cc
+++ b/components/autofill/core/browser/personal_data_manager_unittest.cc
@@ -879,6 +879,53 @@ TEST_F(PersonalDataManagerTest, ImportPhoneNumberSplitAcrossMultipleFields) {
EXPECT_EQ(0, expected.Compare(*results[0]));
}
+TEST_F(PersonalDataManagerTest, ImportFormDataMultilineAddress) {
+ FormData form;
+ FormFieldData field;
+ test::CreateTestFormField(
+ "First name:", "first_name", "George", "text", &field);
+ form.fields.push_back(field);
+ test::CreateTestFormField(
+ "Last name:", "last_name", "Washington", "text", &field);
+ form.fields.push_back(field);
+ test::CreateTestFormField(
+ "Email:", "email", "theprez@gmail.com", "text", &field);
+ form.fields.push_back(field);
+ test::CreateTestFormField(
+ "Address:",
+ "street_address",
+ "21 Laussat St\n"
+ "Apt. #42",
+ "textarea",
+ &field);
+ form.fields.push_back(field);
+ test::CreateTestFormField("City:", "city", "San Francisco", "text", &field);
+ form.fields.push_back(field);
+ test::CreateTestFormField("State:", "state", "California", "text", &field);
+ form.fields.push_back(field);
+ test::CreateTestFormField("Zip:", "zip", "94102", "text", &field);
+ form.fields.push_back(field);
+ FormStructure form_structure(form);
+ form_structure.DetermineHeuristicTypes(TestAutofillMetrics());
+ scoped_ptr<CreditCard> imported_credit_card;
+ EXPECT_TRUE(personal_data_->ImportFormData(form_structure,
+ &imported_credit_card));
+ ASSERT_FALSE(imported_credit_card);
+
+ // Verify that the web database has been updated and the notification sent.
+ EXPECT_CALL(personal_data_observer_,
+ OnPersonalDataChanged()).WillOnce(QuitUIMessageLoop());
+ base::MessageLoop::current()->Run();
+
+ AutofillProfile expected(base::GenerateGUID(), "https://www.example.com");
+ test::SetProfileInfo(&expected, "George", NULL,
+ "Washington", "theprez@gmail.com", NULL, "21 Laussat St", "Apt. #42",
+ "San Francisco", "California", "94102", NULL, NULL);
+ const std::vector<AutofillProfile*>& results = personal_data_->GetProfiles();
+ ASSERT_EQ(1U, results.size());
+ EXPECT_EQ(0, expected.Compare(*results[0]));
+}
+
TEST_F(PersonalDataManagerTest, SetUniqueCreditCardLabels) {
CreditCard credit_card0(base::GenerateGUID(), "https://www.example.com");
credit_card0.SetRawInfo(CREDIT_CARD_NAME, ASCIIToUTF16("John"));
@@ -2164,12 +2211,13 @@ TEST_F(PersonalDataManagerTest, GetNonEmptyTypes) {
base::MessageLoop::current()->Run();
personal_data_->GetNonEmptyTypes(&non_empty_types);
- EXPECT_EQ(14U, non_empty_types.size());
+ EXPECT_EQ(15U, non_empty_types.size());
EXPECT_TRUE(non_empty_types.count(NAME_FIRST));
EXPECT_TRUE(non_empty_types.count(NAME_LAST));
EXPECT_TRUE(non_empty_types.count(NAME_FULL));
EXPECT_TRUE(non_empty_types.count(EMAIL_ADDRESS));
EXPECT_TRUE(non_empty_types.count(ADDRESS_HOME_LINE1));
+ EXPECT_TRUE(non_empty_types.count(ADDRESS_HOME_STREET_ADDRESS));
EXPECT_TRUE(non_empty_types.count(ADDRESS_HOME_CITY));
EXPECT_TRUE(non_empty_types.count(ADDRESS_HOME_STATE));
EXPECT_TRUE(non_empty_types.count(ADDRESS_HOME_ZIP));
@@ -2202,7 +2250,7 @@ TEST_F(PersonalDataManagerTest, GetNonEmptyTypes) {
base::MessageLoop::current()->Run();
personal_data_->GetNonEmptyTypes(&non_empty_types);
- EXPECT_EQ(18U, non_empty_types.size());
+ EXPECT_EQ(19U, non_empty_types.size());
EXPECT_TRUE(non_empty_types.count(NAME_FIRST));
EXPECT_TRUE(non_empty_types.count(NAME_MIDDLE));
EXPECT_TRUE(non_empty_types.count(NAME_MIDDLE_INITIAL));
@@ -2212,6 +2260,7 @@ TEST_F(PersonalDataManagerTest, GetNonEmptyTypes) {
EXPECT_TRUE(non_empty_types.count(COMPANY_NAME));
EXPECT_TRUE(non_empty_types.count(ADDRESS_HOME_LINE1));
EXPECT_TRUE(non_empty_types.count(ADDRESS_HOME_LINE2));
+ EXPECT_TRUE(non_empty_types.count(ADDRESS_HOME_STREET_ADDRESS));
EXPECT_TRUE(non_empty_types.count(ADDRESS_HOME_CITY));
EXPECT_TRUE(non_empty_types.count(ADDRESS_HOME_STATE));
EXPECT_TRUE(non_empty_types.count(ADDRESS_HOME_ZIP));
@@ -2235,7 +2284,7 @@ TEST_F(PersonalDataManagerTest, GetNonEmptyTypes) {
base::MessageLoop::current()->Run();
personal_data_->GetNonEmptyTypes(&non_empty_types);
- EXPECT_EQ(26U, non_empty_types.size());
+ EXPECT_EQ(27U, non_empty_types.size());
EXPECT_TRUE(non_empty_types.count(NAME_FIRST));
EXPECT_TRUE(non_empty_types.count(NAME_MIDDLE));
EXPECT_TRUE(non_empty_types.count(NAME_MIDDLE_INITIAL));
@@ -2245,6 +2294,7 @@ TEST_F(PersonalDataManagerTest, GetNonEmptyTypes) {
EXPECT_TRUE(non_empty_types.count(COMPANY_NAME));
EXPECT_TRUE(non_empty_types.count(ADDRESS_HOME_LINE1));
EXPECT_TRUE(non_empty_types.count(ADDRESS_HOME_LINE2));
+ EXPECT_TRUE(non_empty_types.count(ADDRESS_HOME_STREET_ADDRESS));
EXPECT_TRUE(non_empty_types.count(ADDRESS_HOME_CITY));
EXPECT_TRUE(non_empty_types.count(ADDRESS_HOME_STATE));
EXPECT_TRUE(non_empty_types.count(ADDRESS_HOME_ZIP));
diff --git a/components/autofill/core/browser/webdata/autofill_table.cc b/components/autofill/core/browser/webdata/autofill_table.cc
index 1f61bb3..a57ac0d 100644
--- a/components/autofill/core/browser/webdata/autofill_table.cc
+++ b/components/autofill/core/browser/webdata/autofill_table.cc
@@ -15,6 +15,7 @@
#include "base/i18n/case_conversion.h"
#include "base/logging.h"
#include "base/strings/string_number_conversions.h"
+#include "base/strings/utf_string_conversions.h"
#include "base/time/time.h"
#include "base/tuple.h"
#include "components/autofill/core/browser/autofill_country.h"
@@ -40,14 +41,16 @@ 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) {
+// Returns the |data_model|'s value corresponding to the |type|, trimmed to the
+// maximum length that can be stored in a column of the Autofill database.
+base::string16 GetInfo(const AutofillDataModel& data_model,
+ ServerFieldType type) {
+ base::string16 data = data_model.GetRawInfo(type);
if (data.size() > AutofillTable::kMaxDataLength)
return data.substr(0, AutofillTable::kMaxDataLength);
@@ -55,93 +58,93 @@ base::string16 LimitDataSize(const base::string16& data) {
}
void BindAutofillProfileToStatement(const AutofillProfile& profile,
- sql::Statement* s,
- const std::string& app_locale) {
+ sql::Statement* s) {
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(AutofillType(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));
+ int index = 0;
+ s->BindString(index++, profile.guid());
+
+ s->BindString16(index++, GetInfo(profile, COMPANY_NAME));
+ s->BindString16(index++, GetInfo(profile, ADDRESS_HOME_STREET_ADDRESS));
+ s->BindString16(index++, GetInfo(profile, ADDRESS_HOME_DEPENDENT_LOCALITY));
+ s->BindString16(index++, GetInfo(profile, ADDRESS_HOME_CITY));
+ s->BindString16(index++, GetInfo(profile, ADDRESS_HOME_STATE));
+ s->BindString16(index++, GetInfo(profile, ADDRESS_HOME_ZIP));
+ s->BindString16(index++, GetInfo(profile, ADDRESS_HOME_SORTING_CODE));
+ s->BindString16(index++, GetInfo(profile, ADDRESS_HOME_COUNTRY));
+ s->BindInt64(index++, Time::Now().ToTimeT());
+ s->BindString(index++, profile.origin());
+}
+
+scoped_ptr<AutofillProfile> AutofillProfileFromStatement(
+ const sql::Statement& s) {
+ 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(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));
+ profile->SetRawInfo(COMPANY_NAME, s.ColumnString16(index++));
+ profile->SetRawInfo(ADDRESS_HOME_STREET_ADDRESS, s.ColumnString16(index++));
+ profile->SetRawInfo(ADDRESS_HOME_DEPENDENT_LOCALITY,
+ 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->SetRawInfo(ADDRESS_HOME_SORTING_CODE, s.ColumnString16(index++));
+ profile->SetRawInfo(ADDRESS_HOME_COUNTRY, s.ColumnString16(index++));
// Intentionally skip column 9, which stores the profile's modification date.
- profile->set_origin(s.ColumnString(10));
+ index++;
+ profile->set_origin(s.ColumnString(index++));
- return profile;
+ return profile.Pass();
}
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);
+ int index = 0;
+ s->BindString(index++, credit_card.guid());
+
+ s->BindString16(index++, GetInfo(credit_card, CREDIT_CARD_NAME));
+ s->BindString16(index++, GetInfo(credit_card, CREDIT_CARD_EXP_MONTH));
+ s->BindString16(index++, GetInfo(credit_card, CREDIT_CARD_EXP_4_DIGIT_YEAR));
+
std::string encrypted_data;
- Encryptor::EncryptString16(text, &encrypted_data);
- s->BindBlob(4, encrypted_data.data(),
+ Encryptor::EncryptString16(credit_card.GetRawInfo(CREDIT_CARD_NUMBER),
+ &encrypted_data);
+ s->BindBlob(index++, encrypted_data.data(),
static_cast<int>(encrypted_data.length()));
- s->BindInt64(5, Time::Now().ToTimeT());
- s->BindString(6, credit_card.origin());
+
+ s->BindInt64(index++, Time::Now().ToTimeT());
+ s->BindString(index++, credit_card.origin());
}
-CreditCard* CreditCardFromStatement(const sql::Statement& s) {
- CreditCard* credit_card = new CreditCard;
+scoped_ptr<CreditCard> CreditCardFromStatement(const sql::Statement& s) {
+ scoped_ptr<CreditCard> credit_card(new CreditCard);
- credit_card->set_guid(s.ColumnString(0));
+ int index = 0;
+ credit_card->set_guid(s.ColumnString(index++));
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);
+ credit_card->SetRawInfo(CREDIT_CARD_NAME, s.ColumnString16(index++));
+ credit_card->SetRawInfo(CREDIT_CARD_EXP_MONTH, s.ColumnString16(index++));
+ credit_card->SetRawInfo(CREDIT_CARD_EXP_4_DIGIT_YEAR,
+ s.ColumnString16(index++));
+ int encrypted_number_len = s.ColumnByteLength(index);
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);
+ memcpy(&encrypted_number[0], s.ColumnBlob(index++), encrypted_number_len);
Encryptor::DecryptString16(encrypted_number, &credit_card_number);
+ } else {
+ index++;
}
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));
+ index++;
+ credit_card->set_origin(s.ColumnString(index++));
- return credit_card;
+ return credit_card.Pass();
}
bool AddAutofillProfileNamesToProfile(sql::Connection* db,
@@ -199,13 +202,10 @@ bool AddAutofillProfileEmailsToProfile(sql::Connection* db,
bool AddAutofillProfilePhonesToProfile(sql::Connection* db,
AutofillProfile* profile) {
sql::Statement s(db->GetUniqueStatement(
- "SELECT guid, type, number "
+ "SELECT guid, number "
"FROM autofill_profile_phones "
- "WHERE guid=? AND type=?"));
-
- // Value used to be either [(0, phone), (1, fax)] but fax has been removed.
+ "WHERE guid=?"));
s.BindString(0, profile->guid());
- s.BindInt(1, 0);
if (!s.is_valid())
return false;
@@ -213,7 +213,7 @@ bool AddAutofillProfilePhonesToProfile(sql::Connection* db,
std::vector<base::string16> numbers;
while (s.Step()) {
DCHECK_EQ(profile->guid(), s.ColumnString(0));
- numbers.push_back(s.ColumnString16(2));
+ numbers.push_back(s.ColumnString16(1));
}
if (!s.Succeeded())
return false;
@@ -280,12 +280,10 @@ bool AddAutofillProfilePhones(const AutofillProfile& profile,
// Add the new number.
sql::Statement s(db->GetUniqueStatement(
"INSERT INTO autofill_profile_phones"
- " (guid, type, number) "
- "VALUES (?,?,?)"));
+ " (guid, 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]);
+ s.BindString16(1, numbers[i]);
if (!s.Run())
return false;
@@ -422,6 +420,9 @@ bool AutofillTable::MigrateToVersion(int version,
// 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();
}
return true;
}
@@ -964,10 +965,10 @@ bool AutofillTable::AddAutofillProfile(const AutofillProfile& profile) {
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)"
+ "(guid, company_name, street_address, dependent_locality, city, state,"
+ " zipcode, sorting_code, country_code, date_modified, origin)"
"VALUES (?,?,?,?,?,?,?,?,?,?,?)"));
- BindAutofillProfileToStatement(profile, &s, app_locale_);
+ BindAutofillProfileToStatement(profile, &s);
if (!s.Run())
return false;
@@ -980,8 +981,8 @@ bool AutofillTable::GetAutofillProfile(const std::string& guid,
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 "
+ "SELECT guid, company_name, street_address, dependent_locality, city,"
+ " state, zipcode, sorting_code, country_code, date_modified, origin "
"FROM autofill_profiles "
"WHERE guid=?"));
s.BindString(0, guid);
@@ -989,7 +990,7 @@ bool AutofillTable::GetAutofillProfile(const std::string& guid,
if (!s.Step())
return false;
- scoped_ptr<AutofillProfile> p(AutofillProfileFromStatement(s, app_locale_));
+ scoped_ptr<AutofillProfile> p = AutofillProfileFromStatement(s);
// Get associated name info.
AddAutofillProfileNamesToProfile(db_, p.get());
@@ -1044,11 +1045,11 @@ bool AutofillTable::UpdateAutofillProfile(const AutofillProfile& profile) {
sql::Statement s(db_->GetUniqueStatement(
"UPDATE autofill_profiles "
- "SET guid=?, company_name=?, address_line_1=?, address_line_2=?, "
- " city=?, state=?, zipcode=?, country=?, country_code=?, "
+ "SET guid=?, company_name=?, street_address=?, dependent_locality=?, "
+ " city=?, state=?, zipcode=?, sorting_code=?, country_code=?, "
" date_modified=?, origin=? "
"WHERE guid=?"));
- BindAutofillProfileToStatement(profile, &s, app_locale_);
+ BindAutofillProfileToStatement(profile, &s);
s.BindString(11, profile.guid());
bool result = s.Run();
@@ -1139,7 +1140,7 @@ bool AutofillTable::GetCreditCard(const std::string& guid,
if (!s.Step())
return false;
- *credit_card = CreditCardFromStatement(s);
+ *credit_card = CreditCardFromStatement(s).release();
return true;
}
@@ -1457,12 +1458,12 @@ bool AutofillTable::InitProfilesTable() {
if (!db_->Execute("CREATE TABLE autofill_profiles ( "
"guid VARCHAR PRIMARY KEY, "
"company_name VARCHAR, "
- "address_line_1 VARCHAR, "
- "address_line_2 VARCHAR, "
+ "street_address VARCHAR, "
+ "dependent_locality VARCHAR, "
"city VARCHAR, "
"state VARCHAR, "
"zipcode VARCHAR, "
- "country VARCHAR, "
+ "sorting_code VARCHAR, "
"country_code VARCHAR, "
"date_modified INTEGER NOT NULL DEFAULT 0, "
"origin VARCHAR DEFAULT '')")) {
@@ -1503,7 +1504,6 @@ 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;
@@ -1915,38 +1915,40 @@ bool AutofillTable::MigrateToVersion33ProfilesBasedOnFirstName() {
while (s.Step()) {
AutofillProfile profile;
- profile.set_guid(s.ColumnString(0));
+ int index = 0;
+ profile.set_guid(s.ColumnString(index++));
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(AutofillType(ADDRESS_HOME_COUNTRY), s.ColumnString16(11),
- app_locale_);
- profile.SetRawInfo(PHONE_HOME_WHOLE_NUMBER, s.ColumnString16(12));
- int64 date_modified = s.ColumnInt64(13);
+ 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 (?,?,?,?,?,?,?,?,?)"));
- 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);
+ 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;
@@ -2069,20 +2071,23 @@ bool AutofillTable::MigrateToVersion37MergeAndCullOlderProfiles() {
return false;
scoped_ptr<AutofillProfile> profile(new AutofillProfile);
- profile->set_guid(s.ColumnString(0));
+ int index = 0;
+ profile->set_guid(s.ColumnString(index++));
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));
+ 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.
- profile->SetRawInfo(ADDRESS_HOME_COUNTRY, s.ColumnString16(8));
+ index++;
+ profile->SetRawInfo(ADDRESS_HOME_COUNTRY, s.ColumnString16(index++));
// Intentionally skip column 9, which stores the profile's modification
// date.
- profile->set_origin(s.ColumnString(10));
+ index++;
+ profile->set_origin(s.ColumnString(index++));
// Get associated name info.
AddAutofillProfileNamesToProfile(db_, profile.get());
@@ -2138,24 +2143,17 @@ bool AutofillTable::MigrateToVersion37MergeAndCullOlderProfiles() {
"(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(AutofillType(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);
+ 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;
@@ -2189,4 +2187,108 @@ bool AutofillTable::MigrateToVersion51AddOriginColumn() {
return transaction.Commit();
}
+bool AutofillTable::MigrateToVersion54AddI18nFieldsAndRemoveDeprecatedFields() {
+ sql::Transaction transaction(db_);
+ if (!transaction.Begin())
+ return false;
+
+ // Test the existence of the |address_line_1| column as an indication that a
+ // migration is needed. It is possible that the new |autofill_profile_phones|
+ // schema is in place because the table was newly created when migrating from
+ // a pre-version-23 database.
+ if (db_->DoesColumnExist("autofill_profiles", "address_line_1")) {
+ // Create a temporary copy of the autofill_profiles table in the (newer)
+ // version 54 format. This table
+ // (a) adds columns for street_address, dependent_locality, and
+ // sorting_code,
+ // (b) removes the address_line_1 and address_line_2 columns, which are
+ // replaced by the street_address column, and
+ // (c) removes the country column, which was long deprecated.
+ if (db_->DoesTableExist("autofill_profiles_temp") ||
+ !db_->Execute("CREATE TABLE autofill_profiles_temp ( "
+ "guid VARCHAR PRIMARY KEY, "
+ "company_name VARCHAR, "
+ "street_address VARCHAR, "
+ "dependent_locality VARCHAR, "
+ "city VARCHAR, "
+ "state VARCHAR, "
+ "zipcode VARCHAR, "
+ "sorting_code VARCHAR, "
+ "country_code VARCHAR, "
+ "date_modified INTEGER NOT NULL DEFAULT 0, "
+ "origin VARCHAR DEFAULT '')")) {
+ return false;
+ }
+
+ // Copy over the data from the autofill_profiles table, taking care to merge
+ // the address lines 1 and 2 into the new street_address column.
+ if (!db_->Execute("INSERT INTO autofill_profiles_temp "
+ "SELECT guid, company_name, '', '', city, state, zipcode,"
+ " '', country_code, date_modified, origin "
+ "FROM autofill_profiles")) {
+ return false;
+ }
+ sql::Statement s(db_->GetUniqueStatement(
+ "SELECT guid, address_line_1, address_line_2 FROM autofill_profiles"));
+ while (s.Step()) {
+ std::string guid = s.ColumnString(0);
+ base::string16 line1 = s.ColumnString16(1);
+ base::string16 line2 = s.ColumnString16(2);
+ base::string16 street_address = line1;
+ if (!line2.empty())
+ street_address += ASCIIToUTF16("\n") + line2;
+
+ sql::Statement s_update(db_->GetUniqueStatement(
+ "UPDATE autofill_profiles_temp SET street_address=? WHERE guid=?"));
+ s_update.BindString16(0, street_address);
+ s_update.BindString(1, guid);
+ if (!s_update.Run())
+ return false;
+ }
+ if (!s.Succeeded())
+ return false;
+
+ // Delete the existing (version 53) table and replace it with the contents
+ // of the temporary table.
+ if (!db_->Execute("DROP TABLE autofill_profiles") ||
+ !db_->Execute("ALTER TABLE autofill_profiles_temp "
+ "RENAME TO autofill_profiles")) {
+ return false;
+ }
+ }
+
+ // Test the existence of the |type| column as an indication that a migration
+ // is needed. It is possible that the new |autofill_profile_phones| schema is
+ // in place because the table was newly created when migrating from a
+ // pre-version-23 database.
+ if (db_->DoesColumnExist("autofill_profile_phones", "type")) {
+ // Create a temporary copy of the autofill_profile_phones table in the
+ // (newer) version 54 format. This table removes the deprecated |type|
+ // column.
+ if (db_->DoesTableExist("autofill_profile_phones_temp") ||
+ !db_->Execute("CREATE TABLE autofill_profile_phones_temp ( "
+ "guid VARCHAR, "
+ "number VARCHAR)")) {
+ return false;
+ }
+
+ // Copy over the data from the autofill_profile_phones table.
+ if (!db_->Execute("INSERT INTO autofill_profile_phones_temp "
+ "SELECT guid, number FROM autofill_profile_phones")) {
+ return false;
+ }
+
+ // Delete the existing (version 53) table and replace it with the contents
+ // of the temporary table.
+ if (!db_->Execute("DROP TABLE autofill_profile_phones"))
+ return false;
+ if (!db_->Execute("ALTER TABLE autofill_profile_phones_temp "
+ "RENAME TO autofill_profile_phones")) {
+ return false;
+ }
+ }
+
+ return transaction.Commit();
+}
+
} // namespace autofill
diff --git a/components/autofill/core/browser/webdata/autofill_table.h b/components/autofill/core/browser/webdata/autofill_table.h
index 52012e2..bcacdcd 100644
--- a/components/autofill/core/browser/webdata/autofill_table.h
+++ b/components/autofill/core/browser/webdata/autofill_table.h
@@ -35,17 +35,17 @@ struct FormFieldData;
// Note: The database stores time in seconds, UTC.
//
// autofill
-// name The name of the input as specified in the html.
-// value The literal contents of the text field.
-// value_lower The contents of the text field made lower_case.
-// pair_id An ID number unique to the row in the table.
-// count How many times the user has entered the string |value|
-// in a field of name |name|.
+// name The name of the input as specified in the html.
+// value The literal contents of the text field.
+// value_lower The contents of the text field made lower_case.
+// pair_id An ID number unique to the row in the table.
+// count How many times the user has entered the string |value|
+// in a field of name |name|.
//
-// autofill_dates This table associates a row to each separate time the
-// user submits a form containing a certain name/value
-// pair. The |pair_id| should match the |pair_id| field
-// in the appropriate row of the autofill table.
+// autofill_dates This table associates a row to each separate time the
+// user submits a form containing a certain name/value
+// pair. The |pair_id| should match the |pair_id| field
+// in the appropriate row of the autofill table.
// pair_id
// date_created
//
@@ -56,13 +56,18 @@ struct FormFieldData;
// guid A guid string to uniquely identify the profile.
// Added in version 31.
// company_name
-// address_line_1
-// address_line_2
+// street_address The combined lines of the street address.
+// Added in version 54.
+// dependent_locality
+// A sub-classification beneath the city, e.g. an
+// inner-city district or suburb. Added in version 54.
// city
// state
// zipcode
-// country The country name. Deprecated, should be removed once
-// the stable channel reaches version 11.
+// sorting_code Similar to the zipcode column, but used for businesses
+// or organizations that might not be geographically
+// contiguous. The canonical example is CEDEX in France.
+// Added in version 54.
// country_code
// date_modified The date on which this profile was last modified.
// Added in version 30.
@@ -91,12 +96,8 @@ struct FormFieldData;
// This table contains the multi-valued phone fields
// associated with a profile.
//
-// guid The guid string that identifies the profile to which
-// the phone number belongs.
-// type An integer constant designating either phone type of the
-// number.
-// TODO(jhawkins): Remove the type column and migrate the
-// database.
+// guid The guid string that identifies the profile to which the
+// phone number belongs.
// number
//
// autofill_profiles_trash
@@ -115,7 +116,8 @@ struct FormFieldData;
// name_on_card
// expiration_month
// expiration_year
-// card_number_encrypted Stores encrypted credit card number.
+// card_number_encrypted
+// Stores encrypted credit card number.
// date_modified The date on which this entry was last modified.
// Added in version 30.
// origin The domain of origin for this profile.
@@ -320,6 +322,7 @@ class AutofillTable : public WebDatabaseTable {
bool MigrateToVersion35GreatBritainCountryCodes();
bool MigrateToVersion37MergeAndCullOlderProfiles();
bool MigrateToVersion51AddOriginColumn();
+ bool MigrateToVersion54AddI18nFieldsAndRemoveDeprecatedFields();
// Max data length saved in the table;
static const size_t kMaxDataLength;
diff --git a/components/autofill/core/browser/webdata/autofill_table_unittest.cc b/components/autofill/core/browser/webdata/autofill_table_unittest.cc
index 982c325..241d393 100644
--- a/components/autofill/core/browser/webdata/autofill_table_unittest.cc
+++ b/components/autofill/core/browser/webdata/autofill_table_unittest.cc
@@ -524,9 +524,12 @@ TEST_F(AutofillTableTest, AutofillProfile) {
home_profile.SetRawInfo(COMPANY_NAME, ASCIIToUTF16("Google"));
home_profile.SetRawInfo(ADDRESS_HOME_LINE1, ASCIIToUTF16("1234 Apple Way"));
home_profile.SetRawInfo(ADDRESS_HOME_LINE2, ASCIIToUTF16("unit 5"));
+ home_profile.SetRawInfo(ADDRESS_HOME_DEPENDENT_LOCALITY,
+ ASCIIToUTF16("Beverly Hills"));
home_profile.SetRawInfo(ADDRESS_HOME_CITY, ASCIIToUTF16("Los Angeles"));
home_profile.SetRawInfo(ADDRESS_HOME_STATE, ASCIIToUTF16("CA"));
home_profile.SetRawInfo(ADDRESS_HOME_ZIP, ASCIIToUTF16("90025"));
+ home_profile.SetRawInfo(ADDRESS_HOME_SORTING_CODE, ASCIIToUTF16("MAGIC ###"));
home_profile.SetRawInfo(ADDRESS_HOME_COUNTRY, ASCIIToUTF16("US"));
home_profile.SetRawInfo(PHONE_HOME_WHOLE_NUMBER, ASCIIToUTF16("18181234567"));
@@ -602,9 +605,12 @@ TEST_F(AutofillTableTest, AutofillProfile) {
billing_profile.SetRawInfo(COMPANY_NAME, ASCIIToUTF16("Indy"));
billing_profile.SetRawInfo(ADDRESS_HOME_LINE1, ASCIIToUTF16("Open Road"));
billing_profile.SetRawInfo(ADDRESS_HOME_LINE2, ASCIIToUTF16("Route 66"));
+ billing_profile.SetRawInfo(ADDRESS_HOME_DEPENDENT_LOCALITY,
+ ASCIIToUTF16("District 9"));
billing_profile.SetRawInfo(ADDRESS_HOME_CITY, ASCIIToUTF16("NFA"));
billing_profile.SetRawInfo(ADDRESS_HOME_STATE, ASCIIToUTF16("NY"));
billing_profile.SetRawInfo(ADDRESS_HOME_ZIP, ASCIIToUTF16("10011"));
+ billing_profile.SetRawInfo(ADDRESS_HOME_SORTING_CODE, ASCIIToUTF16("123456"));
billing_profile.SetRawInfo(ADDRESS_HOME_COUNTRY, ASCIIToUTF16("US"));
billing_profile.SetRawInfo(PHONE_HOME_WHOLE_NUMBER,
ASCIIToUTF16("18181230000"));
diff --git a/components/test/data/web_database/version_53.sql b/components/test/data/web_database/version_53.sql
new file mode 100644
index 0000000..751aeed
--- /dev/null
+++ b/components/test/data/web_database/version_53.sql
@@ -0,0 +1,50 @@
+PRAGMA foreign_keys=OFF;
+BEGIN TRANSACTION;
+CREATE TABLE meta(key LONGVARCHAR NOT NULL UNIQUE PRIMARY KEY, value LONGVARCHAR);
+INSERT INTO "meta" VALUES('version','53');
+INSERT INTO "meta" VALUES('last_compatible_version','48');
+INSERT INTO "meta" VALUES('Builtin Keyword Version','67');
+INSERT INTO "meta" VALUES('Default Search Provider ID','2');
+CREATE TABLE keywords (id INTEGER PRIMARY KEY,short_name VARCHAR NOT NULL,keyword VARCHAR NOT NULL,favicon_url VARCHAR NOT NULL,url VARCHAR NOT NULL,safe_for_autoreplace INTEGER,originating_url VARCHAR,date_created INTEGER DEFAULT 0,usage_count INTEGER DEFAULT 0,input_encodings VARCHAR,show_in_default_list INTEGER,suggest_url VARCHAR,prepopulate_id INTEGER DEFAULT 0,created_by_policy INTEGER DEFAULT 0,instant_url VARCHAR,last_modified INTEGER DEFAULT 0,sync_guid VARCHAR,alternate_urls VARCHAR,search_terms_replacement_key VARCHAR,image_url VARCHAR,search_url_post_params VARCHAR,suggest_url_post_params VARCHAR,instant_url_post_params VARCHAR,image_url_post_params VARCHAR,new_tab_url VARCHAR);
+INSERT INTO "keywords" VALUES(2,'Google','google.com','http://www.google.com/favicon.ico','{google:baseURL}search?q={searchTerms}&{google:RLZ}{google:originalQueryForSuggestion}{google:assistedQueryStats}{google:searchFieldtrialParameter}{google:bookmarkBarPinned}{google:searchClient}{google:sourceId}{google:instantExtendedEnabledParameter}{google:omniboxStartMarginParameter}ie={inputEncoding}',1,'',0,0,'UTF-8',1,'{google:baseSuggestURL}search?{google:searchFieldtrialParameter}client={google:suggestClient}&xssi=t&q={searchTerms}&{google:cursorPosition}{google:zeroPrefixUrl}{google:pageClassification}sugkey={google:suggestAPIKeyParameter}',1,0,'{google:baseURL}webhp?sourceid=chrome-instant&{google:RLZ}{google:forceInstantResults}{google:instantExtendedEnabledParameter}{google:ntpIsThemedParameter}{google:omniboxStartMarginParameter}ie={inputEncoding}',0,'1D955A9B-6F30-D3FF-5F5C-002E40BDF482','["{google:baseURL}#q={searchTerms}","{google:baseURL}search#q={searchTerms}","{google:baseURL}webhp#q={searchTerms}"]','espv','{google:baseURL}searchbyimage/upload','','','','encoded_image={google:imageThumbnail},image_url={google:imageURL},sbisrc={google:imageSearchSource},original_width={google:imageOriginalWidth},original_height={google:imageOriginalHeight}','{google:baseURL}_/chrome/newtab?{google:RLZ}{google:instantExtendedEnabledParameter}{google:ntpIsThemedParameter}ie={inputEncoding}');
+INSERT INTO "keywords" VALUES(3,'Bing','bing.com','http://www.bing.com/s/wlflag.ico','http://www.bing.com/search?setmkt=en-US&q={searchTerms}',1,'',0,0,'UTF-8',1,'http://api.bing.com/osjson.aspx?query={searchTerms}&language={language}',3,0,'',0,'E88DEF4C-20E0-5DD7-6A71-20058C05BF09','[]','','','','','','','');
+INSERT INTO "keywords" VALUES(4,'Yahoo!','yahoo.com','http://search.yahoo.com/favicon.ico','http://search.yahoo.com/search?ei={inputEncoding}&fr=crmas&p={searchTerms}',1,'',0,0,'UTF-8',1,'http://ff.search.yahoo.com/gossip?output=fxjson&command={searchTerms}',2,0,'',0,'F2F457FC-8B48-47A4-7D7C-8001AB91D1BD','[]','','','','','','','');
+INSERT INTO "keywords" VALUES(5,'AOL','aol.com','http://search.aol.com/favicon.ico','http://search.aol.com/aol/search?query={searchTerms}',1,'',0,0,'UTF-8',1,'http://autocomplete.search.aol.com/autocomplete/get?output=json&it=&q={searchTerms}',35,0,'',0,'F858668C-43E0-5CF3-7D05-EDE8DBF40106','[]','','','','','','','');
+INSERT INTO "keywords" VALUES(6,'Ask','ask.com','http://sp.ask.com/sh/i/a16/favicon/favicon.ico','http://www.ask.com/web?q={searchTerms}',1,'',0,0,'UTF-8',1,'http://ss.ask.com/query?q={searchTerms}&li=ff',4,0,'',0,'00268D17-EC55-D173-84F3-48D9B862E8E1','[]','','','','','','','');
+CREATE TABLE token_service (service VARCHAR PRIMARY KEY NOT NULL,encrypted_token BLOB);
+CREATE TABLE web_app_icons (url LONGVARCHAR,width int,height int,image BLOB, UNIQUE (url, width, height));
+CREATE TABLE web_apps (url LONGVARCHAR UNIQUE,has_all_images INTEGER NOT NULL);
+CREATE TABLE web_intents ( service_url LONGVARCHAR, action VARCHAR, type VARCHAR, title LONGVARCHAR, disposition VARCHAR, scheme VARCHAR, UNIQUE (service_url, action, scheme, type));
+CREATE TABLE web_intents_defaults ( action VARCHAR, type VARCHAR, url_pattern LONGVARCHAR, user_date INTEGER, suppression INTEGER, service_url LONGVARCHAR, scheme VARCHAR, UNIQUE (action, scheme, type, url_pattern));
+CREATE TABLE autofill (name VARCHAR, value VARCHAR, value_lower VARCHAR, pair_id INTEGER PRIMARY KEY, count INTEGER DEFAULT 1);
+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 '');
+CREATE TABLE autofill_dates ( pair_id INTEGER DEFAULT 0, date_created INTEGER DEFAULT 0);
+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 '');
+INSERT INTO "autofill_profiles" VALUES('00000000-0000-0000-0000-000000000001','Google, Inc.','1950 Charleston Rd.','(2nd floor)','Mountain View','CA','94043','United States','US',1386046731,'Chrome settings');
+INSERT INTO "autofill_profiles" VALUES('00000000-0000-0000-0000-000000000002','Google!','1600 Amphitheatre Pkwy.','','Mtn. View','California','94043-1234','United States','US',1386046800,'Chrome settings');
+INSERT INTO "autofill_profiles" VALUES('00000000-0000-0000-0000-000000000003','','','Only line 2???','','','','','',1386046834,'Chrome settings');
+INSERT INTO "autofill_profiles" VALUES('00000000-0000-0000-0000-000000000004','','','','','Texas','','','',1386046847,'Chrome settings');
+CREATE TABLE autofill_profile_names ( guid VARCHAR, first_name VARCHAR, middle_name VARCHAR, last_name VARCHAR);
+INSERT INTO "autofill_profile_names" VALUES('00000000-0000-0000-0000-000000000001','','','');
+INSERT INTO "autofill_profile_names" VALUES('00000000-0000-0000-0000-000000000002','','','');
+INSERT INTO "autofill_profile_names" VALUES('00000000-0000-0000-0000-000000000003','','','');
+INSERT INTO "autofill_profile_names" VALUES('00000000-0000-0000-0000-000000000004','','','');
+CREATE TABLE autofill_profile_emails ( guid VARCHAR, email VARCHAR);
+INSERT INTO "autofill_profile_emails" VALUES('00000000-0000-0000-0000-000000000001','');
+INSERT INTO "autofill_profile_emails" VALUES('00000000-0000-0000-0000-000000000002','');
+INSERT INTO "autofill_profile_emails" VALUES('00000000-0000-0000-0000-000000000003','');
+INSERT INTO "autofill_profile_emails" VALUES('00000000-0000-0000-0000-000000000004','');
+CREATE TABLE autofill_profile_phones ( guid VARCHAR, type INTEGER DEFAULT 0, number VARCHAR);
+INSERT INTO "autofill_profile_phones" VALUES('00000000-0000-0000-0000-000000000001',0,'1.800.555.1234');
+INSERT INTO "autofill_profile_phones" VALUES('00000000-0000-0000-0000-000000000001',0,'+1 (800) 555-4321');
+INSERT INTO "autofill_profile_phones" VALUES('00000000-0000-0000-0000-000000000002',0,'');
+INSERT INTO "autofill_profile_phones" VALUES('00000000-0000-0000-0000-000000000003',0,'6505557890');
+INSERT INTO "autofill_profile_phones" VALUES('00000000-0000-0000-0000-000000000004',0,'');
+CREATE TABLE autofill_profiles_trash ( guid VARCHAR);
+CREATE INDEX web_apps_url_index ON web_apps (url);
+CREATE INDEX web_intents_index ON web_intents (action);
+CREATE INDEX web_intents_default_index ON web_intents_defaults (action);
+CREATE INDEX autofill_name ON autofill (name);
+CREATE INDEX autofill_name_value_lower ON autofill (name, value_lower);
+CREATE INDEX autofill_dates_pair_id ON autofill_dates (pair_id);
+COMMIT;
diff --git a/components/webdata/common/web_database.cc b/components/webdata/common/web_database.cc
index 161fb80..44b6790 100644
--- a/components/webdata/common/web_database.cc
+++ b/components/webdata/common/web_database.cc
@@ -14,11 +14,11 @@
// corresponding changes must happen in the unit tests, and new migration test
// added. See |WebDatabaseMigrationTest::kCurrentTestedVersionNumber|.
// static
-const int WebDatabase::kCurrentVersionNumber = 53;
+const int WebDatabase::kCurrentVersionNumber = 54;
namespace {
-const int kCompatibleVersionNumber = 48;
+const int kCompatibleVersionNumber = 54;
// Change the version number and possibly the compatibility version of
// |meta_table_|.
diff --git a/components/webdata/common/web_database_migration_unittest.cc b/components/webdata/common/web_database_migration_unittest.cc
index 57ef02d..9b12fac 100644
--- a/components/webdata/common/web_database_migration_unittest.cc
+++ b/components/webdata/common/web_database_migration_unittest.cc
@@ -76,15 +76,15 @@ void AutofillProfile33FromStatement(const sql::Statement& s,
profile->set_guid(s.ColumnString(0));
EXPECT_TRUE(base::IsValidGUID(profile->guid()));
profile->SetRawInfo(autofill::COMPANY_NAME, s.ColumnString16(1));
- profile->SetRawInfo(autofill::ADDRESS_HOME_LINE1, s.ColumnString16(2));
- profile->SetRawInfo(autofill::ADDRESS_HOME_LINE2, s.ColumnString16(3));
- profile->SetRawInfo(autofill::ADDRESS_HOME_CITY, s.ColumnString16(4));
- profile->SetRawInfo(autofill::ADDRESS_HOME_STATE, s.ColumnString16(5));
- profile->SetRawInfo(autofill::ADDRESS_HOME_ZIP, s.ColumnString16(6));
+ profile->SetRawInfo(autofill::ADDRESS_HOME_STREET_ADDRESS,
+ s.ColumnString16(2));
+ profile->SetRawInfo(autofill::ADDRESS_HOME_CITY, s.ColumnString16(3));
+ profile->SetRawInfo(autofill::ADDRESS_HOME_STATE, s.ColumnString16(4));
+ profile->SetRawInfo(autofill::ADDRESS_HOME_ZIP, s.ColumnString16(5));
profile->SetInfo(
autofill::AutofillType(autofill::ADDRESS_HOME_COUNTRY),
- s.ColumnString16(7), "en-US");
- *date_modified = s.ColumnInt64(8);
+ s.ColumnString16(6), "en-US");
+ *date_modified = s.ColumnInt64(7);
}
void CreditCard31FromStatement(const sql::Statement& s,
@@ -247,7 +247,7 @@ class WebDatabaseMigrationTest : public testing::Test {
DISALLOW_COPY_AND_ASSIGN(WebDatabaseMigrationTest);
};
-const int WebDatabaseMigrationTest::kCurrentTestedVersionNumber = 53;
+const int WebDatabaseMigrationTest::kCurrentTestedVersionNumber = 54;
void WebDatabaseMigrationTest::LoadDatabase(
const base::FilePath::StringType& file) {
@@ -805,8 +805,8 @@ TEST_F(WebDatabaseMigrationTest, MigrateVersion31ToCurrent) {
// Verify data in the database after the migration.
sql::Statement s1(
connection.GetUniqueStatement(
- "SELECT guid, company_name, address_line_1, address_line_2, "
- "city, state, zipcode, country, date_modified "
+ "SELECT guid, company_name, street_address, city, state, zipcode,"
+ " country_code, date_modified "
"FROM autofill_profiles"));
ASSERT_TRUE(s1.Step());
@@ -916,13 +916,12 @@ TEST_F(WebDatabaseMigrationTest, MigrateVersion32ToCurrent) {
EXPECT_TRUE(connection.DoesColumnExist("autofill_profiles",
"company_name"));
EXPECT_TRUE(connection.DoesColumnExist("autofill_profiles",
- "address_line_1"));
- EXPECT_TRUE(connection.DoesColumnExist("autofill_profiles",
- "address_line_2"));
+ "street_address"));
EXPECT_TRUE(connection.DoesColumnExist("autofill_profiles", "city"));
EXPECT_TRUE(connection.DoesColumnExist("autofill_profiles", "state"));
EXPECT_TRUE(connection.DoesColumnExist("autofill_profiles", "zipcode"));
- EXPECT_TRUE(connection.DoesColumnExist("autofill_profiles", "country"));
+ EXPECT_TRUE(connection.DoesColumnExist("autofill_profiles",
+ "country_code"));
EXPECT_FALSE(connection.DoesColumnExist("autofill_profiles", "phone"));
EXPECT_FALSE(connection.DoesColumnExist("autofill_profiles", "fax"));
EXPECT_TRUE(connection.DoesColumnExist("autofill_profiles",
@@ -943,7 +942,6 @@ TEST_F(WebDatabaseMigrationTest, MigrateVersion32ToCurrent) {
// New "phones" table.
EXPECT_TRUE(connection.DoesColumnExist("autofill_profile_phones", "guid"));
- EXPECT_TRUE(connection.DoesColumnExist("autofill_profile_phones", "type"));
EXPECT_TRUE(connection.DoesColumnExist("autofill_profile_phones",
"number"));
@@ -952,21 +950,22 @@ TEST_F(WebDatabaseMigrationTest, MigrateVersion32ToCurrent) {
// Verify data in the database after the migration.
sql::Statement s1(
connection.GetUniqueStatement(
- "SELECT guid, company_name, address_line_1, address_line_2, "
- "city, state, zipcode, country, date_modified "
+ "SELECT guid, company_name, street_address, city, state, zipcode, "
+ " country_code, date_modified "
"FROM autofill_profiles"));
// John Doe.
ASSERT_TRUE(s1.Step());
EXPECT_EQ("00580526-FF81-EE2A-0546-1AC593A32E2F", s1.ColumnString(0));
EXPECT_EQ(ASCIIToUTF16("Doe Enterprises"), s1.ColumnString16(1));
- EXPECT_EQ(ASCIIToUTF16("1 Main St"), s1.ColumnString16(2));
- EXPECT_EQ(ASCIIToUTF16("Apt 1"), s1.ColumnString16(3));
- EXPECT_EQ(ASCIIToUTF16("Los Altos"), s1.ColumnString16(4));
- EXPECT_EQ(ASCIIToUTF16("CA"), s1.ColumnString16(5));
- EXPECT_EQ(ASCIIToUTF16("94022"), s1.ColumnString16(6));
- EXPECT_EQ(ASCIIToUTF16("United States"), s1.ColumnString16(7));
- EXPECT_EQ(1297882100L, s1.ColumnInt64(8));
+ EXPECT_EQ(ASCIIToUTF16("1 Main St\n"
+ "Apt 1"),
+ s1.ColumnString16(2));
+ EXPECT_EQ(ASCIIToUTF16("Los Altos"), s1.ColumnString16(3));
+ EXPECT_EQ(ASCIIToUTF16("CA"), s1.ColumnString16(4));
+ EXPECT_EQ(ASCIIToUTF16("94022"), s1.ColumnString16(5));
+ EXPECT_EQ(ASCIIToUTF16("US"), s1.ColumnString16(6));
+ EXPECT_EQ(1297882100L, s1.ColumnInt64(7));
// John P. Doe.
// Gets merged during migration from 35 to 37 due to multi-valued fields.
@@ -976,24 +975,22 @@ TEST_F(WebDatabaseMigrationTest, MigrateVersion32ToCurrent) {
EXPECT_EQ("4C74A9D8-7EEE-423E-F9C2-E7FA70ED1396", s1.ColumnString(0));
EXPECT_EQ(base::string16(), s1.ColumnString16(1));
EXPECT_EQ(ASCIIToUTF16("2 Main Street"), s1.ColumnString16(2));
- EXPECT_EQ(base::string16(), s1.ColumnString16(3));
- EXPECT_EQ(ASCIIToUTF16("Los Altos"), s1.ColumnString16(4));
- EXPECT_EQ(ASCIIToUTF16("CA"), s1.ColumnString16(5));
- EXPECT_EQ(ASCIIToUTF16("94022"), s1.ColumnString16(6));
- EXPECT_EQ(ASCIIToUTF16("United States"), s1.ColumnString16(7));
- EXPECT_EQ(1297882100L, s1.ColumnInt64(8));
+ EXPECT_EQ(ASCIIToUTF16("Los Altos"), s1.ColumnString16(3));
+ EXPECT_EQ(ASCIIToUTF16("CA"), s1.ColumnString16(4));
+ EXPECT_EQ(ASCIIToUTF16("94022"), s1.ColumnString16(5));
+ EXPECT_EQ(ASCIIToUTF16("US"), s1.ColumnString16(6));
+ EXPECT_EQ(1297882100L, s1.ColumnInt64(7));
// Dave Smith (Part 2).
ASSERT_TRUE(s1.Step());
EXPECT_EQ("722DF5C4-F74A-294A-46F0-31FFDED0D635", s1.ColumnString(0));
EXPECT_EQ(base::string16(), s1.ColumnString16(1));
EXPECT_EQ(ASCIIToUTF16("2 Main St"), s1.ColumnString16(2));
- EXPECT_EQ(base::string16(), s1.ColumnString16(3));
- EXPECT_EQ(ASCIIToUTF16("Los Altos"), s1.ColumnString16(4));
- EXPECT_EQ(ASCIIToUTF16("CA"), s1.ColumnString16(5));
- EXPECT_EQ(ASCIIToUTF16("94022"), s1.ColumnString16(6));
- EXPECT_EQ(ASCIIToUTF16("United States"), s1.ColumnString16(7));
- EXPECT_EQ(1297882100L, s1.ColumnInt64(8));
+ EXPECT_EQ(ASCIIToUTF16("Los Altos"), s1.ColumnString16(3));
+ EXPECT_EQ(ASCIIToUTF16("CA"), s1.ColumnString16(4));
+ EXPECT_EQ(ASCIIToUTF16("94022"), s1.ColumnString16(5));
+ EXPECT_EQ(ASCIIToUTF16("US"), s1.ColumnString16(6));
+ EXPECT_EQ(1297882100L, s1.ColumnInt64(7));
// Alfred E Newman.
// Gets culled during migration from 35 to 36 due to incomplete address.
@@ -1003,12 +1000,11 @@ TEST_F(WebDatabaseMigrationTest, MigrateVersion32ToCurrent) {
EXPECT_EQ("9E5FE298-62C7-83DF-6293-381BC589183F", s1.ColumnString(0));
EXPECT_EQ(base::string16(), s1.ColumnString16(1));
EXPECT_EQ(ASCIIToUTF16("3 Main St"), s1.ColumnString16(2));
- EXPECT_EQ(base::string16(), s1.ColumnString16(3));
- EXPECT_EQ(ASCIIToUTF16("Los Altos"), s1.ColumnString16(4));
- EXPECT_EQ(ASCIIToUTF16("CA"), s1.ColumnString16(5));
- EXPECT_EQ(ASCIIToUTF16("94022"), s1.ColumnString16(6));
- EXPECT_EQ(ASCIIToUTF16("United States"), s1.ColumnString16(7));
- EXPECT_EQ(1297882100L, s1.ColumnInt64(8));
+ EXPECT_EQ(ASCIIToUTF16("Los Altos"), s1.ColumnString16(3));
+ EXPECT_EQ(ASCIIToUTF16("CA"), s1.ColumnString16(4));
+ EXPECT_EQ(ASCIIToUTF16("94022"), s1.ColumnString16(5));
+ EXPECT_EQ(ASCIIToUTF16("US"), s1.ColumnString16(6));
+ EXPECT_EQ(1297882100L, s1.ColumnInt64(7));
// That should be all.
EXPECT_FALSE(s1.Step());
@@ -1097,14 +1093,13 @@ TEST_F(WebDatabaseMigrationTest, MigrateVersion32ToCurrent) {
sql::Statement s4(
connection.GetUniqueStatement(
- "SELECT guid, type, number "
+ "SELECT guid, number "
"FROM autofill_profile_phones"));
// John Doe phone.
ASSERT_TRUE(s4.Step());
EXPECT_EQ("00580526-FF81-EE2A-0546-1AC593A32E2F", s4.ColumnString(0));
- EXPECT_EQ(0, s4.ColumnInt(1)); // 0 means phone.
- EXPECT_EQ(ASCIIToUTF16("4151112222"), s4.ColumnString16(2));
+ EXPECT_EQ(ASCIIToUTF16("4151112222"), s4.ColumnString16(1));
// John Doe fax.
// Gets culled after fax type removed.
@@ -1120,8 +1115,7 @@ TEST_F(WebDatabaseMigrationTest, MigrateVersion32ToCurrent) {
// 2 Main Street phone.
ASSERT_TRUE(s4.Step());
EXPECT_EQ("4C74A9D8-7EEE-423E-F9C2-E7FA70ED1396", s4.ColumnString(0));
- EXPECT_EQ(0, s4.ColumnInt(1)); // 0 means phone.
- EXPECT_EQ(base::string16(), s4.ColumnString16(2));
+ EXPECT_EQ(base::string16(), s4.ColumnString16(1));
// 2 Main Street fax.
// Gets culled after fax type removed.
@@ -1140,8 +1134,7 @@ TEST_F(WebDatabaseMigrationTest, MigrateVersion32ToCurrent) {
// 3 Main St phone.
ASSERT_TRUE(s4.Step());
EXPECT_EQ("9E5FE298-62C7-83DF-6293-381BC589183F", s4.ColumnString(0));
- EXPECT_EQ(0, s4.ColumnInt(1)); // 0 means phone.
- EXPECT_EQ(base::string16(), s4.ColumnString16(2));
+ EXPECT_EQ(base::string16(), s4.ColumnString16(1));
// 2 Main St fax.
// Gets culled after fax type removed.
@@ -1295,21 +1288,22 @@ TEST_F(WebDatabaseMigrationTest, MigrateVersion35ToCurrent) {
// Verify data in the database after the migration.
sql::Statement s1(
connection.GetUniqueStatement(
- "SELECT guid, company_name, address_line_1, address_line_2, "
- "city, state, zipcode, country, date_modified "
+ "SELECT guid, company_name, street_address, city, state, zipcode,"
+ " country_code, date_modified "
"FROM autofill_profiles"));
// John Doe.
ASSERT_TRUE(s1.Step());
EXPECT_EQ("00000000-0000-0000-0000-000000000001", s1.ColumnString(0));
EXPECT_EQ(ASCIIToUTF16("Acme Inc."), s1.ColumnString16(1));
- EXPECT_EQ(ASCIIToUTF16("1 Main Street"), s1.ColumnString16(2));
- EXPECT_EQ(ASCIIToUTF16("Apt 2"), s1.ColumnString16(3));
- EXPECT_EQ(ASCIIToUTF16("San Francisco"), s1.ColumnString16(4));
- EXPECT_EQ(ASCIIToUTF16("CA"), s1.ColumnString16(5));
- EXPECT_EQ(ASCIIToUTF16("94102"), s1.ColumnString16(6));
- EXPECT_EQ(ASCIIToUTF16("United States"), s1.ColumnString16(7));
- EXPECT_EQ(1300131704, s1.ColumnInt64(8));
+ EXPECT_EQ(ASCIIToUTF16("1 Main Street\n"
+ "Apt 2"),
+ s1.ColumnString16(2));
+ EXPECT_EQ(ASCIIToUTF16("San Francisco"), s1.ColumnString16(3));
+ EXPECT_EQ(ASCIIToUTF16("CA"), s1.ColumnString16(4));
+ EXPECT_EQ(ASCIIToUTF16("94102"), s1.ColumnString16(5));
+ EXPECT_EQ(ASCIIToUTF16("US"), s1.ColumnString16(6));
+ EXPECT_EQ(1300131704, s1.ColumnInt64(7));
// That should be it.
ASSERT_FALSE(s1.Step());
@@ -2117,3 +2111,161 @@ TEST_F(WebDatabaseMigrationTest, MigrateVersion52ToCurrent) {
EXPECT_TRUE(connection.DoesColumnExist("keywords", "new_tab_url"));
}
}
+
+// Tests that for a version 54 database,
+// (a) The street_address, dependent_locality, and sorting_code columns are
+// added to the autofill_profiles table schema.
+// (b) The address_line1, address_line2, and country columns are dropped from
+// the autofill_profiles table schema.
+// (c) The type column is dropped from the autofill_profile_phones schema.
+TEST_F(WebDatabaseMigrationTest, MigrateVersion53ToCurrent) {
+ ASSERT_NO_FATAL_FAILURE(LoadDatabase(FILE_PATH_LITERAL("version_53.sql")));
+
+ // Verify pre-conditions. These are expectations for version 53 of the
+ // database.
+ {
+ sql::Connection connection;
+ ASSERT_TRUE(connection.Open(GetDatabasePath()));
+
+ EXPECT_TRUE(
+ connection.DoesColumnExist("autofill_profiles", "address_line_1"));
+ EXPECT_TRUE(
+ connection.DoesColumnExist("autofill_profiles", "address_line_2"));
+ EXPECT_TRUE(connection.DoesColumnExist("autofill_profiles", "country"));
+ EXPECT_FALSE(
+ connection.DoesColumnExist("autofill_profiles", "street_address"));
+ EXPECT_FALSE(
+ connection.DoesColumnExist("autofill_profiles", "dependent_locality"));
+ EXPECT_FALSE(
+ connection.DoesColumnExist("autofill_profiles", "sorting_code"));
+ EXPECT_TRUE(connection.DoesColumnExist("autofill_profile_phones", "type"));
+ }
+
+ DoMigration();
+
+ // Verify post-conditions. These are expectations for current version of the
+ // database.
+ {
+ sql::Connection connection;
+ ASSERT_TRUE(connection.Open(GetDatabasePath()));
+ ASSERT_TRUE(sql::MetaTable::DoesTableExist(&connection));
+
+ // Check version.
+ EXPECT_EQ(kCurrentTestedVersionNumber, VersionFromConnection(&connection));
+
+ // Columns should have been added and removed appropriately.
+ EXPECT_FALSE(
+ connection.DoesColumnExist("autofill_profiles", "address_line1"));
+ EXPECT_FALSE(
+ connection.DoesColumnExist("autofill_profiles", "address_line2"));
+ EXPECT_FALSE(connection.DoesColumnExist("autofill_profiles", "country"));
+ EXPECT_TRUE(
+ connection.DoesColumnExist("autofill_profiles", "street_address"));
+ EXPECT_TRUE(
+ connection.DoesColumnExist("autofill_profiles", "dependent_locality"));
+ EXPECT_TRUE(
+ connection.DoesColumnExist("autofill_profiles", "sorting_code"));
+ EXPECT_FALSE(connection.DoesColumnExist("autofill_profile_phones", "type"));
+
+ // Data should have been preserved.
+ sql::Statement s_profiles(
+ connection.GetUniqueStatement(
+ "SELECT guid, company_name, street_address, dependent_locality,"
+ " city, state, zipcode, sorting_code, country_code, date_modified,"
+ " origin "
+ "FROM autofill_profiles"));
+
+ // Address lines 1 and 2.
+ ASSERT_TRUE(s_profiles.Step());
+ EXPECT_EQ("00000000-0000-0000-0000-000000000001",
+ s_profiles.ColumnString(0));
+ EXPECT_EQ(ASCIIToUTF16("Google, Inc."), s_profiles.ColumnString16(1));
+ EXPECT_EQ(ASCIIToUTF16("1950 Charleston Rd.\n"
+ "(2nd floor)"),
+ s_profiles.ColumnString16(2));
+ EXPECT_EQ(base::string16(), s_profiles.ColumnString16(3));
+ EXPECT_EQ(ASCIIToUTF16("Mountain View"), s_profiles.ColumnString16(4));
+ EXPECT_EQ(ASCIIToUTF16("CA"), s_profiles.ColumnString16(5));
+ EXPECT_EQ(ASCIIToUTF16("94043"), s_profiles.ColumnString16(6));
+ EXPECT_EQ(base::string16(), s_profiles.ColumnString16(7));
+ EXPECT_EQ(ASCIIToUTF16("US"), s_profiles.ColumnString16(8));
+ EXPECT_EQ(1386046731, s_profiles.ColumnInt(9));
+ EXPECT_EQ(ASCIIToUTF16("Chrome settings"), s_profiles.ColumnString16(10));
+
+ // Only address line 1.
+ ASSERT_TRUE(s_profiles.Step());
+ EXPECT_EQ("00000000-0000-0000-0000-000000000002",
+ s_profiles.ColumnString(0));
+ EXPECT_EQ(ASCIIToUTF16("Google!"), s_profiles.ColumnString16(1));
+ EXPECT_EQ(ASCIIToUTF16("1600 Amphitheatre Pkwy."),
+ s_profiles.ColumnString16(2));
+ EXPECT_EQ(base::string16(), s_profiles.ColumnString16(3));
+ EXPECT_EQ(ASCIIToUTF16("Mtn. View"), s_profiles.ColumnString16(4));
+ EXPECT_EQ(ASCIIToUTF16("California"), s_profiles.ColumnString16(5));
+ EXPECT_EQ(ASCIIToUTF16("94043-1234"), s_profiles.ColumnString16(6));
+ EXPECT_EQ(base::string16(), s_profiles.ColumnString16(7));
+ EXPECT_EQ(ASCIIToUTF16("US"), s_profiles.ColumnString16(8));
+ EXPECT_EQ(1386046800, s_profiles.ColumnInt(9));
+ EXPECT_EQ(ASCIIToUTF16("Chrome settings"), s_profiles.ColumnString16(10));
+
+ // Only address line 2.
+ ASSERT_TRUE(s_profiles.Step());
+ EXPECT_EQ("00000000-0000-0000-0000-000000000003",
+ s_profiles.ColumnString(0));
+ EXPECT_EQ(base::string16(), s_profiles.ColumnString16(1));
+ EXPECT_EQ(ASCIIToUTF16("\nOnly line 2???"), s_profiles.ColumnString16(2));
+ EXPECT_EQ(base::string16(), s_profiles.ColumnString16(3));
+ EXPECT_EQ(base::string16(), s_profiles.ColumnString16(4));
+ EXPECT_EQ(base::string16(), s_profiles.ColumnString16(5));
+ EXPECT_EQ(base::string16(), s_profiles.ColumnString16(6));
+ EXPECT_EQ(base::string16(), s_profiles.ColumnString16(7));
+ EXPECT_EQ(base::string16(), s_profiles.ColumnString16(8));
+ EXPECT_EQ(1386046834, s_profiles.ColumnInt(9));
+ EXPECT_EQ(ASCIIToUTF16("Chrome settings"), s_profiles.ColumnString16(10));
+
+ // No address lines.
+ ASSERT_TRUE(s_profiles.Step());
+ EXPECT_EQ("00000000-0000-0000-0000-000000000004",
+ s_profiles.ColumnString(0));
+ EXPECT_EQ(base::string16(), s_profiles.ColumnString16(1));
+ EXPECT_EQ(base::string16(), s_profiles.ColumnString16(2));
+ EXPECT_EQ(base::string16(), s_profiles.ColumnString16(3));
+ EXPECT_EQ(base::string16(), s_profiles.ColumnString16(4));
+ EXPECT_EQ(ASCIIToUTF16("Texas"), s_profiles.ColumnString16(5));
+ EXPECT_EQ(base::string16(), s_profiles.ColumnString16(6));
+ EXPECT_EQ(base::string16(), s_profiles.ColumnString16(7));
+ EXPECT_EQ(base::string16(), s_profiles.ColumnString16(8));
+ EXPECT_EQ(1386046847, s_profiles.ColumnInt(9));
+ EXPECT_EQ(ASCIIToUTF16("Chrome settings"), s_profiles.ColumnString16(10));
+
+ // That should be it.
+ EXPECT_FALSE(s_profiles.Step());
+
+ // Verify the phone number data as well.
+ sql::Statement s_phones(
+ connection.GetUniqueStatement(
+ "SELECT guid, number FROM autofill_profile_phones"));
+
+ ASSERT_TRUE(s_phones.Step());
+ EXPECT_EQ("00000000-0000-0000-0000-000000000001", s_phones.ColumnString(0));
+ EXPECT_EQ(ASCIIToUTF16("1.800.555.1234"), s_phones.ColumnString16(1));
+
+ ASSERT_TRUE(s_phones.Step());
+ EXPECT_EQ("00000000-0000-0000-0000-000000000001", s_phones.ColumnString(0));
+ EXPECT_EQ(ASCIIToUTF16("+1 (800) 555-4321"), s_phones.ColumnString16(1));
+
+ ASSERT_TRUE(s_phones.Step());
+ EXPECT_EQ("00000000-0000-0000-0000-000000000002", s_phones.ColumnString(0));
+ EXPECT_EQ(base::string16(), s_phones.ColumnString16(1));
+
+ ASSERT_TRUE(s_phones.Step());
+ EXPECT_EQ("00000000-0000-0000-0000-000000000003", s_phones.ColumnString(0));
+ EXPECT_EQ(ASCIIToUTF16("6505557890"), s_phones.ColumnString16(1));
+
+ ASSERT_TRUE(s_phones.Step());
+ EXPECT_EQ("00000000-0000-0000-0000-000000000004", s_phones.ColumnString(0));
+ EXPECT_EQ(base::string16(), s_phones.ColumnString16(1));
+
+ EXPECT_FALSE(s_phones.Step());
+ }
+}