Main Page   Namespace List   Class Hierarchy   Compound List   File List   Namespace Members   Compound Members   File Members  

sql_query.h

Go to the documentation of this file.
00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 
00010 
00011 
00012 
00013 
00014 
00015 
00016 
00017 /***********************************************************************
00018  Copyright (c) 1998 by Kevin Atkinson, (c) 1999, 2000 and 2001 by
00019  MySQL AB, and (c) 2004, 2005 by Educational Technology Resources, Inc.
00020  Others may also hold copyrights on code in this file.  See the CREDITS
00021  file in the top directory of the distribution for details.
00022 
00023  This file is part of MySQL++.
00024 
00025  MySQL++ is free software; you can redistribute it and/or modify it
00026  under the terms of the GNU Lesser General Public License as published
00027  by the Free Software Foundation; either version 2.1 of the License, or
00028  (at your option) any later version.
00029 
00030  MySQL++ is distributed in the hope that it will be useful, but WITHOUT
00031  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
00032  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
00033  License for more details.
00034 
00035  You should have received a copy of the GNU Lesser General Public
00036  License along with MySQL++; if not, write to the Free Software
00037  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
00038  USA
00039 ***********************************************************************/
00040 
00041 #ifndef MYSQLPP_SQL_QUERY_H
00042 #define MYSQLPP_SQL_QUERY_H
00043 
00044 #include "defs.h"
00045 #include "sql_string.h"
00046 #include "tiny_int.h"
00047 
00048 #include <sstream>
00049 #include <vector>
00050 #include <map>
00051 
00053 #define mysql_query_define0(RETURN, FUNC)\
00054   RETURN FUNC (ss a)\
00055     {return FUNC (parms() << a);}\
00056   RETURN FUNC (ss a, ss b)\
00057     {return FUNC (parms() << a << b);}\
00058   RETURN FUNC (ss a, ss b, ss c)\
00059     {return FUNC (parms() << a << b << c);}\
00060   RETURN FUNC (ss a, ss b, ss c, ss d)\
00061     {return FUNC (parms() << a << b << c << d);}\
00062   RETURN FUNC (ss a, ss b, ss c, ss d, ss e)\
00063     {return FUNC (parms() << a << b << c << d << e);} \
00064   RETURN FUNC (ss a, ss b, ss c, ss d, ss e, ss f)\
00065     {return FUNC (parms() << a << b << c << d << e << f);}\
00066   RETURN FUNC (ss a, ss b, ss c, ss d, ss e, ss f, ss g)\
00067     {return FUNC (parms() << a << b << c << d << e << f << g);}\
00068   RETURN FUNC (ss a, ss b, ss c, ss d, ss e, ss f, ss g, ss h)\
00069     {return FUNC (parms() << a << b << c << d << e << f << g << h);}\
00070   RETURN FUNC (ss a, ss b, ss c, ss d, ss e, ss f, ss g, ss h, ss i)\
00071     {return FUNC (parms() << a << b << c << d << e << f << g << h << i);}\
00072   RETURN FUNC (ss a,ss b,ss c,ss d,ss e,ss f,ss g,ss h,ss i,ss j)\
00073     {return FUNC (parms() <<a <<b <<c <<d <<e <<f <<g <<h <<i <<j);}\
00074   RETURN FUNC (ss a,ss b,ss c,ss d,ss e,ss f,ss g,ss h,ss i,ss j,ss k)\
00075     {return FUNC (parms() <<a <<b <<c <<d <<e <<f <<g <<h <<i <<j <<k);}\
00076   RETURN FUNC (ss a,ss b,ss c,ss d,ss e,ss f,ss g,ss h,ss i,ss j,ss k,\
00077                        ss l)\
00078     {return FUNC (parms() <<a <<b <<c <<d <<e <<f <<g <<h <<i <<j <<k <<l);}\
00079 
00080 namespace mysqlpp {
00081 
00082 class Query;
00083 class SQLQuery;
00084 
00085 
00088 class SQLQueryParms : public std::vector<SQLString>
00089 {
00090 private:
00091         friend class Query;
00092 
00093         typedef const SQLString& ss;
00094         SQLQuery *parent;
00095 
00096 public:
00098         SQLQueryParms() :
00099         parent(0)
00100         {
00101         }
00102         
00107         SQLQueryParms(SQLQuery* p) :
00108         parent(p)
00109         {
00110         }
00111         
00115         bool bound()
00116         {
00117                 return parent != 0;
00118         }
00119 
00121         void clear()
00122         {
00123                 erase(begin(), end());
00124         }
00125 
00127         SQLString& operator [](size_type n)
00128         {
00129                 if (n >= size())
00130                         insert(end(), (n + 1) - size(), "");
00131                 return std::vector<SQLString>::operator [](n);
00132         }
00133 
00135         const SQLString& operator [](size_type n) const
00136         {
00137                 return std::vector<SQLString>::operator [](n);
00138         }
00139         
00141         SQLString& operator [](const char *str);
00142 
00144         const SQLString& operator [](const char *str) const;
00145 
00147         SQLQueryParms& operator <<(const SQLString& str)
00148         {
00149                 push_back(str);
00150                 return *this;
00151         }
00152 
00154         SQLQueryParms& operator +=(const SQLString& str)
00155         {
00156                 push_back(str);
00157                 return *this;
00158         }
00159 
00169         SQLQueryParms operator +(const SQLQueryParms& other) const;
00170 
00171 #if !defined(DOXYGEN_IGNORE)
00172 // Doxygen will not generate documentation for this section.
00173         void set(ss a)
00174         {
00175                 clear();
00176                 *this << a;
00177         }
00178         void set(ss a, ss b)
00179         {
00180                 clear();
00181                 *this << a << b;
00182         }
00183         void set(ss a, ss b, ss c)
00184         {
00185                 clear();
00186                 *this << a << b << c;
00187         }
00188         void set(ss a, ss b, ss c, ss d)
00189         {
00190                 clear();
00191                 *this << a << b << c << d;
00192         }
00193         void set(ss a, ss b, ss c, ss d, ss e)
00194         {
00195                 clear();
00196                 *this << a << b << c << d << e;
00197         }
00198         void set(ss a, ss b, ss c, ss d, ss e, ss f)
00199         {
00200                 clear();
00201                 *this << a << b << c << d << e << f;
00202         }
00203         void set(ss a, ss b, ss c, ss d, ss e, ss f, ss g)
00204         {
00205                 clear();
00206                 *this << a << b << c << d << e << f << g;
00207         }
00208         void set(ss a, ss b, ss c, ss d, ss e, ss f, ss g, ss h)
00209         {
00210                 clear();
00211                 *this << a << b << c << d << e << f << g << h;
00212         }
00213         void set(ss a, ss b, ss c, ss d, ss e, ss f, ss g, ss h, ss i)
00214         {
00215                 clear();
00216                 *this << a << b << c << d << e << f << g << h << i;
00217         }
00218         void set(ss a, ss b, ss c, ss d, ss e, ss f, ss g, ss h, ss i,
00219                          ss j)
00220         {
00221                 clear();
00222                 *this << a << b << c << d << e << f << g << h << i << j;
00223         }
00224         void set(ss a, ss b, ss c, ss d, ss e, ss f, ss g, ss h, ss i,
00225                          ss j, ss k)
00226         {
00227                 clear();
00228                 *this << a << b << c << d << e << f << g << h << i << j << k;
00229         }
00230 #endif // !defined(DOXYGEN_IGNORE)
00231 
00237         void set(ss a, ss b, ss c, ss d, ss e, ss f, ss g, ss h, ss i,
00238                          ss j, ss k, ss l)
00239         {
00240                 clear();
00241                 *this << a << b << c << d << e << f << g << h << i << j << k << l;
00242         }
00243 };
00244 
00245 
00248 enum query_reset { DONT_RESET, RESET_QUERY };
00249 
00250 
00272 
00273 struct SQLParseElement {
00279         SQLParseElement(std::string b, char o, char n) :
00280         before(b),
00281         option(o),
00282         num(n)
00283         {
00284         }
00285         
00286         std::string before;             
00287         char option;                    
00288         char num;                               
00289 };
00290 
00291 
00312 class SQLQuery : public std::stringstream
00313 {
00314 private:
00315         friend class SQLQueryParms;
00316 
00317         char *preview_char();
00318 
00319 protected:
00320         bool Success;                                   
00321         char* errmsg;                                   
00322 
00324         std::vector<SQLParseElement> parsed;
00325 
00328         std::vector<std::string> parsed_names;
00329 
00331         std::map<std::string, int> parsed_nums;
00332 
00333         typedef const SQLString& ss;    
00334         typedef SQLQueryParms parms;    
00335 
00337         void proc(SQLQueryParms& p);
00338 
00339 public:
00341         SQLQuery() :
00342         std::stringstream(),
00343         Success(false),
00344         errmsg(0),
00345         def(this)
00346         {
00347         }
00348         
00350         SQLQuery(const SQLQuery& q);
00351 
00355         SQLQueryParms def;
00356 
00364         void parse();
00365 
00370         std::string error() const
00371         {
00372                 return errmsg;
00373         }
00374         
00376         bool success() const { return Success; }
00377 
00379         operator bool() { return success(); }
00380 
00382         bool operator !() { return !success(); }
00383 
00388         void reset();
00389 
00395         template <class T>
00396         SQLQuery& update(const T& o, const T& n)
00397         {
00398                 reset();
00399 
00400                 // Cast required for VC++ 2003 due to error in overloaded operator
00401                 // lookup logic.  For an explanation of the problem, see:
00402                 // http://groups-beta.google.com/group/microsoft.public.vc.stl/browse_thread/thread/9a68d84644e64f15
00403                 dynamic_cast<std::stringstream&>(*this) << "UPDATE " <<
00404                                 o.table() << " SET " << n.equal_list() << " WHERE " <<
00405                                 o.equal_list(" AND ", sql_use_compare);
00406                 return *this;
00407         }
00408 
00412         template <class T>
00413         SQLQuery& insert(const T& v)
00414         {
00415                 reset();
00416 
00417                 // See above comment for cast rationale
00418                 dynamic_cast<std::stringstream&>(*this) << "INSERT INTO " <<
00419                                 v.table() << " (" << v.field_list() << ") VALUES (" <<
00420                                 v.value_list() << ")";
00421                 return *this;
00422         }
00423 
00429         template <class Iter>
00430         SQLQuery& insert(Iter first, Iter last)
00431         {
00432                 reset();
00433                 if (first == last) {
00434                         return *this;   // empty set!
00435                 }
00436                 
00437                 // See above comment for cast rationale
00438                 dynamic_cast<std::stringstream&>(*this) << "INSERT INTO " <<
00439                                 first->table() << " (" << first->field_list() <<
00440                                 ") VALUES (" << first->value_list() << ')';
00441 
00442                 Iter it = first + 1;
00443                 while (it != last) {
00444                         dynamic_cast<std::stringstream&>(*this) << ",(" <<
00445                                         it->value_list() << ')';
00446                         ++it;
00447                 }
00448 
00449                 return *this;
00450         } 
00451 
00457         template <class T>
00458         SQLQuery& replace(const T& v)
00459         {
00460                 reset();
00461 
00462                 // See above comment for cast rationale
00463                 dynamic_cast<std::stringstream&>(*this) << "REPLACE INTO " <<
00464                                 v.table() << " (" << v.field_list() << ") VALUES (" <<
00465                                 v.value_list() << ")";
00466                 return *this;
00467         }
00468 
00470         std::string str()
00471         {
00472                 return str(def);
00473         }
00474 
00479         std::string str(query_reset r)
00480         {
00481                 return str(def, r);
00482         }
00483 
00488         std::string str(SQLQueryParms& p);
00489 
00496         std::string str(SQLQueryParms& p, query_reset r);
00497 
00498 #if !defined(DOXYGEN_IGNORE)
00499         // Make Doxygen ignore this macro; declaration below is sufficient.
00500         mysql_query_define0(std::string, str);
00501 #endif // !defined(DOXYGEN_IGNORE)
00502 };
00503 
00504 
00505 inline SQLString& SQLQueryParms::operator [](const char* str)
00506 {
00507         if (parent) {
00508                 return operator [](parent->parsed_nums[str]);
00509         }
00510         throw; // only here temporary 
00511 }
00512 
00513 inline const SQLString& SQLQueryParms::operator[] (const char* str) const
00514 {
00515         if (parent) {
00516                 return operator [](parent->parsed_nums[str]);
00517         }
00518         throw; // only here temporary 
00519 }
00520 
00521 } // end namespace mysqlpp
00522 
00523 #endif
00524 

Generated on Thu May 26 09:39:58 2005 for MySQL++ by doxygen1.2.18