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
00028 #include <coconut_config.h>
00029 #include <interval.h>
00030 #include <dbcompare.h>
00031 #include <sstream>
00032
00033 #include "dbcompare_expression_scanner.hh"
00034 #include "dbcompare_sortorder_scanner.hh"
00035
00036 namespace coco {
00037
00038 template <typename _TR>
00039 bool eval_in(const vdbl::rowid& rid, const std::string& colname,
00040 dbc_method tp, vdbl::view* iv, _TR, const basic_alltype& I)
00041 {
00042 bool ret(false);
00043 _TR _help;
00044 interval II;
00045
00046 if(iv->get(rid, colname, _help))
00047 {
00048 if(I.contents_type() == ALLTYPE_INTERVAL)
00049 II = I.ni();
00050 else switch(I.contents_type())
00051 {
00052 case ALLTYPE_ALLOCED_N:
00053 if(I.n().size() != 2)
00054 throw api_exception(apiee_other, std::string("Error in eval_in: ")+
00055 "interval vector size != 2!");
00056 II = interval(I.n()[0], I.n()[1]);
00057 break;
00058 case ALLTYPE_ALLOCED_U:
00059 if(I.u().size() != 2)
00060 throw api_exception(apiee_other, std::string("Error in eval_in: ")+
00061 "interval vector size != 2!");
00062 II = interval(I.u()[0], I.u()[1]);
00063 break;
00064 case ALLTYPE_ALLOCED_D:
00065 if(I.d().size() != 2)
00066 throw api_exception(apiee_other, std::string("Error in eval_in: ")+
00067 "interval vector size != 2!");
00068 II = interval(I.d()[0], I.d()[1]);
00069 break;
00070 default:
00071 throw api_exception(apiee_other, std::string("Error in eval_in: ")+
00072 I.type_name()+" is a wrong type for interval comparison!");
00073 }
00074 if(tp == dbc_cmp_in)
00075 ret = II.contains((double)_help);
00076 else if(tp == dbc_cmp_absin)
00077 ret = II.contains(dbccmps_abs((double)_help));
00078 else
00079 throw api_exception(apiee_other, std::string("Error in eval_in: ")+
00080 convert_to_str(tp)+" is a wrong comparison type!");
00081 }
00082 return ret;
00083 }
00084
00085 template <>
00086 bool eval_in<interval>(const vdbl::rowid& rid, const std::string& colname,
00087 dbc_method tp, vdbl::view* iv, interval, const basic_alltype& I)
00088 {
00089 bool ret(false);
00090 interval _help;
00091
00092 if(iv->get(rid, colname, _help))
00093 {
00094 if(tp == dbc_cmp_in)
00095 ret = I.ni().superset(_help);
00096 else if(tp == dbc_cmp_absin)
00097 ret = I.ni().superset(abs(_help));
00098 else
00099 throw api_exception(apiee_other, std::string("Error in eval_in: ")+
00100 convert_to_str(tp)+" is a wrong comparison type!");
00101 }
00102 return ret;
00103 }
00104
00105 template <>
00106 bool eval_in<std::string>(const vdbl::rowid& rid, const std::string& colname,
00107 dbc_method tp, vdbl::view* iv, std::string, const basic_alltype& I)
00108 {
00109 bool ret(false);
00110 std::string _help;
00111
00112 if(iv->get(rid, colname, _help))
00113 {
00114 if(I.sv().size() != 2)
00115 throw api_exception(apiee_other, std::string("Error in eval_in: ")+
00116 "interval vector size != 2!");
00117 if(tp == dbc_cmp_in || tp == dbc_cmp_absin)
00118 ret = I.sv()[0] <= _help && _help <= I.sv()[1];
00119 else
00120 throw api_exception(apiee_other, std::string("Error in eval_in: ")+
00121 convert_to_str(tp)+" is a wrong comparison type!");
00122 }
00123 return ret;
00124 }
00125
00126 template <typename _TR>
00127 bool eval_s(const vdbl::rowid& rid, const std::string& colname,
00128 dbc_method tp, vdbl::view* iv, _TR cmpval)
00129 {
00130 _TR _help;
00131 bool ret(false);
00132
00133 if(iv->get(rid, colname, _help))
00134 {
00135 switch(tp)
00136 {
00137 case dbc_cmp_eq:
00138 if(_help == cmpval)
00139 ret = true;
00140 break;
00141 case dbc_cmp_ne:
00142 if(_help != cmpval)
00143 ret = true;
00144 break;
00145 case dbc_cmp_gt:
00146 if(_help > cmpval)
00147 ret = true;
00148 break;
00149 case dbc_cmp_ge:
00150 if(_help >= cmpval)
00151 ret = true;
00152 break;
00153 case dbc_cmp_lt:
00154 if(_help < cmpval)
00155 ret = true;
00156 break;
00157 case dbc_cmp_le:
00158 if(_help <= cmpval)
00159 ret = true;
00160 break;
00161 case dbc_cmp_abseq:
00162 if(dbccmps_abs(_help) == dbccmps_abs(cmpval))
00163 ret = true;
00164 break;
00165 case dbc_cmp_absne:
00166 if(dbccmps_abs(_help) != dbccmps_abs(cmpval))
00167 ret = true;
00168 break;
00169 case dbc_cmp_absgt:
00170 if(dbccmps_abs(_help) > dbccmps_abs(cmpval))
00171 ret = true;
00172 break;
00173 case dbc_cmp_absge:
00174 if(dbccmps_abs(_help) >= dbccmps_abs(cmpval))
00175 ret = true;
00176 break;
00177 case dbc_cmp_abslt:
00178 if(dbccmps_abs(_help) < dbccmps_abs(cmpval))
00179 ret = true;
00180 break;
00181 case dbc_cmp_absle:
00182 if(dbccmps_abs(_help) <= dbccmps_abs(cmpval))
00183 ret = true;
00184 break;
00185 default:
00186 throw api_exception(apiee_other, std::string("Error in eval_s: ")+
00187 convert_to_str(tp)+" is a wrong comparison type!");
00188 break;
00189 }
00190 }
00191 return ret;
00192 }
00193
00194 template <>
00195 bool eval_s<interval>(const vdbl::rowid& rid, const std::string& colname,
00196 dbc_method tp, vdbl::view* iv, interval cmpval)
00197 {
00198 interval _help;
00199 bool ret(false);
00200
00201 if(iv->get(rid, colname, _help))
00202 {
00203 switch(tp)
00204 {
00205 case dbc_cmp_eq:
00206 if(_help == cmpval)
00207 ret = true;
00208 break;
00209 case dbc_cmp_ne:
00210 if(_help != cmpval)
00211 ret = true;
00212 break;
00213 case dbc_cmp_gt:
00214 if(_help.inf() > cmpval.sup())
00215 ret = true;
00216 break;
00217 case dbc_cmp_ge:
00218 if(_help.inf() >= cmpval.sup())
00219 ret = true;
00220 break;
00221 case dbc_cmp_lt:
00222 if(_help.sup() < cmpval.inf())
00223 ret = true;
00224 break;
00225 case dbc_cmp_le:
00226 if(_help.sup() <= cmpval.inf())
00227 ret = true;
00228 break;
00229 case dbc_cmp_abseq:
00230 if(abs(_help) == abs(cmpval))
00231 ret = true;
00232 break;
00233 case dbc_cmp_absne:
00234 if(abs(_help) != abs(cmpval))
00235 ret = true;
00236 break;
00237 case dbc_cmp_absgt:
00238 if(abs(_help).inf() > abs(cmpval).sup())
00239 ret = true;
00240 break;
00241 case dbc_cmp_absge:
00242 if(abs(_help).inf() >= abs(cmpval).sup())
00243 ret = true;
00244 break;
00245 case dbc_cmp_abslt:
00246 if(abs(_help).sup() < abs(cmpval).inf())
00247 ret = true;
00248 break;
00249 case dbc_cmp_absle:
00250 if(abs(_help).sup() <= abs(cmpval).inf())
00251 ret = true;
00252 break;
00253 default:
00254 throw api_exception(apiee_other, std::string("Error in eval_s: ")+
00255 convert_to_str(tp)+" is a wrong comparison type!");
00256 break;
00257 }
00258 }
00259 return ret;
00260 }
00261
00262 template <typename _TR>
00263 bool eval_u(const vdbl::rowid& rid, const std::string& colname,
00264 dbc_method tp, vdbl::view* iv, _TR cmpval)
00265 {
00266 _TR _help;
00267 bool ret(false);
00268
00269 if(iv->get(rid, colname, _help))
00270 {
00271 switch(tp)
00272 {
00273 case dbc_cmp_eq:
00274 case dbc_cmp_abseq:
00275 if(_help == cmpval)
00276 ret = true;
00277 break;
00278 case dbc_cmp_ne:
00279 case dbc_cmp_absne:
00280 if(_help != cmpval)
00281 ret = true;
00282 break;
00283 case dbc_cmp_gt:
00284 case dbc_cmp_absgt:
00285 if(_help > cmpval)
00286 ret = true;
00287 break;
00288 case dbc_cmp_ge:
00289 case dbc_cmp_absge:
00290 if(_help >= cmpval)
00291 ret = true;
00292 break;
00293 case dbc_cmp_lt:
00294 case dbc_cmp_abslt:
00295 if(_help < cmpval)
00296 ret = true;
00297 break;
00298 case dbc_cmp_le:
00299 case dbc_cmp_absle:
00300 if(_help <= cmpval)
00301 ret = true;
00302 break;
00303 default:
00304 throw api_exception(apiee_other, std::string("Error in eval_s: ")+
00305 convert_to_str(tp)+" is a wrong comparison type!");
00306 break;
00307 }
00308 }
00309 return ret;
00310 }
00311
00312 bool eval(const vdbl::rowid& rid, const std::string& colname,
00313 dbc_method tp, vdbl::view* iv, const basic_alltype& cmpval)
00314 {
00315 bool res(false);
00316 const char *tyn = iv->get_coltype(colname).name();
00317
00318 if(!strcmp(typeid(double).name(), tyn))
00319 {
00320 if(tp == dbc_cmp_in || tp == dbc_cmp_absin)
00321 res = eval_in(rid, colname, tp, iv, 0.0, cmpval);
00322 else
00323 res = eval_s(rid, colname, tp, iv, cmpval.nd());
00324 }
00325 else if(!strcmp(typeid(long int).name(), tyn))
00326 {
00327 if(tp == dbc_cmp_in || tp == dbc_cmp_absin)
00328 res = eval_in(rid, colname, tp, iv, 0L, cmpval);
00329 else
00330 res = eval_s(rid, colname, tp, iv, (long int)cmpval.nn());
00331 }
00332 else if(!strcmp(typeid(unsigned long int).name(), tyn))
00333 {
00334 if(tp == dbc_cmp_in || tp == dbc_cmp_absin)
00335 res = eval_in(rid, colname, tp, iv, 0UL, cmpval);
00336 else
00337 res = eval_u(rid, colname, tp, iv,
00338 (unsigned long int)cmpval.nu());
00339 }
00340 else if(!strcmp(typeid(search_node_id).name(), tyn))
00341 {
00342 if(tp == dbc_cmp_in || tp == dbc_cmp_absin)
00343 res = eval_in(rid, colname, tp, iv, search_node_id(),
00344 cmpval);
00345 else
00346 res = eval_u(rid, colname, tp, iv,
00347 (search_node_id)cmpval.nu());
00348 }
00349 else if(!strcmp(typeid(bool).name(), tyn))
00350 res = eval_u(rid, colname, tp, iv, cmpval.nb());
00351 else if(!strcmp(typeid(int).name(), tyn))
00352 {
00353 if(tp == dbc_cmp_in || tp == dbc_cmp_absin)
00354 res = eval_in(rid, colname, tp, iv, 0, cmpval);
00355 else
00356 res = eval_s(rid, colname, tp, iv, cmpval.nn());
00357 }
00358 else if(!strcmp(typeid(unsigned int).name(), tyn))
00359 {
00360 if(tp == dbc_cmp_in || tp == dbc_cmp_absin)
00361 res = eval_in(rid, colname, tp, iv, 0U, cmpval);
00362 else
00363 res = eval_u(rid, colname, tp, iv, cmpval.nu());
00364 }
00365 else if(!strcmp(typeid(interval).name(), tyn))
00366 {
00367 if(tp == dbc_cmp_in || tp == dbc_cmp_absin)
00368 res = eval_in(rid, colname, tp, iv, interval(), cmpval);
00369 else
00370 res = eval_s(rid, colname, tp, iv, cmpval.ni());
00371 }
00372 else if(!strcmp(typeid(std::string).name(), tyn))
00373 {
00374 if(tp == dbc_cmp_in || tp == dbc_cmp_absin)
00375 res = eval_in(rid, colname, tp, iv, std::string(), cmpval);
00376 else
00377 res = eval_u(rid, colname, tp, iv, cmpval.s());
00378 }
00379 else
00380 throw api_exception(apiee_other,
00381 std::string("Error in eval: don't know how to handle type ")+
00382 iv->get_coltype(colname).name() + "!");
00383 return res;
00384 }
00385
00386 void parse_dbcompare_expression(const std::string& s,
00387 std::map<int,std::triple<std::string, dbc_method, basic_alltype> >& cols,
00388 std::vector<std::vector<int> >& expr)
00389 {
00390 std::string errormsg;
00391 coco_api_internal::dbcompare_expression_scanner scanner(errormsg);
00392 std::istringstream sstr(s);
00393 int i = 1;
00394 scanner.switch_streams(&sstr, static_cast<std::ostream*>(NULL));
00395 coco_api_internal::dbcompare_expression_parser parser(scanner, cols, expr, i, errormsg);
00396 if (parser.parse()) throw api_exception(apiee_other, errormsg);
00397 }
00398
00399 void parse_dbcompare_sortorder(const std::string& s,
00400 std::map<int,std::triple<std::string, dbc_method, basic_alltype> >& cols,
00401 std::vector<int>& order)
00402 {
00403 std::string errormsg;
00404 coco_api_internal::dbcompare_sortorder_scanner scanner(errormsg);
00405 std::istringstream sstr(s);
00406 int i = 1;
00407 scanner.switch_streams(&sstr, static_cast<std::ostream*>(NULL));
00408 coco_api_internal::dbcompare_sortorder_parser parser(scanner, cols, order, i, errormsg);
00409 if (parser.parse()) throw api_exception(apiee_other, errormsg);
00410 }
00411
00412 }