diff options
Diffstat (limited to 'board.cpp')
-rw-r--r-- | board.cpp | 132 |
1 files changed, 120 insertions, 12 deletions
@@ -1,4 +1,5 @@ #include <QtCore/QDir> +#include <QtCore/QFileInfo> #include <QtCore/QDebug> #include <QtSql/QSqlQuery> #include <QtSql/QSqlError> @@ -55,6 +56,8 @@ Board::~Board() { disconnect(this, SLOT(handleActionFinished(Action*))); if (!_slug.isEmpty()) { + qDebug() << "Cleaning cache database"; + cleanDb(); QSqlDatabase::removeDatabase(_slug); } } @@ -257,12 +260,23 @@ void Board::notifyForumsChanged() emit forumsChanged(); } +void Board::notifyForumChanged(int forumId) +{ + emit forumChanged(forumId); +} + void Board::notifyForumTopicsChanged(int forumId, int start, int end) { qDebug() << "ForumTopics changed" << forumId << start << end; emit forumTopicsChanged(forumId, start, end); } +void Board::notifyForumTopicChanged(int forumId, int topicId) +{ + qDebug() << "ForumTopic changed" << forumId << topicId; + emit forumTopicChanged(forumId, topicId); +} + void Board::notifyTopicPostsChanged(int topicId, int start, int end) { qDebug() << "TopicPosts changed" << topicId << start << end; @@ -303,11 +317,29 @@ void Board::notifyLogout() } } -void Board::markPostAsRead(int postId) +void Board::markTopicAsRead(int topicId) { - _postsToMarkRead.insert(postId); - if (!_markReadDelay->isActive()) { - _markReadDelay->start(); + QSqlQuery q(_db); + q.prepare("UPDATE topics SET new_post = 0 WHERE topic_id = ? AND new_post = 1"); + q.bindValue(0, topicId); + if (q.exec()) { + if (q.numRowsAffected() > 0) { + q.prepare("SELECT forum_id FROM topics WHERE topic_id = ?"); + q.bindValue(0, topicId); + if (q.exec()) { + if (q.next()) { + int forum_id = q.value(0).toInt(); + notifyForumTopicChanged(forum_id, topicId); + updateForumReadState(forum_id); + } else { + qWarning() << "Could not get forum of topic"; + } + } else { + qWarning() << "Could not get forum of topic:" << q.lastError().text(); + } + } + } else { + qWarning() << "Could not mark topic as read:" << q.lastError().text(); } } @@ -337,6 +369,12 @@ QString Board::getTempDbPathFor(const QString& slug) return QDir::tempPath() + "/" + slug + ".sqlite"; } +int Board::dbSize() const +{ + QFileInfo info(getDbPathFor(_slug)); + return info.size(); +} + bool Board::checkCompatibleDb() { QString version = getConfig("tapasboard_db_version"); @@ -357,7 +395,7 @@ bool Board::initializeDb() return false; } - if (!q.exec("CREATE TABLE IF NOT EXISTS forums (forum_id INTEGER PRIMARY KEY, forum_name TEXT, description TEXT, parent_id INT, logo_url TEXT, new_post BOOL, is_protected BOOL, is_subscribed BOOL, can_subscribe BOOL, url TEXT, sub_only BOOL, sort_index INT)")) { + if (!q.exec("CREATE TABLE IF NOT EXISTS forums (forum_id INTEGER PRIMARY KEY, forum_name TEXT, description TEXT, parent_id INT, logo_url TEXT, new_post BOOL, is_protected BOOL, is_subscribed BOOL, can_subscribe BOOL, url TEXT, sub_only BOOL, position INT)")) { qWarning() << "Could not create forums table:" << q.lastError().text(); return false; } @@ -365,12 +403,12 @@ bool Board::initializeDb() qWarning() << "Could not create forums_parent index:" << q.lastError().text(); return false; } - if (!q.exec("CREATE UNIQUE INDEX IF NOT EXISTS forums_order ON forums (sort_index ASC)")) { + if (!q.exec("CREATE UNIQUE INDEX IF NOT EXISTS forums_order ON forums (position ASC)")) { qWarning() << "Could not create forums_order index:" << q.lastError().text(); return false; } - if (!q.exec("CREATE TABLE IF NOT EXISTS topics (forum_id INTEGER, topic_id INTEGER PRIMARY KEY, topic_title TEXT, topic_author_id INTEGER, topic_author_name TEXT, is_subscribed BOOL, is_closed BOOL, icon_url TEXT, last_reply_time TEXT, reply_number INT, new_post BOOL, last_update_time TEXT)")) { + if (!q.exec("CREATE TABLE IF NOT EXISTS topics (forum_id INTEGER, topic_id INTEGER PRIMARY KEY, topic_title TEXT, topic_author_id INTEGER, topic_author_name TEXT, is_subscribed BOOL, is_closed BOOL, icon_url TEXT, last_reply_time TEXT, reply_number INT, new_post BOOL, position INT, last_update_time TEXT)")) { qWarning() << "Could not create topics table:" << q.lastError().text(); return false; } @@ -382,8 +420,12 @@ bool Board::initializeDb() qWarning() << "Could not create topics_time index:" << q.lastError().text(); return false; } + if (!q.exec("CREATE INDEX IF NOT EXISTS topics_order ON topics (forum_id, position ASC)")) { + qWarning() << "Could not create topics_order index:" << q.lastError().text(); + return false; + } - if (!q.exec("CREATE TABLE IF NOT EXISTS posts (forum_id INTEGER, topic_id INTEGER, post_id INTEGER PRIMARY KEY, post_title TEXT, post_content TEXT, post_author_id INTEGER, post_author_name TEXT, can_edit BOOL, icon_url TEXT, post_time TEXT, last_update_time TEXT)")) { + if (!q.exec("CREATE TABLE IF NOT EXISTS posts (forum_id INTEGER, topic_id INTEGER, post_id INTEGER PRIMARY KEY, post_title TEXT, post_content TEXT, post_author_id INTEGER, post_author_name TEXT, can_edit BOOL, icon_url TEXT, post_time TEXT, position INT, last_update_time TEXT)")) { qWarning() << "Could not create posts table:" << q.lastError().text(); return false; } @@ -395,6 +437,10 @@ bool Board::initializeDb() qWarning() << "Could not create posts_time index:" << q.lastError().text(); return false; } + if (!q.exec("CREATE INDEX IF NOT EXISTS posts_order ON posts (topic_id, position ASC)")) { + qWarning() << "Could not create posts_order index:" << q.lastError().text(); + return false; + } return true; } @@ -430,11 +476,44 @@ bool Board::eraseDb() bool Board::cleanDb() { QSqlQuery q(_db); - // TODO: Delete old posts from cache - if (!q.exec("VACUUM")) { - qWarning() << "Could not vacuum database:" << q.lastError().text(); - return false; + + int total_rows = 0; + + q.prepare("DELETE FROM topics WHERE last_update_time < ?"); + q.bindValue(0, QDateTime::currentDateTime().addDays(-FORUM_TOPICS_CACHE)); + if (q.exec()) { + total_rows += q.numRowsAffected(); + } else { + qWarning() << "Could not clean old topics:" << q.lastError().text(); } + + + q.prepare("DELETE FROM posts WHERE last_update_time < ?"); + q.bindValue(0, QDateTime::currentDateTime().addDays(-TOPIC_POSTS_CACHE)); + if (q.exec()) { + total_rows += q.numRowsAffected(); + } else { + qWarning() << "Could not clean old posts:" << q.lastError().text(); + } + + if (q.exec("DELETE FROM topics WHERE forum_id NOT IN (SELECT forum_id FROM forums)")) { + total_rows += q.numRowsAffected(); + } else { + qWarning() << "Could not clean unreferenced topics:" << q.lastError().text(); + } + if (q.exec("DELETE FROM posts WHERE topic_id NOT IN (SELECT topic_id FROM topics)")) { + total_rows += q.numRowsAffected(); + } else { + qWarning() << "Could not clean unreferenced posts:" << q.lastError().text(); + } + + if (total_rows > 100) { + qDebug() << "Vacuuming database"; + if (q.exec("VACUUM")) { + qWarning() << "Could not vacuum database:" << q.lastError().text(); + } + } + return true; } @@ -445,6 +524,7 @@ bool Board::removeFromActionQueue(Action *action) if (_queue.removeOne(action)) { if (!_queue.isEmpty() && head != _queue.head()) { // The head action was removed; advance the queue. + qDebug() << "Now running" << _queue.head(); executeActionFromQueue(); } action->deleteLater(); @@ -552,6 +632,34 @@ void Board::fetchForumsIfOutdated() } } +void Board::updateForumReadState(int forumId) +{ + QSqlQuery q(_db); + + q.prepare("SELECT COUNT() FROM topics WHERE forum_id = ? AND new_post = 1"); + q.bindValue(0, forumId); + if (!q.exec()) { + qWarning() << "Could not select unread topics from forum:" << q.lastError().text(); + return; + } + int unread_topics = q.value(0).toInt(); + int new_post = (unread_topics > 0) ? 1 : 0; + + q.prepare("UPDATE forums SET new_post = :new_post WHERE forum_id = :forum_id AND new_post != :cur_new_post"); + q.bindValue(":new_post", new_post); + q.bindValue(":forum_id", forumId); + q.bindValue(":cur_new_post", new_post); + + if (!q.exec()) { + qWarning() << "Could not update forum read status:" << q.lastError().text(); + return; + } + + if (q.numRowsAffected() > 0) { + notifyForumChanged(forumId); + } +} + void Board::handleActionFinished(Action *action) { qDebug() << action << "finished"; |