Home | History | Annotate | Download | only in engine
      1 // Copyright (c) 2011 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 #pragma once
     11 
     12 #include <set>
     13 #include <string>
     14 #include <vector>
     15 
     16 #include "build/build_config.h"
     17 #include "chrome/browser/sync/engine/syncer.h"
     18 #include "chrome/browser/sync/engine/syncer_types.h"
     19 #include "chrome/browser/sync/syncable/syncable.h"
     20 #include "chrome/browser/sync/syncable/syncable_id.h"
     21 
     22 namespace browser_sync {
     23 
     24 class Cryptographer;
     25 class SyncEntity;
     26 
     27 class 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   // Append |item|, followed by a chain of its predecessors selected by
    105   // |inclusion_filter|, to the |commit_ids| vector and tag them as included by
    106   // storing in the set |inserted_items|.  |inclusion_filter| (typically one of
    107   // IS_UNAPPLIED_UPDATE or IS_UNSYNCED) selects which type of predecessors to
    108   // include.  Returns true if |item| was added, and false if it was already in
    109   // the list.
    110   //
    111   // Use AddPredecessorsThenItem instead of this method if you want the
    112   // item to be the last, rather than first, item appended.
    113   static bool AddItemThenPredecessors(
    114       syncable::BaseTransaction* trans,
    115       syncable::Entry* item,
    116       syncable::IndexedBitField inclusion_filter,
    117       syncable::MetahandleSet* inserted_items,
    118       std::vector<syncable::Id>* commit_ids);
    119 
    120   // Exactly like AddItemThenPredecessors, except items are appended in the
    121   // reverse (and generally more useful) order: a chain of predecessors from
    122   // far to near, and finally the item.
    123   static void AddPredecessorsThenItem(
    124       syncable::BaseTransaction* trans,
    125       syncable::Entry* item,
    126       syncable::IndexedBitField inclusion_filter,
    127       syncable::MetahandleSet* inserted_items,
    128       std::vector<syncable::Id>* commit_ids);
    129 
    130   static void MarkDeletedChildrenSynced(
    131       const syncable::ScopedDirLookup &dir,
    132       std::set<syncable::Id>* deleted_folders);
    133 
    134   // Examine the up-to-date predecessors of this item according to the server
    135   // position, and then again according to the local position.  Return true
    136   // if they match.  For an up-to-date item, this should be the case.
    137   static bool ServerAndLocalOrdersMatch(syncable::Entry* entry);
    138 
    139  private:
    140   DISALLOW_IMPLICIT_CONSTRUCTORS(SyncerUtil);
    141 };
    142 
    143 #ifndef OS_WIN
    144 
    145 // time.h on Linux and Mac both return seconds since the epoch, this should
    146 // be converted to milliseconds.
    147 inline int64 ServerTimeToClientTime(int64 server_time) {
    148   return server_time / GG_LONGLONG(1000);
    149 }
    150 
    151 inline int64 ClientTimeToServerTime(int64 client_time) {
    152   return client_time * GG_LONGLONG(1000);
    153 }
    154 
    155 // As we truncate server times on the client for posix and on the server for
    156 // windows we need two ClientAndServerTimeMatch fucntions.
    157 inline bool ClientAndServerTimeMatch(int64 client_time, int64 server_time) {
    158   // Compare at the coarser timescale (client)
    159   return client_time == ServerTimeToClientTime(server_time);
    160 }
    161 #else
    162 // The sync server uses Java Times (ms since 1970)
    163 // and the client uses FILETIMEs (ns since 1601) so we need to convert
    164 // between the timescales.
    165 // TODO(sync): Fix this. No need to use two timescales.
    166 inline int64 ServerTimeToClientTime(int64 server_time) {
    167   return server_time * GG_LONGLONG(10000) + GG_LONGLONG(116444736000000000);
    168 }
    169 
    170 inline int64 ClientTimeToServerTime(int64 client_time) {
    171   return (client_time - GG_LONGLONG(116444736000000000)) / GG_LONGLONG(10000);
    172 }
    173 
    174 inline bool ClientAndServerTimeMatch(int64 client_time, int64 server_time) {
    175   // Compare at the coarser timescale (server)
    176   return ClientTimeToServerTime(client_time) == server_time;
    177 }
    178 #endif
    179 
    180 }  // namespace browser_sync
    181 
    182 #endif  // CHROME_BROWSER_SYNC_ENGINE_SYNCER_UTIL_H_
    183