[8441] Implement check DBs versions (required_* fields) at mangosd/realmd loading.
[getmangos.git] / src / shared / Database / Database.cpp
blob6bca7c96760ac27492bce9e19a9ffdda95e4a3a5
1 /*
2 * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 #include "DatabaseEnv.h"
20 #include "Config/ConfigEnv.h"
22 #include <ctime>
23 #include <iostream>
24 #include <fstream>
26 Database::~Database()
28 /*Delete objects*/
31 bool Database::Initialize(const char *)
33 // Enable logging of SQL commands (usally only GM commands)
34 // (See method: PExecuteLog)
35 m_logSQL = sConfig.GetBoolDefault("LogSQL", false);
36 m_logsDir = sConfig.GetStringDefault("LogsDir","");
37 if(!m_logsDir.empty())
39 if((m_logsDir.at(m_logsDir.length()-1)!='/') && (m_logsDir.at(m_logsDir.length()-1)!='\\'))
40 m_logsDir.append("/");
43 return true;
46 void Database::ThreadStart()
50 void Database::ThreadEnd()
54 void Database::escape_string(std::string& str)
56 if(str.empty())
57 return;
59 char* buf = new char[str.size()*2+1];
60 escape_string(buf,str.c_str(),str.size());
61 str = buf;
62 delete[] buf;
65 bool Database::PExecuteLog(const char * format,...)
67 if (!format)
68 return false;
70 va_list ap;
71 char szQuery [MAX_QUERY_LEN];
72 va_start(ap, format);
73 int res = vsnprintf( szQuery, MAX_QUERY_LEN, format, ap );
74 va_end(ap);
76 if(res==-1)
78 sLog.outError("SQL Query truncated (and not execute) for format: %s",format);
79 return false;
82 if( m_logSQL )
84 time_t curr;
85 tm local;
86 time(&curr); // get current time_t value
87 local=*(localtime(&curr)); // dereference and assign
88 char fName[128];
89 sprintf( fName, "%04d-%02d-%02d_logSQL.sql", local.tm_year+1900, local.tm_mon+1, local.tm_mday );
91 FILE* log_file;
92 std::string logsDir_fname = m_logsDir+fName;
93 log_file = fopen(logsDir_fname.c_str(), "a");
94 if (log_file)
96 fprintf(log_file, "%s;\n", szQuery);
97 fclose(log_file);
99 else
101 // The file could not be opened
102 sLog.outError("SQL-Logging is disabled - Log file for the SQL commands could not be openend: %s",fName);
106 return Execute(szQuery);
109 void Database::SetResultQueue(SqlResultQueue * queue)
111 m_queryQueues[ACE_Based::Thread::current()] = queue;
115 QueryResult* Database::PQuery(const char *format,...)
117 if(!format) return NULL;
119 va_list ap;
120 char szQuery [MAX_QUERY_LEN];
121 va_start(ap, format);
122 int res = vsnprintf( szQuery, MAX_QUERY_LEN, format, ap );
123 va_end(ap);
125 if(res==-1)
127 sLog.outError("SQL Query truncated (and not execute) for format: %s",format);
128 return false;
131 return Query(szQuery);
134 QueryNamedResult* Database::PQueryNamed(const char *format,...)
136 if(!format) return NULL;
138 va_list ap;
139 char szQuery [MAX_QUERY_LEN];
140 va_start(ap, format);
141 int res = vsnprintf( szQuery, MAX_QUERY_LEN, format, ap );
142 va_end(ap);
144 if(res==-1)
146 sLog.outError("SQL Query truncated (and not execute) for format: %s",format);
147 return false;
150 return QueryNamed(szQuery);
153 bool Database::PExecute(const char * format,...)
155 if (!format)
156 return false;
158 va_list ap;
159 char szQuery [MAX_QUERY_LEN];
160 va_start(ap, format);
161 int res = vsnprintf( szQuery, MAX_QUERY_LEN, format, ap );
162 va_end(ap);
164 if(res==-1)
166 sLog.outError("SQL Query truncated (and not execute) for format: %s",format);
167 return false;
170 return Execute(szQuery);
173 bool Database::DirectPExecute(const char * format,...)
175 if (!format)
176 return false;
178 va_list ap;
179 char szQuery [MAX_QUERY_LEN];
180 va_start(ap, format);
181 int res = vsnprintf( szQuery, MAX_QUERY_LEN, format, ap );
182 va_end(ap);
184 if(res==-1)
186 sLog.outError("SQL Query truncated (and not execute) for format: %s",format);
187 return false;
190 return DirectExecute(szQuery);
193 bool Database::CheckRequiredField( char const* table_name, char const* required_name )
195 // check required field
196 QueryResult* result = PQuery("SELECT %s FROM %s LIMIT 1",required_name,table_name);
197 if(result)
199 delete result;
200 return true;
203 // check fail, prepare readabale error message
205 // search current required_* field in DB
206 QueryNamedResult* result2 = PQueryNamed("SELECT * FROM %s LIMIT 1",table_name);
207 if(result2)
209 QueryFieldNames const& namesMap = result2->GetFieldNames();
210 std::string reqName;
211 for(QueryFieldNames::const_iterator itr = namesMap.begin(); itr != namesMap.end(); ++itr)
213 if(itr->substr(0,9)=="required_")
215 reqName = *itr;
216 break;
220 delete result;
222 if(!reqName.empty())
224 sLog.outErrorDb("Table `%s` have field `%s` but expected `%s`! Not all sql updates applied?",table_name,reqName.c_str(),required_name);
225 return false;
229 sLog.outErrorDb("Table `%s` not have required_* field but expected `%s`! Not all sql updates applied?",table_name,required_name);
230 return false;