Schema.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 //#define protected public
00026 #include <string.h>
00027 #include <assert.h>
00028 #include <sys/stat.h>
00029 #include <time.h>
00030 #include "eyedb_p.h"
00031 #include <eyedblib/rpc_be.h>
00032 #include "DBM_Database.h"
00033 //#include "ipattern.cc"
00034 #include "make_pattern.cc"
00035 #include "odl.h"
00036 #include "Attribute_p.h"
00037 #include "kernel.h"
00038 #include "oqlctb.h"
00039 #include <lib/compile_builtin.h>
00040 
00041 using namespace std;
00042 
00043 namespace eyedb {
00044 
00045   extern Bool odl_smartptr;
00046 
00047   // 22/08/01: defined if one wants the same API when using dynamic-attr
00048   // option or not:
00049 #define UNIFIED_API
00050 
00051   //#define DEF_PREFIX "idb"
00052 #define DEF_PREFIX ""
00053 
00054 #ifdef UNIFIED_API
00055   static const char dyn_call_error[] = "can be called only when the dynamic attribute fonctionnality is on (-dynamic-attr option of eyedbodl)";
00056 #endif
00057 
00058   Database *default_db;
00059   struct SchemaLink {
00060     Oid oid;
00061     char *name;
00062     Class *cls;
00063     Class *cl;
00064 
00065     SchemaLink *next;
00066 
00067     SchemaLink(const Oid &_oid, Class *_class) {
00068       oid = _oid;
00069       cls = _class;
00070       name = 0;
00071       cl = 0;
00072       next = 0;
00073     }
00074 
00075     SchemaLink(const char *_name, Class *_class) {
00076       name = strdup(_name);
00077       cls = _class;
00078       next = 0;
00079     }
00080 
00081     SchemaLink(Class *_class) {
00082       cls = _class;
00083       name = 0;
00084       next = 0;
00085     }
00086 
00087     ~SchemaLink() {
00088       free(name);
00089     }
00090   };
00091 
00092   int check_pointer(void *);
00093   struct SchemaHashList {
00094 
00095     SchemaLink *first, *last;
00096 
00097     SchemaHashList() {first = last = 0;}
00098 
00099     inline void insert(SchemaLink *l) {
00100       if (last)
00101         last->next = l;
00102       else
00103         first = l;
00104 
00105       last = l;
00106     }
00107 
00108     ~SchemaHashList() {
00109 
00110       SchemaLink *l = first;
00111       while (l)
00112         {
00113           SchemaLink *next = l->next;
00114           delete l;
00115           l = next;
00116         }
00117       first = last = 0;
00118     }
00119   };
00120 
00121   static void stop_1() {}
00122   struct SchemaHashTable {
00123 
00124     int hash_cnt;
00125     unsigned int mask;
00126     SchemaHashList **names_lists;
00127     SchemaHashList **oids_lists;
00128     SchemaHashList **pts_lists;
00129 
00130     inline int get_key(const Oid &oid) {
00131       return oid.getNX() & mask;
00132     }
00133 
00134     inline int get_key(const Class *cls) {
00135       return (((unsigned long)cls)>>2) & mask;
00136     }
00137 
00138     inline int get_key(const char *name) {
00139       int len = strlen(name);
00140       int k = 0;
00141 
00142       for (int i = 0; i < len; i++)
00143         k += *name++;
00144 
00145       return k & mask;
00146     }
00147 
00148     inline SchemaHashTable() {
00149       hash_cnt = 256;
00150       mask = hash_cnt - 1;
00151       names_lists = new SchemaHashList*[hash_cnt];
00152       memset(names_lists, 0, sizeof(SchemaHashList *)*hash_cnt);
00153 
00154       oids_lists = new SchemaHashList*[hash_cnt];
00155       memset(oids_lists, 0, sizeof(SchemaHashList *)*hash_cnt);
00156 
00157       pts_lists = new SchemaHashList*[hash_cnt];
00158       memset(pts_lists, 0, sizeof(SchemaHashList *)*hash_cnt);
00159     }
00160 
00161     ~SchemaHashTable() {
00162 
00163       for (int k = 0; k < hash_cnt; k++)
00164         {
00165           delete oids_lists[k];
00166           delete names_lists[k];
00167           delete pts_lists[k];
00168         }
00169 
00170       delete [] oids_lists;
00171       delete [] names_lists;
00172       delete [] pts_lists;
00173     }
00174 
00175     void insert(const Oid &oid, Class *cls) {
00176 #ifdef OPTOPEN_TRACE
00177       printf("inserting %s %s %p\n", oid.getString(), cls->getName(), cls);
00178       if (!strcmp(cls->getName(), "set<object*>") ||
00179           !strcmp(cls->getName(), "set<Division*>"))
00180         stop_1();
00181 #endif
00182       int key = get_key(oid);
00183 
00184       if (!oids_lists[key])
00185         oids_lists[key] = new SchemaHashList();
00186       SchemaLink *l = new SchemaLink(oid, cls);
00187 
00188       oids_lists[key]->insert(l);
00189     }
00190 
00191     void insert(const char *name, Class *cls) {
00192       int key = get_key(name);
00193 
00194       if (!names_lists[key])
00195         names_lists[key] = new SchemaHashList();
00196       SchemaLink *l = new SchemaLink(name, cls);
00197 
00198       names_lists[key]->insert(l);
00199     }
00200 
00201     void insert(Class *cls) {
00202       int key = get_key(cls);
00203 
00204       if (!pts_lists[key])
00205         pts_lists[key] = new SchemaHashList();
00206       SchemaLink *l = new SchemaLink(cls);
00207 
00208       pts_lists[key]->insert(l);
00209     }
00210 
00211     Class *get(const Oid &oid) {
00212       int key = get_key(oid);
00213 
00214       if (!oids_lists[key])
00215         return 0;
00216       SchemaLink *l = oids_lists[key]->first;
00217       while (l)
00218         {
00219           if (l->oid.compare(oid))
00220             return l->cls;
00221           l = l->next;
00222         }
00223       return 0;
00224     }
00225 
00226     Class *get(const char *name) {
00227       int key = get_key(name);
00228 
00229       if (!names_lists[key])
00230         return 0;
00231 
00232       SchemaLink *l = names_lists[key]->first;
00233       while (l)
00234         {
00235           if (!strcmp(l->name, name))
00236             return l->cls;
00237           l = l->next;
00238         }
00239 
00240       return 0;
00241     }
00242 
00243     Class *get(const Class *cls) {
00244       int key = get_key(cls);
00245 
00246       if (!pts_lists[key])
00247         return 0;
00248 
00249       SchemaLink *l = pts_lists[key]->first;
00250       while (l)
00251         {
00252           if (l->cls == cls)
00253             return l->cls;
00254           l = l->next;
00255         }
00256       return 0;
00257     }
00258 
00259     Bool suppress(const char *name) {
00260       int key = get_key(name);
00261 
00262       if (!names_lists[key])
00263         return False;
00264 
00265       SchemaLink *prev = 0;
00266       SchemaLink *l = names_lists[key]->first;
00267 
00268       while (l)
00269         {
00270           if (!strcmp(l->name, name))
00271             {
00272               if (prev)
00273                 prev->next = l->next;
00274               else
00275                 names_lists[key]->first = l->next;
00276 
00277               if (names_lists[key]->last == l)
00278                 names_lists[key]->last = prev;
00279 
00280               delete l;
00281               return True;
00282             }
00283           prev = l;
00284           l = l->next;
00285         }
00286 
00287       return False;
00288     }
00289 
00290     Bool suppress(const Oid &oid) {
00291       int key = get_key(oid);
00292 
00293       if (!oids_lists[key])
00294         return False;
00295 
00296       SchemaLink *prev = 0;
00297       SchemaLink *l = oids_lists[key]->first;
00298 
00299       while (l)
00300         {
00301           if (l->oid.compare(oid))
00302             {
00303               if (prev)
00304                 prev->next = l->next;
00305               else
00306                 oids_lists[key]->first = l->next;
00307 
00308               if (oids_lists[key]->last == l)
00309                 oids_lists[key]->last = prev;
00310 
00311               delete l;
00312               return True;
00313             }
00314           prev = l;
00315           l = l->next;
00316         }
00317 
00318       return False;
00319     }
00320 
00321     Bool suppress(const Class *cls) {
00322       int key = get_key(cls);
00323 
00324       if (!pts_lists[key])
00325         return False;
00326 
00327       SchemaLink *prev = 0;
00328       SchemaLink *l = pts_lists[key]->first;
00329 
00330       while (l)
00331         {
00332           if (l->cls == cls)
00333             {
00334               if (prev)
00335                 prev->next = l->next;
00336               else
00337                 pts_lists[key]->first = l->next;
00338 
00339               if (pts_lists[key]->last == l)
00340                 pts_lists[key]->last = prev;
00341 
00342               delete l;
00343               return True;
00344             }
00345           prev = l;
00346           l = l->next;
00347         }
00348 
00349       return False;
00350     }
00351   };
00352 
00353   struct deferredLink {
00354     char *clname;
00355     eyedbsm::Oid oid;
00356     deferredLink(const char *_clname, const eyedbsm::Oid *_oid) {
00357       clname = strdup(_clname);
00358       oid = *_oid;
00359     }
00360     ~deferredLink() {
00361       free(clname);
00362     }
00363   };
00364 
00365   Schema::Schema() : Instance()
00366   {
00367     _class = new LinkedList();
00368     hash = new SchemaHashTable();
00369     name = strdup("");
00370     deferred_list = 0;
00371     reversal = False;
00372     class_cnt = 0;
00373     classes = 0;
00374     dont_delete_comps = False;
00375   }
00376 
00377   Schema::Schema(const Schema &sch) : Instance(sch)
00378   {
00379     _class = 0;
00380     hash = 0;
00381     name = 0;
00382     class_cnt = 0;
00383     classes = 0;
00384     *this = sch;
00385   }
00386 
00387   Schema& Schema::operator=(const Schema &sch)
00388   {
00389     //garbage(); // automatically called by the copy operator of Object
00390 
00391     *(Instance *)this = (const Instance &)sch;
00392     _class = Object::copyList(sch._class, True);
00393     name = strdup(sch.name);
00394     deferred_list = 0;
00395     reversal = False;
00396     hash = 0;
00397     dont_delete_comps = sch.dont_delete_comps;
00398     computeHashTable();
00399 
00400     Object_Class = sch.Object_Class;
00401     Class_Class = sch.Class_Class;
00402     BasicClass_Class = sch.BasicClass_Class;
00403     EnumClass_Class = sch.EnumClass_Class;
00404     AgregatClass_Class = sch.AgregatClass_Class;
00405     StructClass_Class = sch.StructClass_Class;
00406     UnionClass_Class = sch.UnionClass_Class;
00407     Instance_Class = sch.Instance_Class;
00408     Basic_Class = sch.Basic_Class;
00409     Enum_Class = sch.Enum_Class;
00410     Agregat_Class = sch.Agregat_Class;
00411     Struct_Class = sch.Struct_Class;
00412     Union_Class = sch.Union_Class;
00413     Schema_Class = sch.Schema_Class;
00414     Bool_Class = sch.Bool_Class;
00415     CollectionClass_Class = sch.CollectionClass_Class;
00416     CollSetClass_Class = sch.CollSetClass_Class;
00417     CollBagClass_Class = sch.CollBagClass_Class;
00418     CollListClass_Class = sch.CollListClass_Class;
00419     CollArrayClass_Class = sch.CollArrayClass_Class;
00420     Collection_Class = sch.Collection_Class;
00421     CollSet_Class = sch.CollSet_Class;
00422     CollBag_Class = sch.CollBag_Class;
00423     CollList_Class = sch.CollList_Class;
00424     CollArray_Class = sch.CollArray_Class;
00425     Char_Class = sch.Char_Class;
00426     Byte_Class = sch.Byte_Class;
00427     OidP_Class = sch.OidP_Class;
00428     Int16_Class = sch.Int16_Class;
00429     Int32_Class = sch.Int32_Class;
00430     Int64_Class = sch.Int64_Class;
00431     Float_Class = sch.Float_Class;
00432     return *this;
00433   }
00434 
00435   void Schema::computeHashTable()
00436   {
00437     //  printf("\nSchema::computeHashTable(this=%p)\n\n", this);
00438     delete hash;
00439     hash = new SchemaHashTable();
00440     free(classes);
00441 
00442     LinkedListCursor c(_class);
00443     class_cnt = _class->getCount();
00444     classes = (Class **)malloc(sizeof(Class *)*class_cnt);
00445 
00446     Class *cl;
00447 
00448     for (int n = 0; c.getNext((void *&)cl); n++)
00449       {
00450         assert(!cl->isRemoved());
00451         hash->insert(cl->getOid(), cl);
00452         hash->insert(cl->getName(), cl);
00453         hash->insert(cl);
00454         classes[n] = cl;
00455         cl->setNum(n);
00456       }
00457   }
00458 
00459   void Schema::hashTableInvalidate()
00460   {
00461     //  delete hash;
00462     //  hash = (SchemaHashTable *)0;
00463   }
00464 
00465   //#define BUG_TRACE
00466 
00467   Status Schema::addClass_nocheck(Class *mc, Bool atall)
00468   {
00469     if (mc->isRemoved()) {
00470 #ifdef BUG_TRACE
00471       printf("%d adding class %s %s %p\n", getpid(), mc->getName(), mc->getOid().toString(), mc);
00472 #endif
00473       assert(!mc->isRemoved());
00474     }
00475     /*
00476       printf("adding class %s %s %p\n", mc->getName(), mc->getOid().toString(),
00477       mc);
00478     */
00479     if (!atall)
00480       {
00481         if (mc->getOid().isValid())
00482           {
00483             if (hash->get(mc->getOid()))
00484               return Success;
00485           }
00486         else if (_class->getPos(mc) >= 0)
00487           return Success;
00488       }
00489 
00490     _class->insertObjectLast(mc);
00491     mc->gbx_locked = gbxTrue;
00492 
00493     if (mc->getOid().isValid())
00494       {
00495         hash->insert(mc->getOid(), mc);
00496         hash->insert(mc->getName(), mc);
00497       }
00498 
00499     touch();
00500     mc->sch = this;
00501     // added the 30/03/00
00502     mc->db = db;
00503     // ...
00504 
00505     return Success;
00506   }
00507 
00508   Status Schema::addClass(Class *mc)
00509   {
00510     assert(!mc->isRemoved());
00511     /*
00512       printf("Schema::addingClass(%s, %s)\n", mc->getName(),
00513       mc->getOid().toString());
00514     */
00515     if (mc->getOid().isValid())
00516       {
00517         if (hash->get(mc->getOid()))
00518           return Success;
00519       }
00520     else if (_class->getPos(mc) >= 0)
00521       return Success;
00522 
00523     Class *omc;
00524     if ((omc = getClass(mc->name))) // was &&db : why??
00525       return Exception::make(IDB_SCHEMA_ERROR,
00526                              "duplicate class names in schema: '%s'",
00527                              mc->name);
00528 
00529     _class->insertObjectLast(mc);
00530     mc->gbx_locked = gbxTrue;
00531     if (mc->getOid().isValid())
00532       {
00533         hash->insert(mc->getOid(), mc);
00534         hash->insert(mc->getName(), mc);
00535       }
00536 
00537     touch();
00538     mc->sch = this;
00539     // added the 10/12/99
00540     //#ifndef OPTOPEN
00541     mc->attrsComplete();
00542     //#endif
00543     // ..
00544 
00545     // added the 30/03/00
00546     mc->db = db;
00547     // ...
00548 
00549     return Success;
00550   }
00551 
00552   Status Schema::suppressClass(Class *mc)
00553   {
00554     if (!mc)
00555       return Success;
00556 
00557     /*
00558       printf("schema(this=%p) suppress %p: \"%s\" [%s]\n", this, mc, mc->getName(),
00559       mc->getOid().getString());
00560     */
00561 
00562     if (_class->deleteObject(mc) >= 0)
00563       mc->gbx_locked = gbxFalse;
00564 
00565     if (mc->getOid().isValid())
00566       {
00567         hash->suppress(mc->getOid());
00568         hash->suppress(mc->getName());
00569       }
00570 
00571     touch();
00572     if (mc->sch == this)
00573       mc->sch = NULL;
00574     return Success;
00575   }
00576 
00577   void Schema::setReversal(Bool on_off)
00578   {
00579     reversal = on_off;
00580   }
00581 
00582   Bool Schema::isReversalSet() const
00583   {
00584     return reversal;
00585   }
00586 
00587   void Schema::revert(Bool rev)
00588   {
00589     if (!reversal)
00590       return;
00591 
00592     LinkedListCursor c(_class);
00593     Class *cl;
00594 
00595     while (c.getNext((void *&)cl))
00596       cl->revert(rev);
00597 
00598     reversal = False;
00599   }
00600 
00601   void Schema::purge()
00602   {
00603     Class **tosup = new Class *[_class->getCount()];
00604     int tosup_cnt = 0;
00605     LinkedListCursor *c = _class->startScan();
00606     Class *cl;
00607 
00608     while (_class->getNextObject(c, (void *&)cl))
00609       {
00610         Bool found;
00611         const Oid &xoid = cl->getOid();
00612         if (xoid.isValid())
00613           {
00614             Status status = db->containsObject(xoid, found);
00615             if ((status && status->getStatus() == eyedbsm::INVALID_OID) || !found)
00616               tosup[tosup_cnt++] = cl;
00617           }
00618       }
00619 
00620     for (int i = 0; i < tosup_cnt; i++)
00621       suppressClass(tosup[i]);
00622   
00623     delete[] tosup;
00624     modify = False;
00625   }
00626 
00627   // added the 21/05/99
00628 
00629   void
00630   Schema::postComplete()
00631   {
00632     Class *cl;
00633     LinkedListCursor c(_class);
00634     while (c.getNext((void *&)cl))
00635       {
00636         ObjectPeer::setClass(cl, getClass(cl->getClass()->getName()));
00637 
00638         if (cl->getParent())
00639           ClassPeer::setParent(cl, getClass(cl->getParent()->getName()));
00640       }
00641   }
00642 
00643   Status
00644   Schema::complete(Bool _setup, Bool force)
00645   {
00646     Status status;
00647     Class *cl;
00648 
00649     computeHashTable();
00650 
00651     LinkedListCursor c(_class);
00652 
00653     while (c.getNext((void *&)cl)) {
00654       assert(!cl->isRemoved());
00655       if (status = cl->attrsComplete())
00656         return status;
00657     }
00658 
00659     postComplete();
00660 
00661     if (!_setup)
00662       return Success;
00663 
00664     status = setup(force);
00665     if (status) return status;
00666 
00667     /*
00668       if (db->isBackEnd() && (db->getOpenFlag() & _DBRW))
00669       return completeIndexes();
00670     */
00671 
00672     return Success;
00673   }
00674 
00675   Status Schema::setup(Bool force)
00676   {
00677     Status status;
00678     Class *cl;
00679     LinkedListCursor c(_class);
00680 
00681     while (c.getNext((void *&)cl)) {
00682       assert(!cl->isRemoved());
00683       if (status = cl->setup(force))
00684         return status;
00685     }
00686 
00687     return Success;
00688   }
00689 
00690   Status Schema::trace(FILE* fd, unsigned int flags, const RecMode *rcm) const
00691   {
00692     fprintf(fd, "%s schema = ", oid.getString());
00693     return trace_realize(fd, INDENT_INC, flags, rcm);
00694   }
00695 
00696   Status Schema::setValue(Data)
00697   {
00698     return Success;
00699   }
00700 
00701   Status Schema::getValue(Data*) const
00702   {
00703     return Success;
00704   }
00705 
00706   Status
00707   Schema::trace_realize(FILE *fd, int indent,
00708                         unsigned int flags,
00709                         const RecMode *rcm) const
00710   {
00711     LinkedListCursor *c = _class->startScan();
00712     char *indent_str = make_indent(indent);
00713     void *o;
00714 
00715     if (state & Tracing)
00716       {
00717         fprintf(fd, "%s%s;\n", indent_str, oid.getString());
00718         delete_indent(indent_str);
00719         return Success;
00720       }
00721 
00722     Status s = Success;
00723     char *lastindent_str = make_indent(indent-INDENT_INC);
00724     const_cast<Schema *>(this)->state |= Tracing;
00725 
00726     fprintf(fd, "{\n");
00727 
00728     fprintf(fd, "%sname = \"%s\";\n", indent_str, name);
00729     while (_class->getNextObject(c, o))
00730       {
00731         Class *cl = (Class *)o;
00732         //      fprintf(fd, "%s%s = ", indent_str, cl->getOid().getString());
00733         s = ObjectPeer::trace_realize(cl, fd, indent + INDENT_INC, flags, rcm);
00734       }
00735 
00736     _class->endScan(c);
00737 
00738     fprintf(fd, "%s};\n", lastindent_str);
00739     delete_indent(lastindent_str);
00740     delete_indent(indent_str);
00741     const_cast<Schema *>(this)->state &= ~Tracing;
00742 
00743     return s;
00744   }
00745 
00746   Status Schema::create(void)
00747   {
00748     return Success;
00749   }
00750 
00751   Status
00752   Schema::deferredCollRegisterRealize(DbHandle *dbh)
00753   {
00754     Status status = Success;
00755 
00756     if (!deferred_list)
00757       return Success;
00758 
00759     LinkedListCursor *c = deferred_list->startScan();
00760 
00761     deferredLink *d;
00762 
00763     while (deferred_list->getNextObject(c, (void *&)d))
00764       {
00765         Class *cl = getClass(d->clname);
00766 
00767         if (!cl)
00768           {
00769             status = Exception::make(IDB_ERROR, "class '%s' not found\n", d->clname);
00770             goto out;
00771           }
00772 
00773         Collection *extent;
00774         if (cl->isPartiallyLoaded())
00775           {
00776             status = cl->wholeComplete();
00777             if (status) return status;
00778           }
00779 
00780         status = cl->getExtent(extent);
00781         if (status) return status;
00782 
00783         if (!extent)
00784           {
00785             status = Exception::make(IDB_ERROR, "extent not found for class '%s'", d->clname);
00786             goto out;
00787           }
00788 
00789         const eyedbsm::Oid *colloid = extent->getOid().getOid();
00790         IDB_collClassRegister(dbh, colloid, &d->oid, True);
00791         delete d;
00792       }
00793 
00794   out:
00795     deferred_list->endScan(c);
00796     delete deferred_list;
00797     deferred_list = 0;
00798     return status;
00799   }
00800 
00801   void
00802   Schema::deferredCollRegister(const char *clname,
00803                                const eyedbsm::Oid *_oid)
00804   {
00805     if (!deferred_list)
00806       deferred_list = new LinkedList;
00807 
00808     deferredLink *d = new deferredLink(clname, _oid);
00809     deferred_list->insertObject(d);
00810   }
00811 
00812 #define builtin_make(cls, type) \
00813 cls = new type; \
00814 addClass_nocheck(cls); \
00815 cls->setAttributes((Attribute **)class_info[Basic_Type].items, \
00816                       class_info[Basic_Type].items_cnt); \
00817                       ClassPeer::setMType(cls, Class::System)
00818 
00819   void
00820   Schema::class_make(Class **cl, int _type,
00821                      Class *_parent)
00822   {
00823     *cl = new Class(class_info[_type].name, _parent);
00824 
00825     (*cl)->setAttributes((Attribute **)class_info[_type].items, class_info[_type].items_cnt);
00826 
00827     ClassPeer::setMType(*cl, Class::System);
00828 
00829     addClass_nocheck(*cl);
00830   }
00831 
00832   void
00833   Schema::bool_class_make(Class **cl)
00834   {
00835     *cl = Class::makeBoolClass();
00836     addClass_nocheck(*cl);
00837   }
00838 
00839   Status Schema::init(Database *database, Bool _create)
00840   {
00841     Status status = Success;
00842 
00843     db = database;
00844 
00845     Class_Class = 0;
00846 
00847     class_make(&Object_Class, Object_Type, (Class *)0);
00848 
00849     class_make(&Class_Class, Class_Type, Object_Class);
00850     Object_Class->setClass(Class_Class);
00851     Object_Class->parent = (Class *)0;
00852 
00853     class_make(&BasicClass_Class, BasicClass_Type, Class_Class);
00854 
00855     class_make(&EnumClass_Class, EnumClass_Type, Class_Class);
00856 
00857     class_make(&AgregatClass_Class, AgregatClass_Type, Class_Class);
00858 
00859     class_make(&StructClass_Class, StructClass_Type, AgregatClass_Class);
00860 
00861     class_make(&UnionClass_Class, UnionClass_Type, AgregatClass_Class);
00862 
00863 
00864     class_make(&Instance_Class, Instance_Type, Object_Class);
00865 
00866     class_make(&Basic_Class, Basic_Type, Instance_Class);
00867 
00868     class_make(&Enum_Class, Enum_Type, Instance_Class);
00869 
00870     class_make(&Agregat_Class, Agregat_Type, Instance_Class);
00871 
00872     class_make(&Struct_Class, Struct_Type, Agregat_Class);
00873 
00874     class_make(&Union_Class, Union_Type, Agregat_Class);
00875 
00876     class_make(&Schema_Class, Schema_Type, Instance_Class);
00877 
00878     bool_class_make(&Bool_Class);
00879 
00880     class_make(&CollectionClass_Class, CollectionClass_Type, Class_Class);
00881 
00882     class_make(&CollBagClass_Class, CollBagClass_Type, CollectionClass_Class);
00883 
00884     class_make(&CollSetClass_Class, CollSetClass_Type, CollectionClass_Class);
00885 
00886     class_make(&CollListClass_Class, CollListClass_Type, CollectionClass_Class);
00887 
00888     class_make(&CollArrayClass_Class, CollArrayClass_Type, CollectionClass_Class);
00889 
00890 
00891     class_make(&Collection_Class, Collection_Type, Instance_Class);
00892 
00893     class_make(&CollBag_Class, CollBag_Type, Collection_Class);
00894 
00895     class_make(&CollSet_Class, CollSet_Type, Collection_Class);
00896 
00897     class_make(&CollList_Class, CollList_Type, Collection_Class);
00898 
00899     class_make(&CollArray_Class, CollArray_Type, Collection_Class);
00900 
00901     builtin_make(Char_Class, CharClass);
00902     builtin_make(Byte_Class, ByteClass);
00903     builtin_make(OidP_Class, OidClass);
00904     builtin_make(Int16_Class, Int16Class);
00905     builtin_make(Int32_Class, Int32Class);
00906     builtin_make(Int64_Class, Int64Class);
00907     builtin_make(Float_Class, FloatClass);
00908 
00909     if (db && _create)
00910       {
00911         Database *odb = default_db;
00912         default_db = db;
00913         status = syscls::updateSchema(db);
00914         if (!status) {
00915           db->transactionBegin();
00916           status = post_etc_update(db);
00917           db->transactionCommit();
00918           if (status)
00919             {
00920               default_db = odb;
00921               return status;
00922             }
00923 
00924           if (db->getName() &&
00925               !strcmp(db->getName(), DBM_Database::getDbName()))
00926             status = DBM_Database::updateSchema(db);
00927 
00928           if (!status && !db->isBackEnd())
00929             {
00930               db->transactionBegin();
00931               status = realize();
00932               db->transactionCommit();
00933             }
00934 
00935           if (!status)
00936             status = oqlctb::updateSchema(db);
00937 
00938           if (!status)
00939             status = utils::updateSchema(db);
00940         }
00941 
00942         default_db = odb;
00943         return status;
00944       }
00945 
00946     return status;
00947   }
00948 
00949   Status Schema::remove(const RecMode*)
00950   {
00951     return Success;
00952   }
00953 
00954   Status Schema::realize(const RecMode*)
00955   {
00956     //printf("Schema::realize(%s, state %p)\n", oid.toString(), state);
00957 
00958     if (state & Realizing)
00959       return Success;
00960 
00961     state |= Realizing;
00962 
00963     LinkedListCursor *c = _class->startScan();
00964     Status status;
00965 
00966     Class *cl;
00967 
00968     while (_class->getNextObject(c, (void *&)cl)) {
00969       assert(!cl->isRemoved());
00970       if (status = cl->setDatabase(db))
00971         {
00972           _class->endScan(c);
00973           state &= ~Realizing;
00974           return status;
00975         }
00976     }
00977 
00978     _class->endScan(c);
00979 
00980     ClassPeer::setMType(CollSet_Class, Class::System);
00981     status = CollSet_Class->realize();
00982 
00983     if (status)
00984       {
00985         state &= ~Realizing;
00986         return status;
00987       }
00988 
00989     status = Class_Class->realize();
00990 
00991     if (status)
00992       {
00993         state &= ~Realizing;
00994         return status;
00995       }
00996 
00997     Class **mtmp = (Class **)malloc(_class->getCount() *
00998                                     sizeof(Class *));
00999 
01000     int n = 0;
01001     c = _class->startScan();
01002     while (_class->getNextObject(c, (void* &)cl))
01003       mtmp[n++] = cl;
01004     _class->endScan(c);
01005 
01006     int mod_cnt = 0;
01007     int i;
01008     for (i = 0; i < n ; i++)
01009       {
01010         cl = mtmp[i];
01011         mod_cnt += (cl->isModify() ? 1 : 0);
01012 
01013         status = cl->realize();
01014 
01015         if (status)
01016           {
01017             free(mtmp);
01018             state &= ~Realizing;
01019             return status;
01020           }
01021       }
01022 
01023     if ((status = complete(mod_cnt ? True : False)) ||
01024         (status = StatusMake(schemaComplete(db->getDbHandle(), name))))
01025       {
01026         free(mtmp);
01027         state &= ~Realizing;
01028         return status;
01029       }
01030 
01031     for (i = 0; i < n ; i++) {
01032       status = mtmp[i]->postCreate();
01033       if (status) {
01034         free(mtmp);
01035         state &= ~Realizing;
01036         return status;
01037       }
01038     }
01039 
01040     for (i = 0; i < n ; i++) {
01041       status = mtmp[i]->createComps();
01042       if (status) {
01043         free(mtmp);
01044         state &= ~Realizing;
01045         return status;
01046       }
01047     }
01048 
01049     free(mtmp);
01050 
01051     state &= ~Realizing;
01052 
01053     return status;
01054   }
01055 
01056   Status Schema::storeName()
01057   {
01058     return StatusMake(schemaComplete(db->getDbHandle(), name));
01059   }
01060 
01061   Status Schema::update(void)
01062   {
01063     return realize();
01064   }
01065 
01066   Status
01067   schemaClassMake(Database *db, const Oid *oid, Object **o,
01068                       const RecMode *rcm, const ObjectHeader *hdr,
01069                       Data idr, LockMode lockmode, const Class*)
01070   {
01071     Schema *sch = new Schema();
01072     RPCStatus rpc_status;
01073     Data temp;
01074 
01075     temp = (unsigned char *)malloc(hdr->size);
01076 
01077     if (!idr)
01078       {
01079         object_header_code_head(temp, hdr);
01080         rpc_status = objectRead(db->getDbHandle(), (Data)temp, 0, 0,
01081                                     oid->getOid(), 0, lockmode, 0);
01082       }
01083     else
01084       {
01085         memcpy(temp, idr, hdr->size);
01086         rpc_status = RPCSuccess;
01087       }
01088 
01089     if (rpc_status == RPCSuccess)
01090       {
01091         eyedblib::int32 cnt;
01092         Offset offset = IDB_SCH_CNT_INDEX;
01093         int32_decode(temp, &offset, &cnt);
01094 
01095         sch->init(db, False);
01096 
01097         Schema *o_sch = db->getSchema();
01098         db->setSchema(sch);
01099 
01100         char *s;
01101         offset = IDB_SCH_NAME_INDEX;
01102         string_decode(temp, &offset, &s);
01103 
01104         sch->setName(s);
01105 
01106         for (int i = 0; i < cnt; i++) {
01107           Oid toid;
01108           Status status;
01109           Class *cl;
01110           Offset offset = IDB_SCH_OID_INDEX(i);
01111         
01112           oid_decode(temp, &offset, toid.getOid());
01113         
01114           if (toid.isValid()) {
01115             char *name = 0;
01116             eyedblib::int32 hdr_type;
01117             int32_decode(temp, &offset, &hdr_type);
01118             status = class_name_decode(db->getDbHandle(), temp,
01119                                            &offset, &name);
01120             if (status) return status;
01121             Bool newClass;
01122             status = Class::makeClass(db, toid, hdr_type, name,
01123                                       newClass, cl);
01124             free(name);
01125             if (status) return status;
01126             if (newClass)
01127               sch->addClass_nocheck(cl, True);
01128           }
01129         }
01130 
01131         ObjectPeer::setModify(sch, False);
01132         db->setSchema(o_sch);
01133         *o = sch;
01134         ObjectPeer::setClass(sch, sch->getClass("schema"));
01135       }
01136     else
01137       sch->release();
01138 
01139     free(temp);
01140     return StatusMake(rpc_status);
01141   }
01142 
01143   void
01144   Schema::setName(const char *_name)
01145   {
01146     if (name == _name)
01147       return;
01148 
01149     free(name);
01150     name = strdup(_name);
01151   }
01152 
01153   void Schema::garbage()
01154   {
01155     //printf("Schema::garbage(this=%p, count=%d)\n", this, _class->getCount());
01156     dont_delete_comps = True;
01157 
01158     Class *cl;
01159     LinkedListCursor c_cls(_class);
01160 
01161     ClassComponent *comp;
01162     LinkedList tmpcomplist;
01163 
01164     while (c_cls.getNext((void *&)cl))
01165       {
01166         cl->lock(); // prevents deleting while recursive component deletion
01167         LinkedList *complist = cl->complist;
01168         if (complist)
01169           {
01170             LinkedListCursor cx(complist);
01171             while (cx.getNext((void *&)comp))
01172               {
01173                 if (tmpcomplist.getPos(comp) < 0)
01174                   tmpcomplist.insertObjectLast(comp);
01175               }
01176 
01177             delete complist;
01178           }
01179 
01180         cl->complist = NULL;
01181       }
01182 
01183     LinkedListCursor c_comp(tmpcomplist);
01184   
01185     while (c_comp.getNext((void *&)comp)) {
01186       comp->unlock_refcnt();
01187       comp->release();
01188     }
01189 
01190     c_cls.restart();
01191 
01192     while (c_cls.getNext((void *&)cl)) {
01193       cl->pre_release();
01194     }
01195 
01196     c_cls.restart();
01197 
01198     while (c_cls.getNext((void *&)cl)) {
01199       cl->unlock_refcnt();
01200       cl->release();
01201     }
01202 
01203     delete _class;
01204     delete hash;
01205 
01206     free(classes);
01207     free(name);
01208     Instance::garbage();
01209   }
01210 
01211   Schema::~Schema()
01212   {
01213     garbageRealize();
01214   }
01215 
01216   Status
01217   Schema::manageClassDeferred(Class *cl)
01218   {
01219 #ifdef OPTOPEN_TRACE
01220     printf("class %s is deferred %s %p\n", cl->getName(), cl->getOid().getString(),
01221            cl);
01222 #endif
01223 #ifdef BUG_TRACE
01224     printf("isRemoved %d %p %s\n", cl->isRemoved(), cl, cl->getName());
01225 #endif
01226     cl->setPartiallyLoaded(False);
01227 
01228     Class *clx;
01229     Status s = db->loadObject(cl->getOid(), (Object *&)clx);
01230     if (s) return s;
01231 
01232 #ifdef BUG_TRACE
01233     printf("isRemoved2 %d %p %s\n", clx->isRemoved(), clx, clx->getName());
01234 #endif
01235 #ifdef OPTOPEN_TRACE
01236     printf("clx %s -> %d [clx => %p == %p?\n",
01237            clx->getName(), clx->getAttributesCount(), clx, cl);
01238 #endif
01239     if (cl != clx) {
01240       s = cl->loadComplete(clx);
01241       if (s) return s;
01242       s = cl->attrsComplete();
01243       if (s) return s;
01244       clx->release();
01245     }
01246 
01247 #ifdef OPTOPEN_TRACE
01248     printf("Returning %p %s cnt=%d\n",
01249            cl, cl->getName(), cl->getAttributesCount());
01250 #endif
01251     return Success;
01252   }
01253 
01254   Status
01255   Schema::checkDuplicates()
01256   {
01257     std::string s;
01258 
01259     LinkedListCursor c(_class);
01260     Class *cls;
01261     while (c.getNext((void *&)cls)) {
01262       //printf("class=%p\n", cls);
01263       LinkedListCursor xc(_class);
01264       Class *xcls;
01265       while (xc.getNext((void *&)xcls)) {
01266         //printf("%p vs. %p '%s' vs '%s'\n", xcls, cls, cls->getName(), xcls->getName());
01267         if (xcls != cls && !strcmp(cls->getName(), xcls->getName())) {
01268           s += std::string("duplicate: ") + str_convert((long)cls, "%p") +
01269             " " + str_convert((long)xcls, "%p") + " " + cls->getName() + "\n";
01270         }
01271       }
01272     }
01273 
01274     printf("checking schema duplicates -> %s\n", s.c_str());
01275     if (s.size())
01276       return Exception::make(IDB_ERROR, s.c_str());
01277 
01278     return Success;
01279   }
01280 
01281   Bool
01282   Schema::checkClass(const Class *cl)
01283   {
01284     LinkedListCursor c(_class);
01285     Class *cls;
01286     while (c.getNext((void *&)cls)) {
01287       if (cls == cl)
01288         return True;
01289     }
01290 
01291     return False;
01292   }
01293 
01294   Status
01295   Schema::clean(Database *db)
01296   {
01297     LinkedListCursor c(_class);
01298     Class *cls;
01299     while (c.getNext((void *&)cls)) {
01300       Status s = cls->clean(db);
01301       if (s) return s;
01302     }
01303 
01304     return Success;
01305   }
01306 
01307   Class *Schema::getClass(const Oid &poid, Bool perform_load)
01308   {
01309     if (!poid.isValid())
01310       return (Class *)0;
01311 
01312     Class *cl;
01313 
01314     assert(hash);
01315     if (hash)
01316       {
01317         cl = hash->get(poid);
01318         if (cl)
01319           {
01320             if (cl->isPartiallyLoaded())
01321               {
01322                 Status s = manageClassDeferred(cl);
01323                 if (s) throw *s;
01324               }
01325             return cl;
01326           }
01327       }
01328 
01329     if (!hash || !cl)
01330       {
01331         LinkedListCursor *c = _class->startScan();
01332 
01333         while (_class->getNextObject(c, (void* &)cl))
01334           {
01335             Oid moid = cl->getOid();
01336           
01337             if (moid.compare(poid))
01338               {
01339                 _class->endScan(c);
01340                 return cl;
01341               }
01342           }
01343 
01344         _class->endScan(c);
01345       }
01346 
01347 
01348     if (perform_load)
01349       {
01350         Status status;
01351         Object *o;
01352         status = db->loadObject(&poid, &o);
01353         if (status == Success)
01354           {
01355             if (!o->asClass())
01356               {
01357                 o->release();
01358                 return 0;
01359               }
01360 
01361             cl = (Class *)o;
01362 
01363             Class *tcl;
01364             if (tcl = getClass(cl->getName()))
01365               {
01366                 if (cl != tcl)
01367                   cl->release();
01368                 return tcl;
01369               }
01370 
01371             addClass_nocheck(cl);
01372             cl->attrsComplete();
01373 
01374             return cl;
01375           }
01376         else
01377           throw *status;
01378       }
01379 
01380     return 0;
01381   }
01382 
01383   Class *Schema::getClass(const char *n)
01384   {
01385     Class *cl;
01386 
01387     assert(hash);
01388     if (hash)
01389       {
01390         cl = hash->get(n);
01391         if (cl)
01392           {
01393             if (cl->isPartiallyLoaded())
01394               {
01395                 Status s = manageClassDeferred(cl);
01396                 if (s) throw *s;
01397               }
01398             return cl;
01399           }
01400       }
01401 
01402     if (!hash || !cl)
01403       {
01404         LinkedListCursor c(_class);
01405 
01406         while (c.getNext((void *&)cl))
01407           if (!strcmp(cl->getName(), n) || !strcmp(cl->getAliasName(), n))
01408             return cl;
01409       }
01410 
01411     return 0;
01412   }
01413 
01414   const LinkedList *Schema::getClassList(void) const
01415   {
01416     Class *cl;
01417     LinkedListCursor c(_class);
01418     while (c.getNext((void *&)cl)) {
01419       if (cl->isPartiallyLoaded()) {
01420         Status s = const_cast<Schema *>(this)->manageClassDeferred(cl);
01421         if (s) throw *s;
01422       }
01423     }
01424     return _class;
01425   }
01426 
01427   static void
01428   head_gen_C(FILE *fd, const char *files, const char *ext, const char *package,
01429              const GenCodeHints &hints,
01430              Bool donot_edit, const char *suffix = "",
01431              Bool inclPack = False, Bool use_namespace = False,
01432              const char *c_namespace = 0)
01433   {
01434     char file[256];
01435 
01436     sprintf(file, "%s%s%s", files, ext, suffix);
01437     fprintf(fd ,"\n/*\n");
01438     fprintf(fd, " * EyeDB Version %s Copyright (c) 1995-2006 SYSRA\n",
01439             eyedb::getVersion());
01440     fprintf(fd, " *\n");
01441     fprintf(fd, " * File '%s'\n", file);
01442     fprintf(fd, " *\n");
01443     fprintf(fd, " * Package Name '%s'\n", package);
01444     fprintf(fd, " *\n");
01445     if (hints.gen_date) {
01446       time_t t;
01447       time(&t);
01448       fprintf(fd, " * Generated by eyedbodl at %s", ctime(&t));
01449     }
01450     else
01451       fprintf(fd, " * Generated by eyedbodl\n");
01452 
01453     fprintf(fd ," *\n");
01454 
01455     if (donot_edit)
01456       {
01457         fprintf(fd, " * ---------------------------------------------------\n");
01458         fprintf(fd, " * -------------- DO NOT EDIT THIS CODE --------------\n");
01459         fprintf(fd, " * ---------------------------------------------------\n");
01460         fprintf(fd ," *\n");
01461       }
01462 
01463     fprintf(fd, " */\n\n");
01464 
01465     fprintf(fd, "#include <eyedb/eyedb.h>\n\n");
01466 
01467     if (inclPack)
01468       fprintf(fd, "#include \"%s.h\"\n\n", files); // 22/08/01: was `package'
01469     // instead of files
01470     if (use_namespace && c_namespace)
01471       fprintf(fd, "using namespace %s;\n\n", c_namespace);
01472   }
01473 
01474   /*
01475   static void
01476   head_gen_Java(FILE *fd, const char *files, const char *ext,
01477                 const char *package, Bool donot_edit = True)
01478   {
01479     char file[256];
01480     time_t t;
01481     time(&t);
01482 
01483     sprintf(file, "%s%s", files, ext);
01484     fprintf(fd ,"\n*\n");
01485     fprintf(fd, " * File '%s'\n", file);
01486     fprintf(fd, " *\n");
01487     fprintf(fd, " * Package Name '%s'\n", package);
01488     fprintf(fd, " *\n");
01489     fprintf(fd, " * Generated by eyedbodl at %s", ctime(&t));
01490     fprintf(fd ," *\n");
01491 
01492     if (donot_edit)
01493       {
01494         fprintf(fd, " * Do not edit this code\n");
01495         fprintf(fd ," *\n");
01496       }
01497 
01498     fprintf(fd, " *\n\n");
01499 
01500     fprintf(fd, "#include <eyedb/eyedb.h>\n\n");
01501   }
01502   */
01503 
01504   inline static void
01505   make_file(const char *dirname, const char *files, const char *ext, char file[],
01506             const char *ext1)
01507   {
01508     sprintf(file, "%s/%s%s%s", dirname, files, ext, ext1);
01509   }
01510 
01511   static Status
01512   make_file(const char *dirname, const char *files, const char *ext, FILE **fd,
01513             const char *ext1 = "", Bool check_if_exists = False)
01514   {
01515     static FILE *fdnull;
01516 
01517     char file[256];
01518 
01519     make_file(dirname, files, ext, file, ext1);
01520 
01521     if (check_if_exists) {
01522         struct stat s;
01523         if (stat(file, &s) >= 0) {
01524           /*
01525           fprintf(stderr, "Notice: file %s exists, not overwrite it\n",
01526                   file);
01527           */
01528           /*if (!fdnull)
01529             fdnull = fopen("/dev/null", "rw");
01530           *fd = fdnull;
01531           */
01532           *fd = 0;
01533           return Success;
01534         }
01535     }
01536 
01537     *fd = fopen(file, "w");
01538 
01539     if (!*fd)
01540       return Exception::make(IDB_GENERATION_CODE_ERROR, "cannot open file '%s' for writing", file);
01541 
01542     return Success;
01543   }
01544 
01545   static Status
01546   remove_file(const char *dirname, const char *files, const char *ext,
01547               const char *ext1 = "")
01548   {
01549     char file[256];
01550 
01551     make_file(dirname, files, ext, file, ext1);
01552     unlink(file);
01553     return Success;
01554   }
01555 
01556   static void
01557   skel_comment(FILE *fd, const char *files, const char *febe, Bool backend)
01558   {
01559     fprintf(fd,
01560             "// To implement and use user methods, perform the following operations\n"
01561             "/*\n"
01562             "\n"
01563             "#1. Copy the skeleton file\n"
01564             "cp %s%s-skel.cc %s%s.cc\n"
01565             "\n"
01566             "#2. Implement the user methods in %s%s.cc using a text editor\n"
01567             "\n"
01568             //      "#3. Compile the shared library using GNU make\n"
01569             //      "make -f Makefile.%s all\n",
01570             "#3. Compile the shared library\n",
01571             files, febe, files, febe,
01572             files, febe,
01573             files);
01574 
01575     const char *s = Executable::getSOTag();
01576     fprintf(fd,
01577             "\n"
01578             "#4. Copy the shared library to the eyedb loadable library directory\n"
01579             "cp %s%s%s.so <eyedbinstalldir>/lib/eyedb\n"
01580             "\n"
01581             "#5. Change the file access mode\n"
01582             "chmod a+r <eyedbinstalldir>/lib/eyedb/%s%s%s.so\n",
01583             files, febe, s,
01584             files, febe, s);
01585 
01586     fprintf(fd, "\n*/\n\n");
01587   }
01588 
01589   static Status
01590   make_files(const char *dirname, const char *files, const char *package,
01591              const char *c_suffix, const char *h_suffix,
01592              FILE **pfdh, FILE **pfdc,
01593              FILE **pfdstubsfe, FILE **pfdstubsbe,
01594              FILE **pfdmthfe, FILE **pfdmthbe, FILE **pfdmk,
01595              FILE **pfdtempl)
01596   {
01597     Status status;
01598 
01599     if (status = make_file(dirname, files, h_suffix, pfdh))
01600       return status;
01601   
01602     if (status = make_file(dirname, files, c_suffix, pfdc))
01603       return status;
01604 
01605     if (status = make_file(dirname, files, "stubsfe", pfdstubsfe, c_suffix))
01606       return status;
01607 
01608     if (status = make_file(dirname, files, "stubsbe", pfdstubsbe, c_suffix))
01609       return status;
01610 
01611     if (status = make_file(dirname, files, "mthfe-skel", pfdmthfe, c_suffix))
01612       return status;
01613 
01614     if (status = make_file(dirname, files, "mthbe-skel", pfdmthbe, c_suffix))
01615       return status;
01616 
01617     if (status = make_file(dirname, "Makefile.", package, pfdmk,
01618                            "", True))
01619       return status;
01620 
01621     if (status = make_file(dirname, "template_", package, pfdtempl,
01622                            c_suffix, True))
01623       return status;
01624 
01625     return Success;
01626   }
01627 
01628   static Status
01629   remove_files(const char *dirname, const char *files, const char *package,
01630                const char *c_suffix, const char *h_suffix)
01631   {
01632     Status status;
01633 
01634     if (status = remove_file(dirname, files, h_suffix))
01635       return status;
01636   
01637     if (status = remove_file(dirname, files, "stubsbe", c_suffix))
01638       return status;
01639   
01640     if (status = remove_file(dirname, files, "stubsfe", c_suffix))
01641       return status;
01642   
01643     if (status = remove_file(dirname, files, c_suffix, c_suffix))
01644       return status;
01645 
01646     if (status = remove_file(dirname, files, "init"))
01647       return status;
01648 
01649     if (status = remove_file(dirname, "Makefile.", package))
01650       return status;
01651 
01652     if (status = remove_file(dirname, "template_", package, c_suffix))
01653       return status;
01654 
01655     return Success;
01656   }
01657 
01658   void
01659   Schema::genODL(FILE *fd, unsigned int flags) const
01660   {
01661     ((Schema *)this)->sort_classes();
01662 
01663     if (name && *name)
01664       {
01665         fprintf(fd ,"\n//\n");
01666         fprintf(fd, "// EyeDB Version %s Copyright (c) 1995-2007 SYSRA\n",
01667                 eyedb::getVersion());
01668         fprintf(fd, "//\n");
01669         fprintf(fd, "// %s Schema\n", name);
01670         fprintf(fd, "//\n");
01671         time_t t;
01672         time(&t);
01673         fprintf(fd, "// Generated by eyedbodl at %s", ctime(&t));
01674         fprintf(fd, "//\n\n");
01675         /*
01676         fprintf(fd, "#if defined(EYEDBNUMVERSION) && EYEDBNUMVERSION != %d\n", eyedb::getVersionNumber());
01677         fprintf(fd, "#error \"This file is being compiled with a version of eyedb different from that used to create it (%s)\"\n", eyedb::getVersion());
01678         fprintf(fd, "#endif\n\n");
01679         */
01680       }
01681 
01682     LinkedListCursor c(_class);
01683     Class *cl;
01684     int r = 0;
01685 
01686     if (db && db->isOpened()) db->transactionBegin();
01687     while(c.getNext((void *&)cl)) {
01688       if (r) fprintf(fd, "\n");
01689       r = cl->genODL(fd, (Schema *)this);
01690     }
01691 
01692     if (db && db->isOpened()) db->transactionAbort();
01693   }
01694 
01695   const char *
01696   Schema::generateStubs_C(Bool genstubs, Class *cl,
01697                           const char *dirname, const char *package,
01698                           const GenCodeHints &hints)
01699   {
01700     if (genstubs && cl->asAgregatClass()) {
01701       static char file[256];
01702       sprintf(file, "%s/%s_stubs.h", dirname, cl->getName());
01703       const char *pfile = strchr(file, '/') + 1;
01704       FILE *fd = fopen(file, "r");
01705       if (fd) {
01706         fclose(fd);
01707         return pfile;
01708       }
01709       
01710       fd = fopen(file, "w");
01711 
01712       if (fd) {
01713         head_gen_C(fd, pfile, "", package, hints, False);
01714         fclose(fd);
01715       }
01716 
01717       return pfile;
01718     }
01719     
01720     return (char *)0;
01721   }
01722 
01723   static const char *
01724   cap(const char *s, const char *prefix)
01725   {
01726     static char *str;
01727     static int len;
01728     int l;
01729     int ll = strlen(prefix);
01730     char c;
01731 
01732     l = strlen(s) - ll;
01733 
01734     if (l >= len)
01735       {
01736         str = (char *)realloc(str, l+1);
01737         len = l;
01738       }
01739 
01740     c = s[ll];
01741     strcpy(str, &s[ll]);
01742     str[0] = ((c >= 'a' && c <= 'z') ? (c + 'A' - 'a') : c);
01743     return str;
01744   }
01745 
01746   static void *InitSort = (void *)0;
01747   static void *InsertedSort = (void *)1;
01748   static void *ProcessingSort = (void *)2;
01749 
01750   void
01751   Schema::sort_realize(const Class *cl, LinkedList *l)
01752   {
01753     if (cl->getUserData() != InitSort)
01754       return;
01755 
01756     const_cast<Class *>(cl)->setUserData(ProcessingSort);
01757 
01758     const Class **tmp = new const Class*[_class->getCount()];
01759 
01760     int i, j;
01761     for (i = 0; cl; i++)
01762       {
01763         tmp[i] = cl;
01764         cl = cl->getParent();
01765       }
01766 
01767     for (j = i-1; j >= 0; j--)
01768       if (tmp[j]->getUserData() != InsertedSort)
01769         {
01770           unsigned int attr_cnt;
01771           const Attribute **attr = tmp[j]->getAttributes(attr_cnt);
01772           for (int k = 0; k < attr_cnt; k++)
01773             if (!attr[k]->isIndirect() &&
01774                 attr[k]->getClass()->asAgregatClass())
01775               sort_realize(attr[k]->getClass(), l);
01776 
01777           l->insertObjectLast((void *)tmp[j]);
01778           const_cast<Class *>(tmp[j])->setUserData(InsertedSort);
01779         }
01780 
01781     delete[] tmp;
01782   }
01783 
01784   void
01785   Schema::sort_classes()
01786   {
01787     (void)getClassList(); // to force schema completion
01788     LinkedList *l = new LinkedList();
01789 
01790     LinkedListCursor c(_class);
01791     Class *cl;
01792     int n;
01793     for (n = 0; c.getNext((void *&)cl); n++)
01794       {
01795         cl->setUserData(InitSort);
01796         if (cl->asEnumClass())
01797           {
01798             l->insertObjectLast(cl);
01799             cl->setUserData(InsertedSort);
01800           }
01801       }
01802 
01803     LinkedListCursor cx(_class);
01804     for (n = 0; cx.getNext((void *&)cl); n++)
01805       if (!cl->asEnumClass())
01806         sort_realize(cl, l);
01807 
01808     delete _class;
01809     _class = l;
01810   }
01811 
01812   Status
01813   Schema::generateCode(ProgLang lang,
01814                        const char *package, const char *schname,
01815                        const char *c_namespace,
01816                        const char *prefix,
01817                        const char *db_prefix,
01818                        const GenCodeHints &hints,
01819                        Bool _export,
01820                        Class *superclass,
01821                        LinkedList *qseq_list)
01822   {
01823     sort_classes();
01824 
01825     if (lang == ProgLang_C)
01826       return generateCode_C(package, schname, c_namespace, prefix, db_prefix,
01827                             hints, _export, superclass, qseq_list);
01828 
01829     if (lang == ProgLang_Java)
01830       return generateCode_Java(package, schname, prefix, db_prefix,
01831                                hints, _export, superclass,
01832                                qseq_list);
01833 
01834     return Exception::make(IDB_ERROR, "unknown language: %d", lang);
01835   }
01836 
01837   static Status
01838   make_java_file(const char *dirname, const char *package,
01839                  const char *prefix, const char *name, 
01840                  const GenCodeHints &hints, FILE *&fd)
01841   {
01842     char file[256];
01843     sprintf(file, "%s/%s%s.java", dirname, prefix, name);
01844 
01845     fd = fopen(file, "w");
01846 
01847     if (!fd)
01848       return Exception::make(IDB_ERROR, "cannot create file '%s'", file);
01849 
01850     fprintf(fd, "\n");
01851     fprintf(fd, "//\n");
01852     fprintf(fd, "// class %s%s\n", prefix, name);
01853     fprintf(fd, "//\n");
01854     fprintf(fd, "// package %s\n", package);
01855     fprintf(fd, "//\n");
01856     if (hints.gen_date) {
01857       time_t t;
01858       time(&t);
01859       fprintf(fd, "// Generated by eyedbodl at %s", ctime(&t));
01860     }
01861     else
01862       fprintf(fd, "// Generated by eyedbodl\n");
01863 
01864     fprintf(fd, "//\n\n");
01865 
01866     fprintf(fd, "package %s;\n\n", package);
01867     // (fd): commented out next line for compilation with gcj (org.eyedb.Object conflicts with java.lang.Object)
01868     //    fprintf(fd, "import org.eyedb.*;\n"); 
01869     fprintf(fd, "import org.eyedb.utils.*;\n");
01870     fprintf(fd, "import org.eyedb.syscls.*;\n\n");
01871 
01872     return Success;
01873   }
01874 
01875   static Bool
01876   check_class(const Class *cl, Bool pass)
01877   {
01878     if (cl->getUserData(odlGENCODE))
01879       return True;
01880 
01881     if (pass && cl->getUserData(odlGENCOMP))
01882       return True;
01883 
01884     return False;
01885   }
01886 
01887   static Status
01888   check_dir(const char *dirname)
01889   {
01890     struct stat st;
01891     if (stat(dirname, &st) < 0)
01892       {
01893         if (mkdir(dirname, 0777) < 0)
01894           return Exception::make(IDB_ERROR, "cannot create directory %s",
01895                                  dirname);
01896       }
01897 
01898     return Success;
01899   }
01900 
01901 
01902   Status
01903   Schema::generateCode_Java(const char *package, const char *schname,
01904                             const char *prefix,
01905                             const char *db_prefix,
01906                             const GenCodeHints &hints,
01907                             Bool _export,
01908                             Class *superclass,
01909                             LinkedList *)
01910   {
01911     Status status = Success;
01912     FILE *fd;
01913 
01914     if (status = check_dir(hints.dirname))
01915       return status;
01916 
01917     if (status = make_java_file(hints.dirname, package, prefix, "Database", hints, fd))
01918       return status;
01919 
01920     GenContext ctx(fd, package, odl_rootclass);
01921     ctx.push();
01922 
01923     fprintf(fd, "public class %sDatabase extends org.eyedb.Database {\n\n", prefix);
01924 
01925     fprintf(fd, "  public %sDatabase(String name) {super(name);}\n\n", prefix);
01926 
01927     fprintf(fd, "  public %sDatabase(String name, String dbmfile) {super(name, dbmfile);}\n\n", prefix);
01928 
01929     fprintf(fd, "  public %sDatabase(int dbid) {super(dbid);}\n\n", prefix);
01930 
01931     fprintf(fd, "  public %sDatabase(int dbid, String dbmfile) {super(dbid, dbmfile);}\n\n", prefix);
01932 
01933     fprintf(fd,
01934             "  public void open(org.eyedb.Connection conn, int flags, String userauth, "
01935             "String passwdauth) throws org.eyedb.Exception\n");
01936     fprintf(fd, "  {\n");
01937     fprintf(fd, "    super.open(conn, flags, userauth, passwdauth);\n\n");
01938     fprintf(fd, "    checkSchema(getSchema());\n");
01939     fprintf(fd, "  }\n\n");
01940 
01941     fprintf(fd, "  public org.eyedb.Object loadObjectRealize(org.eyedb.Oid oid, "
01942             "int lockmode, org.eyedb.RecMode rcm)\n  throws org.eyedb.Exception\n");
01943 
01944     fprintf(fd, "  {\n");
01945     fprintf(fd, "    org.eyedb.Object o = super.loadObjectRealize(oid, lockmode, rcm);\n");
01946     fprintf(fd, "    org.eyedb.Object ro = makeObject(o, true);\n");
01947     fprintf(fd, "    if (ro != null) o = ro;\n");
01948     fprintf(fd, "    return o;\n");
01949     fprintf(fd, "  }\n\n");
01950 
01951     fprintf(fd, "  private void checkSchema(org.eyedb.Schema m) throws org.eyedb.Exception {\n");
01952     // TBD
01953     LinkedListCursor c(_class);
01954     fprintf(fd, "    org.eyedb.Class cl;\n");
01955     fprintf(fd, "    String msg = \"\";\n\n");
01956     Class *cl;
01957 
01958     while (c.getNext((void *&)cl))
01959       if (cl->getUserData(odlGENCODE) && !cl->asCollectionClass()) {
01960         if (cl->isRootClass())
01961           continue;
01962         fprintf(fd, "    if ((cl = m.getClass(\"%s\")) == null)\n",
01963                 cl->getAliasName());
01964         fprintf(fd, "      msg += \"class '%s' does not exist\\n\";\n",
01965                 cl->getAliasName());
01966         fprintf(fd, "    else if (!%s.idbclass.compare(cl))\n", cl->getCName());
01967         fprintf(fd, "      msg += \"class '%s' differs in database and in runtime environment\\n\";\n",
01968                 cl->getAliasName());
01969       }
01970 
01971     fprintf(fd, "    if (!msg.equals(\"\")) throw new org.eyedb.Exception(new org.eyedb.Status(org.eyedb.Status.IDB_ERROR, msg));\n");
01972     fprintf(fd, "  }\n\n");
01973 
01974     fprintf(fd, "  static public org.eyedb.Object makeObject(org.eyedb.Object o, boolean share)\n");
01975     fprintf(fd, "  throws org.eyedb.Exception {\n\n");
01976     fprintf(fd, "    if (o == null || o.getClass(true) == null) return o;\n\n");
01977     fprintf(fd, "    if (o.isGRTObject()) return o;\n\n");
01978     //#define Java_DEBUG
01979 
01980     LinkedListCursor *curs;
01981 #ifdef Java_DEBUG
01982     curs = _class->startScan();
01983 
01984     ctx.push();
01985     fprintf(fd, "%sString xname = o.getClass(true).getName();\n",
01986             ctx.get());
01987     while (_class->getNextObject(curs, (void *&)cl))
01988       if (cl->getUserData(odlGENCODE) && cl->asAgregatClass()) {
01989         fprintf(fd, "%sif (xname.equals(\"%s\"))\n", ctx.get(),
01990                 cl->getAliasName());
01991         fprintf(fd, "%s  return new %s((org.eyedb.Struct)o, share);\n",
01992                 ctx.get(), cl->getCName());
01993       }
01994 
01995     fprintf(fd, "%sreturn o;\n", ctx.get());
01996     ctx.pop();
01997 
01998 #else
01999     fprintf(fd, "    try {\n");
02000     fprintf(fd, "      java.lang.reflect.Constructor cons = (java.lang.reflect.Constructor)hash.get(o.getClass(true).getName());\n");
02001     fprintf(fd, "      if (cons == null) return o;\n\n");
02002     fprintf(fd, "      java.lang.Object[] tmp = new java.lang.Object[2]; tmp[0] = o; tmp[1] = new java.lang.Boolean(share);\n");
02003     fprintf(fd, "      return (org.eyedb.Object)cons.newInstance(tmp);\n");
02004     fprintf(fd, "    } catch(java.lang.Exception e) {\n");
02005     fprintf(fd, "      System.err.println(\"caught \" + e + \" in database\");\n");
02006     fprintf(fd, "      System.exit(2);\n");
02007     fprintf(fd, "      return null;\n");
02008     fprintf(fd, "    }\n");
02009 
02010 #endif
02011 
02012     fprintf(fd, "  }\n\n");
02013 
02014     fprintf(fd, "  static java.util.Hashtable hash = new java.util.Hashtable(256);\n");
02015     fprintf(fd, "  static protected java.lang.Class[] clazz;\n");
02016     fprintf(fd, "  static {\n");
02017     fprintf(fd, "    clazz = new java.lang.Class[2];\n");
02018     fprintf(fd, "    clazz[0] = org.eyedb.Struct.class;\n");
02019     fprintf(fd, "    clazz[1] = boolean.class;\n");
02020     fprintf(fd, "  }\n\n");
02021 
02022     fprintf(fd, "  public static void init()\n throws org.eyedb.Exception {\n");
02023 
02024     ctx.push();
02025 
02026     curs = _class->startScan();
02027 
02028     while (_class->getNextObject(curs, (void *&)cl))
02029       if (check_class(cl, False))
02030         fprintf(fd, "%s%s.init_p();\n", ctx.get(), cl->getCName());
02031 
02032     ctx.pop();
02033     _class->endScan(curs);
02034 
02035     ctx.push();
02036     curs = _class->startScan();
02037     while (_class->getNextObject(curs, (void *&)cl))
02038       if (cl->getUserData(odlGENCODE) && !cl->asCollectionClass())
02039         fprintf(fd, "%s%s.init();\n", ctx.get(), cl->getCName());
02040 
02041     ctx.pop();
02042     _class->endScan(curs);
02043 
02044     fprintf(fd, "  }\n");
02045 
02046     fprintf(fd, "}\n\n");
02047 
02048     fclose(fd);
02049 
02050     curs = _class->startScan();
02051 
02052     while (_class->getNextObject(curs, (void *&)cl))
02053       {
02054         if (check_class(cl, False)) {
02055           if (status = make_java_file(hints.dirname, package, "",
02056                                       cl->getCName(), hints, fd))
02057             return status;
02058         
02059           status = cl->generateCode_Java(this, prefix, hints, fd);
02060           if (status) {
02061             _class->endScan(curs);
02062             goto out;
02063           }
02064         
02065           fclose(fd);
02066         }
02067       }
02068 
02069     _class->endScan(curs);
02070 
02071   out:
02072     return status;
02073   }
02074 
02075   static void
02076   pack_init(FILE *fd, const char *package)
02077   {
02078     fprintf(fd, "static Bool __%s_init = False;\n\n", package);
02079     //  fprintf(fd, "static Database *__%s_db = 0;\n\n", package);
02080     fprintf(fd, "#define _packageInit(DB) \\\n \\\n");
02081     fprintf(fd, "  if (!__%s_init) { \\\n", package);
02082     fprintf(fd, "    %s::init(); \\\n", package);
02083     fprintf(fd, "    __%s_init = True; \\\n", package);
02084     fprintf(fd, "  } \\\n \\\n");
02085     fprintf(fd, "  if (!(DB)->getUserData(\"eyedb:%s\")) { \\\n", package);
02086     fprintf(fd, "     Status s = %sDatabase::checkSchema((DB)->getSchema()); \\\n", package);
02087     fprintf(fd, "     if (s) return s; \\\n");
02088     fprintf(fd, "     %sDatabase::setConsApp(DB); \\\n", package);
02089     fprintf(fd, "     (DB)->setUserData(\"eyedb:%s\", (void *)1); \\\n", package);
02090     fprintf(fd, "  }\n\n");
02091   }
02092 
02093   Status
02094   Schema::generateCode_C(const char *package, const char *schname,
02095                          const char *c_namespace,
02096                          const char *prefix,
02097                          const char *db_prefix,
02098                          const GenCodeHints &hints,
02099                          Bool _export,
02100                          Class *superclass,
02101                          LinkedList *qseq_list)
02102   {
02103     FILE *fdh, *fdc, *fdstubsfe, *fdstubsbe, *fdmthfe, *fdmthbe, *fdmk,
02104       *fdtempl;
02105     Status status;
02106 
02107     //Exception::Mode MM = Exception::setMode(Exception::StatusMode);
02108     //status = checkDuplicates();
02109     //if (status) return status;
02110     //Exception::setMode(MM);
02111 
02112     if (status = check_dir(hints.dirname))
02113       return status;
02114 
02115     if (status = make_files(hints.dirname, hints.fileprefix, package,
02116                             hints.c_suffix, hints.h_suffix,
02117                             &fdh, &fdc, &fdstubsfe, &fdstubsbe,
02118                             &fdmthfe, &fdmthbe, &fdmk, &fdtempl))
02119       return status;
02120 
02121     head_gen_C(fdh, hints.fileprefix, hints.h_suffix, package, hints, True);
02122 
02123     fprintf(fdh, "#ifndef _eyedb_%s_\n", package);
02124     fprintf(fdh, "#define _eyedb_%s_\n\n", package);
02125 
02126     // 6/09/05: should be replaced by correct naming for classes
02127     //fprintf(fdh, "using namespace eyedb;\n\n");
02128 
02129     if (c_namespace)
02130       fprintf(fdh, "namespace %s {\n\n", c_namespace);
02131 
02132     if (qseq_list)
02133       {
02134         LinkedListCursor *curs = qseq_list->startScan();
02135 
02136         char *qseq;
02137 
02138         while (qseq_list->getNextObject(curs, (void *&)qseq))
02139           fprintf(fdh, "%s", qseq);
02140 
02141         qseq_list->endScan(curs);
02142       }
02143 
02144     //  fprintf(fdc, "#ifndef _inlining_\n\n");
02145     head_gen_C(fdc, hints.fileprefix, hints.c_suffix, package, hints, True);
02146 
02147     fprintf(fdc, "#include <eyedb/internals/ObjectPeer.h>\n");
02148     fprintf(fdc, "#include <eyedb/internals/ClassPeer.h>\n");
02149     fprintf(fdc, "#include <eyedb/internals/kern_const.h>\n\n");
02150 
02151     fprintf(fdc, "#include \"%s%s\"\n\n", hints.fileprefix, hints.h_suffix);
02152 
02153     fprintf(fdc, "#define min(x,y)((x)<(y)?(x):(y))\n\n");
02154 
02155     if (c_namespace)
02156       fprintf(fdc, "namespace %s {\n\n", c_namespace);
02157 
02158     /*
02159       fprintf(fdc, "static inline unsigned char *rawdup(const unsigned char *data, unsigned int len)\n{\n");
02160       fprintf(fdc, "  unsigned char *x = (unsigned char *)malloc(len);\n");
02161       fprintf(fdc, "  memcpy(x, data, len);\n");
02162       fprintf(fdc, "  return x;\n");
02163       fprintf(fdc, "}\n\n");
02164     */
02165 
02166 #ifndef UNIFIED_API
02167     if (odl_dynamic_attr) {
02168 #endif
02169       fprintf(fdc, "static eyedb::Bool dynget_error_policy = eyedb::False;\n");
02170       fprintf(fdc, "static eyedb::Bool dynset_error_policy = eyedb::True;\n");
02171 #ifndef UNIFIED_API
02172     }
02173 #endif
02174 
02175     fprintf(fdc, "static eyedb::Oid nulloid;\n");
02176     fprintf(fdc, "static unsigned char nulldata[1];\n");
02177     fprintf(fdc, "static eyedb::Bool oid_check = eyedb::True;\n");
02178     fprintf(fdc, "static int class_ind;\n");
02179 
02180     fprintf(fdc, "static eyedb::Database::consapp_t *constructors_x = new eyedb::Database::consapp_t[%d];\n", _class->getCount());
02181 
02182     fprintf(fdc, "static eyedb::Object *(*constructors[%d])(const eyedb::Object *, eyedb::Bool);\n", _class->getCount());
02183     fprintf(fdc, "static eyedb::GenHashTable *hash;\n");
02184     //fprintf(fdc, "extern StructClass *OString_Class;\n");
02185     fprintf(fdc, "#define make_object %sMakeObject\n", package);
02186 
02187     fprintf(fdc, "extern void %sInit(void);\n", package);
02188     fprintf(fdc, "extern void %sRelease(void);\n", package);
02189     fprintf(fdc, "extern eyedb::Status %sSchemaUpdate(eyedb::Database *);\n", package);
02190     fprintf(fdc, "extern eyedb::Status %sSchemaUpdate(eyedb::Schema *);\n\n", package);
02191 
02192     // kludge
02193     fprintf(fdc, "static eyedb::Class *index_Class = new eyedb::Class(\"index\");\n\n");
02194 
02195     fprintf(fdc, "void %s::init()\n{\n  %sInit();\n}\n\n", package, package);
02196     fprintf(fdc, "void %s::release()\n{\n  %sRelease();\n}\n\n", package, package);
02197     fprintf(fdc, "eyedb::Status %s::updateSchema(eyedb::Database *db)\n{\n  return %sSchemaUpdate(db);\n}\n\n", package, package);
02198 
02199     fprintf(fdc, "eyedb::Status %s::updateSchema(eyedb::Schema *m)\n{\n  return %sSchemaUpdate(m);\n}\n\n", package, package);
02200 
02201     /*
02202       head_gen_C(fdinit, hints.fileprefix, "init", package, False,
02203       hints.c_suffix);
02204     */
02205     head_gen_C(fdstubsfe, hints.fileprefix, "stubsfe", package, hints, True,
02206                hints.c_suffix, True, True, c_namespace);
02207     head_gen_C(fdstubsbe, hints.fileprefix, "stubsbe", package, hints, True,
02208                hints.c_suffix, True, True, c_namespace);
02209     head_gen_C(fdmthfe, hints.fileprefix, "mthfe-skel", package, hints, False,
02210                hints.c_suffix, True, True, c_namespace);
02211     skel_comment(fdmthfe, hints.fileprefix, "mthfe", False);
02212     pack_init(fdmthfe, package);
02213     head_gen_C(fdmthbe, hints.fileprefix, "mthbe-skel", package, hints, False,
02214                hints.c_suffix, True, True, c_namespace);
02215     skel_comment(fdmthbe, hints.fileprefix, "mthbe", True);
02216     pack_init(fdmthbe, package);
02217     /*
02218       fprintf(fdinit, ipattern, package, package, package, package, package,
02219       package, package, package);
02220     */
02221     time_t t;
02222     time(&t);
02223     const char *sopath = eyedb::ServerConfig::getSValue("sopath");
02224     if (!sopath)
02225       return Exception::make("Configuration variable sopath is not set");
02226 
02227     char *xsopath = strdup(sopath);
02228     char *r = strchr(xsopath, ':');
02229     if (r) *r = 0;
02230     if (fdmk)
02231       fprintf(fdmk, make_pattern, package, package,
02232               "Generated by eyedbodl at",
02233               ctime(&t),
02234               eyedblib::CompileBuiltin::getPkgdatadir(),
02235               package, package, package,
02236               package);
02237 
02238     if (fdtempl)
02239       fprintf(fdtempl, template_pattern, package, package,
02240               "Generated by eyedbodl at",
02241               ctime(&t), package,
02242               (c_namespace ?
02243                (std::string(c_namespace) + "::" + package).c_str() :
02244                package), package, package,
02245               package, package, package, package);
02246 
02247     free(xsopath);
02248     LinkedListCursor *curs = _class->startScan();
02249 
02250     Class *cl;
02251 
02252     char *true_prefix = NULL;
02253     const char *p = strchr(prefix, ':');
02254     if (p)
02255       {
02256         int len = p - prefix;
02257         true_prefix = new char[len+1];
02258         strcpy(true_prefix, prefix);
02259         true_prefix[len] = 0;
02260       }
02261 
02262     GenContext ctxH(fdh, package, odl_rootclass);
02263 
02264     if (true_prefix){
02265       fprintf(fdh, "class %s {\n", true_prefix);
02266       ctxH.push();
02267     }
02268 
02269     while (_class->getNextObject(curs, (void *&)cl)) {
02270       if (check_class(cl, False)) {
02271         const char *suffix;
02272         string s;
02273         if (cl->asEnumClass())
02274           suffix = "eyedb::Enum";
02275         else if (cl->asAgregatClass())
02276           suffix = cl->asStructClass() ? "eyedb::Struct" : "eyedb::Union";
02277         else if (cl->asCollectionClass()) {
02278           s = string("eyedb::") + cl->asCollectionClass()->getCSuffix();
02279           suffix = s.c_str();
02280         }
02281         else
02282           suffix = "";
02283 
02284         if (!cl->asEnumClass() && !cl->asCollectionClass()) // added !cl->asCollectionClass the 2/11/06
02285           fprintf(fdh, "%sclass %s;\n", ctxH.get(), cl->getCName());
02286 
02287         fprintf(fdc, "%s" DEF_PREFIX "%sClass *%s_Class;\n",
02288                 ((!_export || cl->asCollectionClass()) ? "static " : ""),
02289                 suffix, cl->asBasicClass() ? cl->getName() : cl->getCName());
02290 
02291         cl->setCanonicalName(cap(cl->getName(), prefix));
02292       }
02293     }
02294 
02295     fprintf(fdc, "\n");
02296     fprintf(fdh, "\n");
02297     _class->endScan(curs);
02298 
02299     curs = _class->startScan();
02300     while (_class->getNextObject(curs, (void *&)cl)) {
02301       if (check_class(cl, False)) {
02302         if (!cl->asEnumClass() && !cl->asCollectionClass()) {
02303           if (odl_smartptr) {
02304             fprintf(fdh, "%sclass %sPtr : public %sPtr {\n",
02305                     ctxH.get(), cl->getCName(), cl->getParent()->getCName());
02306 
02307             fprintf(fdh, "\npublic:\n");
02308             fprintf(fdh, "%s  %sPtr(%s *o = 0);\n\n",
02309                     ctxH.get(), cl->getCName(), cl->getCName(),
02310                     cl->getParent()->getCName());
02311           
02312             fprintf(fdh, "%s  %s *get%s();\n",
02313                     ctxH.get(), cl->getCName(), cl->getCName(), cl->getCName());
02314             fprintf(fdh, "%s  const %s *get%s() const;\n\n",
02315                     ctxH.get(), cl->getCName(), cl->getCName(), cl->getCName());
02316     
02317             fprintf(fdh, "%s  %s *operator->();\n",
02318                     ctxH.get(), cl->getCName(), cl->getCName());
02319             fprintf(fdh, "%s  const %s *operator->() const;\n",
02320                     ctxH.get(), cl->getCName(), cl->getCName());
02321             fprintf(fdh, "%s};\n\n", ctxH.get());
02322           }
02323           /*
02324           else
02325             fprintf(fdh, "%stypedef %s * %sPtr;\n", ctxH.get(), cl->getCName(), cl->getName());
02326           */
02327         }
02328       }
02329     }
02330 
02331     _class->endScan(curs);
02332 
02333     fprintf(fdh, "\n%sclass %s {\n\n", ctxH.get(), package);
02334     fprintf(fdh, "%s public:\n", ctxH.get());
02335     fprintf(fdh, "%s  %s(int &argc, char *argv[]) {\n", ctxH.get(), package);
02336     fprintf(fdh, "%s    eyedb::init(argc, argv);\n", ctxH.get());
02337     fprintf(fdh, "%s    init();\n", ctxH.get());
02338     fprintf(fdh, "%s  }\n\n", ctxH.get());
02339     fprintf(fdh, "%s  ~%s() {\n", ctxH.get(), package);
02340     fprintf(fdh, "%s    release();\n", ctxH.get());
02341     fprintf(fdh, "%s    eyedb::release();\n", ctxH.get());
02342     fprintf(fdh, "%s  }\n\n", ctxH.get());
02343     fprintf(fdh, "%s  static void init();\n", ctxH.get());
02344     fprintf(fdh, "%s  static void release();\n", ctxH.get());
02345     fprintf(fdh, "%s  static eyedb::Status updateSchema(eyedb::Database *db);\n", ctxH.get());
02346     fprintf(fdh, "%s  static eyedb::Status updateSchema(eyedb::Schema *m);\n", ctxH.get());
02347     fprintf(fdh, "%s};\n", ctxH.get());
02348 
02349     fprintf(fdh, "%s\nclass %sDatabase : public eyedb::Database {\n", ctxH.get(), package);
02350 
02351 #define NO_COMMENTS
02352 
02353 #ifndef NO_COMMENTS
02354     fprintf(fdh, "%s\n  // ----------------------------------------------------------------------\n", ctxH.get());
02355     fprintf(fdh, "%s  // %sDatabase Interface\n", ctxH.get(), package);
02356     fprintf(fdh, "%s  // ----------------------------------------------------------------------\n", ctxH.get());
02357 #else
02358     fprintf(fdh, "%s\n", ctxH.get());
02359 #endif
02360     fprintf(fdh, "%s public:\n", ctxH.get());
02361 
02362     fprintf(fdh, "%s  %sDatabase(const char *dbname, const char *_dbmdb_str = 0) : eyedb::Database(dbname, _dbmdb_str) {}\n", ctxH.get(), package);
02363 
02364     fprintf(fdh, "%s  %sDatabase(eyedb::Connection *conn, const char *dbname, const char *_dbmdb_str, eyedb::Database::OpenFlag, const char *user = 0, const char *passwd = 0);\n", ctxH.get(), package);
02365 
02366     fprintf(fdh, "%s  %sDatabase(eyedb::Connection *conn, const char *dbname, eyedb::Database::OpenFlag, const char *user = 0, const char *passwd = 0);\n", ctxH.get(), package);
02367 
02368     fprintf(fdh, "%s  %sDatabase(const char *dbname, int _dbid, const char *_dbmdb_str = 0) : eyedb::Database(dbname, _dbid, _dbmdb_str) {}\n", ctxH.get(), package);
02369     fprintf(fdh, "%s  %sDatabase(int _dbid, const char *_dbmdb_str = 0) : eyedb::Database(_dbid, _dbmdb_str) {}\n", ctxH.get(), package);
02370 
02371     fprintf(fdh, "%s  eyedb::Status open(eyedb::Connection *, eyedb::Database::OpenFlag, const char *user = 0, const char *passwd = 0);\n", ctxH.get());
02372 
02373     fprintf(fdh, "%s  eyedb::Status open(eyedb::Connection *, eyedb::Database::OpenFlag, const eyedb::OpenHints *hints, const char *user = 0, const char *passwd = 0);\n", ctxH.get());
02374 
02375     fprintf(fdh, "%s  static void setConsApp(eyedb::Database *);\n", ctxH.get());
02376 
02377     if (superclass)
02378       {
02379         const char *sname = superclass->getName();
02380         fprintf(fdh, "%s\n  static %s *as%s(eyedb::Object *);\n", ctxH.get(), sname,
02381                 superclass->getCanonicalName());
02382         fprintf(fdh, "%s  static const %s *as%s(const eyedb::Object *);\n", ctxH.get(), sname,
02383                 superclass->getCanonicalName());
02384       }
02385 
02386     fprintf(fdh, "%s  static eyedb::Status checkSchema(eyedb::Schema *);\n", ctxH.get());
02387 #ifndef UNIFIED_API
02388     if (odl_dynamic_attr) {
02389 #endif
02390       fprintf(fdh, "%s  static eyedb::Bool getDynamicGetErrorPolicy();\n",
02391               ctxH.get());
02392       fprintf(fdh, "%s  static eyedb::Bool getDynamicSetErrorPolicy();\n",
02393               ctxH.get());
02394       fprintf(fdh, "%s  static void setDynamicGetErrorPolicy(eyedb::Bool policy);\n",
02395               ctxH.get());
02396       fprintf(fdh, "%s  static void setDynamicSetErrorPolicy(eyedb::Bool policy);\n",
02397               ctxH.get());
02398 #ifndef UNIFIED_API
02399     }
02400 #endif
02401 
02402     fprintf(fdh, "%s};\n\n", ctxH.get());
02403 
02404     GenContext ctx(fdc, package, odl_rootclass);
02405 
02406     curs = _class->startScan();
02407     while (_class->getNextObject(curs, (void *&)cl))
02408       if (check_class(cl, True))
02409         {
02410           const char *stubs = generateStubs_C(hints.gen_class_stubs,
02411                                               cl, hints.dirname, package, hints);
02412           status = cl->generateCode_C(this, prefix, hints, stubs, fdh, fdc,
02413                                       fdstubsfe, fdstubsbe, fdmthfe, fdmthbe);
02414           if (status)
02415             {
02416               _class->endScan(curs);
02417               goto out;
02418             }
02419         }
02420 
02421     _class->endScan(curs);
02422 
02423     fprintf(fdc, "static const char not_exit_msg[] = \"class does not exist\";\n");
02424     fprintf(fdc, "static const char differ_msg[] = \"class differs in database and in runtime environment\";\n\n");
02425 
02426     fprintf(fdc, "void %sInit(void)\n{\n", package);
02427 
02428     ctx.push();
02429     curs = _class->startScan();
02430 
02431     fprintf(fdc, "%sif (hash) return;\n\n", ctx.get());
02432     fprintf(fdc, "%shash = new eyedb::GenHashTable(%d, %d);\n\n", ctx.get(),
02433             strlen(db_prefix), _class->getCount());
02434 
02435     while (_class->getNextObject(curs, (void *&)cl))
02436       if (check_class(cl, False))
02437         fprintf(fdc, "%s%s_init_p();\n", ctx.get(), cl->getCName());
02438 
02439     ctx.pop();
02440     _class->endScan(curs);
02441 
02442     ctx.push();
02443     curs = _class->startScan();
02444     while (_class->getNextObject(curs, (void *&)cl))
02445       if (cl->getUserData(odlGENCODE) && !cl->asCollectionClass())
02446         fprintf(fdc, "%s%s_init();\n", ctx.get(), cl->getCName());
02447 
02448     ctx.pop();
02449     _class->endScan(curs);
02450 
02451     fprintf(fdc, "}\n\n");
02452 
02453     fprintf(fdc, "void %sRelease(void)\n{\n", package);
02454 
02455     ctx.push();
02456     curs = _class->startScan();
02457 
02458     fprintf(fdc, "%sif (!hash) return;\n\n", ctx.get());
02459     fprintf(fdc, "%sdelete hash;\n", ctx.get());
02460     fprintf(fdc, "%shash = 0;\n\n", ctx.get());
02461 
02462     while (_class->getNextObject(curs, (void *&)cl))
02463       if (check_class(cl, False))
02464         fprintf(fdc, "%s%s_Class->release();\n", ctx.get(), cl->getCName());
02465 
02466     ctx.pop();
02467     _class->endScan(curs);
02468 
02469     fprintf(fdc, "}\n\n");
02470 
02471     fprintf(fdc, "static eyedb::Status\n%sSchemaUpdate(eyedb::Schema *m, eyedb::Database *db)\n{\n", package);
02472 
02473     ctx.push();
02474     fprintf(fdc, "%sm->setName(\"%s\");\n", ctx.get(),
02475             (schname ? schname : package));
02476     fprintf(fdc, "%seyedb::Status status;\n", ctx.get());
02477 
02478     curs = _class->startScan();
02479     while (_class->getNextObject(curs, (void *&)cl))
02480       if (check_class(cl, False))
02481         {
02482           const char *suffix;
02483           string s;
02484           if (cl->asEnumClass())
02485             suffix = "eyedb::Enum";
02486           else if (cl->asAgregatClass())
02487             suffix = cl->asStructClass() ? "eyedb::Struct" : "eyedb::Union";
02488           else if (cl->asCollectionClass()) {
02489             s = string("eyedb::") + cl->asCollectionClass()->getCSuffix();
02490             suffix = s.c_str();
02491           }
02492           else
02493             suffix = "";
02494 
02495           fprintf(fdc, "%s" DEF_PREFIX "%sClass *%s_class = %s_make(0, m);\n", ctx.get(),
02496                   suffix, cl->getCName(), cl->getCName());
02497 
02498           if (!strcmp(cl->getName(), "set<object*>")) // kludge??
02499             continue;
02500 
02501           if (cl->isRootClass())
02502             continue;
02503 
02504           fprintf(fdc, "%sif (!m->getClass(\"%s\"))\n",
02505                   ctx.get(), cl->getAliasName());
02506           fprintf(fdc, "%s  {\n", ctx.get());
02507           fprintf(fdc, "%s    status = m->addClass(%s_class);\n", ctx.get(), cl->getCName());
02508           fprintf(fdc, "%s    if (status)\n", ctx.get());
02509           fprintf(fdc, "%s%s    return status;\n", ctx.get(), ctx.get());
02510           fprintf(fdc, "%s  }\n", ctx.get());
02511         }
02512 
02513     ctx.pop();
02514     _class->endScan(curs);
02515 
02516     fprintf(fdc, "\n");
02517 
02518     ctx.push();
02519     curs = _class->startScan();
02520     while (_class->getNextObject(curs, (void *&)cl))
02521       if (cl->getUserData(odlGENCODE) && !cl->asCollectionClass())
02522         fprintf(fdc, "%s%s_make(%s_class, m);\n", ctx.get(), cl->getCName(), cl->getName());
02523     _class->endScan(curs);
02524 
02525     fprintf(fdc, "\n%sif (!db) return eyedb::Success;\n\n", ctx.get());
02526 
02527     curs = _class->startScan();
02528     while (_class->getNextObject(curs, (void *&)cl))
02529       if (cl->getUserData(odlGENCODE) && !cl->asCollectionClass()) {
02530         if (cl->isRootClass())
02531           continue;
02532 
02533         fprintf(fdc, "%sif (!%s_class->compare(m->getClass(\"%s\")))\n",
02534                 ctx.get(), cl->getCName(), cl->getAliasName());
02535         fprintf(fdc, "%s  return eyedb::Exception::make(eyedb::IDB_ERROR, \"'%s' %%s\", differ_msg);\n", ctx.get(), cl->getName());
02536       }
02537 
02538     _class->endScan(curs);
02539     fprintf(fdc, "\n");
02540   
02541     //  fprintf(fdc, "%sdb->transactionBegin(DatabaseExclusiveTRMode);\n", ctx.get());
02542     fprintf(fdc, "%sdb->transactionBegin();\n", ctx.get());
02543 #define NEW_COMP_POLICY
02544 #ifndef NEW_COMP_POLICY
02545     fprintf(fdc, "%sstatus = m->realize();\n", ctx.get());
02546     fprintf(fdc, "%sif (status) return status;\n", ctx.get());
02547 #endif
02548 
02549     curs = _class->startScan();
02550     while (_class->getNextObject(curs, (void *&)cl))
02551       if ((cl->getUserData(odlGENCODE) || cl->getUserData(odlGENCOMP)) &&
02552           cl->getCompList() && cl->getCompList()->getCount()) {
02553         if (cl->asAgregatClass()) 
02554           fprintf(fdc, "\n%sif ((status = %s_comp_realize(db, m->getClass(\"%s\")))) "
02555                   "return status;\n", ctx.get(), cl->getName(), cl->getAliasName());
02556         else if (!cl->asCollectionClass())
02557           fprintf(fdc, "\n%sif ((status = %s_comp_realize(db, m->getClass(\"%s\")))) "
02558                   "return status;\n", ctx.get(), cl->getName(),
02559                   cl->getName());
02560       }
02561 
02562     _class->endScan(curs);
02563 
02564     curs = _class->startScan();
02565     while (_class->getNextObject(curs, (void *&)cl))
02566       if (cl->getUserData(odlGENCOMP) ||
02567           (cl->getUserData(odlGENCODE) && cl->asAgregatClass()))
02568         fprintf(fdc, "\n%sif ((status = %s_attrcomp_realize(db, m->getClass(\"%s\")))) "
02569                 "return status;\n", ctx.get(), cl->getName(), cl->getAliasName());
02570 
02571     _class->endScan(curs);
02572 #ifdef NEW_COMP_POLICY
02573     fprintf(fdc, "%sstatus = m->realize();\n", ctx.get());
02574     fprintf(fdc, "%sif (status) return status;\n", ctx.get());
02575 #endif
02576     fprintf(fdc, "%sdb->transactionCommit();\n", ctx.get());
02577     fprintf(fdc, "%sreturn eyedb::Success;\n", ctx.get());
02578 
02579     fprintf(fdc, "}\n\n");
02580 
02581     fprintf(fdc, "eyedb::Status %sSchemaUpdate(eyedb::Database *db)\n{\n",
02582             package);
02583 
02584     fprintf(fdc, "%sreturn %sSchemaUpdate(db->getSchema(), db);\n",
02585             ctx.get(), package);
02586 
02587     fprintf(fdc, "}\n\n");
02588 
02589     fprintf(fdc, "eyedb::Status %sSchemaUpdate(eyedb::Schema *m)\n{\n",
02590             package);
02591     fprintf(fdc, "%sreturn %sSchemaUpdate(m, NULL);\n", ctx.get(), package);
02592     fprintf(fdc, "}\n\n");
02593 
02594     fprintf(fdc, "eyedb::Object *%sMakeObject(eyedb::Object *o, eyedb::Bool remove)\n{\n", package);
02595     fprintf(fdc, "  if (!o->getClass()) return (eyedb::Object *)0;\n");
02596     // these 2 lines: REALLY?
02597     fprintf(fdc, "%sif (eyedb::ObjectPeer::isGRTObject(o))\n", ctx.get());
02598     fprintf(fdc, "%s  return o;\n", ctx.get());
02599     fprintf(fdc, "%sint ind = hash->get(o->getClass()->getName());\n", ctx.get());
02600     // BUG_ETC_UPDATE
02601     // 5/3/00 replaced:
02602     // fprintf(fdc, "%sif (ind < 0) return 0;\n", ctx.get());
02603     // by:
02604     fprintf(fdc, "%sif (ind < 0 && (!o->getClass()->getStrictAliasName() || (ind = hash->get(o->getClass()->getStrictAliasName())) < 0)) return 0;\n", ctx.get());
02605 
02606     fprintf(fdc, "%seyedb::Object *co = constructors[ind](o, (remove ? eyedb::True : eyedb::False));\n", ctx.get());
02607     fprintf(fdc, "%seyedb::ObjectPeer::setClass(co, o->getClass());\n", ctx.get());
02608     fprintf(fdc, "%sif (remove) o->release();\n", ctx.get());
02609     fprintf(fdc, "%sif (co->getDatabase())\n", ctx.get());
02610     fprintf(fdc, "%s  co->getDatabase()->cacheObject(co);\n", ctx.get());
02611     fprintf(fdc, "%sreturn co;\n", ctx.get());
02612     fprintf(fdc, "}\n\n");
02613 
02614     ctx.pop();
02615 
02616     fprintf(fdc, "%sDatabase::%sDatabase(eyedb::Connection *conn, const char *dbname, eyedb::Database::OpenFlag flag, const char *userauth, const char *passwdauth) : eyedb::Database(dbname)\n{\n", package, package);
02617     fprintf(fdc, "  eyedb::Status status = open(conn, flag, 0, userauth, passwdauth);\n");
02618     fprintf(fdc, "  if (status) throw *status;\n");
02619     fprintf(fdc, "}\n\n");
02620 
02621     fprintf(fdc, "%sDatabase::%sDatabase(eyedb::Connection *conn, const char *dbname, const char *dbmdb_str, eyedb::Database::OpenFlag flag, const char *userauth, const char *passwdauth) : eyedb::Database(dbname, dbmdb_str)\n{\n", package, package);
02622     fprintf(fdc, "  eyedb::Status status = open(conn, flag, 0, userauth, passwdauth);\n");
02623     fprintf(fdc, "  if (status) throw *status;\n");
02624     fprintf(fdc, "}\n\n");
02625 
02626     fprintf(fdc, "eyedb::Status %sDatabase::open(eyedb::Connection *conn, eyedb::Database::OpenFlag flag, const char *userauth, const char *passwdauth)\n{\n", package);
02627     fprintf(fdc, "  return open(conn, flag, 0, userauth, passwdauth);\n");
02628     fprintf(fdc, "}\n\n");
02629 
02630     fprintf(fdc, "eyedb::Status %sDatabase::open(eyedb::Connection *conn, eyedb::Database::OpenFlag flag, const eyedb::OpenHints *hints, const char *userauth, const char *passwdauth)\n{\n", package);
02631 
02632     fprintf(fdc, "  eyedb::Status status = eyedb::Database::open(conn, flag, hints, userauth, passwdauth);\n");
02633 
02634     fprintf(fdc, "  if (status) return status;\n");
02635     if (!odl_dynamic_attr) {
02636       fprintf(fdc, "  transactionBegin();\n");
02637       fprintf(fdc, "  status = %sDatabase::checkSchema(getSchema());\n", package);
02638       fprintf(fdc, "  transactionCommit();\n");
02639     }
02640 
02641 
02642     fprintf(fdc, "\n  if (!status) add(hash, constructors_x);\n");
02643     fprintf(fdc, "\n  return status;\n");
02644     fprintf(fdc, "}\n\n");
02645 
02646     fprintf(fdc, "void %sDatabase::setConsApp(eyedb::Database *_db)\n{\n", package);
02647 
02648     /*
02649       fprintf(fdc, "  if (!_db->getUserData(\"eyedb:%s\") {\n", package);
02650       fprintf(fdc, "     _db->setUserData(\"eyedb:%s\", (void *)1);\n", package);
02651       fprintf(fdc, "     _db->add(hash, constructors_x);\n");
02652       fprintf(fdc, "  }\n");
02653     */
02654     fprintf(fdc, "  _db->add(hash, constructors_x);\n");
02655     fprintf(fdc, "}\n\n");
02656 
02657     if (superclass)
02658       {
02659         const char *sname = superclass->getName();
02660         fprintf(fdc, "%s *%sDatabase::as%s(eyedb::Object *o)\n{\n", sname,
02661                 package, superclass->getCanonicalName());
02662 #if 0
02663         fprintf(fdc, "  Bool is;\n");
02664         fprintf(fdc, "  if (o && !%s_Class->isSuperClassOf(o->getClass(), &is) && is)\n", sname);
02665         fprintf(fdc, "     return (%s *)o;\n", sname);
02666         fprintf(fdc, "  return (%s *)0;\n", sname);
02667 #else
02668         fprintf(fdc, "  if (!eyedb::ObjectPeer::isGRTObject(o))\n");
02669         fprintf(fdc, "     return (%s *)make_object(o, eyedb::False);\n\n",
02670                 sname);
02671         fprintf(fdc, "  if (hash->get(o->getClass()->getName()) < 0)\n");
02672         fprintf(fdc, "     return (%s *)0;\n\n", sname);
02673 
02674         fprintf(fdc, "  return (%s *)o;\n", sname);
02675 #endif
02676         fprintf(fdc, "}\n\n");
02677 
02678         fprintf(fdc, "const %s *%sDatabase::as%s(const eyedb::Object *o)\n{\n", sname,
02679                 package,  superclass->getCanonicalName());
02680 #if 0
02681         fprintf(fdc, "  eyedb::Bool is;\n");
02682         fprintf(fdc, "  if (o && !%s_Class->isSuperClassOf(o->getClass(), &is) && is)\n", sname);
02683         fprintf(fdc, "    return (const %s *)o;\n", sname);
02684         fprintf(fdc, "  return (const %s *)0;\n", sname);
02685 #else
02686         fprintf(fdc, "  if (!eyedb::ObjectPeer::isGRTObject((eyedb::Object *)o))\n");
02687         fprintf(fdc, "    return (const %s *)make_object((eyedb::Object *)o, eyedb::False);\n\n",
02688                 sname);
02689         fprintf(fdc, "  if (hash->get(o->getClass()->getName()) < 0)\n");
02690         fprintf(fdc, "    return (const %s *)0;\n\n", sname);
02691 
02692         fprintf(fdc, "  return (const %s *)o;\n", sname);
02693 #endif
02694         fprintf(fdc, "}\n\n");
02695       }
02696 
02697 
02698     fprintf(fdc, "static void append(char *&s, const char *m1, const char *m2)\n{\n");
02699     fprintf(fdc, "  if (!s) {s = (char *)malloc(strlen(m1)+strlen(m2)+2); *s = 0;}\n");
02700     fprintf(fdc, "  else s = (char *)realloc(s, strlen(s)+strlen(m1)+strlen(m2)+2);\n");
02701     fprintf(fdc, "  strcat(s, m1);\n");
02702     fprintf(fdc, "  strcat(s, m2);\n");
02703     fprintf(fdc, "  strcat(s, \"\\n\");\n");
02704     fprintf(fdc, "}\n\n");
02705 
02706 #ifndef UNIFIED_API
02707     if (odl_dynamic_attr) {
02708 #endif
02709       fprintf(fdc, "eyedb::Bool %sDatabase::getDynamicGetErrorPolicy() {\n", package);
02710 #ifdef UNIFIED_API    
02711       if (!odl_dynamic_attr)
02712         fprintf(fdc, "   throw *eyedb::Exception::make(eyedb::IDB_ERROR, \"getDynamicGetErrorPolicy() %s\");\n}\n\n", dyn_call_error);
02713       else
02714 #endif
02715         fprintf(fdc, "   return dynget_error_policy;\n}\n\n");
02716 
02717       fprintf(fdc, "eyedb::Bool %sDatabase::getDynamicSetErrorPolicy() {\n",
02718               package);
02719 
02720 #ifdef UNIFIED_API
02721       if (!odl_dynamic_attr)
02722         fprintf(fdc, "   throw *eyedb::Exception::make(eyedb::IDB_ERROR, \"getDynamicSetErrorPolicy() %s\");\n}\n\n", dyn_call_error);
02723       else
02724 #endif
02725         fprintf(fdc, "   return dynget_error_policy;\n}\n\n");
02726 
02727       fprintf(fdc, "void %sDatabase::setDynamicGetErrorPolicy(eyedb::Bool policy) {\n",
02728               package);
02729 #ifdef UNIFIED_API
02730       if (!odl_dynamic_attr)
02731         fprintf(fdc, "   throw *eyedb::Exception::make(eyedb::IDB_ERROR, \"setDynamicGetErrorPolicy() %s\");\n}\n\n", dyn_call_error);
02732       else
02733 #endif
02734         fprintf(fdc, "   dynget_error_policy = policy;\n}\n\n");
02735       fprintf(fdc, "void %sDatabase::setDynamicSetErrorPolicy(eyedb::Bool policy) {\n",
02736               package);
02737 #ifdef UNIFIED_API
02738       if (!odl_dynamic_attr)
02739         fprintf(fdc, "   throw *eyedb::Exception::make(eyedb::IDB_ERROR, \"setDynamicSetErrorPolicy() %s\");\n}\n\n", dyn_call_error);
02740       else
02741 #endif
02742         fprintf(fdc, "   dynset_error_policy = policy;\n}\n\n");
02743 #ifndef UNIFIED_API
02744     }
02745 #endif
02746 
02747     fprintf(fdc, "eyedb::Status %sDatabase::checkSchema(eyedb::Schema *m)\n{\n", package);
02748     //  fprintf(fdc, "  Schema *m = getSchema();\n");
02749     fprintf(fdc, "  eyedb::Class *cl;\n");
02750     fprintf(fdc, "  char *s = 0;\n\n");
02751 
02752     curs = _class->startScan();
02753 
02754     while (_class->getNextObject(curs, (void *&)cl))
02755       if (cl->getUserData(odlGENCODE) && !cl->asCollectionClass()) {
02756         if (cl->isRootClass())
02757           continue;
02758         fprintf(fdc, "  if (!(cl = m->getClass(\"%s\")))\n",
02759                 cl->getAliasName());
02760         fprintf(fdc, "    append(s, \"'%s' \", not_exit_msg);\n",
02761                 cl->getAliasName());
02762         fprintf(fdc, "  else if (!%s_Class->compare(cl))\n", cl->getCName());
02763         fprintf(fdc, "    append(s, \"'%s' \", differ_msg);\n",
02764                 cl->getName());
02765       }
02766 
02767     _class->endScan(curs);
02768 
02769     fprintf(fdc, "  if (s) {eyedb::Status status = eyedb::Exception::make(s); free(s); return status;}\n");
02770     fprintf(fdc, "  return eyedb::Success;\n}\n\n");
02771 
02772 
02773     fprintf(fdc, "eyedb::Bool %s_set_oid_check(eyedb::Bool _oid_check)\n", package);
02774     fprintf(fdc, "{\n");
02775     fprintf(fdc, "  eyedb::Bool old = oid_check;\n");
02776     fprintf(fdc, "  oid_check = _oid_check;\n");
02777     fprintf(fdc, "  return old;\n");
02778     fprintf(fdc, "}\n\n");
02779 
02780     fprintf(fdc, "eyedb::Bool %s_get_oid_check()\n", package);
02781     fprintf(fdc, "{\n");
02782     fprintf(fdc, "  return oid_check;\n");
02783     fprintf(fdc, "}\n");
02784 
02785     if (c_namespace)
02786       fprintf(fdc, "\n}\n", c_namespace);
02787 
02788     if (true_prefix) {
02789       fprintf(fdh, "};\n\n");
02790       delete [] true_prefix;
02791     }
02792 
02793     if (1) // because of a previous `goto'
02794       {
02795         LinkedListCursor c = LinkedListCursor(_class);
02796         fprintf(fdh, "\n");
02797         while (c.getNext((void *&)cl))
02798           if (cl->getUserData(odlGENCODE) && cl->asAgregatClass())
02799             {
02800               /*
02801               fprintf(fdh, "#define %s(X) ((%s *)(X))\n\n",
02802                       hints.style->getString(GenCodeHints::tCast,
02803                                              cl->getCanonicalName(), prefix),
02804                       cl->getName());
02805               */
02806 
02807               if (!hints.gen_down_casting || !superclass)
02808                 continue;
02809 
02810               fprintf(fdh, "inline %s *%s(eyedb::Object *o)\n{\n",
02811                       cl->getName(),
02812                       hints.style->getString(GenCodeHints::tSafeCast,
02813                                              cl->getCanonicalName(), prefix));
02814               fprintf(fdh, "  %s *x = %sDatabase::as%s(o);\n",
02815                       superclass->getName(),
02816                       package,
02817                       superclass->getCanonicalName());
02818               fprintf(fdh, "  if (!x) return (%s *)0;\n", cl->getName());
02819               fprintf(fdh, "  return x->as%s();\n", cl->getCanonicalName());
02820               fprintf(fdh, "}\n\n");
02821 
02822               fprintf(fdh, "inline const %s *%s(const eyedb::Object *o)\n{\n",
02823                       cl->getName(),
02824                       hints.style->getString(GenCodeHints::tSafeCast,
02825                                              cl->getCanonicalName(), prefix));
02826               fprintf(fdh, "  const %s *x = %sDatabase::as%s(o);\n",
02827                       superclass->getName(),
02828                       package,
02829                       superclass->getCanonicalName());
02830               fprintf(fdh, "  if (!x) return (const %s *)0;\n", cl->getName());
02831               fprintf(fdh, "  return x->as%s();\n", cl->getCanonicalName());
02832               fprintf(fdh, "}\n\n");
02833             }
02834       }
02835 
02836     fprintf(fdh, "%sextern eyedb::Object *%sMakeObject(eyedb::Object *, eyedb::Bool=eyedb::True);\n", ctxH.get(), package);
02837 
02838     fprintf(fdh, "%sextern eyedb::Bool %s_set_oid_check(eyedb::Bool);\n", ctxH.get(), package);
02839     fprintf(fdh, "%sextern eyedb::Bool %s_get_oid_check();\n", ctxH.get(), package);
02840 
02841     // added the 30/05/01
02842     if (_export) {
02843       fprintf(fdh, "\n");
02844       curs = _class->startScan();
02845 
02846       while (_class->getNextObject(curs, (void *&)cl))
02847         if (check_class(cl, False))
02848           {
02849             if (cl->asCollectionClass()) continue;
02850             const char *suffix;
02851             if (cl->asEnumClass())
02852               suffix = "eyedb::Enum";
02853             else if (cl->asAgregatClass())
02854               suffix = cl->asStructClass() ? "eyedb::Struct" : "eyedb::Union";
02855             else if (cl->asCollectionClass())
02856               suffix = cl->asCollectionClass()->getCSuffix();
02857             else
02858               suffix = "";
02859           
02860             fprintf(fdh, "extern " DEF_PREFIX "%sClass *%s_Class;\n", suffix, cl->getCName());
02861           }
02862     
02863       _class->endScan(curs);
02864     }
02865 
02866     // end of add
02867 
02868     fprintf(fdh, "\n");
02869     if (odl_smartptr) {
02870       curs = _class->startScan();
02871       while (_class->getNextObject(curs, (void *&)cl)) {
02872         if (check_class(cl, False)) {
02873           if (!cl->asEnumClass() && !cl->asCollectionClass()) {
02874             fprintf(fdh, "%sinline %sPtr::%sPtr(%s *o) : %sPtr(o) { }\n\n",
02875                     ctxH.get(), cl->getCName(), cl->getCName(), cl->getCName(),
02876                     cl->getParent()->getCName());
02877           
02878             fprintf(fdh, "%sinline %s *%sPtr::get%s() {return dynamic_cast<%s *>(o);}\n",
02879                     ctxH.get(), cl->getCName(), cl->getCName(), cl->getCName(), cl->getCName());
02880             fprintf(fdh, "%sinline const %s *%sPtr::get%s() const "
02881                     "{return dynamic_cast<%s *>(o);}\n\n",
02882                     ctxH.get(), cl->getCName(), cl->getCName(), cl->getCName(), cl->getCName());
02883     
02884             fprintf(fdh, "%sinline %s *%sPtr::operator->() {return dynamic_cast<%s *>(o);}\n",
02885                     ctxH.get(), cl->getCName(), cl->getCName(), cl->getCName());
02886             fprintf(fdh, "%sinline const %s *%sPtr::operator->() const {return dynamic_cast<%s *>(o);}\n\n",
02887                     ctxH.get(), cl->getCName(), cl->getCName(), cl->getCName());
02888           }
02889         }
02890       }
02891 
02892       _class->endScan(curs);
02893     }
02894 
02895     if (c_namespace)
02896       fprintf(fdh, "\n}\n", c_namespace);
02897 
02898     fprintf(fdh, "\n#endif\n");
02899 
02900   out:
02901 
02902     fclose(fdh);
02903     fclose(fdc);
02904     if (fdmk)
02905       fclose(fdmk);
02906     if (fdtempl)
02907       fclose(fdtempl);
02908     fclose(fdstubsfe);
02909     fclose(fdstubsbe);
02910     fclose(fdmthbe);
02911     fclose(fdmthfe);
02912 
02913     if (status)
02914       remove_files(hints.dirname, hints.fileprefix, hints.c_suffix,
02915                    hints.h_suffix, package);
02916 
02917     return status;
02918   }
02919 }

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