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 

Generated on Wed Sep 28 07:44:06 2005 for MySQL++ by doxygen1.2.18