| 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 |