Chromium Code Reviews| 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 8886736126629c35e24a0dd82451e8bd4381b375..440ffc7e624018a6b5657d13061134de77f6e25f 100644 |
| --- a/components/autofill/core/browser/webdata/autofill_table.cc |
| +++ b/components/autofill/core/browser/webdata/autofill_table.cc |
| @@ -35,6 +35,9 @@ |
| #include "components/autofill/core/common/autofill_util.h" |
| #include "components/autofill/core/common/form_field_data.h" |
| #include "components/os_crypt/os_crypt.h" |
| +#include "components/sync/base/model_type.h" |
| +#include "components/sync/protocol/entity_metadata.pb.h" |
| +#include "components/sync/protocol/model_type_state.pb.h" |
| #include "components/webdata/common/web_database.h" |
| #include "sql/statement.h" |
| #include "sql/transaction.h" |
| @@ -416,7 +419,8 @@ bool AutofillTable::CreateTablesIfNecessary() { |
| InitProfilePhonesTable() && InitProfileTrashTable() && |
| InitMaskedCreditCardsTable() && InitUnmaskedCreditCardsTable() && |
| InitServerCardMetadataTable() && InitServerAddressesTable() && |
| - InitServerAddressMetadataTable()); |
| + InitServerAddressMetadataTable() && InitAutofillSyncMetadataTable() && |
| + InitModelTypeStateTable()); |
| } |
| bool AutofillTable::IsSyncable() { |
| @@ -463,6 +467,9 @@ bool AutofillTable::MigrateToVersion(int version, |
| case 67: |
| *update_compatible_version = false; |
| return MigrateToVersion67AddMaskedCardBillingAddress(); |
| + case 70: |
| + *update_compatible_version = false; |
| + return MigrateToVersion70AddSyncMetadata(); |
| } |
| return true; |
| } |
| @@ -1680,6 +1687,114 @@ bool AutofillTable::IsAutofillGUIDInTrash(const std::string& guid) { |
| return s.Step(); |
| } |
| +bool AutofillTable::GetSyncMetadata(syncer::ModelType model_type, |
| + const std::string& storage_key, |
| + sync_pb::EntityMetadata* metadata) { |
| + DCHECK_EQ(model_type, syncer::AUTOFILL) |
| + << "Only the AUTOFILL model type is supported"; |
| + |
| + sql::Statement s(db_->GetUniqueStatement( |
| + "SELECT value FROM autofill_sync_metadata WHERE storage_key=?")); |
| + s.BindString(0, storage_key); |
| + |
| + if (!s.Step()) { |
| + return false; |
| + } |
| + |
| + std::string serialized_metadata = s.ColumnString(0); |
| + return metadata->ParseFromString(serialized_metadata); |
| +} |
| + |
| +bool AutofillTable::GetAllSyncMetadata( |
| + syncer::ModelType model_type, |
| + std::vector<sync_pb::EntityMetadata>* metadata_records) { |
| + DCHECK_EQ(model_type, syncer::AUTOFILL) |
| + << "Only the AUTOFILL model type is supported"; |
| + |
| + sql::Statement s( |
| + db_->GetUniqueStatement("SELECT value FROM autofill_sync_metadata")); |
| + |
| + while (s.Step()) { |
| + std::string serialized_metadata = s.ColumnString(0); |
| + sync_pb::EntityMetadata metadata_record; |
| + //todo(pnoland): account for unparseable entries. |
| + if (metadata_record.ParseFromString(serialized_metadata)) { |
| + metadata_records->push_back(metadata_record); |
| + } |
| + } |
| + return true; |
| +} |
| + |
| +bool AutofillTable::UpdateSyncMetadata( |
| + syncer::ModelType model_type, |
| + const std::string& storage_key, |
| + const sync_pb::EntityMetadata& metadata) { |
| + DCHECK_EQ(model_type, syncer::AUTOFILL) |
| + << "Only the AUTOFILL model type is supported"; |
| + |
| + sql::Statement s( |
| + db_->GetUniqueStatement("INSERT OR REPLACE INTO autofill_sync_metadata " |
| + "(storage_key, value) VALUES(?, ?)")); |
| + s.BindString(0, storage_key); |
| + s.BindString(1, metadata.SerializeAsString()); |
| + |
| + return s.Run(); |
| +} |
| + |
| +bool AutofillTable::ClearSyncMetadata(syncer::ModelType model_type, |
| + const std::string& storage_key) { |
| + DCHECK_EQ(model_type, syncer::AUTOFILL) |
| + << "Only the AUTOFILL model type is supported"; |
| + |
| + sql::Statement s(db_->GetUniqueStatement( |
| + "DELETE FROM autofill_sync_metadata WHERE storage_key=?")); |
| + s.BindString(0, storage_key); |
| + |
| + return s.Run(); |
| +} |
| + |
| +bool AutofillTable::GetModelTypeState(syncer::ModelType model_type, |
| + sync_pb::ModelTypeState* state) { |
| + DCHECK_EQ(model_type, syncer::AUTOFILL) |
| + << "Only the AUTOFILL model type is supported"; |
| + |
| + sql::Statement s( |
| + db_->GetUniqueStatement("SELECT value FROM autofill_model_type_state")); |
| + |
| + if (!s.Step()) { |
| + return false; |
| + } |
| + |
| + std::string serialized_state = s.ColumnString(0); |
| + return state->ParseFromString(serialized_state); |
| +} |
| + |
| +bool AutofillTable::UpdateModelTypeState( |
| + syncer::ModelType model_type, |
| + sync_pb::ModelTypeState& model_type_state) { |
| + DCHECK_EQ(model_type, syncer::AUTOFILL) |
| + << "Only the AUTOFILL model type is supported"; |
| + |
| + // Hardcode the rowid to force a collision, ensuring that there remains only a |
| + // single entry. |
| + sql::Statement s(db_->GetUniqueStatement( |
| + "INSERT OR REPLACE INTO autofill_model_type_state (rowid, value) " |
| + "VALUES(1,?)")); |
| + s.BindString(0, model_type_state.SerializeAsString()); |
| + |
| + return s.Run(); |
| +} |
| + |
| +bool AutofillTable::ClearModelTypeState(syncer::ModelType model_type) { |
| + DCHECK_EQ(model_type, syncer::AUTOFILL) |
| + << "Only the AUTOFILL model type is supported"; |
| + |
| + sql::Statement s( |
| + db_->GetUniqueStatement("DELETE FROM autofill_model_type_state")); |
| + |
| + return s.Run(); |
| +} |
| + |
| bool AutofillTable::InitMainTable() { |
| if (!db_->DoesTableExist("autofill")) { |
| if (!db_->Execute("CREATE TABLE autofill (" |
| @@ -1879,6 +1994,28 @@ bool AutofillTable::InitServerAddressMetadataTable() { |
| return true; |
| } |
| +bool AutofillTable::InitAutofillSyncMetadataTable() { |
| + if (!db_->DoesTableExist("autofill_sync_metadata")) { |
| + if (!db_->Execute("CREATE TABLE autofill_sync_metadata (" |
| + "storage_key VARCHAR primary key," |
| + "value BLOB)")) { |
|
Scott Hess - ex-Googler
2016/12/07 23:15:20
I'd drop a NOT NULL in there. PRIMARY KEY does no
Patrick Noland
2016/12/08 22:51:13
I've added the NOT NULL constraint, but I'm leavin
Scott Hess - ex-Googler
2016/12/08 23:24:01
Acknowledged.
|
| + NOTREACHED(); |
| + return false; |
| + } |
| + } |
| + return true; |
| +} |
| + |
| +bool AutofillTable::InitModelTypeStateTable() { |
| + if (!db_->DoesTableExist("autofill_model_type_state")) { |
| + if (!db_->Execute("CREATE TABLE autofill_model_type_state (value BLOB)")) { |
| + NOTREACHED(); |
| + return false; |
| + } |
| + } |
| + return true; |
| +} |
| + |
| bool AutofillTable::MigrateToVersion54AddI18nFieldsAndRemoveDeprecatedFields() { |
| sql::Transaction transaction(db_); |
| if (!transaction.Begin()) |
| @@ -2315,4 +2452,14 @@ bool AutofillTable::MigrateToVersion67AddMaskedCardBillingAddress() { |
| "ALTER TABLE masked_credit_cards ADD COLUMN billing_address_id VARCHAR"); |
| } |
| -} // namespace autofill |
| +bool AutofillTable::MigrateToVersion70AddSyncMetadata() { |
| + if (!db_->Execute("CREATE TABLE autofill_sync_metadata (" |
| + "storage_key VARCHAR primary key," |
| + "value BLOB)")) { |
| + return false; |
| + } |
| + |
|
Mathieu
2016/12/07 16:17:42
nit: remove extra line to be consistent
Patrick Noland
2016/12/08 22:51:14
Done.
|
| + return db_->Execute("CREATE TABLE autofill_model_type_state (value BLOB)"); |
|
Scott Hess - ex-Googler
2016/12/07 23:15:20
This probably wants a transaction to keep these at
Patrick Noland
2016/12/08 22:51:13
Migration functions are called in the context of a
Scott Hess - ex-Googler
2016/12/08 23:24:01
Acknowledged.
|
| +} |
| + |
| +} // namespace autofill |