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-2006 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 "common.h"
00032 
00033 #include "lockable.h"
00034 #include "noexceptions.h"
00035 #include "qparms.h"
00036 #include "querydef.h"
00037 #include "result.h"
00038 #include "row.h"
00039 #include "sql_string.h"
00040 
00041 #include <mysql.h>
00042 
00043 #include <deque>
00044 #include <iomanip>
00045 #include <list>
00046 #include <map>
00047 #include <set>
00048 #include <sstream>
00049 #include <vector>
00050 
00051 #ifdef HAVE_EXT_SLIST
00052 #  include <ext/slist>
00053 #else
00054 #  if defined(HAVE_STD_SLIST) || defined(HAVE_GLOBAL_SLIST)
00055 #      include <slist>
00056 #  endif
00057 #endif
00058 
00059 namespace mysqlpp {
00060 
00061 #if !defined(DOXYGEN_IGNORE)
00062 // Make Doxygen ignore this
00063 class MYSQLPP_EXPORT Connection;
00064 #endif
00065 
00067 enum query_reset { DONT_RESET, RESET_QUERY };
00068 
00117 
00118 class MYSQLPP_EXPORT Query : public std::ostream,
00119                 public OptionalExceptions, public Lockable
00120 {
00121 public:
00128         Query(Connection* c, bool te = true);
00129 
00137         Query(const Query& q);
00138 
00143         Query& operator=(const Query& rhs);
00144 
00150         std::string error();
00151 
00157         bool success();
00158 
00166         void parse();
00167 
00172         void reset();
00173 
00175         std::string preview() { return str(def); }
00176 
00182         std::string preview(const SQLString& arg0)
00183                         { return preview(SQLQueryParms() << arg0); }
00184 
00186         std::string preview(SQLQueryParms& p) { return str(p); }
00187 
00189         std::string str() { return str(def); }
00190 
00196         std::string str(const SQLString& arg0)
00197                         { return preview(SQLQueryParms() << arg0); }
00198 
00203         std::string str(query_reset r) { return str(def, r); }
00204 
00209         std::string str(SQLQueryParms& p);
00210 
00217         std::string str(SQLQueryParms& p, query_reset r);
00218 
00230         bool exec(const std::string& str);
00231 
00248         ResNSel execute() { return execute(def); }
00249 
00256         ResNSel execute(const SQLString& str);
00257 
00261         ResNSel execute(const char* str);
00262 
00267         ResNSel execute(const char* str, size_t len);
00268 
00293         ResUse use() { return use(def); }
00294 
00300         ResUse use(const SQLString& str);
00301 
00307         ResUse use(const char* str);
00308 
00314         ResUse use(const char* str, size_t len);
00315 
00337         Result store() { return store(def); }
00338 
00344         Result store(const SQLString& str);
00345 
00351         Result store(const char* str);
00352 
00358         Result store(const char* str, size_t len);
00359 
00386         Result store_next();
00387 
00399         bool more_results();
00400 
00418         template <class Sequence>
00419         void storein_sequence(Sequence& con, query_reset r = RESET_QUERY)
00420         {
00421                 storein_sequence_(con, def, r);
00422         }
00423 
00431         template <class Set>
00432         void storein_set(Set& con, query_reset r = RESET_QUERY)
00433         {
00434                 storein_set(con, def, r);
00435         }
00436 
00455         template <class Container>
00456         void storein(Container& con, query_reset r = RESET_QUERY)
00457         {
00458                 storein(con, def, r);
00459         }
00460 
00462         template <class T>
00463         void storein(std::vector<T>& con, const char* s)
00464         {
00465                 storein_sequence(con, s);
00466         }
00467 
00469         template <class T>
00470         void storein(std::deque<T>& con, const char* s)
00471         {
00472                 storein_sequence(con, s);
00473         }
00474 
00476         template <class T>
00477         void storein(std::list<T>& con, const char* s)
00478         {
00479                 storein_sequence(con, s);
00480         }
00481 
00482 #if defined(HAVE_EXT_SLIST)
00485         template <class T>
00486         void storein(__gnu_cxx::slist<T>& con, const char* s)
00487         {
00488                 storein_sequence(con, s);
00489         }
00490 #elif defined(HAVE_GLOBAL_SLIST)
00497         template <class T>
00498         void storein(slist<T>& con, const char* s)
00499         {
00500                 storein_sequence(con, s);
00501         }
00502 #elif defined(HAVE_STD_SLIST)
00508         template <class T>
00509         void storein(std::slist<T>& con, const char* s)
00510         {
00511                 storein_sequence(con, s);
00512         }
00513 #endif
00514 
00516         template <class T>
00517         void storein(std::set<T>& con, const char* s)
00518         {
00519                 storein_set(con, s);
00520         }
00521 
00523         template <class T>
00524         void storein(std::multiset<T>& con, const char* s)
00525         {
00526                 storein_set(con, s);
00527         }
00528 
00539         template <class T>
00540         Query& update(const T& o, const T& n)
00541         {
00542                 reset();
00543 
00544                 // Cast required for VC++ 2003 due to error in overloaded operator
00545                 // lookup logic.  For an explanation of the problem, see:
00546                 // http://groups-beta.google.com/group/microsoft.public.vc.stl/browse_thread/thread/9a68d84644e64f15
00547                 dynamic_cast<std::ostream&>(*this) << std::setprecision(16) <<
00548                                 "UPDATE " << o.table() << " SET " << n.equal_list() <<
00549                                 " WHERE " << o.equal_list(" AND ", sql_use_compare);
00550                 return *this;
00551         }
00552 
00561         template <class T>
00562         Query& insert(const T& v)
00563         {
00564                 reset();
00565 
00566                 // See above comment for cast rationale
00567                 dynamic_cast<std::ostream&>(*this) << std::setprecision(16) <<
00568                                 "INSERT INTO " << v.table() << " (" <<
00569                                 v.field_list() << ") VALUES (" <<
00570                                 v.value_list() << ')';
00571                 return *this;
00572         }
00573 
00587         template <class Iter>
00588         Query& insert(Iter first, Iter last)
00589         {
00590                 reset();
00591                 if (first == last) {
00592                         return *this;   // empty set!
00593                 }
00594                 
00595                 // See above comment for cast rationale
00596                 dynamic_cast<std::ostream&>(*this) << std::setprecision(16) <<
00597                                 "INSERT INTO " << first->table() << " (" <<
00598                                 first->field_list() << ") VALUES (" <<
00599                                 first->value_list() << ')';
00600 
00601                 Iter it = first + 1;
00602                 while (it != last) {
00603                         dynamic_cast<std::ostream&>(*this) << ",(" <<
00604                                         it->value_list() << ')';
00605                         ++it;
00606                 }
00607 
00608                 return *this;
00609         }
00610 
00620         template <class T>
00621         Query& replace(const T& v)
00622         {
00623                 reset();
00624 
00625                 // See above comment for cast rationale
00626                 dynamic_cast<std::ostream&>(*this) << std::setprecision(16) <<
00627                                 "REPLACE INTO " << v.table() << " (" <<
00628                                 v.field_list() << ") VALUES (" << v.value_list() << ')';
00629                 return *this;
00630         }
00631 
00633         operator bool() { return success(); }
00634 
00636         bool operator !() { return !success(); }
00637 
00638 #if !defined(DOXYGEN_IGNORE)
00639         // Declare the remaining overloads.  These are hidden down here partly
00640         // to keep the above code clear, but also so that we may hide them
00641         // from Doxygen, which gets confused by macro instantiations that look
00642         // like method declarations.
00643         mysql_query_define0(std::string, preview)
00644         mysql_query_define0(std::string, str)
00645         mysql_query_define1(ResNSel, execute)
00646         mysql_query_define1(Result, store)
00647         mysql_query_define1(ResUse, use)
00648         mysql_query_define2(storein_sequence)
00649         mysql_query_define2(storein_set)
00650         mysql_query_define2(storein)
00651 #endif // !defined(DOXYGEN_IGNORE)
00652 
00656         SQLQueryParms def;
00657 
00658 private:
00659         friend class SQLQueryParms;
00660 
00662         Connection* conn_;
00663 
00665         bool success_;
00666 
00668         std::vector<SQLParseElement> parse_elems_;
00669 
00672         std::vector<std::string> parsed_names_;
00673 
00675         std::map<std::string, short int> parsed_nums_;
00676 
00678         std::stringbuf sbuffer_;
00679 
00681         my_ulonglong affected_rows() const;
00682         my_ulonglong insert_id();
00683         std::string info();
00684         char* preview_char();
00685 
00687         void proc(SQLQueryParms& p);
00688 
00689         // Locking mechanism
00690         bool lock();
00691         void unlock();
00692 
00693         SQLString* pprepare(char option, SQLString& S, bool replace = true);
00694 };
00695 
00696 
00697 #if !defined(DOXYGEN_IGNORE)
00698 // Doxygen will not generate documentation for this section.
00699 
00700 template <class Seq>
00701 void Query::storein_sequence(Seq& seq, SQLQueryParms& p, query_reset r)
00702 {
00703         r = parse_elems_.size() ? DONT_RESET : RESET_QUERY;
00704         storein_sequence(seq, str(p, r).c_str());
00705 }
00706 
00707 
00708 template <class Sequence>
00709 void Query::storein_sequence(Sequence& con, const char* s)
00710 {
00711         ResUse result = use(s);
00712         while (1) {
00713                 MYSQL_ROW d = mysql_fetch_row(result.raw_result());
00714                 if (!d)
00715                         break;
00716                 Row row(d, &result, mysql_fetch_lengths(result.raw_result()),
00717                                 true);
00718                 if (!row)
00719                         break;
00720                 con.push_back(typename Sequence::value_type(row));
00721         }
00722 }
00723 
00724 
00725 template <class Set>
00726 void Query::storein_set(Set& sett, SQLQueryParms& p, query_reset r)
00727 {
00728         r = parse_elems_.size() ? DONT_RESET : RESET_QUERY;
00729         storein_set(sett, str(p, r).c_str());
00730 }
00731 
00732 
00733 template <class Set>
00734 void Query::storein_set(Set& con, const char* s)
00735 {
00736         ResUse result = use(s);
00737         while (1) {
00738                 MYSQL_ROW d = mysql_fetch_row(result.raw_result());
00739                 if (!d)
00740                         return;
00741                 Row row(d, &result, mysql_fetch_lengths(result.raw_result()),
00742                                 true);
00743                 if (!row)
00744                         break;
00745                 con.insert(typename Set::value_type(row));
00746         }
00747 }
00748 
00749 
00750 template <class T>
00751 void Query::storein(T& con, SQLQueryParms& p, query_reset r)
00752 {
00753         r = parse_elems_.size() ? DONT_RESET : RESET_QUERY;
00754         storein(con, str(p, r).c_str());
00755 }
00756 
00757 
00758 #endif // !defined(DOXYGEN_IGNORE)
00759 
00760 } // end namespace mysqlpp
00761 
00762 #endif
00763 

Generated on Wed Feb 28 06:56:58 2007 for MySQL++ by  doxygen 1.5.1-3