syncer_util.h revision c407dc5cd9bdc5668497f21b26b09d988ab439de
1// Copyright (c) 2006-2008 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// Utility functions manipulating syncable::Entries, intended for use by the 6// syncer. 7 8#ifndef CHROME_BROWSER_SYNC_ENGINE_SYNCER_UTIL_H_ 9#define CHROME_BROWSER_SYNC_ENGINE_SYNCER_UTIL_H_ 10 11#include <set> 12#include <string> 13#include <vector> 14 15#include "build/build_config.h" 16#include "chrome/browser/sync/engine/syncer.h" 17#include "chrome/browser/sync/engine/syncer_types.h" 18#include "chrome/browser/sync/syncable/syncable.h" 19#include "chrome/browser/sync/syncable/syncable_id.h" 20#include "chrome/browser/sync/util/sync_types.h" 21 22namespace browser_sync { 23 24class Cryptographer; 25class SyncEntity; 26 27class SyncerUtil { 28 public: 29 static void ChangeEntryIDAndUpdateChildren( 30 syncable::WriteTransaction* trans, 31 syncable::MutableEntry* entry, 32 const syncable::Id& new_id, 33 syncable::Directory::ChildHandles* children); 34 35 // Returns the number of unsynced entries. 36 static int GetUnsyncedEntries(syncable::BaseTransaction* trans, 37 std::vector<int64> *handles); 38 39 static void ChangeEntryIDAndUpdateChildren(syncable::WriteTransaction* trans, 40 syncable::MutableEntry* entry, 41 const syncable::Id& new_id); 42 43 // If the server sent down a client-tagged entry, or an entry whose 44 // commit response was lost, it is necessary to update a local entry 45 // with an ID that doesn't match the ID of the update. Here, we 46 // find the ID of such an entry, if it exists. This function may 47 // determine that |server_entry| should be dropped; if so, it returns 48 // the null ID -- callers must handle this case. When update application 49 // should proceed normally with a new local entry, this function will 50 // return server_entry.id(); the caller must create an entry with that 51 // ID. This function does not alter the database. 52 static syncable::Id FindLocalIdToUpdate( 53 syncable::BaseTransaction* trans, 54 const SyncEntity& server_entry); 55 56 static UpdateAttemptResponse AttemptToUpdateEntry( 57 syncable::WriteTransaction* const trans, 58 syncable::MutableEntry* const entry, 59 ConflictResolver* resolver, 60 Cryptographer* cryptographer); 61 62 // Pass in name to avoid redundant UTF8 conversion. 63 static void UpdateServerFieldsFromUpdate( 64 syncable::MutableEntry* local_entry, 65 const SyncEntity& server_entry, 66 const std::string& name); 67 68 // Creates a new Entry iff no Entry exists with the given id. 69 static void CreateNewEntry(syncable::WriteTransaction *trans, 70 const syncable::Id& id); 71 72 static bool ServerAndLocalEntriesMatch(syncable::Entry* entry); 73 74 static void SplitServerInformationIntoNewEntry( 75 syncable::WriteTransaction* trans, 76 syncable::MutableEntry* entry); 77 78 // This function is called on an entry when we can update the user-facing data 79 // from the server data. 80 static void UpdateLocalDataFromServerData(syncable::WriteTransaction* trans, 81 syncable::MutableEntry* entry); 82 83 static VerifyCommitResult ValidateCommitEntry(syncable::Entry* entry); 84 85 static VerifyResult VerifyNewEntry(const SyncEntity& update, 86 syncable::Entry* target, 87 const bool deleted); 88 89 // Assumes we have an existing entry; check here for updates that break 90 // consistency rules. 91 static VerifyResult VerifyUpdateConsistency(syncable::WriteTransaction* trans, 92 const SyncEntity& update, 93 syncable::MutableEntry* target, 94 const bool deleted, 95 const bool is_directory, 96 syncable::ModelType model_type); 97 98 // Assumes we have an existing entry; verify an update that seems to be 99 // expressing an 'undelete' 100 static VerifyResult VerifyUndelete(syncable::WriteTransaction* trans, 101 const SyncEntity& update, 102 syncable::MutableEntry* target); 103 104 // Compute a local predecessor position for |update_item|. The position 105 // is determined by the SERVER_POSITION_IN_PARENT value of |update_item|, 106 // as well as the SERVER_POSITION_IN_PARENT values of any up-to-date 107 // children of |parent_id|. 108 static syncable::Id ComputePrevIdFromServerPosition( 109 syncable::BaseTransaction* trans, 110 syncable::Entry* update_item, 111 const syncable::Id& parent_id); 112 113 // Append |item|, followed by a chain of its predecessors selected by 114 // |inclusion_filter|, to the |commit_ids| vector and tag them as included by 115 // storing in the set |inserted_items|. |inclusion_filter| (typically one of 116 // IS_UNAPPLIED_UPDATE or IS_UNSYNCED) selects which type of predecessors to 117 // include. Returns true if |item| was added, and false if it was already in 118 // the list. 119 // 120 // Use AddPredecessorsThenItem instead of this method if you want the 121 // item to be the last, rather than first, item appended. 122 static bool AddItemThenPredecessors( 123 syncable::BaseTransaction* trans, 124 syncable::Entry* item, 125 syncable::IndexedBitField inclusion_filter, 126 syncable::MetahandleSet* inserted_items, 127 std::vector<syncable::Id>* commit_ids); 128 129 // Exactly like AddItemThenPredecessors, except items are appended in the 130 // reverse (and generally more useful) order: a chain of predecessors from 131 // far to near, and finally the item. 132 static void AddPredecessorsThenItem( 133 syncable::BaseTransaction* trans, 134 syncable::Entry* item, 135 syncable::IndexedBitField inclusion_filter, 136 syncable::MetahandleSet* inserted_items, 137 std::vector<syncable::Id>* commit_ids); 138 139 static void AddUncommittedParentsAndTheirPredecessors( 140 syncable::BaseTransaction* trans, 141 syncable::MetahandleSet* inserted_items, 142 std::vector<syncable::Id>* commit_ids, 143 syncable::Id parent_id); 144 145 static void MarkDeletedChildrenSynced( 146 const syncable::ScopedDirLookup &dir, 147 std::set<syncable::Id>* deleted_folders); 148 149 // Examine the up-to-date predecessors of this item according to the server 150 // position, and then again according to the local position. Return true 151 // if they match. For an up-to-date item, this should be the case. 152 static bool ServerAndLocalOrdersMatch(syncable::Entry* entry); 153 154 private: 155 DISALLOW_IMPLICIT_CONSTRUCTORS(SyncerUtil); 156}; 157 158#ifndef OS_WIN 159 160// time.h on Linux and Mac both return seconds since the epoch, this should 161// be converted to milliseconds. 162inline int64 ServerTimeToClientTime(int64 server_time) { 163 return server_time / GG_LONGLONG(1000); 164} 165 166inline int64 ClientTimeToServerTime(int64 client_time) { 167 return client_time * GG_LONGLONG(1000); 168} 169 170// As we truncate server times on the client for posix and on the server for 171// windows we need two ClientAndServerTimeMatch fucntions. 172inline bool ClientAndServerTimeMatch(int64 client_time, int64 server_time) { 173 // Compare at the coarser timescale (client) 174 return client_time == ServerTimeToClientTime(server_time); 175} 176#else 177// The sync server uses Java Times (ms since 1970) 178// and the client uses FILETIMEs (ns since 1601) so we need to convert 179// between the timescales. 180// TODO(sync): Fix this. No need to use two timescales. 181inline int64 ServerTimeToClientTime(int64 server_time) { 182 return server_time * GG_LONGLONG(10000) + GG_LONGLONG(116444736000000000); 183} 184 185inline int64 ClientTimeToServerTime(int64 client_time) { 186 return (client_time - GG_LONGLONG(116444736000000000)) / GG_LONGLONG(10000); 187} 188 189inline bool ClientAndServerTimeMatch(int64 client_time, int64 server_time) { 190 // Compare at the coarser timescale (server) 191 return ClientTimeToServerTime(client_time) == server_time; 192} 193#endif 194 195} // namespace browser_sync 196 197#endif // CHROME_BROWSER_SYNC_ENGINE_SYNCER_UTIL_H_ 198