00001 #ifndef MYSQLPP_SQL_QUERY_H
00002 #define MYSQLPP_SQL_QUERY_H
00003
00019
00020 #include "defs.h"
00021 #include "sql_string.h"
00022 #include "tiny_int.h"
00023
00024 #include <sstream>
00025 #include <vector>
00026 #include <map>
00027
00028 #define mysql_query_define0(RETURN, FUNC)\
00029 RETURN FUNC (ss a)\
00030 {return FUNC (parms() << a);}\
00031 RETURN FUNC (ss a, ss b)\
00032 {return FUNC (parms() << a << b);}\
00033 RETURN FUNC (ss a, ss b, ss c)\
00034 {return FUNC (parms() << a << b << c);}\
00035 RETURN FUNC (ss a, ss b, ss c, ss d)\
00036 {return FUNC (parms() << a << b << c << d);}\
00037 RETURN FUNC (ss a, ss b, ss c, ss d, ss e)\
00038 {return FUNC (parms() << a << b << c << d << e);} \
00039 RETURN FUNC (ss a, ss b, ss c, ss d, ss e, ss f)\
00040 {return FUNC (parms() << a << b << c << d << e << f);}\
00041 RETURN FUNC (ss a, ss b, ss c, ss d, ss e, ss f, ss g)\
00042 {return FUNC (parms() << a << b << c << d << e << f << g);}\
00043 RETURN FUNC (ss a, ss b, ss c, ss d, ss e, ss f, ss g, ss h)\
00044 {return FUNC (parms() << a << b << c << d << e << f << g << h);}\
00045 RETURN FUNC (ss a, ss b, ss c, ss d, ss e, ss f, ss g, ss h, ss i)\
00046 {return FUNC (parms() << a << b << c << d << e << f << g << h << i);}\
00047 RETURN FUNC (ss a,ss b,ss c,ss d,ss e,ss f,ss g,ss h,ss i,ss j)\
00048 {return FUNC (parms() <<a <<b <<c <<d <<e <<f <<g <<h <<i <<j);}\
00049 RETURN FUNC (ss a,ss b,ss c,ss d,ss e,ss f,ss g,ss h,ss i,ss j,ss k)\
00050 {return FUNC (parms() <<a <<b <<c <<d <<e <<f <<g <<h <<i <<j <<k);}\
00051 RETURN FUNC (ss a,ss b,ss c,ss d,ss e,ss f,ss g,ss h,ss i,ss j,ss k,\
00052 ss l)\
00053 {return FUNC (parms() <<a <<b <<c <<d <<e <<f <<g <<h <<i <<j <<k <<l);}\
00054
00055 namespace mysqlpp {
00056
00057 class Query;
00058 class SQLQuery;
00059
00060
00063 class SQLQueryParms : public std::vector<SQLString>
00064 {
00065 friend class Query;
00066
00067 private:
00068 typedef const SQLString & ss;
00069 SQLQuery *parent;
00070
00071 public:
00072 SQLQueryParms() :
00073 parent(NULL)
00074 {
00075 }
00076
00077 SQLQueryParms(SQLQuery * p) :
00078 parent(p)
00079 {
00080 }
00081
00082 bool bound()
00083 {
00084 return parent != 0;
00085 }
00086
00088 void clear()
00089 {
00090 erase(begin(), end());
00091 }
00092
00094 SQLString& operator [](size_type n)
00095 {
00096 if (n >= size())
00097 insert(end(), (n + 1) - size(), "");
00098 return std::vector<SQLString>::operator [](n);
00099 }
00100
00102 const SQLString& operator [](size_type n) const
00103 {
00104 return std::vector<SQLString>::operator [](n);
00105 }
00106
00108 SQLString& operator [](const char *str);
00109
00111 const SQLString& operator [](const char *str) const;
00112
00114 SQLQueryParms& operator <<(const SQLString& str)
00115 {
00116 push_back(str);
00117 return *this;
00118 }
00119
00121 SQLQueryParms& operator +=(const SQLString& str)
00122 {
00123 push_back(str);
00124 return *this;
00125 }
00126
00127 SQLQueryParms operator +(const SQLQueryParms& other) const;
00128
00133 void set(ss a)
00134 {
00135 clear();
00136 *this << a;
00137 }
00138 void set(ss a, ss b)
00139 {
00140 clear();
00141 *this << a << b;
00142 }
00143 void set(ss a, ss b, ss c)
00144 {
00145 clear();
00146 *this << a << b << c;
00147 }
00148 void set(ss a, ss b, ss c, ss d)
00149 {
00150 clear();
00151 *this << a << b << c << d;
00152 }
00153 void set(ss a, ss b, ss c, ss d, ss e)
00154 {
00155 clear();
00156 *this << a << b << c << d << e;
00157 }
00158 void set(ss a, ss b, ss c, ss d, ss e, ss f)
00159 {
00160 clear();
00161 *this << a << b << c << d << e << f;
00162 }
00163 void set(ss a, ss b, ss c, ss d, ss e, ss f, ss g)
00164 {
00165 clear();
00166 *this << a << b << c << d << e << f << g;
00167 }
00168 void set(ss a, ss b, ss c, ss d, ss e, ss f, ss g, ss h)
00169 {
00170 clear();
00171 *this << a << b << c << d << e << f << g << h;
00172 }
00173 void set(ss a, ss b, ss c, ss d, ss e, ss f, ss g, ss h, ss i)
00174 {
00175 clear();
00176 *this << a << b << c << d << e << f << g << h << i;
00177 }
00178 void set(ss a, ss b, ss c, ss d, ss e, ss f, ss g, ss h, ss i,
00179 ss j)
00180 {
00181 clear();
00182 *this << a << b << c << d << e << f << g << h << i << j;
00183 }
00184 void set(ss a, ss b, ss c, ss d, ss e, ss f, ss g, ss h, ss i,
00185 ss j, ss k)
00186 {
00187 clear();
00188 *this << a << b << c << d << e << f << g << h << i << j << k;
00189 }
00190 void set(ss a, ss b, ss c, ss d, ss e, ss f, ss g, ss h, ss i,
00191 ss j, ss k, ss l)
00192 {
00193 clear();
00194 *this << a << b << c << d << e << f << g << h << i << j << k << l;
00195 }
00196 };
00197
00198
00201 enum query_reset { DONT_RESET, RESET_QUERY };
00202
00203
00205 struct SQLParseElement {
00206 SQLParseElement(std::string b, char o, char n):before(b),
00207 option(o), num(n) {
00208 } std::string before;
00209 char option;
00210 char num;
00211 };
00212
00213
00234 class SQLQuery : public std::stringstream
00235 {
00236 friend class SQLQueryParms;
00237
00238 private:
00239 char *preview_char();
00240
00241 protected:
00242 bool Success;
00243 char *errmsg;
00244 std::vector < SQLParseElement > parsed;
00245 std::vector < std::string > parsed_names;
00246 std::map < std::string, int >parsed_nums;
00247 typedef const SQLString & ss;
00248 typedef SQLQueryParms parms;
00249
00251 void proc(SQLQueryParms & p);
00252
00253 public:
00254 SQLQuery() :
00255 std::stringstream(),
00256 Success(false),
00257 errmsg(0),
00258 def(this)
00259 {
00260 }
00261
00262 SQLQuery(const SQLQuery & q);
00263
00267 SQLQueryParms def;
00268
00269 void parse();
00270
00271 std::string error() const
00272 {
00273 return errmsg;
00274 }
00275
00276 bool success() const { return Success; }
00277 operator bool() { return success(); }
00278 bool operator !() { return !success(); }
00279
00284 void reset();
00285
00286 template <class T> SQLQuery& update(const T& o, const T& n)
00287 {
00288 reset();
00289
00290
00291
00292 dynamic_cast<std::stringstream&>(*this) << "UPDATE " <<
00293 o.table() << " SET " << n.equal_list() << " WHERE " <<
00294 o.equal_list(" AND ", sql_use_compare);
00295 return *this;
00296 }
00297
00298 template <class T> SQLQuery& insert(const T& v)
00299 {
00300 reset();
00301
00302 dynamic_cast<std::stringstream&>(*this) << "INSERT INTO " <<
00303 v.table() << " (" << v.field_list() << ") VALUES (" <<
00304 v.value_list() << ")";
00305 return *this;
00306 }
00307
00308 template <class Iter> SQLQuery& insert(Iter first, Iter last)
00309 {
00310 reset();
00311 if (first == last) {
00312 return *this;
00313 }
00314
00315
00316 dynamic_cast<std::stringstream&>(*this) << "INSERT INTO " <<
00317 first->table() << " (" << first->field_list() <<
00318 ") VALUES (" << first->value_list() << ')';
00319
00320 Iter it = first + 1;
00321 while (it != last) {
00322 dynamic_cast<std::stringstream&>(*this) << ",(" <<
00323 it->value_list() << ')';
00324 ++it;
00325 }
00326
00327 return *this;
00328 }
00329
00330 template <class T> SQLQuery& replace(const T& v)
00331 {
00332 reset();
00333
00334 dynamic_cast<std::stringstream&>(*this) << "REPLACE INTO " <<
00335 v.table() << " (" << v.field_list() << ") VALUES (" <<
00336 v.value_list() << ")";
00337 return *this;
00338 }
00339
00340 std::string str()
00341 {
00342 return str(def);
00343 }
00344 std::string str(query_reset r)
00345 {
00346 return str(def, r);
00347 }
00348 std::string str(SQLQueryParms& p);
00349 std::string str(SQLQueryParms& p, query_reset r);
00350
00351 mysql_query_define0(std::string, str);
00352 };
00353
00354
00355 inline SQLString& SQLQueryParms::operator [](const char *str)
00356 {
00357 if (parent) {
00358 return operator [](parent->parsed_nums[str]);
00359 }
00360 throw;
00361 }
00362
00363 inline const SQLString& SQLQueryParms::operator[] (const char *str) const
00364 {
00365 if (parent) {
00366 return operator [](parent->parsed_nums[str]);
00367 }
00368 throw;
00369 }
00370
00371 }
00372
00373 #endif
00374