/home/bes3soft/bes3soft/Boss/7.0.2/dist/7.0.2/Calibration/rdbModel/rdbModel-00-01-01/src/Tables/Datatype.cxx

Go to the documentation of this file.
00001 // $Header: /bes/bes/BossCvs/Calibration/rdbModel/src/Tables/Datatype.cxx,v 1.1.1.1 2005/10/17 06:10:53 maqm Exp $
00002 #include <iostream>
00003 #include "rdbModel/Tables/Datatype.h"
00004 #include "facilities/Util.h"
00005 #include "facilities/Timestamp.h"
00006 
00007 namespace {
00008 
00009   using rdbModel::Datatype;
00010 
00011   bool initDone = false;
00012   const unsigned int N_SUPPORTED_TYPES = rdbModel::Datatype::TYPEchar + 1;
00013   std::string typenames[N_SUPPORTED_TYPES];
00014   void init() {
00015     if (!initDone) {
00016       typenames[Datatype::TYPEenum] = std::string("enum");
00017       typenames[Datatype::TYPEdatetime] = std::string("datetime");
00018       typenames[Datatype::TYPEtimestamp] = std::string("timestamp");
00019       typenames[Datatype::TYPEint] = std::string("int");
00020       typenames[Datatype::TYPEmediumint] = std::string("mediumint");
00021       typenames[Datatype::TYPEsmallint] = std::string("smallint");
00022       typenames[Datatype::TYPEreal] = std::string("real");
00023       typenames[Datatype::TYPEdouble] = std::string("double");
00024       typenames[Datatype::TYPEvarchar] = std::string("varchar");
00025       typenames[Datatype::TYPEchar] = std::string("char");
00026       initDone = true;
00027     }
00028   }
00029   int findType(std::string aType) {
00030     if (!initDone) init();
00031     for (unsigned int i = 0; i < N_SUPPORTED_TYPES; i++) {
00032       if (aType == typenames[i]) return i;
00033     }
00034     return (int) Datatype::TYPEnotFound;
00035   }
00036   enum TYPE_OF_TYPE {
00037     TOTinteger = 0,
00038     TOTreal,
00039     TOTchar,
00040     TOTdate
00041   };
00042   int findTOT(Datatype::TYPES aType) {
00043     if ((aType == Datatype::TYPEint) || (aType == Datatype::TYPEmediumint) ||
00044         (aType == Datatype::TYPEsmallint)) return TOTinteger;
00045     else if ((aType == Datatype::TYPEreal) || (aType == Datatype::TYPEdouble))
00046       return TOTreal;
00047     else if ((aType == Datatype::TYPEdatetime) || 
00048              (aType == Datatype::TYPEtimestamp))
00049       return TOTdate;
00050     else return TOTchar;
00051   }
00052     
00053 }
00054 
00055 namespace rdbModel {
00056 
00057   int Datatype::setType(std::string name) {
00058     m_type = (TYPES) findType(name);
00059     if (m_type >=0 ) {
00060       m_typename = name;
00061     }
00062 
00063     // Set up initial restrictions for integer-like types.  These
00064     // values come from the MySQL doc.  See e.g. 
00065     // http://www.mysql.com/documentation/mysql/bychapter/manual_Column_types.html#Numeric_types
00066     switch (m_type) {
00067       case TYPEint: {
00068         m_maxInt = 2147483647;
00069         m_minInt = -2147483647;
00070         m_isInt = true;
00071         break;
00072       }
00073       case TYPEmediumint: {
00074         m_maxInt = 8388607;
00075         m_minInt = -8388608;
00076         m_isInt = true;
00077         break;
00078       }
00079       case TYPEsmallint: {
00080         m_maxInt = 32767;
00081         m_minInt = -32768;
00082         m_isInt = true;
00083         break;
00084       }
00085     default:
00086       break;
00087     }
00088     return m_type;
00089   }
00090 
00091   // Makes sense only for numeric types or for datetime [or timestamp]
00092   bool Datatype::setInterval(const std::string& min, const std::string& max) {
00093     bool ret = false;
00094     //    if ((m_type == TYPEtimestamp) || (m_type == TYPEenum) || 
00095     if ( (m_type == TYPEenum) || 
00096         (m_type == TYPEchar) || (m_type == TYPEvarchar)) {
00097       std::cerr << "From rdbModel::Datatype::setInterval " << std::endl;
00098       std::cerr << "Cannot set interval restriction for type " <<
00099         typenames[m_type] << std::endl;
00100       return false;
00101     }
00102 
00103     m_restrict = RESTRICTinterval;
00104     m_min = min;
00105     m_max = max;
00106 
00107     // In case data is some integer type, convert min and max to integers,
00108     // store.  Return false if anything about them is unreasonable.
00109     if (m_isInt) {
00110       try {
00111         int minInt = facilities::Util::stringToInt(min);
00112         int maxInt = facilities::Util::stringToInt(max);
00113         if (minInt > m_minInt) m_minInt = minInt;
00114         if (maxInt < m_maxInt) m_maxInt = maxInt;
00115       }
00116       catch (facilities::WrongType ex) {
00117         std::cerr << "Error detected in XercesBuilder::buildDatatype " 
00118                   << std::endl;
00119         std::cerr << ex.getMsg() << std::endl;
00120         return false;
00121       }
00122       ret = (m_min < m_max);
00123     }
00124     // Don't expect to encounter interval restriction for floating point,
00125     // so don't bother to cache values, but at least check for validity
00126     if ((m_type == TYPEdouble) || (m_type == TYPEreal)) {
00127       try {
00128         double minFloat = facilities::Util::stringToDouble(min);
00129         double maxFloat = facilities::Util::stringToDouble(max);
00130         ret =  (minFloat < maxFloat);
00131       }
00132       catch (facilities::WrongType ex) {
00133         std::cerr << "Error detected in XercesBuilder::buildDatatype " 
00134                   << std::endl;
00135         std::cerr << ex.getMsg() << std::endl;
00136         return false;
00137       }
00138     }
00139     if (m_type == TYPEdatetime) {
00140       try {
00141         facilities::Timestamp minTime(min);
00142         facilities::Timestamp maxTime(max);
00143         ret =  (minTime < maxTime);
00144       }
00145       catch (facilities::BadTimeInput ex) {
00146         std::cerr << "From rdbModel::Datatype::setInterval" << std::endl;
00147         std::cerr << ex.complaint << std::endl;
00148         return false;
00149       }
00150     }
00151     return ret;
00152   }
00153 
00154   bool Datatype::getInterval(std::string& min, std::string& max) {
00155     if (m_restrict == RESTRICTinterval) {
00156       min = m_min;
00157       max = m_max;
00158       return true;
00159     }
00160     return false;
00161   }
00162 
00163 
00164   bool Datatype::okValue(const std::string& val) const {
00165     using facilities::Util;
00166 
00167     switch (m_type) {
00168     case TYPEreal:
00169     case TYPEdouble: {
00170       double doubleVal;
00171       try {
00172         doubleVal = Util::stringToDouble(val);
00173       }
00174       catch (facilities::WrongType ex) {
00175         return false;
00176       }
00177       if (m_restrict == RESTRICTnonneg) return (doubleVal  >= 0.0 );
00178       else if (m_restrict == RESTRICTpos) return (doubleVal > 0.0);
00179       else if (m_restrict == RESTRICTinterval) {
00180         double min = Util::stringToDouble(m_min);
00181         double max = Util::stringToDouble(m_max);
00182         return ((min <= doubleVal) && (doubleVal <= max));
00183       }
00184       return true;
00185 
00186     }
00187 
00188     case TYPEint:
00189     case TYPEmediumint:
00190     case TYPEsmallint: {
00191       int intVal;
00192 
00193       try {
00194         intVal = Util::stringToInt(val);
00195       }
00196       catch (facilities::WrongType ex) {
00197         return false;
00198       }
00199       return ((intVal >= m_minInt) && (intVal <= m_maxInt));
00200     }
00201     case TYPEvarchar:
00202     case TYPEchar:
00203       if (m_restrict == RESTRICTnone) return true;
00204       // for now, don't attempt to parse file path
00205       if (m_restrict == RESTRICTfile) return true;  
00206       if (!m_enum->choicesRequired()) return true;
00207     case TYPEenum: {
00208       unsigned nChoice = m_enum->getChoices().size();
00209       for (unsigned i = 0; i < nChoice; i++) {
00210         if (val == m_enum->getChoices()[i]) return true;
00211       }
00212       return false;
00213     }
00214     case TYPEdatetime:
00215     case TYPEtimestamp: {
00216       try {
00217         facilities::Timestamp aTime(val);
00218         if (m_restrict == RESTRICTinterval) {
00219           facilities::Timestamp min(m_min);
00220           facilities::Timestamp max(m_max);
00221           return ((min <= aTime) && (aTime <= max));
00222         }
00223         return true;
00224       }
00225       catch (facilities::BadTimeInput ex) {
00226         std::cerr << "From rdbModel::Datatype::okValue" << std::endl;
00227         std::cerr << ex.complaint << std::endl;
00228         return false;
00229       }
00230 
00231     }
00232     default:
00233       return false;
00234     }
00235   }
00236 
00237   bool Datatype::isCompatible(const Datatype* other) const {
00238     // The ten distinct types can be partitioned into 4 sorts: integer,
00239     // real, character, and date.  Call two types compatible if they're
00240     // in the same partition.
00241     return (findTOT(m_type) == findTOT(other->m_type));
00242   }
00243 }

Generated on Tue Nov 29 22:57:56 2016 for BOSS_7.0.2 by  doxygen 1.4.7