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

Unified Diff: components/autofill/core/browser/webdata/autofill_table.cc

Issue 1042353003: Create syncable metadata table for Wallet credit cards and addresses. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: comment about migration code Created 5 years, 8 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 side-by-side diff with in-line comments
Download patch
Index: components/autofill/core/browser/webdata/autofill_table.cc
diff --git a/components/autofill/core/browser/webdata/autofill_table.cc b/components/autofill/core/browser/webdata/autofill_table.cc
index 10ec2469b0d7c7be7de1a18252784540578b8bbc..3f5a4c21dbd5e776edb5a05cffa4266887fe0107 100644
--- a/components/autofill/core/browser/webdata/autofill_table.cc
+++ b/components/autofill/core/browser/webdata/autofill_table.cc
@@ -437,7 +437,8 @@ bool AutofillTable::CreateTablesIfNecessary() {
InitProfileNamesTable() && InitProfileEmailsTable() &&
InitProfilePhonesTable() && InitProfileTrashTable() &&
InitMaskedCreditCardsTable() && InitUnmaskedCreditCardsTable() &&
- InitServerAddressesTable());
+ InitServerCardMetadataTable() && InitServerAddressesTable() &&
+ InitServerAddressMetadataTable());
}
bool AutofillTable::IsSyncable() {
@@ -475,6 +476,9 @@ bool AutofillTable::MigrateToVersion(int version,
case 64:
*update_compatible_version = false;
return MigrateToVersion64AddUnmaskDate();
+ case 65:
+ *update_compatible_version = false;
+ return MigrateToVersion65AddServerMetadataTables();
}
return true;
}
@@ -904,6 +908,8 @@ bool AutofillTable::GetServerProfiles(std::vector<AutofillProfile*>* profiles) {
sql::Statement s(db_->GetUniqueStatement(
"SELECT "
"id,"
+ "use_count,"
+ "use_date,"
"recipient_name,"
"company_name,"
"street_address,"
@@ -916,12 +922,16 @@ bool AutofillTable::GetServerProfiles(std::vector<AutofillProfile*>* profiles) {
"country_code," // ADDRESS_HOME_COUNTRY
"phone_number," // PHONE_HOME_WHOLE_NUMBER
"language_code "
- "FROM server_addresses"));
+ "FROM server_addresses addresses "
+ "LEFT OUTER JOIN server_address_metadata USING (id)"));
while (s.Step()) {
int index = 0;
scoped_ptr<AutofillProfile> profile(new AutofillProfile(
AutofillProfile::SERVER_PROFILE, s.ColumnString(index++)));
+ profile->set_use_count(s.ColumnInt64(index++));
+ profile->set_use_date(
+ base::Time::FromInternalValue(s.ColumnInt64(index++)));
base::string16 recipient_name = s.ColumnString16(index++);
profile->SetRawInfo(COMPANY_NAME, s.ColumnString16(index++));
@@ -1001,6 +1011,12 @@ void AutofillTable::SetServerProfiles(
insert.Reset(true);
}
+ // Delete metadata that's no longer relevant.
+ sql::Statement metadata_delete(db_->GetUniqueStatement(
+ "DELETE FROM server_address_metadata WHERE id NOT IN "
+ "(SELECT id FROM server_addresses)"));
+ metadata_delete.Run();
+
transaction.Commit();
}
@@ -1155,16 +1171,16 @@ bool AutofillTable::GetServerCreditCards(
"card_number_encrypted, " // 0
"last_four," // 1
"masked.id," // 2
- "use_count," // 3
- "use_date," // 4
+ "metadata.use_count," // 3
+ "metadata.use_date," // 4
"type," // 5
"status," // 6
"name_on_card," // 7
"exp_month," // 8
"exp_year " // 9
"FROM masked_credit_cards masked "
- "LEFT OUTER JOIN unmasked_credit_cards unmasked "
- "ON masked.id = unmasked.id"));
+ "LEFT OUTER JOIN unmasked_credit_cards USING (id) "
+ "LEFT OUTER JOIN server_card_metadata metadata USING (id)"));
while (s.Step()) {
int index = 0;
@@ -1182,19 +1198,16 @@ bool AutofillTable::GetServerCreditCards(
CREDIT_CARD_NUMBER,
record_type == CreditCard::MASKED_SERVER_CARD ? last_four
: full_card_number);
- int64 use_count = s.ColumnInt64(index++);
- int64 use_date = s.ColumnInt64(index++);
+ card->set_use_count(s.ColumnInt64(index++));
+ card->set_use_date(base::Time::FromInternalValue(s.ColumnInt64(index++)));
+
std::string card_type = s.ColumnString(index++);
if (record_type == CreditCard::MASKED_SERVER_CARD) {
// The type must be set after setting the number to override the
// autodectected type.
card->SetTypeForMaskedCard(card_type.c_str());
- DCHECK_EQ(0, use_count);
- DCHECK_EQ(0, use_date);
} else {
DCHECK_EQ(CreditCard::GetCreditCardType(full_card_number), card_type);
- card->set_use_count(use_count);
- card->set_use_date(base::Time::FromInternalValue(use_date));
}
card->SetServerStatus(ServerStatusStringToEnum(s.ColumnString(index++)));
@@ -1218,31 +1231,6 @@ void AutofillTable::SetServerCreditCards(
"DELETE FROM masked_credit_cards"));
masked_delete.Run();
- // Delete all items in the unmasked table that aren't in the new set.
- sql::Statement get_unmasked(db_->GetUniqueStatement(
- "SELECT id FROM unmasked_credit_cards"));
- while (get_unmasked.Step()) {
- // We expect relatively few cards, just do brute-force.
- std::string server_id = get_unmasked.ColumnString(0);
- bool found_card = false;
- for (const CreditCard& cur_card : credit_cards) {
- if (cur_card.server_id() == server_id) {
- found_card = true;
- break;
- }
- }
- if (!found_card) {
- // This unmasked card in the DB isn't present in the input. The statement
- // is compiled every time because it's much more likely that this is never
- // executed than it runs more than once.
- sql::Statement unmasked_delete(db_->GetUniqueStatement(
- "DELETE FROM unmasked_credit_cards WHERE id = ?"));
- unmasked_delete.BindString(0, server_id);
- unmasked_delete.Run();
- DCHECK_EQ(1, db_->GetLastChangeCount());
- }
- }
-
sql::Statement masked_insert(db_->GetUniqueStatement(
"INSERT INTO masked_credit_cards("
"id," // 0
@@ -1270,36 +1258,46 @@ void AutofillTable::SetServerCreditCards(
masked_insert.Reset(true);
}
+ // Delete all items in the unmasked table that aren't in the new set.
+ sql::Statement unmasked_delete(db_->GetUniqueStatement(
+ "DELETE FROM unmasked_credit_cards WHERE id NOT IN "
+ "(SELECT id FROM masked_credit_cards)"));
+ unmasked_delete.Run();
+ // Do the same for metadata.
+ sql::Statement metadata_delete(db_->GetUniqueStatement(
+ "DELETE FROM server_card_metadata WHERE id NOT IN "
+ "(SELECT id FROM masked_credit_cards)"));
+ metadata_delete.Run();
+
transaction.Commit();
}
-bool AutofillTable::UnmaskServerCreditCard(const std::string& id,
+bool AutofillTable::UnmaskServerCreditCard(const CreditCard& masked,
const base::string16& full_number) {
// Make sure there aren't duplicates for this card.
- MaskServerCreditCard(id);
+ MaskServerCreditCard(masked.server_id());
sql::Statement s(db_->GetUniqueStatement(
"INSERT INTO unmasked_credit_cards("
"id,"
"card_number_encrypted,"
- "use_count,"
- "use_date,"
"unmask_date)"
- "VALUES (?,?,?,?,?)"));
- s.BindString(0, id);
+ "VALUES (?,?,?)"));
+ s.BindString(0, masked.server_id());
std::string encrypted_data;
OSCrypt::EncryptString16(full_number, &encrypted_data);
s.BindBlob(1, encrypted_data.data(),
static_cast<int>(encrypted_data.length()));
+ s.BindInt64(2, base::Time::Now().ToInternalValue()); // unmask_date
- // Unmasking counts as a usage, so set the stats accordingly.
- base::Time now = base::Time::Now();
- s.BindInt64(2, 1); // use_count
- s.BindInt64(3, now.ToInternalValue()); // use_date
+ s.Run();
- s.BindInt64(4, now.ToInternalValue()); // unmask_date
+ CreditCard unmasked = masked;
+ unmasked.set_record_type(CreditCard::FULL_SERVER_CARD);
+ unmasked.SetNumber(full_number);
+ unmasked.RecordUse();
+ UpdateServerCardUsageStats(unmasked);
- s.Run();
return db_->GetLastChangeCount() > 0;
}
@@ -1311,18 +1309,54 @@ bool AutofillTable::MaskServerCreditCard(const std::string& id) {
return db_->GetLastChangeCount() > 0;
}
-bool AutofillTable::UpdateUnmaskedCardUsageStats(
+bool AutofillTable::UpdateServerCardUsageStats(
const CreditCard& credit_card) {
- DCHECK_EQ(CreditCard::FULL_SERVER_CARD, credit_card.record_type());
+ DCHECK_NE(CreditCard::LOCAL_CARD, credit_card.record_type());
+ sql::Transaction transaction(db_);
+ if (!transaction.Begin())
+ return false;
+
+ sql::Statement remove(db_->GetUniqueStatement(
+ "DELETE FROM server_card_metadata WHERE id = ?"));
+ remove.BindString(0, credit_card.server_id());
+ remove.Run();
sql::Statement s(db_->GetUniqueStatement(
- "UPDATE unmasked_credit_cards "
- "SET use_count=?, use_date=? "
- "WHERE id=?"));
+ "INSERT INTO server_card_metadata(use_count, use_date, id)"
+ "VALUES (?,?,?)"));
s.BindInt64(0, credit_card.use_count());
s.BindInt64(1, credit_card.use_date().ToInternalValue());
s.BindString(2, credit_card.server_id());
s.Run();
+
+ transaction.Commit();
+
+ return db_->GetLastChangeCount() > 0;
+}
+
+bool AutofillTable::UpdateServerAddressUsageStats(
+ const AutofillProfile& profile) {
+ DCHECK_EQ(AutofillProfile::SERVER_PROFILE, profile.record_type());
+
+ sql::Transaction transaction(db_);
+ if (!transaction.Begin())
+ return false;
+
+ sql::Statement remove(db_->GetUniqueStatement(
+ "DELETE FROM server_address_metadata WHERE id = ?"));
+ remove.BindString(0, profile.server_id());
+ remove.Run();
+
+ sql::Statement s(db_->GetUniqueStatement(
+ "INSERT INTO server_address_metadata(use_count, use_date, id)"
+ "VALUES (?,?,?)"));
+ s.BindInt64(0, profile.use_count());
+ s.BindInt64(1, profile.use_date().ToInternalValue());
+ s.BindString(2, profile.server_id());
+ s.Run();
+
+ transaction.Commit();
+
return db_->GetLastChangeCount() > 0;
}
@@ -1346,6 +1380,16 @@ bool AutofillTable::ClearAllServerData() {
addresses.Run();
changed |= db_->GetLastChangeCount() > 0;
+ sql::Statement card_metadata(db_->GetUniqueStatement(
+ "DELETE FROM server_card_metadata"));
+ card_metadata.Run();
+ changed |= db_->GetLastChangeCount() > 0;
+
+ sql::Statement address_metadata(db_->GetUniqueStatement(
+ "DELETE FROM server_address_metadata"));
+ address_metadata.Run();
+ changed |= db_->GetLastChangeCount() > 0;
+
transaction.Commit();
return changed;
}
@@ -1725,6 +1769,19 @@ bool AutofillTable::InitUnmaskedCreditCardsTable() {
return true;
}
+bool AutofillTable::InitServerCardMetadataTable() {
+ if (!db_->DoesTableExist("server_card_metadata")) {
+ if (!db_->Execute("CREATE TABLE server_card_metadata ("
+ "id VARCHAR NOT NULL,"
+ "use_count INTEGER NOT NULL DEFAULT 0, "
+ "use_date INTEGER NOT NULL DEFAULT 0)")) {
+ NOTREACHED();
+ return false;
+ }
+ }
+ return true;
+}
+
bool AutofillTable::InitServerAddressesTable() {
if (!db_->DoesTableExist("server_addresses")) {
// The space after language_code is necessary to match what sqlite does
@@ -1750,6 +1807,19 @@ bool AutofillTable::InitServerAddressesTable() {
return true;
}
+bool AutofillTable::InitServerAddressMetadataTable() {
+ if (!db_->DoesTableExist("server_address_metadata")) {
+ if (!db_->Execute("CREATE TABLE server_address_metadata ("
+ "id VARCHAR NOT NULL,"
+ "use_count INTEGER NOT NULL DEFAULT 0, "
+ "use_date INTEGER NOT NULL DEFAULT 0)")) {
+ NOTREACHED();
+ return false;
+ }
+ }
+ return true;
+}
+
bool AutofillTable::MigrateToVersion54AddI18nFieldsAndRemoveDeprecatedFields() {
sql::Transaction transaction(db_);
if (!transaction.Begin())
@@ -2054,4 +2124,122 @@ bool AutofillTable::MigrateToVersion64AddUnmaskDate() {
return transaction.Commit();
}
+bool AutofillTable::MigrateToVersion65AddServerMetadataTables() {
+ sql::Transaction transaction(db_);
+ if (!transaction.Begin())
+ return false;
+
+ if (!db_->DoesTableExist("server_card_metadata") &&
+ !db_->Execute("CREATE TABLE server_card_metadata ("
+ "id VARCHAR NOT NULL,"
+ "use_count INTEGER NOT NULL DEFAULT 0, "
+ "use_date INTEGER NOT NULL DEFAULT 0)")) {
+ return false;
+ }
+
+ // This clobbers existing usage metadata, which is not synced and only
+ // applies to unmasked cards. Trying to migrate the usage metadata would be
+ // tricky as multiple devices for the same user get DB upgrades.
+ if (!db_->Execute("UPDATE unmasked_credit_cards "
+ "SET use_count=0, use_date=0")) {
+ return false;
+ }
+
+ if (!db_->DoesTableExist("server_address_metadata") &&
+ !db_->Execute("CREATE TABLE server_address_metadata ("
+ "id VARCHAR NOT NULL,"
+ "use_count INTEGER NOT NULL DEFAULT 0, "
+ "use_date INTEGER NOT NULL DEFAULT 0)")) {
+ return false;
+ }
+
+ // Get existing server addresses and generate IDs for them.
+ sql::Statement s(db_->GetUniqueStatement(
+ "SELECT "
+ "id,"
+ "recipient_name,"
+ "company_name,"
+ "street_address,"
+ "address_1," // ADDRESS_HOME_STATE
+ "address_2," // ADDRESS_HOME_CITY
+ "address_3," // ADDRESS_HOME_DEPENDENT_LOCALITY
+ "address_4," // Not supported in AutofillProfile yet.
+ "postal_code," // ADDRESS_HOME_ZIP
+ "sorting_code," // ADDRESS_HOME_SORTING_CODE
+ "country_code," // ADDRESS_HOME_COUNTRY
+ "phone_number," // PHONE_HOME_WHOLE_NUMBER
+ "language_code "
+ "FROM server_addresses addresses"));
+ std::vector<AutofillProfile> profiles;
+ while (s.Step()) {
+ int index = 0;
+ AutofillProfile profile(
+ AutofillProfile::SERVER_PROFILE, s.ColumnString(index++));
+
+ base::string16 recipient_name = s.ColumnString16(index++);
+ profile.SetRawInfo(COMPANY_NAME, s.ColumnString16(index++));
+ profile.SetRawInfo(ADDRESS_HOME_STREET_ADDRESS, s.ColumnString16(index++));
+ profile.SetRawInfo(ADDRESS_HOME_STATE, s.ColumnString16(index++));
+ profile.SetRawInfo(ADDRESS_HOME_CITY, s.ColumnString16(index++));
+ profile.SetRawInfo(ADDRESS_HOME_DEPENDENT_LOCALITY,
+ s.ColumnString16(index++));
+ index++; // Skip address_4 which we haven't added to AutofillProfile yet.
+ profile.SetRawInfo(ADDRESS_HOME_ZIP, s.ColumnString16(index++));
+ profile.SetRawInfo(ADDRESS_HOME_SORTING_CODE, s.ColumnString16(index++));
+ profile.SetRawInfo(ADDRESS_HOME_COUNTRY, s.ColumnString16(index++));
+ base::string16 phone_number = s.ColumnString16(index++);
+ profile.set_language_code(s.ColumnString(index++));
+ profile.SetInfo(AutofillType(NAME_FULL), recipient_name,
+ profile.language_code());
+ profile.SetInfo(AutofillType(PHONE_HOME_WHOLE_NUMBER), phone_number,
+ profile.language_code());
+ profile.GenerateServerProfileIdentifier();
+ profiles.push_back(profile);
+ }
+
+ // Reinsert with the generated IDs.
+ sql::Statement delete_old(db_->GetUniqueStatement(
+ "DELETE FROM server_addresses"));
+ delete_old.Run();
+
+ sql::Statement insert(db_->GetUniqueStatement(
+ "INSERT INTO server_addresses("
+ "id,"
+ "recipient_name,"
+ "company_name,"
+ "street_address,"
+ "address_1," // ADDRESS_HOME_STATE
+ "address_2," // ADDRESS_HOME_CITY
+ "address_3," // ADDRESS_HOME_DEPENDENT_LOCALITY
+ "address_4," // Not supported in AutofillProfile yet.
+ "postal_code," // ADDRESS_HOME_ZIP
+ "sorting_code," // ADDRESS_HOME_SORTING_CODE
+ "country_code," // ADDRESS_HOME_COUNTRY
+ "phone_number," // PHONE_HOME_WHOLE_NUMBER
+ "language_code) "
+ "VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?)"));
+ for (const AutofillProfile& profile : profiles) {
+ int index = 0;
+ insert.BindString(index++, profile.server_id());
+ insert.BindString16(index++, profile.GetRawInfo(NAME_FULL));
+ insert.BindString16(index++, profile.GetRawInfo(COMPANY_NAME));
+ insert.BindString16(index++,
+ profile.GetRawInfo(ADDRESS_HOME_STREET_ADDRESS));
+ insert.BindString16(index++, profile.GetRawInfo(ADDRESS_HOME_STATE));
+ insert.BindString16(index++, profile.GetRawInfo(ADDRESS_HOME_CITY));
+ insert.BindString16(index++,
+ profile.GetRawInfo(ADDRESS_HOME_DEPENDENT_LOCALITY));
+ index++; // SKip address_4 which we haven't added to AutofillProfile yet.
+ insert.BindString16(index++, profile.GetRawInfo(ADDRESS_HOME_ZIP));
+ insert.BindString16(index++, profile.GetRawInfo(ADDRESS_HOME_SORTING_CODE));
+ insert.BindString16(index++, profile.GetRawInfo(ADDRESS_HOME_COUNTRY));
+ insert.BindString16(index++, profile.GetRawInfo(PHONE_HOME_WHOLE_NUMBER));
+ insert.BindString(index++, profile.language_code());
+ insert.Run();
+ insert.Reset(true);
+ }
+
+ return transaction.Commit();
+}
+
} // namespace autofill

Powered by Google App Engine
This is Rietveld 408576698