Merge branch 'ryzom/marauder-gameplay' into main/gingo-test
[ryzomcore.git] / nelns / login_service / mysql_helper.cpp
blob2979ca6b29c8b757d7fc356ca213430761c5f01a
1 // NeLNS - MMORPG Framework <http://dev.ryzom.com/projects/nel/>
2 // Copyright (C) 2010 Winch Gate Property Limited
3 //
4 // This source file has been modified by the following contributors:
5 // Copyright (C) 2019 Jan BOON (Kaetemi) <jan.boon@kaetemi.be>
6 //
7 // This program is free software: you can redistribute it and/or modify
8 // it under the terms of the GNU Affero General Public License as
9 // published by the Free Software Foundation, either version 3 of the
10 // License, or (at your option) any later version.
12 // This program is distributed in the hope that it will be useful,
13 // but WITHOUT ANY WARRANTY; without even the implied warranty of
14 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 // GNU Affero General Public License for more details.
17 // You should have received a copy of the GNU Affero General Public License
18 // along with this program. If not, see <http://www.gnu.org/licenses/>.
20 #include "nel/misc/types_nl.h"
22 #include "nel/net/service.h"
24 #include "mysql_helper.h"
26 #ifndef LIBMARIADB
27 #include <mysql_version.h>
28 #endif
32 // Namespaces
35 using namespace std;
36 using namespace NLMISC;
37 using namespace NLNET;
41 // Variables
44 static string DatabaseName, DatabaseHost, DatabaseLogin, DatabasePassword;
46 MYSQL *DatabaseConnection = NULL;
50 // Functions
53 string sqlQuery(const string &query)
55 CMysqlResult result;
56 MYSQL_ROW row;
57 sint32 nbrow;
58 return sqlQuery(query, nbrow, row, result);
61 string sqlQuery(const string &query, sint32 &nbRow, MYSQL_ROW &firstRow, CMysqlResult &result)
63 nlassert(DatabaseConnection);
64 //nlinfo("sqlQuery: '%s'", query.c_str());
65 sint ret = mysql_query(DatabaseConnection, query.c_str());
66 if(ret != 0)
68 nlwarning("mysql_query() failed: '%s' (%s)", mysql_error(DatabaseConnection), query.c_str());
69 return toString("mysql_query() failed: '%s' (%s)", mysql_error(DatabaseConnection), query.c_str());
72 if(query.find("select") == 0)
74 // store result on select query
75 result = mysql_store_result(DatabaseConnection);
76 if(result == 0)
78 nlwarning("mysql_store_result() failed: '%s' (%s)", mysql_error(DatabaseConnection), query.c_str ());
79 return toString("mysql_store_result() failed: '%s' (%s)", mysql_error(DatabaseConnection), query.c_str ());
82 nbRow = (sint32)mysql_num_rows(result);
84 if(nbRow > 0)
86 firstRow = mysql_fetch_row(result);
87 if(firstRow == 0)
89 nlwarning("mysql_fetch_row failed: %s (%s)", mysql_error(DatabaseConnection), query.c_str());
90 return toString("mysql_fetch_row failed: %s (%s)", mysql_error(DatabaseConnection), query.c_str());
93 else
95 firstRow = 0;
99 return "";
102 string resetDatabase()
104 // Reset all shards database
105 string reason = sqlQuery("update shard set NbPlayers=0, Online=0");
106 if(!reason.empty()) return reason;
108 // Reset all user database
109 reason = sqlQuery("update user set State='Offline', ShardId=-1, Cookie='' where State!='Offline'");
110 if(!reason.empty()) return reason;
112 return "";
115 static void cbDatabaseVar(CConfigFile::CVar &var)
117 DatabaseName = IService::getInstance()->ConfigFile.getVar("DatabaseName").asString ();
118 DatabaseHost = IService::getInstance()->ConfigFile.getVar("DatabaseHost").asString ();
119 DatabaseLogin = IService::getInstance()->ConfigFile.getVar("DatabaseLogin").asString ();
120 DatabasePassword = IService::getInstance()->ConfigFile.getVar("DatabasePassword").asString ();
122 if(DatabaseConnection)
124 mysql_close(DatabaseConnection);
125 DatabaseConnection = 0;
127 MYSQL *db = mysql_init(0);
128 if(db == 0)
130 nlwarning("mysql_init() failed");
131 return;
134 my_bool opt = true;
135 if (mysql_options (db, MYSQL_OPT_RECONNECT, &opt))
137 mysql_close(db);
138 DatabaseConnection = 0;
139 nlerror("mysql_options() failed for database connection to '%s'", DatabaseHost.c_str());
140 return;
144 DatabaseConnection = mysql_real_connect(db, DatabaseHost.c_str(), DatabaseLogin.c_str(), DatabasePassword.c_str(), DatabaseName.c_str(),0,0,0);
145 if (DatabaseConnection == 0 || DatabaseConnection != db)
147 mysql_close(db);
148 DatabaseConnection = 0;
149 nlerror("mysql_real_connect() failed to '%s' with login '%s' and database name '%s'", DatabaseHost.c_str(), DatabaseLogin.c_str(), DatabaseName.c_str());
150 return;
153 #if MYSQL_VERSION_ID < 50019
154 opt = true;
155 if (mysql_options (DatabaseConnection, MYSQL_OPT_RECONNECT, &opt))
157 mysql_close(db);
158 DatabaseConnection = 0;
159 nlerror("mysql_options() failed for database connection to '%s'", DatabaseHost.c_str());
160 return;
162 #endif
165 sqlQuery("set names utf8mb4");
168 void sqlInit()
170 IService::getInstance()->ConfigFile.setCallback ("ForceDatabaseReconnection", cbDatabaseVar);
171 cbDatabaseVar (IService::getInstance()->ConfigFile.getVar ("ForceDatabaseReconnection"));
172 resetDatabase();