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
00029
00030
00031
00032 #ifndef MYSQLPP_COLDATA_H
00033 #define MYSQLPP_COLDATA_H
00034
00035 #include "common.h"
00036
00037 #include "const_string.h"
00038 #include "convert.h"
00039 #include "exceptions.h"
00040 #include "null.h"
00041 #include "string_util.h"
00042 #include "type_info.h"
00043
00044 #include <mysql.h>
00045
00046 #include <typeinfo>
00047 #include <string>
00048 #include <sstream>
00049
00050 #include <stdlib.h>
00051
00052 namespace mysqlpp {
00053
00084
00085 template <class Str>
00086 class MYSQLPP_EXPORT ColData_Tmpl : public Str
00087 {
00088 public:
00096 ColData_Tmpl() :
00097 null_(false)
00098 {
00099 }
00100
00106 explicit ColData_Tmpl(bool n,
00107 mysql_type_info t = mysql_type_info::string_type) :
00108 type_(t),
00109 null_(n)
00110 {
00111 }
00112
00118 explicit ColData_Tmpl(const char* str,
00119 mysql_type_info t = mysql_type_info::string_type,
00120 bool n = false) :
00121 Str(str),
00122 type_(t),
00123 buf_(str),
00124 null_(n)
00125 {
00126 }
00127
00134 explicit ColData_Tmpl(const char* str, typename Str::size_type len,
00135 mysql_type_info t = mysql_type_info::string_type,
00136 bool n = false) :
00137 Str(str, len),
00138 type_(t),
00139 buf_(str),
00140 null_(n)
00141 {
00142 }
00143
00145 mysql_type_info type() const { return type_; }
00146
00149 bool quote_q() const { return type_.quote_q(); }
00150
00153 bool escape_q() const { return type_.escape_q(); }
00154
00156 template <class Type> Type conv(Type dummy) const;
00157
00159 void it_is_null() { null_ = true; }
00160
00162 inline const bool is_null() const { return null_; }
00163
00165 inline const std::string& get_string() const { return buf_; }
00166
00169 operator cchar*() const { return buf_.c_str(); }
00170
00172 operator signed char() const
00173 { return conv(static_cast<signed char>(0)); }
00174
00176 operator unsigned char() const
00177 { return conv(static_cast<unsigned char>(0)); }
00178
00180 operator int() const
00181 { return conv(static_cast<int>(0)); }
00182
00184 operator unsigned int() const
00185 { return conv(static_cast<unsigned int>(0)); }
00186
00188 operator short int() const
00189 { return conv(static_cast<short int>(0)); }
00190
00193 operator unsigned short int() const
00194 { return conv(static_cast<unsigned short int>(0)); }
00195
00197 operator long int() const
00198 { return conv(static_cast<long int>(0)); }
00199
00202 operator unsigned long int() const
00203 { return conv(static_cast<unsigned long int>(0)); }
00204
00205 #if !defined(NO_LONG_LONGS)
00208 operator longlong() const
00209 { return conv(static_cast<longlong>(0)); }
00210
00213 operator ulonglong() const
00214 { return conv(static_cast<ulonglong>(0)); }
00215 #endif
00216
00218 operator float() const
00219 { return conv(static_cast<float>(0)); }
00220
00222 operator double() const
00223 { return conv(static_cast<double>(0)); }
00224
00226 operator bool() const { return conv(0); }
00227
00228 template <class T, class B> operator Null<T, B>() const;
00229
00230 private:
00231 mysql_type_info type_;
00232 std::string buf_;
00233 bool null_;
00234 };
00235
00238 typedef ColData_Tmpl<const_string> ColData;
00239
00242 typedef ColData_Tmpl<std::string> MutableColData;
00243
00244
00245 #if !defined(NO_BINARY_OPERS) && !defined(DOXYGEN_IGNORE)
00246
00247
00248
00249
00250
00251 #define oprsw(opr, other, conv) \
00252 template<class Str> \
00253 inline other operator opr (ColData_Tmpl<Str> x, other y) \
00254 {return static_cast<conv>(x) opr y;} \
00255 template<class Str> \
00256 inline other operator opr (other x, ColData_Tmpl<Str> y) \
00257 {return x opr static_cast<conv>(y);}
00258
00259 #define operator_binary(other, conv) \
00260 oprsw(+, other, conv) \
00261 oprsw(-, other, conv) \
00262 oprsw(*, other, conv) \
00263 oprsw(/, other, conv)
00264
00265 #define operator_binary_int(other, conv) \
00266 operator_binary(other, conv) \
00267 oprsw(%, other, conv) \
00268 oprsw(&, other, conv) \
00269 oprsw(^, other, conv) \
00270 oprsw(|, other, conv) \
00271 oprsw(<<, other, conv) \
00272 oprsw(>>, other, conv)
00273
00274 operator_binary(float, double)
00275 operator_binary(double, double)
00276
00277 operator_binary_int(char, long int)
00278 operator_binary_int(int, long int)
00279 operator_binary_int(short int, long int)
00280 operator_binary_int(long int, long int)
00281
00282 operator_binary_int(unsigned char, unsigned long int)
00283 operator_binary_int(unsigned int, unsigned long int)
00284 operator_binary_int(unsigned short int, unsigned long int)
00285 operator_binary_int(unsigned long int, unsigned long int)
00286
00287 #if !defined(NO_LONG_LONGS)
00288 operator_binary_int(longlong, longlong)
00289 operator_binary_int(ulonglong, ulonglong)
00290 #endif
00291 #endif // NO_BINARY_OPERS
00292
00298 template <class Str> template<class T, class B>
00299 ColData_Tmpl<Str>::operator Null<T, B>() const
00300 {
00301 if ((Str::size() == 4) &&
00302 (*this)[0] == 'N' &&
00303 (*this)[1] == 'U' &&
00304 (*this)[2] == 'L' &&
00305 (*this)[3] == 'L') {
00306 return Null<T, B>(null);
00307 }
00308 else {
00309 return Null<T, B>(conv(T()));
00310 }
00311 }
00312
00313 template <class Str> template <class Type>
00314 Type ColData_Tmpl<Str>::conv(Type ) const
00315 {
00316 std::string strbuf = buf_;
00317 strip_all_blanks(strbuf);
00318 std::string::size_type len = strbuf.size();
00319 const char* str = strbuf.c_str();
00320 const char* end = str;
00321 Type num = mysql_convert<Type>(str, end);
00322
00323 if (*end == '.') {
00324 ++end;
00325 for (; *end == '0'; ++end) ;
00326 }
00327
00328 if (*end != '\0' && end != 0) {
00329 std::ostringstream outs;
00330 outs << "Tried to convert \"" << *this << "\" to a \"" <<
00331 typeid(Type).name() << "\" object." << std::ends;
00332 throw BadConversion(outs.str().c_str(), Str::c_str(),
00333 end - str, len);
00334 }
00335
00336 return num;
00337 }
00338
00339 }
00340
00341 #endif