X-Git-Url: https://git.quassel-irc.org/?p=quassel.git;a=blobdiff_plain;f=src%2Fcore%2Fsqlitestorage.cpp;h=db174cb451cec9c841eddff445f18d9167bea402;hp=1e1b79822b96087d3a1fa7df5f533a23a533c300;hb=56f686f70bbb212d83803be88adec6fdd225ea8e;hpb=092e6b212637ffbf68800584b7c1f32d1931b602 diff --git a/src/core/sqlitestorage.cpp b/src/core/sqlitestorage.cpp index 1e1b7982..db174cb4 100644 --- a/src/core/sqlitestorage.cpp +++ b/src/core/sqlitestorage.cpp @@ -376,6 +376,60 @@ QVariant SqliteStorage::getUserSetting(UserId userId, const QString &settingName } +void SqliteStorage::setCoreState(const QVariantList &data) +{ + QByteArray rawData; + QDataStream out(&rawData, QIODevice::WriteOnly); + out.setVersion(QDataStream::Qt_4_2); + out << data; + + QSqlDatabase db = logDb(); + db.transaction(); + { + QSqlQuery query(db); + query.prepare(queryString("insert_core_state")); + query.bindValue(":key", "active_sessions"); + query.bindValue(":value", rawData); + lockForWrite(); + safeExec(query); + + if (query.lastError().isValid()) { + QSqlQuery updateQuery(db); + updateQuery.prepare(queryString("update_core_state")); + updateQuery.bindValue(":key", "active_sessions"); + updateQuery.bindValue(":value", rawData); + safeExec(updateQuery); + } + db.commit(); + } + unlock(); +} + + +QVariantList SqliteStorage::getCoreState(const QVariantList &defaultData) +{ + QVariantList data; + { + QSqlQuery query(logDb()); + query.prepare(queryString("select_core_state")); + query.bindValue(":key", "active_sessions"); + lockForRead(); + safeExec(query); + + if (query.first()) { + QByteArray rawData = query.value(0).toByteArray(); + QDataStream in(&rawData, QIODevice::ReadOnly); + in.setVersion(QDataStream::Qt_4_2); + in >> data; + } else { + data = defaultData; + } + } + unlock(); + return data; +} + + IdentityId SqliteStorage::createIdentity(UserId user, CoreIdentity &identity) { IdentityId identityId; @@ -1414,7 +1468,7 @@ void SqliteStorage::setBufferLastSeenMsg(UserId user, const BufferId &bufferId, query.prepare(queryString("update_buffer_lastseen")); query.bindValue(":userid", user.toInt()); query.bindValue(":bufferid", bufferId.toInt()); - query.bindValue(":lastseenmsgid", msgId.toInt()); + query.bindValue(":lastseenmsgid", msgId.toQint64()); lockForWrite(); safeExec(query); @@ -1443,7 +1497,7 @@ QHash SqliteStorage::bufferLastSeenMsgIds(UserId user) error = !watchQuery(query); if (!error) { while (query.next()) { - lastSeenHash[query.value(0).toInt()] = query.value(1).toInt(); + lastSeenHash[query.value(0).toInt()] = query.value(1).toLongLong(); } } } @@ -1464,7 +1518,7 @@ void SqliteStorage::setBufferMarkerLineMsg(UserId user, const BufferId &bufferId query.prepare(queryString("update_buffer_markerlinemsgid")); query.bindValue(":userid", user.toInt()); query.bindValue(":bufferid", bufferId.toInt()); - query.bindValue(":markerlinemsgid", msgId.toInt()); + query.bindValue(":markerlinemsgid", msgId.toQint64()); lockForWrite(); safeExec(query); @@ -1493,7 +1547,7 @@ QHash SqliteStorage::bufferMarkerLineMsgIds(UserId user) error = !watchQuery(query); if (!error) { while (query.next()) { - markerLineHash[query.value(0).toInt()] = query.value(1).toInt(); + markerLineHash[query.value(0).toInt()] = query.value(1).toLongLong(); } } } @@ -1563,7 +1617,7 @@ Message::Types SqliteStorage::bufferActivity(BufferId bufferId, MsgId lastSeenMs QSqlQuery query(db); query.prepare(queryString("select_buffer_bufferactivity")); query.bindValue(":bufferid", bufferId.toInt()); - query.bindValue(":lastseenmsgid", lastSeenMsgId.toInt()); + query.bindValue(":lastseenmsgid", lastSeenMsgId.toQint64()); lockForRead(); safeExec(query); @@ -1680,7 +1734,7 @@ int SqliteStorage::highlightCount(BufferId bufferId, MsgId lastSeenMsgId) QSqlQuery query(db); query.prepare(queryString("select_buffer_highlightcount")); query.bindValue(":bufferid", bufferId.toInt()); - query.bindValue(":lastseenmsgid", lastSeenMsgId.toInt()); + query.bindValue(":lastseenmsgid", lastSeenMsgId.toQint64()); lockForRead(); safeExec(query); @@ -1702,8 +1756,9 @@ bool SqliteStorage::logMessage(Message &msg) { QSqlQuery logMessageQuery(db); logMessageQuery.prepare(queryString("insert_message")); - - logMessageQuery.bindValue(":time", msg.timestamp().toTime_t()); + // As of SQLite schema version 31, timestamps are stored in milliseconds instead of + // seconds. This nets us more precision as well as simplifying 64-bit time. + logMessageQuery.bindValue(":time", msg.timestamp().toMSecsSinceEpoch()); logMessageQuery.bindValue(":bufferid", msg.bufferInfo().bufferId().toInt()); logMessageQuery.bindValue(":type", msg.type()); logMessageQuery.bindValue(":flags", (int)msg.flags()); @@ -1733,7 +1788,7 @@ bool SqliteStorage::logMessage(Message &msg) } } if (!error) { - MsgId msgId = logMessageQuery.lastInsertId().toInt(); + MsgId msgId = logMessageQuery.lastInsertId().toLongLong(); if (msgId.isValid()) { msg.setMsgId(msgId); } @@ -1785,8 +1840,9 @@ bool SqliteStorage::logMessages(MessageList &msgs) logMessageQuery.prepare(queryString("insert_message")); for (int i = 0; i < msgs.count(); i++) { Message &msg = msgs[i]; - - logMessageQuery.bindValue(":time", msg.timestamp().toTime_t()); + // As of SQLite schema version 31, timestamps are stored in milliseconds instead of + // seconds. This nets us more precision as well as simplifying 64-bit time. + logMessageQuery.bindValue(":time", msg.timestamp().toMSecsSinceEpoch()); logMessageQuery.bindValue(":bufferid", msg.bufferInfo().bufferId().toInt()); logMessageQuery.bindValue(":type", msg.type()); logMessageQuery.bindValue(":flags", (int)msg.flags()); @@ -1802,7 +1858,7 @@ bool SqliteStorage::logMessages(MessageList &msgs) break; } else { - msg.setMsgId(logMessageQuery.lastInsertId().toInt()); + msg.setMsgId(logMessageQuery.lastInsertId().toLongLong()); } } } @@ -1833,7 +1889,7 @@ QList SqliteStorage::requestMsgs(UserId user, BufferId bufferId, MsgId bool error = false; BufferInfo bufferInfo; { - // code dupication from getBufferInfo: + // code duplication from getBufferInfo: // this is due to the impossibility of nesting transactions and recursive locking QSqlQuery bufferInfoQuery(db); bufferInfoQuery.prepare(queryString("select_buffer_by_id")); @@ -1861,12 +1917,12 @@ QList SqliteStorage::requestMsgs(UserId user, BufferId bufferId, MsgId } else if (last == -1) { query.prepare(queryString("select_messagesNewerThan")); - query.bindValue(":firstmsg", first.toInt()); + query.bindValue(":firstmsg", first.toQint64()); } else { query.prepare(queryString("select_messagesRange")); - query.bindValue(":lastmsg", last.toInt()); - query.bindValue(":firstmsg", first.toInt()); + query.bindValue(":lastmsg", last.toQint64()); + query.bindValue(":firstmsg", first.toQint64()); } query.bindValue(":bufferid", bufferId.toInt()); query.bindValue(":limit", limit); @@ -1875,16 +1931,99 @@ QList SqliteStorage::requestMsgs(UserId user, BufferId bufferId, MsgId watchQuery(query); while (query.next()) { - Message msg(QDateTime::fromTime_t(query.value(1).toInt()), + Message msg( + // As of SQLite schema version 31, timestamps are stored in milliseconds instead of + // seconds. This nets us more precision as well as simplifying 64-bit time. + QDateTime::fromMSecsSinceEpoch(query.value(1).toLongLong()), bufferInfo, - (Message::Type)query.value(2).toUInt(), + (Message::Type)query.value(2).toInt(), 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()); + (Message::Flags)query.value(3).toInt()); + msg.setMsgId(query.value(0).toLongLong()); + messagelist << msg; + } + } + db.commit(); + unlock(); + + return messagelist; +} + + +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.toQint64()); + } + else { + query.prepare(queryString("select_messagesRange_filtered")); + query.bindValue(":lastmsg", last.toQint64()); + query.bindValue(":firstmsg", first.toQint64()); + } + 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( + // As of SQLite schema version 31, timestamps are stored in milliseconds + // instead of seconds. This nets us more precision as well as simplifying + // 64-bit time. + QDateTime::fromMSecsSinceEpoch(query.value(1).toLongLong()), + bufferInfo, + (Message::Type)query.value(2).toInt(), + 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).toLongLong()); messagelist << msg; } } @@ -1922,26 +2061,29 @@ QList SqliteStorage::requestAllMsgs(UserId user, MsgId first, MsgId las } else { query.prepare(queryString("select_messagesAll")); - query.bindValue(":lastmsg", last.toInt()); + query.bindValue(":lastmsg", last.toQint64()); } query.bindValue(":userid", user.toInt()); - query.bindValue(":firstmsg", first.toInt()); + query.bindValue(":firstmsg", first.toQint64()); query.bindValue(":limit", limit); safeExec(query); watchQuery(query); while (query.next()) { - Message msg(QDateTime::fromTime_t(query.value(2).toInt()), + Message msg( + // As of SQLite schema version 31, timestamps are stored in milliseconds instead of + // seconds. This nets us more precision as well as simplifying 64-bit time. + QDateTime::fromMSecsSinceEpoch(query.value(2).toLongLong()), bufferInfoHash[query.value(1).toInt()], - (Message::Type)query.value(3).toUInt(), + (Message::Type)query.value(3).toInt(), 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()); + (Message::Flags)query.value(4).toInt()); + msg.setMsgId(query.value(0).toLongLong()); messagelist << msg; } } @@ -1950,6 +2092,68 @@ 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.toQint64()); + } + query.bindValue(":userid", user.toInt()); + query.bindValue(":firstmsg", first.toQint64()); + 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( + // As of SQLite schema version 31, timestamps are stored in milliseconds + // instead of seconds. This nets us more precision as well as simplifying + // 64-bit time. + QDateTime::fromMSecsSinceEpoch(query.value(2).toLongLong()), + bufferInfoHash[query.value(1).toInt()], + (Message::Type)query.value(3).toInt(), + 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).toLongLong()); + messagelist << msg; + } + } + db.commit(); + unlock(); + return messagelist; +} QMap SqliteStorage::getAllAuthUserNames() { @@ -2046,7 +2250,7 @@ void SqliteMigrationReader::setMaxId(MigrationObject mo) } QSqlQuery query = logDb().exec(queryString); query.first(); - _maxId = query.value(0).toInt(); + _maxId = query.value(0).toLongLong(); } @@ -2086,6 +2290,9 @@ bool SqliteMigrationReader::prepareQuery(MigrationObject mo) case UserSetting: newQuery(queryString("migrate_read_usersetting"), logDb()); break; + case CoreState: + newQuery(queryString("migrate_read_corestate"), logDb()); + break; } return exec(); } @@ -2124,7 +2331,7 @@ bool SqliteMigrationReader::readMo(IdentityMO &identity) identity.autoAwayReasonEnabled = value(11).toInt() == 1 ? true : false; identity.detachAwayEnabled = value(12).toInt() == 1 ? true : false; identity.detachAwayReason = value(13).toString(); - identity.detchAwayReasonEnabled = value(14).toInt() == 1 ? true : false; + identity.detachAwayReasonEnabled = value(14).toInt() == 1 ? true : false; identity.ident = value(15).toString(); identity.kickReason = value(16).toString(); identity.partReason = value(17).toString(); @@ -2198,9 +2405,9 @@ bool SqliteMigrationReader::readMo(BufferMO &buffer) buffer.buffername = value(4).toString(); buffer.buffercname = value(5).toString(); buffer.buffertype = value(6).toInt(); - buffer.lastmsgid = value(7).toInt(); - buffer.lastseenmsgid = value(8).toInt(); - buffer.markerlinemsgid = value(9).toInt(); + buffer.lastmsgid = value(7).toLongLong(); + buffer.lastseenmsgid = value(8).toLongLong(); + buffer.markerlinemsgid = value(9).toLongLong(); buffer.bufferactivity = value(10).toInt(); buffer.highlightcount = value(11).toInt(); buffer.key = value(12).toString(); @@ -2226,7 +2433,7 @@ bool SqliteMigrationReader::readMo(SenderMO &sender) } } - sender.senderId = value(0).toInt(); + sender.senderId = value(0).toLongLong(); sender.sender = value(1).toString(); sender.realname = value(2).toString(); sender.avatarurl = value(3).toString(); @@ -2236,11 +2443,11 @@ bool SqliteMigrationReader::readMo(SenderMO &sender) bool SqliteMigrationReader::readMo(BacklogMO &backlog) { - int skipSteps = 0; + qint64 skipSteps = 0; while (!next()) { if (backlog.messageid < _maxId) { - bindValue(0, backlog.messageid.toInt() + (skipSteps * stepSize())); - bindValue(1, backlog.messageid.toInt() + ((skipSteps + 1) * stepSize())); + bindValue(0, backlog.messageid.toQint64() + (skipSteps * stepSize())); + bindValue(1, backlog.messageid.toQint64() + ((skipSteps + 1) * stepSize())); skipSteps++; if (!exec()) return false; @@ -2250,12 +2457,14 @@ bool SqliteMigrationReader::readMo(BacklogMO &backlog) } } - backlog.messageid = value(0).toInt(); - backlog.time = QDateTime::fromTime_t(value(1).toInt()).toUTC(); + backlog.messageid = value(0).toLongLong(); + // As of SQLite schema version 31, timestamps are stored in milliseconds instead of + // seconds. This nets us more precision as well as simplifying 64-bit time. + backlog.time = QDateTime::fromMSecsSinceEpoch(value(1).toLongLong()).toUTC(); backlog.bufferid = value(2).toInt(); backlog.type = value(3).toInt(); backlog.flags = value(4).toInt(); - backlog.senderid = value(5).toInt(); + backlog.senderid = value(5).toLongLong(); backlog.senderprefixes = value(6).toString(); backlog.message = value(7).toString(); return true; @@ -2297,3 +2506,15 @@ bool SqliteMigrationReader::readMo(UserSettingMO &userSetting) return true; } + + +bool SqliteMigrationReader::readMo(CoreStateMO &coreState) +{ + if (!next()) + return false; + + coreState.key = value(0).toString(); + coreState.value = value(1).toByteArray(); + + return true; +}