# 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.txt file
    00008  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 #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
    00228         ulonglong insert_id();
    00229
    00234         Query& operator=(const Query& rhs);
    00235
    00254         operator void*() const;
    00255
    00263         void parse();
    00264
    00274         void reset();
    00275
    00277         std::string str() { return str(template_defaults); }
    00278
    00292         std::string str(const SQLTypeAdapter& arg0)
    00293                         { return str(SQLQueryParms() << arg0); }
    00294
    00299         std::string str(SQLQueryParms& p);
    00300
    00311         bool exec() { return exec(str(template_defaults)); }
    00312
    00324         bool exec(const std::string& str);
    00325
    00342         SimpleResult execute() { return execute(str(template_defaults)); }
    00343
    00352         SimpleResult execute(SQLQueryParms& p);
    00353
    00370         SimpleResult execute(const SQLTypeAdapter& str);
    00371
    00376         SimpleResult execute(const char* str, size_t len);
    00377
    00403         UseQueryResult use() { return use(str(template_defaults)); }
    00404
    00414         UseQueryResult use(SQLQueryParms& p);
    00415
    00433         UseQueryResult use(const SQLTypeAdapter& str);
    00434
    00444         UseQueryResult use(const char* str, size_t len);
    00445
    00467         StoreQueryResult store() { return store(str(template_defaults)); }
    00468
    00477         StoreQueryResult store(SQLQueryParms& p);
    00478
    00496         StoreQueryResult store(const SQLTypeAdapter& str);
    00497
    00507         StoreQueryResult store(const char* str, size_t len);
    00508
    00519         template <typename Function>
    00520         Function for_each(const SQLTypeAdapter& query, Function fn)
    00521         {
    00522                 mysqlpp::UseQueryResult res = use(query);
    00523                 if (res) {
    00524                         mysqlpp::NoExceptions ne(res);
    00525                         while (mysqlpp::Row row = res.fetch_row()) {
    00526                                 fn(row);
    00527                         }
    00528                 }
    00529
    00530                 return fn;
    00531         }
    00532
    00540         template <typename Function>
    00541         Function for_each(Function fn)
    00542         {
    00543                 mysqlpp::UseQueryResult res = use();
    00544                 if (res) {
    00545                         mysqlpp::NoExceptions ne(res);
    00546                         while (mysqlpp::Row row = res.fetch_row()) {
    00547                                 fn(row);
    00548                         }
    00549                 }
    00550
    00551                 return fn;
    00552         }
    00553
    00564         template <class SSQLS, typename Function>
    00565         Function for_each(const SSQLS& ssqls, Function fn)
    00566         {
    00567                 std::string query("select * from ");
    00568                 query += ssqls.table();
    00569                 mysqlpp::UseQueryResult res = use(query);
    00570                 if (res) {
    00571                         mysqlpp::NoExceptions ne(res);
    00572                         while (mysqlpp::Row row = res.fetch_row()) {
    00573                                 fn(row);
    00574                         }
    00575                 }
    00576
    00577                 return fn;
    00578         }
    00579
    00599         template <class Sequence, typename Function>
    00600         Function store_if(Sequence& con, const SQLTypeAdapter& query, Function fn)
    00601         {
    00602                 mysqlpp::UseQueryResult res = use(query);
    00603                 if (res) {
    00604                         mysqlpp::NoExceptions ne(res);
    00605                         while (mysqlpp::Row row = res.fetch_row()) {
    00606                                 if (fn(row)) {
    00607                                         con.push_back(row);
    00608                                 }
    00609                         }
    00610                 }
    00611
    00612                 return fn;
    00613         }
    00614
    00626         template <class Sequence, class SSQLS, typename Function>
    00627         Function store_if(Sequence& con, const SSQLS& ssqls, Function fn)
    00628         {
    00629                 std::string query("select * from ");
    00630                 query += ssqls.table();
    00631                 mysqlpp::UseQueryResult res = use(query);
    00632                 if (res) {
    00633                         mysqlpp::NoExceptions ne(res);
    00634                         while (mysqlpp::Row row = res.fetch_row()) {
    00635                                 if (fn(row)) {
    00636                                         con.push_back(row);
    00637                                 }
    00638                         }
    00639                 }
    00640
    00641                 return fn;
    00642         }
    00643
    00653         template <class Sequence, typename Function>
    00654         Function store_if(Sequence& con, Function fn)
    00655         {
    00656                 mysqlpp::UseQueryResult res = use();
    00657                 if (res) {
    00658                         mysqlpp::NoExceptions ne(res);
    00659                         while (mysqlpp::Row row = res.fetch_row()) {
    00660                                 if (fn(row)) {
    00661                                         con.push_back(row);
    00662                                 }
    00663                         }
    00664                 }
    00665
    00666                 return fn;
    00667         }
    00668
    00695         StoreQueryResult store_next();
    00696
    00708         bool more_results();
    00709
    00726         template <class Sequence>
    00727         void storein_sequence(Sequence& con)
    00728         {
    00729                 storein_sequence(con, str(template_defaults));
    00730         }
    00731
    00745         template <class Sequence>
    00746         void storein_sequence(Sequence& con, const SQLTypeAdapter& s)
    00747         {
    00748                 UseQueryResult result = use(s);
    00749                 while (1) {
    00750                         MYSQL_ROW d = result.fetch_raw_row();
    00751                         if (!d)
    00752                                 break;
    00753                         Row row(d, &result, result.fetch_lengths(),
    00754                                         throw_exceptions());
    00755                         if (!row)
    00756                                 break;
    00757                         con.push_back(typename Sequence::value_type(row));
    00758                 }
    00759         }
    00760
    00771         template <class Seq>
    00772         void storein_sequence(Seq& con, SQLQueryParms& p)
    00773         {
    00774                 storein_sequence(con, str(p));
    00775         }
    00776
    00784         template <class Set>
    00785         void storein_set(Set& con)
    00786         {
    00787                 storein_set(con, str(template_defaults));
    00788         }
    00789
    00803         template <class Set>
    00804         void storein_set(Set& con, const SQLTypeAdapter& s)
    00805         {
    00806                 UseQueryResult result = use(s);
    00807                 while (1) {
    00808                         MYSQL_ROW d = result.fetch_raw_row();
    00809                         if (!d)
    00810                                 return;
    00811                         Row row(d, &result, result.fetch_lengths(),
    00812                                         throw_exceptions());
    00813                         if (!row)
    00814                                 break;
    00815                         con.insert(typename Set::value_type(row));
    00816                 }
    00817         }
    00818
    00829         template <class Set>
    00830         void storein_set(Set& con, SQLQueryParms& p)
    00831         {
    00832                 storein_set(con, str(p));
    00833         }
    00834
    00853         template <class Container>
    00854         void storein(Container& con)
    00855         {
    00856                 storein(con, str(template_defaults));
    00857         }
    00858
    00860         template <class T>
    00861         void storein(std::vector<T>& con, const SQLTypeAdapter& s)
    00862         {
    00863                 storein_sequence(con, s);
    00864         }
    00865
    00867         template <class T>
    00868         void storein(std::deque<T>& con, const SQLTypeAdapter& s)
    00869         {
    00870                 storein_sequence(con, s);
    00871         }
    00872
    00874         template <class T>
    00875         void storein(std::list<T>& con, const SQLTypeAdapter& s)
    00876         {
    00877                 storein_sequence(con, s);
    00878         }
    00879
    00880 #if defined(HAVE_EXT_SLIST)
    00883         template <class T>
    00884         void storein(__gnu_cxx::slist<T>& con, const SQLTypeAdapter& s)
    00885         {
    00886                 storein_sequence(con, s);
    00887         }
    00888 #elif defined(HAVE_GLOBAL_SLIST)
    00895         template <class T>
    00896         void storein(slist<T>& con, const SQLTypeAdapter& s)
    00897         {
    00898                 storein_sequence(con, s);
    00899         }
    00900 #elif defined(HAVE_STD_SLIST)
    00906         template <class T>
    00907         void storein(std::slist<T>& con, const SQLTypeAdapter& s)
    00908         {
    00909                 storein_sequence(con, s);
    00910         }
    00911 #endif
    00912
    00914         template <class T>
    00915         void storein(std::set<T>& con, const SQLTypeAdapter& s)
    00916         {
    00917                 storein_set(con, s);
    00918         }
    00919
    00921         template <class T>
    00922         void storein(std::multiset<T>& con, const SQLTypeAdapter& s)
    00923         {
    00924                 storein_set(con, s);
    00925         }
    00926
    00937         template <class T>
    00938         Query& update(const T& o, const T& n)
    00939         {
    00940                 reset();
    00941
    00942                 // Cast required for VC++ 2003 due to error in overloaded operator
    00943                 // lookup logic.  For an explanation of the problem, see:
    00944                 // http://groups-beta.google.com/group/microsoft.public.vc.stl/browse_thread/thread/9a68d84644e64f15
    00945                 MYSQLPP_QUERY_THISPTR << std::setprecision(16) <<
    00946                                 "UPDATE " << o.table() << " SET " << n.equal_list() <<
    00947                                 " WHERE " << o.equal_list(" AND ", sql_use_compare);
    00948                 return *this;
    00949         }
    00950
    00959         template <class T>
    00960         Query& insert(const T& v)
    00961         {
    00962                 reset();
    00963
    00964                 MYSQLPP_QUERY_THISPTR << std::setprecision(16) <<
    00965                                 "INSERT INTO " << v.table() << " (" <<
    00966                                 v.field_list() << ") VALUES (" <<
    00967                                 v.value_list() << ')';
    00968                 return *this;
    00969         }
    00970
    00984         template <class Iter>
    00985         Query& insert(Iter first, Iter last)
    00986         {
    00987                 reset();
    00988                 if (first == last) {
    00989                         return *this;   // empty set!
    00990                 }
    00991
    00992                 MYSQLPP_QUERY_THISPTR << std::setprecision(16) <<
    00993                                 "INSERT INTO " << first->table() << " (" <<
    00994                                 first->field_list() << ") VALUES (" <<
    00995                                 first->value_list() << ')';
    00996
    00997                 Iter it = first + 1;
    00998                 while (it != last) {
    00999                         MYSQLPP_QUERY_THISPTR << ",(" << it->value_list() << ')';
    01000                         ++it;
    01001                 }
    01002
    01003                 return *this;
    01004         }
    01005
    01015         template <class T>
    01016         Query& replace(const T& v)
    01017         {
    01018                 reset();
    01019
    01020                 MYSQLPP_QUERY_THISPTR << std::setprecision(16) <<
    01021                                 "REPLACE INTO " << v.table() << " (" <<
    01022                                 v.field_list() << ") VALUES (" << v.value_list() << ')';
    01023                 return *this;
    01024         }
    01025
    01026 #if !defined(DOXYGEN_IGNORE)
    01027         // Declare the remaining overloads.  These are hidden down here partly
    01028         // to keep the above code clear, but also so that we may hide them
    01029         // from Doxygen, which gets confused by macro instantiations that look
    01030         // like method declarations.
    01031         mysql_query_define0(std::string, str)
    01032         mysql_query_define0(SimpleResult, execute)
    01033         mysql_query_define0(StoreQueryResult, store)
    01034         mysql_query_define0(UseQueryResult, use)
    01035         mysql_query_define1(storein_sequence)
    01036         mysql_query_define1(storein_set)
    01037         mysql_query_define1(storein)
    01038 #endif // !defined(DOXYGEN_IGNORE)
    01039
    01043         SQLQueryParms template_defaults;
    01044
    01045 private:
    01046         friend class SQLQueryParms;
    01047
    01049         Connection* conn_;
    01050
    01052         bool copacetic_;
    01053
    01055         std::vector<SQLParseElement> parse_elems_;
    01056
    01059         std::vector<std::string> parsed_names_;
    01060
    01062         std::map<std::string, short int> parsed_nums_;
    01063
    01065         std::stringbuf sbuffer_;
    01066
    01068         void proc(SQLQueryParms& p);
    01069
    01070         SQLTypeAdapter* pprepare(char option, SQLTypeAdapter& S, bool replace = true);
    01071 };
    01072
    01073
    01077 inline std::ostream& operator <<(std::ostream& os, Query& q)
    01078 {
    01079         return os << q.str();
    01080 }
    01081
    01082
    01083 } // end namespace mysqlpp
    01084
    01085 #endif // !defined(MYSQLPP_QUERY_H)
    01086