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