type_info.h

Go to the documentation of this file.
00001 
00002 
00003 
00004 
00005 
00006 
00007 /***********************************************************************
00008  Copyright (c) 1998 by Kevin Atkinson, (c) 1999-2001 by MySQL AB, and
00009  (c) 2004-2008 by Educational Technology Resources, Inc.  Others may
00010  also hold copyrights on code in this file.  See the CREDITS.txt file
00011  in the top directory of the distribution for details.
00012 
00013  This file is part of MySQL++.
00014 
00015  MySQL++ is free software; you can redistribute it and/or modify it
00016  under the terms of the GNU Lesser General Public License as published
00017  by the Free Software Foundation; either version 2.1 of the License, or
00018  (at your option) any later version.
00019 
00020  MySQL++ is distributed in the hope that it will be useful, but WITHOUT
00021  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
00022  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
00023  License for more details.
00024 
00025  You should have received a copy of the GNU Lesser General Public
00026  License along with MySQL++; if not, write to the Free Software
00027  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
00028  USA
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 // Doxygen will not generate documentation for this section.
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         // For use with flags_ bitset
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         // Not initting _base_type and _default because only mysql_type_info
00067         // can create them.  There *must* be only one copy of each.
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 }                                                               // end namespace mysqlpp
00356 
00357 #endif // !defined(MYSQLPP_TYPE_INFO_H)
00358 

Generated on Wed Feb 4 14:42:56 2009 for MySQL++ by  doxygen 1.4.7