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;
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))
{
return 0;
}
- q.next();
- m_totalRowCount = q.value(0).toInt();
+ if (q.next())
+ m_totalRowCount = q.value(0).toInt();
+
+ q.finish();
return m_totalRowCount;
}
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;
}
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)
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);
// ------
-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);
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,
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;
}
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);
bool MyListAnimeNode::updated(Operation type)
{
- Q_UNUSED(type)
QSqlQuery q = MyList::instance()->database()->prepareOneShot(QString(
" %1 "
"WHERE a.aid = :aid").arg(baseQuery()));
if (!q.next())
return false;
+ if (type == InsertOperation)
+ m_totalRowCount = q.value(0).toInt();
+
AnimeData newData;
QSqlResultIterator it(q);
fillAnimeData(newData, it);
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), "
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);
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();
"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());
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;
}
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);
bool MyListEpisodeNode::updated(Operation type)
{
- Q_UNUSED(type)
QSqlQuery q = MyList::instance()->database()->prepareOneShot(QString(
" %1 "
"WHERE e.eid = :eid").arg(baseQuery()));
if (!q.next())
return false;
+ if (type == InsertOperation)
+ m_totalRowCount = q.value(0).toInt();
+
EpisodeData newData;
QSqlResultIterator it(q);
fillEpisodeData(newData, it);
{
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());
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);
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;
}
if (!q.next())
return false;
+ if (type == InsertOperation)
+ m_totalRowCount = q.value(0).toInt();
+
FileData newData;
QSqlResultIterator it(q);
fillFileData(newData, it);
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);
if (!q.next())
return false;
+ if (type == InsertOperation)
+ m_totalRowCount = q.value(0).toInt();
+
FileLocationData newData;
QSqlResultIterator it(q);
fillFileLocationData(newData, it);
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
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);
MoveType moveChild(MyListNode *child, Operation type);
protected:
- virtual QString totalRowCountSql() const;
-
NodeType m_type;
mutable int m_totalRowCount;
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;
static QString baseQuery();
static void fillAnimeData(AnimeData &data, SqlResultIteratorInterface &q);
-protected:
- QString totalRowCountSql() const;
-
private:
int watchedEpisodes() const;
AnimeData animeData;
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;
static QString baseQuery();
static void fillEpisodeData(EpisodeData &data, SqlResultIteratorInterface &query);
-protected:
- QString totalRowCountSql() const;
-
private:
EpisodeData episodeData;
};
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;
static QString baseQuery();
static void fillFileData(FileData &data, SqlResultIteratorInterface &query);
-protected:
- QString totalRowCountSql() const;
-
private:
FileData fileData;
};
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;
static QString baseQuery();
static void fillFileLocationData(FileLocationData &data, SqlResultIteratorInterface &query);
-protected:
- QString totalRowCountSql() const;
-
private:
FileLocationData fileLocationData;
};