OLD | NEW |
1 // Copyright (c) 2006-2009 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2006-2009 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "chrome/browser/sync/engine/process_updates_command.h" | 5 #include "chrome/browser/sync/engine/process_updates_command.h" |
6 | 6 |
7 #include <vector> | 7 #include <vector> |
8 | 8 |
9 #include "base/basictypes.h" | 9 #include "base/basictypes.h" |
10 #include "chrome/browser/sync/engine/syncer.h" | 10 #include "chrome/browser/sync/engine/syncer.h" |
(...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
117 | 117 |
118 // We need to run the Verify checks again; the world could have changed | 118 // We need to run the Verify checks again; the world could have changed |
119 // since VerifyUpdatesCommand. | 119 // since VerifyUpdatesCommand. |
120 if (!ReverifyEntry(&trans, update, &target_entry)) { | 120 if (!ReverifyEntry(&trans, update, &target_entry)) { |
121 return SUCCESS_PROCESSED; // The entry has become irrelevant. | 121 return SUCCESS_PROCESSED; // The entry has become irrelevant. |
122 } | 122 } |
123 | 123 |
124 // If we're repurposing an existing local entry with a new server ID, | 124 // If we're repurposing an existing local entry with a new server ID, |
125 // change the ID now, after we're sure that the update can succeed. | 125 // change the ID now, after we're sure that the update can succeed. |
126 if (local_id != server_id) { | 126 if (local_id != server_id) { |
| 127 DCHECK(!update.deleted()); |
127 SyncerUtil::ChangeEntryIDAndUpdateChildren(&trans, &target_entry, | 128 SyncerUtil::ChangeEntryIDAndUpdateChildren(&trans, &target_entry, |
128 server_id); | 129 server_id); |
129 // When IDs change, versions become irrelevant. Forcing BASE_VERSION | 130 // When IDs change, versions become irrelevant. Forcing BASE_VERSION |
130 // to zero would ensure that this update gets applied, but historically, | 131 // to zero would ensure that this update gets applied, but would indicate |
131 // that's an illegal state unless the item is using the client tag. | 132 // creation or undeletion if it were committed that way. Instead, prefer |
132 // Alternatively, we can force BASE_VERSION to entry.version(), but | 133 // forcing BASE_VERSION to entry.version() while also forcing |
133 // this has the effect of suppressing update application. | 134 // IS_UNAPPLIED_UPDATE to true. If the item is UNSYNCED, it's committable |
134 // TODO(nick): Make the treatment of these two cases consistent. | 135 // from the new state; it may commit before the conflict resolver gets |
135 int64 new_version = target_entry.Get(UNIQUE_CLIENT_TAG).empty() ? | 136 // a crack at it. |
136 update.version() : 0; | 137 if (target_entry.Get(IS_UNSYNCED) || target_entry.Get(BASE_VERSION) > 0) { |
137 target_entry.Put(BASE_VERSION, new_version); | 138 // If either of these conditions are met, then we can expect valid client |
| 139 // fields for this entry. When BASE_VERSION is positive, consistency is |
| 140 // enforced on the client fields at update-application time. Otherwise, |
| 141 // we leave the BASE_VERSION field alone; it'll get updated the first time |
| 142 // we successfully apply this update. |
| 143 target_entry.Put(BASE_VERSION, update.version()); |
| 144 } |
| 145 // Force application of this update, no matter what. |
| 146 target_entry.Put(IS_UNAPPLIED_UPDATE, true); |
138 } | 147 } |
139 | 148 |
140 SyncerUtil::UpdateServerFieldsFromUpdate(&target_entry, update, name); | 149 SyncerUtil::UpdateServerFieldsFromUpdate(&target_entry, update, name); |
141 | 150 |
142 if (target_entry.Get(SERVER_VERSION) == target_entry.Get(BASE_VERSION) && | 151 if (target_entry.Get(SERVER_VERSION) == target_entry.Get(BASE_VERSION) && |
143 !target_entry.Get(IS_UNSYNCED)) { | 152 !target_entry.Get(IS_UNSYNCED) && |
144 // It's largely OK if data doesn't match exactly since a future update | 153 !target_entry.Get(IS_UNAPPLIED_UPDATE)) { |
145 // will just clobber the data. Conflict resolution will overwrite and | 154 // If these don't match, it means that we have a different view of the |
146 // take one side as the winner and does not try to merge, so strict | 155 // truth from other clients. That's a sync bug, though we may be able |
147 // equality isn't necessary. | 156 // to recover the next time this item commits. |
148 LOG_IF(ERROR, !SyncerUtil::ServerAndLocalEntriesMatch(&target_entry)) | 157 LOG_IF(ERROR, !SyncerUtil::ServerAndLocalEntriesMatch(&target_entry)) |
149 << target_entry; | 158 << target_entry; |
150 } | 159 } |
151 return SUCCESS_PROCESSED; | 160 return SUCCESS_PROCESSED; |
152 } | 161 } |
153 | 162 |
154 } // namespace browser_sync | 163 } // namespace browser_sync |
OLD | NEW |