Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(180)

Side by Side Diff: chrome/browser/sync/engine/syncapi.cc

Issue 593094: Add unique hashing to sync API. (Closed)
Patch Set: New unit test, review fixes. Created 10 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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/syncapi.h" 5 #include "chrome/browser/sync/engine/syncapi.h"
6 6
7 #include "build/build_config.h" 7 #include "build/build_config.h"
8 8
9 #if defined(OS_WIN) 9 #if defined(OS_WIN)
10 #include <windows.h> 10 #include <windows.h>
(...skipping 14 matching lines...) Expand all
25 25
26 #include <iomanip> 26 #include <iomanip>
27 #include <list> 27 #include <list>
28 #include <string> 28 #include <string>
29 #include <vector> 29 #include <vector>
30 30
31 #include "base/basictypes.h" 31 #include "base/basictypes.h"
32 #include "base/lock.h" 32 #include "base/lock.h"
33 #include "base/platform_thread.h" 33 #include "base/platform_thread.h"
34 #include "base/scoped_ptr.h" 34 #include "base/scoped_ptr.h"
35 #include "base/sha1.h"
35 #include "base/string_util.h" 36 #include "base/string_util.h"
36 #include "base/task.h" 37 #include "base/task.h"
37 #include "base/utf_string_conversions.h" 38 #include "base/utf_string_conversions.h"
38 #include "chrome/browser/sync/engine/all_status.h" 39 #include "chrome/browser/sync/engine/all_status.h"
39 #include "chrome/browser/sync/engine/auth_watcher.h" 40 #include "chrome/browser/sync/engine/auth_watcher.h"
40 #include "chrome/browser/sync/engine/change_reorder_buffer.h" 41 #include "chrome/browser/sync/engine/change_reorder_buffer.h"
41 #include "chrome/browser/sync/engine/model_safe_worker.h" 42 #include "chrome/browser/sync/engine/model_safe_worker.h"
42 #include "chrome/browser/sync/engine/net/gaia_authenticator.h" 43 #include "chrome/browser/sync/engine/net/gaia_authenticator.h"
43 #include "chrome/browser/sync/engine/net/server_connection_manager.h" 44 #include "chrome/browser/sync/engine/net/server_connection_manager.h"
44 #include "chrome/browser/sync/engine/net/syncapi_server_connection_manager.h" 45 #include "chrome/browser/sync/engine/net/syncapi_server_connection_manager.h"
(...skipping 337 matching lines...) Expand 10 before | Expand all | Expand 10 after
382 } 383 }
383 } 384 }
384 385
385 //////////////////////////////////// 386 ////////////////////////////////////
386 // BaseNode member definitions. 387 // BaseNode member definitions.
387 388
388 BaseNode::BaseNode() {} 389 BaseNode::BaseNode() {}
389 390
390 BaseNode::~BaseNode() {} 391 BaseNode::~BaseNode() {}
391 392
393 std::string BaseNode::GenerateSyncableHash(
394 syncable::ModelType model_type, const std::string& client_tag) {
395 // blank PB with just the extension in it has termination symbol,
396 // handy for delimiter
397 sync_pb::EntitySpecifics serialized_type;
398 syncable::AddDefaultExtensionValue(model_type, &serialized_type);
399 std::string hash_input;
400 serialized_type.AppendToString(&hash_input);
401 hash_input.append(client_tag);
402 return base::SHA1HashString(hash_input);
403 }
404
392 int64 BaseNode::GetParentId() const { 405 int64 BaseNode::GetParentId() const {
393 return IdToMetahandle(GetTransaction()->GetWrappedTrans(), 406 return IdToMetahandle(GetTransaction()->GetWrappedTrans(),
394 GetEntry()->Get(syncable::PARENT_ID)); 407 GetEntry()->Get(syncable::PARENT_ID));
395 } 408 }
396 409
397 int64 BaseNode::GetId() const { 410 int64 BaseNode::GetId() const {
398 return GetEntry()->Get(syncable::META_HANDLE); 411 return GetEntry()->Get(syncable::META_HANDLE);
399 } 412 }
400 413
401 bool BaseNode::GetIsFolder() const { 414 bool BaseNode::GetIsFolder() const {
(...skipping 147 matching lines...) Expand 10 before | Expand all | Expand 10 after
549 DCHECK(!entry_) << "Init called twice"; 562 DCHECK(!entry_) << "Init called twice";
550 DCHECK_NE(id, kInvalidId); 563 DCHECK_NE(id, kInvalidId);
551 entry_ = new syncable::MutableEntry(transaction_->GetWrappedWriteTrans(), 564 entry_ = new syncable::MutableEntry(transaction_->GetWrappedWriteTrans(),
552 syncable::GET_BY_HANDLE, id); 565 syncable::GET_BY_HANDLE, id);
553 return (entry_->good() && !entry_->Get(syncable::IS_DEL)); 566 return (entry_->good() && !entry_->Get(syncable::IS_DEL));
554 } 567 }
555 568
556 // Find a node by client tag, and bind this WriteNode to it. 569 // Find a node by client tag, and bind this WriteNode to it.
557 // Return true if the write node was found, and was not deleted. 570 // Return true if the write node was found, and was not deleted.
558 // Undeleting a deleted node is possible by ClientTag. 571 // Undeleting a deleted node is possible by ClientTag.
559 bool WriteNode::InitByClientTagLookup(const std::string& tag) { 572 bool WriteNode::InitByClientTagLookup(syncable::ModelType model_type,
573 const std::string& tag) {
560 DCHECK(!entry_) << "Init called twice"; 574 DCHECK(!entry_) << "Init called twice";
561 if (tag.empty()) 575 if (tag.empty())
562 return false; 576 return false;
577
578 const std::string hash = GenerateSyncableHash(model_type, tag);
579
563 entry_ = new syncable::MutableEntry(transaction_->GetWrappedWriteTrans(), 580 entry_ = new syncable::MutableEntry(transaction_->GetWrappedWriteTrans(),
564 syncable::GET_BY_CLIENT_TAG, tag); 581 syncable::GET_BY_CLIENT_TAG, hash);
565 return (entry_->good() && !entry_->Get(syncable::IS_DEL)); 582 return (entry_->good() && !entry_->Get(syncable::IS_DEL));
566 } 583 }
567 584
568 void WriteNode::PutModelType(syncable::ModelType model_type) { 585 void WriteNode::PutModelType(syncable::ModelType model_type) {
569 // Set an empty specifics of the appropriate datatype. The presence 586 // Set an empty specifics of the appropriate datatype. The presence
570 // of the specific extension will identify the model type. 587 // of the specific extension will identify the model type.
588 DCHECK(GetModelType() == model_type ||
589 GetModelType() == syncable::UNSPECIFIED); // Immutable once set.
590
571 sync_pb::EntitySpecifics specifics; 591 sync_pb::EntitySpecifics specifics;
572 syncable::AddDefaultExtensionValue(model_type, &specifics); 592 syncable::AddDefaultExtensionValue(model_type, &specifics);
573 PutSpecificsAndMarkForSyncing(specifics); 593 PutSpecificsAndMarkForSyncing(specifics);
574 DCHECK(GetModelType() == model_type); 594 DCHECK(GetModelType() == model_type);
575 } 595 }
576 596
577 // Create a new node with default properties, and bind this WriteNode to it. 597 // Create a new node with default properties, and bind this WriteNode to it.
578 // Return true on success. 598 // Return true on success.
579 bool WriteNode::InitByCreation(syncable::ModelType model_type, 599 bool WriteNode::InitByCreation(syncable::ModelType model_type,
580 const BaseNode& parent, 600 const BaseNode& parent,
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
613 // and bind this WriteNode to it. 633 // and bind this WriteNode to it.
614 // Return true on success. If the tag exists in the database, then 634 // Return true on success. If the tag exists in the database, then
615 // we will attempt to undelete the node. 635 // we will attempt to undelete the node.
616 // TODO(chron): Code datatype into hash tag. 636 // TODO(chron): Code datatype into hash tag.
617 // TODO(chron): Is model type ever lost? 637 // TODO(chron): Is model type ever lost?
618 bool WriteNode::InitUniqueByCreation(syncable::ModelType model_type, 638 bool WriteNode::InitUniqueByCreation(syncable::ModelType model_type,
619 const BaseNode& parent, 639 const BaseNode& parent,
620 const std::string& tag) { 640 const std::string& tag) {
621 DCHECK(!entry_) << "Init called twice"; 641 DCHECK(!entry_) << "Init called twice";
622 642
643 const std::string hash = GenerateSyncableHash(model_type, tag);
644
623 syncable::Id parent_id = parent.GetEntry()->Get(syncable::ID); 645 syncable::Id parent_id = parent.GetEntry()->Get(syncable::ID);
624 646
625 // Start out with a dummy name. We expect 647 // Start out with a dummy name. We expect
626 // the caller to set a meaningful name after creation. 648 // the caller to set a meaningful name after creation.
627 string dummy(kDefaultNameForNewNodes); 649 string dummy(kDefaultNameForNewNodes);
628 650
629 // Check if we have this locally and need to undelete it. 651 // Check if we have this locally and need to undelete it.
630 scoped_ptr<syncable::MutableEntry> existing_entry( 652 scoped_ptr<syncable::MutableEntry> existing_entry(
631 new syncable::MutableEntry(transaction_->GetWrappedWriteTrans(), 653 new syncable::MutableEntry(transaction_->GetWrappedWriteTrans(),
632 syncable::GET_BY_CLIENT_TAG, tag)); 654 syncable::GET_BY_CLIENT_TAG, hash));
633 655
634 if (existing_entry->good()) { 656 if (existing_entry->good()) {
635 if (existing_entry->Get(syncable::IS_DEL)) { 657 if (existing_entry->Get(syncable::IS_DEL)) {
636 // Rules for undelete: 658 // Rules for undelete:
637 // BASE_VERSION: Must keep the same. 659 // BASE_VERSION: Must keep the same.
638 // ID: Essential to keep the same. 660 // ID: Essential to keep the same.
639 // META_HANDLE: Must be the same, so we can't "split" the entry. 661 // META_HANDLE: Must be the same, so we can't "split" the entry.
640 // IS_DEL: Must be set to false, will cause reindexing. 662 // IS_DEL: Must be set to false, will cause reindexing.
641 // This one is weird because IS_DEL is true for "update only" 663 // This one is weird because IS_DEL is true for "update only"
642 // items. It should be OK to undelete an update only. 664 // items. It should be OK to undelete an update only.
(...skipping 20 matching lines...) Expand all
663 return false; 685 return false;
664 } 686 }
665 } else { 687 } else {
666 entry_ = new syncable::MutableEntry(transaction_->GetWrappedWriteTrans(), 688 entry_ = new syncable::MutableEntry(transaction_->GetWrappedWriteTrans(),
667 syncable::CREATE, parent_id, dummy); 689 syncable::CREATE, parent_id, dummy);
668 if (!entry_->good()) { 690 if (!entry_->good()) {
669 return false; 691 return false;
670 } 692 }
671 693
672 // Only set IS_DIR for new entries. Don't bitflip undeleted ones. 694 // Only set IS_DIR for new entries. Don't bitflip undeleted ones.
673 entry_->Put(syncable::UNIQUE_CLIENT_TAG, tag); 695 entry_->Put(syncable::UNIQUE_CLIENT_TAG, hash);
674 } 696 }
675 697
676 // We don't support directory and tag combinations. 698 // We don't support directory and tag combinations.
677 entry_->Put(syncable::IS_DIR, false); 699 entry_->Put(syncable::IS_DIR, false);
678 700
679 // Will clear specifics data. 701 // Will clear specifics data.
680 PutModelType(model_type); 702 PutModelType(model_type);
681 703
682 // Now set the predecessor, which sets IS_UNSYNCED as necessary. 704 // Now set the predecessor, which sets IS_UNSYNCED as necessary.
683 PutPredecessor(NULL); 705 PutPredecessor(NULL);
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after
774 return false; 796 return false;
775 if (entry_->Get(syncable::IS_DEL)) 797 if (entry_->Get(syncable::IS_DEL))
776 return false; 798 return false;
777 syncable::ModelType model_type = GetModelType(); 799 syncable::ModelType model_type = GetModelType();
778 LOG_IF(WARNING, model_type == syncable::UNSPECIFIED || 800 LOG_IF(WARNING, model_type == syncable::UNSPECIFIED ||
779 model_type == syncable::TOP_LEVEL_FOLDER) 801 model_type == syncable::TOP_LEVEL_FOLDER)
780 << "SyncAPI InitByIdLookup referencing unusual object."; 802 << "SyncAPI InitByIdLookup referencing unusual object.";
781 return true; 803 return true;
782 } 804 }
783 805
784 bool ReadNode::InitByClientTagLookup(const std::string& tag) { 806 bool ReadNode::InitByClientTagLookup(syncable::ModelType model_type,
807 const std::string& tag) {
785 DCHECK(!entry_) << "Init called twice"; 808 DCHECK(!entry_) << "Init called twice";
786 if (tag.empty()) 809 if (tag.empty())
787 return false; 810 return false;
811
812 const std::string hash = GenerateSyncableHash(model_type, tag);
813
788 entry_ = new syncable::Entry(transaction_->GetWrappedTrans(), 814 entry_ = new syncable::Entry(transaction_->GetWrappedTrans(),
789 syncable::GET_BY_CLIENT_TAG, tag); 815 syncable::GET_BY_CLIENT_TAG, hash);
790 return (entry_->good() && !entry_->Get(syncable::IS_DEL)); 816 return (entry_->good() && !entry_->Get(syncable::IS_DEL));
791 } 817 }
792 818
793 const syncable::Entry* ReadNode::GetEntry() const { 819 const syncable::Entry* ReadNode::GetEntry() const {
794 return entry_; 820 return entry_;
795 } 821 }
796 822
797 const BaseTransaction* ReadNode::GetTransaction() const { 823 const BaseTransaction* ReadNode::GetTransaction() const {
798 return transaction_; 824 return transaction_;
799 } 825 }
(...skipping 1038 matching lines...) Expand 10 before | Expand all | Expand 10 after
1838 BaseTransaction::~BaseTransaction() { 1864 BaseTransaction::~BaseTransaction() {
1839 delete lookup_; 1865 delete lookup_;
1840 } 1866 }
1841 1867
1842 UserShare* SyncManager::GetUserShare() const { 1868 UserShare* SyncManager::GetUserShare() const {
1843 DCHECK(data_->initialized()) << "GetUserShare requires initialization!"; 1869 DCHECK(data_->initialized()) << "GetUserShare requires initialization!";
1844 return data_->GetUserShare(); 1870 return data_->GetUserShare();
1845 } 1871 }
1846 1872
1847 } // namespace sync_api 1873 } // namespace sync_api
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698