diff --git a/servatrice/src/servatrice_database_interface.cpp b/servatrice/src/servatrice_database_interface.cpp index 847be61da..a872de0d2 100644 --- a/servatrice/src/servatrice_database_interface.cpp +++ b/servatrice/src/servatrice_database_interface.cpp @@ -12,6 +12,7 @@ #include #include #include +#include #include #include #include @@ -98,12 +99,43 @@ bool Servatrice_DatabaseInterface::openDatabase() return false; } + if (isStrictModeEnabled()) { + qCCritical(DatabaseInterfaceLog) << poolStr + << "Error opening database: MySQL/MariaDB strict mode is enabled, which " + "breaks most servatrice database operations. Please disable strict mode " + "by removing STRICT_TRANS_TABLES and STRICT_ALL_TABLES from sql_mode, " + "for example by adding 'sql_mode=NO_ENGINE_SUBSTITUTION' under [mysqld] " + "in your my.cnf (or my.ini on Windows) and restarting the database " + "server."; + return false; + } + // reset all prepared statements qDeleteAll(preparedStatements); preparedStatements.clear(); return true; } +bool Servatrice_DatabaseInterface::isStrictModeEnabled() const +{ + if (sqlDatabase.driverName() != "QMYSQL") { + return false; + } + + QSqlQuery query(sqlDatabase); + if (!query.exec("SELECT @@GLOBAL.sql_mode")) { + return false; + } + + const QStringList modes = query.next() ? query.value(0).toString().split(',') : QStringList(); + for (const QString &mode : modes) { + if (mode.trimmed() == "STRICT_TRANS_TABLES" || mode.trimmed() == "STRICT_ALL_TABLES") { + return true; + } + } + return false; +} + bool Servatrice_DatabaseInterface::checkSql() { if (!sqlDatabase.isValid()) { diff --git a/servatrice/src/servatrice_database_interface.h b/servatrice/src/servatrice_database_interface.h index cd76ae288..a05d6865d 100644 --- a/servatrice/src/servatrice_database_interface.h +++ b/servatrice/src/servatrice_database_interface.h @@ -32,6 +32,7 @@ private: bool checkUserIsIpBanned(const QString &ipAddress, QString &banReason, int &banSecondsRemaining); /** Must be called after checkSql and server is known to be in auth mode. */ bool checkUserIsNameBanned(QString const &userName, QString &banReason, int &banSecondsRemaining); + bool isStrictModeEnabled() const; protected: AuthenticationResult checkUserPassword(Server_ProtocolHandler *handler,