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 "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 class Connection;
00062
00064 enum query_reset { DONT_RESET, RESET_QUERY };
00065
00114
00115 class Query : public std::ostream,
00116 public OptionalExceptions, public Lockable
00117 {
00118 public:
00125 Query(Connection* c, bool te = true) :
00126 std::ostream(0),
00127 OptionalExceptions(te),
00128 Lockable(false),
00129 def(this),
00130 conn_(c),
00131 success_(false)
00132 {
00133 init(&sbuffer_);
00134 success_ = true;
00135 }
00136
00144 MYSQLPP_EXPORT Query(const Query& q);
00145
00150 MYSQLPP_EXPORT Query& operator=(const Query& rhs);
00151
00157 MYSQLPP_EXPORT std::string error();
00158
00164 MYSQLPP_EXPORT bool success();
00165
00173 MYSQLPP_EXPORT void parse();
00174
00179 MYSQLPP_EXPORT void reset();
00180
00182 std::string preview() { return str(def); }
00183
00185 std::string preview(SQLQueryParms& p)
00186 {
00187 return str(p);
00188 }
00189
00191 std::string str()
00192 {
00193 return str(def);
00194 }
00195
00200 std::string str(query_reset r)
00201 {
00202 return str(def, r);
00203 }
00204
00209 MYSQLPP_EXPORT std::string str(SQLQueryParms& p);
00210
00217 MYSQLPP_EXPORT std::string str(SQLQueryParms& p, query_reset r);
00218
00230 MYSQLPP_EXPORT bool exec(const std::string& str);
00231
00248 ResNSel execute() { return execute(def); }
00249
00253 MYSQLPP_EXPORT ResNSel execute(const char* str);
00254
00279 ResUse use() { return use(def); }
00280
00286 MYSQLPP_EXPORT ResUse use(const char* str);
00287
00309 Result store() { return store(def); }
00310
00316 MYSQLPP_EXPORT Result store(const char* str);
00317
00344 MYSQLPP_EXPORT Result store_next();
00345
00357 MYSQLPP_EXPORT bool more_results();
00358
00376 template <class Sequence>
00377 void storein_sequence(Sequence& con, query_reset r = RESET_QUERY)
00378 {
00379 storein_sequence_(con, def, r);
00380 }
00381
00389 template <class Set>
00390 void storein_set(Set& con, query_reset r = RESET_QUERY)
00391 {
00392 storein_set(con, def, r);
00393 }
00394
00413 template <class Container>
00414 void storein(Container& con, query_reset r = RESET_QUERY)
00415 {
00416 storein(con, def, r);
00417 }
00418
00420 template <class T>
00421 void storein(std::vector<T>& con, const char* s)
00422 {
00423 storein_sequence(con, s);
00424 }
00425
00427 template <class T>
00428 void storein(std::deque<T>& con, const char* s)
00429 {
00430 storein_sequence(con, s);
00431 }
00432
00434 template <class T>
00435 void storein(std::list<T>& con, const char* s)
00436 {
00437 storein_sequence(con, s);
00438 }
00439
00440 #if defined(HAVE_EXT_SLIST)
00443 template <class T>
00444 void storein(__gnu_cxx::slist<T>& con, const char* s)
00445 {
00446 storein_sequence(con, s);
00447 }
00448 #elif defined(HAVE_GLOBAL_SLIST)
00455 template <class T>
00456 void storein(slist<T>& con, const char* s)
00457 {
00458 storein_sequence(con, s);
00459 }
00460 #elif defined(HAVE_STD_SLIST)
00466 template <class T>
00467 void storein(std::slist<T>& con, const char* s)
00468 {
00469 storein_sequence(con, s);
00470 }
00471 #endif
00472
00474 template <class T>
00475 void storein(std::set<T>& con, const char* s)
00476 {
00477 storein_set(con, s);
00478 }
00479
00481 template <class T>
00482 void storein(std::multiset<T>& con, const char* s)
00483 {
00484 storein_set(con, s);
00485 }
00486
00497 template <class T>
00498 Query& update(const T& o, const T& n)
00499 {
00500 reset();
00501
00502
00503
00504
00505 dynamic_cast<std::ostream&>(*this) << std::setprecision(16) <<
00506 "UPDATE " << o.table() << " SET " << n.equal_list() <<
00507 " WHERE " << o.equal_list(" AND ", sql_use_compare);
00508 return *this;
00509 }
00510
00519 template <class T>
00520 Query& insert(const T& v)
00521 {
00522 reset();
00523
00524
00525 dynamic_cast<std::ostream&>(*this) << std::setprecision(16) <<
00526 "INSERT INTO " << v.table() << " (" <<
00527 v.field_list() << ") VALUES (" <<
00528 v.value_list() << ')';
00529 return *this;
00530 }
00531
00545 template <class Iter>
00546 Query& insert(Iter first, Iter last)
00547 {
00548 reset();
00549 if (first == last) {
00550 return *this;
00551 }
00552
00553
00554 dynamic_cast<std::ostream&>(*this) << std::setprecision(16) <<
00555 "INSERT INTO " << first->table() << " (" <<
00556 first->field_list() << ") VALUES (" <<
00557 first->value_list() << ')';
00558
00559 Iter it = first + 1;
00560 while (it != last) {
00561 dynamic_cast<std::ostream&>(*this) << ",(" <<
00562 it->value_list() << ')';
00563 ++it;
00564 }
00565
00566 return *this;
00567 }
00568
00578 template <class T>
00579 Query& replace(const T& v)
00580 {
00581 reset();
00582
00583
00584 dynamic_cast<std::ostream&>(*this) << std::setprecision(16) <<
00585 "REPLACE INTO " << v.table() << " (" <<
00586 v.field_list() << ") VALUES (" << v.value_list() << ')';
00587 return *this;
00588 }
00589
00591 operator bool() { return success(); }
00592
00594 bool operator !() { return !success(); }
00595
00596 #if !defined(DOXYGEN_IGNORE)
00597
00598
00599
00600
00601 mysql_query_define0(std::string, preview)
00602 mysql_query_define0(std::string, str);
00603 mysql_query_define1(ResNSel, execute)
00604 mysql_query_define1(Result, store)
00605 mysql_query_define1(ResUse, use)
00606 mysql_query_define2(storein_sequence)
00607 mysql_query_define2(storein_set)
00608 mysql_query_define2(storein)
00609 #endif
00610
00614 SQLQueryParms def;
00615
00616 private:
00617 friend class SQLQueryParms;
00618
00620 Connection* conn_;
00621
00623 bool success_;
00624
00626 std::vector<SQLParseElement> parse_elems_;
00627
00630 std::vector<std::string> parsed_names_;
00631
00633 std::map<std::string, short int> parsed_nums_;
00634
00636 std::stringbuf sbuffer_;
00637
00639 my_ulonglong affected_rows() const;
00640 my_ulonglong insert_id();
00641 std::string info();
00642 char* preview_char();
00643
00645 void proc(SQLQueryParms& p);
00646
00647
00648 bool lock();
00649 void unlock();
00650
00651 SQLString* pprepare(char option, SQLString& S, bool replace = true);
00652 };
00653
00654
00655 #if !defined(DOXYGEN_IGNORE)
00656
00657
00658 template <class Seq>
00659 void Query::storein_sequence(Seq& seq, SQLQueryParms& p, query_reset r)
00660 {
00661 r = parse_elems_.size() ? DONT_RESET : RESET_QUERY;
00662 storein_sequence(seq, str(p, r).c_str());
00663 }
00664
00665
00666 template <class Sequence>
00667 void Query::storein_sequence(Sequence& con, const char* s)
00668 {
00669 ResUse result = use(s);
00670 while (1) {
00671 MYSQL_ROW d = mysql_fetch_row(result.raw_result());
00672 if (!d)
00673 break;
00674 Row row(d, &result, mysql_fetch_lengths(result.raw_result()),
00675 true);
00676 if (!row)
00677 break;
00678 con.push_back(typename Sequence::value_type(row));
00679 }
00680 }
00681
00682
00683 template <class Set>
00684 void Query::storein_set(Set& sett, SQLQueryParms& p, query_reset r)
00685 {
00686 r = parse_elems_.size() ? DONT_RESET : RESET_QUERY;
00687 storein_set(sett, str(p, r).c_str());
00688 }
00689
00690
00691 template <class Set>
00692 void Query::storein_set(Set& con, const char* s)
00693 {
00694 ResUse result = use(s);
00695 while (1) {
00696 MYSQL_ROW d = mysql_fetch_row(result.raw_result());
00697 if (!d)
00698 return;
00699 Row row(d, &result, mysql_fetch_lengths(result.raw_result()),
00700 true);
00701 if (!row)
00702 break;
00703 con.insert(typename Set::value_type(row));
00704 }
00705 }
00706
00707
00708 template <class T>
00709 void Query::storein(T& con, SQLQueryParms& p, query_reset r)
00710 {
00711 r = parse_elems_.size() ? DONT_RESET : RESET_QUERY;
00712 storein(con, str(p, r).c_str());
00713 }
00714
00715
00716 #endif // !defined(DOXYGEN_IGNORE)
00717
00718 }
00719
00720 #endif
00721