query.h

Go to the documentation of this file.
00001 
00002 
00003 
00004 /***********************************************************************
00005  Copyright (c) 1998 by Kevin Atkinson, (c) 1999-2001 by MySQL AB, and
00006  (c) 2004-2008 by Educational Technology Resources, Inc.  Others may
00007  also hold copyrights on code in this file.  See the CREDITS file in
00008  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 #if !defined(MYSQLPP_QUERY_H)
00029 #define MYSQLPP_QUERY_H
00030 
00031 #include "common.h"
00032 
00033 #include "noexceptions.h"
00034 #include "qparms.h"
00035 #include "querydef.h"
00036 #include "result.h"
00037 #include "row.h"
00038 #include "stadapter.h"
00039 
00040 #include <deque>
00041 #include <iomanip>
00042 #include <list>
00043 #include <map>
00044 #include <set>
00045 #include <vector>
00046 
00047 #ifdef HAVE_EXT_SLIST
00048 #  include <ext/slist>
00049 #else
00050 #  if defined(HAVE_STD_SLIST) || defined(HAVE_GLOBAL_SLIST)
00051 #      include <slist>
00052 #  endif
00053 #endif
00054 
00055 namespace mysqlpp {
00056 
00057 #if !defined(DOXYGEN_IGNORE)
00058 // Make Doxygen ignore this
00059 class MYSQLPP_EXPORT Connection;
00060 #endif
00061 
00116 
00117 class MYSQLPP_EXPORT Query :
00118         public std::ostream,
00119                 public OptionalExceptions
00120 {
00121 public:
00129         Query(Connection* c, bool te = true, const char* qstr = 0);
00130 
00138         Query(const Query& q);
00139 
00141         ulonglong affected_rows();
00142 
00180         size_t escape_string(std::string* ps, const char* original = 0,
00181                         size_t length = 0) const;
00182 
00199         size_t escape_string(char* escaped, const char* original,
00200                         size_t length) const;
00201 
00206         int errnum() const;
00207 
00212         const char* error() const;
00213 
00216         std::string info();
00217 
00224         ulonglong insert_id();
00225 
00230         Query& operator=(const Query& rhs);
00231 
00250         operator void*() const;
00251 
00259         void parse();
00260 
00270         void reset();
00271 
00273         std::string str() { return str(template_defaults); }
00274 
00288         std::string str(const SQLTypeAdapter& arg0)
00289                         { return str(SQLQueryParms() << arg0); }
00290 
00295         std::string str(SQLQueryParms& p);
00296 
00307         bool exec() { return exec(str(template_defaults)); }
00308 
00320         bool exec(const std::string& str);
00321 
00338         SimpleResult execute() { return execute(str(template_defaults)); }
00339 
00348         SimpleResult execute(SQLQueryParms& p);
00349 
00366         SimpleResult execute(const SQLTypeAdapter& str);
00367 
00372         SimpleResult execute(const char* str, size_t len);
00373 
00399         UseQueryResult use() { return use(str(template_defaults)); }
00400 
00410         UseQueryResult use(SQLQueryParms& p);
00411 
00429         UseQueryResult use(const SQLTypeAdapter& str);
00430 
00440         UseQueryResult use(const char* str, size_t len);
00441 
00463         StoreQueryResult store() { return store(str(template_defaults)); }
00464 
00473         StoreQueryResult store(SQLQueryParms& p);
00474 
00492         StoreQueryResult store(const SQLTypeAdapter& str);
00493 
00503         StoreQueryResult store(const char* str, size_t len);
00504 
00515         template <typename Function>
00516         Function for_each(const SQLTypeAdapter& query, Function fn)
00517         {       
00518                 mysqlpp::UseQueryResult res = use(query);
00519                 if (res) {
00520                         mysqlpp::NoExceptions ne(res);
00521                         while (mysqlpp::Row row = res.fetch_row()) {
00522                                 fn(row);
00523                         }
00524                 }
00525 
00526                 return fn;
00527         }
00528 
00536         template <typename Function>
00537         Function for_each(Function fn)
00538         {       
00539                 mysqlpp::UseQueryResult res = use();
00540                 if (res) {
00541                         mysqlpp::NoExceptions ne(res);
00542                         while (mysqlpp::Row row = res.fetch_row()) {
00543                                 fn(row);
00544                         }
00545                 }
00546 
00547                 return fn;
00548         }
00549 
00560         template <class SSQLS, typename Function>
00561         Function for_each(const SSQLS& ssqls, Function fn)
00562         {       
00563                 std::string query("select * from ");
00564                 query += ssqls.table();
00565                 mysqlpp::UseQueryResult res = use(query);
00566                 if (res) {
00567                         mysqlpp::NoExceptions ne(res);
00568                         while (mysqlpp::Row row = res.fetch_row()) {
00569                                 fn(row);
00570                         }
00571                 }
00572 
00573                 return fn;
00574         }
00575 
00595         template <class Sequence, typename Function>
00596         Function store_if(Sequence& con, const SQLTypeAdapter& query, Function fn)
00597         {       
00598                 mysqlpp::UseQueryResult res = use(query);
00599                 if (res) {
00600                         mysqlpp::NoExceptions ne(res);
00601                         while (mysqlpp::Row row = res.fetch_row()) {
00602                                 if (fn(row)) {
00603                                         con.push_back(row);
00604                                 }
00605                         }
00606                 }
00607 
00608                 return fn;
00609         }
00610 
00622         template <class Sequence, class SSQLS, typename Function>
00623         Function store_if(Sequence& con, const SSQLS& ssqls, Function fn)
00624         {       
00625                 std::string query("select * from ");
00626                 query += ssqls.table();
00627                 mysqlpp::UseQueryResult res = use(query);
00628                 if (res) {
00629                         mysqlpp::NoExceptions ne(res);
00630                         while (mysqlpp::Row row = res.fetch_row()) {
00631                                 if (fn(row)) {
00632                                         con.push_back(row);
00633                                 }
00634                         }
00635                 }
00636 
00637                 return fn;
00638         }
00639 
00649         template <class Sequence, typename Function>
00650         Function store_if(Sequence& con, Function fn)
00651         {       
00652                 mysqlpp::UseQueryResult res = use();
00653                 if (res) {
00654                         mysqlpp::NoExceptions ne(res);
00655                         while (mysqlpp::Row row = res.fetch_row()) {
00656                                 if (fn(row)) {
00657                                         con.push_back(row);
00658                                 }
00659                         }
00660                 }
00661 
00662                 return fn;
00663         }
00664 
00691         StoreQueryResult store_next();
00692 
00704         bool more_results();
00705 
00722         template <class Sequence>
00723         void storein_sequence(Sequence& con)
00724         {
00725                 storein_sequence(con, str(template_defaults));
00726         }
00727 
00741         template <class Sequence>
00742         void storein_sequence(Sequence& con, const SQLTypeAdapter& s)
00743         {
00744                 UseQueryResult result = use(s);
00745                 while (1) {
00746                         MYSQL_ROW d = result.fetch_raw_row();
00747                         if (!d)
00748                                 break;
00749                         Row row(d, &result, result.fetch_lengths(), true);
00750                         if (!row)
00751                                 break;
00752                         con.push_back(typename Sequence::value_type(row));
00753                 }
00754         }
00755 
00766     template <class Seq>
00767     void storein_sequence(Seq& con, SQLQueryParms& p)
00768     {
00769         storein_sequence(con, str(p));
00770     }
00771 
00779         template <class Set>
00780         void storein_set(Set& con)
00781         {
00782                 storein_set(con, str(template_defaults));
00783         }
00784 
00798         template <class Set>
00799         void storein_set(Set& con, const SQLTypeAdapter& s)
00800         {
00801                 UseQueryResult result = use(s);
00802                 while (1) {
00803                         MYSQL_ROW d = result.fetch_raw_row();
00804                         if (!d)
00805                                 return;
00806                         Row row(d, &result, result.fetch_lengths(), true);
00807                         if (!row)
00808                                 break;
00809                         con.insert(typename Set::value_type(row));
00810                 }
00811         }
00812 
00823     template <class Set>
00824     void storein_set(Set& con, SQLQueryParms& p)
00825     {
00826         storein_set(con, str(p));
00827     }
00828 
00847         template <class Container>
00848         void storein(Container& con)
00849         {
00850                 storein(con, str(template_defaults));
00851         }
00852 
00854         template <class T>
00855         void storein(std::vector<T>& con, const SQLTypeAdapter& s)
00856         {
00857                 storein_sequence(con, s);
00858         }
00859 
00861         template <class T>
00862         void storein(std::deque<T>& con, const SQLTypeAdapter& s)
00863         {
00864                 storein_sequence(con, s);
00865         }
00866 
00868         template <class T>
00869         void storein(std::list<T>& con, const SQLTypeAdapter& s)
00870         {
00871                 storein_sequence(con, s);
00872         }
00873 
00874 #if defined(HAVE_EXT_SLIST)
00877         template <class T>
00878         void storein(__gnu_cxx::slist<T>& con, const SQLTypeAdapter& s)
00879         {
00880                 storein_sequence(con, s);
00881         }
00882 #elif defined(HAVE_GLOBAL_SLIST)
00889         template <class T>
00890         void storein(slist<T>& con, const SQLTypeAdapter& s)
00891         {
00892                 storein_sequence(con, s);
00893         }
00894 #elif defined(HAVE_STD_SLIST)
00900         template <class T>
00901         void storein(std::slist<T>& con, const SQLTypeAdapter& s)
00902         {
00903                 storein_sequence(con, s);
00904         }
00905 #endif
00906 
00908         template <class T>
00909         void storein(std::set<T>& con, const SQLTypeAdapter& s)
00910         {
00911                 storein_set(con, s);
00912         }
00913 
00915         template <class T>
00916         void storein(std::multiset<T>& con, const SQLTypeAdapter& s)
00917         {
00918                 storein_set(con, s);
00919         }
00920 
00931         template <class T>
00932         Query& update(const T& o, const T& n)
00933         {
00934                 reset();
00935 
00936                 // Cast required for VC++ 2003 due to error in overloaded operator
00937                 // lookup logic.  For an explanation of the problem, see:
00938                 // http://groups-beta.google.com/group/microsoft.public.vc.stl/browse_thread/thread/9a68d84644e64f15
00939                 MYSQLPP_QUERY_THISPTR << std::setprecision(16) <<
00940                                 "UPDATE " << o.table() << " SET " << n.equal_list() <<
00941                                 " WHERE " << o.equal_list(" AND ", sql_use_compare);
00942                 return *this;
00943         }
00944 
00953         template <class T>
00954         Query& insert(const T& v)
00955         {
00956                 reset();
00957 
00958                 MYSQLPP_QUERY_THISPTR << std::setprecision(16) <<
00959                                 "INSERT INTO " << v.table() << " (" <<
00960                                 v.field_list() << ") VALUES (" <<
00961                                 v.value_list() << ')';
00962                 return *this;
00963         }
00964 
00978         template <class Iter>
00979         Query& insert(Iter first, Iter last)
00980         {
00981                 reset();
00982                 if (first == last) {
00983                         return *this;   // empty set!
00984                 }
00985                 
00986                 MYSQLPP_QUERY_THISPTR << std::setprecision(16) <<
00987                                 "INSERT INTO " << first->table() << " (" <<
00988                                 first->field_list() << ") VALUES (" <<
00989                                 first->value_list() << ')';
00990 
00991                 Iter it = first + 1;
00992                 while (it != last) {
00993                         MYSQLPP_QUERY_THISPTR << ",(" << it->value_list() << ')';
00994                         ++it;
00995                 }
00996 
00997                 return *this;
00998         }
00999 
01009         template <class T>
01010         Query& replace(const T& v)
01011         {
01012                 reset();
01013 
01014                 MYSQLPP_QUERY_THISPTR << std::setprecision(16) <<
01015                                 "REPLACE INTO " << v.table() << " (" <<
01016                                 v.field_list() << ") VALUES (" << v.value_list() << ')';
01017                 return *this;
01018         }
01019 
01020 #if !defined(DOXYGEN_IGNORE)
01021         // Declare the remaining overloads.  These are hidden down here partly
01022         // to keep the above code clear, but also so that we may hide them
01023         // from Doxygen, which gets confused by macro instantiations that look
01024         // like method declarations.
01025         mysql_query_define0(std::string, str)
01026         mysql_query_define0(SimpleResult, execute)
01027         mysql_query_define0(StoreQueryResult, store)
01028         mysql_query_define0(UseQueryResult, use)
01029         mysql_query_define1(storein_sequence)
01030         mysql_query_define1(storein_set)
01031         mysql_query_define1(storein)
01032 #endif // !defined(DOXYGEN_IGNORE)
01033 
01037         SQLQueryParms template_defaults;
01038 
01039 private:
01040         friend class SQLQueryParms;
01041 
01043         Connection* conn_;
01044 
01046         bool copacetic_;
01047 
01049         std::vector<SQLParseElement> parse_elems_;
01050 
01053         std::vector<std::string> parsed_names_;
01054 
01056         std::map<std::string, short int> parsed_nums_;
01057 
01059         std::stringbuf sbuffer_;
01060 
01062         void proc(SQLQueryParms& p);
01063 
01064         SQLTypeAdapter* pprepare(char option, SQLTypeAdapter& S, bool replace = true);
01065 };
01066 
01067 
01071 inline std::ostream& operator <<(std::ostream& os, Query& q)
01072 {
01073         return os << q.str();
01074 }
01075 
01076 
01077 } // end namespace mysqlpp
01078 
01079 #endif // !defined(MYSQLPP_QUERY_H)
01080 

Generated on Wed Jul 2 16:09:23 2008 for MySQL++ by  doxygen 1.4.7