00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028 #if !defined(MYSQLPP_QUERY_H)
00029 #define MYSQLPP_QUERY_H
00030
00031 #include "common.h"
00032
00033 #include "exceptions.h"
00034 #include "noexceptions.h"
00035 #include "qparms.h"
00036 #include "querydef.h"
00037 #include "result.h"
00038 #include "row.h"
00039 #include "sqlstream.h"
00040 #include "stadapter.h"
00041 #include "transaction.h"
00042
00043 #include <deque>
00044 #include <iomanip>
00045 #include <list>
00046 #include <map>
00047 #include <set>
00048 #include <vector>
00049
00050 #ifdef HAVE_EXT_SLIST
00051 # include <ext/slist>
00052 #else
00053 # if defined(HAVE_STD_SLIST) || defined(HAVE_GLOBAL_SLIST)
00054 # include <slist>
00055 # endif
00056 #endif
00057
00058 namespace mysqlpp {
00059
00060 #if !defined(DOXYGEN_IGNORE)
00061
00062 class MYSQLPP_EXPORT Connection;
00063 class MYSQLPP_EXPORT Transaction;
00064 #endif
00065
00120
00121 class MYSQLPP_EXPORT Query :
00122 public std::ostream,
00123 public OptionalExceptions
00124 {
00125 public:
00126 #if !defined(DOXYGEN_IGNORE)
00127
00128
00129 #include "insertpolicy.h"
00130 #endif
00131
00139 Query(Connection* c, bool te = true, const char* qstr = 0);
00140
00148 Query(const Query& q);
00149
00151 ulonglong affected_rows();
00152
00167 size_t escape_string(std::string* ps, const char* original = 0,
00168 size_t length = 0) const;
00169
00191 size_t escape_string(char* escaped, const char* original,
00192 size_t length) const;
00193
00198 int errnum() const;
00199
00204 const char* error() const;
00205
00208 std::string info();
00209
00220 ulonglong insert_id();
00221
00226 Query& operator=(const Query& rhs);
00227
00246 operator void*() const;
00247
00255 bool operator !() const { return !operator void*(); }
00256
00264 void parse();
00265
00275 void reset();
00276
00278 std::string str() { return str(template_defaults); }
00279
00293 std::string str(const SQLTypeAdapter& arg0)
00294 { return str(SQLQueryParms() << arg0); }
00295
00300 std::string str(SQLQueryParms& p);
00301
00312 bool exec() { return exec(str(template_defaults)); }
00313
00325 bool exec(const std::string& str);
00326
00343 SimpleResult execute();
00344
00353 SimpleResult execute(SQLQueryParms& p);
00354
00371 SimpleResult execute(const SQLTypeAdapter& str);
00372
00377 SimpleResult execute(const char* str, size_t len);
00378
00404 UseQueryResult use();
00405
00415 UseQueryResult use(SQLQueryParms& p);
00416
00434 UseQueryResult use(const SQLTypeAdapter& str);
00435
00445 UseQueryResult use(const char* str, size_t len);
00446
00468 StoreQueryResult store();
00469
00478 StoreQueryResult store(SQLQueryParms& p);
00479
00497 StoreQueryResult store(const SQLTypeAdapter& str);
00498
00508 StoreQueryResult store(const char* str, size_t len);
00509
00520 template <typename Function>
00521 Function for_each(const SQLTypeAdapter& query, Function fn)
00522 {
00523 mysqlpp::UseQueryResult res = use(query);
00524 if (res) {
00525 mysqlpp::NoExceptions ne(res);
00526 while (mysqlpp::Row row = res.fetch_row()) {
00527 fn(row);
00528 }
00529 }
00530
00531 return fn;
00532 }
00533
00541 template <typename Function>
00542 Function for_each(Function fn)
00543 {
00544 mysqlpp::UseQueryResult res = use();
00545 if (res) {
00546 mysqlpp::NoExceptions ne(res);
00547 while (mysqlpp::Row row = res.fetch_row()) {
00548 fn(row);
00549 }
00550 }
00551
00552 return fn;
00553 }
00554
00565 template <class SSQLS, typename Function>
00566 Function for_each(const SSQLS& ssqls, Function fn)
00567 {
00568 std::string query("select * from `");
00569 query += ssqls.table();
00570 query += '`';
00571 mysqlpp::UseQueryResult res = use(query);
00572 if (res) {
00573 mysqlpp::NoExceptions ne(res);
00574 while (mysqlpp::Row row = res.fetch_row()) {
00575 fn(row);
00576 }
00577 }
00578
00579 return fn;
00580 }
00581
00601 template <class Sequence, typename Function>
00602 Function store_if(Sequence& con, const SQLTypeAdapter& query, Function fn)
00603 {
00604 mysqlpp::UseQueryResult res = use(query);
00605 if (res) {
00606 mysqlpp::NoExceptions ne(res);
00607 while (mysqlpp::Row row = res.fetch_row()) {
00608 if (fn(row)) {
00609 con.push_back(row);
00610 }
00611 }
00612 }
00613
00614 return fn;
00615 }
00616
00628 template <class Sequence, class SSQLS, typename Function>
00629 Function store_if(Sequence& con, const SSQLS& ssqls, Function fn)
00630 {
00631 std::string query("select * from `");
00632 query += ssqls.table();
00633 query += '`';
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(),
00757 throw_exceptions());
00758 if (!row)
00759 break;
00760 con.push_back(typename Sequence::value_type(row));
00761 }
00762 }
00763
00774 template <class Seq>
00775 void storein_sequence(Seq& con, SQLQueryParms& p)
00776 {
00777 storein_sequence(con, str(p));
00778 }
00779
00787 template <class Set>
00788 void storein_set(Set& con)
00789 {
00790 storein_set(con, str(template_defaults));
00791 }
00792
00806 template <class Set>
00807 void storein_set(Set& con, const SQLTypeAdapter& s)
00808 {
00809 UseQueryResult result = use(s);
00810 while (1) {
00811 MYSQL_ROW d = result.fetch_raw_row();
00812 if (!d)
00813 return;
00814 Row row(d, &result, result.fetch_lengths(),
00815 throw_exceptions());
00816 if (!row)
00817 break;
00818 con.insert(typename Set::value_type(row));
00819 }
00820 }
00821
00832 template <class Set>
00833 void storein_set(Set& con, SQLQueryParms& p)
00834 {
00835 storein_set(con, str(p));
00836 }
00837
00856 template <class Container>
00857 void storein(Container& con)
00858 {
00859 storein(con, str(template_defaults));
00860 }
00861
00868 template <class T>
00869 void storein(T& con, SQLQueryParms& p)
00870 {
00871 storein(con, str(p));
00872 }
00873
00875 template <class T>
00876 void storein(std::vector<T>& con, const SQLTypeAdapter& s)
00877 {
00878 storein_sequence(con, s);
00879 }
00880
00882 template <class T>
00883 void storein(std::deque<T>& con, const SQLTypeAdapter& s)
00884 {
00885 storein_sequence(con, s);
00886 }
00887
00889 template <class T>
00890 void storein(std::list<T>& con, const SQLTypeAdapter& s)
00891 {
00892 storein_sequence(con, s);
00893 }
00894
00895 #if defined(HAVE_EXT_SLIST)
00898 template <class T>
00899 void storein(__gnu_cxx::slist<T>& con, const SQLTypeAdapter& s)
00900 {
00901 storein_sequence(con, s);
00902 }
00903 #elif defined(HAVE_GLOBAL_SLIST)
00910 template <class T>
00911 void storein(slist<T>& con, const SQLTypeAdapter& s)
00912 {
00913 storein_sequence(con, s);
00914 }
00915 #elif defined(HAVE_STD_SLIST)
00921 template <class T>
00922 void storein(std::slist<T>& con, const SQLTypeAdapter& s)
00923 {
00924 storein_sequence(con, s);
00925 }
00926 #endif
00927
00929 template <class T>
00930 void storein(std::set<T>& con, const SQLTypeAdapter& s)
00931 {
00932 storein_set(con, s);
00933 }
00934
00936 template <class T>
00937 void storein(std::multiset<T>& con, const SQLTypeAdapter& s)
00938 {
00939 storein_set(con, s);
00940 }
00941
00952 template <class T>
00953 Query& update(const T& o, const T& n)
00954 {
00955 reset();
00956
00957
00958
00959
00960 MYSQLPP_QUERY_THISPTR << std::setprecision(16) <<
00961 "UPDATE `" << o.table() << "` SET " << n.equal_list() <<
00962 " WHERE " << o.equal_list(" AND ", sql_use_compare);
00963 return *this;
00964 }
00965
00974 template <class T>
00975 Query& insert(const T& v)
00976 {
00977 reset();
00978
00979 MYSQLPP_QUERY_THISPTR << std::setprecision(16) <<
00980 "INSERT INTO `" << v.table() << "` (" <<
00981 v.field_list() << ") VALUES (" <<
00982 v.value_list() << ')';
00983 return *this;
00984 }
00985
00999 template <class Iter>
01000 Query& insert(Iter first, Iter last)
01001 {
01002 reset();
01003 if (first == last) {
01004 return *this;
01005 }
01006
01007 MYSQLPP_QUERY_THISPTR << std::setprecision(16) <<
01008 "INSERT INTO `" << first->table() << "` (" <<
01009 first->field_list() << ") VALUES (" <<
01010 first->value_list() << ')';
01011
01012 Iter it = first + 1;
01013 while (it != last) {
01014 MYSQLPP_QUERY_THISPTR << ",(" << it->value_list() << ')';
01015 ++it;
01016 }
01017
01018 return *this;
01019 }
01020
01033 template <class Iter, class InsertPolicy>
01034 Query& insertfrom(Iter first, Iter last, InsertPolicy& policy)
01035 {
01036 bool success = true;
01037 bool empty = true;
01038
01039 reset();
01040
01041 if (first == last) {
01042 return *this;
01043 }
01044
01045 typename InsertPolicy::access_controller ac(*conn_);
01046
01047 for (Iter it = first; it != last; ++it) {
01048 if (policy.can_add(int(tellp()), *it)) {
01049 if (empty) {
01050 MYSQLPP_QUERY_THISPTR << std::setprecision(16) <<
01051 "INSERT INTO `" << it->table() << "` (" <<
01052 it->field_list() << ") VALUES (";
01053 }
01054 else {
01055 MYSQLPP_QUERY_THISPTR << ",(";
01056 }
01057
01058 MYSQLPP_QUERY_THISPTR << it->value_list() << ')';
01059
01060 empty = false;
01061 }
01062 else {
01063
01064 if (!empty) {
01065 if (!exec()) {
01066 success = false;
01067 break;
01068 }
01069
01070 empty = true;
01071 }
01072
01073
01074 if (policy.can_add(int(tellp()), *it)) {
01075 MYSQLPP_QUERY_THISPTR << std::setprecision(16) <<
01076 "INSERT INTO `" << it->table() << "` (" <<
01077 it->field_list() << ") VALUES (" <<
01078 it->value_list() << ')';
01079
01080 empty = false;
01081 }
01082 else {
01083
01084 if (throw_exceptions()) {
01085 throw BadInsertPolicy("Insert policy is too strict");
01086 }
01087
01088 success = false;
01089 break;
01090 }
01091 }
01092 }
01093
01094
01095 if (success && !empty && !exec()) {
01096 success = false;
01097 }
01098
01099 if (success) {
01100 ac.commit();
01101 }
01102 else {
01103 ac.rollback();
01104 }
01105
01106 return *this;
01107 }
01108
01118 template <class T>
01119 Query& replace(const T& v)
01120 {
01121 reset();
01122
01123 MYSQLPP_QUERY_THISPTR << std::setprecision(16) <<
01124 "REPLACE INTO `" << v.table() << "` (" <<
01125 v.field_list() << ") VALUES (" << v.value_list() << ')';
01126 return *this;
01127 }
01128
01143 template <class Iter>
01144 Query& replace(Iter first, Iter last)
01145 {
01146 reset();
01147 if (first == last) {
01148 return *this;
01149 }
01150
01151 MYSQLPP_QUERY_THISPTR << std::setprecision(16) <<
01152 "REPLACE INTO " << first->table() << " (" <<
01153 first->field_list() << ") VALUES (" <<
01154 first->value_list() << ')';
01155
01156 Iter it = first + 1;
01157 while (it != last) {
01158 MYSQLPP_QUERY_THISPTR << ",(" << it->value_list() << ')';
01159 ++it;
01160 }
01161
01162 return *this;
01163 }
01164
01165 #if !defined(DOXYGEN_IGNORE)
01166
01167
01168
01169
01170 mysql_query_define0(std::string, str)
01171 mysql_query_define0(SimpleResult, execute)
01172 mysql_query_define0(StoreQueryResult, store)
01173 mysql_query_define0(UseQueryResult, use)
01174 mysql_query_define1(storein_sequence)
01175 mysql_query_define1(storein_set)
01176 mysql_query_define1(storein)
01177 #endif // !defined(DOXYGEN_IGNORE)
01178
01182 SQLQueryParms template_defaults;
01183
01184 private:
01185 friend class SQLQueryParms;
01186
01188 Connection* conn_;
01189
01191 bool copacetic_;
01192
01194 std::vector<SQLParseElement> parse_elems_;
01195
01198 std::vector<std::string> parsed_names_;
01199
01201 std::map<std::string, short int> parsed_nums_;
01202
01204 std::stringbuf sbuffer_;
01205
01207 void proc(SQLQueryParms& p);
01208
01209 SQLTypeAdapter* pprepare(char option, SQLTypeAdapter& S, bool replace = true);
01210 };
01211
01212
01216 inline std::ostream& operator <<(std::ostream& os, Query& q)
01217 {
01218 return os << q.str();
01219 }
01220
01221
01222 }
01223
01224 #endif // !defined(MYSQLPP_QUERY_H)
01225