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 <deque>
00042 #include <iomanip>
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 
00064 #if defined(_MSC_VER) && (_MSC_VER < 1400)
00065 #       define MYSQLPP_QUERY_THISPTR dynamic_cast<std::ostream&>(*this)
00066 #else
00067 #       define MYSQLPP_QUERY_THISPTR *this
00068 #endif
00069 
00070 namespace mysqlpp {
00071 
00072 #if !defined(DOXYGEN_IGNORE)
00073 // Make Doxygen ignore this
00074 class MYSQLPP_EXPORT Connection;
00075 #endif
00076 
00078 enum query_reset { DONT_RESET, RESET_QUERY };
00079 
00128 
00129 class MYSQLPP_EXPORT Query : public std::ostream,
00130                 public OptionalExceptions, public Lockable
00131 {
00132 public:
00139         Query(Connection* c, bool te = true);
00140 
00148         Query(const Query& q);
00149 
00154         Query& operator=(const Query& rhs);
00155 
00161         std::string error();
00162 
00168         bool success();
00169 
00177         void parse();
00178 
00183         void reset();
00184 
00186         std::string preview() { return str(def); }
00187 
00193         std::string preview(const SQLString& arg0)
00194                         { return preview(SQLQueryParms() << arg0); }
00195 
00197         std::string preview(SQLQueryParms& p) { return str(p); }
00198 
00200         std::string str() { return str(def); }
00201 
00207         std::string str(const SQLString& arg0)
00208                         { return preview(SQLQueryParms() << arg0); }
00209 
00214         std::string str(query_reset r) { return str(def, r); }
00215 
00220         std::string str(SQLQueryParms& p);
00221 
00228         std::string str(SQLQueryParms& p, query_reset r);
00229 
00241         bool exec(const std::string& str);
00242 
00259         ResNSel execute() { return execute(def); }
00260 
00267         ResNSel execute(const SQLString& str);
00268 
00272         ResNSel execute(const char* str);
00273 
00278         ResNSel execute(const char* str, size_t len);
00279 
00304         ResUse use() { return use(def); }
00305 
00311         ResUse use(const SQLString& str);
00312 
00318         ResUse use(const char* str);
00319 
00325         ResUse use(const char* str, size_t len);
00326 
00348         Result store() { return store(def); }
00349 
00355         Result store(const SQLString& str);
00356 
00362         Result store(const char* str);
00363 
00369         Result store(const char* str, size_t len);
00370 
00381         template <typename Function>
00382         Function for_each(const SQLString& query, Function fn)
00383         {       
00384                 mysqlpp::ResUse res = use(query);
00385                 if (res) {
00386                         mysqlpp::NoExceptions ne(res);
00387                         while (mysqlpp::Row row = res.fetch_row()) {
00388                                 fn(row);
00389                         }
00390                 }
00391 
00392                 return fn;
00393         }
00394 
00402         template <typename Function>
00403         Function for_each(Function fn)
00404         {       
00405                 mysqlpp::ResUse res = use();
00406                 if (res) {
00407                         mysqlpp::NoExceptions ne(res);
00408                         while (mysqlpp::Row row = res.fetch_row()) {
00409                                 fn(row);
00410                         }
00411                 }
00412 
00413                 return fn;
00414         }
00415 
00426         template <class SSQLS, typename Function>
00427         Function for_each(const SSQLS& ssqls, Function fn)
00428         {       
00429                 SQLString query("select * from ");
00430                 query += ssqls._table;
00431                 mysqlpp::ResUse res = use(query);
00432                 if (res) {
00433                         mysqlpp::NoExceptions ne(res);
00434                         while (mysqlpp::Row row = res.fetch_row()) {
00435                                 fn(row);
00436                         }
00437                 }
00438 
00439                 return fn;
00440         }
00441 
00461         template <class Sequence, typename Function>
00462         Function store_if(Sequence& seq, const SQLString& query, Function fn)
00463         {       
00464                 mysqlpp::ResUse res = use(query);
00465                 if (res) {
00466                         mysqlpp::NoExceptions ne(res);
00467                         while (mysqlpp::Row row = res.fetch_row()) {
00468                                 if (fn(row)) {
00469                                         seq.push_back(row);
00470                                 }
00471                         }
00472                 }
00473 
00474                 return fn;
00475         }
00476 
00488         template <class Sequence, class SSQLS, typename Function>
00489         Function store_if(Sequence& seq, const SSQLS& ssqls, Function fn)
00490         {       
00491                 SQLString query("select * from ");
00492                 query += ssqls._table;
00493                 mysqlpp::ResUse res = use(query);
00494                 if (res) {
00495                         mysqlpp::NoExceptions ne(res);
00496                         while (mysqlpp::Row row = res.fetch_row()) {
00497                                 if (fn(row)) {
00498                                         seq.push_back(row);
00499                                 }
00500                         }
00501                 }
00502 
00503                 return fn;
00504         }
00505 
00515         template <class Sequence, typename Function>
00516         Function store_if(Sequence& seq, Function fn)
00517         {       
00518                 mysqlpp::ResUse res = use();
00519                 if (res) {
00520                         mysqlpp::NoExceptions ne(res);
00521                         while (mysqlpp::Row row = res.fetch_row()) {
00522                                 if (fn(row)) {
00523                                         seq.push_back(row);
00524                                 }
00525                         }
00526                 }
00527 
00528                 return fn;
00529         }
00530 
00557         Result store_next();
00558 
00570         bool more_results();
00571 
00589         template <class Sequence>
00590         void storein_sequence(Sequence& con, query_reset r = RESET_QUERY)
00591         {
00592                 storein_sequence(con, def, r);
00593         }
00594 
00602         template <class Set>
00603         void storein_set(Set& con, query_reset r = RESET_QUERY)
00604         {
00605                 storein_set(con, def, r);
00606         }
00607 
00626         template <class Container>
00627         void storein(Container& con, query_reset r = RESET_QUERY)
00628         {
00629                 storein(con, def, r);
00630         }
00631 
00633         template <class T>
00634         void storein(std::vector<T>& con, const char* s)
00635         {
00636                 storein_sequence(con, s);
00637         }
00638 
00640         template <class T>
00641         void storein(std::deque<T>& con, const char* s)
00642         {
00643                 storein_sequence(con, s);
00644         }
00645 
00647         template <class T>
00648         void storein(std::list<T>& con, const char* s)
00649         {
00650                 storein_sequence(con, s);
00651         }
00652 
00653 #if defined(HAVE_EXT_SLIST)
00656         template <class T>
00657         void storein(__gnu_cxx::slist<T>& con, const char* s)
00658         {
00659                 storein_sequence(con, s);
00660         }
00661 #elif defined(HAVE_GLOBAL_SLIST)
00668         template <class T>
00669         void storein(slist<T>& con, const char* s)
00670         {
00671                 storein_sequence(con, s);
00672         }
00673 #elif defined(HAVE_STD_SLIST)
00679         template <class T>
00680         void storein(std::slist<T>& con, const char* s)
00681         {
00682                 storein_sequence(con, s);
00683         }
00684 #endif
00685 
00687         template <class T>
00688         void storein(std::set<T>& con, const char* s)
00689         {
00690                 storein_set(con, s);
00691         }
00692 
00694         template <class T>
00695         void storein(std::multiset<T>& con, const char* s)
00696         {
00697                 storein_set(con, s);
00698         }
00699 
00710         template <class T>
00711         Query& update(const T& o, const T& n)
00712         {
00713                 reset();
00714 
00715                 // Cast required for VC++ 2003 due to error in overloaded operator
00716                 // lookup logic.  For an explanation of the problem, see:
00717                 // http://groups-beta.google.com/group/microsoft.public.vc.stl/browse_thread/thread/9a68d84644e64f15
00718                 MYSQLPP_QUERY_THISPTR << std::setprecision(16) <<
00719                                 "UPDATE " << o.table() << " SET " << n.equal_list() <<
00720                                 " WHERE " << o.equal_list(" AND ", sql_use_compare);
00721                 return *this;
00722         }
00723 
00732         template <class T>
00733         Query& insert(const T& v)
00734         {
00735                 reset();
00736 
00737                 MYSQLPP_QUERY_THISPTR << std::setprecision(16) <<
00738                                 "INSERT INTO " << v.table() << " (" <<
00739                                 v.field_list() << ") VALUES (" <<
00740                                 v.value_list() << ')';
00741                 return *this;
00742         }
00743 
00757         template <class Iter>
00758         Query& insert(Iter first, Iter last)
00759         {
00760                 reset();
00761                 if (first == last) {
00762                         return *this;   // empty set!
00763                 }
00764                 
00765                 MYSQLPP_QUERY_THISPTR << std::setprecision(16) <<
00766                                 "INSERT INTO " << first->table() << " (" <<
00767                                 first->field_list() << ") VALUES (" <<
00768                                 first->value_list() << ')';
00769 
00770                 Iter it = first + 1;
00771                 while (it != last) {
00772                         MYSQLPP_QUERY_THISPTR << ",(" << it->value_list() << ')';
00773                         ++it;
00774                 }
00775 
00776                 return *this;
00777         }
00778 
00788         template <class T>
00789         Query& replace(const T& v)
00790         {
00791                 reset();
00792 
00793                 MYSQLPP_QUERY_THISPTR << std::setprecision(16) <<
00794                                 "REPLACE INTO " << v.table() << " (" <<
00795                                 v.field_list() << ") VALUES (" << v.value_list() << ')';
00796                 return *this;
00797         }
00798 
00800         operator bool() { return success(); }
00801 
00803         bool operator !() { return !success(); }
00804 
00805 #if !defined(DOXYGEN_IGNORE)
00806         // Declare the remaining overloads.  These are hidden down here partly
00807         // to keep the above code clear, but also so that we may hide them
00808         // from Doxygen, which gets confused by macro instantiations that look
00809         // like method declarations.
00810         mysql_query_define0(std::string, preview)
00811         mysql_query_define0(std::string, str)
00812         mysql_query_define1(ResNSel, execute)
00813         mysql_query_define1(Result, store)
00814         mysql_query_define1(ResUse, use)
00815         mysql_query_define2(storein_sequence)
00816         mysql_query_define2(storein_set)
00817         mysql_query_define2(storein)
00818 #endif // !defined(DOXYGEN_IGNORE)
00819 
00823         SQLQueryParms def;
00824 
00825 private:
00826         friend class SQLQueryParms;
00827 
00829         Connection* conn_;
00830 
00832         bool success_;
00833 
00835         std::vector<SQLParseElement> parse_elems_;
00836 
00839         std::vector<std::string> parsed_names_;
00840 
00842         std::map<std::string, short int> parsed_nums_;
00843 
00845         std::stringbuf sbuffer_;
00846 
00848         my_ulonglong affected_rows() const;
00849         my_ulonglong insert_id();
00850         std::string info();
00851         char* preview_char();
00852 
00854         void proc(SQLQueryParms& p);
00855 
00856         // Locking mechanism
00857         bool lock();
00858         void unlock();
00859 
00860         SQLString* pprepare(char option, SQLString& S, bool replace = true);
00861 };
00862 
00863 
00864 #if !defined(DOXYGEN_IGNORE)
00865 // Doxygen will not generate documentation for this section.
00866 
00867 template <class Seq>
00868 void Query::storein_sequence(Seq& seq, SQLQueryParms& p, query_reset r)
00869 {
00870         r = parse_elems_.size() ? DONT_RESET : RESET_QUERY;
00871         storein_sequence(seq, str(p, r).c_str());
00872 }
00873 
00874 
00875 template <class Sequence>
00876 void Query::storein_sequence(Sequence& con, const char* s)
00877 {
00878         ResUse result = use(s);
00879         while (1) {
00880                 MYSQL_ROW d = mysql_fetch_row(result.raw_result());
00881                 if (!d)
00882                         break;
00883                 Row row(d, &result, mysql_fetch_lengths(result.raw_result()),
00884                                 true);
00885                 if (!row)
00886                         break;
00887                 con.push_back(typename Sequence::value_type(row));
00888         }
00889 }
00890 
00891 
00892 template <class Set>
00893 void Query::storein_set(Set& sett, SQLQueryParms& p, query_reset r)
00894 {
00895         r = parse_elems_.size() ? DONT_RESET : RESET_QUERY;
00896         storein_set(sett, str(p, r).c_str());
00897 }
00898 
00899 
00900 template <class Set>
00901 void Query::storein_set(Set& con, const char* s)
00902 {
00903         ResUse result = use(s);
00904         while (1) {
00905                 MYSQL_ROW d = mysql_fetch_row(result.raw_result());
00906                 if (!d)
00907                         return;
00908                 Row row(d, &result, mysql_fetch_lengths(result.raw_result()),
00909                                 true);
00910                 if (!row)
00911                         break;
00912                 con.insert(typename Set::value_type(row));
00913         }
00914 }
00915 
00916 
00917 template <class T>
00918 void Query::storein(T& con, SQLQueryParms& p, query_reset r)
00919 {
00920         r = parse_elems_.size() ? DONT_RESET : RESET_QUERY;
00921         storein(con, str(p, r).c_str());
00922 }
00923 
00924 
00925 #endif // !defined(DOXYGEN_IGNORE)
00926 
00927 } // end namespace mysqlpp
00928 
00929 #endif
00930 

Generated on Wed Jul 11 15:34:34 2007 for MySQL++ by doxygen 1.3.5