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 #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
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
00716
00717
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;
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
00807
00808
00809
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
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
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
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 }
00928
00929 #endif
00930