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 #if !defined(MYSQLPP_TYPE_INFO_H)
00032 #define MYSQLPP_TYPE_INFO_H
00033
00034 #include "common.h"
00035
00036 #include "exceptions.h"
00037
00038 #include <map>
00039 #include <sstream>
00040 #include <typeinfo>
00041
00042 namespace mysqlpp {
00043
00044 #if !defined(DOXYGEN_IGNORE)
00045
00046
00047 class MYSQLPP_EXPORT mysql_type_info;
00048 class MYSQLPP_EXPORT mysql_ti_sql_type_info_lookup;
00049
00050 class MYSQLPP_EXPORT mysql_ti_sql_type_info
00051 {
00052 private:
00053
00054 enum {
00055 tf_default = 1,
00056 tf_null = 2,
00057 tf_unsigned = 4
00058 };
00059
00060 friend class mysql_type_info;
00061 friend class mysql_ti_sql_type_info_lookup;
00062
00063 mysql_ti_sql_type_info& operator=(
00064 const mysql_ti_sql_type_info& b);
00065
00066
00067
00068 mysql_ti_sql_type_info() :
00069 sql_name_(0),
00070 c_type_(0),
00071 base_type_(MYSQL_TYPE_NULL),
00072 flags_(0)
00073 {
00074 }
00075
00076 mysql_ti_sql_type_info(const char* s,
00077 const std::type_info& t, const enum_field_types bt,
00078 const unsigned int flags = 0) :
00079 sql_name_(s),
00080 c_type_(&t),
00081 base_type_(bt),
00082 flags_(flags)
00083 {
00084 }
00085
00086 bool is_default() const { return flags_ & tf_default; }
00087 bool is_null() const { return flags_ & tf_null; }
00088 bool is_unsigned() const { return flags_ & tf_unsigned; }
00089
00090 const char* sql_name_;
00091 const std::type_info* c_type_;
00092 const enum_field_types base_type_;
00093 const unsigned int flags_;
00094 };
00095
00096
00097 struct type_info_cmp
00098 {
00099 bool operator() (const std::type_info* lhs,
00100 const std::type_info* rhs) const
00101 {
00102 return lhs->before(*rhs) != 0;
00103 }
00104 };
00105
00106 class MYSQLPP_EXPORT mysql_ti_sql_type_info_lookup
00107 {
00108 private:
00109 friend class mysql_type_info;
00110
00111 typedef mysql_ti_sql_type_info sql_type_info;
00112 typedef std::map<const std::type_info*, unsigned char, type_info_cmp>
00113 map_type;
00114
00115 mysql_ti_sql_type_info_lookup(const sql_type_info types[],
00116 const int size);
00117
00118 const unsigned char& operator [](
00119 const std::type_info& ti) const
00120 {
00121 map_type::const_iterator it = map_.find(&ti);
00122 if (it != map_.end()) {
00123 return it->second;
00124 }
00125 else {
00126 std::ostringstream outs;
00127 outs << "Failed to find MySQL C API type ID for " << ti.name();
00128 throw TypeLookupFailed(outs.str());
00129 }
00130 }
00131
00132 map_type map_;
00133 };
00134
00135 #endif // !defined(DOXYGEN_IGNORE)
00136
00137
00142 class MYSQLPP_EXPORT mysql_type_info
00143 {
00144 public:
00152 mysql_type_info() :
00153 num_(static_cast<unsigned char>(-1))
00154 {
00155 }
00156
00162 mysql_type_info(enum_field_types t, bool _unsigned = false,
00163 bool _null = false) :
00164 num_(type(t, _unsigned, _null))
00165 {
00166 }
00167
00169 mysql_type_info(const mysql_type_info& t) :
00170 num_(t.num_)
00171 {
00172 }
00173
00178 mysql_type_info(const std::type_info& t) :
00179 num_(lookups[t])
00180 {
00181 }
00182
00184 mysql_type_info& operator =(const mysql_type_info& t)
00185 {
00186 num_ = t.num_;
00187 return *this;
00188 }
00189
00194 mysql_type_info& operator =(const std::type_info& t)
00195 {
00196 num_ = lookups[t];
00197 return *this;
00198 }
00199
00204 const char* name() const { return deref().c_type_->name(); }
00205
00209 const char* sql_name() const { return deref().sql_name_; }
00210
00215 const std::type_info& c_type() const { return *deref().c_type_; }
00216
00222 const mysql_type_info base_type() const
00223 {
00224 return mysql_type_info(deref().base_type_);
00225 }
00226
00232 int id() const
00233 {
00234 return num_;
00235 }
00236
00242 bool quote_q() const;
00243
00249 bool escape_q() const;
00250
00255 bool before(mysql_type_info& b)
00256 {
00257 return num_ < b.num_;
00258 }
00259
00264 static const enum_field_types string_type = MYSQL_TYPE_STRING;
00265
00266 private:
00267 typedef mysql_ti_sql_type_info sql_type_info;
00268 typedef mysql_ti_sql_type_info_lookup sql_type_info_lookup;
00269
00270 static const sql_type_info types[];
00271 static const int num_types;
00272
00273 static const sql_type_info_lookup lookups;
00274
00293 static unsigned char type(enum_field_types t,
00294 bool _unsigned, bool _null = false);
00295
00296 const sql_type_info& deref() const
00297 {
00298 return types[num_];
00299 }
00300
00301 unsigned char num_;
00302 };
00303
00305 inline bool operator ==(const mysql_type_info& a, const mysql_type_info& b)
00306 {
00307 return a.id() == b.id();
00308 }
00309
00311 inline bool operator !=(const mysql_type_info& a, const mysql_type_info& b)
00312 {
00313 return a.id() != b.id();
00314 }
00315
00318 inline bool operator ==(const std::type_info& a, const mysql_type_info& b)
00319 {
00320 return a == b.c_type();
00321 }
00322
00325 inline bool operator !=(const std::type_info& a, const mysql_type_info& b)
00326 {
00327 return a != b.c_type();
00328 }
00329
00332 inline bool operator ==(const mysql_type_info& a, const std::type_info& b)
00333 {
00334 return a.c_type() == b;
00335 }
00336
00339 inline bool operator !=(const mysql_type_info& a, const std::type_info& b)
00340 {
00341 return a.c_type() != b;
00342 }
00343
00344 }
00345
00346 #endif // !defined(MYSQLPP_TYPE_INFO_H)
00347