summaryrefslogtreecommitdiffstats
path: root/chrome/browser/sync/engine/build_commit_command.cc
diff options
context:
space:
mode:
Diffstat (limited to 'chrome/browser/sync/engine/build_commit_command.cc')
-rw-r--r--chrome/browser/sync/engine/build_commit_command.cc143
1 files changed, 143 insertions, 0 deletions
diff --git a/chrome/browser/sync/engine/build_commit_command.cc b/chrome/browser/sync/engine/build_commit_command.cc
new file mode 100644
index 0000000..f819d6c
--- /dev/null
+++ b/chrome/browser/sync/engine/build_commit_command.cc
@@ -0,0 +1,143 @@
+// Copyright (c) 2006-2009 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/sync/engine/build_commit_command.h"
+
+#include <set>
+#include <string>
+#include <vector>
+
+#include "chrome/browser/sync/engine/syncer_proto_util.h"
+#include "chrome/browser/sync/engine/syncer_session.h"
+#include "chrome/browser/sync/engine/syncer_util.h"
+#include "chrome/browser/sync/engine/syncproto.h"
+#include "chrome/browser/sync/syncable/syncable.h"
+#include "chrome/browser/sync/syncable/syncable_changes_version.h"
+#include "chrome/browser/sync/util/character_set_converters.h"
+#include "chrome/browser/sync/util/sync_types.h"
+
+using std::set;
+using std::string;
+using std::vector;
+using syncable::ExtendedAttribute;
+using syncable::Id;
+using syncable::MutableEntry;
+using syncable::Name;
+
+namespace browser_sync {
+
+BuildCommitCommand::BuildCommitCommand() {}
+BuildCommitCommand::~BuildCommitCommand() {}
+
+void BuildCommitCommand::ExecuteImpl(SyncerSession *session) {
+ ClientToServerMessage message;
+ message.set_share(ToUTF8(session->account_name()).get_string());
+ message.set_message_contents(ClientToServerMessage::COMMIT);
+
+ CommitMessage* commit_message = message.mutable_commit();
+ commit_message->set_cache_guid(
+ session->write_transaction()->directory()->cache_guid());
+
+ const vector<Id>& commit_ids = session->commit_ids();
+ for (size_t i = 0; i < commit_ids.size(); i++) {
+ Id id = commit_ids[i];
+ SyncEntity* sync_entry =
+ static_cast<SyncEntity*>(commit_message->add_entries());
+ sync_entry->set_id(id);
+ MutableEntry meta_entry(session->write_transaction(),
+ syncable::GET_BY_ID,
+ id);
+ CHECK(meta_entry.good());
+ // this is the only change we make to the entry in this function.
+ meta_entry.Put(syncable::SYNCING, true);
+
+ Name name = meta_entry.GetName();
+ CHECK(!name.value().empty()); // Make sure this isn't an update.
+ sync_entry->set_name(ToUTF8(name.value()).get_string());
+ // Set the non_unique_name if we have one. If we do, the server ignores
+ // the |name| value (using |non_unique_name| instead), and will return
+ // in the CommitResponse a unique name if one is generated. Even though
+ // we could get away with only sending |name|, we send both because it
+ // may aid in logging.
+ if (name.value() != name.non_unique_value()) {
+ sync_entry->set_non_unique_name(
+ ToUTF8(name.non_unique_value()).get_string());
+ }
+ // deleted items with negative parent ids can be a problem so we set the
+ // parent to 0. (TODO(sync): Still true in protocol?
+ Id new_parent_id;
+ if (meta_entry.Get(syncable::IS_DEL) &&
+ !meta_entry.Get(syncable::PARENT_ID).ServerKnows()) {
+ new_parent_id = session->write_transaction()->root_id();
+ } else {
+ new_parent_id = meta_entry.Get(syncable::PARENT_ID);
+ }
+ sync_entry->set_parent_id(new_parent_id);
+ // TODO(sync): Investigate all places that think transactional commits
+ // actually exist.
+ //
+ // This is the only logic we'll need when transactional commits are
+ // moved to the server.
+ // If our parent has changes, send up the old one so the server can
+ // correctly deal with multiple parents.
+ if (new_parent_id != meta_entry.Get(syncable::SERVER_PARENT_ID) &&
+ 0 != meta_entry.Get(syncable::BASE_VERSION) &&
+ syncable::CHANGES_VERSION != meta_entry.Get(syncable::BASE_VERSION)) {
+ sync_entry->set_old_parent_id(meta_entry.Get(syncable::SERVER_PARENT_ID));
+ }
+
+ int64 version = meta_entry.Get(syncable::BASE_VERSION);
+ if (syncable::CHANGES_VERSION == version || 0 == version) {
+ // If this CHECK triggers during unit testing, check that we haven't
+ // altered an item that's an unapplied update.
+ CHECK(!id.ServerKnows()) << meta_entry;
+ sync_entry->set_version(0);
+ } else {
+ CHECK(id.ServerKnows()) << meta_entry;
+ sync_entry->set_version(meta_entry.Get(syncable::BASE_VERSION));
+ }
+ sync_entry->set_ctime(ClientTimeToServerTime(
+ meta_entry.Get(syncable::CTIME)));
+ sync_entry->set_mtime(ClientTimeToServerTime(
+ meta_entry.Get(syncable::MTIME)));
+
+ set<ExtendedAttribute> extended_attributes;
+ meta_entry.GetAllExtendedAttributes(
+ session->write_transaction(), &extended_attributes);
+ set<ExtendedAttribute>::iterator iter;
+ sync_pb::ExtendedAttributes* mutable_extended_attributes =
+ sync_entry->mutable_extended_attributes();
+ for (iter = extended_attributes.begin(); iter != extended_attributes.end();
+ ++iter) {
+ sync_pb::ExtendedAttributes_ExtendedAttribute *extended_attribute =
+ mutable_extended_attributes->add_extendedattribute();
+ extended_attribute->set_key(ToUTF8(iter->key()).get_string());
+ SyncerProtoUtil::CopyBlobIntoProtoBytes(iter->value(),
+ extended_attribute->mutable_value());
+ }
+
+ // Deletion is final on the server, let's move things and then delete them.
+ if (meta_entry.Get(syncable::IS_DEL)) {
+ sync_entry->set_deleted(true);
+ } else if (meta_entry.Get(syncable::IS_BOOKMARK_OBJECT)) {
+ sync_pb::SyncEntity_BookmarkData* bookmark =
+ sync_entry->mutable_bookmarkdata();
+ bookmark->set_bookmark_folder(meta_entry.Get(syncable::IS_DIR));
+ const Id& prev_id = meta_entry.Get(syncable::PREV_ID);
+ string prev_string = prev_id.IsRoot() ? string() : prev_id.GetServerId();
+ sync_entry->set_insert_after_item_id(prev_string);
+
+ if (!meta_entry.Get(syncable::IS_DIR)) {
+ string bookmark_url = ToUTF8(meta_entry.Get(syncable::BOOKMARK_URL));
+ bookmark->set_bookmark_url(bookmark_url);
+ SyncerProtoUtil::CopyBlobIntoProtoBytes(
+ meta_entry.Get(syncable::BOOKMARK_FAVICON),
+ bookmark->mutable_bookmark_favicon());
+ }
+ }
+ }
+ session->set_commit_message(message);
+}
+
+} // namespace browser_sync