| OLD | NEW |
| 1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 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 "components/autofill/core/browser/webdata/autofill_table.h" | 5 #include "components/autofill/core/browser/webdata/autofill_table.h" |
| 6 | 6 |
| 7 #include <algorithm> | 7 #include <algorithm> |
| 8 #include <cmath> | 8 #include <cmath> |
| 9 #include <limits> | 9 #include <limits> |
| 10 #include <map> | 10 #include <map> |
| (...skipping 171 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 182 UnencryptedCardFromColumn(s, index++)); | 182 UnencryptedCardFromColumn(s, index++)); |
| 183 credit_card->set_use_count(s.ColumnInt64(index++)); | 183 credit_card->set_use_count(s.ColumnInt64(index++)); |
| 184 credit_card->set_use_date(base::Time::FromTimeT(s.ColumnInt64(index++))); | 184 credit_card->set_use_date(base::Time::FromTimeT(s.ColumnInt64(index++))); |
| 185 credit_card->set_modification_date( | 185 credit_card->set_modification_date( |
| 186 base::Time::FromTimeT(s.ColumnInt64(index++))); | 186 base::Time::FromTimeT(s.ColumnInt64(index++))); |
| 187 credit_card->set_origin(s.ColumnString(index++)); | 187 credit_card->set_origin(s.ColumnString(index++)); |
| 188 | 188 |
| 189 return credit_card.Pass(); | 189 return credit_card.Pass(); |
| 190 } | 190 } |
| 191 | 191 |
| 192 // Obsolete version of AddAutofillProfileNamesToProfile, but still needed | |
| 193 // for MigrateToVersion37MergeAndCullOlderProfiles(). | |
| 194 bool AddAutofillProfileNamesToProfileForVersion37(sql::Connection* db, | |
| 195 AutofillProfile* profile) { | |
| 196 sql::Statement s(db->GetUniqueStatement( | |
| 197 "SELECT guid, first_name, middle_name, last_name " | |
| 198 "FROM autofill_profile_names " | |
| 199 "WHERE guid=?")); | |
| 200 s.BindString(0, profile->guid()); | |
| 201 | |
| 202 if (!s.is_valid()) | |
| 203 return false; | |
| 204 | |
| 205 std::vector<base::string16> first_names; | |
| 206 std::vector<base::string16> middle_names; | |
| 207 std::vector<base::string16> last_names; | |
| 208 while (s.Step()) { | |
| 209 DCHECK_EQ(profile->guid(), s.ColumnString(0)); | |
| 210 first_names.push_back(s.ColumnString16(1)); | |
| 211 middle_names.push_back(s.ColumnString16(2)); | |
| 212 last_names.push_back(s.ColumnString16(3)); | |
| 213 } | |
| 214 if (!s.Succeeded()) | |
| 215 return false; | |
| 216 | |
| 217 profile->SetRawMultiInfo(NAME_FIRST, first_names); | |
| 218 profile->SetRawMultiInfo(NAME_MIDDLE, middle_names); | |
| 219 profile->SetRawMultiInfo(NAME_LAST, last_names); | |
| 220 return true; | |
| 221 } | |
| 222 | |
| 223 bool AddAutofillProfileNamesToProfile(sql::Connection* db, | 192 bool AddAutofillProfileNamesToProfile(sql::Connection* db, |
| 224 AutofillProfile* profile) { | 193 AutofillProfile* profile) { |
| 225 sql::Statement s(db->GetUniqueStatement( | 194 sql::Statement s(db->GetUniqueStatement( |
| 226 "SELECT guid, first_name, middle_name, last_name, full_name " | 195 "SELECT guid, first_name, middle_name, last_name, full_name " |
| 227 "FROM autofill_profile_names " | 196 "FROM autofill_profile_names " |
| 228 "WHERE guid=?")); | 197 "WHERE guid=?")); |
| 229 s.BindString(0, profile->guid()); | 198 s.BindString(0, profile->guid()); |
| 230 | 199 |
| 231 if (!s.is_valid()) | 200 if (!s.is_valid()) |
| 232 return false; | 201 return false; |
| (...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 291 DCHECK_EQ(profile->guid(), s.ColumnString(0)); | 260 DCHECK_EQ(profile->guid(), s.ColumnString(0)); |
| 292 numbers.push_back(s.ColumnString16(1)); | 261 numbers.push_back(s.ColumnString16(1)); |
| 293 } | 262 } |
| 294 if (!s.Succeeded()) | 263 if (!s.Succeeded()) |
| 295 return false; | 264 return false; |
| 296 | 265 |
| 297 profile->SetRawMultiInfo(PHONE_HOME_WHOLE_NUMBER, numbers); | 266 profile->SetRawMultiInfo(PHONE_HOME_WHOLE_NUMBER, numbers); |
| 298 return true; | 267 return true; |
| 299 } | 268 } |
| 300 | 269 |
| 301 // Obsolete version of AddAutofillProfileNames needed for | |
| 302 // MigrateToVersion33ProfilesBasedOnFirstName() and | |
| 303 // MigrateToVersion37MergeAndCullOlderProfiles(). | |
| 304 bool AddAutofillProfileNamesForVersion3x( | |
| 305 const AutofillProfile& profile, | |
| 306 sql::Connection* db) { | |
| 307 std::vector<base::string16> first_names; | |
| 308 profile.GetRawMultiInfo(NAME_FIRST, &first_names); | |
| 309 std::vector<base::string16> middle_names; | |
| 310 profile.GetRawMultiInfo(NAME_MIDDLE, &middle_names); | |
| 311 std::vector<base::string16> last_names; | |
| 312 profile.GetRawMultiInfo(NAME_LAST, &last_names); | |
| 313 DCHECK_EQ(first_names.size(), middle_names.size()); | |
| 314 DCHECK_EQ(first_names.size(), last_names.size()); | |
| 315 | |
| 316 for (size_t i = 0; i < first_names.size(); ++i) { | |
| 317 // Add the new name. | |
| 318 sql::Statement s(db->GetUniqueStatement( | |
| 319 "INSERT INTO autofill_profile_names" | |
| 320 " (guid, first_name, middle_name, last_name) " | |
| 321 "VALUES (?,?,?,?)")); | |
| 322 s.BindString(0, profile.guid()); | |
| 323 s.BindString16(1, first_names[i]); | |
| 324 s.BindString16(2, middle_names[i]); | |
| 325 s.BindString16(3, last_names[i]); | |
| 326 | |
| 327 if (!s.Run()) | |
| 328 return false; | |
| 329 } | |
| 330 return true; | |
| 331 } | |
| 332 | |
| 333 bool AddAutofillProfileNames(const AutofillProfile& profile, | 270 bool AddAutofillProfileNames(const AutofillProfile& profile, |
| 334 sql::Connection* db) { | 271 sql::Connection* db) { |
| 335 std::vector<base::string16> first_names; | 272 std::vector<base::string16> first_names; |
| 336 profile.GetRawMultiInfo(NAME_FIRST, &first_names); | 273 profile.GetRawMultiInfo(NAME_FIRST, &first_names); |
| 337 std::vector<base::string16> middle_names; | 274 std::vector<base::string16> middle_names; |
| 338 profile.GetRawMultiInfo(NAME_MIDDLE, &middle_names); | 275 profile.GetRawMultiInfo(NAME_MIDDLE, &middle_names); |
| 339 std::vector<base::string16> last_names; | 276 std::vector<base::string16> last_names; |
| 340 profile.GetRawMultiInfo(NAME_LAST, &last_names); | 277 profile.GetRawMultiInfo(NAME_LAST, &last_names); |
| 341 std::vector<base::string16> full_names; | 278 std::vector<base::string16> full_names; |
| 342 profile.GetRawMultiInfo(NAME_FULL, &full_names); | 279 profile.GetRawMultiInfo(NAME_FULL, &full_names); |
| (...skipping 161 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 504 } | 441 } |
| 505 | 442 |
| 506 bool AutofillTable::IsSyncable() { | 443 bool AutofillTable::IsSyncable() { |
| 507 return true; | 444 return true; |
| 508 } | 445 } |
| 509 | 446 |
| 510 bool AutofillTable::MigrateToVersion(int version, | 447 bool AutofillTable::MigrateToVersion(int version, |
| 511 bool* update_compatible_version) { | 448 bool* update_compatible_version) { |
| 512 // Migrate if necessary. | 449 // Migrate if necessary. |
| 513 switch (version) { | 450 switch (version) { |
| 514 case 22: | |
| 515 return MigrateToVersion22ClearAutofillEmptyValueElements(); | |
| 516 case 23: | |
| 517 return MigrateToVersion23AddCardNumberEncryptedColumn(); | |
| 518 case 24: | |
| 519 return MigrateToVersion24CleanupOversizedStringFields(); | |
| 520 case 27: | |
| 521 *update_compatible_version = true; | |
| 522 return MigrateToVersion27UpdateLegacyCreditCards(); | |
| 523 case 30: | |
| 524 *update_compatible_version = true; | |
| 525 return MigrateToVersion30AddDateModifed(); | |
| 526 case 31: | |
| 527 *update_compatible_version = true; | |
| 528 return MigrateToVersion31AddGUIDToCreditCardsAndProfiles(); | |
| 529 case 32: | |
| 530 *update_compatible_version = true; | |
| 531 return MigrateToVersion32UpdateProfilesAndCreditCards(); | |
| 532 case 33: | |
| 533 *update_compatible_version = true; | |
| 534 return MigrateToVersion33ProfilesBasedOnFirstName(); | |
| 535 case 34: | |
| 536 *update_compatible_version = true; | |
| 537 return MigrateToVersion34ProfilesBasedOnCountryCode(); | |
| 538 case 35: | |
| 539 *update_compatible_version = true; | |
| 540 return MigrateToVersion35GreatBritainCountryCodes(); | |
| 541 // Combine migrations 36 and 37. This is due to enhancements to the merge | |
| 542 // step when migrating profiles. The original migration from 35 to 36 did | |
| 543 // not merge profiles with identical addresses, but the migration from 36 to | |
| 544 // 37 does. The step from 35 to 36 should only happen on the Chrome 12 dev | |
| 545 // channel. Chrome 12 beta and release users will jump from 35 to 37 | |
| 546 // directly getting the full benefits of the multi-valued merge as well as | |
| 547 // the culling of bad data. | |
| 548 case 37: | |
| 549 *update_compatible_version = true; | |
| 550 return MigrateToVersion37MergeAndCullOlderProfiles(); | |
| 551 case 51: | |
| 552 // Combine migrations 50 and 51. The migration code from version 49 to 50 | |
| 553 // worked correctly for users with existing 'origin' columns, but failed | |
| 554 // to create these columns for new users. | |
| 555 return MigrateToVersion51AddOriginColumn(); | |
| 556 case 54: | 451 case 54: |
| 557 *update_compatible_version = true; | 452 *update_compatible_version = true; |
| 558 return MigrateToVersion54AddI18nFieldsAndRemoveDeprecatedFields(); | 453 return MigrateToVersion54AddI18nFieldsAndRemoveDeprecatedFields(); |
| 559 case 55: | 454 case 55: |
| 560 *update_compatible_version = true; | 455 *update_compatible_version = true; |
| 561 return MigrateToVersion55MergeAutofillDatesTable(); | 456 return MigrateToVersion55MergeAutofillDatesTable(); |
| 562 case 56: | 457 case 56: |
| 563 *update_compatible_version = true; | 458 *update_compatible_version = true; |
| 564 return MigrateToVersion56AddProfileLanguageCodeForFormatting(); | 459 return MigrateToVersion56AddProfileLanguageCodeForFormatting(); |
| 565 case 57: | 460 case 57: |
| (...skipping 1222 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1788 "sorting_code VARCHAR," | 1683 "sorting_code VARCHAR," |
| 1789 "country_code VARCHAR," | 1684 "country_code VARCHAR," |
| 1790 "language_code VARCHAR)")) { | 1685 "language_code VARCHAR)")) { |
| 1791 NOTREACHED(); | 1686 NOTREACHED(); |
| 1792 return false; | 1687 return false; |
| 1793 } | 1688 } |
| 1794 } | 1689 } |
| 1795 return true; | 1690 return true; |
| 1796 } | 1691 } |
| 1797 | 1692 |
| 1798 bool AutofillTable::MigrateToVersion22ClearAutofillEmptyValueElements() { | |
| 1799 if (!db_->DoesTableExist("autofill") && | |
| 1800 (!db_->Execute("CREATE TABLE autofill (" | |
| 1801 " name VARCHAR," | |
| 1802 " value VARCHAR," | |
| 1803 " value_lower VARCHAR," | |
| 1804 " pair_id INTEGER PRIMARY KEY," | |
| 1805 " count INTEGER DEFAULT 1)") || | |
| 1806 !db_->Execute("CREATE INDEX autofill_name ON autofill (name)") || | |
| 1807 !db_->Execute("CREATE INDEX autofill_name_value_lower ON" | |
| 1808 " autofill (name, value_lower)") || | |
| 1809 !db_->Execute("CREATE TABLE autofill_dates (" | |
| 1810 " pair_id INTEGER DEFAULT 0," | |
| 1811 " date_created INTEGER DEFAULT 0)") || | |
| 1812 !db_->Execute("CREATE INDEX autofill_dates_pair_id ON" | |
| 1813 " autofill (pair_id)"))) | |
| 1814 return false; | |
| 1815 | |
| 1816 | |
| 1817 sql::Statement s(db_->GetUniqueStatement( | |
| 1818 "SELECT pair_id FROM autofill WHERE TRIM(value) = \"\"")); | |
| 1819 if (!s.is_valid()) | |
| 1820 return false; | |
| 1821 | |
| 1822 std::set<int64> ids; | |
| 1823 while (s.Step()) | |
| 1824 ids.insert(s.ColumnInt64(0)); | |
| 1825 if (!s.Succeeded()) | |
| 1826 return false; | |
| 1827 | |
| 1828 if (!db_->Execute("DELETE FROM autofill WHERE TRIM(value) = \"\"")) | |
| 1829 return false; | |
| 1830 | |
| 1831 for (std::set<int64>::const_iterator it = ids.begin(); it != ids.end(); | |
| 1832 ++it) { | |
| 1833 sql::Statement s(db_->GetUniqueStatement( | |
| 1834 "DELETE FROM autofill_dates WHERE pair_id = ?")); | |
| 1835 s.BindInt64(0, *it); | |
| 1836 if (!s.Run()) | |
| 1837 return false; | |
| 1838 } | |
| 1839 | |
| 1840 return true; | |
| 1841 } | |
| 1842 | |
| 1843 // Add the card_number_encrypted column if credit card table was not | |
| 1844 // created in this build (otherwise the column already exists). | |
| 1845 // WARNING: Do not change the order of the execution of the SQL | |
| 1846 // statements in this case! Profile corruption and data migration | |
| 1847 // issues WILL OCCUR. See http://crbug.com/10913 | |
| 1848 // | |
| 1849 // The problem is that if a user has a profile which was created before | |
| 1850 // r37036, when the credit_cards table was added, and then failed to | |
| 1851 // update this profile between the credit card addition and the addition | |
| 1852 // of the "encrypted" columns (44963), the next data migration will put | |
| 1853 // the user's profile in an incoherent state: The user will update from | |
| 1854 // a data profile set to be earlier than 22, and therefore pass through | |
| 1855 // this update case. But because the user did not have a credit_cards | |
| 1856 // table before starting Chrome, it will have just been initialized | |
| 1857 // above, and so already have these columns -- and thus this data | |
| 1858 // update step will have failed. | |
| 1859 // | |
| 1860 // The false assumption in this case is that at this step in the | |
| 1861 // migration, the user has a credit card table, and that this | |
| 1862 // table does not include encrypted columns! | |
| 1863 // Because this case does not roll back the complete set of SQL | |
| 1864 // transactions properly in case of failure (that is, it does not | |
| 1865 // roll back the table initialization done above), the incoherent | |
| 1866 // profile will now see itself as being at version 22 -- but include a | |
| 1867 // fully initialized credit_cards table. Every time Chrome runs, it | |
| 1868 // will try to update the web database and fail at this step, unless | |
| 1869 // we allow for the faulty assumption described above by checking for | |
| 1870 // the existence of the columns only AFTER we've executed the commands | |
| 1871 // to add them. | |
| 1872 bool AutofillTable::MigrateToVersion23AddCardNumberEncryptedColumn() { | |
| 1873 if (!db_->DoesTableExist("autofill_profiles") && | |
| 1874 (!db_->Execute("CREATE TABLE autofill_profiles ( " | |
| 1875 "label VARCHAR, " | |
| 1876 "unique_id INTEGER PRIMARY KEY, " | |
| 1877 "first_name VARCHAR, " | |
| 1878 "middle_name VARCHAR, " | |
| 1879 "last_name VARCHAR, " | |
| 1880 "email VARCHAR, " | |
| 1881 "company_name VARCHAR, " | |
| 1882 "address_line_1 VARCHAR, " | |
| 1883 "address_line_2 VARCHAR, " | |
| 1884 "city VARCHAR, " | |
| 1885 "state VARCHAR, " | |
| 1886 "zipcode VARCHAR, " | |
| 1887 "country VARCHAR, " | |
| 1888 "phone VARCHAR, " | |
| 1889 "fax VARCHAR)") || | |
| 1890 !db_->Execute("CREATE INDEX autofill_profiles_label_index" | |
| 1891 " ON autofill_profiles (label)"))) | |
| 1892 return false; | |
| 1893 | |
| 1894 if (!db_->DoesTableExist("credit_cards") && | |
| 1895 (!db_->Execute("CREATE TABLE credit_cards ( " | |
| 1896 "label VARCHAR, " | |
| 1897 "unique_id INTEGER PRIMARY KEY, " | |
| 1898 "name_on_card VARCHAR, " | |
| 1899 "type VARCHAR, " | |
| 1900 "card_number VARCHAR, " | |
| 1901 "expiration_month INTEGER, " | |
| 1902 "expiration_year INTEGER, " | |
| 1903 "verification_code VARCHAR, " | |
| 1904 "billing_address VARCHAR, " | |
| 1905 "shipping_address VARCHAR)") || | |
| 1906 !db_->Execute("CREATE INDEX credit_cards_label_index" | |
| 1907 " ON credit_cards (label)"))) | |
| 1908 return false; | |
| 1909 | |
| 1910 if (!db_->DoesColumnExist("credit_cards", "card_number_encrypted")) { | |
| 1911 if (!db_->Execute("ALTER TABLE credit_cards ADD COLUMN " | |
| 1912 "card_number_encrypted BLOB DEFAULT NULL")) { | |
| 1913 return false; | |
| 1914 } | |
| 1915 } | |
| 1916 | |
| 1917 if (!db_->DoesColumnExist("credit_cards", "verification_code_encrypted")) { | |
| 1918 if (!db_->Execute("ALTER TABLE credit_cards ADD COLUMN " | |
| 1919 "verification_code_encrypted BLOB DEFAULT NULL")) { | |
| 1920 return false; | |
| 1921 } | |
| 1922 } | |
| 1923 | |
| 1924 return true; | |
| 1925 } | |
| 1926 | |
| 1927 // One-time cleanup for http://crbug.com/38364 - In the presence of | |
| 1928 // multi-byte UTF-8 characters, that bug could cause Autofill strings | |
| 1929 // to grow larger and more corrupt with each save. The cleanup removes | |
| 1930 // any row with a string field larger than a reasonable size. The string | |
| 1931 // fields examined here are precisely the ones that were subject to | |
| 1932 // corruption by the original bug. | |
| 1933 bool AutofillTable::MigrateToVersion24CleanupOversizedStringFields() { | |
| 1934 const std::string autofill_is_too_big = | |
| 1935 "max(length(name), length(value)) > 500"; | |
| 1936 | |
| 1937 const std::string credit_cards_is_too_big = | |
| 1938 "max(length(label), length(name_on_card), length(type), " | |
| 1939 " length(expiration_month), length(expiration_year), " | |
| 1940 " length(billing_address), length(shipping_address) " | |
| 1941 ") > 500"; | |
| 1942 | |
| 1943 const std::string autofill_profiles_is_too_big = | |
| 1944 "max(length(label), length(first_name), " | |
| 1945 " length(middle_name), length(last_name), length(email), " | |
| 1946 " length(company_name), length(address_line_1), " | |
| 1947 " length(address_line_2), length(city), length(state), " | |
| 1948 " length(zipcode), length(country), length(phone)) > 500"; | |
| 1949 | |
| 1950 std::string query = "DELETE FROM autofill_dates WHERE pair_id IN (" | |
| 1951 "SELECT pair_id FROM autofill WHERE " + autofill_is_too_big + ")"; | |
| 1952 | |
| 1953 if (!db_->Execute(query.c_str())) | |
| 1954 return false; | |
| 1955 | |
| 1956 query = "DELETE FROM autofill WHERE " + autofill_is_too_big; | |
| 1957 | |
| 1958 if (!db_->Execute(query.c_str())) | |
| 1959 return false; | |
| 1960 | |
| 1961 // Only delete from legacy credit card tables where specific columns exist. | |
| 1962 if (db_->DoesColumnExist("credit_cards", "label") && | |
| 1963 db_->DoesColumnExist("credit_cards", "name_on_card") && | |
| 1964 db_->DoesColumnExist("credit_cards", "type") && | |
| 1965 db_->DoesColumnExist("credit_cards", "expiration_month") && | |
| 1966 db_->DoesColumnExist("credit_cards", "expiration_year") && | |
| 1967 db_->DoesColumnExist("credit_cards", "billing_address") && | |
| 1968 db_->DoesColumnExist("credit_cards", "shipping_address") && | |
| 1969 db_->DoesColumnExist("autofill_profiles", "label")) { | |
| 1970 query = "DELETE FROM credit_cards WHERE (" + credit_cards_is_too_big + | |
| 1971 ") OR label IN (SELECT label FROM autofill_profiles WHERE " + | |
| 1972 autofill_profiles_is_too_big + ")"; | |
| 1973 | |
| 1974 if (!db_->Execute(query.c_str())) | |
| 1975 return false; | |
| 1976 } | |
| 1977 | |
| 1978 if (db_->DoesColumnExist("autofill_profiles", "label")) { | |
| 1979 query = "DELETE FROM autofill_profiles WHERE " + | |
| 1980 autofill_profiles_is_too_big; | |
| 1981 | |
| 1982 if (!db_->Execute(query.c_str())) | |
| 1983 return false; | |
| 1984 } | |
| 1985 | |
| 1986 return true; | |
| 1987 } | |
| 1988 | |
| 1989 // Change the credit_cards.billing_address column from a string to an | |
| 1990 // int. The stored string is the label of an address, so we have to | |
| 1991 // select the unique ID of this address using the label as a foreign | |
| 1992 // key into the |autofill_profiles| table. | |
| 1993 bool AutofillTable::MigrateToVersion27UpdateLegacyCreditCards() { | |
| 1994 // Only migrate from legacy credit card tables where specific columns | |
| 1995 // exist. | |
| 1996 if (!(db_->DoesColumnExist("credit_cards", "unique_id") && | |
| 1997 db_->DoesColumnExist("credit_cards", "billing_address") && | |
| 1998 db_->DoesColumnExist("autofill_profiles", "unique_id"))) { | |
| 1999 return true; | |
| 2000 } | |
| 2001 | |
| 2002 std::string stmt = | |
| 2003 "SELECT credit_cards.unique_id, autofill_profiles.unique_id " | |
| 2004 "FROM autofill_profiles, credit_cards " | |
| 2005 "WHERE credit_cards.billing_address = autofill_profiles.label"; | |
| 2006 sql::Statement s(db_->GetUniqueStatement(stmt.c_str())); | |
| 2007 | |
| 2008 std::map<int, int> cc_billing_map; | |
| 2009 while (s.Step()) | |
| 2010 cc_billing_map[s.ColumnInt(0)] = s.ColumnInt(1); | |
| 2011 if (!s.Succeeded()) | |
| 2012 return false; | |
| 2013 | |
| 2014 // Windows already stores the IDs as strings in |billing_address|. Try | |
| 2015 // to convert those. | |
| 2016 if (cc_billing_map.empty()) { | |
| 2017 std::string stmt = "SELECT unique_id,billing_address FROM credit_cards"; | |
| 2018 sql::Statement s(db_->GetUniqueStatement(stmt.c_str())); | |
| 2019 | |
| 2020 while (s.Step()) { | |
| 2021 int id = 0; | |
| 2022 if (base::StringToInt(s.ColumnString(1), &id)) | |
| 2023 cc_billing_map[s.ColumnInt(0)] = id; | |
| 2024 } | |
| 2025 if (!s.Succeeded()) | |
| 2026 return false; | |
| 2027 } | |
| 2028 | |
| 2029 if (!db_->Execute("CREATE TABLE credit_cards_temp ( " | |
| 2030 "label VARCHAR, " | |
| 2031 "unique_id INTEGER PRIMARY KEY, " | |
| 2032 "name_on_card VARCHAR, " | |
| 2033 "type VARCHAR, " | |
| 2034 "card_number VARCHAR, " | |
| 2035 "expiration_month INTEGER, " | |
| 2036 "expiration_year INTEGER, " | |
| 2037 "verification_code VARCHAR, " | |
| 2038 "billing_address INTEGER, " | |
| 2039 "shipping_address VARCHAR, " | |
| 2040 "card_number_encrypted BLOB, " | |
| 2041 "verification_code_encrypted BLOB)")) { | |
| 2042 return false; | |
| 2043 } | |
| 2044 | |
| 2045 if (!db_->Execute( | |
| 2046 "INSERT INTO credit_cards_temp " | |
| 2047 "SELECT label,unique_id,name_on_card,type,card_number," | |
| 2048 "expiration_month,expiration_year,verification_code,0," | |
| 2049 "shipping_address,card_number_encrypted," | |
| 2050 "verification_code_encrypted FROM credit_cards")) { | |
| 2051 return false; | |
| 2052 } | |
| 2053 | |
| 2054 if (!db_->Execute("DROP TABLE credit_cards")) | |
| 2055 return false; | |
| 2056 | |
| 2057 if (!db_->Execute("ALTER TABLE credit_cards_temp RENAME TO credit_cards")) | |
| 2058 return false; | |
| 2059 | |
| 2060 for (std::map<int, int>::const_iterator iter = cc_billing_map.begin(); | |
| 2061 iter != cc_billing_map.end(); ++iter) { | |
| 2062 sql::Statement s(db_->GetCachedStatement( | |
| 2063 SQL_FROM_HERE, | |
| 2064 "UPDATE credit_cards SET billing_address=? WHERE unique_id=?")); | |
| 2065 s.BindInt(0, (*iter).second); | |
| 2066 s.BindInt(1, (*iter).first); | |
| 2067 | |
| 2068 if (!s.Run()) | |
| 2069 return false; | |
| 2070 } | |
| 2071 | |
| 2072 return true; | |
| 2073 } | |
| 2074 | |
| 2075 bool AutofillTable::MigrateToVersion30AddDateModifed() { | |
| 2076 // Add date_modified to autofill_profiles. | |
| 2077 if (!db_->DoesColumnExist("autofill_profiles", "date_modified")) { | |
| 2078 if (!db_->Execute("ALTER TABLE autofill_profiles ADD COLUMN " | |
| 2079 "date_modified INTEGER NON NULL DEFAULT 0")) { | |
| 2080 return false; | |
| 2081 } | |
| 2082 | |
| 2083 sql::Statement s(db_->GetUniqueStatement( | |
| 2084 "UPDATE autofill_profiles SET date_modified=?")); | |
| 2085 s.BindInt64(0, Time::Now().ToTimeT()); | |
| 2086 | |
| 2087 if (!s.Run()) | |
| 2088 return false; | |
| 2089 } | |
| 2090 | |
| 2091 // Add date_modified to credit_cards. | |
| 2092 if (!db_->DoesColumnExist("credit_cards", "date_modified")) { | |
| 2093 if (!db_->Execute("ALTER TABLE credit_cards ADD COLUMN " | |
| 2094 "date_modified INTEGER NON NULL DEFAULT 0")) { | |
| 2095 return false; | |
| 2096 } | |
| 2097 | |
| 2098 sql::Statement s(db_->GetUniqueStatement( | |
| 2099 "UPDATE credit_cards SET date_modified=?")); | |
| 2100 s.BindInt64(0, Time::Now().ToTimeT()); | |
| 2101 | |
| 2102 if (!s.Run()) | |
| 2103 return false; | |
| 2104 } | |
| 2105 | |
| 2106 return true; | |
| 2107 } | |
| 2108 | |
| 2109 bool AutofillTable::MigrateToVersion31AddGUIDToCreditCardsAndProfiles() { | |
| 2110 // Note that we need to check for the guid column's existence due to the | |
| 2111 // fact that for a version 22 database the |autofill_profiles| table | |
| 2112 // gets created fresh with |InitAutofillProfilesTable|. | |
| 2113 if (!db_->DoesColumnExist("autofill_profiles", "guid")) { | |
| 2114 if (!db_->Execute("ALTER TABLE autofill_profiles ADD COLUMN " | |
| 2115 "guid VARCHAR NOT NULL DEFAULT \"\"")) { | |
| 2116 return false; | |
| 2117 } | |
| 2118 | |
| 2119 // Set all the |guid| fields to valid values. | |
| 2120 | |
| 2121 sql::Statement s(db_->GetUniqueStatement("SELECT unique_id " | |
| 2122 "FROM autofill_profiles")); | |
| 2123 | |
| 2124 while (s.Step()) { | |
| 2125 sql::Statement update_s( | |
| 2126 db_->GetUniqueStatement("UPDATE autofill_profiles " | |
| 2127 "SET guid=? WHERE unique_id=?")); | |
| 2128 update_s.BindString(0, base::GenerateGUID()); | |
| 2129 update_s.BindInt(1, s.ColumnInt(0)); | |
| 2130 | |
| 2131 if (!update_s.Run()) | |
| 2132 return false; | |
| 2133 } | |
| 2134 if (!s.Succeeded()) | |
| 2135 return false; | |
| 2136 } | |
| 2137 | |
| 2138 // Note that we need to check for the guid column's existence due to the | |
| 2139 // fact that for a version 22 database the |autofill_profiles| table | |
| 2140 // gets created fresh with |InitAutofillProfilesTable|. | |
| 2141 if (!db_->DoesColumnExist("credit_cards", "guid")) { | |
| 2142 if (!db_->Execute("ALTER TABLE credit_cards ADD COLUMN " | |
| 2143 "guid VARCHAR NOT NULL DEFAULT \"\"")) { | |
| 2144 return false; | |
| 2145 } | |
| 2146 | |
| 2147 // Set all the |guid| fields to valid values. | |
| 2148 | |
| 2149 sql::Statement s(db_->GetUniqueStatement("SELECT unique_id " | |
| 2150 "FROM credit_cards")); | |
| 2151 | |
| 2152 while (s.Step()) { | |
| 2153 sql::Statement update_s( | |
| 2154 db_->GetUniqueStatement("UPDATE credit_cards " | |
| 2155 "set guid=? WHERE unique_id=?")); | |
| 2156 update_s.BindString(0, base::GenerateGUID()); | |
| 2157 update_s.BindInt(1, s.ColumnInt(0)); | |
| 2158 | |
| 2159 if (!update_s.Run()) | |
| 2160 return false; | |
| 2161 } | |
| 2162 if (!s.Succeeded()) | |
| 2163 return false; | |
| 2164 } | |
| 2165 | |
| 2166 return true; | |
| 2167 } | |
| 2168 | |
| 2169 bool AutofillTable::MigrateToVersion32UpdateProfilesAndCreditCards() { | |
| 2170 if (db_->DoesColumnExist("autofill_profiles", "unique_id")) { | |
| 2171 if (!db_->Execute("CREATE TABLE autofill_profiles_temp ( " | |
| 2172 "guid VARCHAR PRIMARY KEY, " | |
| 2173 "label VARCHAR, " | |
| 2174 "first_name VARCHAR, " | |
| 2175 "middle_name VARCHAR, " | |
| 2176 "last_name VARCHAR, " | |
| 2177 "email VARCHAR, " | |
| 2178 "company_name VARCHAR, " | |
| 2179 "address_line_1 VARCHAR, " | |
| 2180 "address_line_2 VARCHAR, " | |
| 2181 "city VARCHAR, " | |
| 2182 "state VARCHAR, " | |
| 2183 "zipcode VARCHAR, " | |
| 2184 "country VARCHAR, " | |
| 2185 "phone VARCHAR, " | |
| 2186 "date_modified INTEGER NOT NULL DEFAULT 0)")) { | |
| 2187 return false; | |
| 2188 } | |
| 2189 | |
| 2190 if (!db_->Execute( | |
| 2191 "INSERT INTO autofill_profiles_temp " | |
| 2192 "SELECT guid, label, first_name, middle_name, last_name, email, " | |
| 2193 "company_name, address_line_1, address_line_2, city, state, " | |
| 2194 "zipcode, country, phone, date_modified " | |
| 2195 "FROM autofill_profiles")) { | |
| 2196 return false; | |
| 2197 } | |
| 2198 | |
| 2199 if (!db_->Execute("DROP TABLE autofill_profiles")) | |
| 2200 return false; | |
| 2201 | |
| 2202 if (!db_->Execute( | |
| 2203 "ALTER TABLE autofill_profiles_temp RENAME TO autofill_profiles")) { | |
| 2204 return false; | |
| 2205 } | |
| 2206 } | |
| 2207 | |
| 2208 if (db_->DoesColumnExist("credit_cards", "unique_id")) { | |
| 2209 if (!db_->Execute("CREATE TABLE credit_cards_temp ( " | |
| 2210 "guid VARCHAR PRIMARY KEY, " | |
| 2211 "label VARCHAR, " | |
| 2212 "name_on_card VARCHAR, " | |
| 2213 "expiration_month INTEGER, " | |
| 2214 "expiration_year INTEGER, " | |
| 2215 "card_number_encrypted BLOB, " | |
| 2216 "date_modified INTEGER NOT NULL DEFAULT 0)")) { | |
| 2217 return false; | |
| 2218 } | |
| 2219 | |
| 2220 if (!db_->Execute( | |
| 2221 "INSERT INTO credit_cards_temp " | |
| 2222 "SELECT guid, label, name_on_card, expiration_month, " | |
| 2223 "expiration_year, card_number_encrypted, date_modified " | |
| 2224 "FROM credit_cards")) { | |
| 2225 return false; | |
| 2226 } | |
| 2227 | |
| 2228 if (!db_->Execute("DROP TABLE credit_cards")) | |
| 2229 return false; | |
| 2230 | |
| 2231 if (!db_->Execute("ALTER TABLE credit_cards_temp RENAME TO credit_cards")) | |
| 2232 return false; | |
| 2233 } | |
| 2234 | |
| 2235 return true; | |
| 2236 } | |
| 2237 | |
| 2238 // Test the existence of the |first_name| column as an indication that | |
| 2239 // we need a migration. It is possible that the new |autofill_profiles| | |
| 2240 // schema is in place because the table was newly created when migrating | |
| 2241 // from a pre-version-22 database. | |
| 2242 bool AutofillTable::MigrateToVersion33ProfilesBasedOnFirstName() { | |
| 2243 if (!db_->DoesTableExist("autofill_profile_names") && | |
| 2244 !db_->Execute("CREATE TABLE autofill_profile_names ( " | |
| 2245 "guid VARCHAR, " | |
| 2246 "first_name VARCHAR, " | |
| 2247 "middle_name VARCHAR, " | |
| 2248 "last_name VARCHAR)")) | |
| 2249 return false; | |
| 2250 | |
| 2251 if (!db_->DoesTableExist("autofill_profile_emails") && | |
| 2252 !db_->Execute("CREATE TABLE autofill_profile_emails ( " | |
| 2253 "guid VARCHAR, " | |
| 2254 "email VARCHAR)")) | |
| 2255 return false; | |
| 2256 | |
| 2257 if (!db_->DoesTableExist("autofill_profile_phones") && | |
| 2258 !db_->Execute("CREATE TABLE autofill_profile_phones ( " | |
| 2259 "guid VARCHAR, " | |
| 2260 "type INTEGER DEFAULT 0, " | |
| 2261 "number VARCHAR)")) | |
| 2262 return false; | |
| 2263 | |
| 2264 if (db_->DoesColumnExist("autofill_profiles", "first_name")) { | |
| 2265 // Create autofill_profiles_temp table that will receive the data. | |
| 2266 if (!db_->DoesTableExist("autofill_profiles_temp")) { | |
| 2267 if (!db_->Execute("CREATE TABLE autofill_profiles_temp ( " | |
| 2268 "guid VARCHAR PRIMARY KEY, " | |
| 2269 "company_name VARCHAR, " | |
| 2270 "address_line_1 VARCHAR, " | |
| 2271 "address_line_2 VARCHAR, " | |
| 2272 "city VARCHAR, " | |
| 2273 "state VARCHAR, " | |
| 2274 "zipcode VARCHAR, " | |
| 2275 "country VARCHAR, " | |
| 2276 "date_modified INTEGER NOT NULL DEFAULT 0)")) { | |
| 2277 return false; | |
| 2278 } | |
| 2279 } | |
| 2280 | |
| 2281 sql::Statement s(db_->GetUniqueStatement( | |
| 2282 "SELECT guid, first_name, middle_name, last_name, email, " | |
| 2283 "company_name, address_line_1, address_line_2, city, state, " | |
| 2284 "zipcode, country, phone, date_modified " | |
| 2285 "FROM autofill_profiles")); | |
| 2286 | |
| 2287 while (s.Step()) { | |
| 2288 AutofillProfile profile; | |
| 2289 int index = 0; | |
| 2290 profile.set_guid(s.ColumnString(index++)); | |
| 2291 DCHECK(base::IsValidGUID(profile.guid())); | |
| 2292 | |
| 2293 profile.SetRawInfo(NAME_FIRST, s.ColumnString16(index++)); | |
| 2294 profile.SetRawInfo(NAME_MIDDLE, s.ColumnString16(index++)); | |
| 2295 profile.SetRawInfo(NAME_LAST, s.ColumnString16(index++)); | |
| 2296 profile.SetRawInfo(EMAIL_ADDRESS, s.ColumnString16(index++)); | |
| 2297 profile.SetRawInfo(COMPANY_NAME, s.ColumnString16(index++)); | |
| 2298 profile.SetRawInfo(ADDRESS_HOME_LINE1, s.ColumnString16(index++)); | |
| 2299 profile.SetRawInfo(ADDRESS_HOME_LINE2, s.ColumnString16(index++)); | |
| 2300 profile.SetRawInfo(ADDRESS_HOME_CITY, s.ColumnString16(index++)); | |
| 2301 profile.SetRawInfo(ADDRESS_HOME_STATE, s.ColumnString16(index++)); | |
| 2302 profile.SetRawInfo(ADDRESS_HOME_ZIP, s.ColumnString16(index++)); | |
| 2303 profile.SetInfo(AutofillType(ADDRESS_HOME_COUNTRY), | |
| 2304 s.ColumnString16(index++), app_locale_); | |
| 2305 profile.SetRawInfo(PHONE_HOME_WHOLE_NUMBER, s.ColumnString16(index++)); | |
| 2306 int64 date_modified = s.ColumnInt64(index++); | |
| 2307 | |
| 2308 sql::Statement s_insert(db_->GetUniqueStatement( | |
| 2309 "INSERT INTO autofill_profiles_temp" | |
| 2310 "(guid, company_name, address_line_1, address_line_2, city," | |
| 2311 " state, zipcode, country, date_modified)" | |
| 2312 "VALUES (?,?,?,?,?,?,?,?,?)")); | |
| 2313 index = 0; | |
| 2314 s_insert.BindString(index++, profile.guid()); | |
| 2315 s_insert.BindString16(index++, profile.GetRawInfo(COMPANY_NAME)); | |
| 2316 s_insert.BindString16(index++, profile.GetRawInfo(ADDRESS_HOME_LINE1)); | |
| 2317 s_insert.BindString16(index++, profile.GetRawInfo(ADDRESS_HOME_LINE2)); | |
| 2318 s_insert.BindString16(index++, profile.GetRawInfo(ADDRESS_HOME_CITY)); | |
| 2319 s_insert.BindString16(index++, profile.GetRawInfo(ADDRESS_HOME_STATE)); | |
| 2320 s_insert.BindString16(index++, profile.GetRawInfo(ADDRESS_HOME_ZIP)); | |
| 2321 s_insert.BindString16(index++, profile.GetRawInfo(ADDRESS_HOME_COUNTRY)); | |
| 2322 s_insert.BindInt64(index++, date_modified); | |
| 2323 | |
| 2324 if (!s_insert.Run()) | |
| 2325 return false; | |
| 2326 | |
| 2327 // Add the other bits: names, emails, and phone numbers. | |
| 2328 if (!AddAutofillProfileNamesForVersion3x(profile, db_) || | |
| 2329 !AddAutofillProfileEmails(profile, db_) || | |
| 2330 !AddAutofillProfilePhones(profile, db_)) { | |
| 2331 return false; | |
| 2332 } | |
| 2333 } // endwhile | |
| 2334 if (!s.Succeeded()) | |
| 2335 return false; | |
| 2336 | |
| 2337 if (!db_->Execute("DROP TABLE autofill_profiles")) | |
| 2338 return false; | |
| 2339 | |
| 2340 if (!db_->Execute( | |
| 2341 "ALTER TABLE autofill_profiles_temp RENAME TO autofill_profiles")) { | |
| 2342 return false; | |
| 2343 } | |
| 2344 } | |
| 2345 | |
| 2346 // Remove the labels column from the credit_cards table. | |
| 2347 if (db_->DoesColumnExist("credit_cards", "label")) { | |
| 2348 if (!db_->Execute("CREATE TABLE credit_cards_temp ( " | |
| 2349 "guid VARCHAR PRIMARY KEY, " | |
| 2350 "name_on_card VARCHAR, " | |
| 2351 "expiration_month INTEGER, " | |
| 2352 "expiration_year INTEGER, " | |
| 2353 "card_number_encrypted BLOB, " | |
| 2354 "date_modified INTEGER NOT NULL DEFAULT 0)")) { | |
| 2355 return false; | |
| 2356 } | |
| 2357 | |
| 2358 if (!db_->Execute( | |
| 2359 "INSERT INTO credit_cards_temp " | |
| 2360 "SELECT guid, name_on_card, expiration_month, " | |
| 2361 "expiration_year, card_number_encrypted, date_modified " | |
| 2362 "FROM credit_cards")) { | |
| 2363 return false; | |
| 2364 } | |
| 2365 | |
| 2366 if (!db_->Execute("DROP TABLE credit_cards")) | |
| 2367 return false; | |
| 2368 | |
| 2369 if (!db_->Execute("ALTER TABLE credit_cards_temp RENAME TO credit_cards")) | |
| 2370 return false; | |
| 2371 } | |
| 2372 | |
| 2373 return true; | |
| 2374 } | |
| 2375 | |
| 2376 // Test the existence of the |country_code| column as an indication that | |
| 2377 // we need a migration. It is possible that the new |autofill_profiles| | |
| 2378 // schema is in place because the table was newly created when migrating | |
| 2379 // from a pre-version-22 database. | |
| 2380 bool AutofillTable::MigrateToVersion34ProfilesBasedOnCountryCode() { | |
| 2381 if (!db_->DoesColumnExist("autofill_profiles", "country_code")) { | |
| 2382 if (!db_->Execute("ALTER TABLE autofill_profiles ADD COLUMN " | |
| 2383 "country_code VARCHAR")) { | |
| 2384 return false; | |
| 2385 } | |
| 2386 | |
| 2387 // Set all the |country_code| fields to match existing |country| values. | |
| 2388 sql::Statement s(db_->GetUniqueStatement("SELECT guid, country " | |
| 2389 "FROM autofill_profiles")); | |
| 2390 | |
| 2391 while (s.Step()) { | |
| 2392 sql::Statement update_s( | |
| 2393 db_->GetUniqueStatement("UPDATE autofill_profiles " | |
| 2394 "SET country_code=? WHERE guid=?")); | |
| 2395 | |
| 2396 base::string16 country = s.ColumnString16(1); | |
| 2397 update_s.BindString(0, AutofillCountry::GetCountryCode(country, | |
| 2398 app_locale_)); | |
| 2399 update_s.BindString(1, s.ColumnString(0)); | |
| 2400 | |
| 2401 if (!update_s.Run()) | |
| 2402 return false; | |
| 2403 } | |
| 2404 if (!s.Succeeded()) | |
| 2405 return false; | |
| 2406 } | |
| 2407 | |
| 2408 return true; | |
| 2409 } | |
| 2410 | |
| 2411 // Correct all country codes with value "UK" to be "GB". This data | |
| 2412 // was mistakenly introduced in build 686.0. This migration is to clean | |
| 2413 // it up. See http://crbug.com/74511 for details. | |
| 2414 bool AutofillTable::MigrateToVersion35GreatBritainCountryCodes() { | |
| 2415 sql::Statement s(db_->GetUniqueStatement( | |
| 2416 "UPDATE autofill_profiles SET country_code=\"GB\" " | |
| 2417 "WHERE country_code=\"UK\"")); | |
| 2418 | |
| 2419 return s.Run(); | |
| 2420 } | |
| 2421 | |
| 2422 // Merge and cull older profiles where possible. | |
| 2423 bool AutofillTable::MigrateToVersion37MergeAndCullOlderProfiles() { | |
| 2424 if (!db_->DoesTableExist("autofill_profiles_trash") && | |
| 2425 !db_->Execute("CREATE TABLE autofill_profiles_trash (guid VARCHAR)")) | |
| 2426 return false; | |
| 2427 | |
| 2428 sql::Statement s(db_->GetUniqueStatement( | |
| 2429 "SELECT guid, date_modified FROM autofill_profiles")); | |
| 2430 | |
| 2431 // Accumulate the good profiles. | |
| 2432 std::vector<AutofillProfile> accumulated_profiles; | |
| 2433 std::vector<AutofillProfile*> accumulated_profiles_p; | |
| 2434 std::map<std::string, int64> modification_map; | |
| 2435 while (s.Step()) { | |
| 2436 std::string guid = s.ColumnString(0); | |
| 2437 int64 date_modified = s.ColumnInt64(1); | |
| 2438 modification_map.insert( | |
| 2439 std::pair<std::string, int64>(guid, date_modified)); | |
| 2440 | |
| 2441 sql::Statement s(db_->GetUniqueStatement( | |
| 2442 "SELECT guid, company_name, address_line_1, address_line_2, city, " | |
| 2443 " state, zipcode, country, country_code, date_modified " | |
| 2444 "FROM autofill_profiles " | |
| 2445 "WHERE guid=?")); | |
| 2446 s.BindString(0, guid); | |
| 2447 | |
| 2448 if (!s.Step()) | |
| 2449 return false; | |
| 2450 | |
| 2451 scoped_ptr<AutofillProfile> profile(new AutofillProfile); | |
| 2452 int index = 0; | |
| 2453 profile->set_guid(s.ColumnString(index++)); | |
| 2454 DCHECK(base::IsValidGUID(profile->guid())); | |
| 2455 | |
| 2456 profile->SetRawInfo(COMPANY_NAME, s.ColumnString16(index++)); | |
| 2457 profile->SetRawInfo(ADDRESS_HOME_LINE1, s.ColumnString16(index++)); | |
| 2458 profile->SetRawInfo(ADDRESS_HOME_LINE2, s.ColumnString16(index++)); | |
| 2459 profile->SetRawInfo(ADDRESS_HOME_CITY, s.ColumnString16(index++)); | |
| 2460 profile->SetRawInfo(ADDRESS_HOME_STATE, s.ColumnString16(index++)); | |
| 2461 profile->SetRawInfo(ADDRESS_HOME_ZIP, s.ColumnString16(index++)); | |
| 2462 // Intentionally skip column 7, which stores the localized country name. | |
| 2463 index++; | |
| 2464 profile->SetRawInfo(ADDRESS_HOME_COUNTRY, s.ColumnString16(index++)); | |
| 2465 profile->set_modification_date( | |
| 2466 base::Time::FromTimeT(s.ColumnInt64(index++))); | |
| 2467 profile->set_origin(s.ColumnString(index++)); | |
| 2468 | |
| 2469 // Get associated name info. | |
| 2470 AddAutofillProfileNamesToProfileForVersion37(db_, profile.get()); | |
| 2471 | |
| 2472 // Get associated email info. | |
| 2473 AddAutofillProfileEmailsToProfile(db_, profile.get()); | |
| 2474 | |
| 2475 // Get associated phone info. | |
| 2476 AddAutofillProfilePhonesToProfile(db_, profile.get()); | |
| 2477 | |
| 2478 if (PersonalDataManager::IsValidLearnableProfile(*profile, app_locale_)) { | |
| 2479 std::vector<AutofillProfile> merged_profiles; | |
| 2480 std::string merged_guid = PersonalDataManager::MergeProfile( | |
| 2481 *profile, accumulated_profiles_p, app_locale_, &merged_profiles); | |
| 2482 | |
| 2483 std::swap(accumulated_profiles, merged_profiles); | |
| 2484 | |
| 2485 accumulated_profiles_p.clear(); | |
| 2486 accumulated_profiles_p.resize(accumulated_profiles.size()); | |
| 2487 std::transform(accumulated_profiles.begin(), | |
| 2488 accumulated_profiles.end(), | |
| 2489 accumulated_profiles_p.begin(), | |
| 2490 address_of<AutofillProfile>); | |
| 2491 | |
| 2492 // If the profile got merged trash the original. | |
| 2493 if (merged_guid != profile->guid()) | |
| 2494 AddAutofillGUIDToTrash(profile->guid()); | |
| 2495 } else { | |
| 2496 // An invalid profile, so trash it. | |
| 2497 AddAutofillGUIDToTrash(profile->guid()); | |
| 2498 } | |
| 2499 } // endwhile | |
| 2500 if (!s.Succeeded()) | |
| 2501 return false; | |
| 2502 | |
| 2503 // Drop the current profiles. | |
| 2504 if (!ClearAutofillProfiles()) | |
| 2505 return false; | |
| 2506 | |
| 2507 // Add the newly merged profiles back in. | |
| 2508 for (std::vector<AutofillProfile>::const_iterator | |
| 2509 iter = accumulated_profiles.begin(); | |
| 2510 iter != accumulated_profiles.end(); | |
| 2511 ++iter) { | |
| 2512 // Save the profile with its original modification date. | |
| 2513 std::map<std::string, int64>::const_iterator date_item = | |
| 2514 modification_map.find(iter->guid()); | |
| 2515 if (date_item == modification_map.end()) | |
| 2516 return false; | |
| 2517 | |
| 2518 sql::Statement s(db_->GetUniqueStatement( | |
| 2519 "INSERT INTO autofill_profiles" | |
| 2520 "(guid, company_name, address_line_1, address_line_2, city, state," | |
| 2521 " zipcode, country, country_code, date_modified)" | |
| 2522 "VALUES (?,?,?,?,?,?,?,?,?,?)")); | |
| 2523 int index = 0; | |
| 2524 s.BindString(index++, iter->guid()); | |
| 2525 s.BindString16(index++, GetInfo(*iter, COMPANY_NAME)); | |
| 2526 s.BindString16(index++, GetInfo(*iter, ADDRESS_HOME_LINE1)); | |
| 2527 s.BindString16(index++, GetInfo(*iter, ADDRESS_HOME_LINE2)); | |
| 2528 s.BindString16(index++, GetInfo(*iter, ADDRESS_HOME_CITY)); | |
| 2529 s.BindString16(index++, GetInfo(*iter, ADDRESS_HOME_STATE)); | |
| 2530 s.BindString16(index++, GetInfo(*iter, ADDRESS_HOME_ZIP)); | |
| 2531 s.BindString16(index++, base::string16()); // This column is deprecated. | |
| 2532 s.BindString16(index++, GetInfo(*iter, ADDRESS_HOME_COUNTRY)); | |
| 2533 s.BindInt64(index++, date_item->second); | |
| 2534 | |
| 2535 if (!s.Run()) | |
| 2536 return false; | |
| 2537 | |
| 2538 if (!AddAutofillProfileNamesForVersion3x(*iter, db_) || | |
| 2539 !AddAutofillProfileEmails(*iter, db_) || | |
| 2540 !AddAutofillProfilePhones(*iter, db_)) { | |
| 2541 return false; | |
| 2542 } | |
| 2543 } | |
| 2544 | |
| 2545 return true; | |
| 2546 } | |
| 2547 | |
| 2548 bool AutofillTable::MigrateToVersion51AddOriginColumn() { | |
| 2549 sql::Transaction transaction(db_); | |
| 2550 if (!transaction.Begin()) | |
| 2551 return false; | |
| 2552 | |
| 2553 // Add origin to autofill_profiles. | |
| 2554 if (!db_->DoesColumnExist("autofill_profiles", "origin") && | |
| 2555 !db_->Execute("ALTER TABLE autofill_profiles " | |
| 2556 "ADD COLUMN origin VARCHAR DEFAULT ''")) { | |
| 2557 return false; | |
| 2558 } | |
| 2559 | |
| 2560 // Add origin to credit_cards. | |
| 2561 if (!db_->DoesColumnExist("credit_cards", "origin") && | |
| 2562 !db_->Execute("ALTER TABLE credit_cards " | |
| 2563 "ADD COLUMN origin VARCHAR DEFAULT ''")) { | |
| 2564 return false; | |
| 2565 } | |
| 2566 | |
| 2567 return transaction.Commit(); | |
| 2568 } | |
| 2569 | |
| 2570 bool AutofillTable::MigrateToVersion54AddI18nFieldsAndRemoveDeprecatedFields() { | 1693 bool AutofillTable::MigrateToVersion54AddI18nFieldsAndRemoveDeprecatedFields() { |
| 2571 sql::Transaction transaction(db_); | 1694 sql::Transaction transaction(db_); |
| 2572 if (!transaction.Begin()) | 1695 if (!transaction.Begin()) |
| 2573 return false; | 1696 return false; |
| 2574 | 1697 |
| 2575 // Test the existence of the |address_line_1| column as an indication that a | 1698 // Test the existence of the |address_line_1| column as an indication that a |
| 2576 // migration is needed. It is possible that the new |autofill_profile_phones| | 1699 // migration is needed. It is possible that the new |autofill_profile_phones| |
| 2577 // schema is in place because the table was newly created when migrating from | 1700 // schema is in place because the table was newly created when migrating from |
| 2578 // a pre-version-23 database. | 1701 // a pre-version-23 database. |
| 2579 if (db_->DoesColumnExist("autofill_profiles", "address_line_1")) { | 1702 if (db_->DoesColumnExist("autofill_profiles", "address_line_1")) { |
| (...skipping 257 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2837 if (!db_->DoesColumnExist("unmasked_credit_cards", "use_date") && | 1960 if (!db_->DoesColumnExist("unmasked_credit_cards", "use_date") && |
| 2838 !db_->Execute("ALTER TABLE unmasked_credit_cards ADD COLUMN " | 1961 !db_->Execute("ALTER TABLE unmasked_credit_cards ADD COLUMN " |
| 2839 "use_date INTEGER NOT NULL DEFAULT 0")) { | 1962 "use_date INTEGER NOT NULL DEFAULT 0")) { |
| 2840 return false; | 1963 return false; |
| 2841 } | 1964 } |
| 2842 | 1965 |
| 2843 return transaction.Commit(); | 1966 return transaction.Commit(); |
| 2844 } | 1967 } |
| 2845 | 1968 |
| 2846 } // namespace autofill | 1969 } // namespace autofill |
| OLD | NEW |