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