Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(491)

Side by Side Diff: chrome/browser/webdata/web_database.cc

Issue 6676031: Autofill database migration to clean up bogus profiles. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Move to Lingesh's observer mechanism. Created 9 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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
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
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
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
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
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
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
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
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
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
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
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 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698