diff --git a/src/datamanager.cpp b/src/datamanager.cpp index 72777a3c..8a072765 100644 --- a/src/datamanager.cpp +++ b/src/datamanager.cpp @@ -147,51 +147,6 @@ Entry *DataManager::getEntry(const QString &id) const return m_entries[id]; } -Entry *DataManager::getEntry(const EpisodeModel::Type type, const int entry_index) const -{ - QSqlQuery entryQuery; - if (type == EpisodeModel::All || type == EpisodeModel::New || type == EpisodeModel::Unread || type == EpisodeModel::Downloading - || type == EpisodeModel::PartiallyDownloaded || type == EpisodeModel::Downloaded) { - if (type == EpisodeModel::New) { - entryQuery.prepare(QStringLiteral("SELECT id FROM Entries WHERE new=:new ORDER BY updated DESC LIMIT 1 OFFSET :index;")); - entryQuery.bindValue(QStringLiteral(":new"), true); - } else if (type == EpisodeModel::Unread) { - entryQuery.prepare(QStringLiteral("SELECT id FROM Entries WHERE read=:read ORDER BY updated DESC LIMIT 1 OFFSET :index;")); - entryQuery.bindValue(QStringLiteral(":read"), false); - } else if (type == EpisodeModel::All) { - entryQuery.prepare(QStringLiteral("SELECT id FROM Entries ORDER BY updated DESC LIMIT 1 OFFSET :index;")); - } else if (type == EpisodeModel::Downloading) { - entryQuery.prepare( - QStringLiteral("SELECT * FROM Enclosures INNER JOIN Entries ON Enclosures.id = Entries.id WHERE downloaded=:downloaded ORDER BY updated DESC " - "LIMIT 1 OFFSET :index;")); - entryQuery.bindValue(QStringLiteral(":downloaded"), Enclosure::statusToDb(Enclosure::Downloading)); - } else if (type == EpisodeModel::PartiallyDownloaded) { - entryQuery.prepare( - QStringLiteral("SELECT * FROM Enclosures INNER JOIN Entries ON Enclosures.id = Entries.id WHERE downloaded=:downloaded ORDER BY updated DESC " - "LIMIT 1 OFFSET :index;")); - entryQuery.bindValue(QStringLiteral(":downloaded"), Enclosure::statusToDb(Enclosure::PartiallyDownloaded)); - } else if (type == EpisodeModel::Downloaded) { - entryQuery.prepare( - QStringLiteral("SELECT * FROM Enclosures INNER JOIN Entries ON Enclosures.id = Entries.id WHERE downloaded=:downloaded ORDER BY updated DESC " - "LIMIT 1 OFFSET :index;")); - entryQuery.bindValue(QStringLiteral(":downloaded"), Enclosure::statusToDb(Enclosure::Downloaded)); - } else { - // this should not happen - qWarning() << "Cannot find entry type" << type << "in getEntry for entry index" << entry_index; - } - entryQuery.bindValue(QStringLiteral(":index"), entry_index); - Database::instance().execute(entryQuery); - if (!entryQuery.next()) { - qWarning() << "No element with index" << entry_index << "found"; - return nullptr; - } - QString id = entryQuery.value(QStringLiteral("id")).toString(); - return getEntry(id); - } - qWarning() << "Cannot find entry type" << type << "in getEntry for entry index" << entry_index; - return nullptr; -} - int DataManager::feedCount() const { return m_feedmap.count(); @@ -207,41 +162,6 @@ int DataManager::entryCount(const Feed *feed) const return m_entrymap[feed->url()].count(); } -int DataManager::entryCount(const EpisodeModel::Type type) const -{ - QSqlQuery query; - if (type == EpisodeModel::All || type == EpisodeModel::New || type == EpisodeModel::Unread || type == EpisodeModel::Downloading - || type == EpisodeModel::PartiallyDownloaded || type == EpisodeModel::Downloaded) { - if (type == EpisodeModel::New) { - query.prepare(QStringLiteral("SELECT COUNT (id) FROM Entries WHERE new=:new;")); - query.bindValue(QStringLiteral(":new"), true); - } else if (type == EpisodeModel::Unread) { - query.prepare(QStringLiteral("SELECT COUNT (id) FROM Entries WHERE read=:read;")); - query.bindValue(QStringLiteral(":read"), false); - } else if (type == EpisodeModel::All) { - query.prepare(QStringLiteral("SELECT COUNT (id) FROM Entries;")); - } else if (type == EpisodeModel::Downloading) { - query.prepare(QStringLiteral("SELECT COUNT (id) FROM Enclosures WHERE downloaded=:downloaded;")); - query.bindValue(QStringLiteral(":downloaded"), Enclosure::statusToDb(Enclosure::Downloading)); - } else if (type == EpisodeModel::PartiallyDownloaded) { - query.prepare(QStringLiteral("SELECT COUNT (id) FROM Enclosures WHERE downloaded=:downloaded;")); - query.bindValue(QStringLiteral(":downloaded"), Enclosure::statusToDb(Enclosure::PartiallyDownloaded)); - } else if (type == EpisodeModel::Downloaded) { - query.prepare(QStringLiteral("SELECT COUNT (id) FROM Enclosures WHERE downloaded=:downloaded;")); - query.bindValue(QStringLiteral(":downloaded"), Enclosure::statusToDb(Enclosure::Downloaded)); - } else { - // this should not happen - qWarning() << "Cannot find entry type" << type << "in entryCount"; - } - Database::instance().execute(query); - if (!query.next()) - return -1; - return query.value(0).toInt(); - } - qWarning() << "Cannot find entry type" << type << "in entryCount"; - return -1; -} - int DataManager::unreadEntryCount(const Feed *feed) const { QSqlQuery query; diff --git a/src/datamanager.h b/src/datamanager.h index c424fd93..8503174a 100644 --- a/src/datamanager.h +++ b/src/datamanager.h @@ -31,12 +31,10 @@ public: Feed *getFeed(const QString &feedurl) const; Entry *getEntry(const int feed_index, const int entry_index) const; Entry *getEntry(const Feed *feed, const int entry_index) const; - Entry *getEntry(const EpisodeModel::Type type, const int entry_index) const; Q_INVOKABLE Entry *getEntry(const QString &id) const; int feedCount() const; int entryCount(const int feed_index) const; int entryCount(const Feed *feed) const; - int entryCount(const EpisodeModel::Type type) const; int unreadEntryCount(const Feed *feed) const; int newEntryCount(const Feed *feed) const; Q_INVOKABLE void addFeed(const QString &url); diff --git a/src/models/downloadmodel.cpp b/src/models/downloadmodel.cpp index 678324ef..cf34e3ce 100644 --- a/src/models/downloadmodel.cpp +++ b/src/models/downloadmodel.cpp @@ -7,16 +7,15 @@ #include "models/downloadmodel.h" #include "models/downloadmodellogging.h" +#include + +#include "database.h" #include "datamanager.h" -#include "episodemodel.h" DownloadModel::DownloadModel() : QAbstractListModel(nullptr) { - // initialize item counters - m_downloadingCount = DataManager::instance().entryCount(EpisodeModel::Downloading); - m_partiallyDownloadedCount = DataManager::instance().entryCount(EpisodeModel::PartiallyDownloaded); - m_downloadedCount = DataManager::instance().entryCount(EpisodeModel::Downloaded); + updateInternalState(); } QVariant DownloadModel::data(const QModelIndex &index, int role) const @@ -24,11 +23,11 @@ QVariant DownloadModel::data(const QModelIndex &index, int role) const if (role != 0) return QVariant(); if (index.row() < m_downloadingCount) { - return QVariant::fromValue(DataManager::instance().getEntry(EpisodeModel::Downloading, index.row())); + return QVariant::fromValue(DataManager::instance().getEntry(m_downloadingIds[index.row()])); } else if (index.row() < m_downloadingCount + m_partiallyDownloadedCount) { - return QVariant::fromValue(DataManager::instance().getEntry(EpisodeModel::PartiallyDownloaded, index.row() - m_downloadingCount)); + return QVariant::fromValue(DataManager::instance().getEntry(m_partiallyDownloadedIds[index.row() - m_downloadingCount])); } else if (index.row() < m_downloadingCount + m_partiallyDownloadedCount + m_downloadedCount) { - return QVariant::fromValue(DataManager::instance().getEntry(EpisodeModel::Downloaded, index.row() - m_downloadingCount - m_partiallyDownloadedCount)); + return QVariant::fromValue(DataManager::instance().getEntry(m_downloadedIds[index.row() - m_downloadingCount - m_partiallyDownloadedCount])); } else { qWarning() << "Trying to fetch DownloadModel item outside of valid range; this should never happen"; return QVariant(); @@ -52,10 +51,39 @@ int DownloadModel::rowCount(const QModelIndex &parent) const void DownloadModel::monitorDownloadStatus() { beginResetModel(); - - m_downloadingCount = DataManager::instance().entryCount(EpisodeModel::Downloading); - m_partiallyDownloadedCount = DataManager::instance().entryCount(EpisodeModel::PartiallyDownloaded); - m_downloadedCount = DataManager::instance().entryCount(EpisodeModel::Downloaded); - + updateInternalState(); endResetModel(); } + +void DownloadModel::updateInternalState() +{ + m_downloadingIds.clear(); + m_partiallyDownloadedIds.clear(); + m_downloadedIds.clear(); + + QSqlQuery query; + query.prepare( + QStringLiteral("SELECT * FROM Enclosures INNER JOIN Entries ON Enclosures.id = Entries.id WHERE downloaded=:downloaded ORDER BY updated DESC;")); + + query.bindValue(QStringLiteral(":downloaded"), Enclosure::statusToDb(Enclosure::Downloading)); + Database::instance().execute(query); + while (query.next()) { + m_downloadingIds += query.value(QStringLiteral("id")).toString(); + } + + query.bindValue(QStringLiteral(":downloaded"), Enclosure::statusToDb(Enclosure::PartiallyDownloaded)); + Database::instance().execute(query); + while (query.next()) { + m_partiallyDownloadedIds += query.value(QStringLiteral("id")).toString(); + } + + query.bindValue(QStringLiteral(":downloaded"), Enclosure::statusToDb(Enclosure::Downloaded)); + Database::instance().execute(query); + while (query.next()) { + m_downloadedIds += query.value(QStringLiteral("id")).toString(); + } + + m_downloadingCount = m_downloadingIds.count(); + m_partiallyDownloadedCount = m_partiallyDownloadedIds.count(); + m_downloadedCount = m_downloadedIds.count(); +} diff --git a/src/models/downloadmodel.h b/src/models/downloadmodel.h index 8dd121af..e73216e3 100644 --- a/src/models/downloadmodel.h +++ b/src/models/downloadmodel.h @@ -34,6 +34,13 @@ public Q_SLOTS: private: explicit DownloadModel(); + + void updateInternalState(); + + QStringList m_downloadingIds; + QStringList m_partiallyDownloadedIds; + QStringList m_downloadedIds; + int m_downloadingCount = 0; int m_partiallyDownloadedCount = 0; int m_downloadedCount = 0; diff --git a/src/models/episodemodel.cpp b/src/models/episodemodel.cpp index 0d2ef644..3b2da696 100644 --- a/src/models/episodemodel.cpp +++ b/src/models/episodemodel.cpp @@ -6,6 +6,9 @@ #include "models/episodemodel.h" +#include + +#include "database.h" #include "datamanager.h" #include "entry.h" @@ -18,15 +21,18 @@ EpisodeModel::EpisodeModel() connect(&DataManager::instance(), &DataManager::feedEntriesUpdated, this, [this](const QString &url) { Q_UNUSED(url) beginResetModel(); + updateInternalState(); endResetModel(); }); + + updateInternalState(); } QVariant EpisodeModel::data(const QModelIndex &index, int role) const { if (role != 0) return QVariant(); - return QVariant::fromValue(DataManager::instance().getEntry(m_type, index.row())); + return QVariant::fromValue(DataManager::instance().getEntry(m_entryIds[index.row()])); } QHash EpisodeModel::roleNames() const @@ -39,32 +45,16 @@ QHash EpisodeModel::roleNames() const int EpisodeModel::rowCount(const QModelIndex &parent) const { Q_UNUSED(parent) - return DataManager::instance().entryCount(m_type); + return m_entryIds.count(); } -EpisodeModel::Type EpisodeModel::type() const +void EpisodeModel::updateInternalState() { - return m_type; -} - -void EpisodeModel::setType(EpisodeModel::Type type) -{ - m_type = type; - if (m_type == EpisodeModel::New) { - connect(&DataManager::instance(), &DataManager::newEntryCountChanged, this, [this](const QString &url) { - Q_UNUSED(url) - // we have to reset the entire model in case entries are removed or added - // because we have no way of knowing where those entries will be added/removed - beginResetModel(); - endResetModel(); - }); - } else if (m_type == EpisodeModel::Unread) { - connect(&DataManager::instance(), &DataManager::unreadEntryCountChanged, this, [this](const QString &url) { - Q_UNUSED(url) - // we have to reset the entire model in case entries are removed or added - // because we have no way of knowing where those entries will be added/removed - beginResetModel(); - endResetModel(); - }); + m_entryIds.clear(); + QSqlQuery query; + query.prepare(QStringLiteral("SELECT id FROM Entries ORDER BY updated DESC;")); + Database::instance().execute(query); + while (query.next()) { + m_entryIds += query.value(QStringLiteral("id")).toString(); } } diff --git a/src/models/episodemodel.h b/src/models/episodemodel.h index 7852d613..24fe778a 100644 --- a/src/models/episodemodel.h +++ b/src/models/episodemodel.h @@ -16,28 +16,13 @@ class EpisodeModel : public QAbstractListModel Q_OBJECT public: - enum Type { - All, - New, - Unread, - Downloading, - Downloaded, - PartiallyDownloaded, - }; - Q_ENUM(Type) - - Q_PROPERTY(Type type READ type WRITE setType) - explicit EpisodeModel(); QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override; QHash roleNames() const override; int rowCount(const QModelIndex &parent) const override; - Type type() const; - -public Q_SLOTS: - void setType(Type type); - private: - Type m_type = Type::All; + void updateInternalState(); + + QStringList m_entryIds; };