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(0),
00190 OptionalExceptions(te),
00191 Lockable(false),
00192 def(this),
00193 conn_(c),
00194 success_(false)
00195 {
00196 init(&sbuffer_);
00197 success_ = true;
00198 }
00199
00207 MYSQLPP_EXPORT Query(const Query& q);
00208
00213 MYSQLPP_EXPORT Query& operator=(const Query& rhs);
00214
00220 MYSQLPP_EXPORT std::string error();
00221
00227 MYSQLPP_EXPORT bool success();
00228
00236 MYSQLPP_EXPORT void parse();
00237
00242 MYSQLPP_EXPORT void reset();
00243
00245 std::string preview() { return str(def); }
00246
00248 std::string preview(SQLQueryParms& p)
00249 {
00250 return str(p);
00251 }
00252
00254 std::string str()
00255 {
00256 return str(def);
00257 }
00258
00263 std::string str(query_reset r)
00264 {
00265 return str(def, r);
00266 }
00267
00272 MYSQLPP_EXPORT std::string str(SQLQueryParms& p);
00273
00280 MYSQLPP_EXPORT std::string str(SQLQueryParms& p, query_reset r);
00281
00293 MYSQLPP_EXPORT bool exec(const std::string& str);
00294
00311 ResNSel execute() { return execute(def); }
00312
00316 MYSQLPP_EXPORT ResNSel execute(const char* str);
00317
00342 ResUse use() { return use(def); }
00343
00349 MYSQLPP_EXPORT ResUse use(const char* str);
00350
00372 Result store() { return store(def); }
00373
00379 MYSQLPP_EXPORT Result store(const char* str);
00380
00407 MYSQLPP_EXPORT Result store_next();
00408
00420 MYSQLPP_EXPORT bool more_results();
00421
00439 template <class Sequence>
00440 void storein_sequence(Sequence& con, query_reset r = RESET_QUERY)
00441 {
00442 storein_sequence_(con, def, r);
00443 }
00444
00452 template <class Set>
00453 void storein_set(Set& con, query_reset r = RESET_QUERY)
00454 {
00455 storein_set(con, def, r);
00456 }
00457
00476 template <class Container>
00477 void storein(Container& con, query_reset r = RESET_QUERY)
00478 {
00479 storein(con, def, r);
00480 }
00481
00483 template <class T>
00484 void storein(std::vector<T>& con, const char* s)
00485 {
00486 storein_sequence(con, s);
00487 }
00488
00490 template <class T>
00491 void storein(std::deque<T>& con, const char* s)
00492 {
00493 storein_sequence(con, s);
00494 }
00495
00497 template <class T>
00498 void storein(std::list<T>& con, const char* s)
00499 {
00500 storein_sequence(con, s);
00501 }
00502
00503 #if defined(HAVE_EXT_SLIST)
00506 template <class T>
00507 void storein(__gnu_cxx::slist<T>& con, const char* s)
00508 {
00509 storein_sequence(con, s);
00510 }
00511 #elif defined(HAVE_GLOBAL_SLIST)
00518 template <class T>
00519 void storein(slist<T>& con, const char* s)
00520 {
00521 storein_sequence(con, s);
00522 }
00523 #elif defined(HAVE_STD_SLIST)
00529 template <class T>
00530 void storein(std::slist<T>& con, const char* s)
00531 {
00532 storein_sequence(con, s);
00533 }
00534 #endif
00535
00537 template <class T>
00538 void storein(std::set<T>& con, const char* s)
00539 {
00540 storein_set(con, s);
00541 }
00542
00544 template <class T>
00545 void storein(std::multiset<T>& con, const char* s)
00546 {
00547 storein_set(con, s);
00548 }
00549
00560 template <class T>
00561 Query& update(const T& o, const T& n)
00562 {
00563 reset();
00564
00565
00566
00567
00568 dynamic_cast<std::ostream&>(*this) << "UPDATE " << o.table() <<
00569 " SET " << n.equal_list() << " WHERE " <<
00570 o.equal_list(" AND ", sql_use_compare);
00571 return *this;
00572 }
00573
00582 template <class T>
00583 Query& insert(const T& v)
00584 {
00585 reset();
00586
00587
00588 dynamic_cast<std::ostream&>(*this) << "INSERT INTO " <<
00589 v.table() << " (" << v.field_list() << ") VALUES (" <<
00590 v.value_list() << ")";
00591 return *this;
00592 }
00593
00607 template <class Iter>
00608 Query& insert(Iter first, Iter last)
00609 {
00610 reset();
00611 if (first == last) {
00612 return *this;
00613 }
00614
00615
00616 dynamic_cast<std::ostream&>(*this) << "INSERT INTO " <<
00617 first->table() << " (" << first->field_list() <<
00618 ") VALUES (" << first->value_list() << ')';
00619
00620 Iter it = first + 1;
00621 while (it != last) {
00622 dynamic_cast<std::ostream&>(*this) << ",(" <<
00623 it->value_list() << ')';
00624 ++it;
00625 }
00626
00627 return *this;
00628 }
00629
00639 template <class T>
00640 Query& replace(const T& v)
00641 {
00642 reset();
00643
00644
00645 dynamic_cast<std::ostream&>(*this) << "REPLACE INTO " <<
00646 v.table() << " (" << v.field_list() << ") VALUES (" <<
00647 v.value_list() << ")";
00648 return *this;
00649 }
00650
00652 operator bool() { return success(); }
00653
00655 bool operator !() { return !success(); }
00656
00657 #if !defined(DOXYGEN_IGNORE)
00658
00659
00660
00661
00662 mysql_query_define0(std::string, preview)
00663 mysql_query_define0(std::string, str);
00664 mysql_query_define1(ResNSel, execute)
00665 mysql_query_define1(Result, store)
00666 mysql_query_define1(ResUse, use)
00667 mysql_query_define2(storein_sequence)
00668 mysql_query_define2(storein_set)
00669 mysql_query_define2(storein)
00670 #endif
00671
00675 SQLQueryParms def;
00676
00677 private:
00678 friend class SQLQueryParms;
00679
00681 Connection* conn_;
00682
00684 bool success_;
00685
00687 std::vector<SQLParseElement> parse_elems_;
00688
00691 std::vector<std::string> parsed_names_;
00692
00694 std::map<std::string, short int> parsed_nums_;
00695
00697 std::stringbuf sbuffer_;
00698
00700 my_ulonglong affected_rows() const;
00701 my_ulonglong insert_id();
00702 std::string info();
00703 char* preview_char();
00704
00706 void proc(SQLQueryParms& p);
00707
00708
00709 bool lock();
00710 void unlock();
00711
00712 SQLString* pprepare(char option, SQLString& S, bool replace = true);
00713 };
00714
00715
00716 #if !defined(DOXYGEN_IGNORE)
00717
00718
00719 template <class Seq>
00720 void Query::storein_sequence(Seq& seq, SQLQueryParms& p, query_reset r)
00721 {
00722 r = parse_elems_.size() ? DONT_RESET : RESET_QUERY;
00723 storein_sequence(seq, str(p, r).c_str());
00724 }
00725
00726
00727 template <class Sequence>
00728 void Query::storein_sequence(Sequence& con, const char* s)
00729 {
00730 ResUse result = use(s);
00731 while (1) {
00732 MYSQL_ROW d = mysql_fetch_row(result.raw_result());
00733 if (!d)
00734 break;
00735 Row row(d, &result, mysql_fetch_lengths(result.raw_result()),
00736 true);
00737 if (!row)
00738 break;
00739 con.push_back(typename Sequence::value_type(row));
00740 }
00741 }
00742
00743
00744 template <class Set>
00745 void Query::storein_set(Set& sett, SQLQueryParms& p, query_reset r)
00746 {
00747 r = parse_elems_.size() ? DONT_RESET : RESET_QUERY;
00748 storein_set(sett, str(p, r).c_str());
00749 }
00750
00751
00752 template <class Set>
00753 void Query::storein_set(Set& con, const char* s)
00754 {
00755 ResUse result = use(s);
00756 while (1) {
00757 MYSQL_ROW d = mysql_fetch_row(result.raw_result());
00758 if (!d)
00759 return;
00760 Row row(d, &result, mysql_fetch_lengths(result.raw_result()),
00761 true);
00762 if (!row)
00763 break;
00764 con.insert(typename Set::value_type(row));
00765 }
00766 }
00767
00768
00769 template <class T>
00770 void Query::storein(T& con, SQLQueryParms& p, query_reset r)
00771 {
00772 r = parse_elems_.size() ? DONT_RESET : RESET_QUERY;
00773 storein(con, str(p, r).c_str());
00774 }
00775
00776
00777 #endif // !defined(DOXYGEN_IGNORE)
00778
00779 }
00780
00781 #endif
00782