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(0),
    00190         OptionalExceptions(te),
    00191         Lockable(false),
    00192         def(this),
    00193         conn_(c),
    00194         success_(false)
    00195         {
    00196                 init(&sbuffer_);
    00197                 success_ = true;
    00198         }
    00199
    00207         MYSQLPP_EXPORT Query(const Query& q);
    00208
    00213         MYSQLPP_EXPORT Query& operator=(const Query& rhs);
    00214
    00220         MYSQLPP_EXPORT std::string error();
    00221
    00227         MYSQLPP_EXPORT bool success();
    00228
    00236         MYSQLPP_EXPORT void parse();
    00237
    00242         MYSQLPP_EXPORT void reset();
    00243
    00245         std::string preview() { return str(def); }
    00246
    00248         std::string preview(SQLQueryParms& p)
    00249         {
    00250                 return str(p);
    00251         }
    00252
    00254         std::string str()
    00255         {
    00256                 return str(def);
    00257         }
    00258
    00263         std::string str(query_reset r)
    00264         {
    00265                 return str(def, r);
    00266         }
    00267
    00272         MYSQLPP_EXPORT std::string str(SQLQueryParms& p);
    00273
    00280         MYSQLPP_EXPORT std::string str(SQLQueryParms& p, query_reset r);
    00281
    00293         MYSQLPP_EXPORT bool exec(const std::string& str);
    00294
    00311         ResNSel execute() { return execute(def); }
    00312
    00316         MYSQLPP_EXPORT ResNSel execute(const char* str);
    00317
    00342         ResUse use() { return use(def); }
    00343
    00349         MYSQLPP_EXPORT ResUse use(const char* str);
    00350
    00372         Result store() { return store(def); }
    00373
    00379         MYSQLPP_EXPORT Result store(const char* str);
    00380
    00407         MYSQLPP_EXPORT Result store_next();
    00408
    00420         MYSQLPP_EXPORT bool more_results();
    00421
    00439         template <class Sequence>
    00440         void storein_sequence(Sequence& con, query_reset r = RESET_QUERY)
    00441         {
    00442                 storein_sequence_(con, def, r);
    00443         }
    00444
    00452         template <class Set>
    00453         void storein_set(Set& con, query_reset r = RESET_QUERY)
    00454         {
    00455                 storein_set(con, def, r);
    00456         }
    00457
    00476         template <class Container>
    00477         void storein(Container& con, query_reset r = RESET_QUERY)
    00478         {
    00479                 storein(con, def, r);
    00480         }
    00481
    00483         template <class T>
    00484         void storein(std::vector<T>& con, const char* s)
    00485         {
    00486                 storein_sequence(con, s);
    00487         }
    00488
    00490         template <class T>
    00491         void storein(std::deque<T>& con, const char* s)
    00492         {
    00493                 storein_sequence(con, s);
    00494         }
    00495
    00497         template <class T>
    00498         void storein(std::list<T>& con, const char* s)
    00499         {
    00500                 storein_sequence(con, s);
    00501         }
    00502
    00503 #if defined(HAVE_EXT_SLIST)
    00506         template <class T>
    00507         void storein(__gnu_cxx::slist<T>& con, const char* s)
    00508         {
    00509                 storein_sequence(con, s);
    00510         }
    00511 #elif defined(HAVE_GLOBAL_SLIST)
    00518         template <class T>
    00519         void storein(slist<T>& con, const char* s)
    00520         {
    00521                 storein_sequence(con, s);
    00522         }
    00523 #elif defined(HAVE_STD_SLIST)
    00529         template <class T>
    00530         void storein(std::slist<T>& con, const char* s)
    00531         {
    00532                 storein_sequence(con, s);
    00533         }
    00534 #endif
    00535
    00537         template <class T>
    00538         void storein(std::set<T>& con, const char* s)
    00539         {
    00540                 storein_set(con, s);
    00541         }
    00542
    00544         template <class T>
    00545         void storein(std::multiset<T>& con, const char* s)
    00546         {
    00547                 storein_set(con, s);
    00548         }
    00549
    00560         template <class T>
    00561         Query& update(const T& o, const T& n)
    00562         {
    00563                 reset();
    00564
    00565                 // Cast required for VC++ 2003 due to error in overloaded operator
    00566                 // lookup logic.  For an explanation of the problem, see:
    00567                 // http://groups-beta.google.com/group/microsoft.public.vc.stl/browse_thread/thread/9a68d84644e64f15
    00568                 dynamic_cast<std::ostream&>(*this) << "UPDATE " << o.table() <<
    00569                                 " SET " << n.equal_list() << " WHERE " <<
    00570                                 o.equal_list(" AND ", sql_use_compare);
    00571                 return *this;
    00572         }
    00573
    00582         template <class T>
    00583         Query& insert(const T& v)
    00584         {
    00585                 reset();
    00586
    00587                 // See above comment for cast rationale
    00588                 dynamic_cast<std::ostream&>(*this) << "INSERT INTO " <<
    00589                                 v.table() << " (" << v.field_list() << ") VALUES (" <<
    00590                                 v.value_list() << ")";
    00591                 return *this;
    00592         }
    00593
    00607         template <class Iter>
    00608         Query& insert(Iter first, Iter last)
    00609         {
    00610                 reset();
    00611                 if (first == last) {
    00612                         return *this;   // empty set!
    00613                 }
    00614
    00615                 // See above comment for cast rationale
    00616                 dynamic_cast<std::ostream&>(*this) << "INSERT INTO " <<
    00617                                 first->table() << " (" << first->field_list() <<
    00618                                 ") VALUES (" << first->value_list() << ')';
    00619
    00620                 Iter it = first + 1;
    00621                 while (it != last) {
    00622                         dynamic_cast<std::ostream&>(*this) << ",(" <<
    00623                                         it->value_list() << ')';
    00624                         ++it;
    00625                 }
    00626
    00627                 return *this;
    00628         }
    00629
    00639         template <class T>
    00640         Query& replace(const T& v)
    00641         {
    00642                 reset();
    00643
    00644                 // See above comment for cast rationale
    00645                 dynamic_cast<std::ostream&>(*this) << "REPLACE INTO " <<
    00646                                 v.table() << " (" << v.field_list() << ") VALUES (" <<
    00647                                 v.value_list() << ")";
    00648                 return *this;
    00649         }
    00650
    00652         operator bool() { return success(); }
    00653
    00655         bool operator !() { return !success(); }
    00656
    00657 #if !defined(DOXYGEN_IGNORE)
    00658         // Declare the remaining overloads.  These are hidden down here partly
    00659         // to keep the above code clear, but also so that we may hide them
    00660         // from Doxygen, which gets confused by macro instantiations that look
    00661         // like method declarations.
    00662         mysql_query_define0(std::string, preview)
    00663         mysql_query_define0(std::string, str);
    00664         mysql_query_define1(ResNSel, execute)
    00665         mysql_query_define1(Result, store)
    00666         mysql_query_define1(ResUse, use)
    00667         mysql_query_define2(storein_sequence)
    00668         mysql_query_define2(storein_set)
    00669         mysql_query_define2(storein)
    00670 #endif // !defined(DOXYGEN_IGNORE)
    00671
    00675         SQLQueryParms def;
    00676
    00677 private:
    00678         friend class SQLQueryParms;
    00679
    00681         Connection* conn_;
    00682
    00684         bool success_;
    00685
    00687         std::vector<SQLParseElement> parse_elems_;
    00688
    00691         std::vector<std::string> parsed_names_;
    00692
    00694         std::map<std::string, short int> parsed_nums_;
    00695
    00697         std::stringbuf sbuffer_;
    00698
    00700         my_ulonglong affected_rows() const;
    00701         my_ulonglong insert_id();
    00702         std::string info();
    00703         char* preview_char();
    00704
    00706         void proc(SQLQueryParms& p);
    00707
    00708         // Locking mechanism
    00709         bool lock();
    00710         void unlock();
    00711
    00712         SQLString* pprepare(char option, SQLString& S, bool replace = true);
    00713 };
    00714
    00715
    00716 #if !defined(DOXYGEN_IGNORE)
    00717 // Doxygen will not generate documentation for this section.
    00718
    00719 template <class Seq>
    00720 void Query::storein_sequence(Seq& seq, SQLQueryParms& p, query_reset r)
    00721 {
    00722         r = parse_elems_.size() ? DONT_RESET : RESET_QUERY;
    00723         storein_sequence(seq, str(p, r).c_str());
    00724 }
    00725
    00726
    00727 template <class Sequence>
    00728 void Query::storein_sequence(Sequence& con, const char* s)
    00729 {
    00730         ResUse result = use(s);
    00731         while (1) {
    00732                 MYSQL_ROW d = mysql_fetch_row(result.raw_result());
    00733                 if (!d)
    00734                         break;
    00735                 Row row(d, &result, mysql_fetch_lengths(result.raw_result()),
    00736                                 true);
    00737                 if (!row)
    00738                         break;
    00739                 con.push_back(typename Sequence::value_type(row));
    00740         }
    00741 }
    00742
    00743
    00744 template <class Set>
    00745 void Query::storein_set(Set& sett, SQLQueryParms& p, query_reset r)
    00746 {
    00747         r = parse_elems_.size() ? DONT_RESET : RESET_QUERY;
    00748         storein_set(sett, str(p, r).c_str());
    00749 }
    00750
    00751
    00752 template <class Set>
    00753 void Query::storein_set(Set& con, const char* s)
    00754 {
    00755         ResUse result = use(s);
    00756         while (1) {
    00757                 MYSQL_ROW d = mysql_fetch_row(result.raw_result());
    00758                 if (!d)
    00759                         return;
    00760                 Row row(d, &result, mysql_fetch_lengths(result.raw_result()),
    00761                                 true);
    00762                 if (!row)
    00763                         break;
    00764                 con.insert(typename Set::value_type(row));
    00765         }
    00766 }
    00767
    00768
    00769 template <class T>
    00770 void Query::storein(T& con, SQLQueryParms& p, query_reset r)
    00771 {
    00772         r = parse_elems_.size() ? DONT_RESET : RESET_QUERY;
    00773         storein(con, str(p, r).c_str());
    00774 }
    00775
    00776
    00777 #endif // !defined(DOXYGEN_IGNORE)
    00778
    00779 } // end namespace mysqlpp
    00780
    00781 #endif
    00782