OLD | NEW |
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "chrome/browser/webdata/web_database.h" | 5 #include "chrome/browser/webdata/web_database.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 #include <limits> | 8 #include <limits> |
9 #include <set> | 9 #include <set> |
10 #include <string> | 10 #include <string> |
11 | 11 |
12 #include "app/sql/statement.h" | 12 #include "app/sql/statement.h" |
13 #include "app/sql/transaction.h" | 13 #include "app/sql/transaction.h" |
14 #include "base/string_number_conversions.h" | 14 #include "base/string_number_conversions.h" |
15 #include "base/string_split.h" | 15 #include "base/string_split.h" |
16 #include "base/string_util.h" | 16 #include "base/string_util.h" |
17 #include "base/tuple.h" | 17 #include "base/tuple.h" |
18 #include "base/utf_string_conversions.h" | 18 #include "base/utf_string_conversions.h" |
| 19 #include "chrome/browser/autofill/autofill_country.h" |
19 #include "chrome/browser/autofill/autofill_profile.h" | 20 #include "chrome/browser/autofill/autofill_profile.h" |
20 #include "chrome/browser/autofill/autofill_type.h" | 21 #include "chrome/browser/autofill/autofill_type.h" |
21 #include "chrome/browser/autofill/credit_card.h" | 22 #include "chrome/browser/autofill/credit_card.h" |
22 #include "chrome/browser/diagnostics/sqlite_diagnostics.h" | 23 #include "chrome/browser/diagnostics/sqlite_diagnostics.h" |
23 #include "chrome/browser/history/history_database.h" | 24 #include "chrome/browser/history/history_database.h" |
24 #include "chrome/browser/password_manager/encryptor.h" | 25 #include "chrome/browser/password_manager/encryptor.h" |
25 #include "chrome/browser/search_engines/template_url.h" | 26 #include "chrome/browser/search_engines/template_url.h" |
26 #include "chrome/browser/webdata/autofill_change.h" | 27 #include "chrome/browser/webdata/autofill_change.h" |
27 #include "chrome/common/guid.h" | 28 #include "chrome/common/guid.h" |
28 #include "chrome/common/notification_service.h" | 29 #include "chrome/common/notification_service.h" |
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
116 // first_name | 117 // first_name |
117 // middle_name | 118 // middle_name |
118 // last_name | 119 // last_name |
119 // email | 120 // email |
120 // company_name | 121 // company_name |
121 // address_line_1 | 122 // address_line_1 |
122 // address_line_2 | 123 // address_line_2 |
123 // city | 124 // city |
124 // state | 125 // state |
125 // zipcode | 126 // zipcode |
126 // country | 127 // country The country name. Deprecated, should be removed once |
| 128 // the stable channel reaches version 11. |
| 129 // country_code |
127 // phone | 130 // phone |
128 // fax | 131 // fax |
129 // date_modified The date on which this profile was last modified. | 132 // date_modified The date on which this profile was last modified. |
130 // Added in version 30. | 133 // Added in version 30. |
131 // | 134 // |
132 // credit_cards This table contains credit card data added by the user | 135 // credit_cards This table contains credit card data added by the user |
133 // with the AutoFill dialog. Most of the columns are | 136 // with the AutoFill dialog. Most of the columns are |
134 // standard entries in a credit card form. | 137 // standard entries in a credit card form. |
135 // | 138 // |
136 // guid A guid string to uniquely identify the profile. | 139 // guid A guid string to uniquely identify the profile. |
(...skipping 21 matching lines...) Expand all Loading... |
158 | 161 |
159 using base::Time; | 162 using base::Time; |
160 | 163 |
161 namespace { | 164 namespace { |
162 | 165 |
163 typedef std::vector<Tuple3<int64, string16, string16> > AutofillElementList; | 166 typedef std::vector<Tuple3<int64, string16, string16> > AutofillElementList; |
164 | 167 |
165 // Current version number. Note: when changing the current version number, | 168 // Current version number. Note: when changing the current version number, |
166 // corresponding changes must happen in the unit tests, and new migration test | 169 // corresponding changes must happen in the unit tests, and new migration test |
167 // added. See |WebDatabaseMigrationTest::kCurrentTestedVersionNumber|. | 170 // added. See |WebDatabaseMigrationTest::kCurrentTestedVersionNumber|. |
168 const int kCurrentVersionNumber = 32; | 171 const int kCurrentVersionNumber = 33; |
169 const int kCompatibleVersionNumber = 32; | 172 const int kCompatibleVersionNumber = 33; |
170 | 173 |
171 // ID of the url column in keywords. | 174 // ID of the url column in keywords. |
172 const int kUrlIdPosition = 16; | 175 const int kUrlIdPosition = 16; |
173 | 176 |
174 // Keys used in the meta table. | 177 // Keys used in the meta table. |
175 const char* kDefaultSearchProviderKey = "Default Search Provider ID"; | 178 const char* kDefaultSearchProviderKey = "Default Search Provider ID"; |
176 const char* kBuiltinKeywordVersion = "Builtin Keyword Version"; | 179 const char* kBuiltinKeywordVersion = "Builtin Keyword Version"; |
177 | 180 |
178 // The maximum length allowed for form data. | 181 // The maximum length allowed for form data. |
179 const size_t kMaxDataLength = 1024; | 182 const size_t kMaxDataLength = 1024; |
(...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
274 text = profile.GetFieldText(AutoFillType(ADDRESS_HOME_LINE2)); | 277 text = profile.GetFieldText(AutoFillType(ADDRESS_HOME_LINE2)); |
275 s->BindString16(8, LimitDataSize(text)); | 278 s->BindString16(8, LimitDataSize(text)); |
276 text = profile.GetFieldText(AutoFillType(ADDRESS_HOME_CITY)); | 279 text = profile.GetFieldText(AutoFillType(ADDRESS_HOME_CITY)); |
277 s->BindString16(9, LimitDataSize(text)); | 280 s->BindString16(9, LimitDataSize(text)); |
278 text = profile.GetFieldText(AutoFillType(ADDRESS_HOME_STATE)); | 281 text = profile.GetFieldText(AutoFillType(ADDRESS_HOME_STATE)); |
279 s->BindString16(10, LimitDataSize(text)); | 282 s->BindString16(10, LimitDataSize(text)); |
280 text = profile.GetFieldText(AutoFillType(ADDRESS_HOME_ZIP)); | 283 text = profile.GetFieldText(AutoFillType(ADDRESS_HOME_ZIP)); |
281 s->BindString16(11, LimitDataSize(text)); | 284 s->BindString16(11, LimitDataSize(text)); |
282 text = profile.GetFieldText(AutoFillType(ADDRESS_HOME_COUNTRY)); | 285 text = profile.GetFieldText(AutoFillType(ADDRESS_HOME_COUNTRY)); |
283 s->BindString16(12, LimitDataSize(text)); | 286 s->BindString16(12, LimitDataSize(text)); |
| 287 std::string country_code = profile.CountryCode(); |
| 288 s->BindString(13, country_code); |
284 text = profile.GetFieldText(AutoFillType(PHONE_HOME_WHOLE_NUMBER)); | 289 text = profile.GetFieldText(AutoFillType(PHONE_HOME_WHOLE_NUMBER)); |
285 s->BindString16(13, LimitDataSize(text)); | 290 s->BindString16(14, LimitDataSize(text)); |
286 text = profile.GetFieldText(AutoFillType(PHONE_FAX_WHOLE_NUMBER)); | 291 text = profile.GetFieldText(AutoFillType(PHONE_FAX_WHOLE_NUMBER)); |
287 s->BindString16(14, LimitDataSize(text)); | 292 s->BindString16(15, LimitDataSize(text)); |
288 s->BindInt64(15, Time::Now().ToTimeT()); | 293 s->BindInt64(16, Time::Now().ToTimeT()); |
289 } | 294 } |
290 | 295 |
291 AutoFillProfile* AutoFillProfileFromStatement(const sql::Statement& s) { | 296 AutoFillProfile* AutoFillProfileFromStatement(const sql::Statement& s) { |
292 AutoFillProfile* profile = new AutoFillProfile; | 297 AutoFillProfile* profile = new AutoFillProfile; |
293 profile->set_guid(s.ColumnString(0)); | 298 profile->set_guid(s.ColumnString(0)); |
294 DCHECK(guid::IsValidGUID(profile->guid())); | 299 DCHECK(guid::IsValidGUID(profile->guid())); |
295 // TODO(dhollowa): remove label from |autofill_profiles| table. | 300 // TODO(dhollowa): remove label from |autofill_profiles| table. |
296 // Column 1 is label. | 301 // Column 1 is label. |
297 | 302 |
298 profile->SetInfo(AutoFillType(NAME_FIRST), | 303 profile->SetInfo(AutoFillType(NAME_FIRST), |
299 s.ColumnString16(2)); | 304 s.ColumnString16(2)); |
300 profile->SetInfo(AutoFillType(NAME_MIDDLE), | 305 profile->SetInfo(AutoFillType(NAME_MIDDLE), |
301 s.ColumnString16(3)); | 306 s.ColumnString16(3)); |
302 profile->SetInfo(AutoFillType(NAME_LAST), | 307 profile->SetInfo(AutoFillType(NAME_LAST), |
303 s.ColumnString16(4)); | 308 s.ColumnString16(4)); |
304 profile->SetInfo(AutoFillType(EMAIL_ADDRESS), | 309 profile->SetInfo(AutoFillType(EMAIL_ADDRESS), |
305 s.ColumnString16(5)); | 310 s.ColumnString16(5)); |
306 profile->SetInfo(AutoFillType(COMPANY_NAME), | 311 profile->SetInfo(AutoFillType(COMPANY_NAME), |
307 s.ColumnString16(6)); | 312 s.ColumnString16(6)); |
308 profile->SetInfo(AutoFillType(ADDRESS_HOME_LINE1), | 313 profile->SetInfo(AutoFillType(ADDRESS_HOME_LINE1), |
309 s.ColumnString16(7)); | 314 s.ColumnString16(7)); |
310 profile->SetInfo(AutoFillType(ADDRESS_HOME_LINE2), | 315 profile->SetInfo(AutoFillType(ADDRESS_HOME_LINE2), |
311 s.ColumnString16(8)); | 316 s.ColumnString16(8)); |
312 profile->SetInfo(AutoFillType(ADDRESS_HOME_CITY), | 317 profile->SetInfo(AutoFillType(ADDRESS_HOME_CITY), |
313 s.ColumnString16(9)); | 318 s.ColumnString16(9)); |
314 profile->SetInfo(AutoFillType(ADDRESS_HOME_STATE), | 319 profile->SetInfo(AutoFillType(ADDRESS_HOME_STATE), |
315 s.ColumnString16(10)); | 320 s.ColumnString16(10)); |
316 profile->SetInfo(AutoFillType(ADDRESS_HOME_ZIP), | 321 profile->SetInfo(AutoFillType(ADDRESS_HOME_ZIP), |
317 s.ColumnString16(11)); | 322 s.ColumnString16(11)); |
318 profile->SetInfo(AutoFillType(ADDRESS_HOME_COUNTRY), | 323 // Intentionally skip column 12, which stores the localized country name. |
319 s.ColumnString16(12)); | 324 profile->SetCountryCode(s.ColumnString(13)); |
320 profile->SetInfo(AutoFillType(PHONE_HOME_WHOLE_NUMBER), | 325 profile->SetInfo(AutoFillType(PHONE_HOME_WHOLE_NUMBER), |
321 s.ColumnString16(13)); | 326 s.ColumnString16(14)); |
322 profile->SetInfo(AutoFillType(PHONE_FAX_WHOLE_NUMBER), | 327 profile->SetInfo(AutoFillType(PHONE_FAX_WHOLE_NUMBER), |
323 s.ColumnString16(14)); | 328 s.ColumnString16(15)); |
324 // Intentionally skip column 15, which stores the profile's modification date. | 329 // Intentionally skip column 16, which stores the profile's modification date. |
325 | 330 |
326 return profile; | 331 return profile; |
327 } | 332 } |
328 | 333 |
329 void BindCreditCardToStatement(const CreditCard& credit_card, | 334 void BindCreditCardToStatement(const CreditCard& credit_card, |
330 sql::Statement* s) { | 335 sql::Statement* s) { |
331 DCHECK(guid::IsValidGUID(credit_card.guid())); | 336 DCHECK(guid::IsValidGUID(credit_card.guid())); |
332 s->BindString(0, credit_card.guid()); | 337 s->BindString(0, credit_card.guid()); |
333 s->BindString16(1, credit_card.Label()); | 338 s->BindString16(1, credit_card.Label()); |
334 | 339 |
(...skipping 392 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
727 "middle_name VARCHAR, " | 732 "middle_name VARCHAR, " |
728 "last_name VARCHAR, " | 733 "last_name VARCHAR, " |
729 "email VARCHAR, " | 734 "email VARCHAR, " |
730 "company_name VARCHAR, " | 735 "company_name VARCHAR, " |
731 "address_line_1 VARCHAR, " | 736 "address_line_1 VARCHAR, " |
732 "address_line_2 VARCHAR, " | 737 "address_line_2 VARCHAR, " |
733 "city VARCHAR, " | 738 "city VARCHAR, " |
734 "state VARCHAR, " | 739 "state VARCHAR, " |
735 "zipcode VARCHAR, " | 740 "zipcode VARCHAR, " |
736 "country VARCHAR, " | 741 "country VARCHAR, " |
| 742 "country_code VARCHAR, " |
737 "phone VARCHAR, " | 743 "phone VARCHAR, " |
738 "fax VARCHAR, " | 744 "fax VARCHAR, " |
739 "date_modified INTEGER NOT NULL DEFAULT 0)")) { | 745 "date_modified INTEGER NOT NULL DEFAULT 0)")) { |
740 NOTREACHED(); | 746 NOTREACHED(); |
741 return false; | 747 return false; |
742 } | 748 } |
743 if (!db_.Execute("CREATE INDEX autofill_profiles_label_index " | 749 if (!db_.Execute("CREATE INDEX autofill_profiles_label_index " |
744 "ON autofill_profiles (label)")) { | 750 "ON autofill_profiles (label)")) { |
745 NOTREACHED(); | 751 NOTREACHED(); |
746 return false; | 752 return false; |
(...skipping 855 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1602 if (s.Step()) | 1608 if (s.Step()) |
1603 return RemoveFormElementForID(s.ColumnInt64(0)); | 1609 return RemoveFormElementForID(s.ColumnInt64(0)); |
1604 return false; | 1610 return false; |
1605 } | 1611 } |
1606 | 1612 |
1607 bool WebDatabase::AddAutoFillProfile(const AutoFillProfile& profile) { | 1613 bool WebDatabase::AddAutoFillProfile(const AutoFillProfile& profile) { |
1608 sql::Statement s(db_.GetUniqueStatement( | 1614 sql::Statement s(db_.GetUniqueStatement( |
1609 "INSERT INTO autofill_profiles" | 1615 "INSERT INTO autofill_profiles" |
1610 "(guid, label, first_name, middle_name, last_name, email," | 1616 "(guid, label, first_name, middle_name, last_name, email," |
1611 " company_name, address_line_1, address_line_2, city, state, zipcode," | 1617 " company_name, address_line_1, address_line_2, city, state, zipcode," |
1612 " country, phone, fax, date_modified)" | 1618 " country, country_code, phone, fax, date_modified)" |
1613 "VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)")); | 1619 "VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)")); |
1614 if (!s) { | 1620 if (!s) { |
1615 NOTREACHED() << "Statement prepare failed"; | 1621 NOTREACHED() << "Statement prepare failed"; |
1616 return false; | 1622 return false; |
1617 } | 1623 } |
1618 | 1624 |
1619 BindAutoFillProfileToStatement(profile, &s); | 1625 BindAutoFillProfileToStatement(profile, &s); |
1620 | 1626 |
1621 if (!s.Run()) { | 1627 if (!s.Run()) { |
1622 NOTREACHED(); | 1628 NOTREACHED(); |
1623 return false; | 1629 return false; |
1624 } | 1630 } |
1625 | 1631 |
1626 return s.Succeeded(); | 1632 return s.Succeeded(); |
1627 } | 1633 } |
1628 | 1634 |
1629 bool WebDatabase::GetAutoFillProfile(const std::string& guid, | 1635 bool WebDatabase::GetAutoFillProfile(const std::string& guid, |
1630 AutoFillProfile** profile) { | 1636 AutoFillProfile** profile) { |
1631 DCHECK(guid::IsValidGUID(guid)); | 1637 DCHECK(guid::IsValidGUID(guid)); |
1632 DCHECK(profile); | 1638 DCHECK(profile); |
1633 sql::Statement s(db_.GetUniqueStatement( | 1639 sql::Statement s(db_.GetUniqueStatement( |
1634 "SELECT guid, label, first_name, middle_name, last_name, email, " | 1640 "SELECT guid, label, first_name, middle_name, last_name, email, " |
1635 "company_name, address_line_1, address_line_2, city, state, zipcode, " | 1641 "company_name, address_line_1, address_line_2, city, state, zipcode, " |
1636 "country, phone, fax, date_modified " | 1642 "country, country_code, phone, fax, date_modified " |
1637 "FROM autofill_profiles " | 1643 "FROM autofill_profiles " |
1638 "WHERE guid = ?")); | 1644 "WHERE guid = ?")); |
1639 if (!s) { | 1645 if (!s) { |
1640 NOTREACHED() << "Statement prepare failed"; | 1646 NOTREACHED() << "Statement prepare failed"; |
1641 return false; | 1647 return false; |
1642 } | 1648 } |
1643 | 1649 |
1644 s.BindString(0, guid); | 1650 s.BindString(0, guid); |
1645 if (!s.Step()) | 1651 if (!s.Step()) |
1646 return false; | 1652 return false; |
1647 | 1653 |
1648 *profile = AutoFillProfileFromStatement(s); | 1654 *profile = AutoFillProfileFromStatement(s); |
1649 | 1655 |
1650 return s.Succeeded(); | 1656 return s.Succeeded(); |
1651 } | 1657 } |
1652 | 1658 |
1653 bool WebDatabase::GetAutoFillProfiles( | 1659 bool WebDatabase::GetAutoFillProfiles( |
1654 std::vector<AutoFillProfile*>* profiles) { | 1660 std::vector<AutoFillProfile*>* profiles) { |
1655 DCHECK(profiles); | 1661 DCHECK(profiles); |
1656 profiles->clear(); | 1662 profiles->clear(); |
1657 | 1663 |
1658 sql::Statement s(db_.GetUniqueStatement( | 1664 sql::Statement s(db_.GetUniqueStatement( |
1659 "SELECT guid, label, first_name, middle_name, last_name, email, " | 1665 "SELECT guid, label, first_name, middle_name, last_name, email, " |
1660 "company_name, address_line_1, address_line_2, city, state, zipcode, " | 1666 "company_name, address_line_1, address_line_2, city, state, zipcode, " |
1661 "country, phone, fax, date_modified " | 1667 "country, country_code, phone, fax, date_modified " |
1662 "FROM autofill_profiles")); | 1668 "FROM autofill_profiles")); |
1663 if (!s) { | 1669 if (!s) { |
1664 NOTREACHED() << "Statement prepare failed"; | 1670 NOTREACHED() << "Statement prepare failed"; |
1665 return false; | 1671 return false; |
1666 } | 1672 } |
1667 | 1673 |
1668 while (s.Step()) | 1674 while (s.Step()) |
1669 profiles->push_back(AutoFillProfileFromStatement(s)); | 1675 profiles->push_back(AutoFillProfileFromStatement(s)); |
1670 | 1676 |
1671 return s.Succeeded(); | 1677 return s.Succeeded(); |
1672 } | 1678 } |
1673 | 1679 |
1674 bool WebDatabase::UpdateAutoFillProfile(const AutoFillProfile& profile) { | 1680 bool WebDatabase::UpdateAutoFillProfile(const AutoFillProfile& profile) { |
1675 DCHECK(guid::IsValidGUID(profile.guid())); | 1681 DCHECK(guid::IsValidGUID(profile.guid())); |
1676 | 1682 |
1677 AutoFillProfile* tmp_profile = NULL; | 1683 AutoFillProfile* tmp_profile = NULL; |
1678 if (!GetAutoFillProfile(profile.guid(), &tmp_profile)) | 1684 if (!GetAutoFillProfile(profile.guid(), &tmp_profile)) |
1679 return false; | 1685 return false; |
1680 | 1686 |
1681 // Preserve appropriate modification dates by not updating unchanged profiles. | 1687 // Preserve appropriate modification dates by not updating unchanged profiles. |
1682 scoped_ptr<AutoFillProfile> old_profile(tmp_profile); | 1688 scoped_ptr<AutoFillProfile> old_profile(tmp_profile); |
1683 if (*old_profile == profile) | 1689 if (*old_profile == profile) |
1684 return true; | 1690 return true; |
1685 | 1691 |
1686 sql::Statement s(db_.GetUniqueStatement( | 1692 sql::Statement s(db_.GetUniqueStatement( |
1687 "UPDATE autofill_profiles " | 1693 "UPDATE autofill_profiles " |
1688 "SET guid=?, label=?, first_name=?, middle_name=?, last_name=?, " | 1694 "SET guid=?, label=?, first_name=?, middle_name=?, last_name=?, " |
1689 " email=?, company_name=?, address_line_1=?, address_line_2=?, " | 1695 " email=?, company_name=?, address_line_1=?, address_line_2=?, " |
1690 " city=?, state=?, zipcode=?, country=?, phone=?, fax=?, " | 1696 " city=?, state=?, zipcode=?, country=?, country_code=?, phone=?, " |
1691 " date_modified=? " | 1697 " fax=?, date_modified=? " |
1692 "WHERE guid=?")); | 1698 "WHERE guid=?")); |
1693 if (!s) { | 1699 if (!s) { |
1694 NOTREACHED() << "Statement prepare failed"; | 1700 NOTREACHED() << "Statement prepare failed"; |
1695 return false; | 1701 return false; |
1696 } | 1702 } |
1697 | 1703 |
1698 BindAutoFillProfileToStatement(profile, &s); | 1704 BindAutoFillProfileToStatement(profile, &s); |
1699 s.BindString(16, profile.guid()); | 1705 s.BindString(17, profile.guid()); |
1700 bool result = s.Run(); | 1706 bool result = s.Run(); |
1701 DCHECK_GT(db_.GetLastChangeCount(), 0); | 1707 DCHECK_GT(db_.GetLastChangeCount(), 0); |
1702 return result; | 1708 return result; |
1703 } | 1709 } |
1704 | 1710 |
1705 bool WebDatabase::RemoveAutoFillProfile(const std::string& guid) { | 1711 bool WebDatabase::RemoveAutoFillProfile(const std::string& guid) { |
1706 DCHECK(guid::IsValidGUID(guid)); | 1712 DCHECK(guid::IsValidGUID(guid)); |
1707 sql::Statement s(db_.GetUniqueStatement( | 1713 sql::Statement s(db_.GetUniqueStatement( |
1708 "DELETE FROM autofill_profiles WHERE guid = ?")); | 1714 "DELETE FROM autofill_profiles WHERE guid = ?")); |
1709 if (!s) { | 1715 if (!s) { |
(...skipping 816 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2526 return sql::INIT_FAILURE; | 2532 return sql::INIT_FAILURE; |
2527 } | 2533 } |
2528 } | 2534 } |
2529 | 2535 |
2530 meta_table_.SetVersionNumber(32); | 2536 meta_table_.SetVersionNumber(32); |
2531 meta_table_.SetCompatibleVersionNumber( | 2537 meta_table_.SetCompatibleVersionNumber( |
2532 std::min(32, kCompatibleVersionNumber)); | 2538 std::min(32, kCompatibleVersionNumber)); |
2533 | 2539 |
2534 // FALL THROUGH | 2540 // FALL THROUGH |
2535 | 2541 |
| 2542 case 32: |
| 2543 // Add |country_code| column to |autofill_profiles| table. |
| 2544 // Note that we need to check for the column's existence due to the fact |
| 2545 // that for a version 22 database the |autofill_profiles| table gets |
| 2546 // created fresh with |InitAutoFillProfilesTable|. |
| 2547 if (!db_.DoesColumnExist("autofill_profiles", "country_code")) { |
| 2548 if (!db_.Execute("ALTER TABLE autofill_profiles ADD COLUMN " |
| 2549 "country_code VARCHAR")) { |
| 2550 LOG(WARNING) << "Unable to update web database to version 33."; |
| 2551 NOTREACHED(); |
| 2552 return sql::INIT_FAILURE; |
| 2553 } |
| 2554 |
| 2555 // Set all the |country_code| fields to match existing |country| values. |
| 2556 { |
| 2557 sql::Statement s(db_.GetUniqueStatement("SELECT guid, country " |
| 2558 "FROM autofill_profiles")); |
| 2559 |
| 2560 if (!s) { |
| 2561 LOG(WARNING) << "Unable to update web database to version 33."; |
| 2562 NOTREACHED(); |
| 2563 return sql::INIT_FAILURE; |
| 2564 } |
| 2565 |
| 2566 while (s.Step()) { |
| 2567 sql::Statement update_s( |
| 2568 db_.GetUniqueStatement("UPDATE autofill_profiles " |
| 2569 "SET country_code=? WHERE guid=?")); |
| 2570 if (!update_s) { |
| 2571 LOG(WARNING) << "Unable to update web database to version 33."; |
| 2572 NOTREACHED(); |
| 2573 return sql::INIT_FAILURE; |
| 2574 } |
| 2575 string16 country = s.ColumnString16(1); |
| 2576 update_s.BindString(0, AutoFillCountry::GetCountryCode(country)); |
| 2577 update_s.BindString(1, s.ColumnString(0)); |
| 2578 |
| 2579 if (!update_s.Run()) { |
| 2580 LOG(WARNING) << "Unable to update web database to version 33."; |
| 2581 NOTREACHED(); |
| 2582 return sql::INIT_FAILURE; |
| 2583 } |
| 2584 } |
| 2585 } |
| 2586 } |
| 2587 |
| 2588 meta_table_.SetVersionNumber(33); |
| 2589 meta_table_.SetCompatibleVersionNumber( |
| 2590 std::min(33, kCompatibleVersionNumber)); |
| 2591 |
| 2592 // FALL THROUGH |
| 2593 |
2536 // Add successive versions here. Each should set the version number and | 2594 // Add successive versions here. Each should set the version number and |
2537 // compatible version number as appropriate, then fall through to the next | 2595 // compatible version number as appropriate, then fall through to the next |
2538 // case. | 2596 // case. |
2539 | 2597 |
2540 case kCurrentVersionNumber: | 2598 case kCurrentVersionNumber: |
2541 // No migration needed. | 2599 // No migration needed. |
2542 return sql::INIT_OK; | 2600 return sql::INIT_OK; |
2543 } | 2601 } |
2544 } | 2602 } |
OLD | NEW |