OLD | NEW |
---|---|
1 // Copyright 2016 The Chromium Authors. All rights reserved. | 1 // Copyright 2016 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 "components/reading_list/ios/reading_list_store.h" | 5 #include "components/reading_list/ios/reading_list_store.h" |
6 | 6 |
7 #include "base/bind.h" | 7 #include "base/bind.h" |
8 #include "base/logging.h" | 8 #include "base/logging.h" |
9 #include "base/memory/ptr_util.h" | 9 #include "base/memory/ptr_util.h" |
10 #include "components/reading_list/ios/proto/reading_list.pb.h" | 10 #include "components/reading_list/ios/proto/reading_list.pb.h" |
(...skipping 213 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
224 | 224 |
225 if (!existing_entry) { | 225 if (!existing_entry) { |
226 // This entry is new. Add it to the store and model. | 226 // This entry is new. Add it to the store and model. |
227 // Convert to local store format and write to store. | 227 // Convert to local store format and write to store. |
228 std::unique_ptr<reading_list::ReadingListLocal> entry_pb = | 228 std::unique_ptr<reading_list::ReadingListLocal> entry_pb = |
229 entry->AsReadingListLocal(); | 229 entry->AsReadingListLocal(); |
230 batch_->WriteData(entry->URL().spec(), entry_pb->SerializeAsString()); | 230 batch_->WriteData(entry->URL().spec(), entry_pb->SerializeAsString()); |
231 | 231 |
232 // Notify model about updated entry. | 232 // Notify model about updated entry. |
233 delegate_->SyncAddEntry(std::move(entry)); | 233 delegate_->SyncAddEntry(std::move(entry)); |
234 } else if (existing_entry->UpdateTime() < entry->UpdateTime()) { | 234 } else { |
235 // The entry from sync is more recent. | 235 // The entry from sync is more recent. |
gambard
2016/12/06 17:02:22
Update comment
Olivier
2016/12/06 17:16:21
Done.
| |
236 // Merge the local data to it and store it. | 236 // Merge the local data to it and store it. |
237 ReadingListEntry* merged_entry = | 237 ReadingListEntry* merged_entry = |
238 delegate_->SyncMergeEntry(std::move(entry)); | 238 delegate_->SyncMergeEntry(std::move(entry)); |
239 | 239 |
240 // Write to the store. | 240 // Write to the store. |
241 std::unique_ptr<reading_list::ReadingListLocal> entry_local_pb = | 241 std::unique_ptr<reading_list::ReadingListLocal> entry_local_pb = |
242 merged_entry->AsReadingListLocal(); | 242 merged_entry->AsReadingListLocal(); |
243 batch_->WriteData(entry->URL().spec(), | 243 batch_->WriteData(entry->URL().spec(), |
244 entry_local_pb->SerializeAsString()); | 244 entry_local_pb->SerializeAsString()); |
245 | 245 |
246 // Send to sync | 246 // Send to sync |
247 std::unique_ptr<sync_pb::ReadingListSpecifics> entry_sync_pb = | 247 std::unique_ptr<sync_pb::ReadingListSpecifics> entry_sync_pb = |
248 merged_entry->AsReadingListSpecifics(); | 248 merged_entry->AsReadingListSpecifics(); |
249 DCHECK(CompareEntriesForSync(specifics, *entry_sync_pb)); | |
249 auto entity_data = base::MakeUnique<syncer::EntityData>(); | 250 auto entity_data = base::MakeUnique<syncer::EntityData>(); |
250 *(entity_data->specifics.mutable_reading_list()) = *entry_sync_pb; | 251 *(entity_data->specifics.mutable_reading_list()) = *entry_sync_pb; |
251 entity_data->non_unique_name = entry_sync_pb->entry_id(); | 252 entity_data->non_unique_name = entry_sync_pb->entry_id(); |
252 | 253 |
253 // TODO(crbug.com/666232): Investigate if there is a risk of sync | 254 // TODO(crbug.com/666232): Investigate if there is a risk of sync |
254 // ping-pong. | 255 // ping-pong. |
255 change_processor()->Put(entry_sync_pb->entry_id(), std::move(entity_data), | 256 change_processor()->Put(entry_sync_pb->entry_id(), std::move(entity_data), |
256 metadata_change_list.get()); | 257 metadata_change_list.get()); |
257 | 258 |
258 } else { | |
259 // The entry from sync is out of date. | |
260 // Send back the local more recent entry. | |
261 // No need to update | |
262 std::unique_ptr<sync_pb::ReadingListSpecifics> entry_pb = | |
263 existing_entry->AsReadingListSpecifics(); | |
264 auto entity_data = base::MakeUnique<syncer::EntityData>(); | |
265 *(entity_data->specifics.mutable_reading_list()) = *entry_pb; | |
266 entity_data->non_unique_name = entry_pb->entry_id(); | |
267 | |
268 change_processor()->Put(entry_pb->entry_id(), std::move(entity_data), | |
269 metadata_change_list.get()); | |
270 } | 259 } |
271 } | 260 } |
272 | 261 |
273 // Commit local only entries to server. | 262 // Commit local only entries to server. |
274 for (const auto& url : model_->Keys()) { | 263 for (const auto& url : model_->Keys()) { |
275 const ReadingListEntry* entry = model_->GetEntryByURL(url); | 264 const ReadingListEntry* entry = model_->GetEntryByURL(url); |
276 if (synced_entries.count(url.spec())) { | 265 if (synced_entries.count(url.spec())) { |
277 // Entry already exists and has been merged above. | 266 // Entry already exists and has been merged above. |
278 continue; | 267 continue; |
279 } | 268 } |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
324 | 313 |
325 if (!existing_entry) { | 314 if (!existing_entry) { |
326 // This entry is new. Add it to the store and model. | 315 // This entry is new. Add it to the store and model. |
327 // Convert to local store format and write to store. | 316 // Convert to local store format and write to store. |
328 std::unique_ptr<reading_list::ReadingListLocal> entry_pb = | 317 std::unique_ptr<reading_list::ReadingListLocal> entry_pb = |
329 entry->AsReadingListLocal(); | 318 entry->AsReadingListLocal(); |
330 batch_->WriteData(entry->URL().spec(), entry_pb->SerializeAsString()); | 319 batch_->WriteData(entry->URL().spec(), entry_pb->SerializeAsString()); |
331 | 320 |
332 // Notify model about updated entry. | 321 // Notify model about updated entry. |
333 delegate_->SyncAddEntry(std::move(entry)); | 322 delegate_->SyncAddEntry(std::move(entry)); |
334 } else if (existing_entry->UpdateTime() < entry->UpdateTime()) { | 323 } else { |
335 // The entry from sync is more recent. | 324 // The entry from sync is more recent. |
gambard
2016/12/06 17:02:22
Update comment
Olivier
2016/12/06 17:16:21
Done.
| |
336 // Merge the local data to it and store it. | 325 // Merge the local data to it and store it. |
337 ReadingListEntry* merged_entry = | 326 ReadingListEntry* merged_entry = |
338 delegate_->SyncMergeEntry(std::move(entry)); | 327 delegate_->SyncMergeEntry(std::move(entry)); |
339 | 328 |
340 // Write to the store. | 329 // Write to the store. |
341 std::unique_ptr<reading_list::ReadingListLocal> entry_local_pb = | 330 std::unique_ptr<reading_list::ReadingListLocal> entry_local_pb = |
342 merged_entry->AsReadingListLocal(); | 331 merged_entry->AsReadingListLocal(); |
343 batch_->WriteData(merged_entry->URL().spec(), | 332 batch_->WriteData(merged_entry->URL().spec(), |
344 entry_local_pb->SerializeAsString()); | 333 entry_local_pb->SerializeAsString()); |
345 | 334 |
346 // Send to sync | 335 // Send to sync |
347 std::unique_ptr<sync_pb::ReadingListSpecifics> entry_sync_pb = | 336 std::unique_ptr<sync_pb::ReadingListSpecifics> entry_sync_pb = |
348 merged_entry->AsReadingListSpecifics(); | 337 merged_entry->AsReadingListSpecifics(); |
338 DCHECK(CompareEntriesForSync(specifics, *entry_sync_pb)); | |
349 auto entity_data = base::MakeUnique<syncer::EntityData>(); | 339 auto entity_data = base::MakeUnique<syncer::EntityData>(); |
350 *(entity_data->specifics.mutable_reading_list()) = *entry_sync_pb; | 340 *(entity_data->specifics.mutable_reading_list()) = *entry_sync_pb; |
351 entity_data->non_unique_name = entry_sync_pb->entry_id(); | 341 entity_data->non_unique_name = entry_sync_pb->entry_id(); |
352 | 342 |
353 // TODO(crbug.com/666232): Investigate if there is a risk of sync | 343 // TODO(crbug.com/666232): Investigate if there is a risk of sync |
354 // ping-pong. | 344 // ping-pong. |
355 change_processor()->Put(entry_sync_pb->entry_id(), | 345 change_processor()->Put(entry_sync_pb->entry_id(), |
356 std::move(entity_data), | 346 std::move(entity_data), |
357 metadata_change_list.get()); | 347 metadata_change_list.get()); |
358 | 348 |
359 } else { | |
360 // The entry from sync is out of date. | |
361 // Send back the local more recent entry. | |
362 // No need to update | |
363 std::unique_ptr<sync_pb::ReadingListSpecifics> entry_pb = | |
364 existing_entry->AsReadingListSpecifics(); | |
365 auto entity_data = base::MakeUnique<syncer::EntityData>(); | |
366 *(entity_data->specifics.mutable_reading_list()) = *entry_pb; | |
367 entity_data->non_unique_name = entry_pb->entry_id(); | |
368 | |
369 change_processor()->Put(entry_pb->entry_id(), std::move(entity_data), | |
370 metadata_change_list.get()); | |
371 } | 349 } |
372 } | 350 } |
373 } | 351 } |
374 | 352 |
375 batch_->TransferMetadataChanges(std::move(metadata_change_list)); | 353 batch_->TransferMetadataChanges(std::move(metadata_change_list)); |
376 return syncer::SyncError(); | 354 return syncer::SyncError(); |
377 } | 355 } |
378 | 356 |
379 void ReadingListStore::GetData(StorageKeyList storage_keys, | 357 void ReadingListStore::GetData(StorageKeyList storage_keys, |
380 DataCallback callback) { | 358 DataCallback callback) { |
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
432 // called once when first encountering a remote entity. Local changes will | 410 // called once when first encountering a remote entity. Local changes will |
433 // provide their storage keys directly to Put instead of using this method. | 411 // provide their storage keys directly to Put instead of using this method. |
434 // Theoretically this function doesn't need to be stable across multiple calls | 412 // Theoretically this function doesn't need to be stable across multiple calls |
435 // on the same or different clients, but to keep things simple, it probably | 413 // on the same or different clients, but to keep things simple, it probably |
436 // should be. | 414 // should be. |
437 std::string ReadingListStore::GetStorageKey( | 415 std::string ReadingListStore::GetStorageKey( |
438 const syncer::EntityData& entity_data) { | 416 const syncer::EntityData& entity_data) { |
439 DCHECK(CalledOnValidThread()); | 417 DCHECK(CalledOnValidThread()); |
440 return entity_data.specifics.reading_list().entry_id(); | 418 return entity_data.specifics.reading_list().entry_id(); |
441 } | 419 } |
420 | |
421 bool ReadingListStore::CompareEntriesForSync( | |
422 const sync_pb::ReadingListSpecifics& lhs, | |
423 const sync_pb::ReadingListSpecifics& rhs) { | |
424 DCHECK(lhs.entry_id() == rhs.entry_id()); | |
425 DCHECK(lhs.has_update_time_us()); | |
426 DCHECK(rhs.has_update_time_us()); | |
427 DCHECK(lhs.has_creation_time_us()); | |
428 DCHECK(rhs.has_creation_time_us()); | |
429 DCHECK(lhs.has_url()); | |
430 DCHECK(rhs.has_url()); | |
431 DCHECK(lhs.has_title()); | |
432 DCHECK(rhs.has_title()); | |
433 DCHECK(lhs.has_status()); | |
434 DCHECK(rhs.has_status()); | |
435 if (lhs.update_time_us() < rhs.update_time_us()) { | |
436 // The entry is more recent, so it can be submitted to sync. | |
gambard
2016/12/06 17:02:22
"The entry" here and below is not specific enough.
Olivier
2016/12/06 17:16:21
Done.
| |
437 return true; | |
438 } | |
439 if (lhs.update_time_us() > rhs.update_time_us()) { | |
440 // The entry is older, so it cannot be submitted to sync. | |
441 return false; | |
442 } | |
443 | |
444 if (lhs.url() != rhs.url() || lhs.title() != rhs.title() || | |
gambard
2016/12/06 17:02:22
Not sure the check on "url()" is necessary here.
Olivier
2016/12/06 17:16:21
As far as sync is concerned, the key is entry_id.
| |
445 lhs.creation_time_us() != rhs.creation_time_us() || | |
446 lhs.update_time_us() != rhs.update_time_us()) { | |
gambard
2016/12/06 17:02:22
Actually I don't understand this condition.
If the
Olivier
2016/12/06 17:16:21
This method ensures that you send correct data to
| |
447 // A modification should not be submitted to the server without a change to | |
448 // update_time. | |
449 return false; | |
450 } | |
451 if (lhs.status() == sync_pb::ReadingListSpecifics::UNSEEN) { | |
452 // An entry can always be marked SEEN on a device. | |
453 return true; | |
454 } | |
455 if (lhs.status() != rhs.status()) { | |
gambard
2016/12/06 17:02:22
Maybe add a comment for this?
Olivier
2016/12/06 17:16:21
Done.
| |
456 return false; | |
457 } | |
458 // All cases should be handled. Entries must be the same. | |
459 DCHECK(lhs.SerializeAsString() == rhs.SerializeAsString()); | |
460 return true; | |
461 } | |
OLD | NEW |