mirror of
https://github.com/Cockatrice/Cockatrice.git
synced 2026-11-10 03:53:26 -08:00
[Server] Serve report submission through the database interface (#7843)
cmdReport and sendPendingReportNotifications still issued their SQL inline through Servatrice_DatabaseInterface: the daily report cap, the reported-user lookup, the report insert, both pending-notification selects and the notified flips. Add the two notification records and seven report methods to Server_DatabaseInterface with fail-closed defaults, implement them with the previous statements and binds, and let both functions ask the injected interface. Check order, response codes and notification payloads are unchanged.
This commit is contained in:
parent
9b00972b4d
commit
fb836c6e0c
4 changed files with 242 additions and 87 deletions
|
|
@ -391,6 +391,65 @@ public:
|
||||||
{
|
{
|
||||||
return ReplayWriteResult::Failed;
|
return ReplayWriteResult::Failed;
|
||||||
}
|
}
|
||||||
|
/** @brief One resolved or dismissed report whose reporter has not been told yet. */
|
||||||
|
struct PendingReportNotification
|
||||||
|
{
|
||||||
|
int reportId = 0;
|
||||||
|
QString reportedUserName;
|
||||||
|
QString status;
|
||||||
|
QString resolutionNote;
|
||||||
|
};
|
||||||
|
/** @brief One unannounced comment on a report the user reported, was assigned, or moderates. */
|
||||||
|
struct PendingReportCommentNotification
|
||||||
|
{
|
||||||
|
qlonglong commentId = 0;
|
||||||
|
int reportId = 0;
|
||||||
|
QString authorName;
|
||||||
|
QString commentText;
|
||||||
|
};
|
||||||
|
/** @brief Reports the reporter submitted in the last day, for the daily cap. */
|
||||||
|
virtual int countReportsSubmittedInLastDay(int /* reporterId */)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
/** @brief Resolves a user name for the report's reported-user column, -1 when unknown. */
|
||||||
|
virtual int getReportedUserId(const QString & /* userName */)
|
||||||
|
{
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
/** @brief Stores a new open report, returning whether the insert succeeded. */
|
||||||
|
virtual bool addReport(int /* reporterId */,
|
||||||
|
const QString & /* reporterName */,
|
||||||
|
int /* reportedUserId */,
|
||||||
|
const QString & /* reportedUserName */,
|
||||||
|
int /* gameId */,
|
||||||
|
int /* roomId */,
|
||||||
|
const QString & /* category */,
|
||||||
|
const QString & /* description */,
|
||||||
|
const QString & /* chatLog */)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
/** @brief Collects the reporter's resolved or dismissed reports that were not announced yet. */
|
||||||
|
virtual bool getPendingReportNotifications(int /* reporterId */,
|
||||||
|
QList<PendingReportNotification> & /* notifications */)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
/** @brief Marks a report notification as delivered so it is not announced again. */
|
||||||
|
virtual void markReportNotified(int /* reportId */)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
/** @brief Collects comments on the user's reports that were not announced yet. */
|
||||||
|
virtual bool getPendingReportCommentNotifications(int /* userId */,
|
||||||
|
QList<PendingReportCommentNotification> & /* notifications */)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
/** @brief Marks a comment notification as delivered so it is not announced again. */
|
||||||
|
virtual void markReportCommentNotified(qlonglong /* commentId */)
|
||||||
|
{
|
||||||
|
}
|
||||||
/** @brief Append a moderator/admin action to the server audit log. */
|
/** @brief Append a moderator/admin action to the server audit log. */
|
||||||
virtual void addAuditRecord(const QString & /* user */,
|
virtual void addAuditRecord(const QString & /* user */,
|
||||||
const QString & /* ipaddress */,
|
const QString & /* ipaddress */,
|
||||||
|
|
|
||||||
|
|
@ -3562,6 +3562,148 @@ bool Servatrice_DatabaseInterface::userEmailMatches(const QString &userName, con
|
||||||
return validateTableColumnStringData("{prefix}_users", "email", userName, email);
|
return validateTableColumnStringData("{prefix}_users", "email", userName, email);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int Servatrice_DatabaseInterface::countReportsSubmittedInLastDay(int reporterId)
|
||||||
|
{
|
||||||
|
if (!checkSql()) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
QSqlQuery *query = prepareQuery("SELECT COUNT(*) FROM {prefix}_reports WHERE reporter_id = :id "
|
||||||
|
"AND created_at >= DATE_SUB(NOW(), INTERVAL 1 DAY)");
|
||||||
|
query->bindValue(":id", reporterId);
|
||||||
|
if (!execSqlQuery(query) || !query->next()) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return query->value(0).toInt();
|
||||||
|
}
|
||||||
|
|
||||||
|
int Servatrice_DatabaseInterface::getReportedUserId(const QString &userName)
|
||||||
|
{
|
||||||
|
if (!checkSql()) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
QSqlQuery *query = prepareQuery("SELECT id FROM {prefix}_users WHERE name = :name");
|
||||||
|
query->bindValue(":name", userName);
|
||||||
|
if (!execSqlQuery(query) || !query->next()) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return query->value(0).toInt();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Servatrice_DatabaseInterface::addReport(int reporterId,
|
||||||
|
const QString &reporterName,
|
||||||
|
int reportedUserId,
|
||||||
|
const QString &reportedUserName,
|
||||||
|
int gameId,
|
||||||
|
int roomId,
|
||||||
|
const QString &category,
|
||||||
|
const QString &description,
|
||||||
|
const QString &chatLog)
|
||||||
|
{
|
||||||
|
if (!checkSql()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
QSqlQuery *query = prepareQuery("insert into {prefix}_reports "
|
||||||
|
"(reporter_id, reporter_name, reported_user_id, reported_user_name, "
|
||||||
|
"game_id, room_id, category, description, chat_log, created_at, status) "
|
||||||
|
"values "
|
||||||
|
"(:reporter_id, :reporter_name, :reported_user_id, :reported_user_name, "
|
||||||
|
":game_id, :room_id, :category, :description, :chat_log, NOW(), 'open')");
|
||||||
|
|
||||||
|
query->bindValue(":reporter_id", reporterId);
|
||||||
|
query->bindValue(":reporter_name", reporterName);
|
||||||
|
query->bindValue(":reported_user_id", reportedUserId);
|
||||||
|
query->bindValue(":reported_user_name", reportedUserName);
|
||||||
|
query->bindValue(":game_id", gameId > 0 ? gameId : QVariant());
|
||||||
|
query->bindValue(":room_id", roomId > 0 ? roomId : QVariant());
|
||||||
|
query->bindValue(":category", category);
|
||||||
|
query->bindValue(":description", description);
|
||||||
|
query->bindValue(":chat_log", chatLog.isEmpty() ? QVariant() : chatLog);
|
||||||
|
|
||||||
|
return execSqlQuery(query);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Servatrice_DatabaseInterface::getPendingReportNotifications(
|
||||||
|
int reporterId,
|
||||||
|
QList<Server_DatabaseInterface::PendingReportNotification> ¬ifications)
|
||||||
|
{
|
||||||
|
if (!checkSql()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
QSqlQuery *query = prepareQuery("SELECT id, reported_user_name, status, resolution_note "
|
||||||
|
"FROM {prefix}_reports "
|
||||||
|
"WHERE reporter_id = :reporter_id AND notified = 0 "
|
||||||
|
"AND status IN ('resolved', 'dismissed')");
|
||||||
|
query->bindValue(":reporter_id", reporterId);
|
||||||
|
if (!execSqlQuery(query)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (query->next()) {
|
||||||
|
PendingReportNotification notification;
|
||||||
|
notification.reportId = query->value(0).toInt();
|
||||||
|
notification.reportedUserName = query->value(1).toString();
|
||||||
|
notification.status = query->value(2).toString();
|
||||||
|
notification.resolutionNote = query->value(3).toString();
|
||||||
|
notifications.append(notification);
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Servatrice_DatabaseInterface::markReportNotified(int reportId)
|
||||||
|
{
|
||||||
|
QSqlQuery *query = prepareQuery("UPDATE {prefix}_reports SET notified = 1 WHERE id = :id");
|
||||||
|
query->bindValue(":id", reportId);
|
||||||
|
execSqlQuery(query);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Servatrice_DatabaseInterface::getPendingReportCommentNotifications(
|
||||||
|
int userId,
|
||||||
|
QList<Server_DatabaseInterface::PendingReportCommentNotification> ¬ifications)
|
||||||
|
{
|
||||||
|
if (!checkSql()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
QSqlQuery *query = prepareQuery("SELECT c.id, c.report_id, c.author_name, c.comment_text "
|
||||||
|
"FROM {prefix}_report_comments c "
|
||||||
|
"JOIN {prefix}_reports r ON r.id = c.report_id "
|
||||||
|
"WHERE c.notified = 0 "
|
||||||
|
"AND c.author_id != :user_id "
|
||||||
|
"AND ((c.is_moderator = 1 AND r.reporter_id = :user_id) "
|
||||||
|
"OR (c.is_moderator = 0 AND r.assigned_to = :user_id) "
|
||||||
|
"OR (c.is_moderator = 1 AND r.assigned_to = :user_id)) "
|
||||||
|
"ORDER BY c.created_at ASC");
|
||||||
|
query->bindValue(":user_id", userId);
|
||||||
|
if (!execSqlQuery(query)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (query->next()) {
|
||||||
|
PendingReportCommentNotification notification;
|
||||||
|
notification.commentId = query->value(0).toLongLong();
|
||||||
|
notification.reportId = query->value(1).toInt();
|
||||||
|
notification.authorName = query->value(2).toString();
|
||||||
|
notification.commentText = query->value(3).toString();
|
||||||
|
notifications.append(notification);
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Servatrice_DatabaseInterface::markReportCommentNotified(qlonglong commentId)
|
||||||
|
{
|
||||||
|
QSqlQuery *query = prepareQuery("UPDATE {prefix}_report_comments SET notified = 1 WHERE id = :id");
|
||||||
|
query->bindValue(":id", commentId);
|
||||||
|
execSqlQuery(query);
|
||||||
|
}
|
||||||
|
|
||||||
void Servatrice_DatabaseInterface::addAuditRecord(const QString &user,
|
void Servatrice_DatabaseInterface::addAuditRecord(const QString &user,
|
||||||
const QString &ipaddress,
|
const QString &ipaddress,
|
||||||
const QString &clientid,
|
const QString &clientid,
|
||||||
|
|
|
||||||
|
|
@ -289,6 +289,25 @@ public:
|
||||||
const QString &action,
|
const QString &action,
|
||||||
const QString &details,
|
const QString &details,
|
||||||
bool results) override;
|
bool results) override;
|
||||||
|
int countReportsSubmittedInLastDay(int reporterId) override;
|
||||||
|
int getReportedUserId(const QString &userName) override;
|
||||||
|
bool addReport(int reporterId,
|
||||||
|
const QString &reporterName,
|
||||||
|
int reportedUserId,
|
||||||
|
const QString &reportedUserName,
|
||||||
|
int gameId,
|
||||||
|
int roomId,
|
||||||
|
const QString &category,
|
||||||
|
const QString &description,
|
||||||
|
const QString &chatLog) override;
|
||||||
|
bool
|
||||||
|
getPendingReportNotifications(int reporterId,
|
||||||
|
QList<Server_DatabaseInterface::PendingReportNotification> ¬ifications) override;
|
||||||
|
void markReportNotified(int reportId) override;
|
||||||
|
bool getPendingReportCommentNotifications(
|
||||||
|
int userId,
|
||||||
|
QList<Server_DatabaseInterface::PendingReportCommentNotification> ¬ifications) override;
|
||||||
|
void markReportCommentNotified(qlonglong commentId) override;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
|
|
@ -2582,77 +2582,45 @@ AbstractServerSocketInterface::cmdClearBlacklistedBanners(const Command_ClearBla
|
||||||
|
|
||||||
void AbstractServerSocketInterface::sendPendingReportNotifications(ResponseContainer &rc)
|
void AbstractServerSocketInterface::sendPendingReportNotifications(ResponseContainer &rc)
|
||||||
{
|
{
|
||||||
if (!sqlInterface->checkSql()) {
|
QList<Server_DatabaseInterface::PendingReportNotification> reportNotifications;
|
||||||
|
if (!databaseInterface->getPendingReportNotifications(userInfo->id(), reportNotifications)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
QSqlQuery *query = sqlInterface->prepareQuery("SELECT id, reported_user_name, status, resolution_note "
|
for (const Server_DatabaseInterface::PendingReportNotification ¬ification : reportNotifications) {
|
||||||
"FROM {prefix}_reports "
|
const bool dismissed = notification.status == "dismissed";
|
||||||
"WHERE reporter_id = :reporter_id AND notified = 0 "
|
|
||||||
"AND status IN ('resolved', 'dismissed')");
|
|
||||||
query->bindValue(":reporter_id", userInfo->id());
|
|
||||||
|
|
||||||
if (!sqlInterface->execSqlQuery(query)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
while (query->next()) {
|
|
||||||
const int reportId = query->value(0).toInt();
|
|
||||||
const QString reportedUser = query->value(1).toString();
|
|
||||||
const bool dismissed = query->value(2).toString() == "dismissed";
|
|
||||||
const QString note = query->value(3).toString();
|
|
||||||
|
|
||||||
Event_NotifyUser event;
|
Event_NotifyUser event;
|
||||||
event.set_type(Event_NotifyUser::REPORT_RESOLVED);
|
event.set_type(Event_NotifyUser::REPORT_RESOLVED);
|
||||||
event.set_custom_title(dismissed ? tr("Report Dismissed").toStdString() : tr("Report Resolved").toStdString());
|
event.set_custom_title(dismissed ? tr("Report Dismissed").toStdString() : tr("Report Resolved").toStdString());
|
||||||
|
|
||||||
QString content = dismissed ? tr("Your report about %1 has been dismissed.").arg(reportedUser)
|
QString content = dismissed ? tr("Your report about %1 has been dismissed.").arg(notification.reportedUserName)
|
||||||
: tr("Your report about %1 has been resolved.").arg(reportedUser);
|
: tr("Your report about %1 has been resolved.").arg(notification.reportedUserName);
|
||||||
if (!note.isEmpty()) {
|
if (!notification.resolutionNote.isEmpty()) {
|
||||||
content += "\n" + tr("Note: %1").arg(note);
|
content += "\n" + tr("Note: %1").arg(notification.resolutionNote);
|
||||||
}
|
}
|
||||||
event.set_custom_content(content.toStdString());
|
event.set_custom_content(content.toStdString());
|
||||||
|
|
||||||
rc.enqueuePreResponseItem(ServerMessage::SESSION_EVENT, prepareSessionEvent(event));
|
rc.enqueuePreResponseItem(ServerMessage::SESSION_EVENT, prepareSessionEvent(event));
|
||||||
|
|
||||||
QSqlQuery *notifiedQuery =
|
databaseInterface->markReportNotified(notification.reportId);
|
||||||
sqlInterface->prepareQuery("UPDATE {prefix}_reports SET notified = 1 WHERE id = :id");
|
|
||||||
notifiedQuery->bindValue(":id", reportId);
|
|
||||||
sqlInterface->execSqlQuery(notifiedQuery);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
QSqlQuery *commentQuery = sqlInterface->prepareQuery("SELECT c.id, c.report_id, c.author_name, c.comment_text "
|
QList<Server_DatabaseInterface::PendingReportCommentNotification> commentNotifications;
|
||||||
"FROM {prefix}_report_comments c "
|
if (!databaseInterface->getPendingReportCommentNotifications(userInfo->id(), commentNotifications)) {
|
||||||
"JOIN {prefix}_reports r ON r.id = c.report_id "
|
|
||||||
"WHERE c.notified = 0 "
|
|
||||||
"AND c.author_id != :user_id "
|
|
||||||
"AND ((c.is_moderator = 1 AND r.reporter_id = :user_id) "
|
|
||||||
"OR (c.is_moderator = 0 AND r.assigned_to = :user_id) "
|
|
||||||
"OR (c.is_moderator = 1 AND r.assigned_to = :user_id)) "
|
|
||||||
"ORDER BY c.created_at ASC");
|
|
||||||
commentQuery->bindValue(":user_id", userInfo->id());
|
|
||||||
|
|
||||||
if (!sqlInterface->execSqlQuery(commentQuery)) {
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
while (commentQuery->next()) {
|
for (const Server_DatabaseInterface::PendingReportCommentNotification ¬ification : commentNotifications) {
|
||||||
const qlonglong commentId = commentQuery->value(0).toLongLong();
|
|
||||||
const int reportId = commentQuery->value(1).toInt();
|
|
||||||
const QString authorName = commentQuery->value(2).toString();
|
|
||||||
const QString commentText = commentQuery->value(3).toString();
|
|
||||||
|
|
||||||
Event_NotifyUser event;
|
Event_NotifyUser event;
|
||||||
event.set_type(Event_NotifyUser::REPORT_COMMENT);
|
event.set_type(Event_NotifyUser::REPORT_COMMENT);
|
||||||
event.set_custom_title(tr("New Comment on Report #%1").arg(reportId).toStdString());
|
event.set_custom_title(tr("New Comment on Report #%1").arg(notification.reportId).toStdString());
|
||||||
event.set_custom_content(tr("%1 commented:\n%2").arg(authorName, commentText).toStdString());
|
event.set_custom_content(
|
||||||
|
tr("%1 commented:\n%2").arg(notification.authorName, notification.commentText).toStdString());
|
||||||
|
|
||||||
rc.enqueuePreResponseItem(ServerMessage::SESSION_EVENT, prepareSessionEvent(event));
|
rc.enqueuePreResponseItem(ServerMessage::SESSION_EVENT, prepareSessionEvent(event));
|
||||||
|
|
||||||
QSqlQuery *notifiedQuery =
|
databaseInterface->markReportCommentNotified(notification.commentId);
|
||||||
sqlInterface->prepareQuery("UPDATE {prefix}_report_comments SET notified = 1 WHERE id = :id");
|
|
||||||
notifiedQuery->bindValue(":id", commentId);
|
|
||||||
sqlInterface->execSqlQuery(notifiedQuery);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -3874,7 +3842,7 @@ Response::ResponseCode AbstractServerSocketInterface::cmdReport(const Command_Re
|
||||||
return Response::RespFunctionNotAllowed;
|
return Response::RespFunctionNotAllowed;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!sqlInterface->checkSql()) {
|
if (!databaseInterface->checkSql()) {
|
||||||
return Response::RespInternalError;
|
return Response::RespInternalError;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -3897,24 +3865,11 @@ Response::ResponseCode AbstractServerSocketInterface::cmdReport(const Command_Re
|
||||||
}
|
}
|
||||||
|
|
||||||
const int maxReportsPerDay = settingsCache->value("reporting/max_reports_per_day", 10).toInt();
|
const int maxReportsPerDay = settingsCache->value("reporting/max_reports_per_day", 10).toInt();
|
||||||
if (maxReportsPerDay > 0) {
|
if (maxReportsPerDay > 0 && databaseInterface->countReportsSubmittedInLastDay(userInfo->id()) >= maxReportsPerDay) {
|
||||||
QSqlQuery *countQuery =
|
|
||||||
sqlInterface->prepareQuery("SELECT COUNT(*) FROM {prefix}_reports WHERE reporter_id = :id "
|
|
||||||
"AND created_at >= DATE_SUB(NOW(), INTERVAL 1 DAY)");
|
|
||||||
countQuery->bindValue(":id", userInfo->id());
|
|
||||||
if (sqlInterface->execSqlQuery(countQuery) && countQuery->next() &&
|
|
||||||
countQuery->value(0).toInt() >= maxReportsPerDay) {
|
|
||||||
return Response::RespTooManyRequests;
|
return Response::RespTooManyRequests;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
int reportedUserId = -1;
|
|
||||||
QSqlQuery *lookupQuery = sqlInterface->prepareQuery("SELECT id FROM {prefix}_users WHERE name = :name");
|
|
||||||
lookupQuery->bindValue(":name", reportedUser);
|
|
||||||
if (sqlInterface->execSqlQuery(lookupQuery) && lookupQuery->next()) {
|
|
||||||
reportedUserId = lookupQuery->value(0).toInt();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
const int reportedUserId = databaseInterface->getReportedUserId(reportedUser);
|
||||||
if (reportedUserId == -1) {
|
if (reportedUserId == -1) {
|
||||||
return Response::RespNameNotFound;
|
return Response::RespNameNotFound;
|
||||||
}
|
}
|
||||||
|
|
@ -3933,28 +3888,8 @@ Response::ResponseCode AbstractServerSocketInterface::cmdReport(const Command_Re
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
QSqlQuery *query =
|
if (!databaseInterface->addReport(userInfo->id(), reporterName, reportedUserId, reportedUser, gameId, roomId,
|
||||||
sqlInterface->prepareQuery("insert into {prefix}_reports "
|
category, description, chatLog)) {
|
||||||
"(reporter_id, reporter_name, reported_user_id, reported_user_name, "
|
|
||||||
"game_id, room_id, category, description, chat_log, created_at, status) "
|
|
||||||
"values "
|
|
||||||
"(:reporter_id, :reporter_name, :reported_user_id, :reported_user_name, "
|
|
||||||
":game_id, :room_id, :category, :description, :chat_log, NOW(), 'open')");
|
|
||||||
|
|
||||||
query->bindValue(":reporter_id", userInfo->id());
|
|
||||||
query->bindValue(":reporter_name", reporterName);
|
|
||||||
query->bindValue(":reported_user_id", reportedUserId);
|
|
||||||
query->bindValue(":reported_user_name", reportedUser);
|
|
||||||
|
|
||||||
query->bindValue(":game_id", gameId > 0 ? gameId : QVariant());
|
|
||||||
|
|
||||||
query->bindValue(":room_id", roomId > 0 ? roomId : QVariant());
|
|
||||||
|
|
||||||
query->bindValue(":category", category);
|
|
||||||
query->bindValue(":description", description);
|
|
||||||
query->bindValue(":chat_log", chatLog.isEmpty() ? QVariant() : chatLog);
|
|
||||||
|
|
||||||
if (!sqlInterface->execSqlQuery(query)) {
|
|
||||||
return Response::RespInternalError;
|
return Response::RespInternalError;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue