diff --git a/servatrice/src/servatrice.cpp b/servatrice/src/servatrice.cpp index 4911a816..b2c957b3 100644 --- a/servatrice/src/servatrice.cpp +++ b/servatrice/src/servatrice.cpp @@ -187,23 +187,21 @@ bool Servatrice::initServer() const QString roomMethod = settingsCache->value("rooms/method").toString(); if (roomMethod == "sql") { - QSqlQuery query(servatriceDatabaseInterface->getDatabase()); - query.prepare("select id, name, descr, auto_join, join_message from " + dbPrefix + "_rooms order by id asc"); + QSqlQuery *query = servatriceDatabaseInterface->prepareQuery("select id, name, descr, auto_join, join_message from {prefix}_rooms order by id asc"); servatriceDatabaseInterface->execSqlQuery(query); - while (query.next()) { - QSqlQuery query2(servatriceDatabaseInterface->getDatabase()); - query2.prepare("select name from " + dbPrefix + "_rooms_gametypes where id_room = :id_room"); - query2.bindValue(":id_room", query.value(0).toInt()); + while (query->next()) { + QSqlQuery *query2 = servatriceDatabaseInterface->prepareQuery("select name from {prefix}_rooms_gametypes where id_room = :id_room"); + query2->bindValue(":id_room", query->value(0).toInt()); servatriceDatabaseInterface->execSqlQuery(query2); QStringList gameTypes; - while (query2.next()) - gameTypes.append(query2.value(0).toString()); + while (query2->next()) + gameTypes.append(query2->value(0).toString()); - addRoom(new Server_Room(query.value(0).toInt(), - query.value(1).toString(), - query.value(2).toString(), - query.value(3).toInt(), - query.value(4).toString(), + addRoom(new Server_Room(query->value(0).toInt(), + query->value(1).toString(), + query->value(2).toString(), + query->value(3).toInt(), + query->value(4).toString(), gameTypes, this )); @@ -360,11 +358,10 @@ void Servatrice::updateServerList() serverListMutex.lock(); serverList.clear(); - QSqlQuery query(servatriceDatabaseInterface->getDatabase()); - query.prepare("select id, ssl_cert, hostname, address, game_port, control_port from " + dbPrefix + "_servers order by id asc"); + QSqlQuery *query = servatriceDatabaseInterface->prepareQuery("select id, ssl_cert, hostname, address, game_port, control_port from {prefix}_servers order by id asc"); servatriceDatabaseInterface->execSqlQuery(query); - while (query.next()) { - ServerProperties prop(query.value(0).toInt(), QSslCertificate(query.value(1).toString().toUtf8()), query.value(2).toString(), QHostAddress(query.value(3).toString()), query.value(4).toInt(), query.value(5).toInt()); + while (query->next()) { + ServerProperties prop(query->value(0).toInt(), QSslCertificate(query->value(1).toString().toUtf8()), query->value(2).toString(), QHostAddress(query->value(3).toString()), query->value(4).toInt(), query->value(5).toInt()); serverList.append(prop); qDebug() << QString("#%1 CERT=%2 NAME=%3 IP=%4:%5 CPORT=%6").arg(prop.id).arg(QString(prop.cert.digest().toHex())).arg(prop.hostname).arg(prop.address.toString()).arg(prop.gamePort).arg(prop.controlPort); } @@ -407,12 +404,11 @@ void Servatrice::updateLoginMessage() if (!servatriceDatabaseInterface->checkSql()) return; - QSqlQuery query(servatriceDatabaseInterface->getDatabase()); - query.prepare("select message from " + dbPrefix + "_servermessages where id_server = :id_server order by timest desc limit 1"); - query.bindValue(":id_server", serverId); + QSqlQuery *query = servatriceDatabaseInterface->prepareQuery("select message from {prefix}_servermessages where id_server = :id_server order by timest desc limit 1"); + query->bindValue(":id_server", serverId); if (servatriceDatabaseInterface->execSqlQuery(query)) - if (query.next()) { - const QString newLoginMessage = query.value(0).toString(); + if (query->next()) { + const QString newLoginMessage = query->value(0).toString(); loginMessageMutex.lock(); loginMessage = newLoginMessage; @@ -447,14 +443,13 @@ void Servatrice::statusUpdate() rxBytes = 0; rxBytesMutex.unlock(); - QSqlQuery query(servatriceDatabaseInterface->getDatabase()); - query.prepare("insert into " + dbPrefix + "_uptime (id_server, timest, uptime, users_count, games_count, tx_bytes, rx_bytes) values(:id, NOW(), :uptime, :users_count, :games_count, :tx, :rx)"); - query.bindValue(":id", serverId); - query.bindValue(":uptime", uptime); - query.bindValue(":users_count", uc); - query.bindValue(":games_count", gc); - query.bindValue(":tx", tx); - query.bindValue(":rx", rx); + QSqlQuery *query = servatriceDatabaseInterface->prepareQuery("insert into {prefix}_uptime (id_server, timest, uptime, users_count, games_count, tx_bytes, rx_bytes) values(:id, NOW(), :uptime, :users_count, :games_count, :tx, :rx)"); + query->bindValue(":id", serverId); + query->bindValue(":uptime", uptime); + query->bindValue(":users_count", uc); + query->bindValue(":games_count", gc); + query->bindValue(":tx", tx); + query->bindValue(":rx", rx); servatriceDatabaseInterface->execSqlQuery(query); } diff --git a/servatrice/src/servatrice_database_interface.cpp b/servatrice/src/servatrice_database_interface.cpp index 1bd006f7..e920cde9 100644 --- a/servatrice/src/servatrice_database_interface.cpp +++ b/servatrice/src/servatrice_database_interface.cpp @@ -11,578 +11,582 @@ #include Servatrice_DatabaseInterface::Servatrice_DatabaseInterface(int _instanceId, Servatrice *_server) - : instanceId(_instanceId), - sqlDatabase(QSqlDatabase()), - server(_server) + : instanceId(_instanceId), + sqlDatabase(QSqlDatabase()), + server(_server) { } Servatrice_DatabaseInterface::~Servatrice_DatabaseInterface() { - sqlDatabase.close(); + // reset all prepared statements + qDeleteAll(preparedStatements); + preparedStatements.clear(); + + sqlDatabase.close(); } void Servatrice_DatabaseInterface::initDatabase(const QSqlDatabase &_sqlDatabase) { - if (_sqlDatabase.isValid()) { - sqlDatabase = QSqlDatabase::cloneDatabase(_sqlDatabase, "pool_" + QString::number(instanceId)); - openDatabase(); - } + if (_sqlDatabase.isValid()) { + sqlDatabase = QSqlDatabase::cloneDatabase(_sqlDatabase, "pool_" + QString::number(instanceId)); + openDatabase(); + } } void Servatrice_DatabaseInterface::initDatabase(const QString &type, const QString &hostName, const QString &databaseName, const QString &userName, const QString &password) { - sqlDatabase = QSqlDatabase::addDatabase(type, "main"); - sqlDatabase.setHostName(hostName); - sqlDatabase.setDatabaseName(databaseName); - sqlDatabase.setUserName(userName); - sqlDatabase.setPassword(password); - - openDatabase(); + sqlDatabase = QSqlDatabase::addDatabase(type, "main"); + sqlDatabase.setHostName(hostName); + sqlDatabase.setDatabaseName(databaseName); + sqlDatabase.setUserName(userName); + sqlDatabase.setPassword(password); + + openDatabase(); } bool Servatrice_DatabaseInterface::openDatabase() { - if (sqlDatabase.isOpen()) - sqlDatabase.close(); - - const QString poolStr = instanceId == -1 ? QString("main") : QString("pool %1").arg(instanceId); - qDebug() << QString("[%1] Opening database...").arg(poolStr); - if (!sqlDatabase.open()) { - qCritical() << QString("[%1] Error opening database: %2").arg(poolStr).arg(sqlDatabase.lastError().text()); - return false; - } - - return true; + if (sqlDatabase.isOpen()) + sqlDatabase.close(); + + const QString poolStr = instanceId == -1 ? QString("main") : QString("pool %1").arg(instanceId); + qDebug() << QString("[%1] Opening database...").arg(poolStr); + if (!sqlDatabase.open()) { + qCritical() << QString("[%1] Error opening database: %2").arg(poolStr).arg(sqlDatabase.lastError().text()); + return false; + } + + // reset all prepared statements + qDeleteAll(preparedStatements); + preparedStatements.clear(); + return true; } bool Servatrice_DatabaseInterface::checkSql() { - if (!sqlDatabase.isValid()) - return false; - - if (!sqlDatabase.exec("select 1").isActive()) - return openDatabase(); - return true; + if (!sqlDatabase.isValid()) + return false; + + if (!sqlDatabase.exec("select 1").isActive()) + return openDatabase(); + return true; } -bool Servatrice_DatabaseInterface::execSqlQuery(QSqlQuery &query) +QSqlQuery * Servatrice_DatabaseInterface::prepareQuery(const QString &queryText) { - if (query.exec()) - return true; - const QString poolStr = instanceId == -1 ? QString("main") : QString("pool %1").arg(instanceId); - qCritical() << QString("[%1] Error executing query: %2").arg(poolStr).arg(query.lastError().text()); - return false; + if(preparedStatements.contains(queryText)) + return preparedStatements.value(queryText); + + QString prefixedQueryText = queryText; + prefixedQueryText.replace("{prefix}", server->getDbPrefix()); + QSqlQuery * query = new QSqlQuery(sqlDatabase); + query->prepare(prefixedQueryText); + + preparedStatements.insert(queryText, query); + return query; +} + +bool Servatrice_DatabaseInterface::execSqlQuery(QSqlQuery *query) +{ + if (query->exec()) + return true; + const QString poolStr = instanceId == -1 ? QString("main") : QString("pool %1").arg(instanceId); + qCritical() << QString("[%1] Error executing query: %2").arg(poolStr).arg(query->lastError().text()); + return false; } bool Servatrice_DatabaseInterface::usernameIsValid(const QString &user) { - QString result; - result.reserve(user.size()); - foreach (const QChar& c, user) { - switch (c.category()) { - // TODO: Figure out exactly which categories are OK and not - case QChar::Other_Control: break; - default: result += c; - } - } - result = result.trimmed(); - return (result.size() > 0); + QString result; + result.reserve(user.size()); + foreach (const QChar& c, user) { + switch (c.category()) { + // TODO: Figure out exactly which categories are OK and not + case QChar::Other_Control: break; + default: result += c; + } + } + result = result.trimmed(); + return (result.size() > 0); } bool Servatrice_DatabaseInterface::getRequireRegistration() { - return settingsCache->value("authentication/regonly", 0).toBool(); + return settingsCache->value("authentication/regonly", 0).toBool(); } AuthenticationResult Servatrice_DatabaseInterface::checkUserPassword(Server_ProtocolHandler *handler, const QString &user, const QString &password, QString &reasonStr, int &banSecondsLeft) { - switch (server->getAuthenticationMethod()) { - case Servatrice::AuthenticationNone: return UnknownUser; - case Servatrice::AuthenticationPassword: { - QString configPassword = settingsCache->value("authentication/password").toString(); - if (configPassword == password) - return PasswordRight; + switch (server->getAuthenticationMethod()) { + case Servatrice::AuthenticationNone: return UnknownUser; + case Servatrice::AuthenticationPassword: { + QString configPassword = settingsCache->value("authentication/password").toString(); + if (configPassword == password) + return PasswordRight; - return NotLoggedIn; - } - case Servatrice::AuthenticationSql: { - if (!checkSql()) - return UnknownUser; + return NotLoggedIn; + } + case Servatrice::AuthenticationSql: { + if (!checkSql()) + return UnknownUser; - if (!usernameIsValid(user)) - return UsernameInvalid; - - QSqlQuery ipBanQuery(sqlDatabase); - ipBanQuery.prepare("select time_to_sec(timediff(now(), date_add(b.time_from, interval b.minutes minute))), b.minutes <=> 0, b.visible_reason from " + server->getDbPrefix() + "_bans b where b.time_from = (select max(c.time_from) from " + server->getDbPrefix() + "_bans c where c.ip_address = :address) and b.ip_address = :address2"); - ipBanQuery.bindValue(":address", static_cast(handler)->getPeerAddress().toString()); - ipBanQuery.bindValue(":address2", static_cast(handler)->getPeerAddress().toString()); - if (!execSqlQuery(ipBanQuery)) { - qDebug("Login denied: SQL error"); - return NotLoggedIn; - } - - if (ipBanQuery.next()) { - const int secondsLeft = -ipBanQuery.value(0).toInt(); - const bool permanentBan = ipBanQuery.value(1).toInt(); - if ((secondsLeft > 0) || permanentBan) { - reasonStr = ipBanQuery.value(2).toString(); - banSecondsLeft = permanentBan ? 0 : secondsLeft; - qDebug("Login denied: banned by address"); - return UserIsBanned; - } - } - - QSqlQuery nameBanQuery(sqlDatabase); - nameBanQuery.prepare("select time_to_sec(timediff(now(), date_add(b.time_from, interval b.minutes minute))), b.minutes <=> 0, b.visible_reason from " + server->getDbPrefix() + "_bans b where b.time_from = (select max(c.time_from) from " + server->getDbPrefix() + "_bans c where c.user_name = :name2) and b.user_name = :name1"); - nameBanQuery.bindValue(":name1", user); - nameBanQuery.bindValue(":name2", user); - if (!execSqlQuery(nameBanQuery)) { - qDebug("Login denied: SQL error"); - return NotLoggedIn; - } - - if (nameBanQuery.next()) { - const int secondsLeft = -nameBanQuery.value(0).toInt(); - const bool permanentBan = nameBanQuery.value(1).toInt(); - if ((secondsLeft > 0) || permanentBan) { - reasonStr = nameBanQuery.value(2).toString(); - banSecondsLeft = permanentBan ? 0 : secondsLeft; - qDebug("Login denied: banned by name"); - return UserIsBanned; - } - } - - QSqlQuery passwordQuery(sqlDatabase); - passwordQuery.prepare("select password_sha512 from " + server->getDbPrefix() + "_users where name = :name and active = 1"); - passwordQuery.bindValue(":name", user); - if (!execSqlQuery(passwordQuery)) { - qDebug("Login denied: SQL error"); - return NotLoggedIn; - } - - if (passwordQuery.next()) { - const QString correctPassword = passwordQuery.value(0).toString(); - if (correctPassword == PasswordHasher::computeHash(password, correctPassword.left(16))) { - qDebug("Login accepted: password right"); - return PasswordRight; - } else { - qDebug("Login denied: password wrong"); - return NotLoggedIn; - } - } else { - qDebug("Login accepted: unknown user"); - return UnknownUser; - } - } - } - return UnknownUser; + if (!usernameIsValid(user)) + return UsernameInvalid; + + QSqlQuery *ipBanQuery = prepareQuery("select time_to_sec(timediff(now(), date_add(b.time_from, interval b.minutes minute))), b.minutes <=> 0, b.visible_reason from {prefix}_bans b where b.time_from = (select max(c.time_from) from {prefix}_bans c where c.ip_address = :address) and b.ip_address = :address2"); + ipBanQuery->bindValue(":address", static_cast(handler)->getPeerAddress().toString()); + ipBanQuery->bindValue(":address2", static_cast(handler)->getPeerAddress().toString()); + if (!execSqlQuery(ipBanQuery)) { + qDebug("Login denied: SQL error"); + return NotLoggedIn; + } + + if (ipBanQuery->next()) { + const int secondsLeft = -ipBanQuery->value(0).toInt(); + const bool permanentBan = ipBanQuery->value(1).toInt(); + if ((secondsLeft > 0) || permanentBan) { + reasonStr = ipBanQuery->value(2).toString(); + banSecondsLeft = permanentBan ? 0 : secondsLeft; + qDebug("Login denied: banned by address"); + return UserIsBanned; + } + } + + QSqlQuery *nameBanQuery = prepareQuery("select time_to_sec(timediff(now(), date_add(b.time_from, interval b.minutes minute))), b.minutes <=> 0, b.visible_reason from {prefix}_bans b where b.time_from = (select max(c.time_from) from {prefix}_bans c where c.user_name = :name2) and b.user_name = :name1"); + nameBanQuery->bindValue(":name1", user); + nameBanQuery->bindValue(":name2", user); + if (!execSqlQuery(nameBanQuery)) { + qDebug("Login denied: SQL error"); + return NotLoggedIn; + } + + if (nameBanQuery->next()) { + const int secondsLeft = -nameBanQuery->value(0).toInt(); + const bool permanentBan = nameBanQuery->value(1).toInt(); + if ((secondsLeft > 0) || permanentBan) { + reasonStr = nameBanQuery->value(2).toString(); + banSecondsLeft = permanentBan ? 0 : secondsLeft; + qDebug("Login denied: banned by name"); + return UserIsBanned; + } + } + + QSqlQuery *passwordQuery = prepareQuery("select password_sha512 from {prefix}_users where name = :name and active = 1"); + passwordQuery->bindValue(":name", user); + if (!execSqlQuery(passwordQuery)) { + qDebug("Login denied: SQL error"); + return NotLoggedIn; + } + + if (passwordQuery->next()) { + const QString correctPassword = passwordQuery->value(0).toString(); + if (correctPassword == PasswordHasher::computeHash(password, correctPassword.left(16))) { + qDebug("Login accepted: password right"); + return PasswordRight; + } else { + qDebug("Login denied: password wrong"); + return NotLoggedIn; + } + } else { + qDebug("Login accepted: unknown user"); + return UnknownUser; + } + } + } + return UnknownUser; } bool Servatrice_DatabaseInterface::userExists(const QString &user) { - if (server->getAuthenticationMethod() == Servatrice::AuthenticationSql) { - checkSql(); - - QSqlQuery query(sqlDatabase); - query.prepare("select 1 from " + server->getDbPrefix() + "_users where name = :name and active = 1"); - query.bindValue(":name", user); - if (!execSqlQuery(query)) - return false; - return query.next(); - } - return false; + if (server->getAuthenticationMethod() == Servatrice::AuthenticationSql) { + checkSql(); + + QSqlQuery *query = prepareQuery("select 1 from {prefix}_users where name = :name and active = 1"); + query->bindValue(":name", user); + if (!execSqlQuery(query)) + return false; + return query->next(); + } + return false; } int Servatrice_DatabaseInterface::getUserIdInDB(const QString &name) { - if (server->getAuthenticationMethod() == Servatrice::AuthenticationSql) { - QSqlQuery query(sqlDatabase); - query.prepare("select id from " + server->getDbPrefix() + "_users where name = :name and active = 1"); - query.bindValue(":name", name); - if (!execSqlQuery(query)) - return -1; - if (!query.next()) - return -1; - return query.value(0).toInt(); - } - return -1; + if (server->getAuthenticationMethod() == Servatrice::AuthenticationSql) { + QSqlQuery *query = prepareQuery("select id from {prefix}_users where name = :name and active = 1"); + query->bindValue(":name", name); + if (!execSqlQuery(query)) + return -1; + if (!query->next()) + return -1; + return query->value(0).toInt(); + } + return -1; } bool Servatrice_DatabaseInterface::isInBuddyList(const QString &whoseList, const QString &who) { - if (server->getAuthenticationMethod() == Servatrice::AuthenticationNone) - return false; - - if (!checkSql()) - return false; - - int id1 = getUserIdInDB(whoseList); - int id2 = getUserIdInDB(who); - - QSqlQuery query(sqlDatabase); - query.prepare("select 1 from " + server->getDbPrefix() + "_buddylist where id_user1 = :id_user1 and id_user2 = :id_user2"); - query.bindValue(":id_user1", id1); - query.bindValue(":id_user2", id2); - if (!execSqlQuery(query)) - return false; - return query.next(); + if (server->getAuthenticationMethod() == Servatrice::AuthenticationNone) + return false; + + if (!checkSql()) + return false; + + int id1 = getUserIdInDB(whoseList); + int id2 = getUserIdInDB(who); + + QSqlQuery *query = prepareQuery("select 1 from {prefix}_buddylist where id_user1 = :id_user1 and id_user2 = :id_user2"); + query->bindValue(":id_user1", id1); + query->bindValue(":id_user2", id2); + if (!execSqlQuery(query)) + return false; + return query->next(); } bool Servatrice_DatabaseInterface::isInIgnoreList(const QString &whoseList, const QString &who) { - if (server->getAuthenticationMethod() == Servatrice::AuthenticationNone) - return false; - - if (!checkSql()) - return false; - - int id1 = getUserIdInDB(whoseList); - int id2 = getUserIdInDB(who); - - QSqlQuery query(sqlDatabase); - query.prepare("select 1 from " + server->getDbPrefix() + "_ignorelist where id_user1 = :id_user1 and id_user2 = :id_user2"); - query.bindValue(":id_user1", id1); - query.bindValue(":id_user2", id2); - if (!execSqlQuery(query)) - return false; - return query.next(); + if (server->getAuthenticationMethod() == Servatrice::AuthenticationNone) + return false; + + if (!checkSql()) + return false; + + int id1 = getUserIdInDB(whoseList); + int id2 = getUserIdInDB(who); + + QSqlQuery *query = prepareQuery("select 1 from {prefix}_ignorelist where id_user1 = :id_user1 and id_user2 = :id_user2"); + query->bindValue(":id_user1", id1); + query->bindValue(":id_user2", id2); + if (!execSqlQuery(query)) + return false; + return query->next(); } -ServerInfo_User Servatrice_DatabaseInterface::evalUserQueryResult(const QSqlQuery &query, bool complete, bool withId) +ServerInfo_User Servatrice_DatabaseInterface::evalUserQueryResult(const QSqlQuery *query, bool complete, bool withId) { - ServerInfo_User result; - - if (withId) - result.set_id(query.value(0).toInt()); - result.set_name(query.value(1).toString().toStdString()); - - const QString country = query.value(5).toString(); - if (!country.isEmpty()) - result.set_country(country.toStdString()); - - if (complete) { - const QByteArray avatarBmp = query.value(6).toByteArray(); - if (avatarBmp.size()) - result.set_avatar_bmp(avatarBmp.data(), avatarBmp.size()); - } - - const QString genderStr = query.value(4).toString(); - if (genderStr == "m") - result.set_gender(ServerInfo_User::Male); - else if (genderStr == "f") - result.set_gender(ServerInfo_User::Female); - - const int is_admin = query.value(2).toInt(); - int userLevel = ServerInfo_User::IsUser | ServerInfo_User::IsRegistered; - if (is_admin == 1) - userLevel |= ServerInfo_User::IsAdmin | ServerInfo_User::IsModerator; - else if (is_admin == 2) - userLevel |= ServerInfo_User::IsModerator; - result.set_user_level(userLevel); - - const QString realName = query.value(3).toString(); - if (!realName.isEmpty()) - result.set_real_name(realName.toStdString()); + ServerInfo_User result; + + if (withId) + result.set_id(query->value(0).toInt()); + result.set_name(query->value(1).toString().toStdString()); + + const QString country = query->value(5).toString(); + if (!country.isEmpty()) + result.set_country(country.toStdString()); + + if (complete) { + const QByteArray avatarBmp = query->value(6).toByteArray(); + if (avatarBmp.size()) + result.set_avatar_bmp(avatarBmp.data(), avatarBmp.size()); + } + + const QString genderStr = query->value(4).toString(); + if (genderStr == "m") + result.set_gender(ServerInfo_User::Male); + else if (genderStr == "f") + result.set_gender(ServerInfo_User::Female); + + const int is_admin = query->value(2).toInt(); + int userLevel = ServerInfo_User::IsUser | ServerInfo_User::IsRegistered; + if (is_admin == 1) + userLevel |= ServerInfo_User::IsAdmin | ServerInfo_User::IsModerator; + else if (is_admin == 2) + userLevel |= ServerInfo_User::IsModerator; + result.set_user_level(userLevel); + + const QString realName = query->value(3).toString(); + if (!realName.isEmpty()) + result.set_real_name(realName.toStdString()); - const QDateTime regDate = query.value(7).toDateTime(); + const QDateTime regDate = query->value(7).toDateTime(); if(!regDate.toString(Qt::ISODate).isEmpty()) { qint64 accountAgeInSeconds = regDate.secsTo(QDateTime::currentDateTime()); result.set_accountage_secs(accountAgeInSeconds); } - - return result; + + return result; } ServerInfo_User Servatrice_DatabaseInterface::getUserData(const QString &name, bool withId) { - ServerInfo_User result; - result.set_name(name.toStdString()); - result.set_user_level(ServerInfo_User::IsUser); - - if (server->getAuthenticationMethod() == Servatrice::AuthenticationSql) { - if (!checkSql()) - return result; - - QSqlQuery query(sqlDatabase); - query.prepare("select id, name, admin, realname, gender, country, avatar_bmp, registrationDate from " + server->getDbPrefix() + "_users where name = :name and active = 1"); - query.bindValue(":name", name); - if (!execSqlQuery(query)) - return result; - - if (query.next()) - return evalUserQueryResult(query, true, withId); - else - return result; - } else - return result; + ServerInfo_User result; + result.set_name(name.toStdString()); + result.set_user_level(ServerInfo_User::IsUser); + + if (server->getAuthenticationMethod() == Servatrice::AuthenticationSql) { + if (!checkSql()) + return result; + + QSqlQuery *query = prepareQuery("select id, name, admin, realname, gender, country, avatar_bmp, registrationDate from {prefix}_users where name = :name and active = 1"); + query->bindValue(":name", name); + if (!execSqlQuery(query)) + return result; + + if (query->next()) + return evalUserQueryResult(query, true, withId); + else + return result; + } else + return result; } void Servatrice_DatabaseInterface::clearSessionTables() { - lockSessionTables(); - QSqlQuery query(sqlDatabase); - query.prepare("update " + server->getDbPrefix() + "_sessions set end_time=now() where end_time is null and id_server = :id_server"); - query.bindValue(":id_server", server->getServerId()); - query.exec(); - unlockSessionTables(); + lockSessionTables(); + QSqlQuery *query = prepareQuery("update {prefix}_sessions set end_time=now() where end_time is null and id_server = :id_server"); + query->bindValue(":id_server", server->getServerId()); + execSqlQuery(query); + unlockSessionTables(); } void Servatrice_DatabaseInterface::lockSessionTables() { - QSqlQuery("lock tables " + server->getDbPrefix() + "_sessions write, " + server->getDbPrefix() + "_users read", sqlDatabase); + QSqlQuery *query = prepareQuery("lock tables {prefix}_sessions write, {prefix}_users read"); + execSqlQuery(query); } void Servatrice_DatabaseInterface::unlockSessionTables() { - QSqlQuery("unlock tables", sqlDatabase); + QSqlQuery *query = prepareQuery("unlock tables"); + execSqlQuery(query); } bool Servatrice_DatabaseInterface::userSessionExists(const QString &userName) { - // Call only after lockSessionTables(). - - QSqlQuery query(sqlDatabase); - query.prepare("select 1 from " + server->getDbPrefix() + "_sessions where user_name = :user_name and end_time is null"); - query.bindValue(":user_name", userName); - query.exec(); - return query.next(); + // Call only after lockSessionTables(). + + QSqlQuery *query = prepareQuery("select 1 from {prefix}_sessions where user_name = :user_name and end_time is null"); + query->bindValue(":user_name", userName); + execSqlQuery(query); + return query->next(); } qint64 Servatrice_DatabaseInterface::startSession(const QString &userName, const QString &address) { - if (server->getAuthenticationMethod() == Servatrice::AuthenticationNone) - return -1; - - if (!checkSql()) - return -1; - - QSqlQuery query(sqlDatabase); - query.prepare("insert into " + server->getDbPrefix() + "_sessions (user_name, id_server, ip_address, start_time) values(:user_name, :id_server, :ip_address, NOW())"); - query.bindValue(":user_name", userName); - query.bindValue(":id_server", server->getServerId()); - query.bindValue(":ip_address", address); - if (execSqlQuery(query)) - return query.lastInsertId().toInt(); - return -1; + if (server->getAuthenticationMethod() == Servatrice::AuthenticationNone) + return -1; + + if (!checkSql()) + return -1; + + QSqlQuery *query = prepareQuery("insert into {prefix}_sessions (user_name, id_server, ip_address, start_time) values(:user_name, :id_server, :ip_address, NOW())"); + query->bindValue(":user_name", userName); + query->bindValue(":id_server", server->getServerId()); + query->bindValue(":ip_address", address); + if (execSqlQuery(query)) + return query->lastInsertId().toInt(); + return -1; } void Servatrice_DatabaseInterface::endSession(qint64 sessionId) { - if (server->getAuthenticationMethod() == Servatrice::AuthenticationNone) - return; - - if (!checkSql()) - return; - - QSqlQuery query(sqlDatabase); - query.exec("lock tables " + server->getDbPrefix() + "_sessions write"); - query.prepare("update " + server->getDbPrefix() + "_sessions set end_time=NOW() where id = :id_session"); - query.bindValue(":id_session", sessionId); - execSqlQuery(query); - query.exec("unlock tables"); + if (server->getAuthenticationMethod() == Servatrice::AuthenticationNone) + return; + + if (!checkSql()) + return; + + QSqlQuery *query = prepareQuery("lock tables {prefix}_sessions write"); + execSqlQuery(query); + + query = prepareQuery("update {prefix}_sessions set end_time=NOW() where id = :id_session"); + query->bindValue(":id_session", sessionId); + execSqlQuery(query); + + query = prepareQuery("unlock tables"); + execSqlQuery(query); } QMap Servatrice_DatabaseInterface::getBuddyList(const QString &name) { - QMap result; - - if (server->getAuthenticationMethod() == Servatrice::AuthenticationSql) { - checkSql(); + QMap result; + + if (server->getAuthenticationMethod() == Servatrice::AuthenticationSql) { + checkSql(); - QSqlQuery query(sqlDatabase); - query.prepare("select a.id, a.name, a.admin, a.realname, a.gender, a.country from " + server->getDbPrefix() + "_users a left join " + server->getDbPrefix() + "_buddylist b on a.id = b.id_user2 left join " + server->getDbPrefix() + "_users c on b.id_user1 = c.id where c.name = :name"); - query.bindValue(":name", name); - if (!execSqlQuery(query)) - return result; - - while (query.next()) { - const ServerInfo_User &temp = evalUserQueryResult(query, false); - result.insert(QString::fromStdString(temp.name()), temp); - } - } - return result; + QSqlQuery *query = prepareQuery("select a.id, a.name, a.admin, a.realname, a.gender, a.country from {prefix}_users a left join {prefix}_buddylist b on a.id = b.id_user2 left join {prefix}_users c on b.id_user1 = c.id where c.name = :name"); + query->bindValue(":name", name); + if (!execSqlQuery(query)) + return result; + + while (query->next()) { + const ServerInfo_User &temp = evalUserQueryResult(query, false); + result.insert(QString::fromStdString(temp.name()), temp); + } + } + return result; } QMap Servatrice_DatabaseInterface::getIgnoreList(const QString &name) { - QMap result; - - if (server->getAuthenticationMethod() == Servatrice::AuthenticationSql) { - checkSql(); + QMap result; + + if (server->getAuthenticationMethod() == Servatrice::AuthenticationSql) { + checkSql(); - QSqlQuery query(sqlDatabase); - query.prepare("select a.id, a.name, a.admin, a.realname, a.gender, a.country from " + server->getDbPrefix() + "_users a left join " + server->getDbPrefix() + "_ignorelist b on a.id = b.id_user2 left join " + server->getDbPrefix() + "_users c on b.id_user1 = c.id where c.name = :name"); - query.bindValue(":name", name); - if (!execSqlQuery(query)) - return result; - - while (query.next()) { - ServerInfo_User temp = evalUserQueryResult(query, false); - result.insert(QString::fromStdString(temp.name()), temp); - } - } - return result; + QSqlQuery *query = prepareQuery("select a.id, a.name, a.admin, a.realname, a.gender, a.country from {prefix}_users a left join {prefix}_ignorelist b on a.id = b.id_user2 left join {prefix}_users c on b.id_user1 = c.id where c.name = :name"); + query->bindValue(":name", name); + if (!execSqlQuery(query)) + return result; + + while (query->next()) { + ServerInfo_User temp = evalUserQueryResult(query, false); + result.insert(QString::fromStdString(temp.name()), temp); + } + } + return result; } int Servatrice_DatabaseInterface::getNextGameId() { - if (!sqlDatabase.isValid()) - return server->getNextLocalGameId(); - - if (!checkSql()) - return -1; - - QSqlQuery query(sqlDatabase); - query.prepare("insert into " + server->getDbPrefix() + "_games (time_started) values (now())"); - execSqlQuery(query); - - return query.lastInsertId().toInt(); + if (!sqlDatabase.isValid()) + return server->getNextLocalGameId(); + + if (!checkSql()) + return -1; + + QSqlQuery *query = prepareQuery("insert into {prefix}_games (time_started) values (now())"); + execSqlQuery(query); + + return query->lastInsertId().toInt(); } int Servatrice_DatabaseInterface::getNextReplayId() { - if (!checkSql()) - return -1; - - QSqlQuery query(sqlDatabase); - query.prepare("insert into " + server->getDbPrefix() + "_replays () values ()"); - execSqlQuery(query); - - return query.lastInsertId().toInt(); + if (!checkSql()) + return -1; + + QSqlQuery *query = prepareQuery("insert into {prefix}_replays () values ()"); + execSqlQuery(query); + + return query->lastInsertId().toInt(); } void Servatrice_DatabaseInterface::storeGameInformation(const QString &roomName, const QStringList &roomGameTypes, const ServerInfo_Game &gameInfo, const QSet &allPlayersEver, const QSet &allSpectatorsEver, const QList &replayList) { - if (!checkSql()) - return; - - QVariantList gameIds1, playerNames, gameIds2, userIds, replayNames; - QSetIterator playerIterator(allPlayersEver); - while (playerIterator.hasNext()) { - gameIds1.append(gameInfo.game_id()); - const QString &playerName = playerIterator.next(); - playerNames.append(playerName); - } - QSet allUsersInGame = allPlayersEver + allSpectatorsEver; - QSetIterator allUsersIterator(allUsersInGame); - while (allUsersIterator.hasNext()) { - int id = getUserIdInDB(allUsersIterator.next()); - if (id == -1) - continue; - gameIds2.append(gameInfo.game_id()); - userIds.append(id); - replayNames.append(QString::fromStdString(gameInfo.description())); - } - - QVariantList replayIds, replayGameIds, replayDurations, replayBlobs; - for (int i = 0; i < replayList.size(); ++i) { - QByteArray blob; - const unsigned int size = replayList[i]->ByteSize(); - blob.resize(size); - replayList[i]->SerializeToArray(blob.data(), size); - - replayIds.append(QVariant((qulonglong) replayList[i]->replay_id())); - replayGameIds.append(gameInfo.game_id()); - replayDurations.append(replayList[i]->duration_seconds()); - replayBlobs.append(blob); - } - - { - QSqlQuery query(sqlDatabase); - query.prepare("update " + server->getDbPrefix() + "_games set room_name=:room_name, descr=:descr, creator_name=:creator_name, password=:password, game_types=:game_types, player_count=:player_count, time_finished=now() where id=:id_game"); - query.bindValue(":room_name", roomName); - query.bindValue(":id_game", gameInfo.game_id()); - query.bindValue(":descr", QString::fromStdString(gameInfo.description())); - query.bindValue(":creator_name", QString::fromStdString(gameInfo.creator_info().name())); - query.bindValue(":password", gameInfo.with_password() ? 1 : 0); - query.bindValue(":game_types", roomGameTypes.isEmpty() ? QString("") : roomGameTypes.join(", ")); - query.bindValue(":player_count", gameInfo.max_players()); - if (!execSqlQuery(query)) - return; - } - { - QSqlQuery query(sqlDatabase); - query.prepare("insert into " + server->getDbPrefix() + "_games_players (id_game, player_name) values (:id_game, :player_name)"); - query.bindValue(":id_game", gameIds1); - query.bindValue(":player_name", playerNames); - query.execBatch(); - } - { - QSqlQuery query(sqlDatabase); - query.prepare("update " + server->getDbPrefix() + "_replays set id_game=:id_game, duration=:duration, replay=:replay where id=:id_replay"); - query.bindValue(":id_replay", replayIds); - query.bindValue(":id_game", replayGameIds); - query.bindValue(":duration", replayDurations); - query.bindValue(":replay", replayBlobs); - query.execBatch(); - } - { - QSqlQuery query(sqlDatabase); - query.prepare("insert into " + server->getDbPrefix() + "_replays_access (id_game, id_player, replay_name) values (:id_game, :id_player, :replay_name)"); - query.bindValue(":id_game", gameIds2); - query.bindValue(":id_player", userIds); - query.bindValue(":replay_name", replayNames); - query.execBatch(); - } + if (!checkSql()) + return; + + QVariantList gameIds1, playerNames, gameIds2, userIds, replayNames; + QSetIterator playerIterator(allPlayersEver); + while (playerIterator.hasNext()) { + gameIds1.append(gameInfo.game_id()); + const QString &playerName = playerIterator.next(); + playerNames.append(playerName); + } + QSet allUsersInGame = allPlayersEver + allSpectatorsEver; + QSetIterator allUsersIterator(allUsersInGame); + while (allUsersIterator.hasNext()) { + int id = getUserIdInDB(allUsersIterator.next()); + if (id == -1) + continue; + gameIds2.append(gameInfo.game_id()); + userIds.append(id); + replayNames.append(QString::fromStdString(gameInfo.description())); + } + + QVariantList replayIds, replayGameIds, replayDurations, replayBlobs; + for (int i = 0; i < replayList.size(); ++i) { + QByteArray blob; + const unsigned int size = replayList[i]->ByteSize(); + blob.resize(size); + replayList[i]->SerializeToArray(blob.data(), size); + + replayIds.append(QVariant((qulonglong) replayList[i]->replay_id())); + replayGameIds.append(gameInfo.game_id()); + replayDurations.append(replayList[i]->duration_seconds()); + replayBlobs.append(blob); + } + + { + QSqlQuery *query = prepareQuery("update {prefix}_games set room_name=:room_name, descr=:descr, creator_name=:creator_name, password=:password, game_types=:game_types, player_count=:player_count, time_finished=now() where id=:id_game"); + query->bindValue(":room_name", roomName); + query->bindValue(":id_game", gameInfo.game_id()); + query->bindValue(":descr", QString::fromStdString(gameInfo.description())); + query->bindValue(":creator_name", QString::fromStdString(gameInfo.creator_info().name())); + query->bindValue(":password", gameInfo.with_password() ? 1 : 0); + query->bindValue(":game_types", roomGameTypes.isEmpty() ? QString("") : roomGameTypes.join(", ")); + query->bindValue(":player_count", gameInfo.max_players()); + if (!execSqlQuery(query)) + return; + } + { + QSqlQuery *query = prepareQuery("insert into {prefix}_games_players (id_game, player_name) values (:id_game, :player_name)"); + query->bindValue(":id_game", gameIds1); + query->bindValue(":player_name", playerNames); + query->execBatch(); + } + { + QSqlQuery *query = prepareQuery("update {prefix}_replays set id_game=:id_game, duration=:duration, replay=:replay where id=:id_replay"); + query->bindValue(":id_replay", replayIds); + query->bindValue(":id_game", replayGameIds); + query->bindValue(":duration", replayDurations); + query->bindValue(":replay", replayBlobs); + query->execBatch(); + } + { + QSqlQuery *query = prepareQuery("insert into {prefix}_replays_access (id_game, id_player, replay_name) values (:id_game, :id_player, :replay_name)"); + query->bindValue(":id_game", gameIds2); + query->bindValue(":id_player", userIds); + query->bindValue(":replay_name", replayNames); + query->execBatch(); + } } DeckList *Servatrice_DatabaseInterface::getDeckFromDatabase(int deckId, int userId) { - checkSql(); - - QSqlQuery query(sqlDatabase); - - query.prepare("select content from " + server->getDbPrefix() + "_decklist_files where id = :id and id_user = :id_user"); - query.bindValue(":id", deckId); - query.bindValue(":id_user", userId); - execSqlQuery(query); - if (!query.next()) - throw Response::RespNameNotFound; - - DeckList *deck = new DeckList; - deck->loadFromString_Native(query.value(0).toString()); - - return deck; + checkSql(); + + QSqlQuery *query = prepareQuery("select content from {prefix}_decklist_files where id = :id and id_user = :id_user"); + query->bindValue(":id", deckId); + query->bindValue(":id_user", userId); + execSqlQuery(query); + if (!query->next()) + throw Response::RespNameNotFound; + + DeckList *deck = new DeckList; + deck->loadFromString_Native(query->value(0).toString()); + + return deck; } void Servatrice_DatabaseInterface::logMessage(const int senderId, const QString &senderName, const QString &senderIp, const QString &logMessage, LogMessage_TargetType targetType, const int targetId, const QString &targetName) { - QSqlQuery query(sqlDatabase); - QString targetTypeString; - switch(targetType) - { - case MessageTargetRoom: - if(!settingsCache->value("logging/log_user_msg_room", 0).toBool()) - return; - targetTypeString = "room"; - break; - case MessageTargetGame: - if(!settingsCache->value("logging/log_user_msg_game", 0).toBool()) - return; - targetTypeString = "game"; - break; - case MessageTargetChat: - if(!settingsCache->value("logging/log_user_msg_chat", 0).toBool()) - return; - targetTypeString = "chat"; - break; - case MessageTargetIslRoom: - if(!settingsCache->value("logging/log_user_msg_isl", 0).toBool()) - return; - targetTypeString = "room"; - break; - default: - return; - } + QString targetTypeString; + switch(targetType) + { + case MessageTargetRoom: + if(!settingsCache->value("logging/log_user_msg_room", 0).toBool()) + return; + targetTypeString = "room"; + break; + case MessageTargetGame: + if(!settingsCache->value("logging/log_user_msg_game", 0).toBool()) + return; + targetTypeString = "game"; + break; + case MessageTargetChat: + if(!settingsCache->value("logging/log_user_msg_chat", 0).toBool()) + return; + targetTypeString = "chat"; + break; + case MessageTargetIslRoom: + if(!settingsCache->value("logging/log_user_msg_isl", 0).toBool()) + return; + targetTypeString = "room"; + break; + default: + return; + } - query.prepare("insert into " + server->getDbPrefix() + "_log (log_time, sender_id, sender_name, sender_ip, log_message, target_type, target_id, target_name) values (now(), :sender_id, :sender_name, :sender_ip, :log_message, :target_type, :target_id, :target_name)"); - query.bindValue(":sender_id", senderId < 1 ? QVariant() : senderId); - query.bindValue(":sender_name", senderName); - query.bindValue(":sender_ip", senderIp); - query.bindValue(":log_message", logMessage); - query.bindValue(":target_type", targetTypeString); - query.bindValue(":target_id", (targetType == MessageTargetChat && targetId < 1) ? QVariant() : targetId); - query.bindValue(":target_name", targetName); - execSqlQuery(query); + QSqlQuery *query = prepareQuery("insert into {prefix}_log (log_time, sender_id, sender_name, sender_ip, log_message, target_type, target_id, target_name) values (now(), :sender_id, :sender_name, :sender_ip, :log_message, :target_type, :target_id, :target_name)"); + query->bindValue(":sender_id", senderId < 1 ? QVariant() : senderId); + query->bindValue(":sender_name", senderName); + query->bindValue(":sender_ip", senderIp); + query->bindValue(":log_message", logMessage); + query->bindValue(":target_type", targetTypeString); + query->bindValue(":target_id", (targetType == MessageTargetChat && targetId < 1) ? QVariant() : targetId); + query->bindValue(":target_name", targetName); + execSqlQuery(query); } diff --git a/servatrice/src/servatrice_database_interface.h b/servatrice/src/servatrice_database_interface.h index 9488ded8..8850d7be 100644 --- a/servatrice/src/servatrice_database_interface.h +++ b/servatrice/src/servatrice_database_interface.h @@ -3,6 +3,7 @@ #include #include +#include #include "server.h" #include "server_database_interface.h" @@ -14,8 +15,9 @@ class Servatrice_DatabaseInterface : public Server_DatabaseInterface { private: int instanceId; QSqlDatabase sqlDatabase; + QHash preparedStatements; Servatrice *server; - ServerInfo_User evalUserQueryResult(const QSqlQuery &query, bool complete, bool withId = false); + ServerInfo_User evalUserQueryResult(const QSqlQuery *query, bool complete, bool withId = false); bool usernameIsValid(const QString &user); protected: AuthenticationResult checkUserPassword(Server_ProtocolHandler *handler, const QString &user, const QString &password, QString &reasonStr, int &secondsLeft); @@ -27,7 +29,8 @@ public: void initDatabase(const QString &type, const QString &hostName, const QString &databaseName, const QString &userName, const QString &password); bool openDatabase(); bool checkSql(); - bool execSqlQuery(QSqlQuery &query); + QSqlQuery * prepareQuery(const QString &queryText); + bool execSqlQuery(QSqlQuery *query); const QSqlDatabase &getDatabase() { return sqlDatabase; } bool userExists(const QString &user); diff --git a/servatrice/src/serversocketinterface.cpp b/servatrice/src/serversocketinterface.cpp index 87e17596..3abb5326 100644 --- a/servatrice/src/serversocketinterface.cpp +++ b/servatrice/src/serversocketinterface.cpp @@ -289,10 +289,9 @@ Response::ResponseCode ServerSocketInterface::cmdAddToList(const Command_AddToLi if (id1 == id2) return Response::RespContextError; - QSqlQuery query(sqlInterface->getDatabase()); - query.prepare("insert into " + servatrice->getDbPrefix() + "_" + list + "list (id_user1, id_user2) values(:id1, :id2)"); - query.bindValue(":id1", id1); - query.bindValue(":id2", id2); + QSqlQuery *query = sqlInterface->prepareQuery("insert into {prefix}_" + list + "list (id_user1, id_user2) values(:id1, :id2)"); + query->bindValue(":id1", id1); + query->bindValue(":id2", id2); if (!sqlInterface->execSqlQuery(query)) return Response::RespInternalError; @@ -327,10 +326,9 @@ Response::ResponseCode ServerSocketInterface::cmdRemoveFromList(const Command_Re if (id2 < 0) return Response::RespNameNotFound; - QSqlQuery query(sqlInterface->getDatabase()); - query.prepare("delete from " + servatrice->getDbPrefix() + "_" + list + "list where id_user1 = :id1 and id_user2 = :id2"); - query.bindValue(":id1", id1); - query.bindValue(":id2", id2); + QSqlQuery *query = sqlInterface->prepareQuery("delete from {prefix}_" + list + "list where id_user1 = :id1 and id_user2 = :id2"); + query->bindValue(":id1", id1); + query->bindValue(":id2", id2); if (!sqlInterface->execSqlQuery(query)) return Response::RespInternalError; @@ -349,16 +347,15 @@ int ServerSocketInterface::getDeckPathId(int basePathId, QStringList path) if (path[0].isEmpty()) return 0; - QSqlQuery query(sqlInterface->getDatabase()); - query.prepare("select id from " + servatrice->getDbPrefix() + "_decklist_folders where id_parent = :id_parent and name = :name and id_user = :id_user"); - query.bindValue(":id_parent", basePathId); - query.bindValue(":name", path.takeFirst()); - query.bindValue(":id_user", userInfo->id()); + QSqlQuery *query = sqlInterface->prepareQuery("select id from {prefix}_decklist_folders where id_parent = :id_parent and name = :name and id_user = :id_user"); + query->bindValue(":id_parent", basePathId); + query->bindValue(":name", path.takeFirst()); + query->bindValue(":id_user", userInfo->id()); if (!sqlInterface->execSqlQuery(query)) return -1; - if (!query.next()) + if (!query->next()) return -1; - int id = query.value(0).toInt(); + int id = query->value(0).toInt(); if (path.isEmpty()) return id; else @@ -372,35 +369,34 @@ int ServerSocketInterface::getDeckPathId(const QString &path) bool ServerSocketInterface::deckListHelper(int folderId, ServerInfo_DeckStorage_Folder *folder) { - QSqlQuery query(sqlInterface->getDatabase()); - query.prepare("select id, name from " + servatrice->getDbPrefix() + "_decklist_folders where id_parent = :id_parent and id_user = :id_user"); - query.bindValue(":id_parent", folderId); - query.bindValue(":id_user", userInfo->id()); + QSqlQuery *query = sqlInterface->prepareQuery("select id, name from {prefix}_decklist_folders where id_parent = :id_parent and id_user = :id_user"); + query->bindValue(":id_parent", folderId); + query->bindValue(":id_user", userInfo->id()); if (!sqlInterface->execSqlQuery(query)) return false; - while (query.next()) { + while (query->next()) { ServerInfo_DeckStorage_TreeItem *newItem = folder->add_items(); - newItem->set_id(query.value(0).toInt()); - newItem->set_name(query.value(1).toString().toStdString()); + newItem->set_id(query->value(0).toInt()); + newItem->set_name(query->value(1).toString().toStdString()); if (!deckListHelper(newItem->id(), newItem->mutable_folder())) return false; } - query.prepare("select id, name, upload_time from " + servatrice->getDbPrefix() + "_decklist_files where id_folder = :id_folder and id_user = :id_user"); - query.bindValue(":id_folder", folderId); - query.bindValue(":id_user", userInfo->id()); + query = sqlInterface->prepareQuery("select id, name, upload_time from {prefix}_decklist_files where id_folder = :id_folder and id_user = :id_user"); + query->bindValue(":id_folder", folderId); + query->bindValue(":id_user", userInfo->id()); if (!sqlInterface->execSqlQuery(query)) return false; - while (query.next()) { + while (query->next()) { ServerInfo_DeckStorage_TreeItem *newItem = folder->add_items(); - newItem->set_id(query.value(0).toInt()); - newItem->set_name(query.value(1).toString().toStdString()); + newItem->set_id(query->value(0).toInt()); + newItem->set_name(query->value(1).toString().toStdString()); ServerInfo_DeckStorage_File *newFile = newItem->mutable_file(); - newFile->set_creation_time(query.value(2).toDateTime().toTime_t()); + newFile->set_creation_time(query->value(2).toDateTime().toTime_t()); } return true; @@ -437,11 +433,10 @@ Response::ResponseCode ServerSocketInterface::cmdDeckNewDir(const Command_DeckNe if (folderId == -1) return Response::RespNameNotFound; - QSqlQuery query(sqlInterface->getDatabase()); - query.prepare("insert into " + servatrice->getDbPrefix() + "_decklist_folders (id_parent, id_user, name) values(:id_parent, :id_user, :name)"); - query.bindValue(":id_parent", folderId); - query.bindValue(":id_user", userInfo->id()); - query.bindValue(":name", QString::fromStdString(cmd.dir_name())); + QSqlQuery *query = sqlInterface->prepareQuery("insert into {prefix}_decklist_folders (id_parent, id_user, name) values(:id_parent, :id_user, :name)"); + query->bindValue(":id_parent", folderId); + query->bindValue(":id_user", userInfo->id()); + query->bindValue(":name", QString::fromStdString(cmd.dir_name())); if (!sqlInterface->execSqlQuery(query)) return Response::RespContextError; return Response::RespOk; @@ -450,20 +445,18 @@ Response::ResponseCode ServerSocketInterface::cmdDeckNewDir(const Command_DeckNe void ServerSocketInterface::deckDelDirHelper(int basePathId) { sqlInterface->checkSql(); - QSqlQuery query(sqlInterface->getDatabase()); - - query.prepare("select id from " + servatrice->getDbPrefix() + "_decklist_folders where id_parent = :id_parent"); - query.bindValue(":id_parent", basePathId); + QSqlQuery *query = sqlInterface->prepareQuery("select id from {prefix}_decklist_folders where id_parent = :id_parent"); + query->bindValue(":id_parent", basePathId); sqlInterface->execSqlQuery(query); - while (query.next()) - deckDelDirHelper(query.value(0).toInt()); + while (query->next()) + deckDelDirHelper(query->value(0).toInt()); - query.prepare("delete from " + servatrice->getDbPrefix() + "_decklist_files where id_folder = :id_folder"); - query.bindValue(":id_folder", basePathId); + query = sqlInterface->prepareQuery("delete from {prefix}_decklist_files where id_folder = :id_folder"); + query->bindValue(":id_folder", basePathId); sqlInterface->execSqlQuery(query); - query.prepare("delete from " + servatrice->getDbPrefix() + "_decklist_folders where id = :id"); - query.bindValue(":id", basePathId); + query = sqlInterface->prepareQuery("delete from {prefix}_decklist_folders where id = :id"); + query->bindValue(":id", basePathId); sqlInterface->execSqlQuery(query); } @@ -487,17 +480,15 @@ Response::ResponseCode ServerSocketInterface::cmdDeckDel(const Command_DeckDel & return Response::RespFunctionNotAllowed; sqlInterface->checkSql(); - QSqlQuery query(sqlInterface->getDatabase()); - - query.prepare("select id from " + servatrice->getDbPrefix() + "_decklist_files where id = :id and id_user = :id_user"); - query.bindValue(":id", cmd.deck_id()); - query.bindValue(":id_user", userInfo->id()); + QSqlQuery *query = sqlInterface->prepareQuery("select id from {prefix}_decklist_files where id = :id and id_user = :id_user"); + query->bindValue(":id", cmd.deck_id()); + query->bindValue(":id_user", userInfo->id()); sqlInterface->execSqlQuery(query); - if (!query.next()) + if (!query->next()) return Response::RespNameNotFound; - query.prepare("delete from " + servatrice->getDbPrefix() + "_decklist_files where id = :id"); - query.bindValue(":id", cmd.deck_id()); + query = sqlInterface->prepareQuery("delete from {prefix}_decklist_files where id = :id"); + query->bindValue(":id", cmd.deck_id()); sqlInterface->execSqlQuery(query); return Response::RespOk; @@ -525,30 +516,28 @@ Response::ResponseCode ServerSocketInterface::cmdDeckUpload(const Command_DeckUp if (folderId == -1) return Response::RespNameNotFound; - QSqlQuery query(sqlInterface->getDatabase()); - query.prepare("insert into " + servatrice->getDbPrefix() + "_decklist_files (id_folder, id_user, name, upload_time, content) values(:id_folder, :id_user, :name, NOW(), :content)"); - query.bindValue(":id_folder", folderId); - query.bindValue(":id_user", userInfo->id()); - query.bindValue(":name", deckName); - query.bindValue(":content", deckStr); + QSqlQuery *query = sqlInterface->prepareQuery("insert into {prefix}_decklist_files (id_folder, id_user, name, upload_time, content) values(:id_folder, :id_user, :name, NOW(), :content)"); + query->bindValue(":id_folder", folderId); + query->bindValue(":id_user", userInfo->id()); + query->bindValue(":name", deckName); + query->bindValue(":content", deckStr); sqlInterface->execSqlQuery(query); Response_DeckUpload *re = new Response_DeckUpload; ServerInfo_DeckStorage_TreeItem *fileInfo = re->mutable_new_file(); - fileInfo->set_id(query.lastInsertId().toInt()); + fileInfo->set_id(query->lastInsertId().toInt()); fileInfo->set_name(deckName.toStdString()); fileInfo->mutable_file()->set_creation_time(QDateTime::currentDateTime().toTime_t()); rc.setResponseExtension(re); } else if (cmd.has_deck_id()) { - QSqlQuery query(sqlInterface->getDatabase()); - query.prepare("update " + servatrice->getDbPrefix() + "_decklist_files set name=:name, upload_time=NOW(), content=:content where id = :id_deck and id_user = :id_user"); - query.bindValue(":id_deck", cmd.deck_id()); - query.bindValue(":id_user", userInfo->id()); - query.bindValue(":name", deckName); - query.bindValue(":content", deckStr); + QSqlQuery *query = sqlInterface->prepareQuery("update {prefix}_decklist_files set name=:name, upload_time=NOW(), content=:content where id = :id_deck and id_user = :id_user"); + query->bindValue(":id_deck", cmd.deck_id()); + query->bindValue(":id_user", userInfo->id()); + query->bindValue(":name", deckName); + query->bindValue(":content", deckStr); sqlInterface->execSqlQuery(query); - if (query.numRowsAffected() == 0) + if (query->numRowsAffected() == 0) return Response::RespNameNotFound; Response_DeckUpload *re = new Response_DeckUpload; @@ -590,42 +579,39 @@ Response::ResponseCode ServerSocketInterface::cmdReplayList(const Command_Replay Response_ReplayList *re = new Response_ReplayList; - QSqlQuery query1(sqlInterface->getDatabase()); - query1.prepare("select a.id_game, a.replay_name, b.room_name, b.time_started, b.time_finished, b.descr, a.do_not_hide from cockatrice_replays_access a left join cockatrice_games b on b.id = a.id_game where a.id_player = :id_player and (a.do_not_hide = 1 or date_add(b.time_started, interval 7 day) > now())"); - query1.bindValue(":id_player", userInfo->id()); + QSqlQuery *query1 = sqlInterface->prepareQuery("select a.id_game, a.replay_name, b.room_name, b.time_started, b.time_finished, b.descr, a.do_not_hide from cockatrice_replays_access a left join cockatrice_games b on b.id = a.id_game where a.id_player = :id_player and (a.do_not_hide = 1 or date_add(b.time_started, interval 7 day) > now())"); + query1->bindValue(":id_player", userInfo->id()); sqlInterface->execSqlQuery(query1); - while (query1.next()) { + while (query1->next()) { ServerInfo_ReplayMatch *matchInfo = re->add_match_list(); - const int gameId = query1.value(0).toInt(); + const int gameId = query1->value(0).toInt(); matchInfo->set_game_id(gameId); - matchInfo->set_room_name(query1.value(2).toString().toStdString()); - const int timeStarted = query1.value(3).toDateTime().toTime_t(); - const int timeFinished = query1.value(4).toDateTime().toTime_t(); + matchInfo->set_room_name(query1->value(2).toString().toStdString()); + const int timeStarted = query1->value(3).toDateTime().toTime_t(); + const int timeFinished = query1->value(4).toDateTime().toTime_t(); matchInfo->set_time_started(timeStarted); matchInfo->set_length(timeFinished - timeStarted); - matchInfo->set_game_name(query1.value(5).toString().toStdString()); - const QString replayName = query1.value(1).toString(); - matchInfo->set_do_not_hide(query1.value(6).toBool()); + matchInfo->set_game_name(query1->value(5).toString().toStdString()); + const QString replayName = query1->value(1).toString(); + matchInfo->set_do_not_hide(query1->value(6).toBool()); { - QSqlQuery query2(sqlInterface->getDatabase()); - query2.prepare("select player_name from cockatrice_games_players where id_game = :id_game"); - query2.bindValue(":id_game", gameId); + QSqlQuery *query2 = sqlInterface->prepareQuery("select player_name from cockatrice_games_players where id_game = :id_game"); + query2->bindValue(":id_game", gameId); sqlInterface->execSqlQuery(query2); - while (query2.next()) - matchInfo->add_player_names(query2.value(0).toString().toStdString()); + while (query2->next()) + matchInfo->add_player_names(query2->value(0).toString().toStdString()); } { - QSqlQuery query3(sqlInterface->getDatabase()); - query3.prepare("select id, duration from " + servatrice->getDbPrefix() + "_replays where id_game = :id_game"); - query3.bindValue(":id_game", gameId); + QSqlQuery *query3 = sqlInterface->prepareQuery("select id, duration from {prefix}_replays where id_game = :id_game"); + query3->bindValue(":id_game", gameId); sqlInterface->execSqlQuery(query3); - while (query3.next()) { + while (query3->next()) { ServerInfo_Replay *replayInfo = matchInfo->add_replay_list(); - replayInfo->set_replay_id(query3.value(0).toInt()); + replayInfo->set_replay_id(query3->value(0).toInt()); replayInfo->set_replay_name(replayName.toStdString()); - replayInfo->set_duration(query3.value(1).toInt()); + replayInfo->set_duration(query3->value(1).toInt()); } } } @@ -640,25 +626,23 @@ Response::ResponseCode ServerSocketInterface::cmdReplayDownload(const Command_Re return Response::RespFunctionNotAllowed; { - QSqlQuery query(sqlInterface->getDatabase()); - query.prepare("select 1 from " + servatrice->getDbPrefix() + "_replays_access a left join " + servatrice->getDbPrefix() + "_replays b on a.id_game = b.id_game where b.id = :id_replay and a.id_player = :id_player"); - query.bindValue(":id_replay", cmd.replay_id()); - query.bindValue(":id_player", userInfo->id()); + QSqlQuery *query = sqlInterface->prepareQuery("select 1 from {prefix}_replays_access a left join {prefix}_replays b on a.id_game = b.id_game where b.id = :id_replay and a.id_player = :id_player"); + query->bindValue(":id_replay", cmd.replay_id()); + query->bindValue(":id_player", userInfo->id()); if (!sqlInterface->execSqlQuery(query)) return Response::RespInternalError; - if (!query.next()) + if (!query->next()) return Response::RespAccessDenied; } - QSqlQuery query(sqlInterface->getDatabase()); - query.prepare("select replay from " + servatrice->getDbPrefix() + "_replays where id = :id_replay"); - query.bindValue(":id_replay", cmd.replay_id()); + QSqlQuery *query = sqlInterface->prepareQuery("select replay from {prefix}_replays where id = :id_replay"); + query->bindValue(":id_replay", cmd.replay_id()); if (!sqlInterface->execSqlQuery(query)) return Response::RespInternalError; - if (!query.next()) + if (!query->next()) return Response::RespNameNotFound; - QByteArray data = query.value(0).toByteArray(); + QByteArray data = query->value(0).toByteArray(); Response_ReplayDownload *re = new Response_ReplayDownload; re->set_replay_data(data.data(), data.size()); @@ -675,15 +659,14 @@ Response::ResponseCode ServerSocketInterface::cmdReplayModifyMatch(const Command if (!sqlInterface->checkSql()) return Response::RespInternalError; - QSqlQuery query(sqlInterface->getDatabase()); - query.prepare("update " + servatrice->getDbPrefix() + "_replays_access set do_not_hide=:do_not_hide where id_player = :id_player and id_game = :id_game"); - query.bindValue(":id_player", userInfo->id()); - query.bindValue(":id_game", cmd.game_id()); - query.bindValue(":do_not_hide", cmd.do_not_hide()); + QSqlQuery *query = sqlInterface->prepareQuery("update {prefix}_replays_access set do_not_hide=:do_not_hide where id_player = :id_player and id_game = :id_game"); + query->bindValue(":id_player", userInfo->id()); + query->bindValue(":id_game", cmd.game_id()); + query->bindValue(":do_not_hide", cmd.do_not_hide()); if (!sqlInterface->execSqlQuery(query)) return Response::RespInternalError; - return query.numRowsAffected() > 0 ? Response::RespOk : Response::RespNameNotFound; + return query->numRowsAffected() > 0 ? Response::RespOk : Response::RespNameNotFound; } Response::ResponseCode ServerSocketInterface::cmdReplayDeleteMatch(const Command_ReplayDeleteMatch &cmd, ResponseContainer & /*rc*/) @@ -694,14 +677,13 @@ Response::ResponseCode ServerSocketInterface::cmdReplayDeleteMatch(const Command if (!sqlInterface->checkSql()) return Response::RespInternalError; - QSqlQuery query(sqlInterface->getDatabase()); - query.prepare("delete from " + servatrice->getDbPrefix() + "_replays_access where id_player = :id_player and id_game = :id_game"); - query.bindValue(":id_player", userInfo->id()); - query.bindValue(":id_game", cmd.game_id()); + QSqlQuery *query = sqlInterface->prepareQuery("delete from {prefix}_replays_access where id_player = :id_player and id_game = :id_game"); + query->bindValue(":id_player", userInfo->id()); + query->bindValue(":id_game", cmd.game_id()); if (!sqlInterface->execSqlQuery(query)) return Response::RespInternalError; - return query.numRowsAffected() > 0 ? Response::RespOk : Response::RespNameNotFound; + return query->numRowsAffected() > 0 ? Response::RespOk : Response::RespNameNotFound; } @@ -720,14 +702,13 @@ Response::ResponseCode ServerSocketInterface::cmdBanFromServer(const Command_Ban if (trustedSources.contains(address,Qt::CaseInsensitive)) address = ""; - QSqlQuery query(sqlInterface->getDatabase()); - query.prepare("insert into " + servatrice->getDbPrefix() + "_bans (user_name, ip_address, id_admin, time_from, minutes, reason, visible_reason) values(:user_name, :ip_address, :id_admin, NOW(), :minutes, :reason, :visible_reason)"); - query.bindValue(":user_name", userName); - query.bindValue(":ip_address", address); - query.bindValue(":id_admin", userInfo->id()); - query.bindValue(":minutes", minutes); - query.bindValue(":reason", QString::fromStdString(cmd.reason())); - query.bindValue(":visible_reason", QString::fromStdString(cmd.visible_reason())); + QSqlQuery *query = sqlInterface->prepareQuery("insert into {prefix}_bans (user_name, ip_address, id_admin, time_from, minutes, reason, visible_reason) values(:user_name, :ip_address, :id_admin, NOW(), :minutes, :reason, :visible_reason)"); + query->bindValue(":user_name", userName); + query->bindValue(":ip_address", address); + query->bindValue(":id_admin", userInfo->id()); + query->bindValue(":minutes", minutes); + query->bindValue(":reason", QString::fromStdString(cmd.reason())); + query->bindValue(":visible_reason", QString::fromStdString(cmd.visible_reason())); sqlInterface->execSqlQuery(query); servatrice->clientsLock.lockForRead();