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 <mysql.h>
00042
00043 #include <deque>
00044 #include <iomanip>
00045 #include <list>
00046 #include <map>
00047 #include <set>
00048 #include <sstream>
00049 #include <vector>
00050
00051 #ifdef HAVE_EXT_SLIST
00052 # include <ext/slist>
00053 #else
00054 # if defined(HAVE_STD_SLIST) || defined(HAVE_GLOBAL_SLIST)
00055 # include <slist>
00056 # endif
00057 #endif
00058
00059 namespace mysqlpp {
00060
00061 #if !defined(DOXYGEN_IGNORE)
00062
00063 class MYSQLPP_EXPORT Connection;
00064 #endif
00065
00067 enum query_reset { DONT_RESET, RESET_QUERY };
00068
00117
00118 class MYSQLPP_EXPORT Query : public std::ostream,
00119 public OptionalExceptions, public Lockable
00120 {
00121 public:
00128 Query(Connection* c, bool te = true);
00129
00137 Query(const Query& q);
00138
00143 Query& operator=(const Query& rhs);
00144
00150 std::string error();
00151
00157 bool success();
00158
00166 void parse();
00167
00172 void reset();
00173
00175 std::string preview() { return str(def); }
00176
00182 std::string preview(const SQLString& arg0)
00183 { return preview(SQLQueryParms() << arg0); }
00184
00186 std::string preview(SQLQueryParms& p) { return str(p); }
00187
00189 std::string str() { return str(def); }
00190
00196 std::string str(const SQLString& arg0)
00197 { return preview(SQLQueryParms() << arg0); }
00198
00203 std::string str(query_reset r) { return str(def, r); }
00204
00209 std::string str(SQLQueryParms& p);
00210
00217 std::string str(SQLQueryParms& p, query_reset r);
00218
00230 bool exec(const std::string& str);
00231
00248 ResNSel execute() { return execute(def); }
00249
00256 ResNSel execute(const SQLString& str);
00257
00261 ResNSel execute(const char* str);
00262
00267 ResNSel execute(const char* str, size_t len);
00268
00293 ResUse use() { return use(def); }
00294
00300 ResUse use(const SQLString& str);
00301
00307 ResUse use(const char* str);
00308
00314 ResUse use(const char* str, size_t len);
00315
00337 Result store() { return store(def); }
00338
00344 Result store(const SQLString& str);
00345
00351 Result store(const char* str);
00352
00358 Result store(const char* str, size_t len);
00359
00386 Result store_next();
00387
00399 bool more_results();
00400
00418 template <class Sequence>
00419 void storein_sequence(Sequence& con, query_reset r = RESET_QUERY)
00420 {
00421 storein_sequence_(con, def, r);
00422 }
00423
00431 template <class Set>
00432 void storein_set(Set& con, query_reset r = RESET_QUERY)
00433 {
00434 storein_set(con, def, r);
00435 }
00436
00455 template <class Container>
00456 void storein(Container& con, query_reset r = RESET_QUERY)
00457 {
00458 storein(con, def, r);
00459 }
00460
00462 template <class T>
00463 void storein(std::vector<T>& con, const char* s)
00464 {
00465 storein_sequence(con, s);
00466 }
00467
00469 template <class T>
00470 void storein(std::deque<T>& con, const char* s)
00471 {
00472 storein_sequence(con, s);
00473 }
00474
00476 template <class T>
00477 void storein(std::list<T>& con, const char* s)
00478 {
00479 storein_sequence(con, s);
00480 }
00481
00482 #if defined(HAVE_EXT_SLIST)
00485 template <class T>
00486 void storein(__gnu_cxx::slist<T>& con, const char* s)
00487 {
00488 storein_sequence(con, s);
00489 }
00490 #elif defined(HAVE_GLOBAL_SLIST)
00497 template <class T>
00498 void storein(slist<T>& con, const char* s)
00499 {
00500 storein_sequence(con, s);
00501 }
00502 #elif defined(HAVE_STD_SLIST)
00508 template <class T>
00509 void storein(std::slist<T>& con, const char* s)
00510 {
00511 storein_sequence(con, s);
00512 }
00513 #endif
00514
00516 template <class T>
00517 void storein(std::set<T>& con, const char* s)
00518 {
00519 storein_set(con, s);
00520 }
00521
00523 template <class T>
00524 void storein(std::multiset<T>& con, const char* s)
00525 {
00526 storein_set(con, s);
00527 }
00528
00539 template <class T>
00540 Query& update(const T& o, const T& n)
00541 {
00542 reset();
00543
00544
00545
00546
00547 dynamic_cast<std::ostream&>(*this) << std::setprecision(16) <<
00548 "UPDATE " << o.table() << " SET " << n.equal_list() <<
00549 " WHERE " << o.equal_list(" AND ", sql_use_compare);
00550 return *this;
00551 }
00552
00561 template <class T>
00562 Query& insert(const T& v)
00563 {
00564 reset();
00565
00566
00567 dynamic_cast<std::ostream&>(*this) << std::setprecision(16) <<
00568 "INSERT INTO " << v.table() << " (" <<
00569 v.field_list() << ") VALUES (" <<
00570 v.value_list() << ')';
00571 return *this;
00572 }
00573
00587 template <class Iter>
00588 Query& insert(Iter first, Iter last)
00589 {
00590 reset();
00591 if (first == last) {
00592 return *this;
00593 }
00594
00595
00596 dynamic_cast<std::ostream&>(*this) << std::setprecision(16) <<
00597 "INSERT INTO " << first->table() << " (" <<
00598 first->field_list() << ") VALUES (" <<
00599 first->value_list() << ')';
00600
00601 Iter it = first + 1;
00602 while (it != last) {
00603 dynamic_cast<std::ostream&>(*this) << ",(" <<
00604 it->value_list() << ')';
00605 ++it;
00606 }
00607
00608 return *this;
00609 }
00610
00620 template <class T>
00621 Query& replace(const T& v)
00622 {
00623 reset();
00624
00625
00626 dynamic_cast<std::ostream&>(*this) << std::setprecision(16) <<
00627 "REPLACE INTO " << v.table() << " (" <<
00628 v.field_list() << ") VALUES (" << v.value_list() << ')';
00629 return *this;
00630 }
00631
00633 operator bool() { return success(); }
00634
00636 bool operator !() { return !success(); }
00637
00638 #if !defined(DOXYGEN_IGNORE)
00639
00640
00641
00642
00643 mysql_query_define0(std::string, preview)
00644 mysql_query_define0(std::string, str)
00645 mysql_query_define1(ResNSel, execute)
00646 mysql_query_define1(Result, store)
00647 mysql_query_define1(ResUse, use)
00648 mysql_query_define2(storein_sequence)
00649 mysql_query_define2(storein_set)
00650 mysql_query_define2(storein)
00651 #endif // !defined(DOXYGEN_IGNORE)
00652
00656 SQLQueryParms def;
00657
00658 private:
00659 friend class SQLQueryParms;
00660
00662 Connection* conn_;
00663
00665 bool success_;
00666
00668 std::vector<SQLParseElement> parse_elems_;
00669
00672 std::vector<std::string> parsed_names_;
00673
00675 std::map<std::string, short int> parsed_nums_;
00676
00678 std::stringbuf sbuffer_;
00679
00681 my_ulonglong affected_rows() const;
00682 my_ulonglong insert_id();
00683 std::string info();
00684 char* preview_char();
00685
00687 void proc(SQLQueryParms& p);
00688
00689
00690 bool lock();
00691 void unlock();
00692
00693 SQLString* pprepare(char option, SQLString& S, bool replace = true);
00694 };
00695
00696
00697 #if !defined(DOXYGEN_IGNORE)
00698
00699
00700 template <class Seq>
00701 void Query::storein_sequence(Seq& seq, SQLQueryParms& p, query_reset r)
00702 {
00703 r = parse_elems_.size() ? DONT_RESET : RESET_QUERY;
00704 storein_sequence(seq, str(p, r).c_str());
00705 }
00706
00707
00708 template <class Sequence>
00709 void Query::storein_sequence(Sequence& con, const char* s)
00710 {
00711 ResUse result = use(s);
00712 while (1) {
00713 MYSQL_ROW d = mysql_fetch_row(result.raw_result());
00714 if (!d)
00715 break;
00716 Row row(d, &result, mysql_fetch_lengths(result.raw_result()),
00717 true);
00718 if (!row)
00719 break;
00720 con.push_back(typename Sequence::value_type(row));
00721 }
00722 }
00723
00724
00725 template <class Set>
00726 void Query::storein_set(Set& sett, SQLQueryParms& p, query_reset r)
00727 {
00728 r = parse_elems_.size() ? DONT_RESET : RESET_QUERY;
00729 storein_set(sett, str(p, r).c_str());
00730 }
00731
00732
00733 template <class Set>
00734 void Query::storein_set(Set& con, const char* s)
00735 {
00736 ResUse result = use(s);
00737 while (1) {
00738 MYSQL_ROW d = mysql_fetch_row(result.raw_result());
00739 if (!d)
00740 return;
00741 Row row(d, &result, mysql_fetch_lengths(result.raw_result()),
00742 true);
00743 if (!row)
00744 break;
00745 con.insert(typename Set::value_type(row));
00746 }
00747 }
00748
00749
00750 template <class T>
00751 void Query::storein(T& con, SQLQueryParms& p, query_reset r)
00752 {
00753 r = parse_elems_.size() ? DONT_RESET : RESET_QUERY;
00754 storein(con, str(p, r).c_str());
00755 }
00756
00757
00758 #endif // !defined(DOXYGEN_IGNORE)
00759
00760 }
00761
00762 #endif
00763