BOSS 8.0.0
BESIII Offline Software System
Loading...
Searching...
No Matches
Datatype.cxx
Go to the documentation of this file.
1// $Header: /bes/bes/BossCvs/Calibration/rdbModel/src/Tables/Datatype.cxx,v 1.1.1.1 2005/10/17
2// 06:10:53 maqm Exp $
3#include "rdbModel/Tables/Datatype.h"
4#include "facilities/Timestamp.h"
5#include "facilities/Util.h"
6#include <iostream>
7
8namespace {
9
11
12 bool initDone = false;
13 const unsigned int N_SUPPORTED_TYPES = rdbModel::Datatype::TYPEchar + 1;
14 std::string typenames[N_SUPPORTED_TYPES];
15 void init() {
16 if ( !initDone )
17 {
18 typenames[Datatype::TYPEenum] = std::string( "enum" );
19 typenames[Datatype::TYPEdatetime] = std::string( "datetime" );
20 typenames[Datatype::TYPEtimestamp] = std::string( "timestamp" );
21 typenames[Datatype::TYPEint] = std::string( "int" );
22 typenames[Datatype::TYPEmediumint] = std::string( "mediumint" );
23 typenames[Datatype::TYPEsmallint] = std::string( "smallint" );
24 typenames[Datatype::TYPEreal] = std::string( "real" );
25 typenames[Datatype::TYPEdouble] = std::string( "double" );
26 typenames[Datatype::TYPEvarchar] = std::string( "varchar" );
27 typenames[Datatype::TYPEchar] = std::string( "char" );
28 initDone = true;
29 }
30 }
31 int findType( std::string aType ) {
32 if ( !initDone ) init();
33 for ( unsigned int i = 0; i < N_SUPPORTED_TYPES; i++ )
34 {
35 if ( aType == typenames[i] ) return i;
36 }
37 return (int)Datatype::TYPEnotFound;
38 }
39 enum TYPE_OF_TYPE { TOTinteger = 0, TOTreal, TOTchar, TOTdate };
40 int findTOT( Datatype::TYPES aType ) {
41 if ( ( aType == Datatype::TYPEint ) || ( aType == Datatype::TYPEmediumint ) ||
42 ( aType == Datatype::TYPEsmallint ) )
43 return TOTinteger;
44 else if ( ( aType == Datatype::TYPEreal ) || ( aType == Datatype::TYPEdouble ) )
45 return TOTreal;
46 else if ( ( aType == Datatype::TYPEdatetime ) || ( aType == Datatype::TYPEtimestamp ) )
47 return TOTdate;
48 else return TOTchar;
49 }
50
51} // namespace
52
53namespace rdbModel {
54
55 int Datatype::setType( std::string name ) {
56 m_type = (TYPES)findType( name );
57 if ( m_type >= 0 ) { m_typename = name; }
58
59 // Set up initial restrictions for integer-like types. These
60 // values come from the MySQL doc. See e.g.
61 // http://www.mysql.com/documentation/mysql/bychapter/manual_Column_types.html#Numeric_types
62 switch ( m_type )
63 {
64 case TYPEint: {
65 m_maxInt = 2147483647;
66 m_minInt = -2147483647;
67 m_isInt = true;
68 break;
69 }
70 case TYPEmediumint: {
71 m_maxInt = 8388607;
72 m_minInt = -8388608;
73 m_isInt = true;
74 break;
75 }
76 case TYPEsmallint: {
77 m_maxInt = 32767;
78 m_minInt = -32768;
79 m_isInt = true;
80 break;
81 }
82 default: break;
83 }
84 return m_type;
85 }
86
87 // Makes sense only for numeric types or for datetime [or timestamp]
88 bool Datatype::setInterval( const std::string& min, const std::string& max ) {
89 bool ret = false;
90 // if ((m_type == TYPEtimestamp) || (m_type == TYPEenum) ||
91 if ( ( m_type == TYPEenum ) || ( m_type == TYPEchar ) || ( m_type == TYPEvarchar ) )
92 {
93 std::cerr << "From rdbModel::Datatype::setInterval " << std::endl;
94 std::cerr << "Cannot set interval restriction for type " << typenames[m_type]
95 << std::endl;
96 return false;
97 }
98
99 m_restrict = RESTRICTinterval;
100 m_min = min;
101 m_max = max;
102
103 // In case data is some integer type, convert min and max to integers,
104 // store. Return false if anything about them is unreasonable.
105 if ( m_isInt )
106 {
107 try
108 {
109 int minInt = facilities::Util::stringToInt( min );
110 int maxInt = facilities::Util::stringToInt( max );
111 if ( minInt > m_minInt ) m_minInt = minInt;
112 if ( maxInt < m_maxInt ) m_maxInt = maxInt;
113 } catch ( facilities::WrongType ex )
114 {
115 std::cerr << "Error detected in XercesBuilder::buildDatatype " << std::endl;
116 std::cerr << ex.getMsg() << std::endl;
117 return false;
118 }
119 ret = ( m_min < m_max );
120 }
121 // Don't expect to encounter interval restriction for floating point,
122 // so don't bother to cache values, but at least check for validity
123 if ( ( m_type == TYPEdouble ) || ( m_type == TYPEreal ) )
124 {
125 try
126 {
127 double minFloat = facilities::Util::stringToDouble( min );
128 double maxFloat = facilities::Util::stringToDouble( max );
129 ret = ( minFloat < maxFloat );
130 } catch ( facilities::WrongType ex )
131 {
132 std::cerr << "Error detected in XercesBuilder::buildDatatype " << std::endl;
133 std::cerr << ex.getMsg() << std::endl;
134 return false;
135 }
136 }
137 if ( m_type == TYPEdatetime )
138 {
139 try
140 {
141 facilities::Timestamp minTime( min );
142 facilities::Timestamp maxTime( max );
143 ret = ( minTime < maxTime );
144 } catch ( facilities::BadTimeInput ex )
145 {
146 std::cerr << "From rdbModel::Datatype::setInterval" << std::endl;
147 std::cerr << ex.complaint << std::endl;
148 return false;
149 }
150 }
151 return ret;
152 }
153
154 bool Datatype::getInterval( std::string& min, std::string& max ) {
155 if ( m_restrict == RESTRICTinterval )
156 {
157 min = m_min;
158 max = m_max;
159 return true;
160 }
161 return false;
162 }
163
164 bool Datatype::okValue( const std::string& val ) const {
165 using facilities::Util;
166
167 switch ( m_type )
168 {
169 case TYPEreal:
170 case TYPEdouble: {
171 double doubleVal;
172 try
173 { doubleVal = Util::stringToDouble( val ); } catch ( facilities::WrongType ex )
174 { return false; }
175 if ( m_restrict == RESTRICTnonneg ) return ( doubleVal >= 0.0 );
176 else if ( m_restrict == RESTRICTpos ) return ( doubleVal > 0.0 );
177 else if ( m_restrict == RESTRICTinterval )
178 {
179 double min = Util::stringToDouble( m_min );
180 double max = Util::stringToDouble( m_max );
181 return ( ( min <= doubleVal ) && ( doubleVal <= max ) );
182 }
183 return true;
184 }
185
186 case TYPEint:
187 case TYPEmediumint:
188 case TYPEsmallint: {
189 int intVal;
190
191 try
192 { intVal = Util::stringToInt( val ); } catch ( facilities::WrongType ex )
193 { return false; }
194 return ( ( intVal >= m_minInt ) && ( intVal <= m_maxInt ) );
195 }
196 case TYPEvarchar:
197 case TYPEchar:
198 if ( m_restrict == RESTRICTnone ) return true;
199 // for now, don't attempt to parse file path
200 if ( m_restrict == RESTRICTfile ) return true;
201 if ( !m_enum->choicesRequired() ) return true;
202 case TYPEenum: {
203 unsigned nChoice = m_enum->getChoices().size();
204 for ( unsigned i = 0; i < nChoice; i++ )
205 {
206 if ( val == m_enum->getChoices()[i] ) return true;
207 }
208 return false;
209 }
210 case TYPEdatetime:
211 case TYPEtimestamp: {
212 try
213 {
214 facilities::Timestamp aTime( val );
215 if ( m_restrict == RESTRICTinterval )
216 {
217 facilities::Timestamp min( m_min );
218 facilities::Timestamp max( m_max );
219 return ( ( min <= aTime ) && ( aTime <= max ) );
220 }
221 return true;
222 } catch ( facilities::BadTimeInput ex )
223 {
224 std::cerr << "From rdbModel::Datatype::okValue" << std::endl;
225 std::cerr << ex.complaint << std::endl;
226 return false;
227 }
228 }
229 default: return false;
230 }
231 }
232
233 bool Datatype::isCompatible( const Datatype* other ) const {
234 // The ten distinct types can be partitioned into 4 sorts: integer,
235 // real, character, and date. Call two types compatible if they're
236 // in the same partition.
237 return ( findTOT( m_type ) == findTOT( other->m_type ) );
238 }
239} // namespace rdbModel
#define min(a, b)
#define max(a, b)
static double stringToDouble(const std::string &InStr)
static int stringToInt(const std::string &InStr)
Exception class used when converting from string to numeric type.
bool okValue(const std::string &val) const
Definition Datatype.cxx:164
bool getInterval(std::string &min, std::string &max)
Definition Datatype.cxx:154
bool isCompatible(const Datatype *other) const
Definition Datatype.cxx:233