Chromium Code Reviews| Index: components/dom_distiller/core/dom_distiller_store.cc |
| diff --git a/components/dom_distiller/core/dom_distiller_store.cc b/components/dom_distiller/core/dom_distiller_store.cc |
| index 8a3aad588139ad4f1082b11d26a44b5b27e287fd..f8be2132bef418ce479f5c55397c5fcbff958b2f 100644 |
| --- a/components/dom_distiller/core/dom_distiller_store.cc |
| +++ b/components/dom_distiller/core/dom_distiller_store.cc |
| @@ -6,6 +6,7 @@ |
| #include "base/bind.h" |
| #include "base/logging.h" |
| +#include "base/message_loop/message_loop.h" |
| #include "components/dom_distiller/core/article_entry.h" |
| #include "sync/api/sync_change.h" |
| #include "sync/protocol/article_specifics.pb.h" |
| @@ -29,6 +30,7 @@ DomDistillerStore::DomDistillerStore( |
| const base::FilePath& database_dir) |
| : database_(database.Pass()), |
| database_loaded_(false), |
| + attachment_store_(syncer::AttachmentStore::CreateInMemoryStore()), |
|
maniscalco
2014/11/12 18:59:44
Is the async construction requirement of the on di
cjhopman
2014/11/14 02:45:15
yes.
|
| weak_ptr_factory_(this) { |
| database_->Init(database_dir, base::Bind(&DomDistillerStore::OnDatabaseInit, |
| weak_ptr_factory_.GetWeakPtr())); |
| @@ -40,6 +42,7 @@ DomDistillerStore::DomDistillerStore( |
| const base::FilePath& database_dir) |
| : database_(database.Pass()), |
| database_loaded_(false), |
| + attachment_store_(syncer::AttachmentStore::CreateInMemoryStore()), |
| model_(initial_data), |
| weak_ptr_factory_(this) { |
| database_->Init(database_dir, base::Bind(&DomDistillerStore::OnDatabaseInit, |
| @@ -62,6 +65,102 @@ bool DomDistillerStore::GetEntryByUrl(const GURL& url, ArticleEntry* entry) { |
| return model_.GetEntryByUrl(url, entry); |
| } |
| +void DomDistillerStore::UpdateAttachments( |
| + const std::string& entry_id, |
| + scoped_ptr<ArticleAttachmentsData> attachments_data, |
| + UpdateAttachmentsCallback callback) { |
|
maniscalco
2014/11/12 18:59:44
Can be passed by const&.
cjhopman
2014/11/14 02:45:15
Done.
|
| + if (!GetEntryById(entry_id, nullptr)) { |
| + base::MessageLoop::current()->PostTask(FROM_HERE, |
| + base::Bind(callback, false)); |
| + } |
| + |
| + scoped_ptr<sync_pb::ArticleAttachments> article_attachments( |
| + new sync_pb::ArticleAttachments()); |
| + syncer::AttachmentList attachment_list; |
| + attachments_data->CreateSyncAttachments(&attachment_list, |
| + article_attachments.get()); |
| + |
| + attachment_store_->Write( |
| + attachment_list, |
| + base::Bind(&DomDistillerStore::OnAttachmentsWrite, |
| + weak_ptr_factory_.GetWeakPtr(), entry_id, |
| + base::Passed(&article_attachments), callback)); |
| +} |
| + |
| +void DomDistillerStore::OnAttachmentsWrite( |
| + const std::string& entry_id, |
| + scoped_ptr<sync_pb::ArticleAttachments> article_attachments, |
| + UpdateAttachmentsCallback callback, |
|
maniscalco
2014/11/12 18:59:43
Can be passed by const&.
cjhopman
2014/11/14 02:45:15
Done.
|
| + const syncer::AttachmentStore::Result& result) { |
| + bool success = result == syncer::AttachmentStore::SUCCESS; |
|
maniscalco
2014/11/12 18:59:43
WDYT about using a switch statement without a defa
cjhopman
2014/11/14 02:45:15
Done.
|
| + if (success) { |
|
maniscalco
2014/11/12 18:59:43
I'm thinking about cases where the write might fai
cjhopman
2014/11/14 02:45:15
Yeah, I could see us handling disk full differentl
|
| + ArticleEntry entry; |
| + bool has_entry = GetEntryById(entry_id, &entry); |
| + if (!has_entry) { |
| + success = false; |
| + attachment_store_->Drop(GetAttachmentIds(*article_attachments), |
| + syncer::AttachmentStore::DropCallback()); |
| + } else { |
| + if (entry.has_attachments()) { |
| + attachment_store_->Drop(GetAttachmentIds(entry.attachments()), |
| + syncer::AttachmentStore::DropCallback()); |
| + } |
| + entry.set_allocated_attachments(article_attachments.release()); |
| + |
| + SyncChangeList changes_to_apply; |
| + changes_to_apply.push_back(SyncChange( |
| + FROM_HERE, SyncChange::ACTION_UPDATE, CreateLocalData(entry))); |
| + |
| + SyncChangeList changes_applied; |
| + SyncChangeList changes_missing; |
| + |
| + ApplyChangesToModel(changes_to_apply, &changes_applied, &changes_missing); |
| + |
| + DCHECK_EQ(size_t(0), changes_missing.size()); |
| + DCHECK_EQ(size_t(1), changes_applied.size()); |
| + |
| + ApplyChangesToSync(FROM_HERE, changes_applied); |
| + ApplyChangesToDatabase(changes_applied); |
| + } |
| + } |
| + callback.Run(success); |
|
maniscalco
2014/11/12 18:59:44
Is it important that callback executes before cont
cjhopman
2014/11/14 02:45:15
Done.
|
| +} |
| + |
| +void DomDistillerStore::GetAttachments( |
| + const std::string& entry_id, |
| + GetAttachmentsCallback callback) { |
|
maniscalco
2014/11/12 18:59:44
Can be passed by const&.
cjhopman
2014/11/14 02:45:15
Done.
|
| + ArticleEntry entry; |
| + if (!model_.GetEntryById(entry_id, &entry) |
| + || !entry.has_attachments()) { |
| + base::MessageLoop::current()->PostTask( |
| + FROM_HERE, base::Bind(callback, false, nullptr)); |
| + return; |
| + } |
| + |
| + // TODO(cjhopman): This should use GetOrDownloadAttachments() once there is a |
| + // feasible way to use that. |
| + attachment_store_->Read(GetAttachmentIds(entry.attachments()), |
| + base::Bind(&DomDistillerStore::OnAttachmentsRead, |
| + weak_ptr_factory_.GetWeakPtr(), |
| + entry.attachments(), callback)); |
| +} |
| + |
| +void DomDistillerStore::OnAttachmentsRead( |
| + const sync_pb::ArticleAttachments& attachments_proto, |
| + GetAttachmentsCallback callback, |
|
maniscalco
2014/11/12 18:59:43
Can be passed by const&.
cjhopman
2014/11/14 02:45:15
Done.
|
| + const syncer::AttachmentStore::Result& result, |
| + scoped_ptr<syncer::AttachmentMap> attachments, |
| + scoped_ptr<syncer::AttachmentIdList> missing) { |
| + bool success = |
| + (result == syncer::AttachmentStore::SUCCESS) && missing->empty(); |
| + scoped_ptr<ArticleAttachmentsData> attachments_data; |
| + if (success) { |
| + attachments_data = ArticleAttachmentsData::GetFromAttachmentMap( |
| + attachments_proto, *attachments); |
| + } |
| + callback.Run(success, attachments_data.Pass()); |
| +} |
| + |
| bool DomDistillerStore::AddEntry(const ArticleEntry& entry) { |
| return ChangeEntry(entry, SyncChange::ACTION_ADD); |
| } |
| @@ -86,6 +185,15 @@ bool DomDistillerStore::ChangeEntry(const ArticleEntry& entry, |
| DVLOG(1) << "Already have entry with id " << entry.entry_id() << "."; |
| return false; |
| } |
| +#ifndef NDEBUG |
|
maniscalco
2014/11/12 18:59:44
WDYT about moving this code into function and call
cjhopman
2014/11/14 02:45:15
I think it's a great idea.
|
| + ArticleEntry currentEntry; |
| + model_.GetEntryById(entry.entry_id(), ¤tEntry); |
| + DCHECK_EQ(currentEntry.has_attachments(), entry.has_attachments()); |
| + if (currentEntry.has_attachments()) { |
| + DCHECK_EQ(currentEntry.attachments().SerializeAsString(), |
| + entry.attachments().SerializeAsString()); |
| + } |
| +#endif |
| } else if (changeType != SyncChange::ACTION_ADD) { |
| DVLOG(1) << "No entry with id " << entry.entry_id() << " found."; |
| return false; |