14e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)// Copyright 2013 The Chromium Authors. All rights reserved. 24e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 34e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)// found in the LICENSE file. 44e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 54e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "components/dom_distiller/core/dom_distiller_store.h" 64e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 74e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "base/bind.h" 84e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "base/logging.h" 94e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "components/dom_distiller/core/article_entry.h" 104e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "sync/api/sync_change.h" 114e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "sync/protocol/article_specifics.pb.h" 124e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "sync/protocol/sync.pb.h" 134e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 14f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)using leveldb_proto::ProtoDatabase; 154e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)using sync_pb::ArticleSpecifics; 164e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)using sync_pb::EntitySpecifics; 174e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)using syncer::ModelType; 184e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)using syncer::SyncChange; 194e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)using syncer::SyncChangeList; 204e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)using syncer::SyncData; 214e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)using syncer::SyncDataList; 224e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)using syncer::SyncError; 234e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)using syncer::SyncMergeResult; 244e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 254e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)namespace dom_distiller { 264e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 274e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)DomDistillerStore::DomDistillerStore( 28f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) scoped_ptr<ProtoDatabase<ArticleEntry> > database, 294e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) const base::FilePath& database_dir) 304e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) : database_(database.Pass()), 314e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) database_loaded_(false), 324e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) weak_ptr_factory_(this) { 33f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) database_->Init(database_dir, base::Bind(&DomDistillerStore::OnDatabaseInit, 34f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) weak_ptr_factory_.GetWeakPtr())); 354e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)} 364e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 374e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)DomDistillerStore::DomDistillerStore( 38f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) scoped_ptr<ProtoDatabase<ArticleEntry> > database, 391e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) const std::vector<ArticleEntry>& initial_data, 404e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) const base::FilePath& database_dir) 414e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) : database_(database.Pass()), 424e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) database_loaded_(false), 431e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) model_(initial_data), 444e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) weak_ptr_factory_(this) { 45f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) database_->Init(database_dir, base::Bind(&DomDistillerStore::OnDatabaseInit, 46f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) weak_ptr_factory_.GetWeakPtr())); 474e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)} 484e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 494e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)DomDistillerStore::~DomDistillerStore() {} 504e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 514e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)// DomDistillerStoreInterface implementation. 524e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)syncer::SyncableService* DomDistillerStore::GetSyncableService() { 534e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) return this; 544e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)} 554e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 561e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)bool DomDistillerStore::GetEntryById(const std::string& entry_id, 571e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) ArticleEntry* entry) { 581e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) return model_.GetEntryById(entry_id, entry); 591e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)} 601e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 61f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)bool DomDistillerStore::GetEntryByUrl(const GURL& url, ArticleEntry* entry) { 621e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) return model_.GetEntryByUrl(url, entry); 631e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)} 641e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 654e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)bool DomDistillerStore::AddEntry(const ArticleEntry& entry) { 664e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (!database_loaded_) { 674e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) return false; 684e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } 691e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 701e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) if (model_.GetEntryById(entry.entry_id(), NULL)) { 71a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) DVLOG(1) << "Already have entry with id " << entry.entry_id() << "."; 724e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) return false; 734e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } 744e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 754e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) SyncChangeList changes_to_apply; 764e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) changes_to_apply.push_back( 774e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) SyncChange(FROM_HERE, SyncChange::ACTION_ADD, CreateLocalData(entry))); 784e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 794e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) SyncChangeList changes_applied; 804e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) SyncChangeList changes_missing; 811e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 82a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) ApplyChangesToModel(changes_to_apply, &changes_applied, &changes_missing); 83a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 84a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) DCHECK_EQ(size_t(0), changes_missing.size()); 85a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) DCHECK_EQ(size_t(1), changes_applied.size()); 86a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 87a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) ApplyChangesToSync(FROM_HERE, changes_applied); 88a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) ApplyChangesToDatabase(changes_applied); 89a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 90a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) return true; 91a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)} 92a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)bool DomDistillerStore::UpdateEntry(const ArticleEntry& entry) { 945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (!database_loaded_) { 955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return false; 965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (!model_.GetEntryById(entry.entry_id(), NULL)) { 995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) DVLOG(1) << "No entry with id " << entry.entry_id() << " found."; 1005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return false; 1015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 1025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) SyncChangeList changes_to_apply; 1045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) changes_to_apply.push_back( 1055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) SyncChange(FROM_HERE, SyncChange::ACTION_UPDATE, CreateLocalData(entry))); 1065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) SyncChangeList changes_applied; 1085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) SyncChangeList changes_missing; 1095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ApplyChangesToModel(changes_to_apply, &changes_applied, &changes_missing); 1115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (changes_applied.size() != 1) { 1135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) DVLOG(1) << "Failed to update entry with id " << entry.entry_id() << "."; 1145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return false; 1155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 1165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ApplyChangesToSync(FROM_HERE, changes_applied); 1185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ApplyChangesToDatabase(changes_applied); 1195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return true; 1215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 1225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 123a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)bool DomDistillerStore::RemoveEntry(const ArticleEntry& entry) { 124a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) if (!database_loaded_) { 125a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) return false; 126a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) } 127a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 128a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) if (!model_.GetEntryById(entry.entry_id(), NULL)) { 129a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) DVLOG(1) << "No entry with id " << entry.entry_id() << " found."; 1301e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) return false; 1311e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) } 1324e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 133a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) SyncChangeList changes_to_apply; 134a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) changes_to_apply.push_back( 135a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) SyncChange(FROM_HERE, SyncChange::ACTION_DELETE, CreateLocalData(entry))); 136a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 137a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) SyncChangeList changes_applied; 138a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) SyncChangeList changes_missing; 139a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 140a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) ApplyChangesToModel(changes_to_apply, &changes_applied, &changes_missing); 141a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 1424e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) DCHECK_EQ(size_t(0), changes_missing.size()); 1434e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) DCHECK_EQ(size_t(1), changes_applied.size()); 1444e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 1454e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) ApplyChangesToSync(FROM_HERE, changes_applied); 1464e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) ApplyChangesToDatabase(changes_applied); 1474e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 1484e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) return true; 1494e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)} 1504e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 151a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)void DomDistillerStore::AddObserver(DomDistillerObserver* observer) { 152a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) observers_.AddObserver(observer); 153a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)} 154a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 155a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)void DomDistillerStore::RemoveObserver(DomDistillerObserver* observer) { 156a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) observers_.RemoveObserver(observer); 157a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)} 158a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 1594e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)std::vector<ArticleEntry> DomDistillerStore::GetEntries() const { 1601e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) return model_.GetEntries(); 1614e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)} 1624e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 1634e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)// syncer::SyncableService implementation. 1644e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)SyncMergeResult DomDistillerStore::MergeDataAndStartSyncing( 165f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) ModelType type, const SyncDataList& initial_sync_data, 1664e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) scoped_ptr<syncer::SyncChangeProcessor> sync_processor, 1674e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) scoped_ptr<syncer::SyncErrorFactory> error_handler) { 1684e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) DCHECK_EQ(syncer::ARTICLES, type); 1694e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) DCHECK(!sync_processor_); 1704e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) DCHECK(!error_factory_); 1714e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) sync_processor_.reset(sync_processor.release()); 1724e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) error_factory_.reset(error_handler.release()); 1734e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 1744e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) SyncChangeList database_changes; 1754e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) SyncChangeList sync_changes; 1764e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) SyncMergeResult result = 1774e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) MergeDataWithModel(initial_sync_data, &database_changes, &sync_changes); 1784e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) ApplyChangesToDatabase(database_changes); 1794e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) ApplyChangesToSync(FROM_HERE, sync_changes); 1804e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 1814e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) return result; 1824e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)} 1834e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 1844e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)void DomDistillerStore::StopSyncing(ModelType type) { 1854e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) sync_processor_.reset(); 1864e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) error_factory_.reset(); 1874e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)} 1884e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 1894e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)SyncDataList DomDistillerStore::GetAllSyncData(ModelType type) const { 1901e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) return model_.GetAllSyncData(); 1914e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)} 1924e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 1934e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)SyncError DomDistillerStore::ProcessSyncChanges( 1944e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) const tracked_objects::Location& from_here, 1954e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) const SyncChangeList& change_list) { 1964e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) DCHECK(database_loaded_); 1974e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) SyncChangeList database_changes; 1984e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) SyncChangeList sync_changes; 199a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) ApplyChangesToModel(change_list, &database_changes, &sync_changes); 2004e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) ApplyChangesToDatabase(database_changes); 2014e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) DCHECK_EQ(size_t(0), sync_changes.size()); 2021e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) return SyncError(); 2034e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)} 2044e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 205a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)void DomDistillerStore::NotifyObservers(const syncer::SyncChangeList& changes) { 206a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) if (observers_.might_have_observers() && changes.size() > 0) { 207a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) std::vector<DomDistillerObserver::ArticleUpdate> article_changes; 208a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) for (SyncChangeList::const_iterator it = changes.begin(); 209f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) it != changes.end(); ++it) { 210a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) DomDistillerObserver::ArticleUpdate article_update; 211a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) switch (it->change_type()) { 212a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) case SyncChange::ACTION_ADD: 213a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) article_update.update_type = DomDistillerObserver::ArticleUpdate::ADD; 214a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) break; 215a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) case SyncChange::ACTION_UPDATE: 216a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) article_update.update_type = 217a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) DomDistillerObserver::ArticleUpdate::UPDATE; 218a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) break; 219a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) case SyncChange::ACTION_DELETE: 220a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) article_update.update_type = 221a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) DomDistillerObserver::ArticleUpdate::REMOVE; 222a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) break; 223a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) case SyncChange::ACTION_INVALID: 224a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) NOTREACHED(); 225a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) break; 226a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) } 227a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) const ArticleEntry& entry = GetEntryFromChange(*it); 228a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) article_update.entry_id = entry.entry_id(); 229a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) article_changes.push_back(article_update); 230a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) } 231f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) FOR_EACH_OBSERVER(DomDistillerObserver, observers_, 232a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) ArticleEntriesUpdated(article_changes)); 233a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) } 234a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)} 235a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 236f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)void DomDistillerStore::ApplyChangesToModel(const SyncChangeList& changes, 237f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) SyncChangeList* changes_applied, 238f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) SyncChangeList* changes_missing) { 239a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) model_.ApplyChangesToModel(changes, changes_applied, changes_missing); 240a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) NotifyObservers(*changes_applied); 2414e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)} 2424e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 2434e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)void DomDistillerStore::OnDatabaseInit(bool success) { 2444e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (!success) { 245a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) DVLOG(1) << "DOM Distiller database init failed."; 2464e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) database_.reset(); 2474e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) return; 2484e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } 2494e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) database_->LoadEntries(base::Bind(&DomDistillerStore::OnDatabaseLoad, 2504e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) weak_ptr_factory_.GetWeakPtr())); 2514e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)} 2524e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 2534e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)void DomDistillerStore::OnDatabaseLoad(bool success, 2544e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) scoped_ptr<EntryVector> entries) { 2554e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (!success) { 256a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) DVLOG(1) << "DOM Distiller database load failed."; 2574e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) database_.reset(); 2584e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) return; 2594e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } 2604e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) database_loaded_ = true; 2614e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 2624e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) SyncDataList data; 2634e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) for (EntryVector::iterator it = entries->begin(); it != entries->end(); 2644e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) ++it) { 2654e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) data.push_back(CreateLocalData(*it)); 2664e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } 2674e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) SyncChangeList changes_applied; 2684e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) SyncChangeList database_changes_needed; 2694e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) MergeDataWithModel(data, &changes_applied, &database_changes_needed); 2704e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) ApplyChangesToDatabase(database_changes_needed); 2714e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)} 2724e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 2734e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)void DomDistillerStore::OnDatabaseSave(bool success) { 2744e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (!success) { 275a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) DVLOG(1) << "DOM Distiller database save failed." 276a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) << " Disabling modifications and sync."; 2774e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) database_.reset(); 2784e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) database_loaded_ = false; 2794e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) StopSyncing(syncer::ARTICLES); 2804e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } 2814e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)} 2824e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 2834e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)bool DomDistillerStore::ApplyChangesToSync( 2844e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) const tracked_objects::Location& from_here, 2854e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) const SyncChangeList& change_list) { 2864e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (!sync_processor_) { 2874e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) return false; 2884e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } 2894e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (change_list.empty()) { 2904e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) return true; 2914e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } 2924e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 2934e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) SyncError error = sync_processor_->ProcessSyncChanges(from_here, change_list); 2944e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (error.IsSet()) { 2954e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) StopSyncing(syncer::ARTICLES); 2964e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) return false; 2974e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } 2984e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) return true; 2994e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)} 3004e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 3014e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)bool DomDistillerStore::ApplyChangesToDatabase( 3024e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) const SyncChangeList& change_list) { 3034e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (!database_loaded_) { 3044e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) return false; 3054e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } 3064e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (change_list.empty()) { 3074e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) return true; 3084e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } 309f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) scoped_ptr<ProtoDatabase<ArticleEntry>::KeyEntryVector> entries_to_save( 310f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) new ProtoDatabase<ArticleEntry>::KeyEntryVector()); 311f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) scoped_ptr<std::vector<std::string> > keys_to_remove( 312f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) new std::vector<std::string>()); 3134e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 3144e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) for (SyncChangeList::const_iterator it = change_list.begin(); 315f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) it != change_list.end(); ++it) { 316f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) if (it->change_type() == SyncChange::ACTION_DELETE) { 317f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) ArticleEntry entry = GetEntryFromChange(*it); 318f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) keys_to_remove->push_back(entry.entry_id()); 319f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) } else { 320f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) ArticleEntry entry = GetEntryFromChange(*it); 321f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) entries_to_save->push_back(std::make_pair(entry.entry_id(), entry)); 322f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) } 3234e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } 324f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) database_->UpdateEntries(entries_to_save.Pass(), keys_to_remove.Pass(), 325a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) base::Bind(&DomDistillerStore::OnDatabaseSave, 326a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) weak_ptr_factory_.GetWeakPtr())); 3274e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) return true; 3284e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)} 3294e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 3304e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)SyncMergeResult DomDistillerStore::MergeDataWithModel( 331f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) const SyncDataList& data, SyncChangeList* changes_applied, 3324e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) SyncChangeList* changes_missing) { 3334e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) DCHECK(changes_applied); 3344e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) DCHECK(changes_missing); 3354e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 3364e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) SyncMergeResult result(syncer::ARTICLES); 3371e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) result.set_num_items_before_association(model_.GetNumEntries()); 3384e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 3394e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) SyncChangeList changes_to_apply; 3401e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) model_.CalculateChangesForMerge(data, &changes_to_apply, changes_missing); 3411e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) SyncError error; 342a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) ApplyChangesToModel(changes_to_apply, changes_applied, changes_missing); 3434e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 3444e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) int num_added = 0; 3454e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) int num_modified = 0; 3464e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) for (SyncChangeList::const_iterator it = changes_applied->begin(); 347f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) it != changes_applied->end(); ++it) { 3484e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) DCHECK(it->IsValid()); 3494e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) switch (it->change_type()) { 3504e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) case SyncChange::ACTION_ADD: 3514e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) num_added++; 3524e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) break; 3534e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) case SyncChange::ACTION_UPDATE: 3544e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) num_modified++; 3554e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) break; 3564e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) default: 3574e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) NOTREACHED(); 3584e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } 3594e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } 3604e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) result.set_num_items_added(num_added); 3614e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) result.set_num_items_modified(num_modified); 3624e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) result.set_num_items_deleted(0); 3634e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 3644e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) result.set_pre_association_version(0); 3651e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) result.set_num_items_after_association(model_.GetNumEntries()); 3664e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) result.set_error(error); 3674e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 3684e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) return result; 3694e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)} 3704e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 3714e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)} // namespace dom_distiller 372