From: APTX Date: Tue, 9 Apr 2013 17:40:37 +0000 (+0200) Subject: Rewrite MyListNode to provide its children with their total row count. X-Git-Url: https://gitweb.aptx.org/?a=commitdiff_plain;h=03b041e6d233359987ba19955ead54e8e2740238;p=localmylist.git Rewrite MyListNode to provide its children with their total row count. This eliminates totalRowCountSql() queries that were executed for each child once. --- diff --git a/localmylist/mylistnode.cpp b/localmylist/mylistnode.cpp index 1673f59..7ba876f 100644 --- a/localmylist/mylistnode.cpp +++ b/localmylist/mylistnode.cpp @@ -10,8 +10,8 @@ namespace LocalMyList { -MyListNode::MyListNode(MyListModel *model_, NodeType type, MyListNode *parent) : - m_totalRowCount(-1), fetchedRowCount(0), m_working(false) +MyListNode::MyListNode(MyListModel *model_, NodeType type, int totalRowCount, MyListNode *parent) : + m_totalRowCount(totalRowCount), fetchedRowCount(0), m_working(false) { m_type = type; parentItem = parent; @@ -79,7 +79,12 @@ int MyListNode::totalRowCount() const return m_totalRowCount; } - QSqlQuery q = LocalMyList::instance()->database()->prepareOneShot(totalRowCountSql()); + // Other nodes should know their totalRowCount + if (m_type != RootNode) + return 0; + + QSqlQuery &q = LocalMyList::instance()->database()->prepare( + "SELECT COUNT(aid) FROM anime"); if (!LocalMyList::instance()->database()->exec(q)) { @@ -87,8 +92,10 @@ int MyListNode::totalRowCount() const return 0; } - q.next(); - m_totalRowCount = q.value(0).toInt(); + if (q.next()) + m_totalRowCount = q.value(0).toInt(); + + q.finish(); return m_totalRowCount; } @@ -119,8 +126,11 @@ void MyListNode::fetchComplete() while (query->next()) { AnimeData ad; + int totalRowCount = query->value(0).toInt(); + MyListAnimeNode::fillAnimeData(ad, *query); - auto node = new MyListAnimeNode(model, ad, this); + + auto node = new MyListAnimeNode(model, ad, totalRowCount, this); newItems << node; } @@ -153,11 +163,6 @@ void MyListNode::setWorking(bool working) m_working = working; } -QString MyListNode::totalRowCountSql() const -{ - return "SELECT COUNT(aid) FROM anime"; -} - void MyListNode::childUpdate(const EpisodeData &oldData, const EpisodeData &newData, Operation type) { Q_UNUSED(oldData) @@ -283,7 +288,7 @@ void MyListNode::childAdded(int id) if (m_totalRowCount == -1) return; - MyListAnimeNode *newChild = new MyListAnimeNode(model, AnimeData(id), this); + MyListAnimeNode *newChild = new MyListAnimeNode(model, AnimeData(id), -1, this); newChild->updated(InsertOperation); MoveType result = moveChild(newChild, InsertOperation); @@ -300,8 +305,8 @@ bool MyListNode::updated(Operation type) // ------ -MyListAnimeNode::MyListAnimeNode(MyListModel *model, const AnimeData &data, MyListNode *parent) : - MyListNode(model, AnimeNode, parent), animeData(data) +MyListAnimeNode::MyListAnimeNode(MyListModel *model, const AnimeData &data, int totalRowCount, MyListNode *parent) : + MyListNode(model, AnimeNode, totalRowCount, parent), animeData(data) { animeData.node = this; model->animeSet.insert(animeData); @@ -352,11 +357,6 @@ QVariant MyListAnimeNode::data(int column, int role) const return QVariant(); } -QString MyListAnimeNode::totalRowCountSql() const -{ - return "SELECT COUNT(eid) FROM episode WHERE aid = " + QString::number(id()); -} - int MyListAnimeNode::watchedEpisodes() const { return qMax(animeData.data.totalEpisodeCount, @@ -385,8 +385,11 @@ void MyListAnimeNode::fetchComplete() while (query->next()) { EpisodeData ed; + int totalRowCount = query->value(0).toInt(); + MyListEpisodeNode::fillEpisodeData(ed, *query); - auto node = new MyListEpisodeNode(model, ed, this); + + auto node = new MyListEpisodeNode(model, ed, totalRowCount, this); newItems << node; } @@ -406,7 +409,7 @@ void MyListAnimeNode::childAdded(int id) if (m_totalRowCount == -1) return; - MyListEpisodeNode *newChild = new MyListEpisodeNode(model, EpisodeData(id), this); + MyListEpisodeNode *newChild = new MyListEpisodeNode(model, EpisodeData(id), -1, this); newChild->updated(InsertOperation); MoveType result = moveChild(newChild, InsertOperation); @@ -417,7 +420,6 @@ void MyListAnimeNode::childAdded(int id) bool MyListAnimeNode::updated(Operation type) { - Q_UNUSED(type) QSqlQuery q = MyList::instance()->database()->prepareOneShot(QString( " %1 " "WHERE a.aid = :aid").arg(baseQuery())); @@ -429,6 +431,9 @@ bool MyListAnimeNode::updated(Operation type) if (!q.next()) return false; + if (type == InsertOperation) + m_totalRowCount = q.value(0).toInt(); + AnimeData newData; QSqlResultIterator it(q); fillAnimeData(newData, it); @@ -478,7 +483,7 @@ const AnimeData &MyListAnimeNode::internalData() const QString MyListAnimeNode::baseQuery() { return QString( - "SELECT " + "SELECT (SELECT COUNT(eid) FROM episode WHERE aid = a.aid), " " (SELECT COUNT(e.eid) " " FROM episode e " " WHERE e.aid = a.aid), " @@ -494,15 +499,15 @@ QString MyListAnimeNode::baseQuery() void MyListAnimeNode::fillAnimeData(AnimeData &data, SqlResultIteratorInterface &query) { - data.episodesInMyList = query.value(0).toInt(); - data.watchedEpisodes = query.value(1).toInt(); - Database::readAnimeData(query, data.data, 2); + data.episodesInMyList = query.value(1).toInt(); + data.watchedEpisodes = query.value(2).toInt(); + Database::readAnimeData(query, data.data, 3); } // ---- -MyListEpisodeNode::MyListEpisodeNode(MyListModel *model, const EpisodeData &data, MyListNode *parent) : - MyListNode(model, EpisodeNode, parent), episodeData(data) +MyListEpisodeNode::MyListEpisodeNode(MyListModel *model, const EpisodeData &data, int totalRowCount, MyListNode *parent) : + MyListNode(model, EpisodeNode, totalRowCount, parent), episodeData(data) { episodeData.node = this; model->episodeSet.insert(episodeData); @@ -555,21 +560,6 @@ QVariant MyListEpisodeNode::data(int column, int role) const return QVariant(); } -QString MyListEpisodeNode::totalRowCountSql() const -{ - return QString( - "SELECT COUNT(fid) " - " FROM ( " - " SELECT fid " - " FROM file " - " WHERE eid = %1 " - " UNION " - " SELECT f.fid FROM file f " - " JOIN file_episode_rel fer ON (fer.fid = f.fid) " - " WHERE fer.eid = %1 " - " ) AS sq ").arg(id()); -} - void MyListEpisodeNode::fetchMore() { qDebug() << "fetching some more for eid" << id(); @@ -581,7 +571,7 @@ void MyListEpisodeNode::fetchMore() "SELECT %1 FROM file f " " JOIN file_episode_rel fer ON (fer.fid = f.fid) " " WHERE fer.eid = :eidb ") - .arg(Database::fileFields())); + .arg(MyListFileNode::baseQuery())); query->bindValue(":eida", id()); query->bindValue(":eidb", id()); @@ -593,9 +583,11 @@ void MyListEpisodeNode::fetchComplete() while (query->next()) { FileData fd; + int totalRowCount = query->value(0).toInt(); + MyListFileNode::fillFileData(fd, *query); - auto node = new MyListFileNode(model, fd, this); + auto node = new MyListFileNode(model, fd, totalRowCount, this); newItems << node; } @@ -614,7 +606,7 @@ void MyListEpisodeNode::childAdded(int id) if (m_totalRowCount == -1) return; - MyListFileNode *newChild = new MyListFileNode(model, FileData(id), this); + MyListFileNode *newChild = new MyListFileNode(model, FileData(id), -1, this); newChild->updated(InsertOperation); MoveType result = moveChild(newChild, InsertOperation); @@ -625,7 +617,6 @@ void MyListEpisodeNode::childAdded(int id) bool MyListEpisodeNode::updated(Operation type) { - Q_UNUSED(type) QSqlQuery q = MyList::instance()->database()->prepareOneShot(QString( " %1 " "WHERE e.eid = :eid").arg(baseQuery())); @@ -637,6 +628,9 @@ bool MyListEpisodeNode::updated(Operation type) if (!q.next()) return false; + if (type == InsertOperation) + m_totalRowCount = q.value(0).toInt(); + EpisodeData newData; QSqlResultIterator it(q); fillEpisodeData(newData, it); @@ -710,19 +704,29 @@ QString MyListEpisodeNode::baseQuery() { return QString( "SELECT " - " (SELECT MIN(my_watched) " - " FROM " - " (SELECT my_watched " - " FROM file " - " WHERE eid = e.eid " - " AND my_watched IS NOT NULL " - " UNION " - " SELECT f.my_watched " - " FROM file f " - " JOIN file_episode_rel fer ON (fer.fid = f.fid) " - " WHERE fer.eid = e.eid " - " AND my_watched IS NOT NULL) AS sq) AS my_watched, " - " et.ordering, %1 " + " (SELECT COUNT(fid) " + " FROM ( " + " SELECT fid " + " FROM file " + " WHERE eid = e.eid " + " UNION " + " SELECT f.fid FROM file f " + " JOIN file_episode_rel fer ON (fer.fid = f.fid) " + " WHERE fer.eid = e.eid " + " ) AS sq), " + " (SELECT MIN(my_watched) " + " FROM " + " (SELECT my_watched " + " FROM file " + " WHERE eid = e.eid " + " AND my_watched IS NOT NULL " + " UNION " + " SELECT f.my_watched " + " FROM file f " + " JOIN file_episode_rel fer ON (fer.fid = f.fid) " + " WHERE fer.eid = e.eid " + " AND my_watched IS NOT NULL) AS sq) AS my_watched, " + " et.ordering, %1 " " FROM episode e " " JOIN episode_type et ON (et.type = e.type)") .arg(Database::episodeFields()); @@ -730,15 +734,15 @@ QString MyListEpisodeNode::baseQuery() void MyListEpisodeNode::fillEpisodeData(EpisodeData &data, SqlResultIteratorInterface &query) { - data.watchedDate = query.value(0).toDateTime(); - data.episodeTypeOrdering = query.value(1).toInt(); - Database::readEpisodeData(query, data.data, 2); + data.watchedDate = query.value(1).toDateTime(); + data.episodeTypeOrdering = query.value(2).toInt(); + Database::readEpisodeData(query, data.data, 3); } // --------------- -MyListFileNode::MyListFileNode(MyListModel *model, const FileData &data, MyListNode *parent) : - MyListNode(model, FileNode, parent), fileData(data) +MyListFileNode::MyListFileNode(MyListModel *model, const FileData &data, int totalRowCount, MyListNode *parent) : + MyListNode(model, FileNode, totalRowCount, parent), fileData(data) { fileData.node = this; model->fileSet.insert(fileData); @@ -791,9 +795,11 @@ void MyListFileNode::fetchComplete() while (query->next()) { FileLocationData fld; + int totalRowCount = query->value(0).toInt(); + MyListFileLocationNode::fillFileLocationData(fld, *query); - auto node = new MyListFileLocationNode(model, fld, this); + auto node = new MyListFileLocationNode(model, fld, totalRowCount, this); newItems << node; } @@ -827,6 +833,9 @@ bool MyListFileNode::updated(Operation type) if (!q.next()) return false; + if (type == InsertOperation) + m_totalRowCount = q.value(0).toInt(); + FileData newData; QSqlResultIterator it(q); fillFileData(newData, it); @@ -857,23 +866,20 @@ const FileData &MyListFileNode::internalData() const QString MyListFileNode::baseQuery() { - return QString(); + return QString( + "(SELECT COUNT(location_id) FROM file_location WHERE fid = f.fid), %1") + .arg(Database::fileFields()); } void MyListFileNode::fillFileData(FileData &data, SqlResultIteratorInterface &query) { - Database::readFileData(query, data.data); -} - -QString MyListFileNode::totalRowCountSql() const -{ - return "SELECT COUNT(fid) FROM file_location WHERE fid = " + QString::number(id()); + Database::readFileData(query, data.data, 1); } // --------------- -MyListFileLocationNode::MyListFileLocationNode(MyListModel *model, const FileLocationData &data, MyListNode *parent) : - MyListNode(model, FileLocationNode, parent), fileLocationData(data) +MyListFileLocationNode::MyListFileLocationNode(MyListModel *model, const FileLocationData &data, int totalRowCount, MyListNode *parent) : + MyListNode(model, FileLocationNode, totalRowCount, parent), fileLocationData(data) { fileLocationData.node = this; model->fileLocationSet.insert(fileLocationData); @@ -937,6 +943,9 @@ bool MyListFileLocationNode::updated(Operation type) if (!q.next()) return false; + if (type == InsertOperation) + m_totalRowCount = q.value(0).toInt(); + FileLocationData newData; QSqlResultIterator it(q); fillFileLocationData(newData, it); @@ -958,20 +967,15 @@ const FileLocationData &MyListFileLocationNode::internalData() const QString MyListFileLocationNode::baseQuery() { return QString( - "SELECT h.name, %1 FROM file_location fl " + "SELECT 0, h.name, %1 FROM file_location fl " " JOIN host h ON (fl.host_id = h.host_id) ") .arg(Database::fileLocationFields()); } void MyListFileLocationNode::fillFileLocationData(FileLocationData &data, SqlResultIteratorInterface &query) { - data.hostName = query.value(0).toString(); - Database::readFileLocationData(query, data.data, 1); -} - -QString MyListFileLocationNode::totalRowCountSql() const -{ - return "SELECT 0"; + data.hostName = query.value(1).toString(); + Database::readFileLocationData(query, data.data, 2); } } // namespace LocalMyList diff --git a/localmylist/mylistnode.h b/localmylist/mylistnode.h index fdcbaa5..153805a 100644 --- a/localmylist/mylistnode.h +++ b/localmylist/mylistnode.h @@ -37,7 +37,7 @@ public: OutOfBoundsMove }; - MyListNode(MyListModel *model, NodeType type = RootNode, MyListNode *parent = 0); + MyListNode(MyListModel *model, NodeType type = RootNode, int totalRowCount = -1, MyListNode *parent = 0); virtual ~MyListNode(); MyListNode *child(int row); @@ -72,8 +72,6 @@ public: MoveType moveChild(MyListNode *child, Operation type); protected: - virtual QString totalRowCountSql() const; - NodeType m_type; mutable int m_totalRowCount; @@ -94,7 +92,7 @@ protected: class LOCALMYLISTSHARED_EXPORT MyListAnimeNode : public MyListNode { public: - MyListAnimeNode(MyListModel *model, const AnimeData &data, MyListNode *parent); + MyListAnimeNode(MyListModel *model, const AnimeData &data, int totalRowCount, MyListNode *parent); ~MyListAnimeNode(); QVariant data(int column, int role) const; @@ -112,9 +110,6 @@ public: static QString baseQuery(); static void fillAnimeData(AnimeData &data, SqlResultIteratorInterface &q); -protected: - QString totalRowCountSql() const; - private: int watchedEpisodes() const; AnimeData animeData; @@ -123,7 +118,7 @@ private: class LOCALMYLISTSHARED_EXPORT MyListEpisodeNode : public MyListNode { public: - MyListEpisodeNode(MyListModel *model, const EpisodeData &data, MyListNode *parent); + MyListEpisodeNode(MyListModel *model, const EpisodeData &data, int totalRowCount, MyListNode *parent); ~MyListEpisodeNode(); QVariant data(int column, int role) const; @@ -141,9 +136,6 @@ public: static QString baseQuery(); static void fillEpisodeData(EpisodeData &data, SqlResultIteratorInterface &query); -protected: - QString totalRowCountSql() const; - private: EpisodeData episodeData; }; @@ -151,7 +143,7 @@ private: class LOCALMYLISTSHARED_EXPORT MyListFileNode : public MyListNode { public: - MyListFileNode(MyListModel *model, const FileData &data, MyListNode *parent); + MyListFileNode(MyListModel *model, const FileData &data, int totalRowCount, MyListNode *parent); ~MyListFileNode(); QVariant data(int column, int role) const; @@ -168,9 +160,6 @@ public: static QString baseQuery(); static void fillFileData(FileData &data, SqlResultIteratorInterface &query); -protected: - QString totalRowCountSql() const; - private: FileData fileData; }; @@ -178,7 +167,7 @@ private: class LOCALMYLISTSHARED_EXPORT MyListFileLocationNode : public MyListNode { public: - MyListFileLocationNode(MyListModel *model, const FileLocationData &data, MyListNode *parent); + MyListFileLocationNode(MyListModel *model, const FileLocationData &data, int totalRowCount, MyListNode *parent); ~MyListFileLocationNode(); QVariant data(int column, int role) const; @@ -192,9 +181,6 @@ public: static QString baseQuery(); static void fillFileLocationData(FileLocationData &data, SqlResultIteratorInterface &query); -protected: - QString totalRowCountSql() const; - private: FileLocationData fileLocationData; };