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_(
00072 #if MYSQL_VERSION_ID > 40000
00073 MYSQL_TYPE_NULL
00074 #else
00075 FIELD_TYPE_NULL
00076 #endif
00077 ),
00078 flags_(0)
00079 {
00080 }
00081
00082 mysql_ti_sql_type_info(const char* s,
00083 const std::type_info& t, const enum_field_types bt,
00084 const unsigned int flags = 0) :
00085 sql_name_(s),
00086 c_type_(&t),
00087 base_type_(bt),
00088 flags_(flags)
00089 {
00090 }
00091
00092 bool is_default() const { return flags_ & tf_default; }
00093 bool is_null() const { return flags_ & tf_null; }
00094 bool is_unsigned() const { return flags_ & tf_unsigned; }
00095
00096 const char* sql_name_;
00097 const std::type_info* c_type_;
00098 const enum_field_types base_type_;
00099 const unsigned int flags_;
00100 };
00101
00102
00103 struct type_info_cmp
00104 {
00105 bool operator() (const std::type_info* lhs,
00106 const std::type_info* rhs) const
00107 {
00108 return lhs->before(*rhs) != 0;
00109 }
00110 };
00111
00112 class MYSQLPP_EXPORT mysql_ti_sql_type_info_lookup
00113 {
00114 private:
00115 friend class mysql_type_info;
00116
00117 typedef mysql_ti_sql_type_info sql_type_info;
00118 typedef std::map<const std::type_info*, unsigned char, type_info_cmp>
00119 map_type;
00120
00121 mysql_ti_sql_type_info_lookup(const sql_type_info types[],
00122 const int size);
00123
00124 const unsigned char& operator [](
00125 const std::type_info& ti) const
00126 {
00127 map_type::const_iterator it = map_.find(&ti);
00128 if (it != map_.end()) {
00129 return it->second;
00130 }
00131 else {
00132 std::ostringstream outs;
00133 outs << "Failed to find MySQL C API type ID for " << ti.name();
00134 throw TypeLookupFailed(outs.str());
00135 }
00136 }
00137
00138 map_type map_;
00139 };
00140
00141 #endif // !defined(DOXYGEN_IGNORE)
00142
00143
00148 class MYSQLPP_EXPORT mysql_type_info
00149 {
00150 public:
00158 mysql_type_info() :
00159 num_(static_cast<unsigned char>(-1))
00160 {
00161 }
00162
00168 mysql_type_info(enum_field_types t, bool _unsigned = false,
00169 bool _null = false) :
00170 num_(type(t, _unsigned, _null))
00171 {
00172 }
00173
00175 mysql_type_info(const mysql_type_info& t) :
00176 num_(t.num_)
00177 {
00178 }
00179
00184 mysql_type_info(const std::type_info& t) :
00185 num_(lookups[t])
00186 {
00187 }
00188
00190 mysql_type_info& operator =(const mysql_type_info& t)
00191 {
00192 num_ = t.num_;
00193 return *this;
00194 }
00195
00200 mysql_type_info& operator =(const std::type_info& t)
00201 {
00202 num_ = lookups[t];
00203 return *this;
00204 }
00205
00210 const char* name() const { return deref().c_type_->name(); }
00211
00215 const char* sql_name() const { return deref().sql_name_; }
00216
00221 const std::type_info& c_type() const { return *deref().c_type_; }
00222
00228 const mysql_type_info base_type() const
00229 {
00230 return mysql_type_info(deref().base_type_);
00231 }
00232
00238 int id() const
00239 {
00240 return num_;
00241 }
00242
00248 bool quote_q() const;
00249
00255 bool escape_q() const;
00256
00261 bool before(mysql_type_info& b)
00262 {
00263 return num_ < b.num_;
00264 }
00265
00270 static const enum_field_types string_type =
00271 #if MYSQL_VERSION_ID > 40000
00272 MYSQL_TYPE_STRING;
00273 #else
00274 FIELD_TYPE_STRING;
00275 #endif
00276
00277 private:
00278 typedef mysql_ti_sql_type_info sql_type_info;
00279 typedef mysql_ti_sql_type_info_lookup sql_type_info_lookup;
00280
00281 static const sql_type_info types[];
00282 static const int num_types;
00283
00284 static const sql_type_info_lookup lookups;
00285
00304 static unsigned char type(enum_field_types t,
00305 bool _unsigned, bool _null = false);
00306
00307 const sql_type_info& deref() const
00308 {
00309 return types[num_];
00310 }
00311
00312 unsigned char num_;
00313 };
00314
00316 inline bool operator ==(const mysql_type_info& a, const mysql_type_info& b)
00317 {
00318 return a.id() == b.id();
00319 }
00320
00322 inline bool operator !=(const mysql_type_info& a, const mysql_type_info& b)
00323 {
00324 return a.id() != b.id();
00325 }
00326
00329 inline bool operator ==(const std::type_info& a, const mysql_type_info& b)
00330 {
00331 return a == b.c_type();
00332 }
00333
00336 inline bool operator !=(const std::type_info& a, const mysql_type_info& b)
00337 {
00338 return a != b.c_type();
00339 }
00340
00343 inline bool operator ==(const mysql_type_info& a, const std::type_info& b)
00344 {
00345 return a.c_type() == b;
00346 }
00347
00350 inline bool operator !=(const mysql_type_info& a, const std::type_info& b)
00351 {
00352 return a.c_type() != b;
00353 }
00354
00355 }
00356
00357 #endif // !defined(MYSQLPP_TYPE_INFO_H)
00358