oqlcast.cc

00001 /* 
00002    EyeDB Object Database Management System
00003    Copyright (C) 1994-2008 SYSRA
00004    
00005    EyeDB is free software; you can redistribute it and/or
00006    modify it under the terms of the GNU Lesser General Public
00007    License as published by the Free Software Foundation; either
00008    version 2.1 of the License, or (at your option) any later version.
00009    
00010    EyeDB is distributed in the hope that it will be useful,
00011    but WITHOUT ANY WARRANTY; without even the implied warranty of
00012    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00013    Lesser General Public License for more details.
00014    
00015    You should have received a copy of the GNU Lesser General Public
00016    License along with this library; if not, write to the Free Software
00017    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA 
00018 */
00019 
00020 /*
00021    Author: Eric Viara <viara@sysra.com>
00022 */
00023 
00024 
00025 #include <unistd.h>
00026 #include <fcntl.h>
00027 #include <wctype.h>
00028 #include <sys/stat.h>
00029 
00030 #include "oql_p.h"
00031 
00032 namespace eyedb {
00033 
00034 // +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
00035 //
00036 // oqmlStringOp methods
00037 //
00038 // +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
00039 
00040 oqmlStringOp::oqmlStringOp(oqmlNode * _ql) : oqmlNode(oqmlSTRINGOP)
00041 {
00042   ql = _ql;
00043   eval_type.type = oqmlATOM_STRING;
00044   eval_type.cls = 0;
00045   eval_type.comp = oqml_True;
00046 }
00047 
00048 oqmlStringOp::~oqmlStringOp()
00049 {
00050 }
00051 
00052 oqmlStatus *oqmlStringOp::compile(Database *db, oqmlContext *ctx)
00053 {
00054   oqmlStatus *s;
00055 
00056   s = ql->compile(db, ctx);
00057 
00058   if (s)
00059     return s;
00060 
00061   return oqmlSuccess;
00062 }
00063 
00064 oqmlStatus *oqmlStringOp::eval(Database *db, oqmlContext *ctx, oqmlAtomList **alist, oqmlComp *, oqmlAtom *)
00065 {
00066   oqmlStatus *s;
00067 
00068   oqmlAtomList *al;
00069   s = ql->eval(db, ctx, &al);
00070 
00071   if (s)
00072     return s;
00073 
00074   if (al->cnt == 1)
00075     {
00076       const char *str = al->first->getString();
00077 
00078       if (al->first->as_char())
00079         {
00080           char *x = strdup(&str[1]);
00081           x[strlen(x)-1] = 0;
00082           *alist = new oqmlAtomList(new oqmlAtom_string(x));
00083           free(x);
00084         }
00085       else
00086         *alist = new oqmlAtomList(new oqmlAtom_string(str));
00087     }
00088   else // should not
00089     *alist = new oqmlAtomList(new oqmlAtom_string(al->getString()));
00090 
00091   return oqmlSuccess;
00092 }
00093 
00094 void oqmlStringOp::evalType(Database *db, oqmlContext *ctx, oqmlAtomType *at)
00095 {
00096   *at = eval_type;
00097 }
00098 
00099 oqmlBool oqmlStringOp::isConstant() const
00100 {
00101   return OQMLBOOL(ql->isConstant());
00102 }
00103 
00104 std::string
00105 oqmlStringOp::toString(void) const
00106 {
00107   return std::string("(string ") + ql->toString() + ")";
00108 }
00109 
00110 // ---------------------------------------------------------------------------
00111 //
00112 // STD_CAST_EVAL: macro used by IntOp, CharOp and FloatOp cast operators
00113 //
00114 // ---------------------------------------------------------------------------
00115 
00116 #define STD_CAST_EVAL(ATOM_CONSTRUCT, ASC2ATOM) \
00117  \
00118   oqmlStatus *s; \
00119  \
00120   oqmlAtomList *al; \
00121   s = ql->eval(db, ctx, &al); \
00122  \
00123   if (s) \
00124     return s; \
00125  \
00126   if (al->cnt > 1) \
00127     return oqmlStatus::expected(this, "integer, character, float or string", \
00128                                 al->first->type.getString()); \
00129  \
00130   if (!al->cnt) \
00131     return new oqmlStatus(this, "integer, character, float or string expected"); \
00132   oqmlAtom *a = al->first; \
00133  \
00134   if (a->as_int()) \
00135     *alist = new oqmlAtomList(new ATOM_CONSTRUCT(OQML_ATOM_INTVAL(a))); \
00136   else if (a->as_char()) \
00137     *alist = new oqmlAtomList(new ATOM_CONSTRUCT(OQML_ATOM_CHARVAL(a))); \
00138   else if (a->as_double()) \
00139     *alist = new oqmlAtomList(new ATOM_CONSTRUCT(OQML_ATOM_DBLVAL(a))); \
00140   else if (a->as_string()) \
00141     *alist = new oqmlAtomList(new ATOM_CONSTRUCT(ASC2ATOM(OQML_ATOM_STRVAL(a)))); \
00142   else \
00143     return oqmlStatus::expected(this, "integer, character, float or string", \
00144                                 a->type.getString()); \
00145  \
00146   return oqmlSuccess
00147 
00148 // +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
00149 //
00150 // oqmlIntOp methods
00151 //
00152 // +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
00153 
00154 oqmlIntOp::oqmlIntOp(oqmlNode * _ql) : oqmlNode(oqmlINTOP)
00155 {
00156   ql = _ql;
00157   eval_type.type = oqmlATOM_INT;
00158   eval_type.cls = 0;
00159 }
00160 
00161 oqmlIntOp::~oqmlIntOp()
00162 {
00163 }
00164 
00165 oqmlStatus *oqmlIntOp::compile(Database *db, oqmlContext *ctx)
00166 {
00167   return ql->compile(db, ctx);
00168 }
00169 
00170 oqmlStatus *oqmlIntOp::eval(Database *db, oqmlContext *ctx, oqmlAtomList **alist, oqmlComp *, oqmlAtom *)
00171 {
00172   STD_CAST_EVAL(oqmlAtom_int, atoi);
00173 }
00174 
00175 void oqmlIntOp::evalType(Database *db, oqmlContext *ctx, oqmlAtomType *at)
00176 {
00177   *at = eval_type;
00178 }
00179 
00180 oqmlBool oqmlIntOp::isConstant() const
00181 {
00182   return OQMLBOOL(ql->isConstant());
00183 }
00184 
00185 std::string
00186 oqmlIntOp::toString(void) const
00187 {
00188   return std::string("(int ") + ql->toString() + ")";
00189 }
00190 
00191 // +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
00192 //
00193 // oqmlCharOp methods
00194 //
00195 // +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
00196 
00197 oqmlCharOp::oqmlCharOp(oqmlNode * _ql) : oqmlNode(oqmlCHAROP)
00198 {
00199   ql = _ql;
00200   eval_type.type = oqmlATOM_CHAR;
00201   eval_type.cls = 0;
00202 }
00203 
00204 oqmlCharOp::~oqmlCharOp()
00205 {
00206 }
00207 
00208 oqmlStatus *oqmlCharOp::compile(Database *db, oqmlContext *ctx)
00209 {
00210   return ql->compile(db, ctx);
00211 }
00212 
00213 static char
00214 atoc(const char *s)
00215 {
00216   return strlen(s) == 1 ? s[0] : 0;
00217 }
00218 
00219 oqmlStatus *oqmlCharOp::eval(Database *db, oqmlContext *ctx, oqmlAtomList **alist, oqmlComp *, oqmlAtom *)
00220 {
00221   STD_CAST_EVAL(oqmlAtom_char, atoc);
00222 }
00223 
00224 void oqmlCharOp::evalType(Database *db, oqmlContext *ctx, oqmlAtomType *at)
00225 {
00226   *at = eval_type;
00227 }
00228 
00229 oqmlBool oqmlCharOp::isConstant() const
00230 {
00231   return OQMLBOOL(ql->isConstant());
00232 }
00233 
00234 std::string
00235 oqmlCharOp::toString(void) const
00236 {
00237   return std::string("(char ") + ql->toString() + ")";
00238 }
00239 
00240 // +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
00241 //
00242 // oqmlFloatOp methods
00243 //
00244 // +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
00245 
00246 oqmlFloatOp::oqmlFloatOp(oqmlNode * _ql) : oqmlNode(oqmlFLOATOP)
00247 {
00248   ql = _ql;
00249   eval_type.type = oqmlATOM_DOUBLE;
00250   eval_type.cls = 0;
00251 }
00252 
00253 oqmlFloatOp::~oqmlFloatOp()
00254 {
00255 }
00256 
00257 oqmlStatus *oqmlFloatOp::compile(Database *db, oqmlContext *ctx)
00258 {
00259   return ql->compile(db, ctx);
00260 }
00261 
00262 oqmlStatus *oqmlFloatOp::eval(Database *db, oqmlContext *ctx, oqmlAtomList **alist, oqmlComp *, oqmlAtom *)
00263 {
00264   STD_CAST_EVAL(oqmlAtom_double, atof);
00265 }
00266 
00267 void oqmlFloatOp::evalType(Database *db, oqmlContext *ctx, oqmlAtomType *at)
00268 {
00269   *at = eval_type;
00270 }
00271 
00272 oqmlBool oqmlFloatOp::isConstant() const
00273 {
00274   return OQMLBOOL(ql->isConstant());
00275 }
00276 
00277 std::string
00278 oqmlFloatOp::toString(void) const
00279 {
00280   return std::string("(float ") + ql->toString() + ")";
00281 }
00282 
00283 // +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
00284 //
00285 // oqmlIdentOp methods
00286 //
00287 // +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
00288 
00289 oqmlIdentOp::oqmlIdentOp(oqmlNode * _ql) : oqmlNode(oqmlIDENTOP)
00290 {
00291   ql = _ql;
00292   eval_type.type = oqmlATOM_IDENT;
00293   eval_type.cls = 0;
00294 }
00295 
00296 oqmlIdentOp::~oqmlIdentOp()
00297 {
00298 }
00299 
00300 oqmlStatus *oqmlIdentOp::compile(Database *db, oqmlContext *ctx)
00301 {
00302   return ql->compile(db, ctx);
00303 }
00304 
00305 oqmlStatus *oqmlIdentOp::eval(Database *db, oqmlContext *ctx, oqmlAtomList **alist, oqmlComp *, oqmlAtom *)
00306 {
00307   oqmlStatus *s;
00308 
00309   oqmlAtomList *al;
00310   s = ql->eval(db, ctx, &al);
00311 
00312   if (s)
00313     return s;
00314 
00315   if (al->cnt > 1)
00316     return oqmlStatus::expected(this, "string", al->first->type.getString());
00317 
00318   if (!al->cnt)
00319     return new oqmlStatus(this, "string expected");
00320 
00321   oqmlAtom *a = al->first;
00322 
00323   if (a->as_string())
00324     *alist = new oqmlAtomList(new oqmlAtom_ident(OQML_ATOM_STRVAL(a)));
00325   else if (a->as_ident())
00326     *alist = new oqmlAtomList(a);
00327   else
00328     return oqmlStatus::expected(this, "string", a->type.getString());
00329   return oqmlSuccess;
00330 }
00331 
00332 void oqmlIdentOp::evalType(Database *db, oqmlContext *ctx, oqmlAtomType *at)
00333 {
00334   *at = eval_type;
00335 }
00336 
00337 oqmlBool oqmlIdentOp::isConstant() const
00338 {
00339   return OQMLBOOL(ql->isConstant());
00340 }
00341 
00342 std::string
00343 oqmlIdentOp::toString(void) const
00344 {
00345   return std::string("(ident ") + ql->toString() + ")";
00346 }
00347 
00348 // +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
00349 //
00350 // oqmlIdentOp methods
00351 //
00352 // +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
00353 
00354 oqmlOidOp::oqmlOidOp(oqmlNode * _ql) : oqmlNode(oqmlOIDOP)
00355 {
00356   ql = _ql;
00357   eval_type.type = oqmlATOM_OID;
00358   eval_type.cls = 0;
00359 }
00360 
00361 oqmlOidOp::~oqmlOidOp()
00362 {
00363 }
00364 
00365 oqmlStatus *oqmlOidOp::compile(Database *db, oqmlContext *ctx)
00366 {
00367   return ql->compile(db, ctx);
00368 }
00369 
00370 oqmlStatus *oqmlOidOp::eval(Database *db, oqmlContext *ctx, oqmlAtomList **alist, oqmlComp *, oqmlAtom *)
00371 {
00372   oqmlStatus *s;
00373 
00374   oqmlAtomList *al;
00375   s = ql->eval(db, ctx, &al);
00376 
00377   if (s)
00378     return s;
00379 
00380   if (al->cnt > 1)
00381     return oqmlStatus::expected(this, "string", al->first->type.getString());
00382 
00383   if (!al->cnt)
00384     return new oqmlStatus(this, "string expected");
00385 
00386   oqmlAtom *a = al->first;
00387 
00388   if (a->as_string())
00389     *alist = new oqmlAtomList(new oqmlAtom_oid(Oid(OQML_ATOM_STRVAL(a))));
00390   else if (a->as_oid())
00391     *alist = new oqmlAtomList(a);
00392   else
00393     return oqmlStatus::expected(this, "string", a->type.getString());
00394 
00395   return oqmlSuccess;
00396 }
00397 
00398 void oqmlOidOp::evalType(Database *db, oqmlContext *ctx, oqmlAtomType *at)
00399 {
00400   *at = eval_type;
00401 }
00402 
00403 oqmlBool oqmlOidOp::isConstant() const
00404 {
00405   return OQMLBOOL(ql->isConstant());
00406 }
00407 
00408 std::string
00409 oqmlOidOp::toString(void) const
00410 {
00411   return std::string("(oid ") + ql->toString() + ")";
00412 }
00413 
00414 }

Generated on Mon Dec 22 18:16:01 2008 for eyedb by  doxygen 1.5.3