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 |