diff --git a/interfaces/feedstorage.h b/interfaces/feedstorage.h index 7367f775..1ab0fe2c 100644 --- a/interfaces/feedstorage.h +++ b/interfaces/feedstorage.h @@ -1,98 +1,94 @@ /* This file is part of Akregator. Copyright (C) 2005 Frank Osterfeld This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. As a special exception, permission is given to link this program with any edition of Qt, and distribute the resulting executable, without including the source code for Qt in the source distribution. */ #ifndef AKREGATOR_BACKEND_FEEDSTORAGE_H #define AKREGATOR_BACKEND_FEEDSTORAGE_H #include #include class QString; class QStringList; class QDateTime; namespace Akregator { namespace Backend { class Storage; class FeedStorage : public QObject //krazy:exclude=qobject { public: virtual int unread() const = 0; virtual void setUnread(int unread) = 0; virtual int totalCount() const = 0; virtual QDateTime lastFetch() const = 0; virtual void setLastFetch(const QDateTime &lastFetch) = 0; /** returns the guids of all articles in this storage. */ virtual QStringList articles() const = 0; - /** deletes all articles from the archive */ - virtual void clear() = 0; - virtual void article(const QString &guid, uint &hash, QString &title, int &status, QDateTime &pubDate) const = 0; virtual bool contains(const QString &guid) const = 0; virtual void addEntry(const QString &guid) = 0; virtual void deleteArticle(const QString &guid) = 0; virtual bool guidIsHash(const QString &guid) const = 0; virtual void setGuidIsHash(const QString &guid, bool isHash) = 0; virtual bool guidIsPermaLink(const QString &guid) const = 0; virtual void setGuidIsPermaLink(const QString &guid, bool isPermaLink) = 0; virtual uint hash(const QString &guid) const = 0; virtual void setHash(const QString &guid, uint hash) = 0; virtual void setDeleted(const QString &guid) = 0; virtual QString link(const QString &guid) const = 0; virtual void setLink(const QString &guid, const QString &link) = 0; virtual QDateTime pubDate(const QString &guid) const = 0; virtual void setPubDate(const QString &guid, const QDateTime &pubdate) = 0; virtual int status(const QString &guid) const = 0; virtual void setStatus(const QString &guid, int status) = 0; virtual QString title(const QString &guid) const = 0; virtual void setTitle(const QString &guid, const QString &title) = 0; virtual QString description(const QString &guid) const = 0; virtual void setDescription(const QString &guid, const QString &description) = 0; virtual QString content(const QString &guid) const = 0; virtual void setContent(const QString &guid, const QString &content) = 0; virtual void setEnclosure(const QString &guid, const QString &url, const QString &type, int length) = 0; virtual void removeEnclosure(const QString &guid) = 0; virtual void setAuthorName(const QString & /*guid*/, const QString &name) = 0; virtual void setAuthorUri(const QString & /*guid*/, const QString &uri) = 0; virtual void setAuthorEMail(const QString & /*guid*/, const QString &email) = 0; virtual QString authorName(const QString &guid) const = 0; virtual QString authorUri(const QString &guid) const = 0; virtual QString authorEMail(const QString &guid) const = 0; virtual void enclosure(const QString &guid, bool &hasEnclosure, QString &url, QString &type, int &length) const = 0; - virtual void close() = 0; virtual void commit() = 0; virtual void rollback() = 0; }; } // namespace Backend } // namespace Akregator #endif // AKREGATOR_BACKEND_FEEDSTORAGE_H diff --git a/interfaces/storage.h b/interfaces/storage.h index 5dde4c40..823d60f6 100644 --- a/interfaces/storage.h +++ b/interfaces/storage.h @@ -1,102 +1,99 @@ /* This file is part of Akregator. Copyright (C) 2005 Stanislav Karchebny This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. As a special exception, permission is given to link this program with any edition of Qt, and distribute the resulting executable, without including the source code for Qt in the source distribution. */ #ifndef AKREGATOR_BACKEND_STORAGE_H #define AKREGATOR_BACKEND_STORAGE_H #include "akregatorinterfaces_export.h" #include class QString; class QStringList; namespace Akregator { namespace Backend { class FeedStorage; /** \brief Storage is the main interface to the article archive. It creates and manages FeedStorage objects handling the article list for a feed. An archive implementation must implement Storage, FeedStorage and StorageFactory. See mk4storage for an example. */ class Storage : public QObject //krazy:exclude=qobject { public: virtual ~Storage() { } /** initializes the storage object with given parameters */ virtual void initialize(const QStringList ¶ms) = 0; /** * Open storage and prepare it for work. * @return true on success. */ virtual bool open(bool autoCommit = false) = 0; /** * Commit changes made in feeds and articles, making them persistent. * @return true on success. */ virtual bool commit() = 0; /** * Rollback changes made in feeds and articles, reverting to last committed values. * @returns true on success. */ virtual bool rollback() = 0; /** * Closes storage, freeing all allocated resources. Called from destructor, so you don't need to call it directly. * @return true on success. */ virtual void close() = 0; /** * @return Article archive for feed at given url. */ virtual FeedStorage *archiveFor(const QString &url) = 0; virtual const FeedStorage *archiveFor(const QString &url) const = 0; virtual bool autoCommit() const = 0; /** stores the feed list in the storage backend. This is a fallback for the case that the feeds.opml file gets corrupted @param opmlStr the feed list in OPML format */ virtual void storeFeedList(const QString &opmlStr) = 0; virtual QString restoreFeedList() const = 0; /** returns a list of all feeds (URLs) stored in this archive */ virtual QStringList feeds() const = 0; - - /** deletes all feed storages in this archive */ - virtual void clear() = 0; }; } // namespace Backend } // namespace Akregator #endif // AKREGATOR_BACKEND_STORAGE_H diff --git a/plugins/mk4storage/feedstoragemk4impl.cpp b/plugins/mk4storage/feedstoragemk4impl.cpp index bad1c81d..076b188b 100644 --- a/plugins/mk4storage/feedstoragemk4impl.cpp +++ b/plugins/mk4storage/feedstoragemk4impl.cpp @@ -1,557 +1,550 @@ /* This file is part of Akregator. Copyright (C) 2005 Frank Osterfeld This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. As a special exception, permission is given to link this program with any edition of Qt, and distribute the resulting executable, without including the source code for Qt in the source distribution. */ #include "feedstoragemk4impl.h" #include "storagemk4impl.h" #include #include #include #include #include #include #include #include #include #include namespace { static uint calcHash(const QString &str) { if (str.isNull()) { // handle null string as "", prevents crash return calcHash(QLatin1String("")); } const char *s = str.toLatin1(); uint hash = 5381; int c; while ((c = *s++)) { hash = ((hash << 5) + hash) + c; // hash*33 + c } return hash; } } namespace Akregator { namespace Backend { class FeedStorageMK4Impl::FeedStorageMK4ImplPrivate { public: FeedStorageMK4ImplPrivate() : modified(false) , pguid("guid") , ptitle("title") , pdescription("description") , pcontent("content") , plink("link") , pcommentsLink("commentsLink") , ptag("tag") , pEnclosureType("enclosureType") , pEnclosureUrl("enclosureUrl") , pcatTerm("catTerm") , pcatScheme("catScheme") , pcatName("catName") , pauthorName("authorName") , pauthorUri("authorUri") , pauthorEMail("authorEMail") , phash("hash") , pguidIsHash("guidIsHash") , pguidIsPermaLink("guidIsPermaLink") , pcomments("comments") , pstatus("status") , ppubDate("pubDate") , pHasEnclosure("hasEnclosure") , pEnclosureLength("enclosureLength") { } QString url; c4_Storage *storage; StorageMK4Impl *mainStorage; c4_View archiveView; bool autoCommit; bool modified; c4_StringProp pguid, ptitle, pdescription, pcontent, plink, pcommentsLink, ptag, pEnclosureType, pEnclosureUrl, pcatTerm, pcatScheme, pcatName, pauthorName, pauthorUri, pauthorEMail; c4_IntProp phash, pguidIsHash, pguidIsPermaLink, pcomments, pstatus, ppubDate, pHasEnclosure, pEnclosureLength; }; FeedStorageMK4Impl::FeedStorageMK4Impl(const QString &url, StorageMK4Impl *main) { d = new FeedStorageMK4ImplPrivate; d->autoCommit = main->autoCommit(); d->url = url; d->mainStorage = main; QString url2 = url; if (url.length() > 255) { url2 = url.left(200) + QString::number(::calcHash(url), 16); } qDebug() << url2; QString t = url2; QString t2 = url2; QString filePath = main->archivePath() + QLatin1Char('/') + t.replace(QLatin1Char('/'), QLatin1Char('_')).replace(QLatin1Char(':'), QLatin1Char('_')); d->storage = new c4_Storage(QString(filePath + QLatin1String(".mk4")).toLocal8Bit(), true); d->archiveView = d->storage->GetAs( "articles[guid:S,title:S,hash:I,guidIsHash:I,guidIsPermaLink:I,description:S,link:S,comments:I,commentsLink:S,status:I,pubDate:I,tags[tag:S],hasEnclosure:I,enclosureUrl:S,enclosureType:S,enclosureLength:I,categories[catTerm:S,catScheme:S,catName:S],authorName:S,content:S,authorUri:S,authorEMail:S]"); c4_View hash = d->storage->GetAs("archiveHash[_H:I,_R:I]"); d->archiveView = d->archiveView.Hash(hash, 1); // hash on guid } FeedStorageMK4Impl::~FeedStorageMK4Impl() { delete d->storage; delete d; d = 0; } void FeedStorageMK4Impl::markDirty() { if (!d->modified) { d->modified = true; // Tell this to mainStorage d->mainStorage->markDirty(); } } void FeedStorageMK4Impl::commit() { if (d->modified) { d->storage->Commit(); } d->modified = false; } void FeedStorageMK4Impl::rollback() { d->storage->Rollback(); } void FeedStorageMK4Impl::close() { if (d->autoCommit) { commit(); } } int FeedStorageMK4Impl::unread() const { return d->mainStorage->unreadFor(d->url); } void FeedStorageMK4Impl::setUnread(int unread) { d->mainStorage->setUnreadFor(d->url, unread); } int FeedStorageMK4Impl::totalCount() const { return d->mainStorage->totalCountFor(d->url); } void FeedStorageMK4Impl::setTotalCount(int total) { d->mainStorage->setTotalCountFor(d->url, total); } QDateTime FeedStorageMK4Impl::lastFetch() const { return d->mainStorage->lastFetchFor(d->url); } void FeedStorageMK4Impl::setLastFetch(const QDateTime &lastFetch) { d->mainStorage->setLastFetchFor(d->url, lastFetch); } QStringList FeedStorageMK4Impl::articles() const { QStringList list; int size = d->archiveView.GetSize(); list.reserve(size); for (int i = 0; i < size; ++i) { // fill with guids list += QString::fromLatin1(d->pguid(d->archiveView.GetAt(i))); } return list; } void FeedStorageMK4Impl::addEntry(const QString &guid) { c4_Row row; d->pguid(row) = guid.toLatin1(); if (!contains(guid)) { d->archiveView.Add(row); markDirty(); setTotalCount(totalCount() + 1); } } bool FeedStorageMK4Impl::contains(const QString &guid) const { return findArticle(guid) != -1; } int FeedStorageMK4Impl::findArticle(const QString &guid) const { c4_Row findrow; d->pguid(findrow) = guid.toLatin1(); return d->archiveView.Find(findrow); } void FeedStorageMK4Impl::deleteArticle(const QString &guid) { int findidx = findArticle(guid); if (findidx != -1) { setTotalCount(totalCount() - 1); d->archiveView.RemoveAt(findidx); markDirty(); } } bool FeedStorageMK4Impl::guidIsHash(const QString &guid) const { int findidx = findArticle(guid); return findidx != -1 ? d->pguidIsHash(d->archiveView.GetAt(findidx)) : false; } bool FeedStorageMK4Impl::guidIsPermaLink(const QString &guid) const { int findidx = findArticle(guid); return findidx != -1 ? d->pguidIsPermaLink(d->archiveView.GetAt(findidx)) : false; } uint FeedStorageMK4Impl::hash(const QString &guid) const { int findidx = findArticle(guid); return findidx != -1 ? d->phash(d->archiveView.GetAt(findidx)) : 0; } void FeedStorageMK4Impl::setDeleted(const QString &guid) { int findidx = findArticle(guid); if (findidx == -1) { return; } c4_Row row; row = d->archiveView.GetAt(findidx); d->pdescription(row) = ""; d->pcontent(row) = ""; d->ptitle(row) = ""; d->plink(row) = ""; d->pauthorName(row) = ""; d->pauthorUri(row) = ""; d->pauthorEMail(row) = ""; d->pcommentsLink(row) = ""; d->archiveView.SetAt(findidx, row); markDirty(); } QString FeedStorageMK4Impl::link(const QString &guid) const { int findidx = findArticle(guid); return findidx != -1 ? QString::fromLatin1(d->plink(d->archiveView.GetAt(findidx))) : QLatin1String(""); } QDateTime FeedStorageMK4Impl::pubDate(const QString &guid) const { int findidx = findArticle(guid); return findidx != -1 ? QDateTime::fromTime_t(d->ppubDate(d->archiveView.GetAt(findidx))) : QDateTime(); } int FeedStorageMK4Impl::status(const QString &guid) const { int findidx = findArticle(guid); return findidx != -1 ? d->pstatus(d->archiveView.GetAt(findidx)) : 0; } void FeedStorageMK4Impl::setStatus(const QString &guid, int status) { int findidx = findArticle(guid); if (findidx == -1) { return; } c4_Row row; row = d->archiveView.GetAt(findidx); d->pstatus(row) = status; d->archiveView.SetAt(findidx, row); markDirty(); } void FeedStorageMK4Impl::article(const QString &guid, uint &hash, QString &title, int &status, QDateTime &pubDate) const { int idx = findArticle(guid); if (idx != -1) { auto view = d->archiveView.GetAt(idx); hash = d->phash(view); title = QString::fromUtf8(d->ptitle(view)); status = d->pstatus(view); pubDate = QDateTime::fromTime_t(d->ppubDate(view)); } } QString FeedStorageMK4Impl::title(const QString &guid) const { int findidx = findArticle(guid); return findidx != -1 ? QString::fromUtf8(d->ptitle(d->archiveView.GetAt(findidx))) : QLatin1String(""); } QString FeedStorageMK4Impl::description(const QString &guid) const { int findidx = findArticle(guid); return findidx != -1 ? QString::fromUtf8(d->pdescription(d->archiveView.GetAt(findidx))) : QLatin1String(""); } QString FeedStorageMK4Impl::content(const QString &guid) const { int findidx = findArticle(guid); return findidx != -1 ? QString::fromUtf8(d->pcontent(d->archiveView.GetAt(findidx))) : QLatin1String(""); } void FeedStorageMK4Impl::setPubDate(const QString &guid, const QDateTime &pubdate) { int findidx = findArticle(guid); if (findidx == -1) { return; } c4_Row row; row = d->archiveView.GetAt(findidx); d->ppubDate(row) = pubdate.toTime_t(); d->archiveView.SetAt(findidx, row); markDirty(); } void FeedStorageMK4Impl::setGuidIsHash(const QString &guid, bool isHash) { int findidx = findArticle(guid); if (findidx == -1) { return; } c4_Row row; row = d->archiveView.GetAt(findidx); d->pguidIsHash(row) = isHash; d->archiveView.SetAt(findidx, row); markDirty(); } void FeedStorageMK4Impl::setLink(const QString &guid, const QString &link) { int findidx = findArticle(guid); if (findidx == -1) { return; } c4_Row row; row = d->archiveView.GetAt(findidx); d->plink(row) = !link.isEmpty() ? link.toLatin1() : ""; d->archiveView.SetAt(findidx, row); markDirty(); } void FeedStorageMK4Impl::setHash(const QString &guid, uint hash) { int findidx = findArticle(guid); if (findidx == -1) { return; } c4_Row row; row = d->archiveView.GetAt(findidx); d->phash(row) = hash; d->archiveView.SetAt(findidx, row); markDirty(); } void FeedStorageMK4Impl::setTitle(const QString &guid, const QString &title) { int findidx = findArticle(guid); if (findidx == -1) { return; } c4_Row row; row = d->archiveView.GetAt(findidx); d->ptitle(row) = !title.isEmpty() ? title.toUtf8().data() : ""; d->archiveView.SetAt(findidx, row); markDirty(); } void FeedStorageMK4Impl::setDescription(const QString &guid, const QString &description) { int findidx = findArticle(guid); if (findidx == -1) { return; } c4_Row row; row = d->archiveView.GetAt(findidx); d->pdescription(row) = !description.isEmpty() ? description.toUtf8().data() : ""; d->archiveView.SetAt(findidx, row); markDirty(); } void FeedStorageMK4Impl::setContent(const QString &guid, const QString &content) { int findidx = findArticle(guid); if (findidx == -1) { return; } c4_Row row; row = d->archiveView.GetAt(findidx); d->pcontent(row) = !content.isEmpty() ? content.toUtf8().data() : ""; d->archiveView.SetAt(findidx, row); markDirty(); } void FeedStorageMK4Impl::setAuthorName(const QString &guid, const QString &author) { int findidx = findArticle(guid); if (findidx == -1) { return; } c4_Row row; row = d->archiveView.GetAt(findidx); d->pauthorName(row) = !author.isEmpty() ? author.toUtf8().data() : ""; d->archiveView.SetAt(findidx, row); markDirty(); } void FeedStorageMK4Impl::setAuthorUri(const QString &guid, const QString &author) { int findidx = findArticle(guid); if (findidx == -1) { return; } c4_Row row; row = d->archiveView.GetAt(findidx); d->pauthorUri(row) = !author.isEmpty() ? author.toUtf8().data() : ""; d->archiveView.SetAt(findidx, row); markDirty(); } void FeedStorageMK4Impl::setAuthorEMail(const QString &guid, const QString &author) { int findidx = findArticle(guid); if (findidx == -1) { return; } c4_Row row; row = d->archiveView.GetAt(findidx); d->pauthorEMail(row) = !author.isEmpty() ? author.toUtf8().data() : ""; d->archiveView.SetAt(findidx, row); markDirty(); } QString FeedStorageMK4Impl::authorName(const QString &guid) const { int findidx = findArticle(guid); return findidx != -1 ? QString::fromUtf8(d->pauthorName(d->archiveView.GetAt(findidx))) : QString(); } QString FeedStorageMK4Impl::authorUri(const QString &guid) const { int findidx = findArticle(guid); return findidx != -1 ? QString::fromUtf8(d->pauthorUri(d->archiveView.GetAt(findidx))) : QString(); } QString FeedStorageMK4Impl::authorEMail(const QString &guid) const { int findidx = findArticle(guid); return findidx != -1 ? QString::fromUtf8(d->pauthorEMail(d->archiveView.GetAt(findidx))) : QString(); } void FeedStorageMK4Impl::setGuidIsPermaLink(const QString &guid, bool isPermaLink) { int findidx = findArticle(guid); if (findidx == -1) { return; } c4_Row row; row = d->archiveView.GetAt(findidx); d->pguidIsPermaLink(row) = isPermaLink; d->archiveView.SetAt(findidx, row); markDirty(); } void FeedStorageMK4Impl::setEnclosure(const QString &guid, const QString &url, const QString &type, int length) { int findidx = findArticle(guid); if (findidx == -1) { return; } c4_Row row; row = d->archiveView.GetAt(findidx); d->pHasEnclosure(row) = true; d->pEnclosureUrl(row) = !url.isEmpty() ? url.toUtf8().data() : ""; d->pEnclosureType(row) = !type.isEmpty() ? type.toUtf8().data() : ""; d->pEnclosureLength(row) = length; d->archiveView.SetAt(findidx, row); markDirty(); } void FeedStorageMK4Impl::removeEnclosure(const QString &guid) { int findidx = findArticle(guid); if (findidx == -1) { return; } c4_Row row; row = d->archiveView.GetAt(findidx); d->pHasEnclosure(row) = false; d->pEnclosureUrl(row) = ""; d->pEnclosureType(row) = ""; d->pEnclosureLength(row) = -1; d->archiveView.SetAt(findidx, row); markDirty(); } void FeedStorageMK4Impl::enclosure(const QString &guid, bool &hasEnclosure, QString &url, QString &type, int &length) const { int findidx = findArticle(guid); if (findidx == -1) { hasEnclosure = false; url.clear(); type.clear(); length = -1; return; } c4_Row row = d->archiveView.GetAt(findidx); hasEnclosure = d->pHasEnclosure(row); url = QLatin1String(d->pEnclosureUrl(row)); type = QLatin1String(d->pEnclosureType(row)); length = d->pEnclosureLength(row); } -void FeedStorageMK4Impl::clear() -{ - d->storage->RemoveAll(); - - setUnread(0); - markDirty(); -} } // namespace Backend } // namespace Akregator diff --git a/plugins/mk4storage/feedstoragemk4impl.h b/plugins/mk4storage/feedstoragemk4impl.h index be16d1aa..961ccca9 100644 --- a/plugins/mk4storage/feedstoragemk4impl.h +++ b/plugins/mk4storage/feedstoragemk4impl.h @@ -1,97 +1,95 @@ /* This file is part of Akregator. Copyright (C) 2005 Frank Osterfeld This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. As a special exception, permission is given to link this program with any edition of Qt, and distribute the resulting executable, without including the source code for Qt in the source distribution. */ #ifndef AKREGATOR_BACKEND_FEEDSTORAGEMK4IMPL_H #define AKREGATOR_BACKEND_FEEDSTORAGEMK4IMPL_H #include "feedstorage.h" namespace Akregator { namespace Backend { class StorageMK4Impl; class FeedStorageMK4Impl : public FeedStorage { public: FeedStorageMK4Impl(const QString &url, StorageMK4Impl *main); ~FeedStorageMK4Impl(); - void clear() override; - int unread() const override; void setUnread(int unread) override; int totalCount() const override; QDateTime lastFetch() const override; void setLastFetch(const QDateTime &lastFetch) override; QStringList articles() const override; void article(const QString &guid, uint &hash, QString &title, int &status, QDateTime &pubDate) const override; bool contains(const QString &guid) const override; void addEntry(const QString &guid) override; void deleteArticle(const QString &guid) override; bool guidIsHash(const QString &guid) const override; void setGuidIsHash(const QString &guid, bool isHash) override; bool guidIsPermaLink(const QString &guid) const override; void setGuidIsPermaLink(const QString &guid, bool isPermaLink) override; uint hash(const QString &guid) const override; void setHash(const QString &guid, uint hash) override; void setDeleted(const QString &guid) override; QString link(const QString &guid) const override; void setLink(const QString &guid, const QString &link) override; QDateTime pubDate(const QString &guid) const override; void setPubDate(const QString &guid, const QDateTime &pubdate) override; int status(const QString &guid) const override; void setStatus(const QString &guid, int status) override; QString title(const QString &guid) const override; void setTitle(const QString &guid, const QString &title) override; QString description(const QString &guid) const override; void setDescription(const QString &guid, const QString &description) override; QString content(const QString &guid) const override; void setContent(const QString &guid, const QString &content) override; void setEnclosure(const QString &guid, const QString &url, const QString &type, int length) override; void removeEnclosure(const QString &guid) override; void enclosure(const QString &guid, bool &hasEnclosure, QString &url, QString &type, int &length) const override; void setAuthorName(const QString &guid, const QString &name) override; void setAuthorUri(const QString &guid, const QString &uri) override; void setAuthorEMail(const QString &guid, const QString &email) override; QString authorName(const QString &guid) const override; QString authorUri(const QString &guid) const override; QString authorEMail(const QString &guid) const override; - void close() override; + void close(); void commit() override; void rollback() override; private: void markDirty(); /** finds article by guid, returns -1 if not in archive **/ int findArticle(const QString &guid) const; void setTotalCount(int total); class FeedStorageMK4ImplPrivate; FeedStorageMK4ImplPrivate *d; }; } // namespace Backend } // namespace Akregator #endif // AKREGATOR_BACKEND_FEEDSTORAGEMK4IMPL_H diff --git a/plugins/mk4storage/storagemk4impl.cpp b/plugins/mk4storage/storagemk4impl.cpp index 139aa644..08a74c22 100644 --- a/plugins/mk4storage/storagemk4impl.cpp +++ b/plugins/mk4storage/storagemk4impl.cpp @@ -1,345 +1,327 @@ /* This file is part of Akregator. Copyright (C) 2005 Stanislav Karchebny 2005 Frank Osterfeld This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. As a special exception, permission is given to link this program with any edition of Qt, and distribute the resulting executable, without including the source code for Qt in the source distribution. */ #include "storagemk4impl.h" #include "feedstoragemk4impl.h" #include #include #include #include #include #include #include #include #include class Akregator::Backend::StorageMK4Impl::StorageMK4ImplPrivate { public: StorageMK4ImplPrivate() : modified(false) , purl("url") , pFeedList("feedList") , punread("unread") , ptotalCount("totalCount") , plastFetch("lastFetch") { } c4_Storage *storage; Akregator::Backend::StorageMK4Impl *q; c4_View archiveView; bool autoCommit; bool modified; mutable QMap feeds; QStringList feedURLs; c4_StringProp purl, pFeedList; c4_IntProp punread, ptotalCount, plastFetch; QString archivePath; c4_Storage *feedListStorage; c4_View feedListView; Akregator::Backend::FeedStorageMK4Impl *createFeedStorage(const QString &url); }; Akregator::Backend::StorageMK4Impl::StorageMK4Impl() : d(new StorageMK4ImplPrivate) { d->q = this; setArchivePath(QString()); } Akregator::Backend::FeedStorageMK4Impl *Akregator::Backend::StorageMK4Impl::StorageMK4ImplPrivate::createFeedStorage(const QString &url) { if (!feeds.contains(url)) { Akregator::Backend::FeedStorageMK4Impl *fs = new Akregator::Backend::FeedStorageMK4Impl(url, q); feeds[url] = fs; c4_Row findrow; purl(findrow) = url.toLatin1(); int findidx = archiveView.Find(findrow); if (findidx == -1) { punread(findrow) = 0; ptotalCount(findrow) = 0; plastFetch(findrow) = 0; archiveView.Add(findrow); modified = true; } } return feeds[url]; } Akregator::Backend::FeedStorage *Akregator::Backend::StorageMK4Impl::archiveFor(const QString &url) { return d->createFeedStorage(url); } const Akregator::Backend::FeedStorage *Akregator::Backend::StorageMK4Impl::archiveFor(const QString &url) const { return d->createFeedStorage(url); } void Akregator::Backend::StorageMK4Impl::setArchivePath(const QString &archivePath) { if (archivePath.isNull()) { // if isNull, reset to default d->archivePath = defaultArchivePath(); } else { d->archivePath = archivePath; } } QString Akregator::Backend::StorageMK4Impl::archivePath() const { return d->archivePath; } QString Akregator::Backend::StorageMK4Impl::defaultArchivePath() { const QString ret = QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation) + QStringLiteral("/akregator/Archive"); QDir().mkpath(ret); return ret; } Akregator::Backend::StorageMK4Impl::~StorageMK4Impl() { close(); delete d; d = 0; } void Akregator::Backend::StorageMK4Impl::initialize(const QStringList &) { } bool Akregator::Backend::StorageMK4Impl::open(bool autoCommit) { QString filePath = d->archivePath + QLatin1String("/archiveindex.mk4"); d->storage = new c4_Storage(filePath.toLocal8Bit(), true); d->archiveView = d->storage->GetAs("archive[url:S,unread:I,totalCount:I,lastFetch:I]"); c4_View hash = d->storage->GetAs("archiveHash[_H:I,_R:I]"); d->archiveView = d->archiveView.Hash(hash, 1); // hash on url d->autoCommit = autoCommit; filePath = d->archivePath + QLatin1String("/feedlistbackup.mk4"); d->feedListStorage = new c4_Storage(filePath.toLocal8Bit(), true); d->feedListView = d->feedListStorage->GetAs("archive[feedList:S,tagSet:S]"); return true; } bool Akregator::Backend::StorageMK4Impl::autoCommit() const { return d->autoCommit; } void Akregator::Backend::StorageMK4Impl::close() { QMap::Iterator it; QMap::Iterator end(d->feeds.end()); for (it = d->feeds.begin(); it != end; ++it) { it.value()->close(); delete it.value(); } if (d->autoCommit) { d->storage->Commit(); } delete d->storage; d->storage = 0; d->feedListStorage->Commit(); delete d->feedListStorage; d->feedListStorage = 0; } bool Akregator::Backend::StorageMK4Impl::commit() { QMap::Iterator it; QMap::Iterator end(d->feeds.end()); for (it = d->feeds.begin(); it != end; ++it) { it.value()->commit(); } if (d->storage) { d->storage->Commit(); return true; } return false; } bool Akregator::Backend::StorageMK4Impl::rollback() { QMap::Iterator it; QMap::Iterator end(d->feeds.end()); for (it = d->feeds.begin(); it != end; ++it) { it.value()->rollback(); } if (d->storage) { d->storage->Rollback(); return true; } return false; } int Akregator::Backend::StorageMK4Impl::unreadFor(const QString &url) const { c4_Row findrow; d->purl(findrow) = url.toLatin1(); int findidx = d->archiveView.Find(findrow); return findidx != -1 ? d->punread(d->archiveView.GetAt(findidx)) : 0; } void Akregator::Backend::StorageMK4Impl::setUnreadFor(const QString &url, int unread) { c4_Row findrow; d->purl(findrow) = url.toLatin1(); int findidx = d->archiveView.Find(findrow); if (findidx == -1) { return; } findrow = d->archiveView.GetAt(findidx); d->punread(findrow) = unread; d->archiveView.SetAt(findidx, findrow); markDirty(); } int Akregator::Backend::StorageMK4Impl::totalCountFor(const QString &url) const { c4_Row findrow; d->purl(findrow) = url.toLatin1(); int findidx = d->archiveView.Find(findrow); return findidx != -1 ? d->ptotalCount(d->archiveView.GetAt(findidx)) : 0; } void Akregator::Backend::StorageMK4Impl::setTotalCountFor(const QString &url, int total) { c4_Row findrow; d->purl(findrow) = url.toLatin1(); int findidx = d->archiveView.Find(findrow); if (findidx == -1) { return; } findrow = d->archiveView.GetAt(findidx); d->ptotalCount(findrow) = total; d->archiveView.SetAt(findidx, findrow); markDirty(); } QDateTime Akregator::Backend::StorageMK4Impl::lastFetchFor(const QString &url) const { c4_Row findrow; d->purl(findrow) = url.toLatin1(); int findidx = d->archiveView.Find(findrow); return findidx != -1 ? QDateTime::fromTime_t(d->plastFetch(d->archiveView.GetAt(findidx))) : QDateTime(); } void Akregator::Backend::StorageMK4Impl::setLastFetchFor(const QString &url, const QDateTime &lastFetch) { c4_Row findrow; d->purl(findrow) = url.toLatin1(); int findidx = d->archiveView.Find(findrow); if (findidx == -1) { return; } findrow = d->archiveView.GetAt(findidx); d->plastFetch(findrow) = lastFetch.toTime_t(); d->archiveView.SetAt(findidx, findrow); markDirty(); } void Akregator::Backend::StorageMK4Impl::markDirty() { if (!d->modified) { d->modified = true; // commit changes after 3 seconds QTimer::singleShot(3000, this, &StorageMK4Impl::slotCommit); } } void Akregator::Backend::StorageMK4Impl::slotCommit() { if (d->modified) { commit(); } d->modified = false; } QStringList Akregator::Backend::StorageMK4Impl::feeds() const { // TODO: cache list QStringList list; int size = d->archiveView.GetSize(); for (int i = 0; i < size; ++i) { list += QString::fromLatin1(d->purl(d->archiveView.GetAt(i))); } // fill with urls return list; } -void Akregator::Backend::StorageMK4Impl::clear() -{ - QStringList feeds; - int size = d->archiveView.GetSize(); - for (int i = 0; i < size; ++i) { - feeds += QString::fromLatin1(d->purl(d->archiveView.GetAt(i))); - } - QStringList::ConstIterator end(feeds.constEnd()); - - for (QStringList::ConstIterator it = feeds.constBegin(); it != end; ++it) { - FeedStorage *fa = archiveFor(*it); - fa->clear(); - fa->commit(); - // FIXME: delete file (should be 0 in size now) - } - d->storage->RemoveAll(); -} - void Akregator::Backend::StorageMK4Impl::storeFeedList(const QString &opmlStr) { if (d->feedListView.GetSize() == 0) { c4_Row row; d->pFeedList(row) = !opmlStr.isEmpty() ? opmlStr.toUtf8().data() : ""; d->feedListView.Add(row); } else { c4_Row row = d->feedListView.GetAt(0); d->pFeedList(row) = !opmlStr.isEmpty() ? opmlStr.toUtf8().data() : ""; d->feedListView.SetAt(0, row); } markDirty(); } QString Akregator::Backend::StorageMK4Impl::restoreFeedList() const { if (d->feedListView.GetSize() == 0) { return QString(); } c4_Row row = d->feedListView.GetAt(0); return QString::fromUtf8(d->pFeedList(row)); } diff --git a/plugins/mk4storage/storagemk4impl.h b/plugins/mk4storage/storagemk4impl.h index 61416273..3e945fa6 100644 --- a/plugins/mk4storage/storagemk4impl.h +++ b/plugins/mk4storage/storagemk4impl.h @@ -1,119 +1,116 @@ /* This file is part of Akregator. Copyright (C) 2005 Stanislav Karchebny 2005 Frank Osterfeld This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. As a special exception, permission is given to link this program with any edition of Qt, and distribute the resulting executable, without including the source code for Qt in the source distribution. */ #ifndef STORAGEMK4IMPL_H #define STORAGEMK4IMPL_H #include "storage.h" namespace Akregator { namespace Backend { /** * Metakit implementation of Storage interface */ class StorageMK4Impl : public Storage { Q_OBJECT public: StorageMK4Impl(); StorageMK4Impl(const StorageMK4Impl &); StorageMK4Impl &operator =(const StorageMK4Impl &); ~StorageMK4Impl(); /** KGlobal::dirs()->saveLocation("data", "akregator")+"/Archive" */ static QString defaultArchivePath(); /** sets the directory where the metakit files will be stored. @param archivePath the path to the archive, or QString() to reset it to the default. */ void setArchivePath(const QString &archivePath); /** returns the path to the metakit archives */ QString archivePath() const; void initialize(const QStringList ¶ms) override; /** * Open storage and prepare it for work. * @return true on success. */ bool open(bool autoCommit = false) override; /** * Commit changes made in feeds and articles, making them persistent. * @return true on success. */ bool commit() override; /** * Rollback changes made in feeds and articles, reverting to last committed values. * @returns true on success. */ bool rollback() override; /** * Closes storage, freeing all allocated resources. Called from destructor, so you don't need to call it directly. * @return true on success. */ void close() override; /** * @return Article archive for feed at given url. */ FeedStorage *archiveFor(const QString &url) override; const FeedStorage *archiveFor(const QString &url) const override; bool autoCommit() const override; // API for FeedStorage to alter the feed index 'view' int unreadFor(const QString &url) const; void setUnreadFor(const QString &url, int unread); int totalCountFor(const QString &url) const; void setTotalCountFor(const QString &url, int total); QDateTime lastFetchFor(const QString &url) const; void setLastFetchFor(const QString &url, const QDateTime &lastFetch); QStringList feeds() const override; void storeFeedList(const QString &opmlStr) override; QString restoreFeedList() const override; - /** deletes all feed storages in this archive */ - void clear() override; - void markDirty(); protected Q_SLOTS: void slotCommit(); private: class StorageMK4ImplPrivate; StorageMK4ImplPrivate *d; }; } // namespace Backend } // namespace Akregator #endif // STORAGEMK4IMPL_H diff --git a/src/dummystorage/feedstoragedummyimpl.cpp b/src/dummystorage/feedstoragedummyimpl.cpp index 8bef5dc9..99158a48 100644 --- a/src/dummystorage/feedstoragedummyimpl.cpp +++ b/src/dummystorage/feedstoragedummyimpl.cpp @@ -1,376 +1,365 @@ /* This file is part of Akregator. Copyright (C) 2005 Frank Osterfeld This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. As a special exception, permission is given to link this program with any edition of Qt, and distribute the resulting executable, without including the source code for Qt in the source distribution. */ #include "feedstoragedummyimpl.h" #include "storagedummyimpl.h" #include #include #include #include #include #include #include namespace Akregator { namespace Backend { class FeedStorageDummyImpl::FeedStorageDummyImplPrivate { public: class Entry { public: Entry() : status(0) , pubDate() , hash(0) , guidIsHash(false) , guidIsPermaLink(false) { } StorageDummyImpl *mainStorage = nullptr; QString enclosureUrl; QString enclosureType; QString title; QString description; QString content; QString link; QString authorName; QString authorUri; QString authorEMail; int status; int enclosureLength; QDateTime pubDate; uint hash; bool guidIsHash = false; bool guidIsPermaLink = false; bool hasEnclosure = false; }; QHash entries; StorageDummyImpl *mainStorage; QString url; }; FeedStorageDummyImpl::FeedStorageDummyImpl(const QString &url, StorageDummyImpl *main) : d(new FeedStorageDummyImplPrivate) { d->url = url; d->mainStorage = main; } FeedStorageDummyImpl::~FeedStorageDummyImpl() { delete d; d = nullptr; } void FeedStorageDummyImpl::commit() { } void FeedStorageDummyImpl::rollback() { } -void FeedStorageDummyImpl::close() -{ -} - int FeedStorageDummyImpl::unread() const { return d->mainStorage->unreadFor(d->url); } void FeedStorageDummyImpl::setUnread(int unread) { d->mainStorage->setUnreadFor(d->url, unread); } int FeedStorageDummyImpl::totalCount() const { return d->mainStorage->totalCountFor(d->url); } void FeedStorageDummyImpl::setTotalCount(int total) { d->mainStorage->setTotalCountFor(d->url, total); } QDateTime FeedStorageDummyImpl::lastFetch() const { return d->mainStorage->lastFetchFor(d->url); } void FeedStorageDummyImpl::setLastFetch(const QDateTime &lastFetch) { d->mainStorage->setLastFetchFor(d->url, lastFetch); } QStringList FeedStorageDummyImpl::articles() const { return QStringList(d->entries.keys()); } void FeedStorageDummyImpl::addEntry(const QString &guid) { if (!d->entries.contains(guid)) { d->entries[guid] = FeedStorageDummyImplPrivate::Entry(); setTotalCount(totalCount() + 1); } } bool FeedStorageDummyImpl::contains(const QString &guid) const { return d->entries.contains(guid); } void FeedStorageDummyImpl::deleteArticle(const QString &guid) { if (!d->entries.contains(guid)) { return; } setDeleted(guid); d->entries.remove(guid); } bool FeedStorageDummyImpl::guidIsHash(const QString &guid) const { return contains(guid) ? d->entries[guid].guidIsHash : false; } bool FeedStorageDummyImpl::guidIsPermaLink(const QString &guid) const { return contains(guid) ? d->entries[guid].guidIsPermaLink : false; } uint FeedStorageDummyImpl::hash(const QString &guid) const { return contains(guid) ? d->entries[guid].hash : 0; } void FeedStorageDummyImpl::setDeleted(const QString &guid) { if (!contains(guid)) { return; } FeedStorageDummyImplPrivate::Entry entry = d->entries[guid]; entry.description.clear(); entry.content.clear(); entry.title.clear(); entry.link.clear(); } QString FeedStorageDummyImpl::link(const QString &guid) const { return contains(guid) ? d->entries[guid].link : QString(); } QDateTime FeedStorageDummyImpl::pubDate(const QString &guid) const { return contains(guid) ? d->entries[guid].pubDate : QDateTime(); } int FeedStorageDummyImpl::status(const QString &guid) const { return contains(guid) ? d->entries[guid].status : 0; } void FeedStorageDummyImpl::setStatus(const QString &guid, int status) { if (contains(guid)) { d->entries[guid].status = status; } } void FeedStorageDummyImpl::article(const QString &guid, uint &hash, QString &title, int &status, QDateTime &pubDate) const { if (contains(guid)) { auto &entry = d->entries[guid]; hash = entry.hash; title = entry.title; status = entry.status; pubDate = entry.pubDate; } } QString FeedStorageDummyImpl::title(const QString &guid) const { return contains(guid) ? d->entries[guid].title : QString(); } QString FeedStorageDummyImpl::description(const QString &guid) const { return contains(guid) ? d->entries[guid].description : QString(); } QString FeedStorageDummyImpl::content(const QString &guid) const { return contains(guid) ? d->entries[guid].content : QString(); } QString FeedStorageDummyImpl::authorName(const QString &guid) const { return contains(guid) ? d->entries[guid].authorName : QString(); } QString FeedStorageDummyImpl::authorUri(const QString &guid) const { return contains(guid) ? d->entries[guid].authorUri : QString(); } QString FeedStorageDummyImpl::authorEMail(const QString &guid) const { return contains(guid) ? d->entries[guid].authorEMail : QString(); } void FeedStorageDummyImpl::setPubDate(const QString &guid, const QDateTime &pubdate) { if (contains(guid)) { d->entries[guid].pubDate = pubdate; } } void FeedStorageDummyImpl::setGuidIsHash(const QString &guid, bool isHash) { if (contains(guid)) { d->entries[guid].guidIsHash = isHash; } } void FeedStorageDummyImpl::setLink(const QString &guid, const QString &link) { if (contains(guid)) { d->entries[guid].link = link; } } void FeedStorageDummyImpl::setHash(const QString &guid, uint hash) { if (contains(guid)) { d->entries[guid].hash = hash; } } void FeedStorageDummyImpl::setTitle(const QString &guid, const QString &title) { if (contains(guid)) { d->entries[guid].title = title; } } void FeedStorageDummyImpl::setDescription(const QString &guid, const QString &description) { if (contains(guid)) { d->entries[guid].description = description; } } void FeedStorageDummyImpl::setContent(const QString &guid, const QString &content) { if (contains(guid)) { d->entries[guid].content = content; } } void FeedStorageDummyImpl::setAuthorName(const QString &guid, const QString &author) { if (contains(guid)) { d->entries[guid].authorName = author; } } void FeedStorageDummyImpl::setAuthorUri(const QString &guid, const QString &author) { if (contains(guid)) { d->entries[guid].authorUri = author; } } void FeedStorageDummyImpl::setAuthorEMail(const QString &guid, const QString &author) { if (contains(guid)) { d->entries[guid].authorEMail = author; } } void FeedStorageDummyImpl::setGuidIsPermaLink(const QString &guid, bool isPermaLink) { if (contains(guid)) { d->entries[guid].guidIsPermaLink = isPermaLink; } } -void FeedStorageDummyImpl::clear() -{ - d->entries.clear(); - setUnread(0); - setTotalCount(0); -} - void FeedStorageDummyImpl::setEnclosure(const QString &guid, const QString &url, const QString &type, int length) { if (contains(guid)) { FeedStorageDummyImplPrivate::Entry entry = d->entries[guid]; entry.hasEnclosure = true; entry.enclosureUrl = url; entry.enclosureType = type; entry.enclosureLength = length; } } void FeedStorageDummyImpl::removeEnclosure(const QString &guid) { if (contains(guid)) { FeedStorageDummyImplPrivate::Entry entry = d->entries[guid]; entry.hasEnclosure = false; entry.enclosureUrl.clear(); entry.enclosureType.clear(); entry.enclosureLength = -1; } } void FeedStorageDummyImpl::enclosure(const QString &guid, bool &hasEnclosure, QString &url, QString &type, int &length) const { if (contains(guid)) { FeedStorageDummyImplPrivate::Entry entry = d->entries[guid]; hasEnclosure = entry.hasEnclosure; url = entry.enclosureUrl; type = entry.enclosureType; length = entry.enclosureLength; } else { hasEnclosure = false; url.clear(); type.clear(); length = -1; } } } // namespace Backend } // namespace Akregator diff --git a/src/dummystorage/feedstoragedummyimpl.h b/src/dummystorage/feedstoragedummyimpl.h index 56a10690..f55761e3 100644 --- a/src/dummystorage/feedstoragedummyimpl.h +++ b/src/dummystorage/feedstoragedummyimpl.h @@ -1,96 +1,94 @@ /* This file is part of Akregator. Copyright (C) 2005 Frank Osterfeld This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. As a special exception, permission is given to link this program with any edition of Qt, and distribute the resulting executable, without including the source code for Qt in the source distribution. */ #ifndef AKREGATOR_BACKEND_FEEDSTORAGEDUMMYIMPL_H #define AKREGATOR_BACKEND_FEEDSTORAGEDUMMYIMPL_H #include "feedstorage.h" #include namespace Akregator { namespace Backend { class StorageDummyImpl; class FeedStorageDummyImpl : public FeedStorage { public: FeedStorageDummyImpl(const QString &url, StorageDummyImpl *main); ~FeedStorageDummyImpl() override; - void clear() override; int unread() const override; void setUnread(int unread) override; int totalCount() const override; QDateTime lastFetch() const override; void setLastFetch(const QDateTime &lastFetch) override; QStringList articles() const override; void article(const QString &guid, uint &hash, QString &title, int &status, QDateTime &pubDate) const override; bool contains(const QString &guid) const override; void addEntry(const QString &guid) override; void deleteArticle(const QString &guid) override; bool guidIsHash(const QString &guid) const override; void setGuidIsHash(const QString &guid, bool isHash) override; bool guidIsPermaLink(const QString &guid) const override; void setGuidIsPermaLink(const QString &guid, bool isPermaLink) override; uint hash(const QString &guid) const override; void setHash(const QString &guid, uint hash) override; void setDeleted(const QString &guid) override; QString link(const QString &guid) const override; void setLink(const QString &guid, const QString &link) override; QDateTime pubDate(const QString &guid) const override; void setPubDate(const QString &guid, const QDateTime & pubdate) override; int status(const QString &guid) const override; void setStatus(const QString &guid, int status) override; QString title(const QString &guid) const override; void setTitle(const QString &guid, const QString &title) override; QString description(const QString &guid) const override; void setDescription(const QString &guid, const QString &description) override; QString content(const QString &guid) const override; void setContent(const QString &guid, const QString &content) override; void setEnclosure(const QString &guid, const QString &url, const QString &type, int length) override; void removeEnclosure(const QString &guid) override; void enclosure(const QString &guid, bool &hasEnclosure, QString &url, QString &type, int &length) const override; void setAuthorName(const QString &guid, const QString &authorName) override; void setAuthorUri(const QString &guid, const QString &authorUri) override; void setAuthorEMail(const QString &guid, const QString &authorEMail) override; QString authorName(const QString &guid) const override; QString authorUri(const QString &guid) const override; QString authorEMail(const QString &guid) const override; - void close() override; void commit() override; void rollback() override; private: /** finds article by guid, returns -1 if not in archive **/ int findArticle(const QString &guid) const; void setTotalCount(int total); class FeedStorageDummyImplPrivate; FeedStorageDummyImplPrivate *d; }; } // namespace Backend } // namespace Akregator #endif // AKREGATOR_FEEDSTORAGEDUMMYIMPL_H diff --git a/src/dummystorage/storagedummyimpl.cpp b/src/dummystorage/storagedummyimpl.cpp index cb4451a8..fe845708 100644 --- a/src/dummystorage/storagedummyimpl.cpp +++ b/src/dummystorage/storagedummyimpl.cpp @@ -1,190 +1,181 @@ /* This file is part of Akregator. Copyright 2005 Frank Osterfeld This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. As a special exception, permission is given to link this program with any edition of Qt, and distribute the resulting executable, without including the source code for Qt in the source distribution. */ #include "storagedummyimpl.h" #include "feedstoragedummyimpl.h" #include #include #include #include namespace Akregator { namespace Backend { class StorageDummyImpl::StorageDummyImplPrivate { public: class Entry { public: int unread; int totalCount; QDateTime lastFetch; FeedStorage *feedStorage; }; void addEntry(const QString &url, int unread, int totalCount, const QDateTime &lastFetch) { Entry entry; entry.unread = unread; entry.totalCount = totalCount; entry.lastFetch = lastFetch; entry.feedStorage = nullptr; feeds[url] = entry; } QString feedList; QHash feeds; }; StorageDummyImpl::StorageDummyImpl() : d(new StorageDummyImplPrivate) { } StorageDummyImpl::~StorageDummyImpl() { close(); delete d; d = nullptr; } void StorageDummyImpl::initialize(const QStringList &) { } bool StorageDummyImpl::open(bool /*autoCommit*/) { return true; } bool StorageDummyImpl::autoCommit() const { return false; } void StorageDummyImpl::close() { for (QHash::ConstIterator it = d->feeds.constBegin(); it != d->feeds.constEnd(); ++it) { - (*it).feedStorage->close(); delete(*it).feedStorage; } } bool StorageDummyImpl::commit() { return true; } bool StorageDummyImpl::rollback() { return true; } int StorageDummyImpl::unreadFor(const QString &url) const { return d->feeds.contains(url) ? d->feeds[url].unread : 0; } void StorageDummyImpl::setUnreadFor(const QString &url, int unread) { if (!d->feeds.contains(url)) { d->addEntry(url, unread, unread, QDateTime()); } else { d->feeds[url].unread = unread; } } int StorageDummyImpl::totalCountFor(const QString &url) const { return d->feeds.contains(url) ? d->feeds[url].totalCount : 0; } void StorageDummyImpl::setTotalCountFor(const QString &url, int total) { if (!d->feeds.contains(url)) { d->addEntry(url, 0, total, QDateTime()); } else { d->feeds[url].totalCount = total; } } QDateTime StorageDummyImpl::lastFetchFor(const QString &url) const { return d->feeds.contains(url) ? d->feeds[url].lastFetch : QDateTime(); } void StorageDummyImpl::setLastFetchFor(const QString &url, const QDateTime &lastFetch) { if (!d->feeds.contains(url)) { d->addEntry(url, 0, 0, lastFetch); } else { d->feeds[url].lastFetch = lastFetch; } } void StorageDummyImpl::slotCommit() { } FeedStorage *StorageDummyImpl::archiveFor(const QString &url) { if (!d->feeds.contains(url)) { d->feeds[url].feedStorage = new FeedStorageDummyImpl(url, this); } return d->feeds[url].feedStorage; } const FeedStorage *StorageDummyImpl::archiveFor(const QString &url) const { if (!d->feeds.contains(url)) { d->feeds[url].feedStorage = new FeedStorageDummyImpl(url, const_cast(this)); } return d->feeds[url].feedStorage; } QStringList StorageDummyImpl::feeds() const { return d->feeds.keys(); } -void StorageDummyImpl::clear() -{ - for (QHash::ConstIterator it = d->feeds.constBegin(); it != d->feeds.constEnd(); ++it) { - delete(*it).feedStorage; - } - d->feeds.clear(); -} - void StorageDummyImpl::storeFeedList(const QString &opmlStr) { d->feedList = opmlStr; } QString StorageDummyImpl::restoreFeedList() const { return d->feedList; } } // namespace Backend } // namespace Akregator diff --git a/src/dummystorage/storagedummyimpl.h b/src/dummystorage/storagedummyimpl.h index 2e10a1bf..46d6f690 100644 --- a/src/dummystorage/storagedummyimpl.h +++ b/src/dummystorage/storagedummyimpl.h @@ -1,102 +1,99 @@ /* This file is part of Akregator. Copyright (C) 2005 Stanislav Karchebny 2005 Frank Osterfeld This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. As a special exception, permission is given to link this program with any edition of Qt, and distribute the resulting executable, without including the source code for Qt in the source distribution. */ #ifndef AKREGATOR_STORAGEDUMMYIMPL_H #define AKREGATOR_STORAGEDUMMYIMPL_H #include "storage.h" namespace Akregator { namespace Backend { /** * Metakit implementation of Storage interface */ class StorageDummyImpl : public Storage { Q_OBJECT public: StorageDummyImpl(); StorageDummyImpl(const StorageDummyImpl &); StorageDummyImpl &operator =(const StorageDummyImpl &); ~StorageDummyImpl() override; void initialize(const QStringList ¶ms) override; /** * Open storage and prepare it for work. * @return true on success. */ bool open(bool autoCommit = false) override; /** * Commit changes made in feeds and articles, making them persistent. * @return true on success. */ bool commit() override; /** * Rollback changes made in feeds and articles, reverting to last committed values. * @returns true on success. */ bool rollback() override; /** * Closes storage, freeing all allocated resources. Called from destructor, so you don't need to call it directly. * @return true on success. */ void close() override; /** * @return Article archive for feed at given url. */ FeedStorage *archiveFor(const QString &url) override; const FeedStorage *archiveFor(const QString &url) const override; bool autoCommit() const override; QStringList feeds() const override; // Mimic the MK4 api for feedstorage to alter the 'main' storage int unreadFor(const QString &url) const; void setUnreadFor(const QString &url, int unread); int totalCountFor(const QString &url) const; void setTotalCountFor(const QString &url, int total); QDateTime lastFetchFor(const QString &url) const; void setLastFetchFor(const QString &url, const QDateTime &lastFetch); void storeFeedList(const QString &opmlStr) override; QString restoreFeedList() const override; - /** deletes all feed storages in this archive */ - void clear() override; - protected Q_SLOTS: void slotCommit(); private: class StorageDummyImplPrivate; StorageDummyImplPrivate *d; }; } // namespace Backend } // namespace Akregator #endif // AKREGATOR_STORAGEDUMMYIMPL_H