Forums  +  C++ and Sockets  +  C++ and SQL: MySQL, sqlite, ODBC  +  Miscellaneous Projects
Logo
~Database~
~ C++ ~
~Contact~

Query.cpp

Go to the documentation of this file.
00001 
00007 /*
00008 Copyright (C) 2001  Anders Hedstrom
00009 
00010 This program is made available under the terms of the GNU GPL.
00011 
00012 If you would like to use this program in a closed-source application,
00013 a separate license agreement is available. For information about 
00014 the closed-source license agreement for this program, please
00015 visit http://www.alhem.net/sqlwrapped/license.html and/or
00016 email license@alhem.net.
00017 
00018 This program is free software; you can redistribute it and/or
00019 modify it under the terms of the GNU General Public License
00020 as published by the Free Software Foundation; either version 2
00021 of the License, or (at your option) any later version.
00022 
00023 This program is distributed in the hope that it will be useful,
00024 but WITHOUT ANY WARRANTY; without even the implied warranty of
00025 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00026 GNU General Public License for more details.
00027 
00028 You should have received a copy of the GNU General Public License
00029 along with this program; if not, write to the Free Software
00030 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
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); // returns 0 if fail
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 {               // query, no result
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 // methods using db specific api calls
00132 
00133 MYSQL_RES *Query::get_result(const std::string& sql)
00134 {       // query, result
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(); // %! changed from 1.0 which didn't return NULL on failed query
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 } // namespace MYSQLW_NAMESPACE {
00470 #endif
00471 
Page, code, and content Copyright (C) 2006 by Anders Hedström