summaryrefslogtreecommitdiff
path: root/board.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'board.cpp')
-rw-r--r--board.cpp132
1 files changed, 120 insertions, 12 deletions
diff --git a/board.cpp b/board.cpp
index b3c5bcb..9a3d6cc 100644
--- a/board.cpp
+++ b/board.cpp
@@ -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";