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 "defs.h"
00032
00033 #include "lockable.h"
00034 #include "noexceptions.h"
00035 #include "qparms.h"
00036 #include "result.h"
00037 #include "row.h"
00038 #include "sql_string.h"
00039
00040 #include <mysql.h>
00041
00042 #include <deque>
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
00057
00059 #define mysql_query_define0(RETURN, FUNC)\
00060 RETURN FUNC (ss a)\
00061 {return FUNC (parms() << a);}\
00062 RETURN FUNC (ss a, ss b)\
00063 {return FUNC (parms() << a << b);}\
00064 RETURN FUNC (ss a, ss b, ss c)\
00065 {return FUNC (parms() << a << b << c);}\
00066 RETURN FUNC (ss a, ss b, ss c, ss d)\
00067 {return FUNC (parms() << a << b << c << d);}\
00068 RETURN FUNC (ss a, ss b, ss c, ss d, ss e)\
00069 {return FUNC (parms() << a << b << c << d << e);} \
00070 RETURN FUNC (ss a, ss b, ss c, ss d, ss e, ss f)\
00071 {return FUNC (parms() << a << b << c << d << e << f);}\
00072 RETURN FUNC (ss a, ss b, ss c, ss d, ss e, ss f, ss g)\
00073 {return FUNC (parms() << a << b << c << d << e << f << g);}\
00074 RETURN FUNC (ss a, ss b, ss c, ss d, ss e, ss f, ss g, ss h)\
00075 {return FUNC (parms() << a << b << c << d << e << f << g << h);}\
00076 RETURN FUNC (ss a, ss b, ss c, ss d, ss e, ss f, ss g, ss h, ss i)\
00077 {return FUNC (parms() << a << b << c << d << e << f << g << h << i);}\
00078 RETURN FUNC (ss a,ss b,ss c,ss d,ss e,ss f,ss g,ss h,ss i,ss j)\
00079 {return FUNC (parms() <<a <<b <<c <<d <<e <<f <<g <<h <<i <<j);}\
00080 RETURN FUNC (ss a,ss b,ss c,ss d,ss e,ss f,ss g,ss h,ss i,ss j,ss k)\
00081 {return FUNC (parms() <<a <<b <<c <<d <<e <<f <<g <<h <<i <<j <<k);}\
00082 RETURN FUNC (ss a,ss b,ss c,ss d,ss e,ss f,ss g,ss h,ss i,ss j,ss k,ss l)\
00083 {return FUNC (parms() <<a <<b <<c <<d <<e <<f <<g <<h <<i <<j <<k <<l);}\
00084
00085
00086 #define mysql_query_define1(RETURN, FUNC) \
00087 MYSQLPP_EXPORT RETURN FUNC (parms &p);\
00088 mysql_query_define0(RETURN,FUNC) \
00089
00090
00091 #define mysql_query_define2(FUNC) \
00092 template <class T1> void FUNC (T1 &con, const char* str); \
00093 template <class T1> void FUNC (T1 &con, parms &p, query_reset r = RESET_QUERY);\
00094 template <class T1> void FUNC (T1 &con, ss a)\
00095 {FUNC (con, parms() << a);}\
00096 template <class T1> void FUNC (T1 &con, ss a, ss b)\
00097 {FUNC (con, parms() << a << b);}\
00098 template <class T1> void FUNC (T1 &con, ss a, ss b, ss c)\
00099 {FUNC (con, parms() << a << b << c);}\
00100 template <class T1> void FUNC (T1 &con, ss a, ss b, ss c, ss d)\
00101 {FUNC (con, parms() << a << b << c << d);}\
00102 template <class T1> void FUNC (T1 &con, ss a, ss b, ss c, ss d, ss e)\
00103 {FUNC (con, parms() << a << b << c << d << e);} \
00104 template <class T1> void FUNC (T1 &con, ss a, ss b, ss c, ss d, ss e, ss f)\
00105 {FUNC (con, parms() << a << b << c << d << e << f);}\
00106 template <class T1> void FUNC (T1 &con,ss a,ss b,ss c,ss d,ss e,ss f,ss g)\
00107 {FUNC (con, parms() << a << b << c << d << e << f << g);}\
00108 template <class T1> void FUNC (T1 &con,ss a,ss b,ss c,ss d,ss e,ss f,ss g,ss h)\
00109 {FUNC (con, parms() << a << b << c << d << e << f << g << h);}\
00110 template <class T1> void FUNC (T1 &con, ss a, ss b, ss c, ss d, ss e, ss f, ss g, ss h, ss i)\
00111 {FUNC (con, parms() << a << b << c << d << e << f << g << h << i);}\
00112 template <class T1> void FUNC (T1 &con, ss a,ss b,ss c,ss d,ss e,ss f,ss g,ss h,ss i,ss j)\
00113 {FUNC (con, parms() <<a <<b <<c <<d <<e <<f <<g <<h <<i <<j);}\
00114 template <class T1> void FUNC (T1 &con, ss a,ss b,ss c,ss d,ss e,ss f,ss g,ss h,ss i,ss j,ss k)\
00115 {FUNC (con, parms() <<a <<b <<c <<d <<e <<f <<g <<h <<i <<j <<k);}\
00116 template <class T1> void FUNC (T1 &con, ss a,ss b,ss c,ss d,ss e,ss f,ss g,ss h,ss i,ss j,ss k,ss l)\
00117 {FUNC (con, parms() <<a <<b <<c <<d <<e <<f <<g <<h <<i <<j <<k <<l);}\
00118
00119 namespace mysqlpp {
00120
00121 class Connection;
00122
00124 enum query_reset { DONT_RESET, RESET_QUERY };
00125
00174
00175 class Query : public std::ostream,
00176 public OptionalExceptions, public Lockable
00177 {
00178 public:
00179 typedef const SQLString& ss;
00180 typedef SQLQueryParms parms;
00181
00188 Query(Connection* c, bool te = true) :
00189 std::ostream(&sbuffer_),
00190 OptionalExceptions(te),
00191 Lockable(false),
00192 def(this),
00193 conn_(c),
00194 success_(false)
00195 {
00196 success_ = true;
00197 }
00198
00206 MYSQLPP_EXPORT Query(const Query& q);
00207
00212 MYSQLPP_EXPORT Query& operator=(const Query& rhs);
00213
00219 MYSQLPP_EXPORT std::string error();
00220
00226 MYSQLPP_EXPORT bool success();
00227
00235 MYSQLPP_EXPORT void parse();
00236
00241 MYSQLPP_EXPORT void reset();
00242
00244 std::string preview() { return str(def); }
00245
00247 std::string preview(SQLQueryParms& p)
00248 {
00249 return str(p);
00250 }
00251
00253 std::string str()
00254 {
00255 return str(def);
00256 }
00257
00262 std::string str(query_reset r)
00263 {
00264 return str(def, r);
00265 }
00266
00271 MYSQLPP_EXPORT std::string str(SQLQueryParms& p);
00272
00279 MYSQLPP_EXPORT std::string str(SQLQueryParms& p, query_reset r);
00280
00292 MYSQLPP_EXPORT bool exec(const std::string& str);
00293
00310 ResNSel execute() { return execute(def); }
00311
00315 MYSQLPP_EXPORT ResNSel execute(const char* str);
00316
00341 ResUse use() { return use(def); }
00342
00348 MYSQLPP_EXPORT ResUse use(const char* str);
00349
00371 Result store() { return store(def); }
00372
00378 MYSQLPP_EXPORT Result store(const char* str);
00379
00406 MYSQLPP_EXPORT Result store_next();
00407
00419 MYSQLPP_EXPORT bool more_results();
00420
00438 template <class Sequence>
00439 void storein_sequence(Sequence& con, query_reset r = RESET_QUERY)
00440 {
00441 storein_sequence_(con, def, r);
00442 }
00443
00451 template <class Set>
00452 void storein_set(Set& con, query_reset r = RESET_QUERY)
00453 {
00454 storein_set(con, def, r);
00455 }
00456
00475 template <class Container>
00476 void storein(Container& con, query_reset r = RESET_QUERY)
00477 {
00478 storein(con, def, r);
00479 }
00480
00482 template <class T>
00483 void storein(std::vector<T>& con, const char* s)
00484 {
00485 storein_sequence(con, s);
00486 }
00487
00489 template <class T>
00490 void storein(std::deque<T>& con, const char* s)
00491 {
00492 storein_sequence(con, s);
00493 }
00494
00496 template <class T>
00497 void storein(std::list<T>& con, const char* s)
00498 {
00499 storein_sequence(con, s);
00500 }
00501
00502 #if defined(HAVE_EXT_SLIST)
00505 template <class T>
00506 void storein(__gnu_cxx::slist<T>& con, const char* s)
00507 {
00508 storein_sequence(con, s);
00509 }
00510 #elif defined(HAVE_GLOBAL_SLIST)
00517 template <class T>
00518 void storein(slist<T>& con, const char* s)
00519 {
00520 storein_sequence(con, s);
00521 }
00522 #elif defined(HAVE_STD_SLIST)
00528 template <class T>
00529 void storein(std::slist<T>& con, const char* s)
00530 {
00531 storein_sequence(con, s);
00532 }
00533 #endif
00534
00536 template <class T>
00537 void storein(std::set<T>& con, const char* s)
00538 {
00539 storein_set(con, s);
00540 }
00541
00543 template <class T>
00544 void storein(std::multiset<T>& con, const char* s)
00545 {
00546 storein_set(con, s);
00547 }
00548
00559 template <class T>
00560 Query& update(const T& o, const T& n)
00561 {
00562 reset();
00563
00564
00565
00566
00567 dynamic_cast<std::ostream&>(*this) << "UPDATE " << o.table() <<
00568 " SET " << n.equal_list() << " WHERE " <<
00569 o.equal_list(" AND ", sql_use_compare);
00570 return *this;
00571 }
00572
00581 template <class T>
00582 Query& insert(const T& v)
00583 {
00584 reset();
00585
00586
00587 dynamic_cast<std::ostream&>(*this) << "INSERT INTO " <<
00588 v.table() << " (" << v.field_list() << ") VALUES (" <<
00589 v.value_list() << ")";
00590 return *this;
00591 }
00592
00606 template <class Iter>
00607 Query& insert(Iter first, Iter last)
00608 {
00609 reset();
00610 if (first == last) {
00611 return *this;
00612 }
00613
00614
00615 dynamic_cast<std::ostream&>(*this) << "INSERT INTO " <<
00616 first->table() << " (" << first->field_list() <<
00617 ") VALUES (" << first->value_list() << ')';
00618
00619 Iter it = first + 1;
00620 while (it != last) {
00621 *this << ",(" << it->value_list() << ')';
00622 ++it;
00623 }
00624
00625 return *this;
00626 }
00627
00637 template <class T>
00638 Query& replace(const T& v)
00639 {
00640 reset();
00641
00642
00643 dynamic_cast<std::ostream&>(*this) << "REPLACE INTO " <<
00644 v.table() << " (" << v.field_list() << ") VALUES (" <<
00645 v.value_list() << ")";
00646 return *this;
00647 }
00648
00650 operator bool() { return success(); }
00651
00653 bool operator !() { return !success(); }
00654
00655 #if !defined(DOXYGEN_IGNORE)
00656
00657
00658
00659
00660 mysql_query_define0(std::string, preview)
00661 mysql_query_define0(std::string, str);
00662 mysql_query_define1(ResNSel, execute)
00663 mysql_query_define1(Result, store)
00664 mysql_query_define1(ResUse, use)
00665 mysql_query_define2(storein_sequence)
00666 mysql_query_define2(storein_set)
00667 mysql_query_define2(storein)
00668 #endif
00669
00673 SQLQueryParms def;
00674
00675 private:
00676 friend class SQLQueryParms;
00677
00679 Connection* conn_;
00680
00682 bool success_;
00683
00685 std::vector<SQLParseElement> parse_elems_;
00686
00689 std::vector<std::string> parsed_names_;
00690
00692 std::map<std::string, short int> parsed_nums_;
00693
00695 std::stringbuf sbuffer_;
00696
00698 my_ulonglong affected_rows() const;
00699 my_ulonglong insert_id();
00700 std::string info();
00701 char* preview_char();
00702
00704 void proc(SQLQueryParms& p);
00705
00706
00707 bool lock();
00708 void unlock();
00709
00710 SQLString* pprepare(char option, SQLString& S, bool replace = true);
00711 };
00712
00713
00714 #if !defined(DOXYGEN_IGNORE)
00715
00716
00717 template <class Seq>
00718 void Query::storein_sequence(Seq& seq, SQLQueryParms& p, query_reset r)
00719 {
00720 r = parse_elems_.size() ? DONT_RESET : RESET_QUERY;
00721 storein_sequence(seq, str(p, r).c_str());
00722 }
00723
00724
00725 template <class Sequence>
00726 void Query::storein_sequence(Sequence& con, const char* s)
00727 {
00728 ResUse result = use(s);
00729 while (1) {
00730 MYSQL_ROW d = mysql_fetch_row(result.raw_result());
00731 if (!d)
00732 break;
00733 Row row(d, &result, mysql_fetch_lengths(result.raw_result()),
00734 true);
00735 if (!row)
00736 break;
00737 con.push_back(typename Sequence::value_type(row));
00738 }
00739 }
00740
00741
00742 template <class Set>
00743 void Query::storein_set(Set& sett, SQLQueryParms& p, query_reset r)
00744 {
00745 r = parse_elems_.size() ? DONT_RESET : RESET_QUERY;
00746 storein_set(sett, str(p, r).c_str());
00747 }
00748
00749
00750 template <class Set>
00751 void Query::storein_set(Set& con, const char* s)
00752 {
00753 ResUse result = use(s);
00754 while (1) {
00755 MYSQL_ROW d = mysql_fetch_row(result.raw_result());
00756 if (!d)
00757 return;
00758 Row row(d, &result, mysql_fetch_lengths(result.raw_result()),
00759 true);
00760 if (!row)
00761 break;
00762 con.insert(typename Set::value_type(row));
00763 }
00764 }
00765
00766
00767 template <class T>
00768 void Query::storein(T& con, SQLQueryParms& p, query_reset r)
00769 {
00770 r = parse_elems_.size() ? DONT_RESET : RESET_QUERY;
00771 storein(con, str(p, r).c_str());
00772 }
00773
00774
00775 #endif // !defined(DOXYGEN_IGNORE)
00776
00777 }
00778
00779 #endif
00780