odl.h

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 #ifndef _EYEDB_ODL_H
00026 #define _EYEDB_ODL_H
00027 
00028 #include <stdio.h>
00029 #include <stdlib.h>
00030 #include <string.h>
00031 #include <eyedb/eyedb.h>
00032 
00033 extern "C" {
00034   extern int odlparse();
00035 }
00036 
00037 namespace eyedb {
00038 
00039   extern int odl_error;
00040 
00041   //
00042   // basic list template
00043   //
00044 
00045   template <class T> struct odl_temp_link {
00046     T x;
00047     odl_temp_link<T> *next;
00048 
00049     odl_temp_link(T _x) : x(_x) {
00050       next = 0;
00051     }
00052 
00053     ~odl_temp_link() {}
00054   };
00055 
00056   template <class T> class odl_temp_list {
00057 
00058   public:
00059     odl_temp_link<T> *first;
00060     odl_temp_link<T> *last;
00061 
00062     int count;
00063 
00064     odl_temp_list() {
00065       first = last = 0;
00066       count = 0;
00067     }
00068     void add(T x) {
00069       odl_temp_link<T> *l = new odl_temp_link<T>(x);
00070       if (last)
00071         last->next = l;
00072       else
00073         first = l;
00074       last = l;
00075       count++;
00076     }
00077     /*
00078       void add(T _x) {
00079       T *x = new T;
00080       *x = _x;
00081       add(x);
00082       }
00083     */
00084 
00085     ~odl_temp_list() {
00086       odl_temp_link<T> *l = first;
00087       while (l)
00088         {
00089           odl_temp_link<T> *next = l->next;
00090           delete l;
00091           l = next;
00092         }
00093     }
00094   };
00095 
00096   enum odlBool {
00097     odlFalse = 0,
00098     odlTrue = 1
00099   };
00100 
00101   extern const char *odl_get_typname(const char *);
00102 
00103   class odlIndexSpec;
00104   class odlImplementation;
00105 
00106   class odlClassSpec {
00107 
00108   public:
00109     char *classname, *parentname, *aliasname;
00110     odlIndexSpec *index_spec;
00111 
00112     odlClassSpec(const char *_classname, const char *_parentname,
00113                  const char *_aliasname, odlIndexSpec *_index_spec);
00114 
00115     ~odlClassSpec() {
00116       free(classname);
00117       free(parentname);
00118       free(aliasname);
00119     }
00120   };
00121 
00122   //
00123   // forward declarations
00124   //
00125 
00126   class odlInverse;
00127   class odlImplementation;
00128   class odlIndex;
00129   class odlCardinality;
00130   class odlMagOrder;
00131   class odlImplementation;
00132   class odlExecSpec;
00133   class odlDeclItem;
00134   class odlMethodSpec;
00135   class odlTriggerSpec;
00136   class odlQuotedSeq;
00137   class odlArgSpec;
00138   class odlAgregatClass;
00139   class odlEnumClass;
00140   class odlAttrComponent;
00141   class odlConstraint;
00142   class odlUnique;
00143   class odlNotnull;
00144   class odlIndexSpec;
00145   class odlIndexSpecItem;
00146 
00147   typedef odl_temp_link<int>           odlArrayItemLink;
00148   typedef odl_temp_list<int>           odlArrayList;
00149   typedef odl_temp_link<odlArgSpec *>  odlArgSpecLink;
00150   typedef odl_temp_list<odlArgSpec *>  odlArgSpecList;
00151   typedef odl_temp_link<odlExecSpec *> odlExecLink;
00152   typedef odl_temp_list<odlExecSpec *> odlExecList;
00153 
00154   class odlUpdateHint;
00155 
00156   struct odlDeclRoot {
00157     virtual odlDeclItem *asDeclItem() {return 0;}
00158     virtual odlExecSpec *asExecSpec() {return 0;}
00159     virtual odlQuotedSeq *asQuotedSeq() {return 0;}
00160     virtual odlAttrComponent *asAttrComponent() {return 0;}
00161     virtual odlConstraint *asConstraint() {return 0;}
00162     virtual odlUnique *asUnique() {return 0;}
00163     virtual odlNotnull *asNotnull() {return 0;}
00164     virtual odlIndex *asIndex() {return 0;}
00165     virtual odlCardinality *asCardinality() {return 0;}
00166     virtual odlImplementation *asImplementation() {return 0;}
00167     virtual void setUpdateHint(odlUpdateHint *) { }
00168   };
00169 
00170   struct odlQuotedSeq : public odlDeclRoot {
00171 
00172     char *quoted_seq;
00173 
00174     odlQuotedSeq(const char *_quoted_seq) {
00175       quoted_seq = strdup(_quoted_seq);
00176     }
00177 
00178     odlQuotedSeq *asQuotedSeq() {return this;}
00179 
00180     ~odlQuotedSeq() {
00181       delete quoted_seq;
00182     }
00183   };
00184 
00185   struct odlCollSpec {
00186     char *collname;
00187     char *typname;
00188     odlBool isref;
00189     int dim;
00190     odlCollSpec *coll_spec;
00191     odlBool isString;
00192 
00193     odlCollSpec(const char *_collname, const char *_typname, odlBool _isref,
00194                 int _dim) :
00195       collname(strdup(_collname)), typname(strdup(odl_get_typname(_typname))),
00196       isref(_isref), dim(_dim), coll_spec(NULL), isString(odlFalse) {}
00197   
00198     odlCollSpec(int _dim) : collname(NULL),
00199                             dim(_dim), typname(NULL), coll_spec(NULL), isref(odlFalse),
00200                             isString(odlTrue) {}
00201 
00202     odlCollSpec(const char *_collname, odlCollSpec *_coll_spec, odlBool _isref,
00203                 int _dim) :
00204       collname(strdup(_collname)), typname(NULL),
00205       coll_spec(_coll_spec), isref(_isref), dim(_dim), isString(odlFalse) {}
00206 
00207     ~odlCollSpec() {
00208       free(collname);
00209       free(typname);
00210     }
00211   };
00212 
00213   struct odlUpdateHint {
00214 
00215     enum Type {
00216       UNDEFINED,
00217       Remove,
00218       RenameFrom,
00219       Convert,
00220       Extend,
00221       MigrateFrom,
00222       MigrateTo
00223     } type;
00224 
00225     char *detail, *detail2, *detail3;
00226     odlUpdateHint(Type _type, const char *_detail = 0,
00227                   const char *_detail2 = 0, 
00228                   const char *_detail3 = 0) :
00229       type(_type),
00230       detail(_detail ? strdup(_detail) : 0),
00231       detail2(_detail2 ? strdup(_detail2) : 0),
00232       detail3(_detail3 ? strdup(_detail3) : 0) { }
00233   };
00234 
00235   struct odlInverse {
00236     char *classname, *attrname;
00237 
00238     odlInverse(const char *_classname, const char *_attrname) {
00239       classname = (_classname ? strdup(_classname) : NULL);
00240       attrname = strdup(_attrname);
00241     }
00242 
00243     ~odlInverse() {
00244       free(classname);
00245       free(attrname);
00246     }
00247   };
00248 
00249   struct odlDeclItem : odlDeclRoot {
00250     char *attrname;
00251     char *typname;
00252     odlArrayList *array_list;
00253     odlInverse *inverse;
00254     odlCollSpec *coll_spec;
00255     odlBool isref;
00256     odlUpdateHint *upd_hints;
00257 
00258     odlDeclItem(const char *_attrname,
00259                 const char *_typname, odlBool _isref,
00260                 odlArrayList *_array_list, odlInverse *_inverse) {
00261 
00262       upd_hints = 0;
00263       attrname   = strdup(_attrname);
00264       array_list = _array_list;
00265       inverse  = _inverse;
00266 
00267       if (!strcmp(_typname, "string"))
00268         {
00269           typname = strdup("char");
00270           if (!array_list)
00271             {
00272               array_list = new odlArrayList();
00273               array_list->add(-1);
00274             }
00275           else 
00276             {
00277               /*
00278                 fprintf(stderr, "eyedbodl: attribute '%s': "
00279                 "arrays of unbounded strings are not allowed. Use class 'ostring' instead of class 'string'.\n", attrname);
00280                 odl_error++;
00281               */
00282               fprintf(stderr, "eyedbodl: warning attribute '%s': "
00283                       "arrays of unbounded strings are not allowed.\n"
00284                       "Using class 'ostring' instead of class 'string'.\n",
00285                       attrname);
00286               free(typname);
00287               typname = strdup("ostring");
00288             }
00289         }
00290       else
00291         typname = strdup(odl_get_typname(_typname));
00292 
00293       coll_spec  = NULL;
00294       isref      = _isref;
00295     }
00296 
00297     odlDeclItem *asDeclItem() {return this;}
00298 
00299     odlDeclItem(const char *_attrname, odlCollSpec *_coll_spec,
00300                 odlBool _isref,
00301                 odlArrayList *_array_list, odlInverse *_inverse) {
00302 
00303       attrname   = strdup(_attrname);
00304       array_list = _array_list;
00305       inverse = _inverse;
00306 
00307       if (_coll_spec->isString)
00308         {
00309           typname = strdup("char");
00310           if (!array_list)
00311             array_list = new odlArrayList();
00312           else /*if (_coll_spec->dim < 0)*/
00313             {
00314               fprintf(stderr, "eyedbodl: attribute '%s': "
00315                       "array of string are not allowed: use class 'ostring'.\n", attrname);
00316               odl_error++;
00317             }
00318             
00319           array_list->add(_coll_spec->dim);
00320           coll_spec = 0;
00321         }
00322       else
00323         {
00324           coll_spec = _coll_spec;
00325           typname = NULL;
00326         }
00327 
00328       isref      = _isref;
00329       upd_hints = 0;
00330     }
00331 
00332     void setUpdateHint(odlUpdateHint *_upd_hints) {
00333       upd_hints = _upd_hints;
00334     }
00335 
00336     odlBool hasInverseAttr() const;
00337 
00338     ~odlDeclItem() {
00339       free(attrname);
00340       free(typname);
00341       delete array_list;
00342     }
00343   };
00344 
00345   struct odlAttrComponent : public odlDeclRoot {
00346 
00347     char *attrpath;
00348     odlBool propagate;
00349     odlBool isCloned;
00350 
00351     odlAttrComponent(const char *_attrpath, odlBool propag) : 
00352       attrpath(strdup(_attrpath)), propagate(propag), isCloned(odlFalse) {}
00353     virtual odlAttrComponent  *asAttrComponent()  {return this;}
00354     AttributeComponent *make(Database *, Schema *m, Class *cls,
00355                              const Attribute *&);
00356     virtual AttributeComponent *make_realize(Database *, Schema *m, Class *cls, const Attribute *) = 0;
00357     virtual odlBool similar(odlAttrComponent *,
00358                             const Class *, const Class *);
00359     virtual odlAttrComponent *clone() {abort(); return 0;}
00360   };
00361 
00362   struct odlImplementation : public odlAttrComponent {
00363 
00364     odlIndexSpec *index_spec;
00365 
00366     odlImplementation(const char *_attrpath, odlIndexSpec *_index_spec,
00367                       odlBool propag = odlTrue) :
00368       odlAttrComponent(_attrpath, propag), index_spec(_index_spec) {}
00369 
00370     virtual odlImplementation *asImplementation() {return this;}
00371     AttributeComponent *make_realize(Database *, Schema *m, Class *cls, const Attribute *);
00372     odlBool similar(odlAttrComponent *,
00373                     const Class *, const Class *);
00374     virtual odlAttrComponent *clone() {odlAttrComponent *comp = new odlImplementation(attrpath, index_spec); comp->isCloned = odlTrue; return comp;}
00375   };
00376 
00377   struct odlIndexSpecItem {
00378     enum Type {
00379       UndefType,
00380       Hash,
00381       BTree
00382     } type;
00383     char *hints;
00384     /*
00385       enum Propagate {
00386       UndefPropag,
00387       On,
00388       Off
00389       } propag;
00390     */
00391 
00392     void init() {
00393       type = UndefType;
00394       hints = 0;
00395       //propag = UndefPropag;
00396     }
00397   };
00398 
00399   struct odlIndexSpec {
00400     unsigned int item_alloc, item_cnt;
00401     odlIndexSpecItem *items;
00402 
00403     odlIndexSpec() {
00404       item_alloc = item_cnt = 0;
00405       items = 0;
00406     }
00407 
00408     void add(const odlIndexSpecItem &item) {
00409       if (item_cnt >= item_alloc) {
00410         item_alloc += 4;
00411         items = (odlIndexSpecItem *)realloc(items, item_alloc * sizeof(odlIndexSpecItem));
00412       }
00413       items[item_cnt++] = item;
00414     }
00415 
00416     int make_class_prologue(const char *clsname,
00417                             odlIndexSpecItem::Type &type,
00418                             char *&hints) const;
00419     int make_attr_prologue(const char *attrpath,
00420                            odlIndexSpecItem::Type &type,
00421                            char *&hints, const Attribute *) const;
00422     int make_prologue(Bool isclass, const char *attrpath,
00423                       odlIndexSpecItem::Type &type,
00424                       char *&hints, const Attribute *) const;
00425     ~odlIndexSpec() {
00426       free(items);
00427     }
00428   };
00429 
00430   struct odlIndex : public odlAttrComponent {
00431     odlIndexSpec *index_spec;
00432     odlIndexSpec *index_spec_in;
00433 
00434     odlIndex(const char *_attrpath, odlIndexSpec *_index_spec = 0,
00435              odlBool propag = odlTrue) :
00436       odlAttrComponent(_attrpath, propag), index_spec(_index_spec),
00437       index_spec_in(_index_spec) {}
00438 
00439     static Status findIndex(Schema *m, Index *&idx_obj);
00440 
00441     virtual void retype(odlBool isCollOrIsRef) {
00442     }
00443 
00444     /*
00445       int make_prologue(odlIndexSpecItem::Type &type,
00446       char *&hints, Bool is_string);
00447     */
00448 
00449     AttributeComponent *make_realize(Database *, Schema *m, Class *cls, const Attribute *);
00450     odlBool similar(odlAttrComponent *,
00451                     const Class *, const Class *);
00452     virtual odlIndex   *asIndex()   {return this;}
00453     virtual odlAttrComponent *clone() {odlAttrComponent *comp = new odlIndex(attrpath, index_spec);  comp->isCloned = odlTrue; return comp;}
00454   };
00455 
00456   struct odlConstraint : public odlAttrComponent {
00457 
00458     odlConstraint(const char *_attrpath, odlBool propag) :
00459       odlAttrComponent(_attrpath, propag) {}
00460     virtual odlConstraint  *asConstraint()  {return this;}
00461   };
00462 
00463   struct odlUnique : public odlConstraint {
00464 
00465     odlUnique(const char *attrpath, odlBool propag = odlTrue) :
00466       odlConstraint(attrpath, odlTrue) {}
00467     virtual odlUnique  *asUnique()  {return this;}
00468     AttributeComponent *make_realize(Database *, Schema *m, Class *cls, const Attribute *);
00469     odlBool similar(odlAttrComponent *,
00470                     const Class *, const Class *);
00471     virtual odlAttrComponent *clone() {odlAttrComponent *comp = new odlUnique(attrpath); comp->isCloned = odlTrue; return comp;}
00472   };
00473 
00474   struct odlNotnull : public odlConstraint {
00475 
00476     odlNotnull(const char *attrpath, odlBool propag = odlTrue) :
00477       odlConstraint(attrpath, propag) {}
00478     virtual odlNotnull *asNotnull() {return this;}
00479     AttributeComponent *make_realize(Database *, Schema *m, Class *cls, const Attribute *);
00480     odlBool similar(odlAttrComponent *,
00481                     const Class *, const Class *);
00482     virtual odlAttrComponent *clone() {odlAttrComponent *comp = new odlNotnull(attrpath); comp->isCloned = odlTrue; return comp;}
00483   };
00484 
00485   struct odlCardinality : public odlAttrComponent {
00486     int bottom;
00487     odlBool bottom_excl;
00488     int top;
00489     odlBool top_excl;
00490 
00491     odlCardinality(int _bottom, odlBool _bottom_excl,
00492                    int _top, odlBool _top_excl) :
00493       odlAttrComponent("", odlTrue),
00494       bottom(_bottom), bottom_excl(_bottom_excl),
00495       top(_top), top_excl(_top_excl)
00496     { }
00497 
00498     AttributeComponent *make_realize(Database *, Schema *m, Class *cls, const Attribute *);
00499     odlBool similar(odlAttrComponent *,
00500                     const Class *, const Class *);
00501     virtual odlAttrComponent *clone() {odlAttrComponent *comp = new odlCardinality(bottom, bottom_excl, top, top_excl); comp->isCloned = odlTrue; return comp;}
00502     virtual odlCardinality *asCardinality() {return this;}
00503   };
00504 
00505   struct odlExecSpec : public odlDeclRoot {
00506     odlUpdateHint *upd_hints;
00507 
00508     odlExecSpec() {upd_hints = 0;}
00509     virtual odlMethodSpec *asMethodSpec() {return 0;}
00510     virtual odlTriggerSpec *asTriggerSpec() {return 0;}
00511     odlExecSpec *asExecSpec() {return this;}
00512     void setUpdateHint(odlUpdateHint *_upd_hints) {
00513       upd_hints = _upd_hints;
00514     }
00515   };
00516 
00517   struct odlArgSpec {
00518 
00519     int inout;
00520     char *typname;
00521     char *varname;
00522 
00523     odlArgSpec(int _inout, const char *_typname, const char *_varname) :
00524       inout(_inout), typname(strdup(_typname)),
00525       varname(_varname ? strdup(_varname) : NULL) {}
00526 
00527     ~odlArgSpec() {
00528       free(typname);
00529       free(varname);
00530     }
00531   };
00532 
00533   struct odlMethodHints {
00534     odlBool isClient;
00535     enum {
00536       ANY_HINTS, /* default */
00537       OQL_HINTS,
00538       C_HINTS,
00539       JAVA_HINTS
00540     } calledFrom;
00541   };
00542 
00543   struct odlSignUserData {
00544     char **names;
00545     odlMethodHints *mth_hints;
00546     odlUpdateHint *upd_hints;
00547     odlSignUserData(char **_names) {
00548       names = _names;
00549       mth_hints = 0;
00550       upd_hints = 0;
00551     }
00552   };
00553 
00554   struct odlMethodSpec : public odlExecSpec {
00555     char *rettype;
00556     char *fname;
00557     odlArgSpecList *arglist;
00558     char *extref;
00559     odlMethodHints mth_hints;
00560     odlBool isClassMethod;
00561     char *oqlSpec;
00562 
00563     odlMethodSpec(const char *_rettype, const char *_fname,
00564                   odlArgSpecList *_arglist)
00565     {
00566       mth_hints.isClient = odlFalse;
00567       mth_hints.calledFrom = odlMethodHints::ANY_HINTS;
00568       isClassMethod = odlFalse;
00569       rettype = strdup(_rettype);
00570       fname = strdup(_fname);
00571       arglist = _arglist;
00572       extref = 0;
00573       oqlSpec = 0;
00574     }
00575 
00576     odlMethodSpec *asMethodSpec() {return this;}
00577 
00578     int getParamNames(char **&typnames, char **&varnames);
00579 
00580     ~odlMethodSpec() {
00581       free(rettype);
00582       free(fname);
00583       free(extref);
00584       free(oqlSpec);
00585       delete arglist;
00586     }
00587   };
00588 
00589   struct odlTriggerSpec : public odlExecSpec {
00590     int light;
00591     char *name;
00592     char *localisation;
00593     char *oqlSpec;
00594     char *extref;
00595 
00596     odlTriggerSpec(int _light, const char *_localisation, const char *_name)
00597     {
00598       light = _light;
00599       name = strdup(_name);
00600       localisation = strdup(_localisation);
00601       oqlSpec = 0;
00602       extref = 0;
00603     }
00604 
00605     std::string makeOQLBody(const Class *cls) const;
00606 
00607     odlTriggerSpec *asTriggerSpec() {return this;}
00608 
00609     ~odlTriggerSpec() {
00610       free(oqlSpec);
00611       free(extref);
00612       free(name);
00613       free(localisation);
00614     }
00615   };
00616 
00617   struct odlEnumItem {
00618     char *name;
00619     char *aliasname;
00620     int value;
00621     odlBool novalue;
00622 
00623     odlEnumItem(const char *_name, const char *_aliasname, int _value) {
00624       name = strdup(_name);
00625       aliasname = _aliasname ? strdup(_aliasname) : 0;
00626       value = _value;
00627       novalue = odlFalse;
00628     }
00629 
00630     odlEnumItem(const char *_name, const char *_aliasname, odlBool) {
00631       name = strdup(_name);
00632       aliasname = _aliasname ? strdup(_aliasname) : strdup(_name);
00633       value = 0;
00634       novalue = odlTrue;
00635     }
00636   };
00637 
00638 
00639   typedef odl_temp_link<odlDeclRoot *> odlDeclRootLink;
00640   typedef odl_temp_list<odlDeclRoot *> odlDeclRootList;
00641 
00642   typedef odl_temp_link<odlDeclItem *> odlDeclItemLink;
00643   typedef odl_temp_list<odlDeclItem *> odlDeclList;
00644 
00645   typedef odl_temp_link<odlTriggerSpec *> odlTriggerSpecLink;
00646   typedef odl_temp_list<odlTriggerSpec *> odlTriggerList;
00647 
00648   typedef odl_temp_link<odlEnumItem *> odlEnumItemLink;
00649   typedef odl_temp_list<odlEnumItem *> odlEnumList;
00650 
00651   extern LinkedList *odl_decl_list;
00652 
00653   enum odlAgregSpec {
00654     odl_Struct,
00655     odl_Union,
00656     odl_SuperClass,
00657     odl_RootClass,
00658     odl_NativeClass,
00659     odl_Declare,
00660     odl_Remove
00661   };
00662 
00663   class odlDeclaration {
00664   protected:
00665     char *name;
00666     Class *ocls;
00667     Class *cls;
00668     char *aliasname;
00669     int check(Schema *, const char *prefix);
00670 
00671   public:
00672     odlDeclaration(const char *_name, const char *_aliasname) :
00673       name(_name ? strdup(_name) : 0), aliasname(_aliasname ? strdup(_aliasname) : 0) {
00674       odl_decl_list->insertObjectLast(this);
00675       ocls = NULL;
00676     }
00677     virtual int record(Database *, Schema *, const char *, const char *) = 0;
00678     virtual int realize(Database *, Schema *, const char *, const char *, Bool diff) = 0;
00679     const char *getName() const {return name;}
00680     const char *getAliasName() const {return aliasname;}
00681 
00682     void addPrefix(const char *prefix) {
00683       char *s = (char *)malloc(strlen(name)+strlen(prefix)+1);
00684       strcpy(s, prefix);
00685       strcat(s, name);
00686       free(name);
00687       name = s;
00688     }
00689 
00690     virtual odlAgregatClass *asAgregatClass() {return 0;}
00691     virtual odlEnumClass *asEnumClass() {return 0;}
00692     Class *getClass() {return cls;}
00693     Class *getOClass() {return ocls;}
00694     ~odlDeclaration() {free(name); free(aliasname);}
00695   };
00696 
00697   extern const char *odl_rootclass;
00698 
00699   class odlAgregatClass : public odlDeclaration {
00700     odlAgregSpec agrspec;
00701     char *parentname;
00702     odlDeclRootList *decl_list;
00703     Class *parent;
00704     odlIndexSpec *index_spec;
00705     static LinkedList declared_list;
00706 
00707   public:
00708     odlUpdateHint *upd_hints;
00709 
00710     odlAgregatClass(odlUpdateHint *_upd_hints, odlAgregSpec _agrspec,
00711                     odlClassSpec *spec, odlDeclRootList *_decl_list) :
00712       odlDeclaration(spec->classname, spec->aliasname) {
00713       upd_hints = _upd_hints;
00714       agrspec = _agrspec;
00715       parentname = (spec->parentname ? strdup(spec->parentname) :
00716                     (superclass ? superclass->name : 0));
00717       index_spec = spec->index_spec;
00718       decl_list = _decl_list;
00719 
00720       class_count++;
00721 
00722       if (agrspec == odl_Declare)
00723         declared_list.insertObject(spec->classname);
00724 
00725       if (agrspec != odl_SuperClass &&
00726           agrspec != odl_RootClass)
00727         return;
00728 
00729       if (superclass)
00730         {
00731           if (superclass->agrspec == odl_RootClass)
00732             fprintf(stderr,
00733                     "eyedbodl: superclass `%s' must be defined before all other classes\n", spec->classname);
00734           else
00735             fprintf(stderr,
00736                     "eyedbodl: can't have 2 superclasses `%s' and `%s'\n", 
00737                     spec->classname, superclass->name);
00738           exit(1);
00739         }
00740 
00741       //      if (odl_decl_list->getCount() > 1)
00742       if (class_count > 1)
00743         {
00744           fprintf(stderr,
00745                   "eyedbodl: superclass `%s' must be defined before all other classes\n", spec->classname);
00746           exit(1);
00747         }
00748 
00749       if (agrspec == odl_RootClass &&
00750           decl_list && decl_list->count > 0)
00751         {
00752           fprintf(stderr,
00753                   "eyedbodl: volatile superclass `%s' cannot contain any attributes\n", spec->classname);
00754           exit(1);
00755         }
00756 
00757       superclass = this;
00758     }
00759 
00760     odlBool hasSimilarComp(odlAttrComponent *comp, const Class *);
00761     int propagateComponents(Database *db, Schema *m);
00762     int record(Database *, Schema *, const char *, const char *);
00763     int realize(Database *db, Schema *, const char *, const char *, Bool diff);
00764     int postRealize(Database *db, Schema *, const char *);
00765     void realize(odlDeclItem *item,
00766                  Schema *m, const char *prefix,
00767                  int n, ClassComponent **comp,
00768                  int &comp_cnt, Attribute **agr);
00769     void realize(Database *db, odlAttrComponent *comp,
00770                  Schema *m, const char *prefix);
00771     void realize(Database *db, Schema *, odlExecSpec *, const char *);
00772 
00773     void addComp(odlAttrComponent *comp);
00774     int preManage(Schema *m);
00775     int manageDifferences(Database *db, Schema *m, Bool diff);
00776     int manageDiffRelationShips(Database *db, Schema *m, Bool diff);
00777 
00778     odlAgregSpec getAgregSpec() const {return agrspec;}
00779 
00780     static int getDeclaredCount() {return declared_list.getCount();}
00781     static LinkedList &getDeclaredList() {return declared_list;}
00782 
00783     virtual odlAgregatClass *asAgregatClass() {return this;}
00784 
00785     ~odlAgregatClass() {
00786       free(parentname);
00787       delete decl_list;
00788     }
00789     static odlAgregatClass *superclass;
00790     static unsigned int class_count;
00791   };
00792 
00793   class odlEnumClass : public odlDeclaration {
00794     odlEnumList *enum_list;
00795 
00796   public:
00797     /*
00798       odlEnumClass(const char *_name, odlEnumList *_enum_list,
00799       const char *_aliasname) :
00800       odlDeclaration(_name, _aliasname) {
00801       enum_list = _enum_list;
00802       }
00803     */
00804 
00805     odlEnumClass(const char *_aliasname, odlEnumList *_enum_list,
00806                  const char *_name) :
00807       odlDeclaration((_name ? _name : _aliasname), _aliasname) {
00808       enum_list = _enum_list;
00809     }
00810 
00811     int record(Database *, Schema *, const char *, const char *);
00812     int realize(Database *, Schema *, const char *, const char *, Bool diff);
00813 
00814     odlEnumClass *asEnumClass() {return this;}
00815     ~odlEnumClass() {
00816       delete enum_list;
00817     }
00818   };
00819 
00820   //
00821   // schema flexibility
00822   //
00823 
00824   class odlUpdateComponent;
00825   class odlAddComponent;
00826   class odlRemoveComponent;
00827 
00828   class odlUpdateAttribute;
00829   class odlAddAttribute;
00830   class odlRemoveAttribute;
00831   class odlRenameAttribute;
00832   class odlConvertAttribute;
00833   class odlReorderAttribute;
00834   class odlMigrateAttribute;
00835 
00836   class odlUpdateRelationship;
00837   class odlAddRelationship;
00838   class odlRemoveRelationship;
00839 
00840   class odlUpdateClass;
00841   class odlAddClass;
00842   class odlRemoveClass;
00843   class odlRenameClass;
00844   class odlReparentClass;
00845   class odlConvertClass;
00846 
00847   class odlUpdateEnum;
00848 
00849   class odlUpdateItem {
00850 
00851   public:
00852     ClassConversion *clsconv;
00853 
00854     odlUpdateItem() : clsconv(0) { }
00855 
00856     virtual void display() = 0;
00857     virtual void displayDiff(Database *db, const char *odlfile) = 0;
00858     virtual Status prePerform(Database *, Schema *m) {
00859       return Success;
00860     }
00861 
00862     virtual Status postPerform(Database *, Schema *m) {
00863       return Success;
00864     }
00865 
00866     static void initDisplay();
00867     static void initDisplayDiff(Database *, const char * = 0);
00868 
00869     virtual odlUpdateComponent *asUpdateComponent() {return 0;}
00870     virtual odlAddComponent *asAddComponent() {return 0;}
00871     virtual odlRemoveComponent *asRemoveComponent() {return 0;}
00872 
00873     virtual odlUpdateAttribute *asUpdateAttribute() {return 0;}
00874     virtual odlAddAttribute *asAddAttribute() {return 0;}
00875     virtual odlRemoveAttribute *asRemoveAttribute() {return 0;}
00876     virtual odlRenameAttribute *asRenameAttribute() {return 0;}
00877     virtual odlConvertAttribute *asConvertAttribute() {return 0;}
00878     virtual odlReorderAttribute *asReorderAttribute() {return 0;}
00879     virtual odlMigrateAttribute *asMigrateAttribute() {return 0;}
00880 
00881     virtual odlUpdateRelationship *asUpdateRelationship() {return 0;}
00882     virtual odlAddRelationship *asAddRelationship() {return 0;}
00883     virtual odlRemoveRelationship *asRemoveRelationship() {return 0;}
00884 
00885     virtual odlUpdateClass *asUpdateClass() {return 0;}
00886     virtual odlAddClass *asAddClass() {return 0;}
00887     virtual odlRemoveClass *asRemoveClass() {return 0;}
00888     virtual odlRenameClass *asRenameClass() {return 0;}
00889     virtual odlReparentClass *asReparentClass() {return 0;}
00890     virtual odlConvertClass *asConvertClass() {return 0;}
00891   };
00892 
00893   class odlUpdateComponent : public odlUpdateItem {
00894 
00895   private:
00896     odlBool updating;
00897     void setUpdating(Object *o) {
00898       updating = o->getOid().isValid() ? odlTrue : odlFalse;
00899     }
00900 
00901   protected:
00902     void realize(Database *, Schema *);
00903 
00904   public:
00905     ClassComponent *cls_comp;
00906     AttributeComponent *attr_comp;
00907 
00908     odlUpdateComponent(ClassComponent *_cls_comp) :
00909       cls_comp(_cls_comp), attr_comp(0) { setUpdating(cls_comp); }
00910     odlUpdateComponent(AttributeComponent *_attr_comp) :
00911       attr_comp(_attr_comp), cls_comp(0) { setUpdating(attr_comp); }
00912     virtual void display();
00913     virtual void displayDiff(Database *db, const char *odlfile);
00914     virtual odlUpdateComponent *asUpdateComponent() {return this;}
00915   };
00916 
00917   class odlAddComponent : public odlUpdateComponent {
00918 
00919   public:
00920 
00921     odlAddComponent(ClassComponent *);
00922     odlAddComponent(AttributeComponent *);
00923     virtual odlAddComponent *asAddComponent() {return this;}
00924     Status postPerform(Database *, Schema *);
00925   };
00926 
00927   class odlRemoveComponent : public odlUpdateComponent {
00928 
00929   public:
00930 
00931     odlRemoveComponent(ClassComponent *);
00932     odlRemoveComponent(AttributeComponent *);
00933     virtual odlRemoveComponent *asRemoveComponent() {return this;}
00934     Status postPerform(Database *, Schema *);
00935     Status prePerform(Database *, Schema *);
00936   };
00937 
00938   class odlUpdateRelationship : public odlUpdateItem {
00939 
00940   public:
00941     const Attribute *item, *invitem;
00942 
00943     odlUpdateRelationship(const Attribute *_item,
00944                           const Attribute *_invitem) :
00945       item(_item), invitem(_invitem) { }
00946 
00947     virtual odlUpdateRelationship *asUpdateRelationship() {return this;}
00948     virtual void display();
00949     virtual void displayDiff(Database *db, const char *odlfile);
00950   };
00951 
00952   class odlAddRelationship : public odlUpdateRelationship {
00953 
00954   public:
00955     odlAddRelationship(const Attribute *_item,
00956                        const Attribute *_invitem) :
00957       odlUpdateRelationship(_item, _invitem) { }
00958 
00959     virtual odlAddRelationship *asAddRelationship() {return this;}
00960     Status postPerform(Database *, Schema *);
00961   };
00962 
00963   class odlRemoveRelationship : public odlUpdateRelationship {
00964 
00965   public:
00966     odlRemoveRelationship(const Attribute *_item,
00967                           const Attribute *_invitem) :
00968       odlUpdateRelationship(_item, _invitem) { }
00969 
00970     virtual odlRemoveRelationship *asRemoveRelationship() {return this;}
00971     Status postPerform(Database *, Schema *);
00972   };
00973 
00974   class odlUpdateAttribute : public odlUpdateItem {
00975 
00976     Status check();
00977     Status check(Database *, const Class *);
00978   public:
00979     const Class *cls;
00980     const Attribute *item;
00981     Status initClassConv(Database *);
00982 
00983     odlUpdateAttribute(const Class *_cls, const Attribute *_item) :
00984       cls(_cls), item(_item) { }
00985 
00986     virtual Status postPerform(Database *, Schema *m);
00987 
00988     virtual void display();
00989     virtual void displayDiff(Database *db, const char *odlfile);
00990 
00991     virtual odlUpdateAttribute *asUpdateAttribute() {return this;}
00992 
00993   protected:
00994     Status invalidateCollClassOid(Database *, const Class *);
00995     Status invalidateInverseOid(Database *, const Class *);
00996     Status reportExtentOid(Database *db, const Class *);
00997   };
00998 
00999   class odlAddAttribute : public odlUpdateAttribute {
01000 
01001   public:
01002     odlAddAttribute(const Class *_cls, const Attribute *_item) :
01003       odlUpdateAttribute(_cls, _item) { }
01004     virtual odlAddAttribute *asAddAttribute() {return this;}
01005     Status prePerform(Database *, Schema *);
01006   };
01007 
01008   class odlRemoveAttribute : public odlUpdateAttribute {
01009 
01010   public:
01011     odlRemoveAttribute(const Class *_cls, const Attribute *_item) :
01012       odlUpdateAttribute(_cls, _item) { }
01013     virtual odlRemoveAttribute *asRemoveAttribute() {return this;}
01014     Status prePerform(Database *, Schema *);
01015   };
01016 
01017   class odlRenameAttribute : public odlUpdateAttribute {
01018 
01019   public:
01020     odlUpdateHint *upd_hints;
01021     odlRenameAttribute(const Class *_cls, const Attribute *_item,
01022                        odlUpdateHint *_upd_hints) :
01023       odlUpdateAttribute(_cls, _item), upd_hints(_upd_hints) { }
01024     virtual odlRenameAttribute *asRenameAttribute() {return this;}
01025     virtual void display();
01026     virtual void displayDiff(Database *db, const char *odlfile);
01027     Status prePerform(Database *, Schema *);
01028   };
01029 
01030   class odlConvertAttribute : public odlUpdateAttribute {
01031 
01032   public:
01033     odlUpdateHint *upd_hints;
01034     const Attribute *oitem;
01035     odlConvertAttribute(const Class *_cls, const Attribute *_oitem,
01036                         const Attribute *_item, odlUpdateHint *_upd_hints) :
01037       odlUpdateAttribute(_cls, _item), oitem(_oitem), upd_hints(_upd_hints) {
01038     }
01039     virtual odlConvertAttribute *asConvertAttribute() {return this;}
01040     virtual void display();
01041     virtual void displayDiff(Database *db, const char *odlfile);
01042     Status prePerform(Database *, Schema *);
01043     Status prePerformBasic(Schema *, const Class *ncls,
01044                            const Class *ocls);
01045   };
01046 
01047   class odlReorderAttribute : public odlUpdateAttribute {
01048 
01049   public:
01050     int oldnum, newnum;
01051     odlReorderAttribute(const Class *_cls, const Attribute *_item,
01052                         int _oldnum, int _newnum) :
01053       odlUpdateAttribute(_cls, _item), oldnum(_oldnum), newnum(_newnum) { }
01054     void display();
01055     void displayDiff(Database *db, const char *odlfile);
01056     virtual odlReorderAttribute *asReorderAttribute() {return this;}
01057     Status prePerform(Database *, Schema *);
01058   };
01059 
01060   class odlMigrateAttribute : public odlUpdateAttribute {
01061 
01062   public:
01063     odlUpdateHint *upd_hints;
01064     odlMigrateAttribute(const Class *_cls, const Attribute *_item,
01065                         odlUpdateHint *_upd_hints) :
01066       odlUpdateAttribute(_cls, _item), upd_hints(_upd_hints) { }
01067     virtual odlMigrateAttribute *asMigrateAttribute() {return this;}
01068     void display();
01069     void displayDiff(Database *db, const char *odlfile);
01070     Status prePerform(Database *, Schema *);
01071   };
01072 
01073 
01074   class odlUpdateClass : public odlUpdateItem {
01075 
01076   public:
01077     const Class *cls;
01078     odlUpdateClass(const Class *_cls) : cls(_cls) { }
01079     virtual Status postPerform(Database *, Schema *m);
01080     void display();
01081     void displayDiff(Database *db, const char *odlfile);
01082   };
01083 
01084   class odlAddClass : public odlUpdateClass {
01085 
01086   public:
01087     odlAddClass(const Class *_cls) : odlUpdateClass(_cls) { }
01088     virtual odlAddClass *asAddClass() {return this;}
01089     Status prePerform(Database *, Schema *);
01090   };
01091 
01092   class odlRemoveClass : public odlUpdateClass {
01093 
01094     LinkedList *list;
01095   public:
01096     odlRemoveClass(Database *db, const Class *_cls, LinkedList *list);
01097     virtual odlRemoveClass *asRemoveClass() {return this;}
01098     Status prePerform(Database *, Schema *);
01099     Status postPerform(Database *, Schema *);
01100   };
01101 
01102   class odlRenameClass : public odlUpdateClass {
01103 
01104   public:
01105     char *name;
01106     odlRenameClass(const Class *_cls, const char *_name) :
01107       odlUpdateClass(_cls), name(strdup(_name)) { }
01108     virtual odlRenameClass *asRenameClass() {return this;}
01109     Status prePerform(Database *, Schema *);
01110   };
01111 
01112   class odlReparentClass : public odlUpdateClass {
01113 
01114   public:
01115     odlReparentClass(const Class *_cls) : odlUpdateClass(_cls) { }
01116     virtual odlReparentClass *asReparentClass() {return this;}
01117     Status prePerform(Database *, Schema *);
01118   };
01119 
01120   class odlConvertClass : public odlUpdateClass {
01121 
01122   public:
01123     odlConvertClass(const Class *_cls) : odlUpdateClass(_cls) { }
01124     virtual odlConvertClass *asConvertClass() {return this;}
01125     Status prePerform(Database *, Schema *);
01126   };
01127 
01128 
01129   //
01130   // procedural corner
01131   //
01132 
01133   extern int
01134   odl_generate_code(Database *, Schema *, ProgLang, LinkedList *,
01135                     const char *package,
01136                     const char *schname,  const char *prefix,
01137                     const char *db_prefix, const GenCodeHints &);
01138   extern int
01139   odl_realize(Database *, Schema *m, LinkedList *list,
01140               const char *prefix = "", const char *db_prefix = "",
01141               const char *package = "",
01142               Bool diff = False);
01143 
01144   extern int
01145   odl_generate(Schema *m, const char *ofile);
01146 
01147   extern void
01148   odl_prompt_init(FILE *);
01149 
01150   extern void
01151   odl_prompt(const char *prompt = "> ");
01152 
01153   extern void
01154   odl_skip_volatiles(Database *db, Schema *m);
01155 
01156   extern LinkedList qseq_list;
01157   extern ProgLang odl_lang;
01158   extern int odl_diff;
01159   extern void odl_add_error(Status s);
01160   extern void odl_add_error(const char *fmt, ...);
01161   extern void odl_add_error(const std::string &s);
01162   extern Status odl_post_update(Database *db);
01163   extern Bool odl_dynamic_attr;
01164   extern Bool odl_system_class;
01165   extern Bool odl_rmv_undef_attrcomp;
01166   extern Bool odl_update_index;
01167   extern Bool odl_sch_rm;
01168   extern LinkedList odl_cls_rm;
01169   extern void odl_remove_component(Schema *m, ClassComponent *comp);
01170   extern void odl_add_component(Schema *m, ClassComponent *comp);
01171 
01172   extern char odlMTHLIST[];
01173   extern char odlGENCOMP[];
01174   extern char odlGENCODE[];
01175 }
01176 
01177 extern FILE *odlin;
01178 
01179 #endif

Generated on Mon Dec 22 18:15:59 2008 for eyedb by  doxygen 1.5.3