00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
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
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
00048
00049 #define UNIFIED_API
00050
00051
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
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
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
00462
00463 }
00464
00465
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
00477
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
00502 mc->db = db;
00503
00504
00505 return Success;
00506 }
00507
00508 Status Schema::addClass(Class *mc)
00509 {
00510 assert(!mc->isRemoved());
00511
00512
00513
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)))
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
00540
00541 mc->attrsComplete();
00542
00543
00544
00545
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
00559
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
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
00669
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
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
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
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();
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
01263 LinkedListCursor xc(_class);
01264 Class *xcls;
01265 while (xc.getNext((void *&)xcls)) {
01266
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);
01469
01470 if (use_namespace && c_namespace)
01471 fprintf(fd, "using namespace %s;\n\n", c_namespace);
01472 }
01473
01474
01475
01476
01477
01478
01479
01480
01481
01482
01483
01484
01485
01486
01487
01488
01489
01490
01491
01492
01493
01494
01495
01496
01497
01498
01499
01500
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
01526
01527
01528
01529
01530
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
01569
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
01677
01678
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();
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
01868
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
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
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
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
02108
02109
02110
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
02127
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
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
02160
02161
02162
02163
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
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
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
02203
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
02219
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())
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
02325
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*>"))
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
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
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
02601
02602
02603
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
02650
02651
02652
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
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)
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
02802
02803
02804
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
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
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 }