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 <typeinfo>
00045 #include <string>
00046 #include <sstream>
00047
00048 #include <stdlib.h>
00049
00050 namespace mysqlpp {
00051
00082
00083 template <class Str>
00084 class MYSQLPP_EXPORT ColData_Tmpl : public Str
00085 {
00086 public:
00094 ColData_Tmpl() :
00095 null_(false)
00096 {
00097 }
00098
00102 ColData_Tmpl(const ColData_Tmpl<Str>& cd) :
00103 Str(cd.data(), cd.length()),
00104 type_(cd.type_),
00105 null_(cd.null_)
00106 {
00107 }
00108
00114 explicit ColData_Tmpl(bool n,
00115 mysql_type_info t = mysql_type_info::string_type) :
00116 type_(t),
00117 null_(n)
00118 {
00119 }
00120
00126 explicit ColData_Tmpl(const std::string& str,
00127 mysql_type_info t = mysql_type_info::string_type,
00128 bool n = false) :
00129 Str(str),
00130 type_(t),
00131 null_(n)
00132 {
00133 }
00134
00140 explicit ColData_Tmpl(const char* str,
00141 mysql_type_info t = mysql_type_info::string_type,
00142 bool n = false) :
00143 Str(str),
00144 type_(t),
00145 null_(n)
00146 {
00147 }
00148
00155 explicit ColData_Tmpl(const char* str, typename Str::size_type len,
00156 mysql_type_info t = mysql_type_info::string_type,
00157 bool n = false) :
00158 Str(str, len),
00159 type_(t),
00160 null_(n)
00161 {
00162 }
00163
00165 mysql_type_info type() const { return type_; }
00166
00169 bool quote_q() const { return type_.quote_q(); }
00170
00173 bool escape_q() const { return type_.escape_q(); }
00174
00176 template <class Type> Type conv(Type dummy) const;
00177
00179 void it_is_null() { null_ = true; }
00180
00182 inline const bool is_null() const { return null_; }
00183
00210 inline const std::string& get_string() const
00211 {
00212 temp_buf_.assign(Str::data(), Str::length());
00213 return temp_buf_;
00214 }
00215
00217 operator cchar*() const { return Str::data(); }
00218
00220 operator signed char() const
00221 { return conv(static_cast<signed char>(0)); }
00222
00224 operator unsigned char() const
00225 { return conv(static_cast<unsigned char>(0)); }
00226
00228 operator int() const
00229 { return conv(static_cast<int>(0)); }
00230
00232 operator unsigned int() const
00233 { return conv(static_cast<unsigned int>(0)); }
00234
00236 operator short int() const
00237 { return conv(static_cast<short int>(0)); }
00238
00241 operator unsigned short int() const
00242 { return conv(static_cast<unsigned short int>(0)); }
00243
00245 operator long int() const
00246 { return conv(static_cast<long int>(0)); }
00247
00250 operator unsigned long int() const
00251 { return conv(static_cast<unsigned long int>(0)); }
00252
00253 #if !defined(NO_LONG_LONGS)
00256 operator longlong() const
00257 { return conv(static_cast<longlong>(0)); }
00258
00261 operator ulonglong() const
00262 { return conv(static_cast<ulonglong>(0)); }
00263 #endif
00264
00266 operator float() const
00267 { return conv(static_cast<float>(0)); }
00268
00270 operator double() const
00271 { return conv(static_cast<double>(0)); }
00272
00274 operator bool() const { return conv(0); }
00275
00276 template <class T, class B> operator Null<T, B>() const;
00277
00278 private:
00279 mysql_type_info type_;
00280 mutable std::string temp_buf_;
00281 bool null_;
00282 };
00283
00286 typedef ColData_Tmpl<const_string> ColData;
00287
00290 typedef ColData_Tmpl<std::string> MutableColData;
00291
00292
00293 #if !defined(NO_BINARY_OPERS) && !defined(DOXYGEN_IGNORE)
00294
00295
00296
00297
00298
00299 #define oprsw(opr, other, conv) \
00300 template<class Str> \
00301 inline other operator opr (ColData_Tmpl<Str> x, other y) \
00302 {return static_cast<conv>(x) opr y;} \
00303 template<class Str> \
00304 inline other operator opr (other x, ColData_Tmpl<Str> y) \
00305 {return x opr static_cast<conv>(y);}
00306
00307 #define operator_binary(other, conv) \
00308 oprsw(+, other, conv) \
00309 oprsw(-, other, conv) \
00310 oprsw(*, other, conv) \
00311 oprsw(/, other, conv)
00312
00313 #define operator_binary_int(other, conv) \
00314 operator_binary(other, conv) \
00315 oprsw(%, other, conv) \
00316 oprsw(&, other, conv) \
00317 oprsw(^, other, conv) \
00318 oprsw(|, other, conv) \
00319 oprsw(<<, other, conv) \
00320 oprsw(>>, other, conv)
00321
00322 operator_binary(float, double)
00323 operator_binary(double, double)
00324
00325 operator_binary_int(char, long int)
00326 operator_binary_int(int, long int)
00327 operator_binary_int(short int, long int)
00328 operator_binary_int(long int, long int)
00329
00330 operator_binary_int(unsigned char, unsigned long int)
00331 operator_binary_int(unsigned int, unsigned long int)
00332 operator_binary_int(unsigned short int, unsigned long int)
00333 operator_binary_int(unsigned long int, unsigned long int)
00334
00335 #if !defined(NO_LONG_LONGS)
00336 operator_binary_int(longlong, longlong)
00337 operator_binary_int(ulonglong, ulonglong)
00338 #endif
00339 #endif // NO_BINARY_OPERS
00340
00346 template <class Str> template<class T, class B>
00347 ColData_Tmpl<Str>::operator Null<T, B>() const
00348 {
00349 if ((Str::size() == 4) &&
00350 (*this)[0] == 'N' &&
00351 (*this)[1] == 'U' &&
00352 (*this)[2] == 'L' &&
00353 (*this)[3] == 'L') {
00354 return Null<T, B>(null);
00355 }
00356 else {
00357 return Null<T, B>(conv(T()));
00358 }
00359 }
00360
00361 template <class Str> template <class Type>
00362 Type ColData_Tmpl<Str>::conv(Type ) const
00363 {
00364 std::string strbuf(Str::data(), Str::length());
00365 strip_all_blanks(strbuf);
00366 std::string::size_type len = strbuf.size();
00367 const char* str = strbuf.c_str();
00368 const char* end = str;
00369 Type num = mysql_convert<Type>(str, end);
00370
00371 if (*end == '.') {
00372 ++end;
00373 for (; *end == '0'; ++end) ;
00374 }
00375
00376 if (*end != '\0' && end != 0) {
00377 throw BadConversion(typeid(Type).name(), Str::c_str(),
00378 end - str, len);
00379 }
00380
00381 return num;
00382 }
00383
00384 }
00385
00386 #endif