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