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 <stdint.h> | 7 #include <stdint.h> |
8 | 8 |
9 #include <algorithm> | 9 #include <algorithm> |
10 #include <cmath> | 10 #include <cmath> |
11 #include <limits> | 11 #include <limits> |
12 #include <map> | 12 #include <map> |
13 #include <set> | 13 #include <set> |
14 #include <string> | 14 #include <string> |
15 #include <vector> | 15 #include <vector> |
16 | 16 |
17 #include "base/command_line.h" | 17 #include "base/command_line.h" |
18 #include "base/guid.h" | 18 #include "base/guid.h" |
19 #include "base/i18n/case_conversion.h" | 19 #include "base/i18n/case_conversion.h" |
20 #include "base/logging.h" | 20 #include "base/logging.h" |
| 21 #include "base/memory/ptr_util.h" |
21 #include "base/numerics/safe_conversions.h" | 22 #include "base/numerics/safe_conversions.h" |
22 #include "base/strings/string_number_conversions.h" | 23 #include "base/strings/string_number_conversions.h" |
23 #include "base/strings/string_util.h" | 24 #include "base/strings/string_util.h" |
24 #include "base/strings/utf_string_conversions.h" | 25 #include "base/strings/utf_string_conversions.h" |
25 #include "base/time/time.h" | 26 #include "base/time/time.h" |
26 #include "components/autofill/core/browser/autofill_country.h" | 27 #include "components/autofill/core/browser/autofill_country.h" |
27 #include "components/autofill/core/browser/autofill_profile.h" | 28 #include "components/autofill/core/browser/autofill_profile.h" |
28 #include "components/autofill/core/browser/autofill_type.h" | 29 #include "components/autofill/core/browser/autofill_type.h" |
29 #include "components/autofill/core/browser/credit_card.h" | 30 #include "components/autofill/core/browser/credit_card.h" |
30 #include "components/autofill/core/browser/personal_data_manager.h" | 31 #include "components/autofill/core/browser/personal_data_manager.h" |
(...skipping 874 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
905 // Get associated email info. | 906 // Get associated email info. |
906 AddAutofillProfileEmailsToProfile(db_, p.get()); | 907 AddAutofillProfileEmailsToProfile(db_, p.get()); |
907 | 908 |
908 // Get associated phone info. | 909 // Get associated phone info. |
909 AddAutofillProfilePhonesToProfile(db_, p.get()); | 910 AddAutofillProfilePhonesToProfile(db_, p.get()); |
910 | 911 |
911 return p; | 912 return p; |
912 } | 913 } |
913 | 914 |
914 bool AutofillTable::GetAutofillProfiles( | 915 bool AutofillTable::GetAutofillProfiles( |
915 std::vector<AutofillProfile*>* profiles) { | 916 std::vector<std::unique_ptr<AutofillProfile>>* profiles) { |
916 DCHECK(profiles); | 917 DCHECK(profiles); |
917 profiles->clear(); | 918 profiles->clear(); |
918 | 919 |
919 sql::Statement s(db_->GetUniqueStatement( | 920 sql::Statement s(db_->GetUniqueStatement( |
920 "SELECT guid " | 921 "SELECT guid " |
921 "FROM autofill_profiles " | 922 "FROM autofill_profiles " |
922 "ORDER BY date_modified DESC, guid")); | 923 "ORDER BY date_modified DESC, guid")); |
923 | 924 |
924 while (s.Step()) { | 925 while (s.Step()) { |
925 std::string guid = s.ColumnString(0); | 926 std::string guid = s.ColumnString(0); |
926 std::unique_ptr<AutofillProfile> profile = GetAutofillProfile(guid); | 927 std::unique_ptr<AutofillProfile> profile = GetAutofillProfile(guid); |
927 if (!profile) | 928 if (!profile) |
928 return false; | 929 return false; |
929 profiles->push_back(profile.release()); | 930 profiles->push_back(std::move(profile)); |
930 } | 931 } |
931 | 932 |
932 return s.Succeeded(); | 933 return s.Succeeded(); |
933 } | 934 } |
934 | 935 |
935 bool AutofillTable::GetServerProfiles(std::vector<AutofillProfile*>* profiles) { | 936 bool AutofillTable::GetServerProfiles( |
| 937 std::vector<std::unique_ptr<AutofillProfile>>* profiles) { |
936 profiles->clear(); | 938 profiles->clear(); |
937 | 939 |
938 sql::Statement s(db_->GetUniqueStatement( | 940 sql::Statement s(db_->GetUniqueStatement( |
939 "SELECT " | 941 "SELECT " |
940 "id," | 942 "id," |
941 "use_count," | 943 "use_count," |
942 "use_date," | 944 "use_date," |
943 "recipient_name," | 945 "recipient_name," |
944 "company_name," | 946 "company_name," |
945 "street_address," | 947 "street_address," |
946 "address_1," // ADDRESS_HOME_STATE | 948 "address_1," // ADDRESS_HOME_STATE |
947 "address_2," // ADDRESS_HOME_CITY | 949 "address_2," // ADDRESS_HOME_CITY |
948 "address_3," // ADDRESS_HOME_DEPENDENT_LOCALITY | 950 "address_3," // ADDRESS_HOME_DEPENDENT_LOCALITY |
949 "address_4," // Not supported in AutofillProfile yet. | 951 "address_4," // Not supported in AutofillProfile yet. |
950 "postal_code," // ADDRESS_HOME_ZIP | 952 "postal_code," // ADDRESS_HOME_ZIP |
951 "sorting_code," // ADDRESS_HOME_SORTING_CODE | 953 "sorting_code," // ADDRESS_HOME_SORTING_CODE |
952 "country_code," // ADDRESS_HOME_COUNTRY | 954 "country_code," // ADDRESS_HOME_COUNTRY |
953 "phone_number," // PHONE_HOME_WHOLE_NUMBER | 955 "phone_number," // PHONE_HOME_WHOLE_NUMBER |
954 "language_code " | 956 "language_code " |
955 "FROM server_addresses addresses " | 957 "FROM server_addresses addresses " |
956 "LEFT OUTER JOIN server_address_metadata USING (id)")); | 958 "LEFT OUTER JOIN server_address_metadata USING (id)")); |
957 | 959 |
958 while (s.Step()) { | 960 while (s.Step()) { |
959 int index = 0; | 961 int index = 0; |
960 std::unique_ptr<AutofillProfile> profile(new AutofillProfile( | 962 std::unique_ptr<AutofillProfile> profile = |
961 AutofillProfile::SERVER_PROFILE, s.ColumnString(index++))); | 963 base::MakeUnique<AutofillProfile>(AutofillProfile::SERVER_PROFILE, |
| 964 s.ColumnString(index++)); |
962 profile->set_use_count(s.ColumnInt64(index++)); | 965 profile->set_use_count(s.ColumnInt64(index++)); |
963 profile->set_use_date(Time::FromInternalValue(s.ColumnInt64(index++))); | 966 profile->set_use_date(Time::FromInternalValue(s.ColumnInt64(index++))); |
964 // Modification date is not tracked for server profiles. Explicitly set it | 967 // Modification date is not tracked for server profiles. Explicitly set it |
965 // here to override the default value of Time::Now(). | 968 // here to override the default value of Time::Now(). |
966 profile->set_modification_date(Time()); | 969 profile->set_modification_date(Time()); |
967 | 970 |
968 base::string16 recipient_name = s.ColumnString16(index++); | 971 base::string16 recipient_name = s.ColumnString16(index++); |
969 profile->SetRawInfo(COMPANY_NAME, s.ColumnString16(index++)); | 972 profile->SetRawInfo(COMPANY_NAME, s.ColumnString16(index++)); |
970 profile->SetRawInfo(ADDRESS_HOME_STREET_ADDRESS, s.ColumnString16(index++)); | 973 profile->SetRawInfo(ADDRESS_HOME_STREET_ADDRESS, s.ColumnString16(index++)); |
971 profile->SetRawInfo(ADDRESS_HOME_STATE, s.ColumnString16(index++)); | 974 profile->SetRawInfo(ADDRESS_HOME_STATE, s.ColumnString16(index++)); |
972 profile->SetRawInfo(ADDRESS_HOME_CITY, s.ColumnString16(index++)); | 975 profile->SetRawInfo(ADDRESS_HOME_CITY, s.ColumnString16(index++)); |
973 profile->SetRawInfo(ADDRESS_HOME_DEPENDENT_LOCALITY, | 976 profile->SetRawInfo(ADDRESS_HOME_DEPENDENT_LOCALITY, |
974 s.ColumnString16(index++)); | 977 s.ColumnString16(index++)); |
975 index++; // Skip address_4 which we haven't added to AutofillProfile yet. | 978 index++; // Skip address_4 which we haven't added to AutofillProfile yet. |
976 profile->SetRawInfo(ADDRESS_HOME_ZIP, s.ColumnString16(index++)); | 979 profile->SetRawInfo(ADDRESS_HOME_ZIP, s.ColumnString16(index++)); |
977 profile->SetRawInfo(ADDRESS_HOME_SORTING_CODE, s.ColumnString16(index++)); | 980 profile->SetRawInfo(ADDRESS_HOME_SORTING_CODE, s.ColumnString16(index++)); |
978 profile->SetRawInfo(ADDRESS_HOME_COUNTRY, s.ColumnString16(index++)); | 981 profile->SetRawInfo(ADDRESS_HOME_COUNTRY, s.ColumnString16(index++)); |
979 base::string16 phone_number = s.ColumnString16(index++); | 982 base::string16 phone_number = s.ColumnString16(index++); |
980 profile->set_language_code(s.ColumnString(index++)); | 983 profile->set_language_code(s.ColumnString(index++)); |
981 | 984 |
982 // SetInfo instead of SetRawInfo so the constituent pieces will be parsed | 985 // SetInfo instead of SetRawInfo so the constituent pieces will be parsed |
983 // for these data types. | 986 // for these data types. |
984 profile->SetInfo(AutofillType(NAME_FULL), recipient_name, | 987 profile->SetInfo(AutofillType(NAME_FULL), recipient_name, |
985 profile->language_code()); | 988 profile->language_code()); |
986 profile->SetInfo(AutofillType(PHONE_HOME_WHOLE_NUMBER), phone_number, | 989 profile->SetInfo(AutofillType(PHONE_HOME_WHOLE_NUMBER), phone_number, |
987 profile->language_code()); | 990 profile->language_code()); |
988 | 991 |
989 profiles->push_back(profile.release()); | 992 profiles->push_back(std::move(profile)); |
990 } | 993 } |
991 | 994 |
992 return s.Succeeded(); | 995 return s.Succeeded(); |
993 } | 996 } |
994 | 997 |
995 void AutofillTable::SetServerProfiles( | 998 void AutofillTable::SetServerProfiles( |
996 const std::vector<AutofillProfile>& profiles) { | 999 const std::vector<AutofillProfile>& profiles) { |
997 sql::Transaction transaction(db_); | 1000 sql::Transaction transaction(db_); |
998 if (!transaction.Begin()) | 1001 if (!transaction.Begin()) |
999 return; | 1002 return; |
(...skipping 166 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1166 "WHERE guid = ?")); | 1169 "WHERE guid = ?")); |
1167 s.BindString(0, guid); | 1170 s.BindString(0, guid); |
1168 | 1171 |
1169 if (!s.Step()) | 1172 if (!s.Step()) |
1170 return std::unique_ptr<CreditCard>(); | 1173 return std::unique_ptr<CreditCard>(); |
1171 | 1174 |
1172 return CreditCardFromStatement(s); | 1175 return CreditCardFromStatement(s); |
1173 } | 1176 } |
1174 | 1177 |
1175 bool AutofillTable::GetCreditCards( | 1178 bool AutofillTable::GetCreditCards( |
1176 std::vector<CreditCard*>* credit_cards) { | 1179 std::vector<std::unique_ptr<CreditCard>>* credit_cards) { |
1177 DCHECK(credit_cards); | 1180 DCHECK(credit_cards); |
1178 credit_cards->clear(); | 1181 credit_cards->clear(); |
1179 | 1182 |
1180 sql::Statement s(db_->GetUniqueStatement( | 1183 sql::Statement s(db_->GetUniqueStatement( |
1181 "SELECT guid " | 1184 "SELECT guid " |
1182 "FROM credit_cards " | 1185 "FROM credit_cards " |
1183 "ORDER BY date_modified DESC, guid")); | 1186 "ORDER BY date_modified DESC, guid")); |
1184 | 1187 |
1185 while (s.Step()) { | 1188 while (s.Step()) { |
1186 std::string guid = s.ColumnString(0); | 1189 std::string guid = s.ColumnString(0); |
1187 std::unique_ptr<CreditCard> credit_card = GetCreditCard(guid); | 1190 std::unique_ptr<CreditCard> credit_card = GetCreditCard(guid); |
1188 if (!credit_card) | 1191 if (!credit_card) |
1189 return false; | 1192 return false; |
1190 credit_cards->push_back(credit_card.release()); | 1193 credit_cards->push_back(std::move(credit_card)); |
1191 } | 1194 } |
1192 | 1195 |
1193 return s.Succeeded(); | 1196 return s.Succeeded(); |
1194 } | 1197 } |
1195 | 1198 |
1196 bool AutofillTable::GetServerCreditCards( | 1199 bool AutofillTable::GetServerCreditCards( |
1197 std::vector<CreditCard*>* credit_cards) { | 1200 std::vector<std::unique_ptr<CreditCard>>* credit_cards) { |
1198 credit_cards->clear(); | 1201 credit_cards->clear(); |
1199 | 1202 |
1200 sql::Statement s(db_->GetUniqueStatement( | 1203 sql::Statement s(db_->GetUniqueStatement( |
1201 "SELECT " | 1204 "SELECT " |
1202 "card_number_encrypted, " // 0 | 1205 "card_number_encrypted, " // 0 |
1203 "last_four," // 1 | 1206 "last_four," // 1 |
1204 "masked.id," // 2 | 1207 "masked.id," // 2 |
1205 "metadata.use_count," // 3 | 1208 "metadata.use_count," // 3 |
1206 "metadata.use_date," // 4 | 1209 "metadata.use_date," // 4 |
1207 "type," // 5 | 1210 "type," // 5 |
(...skipping 10 matching lines...) Expand all Loading... |
1218 | 1221 |
1219 // If the card_number_encrypted field is nonempty, we can assume this card | 1222 // If the card_number_encrypted field is nonempty, we can assume this card |
1220 // is a full card, otherwise it's masked. | 1223 // is a full card, otherwise it's masked. |
1221 base::string16 full_card_number = UnencryptedCardFromColumn(s, index++); | 1224 base::string16 full_card_number = UnencryptedCardFromColumn(s, index++); |
1222 base::string16 last_four = s.ColumnString16(index++); | 1225 base::string16 last_four = s.ColumnString16(index++); |
1223 CreditCard::RecordType record_type = full_card_number.empty() ? | 1226 CreditCard::RecordType record_type = full_card_number.empty() ? |
1224 CreditCard::MASKED_SERVER_CARD : | 1227 CreditCard::MASKED_SERVER_CARD : |
1225 CreditCard::FULL_SERVER_CARD; | 1228 CreditCard::FULL_SERVER_CARD; |
1226 std::string server_id = s.ColumnString(index++); | 1229 std::string server_id = s.ColumnString(index++); |
1227 | 1230 |
1228 CreditCard* card = new CreditCard(record_type, server_id); | 1231 std::unique_ptr<CreditCard> card = |
| 1232 base::MakeUnique<CreditCard>(record_type, server_id); |
1229 card->SetRawInfo( | 1233 card->SetRawInfo( |
1230 CREDIT_CARD_NUMBER, | 1234 CREDIT_CARD_NUMBER, |
1231 record_type == CreditCard::MASKED_SERVER_CARD ? last_four | 1235 record_type == CreditCard::MASKED_SERVER_CARD ? last_four |
1232 : full_card_number); | 1236 : full_card_number); |
1233 card->set_use_count(s.ColumnInt64(index++)); | 1237 card->set_use_count(s.ColumnInt64(index++)); |
1234 card->set_use_date(Time::FromInternalValue(s.ColumnInt64(index++))); | 1238 card->set_use_date(Time::FromInternalValue(s.ColumnInt64(index++))); |
1235 // Modification date is not tracked for server cards. Explicitly set it here | 1239 // Modification date is not tracked for server cards. Explicitly set it here |
1236 // to override the default value of Time::Now(). | 1240 // to override the default value of Time::Now(). |
1237 card->set_modification_date(Time()); | 1241 card->set_modification_date(Time()); |
1238 | 1242 |
1239 std::string card_type = s.ColumnString(index++); | 1243 std::string card_type = s.ColumnString(index++); |
1240 if (record_type == CreditCard::MASKED_SERVER_CARD) { | 1244 if (record_type == CreditCard::MASKED_SERVER_CARD) { |
1241 // The type must be set after setting the number to override the | 1245 // The type must be set after setting the number to override the |
1242 // autodectected type. | 1246 // autodetected type. |
1243 card->SetTypeForMaskedCard(card_type.c_str()); | 1247 card->SetTypeForMaskedCard(card_type.c_str()); |
1244 } else { | 1248 } else { |
1245 DCHECK_EQ(CreditCard::GetCreditCardType(full_card_number), card_type); | 1249 DCHECK_EQ(CreditCard::GetCreditCardType(full_card_number), card_type); |
1246 } | 1250 } |
1247 | 1251 |
1248 card->SetServerStatus(ServerStatusStringToEnum(s.ColumnString(index++))); | 1252 card->SetServerStatus(ServerStatusStringToEnum(s.ColumnString(index++))); |
1249 card->SetRawInfo(CREDIT_CARD_NAME_FULL, s.ColumnString16(index++)); | 1253 card->SetRawInfo(CREDIT_CARD_NAME_FULL, s.ColumnString16(index++)); |
1250 card->SetRawInfo(CREDIT_CARD_EXP_MONTH, s.ColumnString16(index++)); | 1254 card->SetRawInfo(CREDIT_CARD_EXP_MONTH, s.ColumnString16(index++)); |
1251 card->SetRawInfo(CREDIT_CARD_EXP_4_DIGIT_YEAR, s.ColumnString16(index++)); | 1255 card->SetRawInfo(CREDIT_CARD_EXP_4_DIGIT_YEAR, s.ColumnString16(index++)); |
1252 card->set_billing_address_id(s.ColumnString(index++)); | 1256 card->set_billing_address_id(s.ColumnString(index++)); |
1253 credit_cards->push_back(card); | 1257 credit_cards->push_back(std::move(card)); |
1254 } | 1258 } |
1255 | 1259 |
1256 return s.Succeeded(); | 1260 return s.Succeeded(); |
1257 } | 1261 } |
1258 | 1262 |
1259 void AutofillTable::SetServerCreditCards( | 1263 void AutofillTable::SetServerCreditCards( |
1260 const std::vector<CreditCard>& credit_cards) { | 1264 const std::vector<CreditCard>& credit_cards) { |
1261 sql::Transaction transaction(db_); | 1265 sql::Transaction transaction(db_); |
1262 if (!transaction.Begin()) | 1266 if (!transaction.Begin()) |
1263 return; | 1267 return; |
(...skipping 286 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1550 "DELETE FROM unmasked_credit_cards " | 1554 "DELETE FROM unmasked_credit_cards " |
1551 "WHERE unmask_date >= ? AND unmask_date < ?")); | 1555 "WHERE unmask_date >= ? AND unmask_date < ?")); |
1552 s_unmasked_cards.BindInt64(0, delete_begin.ToInternalValue()); | 1556 s_unmasked_cards.BindInt64(0, delete_begin.ToInternalValue()); |
1553 s_unmasked_cards.BindInt64(1, delete_end.ToInternalValue()); | 1557 s_unmasked_cards.BindInt64(1, delete_end.ToInternalValue()); |
1554 return s_unmasked_cards.Run(); | 1558 return s_unmasked_cards.Run(); |
1555 } | 1559 } |
1556 | 1560 |
1557 bool AutofillTable::RemoveOriginURLsModifiedBetween( | 1561 bool AutofillTable::RemoveOriginURLsModifiedBetween( |
1558 const Time& delete_begin, | 1562 const Time& delete_begin, |
1559 const Time& delete_end, | 1563 const Time& delete_end, |
1560 ScopedVector<AutofillProfile>* profiles) { | 1564 std::vector<std::unique_ptr<AutofillProfile>>* profiles) { |
1561 DCHECK(delete_end.is_null() || delete_begin < delete_end); | 1565 DCHECK(delete_end.is_null() || delete_begin < delete_end); |
1562 | 1566 |
1563 time_t delete_begin_t = delete_begin.ToTimeT(); | 1567 time_t delete_begin_t = delete_begin.ToTimeT(); |
1564 time_t delete_end_t = GetEndTime(delete_end); | 1568 time_t delete_end_t = GetEndTime(delete_end); |
1565 | 1569 |
1566 // Remember Autofill profiles with URL origins in the time range. | 1570 // Remember Autofill profiles with URL origins in the time range. |
1567 sql::Statement s_profiles_get(db_->GetUniqueStatement( | 1571 sql::Statement s_profiles_get(db_->GetUniqueStatement( |
1568 "SELECT guid, origin FROM autofill_profiles " | 1572 "SELECT guid, origin FROM autofill_profiles " |
1569 "WHERE date_modified >= ? AND date_modified < ?")); | 1573 "WHERE date_modified >= ? AND date_modified < ?")); |
1570 s_profiles_get.BindInt64(0, delete_begin_t); | 1574 s_profiles_get.BindInt64(0, delete_begin_t); |
(...skipping 14 matching lines...) Expand all Loading... |
1585 sql::Statement s_profile(db_->GetUniqueStatement( | 1589 sql::Statement s_profile(db_->GetUniqueStatement( |
1586 "UPDATE autofill_profiles SET origin='' WHERE guid=?")); | 1590 "UPDATE autofill_profiles SET origin='' WHERE guid=?")); |
1587 s_profile.BindString(0, guid); | 1591 s_profile.BindString(0, guid); |
1588 if (!s_profile.Run()) | 1592 if (!s_profile.Run()) |
1589 return false; | 1593 return false; |
1590 | 1594 |
1591 std::unique_ptr<AutofillProfile> profile = GetAutofillProfile(guid); | 1595 std::unique_ptr<AutofillProfile> profile = GetAutofillProfile(guid); |
1592 if (!profile) | 1596 if (!profile) |
1593 return false; | 1597 return false; |
1594 | 1598 |
1595 profiles->push_back(profile.release()); | 1599 profiles->push_back(std::move(profile)); |
1596 } | 1600 } |
1597 | 1601 |
1598 // Remember Autofill credit cards with URL origins in the time range. | 1602 // Remember Autofill credit cards with URL origins in the time range. |
1599 sql::Statement s_credit_cards_get(db_->GetUniqueStatement( | 1603 sql::Statement s_credit_cards_get(db_->GetUniqueStatement( |
1600 "SELECT guid, origin FROM credit_cards " | 1604 "SELECT guid, origin FROM credit_cards " |
1601 "WHERE date_modified >= ? AND date_modified < ?")); | 1605 "WHERE date_modified >= ? AND date_modified < ?")); |
1602 s_credit_cards_get.BindInt64(0, delete_begin_t); | 1606 s_credit_cards_get.BindInt64(0, delete_begin_t); |
1603 s_credit_cards_get.BindInt64(1, delete_end_t); | 1607 s_credit_cards_get.BindInt64(1, delete_end_t); |
1604 | 1608 |
1605 std::vector<std::string> credit_card_guids; | 1609 std::vector<std::string> credit_card_guids; |
(...skipping 699 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2305 } | 2309 } |
2306 | 2310 |
2307 bool AutofillTable::MigrateToVersion67AddMaskedCardBillingAddress() { | 2311 bool AutofillTable::MigrateToVersion67AddMaskedCardBillingAddress() { |
2308 // The default value for this column is null, but Connection::ColumnString() | 2312 // The default value for this column is null, but Connection::ColumnString() |
2309 // returns an empty string for that. | 2313 // returns an empty string for that. |
2310 return db_->Execute( | 2314 return db_->Execute( |
2311 "ALTER TABLE masked_credit_cards ADD COLUMN billing_address_id VARCHAR"); | 2315 "ALTER TABLE masked_credit_cards ADD COLUMN billing_address_id VARCHAR"); |
2312 } | 2316 } |
2313 | 2317 |
2314 } // namespace autofill | 2318 } // namespace autofill |
OLD | NEW |