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 

Generated on Wed Nov 23 14:54:48 2005 for MySQL++ by doxygen1.2.18