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
00066 #if defined(_MSC_VER) && (_MSC_VER < 1400)
00067 # define MYSQLPP_QUERY_THISPTR dynamic_cast<std::ostream&>(*this)
00068 #else
00069 # define MYSQLPP_QUERY_THISPTR *this
00070 #endif
00071
00072 namespace mysqlpp {
00073
00074 #if !defined(DOXYGEN_IGNORE)
00075
00076 class MYSQLPP_EXPORT Connection;
00077 #endif
00078
00080 enum query_reset { DONT_RESET, RESET_QUERY };
00081
00130
00131 class MYSQLPP_EXPORT Query : public std::ostream,
00132 public OptionalExceptions, public Lockable
00133 {
00134 public:
00141 Query(Connection* c, bool te = true);
00142
00150 Query(const Query& q);
00151
00156 Query& operator=(const Query& rhs);
00157
00163 std::string error();
00164
00170 bool success();
00171
00179 void parse();
00180
00185 void reset();
00186
00188 std::string preview() { return str(def); }
00189
00195 std::string preview(const SQLString& arg0)
00196 { return preview(SQLQueryParms() << arg0); }
00197
00199 std::string preview(SQLQueryParms& p) { return str(p); }
00200
00202 std::string str() { return str(def); }
00203
00209 std::string str(const SQLString& arg0)
00210 { return preview(SQLQueryParms() << arg0); }
00211
00216 std::string str(query_reset r) { return str(def, r); }
00217
00222 std::string str(SQLQueryParms& p);
00223
00230 std::string str(SQLQueryParms& p, query_reset r);
00231
00243 bool exec(const std::string& str);
00244
00261 ResNSel execute() { return execute(def); }
00262
00269 ResNSel execute(const SQLString& str);
00270
00274 ResNSel execute(const char* str);
00275
00280 ResNSel execute(const char* str, size_t len);
00281
00306 ResUse use() { return use(def); }
00307
00313 ResUse use(const SQLString& str);
00314
00320 ResUse use(const char* str);
00321
00327 ResUse use(const char* str, size_t len);
00328
00350 Result store() { return store(def); }
00351
00357 Result store(const SQLString& str);
00358
00364 Result store(const char* str);
00365
00371 Result store(const char* str, size_t len);
00372
00399 Result store_next();
00400
00412 bool more_results();
00413
00431 template <class Sequence>
00432 void storein_sequence(Sequence& con, query_reset r = RESET_QUERY)
00433 {
00434 storein_sequence_(con, def, r);
00435 }
00436
00444 template <class Set>
00445 void storein_set(Set& con, query_reset r = RESET_QUERY)
00446 {
00447 storein_set(con, def, r);
00448 }
00449
00468 template <class Container>
00469 void storein(Container& con, query_reset r = RESET_QUERY)
00470 {
00471 storein(con, def, r);
00472 }
00473
00475 template <class T>
00476 void storein(std::vector<T>& con, const char* s)
00477 {
00478 storein_sequence(con, s);
00479 }
00480
00482 template <class T>
00483 void storein(std::deque<T>& con, const char* s)
00484 {
00485 storein_sequence(con, s);
00486 }
00487
00489 template <class T>
00490 void storein(std::list<T>& con, const char* s)
00491 {
00492 storein_sequence(con, s);
00493 }
00494
00495 #if defined(HAVE_EXT_SLIST)
00498 template <class T>
00499 void storein(__gnu_cxx::slist<T>& con, const char* s)
00500 {
00501 storein_sequence(con, s);
00502 }
00503 #elif defined(HAVE_GLOBAL_SLIST)
00510 template <class T>
00511 void storein(slist<T>& con, const char* s)
00512 {
00513 storein_sequence(con, s);
00514 }
00515 #elif defined(HAVE_STD_SLIST)
00521 template <class T>
00522 void storein(std::slist<T>& con, const char* s)
00523 {
00524 storein_sequence(con, s);
00525 }
00526 #endif
00527
00529 template <class T>
00530 void storein(std::set<T>& con, const char* s)
00531 {
00532 storein_set(con, s);
00533 }
00534
00536 template <class T>
00537 void storein(std::multiset<T>& con, const char* s)
00538 {
00539 storein_set(con, s);
00540 }
00541
00552 template <class T>
00553 Query& update(const T& o, const T& n)
00554 {
00555 reset();
00556
00557
00558
00559
00560 MYSQLPP_QUERY_THISPTR << std::setprecision(16) <<
00561 "UPDATE " << o.table() << " SET " << n.equal_list() <<
00562 " WHERE " << o.equal_list(" AND ", sql_use_compare);
00563 return *this;
00564 }
00565
00574 template <class T>
00575 Query& insert(const T& v)
00576 {
00577 reset();
00578
00579 MYSQLPP_QUERY_THISPTR << std::setprecision(16) <<
00580 "INSERT INTO " << v.table() << " (" <<
00581 v.field_list() << ") VALUES (" <<
00582 v.value_list() << ')';
00583 return *this;
00584 }
00585
00599 template <class Iter>
00600 Query& insert(Iter first, Iter last)
00601 {
00602 reset();
00603 if (first == last) {
00604 return *this;
00605 }
00606
00607 MYSQLPP_QUERY_THISPTR << std::setprecision(16) <<
00608 "INSERT INTO " << first->table() << " (" <<
00609 first->field_list() << ") VALUES (" <<
00610 first->value_list() << ')';
00611
00612 Iter it = first + 1;
00613 while (it != last) {
00614 MYSQLPP_QUERY_THISPTR << ",(" << it->value_list() << ')';
00615 ++it;
00616 }
00617
00618 return *this;
00619 }
00620
00630 template <class T>
00631 Query& replace(const T& v)
00632 {
00633 reset();
00634
00635 MYSQLPP_QUERY_THISPTR << std::setprecision(16) <<
00636 "REPLACE INTO " << v.table() << " (" <<
00637 v.field_list() << ") VALUES (" << v.value_list() << ')';
00638 return *this;
00639 }
00640
00642 operator bool() { return success(); }
00643
00645 bool operator !() { return !success(); }
00646
00647 #if !defined(DOXYGEN_IGNORE)
00648
00649
00650
00651
00652 mysql_query_define0(std::string, preview)
00653 mysql_query_define0(std::string, str)
00654 mysql_query_define1(ResNSel, execute)
00655 mysql_query_define1(Result, store)
00656 mysql_query_define1(ResUse, use)
00657 mysql_query_define2(storein_sequence)
00658 mysql_query_define2(storein_set)
00659 mysql_query_define2(storein)
00660 #endif
00661
00665 SQLQueryParms def;
00666
00667 private:
00668 friend class SQLQueryParms;
00669
00671 Connection* conn_;
00672
00674 bool success_;
00675
00677 std::vector<SQLParseElement> parse_elems_;
00678
00681 std::vector<std::string> parsed_names_;
00682
00684 std::map<std::string, short int> parsed_nums_;
00685
00687 std::stringbuf sbuffer_;
00688
00690 my_ulonglong affected_rows() const;
00691 my_ulonglong insert_id();
00692 std::string info();
00693 char* preview_char();
00694
00696 void proc(SQLQueryParms& p);
00697
00698
00699 bool lock();
00700 void unlock();
00701
00702 SQLString* pprepare(char option, SQLString& S, bool replace = true);
00703 };
00704
00705
00706 #if !defined(DOXYGEN_IGNORE)
00707
00708
00709 template <class Seq>
00710 void Query::storein_sequence(Seq& seq, SQLQueryParms& p, query_reset r)
00711 {
00712 r = parse_elems_.size() ? DONT_RESET : RESET_QUERY;
00713 storein_sequence(seq, str(p, r).c_str());
00714 }
00715
00716
00717 template <class Sequence>
00718 void Query::storein_sequence(Sequence& con, const char* s)
00719 {
00720 ResUse result = use(s);
00721 while (1) {
00722 MYSQL_ROW d = mysql_fetch_row(result.raw_result());
00723 if (!d)
00724 break;
00725 Row row(d, &result, mysql_fetch_lengths(result.raw_result()),
00726 true);
00727 if (!row)
00728 break;
00729 con.push_back(typename Sequence::value_type(row));
00730 }
00731 }
00732
00733
00734 template <class Set>
00735 void Query::storein_set(Set& sett, SQLQueryParms& p, query_reset r)
00736 {
00737 r = parse_elems_.size() ? DONT_RESET : RESET_QUERY;
00738 storein_set(sett, str(p, r).c_str());
00739 }
00740
00741
00742 template <class Set>
00743 void Query::storein_set(Set& con, const char* s)
00744 {
00745 ResUse result = use(s);
00746 while (1) {
00747 MYSQL_ROW d = mysql_fetch_row(result.raw_result());
00748 if (!d)
00749 return;
00750 Row row(d, &result, mysql_fetch_lengths(result.raw_result()),
00751 true);
00752 if (!row)
00753 break;
00754 con.insert(typename Set::value_type(row));
00755 }
00756 }
00757
00758
00759 template <class T>
00760 void Query::storein(T& con, SQLQueryParms& p, query_reset r)
00761 {
00762 r = parse_elems_.size() ? DONT_RESET : RESET_QUERY;
00763 storein(con, str(p, r).c_str());
00764 }
00765
00766
00767 #endif // !defined(DOXYGEN_IGNORE)
00768
00769 }
00770
00771 #endif
00772