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