00001
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032 #ifdef _WIN32
00033 #pragma warning(disable:4786)
00034 #endif
00035
00036 #include <string>
00037 #include <map>
00038 #ifdef WIN32
00039 #include <config-win.h>
00040 #include <mysql.h>
00041 #else
00042 #include <stdio.h>
00043 #include <stdlib.h>
00044 #include <string.h>
00045 #include <mysql/mysql.h>
00046 #endif
00047
00048 #include "Database.h"
00049 #include "Query.h"
00050
00051
00052 #ifdef MYSQLW_NAMESPACE
00053 namespace MYSQLW_NAMESPACE {
00054 #endif
00055
00056
00057 Query::Query(Database *dbin)
00058 :m_db(*dbin)
00059 ,odb(dbin ? dbin -> grabdb() : NULL)
00060 ,res(NULL)
00061 ,row(NULL)
00062 ,m_num_cols(0)
00063 {
00064 }
00065
00066
00067 Query::Query(Database& dbin) : m_db(dbin),odb(dbin.grabdb()),res(NULL),row(NULL)
00068 ,m_num_cols(0)
00069 {
00070 }
00071
00072
00073 Query::Query(Database *dbin,const std::string& sql) : m_db(*dbin)
00074 ,odb(dbin ? dbin -> grabdb() : NULL),res(NULL),row(NULL)
00075 ,m_num_cols(0)
00076 {
00077 execute(sql);
00078 }
00079
00080
00081 Query::Query(Database& dbin,const std::string& sql) : m_db(dbin),odb(dbin.grabdb()),res(NULL),row(NULL)
00082 ,m_num_cols(0)
00083 {
00084 execute(sql);
00085 }
00086
00087
00088 Query::~Query()
00089 {
00090 if (res)
00091 {
00092 GetDatabase().error(*this, "mysql_free_result in destructor");
00093 mysql_free_result(res);
00094 }
00095 if (odb)
00096 {
00097 m_db.freedb(odb);
00098 }
00099 }
00100
00101
00102 Database& Query::GetDatabase() const
00103 {
00104 return m_db;
00105 }
00106
00107
00108 bool Query::execute(const std::string& sql)
00109 {
00110 m_last_query = sql;
00111 if (odb && res)
00112 {
00113 GetDatabase().error(*this, "execute: query busy");
00114 }
00115 if (odb && !res)
00116 {
00117 if (mysql_query(&odb -> mysql,sql.c_str()))
00118 {
00119 GetDatabase().error(*this,"query failed");
00120 }
00121 else
00122 {
00123 return true;
00124 }
00125 }
00126 return false;
00127 }
00128
00129
00130
00131
00132
00133 MYSQL_RES *Query::get_result(const std::string& sql)
00134 {
00135 if (odb && res)
00136 {
00137 GetDatabase().error(*this, "get_result: query busy");
00138 }
00139 if (odb && !res)
00140 {
00141 if (execute(sql))
00142 {
00143 res = mysql_store_result(&odb -> mysql);
00144 if (res)
00145 {
00146 MYSQL_FIELD *f = mysql_fetch_field(res);
00147 int i = 1;
00148 while (f)
00149 {
00150 if (f -> name)
00151 m_nmap[f -> name] = i;
00152 f = mysql_fetch_field(res);
00153 i++;
00154 }
00155 m_num_cols = i - 1;
00156 }
00157 }
00158 }
00159 return res;
00160 }
00161
00162
00163 void Query::free_result()
00164 {
00165 if (odb && res)
00166 {
00167 mysql_free_result(res);
00168 res = NULL;
00169 row = NULL;
00170 }
00171 while (m_nmap.size())
00172 {
00173 std::map<std::string,int>::iterator it = m_nmap.begin();
00174 m_nmap.erase(it);
00175 }
00176 m_num_cols = 0;
00177 }
00178
00179
00180 MYSQL_ROW Query::fetch_row()
00181 {
00182 rowcount = 0;
00183 return odb && res ? row = mysql_fetch_row(res) : NULL;
00184 }
00185
00186
00187 my_ulonglong Query::insert_id()
00188 {
00189 if (odb)
00190 {
00191 return mysql_insert_id(&odb -> mysql);
00192 }
00193 else
00194 {
00195 return 0;
00196 }
00197 }
00198
00199
00200 long Query::num_rows()
00201 {
00202 return odb && res ? mysql_num_rows(res) : 0;
00203 }
00204
00205
00206 int Query::num_cols()
00207 {
00208 return m_num_cols;
00209 }
00210
00211
00212 bool Query::is_null(int x)
00213 {
00214 if (odb && res && row)
00215 {
00216 return row[x] ? false : true;
00217 }
00218 return false;
00219 }
00220
00221
00222 bool Query::is_null(const std::string& x)
00223 {
00224 int index = m_nmap[x] - 1;
00225 if (index >= 0)
00226 return is_null(index);
00227 error("Column name lookup failure: " + x);
00228 return false;
00229 }
00230
00231
00232 bool Query::is_null()
00233 {
00234 return is_null(rowcount++);
00235 }
00236
00237
00238 const char *Query::getstr(const std::string& x)
00239 {
00240 int index = m_nmap[x] - 1;
00241 if (index >= 0)
00242 return getstr(index);
00243 error("Column name lookup failure: " + x);
00244 return NULL;
00245 }
00246
00247
00248 const char *Query::getstr(int x)
00249 {
00250 if (odb && res && row)
00251 {
00252 return row[x] ? row[x] : "";
00253 }
00254 return NULL;
00255 }
00256
00257
00258 const char *Query::getstr()
00259 {
00260 return getstr(rowcount++);
00261 }
00262
00263
00264 double Query::getnum(const std::string& x)
00265 {
00266 int index = m_nmap[x] - 1;
00267 if (index >= 0)
00268 return getnum(index);
00269 error("Column name lookup failure: " + x);
00270 return 0;
00271 }
00272
00273
00274 double Query::getnum(int x)
00275 {
00276 return odb && res && row && row[x] ? atof(row[x]) : 0;
00277 }
00278
00279
00280 long Query::getval(const std::string& x)
00281 {
00282 int index = m_nmap[x] - 1;
00283 if (index >= 0)
00284 return getval(index);
00285 error("Column name lookup failure: " + x);
00286 return 0;
00287 }
00288
00289
00290 long Query::getval(int x)
00291 {
00292 return odb && res && row && row[x] ? atol(row[x]) : 0;
00293 }
00294
00295
00296 double Query::getnum()
00297 {
00298 return getnum(rowcount++);
00299 }
00300
00301
00302 long Query::getval()
00303 {
00304 return getval(rowcount++);
00305 }
00306
00307
00308 unsigned long Query::getuval(const std::string& x)
00309 {
00310 int index = m_nmap[x] - 1;
00311 if (index >= 0)
00312 return getuval(index);
00313 error("Column name lookup failure: " + x);
00314 return 0;
00315 }
00316
00317
00318 unsigned long Query::getuval(int x)
00319 {
00320 unsigned long l = 0;
00321 if (odb && res && row && row[x])
00322 {
00323 l = m_db.a2ubigint(row[x]);
00324 }
00325 return l;
00326 }
00327
00328
00329 unsigned long Query::getuval()
00330 {
00331 return getuval(rowcount++);
00332 }
00333
00334
00335 int64_t Query::getbigint(const std::string& x)
00336 {
00337 int index = m_nmap[x] - 1;
00338 if (index >= 0)
00339 return getbigint(index);
00340 error("Column name lookup failure: " + x);
00341 return 0;
00342 }
00343
00344
00345 int64_t Query::getbigint(int x)
00346 {
00347 return odb && res && row && row[x] ? m_db.a2bigint(row[x]) : 0;
00348 }
00349
00350
00351 int64_t Query::getbigint()
00352 {
00353 return getbigint(rowcount++);
00354 }
00355
00356
00357 uint64_t Query::getubigint(const std::string& x)
00358 {
00359 int index = m_nmap[x] - 1;
00360 if (index >= 0)
00361 return getubigint(index);
00362 error("Column name lookup failure: " + x);
00363 return 0;
00364 }
00365
00366
00367 uint64_t Query::getubigint(int x)
00368 {
00369 return odb && res && row && row[x] ? m_db.a2ubigint(row[x]) : 0;
00370 }
00371
00372
00373 uint64_t Query::getubigint()
00374 {
00375 return getubigint(rowcount++);
00376 }
00377
00378
00379 double Query::get_num(const std::string& sql)
00380 {
00381 double l = 0;
00382 if (get_result(sql))
00383 {
00384 if (fetch_row())
00385 {
00386 l = getnum();
00387 }
00388 free_result();
00389 }
00390 return l;
00391 }
00392
00393
00394 long Query::get_count(const std::string& sql)
00395 {
00396 long l = 0;
00397 if (get_result(sql))
00398 {
00399 if (fetch_row())
00400 l = getval();
00401 free_result();
00402 }
00403 return l;
00404 }
00405
00406
00407 const char *Query::get_string(const std::string& sql)
00408 {
00409 bool found = false;
00410 m_tmpstr = "";
00411 if (get_result(sql))
00412 {
00413 if (fetch_row())
00414 {
00415 m_tmpstr = getstr();
00416 found = true;
00417 }
00418 free_result();
00419 }
00420 return m_tmpstr.c_str();
00421 }
00422
00423
00424 const std::string& Query::GetLastQuery()
00425 {
00426 return m_last_query;
00427 }
00428
00429
00430 std::string Query::GetError()
00431 {
00432 return odb ? mysql_error(&odb -> mysql) : "";
00433 }
00434
00435
00436 int Query::GetErrno()
00437 {
00438 return odb ? mysql_errno(&odb -> mysql) : 0;
00439 }
00440
00441
00442 bool Query::Connected()
00443 {
00444 if (odb)
00445 {
00446 if (mysql_ping(&odb -> mysql))
00447 {
00448 GetDatabase().error(*this, "mysql_ping() failed");
00449 return false;
00450 }
00451 }
00452 return odb ? true : false;
00453 }
00454
00455
00456 void Query::error(const std::string& x)
00457 {
00458 m_db.error(*this, x.c_str());
00459 }
00460
00461
00462 std::string Query::safestr(const std::string& x)
00463 {
00464 return m_db.safestr(x);
00465 }
00466
00467
00468 #ifdef MYSQLW_NAMESPACE
00469 }
00470 #endif
00471