| Index: chrome/browser/sync/engine/syncapi.cc
|
| diff --git a/chrome/browser/sync/engine/syncapi.cc b/chrome/browser/sync/engine/syncapi.cc
|
| index 82d5a21ad6106c9675609ddfcda808240be86aca..c4eda7bafa5ebd5f62c82b2137198e8841aa7203 100755
|
| --- a/chrome/browser/sync/engine/syncapi.cc
|
| +++ b/chrome/browser/sync/engine/syncapi.cc
|
| @@ -32,6 +32,7 @@
|
| #include "base/lock.h"
|
| #include "base/platform_thread.h"
|
| #include "base/scoped_ptr.h"
|
| +#include "base/sha1.h"
|
| #include "base/string_util.h"
|
| #include "base/task.h"
|
| #include "base/utf_string_conversions.h"
|
| @@ -389,6 +390,18 @@ BaseNode::BaseNode() {}
|
|
|
| BaseNode::~BaseNode() {}
|
|
|
| +std::string BaseNode::GenerateSyncableHash(
|
| + syncable::ModelType model_type, const std::string& client_tag) {
|
| + // blank PB with just the extension in it has termination symbol,
|
| + // handy for delimiter
|
| + sync_pb::EntitySpecifics serialized_type;
|
| + syncable::AddDefaultExtensionValue(model_type, &serialized_type);
|
| + std::string hash_input;
|
| + serialized_type.AppendToString(&hash_input);
|
| + hash_input.append(client_tag);
|
| + return base::SHA1HashString(hash_input);
|
| +}
|
| +
|
| int64 BaseNode::GetParentId() const {
|
| return IdToMetahandle(GetTransaction()->GetWrappedTrans(),
|
| GetEntry()->Get(syncable::PARENT_ID));
|
| @@ -556,18 +569,25 @@ bool WriteNode::InitByIdLookup(int64 id) {
|
| // Find a node by client tag, and bind this WriteNode to it.
|
| // Return true if the write node was found, and was not deleted.
|
| // Undeleting a deleted node is possible by ClientTag.
|
| -bool WriteNode::InitByClientTagLookup(const std::string& tag) {
|
| +bool WriteNode::InitByClientTagLookup(syncable::ModelType model_type,
|
| + const std::string& tag) {
|
| DCHECK(!entry_) << "Init called twice";
|
| if (tag.empty())
|
| return false;
|
| +
|
| + const std::string hash = GenerateSyncableHash(model_type, tag);
|
| +
|
| entry_ = new syncable::MutableEntry(transaction_->GetWrappedWriteTrans(),
|
| - syncable::GET_BY_CLIENT_TAG, tag);
|
| + syncable::GET_BY_CLIENT_TAG, hash);
|
| return (entry_->good() && !entry_->Get(syncable::IS_DEL));
|
| }
|
|
|
| void WriteNode::PutModelType(syncable::ModelType model_type) {
|
| // Set an empty specifics of the appropriate datatype. The presence
|
| // of the specific extension will identify the model type.
|
| + DCHECK(GetModelType() == model_type ||
|
| + GetModelType() == syncable::UNSPECIFIED); // Immutable once set.
|
| +
|
| sync_pb::EntitySpecifics specifics;
|
| syncable::AddDefaultExtensionValue(model_type, &specifics);
|
| PutSpecificsAndMarkForSyncing(specifics);
|
| @@ -620,6 +640,8 @@ bool WriteNode::InitUniqueByCreation(syncable::ModelType model_type,
|
| const std::string& tag) {
|
| DCHECK(!entry_) << "Init called twice";
|
|
|
| + const std::string hash = GenerateSyncableHash(model_type, tag);
|
| +
|
| syncable::Id parent_id = parent.GetEntry()->Get(syncable::ID);
|
|
|
| // Start out with a dummy name. We expect
|
| @@ -629,7 +651,7 @@ bool WriteNode::InitUniqueByCreation(syncable::ModelType model_type,
|
| // Check if we have this locally and need to undelete it.
|
| scoped_ptr<syncable::MutableEntry> existing_entry(
|
| new syncable::MutableEntry(transaction_->GetWrappedWriteTrans(),
|
| - syncable::GET_BY_CLIENT_TAG, tag));
|
| + syncable::GET_BY_CLIENT_TAG, hash));
|
|
|
| if (existing_entry->good()) {
|
| if (existing_entry->Get(syncable::IS_DEL)) {
|
| @@ -670,7 +692,7 @@ bool WriteNode::InitUniqueByCreation(syncable::ModelType model_type,
|
| }
|
|
|
| // Only set IS_DIR for new entries. Don't bitflip undeleted ones.
|
| - entry_->Put(syncable::UNIQUE_CLIENT_TAG, tag);
|
| + entry_->Put(syncable::UNIQUE_CLIENT_TAG, hash);
|
| }
|
|
|
| // We don't support directory and tag combinations.
|
| @@ -781,12 +803,16 @@ bool ReadNode::InitByIdLookup(int64 id) {
|
| return true;
|
| }
|
|
|
| -bool ReadNode::InitByClientTagLookup(const std::string& tag) {
|
| +bool ReadNode::InitByClientTagLookup(syncable::ModelType model_type,
|
| + const std::string& tag) {
|
| DCHECK(!entry_) << "Init called twice";
|
| if (tag.empty())
|
| return false;
|
| +
|
| + const std::string hash = GenerateSyncableHash(model_type, tag);
|
| +
|
| entry_ = new syncable::Entry(transaction_->GetWrappedTrans(),
|
| - syncable::GET_BY_CLIENT_TAG, tag);
|
| + syncable::GET_BY_CLIENT_TAG, hash);
|
| return (entry_->good() && !entry_->Get(syncable::IS_DEL));
|
| }
|
|
|
|
|