00001 #ifndef MYSQLPP_COLDATA_H
00002 #define MYSQLPP_COLDATA_H
00003
00010
00011 #include "platform.h"
00012
00013 #include "const_string.h"
00014 #include "convert.h"
00015 #include "defs.h"
00016 #include "exceptions.h"
00017 #include "null.h"
00018 #include "string_util.h"
00019 #include "type_info.h"
00020
00021 #include <mysql.h>
00022
00023 #include <typeinfo>
00024 #include <string>
00025
00026 #include <stdlib.h>
00027
00028 namespace mysqlpp {
00029
00054
00055 template <class Str>
00056 class ColData_Tmpl : public Str {
00057 private:
00058 mysql_type_info _type;
00059 std::string buf;
00060 bool _null;
00061 public:
00062 explicit ColData_Tmpl(bool n,
00063 mysql_type_info t = mysql_type_info::string_type) :
00064 _type(t),
00065 _null(n)
00066 {
00067 }
00068
00069 explicit ColData_Tmpl(const char *str,
00070 mysql_type_info t = mysql_type_info::string_type,
00071 bool n = false) :
00072 Str(str),
00073 _type(t),
00074 _null(n)
00075 {
00076 buf=str;
00077 }
00078
00079 ColData_Tmpl() { }
00080
00082 mysql_type_info type() { return _type; }
00083
00086 bool quote_q() const { return _type.quote_q(); }
00087
00090 bool escape_q() const { return _type.escape_q(); }
00091
00092 template<class Type> Type conv(Type dummy) const;
00093
00094 void it_is_null (void) {_null=true;}
00095 inline const bool is_null(void) const {return _null;}
00096 inline const std::string& get_string(void) const {return buf;}
00097 operator cchar*() const {return buf.c_str();}
00098 operator signed char() const {return conv(static_cast<signed char>(0));}
00099 operator unsigned char() const {return conv(static_cast<unsigned char>(0));}
00100 operator int() const {return conv(static_cast<int>(0));}
00101 operator unsigned int() const {return conv(static_cast<unsigned int>(0));}
00102 operator short int() const {return conv(static_cast<short int>(0));}
00103 operator unsigned short int() const {return conv(static_cast<unsigned short int>(0));}
00104 operator long int() const {return conv(static_cast<long int>(0));}
00105 operator unsigned long int() const {return conv(static_cast<unsigned long int>(0));}
00106 operator longlong() const {return conv(static_cast<longlong>(0));}
00107 operator ulonglong() const {return conv(static_cast<ulonglong>(0));}
00108 operator float() const {return conv(static_cast<float>(0));}
00109 operator double() const {return conv(static_cast<double>(0));}
00110
00111 template <class T, class B> operator Null<T,B> () const;
00112 };
00113
00116 typedef ColData_Tmpl<const_string> ColData;
00117
00120 typedef ColData_Tmpl<std::string> MutableColData;
00121
00122
00123
00124 #ifndef NO_BINARY_OPERS
00125
00126 #define oprsw(opr, other, conv) \
00127 template<class Str> \
00128 inline other operator opr (ColData_Tmpl<Str> x, other y) \
00129 {return static_cast<conv>(x) opr y;} \
00130 template<class Str> \
00131 inline other operator opr (other x, ColData_Tmpl<Str> y) \
00132 {return x opr static_cast<conv>(y);}
00133
00134 #define operator_binary(other, conv) \
00135 oprsw(+, other, conv) \
00136 oprsw(-, other, conv) \
00137 oprsw(*, other, conv) \
00138 oprsw(/, other, conv)
00139
00140 #define operator_binary_int(other, conv) \
00141 operator_binary(other, conv) \
00142 oprsw(%, other, conv) \
00143 oprsw(&, other, conv) \
00144 oprsw(^, other, conv) \
00145 oprsw(|, other, conv) \
00146 oprsw(<<, other, conv) \
00147 oprsw(>>, other, conv)
00148
00149 operator_binary(float, double)
00150 operator_binary(double, double)
00151
00152 operator_binary_int(char,long int)
00153 operator_binary_int(int, long int)
00154 operator_binary_int(short int, long int)
00155 operator_binary_int(long int, long int)
00156
00157 operator_binary_int(unsigned char, unsigned long int)
00158 operator_binary_int(unsigned int, unsigned long int)
00159 operator_binary_int(unsigned short int, unsigned long int)
00160 operator_binary_int(unsigned long int, unsigned long int)
00161
00162 operator_binary_int(longlong, longlong)
00163 operator_binary_int(ulonglong, ulonglong)
00164
00165 #endif
00166
00167
00168 template <class Str> template<class T, class B>
00169 ColData_Tmpl<Str>::operator Null<T,B> () const {
00170 if ((*this)[0] == 'N' && (*this)[1] == 'U' &&
00171 (*this)[2] == 'L' && (*this)[3] == 'L' && Str::size() == 4)
00172 return Null<T,B>(null);
00173 else return Null<T,B>(conv(T()));
00174 }
00175
00176
00177 template <class Str> template<class Type>
00178 Type ColData_Tmpl<Str>::conv (Type ) const {
00179 std::string strbuf = buf;
00180 strip_all_blanks(strbuf);
00181 size_t len = strbuf.size();
00182 const char *str = strbuf.c_str();
00183 const char *end = str;
00184 Type num = mysql_convert<Type>(str, end);
00185 if (*end == '.') {
00186 end++;
00187 for (;*end == '0'; end++);
00188 }
00189 if (*end != '\0' && end != NULL ) {
00190 throw BadConversion (typeid(Type).name(), Str::c_str(), end - str, len);
00191 }
00192 return num;
00193 }
00194
00195 }
00196
00197 #endif
00198