# 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 private:
    00126     typedef bool Query::*private_bool_type;
    00127
    00128 public:
    00136         Query(Connection* c, bool te = true, const char* qstr = 0);
    00137
    00145         Query(const Query& q);
    00146
    00148         ulonglong affected_rows();
    00149
    00187         size_t escape_string(std::string* ps, const char* original = 0,
    00188                         size_t length = 0) const;
    00189
    00206         size_t escape_string(char* escaped, const char* original,
    00207                         size_t length) const;
    00208
    00213         int errnum() const;
    00214
    00219         const char* error() const;
    00220
    00223         std::string info();
    00224
    00231         ulonglong insert_id();
    00232
    00237         Query& operator=(const Query& rhs);
    00238
    00257         operator private_bool_type() const;
    00258
    00266         void parse();
    00267
    00277         void reset();
    00278
    00280         std::string str() { return str(template_defaults); }
    00281
    00295         std::string str(const SQLTypeAdapter& arg0)
    00296                         { return str(SQLQueryParms() << arg0); }
    00297
    00302         std::string str(SQLQueryParms& p);
    00303
    00314         bool exec() { return exec(str(template_defaults)); }
    00315
    00327         bool exec(const std::string& str);
    00328
    00345         SimpleResult execute() { return execute(str(template_defaults)); }
    00346
    00355         SimpleResult execute(SQLQueryParms& p);
    00356
    00373         SimpleResult execute(const SQLTypeAdapter& str);
    00374
    00379         SimpleResult execute(const char* str, size_t len);
    00380
    00406         UseQueryResult use() { return use(str(template_defaults)); }
    00407
    00417         UseQueryResult use(SQLQueryParms& p);
    00418
    00436         UseQueryResult use(const SQLTypeAdapter& str);
    00437
    00447         UseQueryResult use(const char* str, size_t len);
    00448
    00470         StoreQueryResult store() { return store(str(template_defaults)); }
    00471
    00480         StoreQueryResult store(SQLQueryParms& p);
    00481
    00499         StoreQueryResult store(const SQLTypeAdapter& str);
    00500
    00510         StoreQueryResult store(const char* str, size_t len);
    00511
    00522         template <typename Function>
    00523         Function for_each(const SQLTypeAdapter& query, Function fn)
    00524         {
    00525                 mysqlpp::UseQueryResult res = use(query);
    00526                 if (res) {
    00527                         mysqlpp::NoExceptions ne(res);
    00528                         while (mysqlpp::Row row = res.fetch_row()) {
    00529                                 fn(row);
    00530                         }
    00531                 }
    00532
    00533                 return fn;
    00534         }
    00535
    00543         template <typename Function>
    00544         Function for_each(Function fn)
    00545         {
    00546                 mysqlpp::UseQueryResult res = use();
    00547                 if (res) {
    00548                         mysqlpp::NoExceptions ne(res);
    00549                         while (mysqlpp::Row row = res.fetch_row()) {
    00550                                 fn(row);
    00551                         }
    00552                 }
    00553
    00554                 return fn;
    00555         }
    00556
    00567         template <class SSQLS, typename Function>
    00568         Function for_each(const SSQLS& ssqls, Function fn)
    00569         {
    00570                 std::string query("select * from ");
    00571                 query += ssqls.table();
    00572                 mysqlpp::UseQueryResult res = use(query);
    00573                 if (res) {
    00574                         mysqlpp::NoExceptions ne(res);
    00575                         while (mysqlpp::Row row = res.fetch_row()) {
    00576                                 fn(row);
    00577                         }
    00578                 }
    00579
    00580                 return fn;
    00581         }
    00582
    00602         template <class Sequence, typename Function>
    00603         Function store_if(Sequence& con, const SQLTypeAdapter& query, Function fn)
    00604         {
    00605                 mysqlpp::UseQueryResult res = use(query);
    00606                 if (res) {
    00607                         mysqlpp::NoExceptions ne(res);
    00608                         while (mysqlpp::Row row = res.fetch_row()) {
    00609                                 if (fn(row)) {
    00610                                         con.push_back(row);
    00611                                 }
    00612                         }
    00613                 }
    00614
    00615                 return fn;
    00616         }
    00617
    00629         template <class Sequence, class SSQLS, typename Function>
    00630         Function store_if(Sequence& con, const SSQLS& ssqls, Function fn)
    00631         {
    00632                 std::string query("select * from ");
    00633                 query += ssqls.table();
    00634                 mysqlpp::UseQueryResult res = use(query);
    00635                 if (res) {
    00636                         mysqlpp::NoExceptions ne(res);
    00637                         while (mysqlpp::Row row = res.fetch_row()) {
    00638                                 if (fn(row)) {
    00639                                         con.push_back(row);
    00640                                 }
    00641                         }
    00642                 }
    00643
    00644                 return fn;
    00645         }
    00646
    00656         template <class Sequence, typename Function>
    00657         Function store_if(Sequence& con, Function fn)
    00658         {
    00659                 mysqlpp::UseQueryResult res = use();
    00660                 if (res) {
    00661                         mysqlpp::NoExceptions ne(res);
    00662                         while (mysqlpp::Row row = res.fetch_row()) {
    00663                                 if (fn(row)) {
    00664                                         con.push_back(row);
    00665                                 }
    00666                         }
    00667                 }
    00668
    00669                 return fn;
    00670         }
    00671
    00698         StoreQueryResult store_next();
    00699
    00711         bool more_results();
    00712
    00729         template <class Sequence>
    00730         void storein_sequence(Sequence& con)
    00731         {
    00732                 storein_sequence(con, str(template_defaults));
    00733         }
    00734
    00748         template <class Sequence>
    00749         void storein_sequence(Sequence& con, const SQLTypeAdapter& s)
    00750         {
    00751                 UseQueryResult result = use(s);
    00752                 while (1) {
    00753                         MYSQL_ROW d = result.fetch_raw_row();
    00754                         if (!d)
    00755                                 break;
    00756                         Row row(d, &result, result.fetch_lengths(), true);
    00757                         if (!row)
    00758                                 break;
    00759                         con.push_back(typename Sequence::value_type(row));
    00760                 }
    00761         }
    00762
    00773     template <class Seq>
    00774     void storein_sequence(Seq& con, SQLQueryParms& p)
    00775     {
    00776         storein_sequence(con, str(p));
    00777     }
    00778
    00786         template <class Set>
    00787         void storein_set(Set& con)
    00788         {
    00789                 storein_set(con, str(template_defaults));
    00790         }
    00791
    00805         template <class Set>
    00806         void storein_set(Set& con, const SQLTypeAdapter& s)
    00807         {
    00808                 UseQueryResult result = use(s);
    00809                 while (1) {
    00810                         MYSQL_ROW d = result.fetch_raw_row();
    00811                         if (!d)
    00812                                 return;
    00813                         Row row(d, &result, result.fetch_lengths(), true);
    00814                         if (!row)
    00815                                 break;
    00816                         con.insert(typename Set::value_type(row));
    00817                 }
    00818         }
    00819
    00830     template <class Set>
    00831     void storein_set(Set& con, SQLQueryParms& p)
    00832     {
    00833         storein_set(con, str(p));
    00834     }
    00835
    00854         template <class Container>
    00855         void storein(Container& con)
    00856         {
    00857                 storein(con, str(template_defaults));
    00858         }
    00859
    00861         template <class T>
    00862         void storein(std::vector<T>& con, const SQLTypeAdapter& s)
    00863         {
    00864                 storein_sequence(con, s);
    00865         }
    00866
    00868         template <class T>
    00869         void storein(std::deque<T>& con, const SQLTypeAdapter& s)
    00870         {
    00871                 storein_sequence(con, s);
    00872         }
    00873
    00875         template <class T>
    00876         void storein(std::list<T>& con, const SQLTypeAdapter& s)
    00877         {
    00878                 storein_sequence(con, s);
    00879         }
    00880
    00881 #if defined(HAVE_EXT_SLIST)
    00884         template <class T>
    00885         void storein(__gnu_cxx::slist<T>& con, const SQLTypeAdapter& s)
    00886         {
    00887                 storein_sequence(con, s);
    00888         }
    00889 #elif defined(HAVE_GLOBAL_SLIST)
    00896         template <class T>
    00897         void storein(slist<T>& con, const SQLTypeAdapter& s)
    00898         {
    00899                 storein_sequence(con, s);
    00900         }
    00901 #elif defined(HAVE_STD_SLIST)
    00907         template <class T>
    00908         void storein(std::slist<T>& con, const SQLTypeAdapter& s)
    00909         {
    00910                 storein_sequence(con, s);
    00911         }
    00912 #endif
    00913
    00915         template <class T>
    00916         void storein(std::set<T>& con, const SQLTypeAdapter& s)
    00917         {
    00918                 storein_set(con, s);
    00919         }
    00920
    00922         template <class T>
    00923         void storein(std::multiset<T>& con, const SQLTypeAdapter& s)
    00924         {
    00925                 storein_set(con, s);
    00926         }
    00927
    00938         template <class T>
    00939         Query& update(const T& o, const T& n)
    00940         {
    00941                 reset();
    00942
    00943                 // Cast required for VC++ 2003 due to error in overloaded operator
    00944                 // lookup logic.  For an explanation of the problem, see:
    00945                 // http://groups-beta.google.com/group/microsoft.public.vc.stl/browse_thread/thread/9a68d84644e64f15
    00946                 MYSQLPP_QUERY_THISPTR << std::setprecision(16) <<
    00947                                 "UPDATE " << o.table() << " SET " << n.equal_list() <<
    00948                                 " WHERE " << o.equal_list(" AND ", sql_use_compare);
    00949                 return *this;
    00950         }
    00951
    00960         template <class T>
    00961         Query& insert(const T& v)
    00962         {
    00963                 reset();
    00964
    00965                 MYSQLPP_QUERY_THISPTR << std::setprecision(16) <<
    00966                                 "INSERT INTO " << v.table() << " (" <<
    00967                                 v.field_list() << ") VALUES (" <<
    00968                                 v.value_list() << ')';
    00969                 return *this;
    00970         }
    00971
    00985         template <class Iter>
    00986         Query& insert(Iter first, Iter last)
    00987         {
    00988                 reset();
    00989                 if (first == last) {
    00990                         return *this;   // empty set!
    00991                 }
    00992
    00993                 MYSQLPP_QUERY_THISPTR << std::setprecision(16) <<
    00994                                 "INSERT INTO " << first->table() << " (" <<
    00995                                 first->field_list() << ") VALUES (" <<
    00996                                 first->value_list() << ')';
    00997
    00998                 Iter it = first + 1;
    00999                 while (it != last) {
    01000                         MYSQLPP_QUERY_THISPTR << ",(" << it->value_list() << ')';
    01001                         ++it;
    01002                 }
    01003
    01004                 return *this;
    01005         }
    01006
    01016         template <class T>
    01017         Query& replace(const T& v)
    01018         {
    01019                 reset();
    01020
    01021                 MYSQLPP_QUERY_THISPTR << std::setprecision(16) <<
    01022                                 "REPLACE INTO " << v.table() << " (" <<
    01023                                 v.field_list() << ") VALUES (" << v.value_list() << ')';
    01024                 return *this;
    01025         }
    01026
    01027 #if !defined(DOXYGEN_IGNORE)
    01028         // Declare the remaining overloads.  These are hidden down here partly
    01029         // to keep the above code clear, but also so that we may hide them
    01030         // from Doxygen, which gets confused by macro instantiations that look
    01031         // like method declarations.
    01032         mysql_query_define0(std::string, str)
    01033         mysql_query_define0(SimpleResult, execute)
    01034         mysql_query_define0(StoreQueryResult, store)
    01035         mysql_query_define0(UseQueryResult, use)
    01036         mysql_query_define1(storein_sequence)
    01037         mysql_query_define1(storein_set)
    01038         mysql_query_define1(storein)
    01039 #endif // !defined(DOXYGEN_IGNORE)
    01040
    01044         SQLQueryParms template_defaults;
    01045
    01046 private:
    01047         friend class SQLQueryParms;
    01048
    01050         Connection* conn_;
    01051
    01053         bool copacetic_;
    01054
    01056         std::vector<SQLParseElement> parse_elems_;
    01057
    01060         std::vector<std::string> parsed_names_;
    01061
    01063         std::map<std::string, short int> parsed_nums_;
    01064
    01066         std::stringbuf sbuffer_;
    01067
    01069         void proc(SQLQueryParms& p);
    01070
    01071         SQLTypeAdapter* pprepare(char option, SQLTypeAdapter& S, bool replace = true);
    01072 };
    01073
    01074
    01078 inline std::ostream& operator <<(std::ostream& os, Query& q)
    01079 {
    01080         return os << q.str();
    01081 }
    01082
    01083
    01084 } // end namespace mysqlpp
    01085
    01086 #endif // !defined(MYSQLPP_QUERY_H)
    01087