]> Some of my projects - localmylist.git/commitdiff
Rewrite MyListNode to provide its children with their total row count.
authorAPTX <marek321@gmail.com>
Tue, 9 Apr 2013 17:40:37 +0000 (19:40 +0200)
committerAPTX <marek321@gmail.com>
Tue, 9 Apr 2013 17:40:37 +0000 (19:40 +0200)
This eliminates totalRowCountSql() queries that were executed for each child once.

localmylist/mylistnode.cpp
localmylist/mylistnode.h

index 1673f5964f97c91eb13bb0448e13987de0eeb19e..7ba876f8d456bc323e4769b0b98880e3873a3418 100644 (file)
@@ -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
index fdcbaa52a8924e8ddc04e8655915198b5cc45b61..153805ad24a55c14c42d9d72d6b07aefcbe9ca7f 100644 (file)
@@ -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;
 };