X-Git-Url: https://git.quassel-irc.org/?p=quassel.git;a=blobdiff_plain;f=src%2Fcore%2Fsqlitestorage.cpp;h=5139d38791604b257cb5d312dde034e6c7b79039;hp=3457c1efdfe98c4edfbb8dbf071c2b6ff15f869d;hb=b9169a652a6854b3fa85aee8f833cb9e18a8d510;hpb=7fb88a023ef8e4658b39d22c2d88c0d8bd6709f8 diff --git a/src/core/sqlitestorage.cpp b/src/core/sqlitestorage.cpp index 3457c1ef..5139d387 100644 --- a/src/core/sqlitestorage.cpp +++ b/src/core/sqlitestorage.cpp @@ -1,5 +1,5 @@ /*************************************************************************** - * Copyright (C) 2005-2016 by the Quassel Project * + * Copyright (C) 2005-2018 by the Quassel Project * * devel@quassel-irc.org * * * * This program is free software; you can redistribute it and/or modify * @@ -46,12 +46,19 @@ bool SqliteStorage::isAvailable() const } +QString SqliteStorage::backendId() const +{ + return QString("SQLite"); +} + + QString SqliteStorage::displayName() const { + // Note: Pre-0.13 clients use the displayName property for backend idenfication // We identify the backend to use for the monolithic core by its displayname. // so only change this string if you _really_ have to and make sure the core // setup for the mono client still works ;) - return QString("SQLite"); + return backendId(); } @@ -1496,6 +1503,196 @@ QHash SqliteStorage::bufferMarkerLineMsgIds(UserId user) return markerLineHash; } +void SqliteStorage::setBufferActivity(UserId user, BufferId bufferId, Message::Types bufferActivity) +{ + QSqlDatabase db = logDb(); + db.transaction(); + + { + QSqlQuery query(db); + query.prepare(queryString("update_buffer_bufferactivity")); + query.bindValue(":userid", user.toInt()); + query.bindValue(":bufferid", bufferId.toInt()); + query.bindValue(":bufferactivity", (int) bufferActivity); + + lockForWrite(); + safeExec(query); + watchQuery(query); + } + db.commit(); + unlock(); +} + + +QHash SqliteStorage::bufferActivities(UserId user) +{ + QHash bufferActivityHash; + + QSqlDatabase db = logDb(); + db.transaction(); + + bool error = false; + { + QSqlQuery query(db); + query.prepare(queryString("select_buffer_bufferactivities")); + query.bindValue(":userid", user.toInt()); + + lockForRead(); + safeExec(query); + error = !watchQuery(query); + if (!error) { + while (query.next()) { + bufferActivityHash[query.value(0).toInt()] = Message::Types(query.value(1).toInt()); + } + } + } + + db.commit(); + unlock(); + return bufferActivityHash; +} + + +Message::Types SqliteStorage::bufferActivity(BufferId bufferId, MsgId lastSeenMsgId) +{ + QSqlDatabase db = logDb(); + db.transaction(); + + Message::Types result = Message::Types(0); + { + QSqlQuery query(db); + query.prepare(queryString("select_buffer_bufferactivity")); + query.bindValue(":bufferid", bufferId.toInt()); + query.bindValue(":lastseenmsgid", lastSeenMsgId.toInt()); + + lockForRead(); + safeExec(query); + if (query.first()) + result = Message::Types(query.value(0).toInt()); + } + + db.commit(); + unlock(); + return result; +} + +QHash SqliteStorage::bufferCiphers(UserId user, const NetworkId &networkId) +{ + QHash bufferCiphers; + + QSqlDatabase db = logDb(); + db.transaction(); + { + QSqlQuery query(db); + query.prepare(queryString("select_buffer_ciphers")); + query.bindValue(":userid", user.toInt()); + query.bindValue(":networkid", networkId.toInt()); + + lockForRead(); + safeExec(query); + watchQuery(query); + while (query.next()) { + bufferCiphers[query.value(0).toString()] = QByteArray::fromHex(query.value(1).toString().toUtf8()); + } + } + unlock(); + return bufferCiphers; +} + +void SqliteStorage::setBufferCipher(UserId user, const NetworkId &networkId, const QString &bufferName, const QByteArray &cipher) +{ + QSqlDatabase db = logDb(); + db.transaction(); + + { + QSqlQuery query(db); + query.prepare(queryString("update_buffer_cipher")); + query.bindValue(":userid", user.toInt()); + query.bindValue(":networkid", networkId.toInt()); + query.bindValue(":buffercname", bufferName.toLower()); + query.bindValue(":cipher", QString(cipher.toHex())); + + lockForWrite(); + safeExec(query); + watchQuery(query); + db.commit(); + } + unlock(); +} + +void SqliteStorage::setHighlightCount(UserId user, BufferId bufferId, int count) +{ + QSqlDatabase db = logDb(); + db.transaction(); + + { + QSqlQuery query(db); + query.prepare(queryString("update_buffer_highlightcount")); + query.bindValue(":userid", user.toInt()); + query.bindValue(":bufferid", bufferId.toInt()); + query.bindValue(":highlightcount", count); + + lockForWrite(); + safeExec(query); + watchQuery(query); + } + db.commit(); + unlock(); +} + + +QHash SqliteStorage::highlightCounts(UserId user) +{ + QHash highlightCountHash; + + QSqlDatabase db = logDb(); + db.transaction(); + + bool error = false; + { + QSqlQuery query(db); + query.prepare(queryString("select_buffer_highlightcounts")); + query.bindValue(":userid", user.toInt()); + + lockForRead(); + safeExec(query); + error = !watchQuery(query); + if (!error) { + while (query.next()) { + highlightCountHash[query.value(0).toInt()] = query.value(1).toInt(); + } + } + } + + db.commit(); + unlock(); + return highlightCountHash; +} + + +int SqliteStorage::highlightCount(BufferId bufferId, MsgId lastSeenMsgId) +{ + QSqlDatabase db = logDb(); + db.transaction(); + + int result = 0; + { + QSqlQuery query(db); + query.prepare(queryString("select_buffer_highlightcount")); + query.bindValue(":bufferid", bufferId.toInt()); + query.bindValue(":lastseenmsgid", lastSeenMsgId.toInt()); + + lockForRead(); + safeExec(query); + if (query.first()) + result = query.value(0).toInt(); + } + + db.commit(); + unlock(); + return result; +} + bool SqliteStorage::logMessage(Message &msg) { QSqlDatabase db = logDb(); @@ -1511,6 +1708,9 @@ bool SqliteStorage::logMessage(Message &msg) logMessageQuery.bindValue(":type", msg.type()); logMessageQuery.bindValue(":flags", (int)msg.flags()); logMessageQuery.bindValue(":sender", msg.sender()); + logMessageQuery.bindValue(":realname", msg.realName()); + logMessageQuery.bindValue(":avatarurl", msg.avatarUrl()); + logMessageQuery.bindValue(":senderprefixes", msg.senderPrefixes()); logMessageQuery.bindValue(":message", msg.contents()); lockForWrite(); @@ -1522,6 +1722,8 @@ bool SqliteStorage::logMessage(Message &msg) QSqlQuery addSenderQuery(db); addSenderQuery.prepare(queryString("insert_sender")); addSenderQuery.bindValue(":sender", msg.sender()); + addSenderQuery.bindValue(":realname", msg.realName()); + addSenderQuery.bindValue(":avatarurl", msg.avatarUrl()); safeExec(addSenderQuery); safeExec(logMessageQuery); error = !watchQuery(logMessageQuery); @@ -1559,17 +1761,20 @@ bool SqliteStorage::logMessages(MessageList &msgs) db.transaction(); { - QSet senders; + QSet senders; QSqlQuery addSenderQuery(db); addSenderQuery.prepare(queryString("insert_sender")); lockForWrite(); for (int i = 0; i < msgs.count(); i++) { - const QString &sender = msgs.at(i).sender(); + auto &msg = msgs.at(i); + SenderData sender = { msg.sender(), msg.realName(), msg.avatarUrl() }; if (senders.contains(sender)) continue; senders << sender; - addSenderQuery.bindValue(":sender", sender); + addSenderQuery.bindValue(":sender", sender.sender); + addSenderQuery.bindValue(":realname", sender.realname); + addSenderQuery.bindValue(":avatarurl", sender.avatarurl); safeExec(addSenderQuery); } } @@ -1586,6 +1791,9 @@ bool SqliteStorage::logMessages(MessageList &msgs) logMessageQuery.bindValue(":type", msg.type()); logMessageQuery.bindValue(":flags", (int)msg.flags()); logMessageQuery.bindValue(":sender", msg.sender()); + logMessageQuery.bindValue(":realname", msg.realName()); + logMessageQuery.bindValue(":avatarurl", msg.avatarUrl()); + logMessageQuery.bindValue(":senderprefixes", msg.senderPrefixes()); logMessageQuery.bindValue(":message", msg.contents()); safeExec(logMessageQuery); @@ -1670,8 +1878,11 @@ QList SqliteStorage::requestMsgs(UserId user, BufferId bufferId, MsgId Message msg(QDateTime::fromTime_t(query.value(1).toInt()), bufferInfo, (Message::Type)query.value(2).toUInt(), - query.value(5).toString(), + query.value(8).toString(), query.value(4).toString(), + query.value(5).toString(), + query.value(6).toString(), + query.value(7).toString(), (Message::Flags)query.value(3).toUInt()); msg.setMsgId(query.value(0).toInt()); messagelist << msg; @@ -1684,6 +1895,82 @@ QList SqliteStorage::requestMsgs(UserId user, BufferId bufferId, MsgId } +QList SqliteStorage::requestMsgsFiltered(UserId user, BufferId bufferId, MsgId first, MsgId last, int limit, Message::Types type, Message::Flags flags) +{ + QList messagelist; + + QSqlDatabase db = logDb(); + db.transaction(); + + bool error = false; + BufferInfo bufferInfo; + { + // code dupication from getBufferInfo: + // this is due to the impossibility of nesting transactions and recursive locking + QSqlQuery bufferInfoQuery(db); + bufferInfoQuery.prepare(queryString("select_buffer_by_id")); + bufferInfoQuery.bindValue(":userid", user.toInt()); + bufferInfoQuery.bindValue(":bufferid", bufferId.toInt()); + + lockForRead(); + safeExec(bufferInfoQuery); + error = !watchQuery(bufferInfoQuery) || !bufferInfoQuery.first(); + if (!error) { + bufferInfo = BufferInfo(bufferInfoQuery.value(0).toInt(), bufferInfoQuery.value(1).toInt(), (BufferInfo::Type)bufferInfoQuery.value(2).toInt(), 0, bufferInfoQuery.value(4).toString()); + error = !bufferInfo.isValid(); + } + } + if (error) { + db.rollback(); + unlock(); + return messagelist; + } + + { + QSqlQuery query(db); + if (last == -1 && first == -1) { + query.prepare(queryString("select_messagesNewestK_filtered")); + } + else if (last == -1) { + query.prepare(queryString("select_messagesNewerThan_filtered")); + query.bindValue(":firstmsg", first.toInt()); + } + else { + query.prepare(queryString("select_messagesRange_filtered")); + query.bindValue(":lastmsg", last.toInt()); + query.bindValue(":firstmsg", first.toInt()); + } + query.bindValue(":bufferid", bufferId.toInt()); + query.bindValue(":limit", limit); + int typeRaw = type; + query.bindValue(":type", typeRaw); + int flagsRaw = flags; + query.bindValue(":flags", flagsRaw); + + safeExec(query); + watchQuery(query); + + while (query.next()) { + Message msg(QDateTime::fromTime_t(query.value(1).toInt()), + bufferInfo, + (Message::Type)query.value(2).toUInt(), + query.value(8).toString(), + query.value(4).toString(), + query.value(5).toString(), + query.value(6).toString(), + query.value(7).toString(), + Message::Flags{query.value(3).toInt()}); + msg.setMsgId(query.value(0).toInt()); + messagelist << msg; + } + } + db.commit(); + unlock(); + + return messagelist; +} + + QList SqliteStorage::requestAllMsgs(UserId user, MsgId first, MsgId last, int limit) { QList messagelist; @@ -1724,8 +2011,11 @@ QList SqliteStorage::requestAllMsgs(UserId user, MsgId first, MsgId las Message msg(QDateTime::fromTime_t(query.value(2).toInt()), bufferInfoHash[query.value(1).toInt()], (Message::Type)query.value(3).toUInt(), - query.value(6).toString(), + query.value(9).toString(), query.value(5).toString(), + query.value(6).toString(), + query.value(7).toString(), + query.value(8).toString(), (Message::Flags)query.value(4).toUInt()); msg.setMsgId(query.value(0).toInt()); messagelist << msg; @@ -1736,6 +2026,106 @@ QList SqliteStorage::requestAllMsgs(UserId user, MsgId first, MsgId las return messagelist; } +QList SqliteStorage::requestAllMsgsFiltered(UserId user, MsgId first, MsgId last, int limit, Message::Types type, Message::Flags flags) +{ + QList messagelist; + + QSqlDatabase db = logDb(); + db.transaction(); + + QHash bufferInfoHash; + { + QSqlQuery bufferInfoQuery(db); + bufferInfoQuery.prepare(queryString("select_buffers")); + bufferInfoQuery.bindValue(":userid", user.toInt()); + + lockForRead(); + safeExec(bufferInfoQuery); + watchQuery(bufferInfoQuery); + while (bufferInfoQuery.next()) { + BufferInfo bufferInfo = BufferInfo(bufferInfoQuery.value(0).toInt(), bufferInfoQuery.value(1).toInt(), (BufferInfo::Type)bufferInfoQuery.value(2).toInt(), bufferInfoQuery.value(3).toInt(), bufferInfoQuery.value(4).toString()); + bufferInfoHash[bufferInfo.bufferId()] = bufferInfo; + } + + QSqlQuery query(db); + if (last == -1) { + query.prepare(queryString("select_messagesAllNew_filtered")); + } + else { + query.prepare(queryString("select_messagesAll_filtered")); + query.bindValue(":lastmsg", last.toInt()); + } + query.bindValue(":userid", user.toInt()); + query.bindValue(":firstmsg", first.toInt()); + query.bindValue(":limit", limit); + int typeRaw = type; + query.bindValue(":type", typeRaw); + int flagsRaw = flags; + query.bindValue(":flags", flagsRaw); + safeExec(query); + + watchQuery(query); + + while (query.next()) { + Message msg(QDateTime::fromTime_t(query.value(2).toInt()), + bufferInfoHash[query.value(1).toInt()], + (Message::Type)query.value(3).toUInt(), + query.value(9).toString(), + query.value(5).toString(), + query.value(6).toString(), + query.value(7).toString(), + query.value(8).toString(), + Message::Flags{query.value(4).toInt()}); + msg.setMsgId(query.value(0).toInt()); + messagelist << msg; + } + } + db.commit(); + unlock(); + return messagelist; +} + +QMap SqliteStorage::getAllAuthUserNames() +{ + QMap authusernames; + + QSqlDatabase db = logDb(); + db.transaction(); + { + QSqlQuery query(db); + query.prepare(queryString("select_all_authusernames")); + + lockForRead(); + safeExec(query); + watchQuery(query); + while (query.next()) { + authusernames[query.value(0).toInt()] = query.value(1).toString(); + } + } + db.commit(); + unlock(); + return authusernames; +} + + +QString SqliteStorage::getAuthUserName(UserId user) { + QString authusername; + QSqlQuery query(logDb()); + query.prepare(queryString("select_authusername")); + query.bindValue(":userid", user.toInt()); + + lockForRead(); + safeExec(query); + watchQuery(query); + unlock(); + + if (query.first()) { + authusername = query.value(0).toString(); + } + + return authusername; +} + QString SqliteStorage::backlogFile() { @@ -1752,12 +2142,15 @@ bool SqliteStorage::safeExec(QSqlQuery &query, int retryCount) switch (query.lastError().number()) { case 5: // SQLITE_BUSY 5 /* The database file is locked */ + [[clang::fallthrough]]; case 6: // SQLITE_LOCKED 6 /* A table in the database is locked */ if (retryCount < _maxRetryCount) return safeExec(query, retryCount + 1); + break; default: - return false; + ; } + return false; } @@ -1841,6 +2234,7 @@ bool SqliteMigrationReader::readMo(QuasselUserMO &user) user.username = value(1).toString(); user.password = value(2).toString(); user.hashversion = value(3).toInt(); + user.authenticator = value(4).toString(); return true; } @@ -1941,8 +2335,11 @@ bool SqliteMigrationReader::readMo(BufferMO &buffer) buffer.lastmsgid = value(7).toInt(); buffer.lastseenmsgid = value(8).toInt(); buffer.markerlinemsgid = value(9).toInt(); - buffer.key = value(10).toString(); - buffer.joined = value(11).toInt() == 1 ? true : false; + buffer.bufferactivity = value(10).toInt(); + buffer.highlightcount = value(11).toInt(); + buffer.key = value(12).toString(); + buffer.joined = value(13).toInt() == 1 ? true : false; + buffer.cipher = value(14).toString(); return true; } @@ -1965,6 +2362,8 @@ bool SqliteMigrationReader::readMo(SenderMO &sender) sender.senderId = value(0).toInt(); sender.sender = value(1).toString(); + sender.realname = value(2).toString(); + sender.avatarurl = value(3).toString(); return true; } @@ -1991,7 +2390,8 @@ bool SqliteMigrationReader::readMo(BacklogMO &backlog) backlog.type = value(3).toInt(); backlog.flags = value(4).toInt(); backlog.senderid = value(5).toInt(); - backlog.message = value(6).toString(); + backlog.senderprefixes = value(6).toString(); + backlog.message = value(7).toString(); return true; }