Logo
~Sockets~
~Examples~
~Contact~


Query.cpp

Go to the documentation of this file.
00001 // Query.cpp
00002 /*
00003 Copyright (C) 2001-2005  Anders Hedstrom
00004 
00005 This program is free software; you can redistribute it and/or
00006 modify it under the terms of the GNU General Public License
00007 as published by the Free Software Foundation; either version 2
00008 of the License, or (at your option) any later version.
00009 
00010 This program is distributed in the hope that it will be useful,
00011 but WITHOUT ANY WARRANTY; without even the implied warranty of
00012 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00013 GNU General Public License for more details.
00014 
00015 You should have received a copy of the GNU General Public License
00016 along with this program; if not, write to the Free Software
00017 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
00018 */
00019 
00020 #include <stdio.h>
00021 #include <stdlib.h>
00022 #include <sys/types.h>
00023 namespace SQLITE {
00024 #include <sqlite/sqlite.h>
00025 }
00026 #include <string.h>
00027 // STL include begin
00028 #ifdef WIN32
00029 #pragma warning(push, 3)
00030 #endif
00031 //
00032 #include <vector>
00033 #include <string>
00034 //
00035 #ifdef WIN32
00036 #pragma warning(pop)
00037 #endif
00038 // STL include end
00039 using std::string;
00040 
00041 #include "Session.h"
00042 #include "Database.h"
00043 #include "Query.h"
00044 
00045 
00046 Query::Query()
00047 :db(NULL)
00048 ,odb(NULL)
00049 ,res(NULL)
00050 ,m_tmpstrbase(NULL)
00051 ,rowcount(0)
00052 ,_debug(0)
00053 ,_syslog(0)
00054 ,m_fetchrows(0)
00055 ,m_results(0)
00056 ,m_ncolumns(0)
00057 {
00058 }
00059 
00060 Query::Query(Database *dbin)
00061 :db(dbin)
00062 ,odb(dbin -> grabdb())
00063 ,res(NULL)
00064 ,m_tmpstrbase(NULL)
00065 ,rowcount(0)
00066 ,_debug(dbin -> debug())
00067 ,_syslog(0)
00068 ,m_fetchrows(0)
00069 ,m_results(0)
00070 ,m_ncolumns(0)
00071 {
00072 }
00073 
00074 Query::Query(Database *dbin,const char *sql)
00075 :db(dbin)
00076 ,odb(dbin -> grabdb())
00077 ,res(NULL)
00078 ,m_tmpstrbase(NULL)
00079 ,rowcount(0)
00080 ,_debug(dbin -> debug())
00081 ,_syslog(0)
00082 ,m_fetchrows(0)
00083 ,m_results(0)
00084 ,m_ncolumns(0)
00085 {
00086         if (!execute(sql))
00087                 fprintf(stderr,"query failed: '%s'\n",sql);
00088 }
00089 
00090 // destructor
00091 
00092 Query::~Query()
00093 {
00094         TMPSTR *tmpstr;
00095 
00096         while (m_tmpstrbase)
00097         {
00098                 tmpstr = m_tmpstrbase -> next;
00099                 delete m_tmpstrbase->buffer;
00100                 delete m_tmpstrbase;
00101                 m_tmpstrbase = tmpstr;
00102         }
00103 //printf("~Query()\n");
00104         if (res)
00105         {
00106                 SQLITE::sqlite_free_table(res);
00107                 res = NULL;
00108         }
00109         if (odb)
00110                 db -> freedb(odb);
00111 }
00112 
00113 
00114 short Query::execute(const std::string &sql)
00115 {
00116         return execute(sql.c_str());
00117 }
00118 
00119 
00120 short Query::execute(const char *sql)
00121 {               // query, no result
00122         if (db && odb && res)
00123                 fprintf(stderr,"query busy\n");
00124         if (db && odb && !res)
00125         {
00126                 SQLITE::sqlite *db = static_cast<SQLITE::sqlite *>(odb -> GetHandle());
00127                 char *errmsg;
00128                 m_results = 0;
00129                 m_fetchrows = 1;
00130                 m_ncolumns = 0;
00131                 if (SQLITE::sqlite_get_table(db,sql,&res,&m_results,&m_ncolumns,&errmsg) != SQLITE_OK)
00132                 {
00133                         fprintf(stderr,"query failed: '%s'  because: '%s'\n",sql,errmsg);
00134                 }
00135                 else
00136                 {
00137                         free_result();
00138                         return 1;
00139                 }
00140         }
00141         return 0;
00142 }
00143 
00144 
00145 // methods using db specific api calls
00146 bool Query::get_result(const std::string &sql)
00147 {
00148         return get_result(sql.c_str());
00149 }
00150 
00151 
00152 bool Query::get_result(const char *sql,char **attrs)
00153 {       // query, result
00154         if (attrs); // UNUSED_ALWAYS
00155         if (db && odb && res)
00156                 fprintf(stderr,"query busy\n");
00157         if (db && odb && !res)
00158         {
00159                 SQLITE::sqlite *db = static_cast<SQLITE::sqlite *>(odb -> GetHandle());
00160                 char *errmsg;
00161                 m_results = 0;
00162                 m_fetchrows = 1;
00163                 m_ncolumns = 0;
00164                 if (SQLITE::sqlite_get_table(db,sql,&res,&m_results,&m_ncolumns,&errmsg) != SQLITE_OK)
00165                 {
00166                         fprintf(stderr,"query failed: '%s'  because: '%s'\n",sql,errmsg);
00167                 }
00168                 else
00169                 {
00170                         return 1;
00171                 }
00172         }
00173         return false;
00174 }
00175 
00176 void Query::free_result()
00177 {
00178         if (db && odb && res)
00179         {
00180                 SQLITE::sqlite_free_table(res);
00181                 res = NULL;
00182         }
00183 }
00184 
00185 bool Query::fetch_row()
00186 {
00187         rowcount = 0;
00188         if (db && odb && res)
00189         {
00190                 if (m_fetchrows <= m_results)
00191                 {
00192                         for (int i = 0; i < m_ncolumns; i++)
00193                                 row[i] = res[m_fetchrows * m_ncolumns + i];
00194                         m_fetchrows++;
00195                         return true;
00196                 }
00197         }
00198         return false;
00199 }
00200 
00201 long Query::insert_id()
00202 {
00203         if (db && odb)
00204         {
00205                 SQLITE::sqlite *db = static_cast<SQLITE::sqlite *>(odb -> GetHandle());
00206                 return SQLITE::sqlite_last_insert_rowid(db);
00207         }
00208         else
00209         {
00210                 return -1;
00211         }
00212 }
00213 
00214 long Query::num_rows()
00215 {
00216         return db && odb && res ? m_results : 0;
00217 }
00218 
00219 // data retreival methods
00220 
00221 char *Query::getstr(int x)
00222 {
00223         if (db && odb && res && row)
00224                 return row[x] ? row[x] : (char *)"";
00225         else
00226                 return NULL;
00227 }
00228 
00229 char *Query::getstr()
00230 {
00231         return Query::getstr(rowcount++);
00232 }
00233 
00234 double Query::getnum(int x)
00235 {
00236         return db && odb && res && row && row[x] ? atof(row[x]) : 0;
00237 }
00238 
00239 long Query::getval(int x)
00240 {
00241         return db && odb && res && row && row[x] ? atol(row[x]) : 0;
00242 }
00243 
00244 double Query::getnum()
00245 {
00246         return getnum(rowcount++);
00247 }
00248 
00249 long Query::getval()
00250 {
00251         return getval(rowcount++);
00252 }
00253 
00254 double Query::get_num(const std::string &sql)
00255 {
00256         return get_num(sql.c_str());
00257 }
00258 
00259 double Query::get_num(const char *sql)
00260 {
00261         double l = 0;
00262         if (Query::get_result(sql))
00263         {
00264                 if (Query::fetch_row())
00265                         l = Query::getnum();
00266                 Query::free_result();
00267         }
00268         return l;
00269 }
00270 
00271 long Query::get_count(const std::string &sql)
00272 {
00273         return get_count(sql.c_str());
00274 }
00275 
00276 long Query::get_count(const char *sql)
00277 {
00278         long l = 0;
00279         if (Query::get_result(sql))
00280         {
00281                 if (Query::fetch_row())
00282                         l = Query::getval();
00283                 Query::free_result();
00284         }
00285         return l;
00286 }
00287 
00288 char *Query::get_string(const std::string &sql)
00289 {
00290         return get_string(sql.c_str());
00291 }
00292 
00293 char *Query::get_string(const char *sql)
00294 {
00295 static  char slask[999];
00296         *slask = 0;
00297         if (Query::get_result(sql))
00298         {
00299                 if (Query::fetch_row())
00300                         strcpy(slask,Query::getstr());
00301                 Query::free_result();
00302         }
00303         return slask;
00304 }
00305 
00306 void Query::debug(short val)
00307 { 
00308         _debug = val; 
00309 }
00310 
00311 void Query::syslog(short val)
00312 { 
00313         _syslog = val; 
00314 }
00315 
00316 //MYSQL_FIELD * STDCALL mysql_fetch_field(MYSQL_RES *result);
00317 /*
00318 MYSQL_FIELD *Query::fetch_field()
00319 {
00320         return db && odb && res ? mysql_fetch_field(res) : NULL;
00321 }
00322 */
00323 
00324 char *Query::fetch_fieldname()
00325 {
00326         if (res)
00327                 return res[rowcount]; // rowcount is colcount actually
00328         return NULL;
00329 }
00330 
00331 
00332 /*
00333 void Query::safestr(char *s) 
00334 {
00335         char *s2 = new char[strlen(s) * 2 + 2];
00336         int i,j = 0;
00337 
00338         *s2 = 0;
00339         for (i = 0; i < (int)strlen(s); i++)
00340                 switch (s[i])
00341                 {
00342                 case '\'':
00343                 case '\\':
00344                 case 34:
00345                         s2[j++] = '\\';
00346                 default:
00347                         s2[j++] = s[i];
00348                 }
00349         s2[j] = 0;
00350         strcpy(s,s2);
00351         delete s2;
00352 }
00353 
00354 
00355 void Query::unsafestr(char *s) 
00356 {
00357         int i;
00358 
00359         for (i = 0; i < (int)strlen(s); i++)
00360                 if (s[i] == '\\')
00361                         memmove(s + i,s + i + 1,strlen(s + i) + 1);
00362 }
00363 */
00364 
00365 
00366 bool Query::GotMore()
00367 {
00368   return (m_fetchrows < m_results) ? true : false;
00369 }
00370 
00371 
00372 // ================================%METHOD%====================================
00373 // Metod                allocsafestr
00374 // Åtkomst              public
00375 //                      Typ             Namn            Beskrivning / Status
00376 //                      --------------- --------------- -----------------------           
00377 // Parametrar           
00378 //
00379 // Returnerar           
00380 //
00381 // Beskrivning          Allocate a temp storage for conversion
00382 // ================================%ENDMETHOD%=================================
00383 char *Query::allocsafestr(const char *s)
00384 {
00385   char                  *str = new char[strlen(s) * 2 + 4];
00386 
00387   safestr(s, str);
00388   return str;
00389 } // allocsafestr
00390 
00391 
00392 // ================================%METHOD%====================================
00393 // Metod                safestr
00394 // Åtkomst              public
00395 //                      Typ             Namn            Beskrivning / Status
00396 //                      --------------- --------------- -----------------------           
00397 // Parametrar           
00398 //
00399 // Returnerar           
00400 //
00401 // Beskrivning          Convert a string to a sql safe string
00402 // ================================%ENDMETHOD%=================================
00403 void Query::safestr(const char *s,char *s2) 
00404 {
00405   int register          i;
00406   int register          j = 0;
00407 
00408   *s2 = 0;
00409   for (i = 0; i < (int)strlen(s); i++)
00410   {
00411     switch (s[i])
00412     {
00413     case '\'':
00414     case '\\':
00415     case 34:
00416       s2[j++] = '\\';
00417     default:
00418       s2[j++] = s[i];
00419     }
00420   }
00421   s2[j] = 0;
00422 } // safestr
00423 
00424 
00425 void Query::safestr(std::string &str)
00426 {
00427         std::string s2;
00428         for (size_t i = 0; i < str.size(); i++)
00429         {
00430                 switch (str[i])
00431                 {
00432                 case '\'':
00433                 case '\\':
00434                 case 34:
00435                         s2 += '\\';
00436                 default:
00437                         s2 += str[i];
00438                 }
00439         }
00440         str = s2;
00441 }
00442 
00443 
00444 // ================================%METHOD%====================================
00445 // Metod                unsafestr
00446 // Åtkomst              public
00447 //                      Typ             Namn            Beskrivning / Status
00448 //                      --------------- --------------- -----------------------           
00449 // Parametrar           
00450 //
00451 // Returnerar           
00452 //
00453 // Beskrivning          Convert an sql safe string to a normal string
00454 // ================================%ENDMETHOD%=================================
00455 void Query::unsafestr(char *s) 
00456 {
00457   int                   i;
00458 
00459   for (i = 0; i < (int)strlen(s); i++)
00460     if (s[i] == '\\')
00461       memmove(s + i,s + i + 1,strlen(s + i) + 1);
00462 } // unsafestr
00463 
00464 
00465 // ================================%METHOD%====================================
00466 // Metod                gettmpstr
00467 // Åtkomst              public
00468 //                      Typ             Namn            Beskrivning / Status
00469 //                      --------------- --------------- -----------------------           
00470 // Parametrar           
00471 //
00472 // Returnerar           
00473 //
00474 // Beskrivning          Allocate a temporary storage
00475 // ================================%ENDMETHOD%=================================
00476 char *Query::gettmpstr(int l)
00477 {
00478   TMPSTR                *tmp = new TMPSTR;
00479 
00480   tmp->next = m_tmpstrbase;
00481   tmp->buffer = new char[l + 1];
00482   tmp->temporary = 0;
00483   m_tmpstrbase = tmp;
00484   return tmp->buffer;
00485 } // gettmpstr
00486 
00487 
00488 string Query::XMLSafe(const string &str)
00489 {
00490         string str2 = "";
00491         char *s = (char *)str.c_str();
00492 
00493         for (int i = 0; i < (int)str.size(); i++)
00494         {
00495                 switch (s[i])
00496                 {
00497                 case '&':
00498                         str2 += "&amp;";
00499                         break;
00500                 case '<':
00501                         str2 += "&lt;";
00502                         break;
00503                 case '>':
00504                         str2 += "&gt;";
00505                         break;
00506                 case '"':
00507                         str2 += "&quot;";
00508                         break;
00509                 case '\'':
00510                         str2 += "&apos;";
00511                         break;
00512                 default:
00513                         str2 += s[i];
00514                 }
00515         }
00516         return str2;
00517 }
00518 
00519 
00520 // ================================%METHOD%====================================
00521 // Metod                ReturnRowAsXML
00522 // Åtkomst              public
00523 //                      Typ             Namn            Beskrivning / Status
00524 //                      --------------- --------------- -----------------------           
00525 // Parametrar           
00526 //
00527 // Returnerar           
00528 //
00529 // Beskrivning          Returns current row as an xml string
00530 // ================================%ENDMETHOD%=================================
00531 /*
00532 void Query::ReturnRowAsXML(string &xml,const string &strObjectName,long dwFlags)
00533 {
00534   string                typ;
00535   string                str;
00536   bool                  endtag =   (dwFlags & DQ_XML_ENDTAG) ? true : false;
00537   bool                  cdata =    (dwFlags & DQ_XML_CDATASTRINGS) ? true : false;
00538   bool                  typeinfo = (dwFlags & DQ_XML_TYPEINFO) ? true : false;
00539   bool                  append =   (dwFlags & DQ_XML_APPEND) ? true : false;
00540   bool                  xmlbegin = (dwFlags & DQ_XML_BEGIN) ? true : false;
00541   bool                  xmlend =   (dwFlags & DQ_XML_END) ? true : false;
00542   char                  slask[32000];
00543 
00544   if (db && odb && res && row)
00545   {
00546     if (!append)
00547     {
00548       xml = "";         // det e bra
00549     }
00550     if (xmlbegin)
00551     {
00552       xml += "<xml version=\"1.0\" encoding=\"ISO-8859-1\">\n";
00553     }
00554     if (strObjectName != "")
00555     {
00556       xml += "<";
00557       xml += strObjectName;
00558       xml += ">\n";
00559     }
00560 
00561     MYSQL_FIELD *field;
00562     int x;
00563     field = fetch_field();
00564     x = 0;
00565     while (field)
00566     {
00567       if (typeinfo)
00568       {
00569       }
00570       typ = "";
00571       if (!*getstr(x))
00572       {
00573         sprintf(slask,"<%s%s/>", field -> name, typ.c_str());
00574         str = slask;
00575       } 
00576       else
00577       {
00578         if (cdata) // && (col->nCType == SQL_C_CHAR || col->nCType == SQL_C_TCHAR))
00579         {
00580           sprintf(slask,"<%s%s><![CDATA[%s]]></%s>\n", field -> name, typ.c_str(), XMLSafe(getstr(x)).c_str(), field -> name);
00581           str = slask;
00582         } 
00583         else
00584         {
00585           sprintf(slask,"<%s%s>%s</%s>\n", field -> name, typ.c_str(), XMLSafe(getstr(x)).c_str(), field -> name);
00586           str = slask;
00587         }
00588       }
00589       xml += str;
00590 
00591       field = fetch_field();
00592       x++;
00593     }
00594     if (endtag && strObjectName != "")
00595     {
00596       xml += "</";
00597       xml += strObjectName;
00598       xml += ">\n";
00599     }
00600     if (xmlend)
00601     {
00602       xml += "</xml>\n";
00603     }
00604   }
00605 }
00606 */
00607 bool Query::getcol(std::string &colname,std::string &coltype,int &width,int &dec,int &nullable)
00608 {
00609         if (res)
00610         {
00611                 colname = res[rowcount];
00612                 return true;
00613         }
00614         return false;
00615 }
00616 
00617 bool Query::getcol(int x,std::string &colname,std::string &coltype,int &width,int &dec,int &nullable)
00618 {
00619         if (res && x >= 0 && x < m_ncolumns)
00620         {
00621                 colname = res[x];
00622                 return true;
00623         }
00624         return false;
00625 }
00626 
00627 
Page, code, and content Copyright (C) 2006 by Anders Hedström
Generated on Mon Aug 29 20:21:47 2005 for C++ Sockets by  doxygen 1.4.4