OLD | NEW |
---|---|
1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 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 "components/autofill/core/browser/webdata/autofill_table.h" | 5 #include "components/autofill/core/browser/webdata/autofill_table.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 #include <cmath> | 8 #include <cmath> |
9 #include <limits> | 9 #include <limits> |
10 #include <map> | 10 #include <map> |
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
82 s->BindString(index++, profile.guid()); | 82 s->BindString(index++, profile.guid()); |
83 | 83 |
84 s->BindString16(index++, GetInfo(profile, COMPANY_NAME)); | 84 s->BindString16(index++, GetInfo(profile, COMPANY_NAME)); |
85 s->BindString16(index++, GetInfo(profile, ADDRESS_HOME_STREET_ADDRESS)); | 85 s->BindString16(index++, GetInfo(profile, ADDRESS_HOME_STREET_ADDRESS)); |
86 s->BindString16(index++, GetInfo(profile, ADDRESS_HOME_DEPENDENT_LOCALITY)); | 86 s->BindString16(index++, GetInfo(profile, ADDRESS_HOME_DEPENDENT_LOCALITY)); |
87 s->BindString16(index++, GetInfo(profile, ADDRESS_HOME_CITY)); | 87 s->BindString16(index++, GetInfo(profile, ADDRESS_HOME_CITY)); |
88 s->BindString16(index++, GetInfo(profile, ADDRESS_HOME_STATE)); | 88 s->BindString16(index++, GetInfo(profile, ADDRESS_HOME_STATE)); |
89 s->BindString16(index++, GetInfo(profile, ADDRESS_HOME_ZIP)); | 89 s->BindString16(index++, GetInfo(profile, ADDRESS_HOME_ZIP)); |
90 s->BindString16(index++, GetInfo(profile, ADDRESS_HOME_SORTING_CODE)); | 90 s->BindString16(index++, GetInfo(profile, ADDRESS_HOME_SORTING_CODE)); |
91 s->BindString16(index++, GetInfo(profile, ADDRESS_HOME_COUNTRY)); | 91 s->BindString16(index++, GetInfo(profile, ADDRESS_HOME_COUNTRY)); |
92 s->BindString(index++, profile.language_code()); | |
92 s->BindInt64(index++, Time::Now().ToTimeT()); | 93 s->BindInt64(index++, Time::Now().ToTimeT()); |
93 s->BindString(index++, profile.origin()); | 94 s->BindString(index++, profile.origin()); |
94 } | 95 } |
95 | 96 |
96 scoped_ptr<AutofillProfile> AutofillProfileFromStatement( | 97 scoped_ptr<AutofillProfile> AutofillProfileFromStatement( |
97 const sql::Statement& s) { | 98 const sql::Statement& s) { |
98 scoped_ptr<AutofillProfile> profile(new AutofillProfile); | 99 scoped_ptr<AutofillProfile> profile(new AutofillProfile); |
99 int index = 0; | 100 int index = 0; |
100 profile->set_guid(s.ColumnString(index++)); | 101 profile->set_guid(s.ColumnString(index++)); |
101 DCHECK(base::IsValidGUID(profile->guid())); | 102 DCHECK(base::IsValidGUID(profile->guid())); |
102 | 103 |
103 profile->SetRawInfo(COMPANY_NAME, s.ColumnString16(index++)); | 104 profile->SetRawInfo(COMPANY_NAME, s.ColumnString16(index++)); |
104 profile->SetRawInfo(ADDRESS_HOME_STREET_ADDRESS, s.ColumnString16(index++)); | 105 profile->SetRawInfo(ADDRESS_HOME_STREET_ADDRESS, s.ColumnString16(index++)); |
105 profile->SetRawInfo(ADDRESS_HOME_DEPENDENT_LOCALITY, | 106 profile->SetRawInfo(ADDRESS_HOME_DEPENDENT_LOCALITY, |
106 s.ColumnString16(index++)); | 107 s.ColumnString16(index++)); |
107 profile->SetRawInfo(ADDRESS_HOME_CITY, s.ColumnString16(index++)); | 108 profile->SetRawInfo(ADDRESS_HOME_CITY, s.ColumnString16(index++)); |
108 profile->SetRawInfo(ADDRESS_HOME_STATE, s.ColumnString16(index++)); | 109 profile->SetRawInfo(ADDRESS_HOME_STATE, s.ColumnString16(index++)); |
109 profile->SetRawInfo(ADDRESS_HOME_ZIP, s.ColumnString16(index++)); | 110 profile->SetRawInfo(ADDRESS_HOME_ZIP, s.ColumnString16(index++)); |
110 profile->SetRawInfo(ADDRESS_HOME_SORTING_CODE, s.ColumnString16(index++)); | 111 profile->SetRawInfo(ADDRESS_HOME_SORTING_CODE, s.ColumnString16(index++)); |
111 profile->SetRawInfo(ADDRESS_HOME_COUNTRY, s.ColumnString16(index++)); | 112 profile->SetRawInfo(ADDRESS_HOME_COUNTRY, s.ColumnString16(index++)); |
113 profile->set_language_code(s.ColumnString(index++)); | |
112 // Intentionally skip column 9, which stores the profile's modification date. | 114 // Intentionally skip column 9, which stores the profile's modification date. |
113 index++; | 115 index++; |
114 profile->set_origin(s.ColumnString(index++)); | 116 profile->set_origin(s.ColumnString(index++)); |
115 | 117 |
116 return profile.Pass(); | 118 return profile.Pass(); |
117 } | 119 } |
118 | 120 |
119 void BindCreditCardToStatement(const CreditCard& credit_card, | 121 void BindCreditCardToStatement(const CreditCard& credit_card, |
120 sql::Statement* s) { | 122 sql::Statement* s) { |
121 DCHECK(base::IsValidGUID(credit_card.guid())); | 123 DCHECK(base::IsValidGUID(credit_card.guid())); |
(...skipping 313 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
435 // Combine migrations 50 and 51. The migration code from version 49 to 50 | 437 // Combine migrations 50 and 51. The migration code from version 49 to 50 |
436 // worked correctly for users with existing 'origin' columns, but failed | 438 // worked correctly for users with existing 'origin' columns, but failed |
437 // to create these columns for new users. | 439 // to create these columns for new users. |
438 return MigrateToVersion51AddOriginColumn(); | 440 return MigrateToVersion51AddOriginColumn(); |
439 case 54: | 441 case 54: |
440 *update_compatible_version = true; | 442 *update_compatible_version = true; |
441 return MigrateToVersion54AddI18nFieldsAndRemoveDeprecatedFields(); | 443 return MigrateToVersion54AddI18nFieldsAndRemoveDeprecatedFields(); |
442 case 55: | 444 case 55: |
443 *update_compatible_version = true; | 445 *update_compatible_version = true; |
444 return MigrateToVersion55MergeAutofillDatesTable(); | 446 return MigrateToVersion55MergeAutofillDatesTable(); |
447 case 56: | |
448 *update_compatible_version = true; | |
449 return MigrateToVersion56AddProfileLanguageCodeForFormatting(); | |
445 } | 450 } |
446 return true; | 451 return true; |
447 } | 452 } |
448 | 453 |
449 bool AutofillTable::AddFormFieldValues( | 454 bool AutofillTable::AddFormFieldValues( |
450 const std::vector<FormFieldData>& elements, | 455 const std::vector<FormFieldData>& elements, |
451 std::vector<AutofillChange>* changes) { | 456 std::vector<AutofillChange>* changes) { |
452 return AddFormFieldValuesTime(elements, changes, Time::Now()); | 457 return AddFormFieldValuesTime(elements, changes, Time::Now()); |
453 } | 458 } |
454 | 459 |
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
542 change_type = AutofillChange::REMOVE; | 547 change_type = AutofillChange::REMOVE; |
543 } else { | 548 } else { |
544 change_type = AutofillChange::UPDATE; | 549 change_type = AutofillChange::UPDATE; |
545 | 550 |
546 // For all updated elements, set either date_created or date_last_used so | 551 // For all updated elements, set either date_created or date_last_used so |
547 // that the range [date_created, date_last_used] no longer overlaps with | 552 // that the range [date_created, date_last_used] no longer overlaps with |
548 // [delete_begin, delete_end). Update the count by interpolating. | 553 // [delete_begin, delete_end). Update the count by interpolating. |
549 // Precisely, compute the average amount of time between increments to the | 554 // Precisely, compute the average amount of time between increments to the |
550 // count in the original range [date_created, date_last_used]: | 555 // count in the original range [date_created, date_last_used]: |
551 // avg_delta = (date_last_used_orig - date_created_orig) / (count - 1) | 556 // avg_delta = (date_last_used_orig - date_created_orig) / (count - 1) |
552 // The count can be exressed as | 557 // The count can be expressed as |
553 // count = 1 + (date_last_used - date_created) / avg_delta | 558 // count = 1 + (date_last_used - date_created) / avg_delta |
554 // Hence, update the count to | 559 // Hence, update the count to |
555 // count_new = 1 + (date_last_used_new - date_created_new) / avg_delta | 560 // count_new = 1 + (date_last_used_new - date_created_new) / avg_delta |
556 // = 1 + ((count - 1) * | 561 // = 1 + ((count - 1) * |
557 // (date_last_used_new - date_created_new) / | 562 // (date_last_used_new - date_created_new) / |
558 // (date_last_used_orig - date_created_orig)) | 563 // (date_last_used_orig - date_created_orig)) |
559 // Interpolating might not give a result that completely accurately | 564 // Interpolating might not give a result that completely accurately |
560 // reflects the user's history, but it's the best that can be done given | 565 // reflects the user's history, but it's the best that can be done given |
561 // the information in the database. | 566 // the information in the database. |
562 AutofillUpdate updated_entry; | 567 AutofillUpdate updated_entry; |
(...skipping 233 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
796 return s.Run(); | 801 return s.Run(); |
797 } | 802 } |
798 | 803 |
799 bool AutofillTable::AddAutofillProfile(const AutofillProfile& profile) { | 804 bool AutofillTable::AddAutofillProfile(const AutofillProfile& profile) { |
800 if (IsAutofillGUIDInTrash(profile.guid())) | 805 if (IsAutofillGUIDInTrash(profile.guid())) |
801 return true; | 806 return true; |
802 | 807 |
803 sql::Statement s(db_->GetUniqueStatement( | 808 sql::Statement s(db_->GetUniqueStatement( |
804 "INSERT INTO autofill_profiles" | 809 "INSERT INTO autofill_profiles" |
805 "(guid, company_name, street_address, dependent_locality, city, state," | 810 "(guid, company_name, street_address, dependent_locality, city, state," |
806 " zipcode, sorting_code, country_code, date_modified, origin)" | 811 " zipcode, sorting_code, country_code, language_code, date_modified," |
807 "VALUES (?,?,?,?,?,?,?,?,?,?,?)")); | 812 " origin)" |
813 "VALUES (?,?,?,?,?,?,?,?,?,?,?,?)")); | |
808 BindAutofillProfileToStatement(profile, &s); | 814 BindAutofillProfileToStatement(profile, &s); |
809 | 815 |
810 if (!s.Run()) | 816 if (!s.Run()) |
811 return false; | 817 return false; |
812 | 818 |
813 return AddAutofillProfilePieces(profile, db_); | 819 return AddAutofillProfilePieces(profile, db_); |
814 } | 820 } |
815 | 821 |
816 bool AutofillTable::GetAutofillProfile(const std::string& guid, | 822 bool AutofillTable::GetAutofillProfile(const std::string& guid, |
817 AutofillProfile** profile) { | 823 AutofillProfile** profile) { |
818 DCHECK(base::IsValidGUID(guid)); | 824 DCHECK(base::IsValidGUID(guid)); |
819 DCHECK(profile); | 825 DCHECK(profile); |
820 sql::Statement s(db_->GetUniqueStatement( | 826 sql::Statement s(db_->GetUniqueStatement( |
821 "SELECT guid, company_name, street_address, dependent_locality, city," | 827 "SELECT guid, company_name, street_address, dependent_locality, city," |
822 " state, zipcode, sorting_code, country_code, date_modified, origin " | 828 " state, zipcode, sorting_code, country_code, language_code," |
829 " date_modified, origin " | |
823 "FROM autofill_profiles " | 830 "FROM autofill_profiles " |
824 "WHERE guid=?")); | 831 "WHERE guid=?")); |
825 s.BindString(0, guid); | 832 s.BindString(0, guid); |
826 | 833 |
827 if (!s.Step()) | 834 if (!s.Step()) |
828 return false; | 835 return false; |
829 | 836 |
830 scoped_ptr<AutofillProfile> p = AutofillProfileFromStatement(s); | 837 scoped_ptr<AutofillProfile> p = AutofillProfileFromStatement(s); |
831 | 838 |
832 // Get associated name info. | 839 // Get associated name info. |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
877 // Preserve appropriate modification dates by not updating unchanged profiles. | 884 // Preserve appropriate modification dates by not updating unchanged profiles. |
878 scoped_ptr<AutofillProfile> old_profile(tmp_profile); | 885 scoped_ptr<AutofillProfile> old_profile(tmp_profile); |
879 if (old_profile->Compare(profile) == 0 && | 886 if (old_profile->Compare(profile) == 0 && |
880 old_profile->origin() == profile.origin()) | 887 old_profile->origin() == profile.origin()) |
881 return true; | 888 return true; |
882 | 889 |
883 sql::Statement s(db_->GetUniqueStatement( | 890 sql::Statement s(db_->GetUniqueStatement( |
884 "UPDATE autofill_profiles " | 891 "UPDATE autofill_profiles " |
885 "SET guid=?, company_name=?, street_address=?, dependent_locality=?, " | 892 "SET guid=?, company_name=?, street_address=?, dependent_locality=?, " |
886 " city=?, state=?, zipcode=?, sorting_code=?, country_code=?, " | 893 " city=?, state=?, zipcode=?, sorting_code=?, country_code=?, " |
887 " date_modified=?, origin=? " | 894 " language_code=?, date_modified=?, origin=? " |
888 "WHERE guid=?")); | 895 "WHERE guid=?")); |
889 BindAutofillProfileToStatement(profile, &s); | 896 BindAutofillProfileToStatement(profile, &s); |
890 s.BindString(11, profile.guid()); | 897 s.BindString(12, profile.guid()); |
891 | 898 |
892 bool result = s.Run(); | 899 bool result = s.Run(); |
893 DCHECK_GT(db_->GetLastChangeCount(), 0); | 900 DCHECK_GT(db_->GetLastChangeCount(), 0); |
894 if (!result) | 901 if (!result) |
895 return result; | 902 return result; |
896 | 903 |
897 // Remove the old names, emails, and phone numbers. | 904 // Remove the old names, emails, and phone numbers. |
898 if (!RemoveAutofillProfilePieces(profile.guid(), db_)) | 905 if (!RemoveAutofillProfilePieces(profile.guid(), db_)) |
899 return false; | 906 return false; |
900 | 907 |
(...skipping 362 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1263 if (!db_->Execute("CREATE TABLE autofill_profiles ( " | 1270 if (!db_->Execute("CREATE TABLE autofill_profiles ( " |
1264 "guid VARCHAR PRIMARY KEY, " | 1271 "guid VARCHAR PRIMARY KEY, " |
1265 "company_name VARCHAR, " | 1272 "company_name VARCHAR, " |
1266 "street_address VARCHAR, " | 1273 "street_address VARCHAR, " |
1267 "dependent_locality VARCHAR, " | 1274 "dependent_locality VARCHAR, " |
1268 "city VARCHAR, " | 1275 "city VARCHAR, " |
1269 "state VARCHAR, " | 1276 "state VARCHAR, " |
1270 "zipcode VARCHAR, " | 1277 "zipcode VARCHAR, " |
1271 "sorting_code VARCHAR, " | 1278 "sorting_code VARCHAR, " |
1272 "country_code VARCHAR, " | 1279 "country_code VARCHAR, " |
1280 "language_code VARCHAR, " | |
Scott Hess - ex-Googler
2014/03/28 19:53:57
Since ALTER TABLE can only add new columns, I gene
please use gerrit instead
2014/03/28 22:00:38
Changed the statement to append the column instead
| |
1273 "date_modified INTEGER NOT NULL DEFAULT 0, " | 1281 "date_modified INTEGER NOT NULL DEFAULT 0, " |
1274 "origin VARCHAR DEFAULT '')")) { | 1282 "origin VARCHAR DEFAULT '')")) { |
1275 NOTREACHED(); | 1283 NOTREACHED(); |
1276 return false; | 1284 return false; |
1277 } | 1285 } |
1278 } | 1286 } |
1279 return true; | 1287 return true; |
1280 } | 1288 } |
1281 | 1289 |
1282 bool AutofillTable::InitProfileNamesTable() { | 1290 bool AutofillTable::InitProfileNamesTable() { |
(...skipping 970 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2253 if (!db_->Execute("CREATE INDEX autofill_name ON autofill (name)") || | 2261 if (!db_->Execute("CREATE INDEX autofill_name ON autofill (name)") || |
2254 !db_->Execute("CREATE INDEX autofill_name_value_lower ON " | 2262 !db_->Execute("CREATE INDEX autofill_name_value_lower ON " |
2255 "autofill (name, value_lower)")) { | 2263 "autofill (name, value_lower)")) { |
2256 return false; | 2264 return false; |
2257 } | 2265 } |
2258 | 2266 |
2259 | 2267 |
2260 return transaction.Commit(); | 2268 return transaction.Commit(); |
2261 } | 2269 } |
2262 | 2270 |
2271 bool AutofillTable::MigrateToVersion56AddProfileLanguageCodeForFormatting() { | |
Scott Hess - ex-Googler
2014/03/28 19:53:57
AFAICT, this is just manually implementing ALTER T
please use gerrit instead
2014/03/28 22:00:38
Replaced the manual operations with a single alter
| |
2272 sql::Transaction transaction(db_); | |
2273 if (!transaction.Begin()) | |
2274 return false; | |
2275 | |
2276 // Test the existence of the |language_code| column as an indication that a | |
2277 // migration is needed. It is possible that this column already exists because | |
2278 // the table was newly created when migrating from a pre-version-23 database. | |
2279 if (!db_->DoesColumnExist("autofill_profiles", "language_code")) { | |
2280 // Create a temporary copy of the autofill_profiles table in the (newer) | |
2281 // version 56 format. This table adds a column for |language_code|. | |
2282 if (db_->DoesTableExist("autofill_profiles_temp") || | |
2283 !db_->Execute("CREATE TABLE autofill_profiles_temp ( " | |
2284 "guid VARCHAR PRIMARY KEY, " | |
2285 "company_name VARCHAR, " | |
2286 "street_address VARCHAR, " | |
2287 "dependent_locality VARCHAR, " | |
2288 "city VARCHAR, " | |
2289 "state VARCHAR, " | |
2290 "zipcode VARCHAR, " | |
2291 "sorting_code VARCHAR, " | |
2292 "country_code VARCHAR, " | |
2293 "language_code VARCHAR, " | |
2294 "date_modified INTEGER NOT NULL DEFAULT 0, " | |
2295 "origin VARCHAR DEFAULT '')")) { | |
2296 return false; | |
2297 } | |
2298 | |
2299 // Copy over the data from the autofill_profiles table, initiating the | |
2300 // |language_code| column with an empty string. | |
2301 if (!db_->Execute("INSERT INTO autofill_profiles_temp " | |
2302 "SELECT guid, company_name, street_address, " | |
2303 "dependent_locality, city, state, zipcode, sorting_code, " | |
2304 "country_code, '', date_modified, origin " | |
2305 "FROM autofill_profiles")) { | |
2306 return false; | |
2307 } | |
2308 | |
2309 // Delete the existing (version 55) table and replace it with the contents | |
2310 // of the temporary table. | |
2311 if (!db_->Execute("DROP TABLE autofill_profiles") || | |
2312 !db_->Execute("ALTER TABLE autofill_profiles_temp " | |
2313 "RENAME TO autofill_profiles")) { | |
2314 return false; | |
2315 } | |
2316 } | |
2317 | |
2318 return transaction.Commit(); | |
2319 } | |
2320 | |
2263 } // namespace autofill | 2321 } // namespace autofill |
OLD | NEW |