/* 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 TQt, and distribute the resulting executable, without including the source code for TQt in the source distribution. */ #include "storagemk4impl.h" #include "feedstoragemk4impl.h" #include #include #include #include #include #include #include namespace Akregator { namespace Backend { class StorageMK4Impl::StorageMK4ImplPrivate { public: StorageMK4ImplPrivate() : modified(false), purl("url"), pFeedList("feedList"), pTagSet("tagSet"), punread("unread"), ptotalCount("totalCount"), plastFetch("lastFetch") {} c4_Storage* storage; c4_View archiveView; bool autoCommit; bool modified; TQMap feeds; TQStringList feedURLs; c4_StringProp purl, pFeedList, pTagSet; c4_IntProp punread, ptotalCount, plastFetch; TQString archivePath; bool taggingEnabled; c4_Storage* feedListStorage; c4_View feedListView; }; bool StorageMK4Impl::taggingEnabled() const { return d->taggingEnabled; } void StorageMK4Impl::setArchivePath(const TQString& archivePath) { if (archivePath.isNull()) // if isNull, reset to default d->archivePath = defaultArchivePath(); else d->archivePath = archivePath; } TQString StorageMK4Impl::archivePath() const { return d->archivePath; } StorageMK4Impl::StorageMK4Impl() : d(new StorageMK4ImplPrivate) { setArchivePath(TQString()); // set path to default } TQString StorageMK4Impl::defaultArchivePath() { return TDEGlobal::dirs()->saveLocation("data", "akregator")+"Archive"; } StorageMK4Impl::~StorageMK4Impl() { close(); delete d; d = 0; } void StorageMK4Impl::initialize(const TQStringList& params) { d->taggingEnabled = false; TQStringList::ConstIterator it = params.begin(); TQStringList::ConstIterator end = params.end(); for ( ; it != end; ++it) { TQStringList tokens = TQStringList::split("=", *it); if (tokens.count() == 2 && *(tokens.at(0)) == "taggingEnabled" && *(tokens.at(1)) == "true") { d->taggingEnabled = true; } } } bool StorageMK4Impl::open(bool autoCommit) { TQString filePath = d->archivePath +"/archiveindex.mk4"; d->storage = new c4_Storage(filePath.local8Bit(), 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 +"/feedlistbackup.mk4"; d->feedListStorage = new c4_Storage(filePath.local8Bit(), true); d->feedListView = d->feedListStorage->GetAs("archive[feedList:S,tagSet:S]"); return true; } bool StorageMK4Impl::autoCommit() const { return d->autoCommit; } bool StorageMK4Impl::close() { TQMap::Iterator it; TQMap::Iterator end(d->feeds.end() ) ; for (it = d->feeds.begin(); it != end; ++it) { it.data()->close(); delete it.data(); } if(d->autoCommit) d->storage->Commit(); delete d->storage; d->storage = 0; d->feedListStorage->Commit(); delete d->feedListStorage; d->feedListStorage = 0; return true; } bool StorageMK4Impl::commit() { TQMap::Iterator it; TQMap::Iterator end(d->feeds.end() ) ; for ( it = d->feeds.begin(); it != end; ++it ) it.data()->commit(); if(d->storage) { d->storage->Commit(); return true; } return false; } bool StorageMK4Impl::rollback() { TQMap::Iterator it; TQMap::Iterator end(d->feeds.end() ) ; for ( it = d->feeds.begin(); it != end; ++it ) it.data()->rollback(); if(d->storage) { d->storage->Rollback(); return true; } return false; } int StorageMK4Impl::unreadFor(const TQString &url) { c4_Row findrow; d->purl(findrow) = url.ascii(); int findidx = d->archiveView.Find(findrow); return findidx != -1 ? d->punread(d->archiveView.GetAt(findidx)) : 0; } void StorageMK4Impl::setUnreadFor(const TQString &url, int unread) { c4_Row findrow; d->purl(findrow) = url.ascii(); 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 StorageMK4Impl::totalCountFor(const TQString &url) { c4_Row findrow; d->purl(findrow) = url.ascii(); int findidx = d->archiveView.Find(findrow); return findidx != -1 ? d->ptotalCount(d->archiveView.GetAt(findidx)) : 0; } void StorageMK4Impl::setTotalCountFor(const TQString &url, int total) { c4_Row findrow; d->purl(findrow) = url.ascii(); 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(); } int StorageMK4Impl::lastFetchFor(const TQString& url) { c4_Row findrow; d->purl(findrow) = url.ascii(); int findidx = d->archiveView.Find(findrow); return (findidx != -1 ? d->plastFetch(d->archiveView.GetAt(findidx)) : 0); } void StorageMK4Impl::setLastFetchFor(const TQString& url, int lastFetch) { c4_Row findrow; d->purl(findrow) = url.ascii(); int findidx = d->archiveView.Find(findrow); if (findidx == -1) return; findrow = d->archiveView.GetAt(findidx); d->plastFetch(findrow) = lastFetch; d->archiveView.SetAt(findidx, findrow); markDirty(); } void StorageMK4Impl::markDirty() { if (!d->modified) { d->modified = true; // commit changes after 3 seconds TQTimer::singleShot(3000, this, TQT_SLOT(slotCommit())); } } void StorageMK4Impl::slotCommit() { if (d->modified) commit(); d->modified = false; } FeedStorage* StorageMK4Impl::archiveFor(const TQString& url) { if (!d->feeds.contains(url)) { FeedStorage* fs = new FeedStorageMK4Impl(url, this); d->feeds[url] = fs; c4_Row findrow; d->purl(findrow) = url.ascii(); int findidx = d->archiveView.Find(findrow); if (findidx == -1) { d->punread(findrow) = 0; d->ptotalCount(findrow) = 0; d->plastFetch(findrow) = 0; d->archiveView.Add(findrow); markDirty(); } fs->convertOldArchive(); } return d->feeds[url]; } TQStringList StorageMK4Impl::feeds() const { // TODO: cache list TQStringList list; int size = d->archiveView.GetSize(); for (int i = 0; i < size; i++) list += TQString(d->purl(d->archiveView.GetAt(i))); // fill with urls return list; } void StorageMK4Impl::add(Storage* source) { TQStringList feeds = source->feeds(); TQStringList::ConstIterator end(feeds.end() ) ; for (TQStringList::ConstIterator it = feeds.begin(); it != end; ++it) { FeedStorage* fa = archiveFor(*it); fa->add(source->archiveFor(*it)); } } void StorageMK4Impl::clear() { TQStringList feeds; int size = d->archiveView.GetSize(); for (int i = 0; i < size; i++) feeds += TQString(d->purl(d->archiveView.GetAt(i))); TQStringList::ConstIterator end(feeds.end() ) ; for (TQStringList::ConstIterator it = feeds.begin(); it != end; ++it) { FeedStorage* fa = archiveFor(*it); fa->clear(); fa->commit(); // FIXME: delete file (should be 0 in size now) } d->storage->RemoveAll(); } void StorageMK4Impl::storeFeedList(const TQString& opmlStr) { if (d->feedListView.GetSize() == 0) { c4_Row row; d->pFeedList(row) = !opmlStr.isEmpty() ? opmlStr.utf8().data() : ""; d->pTagSet(row) = ""; d->feedListView.Add(row); } else { c4_Row row = d->feedListView.GetAt(0); d->pFeedList(row) = !opmlStr.isEmpty() ? opmlStr.utf8().data() : ""; d->feedListView.SetAt(0, row); } markDirty(); } TQString StorageMK4Impl::restoreFeedList() const { if (d->feedListView.GetSize() == 0) return ""; c4_Row row = d->feedListView.GetAt(0); return TQString::fromUtf8(d->pFeedList(row)); } void StorageMK4Impl::storeTagSet(const TQString& xmlStr) { if (d->feedListView.GetSize() == 0) { c4_Row row; d->pTagSet(row) = !xmlStr.isEmpty() ? xmlStr.utf8().data() : ""; d->pFeedList(row) = ""; d->feedListView.Add(row); } else { c4_Row row = d->feedListView.GetAt(0); d->pTagSet(row) = !xmlStr.isEmpty() ? xmlStr.utf8().data() : ""; d->feedListView.SetAt(0, row); } markDirty(); } TQString StorageMK4Impl::restoreTagSet() const { if (d->feedListView.GetSize() == 0) return ""; c4_Row row = d->feedListView.GetAt(0); return TQString::fromUtf8(d->pTagSet(row)); } } // namespace Backend } // namespace Akregator #include "storagemk4impl.moc"