00001 #ifndef MYSQLPP_TYPE_INFO_H
00002 #define MYSQLPP_TYPE_INFO_H
00003
00009
00010 #include "defs.h"
00011
00012 #include <mysql.h>
00013
00014 #include <typeinfo>
00015 #include <map>
00016
00017 namespace mysqlpp {
00018
00019 class mysql_type_info;
00020 class mysql_ti_sql_type_info_lookup;
00021
00023
00024
00025 class mysql_ti_sql_type_info {
00026 friend class mysql_type_info;
00027 friend class mysql_ti_sql_type_info_lookup;
00028 private:
00029 const char *_sql_name;
00030 const std::type_info *_c_type;
00031 const unsigned char _base_type;
00032 const bool _default;
00033 mysql_ti_sql_type_info& operator=(const mysql_ti_sql_type_info &b);
00034 mysql_ti_sql_type_info () : _base_type(0), _default(false) {}
00035
00036
00037
00038
00039 mysql_ti_sql_type_info (const char *s, const std::type_info &t,
00040 const unsigned char bt = 0, const bool d = false )
00041 : _sql_name(s), _c_type(&t), _base_type(bt), _default(d) {}
00042 };
00043
00045
00047 struct type_info_cmp {
00048 bool operator() (const std::type_info *lhs, const std::type_info *rhs) const {
00049 return lhs->before(*rhs) != 0;
00050 }
00051 };
00052
00054
00055
00056 class mysql_ti_sql_type_info_lookup {
00057 friend class mysql_type_info;
00058 private:
00059 typedef mysql_ti_sql_type_info sql_type_info;
00060
00061 std::map<const std::type_info *, unsigned char, type_info_cmp> _map;
00062
00063 mysql_ti_sql_type_info_lookup(const sql_type_info types[], const int size);
00064
00065 const unsigned char& operator [] (const std::type_info &ti) const {
00066 return _map.find(&ti)->second;
00067 }
00068 };
00069
00071
00072
00076 class mysql_type_info {
00077 private:
00078 typedef mysql_ti_sql_type_info sql_type_info;
00079 typedef mysql_ti_sql_type_info_lookup sql_type_info_lookup;
00080 private:
00081 static const sql_type_info types[62];
00082
00083 static const unsigned char offset = 0;
00084 static const unsigned char unsigned_offset = 21;
00085 static const unsigned char null_offset = 31;
00086 static const unsigned char unsigned_null_offset = 52;
00087
00088 static const sql_type_info_lookup lookups;
00089
00090 static unsigned char type(enum_field_types t,
00091 bool _unsigned, bool _null = false);
00092 public:
00093 static const unsigned char string_type = 20;
00094 unsigned int _length;
00095 unsigned int _max_length;
00096 private:
00097 unsigned char num;
00098 inline const sql_type_info& deref() const;
00099 public:
00100 mysql_type_info() { }
00101
00102 mysql_type_info(unsigned char n) : num(n) {}
00103
00104 inline mysql_type_info(enum_field_types t,
00105 bool _unsigned, bool _null);
00106
00107 inline mysql_type_info(const MYSQL_FIELD &f);
00108
00109 mysql_type_info(const mysql_type_info &t) : num(t.num) {}
00110
00111 mysql_type_info(const std::type_info &t) {num = lookups[t]; }
00112
00113 mysql_type_info& operator = (unsigned char n) {num=n; return *this;}
00114
00115 mysql_type_info& operator = (const mysql_type_info &t)
00116 {num = t.num; return *this;}
00117
00118 mysql_type_info& operator = (const std::type_info &t)
00119 {num = lookups[t]; return *this;}
00120
00125 inline const char* name() const;
00126
00130 inline const char* sql_name() const;
00131
00136 inline const std::type_info& c_type() const;
00137 inline const unsigned int length() const;
00138 inline const unsigned int max_length() const;
00139
00145 inline const mysql_type_info base_type() const;
00146
00152 int id() const { return num; }
00153
00159 bool quote_q() const;
00160
00166 bool escape_q() const;
00167
00172 bool before(mysql_type_info &b) { return num < b.num; }
00173 };
00174
00175 inline const mysql_type_info::sql_type_info& mysql_type_info::deref() const
00176 {
00177 return types[num];
00178 }
00179
00180 inline const char* mysql_type_info::name() const
00181 {
00182 return deref()._c_type->name();
00183 }
00184
00185 inline const char* mysql_type_info::sql_name() const
00186 {
00187 return deref()._sql_name;
00188 }
00189
00190 inline const unsigned int mysql_type_info::length() const
00191 {
00192 return _length;
00193 }
00194
00195 inline const unsigned int mysql_type_info::max_length() const
00196 {
00197 return _max_length;
00198 }
00199
00200 inline const std::type_info& mysql_type_info::c_type() const
00201 {
00202 return *deref()._c_type;
00203 }
00204
00205 inline const mysql_type_info mysql_type_info::base_type() const
00206 {
00207 return mysql_type_info(deref()._base_type);
00208 }
00209
00210 inline mysql_type_info::mysql_type_info(enum_field_types t,
00211 bool _unsigned, bool _null)
00212 {
00213 num = type(t,_unsigned,_null);
00214 }
00215
00216 inline mysql_type_info::mysql_type_info(const MYSQL_FIELD &f)
00217 {
00218 num = type(f.type,
00219 (f.flags & UNSIGNED_FLAG) != 0,
00220 (f.flags & NOT_NULL_FLAG) == 0);
00221 _length = f.length;
00222 _max_length = f.max_length;
00223 }
00224
00225 inline bool operator == (const mysql_type_info& a, const mysql_type_info& b)
00226 {
00227 return a.id() == b.id();
00228 }
00229
00230 inline bool operator != (const mysql_type_info& a, const mysql_type_info& b)
00231 {
00232 return a.id() != b.id();
00233 }
00234
00235 inline bool operator == (const std::type_info &a, const mysql_type_info &b)
00236 {
00237 return a == b.c_type();
00238 }
00239
00240 inline bool operator != (const std::type_info &a, const mysql_type_info &b)
00241 {
00242 return a != b.c_type();
00243 }
00244
00245 inline bool operator == (const mysql_type_info &a, const std::type_info &b)
00246 {
00247 return a.c_type() == b;
00248 }
00249
00250 inline bool operator != (const mysql_type_info &a, const std::type_info &b)
00251 {
00252 return a.c_type() != b;
00253 }
00254
00255 }
00256
00257 #endif
00258