Main Page | Namespace List | Class Hierarchy | Class List | File List | Namespace Members | Class 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-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 
00066 #if defined(_MSC_VER) && (_MSC_VER < 1400)
00067 #       define MYSQLPP_QUERY_THISPTR dynamic_cast<std::ostream&>(*this)
00068 #else
00069 #       define MYSQLPP_QUERY_THISPTR *this
00070 #endif
00071 
00072 namespace mysqlpp {
00073 
00074 #if !defined(DOXYGEN_IGNORE)
00075 // Make Doxygen ignore this
00076 class MYSQLPP_EXPORT Connection;
00077 #endif
00078 
00080 enum query_reset { DONT_RESET, RESET_QUERY };
00081 
00130 
00131 class MYSQLPP_EXPORT Query : public std::ostream,
00132                 public OptionalExceptions, public Lockable
00133 {
00134 public:
00141         Query(Connection* c, bool te = true);
00142 
00150         Query(const Query& q);
00151 
00156         Query& operator=(const Query& rhs);
00157 
00163         std::string error();
00164 
00170         bool success();
00171 
00179         void parse();
00180 
00185         void reset();
00186 
00188         std::string preview() { return str(def); }
00189 
00195         std::string preview(const SQLString& arg0)
00196                         { return preview(SQLQueryParms() << arg0); }
00197 
00199         std::string preview(SQLQueryParms& p) { return str(p); }
00200 
00202         std::string str() { return str(def); }
00203 
00209         std::string str(const SQLString& arg0)
00210                         { return preview(SQLQueryParms() << arg0); }
00211 
00216         std::string str(query_reset r) { return str(def, r); }
00217 
00222         std::string str(SQLQueryParms& p);
00223 
00230         std::string str(SQLQueryParms& p, query_reset r);
00231 
00243         bool exec(const std::string& str);
00244 
00261         ResNSel execute() { return execute(def); }
00262 
00269         ResNSel execute(const SQLString& str);
00270 
00274         ResNSel execute(const char* str);
00275 
00280         ResNSel execute(const char* str, size_t len);
00281 
00306         ResUse use() { return use(def); }
00307 
00313         ResUse use(const SQLString& str);
00314 
00320         ResUse use(const char* str);
00321 
00327         ResUse use(const char* str, size_t len);
00328 
00350         Result store() { return store(def); }
00351 
00357         Result store(const SQLString& str);
00358 
00364         Result store(const char* str);
00365 
00371         Result store(const char* str, size_t len);
00372 
00399         Result store_next();
00400 
00412         bool more_results();
00413 
00431         template <class Sequence>
00432         void storein_sequence(Sequence& con, query_reset r = RESET_QUERY)
00433         {
00434                 storein_sequence_(con, def, r);
00435         }
00436 
00444         template <class Set>
00445         void storein_set(Set& con, query_reset r = RESET_QUERY)
00446         {
00447                 storein_set(con, def, r);
00448         }
00449 
00468         template <class Container>
00469         void storein(Container& con, query_reset r = RESET_QUERY)
00470         {
00471                 storein(con, def, r);
00472         }
00473 
00475         template <class T>
00476         void storein(std::vector<T>& con, const char* s)
00477         {
00478                 storein_sequence(con, s);
00479         }
00480 
00482         template <class T>
00483         void storein(std::deque<T>& con, const char* s)
00484         {
00485                 storein_sequence(con, s);
00486         }
00487 
00489         template <class T>
00490         void storein(std::list<T>& con, const char* s)
00491         {
00492                 storein_sequence(con, s);
00493         }
00494 
00495 #if defined(HAVE_EXT_SLIST)
00498         template <class T>
00499         void storein(__gnu_cxx::slist<T>& con, const char* s)
00500         {
00501                 storein_sequence(con, s);
00502         }
00503 #elif defined(HAVE_GLOBAL_SLIST)
00510         template <class T>
00511         void storein(slist<T>& con, const char* s)
00512         {
00513                 storein_sequence(con, s);
00514         }
00515 #elif defined(HAVE_STD_SLIST)
00521         template <class T>
00522         void storein(std::slist<T>& con, const char* s)
00523         {
00524                 storein_sequence(con, s);
00525         }
00526 #endif
00527 
00529         template <class T>
00530         void storein(std::set<T>& con, const char* s)
00531         {
00532                 storein_set(con, s);
00533         }
00534 
00536         template <class T>
00537         void storein(std::multiset<T>& con, const char* s)
00538         {
00539                 storein_set(con, s);
00540         }
00541 
00552         template <class T>
00553         Query& update(const T& o, const T& n)
00554         {
00555                 reset();
00556 
00557                 // Cast required for VC++ 2003 due to error in overloaded operator
00558                 // lookup logic.  For an explanation of the problem, see:
00559                 // http://groups-beta.google.com/group/microsoft.public.vc.stl/browse_thread/thread/9a68d84644e64f15
00560                 MYSQLPP_QUERY_THISPTR << std::setprecision(16) <<
00561                                 "UPDATE " << o.table() << " SET " << n.equal_list() <<
00562                                 " WHERE " << o.equal_list(" AND ", sql_use_compare);
00563                 return *this;
00564         }
00565 
00574         template <class T>
00575         Query& insert(const T& v)
00576         {
00577                 reset();
00578 
00579                 MYSQLPP_QUERY_THISPTR << std::setprecision(16) <<
00580                                 "INSERT INTO " << v.table() << " (" <<
00581                                 v.field_list() << ") VALUES (" <<
00582                                 v.value_list() << ')';
00583                 return *this;
00584         }
00585 
00599         template <class Iter>
00600         Query& insert(Iter first, Iter last)
00601         {
00602                 reset();
00603                 if (first == last) {
00604                         return *this;   // empty set!
00605                 }
00606                 
00607                 MYSQLPP_QUERY_THISPTR << std::setprecision(16) <<
00608                                 "INSERT INTO " << first->table() << " (" <<
00609                                 first->field_list() << ") VALUES (" <<
00610                                 first->value_list() << ')';
00611 
00612                 Iter it = first + 1;
00613                 while (it != last) {
00614                         MYSQLPP_QUERY_THISPTR << ",(" << it->value_list() << ')';
00615                         ++it;
00616                 }
00617 
00618                 return *this;
00619         }
00620 
00630         template <class T>
00631         Query& replace(const T& v)
00632         {
00633                 reset();
00634 
00635                 MYSQLPP_QUERY_THISPTR << std::setprecision(16) <<
00636                                 "REPLACE INTO " << v.table() << " (" <<
00637                                 v.field_list() << ") VALUES (" << v.value_list() << ')';
00638                 return *this;
00639         }
00640 
00642         operator bool() { return success(); }
00643 
00645         bool operator !() { return !success(); }
00646 
00647 #if !defined(DOXYGEN_IGNORE)
00648         // Declare the remaining overloads.  These are hidden down here partly
00649         // to keep the above code clear, but also so that we may hide them
00650         // from Doxygen, which gets confused by macro instantiations that look
00651         // like method declarations.
00652         mysql_query_define0(std::string, preview)
00653         mysql_query_define0(std::string, str)
00654         mysql_query_define1(ResNSel, execute)
00655         mysql_query_define1(Result, store)
00656         mysql_query_define1(ResUse, use)
00657         mysql_query_define2(storein_sequence)
00658         mysql_query_define2(storein_set)
00659         mysql_query_define2(storein)
00660 #endif // !defined(DOXYGEN_IGNORE)
00661 
00665         SQLQueryParms def;
00666 
00667 private:
00668         friend class SQLQueryParms;
00669 
00671         Connection* conn_;
00672 
00674         bool success_;
00675 
00677         std::vector<SQLParseElement> parse_elems_;
00678 
00681         std::vector<std::string> parsed_names_;
00682 
00684         std::map<std::string, short int> parsed_nums_;
00685 
00687         std::stringbuf sbuffer_;
00688 
00690         my_ulonglong affected_rows() const;
00691         my_ulonglong insert_id();
00692         std::string info();
00693         char* preview_char();
00694 
00696         void proc(SQLQueryParms& p);
00697 
00698         // Locking mechanism
00699         bool lock();
00700         void unlock();
00701 
00702         SQLString* pprepare(char option, SQLString& S, bool replace = true);
00703 };
00704 
00705 
00706 #if !defined(DOXYGEN_IGNORE)
00707 // Doxygen will not generate documentation for this section.
00708 
00709 template <class Seq>
00710 void Query::storein_sequence(Seq& seq, SQLQueryParms& p, query_reset r)
00711 {
00712         r = parse_elems_.size() ? DONT_RESET : RESET_QUERY;
00713         storein_sequence(seq, str(p, r).c_str());
00714 }
00715 
00716 
00717 template <class Sequence>
00718 void Query::storein_sequence(Sequence& con, const char* s)
00719 {
00720         ResUse result = use(s);
00721         while (1) {
00722                 MYSQL_ROW d = mysql_fetch_row(result.raw_result());
00723                 if (!d)
00724                         break;
00725                 Row row(d, &result, mysql_fetch_lengths(result.raw_result()),
00726                                 true);
00727                 if (!row)
00728                         break;
00729                 con.push_back(typename Sequence::value_type(row));
00730         }
00731 }
00732 
00733 
00734 template <class Set>
00735 void Query::storein_set(Set& sett, SQLQueryParms& p, query_reset r)
00736 {
00737         r = parse_elems_.size() ? DONT_RESET : RESET_QUERY;
00738         storein_set(sett, str(p, r).c_str());
00739 }
00740 
00741 
00742 template <class Set>
00743 void Query::storein_set(Set& con, const char* s)
00744 {
00745         ResUse result = use(s);
00746         while (1) {
00747                 MYSQL_ROW d = mysql_fetch_row(result.raw_result());
00748                 if (!d)
00749                         return;
00750                 Row row(d, &result, mysql_fetch_lengths(result.raw_result()),
00751                                 true);
00752                 if (!row)
00753                         break;
00754                 con.insert(typename Set::value_type(row));
00755         }
00756 }
00757 
00758 
00759 template <class T>
00760 void Query::storein(T& con, SQLQueryParms& p, query_reset r)
00761 {
00762         r = parse_elems_.size() ? DONT_RESET : RESET_QUERY;
00763         storein(con, str(p, r).c_str());
00764 }
00765 
00766 
00767 #endif // !defined(DOXYGEN_IGNORE)
00768 
00769 } // end namespace mysqlpp
00770 
00771 #endif
00772 

Generated on Fri Apr 13 09:28:45 2007 for MySQL++ by doxygen 1.3.5