Chromium Code Reviews| 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 363 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 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, " |
| 1273 "date_modified INTEGER NOT NULL DEFAULT 0, " | 1280 "date_modified INTEGER NOT NULL DEFAULT 0, " |
| 1274 "origin VARCHAR DEFAULT '')")) { | 1281 "origin VARCHAR DEFAULT '', " |
| 1282 "language_code VARCHAR)")) { | |
|
Ilya Sherman
2014/03/29 01:24:42
nit: Please sort this between country_code and dat
Scott Hess - ex-Googler
2014/03/31 17:46:38
It should be at the end to match the ALTER TABLE.
please use gerrit instead
2014/04/02 21:54:52
Keeping the field at the end to enable using ALTER
| |
| 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() { |
| 1283 if (!db_->DoesTableExist("autofill_profile_names")) { | 1291 if (!db_->DoesTableExist("autofill_profile_names")) { |
| 1284 if (!db_->Execute("CREATE TABLE autofill_profile_names ( " | 1292 if (!db_->Execute("CREATE TABLE autofill_profile_names ( " |
| (...skipping 968 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() { | |
| 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. | |
|
Ilya Sherman
2014/03/29 01:24:42
This sort of thing should no longer be needed. It
Scott Hess - ex-Googler
2014/03/31 17:46:38
I agree, no reason for a commit if there's only a
please use gerrit instead
2014/04/02 21:54:52
Since the existence check is no longer necessary (
Scott Hess - ex-Googler
2014/04/02 22:20:22
Unfortunately, Chromium's overall schema version m
| |
| 2279 if (!db_->DoesColumnExist("autofill_profiles", "language_code")) { | |
| 2280 if (!db_->Execute("ALTER TABLE autofill_profiles " | |
| 2281 "ADD COLUMN language_code VARCHAR")) { | |
| 2282 return false; | |
| 2283 } | |
| 2284 } | |
| 2285 | |
| 2286 return transaction.Commit(); | |
| 2287 } | |
| 2288 | |
| 2263 } // namespace autofill | 2289 } // namespace autofill |
| OLD | NEW |