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 |