WebSocket header continuations test case.
[chromium-blink-merge.git] / sync / syncable / syncable_util.cc
blob89d1375e632af2720ec78e530dec53175cae4ecc
1 // Copyright 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "sync/syncable/syncable_util.h"
7 #include "base/base64.h"
8 #include "base/location.h"
9 #include "base/logging.h"
10 #include "base/sha1.h"
11 #include "sync/syncable/directory.h"
12 #include "sync/syncable/entry.h"
13 #include "sync/syncable/mutable_entry.h"
14 #include "sync/syncable/syncable_id.h"
15 #include "sync/syncable/syncable_write_transaction.h"
17 namespace syncer {
18 namespace syncable {
20 // Returns the number of unsynced entries.
21 int GetUnsyncedEntries(BaseTransaction* trans,
22 std::vector<int64> *handles) {
23 trans->directory()->GetUnsyncedMetaHandles(trans, handles);
24 DVLOG_IF(1, !handles->empty()) << "Have " << handles->size()
25 << " unsynced items.";
26 return handles->size();
29 bool IsLegalNewParent(BaseTransaction* trans, const Id& entry_id,
30 const Id& new_parent_id) {
31 DCHECK(!entry_id.IsNull());
32 DCHECK(!new_parent_id.IsNull());
33 if (entry_id.IsRoot())
34 return false;
35 // we have to ensure that the entry is not an ancestor of the new parent.
36 Id ancestor_id = new_parent_id;
37 while (!ancestor_id.IsRoot()) {
38 if (entry_id == ancestor_id)
39 return false;
40 Entry new_parent(trans, GET_BY_ID, ancestor_id);
41 if (!SyncAssert(new_parent.good(),
42 FROM_HERE,
43 "Invalid new parent",
44 trans))
45 return false;
46 ancestor_id = new_parent.GetParentId();
48 return true;
51 void ChangeEntryIDAndUpdateChildren(
52 BaseWriteTransaction* trans,
53 ModelNeutralMutableEntry* entry,
54 const Id& new_id) {
55 Id old_id = entry->GetId();
56 if (!entry->PutId(new_id)) {
57 Entry old_entry(trans, GET_BY_ID, new_id);
58 CHECK(old_entry.good());
59 LOG(FATAL) << "Attempt to change ID to " << new_id
60 << " conflicts with existing entry.\n\n"
61 << *entry << "\n\n" << old_entry;
63 if (entry->GetIsDir()) {
64 // Get all child entries of the old id.
65 Directory::Metahandles children;
66 trans->directory()->GetChildHandlesById(trans, old_id, &children);
67 Directory::Metahandles::iterator i = children.begin();
68 while (i != children.end()) {
69 ModelNeutralMutableEntry child_entry(trans, GET_BY_HANDLE, *i++);
70 CHECK(child_entry.good());
71 // Change the parent ID of the entry unless it was unset (implicit)
72 if (!child_entry.GetParentId().IsNull()) {
73 // Use the unchecked setter here to avoid touching the child's
74 // UNIQUE_POSITION field. In this case, UNIQUE_POSITION among the
75 // children will be valid after the loop, since we update all the
76 // children at once.
77 child_entry.PutParentIdPropertyOnly(new_id);
83 // Function to handle runtime failures on syncable code. Rather than crashing,
84 // if the |condition| is false the following will happen:
85 // 1. Sets unrecoverable error on transaction.
86 // 2. Returns false.
87 bool SyncAssert(bool condition,
88 const tracked_objects::Location& location,
89 const char* msg,
90 BaseTransaction* trans) {
91 if (!condition) {
92 trans->OnUnrecoverableError(location, msg);
93 return false;
95 return true;
98 std::string GenerateSyncableHash(
99 ModelType model_type, const std::string& client_tag) {
100 // Blank PB with just the field in it has termination symbol,
101 // handy for delimiter.
102 sync_pb::EntitySpecifics serialized_type;
103 AddDefaultFieldValue(model_type, &serialized_type);
104 std::string hash_input;
105 serialized_type.AppendToString(&hash_input);
106 hash_input.append(client_tag);
108 std::string encode_output;
109 base::Base64Encode(base::SHA1HashString(hash_input), &encode_output);
110 return encode_output;
113 std::string GenerateSyncableBookmarkHash(
114 const std::string& originator_cache_guid,
115 const std::string& originator_client_item_id) {
116 return syncable::GenerateSyncableHash(
117 BOOKMARKS, originator_cache_guid + originator_client_item_id);
120 } // namespace syncable
121 } // namespace syncer