| 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_country.h" |
| 20 #include "chrome/browser/autofill/autofill_profile.h" | 20 #include "chrome/browser/autofill/autofill_profile.h" |
| 21 #include "chrome/browser/autofill/autofill_type.h" | 21 #include "chrome/browser/autofill/autofill_type.h" |
| 22 #include "chrome/browser/autofill/credit_card.h" | 22 #include "chrome/browser/autofill/credit_card.h" |
| 23 #include "chrome/browser/autofill/personal_data_manager.h" |
| 23 #include "chrome/browser/diagnostics/sqlite_diagnostics.h" | 24 #include "chrome/browser/diagnostics/sqlite_diagnostics.h" |
| 24 #include "chrome/browser/history/history_database.h" | 25 #include "chrome/browser/history/history_database.h" |
| 25 #include "chrome/browser/password_manager/encryptor.h" | 26 #include "chrome/browser/password_manager/encryptor.h" |
| 26 #include "chrome/browser/search_engines/template_url.h" | 27 #include "chrome/browser/search_engines/template_url.h" |
| 27 #include "chrome/browser/webdata/autofill_change.h" | 28 #include "chrome/browser/webdata/autofill_change.h" |
| 28 #include "chrome/common/guid.h" | 29 #include "chrome/common/guid.h" |
| 29 #include "content/common/notification_service.h" | 30 #include "content/common/notification_service.h" |
| 30 #include "third_party/skia/include/core/SkBitmap.h" | 31 #include "third_party/skia/include/core/SkBitmap.h" |
| 31 #include "ui/base/l10n/l10n_util.h" | 32 #include "ui/base/l10n/l10n_util.h" |
| 32 #include "ui/gfx/codec/png_codec.h" | 33 #include "ui/gfx/codec/png_codec.h" |
| (...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 151 // autofill_profile_phones | 152 // autofill_profile_phones |
| 152 // This table contains the multi-valued phone fields | 153 // This table contains the multi-valued phone fields |
| 153 // associated with a profile. | 154 // associated with a profile. |
| 154 // | 155 // |
| 155 // guid The guid string that identifies the profile to which | 156 // guid The guid string that identifies the profile to which |
| 156 // the phone or fax number belongs. | 157 // the phone or fax number belongs. |
| 157 // type An integer constant designating either phone or fax type | 158 // type An integer constant designating either phone or fax type |
| 158 // of the number. | 159 // of the number. |
| 159 // number | 160 // number |
| 160 // | 161 // |
| 162 // autofill_profiles_trash |
| 163 // This table contains guids of "trashed" autofill |
| 164 // profiles. When a profile is removed its guid is added |
| 165 // to this table so that Sync can perform deferred removal. |
| 166 // |
| 167 // guid The guid string that identifies the trashed profile. |
| 168 // |
| 161 // credit_cards This table contains credit card data added by the user | 169 // credit_cards This table contains credit card data added by the user |
| 162 // with the AutoFill dialog. Most of the columns are | 170 // with the AutoFill dialog. Most of the columns are |
| 163 // standard entries in a credit card form. | 171 // standard entries in a credit card form. |
| 164 // | 172 // |
| 165 // guid A guid string to uniquely identify the profile. | 173 // guid A guid string to uniquely identify the profile. |
| 166 // Added in version 31. | 174 // Added in version 31. |
| 167 // name_on_card | 175 // name_on_card |
| 168 // expiration_month | 176 // expiration_month |
| 169 // expiration_year | 177 // expiration_year |
| 170 // card_number_encrypted Stores encrypted credit card number. | 178 // card_number_encrypted Stores encrypted credit card number. |
| (...skipping 14 matching lines...) Expand all Loading... |
| 185 | 193 |
| 186 using base::Time; | 194 using base::Time; |
| 187 | 195 |
| 188 namespace { | 196 namespace { |
| 189 | 197 |
| 190 typedef std::vector<Tuple3<int64, string16, string16> > AutofillElementList; | 198 typedef std::vector<Tuple3<int64, string16, string16> > AutofillElementList; |
| 191 | 199 |
| 192 // Current version number. Note: when changing the current version number, | 200 // Current version number. Note: when changing the current version number, |
| 193 // corresponding changes must happen in the unit tests, and new migration test | 201 // corresponding changes must happen in the unit tests, and new migration test |
| 194 // added. See |WebDatabaseMigrationTest::kCurrentTestedVersionNumber|. | 202 // added. See |WebDatabaseMigrationTest::kCurrentTestedVersionNumber|. |
| 195 const int kCurrentVersionNumber = 35; | 203 const int kCurrentVersionNumber = 36; |
| 196 const int kCompatibleVersionNumber = 35; | 204 const int kCompatibleVersionNumber = 36; |
| 197 | 205 |
| 198 // ID of the url column in keywords. | 206 // ID of the url column in keywords. |
| 199 const int kUrlIdPosition = 16; | 207 const int kUrlIdPosition = 16; |
| 200 | 208 |
| 201 // Keys used in the meta table. | 209 // Keys used in the meta table. |
| 202 const char* kDefaultSearchProviderKey = "Default Search Provider ID"; | 210 const char* kDefaultSearchProviderKey = "Default Search Provider ID"; |
| 203 const char* kBuiltinKeywordVersion = "Builtin Keyword Version"; | 211 const char* kBuiltinKeywordVersion = "Builtin Keyword Version"; |
| 204 | 212 |
| 205 // The maximum length allowed for form data. | 213 // The maximum length allowed for form data. |
| 206 const size_t kMaxDataLength = 1024; | 214 const size_t kMaxDataLength = 1024; |
| (...skipping 378 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 585 "DELETE FROM autofill_profile_phones WHERE guid = ?")); | 593 "DELETE FROM autofill_profile_phones WHERE guid = ?")); |
| 586 if (!s3) { | 594 if (!s3) { |
| 587 NOTREACHED() << "Statement prepare failed"; | 595 NOTREACHED() << "Statement prepare failed"; |
| 588 return false; | 596 return false; |
| 589 } | 597 } |
| 590 | 598 |
| 591 s3.BindString(0, guid); | 599 s3.BindString(0, guid); |
| 592 return s3.Run(); | 600 return s3.Run(); |
| 593 } | 601 } |
| 594 | 602 |
| 603 // TODO(dhollowa): Find a common place for this. It is duplicated in |
| 604 // personal_data_manager.cc. |
| 605 template<typename T> |
| 606 T* address_of(T& v) { |
| 607 return &v; |
| 608 } |
| 609 |
| 595 } // namespace | 610 } // namespace |
| 596 | 611 |
| 597 WebDatabase::WebDatabase() { | 612 WebDatabase::WebDatabase() { |
| 598 } | 613 } |
| 599 | 614 |
| 600 WebDatabase::~WebDatabase() { | 615 WebDatabase::~WebDatabase() { |
| 601 } | 616 } |
| 602 | 617 |
| 603 void WebDatabase::BeginTransaction() { | 618 void WebDatabase::BeginTransaction() { |
| 604 db_.BeginTransaction(); | 619 db_.BeginTransaction(); |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 644 if (meta_table_.GetCompatibleVersionNumber() > kCurrentVersionNumber) { | 659 if (meta_table_.GetCompatibleVersionNumber() > kCurrentVersionNumber) { |
| 645 LOG(WARNING) << "Web database is too new."; | 660 LOG(WARNING) << "Web database is too new."; |
| 646 return sql::INIT_TOO_NEW; | 661 return sql::INIT_TOO_NEW; |
| 647 } | 662 } |
| 648 | 663 |
| 649 // Initialize the tables. | 664 // Initialize the tables. |
| 650 if (!InitKeywordsTable() || !InitLoginsTable() || !InitWebAppIconsTable() || | 665 if (!InitKeywordsTable() || !InitLoginsTable() || !InitWebAppIconsTable() || |
| 651 !InitWebAppsTable() || !InitAutofillTable() || | 666 !InitWebAppsTable() || !InitAutofillTable() || |
| 652 !InitAutofillDatesTable() || !InitAutofillProfilesTable() || | 667 !InitAutofillDatesTable() || !InitAutofillProfilesTable() || |
| 653 !InitAutofillProfileNamesTable() || !InitAutofillProfileEmailsTable() || | 668 !InitAutofillProfileNamesTable() || !InitAutofillProfileEmailsTable() || |
| 654 !InitAutofillProfilePhonesTable() || !InitCreditCardsTable() || | 669 !InitAutofillProfilePhonesTable() || !InitAutofillProfileTrashTable() || |
| 655 !InitTokenServiceTable()) { | 670 !InitCreditCardsTable() || !InitTokenServiceTable()) { |
| 656 LOG(WARNING) << "Unable to initialize the web database."; | 671 LOG(WARNING) << "Unable to initialize the web database."; |
| 657 return sql::INIT_FAILURE; | 672 return sql::INIT_FAILURE; |
| 658 } | 673 } |
| 659 | 674 |
| 660 // If the file on disk is an older database version, bring it up to date. | 675 // If the file on disk is an older database version, bring it up to date. |
| 661 // If the migration fails we return an error to caller and do not commit | 676 // If the migration fails we return an error to caller and do not commit |
| 662 // the migration. | 677 // the migration. |
| 663 sql::InitStatus migration_status = MigrateOldVersionsAsNeeded(); | 678 sql::InitStatus migration_status = MigrateOldVersionsAsNeeded(); |
| 664 if (migration_status != sql::INIT_OK) | 679 if (migration_status != sql::INIT_OK) |
| 665 return migration_status; | 680 return migration_status; |
| (...skipping 324 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 990 "guid VARCHAR, " | 1005 "guid VARCHAR, " |
| 991 "type INTEGER DEFAULT 0, " | 1006 "type INTEGER DEFAULT 0, " |
| 992 "number VARCHAR)")) { | 1007 "number VARCHAR)")) { |
| 993 NOTREACHED(); | 1008 NOTREACHED(); |
| 994 return false; | 1009 return false; |
| 995 } | 1010 } |
| 996 } | 1011 } |
| 997 return true; | 1012 return true; |
| 998 } | 1013 } |
| 999 | 1014 |
| 1015 bool WebDatabase::InitAutofillProfileTrashTable() { |
| 1016 if (!db_.DoesTableExist("autofill_profiles_trash")) { |
| 1017 if (!db_.Execute("CREATE TABLE autofill_profiles_trash ( " |
| 1018 "guid VARCHAR)")) { |
| 1019 NOTREACHED(); |
| 1020 return false; |
| 1021 } |
| 1022 } |
| 1023 return true; |
| 1024 } |
| 1025 |
| 1000 bool WebDatabase::InitCreditCardsTable() { | 1026 bool WebDatabase::InitCreditCardsTable() { |
| 1001 if (!db_.DoesTableExist("credit_cards")) { | 1027 if (!db_.DoesTableExist("credit_cards")) { |
| 1002 if (!db_.Execute("CREATE TABLE credit_cards ( " | 1028 if (!db_.Execute("CREATE TABLE credit_cards ( " |
| 1003 "guid VARCHAR PRIMARY KEY, " | 1029 "guid VARCHAR PRIMARY KEY, " |
| 1004 "name_on_card VARCHAR, " | 1030 "name_on_card VARCHAR, " |
| 1005 "expiration_month INTEGER, " | 1031 "expiration_month INTEGER, " |
| 1006 "expiration_year INTEGER, " | 1032 "expiration_year INTEGER, " |
| 1007 "card_number_encrypted BLOB, " | 1033 "card_number_encrypted BLOB, " |
| 1008 "date_modified INTEGER NOT NULL DEFAULT 0)")) { | 1034 "date_modified INTEGER NOT NULL DEFAULT 0)")) { |
| 1009 NOTREACHED(); | 1035 NOTREACHED(); |
| (...skipping 830 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1840 } | 1866 } |
| 1841 s.BindString16(0, name); | 1867 s.BindString16(0, name); |
| 1842 s.BindString16(1, value); | 1868 s.BindString16(1, value); |
| 1843 | 1869 |
| 1844 if (s.Step()) | 1870 if (s.Step()) |
| 1845 return RemoveFormElementForID(s.ColumnInt64(0)); | 1871 return RemoveFormElementForID(s.ColumnInt64(0)); |
| 1846 return false; | 1872 return false; |
| 1847 } | 1873 } |
| 1848 | 1874 |
| 1849 bool WebDatabase::AddAutofillProfile(const AutofillProfile& profile) { | 1875 bool WebDatabase::AddAutofillProfile(const AutofillProfile& profile) { |
| 1876 if (IsAutofillGUIDInTrash(profile.guid())) |
| 1877 return true; |
| 1878 |
| 1850 sql::Statement s(db_.GetUniqueStatement( | 1879 sql::Statement s(db_.GetUniqueStatement( |
| 1851 "INSERT INTO autofill_profiles" | 1880 "INSERT INTO autofill_profiles" |
| 1852 "(guid, company_name, address_line_1, address_line_2, city, state," | 1881 "(guid, company_name, address_line_1, address_line_2, city, state," |
| 1853 " zipcode, country, country_code, date_modified)" | 1882 " zipcode, country, country_code, date_modified)" |
| 1854 "VALUES (?,?,?,?,?,?,?,?,?,?)")); | 1883 "VALUES (?,?,?,?,?,?,?,?,?,?)")); |
| 1855 if (!s) { | 1884 if (!s) { |
| 1856 NOTREACHED() << "Statement prepare failed"; | 1885 NOTREACHED() << "Statement prepare failed"; |
| 1857 return false; | 1886 return false; |
| 1858 } | 1887 } |
| 1859 | 1888 |
| (...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1979 return false; | 2008 return false; |
| 1980 profiles->push_back(profile); | 2009 profiles->push_back(profile); |
| 1981 } | 2010 } |
| 1982 | 2011 |
| 1983 return s.Succeeded(); | 2012 return s.Succeeded(); |
| 1984 } | 2013 } |
| 1985 | 2014 |
| 1986 bool WebDatabase::UpdateAutofillProfile(const AutofillProfile& profile) { | 2015 bool WebDatabase::UpdateAutofillProfile(const AutofillProfile& profile) { |
| 1987 DCHECK(guid::IsValidGUID(profile.guid())); | 2016 DCHECK(guid::IsValidGUID(profile.guid())); |
| 1988 | 2017 |
| 2018 if (IsAutofillGUIDInTrash(profile.guid())) |
| 2019 return true; |
| 2020 |
| 1989 AutofillProfile* tmp_profile = NULL; | 2021 AutofillProfile* tmp_profile = NULL; |
| 1990 if (!GetAutofillProfile(profile.guid(), &tmp_profile)) | 2022 if (!GetAutofillProfile(profile.guid(), &tmp_profile)) |
| 1991 return false; | 2023 return false; |
| 1992 | 2024 |
| 1993 // Preserve appropriate modification dates by not updating unchanged profiles. | 2025 // Preserve appropriate modification dates by not updating unchanged profiles. |
| 1994 scoped_ptr<AutofillProfile> old_profile(tmp_profile); | 2026 scoped_ptr<AutofillProfile> old_profile(tmp_profile); |
| 1995 if (*old_profile == profile) | 2027 if (*old_profile == profile) |
| 1996 return true; | 2028 return true; |
| 1997 | 2029 |
| 1998 sql::Statement s(db_.GetUniqueStatement( | 2030 sql::Statement s(db_.GetUniqueStatement( |
| (...skipping 16 matching lines...) Expand all Loading... |
| 2015 | 2047 |
| 2016 // Remove the old names, emails, and phone/fax numbers. | 2048 // Remove the old names, emails, and phone/fax numbers. |
| 2017 if (!RemoveAutofillProfilePieces(profile.guid(), &db_)) | 2049 if (!RemoveAutofillProfilePieces(profile.guid(), &db_)) |
| 2018 return false; | 2050 return false; |
| 2019 | 2051 |
| 2020 return AddAutofillProfilePieces(profile.guid(), profile, &db_); | 2052 return AddAutofillProfilePieces(profile.guid(), profile, &db_); |
| 2021 } | 2053 } |
| 2022 | 2054 |
| 2023 bool WebDatabase::RemoveAutofillProfile(const std::string& guid) { | 2055 bool WebDatabase::RemoveAutofillProfile(const std::string& guid) { |
| 2024 DCHECK(guid::IsValidGUID(guid)); | 2056 DCHECK(guid::IsValidGUID(guid)); |
| 2057 |
| 2058 if (IsAutofillGUIDInTrash(guid)) { |
| 2059 sql::Statement s_trash(db_.GetUniqueStatement( |
| 2060 "DELETE FROM autofill_profiles_trash WHERE guid = ?")); |
| 2061 if (!s_trash) { |
| 2062 NOTREACHED() << "Statement prepare failed"; |
| 2063 return false; |
| 2064 } |
| 2065 s_trash.BindString(0, guid); |
| 2066 if (!s_trash.Run()) { |
| 2067 NOTREACHED() << "Expected item in trash."; |
| 2068 return false; |
| 2069 } |
| 2070 |
| 2071 return true; |
| 2072 } |
| 2073 |
| 2025 sql::Statement s(db_.GetUniqueStatement( | 2074 sql::Statement s(db_.GetUniqueStatement( |
| 2026 "DELETE FROM autofill_profiles WHERE guid = ?")); | 2075 "DELETE FROM autofill_profiles WHERE guid = ?")); |
| 2027 if (!s) { | 2076 if (!s) { |
| 2028 NOTREACHED() << "Statement prepare failed"; | 2077 NOTREACHED() << "Statement prepare failed"; |
| 2029 return false; | 2078 return false; |
| 2030 } | 2079 } |
| 2031 | 2080 |
| 2032 s.BindString(0, guid); | 2081 s.BindString(0, guid); |
| 2033 if (!s.Run()) | 2082 if (!s.Run()) |
| 2034 return false; | 2083 return false; |
| 2035 | 2084 |
| 2036 return RemoveAutofillProfilePieces(guid, &db_); | 2085 return RemoveAutofillProfilePieces(guid, &db_); |
| 2037 } | 2086 } |
| 2038 | 2087 |
| 2088 bool WebDatabase::ClearAutofillProfiles() { |
| 2089 sql::Statement s1(db_.GetUniqueStatement( |
| 2090 "DELETE FROM autofill_profiles")); |
| 2091 if (!s1) { |
| 2092 NOTREACHED() << "Statement prepare failed"; |
| 2093 return false; |
| 2094 } |
| 2095 |
| 2096 if (!s1.Run()) |
| 2097 return false; |
| 2098 |
| 2099 sql::Statement s2(db_.GetUniqueStatement( |
| 2100 "DELETE FROM autofill_profile_names")); |
| 2101 if (!s2) { |
| 2102 NOTREACHED() << "Statement prepare failed"; |
| 2103 return false; |
| 2104 } |
| 2105 |
| 2106 if (!s2.Run()) |
| 2107 return false; |
| 2108 |
| 2109 sql::Statement s3(db_.GetUniqueStatement( |
| 2110 "DELETE FROM autofill_profile_emails")); |
| 2111 if (!s3) { |
| 2112 NOTREACHED() << "Statement prepare failed"; |
| 2113 return false; |
| 2114 } |
| 2115 |
| 2116 if (!s3.Run()) |
| 2117 return false; |
| 2118 |
| 2119 sql::Statement s4(db_.GetUniqueStatement( |
| 2120 "DELETE FROM autofill_profile_phones")); |
| 2121 if (!s4) { |
| 2122 NOTREACHED() << "Statement prepare failed"; |
| 2123 return false; |
| 2124 } |
| 2125 |
| 2126 if (!s4.Run()) |
| 2127 return false; |
| 2128 |
| 2129 return true; |
| 2130 } |
| 2131 |
| 2039 bool WebDatabase::AddCreditCard(const CreditCard& credit_card) { | 2132 bool WebDatabase::AddCreditCard(const CreditCard& credit_card) { |
| 2040 sql::Statement s(db_.GetUniqueStatement( | 2133 sql::Statement s(db_.GetUniqueStatement( |
| 2041 "INSERT INTO credit_cards" | 2134 "INSERT INTO credit_cards" |
| 2042 "(guid, name_on_card, expiration_month, expiration_year, " | 2135 "(guid, name_on_card, expiration_month, expiration_year, " |
| 2043 "card_number_encrypted, date_modified)" | 2136 "card_number_encrypted, date_modified)" |
| 2044 "VALUES (?,?,?,?,?,?)")); | 2137 "VALUES (?,?,?,?,?,?)")); |
| 2045 if (!s) { | 2138 if (!s) { |
| 2046 NOTREACHED() << "Statement prepare failed"; | 2139 NOTREACHED() << "Statement prepare failed"; |
| 2047 return false; | 2140 return false; |
| 2048 } | 2141 } |
| (...skipping 139 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2188 s_credit_cards.Run(); | 2281 s_credit_cards.Run(); |
| 2189 | 2282 |
| 2190 if (!s_credit_cards.Succeeded()) { | 2283 if (!s_credit_cards.Succeeded()) { |
| 2191 NOTREACHED(); | 2284 NOTREACHED(); |
| 2192 return false; | 2285 return false; |
| 2193 } | 2286 } |
| 2194 | 2287 |
| 2195 return true; | 2288 return true; |
| 2196 } | 2289 } |
| 2197 | 2290 |
| 2291 bool WebDatabase::GetAutofillProfilesInTrash(std::vector<std::string>* guids) { |
| 2292 guids->clear(); |
| 2293 |
| 2294 sql::Statement s(db_.GetUniqueStatement( |
| 2295 "SELECT guid " |
| 2296 "FROM autofill_profiles_trash")); |
| 2297 if (!s) { |
| 2298 NOTREACHED() << "Statement prepare failed"; |
| 2299 return false; |
| 2300 } |
| 2301 |
| 2302 while (s.Step()) { |
| 2303 std::string guid = s.ColumnString(0); |
| 2304 guids->push_back(guid); |
| 2305 } |
| 2306 |
| 2307 return s.Succeeded(); |
| 2308 } |
| 2309 |
| 2310 bool WebDatabase::EmptyAutofillProfilesTrash() { |
| 2311 sql::Statement s(db_.GetUniqueStatement( |
| 2312 "DELETE FROM autofill_profiles_trash")); |
| 2313 if (!s) { |
| 2314 NOTREACHED() << "Statement prepare failed"; |
| 2315 return false; |
| 2316 } |
| 2317 |
| 2318 return s.Run(); |
| 2319 } |
| 2320 |
| 2198 bool WebDatabase::AddToCountOfFormElement(int64 pair_id, | 2321 bool WebDatabase::AddToCountOfFormElement(int64 pair_id, |
| 2199 int delta, | 2322 int delta, |
| 2200 bool* was_removed) { | 2323 bool* was_removed) { |
| 2201 DCHECK(was_removed); | 2324 DCHECK(was_removed); |
| 2202 int count = 0; | 2325 int count = 0; |
| 2203 *was_removed = false; | 2326 *was_removed = false; |
| 2204 | 2327 |
| 2205 if (!GetCountOfFormElement(pair_id, &count)) | 2328 if (!GetCountOfFormElement(pair_id, &count)) |
| 2206 return false; | 2329 return false; |
| 2207 | 2330 |
| (...skipping 16 matching lines...) Expand all Loading... |
| 2224 return false; | 2347 return false; |
| 2225 } | 2348 } |
| 2226 s.BindInt64(0, pair_id); | 2349 s.BindInt64(0, pair_id); |
| 2227 if (s.Run()) { | 2350 if (s.Run()) { |
| 2228 return RemoveFormElementForTimeRange(pair_id, base::Time(), base::Time(), | 2351 return RemoveFormElementForTimeRange(pair_id, base::Time(), base::Time(), |
| 2229 NULL); | 2352 NULL); |
| 2230 } | 2353 } |
| 2231 return false; | 2354 return false; |
| 2232 } | 2355 } |
| 2233 | 2356 |
| 2357 bool WebDatabase::AddAutofillGUIDToTrash(const std::string& guid) { |
| 2358 sql::Statement s(db_.GetUniqueStatement( |
| 2359 "INSERT INTO autofill_profiles_trash" |
| 2360 " (guid) " |
| 2361 "VALUES (?)")); |
| 2362 if (!s) { |
| 2363 NOTREACHED(); |
| 2364 return sql::INIT_FAILURE; |
| 2365 } |
| 2366 |
| 2367 s.BindString(0, guid); |
| 2368 if (!s.Run()) { |
| 2369 NOTREACHED(); |
| 2370 return false; |
| 2371 } |
| 2372 return true; |
| 2373 } |
| 2374 |
| 2375 bool WebDatabase::IsAutofillGUIDInTrash(const std::string& guid) { |
| 2376 sql::Statement s(db_.GetUniqueStatement( |
| 2377 "SELECT guid " |
| 2378 "FROM autofill_profiles_trash " |
| 2379 "WHERE guid = ?")); |
| 2380 if (!s) { |
| 2381 NOTREACHED() << "Statement prepare failed"; |
| 2382 return false; |
| 2383 } |
| 2384 |
| 2385 s.BindString(0, guid); |
| 2386 return s.Step(); |
| 2387 } |
| 2388 |
| 2234 sql::InitStatus WebDatabase::MigrateOldVersionsAsNeeded(){ | 2389 sql::InitStatus WebDatabase::MigrateOldVersionsAsNeeded(){ |
| 2235 // Migrate if necessary. | 2390 // Migrate if necessary. |
| 2236 int current_version = meta_table_.GetVersionNumber(); | 2391 int current_version = meta_table_.GetVersionNumber(); |
| 2237 switch (current_version) { | 2392 switch (current_version) { |
| 2238 // Versions 1 - 19 are unhandled. Version numbers greater than | 2393 // Versions 1 - 19 are unhandled. Version numbers greater than |
| 2239 // kCurrentVersionNumber should have already been weeded out by the caller. | 2394 // kCurrentVersionNumber should have already been weeded out by the caller. |
| 2240 default: | 2395 default: |
| 2241 // When the version is too old, we return failure error code. The schema | 2396 // When the version is too old, we return failure error code. The schema |
| 2242 // is too out of date to migrate. | 2397 // is too out of date to migrate. |
| 2243 // There should not be a released product that makes a database too old to | 2398 // There should not be a released product that makes a database too old to |
| (...skipping 841 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3085 return sql::INIT_FAILURE; | 3240 return sql::INIT_FAILURE; |
| 3086 } | 3241 } |
| 3087 } | 3242 } |
| 3088 | 3243 |
| 3089 meta_table_.SetVersionNumber(35); | 3244 meta_table_.SetVersionNumber(35); |
| 3090 meta_table_.SetCompatibleVersionNumber( | 3245 meta_table_.SetCompatibleVersionNumber( |
| 3091 std::min(35, kCompatibleVersionNumber)); | 3246 std::min(35, kCompatibleVersionNumber)); |
| 3092 | 3247 |
| 3093 // FALL THROUGH | 3248 // FALL THROUGH |
| 3094 | 3249 |
| 3250 case 35: |
| 3251 // Merge and cull older profiles where possible. |
| 3252 { |
| 3253 sql::Statement s(db_.GetUniqueStatement( |
| 3254 "SELECT guid, date_modified " |
| 3255 "FROM autofill_profiles")); |
| 3256 if (!s) { |
| 3257 NOTREACHED() << "Statement prepare failed"; |
| 3258 return sql::INIT_FAILURE; |
| 3259 } |
| 3260 |
| 3261 // Accumulate the good profiles. |
| 3262 std::vector<AutofillProfile> accumulated_profiles; |
| 3263 std::vector<AutofillProfile*> accumulated_profiles_p; |
| 3264 std::map<std::string, int64> modification_map; |
| 3265 while (s.Step()) { |
| 3266 std::string guid = s.ColumnString(0); |
| 3267 int64 date_modified = s.ColumnInt64(1); |
| 3268 modification_map.insert( |
| 3269 std::pair<std::string, int64>(guid, date_modified)); |
| 3270 AutofillProfile* profile = NULL; |
| 3271 if (!GetAutofillProfile(guid, &profile)) { |
| 3272 NOTREACHED() << "Bad read of profile."; |
| 3273 return sql::INIT_FAILURE; |
| 3274 } |
| 3275 scoped_ptr<AutofillProfile> p(profile); |
| 3276 |
| 3277 if (PersonalDataManager::IsValidLearnableProfile(*p)) { |
| 3278 std::vector<AutofillProfile> merged_profiles; |
| 3279 bool merged = PersonalDataManager::MergeProfile( |
| 3280 *p, accumulated_profiles_p, &merged_profiles); |
| 3281 |
| 3282 std::swap(accumulated_profiles, merged_profiles); |
| 3283 |
| 3284 accumulated_profiles_p.clear(); |
| 3285 accumulated_profiles_p.resize(accumulated_profiles.size()); |
| 3286 std::transform(accumulated_profiles.begin(), |
| 3287 accumulated_profiles.end(), |
| 3288 accumulated_profiles_p.begin(), |
| 3289 address_of<AutofillProfile>); |
| 3290 |
| 3291 // If the profile got merged trash the original. |
| 3292 if (merged) |
| 3293 AddAutofillGUIDToTrash(p->guid()); |
| 3294 } else { |
| 3295 // An invalid profile, so trash it. |
| 3296 AddAutofillGUIDToTrash(p->guid()); |
| 3297 } |
| 3298 } |
| 3299 |
| 3300 // Drop the current profiles. |
| 3301 if (!ClearAutofillProfiles()) { |
| 3302 LOG(WARNING) << "Unable to update web database to version 36."; |
| 3303 NOTREACHED(); |
| 3304 return sql::INIT_FAILURE; |
| 3305 } |
| 3306 |
| 3307 // Add the newly merged profiles back in. |
| 3308 for (std::vector<AutofillProfile>::const_iterator |
| 3309 iter = accumulated_profiles.begin(); |
| 3310 iter != accumulated_profiles.end(); |
| 3311 ++iter) { |
| 3312 if (!AddAutofillProfile(*iter)) { |
| 3313 LOG(WARNING) << "Unable to update web database to version 36."; |
| 3314 NOTREACHED(); |
| 3315 return sql::INIT_FAILURE; |
| 3316 } |
| 3317 |
| 3318 // Fix up the original modification date. |
| 3319 std::map<std::string, int64>::const_iterator date_item = |
| 3320 modification_map.find(iter->guid()); |
| 3321 if (date_item == modification_map.end()) { |
| 3322 LOG(WARNING) << "Unable to update web database to version 36."; |
| 3323 NOTREACHED(); |
| 3324 return sql::INIT_FAILURE; |
| 3325 } |
| 3326 sql::Statement s_date(db_.GetUniqueStatement( |
| 3327 "UPDATE autofill_profiles SET date_modified=? " |
| 3328 "WHERE guid=?")); |
| 3329 s_date.BindInt64(0, date_item->second); |
| 3330 s_date.BindString(1, iter->guid()); |
| 3331 if (!s_date.Run()) { |
| 3332 LOG(WARNING) << "Unable to update web database to version 36."; |
| 3333 NOTREACHED(); |
| 3334 return sql::INIT_FAILURE; |
| 3335 } |
| 3336 } |
| 3337 } |
| 3338 |
| 3339 meta_table_.SetVersionNumber(36); |
| 3340 meta_table_.SetCompatibleVersionNumber( |
| 3341 std::min(36, kCompatibleVersionNumber)); |
| 3342 |
| 3343 // FALL THROUGH |
| 3344 |
| 3095 // Add successive versions here. Each should set the version number and | 3345 // Add successive versions here. Each should set the version number and |
| 3096 // compatible version number as appropriate, then fall through to the next | 3346 // compatible version number as appropriate, then fall through to the next |
| 3097 // case. | 3347 // case. |
| 3098 | 3348 |
| 3099 case kCurrentVersionNumber: | 3349 case kCurrentVersionNumber: |
| 3100 // No migration needed. | 3350 // No migration needed. |
| 3101 return sql::INIT_OK; | 3351 return sql::INIT_OK; |
| 3102 } | 3352 } |
| 3103 } | 3353 } |
| OLD | NEW |