oqllist.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 "oql_p.h"
00026 
00027 // +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
00028 //
00029 // oqmlColl operator methods
00030 //
00031 // +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
00032 
00033 namespace eyedb {
00034 
00035 oqmlColl::oqmlColl(oqml_List * _list, oqmlTYPE _type) : oqmlNode(_type)
00036 {
00037   list = _list;
00038 }
00039 
00040 oqmlColl::~oqmlColl()
00041 {
00042   delete list;
00043 }
00044 
00045 oqmlStatus *oqmlColl::compile(Database *db, oqmlContext *ctx)
00046 {
00047   if (!list)
00048     return oqmlSuccess;
00049 
00050   oqml_Link *l = list->first;
00051 
00052   while (l)
00053     {
00054       oqmlStatus *s;
00055 
00056       if ((s = l->ql->compile(db, ctx)) != oqmlSuccess)
00057         return s;
00058 
00059       l = l->next;
00060     }
00061 
00062   return oqmlSuccess;
00063 }
00064 
00065 oqmlStatus *oqmlColl::eval(Database *db, oqmlContext *ctx,
00066                          oqmlAtomList **alist, oqmlComp *, oqmlAtom *)
00067 {
00068   if (!list)
00069     {
00070       *alist = new oqmlAtomList(makeAtomColl(new oqmlAtomList()));
00071       return oqmlSuccess;
00072     }
00073 
00074   oqml_Link *l = list->first;
00075   oqmlAtomList *al = new oqmlAtomList();
00076 
00077   while (l)
00078     {
00079       oqml_Link *next = l->next;
00080       oqmlAtomList *tal;
00081       oqmlStatus *s;
00082 
00083       tal = 0;
00084       if ((s = l->ql->eval(db, ctx, &tal)) != oqmlSuccess)
00085         return s;
00086 
00087       al->append(tal);
00088 
00089       l = next;
00090     }
00091 
00092   *alist = new oqmlAtomList(makeAtomColl(al));
00093   return oqmlSuccess;
00094 }
00095 
00096 void oqmlColl::evalType(Database *db, oqmlContext *ctx, oqmlAtomType *at)
00097 {
00098   *at = eval_type;
00099 }
00100 
00101 oqmlBool oqmlColl::isConstant() const
00102 {
00103   return oqml_False;
00104 }
00105 
00106 std::string
00107 oqmlColl::toString(void) const
00108 {
00109   std::string s = std::string(getTypeName()) + "(";
00110 
00111   if (list)
00112     {
00113       oqml_Link *l = list->first;
00114 
00115       for (int n = 0; l; n++)
00116         {
00117           if (n) s += ",";
00118           s += l->ql->toString();
00119           l = l->next;
00120         }
00121     }
00122 
00123   return s + ")" + oqml_isstat();
00124 }
00125 
00126 // +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
00127 //
00128 // oqmlListColl operator methods
00129 //
00130 // +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
00131 
00132 oqmlListColl::oqmlListColl(oqml_List * _list) : oqmlColl(_list, oqmlLISTCOLL)
00133 {
00134   eval_type.type = oqmlATOM_LIST;
00135 }
00136 
00137 // +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
00138 //
00139 // oqmlSetColl operator methods
00140 //
00141 // +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
00142 
00143 oqmlSetColl::oqmlSetColl(oqml_List * _list) : oqmlColl(_list, oqmlSETCOLL)
00144 {
00145   eval_type.type = oqmlATOM_SET;
00146 }
00147 
00148 // +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
00149 //
00150 // oqmlBagColl operator methods
00151 //
00152 // +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
00153 
00154 oqmlBagColl::oqmlBagColl(oqml_List * _list) : oqmlColl(_list, oqmlBAGCOLL)
00155 {
00156   eval_type.type = oqmlATOM_BAG;
00157 }
00158 
00159 // +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
00160 //
00161 // oqmlArrayColl operator methods
00162 //
00163 // +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
00164 
00165 oqmlArrayColl::oqmlArrayColl(oqml_List * _list) : oqmlColl(_list, oqmlARRAYCOLL)
00166 {
00167   eval_type.type = oqmlATOM_ARRAY;
00168 }
00169 
00170 // +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
00171 //
00172 // oqmlStruct operator methods
00173 //
00174 // +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
00175 
00176 oqmlStruct::oqmlStruct(oqml_IdentList *_list) : oqmlNode(oqmlSTRUCT)
00177 {
00178   list = _list;
00179 }
00180 
00181 oqmlStatus *oqmlStruct::compile(Database *db, oqmlContext *ctx)
00182 {
00183   oqmlStatus *s;
00184   oqml_IdentLink *l = list->first;
00185 
00186   while (l)
00187     {
00188       s = l->ql->compile(db, ctx);
00189       if (s) return s;
00190       l = l->next;
00191     }
00192 
00193   return oqmlSuccess;
00194 }
00195 
00196 oqmlStatus *oqmlStruct::eval(Database *db, oqmlContext *ctx,
00197                              oqmlAtomList **alist, oqmlComp *, oqmlAtom *)
00198 {
00199   oqmlStatus *s;
00200   oqml_StructAttr *attr = new oqml_StructAttr[list->cnt];
00201   oqml_IdentLink *l = list->first;
00202   for (int n = 0; l; n++)
00203     {
00204       oqmlAtomList *al;
00205       s = l->ql->eval(db, ctx, &al);
00206       if (s)
00207         {
00208           delete[] attr;
00209           return s;
00210         }
00211 
00212       if (l->left->getType() != oqmlIDENT)
00213         {
00214           delete[] attr;
00215           return oqmlStatus::expected(this, "identifier",
00216                                       l->left->toString().c_str());
00217         }
00218 
00219       attr[n].set(((oqmlIdent *)l->left)->getName(), al->first);
00220       l = l->next;
00221     }
00222 
00223   *alist = new oqmlAtomList(new oqmlAtom_struct(attr, list->cnt));
00224   return oqmlSuccess;
00225 }
00226 
00227 void oqmlStruct::evalType(Database *db, oqmlContext *ctx, oqmlAtomType *at)
00228 {
00229   at->type = oqmlATOM_STRUCT;
00230   at->cls = 0;
00231   at->comp = oqml_False;
00232 }
00233 
00234 oqmlBool oqmlStruct::isConstant() const
00235 {
00236   return oqml_False;
00237 }
00238 
00239 oqmlBool
00240 oqmlStruct::hasIdent(const char *ident)
00241 {
00242   oqml_IdentLink *ln = list->first;
00243 
00244   while (ln)
00245     {
00246       if (ln->ql->hasIdent(ident))
00247         return oqml_True;
00248       ln = ln->next;
00249     }
00250 
00251   return oqml_False;
00252 }
00253 
00254 void oqmlStruct::lock()
00255 {
00256   oqmlNode::lock();
00257   if (list) list->lock();
00258 }
00259 
00260 void oqmlStruct::unlock()
00261 {
00262   oqmlNode::unlock();
00263   if (list) list->unlock();
00264 }
00265 
00266 std::string
00267 oqmlStruct::toString(void) const
00268 {
00269   std::string s = "struct(";
00270 
00271   oqml_IdentLink *l = list->first;
00272   for (int n = 0; l; n++)
00273     {
00274       if (n) s += ", ";
00275       s += l->left->toString() + ": " + l->ql->toString();
00276       l = l->next;
00277     }
00278 
00279   return s + ")" + oqml_isstat();
00280 }
00281 
00282 oqmlStruct::~oqmlStruct()
00283 {
00284 }
00285 
00286 // +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
00287 //
00288 // unary structof operator methods
00289 //
00290 // +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
00291 
00292 oqmlStructOf::oqmlStructOf(oqmlNode * _ql) : oqmlNode(oqmlSTRUCTOF)
00293 {
00294   ql = _ql;
00295   eval_type.type = oqmlATOM_STRING;
00296   eval_type.comp = oqml_True;
00297 }
00298 
00299 oqmlStructOf::~oqmlStructOf()
00300 {
00301 }
00302 
00303 oqmlStatus *oqmlStructOf::compile(Database *db, oqmlContext *ctx)
00304 {
00305   return ql->compile(db, ctx);
00306 }
00307 
00308 oqmlStatus *oqmlStructOf::eval(Database *db, oqmlContext *ctx, oqmlAtomList **alist, oqmlComp *, oqmlAtom *)
00309 {
00310   oqmlStatus *s;
00311 
00312   oqmlAtomList *al;
00313   s = ql->eval(db, ctx, &al);
00314   if (s)
00315     return s;
00316 
00317   if (!al->cnt)
00318     return oqmlStatus::expected(this, "struct", "nil");
00319 
00320   oqmlAtom *r = al->first;
00321   if (!OQML_IS_STRUCT(r))
00322     return oqmlStatus::expected(this, "struct", r->type.getString());
00323 
00324   oqmlAtom_struct *as = r->as_struct();
00325 
00326   oqmlAtomList *list = new oqmlAtomList();
00327 
00328   for (int i = 0; i < as->attr_cnt; i++)
00329     list->append(new oqmlAtom_string(as->attr[i].name));
00330 
00331   *alist = new oqmlAtomList(new oqmlAtom_list(list));
00332 
00333   return oqmlSuccess;
00334 }
00335 
00336 void oqmlStructOf::evalType(Database *db, oqmlContext *ctx, oqmlAtomType *at)
00337 {
00338   *at = eval_type;
00339 }
00340 
00341 oqmlBool oqmlStructOf::isConstant() const
00342 {
00343   return OQMLBOOL(ql->isConstant());
00344 }
00345 
00346 std::string
00347 oqmlStructOf::toString(void) const
00348 {
00349   return oqml_unop_string(ql, "structof ", is_statement);
00350 }
00351 
00352 // +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
00353 //
00354 // oqmlFlatten operator methods
00355 //
00356 // +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
00357 
00358 static void
00359 oqml_flatten_realize(oqmlAtom *a, int flat, oqmlAtomList *alist)
00360 {
00361   if (a->type.type == oqmlATOM_LIST && flat) {
00362     oqmlAtom *ta = ((oqmlAtom_list *)a)->list->first;
00363     while (ta) {
00364       oqmlAtom *next = ta->next;
00365       oqml_flatten_realize(ta, flat, alist);
00366       ta = next;
00367     }
00368   }
00369   else
00370     alist->append(a);
00371 }
00372 
00373 oqmlFlatten::oqmlFlatten(oqml_List * _list, int _flat) : oqmlNode(oqmlFLATTEN)
00374 {
00375   list = _list;
00376   flat = _flat;
00377 }
00378 
00379 oqmlFlatten::~oqmlFlatten()
00380 {
00381   delete list;
00382 }
00383 
00384 oqmlStatus *oqmlFlatten::compile(Database *db, oqmlContext *ctx)
00385 {
00386   if (!list)
00387     return oqmlSuccess;
00388 
00389   oqml_Link *l = list->first;
00390 
00391   oqmlBool first = oqml_True;
00392   oqmlBool do_ev_type = oqml_True;
00393 
00394   while (l)
00395     {
00396       oqmlStatus *s;
00397 
00398       if ((s = l->ql->compile(db, ctx)) != oqmlSuccess)
00399         return s;
00400 
00401       if (do_ev_type)
00402         {
00403           oqmlAtomType at;
00404           l->ql->evalType(db, ctx, &at);
00405           
00406           if (first)
00407             {
00408               first = oqml_False;
00409               eval_type = at;
00410             }
00411           else if (eval_type.type != at.type)
00412             {
00413               eval_type.type = oqmlATOM_UNKNOWN_TYPE;
00414               eval_type.cls = 0;
00415               do_ev_type = oqml_False;
00416             }
00417         }
00418 
00419       l = l->next;
00420     }
00421 
00422   // kludge added the 8/02/99
00423   if (eval_type.type == oqmlATOM_LIST)
00424     {
00425       eval_type.type = oqmlATOM_UNKNOWN_TYPE;
00426       eval_type.cls = 0;
00427       do_ev_type = oqml_False;
00428     }
00429 
00430   return oqmlSuccess;
00431 }
00432 
00433 oqmlStatus *oqmlFlatten::eval(Database *db, oqmlContext *ctx,
00434                               oqmlAtomList **alist, oqmlComp *, oqmlAtom *)
00435 {
00436   *alist = new oqmlAtomList();
00437 
00438   if (!list)
00439     return oqmlSuccess;
00440 
00441   oqmlStatus *s;
00442   oqml_Link *l = list->first;
00443 
00444   while (l)
00445     {
00446       oqmlAtomList *tal;
00447       tal = 0;
00448       if ((s = l->ql->eval(db, ctx, &tal)) != oqmlSuccess)
00449         {
00450           delete tal;
00451           delete *alist;
00452           return s;
00453         }
00454 
00455       oqmlAtom *a = tal->first;
00456   
00457       while (a)
00458         {
00459           oqmlAtom *next = a->next;
00460           oqml_flatten_realize(a, flat, *alist);
00461           a = next;
00462         }
00463 
00464       l = l->next;
00465     }
00466   return oqmlSuccess;
00467 }
00468 
00469 void oqmlFlatten::evalType(Database *db, oqmlContext *ctx, oqmlAtomType *at)
00470 {
00471   *at = eval_type;
00472 }
00473 
00474 oqmlBool oqmlFlatten::isConstant() const
00475 {
00476   return oqml_False;
00477 }
00478 
00479 std::string
00480 oqmlFlatten::toString(void) const
00481 {
00482   std::string s = std::string("flatten(");
00483   oqml_Link *l = list->first;
00484 
00485   for (int n = 0; l; n++)
00486     {
00487       if (n) s += ",";
00488       s += l->ql->toString();
00489       l = l->next;
00490     }
00491 
00492   return s + ")" + oqml_isstat();
00493 }
00494 
00495 void
00496 oqmlFlatten::lock()
00497 {
00498   oqmlNode::lock();
00499   if (!list)
00500     return;
00501 
00502   list->lock();
00503 }
00504 
00505 void
00506 oqmlFlatten::unlock()
00507 {
00508   oqmlNode::unlock();
00509   if (!list)
00510     return;
00511 
00512   list->unlock();
00513 }
00514 
00515 // +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
00516 //
00517 // oqmlCount operator methods
00518 //
00519 // +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
00520 
00521 oqmlStatus *oqmlCount::eval(Database *db, oqmlContext *ctx,
00522                           oqmlAtomList **alist, oqmlComp *, oqmlAtom *)
00523 {
00524   oqmlStatus *s;
00525   oqmlAtomList *al;
00526 
00527   s = ql->eval(db, ctx, &al);
00528 
00529   if (s)
00530     return s;
00531 
00532   *alist = new oqmlAtomList(new oqmlAtom_int(al->cnt));
00533 
00534   return oqmlSuccess;
00535 }
00536 
00537 void oqmlCount::evalType(Database *db, oqmlContext *ctx, oqmlAtomType *at)
00538 {
00539   at->type = oqmlATOM_INT;
00540   at->cls = 0;
00541   at->comp = oqml_False;
00542 }
00543 
00544 oqmlBool oqmlCount::isConstant() const
00545 {
00546   return OQMLBOOL(ql->isConstant());
00547 }
00548 
00549 oqmlCount::oqmlCount(oqmlNode * _ql) : oqmlNode(oqmlCOUNT)
00550 {
00551   ql = _ql;
00552 }
00553 
00554 oqmlCount::~oqmlCount()
00555 {
00556 }
00557 
00558 oqmlStatus *oqmlCount::compile(Database *db, oqmlContext *ctx)
00559 {
00560   oqmlStatus *s;
00561   s = ql->compile(db, ctx);
00562 
00563   if (s)
00564     return s;
00565 
00566   return oqmlSuccess;
00567 }
00568 
00569 std::string
00570 oqmlCount::toString(void) const
00571 {
00572   return std::string("count(") + ql->toString() + ")" + oqml_isstat();
00573 }
00574 }

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