Adding some attributes to tables. Rough. :(

This commit is contained in:
Martin Rotter 2015-12-03 10:29:25 +01:00
parent b61814db88
commit 057a5da197
13 changed files with 58 additions and 35 deletions

View File

@ -74,6 +74,8 @@ CREATE TABLE IF NOT EXISTS Messages (
contents TEXT,
is_pdeleted INTEGER(1) NOT NULL DEFAULT 0 CHECK (is_pdeleted >= 0 AND is_pdeleted <= 1),
enclosures TEXT,
account_id INTEGER NOT NULL,
FOREIGN KEY (feed) REFERENCES Feeds (id)
FOREIGN KEY (feed) REFERENCES Feeds (id),
FOREIGN KEY (account_id) REFERENCES Accounts (id)
);

View File

@ -69,6 +69,8 @@ CREATE TABLE IF NOT EXISTS Messages (
contents TEXT,
is_pdeleted INTEGER(1) NOT NULL DEFAULT 0 CHECK (is_pdeleted >= 0 AND is_pdeleted <= 1),
enclosures TEXT,
account_id INTEGER NOT NULL,
FOREIGN KEY (feed) REFERENCES Feeds (id)
FOREIGN KEY (feed) REFERENCES Feeds (id),
FOREIGN KEY (account_id) REFERENCES Accounts (id)
);

View File

@ -16,4 +16,8 @@ CREATE TABLE IF NOT EXISTS TtRssAccounts (
FOREIGN KEY (id) REFERENCES Accounts (id)
);
-- !
ALTER TABLE Messages
ADD COLUMN account_id INTEGER NOT NULL DEFAULT (1);
-- !
UPDATE Information SET inf_value = '4' WHERE inf_key = 'schema_version';

View File

@ -16,4 +16,7 @@ CREATE TABLE IF NOT EXISTS TtRssAccounts (
FOREIGN KEY (id) REFERENCES Accounts (id)
);
-- !
ALTER TABLE Messages
ADD COLUMN account_id INTEGER NOT NULL DEFAULT (1);
-- !
UPDATE Information SET inf_value = '4' WHERE inf_key = 'schema_version';

View File

@ -71,8 +71,6 @@ void MessagesModel::setupFonts() {
m_boldFont.setBold(true);
}
void MessagesModel::loadMessages(RootItem *item) {
m_selectedItem = item;
@ -159,7 +157,8 @@ void MessagesModel::setupHeaderData() {
/*: Tooltip for creation date of message.*/ tr("Created on") <<
/*: Tooltip for contents of message.*/ tr("Contents") <<
/*: Tooltip for "pdeleted" column in msg list.*/ tr("Permanently deleted") <<
/*: Tooltip for attachments of message.*/ tr("Attachments");
/*: Tooltip for attachments of message.*/ tr("Attachments") <<
/*: Tooltip for account ID of message.*/ tr("Account ID");
m_tooltipData << tr("Id of the message.") << tr("Is message read?") <<
tr("Is message deleted?") << tr("Is message important?") <<
@ -167,7 +166,7 @@ void MessagesModel::setupHeaderData() {
tr("Title of the message.") << tr("Url of the message.") <<
tr("Author of the message.") << tr("Creation date of the message.") <<
tr("Contents of the message.") << tr("Is message permanently deleted from recycle bin?") <<
tr("List of attachments.");
tr("List of attachments.") << tr("Account ID of message.");
}
Qt::ItemFlags MessagesModel::flags(const QModelIndex &index) const {

View File

@ -183,6 +183,7 @@
#define MSG_DB_CONTENTS_INDEX 9
#define MSG_DB_PDELETED_INDEX 10
#define MSG_DB_ENCLOSURES_INDEX 11
#define MSG_DB_ACCOUNT_ID_INDEX 12
// Indexes of columns as they are DEFINED IN THE TABLE for CATEGORIES.
#define CAT_DB_ID_INDEX 0

View File

@ -547,6 +547,7 @@ void MessagesView::adjustColumns() {
hideColumn(MSG_DB_CONTENTS_INDEX);
hideColumn(MSG_DB_PDELETED_INDEX);
hideColumn(MSG_DB_ENCLOSURES_INDEX);
hideColumn(MSG_DB_ACCOUNT_ID_INDEX);
qDebug("Adjusting column resize modes for MessagesView.");
}

View File

@ -205,7 +205,7 @@ QSqlDatabase DatabaseFactory::sqliteInitializeInMemoryDatabase() {
// Copy all stuff.
// WARNING: All tables belong here.
QStringList tables; tables << QSL("Information") << QSL("Categories") << QSL("Feeds") <<
QSL("FeedsData") << QSL("Messages") << QSL("Accounts") << QSL("TtRssAccounts");
QSL("Accounts") << QSL("TtRssAccounts") << QSL("Messages");
foreach (const QString &table, tables) {
copy_contents.exec(QString("INSERT INTO main.%1 SELECT * FROM storage.%1;").arg(table));
@ -471,8 +471,8 @@ void DatabaseFactory::sqliteSaveMemoryDatabase() {
// Copy all stuff.
// WARNING: All tables belong here.
QStringList tables; tables << QSL("Categories") << QSL("Feeds") << QSL("FeedsData") <<
QSL("Messages") << QSL("Accounts") << QSL("TtRssAccounts");
QStringList tables; tables << QSL("Information") << QSL("Categories") << QSL("Feeds") <<
QSL("Accounts") << QSL("TtRssAccounts") << QSL("Messages");
foreach (const QString &table, tables) {
copy_contents.exec(QString(QSL("DELETE FROM storage.%1;")).arg(table));

View File

@ -140,9 +140,12 @@ QList<Message> StandardFeed::undeletedMessages() const {
query_read_msg.setForwardOnly(true);
query_read_msg.prepare("SELECT title, url, author, date_created, contents "
"FROM Messages "
"WHERE is_deleted = 0 AND feed = :feed;");
"WHERE is_deleted = 0 AND feed = :feed AND account_id = :account_id;");
query_read_msg.bindValue(QSL(":feed"), id());
query_read_msg.bindValue(QSL(":account_id"), const_cast<StandardFeed*>(this)->serviceRoot()->accountId());
// FIXME: Fix those const functions, this is fucking ugly.
if (query_read_msg.exec()) {
while (query_read_msg.next()) {
@ -186,13 +189,15 @@ void StandardFeed::updateCounts(bool including_total_count) {
query_all.setForwardOnly(true);
if (including_total_count) {
if (query_all.exec(QString("SELECT count(*) FROM Messages WHERE feed = %1 AND is_deleted = 0;").arg(id())) && query_all.next()) {
if (query_all.exec(QString("SELECT count(*) FROM Messages WHERE feed = %1 AND is_deleted = 0 AND account_id = %2;").arg(QString::number(id()),
QString::number(const_cast<StandardFeed*>(this)->serviceRoot()->accountId()))) && query_all.next()) {
m_totalCount = query_all.value(0).toInt();
}
}
// Obtain count of unread messages.
if (query_all.exec(QString("SELECT count(*) FROM Messages WHERE feed = %1 AND is_deleted = 0 AND is_read = 0;").arg(id())) && query_all.next()) {
if (query_all.exec(QString("SELECT count(*) FROM Messages WHERE feed = %1 AND is_deleted = 0 AND is_read = 0 AND account_id = %2;").arg(QString::number(id()),
QString::number(const_cast<StandardFeed*>(this)->serviceRoot()->accountId()))) && query_all.next()) {
int new_unread_count = query_all.value(0).toInt();
if (status() == NewMessages && new_unread_count < m_unreadCount) {
@ -514,8 +519,9 @@ bool StandardFeed::removeItself() {
query_remove.setForwardOnly(true);
// Remove all messages from this standard feed.
query_remove.prepare(QSL("DELETE FROM Messages WHERE feed = :feed;"));
query_remove.prepare(QSL("DELETE FROM Messages WHERE feed = :feed AND account_id = :account_id;"));
query_remove.bindValue(QSL(":feed"), id());
query_remove.bindValue(QSL(":account_id"), const_cast<StandardFeed*>(this)->serviceRoot()->accountId());
if (!query_remove.exec()) {
return false;
@ -638,6 +644,7 @@ int StandardFeed::updateMessages(const QList<Message> &messages) {
int updated_messages = 0;
QSqlDatabase database = qApp->database()->connection(metaObject()->className(), DatabaseFactory::FromSettings);
bool remove_duplicates = qApp->settings()->value(GROUP(Messages), SETTING(Messages::RemoveDuplicates)).toBool();
int account_id = serviceRoot()->accountId();
// Prepare queries.
QSqlQuery query_select(database);
@ -648,13 +655,13 @@ int StandardFeed::updateMessages(const QList<Message> &messages) {
// WARNING: One feed CANNOT contain two (or more) messages with same AUTHOR AND TITLE AND URL AND DATE_CREATED.
query_select.setForwardOnly(true);
query_select.prepare("SELECT id, feed, date_created FROM Messages "
"WHERE feed = :feed AND title = :title AND url = :url AND author = :author;");
"WHERE feed = :feed AND title = :title AND url = :url AND author = :author AND account_id = :account_id;");
// Used to insert new messages.
query_insert.setForwardOnly(true);
query_insert.prepare("INSERT INTO Messages "
"(feed, title, url, author, date_created, contents, enclosures) "
"VALUES (:feed, :title, :url, :author, :date_created, :contents, :enclosures);");
"(feed, title, url, author, date_created, contents, enclosures, account_id) "
"VALUES (:feed, :title, :url, :author, :date_created, :contents, :enclosures, :account_id);");
if (remove_duplicates) {
query_update.setForwardOnly(true);
@ -685,6 +692,7 @@ int StandardFeed::updateMessages(const QList<Message> &messages) {
query_select.bindValue(QSL(":title"), message.m_title);
query_select.bindValue(QSL(":url"), message.m_url);
query_select.bindValue(QSL(":author"), message.m_author);
query_select.bindValue(QSL(":account_id"), account_id);
query_select.exec();
QList<qint64> datetime_stamps;
@ -706,6 +714,7 @@ int StandardFeed::updateMessages(const QList<Message> &messages) {
query_insert.bindValue(QSL(":date_created"), message.m_created.toMSecsSinceEpoch());
query_insert.bindValue(QSL(":contents"), message.m_contents);
query_insert.bindValue(QSL(":enclosures"), Enclosures::encodeEnclosuresToString(message.m_enclosures));
query_insert.bindValue(QSL(":account_id"), account_id);
if (query_insert.exec() && query_insert.numRowsAffected() == 1) {
setStatus(NewMessages);
@ -790,5 +799,4 @@ StandardFeed::StandardFeed(const QSqlRecord &record) : Feed(NULL) {
setAutoUpdateType(static_cast<StandardFeed::AutoUpdateType>(record.value(FDS_DB_UPDATE_TYPE_INDEX).toInt()));
setAutoUpdateInitialInterval(record.value(FDS_DB_UPDATE_INTERVAL_INDEX).toInt());
updateCounts(true);
}

View File

@ -27,7 +27,6 @@
StandardRecycleBin::StandardRecycleBin(RootItem *parent)
: RecycleBin(parent) {
setId(ID_RECYCLE_BIN);
updateCounts(true);
}
StandardRecycleBin::~StandardRecycleBin() {
@ -63,7 +62,7 @@ void StandardRecycleBin::updateCounts(bool update_total_count) {
QSqlQuery query_all(database);
query_all.setForwardOnly(true);
if (query_all.exec(QSL("SELECT count(*) FROM Messages WHERE is_read = 0 AND is_deleted = 1 AND is_pdeleted = 0;")) && query_all.next()) {
if (query_all.exec(QString("SELECT count(*) FROM Messages WHERE is_read = 0 AND is_deleted = 1 AND is_pdeleted = 0 AND account_id = %1;").arg(serviceRoot()->accountId())) && query_all.next()) {
m_unreadCount = query_all.value(0).toInt();
}
else {
@ -71,7 +70,7 @@ void StandardRecycleBin::updateCounts(bool update_total_count) {
}
if (update_total_count) {
if (query_all.exec(QSL("SELECT count(*) FROM Messages WHERE is_deleted = 1 AND is_pdeleted = 0;")) && query_all.next()) {
if (query_all.exec(QString("SELECT count(*) FROM Messages WHERE is_deleted = 1 AND is_pdeleted = 0 AND account_id = %1;").arg(serviceRoot()->accountId())) && query_all.next()) {
m_totalCount = query_all.value(0).toInt();
}
else {

View File

@ -73,8 +73,9 @@ ServiceRoot *StandardServiceEntryPoint::createNewRoot() {
if (query.exec(QString("INSERT INTO Accounts (id, type) VALUES (%1, '%2');").arg(QString::number(id_to_assing),
SERVICE_CODE_STD_RSS))) {
StandardServiceRoot *root = new StandardServiceRoot(true);
StandardServiceRoot *root = new StandardServiceRoot();
root->setAccountId(id_to_assing);
root->loadFromDatabase();
return root;
}
else {
@ -90,8 +91,9 @@ QList<ServiceRoot*> StandardServiceEntryPoint::initializeSubtree() {
if (query.exec(QString("SELECT id FROM Accounts WHERE type = '%1';").arg(SERVICE_CODE_STD_RSS))) {
while (query.next()) {
StandardServiceRoot *root = new StandardServiceRoot(true);
StandardServiceRoot *root = new StandardServiceRoot();
root->setAccountId(query.value(0).toInt());
root->loadFromDatabase();
roots.append(root);
}
}

View File

@ -43,7 +43,7 @@
#include <QSqlTableModel>
StandardServiceRoot::StandardServiceRoot(bool load_from_db, RootItem *parent)
StandardServiceRoot::StandardServiceRoot(RootItem *parent)
: ServiceRoot(parent), m_recycleBin(new StandardRecycleBin(this)),
m_actionExportFeeds(NULL), m_actionImportFeeds(NULL), m_serviceMenu(QList<QAction*>()),
m_addItemMenu(QList<QAction*>()), m_feedContextMenu(QList<QAction*>()), m_actionFeedFetchMetadata(NULL) {
@ -52,10 +52,6 @@ StandardServiceRoot::StandardServiceRoot(bool load_from_db, RootItem *parent)
setIcon(StandardServiceEntryPoint().icon());
setDescription(tr("This is obligatory service account for standard RSS/RDF/ATOM feeds."));
setCreationDate(QDateTime::currentDateTime());
if (load_from_db) {
loadFromDatabase();
}
}
StandardServiceRoot::~StandardServiceRoot() {
@ -116,10 +112,12 @@ bool StandardServiceRoot::deleteViaGui() {
QSqlDatabase connection = qApp->database()->connection(metaObject()->className(), DatabaseFactory::FromSettings);
// Remove all messages.
if (!QSqlQuery(connection).exec(QSL("DELETE FROM Messages;"))) {
if (!QSqlQuery(connection).exec(QString("DELETE FROM Messages WHERE account_id = %1;").arg(accountId()))) {
return false;
}
// TODO: todo
// Remove all feeds.
if (!QSqlQuery(connection).exec(QSL("DELETE FROM Feeds;"))) {
return false;
@ -131,7 +129,7 @@ bool StandardServiceRoot::deleteViaGui() {
}
// Switch "existence" flag.
bool data_removed = QSqlQuery(connection).exec(QString("DELETE FROM Accounts WHERE id = %1;").arg(QString::number(id())));
bool data_removed = QSqlQuery(connection).exec(QString("DELETE FROM Accounts WHERE id = %1;").arg(accountId()));
if (data_removed) {
requestItemRemoval(this);
@ -223,7 +221,7 @@ bool StandardServiceRoot::markRecycleBinReadUnread(RootItem::ReadStatus read) {
QSqlQuery query_read_msg(db_handle);
query_read_msg.setForwardOnly(true);
if (!query_read_msg.prepare("UPDATE Messages SET is_read = :read WHERE is_deleted = 1;")) {
if (!query_read_msg.prepare("UPDATE Messages SET is_read = :read WHERE is_deleted = 1 AND account_id = :account_id;")) {
qWarning("Query preparation failed for recycle bin read change.");
db_handle.rollback();
@ -231,6 +229,7 @@ bool StandardServiceRoot::markRecycleBinReadUnread(RootItem::ReadStatus read) {
}
query_read_msg.bindValue(QSL(":read"), read == RootItem::Read ? 1 : 0);
query_read_msg.bindValue(QSL(":account_id"), accountId());
if (!query_read_msg.exec()) {
qDebug("Query execution for recycle bin read change failed.");
@ -305,7 +304,7 @@ bool StandardServiceRoot::restoreBin() {
QSqlQuery query_empty_bin(db_handle);
query_empty_bin.setForwardOnly(true);
if (!query_empty_bin.exec(QSL("UPDATE Messages SET is_deleted = 0 WHERE is_deleted = 1 AND is_pdeleted = 0;"))) {
if (!query_empty_bin.exec(QString("UPDATE Messages SET is_deleted = 0 WHERE is_deleted = 1 AND is_pdeleted = 0 AND account_id = %1;").arg(accountId()))) {
qWarning("Query execution failed for recycle bin restoring.");
db_handle.rollback();
@ -336,7 +335,7 @@ bool StandardServiceRoot::emptyBin() {
QSqlQuery query_empty_bin(db_handle);
query_empty_bin.setForwardOnly(true);
if (!query_empty_bin.exec(QSL("UPDATE Messages SET is_pdeleted = 1 WHERE is_deleted = 1;"))) {
if (!query_empty_bin.exec(QString("UPDATE Messages SET is_pdeleted = 1 WHERE is_deleted = 1 AND account_id = %1;").arg(accountId()))) {
qWarning("Query execution failed for recycle bin emptying.");
db_handle.rollback();
@ -415,6 +414,7 @@ void StandardServiceRoot::loadFromDatabase(){
// As the last item, add recycle bin, which is needed.
appendChild(m_recycleBin);
m_recycleBin->updateCounts(true);
}
QHash<int,StandardCategory*> StandardServiceRoot::categoriesForItem(RootItem *root) {
@ -468,10 +468,12 @@ void StandardServiceRoot::assembleFeeds(FeedAssignment feeds) {
if (feed.first == NO_PARENT_CATEGORY) {
// This is top-level feed, add it to the root item.
appendChild(feed.second);
feed.second->updateCounts(true);
}
else if (categories.contains(feed.first)) {
// This feed belongs to this category.
categories.value(feed.first)->appendChild(feed.second);
feed.second->updateCounts(true);
}
else {
qWarning("Feed '%s' is loose, skipping it.", qPrintable(feed.second->title()));

View File

@ -40,7 +40,7 @@ class StandardServiceRoot : public ServiceRoot {
Q_OBJECT
public:
explicit StandardServiceRoot(bool load_from_db, RootItem *parent = NULL);
explicit StandardServiceRoot(RootItem *parent = NULL);
virtual ~StandardServiceRoot();
// Start/stop root.
@ -104,6 +104,8 @@ class StandardServiceRoot : public ServiceRoot {
bool restoreBin();
bool emptyBin();
void loadFromDatabase();
public slots:
void addNewCategory();
void addNewFeed();
@ -115,8 +117,6 @@ class StandardServiceRoot : public ServiceRoot {
// which are suitable as IN clause for SQL queries.
QStringList textualFeedIds(const QList<Feed *> &feeds);
void loadFromDatabase();
// Takes lists of feeds/categories and assembles
// them into the tree structure.
void assembleCategories(CategoryAssignment categories);