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 "platform.h"
00036
00037 #include "const_string.h"
00038 #include "convert.h"
00039 #include "defs.h"
00040 #include "exceptions.h"
00041 #include "null.h"
00042 #include "string_util.h"
00043 #include "type_info.h"
00044
00045 #include <mysql.h>
00046
00047 #include <typeinfo>
00048 #include <string>
00049 #include <sstream>
00050
00051 #include <stdlib.h>
00052
00053 namespace mysqlpp {
00054
00085
00086 template <class Str>
00087 class ColData_Tmpl : public Str
00088 {
00089 public:
00097 ColData_Tmpl() :
00098 null_(false)
00099 {
00100 }
00101
00107 explicit ColData_Tmpl(bool n,
00108 mysql_type_info t = mysql_type_info::string_type) :
00109 type_(t),
00110 null_(n)
00111 {
00112 }
00113
00119 explicit ColData_Tmpl(const char* str,
00120 mysql_type_info t = mysql_type_info::string_type,
00121 bool n = false) :
00122 Str(str),
00123 type_(t),
00124 buf_(str),
00125 null_(n)
00126 {
00127 }
00128
00130 mysql_type_info type() const
00131 {
00132 return type_;
00133 }
00134
00137 bool quote_q() const
00138 {
00139 return type_.quote_q();
00140 }
00141
00144 bool escape_q() const
00145 {
00146 return type_.escape_q();
00147 }
00148
00150 template <class Type> Type conv(Type dummy) const;
00151
00153 void it_is_null() { null_ = true; }
00154
00156 inline const bool is_null() const { return null_; }
00157
00159 inline const std::string& get_string() const
00160 {
00161 return buf_;
00162 }
00163
00166 operator cchar*() const { return buf_.c_str(); }
00167
00169 operator signed char() const
00170 { return conv(static_cast<signed char>(0)); }
00171
00173 operator unsigned char() const
00174 { return conv(static_cast<unsigned char>(0)); }
00175
00177 operator int() const
00178 { return conv(static_cast<int>(0)); }
00179
00181 operator unsigned int() const
00182 { return conv(static_cast<unsigned int>(0)); }
00183
00185 operator short int() const
00186 { return conv(static_cast<short int>(0)); }
00187
00190 operator unsigned short int() const
00191 { return conv(static_cast<unsigned short int>(0)); }
00192
00194 operator long int() const
00195 { return conv(static_cast<long int>(0)); }
00196
00199 operator unsigned long int() const
00200 { return conv(static_cast<unsigned long int>(0)); }
00201
00202 #if !defined(NO_LONG_LONGS)
00205 operator longlong() const
00206 { return conv(static_cast<longlong>(0)); }
00207
00210 operator ulonglong() const
00211 { return conv(static_cast<ulonglong>(0)); }
00212 #endif
00213
00215 operator float() const
00216 { return conv(static_cast<float>(0)); }
00217
00219 operator double() const
00220 { return conv(static_cast<double>(0)); }
00221
00223 operator bool() const { return conv(0); }
00224
00225 template <class T, class B> operator Null<T, B>() const;
00226
00227 private:
00228 mysql_type_info type_;
00229 std::string buf_;
00230 bool null_;
00231 };
00232
00235 typedef ColData_Tmpl<const_string> ColData;
00236
00239 typedef ColData_Tmpl<std::string> MutableColData;
00240
00241
00242 #if !defined(NO_BINARY_OPERS) && !defined(DOXYGEN_IGNORE)
00243
00244
00245
00246
00247
00248 #define oprsw(opr, other, conv) \
00249 template<class Str> \
00250 inline other operator opr (ColData_Tmpl<Str> x, other y) \
00251 {return static_cast<conv>(x) opr y;} \
00252 template<class Str> \
00253 inline other operator opr (other x, ColData_Tmpl<Str> y) \
00254 {return x opr static_cast<conv>(y);}
00255
00256 #define operator_binary(other, conv) \
00257 oprsw(+, other, conv) \
00258 oprsw(-, other, conv) \
00259 oprsw(*, other, conv) \
00260 oprsw(/, other, conv)
00261
00262 #define operator_binary_int(other, conv) \
00263 operator_binary(other, conv) \
00264 oprsw(%, other, conv) \
00265 oprsw(&, other, conv) \
00266 oprsw(^, other, conv) \
00267 oprsw(|, other, conv) \
00268 oprsw(<<, other, conv) \
00269 oprsw(>>, other, conv)
00270
00271 operator_binary(float, double)
00272 operator_binary(double, double)
00273
00274 operator_binary_int(char, long int)
00275 operator_binary_int(int, long int)
00276 operator_binary_int(short int, long int)
00277 operator_binary_int(long int, long int)
00278
00279 operator_binary_int(unsigned char, unsigned long int)
00280 operator_binary_int(unsigned int, unsigned long int)
00281 operator_binary_int(unsigned short int, unsigned long int)
00282 operator_binary_int(unsigned long int, unsigned long int)
00283
00284 #if !defined(NO_LONG_LONGS)
00285 operator_binary_int(longlong, longlong)
00286 operator_binary_int(ulonglong, ulonglong)
00287 #endif
00288 #endif // NO_BINARY_OPERS
00289
00291
00297 template <class Str> template<class T, class B>
00298 ColData_Tmpl<Str>::operator Null<T, B>() const
00299 {
00300 if ((Str::size() == 4) &&
00301 (*this)[0] == 'N' &&
00302 (*this)[1] == 'U' &&
00303 (*this)[2] == 'L' &&
00304 (*this)[3] == 'L') {
00305 return Null<T, B>(null);
00306 }
00307 else {
00308 return Null<T, B>(conv(T()));
00309 }
00310 }
00311
00312 template <class Str> template <class Type>
00313 Type ColData_Tmpl<Str>::conv(Type ) const
00314 {
00315 std::string strbuf = buf_;
00316 strip_all_blanks(strbuf);
00317 size_t len = strbuf.size();
00318 const char* str = strbuf.c_str();
00319 const char* end = str;
00320 Type num = mysql_convert<Type>(str, end);
00321
00322 if (*end == '.') {
00323 ++end;
00324 for (; *end == '0'; ++end) ;
00325 }
00326
00327 if (*end != '\0' && end != 0) {
00328 std::ostringstream outs;
00329 outs << "Tried to convert \"" << *this << "\" to a \"" <<
00330 typeid(Type).name() << "\" object." << std::ends;
00331 throw BadConversion(outs.str().c_str(), Str::c_str(),
00332 end - str, len);
00333 }
00334
00335 return num;
00336 }
00337
00338 }
00339
00340 #endif