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

Unified Diff: components/dom_distiller/core/dom_distiller_store.cc

Issue 717793007: Add attachments support to DomDistillerStore (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 6 years, 1 month 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 side-by-side diff with in-line comments
Download patch
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..72e480f4127c8fba819d97586f816790faef942e 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()),
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,119 @@ 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,
+ const UpdateAttachmentsCallback& callback) {
+ 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,
+ const UpdateAttachmentsCallback& callback,
+ const syncer::AttachmentStore::Result& result) {
+ bool success = false;
+ switch (result) {
+ case syncer::AttachmentStore::UNSPECIFIED_ERROR:
+ break;
+ case syncer::AttachmentStore::SUCCESS:
+ success = true;
+ break;
+ }
+
+ if (success) {
+ 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);
+ }
+ }
+ base::MessageLoop::current()->PostTask(FROM_HERE,
+ base::Bind(callback, success));
+}
+
+void DomDistillerStore::GetAttachments(
+ const std::string& entry_id,
+ const GetAttachmentsCallback& callback) {
+ 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,
+ const GetAttachmentsCallback& callback,
+ const syncer::AttachmentStore::Result& result,
+ scoped_ptr<syncer::AttachmentMap> attachments,
+ scoped_ptr<syncer::AttachmentIdList> missing) {
+ bool success = false;
+ switch (result) {
+ case syncer::AttachmentStore::UNSPECIFIED_ERROR:
+ break;
+ case syncer::AttachmentStore::SUCCESS:
+ success = missing->empty();
pavely 2014/11/17 19:09:00 Minor comment: if result is SUCCESS then |missing|
cjhopman 2014/11/18 20:57:45 Done.
+ break;
+ }
+ scoped_ptr<ArticleAttachmentsData> attachments_data;
+ if (success) {
+ attachments_data = ArticleAttachmentsData::GetFromAttachmentMap(
+ attachments_proto, *attachments);
+ }
+ base::MessageLoop::current()->PostTask(
+ FROM_HERE,
+ base::Bind(callback, success, base::Passed(&attachments_data)));
+}
+
bool DomDistillerStore::AddEntry(const ArticleEntry& entry) {
return ChangeEntry(entry, SyncChange::ACTION_ADD);
}
@@ -74,6 +190,22 @@ bool DomDistillerStore::RemoveEntry(const ArticleEntry& entry) {
return ChangeEntry(entry, SyncChange::ACTION_DELETE);
}
+namespace {
+
+bool VerifyAttachmentsUnchanged(const ArticleEntry& entry,
+ const DomDistillerModel& model) {
+ ArticleEntry currentEntry;
+ model.GetEntryById(entry.entry_id(), &currentEntry);
+ DCHECK_EQ(currentEntry.has_attachments(), entry.has_attachments());
+ if (currentEntry.has_attachments()) {
+ DCHECK_EQ(currentEntry.attachments().SerializeAsString(),
+ entry.attachments().SerializeAsString());
+ }
+ return true;
+}
+
+} // namespace
+
bool DomDistillerStore::ChangeEntry(const ArticleEntry& entry,
SyncChange::SyncChangeType changeType) {
if (!database_loaded_) {
@@ -86,6 +218,7 @@ bool DomDistillerStore::ChangeEntry(const ArticleEntry& entry,
DVLOG(1) << "Already have entry with id " << entry.entry_id() << ".";
return false;
}
+ DCHECK(VerifyAttachmentsUnchanged(entry, model_));
} else if (changeType != SyncChange::ACTION_ADD) {
DVLOG(1) << "No entry with id " << entry.entry_id() << " found.";
return false;

Powered by Google App Engine
This is Rietveld 408576698