MySQL++ Reference Manual

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

# query.h

Go to the documentation of this file.

    00001
    00002
    00003
    00004 /***********************************************************************
    00005  Copyright (c) 1998 by Kevin Atkinson, (c) 1999, 2000 and 2001 by
    00006  MySQL AB, and (c) 2004, 2005 by Educational Technology Resources, Inc.
    00007  Others may also hold copyrights on code in this file.  See the CREDITS
    00008  file in the top directory of the distribution for details.
    00009
    00010  This file is part of MySQL++.
    00011
    00012  MySQL++ is free software; you can redistribute it and/or modify it
    00013  under the terms of the GNU Lesser General Public License as published
    00014  by the Free Software Foundation; either version 2.1 of the License, or
    00015  (at your option) any later version.
    00016
    00017  MySQL++ is distributed in the hope that it will be useful, but WITHOUT
    00018  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    00019  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
    00020  License for more details.
    00021
    00022  You should have received a copy of the GNU Lesser General Public
    00023  License along with MySQL++; if not, write to the Free Software
    00024  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
    00025  USA
    00026 ***********************************************************************/
    00027
    00028 #ifndef MYSQLPP_QUERY_H
    00029 #define MYSQLPP_QUERY_H
    00030
    00031 #include "defs.h"
    00032
    00033 #include "lockable.h"
    00034 #include "noexceptions.h"
    00035 #include "qparms.h"
    00036 #include "result.h"
    00037 #include "row.h"
    00038 #include "sql_string.h"
    00039
    00040 #include <mysql.h>
    00041
    00042 #include <deque>
    00043 #include <list>
    00044 #include <map>
    00045 #include <set>
    00046 #include <sstream>
    00047 #include <vector>
    00048
    00049 #ifdef HAVE_EXT_SLIST
    00050 #  include <ext/slist>
    00051 #else
    00052 #  if defined(HAVE_STD_SLIST) || defined(HAVE_GLOBAL_SLIST)
    00053 #      include <slist>
    00054 #  endif
    00055 #endif
    00056
    00057
    00059 #define mysql_query_define0(RETURN, FUNC)\
    00060   RETURN FUNC (ss a)\
    00061     {return FUNC (parms() << a);}\
    00062   RETURN FUNC (ss a, ss b)\
    00063     {return FUNC (parms() << a << b);}\
    00064   RETURN FUNC (ss a, ss b, ss c)\
    00065     {return FUNC (parms() << a << b << c);}\
    00066   RETURN FUNC (ss a, ss b, ss c, ss d)\
    00067     {return FUNC (parms() << a << b << c << d);}\
    00068   RETURN FUNC (ss a, ss b, ss c, ss d, ss e)\
    00069     {return FUNC (parms() << a << b << c << d << e);} \
    00070   RETURN FUNC (ss a, ss b, ss c, ss d, ss e, ss f)\
    00071     {return FUNC (parms() << a << b << c << d << e << f);}\
    00072   RETURN FUNC (ss a, ss b, ss c, ss d, ss e, ss f, ss g)\
    00073     {return FUNC (parms() << a << b << c << d << e << f << g);}\
    00074   RETURN FUNC (ss a, ss b, ss c, ss d, ss e, ss f, ss g, ss h)\
    00075     {return FUNC (parms() << a << b << c << d << e << f << g << h);}\
    00076   RETURN FUNC (ss a, ss b, ss c, ss d, ss e, ss f, ss g, ss h, ss i)\
    00077     {return FUNC (parms() << a << b << c << d << e << f << g << h << i);}\
    00078   RETURN FUNC (ss a,ss b,ss c,ss d,ss e,ss f,ss g,ss h,ss i,ss j)\
    00079     {return FUNC (parms() <<a <<b <<c <<d <<e <<f <<g <<h <<i <<j);}\
    00080   RETURN FUNC (ss a,ss b,ss c,ss d,ss e,ss f,ss g,ss h,ss i,ss j,ss k)\
    00081     {return FUNC (parms() <<a <<b <<c <<d <<e <<f <<g <<h <<i <<j <<k);}\
    00082   RETURN FUNC (ss a,ss b,ss c,ss d,ss e,ss f,ss g,ss h,ss i,ss j,ss k,ss l)\
    00083     {return FUNC (parms() <<a <<b <<c <<d <<e <<f <<g <<h <<i <<j <<k <<l);}\
    00084
    00085
    00086 #define mysql_query_define1(RETURN, FUNC) \
    00087   MYSQLPP_EXPORT RETURN FUNC (parms &p);\
    00088   mysql_query_define0(RETURN,FUNC) \
    00089
    00090
    00091 #define mysql_query_define2(FUNC) \
    00092   template <class T1> void FUNC (T1 &con, const char* str); \
    00093   template <class T1> void FUNC (T1 &con, parms &p, query_reset r = RESET_QUERY);\
    00094   template <class T1> void FUNC (T1 &con, ss a)\
    00095         {FUNC (con, parms() << a);}\
    00096   template <class T1> void FUNC (T1 &con, ss a, ss b)\
    00097         {FUNC (con, parms() << a << b);}\
    00098   template <class T1> void FUNC (T1 &con, ss a, ss b, ss c)\
    00099         {FUNC (con, parms() << a << b << c);}\
    00100   template <class T1> void FUNC (T1 &con, ss a, ss b, ss c, ss d)\
    00101         {FUNC (con, parms() << a << b << c << d);}\
    00102   template <class T1> void FUNC (T1 &con, ss a, ss b, ss c, ss d, ss e)\
    00103         {FUNC (con, parms() << a << b << c << d << e);} \
    00104   template <class T1> void FUNC (T1 &con, ss a, ss b, ss c, ss d, ss e, ss f)\
    00105         {FUNC (con, parms() << a << b << c << d << e << f);}\
    00106   template <class T1> void FUNC (T1 &con,ss a,ss b,ss c,ss d,ss e,ss f,ss g)\
    00107         {FUNC (con, parms() << a << b << c << d << e << f << g);}\
    00108   template <class T1> void FUNC (T1 &con,ss a,ss b,ss c,ss d,ss e,ss f,ss g,ss h)\
    00109         {FUNC (con, parms() << a << b << c << d << e << f << g << h);}\
    00110   template <class T1> void FUNC (T1 &con, ss a, ss b, ss c, ss d, ss e, ss f, ss g, ss h, ss i)\
    00111         {FUNC (con, parms() << a << b << c << d << e << f << g << h << i);}\
    00112   template <class T1> void FUNC (T1 &con, ss a,ss b,ss c,ss d,ss e,ss f,ss g,ss h,ss i,ss j)\
    00113         {FUNC (con, parms() <<a <<b <<c <<d <<e <<f <<g <<h <<i <<j);}\
    00114   template <class T1> void FUNC (T1 &con, ss a,ss b,ss c,ss d,ss e,ss f,ss g,ss h,ss i,ss j,ss k)\
    00115         {FUNC (con, parms() <<a <<b <<c <<d <<e <<f <<g <<h <<i <<j <<k);}\
    00116   template <class T1> void FUNC (T1 &con, ss a,ss b,ss c,ss d,ss e,ss f,ss g,ss h,ss i,ss j,ss k,ss l)\
    00117         {FUNC (con, parms() <<a <<b <<c <<d <<e <<f <<g <<h <<i <<j <<k <<l);}\
    00118
    00119 namespace mysqlpp {
    00120
    00121 class Connection;
    00122
    00124 enum query_reset { DONT_RESET, RESET_QUERY };
    00125
    00174
    00175 class Query : public std::ostream,
    00176                 public OptionalExceptions, public Lockable
    00177 {
    00178 public:
    00179         typedef const SQLString& ss;
    00180         typedef SQLQueryParms parms;
    00181
    00188         Query(Connection* c, bool te = true) :
    00189         std::ostream(&sbuffer_),
    00190         OptionalExceptions(te),
    00191         Lockable(false),
    00192         def(this),
    00193         conn_(c),
    00194         success_(false)
    00195         {
    00196                 success_ = true;
    00197         }
    00198
    00206         MYSQLPP_EXPORT Query(const Query& q);
    00207
    00212         MYSQLPP_EXPORT Query& operator=(const Query& rhs);
    00213
    00219         MYSQLPP_EXPORT std::string error();
    00220
    00226         MYSQLPP_EXPORT bool success();
    00227
    00235         MYSQLPP_EXPORT void parse();
    00236
    00241         MYSQLPP_EXPORT void reset();
    00242
    00244         std::string preview() { return str(def); }
    00245
    00247         std::string preview(SQLQueryParms& p)
    00248         {
    00249                 return str(p);
    00250         }
    00251
    00253         std::string str()
    00254         {
    00255                 return str(def);
    00256         }
    00257
    00262         std::string str(query_reset r)
    00263         {
    00264                 return str(def, r);
    00265         }
    00266
    00271         MYSQLPP_EXPORT std::string str(SQLQueryParms& p);
    00272
    00279         MYSQLPP_EXPORT std::string str(SQLQueryParms& p, query_reset r);
    00280
    00292         MYSQLPP_EXPORT bool exec(const std::string& str);
    00293
    00310         ResNSel execute() { return execute(def); }
    00311
    00315         MYSQLPP_EXPORT ResNSel execute(const char* str);
    00316
    00341         ResUse use() { return use(def); }
    00342
    00348         MYSQLPP_EXPORT ResUse use(const char* str);
    00349
    00371         Result store() { return store(def); }
    00372
    00378         MYSQLPP_EXPORT Result store(const char* str);
    00379
    00406         MYSQLPP_EXPORT Result store_next();
    00407
    00419         MYSQLPP_EXPORT bool more_results();
    00420
    00438         template <class Sequence>
    00439         void storein_sequence(Sequence& con, query_reset r = RESET_QUERY)
    00440         {
    00441                 storein_sequence_(con, def, r);
    00442         }
    00443
    00451         template <class Set>
    00452         void storein_set(Set& con, query_reset r = RESET_QUERY)
    00453         {
    00454                 storein_set(con, def, r);
    00455         }
    00456
    00475         template <class Container>
    00476         void storein(Container& con, query_reset r = RESET_QUERY)
    00477         {
    00478                 storein(con, def, r);
    00479         }
    00480
    00482         template <class T>
    00483         void storein(std::vector<T>& con, const char* s)
    00484         {
    00485                 storein_sequence(con, s);
    00486         }
    00487
    00489         template <class T>
    00490         void storein(std::deque<T>& con, const char* s)
    00491         {
    00492                 storein_sequence(con, s);
    00493         }
    00494
    00496         template <class T>
    00497         void storein(std::list<T>& con, const char* s)
    00498         {
    00499                 storein_sequence(con, s);
    00500         }
    00501
    00502 #if defined(HAVE_EXT_SLIST)
    00505         template <class T>
    00506         void storein(__gnu_cxx::slist<T>& con, const char* s)
    00507         {
    00508                 storein_sequence(con, s);
    00509         }
    00510 #elif defined(HAVE_GLOBAL_SLIST)
    00517         template <class T>
    00518         void storein(slist<T>& con, const char* s)
    00519         {
    00520                 storein_sequence(con, s);
    00521         }
    00522 #elif defined(HAVE_STD_SLIST)
    00528         template <class T>
    00529         void storein(std::slist<T>& con, const char* s)
    00530         {
    00531                 storein_sequence(con, s);
    00532         }
    00533 #endif
    00534
    00536         template <class T>
    00537         void storein(std::set<T>& con, const char* s)
    00538         {
    00539                 storein_set(con, s);
    00540         }
    00541
    00543         template <class T>
    00544         void storein(std::multiset<T>& con, const char* s)
    00545         {
    00546                 storein_set(con, s);
    00547         }
    00548
    00559         template <class T>
    00560         Query& update(const T& o, const T& n)
    00561         {
    00562                 reset();
    00563
    00564                 // Cast required for VC++ 2003 due to error in overloaded operator
    00565                 // lookup logic.  For an explanation of the problem, see:
    00566                 // http://groups-beta.google.com/group/microsoft.public.vc.stl/browse_thread/thread/9a68d84644e64f15
    00567                 dynamic_cast<std::ostream&>(*this) << "UPDATE " << o.table() <<
    00568                                 " SET " << n.equal_list() << " WHERE " <<
    00569                                 o.equal_list(" AND ", sql_use_compare);
    00570                 return *this;
    00571         }
    00572
    00581         template <class T>
    00582         Query& insert(const T& v)
    00583         {
    00584                 reset();
    00585
    00586                 // See above comment for cast rationale
    00587                 dynamic_cast<std::ostream&>(*this) << "INSERT INTO " <<
    00588                                 v.table() << " (" << v.field_list() << ") VALUES (" <<
    00589                                 v.value_list() << ")";
    00590                 return *this;
    00591         }
    00592
    00606         template <class Iter>
    00607         Query& insert(Iter first, Iter last)
    00608         {
    00609                 reset();
    00610                 if (first == last) {
    00611                         return *this;   // empty set!
    00612                 }
    00613
    00614                 // See above comment for cast rationale
    00615                 dynamic_cast<std::ostream&>(*this) << "INSERT INTO " <<
    00616                                 first->table() << " (" << first->field_list() <<
    00617                                 ") VALUES (" << first->value_list() << ')';
    00618
    00619                 Iter it = first + 1;
    00620                 while (it != last) {
    00621                         *this << ",(" << it->value_list() << ')';
    00622                         ++it;
    00623                 }
    00624
    00625                 return *this;
    00626         }
    00627
    00637         template <class T>
    00638         Query& replace(const T& v)
    00639         {
    00640                 reset();
    00641
    00642                 // See above comment for cast rationale
    00643                 dynamic_cast<std::ostream&>(*this) << "REPLACE INTO " <<
    00644                                 v.table() << " (" << v.field_list() << ") VALUES (" <<
    00645                                 v.value_list() << ")";
    00646                 return *this;
    00647         }
    00648
    00650         operator bool() { return success(); }
    00651
    00653         bool operator !() { return !success(); }
    00654
    00655 #if !defined(DOXYGEN_IGNORE)
    00656         // Declare the remaining overloads.  These are hidden down here partly
    00657         // to keep the above code clear, but also so that we may hide them
    00658         // from Doxygen, which gets confused by macro instantiations that look
    00659         // like method declarations.
    00660         mysql_query_define0(std::string, preview)
    00661         mysql_query_define0(std::string, str);
    00662         mysql_query_define1(ResNSel, execute)
    00663         mysql_query_define1(Result, store)
    00664         mysql_query_define1(ResUse, use)
    00665         mysql_query_define2(storein_sequence)
    00666         mysql_query_define2(storein_set)
    00667         mysql_query_define2(storein)
    00668 #endif // !defined(DOXYGEN_IGNORE)
    00669
    00673         SQLQueryParms def;
    00674
    00675 private:
    00676         friend class SQLQueryParms;
    00677
    00679         Connection* conn_;
    00680
    00682         bool success_;
    00683
    00685         std::vector<SQLParseElement> parse_elems_;
    00686
    00689         std::vector<std::string> parsed_names_;
    00690
    00692         std::map<std::string, short int> parsed_nums_;
    00693
    00695         std::stringbuf sbuffer_;
    00696
    00698         my_ulonglong affected_rows() const;
    00699         my_ulonglong insert_id();
    00700         std::string info();
    00701         char* preview_char();
    00702
    00704         void proc(SQLQueryParms& p);
    00705
    00706         // Locking mechanism
    00707         bool lock();
    00708         void unlock();
    00709
    00710         SQLString* pprepare(char option, SQLString& S, bool replace = true);
    00711 };
    00712
    00713
    00714 #if !defined(DOXYGEN_IGNORE)
    00715 // Doxygen will not generate documentation for this section.
    00716
    00717 template <class Seq>
    00718 void Query::storein_sequence(Seq& seq, SQLQueryParms& p, query_reset r)
    00719 {
    00720         r = parse_elems_.size() ? DONT_RESET : RESET_QUERY;
    00721         storein_sequence(seq, str(p, r).c_str());
    00722 }
    00723
    00724
    00725 template <class Sequence>
    00726 void Query::storein_sequence(Sequence& con, const char* s)
    00727 {
    00728         ResUse result = use(s);
    00729         while (1) {
    00730                 MYSQL_ROW d = mysql_fetch_row(result.raw_result());
    00731                 if (!d)
    00732                         break;
    00733                 Row row(d, &result, mysql_fetch_lengths(result.raw_result()),
    00734                                 true);
    00735                 if (!row)
    00736                         break;
    00737                 con.push_back(typename Sequence::value_type(row));
    00738         }
    00739 }
    00740
    00741
    00742 template <class Set>
    00743 void Query::storein_set(Set& sett, SQLQueryParms& p, query_reset r)
    00744 {
    00745         r = parse_elems_.size() ? DONT_RESET : RESET_QUERY;
    00746         storein_set(sett, str(p, r).c_str());
    00747 }
    00748
    00749
    00750 template <class Set>
    00751 void Query::storein_set(Set& con, const char* s)
    00752 {
    00753         ResUse result = use(s);
    00754         while (1) {
    00755                 MYSQL_ROW d = mysql_fetch_row(result.raw_result());
    00756                 if (!d)
    00757                         return;
    00758                 Row row(d, &result, mysql_fetch_lengths(result.raw_result()),
    00759                                 true);
    00760                 if (!row)
    00761                         break;
    00762                 con.insert(typename Set::value_type(row));
    00763         }
    00764 }
    00765
    00766
    00767 template <class T>
    00768 void Query::storein(T& con, SQLQueryParms& p, query_reset r)
    00769 {
    00770         r = parse_elems_.size() ? DONT_RESET : RESET_QUERY;
    00771         storein(con, str(p, r).c_str());
    00772 }
    00773
    00774
    00775 #endif // !defined(DOXYGEN_IGNORE)
    00776
    00777 } // end namespace mysqlpp
    00778
    00779 #endif
    00780