oqlatom.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 <math.h>
00026 #include <ctype.h>
00027 #include "oql_p.h"
00028 
00029 // +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
00030 //
00031 // oqmlString operator methods
00032 //
00033 // +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
00034 
00035 namespace eyedb {
00036 
00037   oqmlString::oqmlString(const char * _s) : oqmlNode(oqmlSTRING)
00038   {
00039     s = strdup(_s);
00040     eval_type.type = oqmlATOM_STRING;
00041     eval_type.cls = 0;
00042     eval_type.comp = oqml_True;
00043   }
00044 
00045   oqmlString::~oqmlString()
00046   {
00047     free(s);
00048   }
00049 
00050   oqmlStatus *oqmlString::compile(Database *db, oqmlContext *ctx)
00051   {
00052     return oqmlSuccess;
00053   }
00054 
00055   oqmlStatus *oqmlString::eval(Database *db, oqmlContext *ctx, oqmlAtomList **alist, oqmlComp *, oqmlAtom *)
00056   {
00057     *alist = new oqmlAtomList(new oqmlAtom_string(s));
00058     return oqmlSuccess;
00059   }
00060 
00061   void oqmlString::evalType(Database *db, oqmlContext *ctx, oqmlAtomType *at)
00062   {
00063     *at = eval_type;
00064   }
00065 
00066   oqmlBool oqmlString::isConstant() const
00067   {
00068     return oqml_True;
00069   }
00070 
00071   std::string
00072   oqmlString::toString(void) const
00073   {
00074     return std::string("\"") + s + "\"" + oqml_isstat();
00075   }
00076 
00077   // +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
00078   //
00079   // oqmlInt operator methods
00080   //
00081   // +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
00082 
00083   oqmlInt::oqmlInt(eyedblib::int64 _i) : oqmlNode(oqmlINT)
00084   {
00085     i = _i;
00086     eval_type.type = oqmlATOM_INT;
00087     ql = 0;
00088   }
00089 
00090   oqmlInt::oqmlInt(oqmlNode *_ql) : oqmlNode(oqmlINT)
00091   {
00092     ql = _ql;
00093     eval_type.type = oqmlATOM_INT;
00094     i = 0;
00095   }
00096 
00097   oqmlInt::~oqmlInt()
00098   {
00099   }
00100 
00101   oqmlStatus *oqmlInt::compile(Database *db, oqmlContext *ctx)
00102   {
00103     if (ql)
00104       {
00105         oqmlStatus *s;
00106 
00107         s = ql->compile(db, ctx);
00108 
00109         if (s)
00110           return s;
00111 
00112         oqmlAtomType at;
00113 
00114         ql->evalType(db, ctx, &at);
00115 
00116         if (at.type != oqmlATOM_DOUBLE &&
00117             at.type != oqmlATOM_INT &&
00118             at.type != oqmlATOM_UNKNOWN_TYPE)
00119           return new oqmlStatus("int() function expects a 'float' or an 'int'.");
00120 
00121         return oqmlSuccess;
00122       }
00123 
00124     return oqmlSuccess;
00125   }
00126 
00127   oqmlStatus *oqmlInt::eval(Database *db, oqmlContext *ctx, oqmlAtomList **alist, oqmlComp *, oqmlAtom *)
00128   {
00129     if (ql)
00130       {
00131         oqmlStatus *s;
00132         oqmlAtomList *al;
00133 
00134         *alist = new oqmlAtomList();
00135 
00136         s = ql->eval(db, ctx, &al);
00137 
00138         if (s)
00139           return s;
00140 
00141         if (al->cnt == 1)
00142           {
00143             if (al->first->type.type == oqmlATOM_INT)
00144               {
00145                 *alist = new oqmlAtomList(al->first);
00146                 return oqmlSuccess;
00147               }
00148           
00149             if (al->first->type.type == oqmlATOM_DOUBLE)
00150               {
00151                 *alist = new oqmlAtomList
00152                   (new oqmlAtom_int(floor(((oqmlAtom_double *)al->first)->d)));
00153                 return oqmlSuccess;
00154               }
00155           
00156           }
00157 
00158         return new oqmlStatus("int() function expects a 'float' or an 'int'.");
00159       }
00160 
00161     *alist = new oqmlAtomList(new oqmlAtom_int(i));
00162     return oqmlSuccess;
00163   }
00164 
00165   void oqmlInt::evalType(Database *db, oqmlContext *ctx, oqmlAtomType *at)
00166   {
00167     *at = eval_type;
00168   }
00169 
00170   oqmlBool oqmlInt::isConstant() const
00171   {
00172     return oqml_True;
00173   }
00174 
00175   std::string
00176   oqmlInt::toString(void) const
00177   {
00178     return str_convert(i) + oqml_isstat();
00179   }
00180 
00181   // +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
00182   //
00183   // oqmlChar operator methods
00184   //
00185   // +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
00186 
00187   oqmlChar::oqmlChar(char _c) : oqmlNode(oqmlCHAR)
00188   {
00189     c = _c;
00190     eval_type.type = oqmlATOM_CHAR;
00191   }
00192 
00193   oqmlChar::~oqmlChar()
00194   {
00195   }
00196 
00197   oqmlStatus *oqmlChar::compile(Database *db, oqmlContext *ctx)
00198   {
00199     return oqmlSuccess;
00200   }
00201 
00202   oqmlStatus *oqmlChar::eval(Database *db, oqmlContext *ctx, oqmlAtomList **alist, oqmlComp *, oqmlAtom *)
00203   {
00204     *alist = new oqmlAtomList(new oqmlAtom_char(c));
00205     return oqmlSuccess;
00206   }
00207 
00208   void oqmlChar::evalType(Database *db, oqmlContext *ctx, oqmlAtomType *at)
00209   {
00210     *at = eval_type;
00211   }
00212 
00213   oqmlBool oqmlChar::isConstant() const
00214   {
00215     return oqml_True;
00216   }
00217 
00218   std::string
00219   oqmlChar::toString(void) const
00220   {
00221     if (c && !iscntrl(c))
00222       return std::string("'") + str_convert(c) + "'" + oqml_isstat();
00223 
00224     return std::string("'") + str_convert(c, "\\%03o") + "'" + oqml_isstat();
00225   }
00226 
00227   // +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
00228   //
00229   // oqmlFloat operator methods
00230   //
00231   // +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
00232 
00233   oqmlFloat::oqmlFloat(double _f) : oqmlNode(oqmlFLOAT)
00234   {
00235     f = _f;
00236     eval_type.type = oqmlATOM_DOUBLE;
00237   }
00238 
00239   oqmlFloat::~oqmlFloat()
00240   {
00241   }
00242 
00243   oqmlStatus *oqmlFloat::compile(Database *db, oqmlContext *ctx)
00244   {
00245     return oqmlSuccess;
00246   }
00247 
00248   oqmlStatus *oqmlFloat::eval(Database *db, oqmlContext *ctx, oqmlAtomList **alist, oqmlComp *, oqmlAtom *)
00249   {
00250     *alist = new oqmlAtomList(new oqmlAtom_double(f));
00251     return oqmlSuccess;
00252   }
00253 
00254   void oqmlFloat::evalType(Database *db, oqmlContext *ctx, oqmlAtomType *at)
00255   {
00256     *at = eval_type;
00257   }
00258 
00259   oqmlBool oqmlFloat::isConstant() const
00260   {
00261     return oqml_True;
00262   }
00263 
00264   std::string
00265   oqmlFloat::toString(void) const
00266   {
00267     return str_convert(f) + + oqml_isstat();
00268   }
00269 
00270   // +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
00271   //
00272   // oqmlOid operator methods
00273   //
00274   // +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
00275 
00276   oqmlOid::oqmlOid(const Oid &_oid) : oqmlNode(oqmlOID)
00277   {
00278     oid = _oid;
00279     eval_type.type = oqmlATOM_OID;
00280     cls = 0;
00281     ql = 0;
00282   }
00283 
00284   oqmlOid::oqmlOid(oqmlNode *_ql) : oqmlNode(oqmlOID)
00285   {
00286     eval_type.type = oqmlATOM_OID;
00287     cls = 0;
00288     ql = _ql;
00289   }
00290 
00291   oqmlOid::~oqmlOid()
00292   {
00293     // delete ql;
00294   }
00295 
00296   oqmlStatus *oqmlOid::compile(Database *db, oqmlContext *ctx)
00297   {
00298     if (ql)
00299       {
00300         oqmlStatus *s;
00301 
00302         s = ql->compile(db, ctx);
00303 
00304         if (s)
00305           return s;
00306 
00307         oqmlAtomType at;
00308 
00309         ql->evalType(db, ctx, &at);
00310 
00311         if (at.type != oqmlATOM_STRING && at.type != oqmlATOM_UNKNOWN_TYPE)
00312           return new oqmlStatus("oid() function expects a 'string'.");
00313 
00314         return oqmlSuccess;
00315       }
00316 
00317     if (oid.isValid())
00318       return oqml_get_class(db, oid, &cls);
00319 
00320     return oqmlSuccess;
00321   }
00322 
00323   oqmlStatus *oqmlOid::eval(Database *db, oqmlContext *ctx, oqmlAtomList **alist, oqmlComp *, oqmlAtom *)
00324   {
00325     if (ql)
00326       {
00327         oqmlStatus *s;
00328         oqmlAtomList *al;
00329 
00330         *alist = new oqmlAtomList();
00331 
00332         s = ql->eval(db, ctx, &al);
00333 
00334         if (s)
00335           return s;
00336 
00337         if (al->cnt != 1 || al->first->type.type != oqmlATOM_STRING)
00338           return new oqmlStatus("oid() function expects a 'string'.");
00339 
00340         oid = Oid(OQML_ATOM_STRVAL(al->first));
00341         s = oqml_get_class(db, oid, &cls);
00342 
00343         if (s) return s;
00344         *alist = new oqmlAtomList(new oqmlAtom_oid(oid, cls));
00345 
00346         return oqmlSuccess;
00347       }
00348       
00349     *alist = new oqmlAtomList(new oqmlAtom_oid(oid, cls));
00350     return oqmlSuccess;
00351   }
00352 
00353   void oqmlOid::evalType(Database *db, oqmlContext *ctx, oqmlAtomType *at)
00354   {
00355     *at = eval_type;
00356   }
00357 
00358   oqmlBool oqmlOid::isConstant() const
00359   {
00360     return oqml_True;
00361   }
00362 
00363   std::string
00364   oqmlOid::toString(void) const
00365   {
00366     return std::string(oid.toString()) + + oqml_isstat();
00367   }
00368 
00369   // +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
00370   //
00371   // oqmlObject operator methods
00372   //
00373   // +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
00374 
00375   oqmlObject::oqmlObject(const char *_s) : oqmlNode(oqmlOBJECT)
00376   {
00377     eval_type.type = oqmlATOM_OBJ;
00378     s = strdup(_s);
00379     o = 0;
00380     idx = 0;
00381   }
00382 
00383   oqmlObject::oqmlObject(Object *_o, unsigned int _idx) : oqmlNode(oqmlOBJECT)
00384   {
00385     s = 0;
00386     o = _o;
00387     idx = _idx;
00388   }
00389 
00390   oqmlObject::oqmlObject(oqmlNode *) : oqmlNode(oqmlOBJECT)
00391   {
00392     abort();
00393   }
00394 
00395   oqmlStatus *oqmlObject::compile(Database *db, oqmlContext *ctx)
00396   {
00397     if (!o)
00398       return oqmlObjectManager::getObject(this, s, o, idx);
00399     return oqmlSuccess;
00400   }
00401 
00402   oqmlStatus *oqmlObject::eval(Database *db, oqmlContext *ctx, oqmlAtomList **alist, oqmlComp *, oqmlAtom *)
00403   {
00404     *alist = new oqmlAtomList(oqmlObjectManager::registerObject(o));
00405     return oqmlSuccess;
00406   }
00407 
00408   void
00409   oqmlObject::evalType(Database *db, oqmlContext *ctx, oqmlAtomType *at)
00410   {
00411     *at = eval_type;
00412   }
00413 
00414   oqmlBool oqmlObject::isConstant() const
00415   {
00416     return oqml_True;
00417   }
00418 
00419   std::string
00420   oqmlObject::toString() const
00421   {
00422     return (s ? std::string(s) : str_convert((long)idx, "%x") + ":obj") + oqml_isstat();;
00423   }
00424 
00425   oqmlObject::~oqmlObject()
00426   {
00427     free(s);
00428   }
00429 
00430   // +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
00431   //
00432   // oqmlNil operator methods
00433   //
00434   // +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
00435 
00436   oqmlNil::oqmlNil() : oqmlNode(oqmlNIL)
00437   {
00438   }
00439 
00440   oqmlNil::~oqmlNil()
00441   {
00442   }
00443 
00444   oqmlStatus *oqmlNil::compile(Database *db, oqmlContext *ctx)
00445   {
00446     return oqmlSuccess;
00447   }
00448 
00449   oqmlStatus *oqmlNil::eval(Database *db, oqmlContext *ctx, oqmlAtomList **alist, oqmlComp *, oqmlAtom *)
00450   {
00451     //*alist = new oqmlAtomList(); //WARNING: modified the 13/09/98
00452     //*alist = new oqmlAtomList(new oqmlAtom_nil());
00453     *alist = new oqmlAtomList(); //WARNING: remodified the 10/06/99
00454     return oqmlSuccess;
00455   }
00456 
00457   void oqmlNil::evalType(Database *db, oqmlContext *ctx, oqmlAtomType *at)
00458   {
00459     *at = eval_type;
00460   }
00461 
00462   oqmlBool oqmlNil::isConstant() const
00463   {
00464     return oqml_True;
00465   }
00466 
00467   std::string
00468   oqmlNil::toString(void) const
00469   {
00470     return std::string("nil") + oqml_isstat();;
00471   }
00472 
00473   // +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
00474   //
00475   // oqmlNull operator methods
00476   //
00477   // +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
00478 
00479   oqmlNull::oqmlNull() : oqmlNode(oqmlNULL)
00480   {
00481     eval_type.type = oqmlATOM_NULL;
00482   }
00483 
00484   oqmlNull::~oqmlNull()
00485   {
00486   }
00487 
00488   oqmlStatus *oqmlNull::compile(Database *db, oqmlContext *ctx)
00489   {
00490     return oqmlSuccess;
00491   }
00492 
00493   oqmlStatus *oqmlNull::eval(Database *db, oqmlContext *ctx, oqmlAtomList **alist, oqmlComp *, oqmlAtom *)
00494   {
00495     *alist = new oqmlAtomList(new oqmlAtom_null);
00496     return oqmlSuccess;
00497   }
00498 
00499   void oqmlNull::evalType(Database *db, oqmlContext *ctx, oqmlAtomType *at)
00500   {
00501     *at = eval_type;
00502   }
00503 
00504   oqmlBool oqmlNull::isConstant() const
00505   {
00506     return oqml_True;
00507   }
00508 
00509   std::string
00510   oqmlNull::toString(void) const
00511   {
00512     return std::string("NULL") + oqml_isstat();
00513   }
00514 
00515   // +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
00516   //
00517   // oqmlTrue operator methods
00518   //
00519   // +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
00520 
00521   oqmlTrue::oqmlTrue() : oqmlNode(oqmlTRUE)
00522   {
00523     eval_type.type = oqmlATOM_BOOL;
00524   }
00525 
00526   oqmlTrue::~oqmlTrue()
00527   {
00528   }
00529 
00530   oqmlStatus *oqmlTrue::compile(Database *db, oqmlContext *ctx)
00531   {
00532     return oqmlSuccess;
00533   }
00534 
00535   oqmlStatus *oqmlTrue::eval(Database *db, oqmlContext *ctx, oqmlAtomList **alist, oqmlComp *, oqmlAtom *)
00536   {
00537     *alist = new oqmlAtomList(new oqmlAtom_bool(oqml_True));
00538     return oqmlSuccess;
00539   }
00540 
00541   void oqmlTrue::evalType(Database *db, oqmlContext *ctx, oqmlAtomType *at)
00542   {
00543     *at = eval_type;
00544   }
00545 
00546   oqmlBool oqmlTrue::isConstant() const
00547   {
00548     return oqml_True;
00549   }
00550 
00551   std::string
00552   oqmlTrue::toString(void) const
00553   {
00554     return std::string("true") + oqml_isstat();
00555   }
00556 
00557   // +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
00558   //
00559   // oqmlFalse operator methods
00560   //
00561   // +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
00562 
00563   oqmlFalse::oqmlFalse() : oqmlNode(oqmlFALSE)
00564   {
00565     eval_type.type = oqmlATOM_BOOL;
00566   }
00567 
00568   oqmlFalse::~oqmlFalse()
00569   {
00570   }
00571 
00572   oqmlStatus *oqmlFalse::compile(Database *db, oqmlContext *ctx)
00573   {
00574     return oqmlSuccess;
00575   }
00576 
00577   oqmlStatus *oqmlFalse::eval(Database *db, oqmlContext *ctx, oqmlAtomList **alist, oqmlComp *, oqmlAtom *)
00578   {
00579     *alist = new oqmlAtomList(new oqmlAtom_bool(oqml_False));
00580     return oqmlSuccess;
00581   }
00582 
00583   void oqmlFalse::evalType(Database *db, oqmlContext *ctx, oqmlAtomType *at)
00584   {
00585     *at = eval_type;
00586   }
00587 
00588   oqmlBool oqmlFalse::isConstant() const
00589   {
00590     return oqml_True;
00591   }
00592 
00593   std::string
00594   oqmlFalse::toString(void) const
00595   {
00596     return std::string("false") + oqml_isstat();
00597   }
00598 
00599   // +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
00600   //
00601   // oqmlRange operator methods
00602   //
00603   // +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
00604 
00605   oqmlRange::oqmlRange(oqmlNode *_qleft, oqmlBool _left_incl,
00606                        oqmlNode *_qright, oqmlBool _right_incl,
00607                        oqmlBool _is_between) :
00608     oqmlNode(oqmlRANGE)
00609   {
00610     qleft = _qleft;
00611     qright = _qright;
00612     left_incl = _left_incl;
00613     right_incl = _right_incl;
00614     is_between = _is_between;
00615     eval_type.type = oqmlATOM_RANGE;
00616   }
00617 
00618   oqmlRange::~oqmlRange()
00619   {
00620   }
00621 
00622   oqmlStatus *oqmlRange::compile(Database *db, oqmlContext *ctx)
00623   {
00624     oqmlStatus *s = qleft->compile(db, ctx);
00625     if (s) return s;
00626     return qright->compile(db, ctx);
00627   }
00628 
00629   oqmlStatus *oqmlRange::eval(Database *db, oqmlContext *ctx, oqmlAtomList **alist, oqmlComp *, oqmlAtom *)
00630   {
00631     static const char fmt[] = "invalid %s operand: expected int, float, char or string, got %s";
00632 
00633     oqmlStatus *s;
00634     oqmlAtomList *aleft, *aright;
00635 
00636     s = qleft->eval(db, ctx, &aleft);
00637     if (s) return s;
00638 
00639     s = qright->eval(db, ctx, &aright);
00640     if (s) return s;
00641 
00642     oqmlAtom *left =  (aleft->cnt == 1 ? aleft->first : 0);
00643     oqmlAtom *right = (aright->cnt == 1 ? aright->first : 0);
00644 
00645     if (!left)
00646       return new oqmlStatus(this, fmt, "left", "nil");
00647 
00648     if (!right)
00649       return new oqmlStatus(this, fmt, "right", "nil");
00650 
00651     if (left->type.type != right->type.type)
00652       return new oqmlStatus(this, "operand types differ");
00653 
00654     if (!OQML_IS_INT(left) &&
00655         !OQML_IS_DOUBLE(left) &&
00656         !OQML_IS_CHAR(left) &&
00657         !OQML_IS_STRING(left))
00658       return new oqmlStatus(this, fmt, "left", left->type.getString());
00659 
00660     *alist = new oqmlAtomList(new oqmlAtom_range(left, left_incl,
00661                                                  right, right_incl));
00662     return oqmlSuccess;
00663   }
00664 
00665   void oqmlRange::evalType(Database *db, oqmlContext *ctx, oqmlAtomType *at)
00666   {
00667     *at = eval_type;
00668   }
00669 
00670   oqmlBool oqmlRange::isConstant() const
00671   {
00672     return OQMLBOOL(qleft->isConstant() && qright->isConstant());
00673   }
00674 
00675   std::string
00676   oqmlRange::toString(void) const
00677   {
00678     if (is_between)
00679       return qleft->toString() + " and " + qright->toString();
00680 
00681     return (left_incl ? std::string("[") : std::string("]")) +
00682       qleft->toString() + "," + qright->toString() +
00683       (right_incl ? std::string("]") : std::string("["));
00684   }
00685 }

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