+ (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).toUInt());
+ msg.setMsgId(query.value(0).toInt());
+ messagelist << msg;
+ }
+ }
+ db.commit();
+ unlock();
+
+ return messagelist;
+}
+
+
+QList<Message> SqliteStorage::requestAllMsgs(UserId user, MsgId first, MsgId last, int limit)
+{
+ QList<Message> messagelist;
+
+ QSqlDatabase db = logDb();
+ db.transaction();
+
+ QHash<BufferId, BufferInfo> 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"));
+ }
+ else {
+ query.prepare(queryString("select_messagesAll"));
+ query.bindValue(":lastmsg", last.toInt());
+ }
+ query.bindValue(":userid", user.toInt());
+ query.bindValue(":firstmsg", first.toInt());
+ query.bindValue(":limit", limit);
+ 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).toUInt());
+ msg.setMsgId(query.value(0).toInt());
+ messagelist << msg;
+ }
+ }
+ db.commit();
+ unlock();
+ return messagelist;
+}
+
+
+QMap<UserId, QString> SqliteStorage::getAllAuthUserNames()
+{
+ QMap<UserId, QString> 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()
+{
+ return Quassel::configDirPath() + "quassel-storage.sqlite";
+}
+
+
+bool SqliteStorage::safeExec(QSqlQuery &query, int retryCount)
+{
+ query.exec();
+
+ if (!query.lastError().isValid())
+ return true;
+
+ 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;
+}
+
+
+// ========================================
+// SqliteMigration
+// ========================================
+SqliteMigrationReader::SqliteMigrationReader()
+ : SqliteStorage(),
+ _maxId(0)
+{
+}
+
+
+void SqliteMigrationReader::setMaxId(MigrationObject mo)
+{
+ QString queryString;
+ switch (mo) {
+ case Sender:
+ queryString = "SELECT max(senderid) FROM sender";
+ break;
+ case Backlog:
+ queryString = "SELECT max(messageid) FROM backlog";
+ break;
+ default:
+ _maxId = 0;
+ return;
+ }
+ QSqlQuery query = logDb().exec(queryString);
+ query.first();
+ _maxId = query.value(0).toInt();
+}
+
+
+bool SqliteMigrationReader::prepareQuery(MigrationObject mo)
+{
+ setMaxId(mo);
+
+ switch (mo) {
+ case QuasselUser:
+ newQuery(queryString("migrate_read_quasseluser"), logDb());
+ break;
+ case Identity:
+ newQuery(queryString("migrate_read_identity"), logDb());
+ break;
+ case IdentityNick:
+ newQuery(queryString("migrate_read_identity_nick"), logDb());
+ break;
+ case Network:
+ newQuery(queryString("migrate_read_network"), logDb());
+ break;
+ case Buffer:
+ newQuery(queryString("migrate_read_buffer"), logDb());
+ break;
+ case Sender:
+ newQuery(queryString("migrate_read_sender"), logDb());
+ bindValue(0, 0);
+ bindValue(1, stepSize());
+ break;
+ case Backlog:
+ newQuery(queryString("migrate_read_backlog"), logDb());
+ bindValue(0, 0);
+ bindValue(1, stepSize());
+ break;
+ case IrcServer:
+ newQuery(queryString("migrate_read_ircserver"), logDb());
+ break;
+ case UserSetting:
+ newQuery(queryString("migrate_read_usersetting"), logDb());
+ break;
+ }
+ return exec();
+}
+
+
+bool SqliteMigrationReader::readMo(QuasselUserMO &user)
+{
+ if (!next())
+ return false;
+
+ user.id = value(0).toInt();
+ user.username = value(1).toString();
+ user.password = value(2).toString();
+ user.hashversion = value(3).toInt();
+ user.authenticator = value(4).toString();
+ return true;
+}
+
+
+bool SqliteMigrationReader::readMo(IdentityMO &identity)
+{
+ if (!next())
+ return false;
+
+ identity.id = value(0).toInt();
+ identity.userid = value(1).toInt();
+ identity.identityname = value(2).toString();
+ identity.realname = value(3).toString();
+ identity.awayNick = value(4).toString();
+ identity.awayNickEnabled = value(5).toInt() == 1 ? true : false;
+ identity.awayReason = value(6).toString();
+ identity.awayReasonEnabled = value(7).toInt() == 1 ? true : false;
+ identity.autoAwayEnabled = value(8).toInt() == 1 ? true : false;
+ identity.autoAwayTime = value(9).toInt();
+ identity.autoAwayReason = value(10).toString();
+ 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.ident = value(15).toString();
+ identity.kickReason = value(16).toString();
+ identity.partReason = value(17).toString();
+ identity.quitReason = value(18).toString();
+ identity.sslCert = value(19).toByteArray();
+ identity.sslKey = value(20).toByteArray();
+ return true;
+}
+
+
+bool SqliteMigrationReader::readMo(IdentityNickMO &identityNick)
+{
+ if (!next())
+ return false;
+
+ identityNick.nickid = value(0).toInt();
+ identityNick.identityId = value(1).toInt();
+ identityNick.nick = value(2).toString();
+ return true;
+}
+
+
+bool SqliteMigrationReader::readMo(NetworkMO &network)
+{
+ if (!next())
+ return false;
+
+ network.networkid = value(0).toInt();
+ network.userid = value(1).toInt();
+ network.networkname = value(2).toString();
+ network.identityid = value(3).toInt();
+ network.encodingcodec = value(4).toString();
+ network.decodingcodec = value(5).toString();
+ network.servercodec = value(6).toString();
+ network.userandomserver = value(7).toInt() == 1 ? true : false;
+ network.perform = value(8).toString();
+ network.useautoidentify = value(9).toInt() == 1 ? true : false;
+ network.autoidentifyservice = value(10).toString();
+ network.autoidentifypassword = value(11).toString();
+ network.useautoreconnect = value(12).toInt() == 1 ? true : false;
+ network.autoreconnectinterval = value(13).toInt();
+ network.autoreconnectretries = value(14).toInt();
+ network.unlimitedconnectretries = value(15).toInt() == 1 ? true : false;
+ network.rejoinchannels = value(16).toInt() == 1 ? true : false;
+ network.connected = value(17).toInt() == 1 ? true : false;
+ network.usermode = value(18).toString();
+ network.awaymessage = value(19).toString();
+ network.attachperform = value(20).toString();
+ network.detachperform = value(21).toString();
+ network.usesasl = value(22).toInt() == 1 ? true : false;
+ network.saslaccount = value(23).toString();
+ network.saslpassword = value(24).toString();
+ // Custom rate limiting
+ network.usecustommessagerate = value(25).toInt() == 1 ? true : false;
+ network.messagerateburstsize = value(26).toInt();
+ network.messageratedelay = value(27).toUInt();
+ network.unlimitedmessagerate = value(28).toInt() == 1 ? true : false;
+ return true;
+}
+
+
+bool SqliteMigrationReader::readMo(BufferMO &buffer)
+{
+ if (!next())
+ return false;
+
+ buffer.bufferid = value(0).toInt();
+ buffer.userid = value(1).toInt();
+ buffer.groupid = value(2).toInt();
+ buffer.networkid = value(3).toInt();
+ 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.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;
+}