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