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_profile.h" | 20 #include "chrome/browser/autofill/autofill_profile.h" |
20 #include "chrome/browser/autofill/autofill_type.h" | 21 #include "chrome/browser/autofill/autofill_type.h" |
21 #include "chrome/browser/autofill/credit_card.h" | 22 #include "chrome/browser/autofill/credit_card.h" |
22 #include "chrome/browser/diagnostics/sqlite_diagnostics.h" | 23 #include "chrome/browser/diagnostics/sqlite_diagnostics.h" |
23 #include "chrome/browser/history/history_database.h" | 24 #include "chrome/browser/history/history_database.h" |
24 #include "chrome/browser/password_manager/encryptor.h" | 25 #include "chrome/browser/password_manager/encryptor.h" |
25 #include "chrome/browser/search_engines/template_url.h" | 26 #include "chrome/browser/search_engines/template_url.h" |
26 #include "chrome/browser/webdata/autofill_change.h" | 27 #include "chrome/browser/webdata/autofill_change.h" |
27 #include "chrome/common/guid.h" | 28 #include "chrome/common/guid.h" |
28 #include "chrome/common/notification_service.h" | 29 #include "chrome/common/notification_service.h" |
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
116 // standard entries in a contact information form. | 117 // standard entries in a contact information form. |
117 // | 118 // |
118 // guid A guid string to uniquely identify the profile. | 119 // guid A guid string to uniquely identify the profile. |
119 // Added in version 31. | 120 // Added in version 31. |
120 // company_name | 121 // company_name |
121 // address_line_1 | 122 // address_line_1 |
122 // address_line_2 | 123 // address_line_2 |
123 // city | 124 // city |
124 // state | 125 // state |
125 // zipcode | 126 // zipcode |
126 // country | 127 // country The country name. Deprecated, should be removed once |
| 128 // the stable channel reaches version 11. |
| 129 // country_code |
127 // date_modified The date on which this profile was last modified. | 130 // date_modified The date on which this profile was last modified. |
128 // Added in version 30. | 131 // Added in version 30. |
129 // | 132 // |
130 // autofill_profile_names | 133 // autofill_profile_names |
131 // This table contains the multi-valued name fields | 134 // This table contains the multi-valued name fields |
132 // associated with a profile. | 135 // associated with a profile. |
133 // | 136 // |
134 // guid The guid string that identifies the profile to which | 137 // guid The guid string that identifies the profile to which |
135 // the name belongs. | 138 // the name belongs. |
136 // first_name | 139 // first_name |
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
182 | 185 |
183 using base::Time; | 186 using base::Time; |
184 | 187 |
185 namespace { | 188 namespace { |
186 | 189 |
187 typedef std::vector<Tuple3<int64, string16, string16> > AutofillElementList; | 190 typedef std::vector<Tuple3<int64, string16, string16> > AutofillElementList; |
188 | 191 |
189 // Current version number. Note: when changing the current version number, | 192 // Current version number. Note: when changing the current version number, |
190 // corresponding changes must happen in the unit tests, and new migration test | 193 // corresponding changes must happen in the unit tests, and new migration test |
191 // added. See |WebDatabaseMigrationTest::kCurrentTestedVersionNumber|. | 194 // added. See |WebDatabaseMigrationTest::kCurrentTestedVersionNumber|. |
192 const int kCurrentVersionNumber = 33; | 195 const int kCurrentVersionNumber = 34; |
193 const int kCompatibleVersionNumber = 33; | 196 const int kCompatibleVersionNumber = 34; |
194 | 197 |
195 // ID of the url column in keywords. | 198 // ID of the url column in keywords. |
196 const int kUrlIdPosition = 16; | 199 const int kUrlIdPosition = 16; |
197 | 200 |
198 // Keys used in the meta table. | 201 // Keys used in the meta table. |
199 const char* kDefaultSearchProviderKey = "Default Search Provider ID"; | 202 const char* kDefaultSearchProviderKey = "Default Search Provider ID"; |
200 const char* kBuiltinKeywordVersion = "Builtin Keyword Version"; | 203 const char* kBuiltinKeywordVersion = "Builtin Keyword Version"; |
201 | 204 |
202 // The maximum length allowed for form data. | 205 // The maximum length allowed for form data. |
203 const size_t kMaxDataLength = 1024; | 206 const size_t kMaxDataLength = 1024; |
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
289 text = profile.GetFieldText(AutoFillType(ADDRESS_HOME_LINE2)); | 292 text = profile.GetFieldText(AutoFillType(ADDRESS_HOME_LINE2)); |
290 s->BindString16(3, LimitDataSize(text)); | 293 s->BindString16(3, LimitDataSize(text)); |
291 text = profile.GetFieldText(AutoFillType(ADDRESS_HOME_CITY)); | 294 text = profile.GetFieldText(AutoFillType(ADDRESS_HOME_CITY)); |
292 s->BindString16(4, LimitDataSize(text)); | 295 s->BindString16(4, LimitDataSize(text)); |
293 text = profile.GetFieldText(AutoFillType(ADDRESS_HOME_STATE)); | 296 text = profile.GetFieldText(AutoFillType(ADDRESS_HOME_STATE)); |
294 s->BindString16(5, LimitDataSize(text)); | 297 s->BindString16(5, LimitDataSize(text)); |
295 text = profile.GetFieldText(AutoFillType(ADDRESS_HOME_ZIP)); | 298 text = profile.GetFieldText(AutoFillType(ADDRESS_HOME_ZIP)); |
296 s->BindString16(6, LimitDataSize(text)); | 299 s->BindString16(6, LimitDataSize(text)); |
297 text = profile.GetFieldText(AutoFillType(ADDRESS_HOME_COUNTRY)); | 300 text = profile.GetFieldText(AutoFillType(ADDRESS_HOME_COUNTRY)); |
298 s->BindString16(7, LimitDataSize(text)); | 301 s->BindString16(7, LimitDataSize(text)); |
299 s->BindInt64(8, Time::Now().ToTimeT()); | 302 std::string country_code = profile.CountryCode(); |
| 303 s->BindString(8, country_code); |
| 304 s->BindInt64(9, Time::Now().ToTimeT()); |
300 } | 305 } |
301 | 306 |
302 AutoFillProfile* AutoFillProfileFromStatement(const sql::Statement& s) { | 307 AutoFillProfile* AutoFillProfileFromStatement(const sql::Statement& s) { |
303 AutoFillProfile* profile = new AutoFillProfile; | 308 AutoFillProfile* profile = new AutoFillProfile; |
304 profile->set_guid(s.ColumnString(0)); | 309 profile->set_guid(s.ColumnString(0)); |
305 DCHECK(guid::IsValidGUID(profile->guid())); | 310 DCHECK(guid::IsValidGUID(profile->guid())); |
306 | 311 |
307 profile->SetInfo(AutoFillType(COMPANY_NAME), s.ColumnString16(1)); | 312 profile->SetInfo(AutoFillType(COMPANY_NAME), s.ColumnString16(1)); |
308 profile->SetInfo(AutoFillType(ADDRESS_HOME_LINE1), s.ColumnString16(2)); | 313 profile->SetInfo(AutoFillType(ADDRESS_HOME_LINE1), s.ColumnString16(2)); |
309 profile->SetInfo(AutoFillType(ADDRESS_HOME_LINE2), s.ColumnString16(3)); | 314 profile->SetInfo(AutoFillType(ADDRESS_HOME_LINE2), s.ColumnString16(3)); |
310 profile->SetInfo(AutoFillType(ADDRESS_HOME_CITY), s.ColumnString16(4)); | 315 profile->SetInfo(AutoFillType(ADDRESS_HOME_CITY), s.ColumnString16(4)); |
311 profile->SetInfo(AutoFillType(ADDRESS_HOME_STATE), s.ColumnString16(5)); | 316 profile->SetInfo(AutoFillType(ADDRESS_HOME_STATE), s.ColumnString16(5)); |
312 profile->SetInfo(AutoFillType(ADDRESS_HOME_ZIP), s.ColumnString16(6)); | 317 profile->SetInfo(AutoFillType(ADDRESS_HOME_ZIP), s.ColumnString16(6)); |
313 profile->SetInfo(AutoFillType(ADDRESS_HOME_COUNTRY), s.ColumnString16(7)); | 318 // Intentionally skip column 7, which stores the localized country name. |
314 // Intentionally skip column 8, which stores the profile's modification date. | 319 profile->SetCountryCode(s.ColumnString(8)); |
| 320 // Intentionally skip column 9, which stores the profile's modification date. |
315 | 321 |
316 return profile; | 322 return profile; |
317 } | 323 } |
318 | 324 |
319 void AddAutoFillProfileNameFromStatement(const sql::Statement& s, | 325 void AddAutoFillProfileNameFromStatement(const sql::Statement& s, |
320 AutoFillProfile* profile) { | 326 AutoFillProfile* profile) { |
321 DCHECK_EQ(profile->guid(), s.ColumnString(0)); | 327 DCHECK_EQ(profile->guid(), s.ColumnString(0)); |
322 DCHECK(guid::IsValidGUID(profile->guid())); | 328 DCHECK(guid::IsValidGUID(profile->guid())); |
323 | 329 |
324 profile->SetInfo(AutoFillType(NAME_FIRST), s.ColumnString16(1)); | 330 profile->SetInfo(AutoFillType(NAME_FIRST), s.ColumnString16(1)); |
(...skipping 611 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
936 if (!db_.DoesTableExist("autofill_profiles")) { | 942 if (!db_.DoesTableExist("autofill_profiles")) { |
937 if (!db_.Execute("CREATE TABLE autofill_profiles ( " | 943 if (!db_.Execute("CREATE TABLE autofill_profiles ( " |
938 "guid VARCHAR PRIMARY KEY, " | 944 "guid VARCHAR PRIMARY KEY, " |
939 "company_name VARCHAR, " | 945 "company_name VARCHAR, " |
940 "address_line_1 VARCHAR, " | 946 "address_line_1 VARCHAR, " |
941 "address_line_2 VARCHAR, " | 947 "address_line_2 VARCHAR, " |
942 "city VARCHAR, " | 948 "city VARCHAR, " |
943 "state VARCHAR, " | 949 "state VARCHAR, " |
944 "zipcode VARCHAR, " | 950 "zipcode VARCHAR, " |
945 "country VARCHAR, " | 951 "country VARCHAR, " |
| 952 "country_code VARCHAR, " |
946 "date_modified INTEGER NOT NULL DEFAULT 0)")) { | 953 "date_modified INTEGER NOT NULL DEFAULT 0)")) { |
947 NOTREACHED(); | 954 NOTREACHED(); |
948 return false; | 955 return false; |
949 } | 956 } |
950 } | 957 } |
951 return true; | 958 return true; |
952 } | 959 } |
953 | 960 |
954 bool WebDatabase::InitAutoFillProfileNamesTable() { | 961 bool WebDatabase::InitAutoFillProfileNamesTable() { |
955 if (!db_.DoesTableExist("autofill_profile_names")) { | 962 if (!db_.DoesTableExist("autofill_profile_names")) { |
(...skipping 880 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1836 | 1843 |
1837 if (s.Step()) | 1844 if (s.Step()) |
1838 return RemoveFormElementForID(s.ColumnInt64(0)); | 1845 return RemoveFormElementForID(s.ColumnInt64(0)); |
1839 return false; | 1846 return false; |
1840 } | 1847 } |
1841 | 1848 |
1842 bool WebDatabase::AddAutoFillProfile(const AutoFillProfile& profile) { | 1849 bool WebDatabase::AddAutoFillProfile(const AutoFillProfile& profile) { |
1843 sql::Statement s(db_.GetUniqueStatement( | 1850 sql::Statement s(db_.GetUniqueStatement( |
1844 "INSERT INTO autofill_profiles" | 1851 "INSERT INTO autofill_profiles" |
1845 "(guid, company_name, address_line_1, address_line_2, city, state," | 1852 "(guid, company_name, address_line_1, address_line_2, city, state," |
1846 " zipcode, country, date_modified)" | 1853 " zipcode, country, country_code, date_modified)" |
1847 "VALUES (?,?,?,?,?,?,?,?,?)")); | 1854 "VALUES (?,?,?,?,?,?,?,?,?,?)")); |
1848 if (!s) { | 1855 if (!s) { |
1849 NOTREACHED() << "Statement prepare failed"; | 1856 NOTREACHED() << "Statement prepare failed"; |
1850 return false; | 1857 return false; |
1851 } | 1858 } |
1852 | 1859 |
1853 BindAutoFillProfileToStatement(profile, &s); | 1860 BindAutoFillProfileToStatement(profile, &s); |
1854 | 1861 |
1855 if (!s.Run()) { | 1862 if (!s.Run()) { |
1856 NOTREACHED(); | 1863 NOTREACHED(); |
1857 return false; | 1864 return false; |
1858 } | 1865 } |
1859 | 1866 |
1860 if (!s.Succeeded()) | 1867 if (!s.Succeeded()) |
1861 return false; | 1868 return false; |
1862 | 1869 |
1863 return AddAutoFillProfilePieces(profile.guid(), profile, &db_); | 1870 return AddAutoFillProfilePieces(profile.guid(), profile, &db_); |
1864 } | 1871 } |
1865 | 1872 |
1866 bool WebDatabase::GetAutoFillProfile(const std::string& guid, | 1873 bool WebDatabase::GetAutoFillProfile(const std::string& guid, |
1867 AutoFillProfile** profile) { | 1874 AutoFillProfile** profile) { |
1868 DCHECK(guid::IsValidGUID(guid)); | 1875 DCHECK(guid::IsValidGUID(guid)); |
1869 DCHECK(profile); | 1876 DCHECK(profile); |
1870 sql::Statement s(db_.GetUniqueStatement( | 1877 sql::Statement s(db_.GetUniqueStatement( |
1871 "SELECT guid, company_name, address_line_1, address_line_2, city, state," | 1878 "SELECT guid, company_name, address_line_1, address_line_2, city, state," |
1872 " zipcode, country, date_modified " | 1879 " zipcode, country, country_code, date_modified " |
1873 "FROM autofill_profiles " | 1880 "FROM autofill_profiles " |
1874 "WHERE guid=?")); | 1881 "WHERE guid=?")); |
1875 if (!s) { | 1882 if (!s) { |
1876 NOTREACHED() << "Statement prepare failed"; | 1883 NOTREACHED() << "Statement prepare failed"; |
1877 return false; | 1884 return false; |
1878 } | 1885 } |
1879 | 1886 |
1880 s.BindString(0, guid); | 1887 s.BindString(0, guid); |
1881 if (!s.Step()) | 1888 if (!s.Step()) |
1882 return false; | 1889 return false; |
(...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1984 return false; | 1991 return false; |
1985 | 1992 |
1986 // Preserve appropriate modification dates by not updating unchanged profiles. | 1993 // Preserve appropriate modification dates by not updating unchanged profiles. |
1987 scoped_ptr<AutoFillProfile> old_profile(tmp_profile); | 1994 scoped_ptr<AutoFillProfile> old_profile(tmp_profile); |
1988 if (*old_profile == profile) | 1995 if (*old_profile == profile) |
1989 return true; | 1996 return true; |
1990 | 1997 |
1991 sql::Statement s(db_.GetUniqueStatement( | 1998 sql::Statement s(db_.GetUniqueStatement( |
1992 "UPDATE autofill_profiles " | 1999 "UPDATE autofill_profiles " |
1993 "SET guid=?, company_name=?, address_line_1=?, address_line_2=?, " | 2000 "SET guid=?, company_name=?, address_line_1=?, address_line_2=?, " |
1994 " city=?, state=?, zipcode=?, country=?, date_modified=? " | 2001 " city=?, state=?, zipcode=?, country=?, country_code=?, " |
| 2002 " date_modified=? " |
1995 "WHERE guid=?")); | 2003 "WHERE guid=?")); |
1996 if (!s) { | 2004 if (!s) { |
1997 NOTREACHED() << "Statement prepare failed"; | 2005 NOTREACHED() << "Statement prepare failed"; |
1998 return false; | 2006 return false; |
1999 } | 2007 } |
2000 | 2008 |
2001 BindAutoFillProfileToStatement(profile, &s); | 2009 BindAutoFillProfileToStatement(profile, &s); |
2002 s.BindString(9, profile.guid()); | 2010 s.BindString(10, profile.guid()); |
2003 bool result = s.Run(); | 2011 bool result = s.Run(); |
2004 DCHECK_GT(db_.GetLastChangeCount(), 0); | 2012 DCHECK_GT(db_.GetLastChangeCount(), 0); |
2005 if (!result) | 2013 if (!result) |
2006 return result; | 2014 return result; |
2007 | 2015 |
2008 // Remove the old names, emails, and phone/fax numbers. | 2016 // Remove the old names, emails, and phone/fax numbers. |
2009 if (!RemoveAutoFillProfilePieces(profile.guid(), &db_)) | 2017 if (!RemoveAutoFillProfilePieces(profile.guid(), &db_)) |
2010 return false; | 2018 return false; |
2011 | 2019 |
2012 return AddAutoFillProfilePieces(profile.guid(), profile, &db_); | 2020 return AddAutoFillProfilePieces(profile.guid(), profile, &db_); |
(...skipping 988 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3001 return sql::INIT_FAILURE; | 3009 return sql::INIT_FAILURE; |
3002 } | 3010 } |
3003 } | 3011 } |
3004 | 3012 |
3005 meta_table_.SetVersionNumber(33); | 3013 meta_table_.SetVersionNumber(33); |
3006 meta_table_.SetCompatibleVersionNumber( | 3014 meta_table_.SetCompatibleVersionNumber( |
3007 std::min(33, kCompatibleVersionNumber)); | 3015 std::min(33, kCompatibleVersionNumber)); |
3008 | 3016 |
3009 // FALL THROUGH | 3017 // FALL THROUGH |
3010 | 3018 |
| 3019 case 33: |
| 3020 // Test the existence of the |country_code| column as an indication that |
| 3021 // we need a migration. It is possible that the new |autofill_profiles| |
| 3022 // schema is in place because the table was newly created when migrating |
| 3023 // from a pre-version-22 database. |
| 3024 if (!db_.DoesColumnExist("autofill_profiles", "country_code")) { |
| 3025 if (!db_.Execute("ALTER TABLE autofill_profiles ADD COLUMN " |
| 3026 "country_code VARCHAR")) { |
| 3027 LOG(WARNING) << "Unable to update web database to version 33."; |
| 3028 NOTREACHED(); |
| 3029 return sql::INIT_FAILURE; |
| 3030 } |
| 3031 |
| 3032 // Set all the |country_code| fields to match existing |country| values. |
| 3033 { |
| 3034 sql::Statement s(db_.GetUniqueStatement("SELECT guid, country " |
| 3035 "FROM autofill_profiles")); |
| 3036 |
| 3037 if (!s) { |
| 3038 LOG(WARNING) << "Unable to update web database to version 33."; |
| 3039 NOTREACHED(); |
| 3040 return sql::INIT_FAILURE; |
| 3041 } |
| 3042 |
| 3043 while (s.Step()) { |
| 3044 sql::Statement update_s( |
| 3045 db_.GetUniqueStatement("UPDATE autofill_profiles " |
| 3046 "SET country_code=? WHERE guid=?")); |
| 3047 if (!update_s) { |
| 3048 LOG(WARNING) << "Unable to update web database to version 33."; |
| 3049 NOTREACHED(); |
| 3050 return sql::INIT_FAILURE; |
| 3051 } |
| 3052 string16 country = s.ColumnString16(1); |
| 3053 std::string app_locale = AutoFillCountry::ApplicationLocale(); |
| 3054 update_s.BindString(0, AutoFillCountry::GetCountryCode(country, |
| 3055 app_locale)); |
| 3056 update_s.BindString(1, s.ColumnString(0)); |
| 3057 |
| 3058 if (!update_s.Run()) { |
| 3059 LOG(WARNING) << "Unable to update web database to version 33."; |
| 3060 NOTREACHED(); |
| 3061 return sql::INIT_FAILURE; |
| 3062 } |
| 3063 } |
| 3064 } |
| 3065 } |
| 3066 |
| 3067 meta_table_.SetVersionNumber(34); |
| 3068 meta_table_.SetCompatibleVersionNumber( |
| 3069 std::min(34, kCompatibleVersionNumber)); |
| 3070 |
| 3071 // FALL THROUGH |
| 3072 |
3011 // Add successive versions here. Each should set the version number and | 3073 // Add successive versions here. Each should set the version number and |
3012 // compatible version number as appropriate, then fall through to the next | 3074 // compatible version number as appropriate, then fall through to the next |
3013 // case. | 3075 // case. |
3014 | 3076 |
3015 case kCurrentVersionNumber: | 3077 case kCurrentVersionNumber: |
3016 // No migration needed. | 3078 // No migration needed. |
3017 return sql::INIT_OK; | 3079 return sql::INIT_OK; |
3018 } | 3080 } |
3019 } | 3081 } |
OLD | NEW |