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 #include "odl.h"
00026 #include "misc.h"
00027 #include "eyedb/internals/ClassPeer.h"
00028 #include "eyedb/internals/ObjectPeer.h"
00029 #include "oql_p.h"
00030 #include "CollectionBE.h"
00031 #include <sstream>
00032 #include <pthread.h>
00033 #include "eyedblib/butils.h"
00034 #include "oqlctb.h"
00035
00036 using std::ostringstream;
00037
00038 #define NO_DIRECT_SET
00039
00040 #define NEW_REORDER
00041 #define NEW_DIFF_RELSHIP
00042
00043 namespace eyedb {
00044
00045 LinkedList *odl_decl_list;
00046 ProgLang odl_lang = (ProgLang)0;
00047 int odl_error;
00048 int odl_diff;
00049 const char *odl_rootclass;
00050 LinkedList qseq_list;
00051 odlAgregatClass *odlAgregatClass::superclass;
00052 unsigned int odlAgregatClass::class_count;
00053 static const char *odl_prefix;
00054 static std::string odl_db_prefix;
00055 static Bool odl_gencode = False;
00056 Bool odl_system_class = False;
00057 Bool odl_rmv_undef_attrcomp = False;
00058 Bool odl_update_index = False;
00059 Bool odl_dynamic_attr = False;
00060 Bool odl_class_enums = False;
00061 Bool odl_sch_rm = False;
00062 Bool odl_smartptr = False;
00063
00064 LinkedList odl_cls_rm;
00065 static Bool odl_not_check_missing = IDBBOOL(getenv("EYEDBNOCHECKMISSING"));
00066 FILE *odl_fd = stdout;
00067 static FILE *odl_fdnull = fopen("/dev/null", "rw");
00068 LinkedList odlAgregatClass::declared_list;
00069
00070 static const char odlUPDLIST[] = "eyedb:odl:update:list";
00071 static const char odlSELF[] = "eyedb:odl:self";
00072 char odlMTHLIST[] = "eyedb:odl:method";
00073 char odlGENCOMP[] = "eyedb:odl:gencomp";
00074 char odlGENCODE[] = "eyedb:odl:gencode";
00075
00076 #define odlUPDLIST(M) ((LinkedList *)(M)->getUserData(odlUPDLIST))
00077 #define odlMTHLIST(C) ((LinkedList *)(C)->getUserData(odlMTHLIST))
00078
00079 FILE *
00080 run_cpp(FILE *fd, const char *cpp_cmd, const char *cpp_flags,
00081 const char *file);
00082
00083 static
00084 Database *odl_get_dummy_db(Schema *m)
00085 {
00086 static Database *dumdb;
00087 if (!dumdb) {
00088 dumdb = new Database("dummy");
00089 dumdb->setSchema(m);
00090 }
00091
00092 return dumdb;
00093 }
00094
00095 static int
00096 magorder_error(const Class *cls, const char *attrname, const char *type)
00097 {
00098 if (attrname)
00099 odl_add_error
00100 (std::string("attribute: ") + cls->getName() + "::" +
00101 attrname + " cannot have several " + type + " specifications\n");
00102 else
00103 odl_add_error
00104 (std::string("class: ") + cls->getName() +
00105 " cannot have several " + type + " specifications\n");
00106
00107 return 0;
00108 }
00109
00110 static std::string odl_str_error;
00111
00112 void
00113 odl_add_error(Status s)
00114 {
00115 ostringstream ostr;
00116 ostr << s;
00117 odl_str_error += ostr.str();
00118 if (odl_str_error[odl_str_error.size()-1] != '\n')
00119 odl_str_error += "\n";
00120 odl_error++;
00121 }
00122
00123 void
00124 odl_add_error(const char *fmt, ...)
00125 {
00126 va_list ap, aq;
00127 va_start(ap, fmt);
00128 va_copy(aq, ap);
00129
00130 char *s = eyedblib::getFBuffer(fmt, ap);
00131 vsprintf(s, fmt, aq);
00132 va_end(ap);
00133 odl_str_error += s;
00134 odl_error++;
00135 }
00136
00137 void
00138 odl_add_error(const std::string &s)
00139 {
00140 odl_str_error += s;
00141 odl_error++;
00142 }
00143
00144 static Status
00145 odl_status_error(int r = 0)
00146 {
00147 if (odl_error)
00148 return Exception::make(IDB_ERROR, odl_str_error.c_str());
00149
00150 if (odl_str_error != std::string(""))
00151 fprintf(stderr, "%s\n", odl_str_error.c_str());
00152 else if (r)
00153 return Exception::make(IDB_ERROR, "");
00154
00155 return Success;
00156 }
00157
00158 static Class *
00159 getClass(Schema *m, const char *name, const char *prefix)
00160 {
00161 Class *cls;
00162
00163 cls = m->getClass(name);
00164
00165 if (cls) return cls;
00166
00167 return m->getClass(makeName(name, prefix));
00168 }
00169
00170 static void
00171 odl_copy_attr_comp_sets(Class *ocls, Class *cls)
00172 {
00173 unsigned int attr_cnt;
00174 Attribute **attrs = (Attribute **)cls->getAttributes(attr_cnt);
00175
00176 for (int i = 0; i < attr_cnt; i++)
00177 {
00178 const Attribute *oattr = ocls->getAttribute(attrs[i]->getName());
00179 if (oattr) {
00180
00181
00182
00183
00184
00185
00186
00187 attrs[i]->setAttrCompSetOid(oattr->getAttrCompSetOid());
00188 }
00189 }
00190 }
00191
00192 static bool is_in(const std::vector<Class *> &rm_v, Class *cls) {
00193 std::vector<Class *>::const_iterator begin = rm_v.begin();
00194 std::vector<Class *>::const_iterator end = rm_v.end();
00195 while (begin != end) {
00196 if (cls == *begin)
00197 return true;
00198 ++begin;
00199 }
00200 return false;
00201 }
00202
00203 static void
00204 odl_check_removed(Schema *m, LinkedList *&list)
00205 {
00206 if (odl_sch_rm) {
00207 if (!list)
00208 list = new LinkedList();
00209 const LinkedList *cls_list = m->getClassList();
00210 odlUpdateHint *rmHints = new odlUpdateHint(odlUpdateHint::Remove);
00211 Class *cls;
00212
00213 #if 1
00214 std::vector<Class *> rm_v;
00215
00216 unsigned int cnt = 0;
00217
00218 do {
00219 LinkedListCursor c(cls_list);
00220 cnt = 0;
00221 while (c.getNext((void *&)cls)) {
00222 if (cls->isSystem() || is_in(rm_v, cls))
00223 continue;
00224
00225 Class **subclasses;
00226 unsigned int subclass_cnt;
00227 cls->getSubClasses(subclasses, subclass_cnt);
00228 bool subclass_notin = false;
00229 for (int n = 0; n < subclass_cnt; n++) {
00230 if (subclasses[n] != cls && !is_in(rm_v, subclasses[n])) {
00231 subclass_notin = true;
00232 break;
00233 }
00234 }
00235
00236 if (!subclass_notin) {
00237 rm_v.push_back(cls);
00238 cnt++;
00239 }
00240 }
00241
00242 } while(cnt);
00243
00244 std::vector<Class *>::iterator begin = rm_v.begin();
00245 std::vector<Class *>::iterator end = rm_v.end();
00246 while (begin != end) {
00247 cls = *begin;
00248 odlClassSpec *clsspec = new odlClassSpec(cls->getName(), 0,
00249 cls->getName(), 0);
00250 new odlAgregatClass(rmHints, odl_Struct, clsspec,
00251 new odlDeclRootList());
00252 ++begin;
00253 }
00254 #else
00255 LinkedListCursor c(cls_list);
00256 while (c.getNext((void *&)cls)) {
00257 if (cls->isSystem())
00258 continue;
00259 odlClassSpec *clsspec = new odlClassSpec(cls->getName(), 0,
00260 cls->getName(), 0);
00261 new odlAgregatClass(rmHints, odl_Struct, clsspec,
00262 new odlDeclRootList());
00263 }
00264 #endif
00265
00266 return;
00267 }
00268
00269 if (odl_cls_rm.getCount() == 0)
00270 return;
00271
00272 if (!list)
00273 list = new LinkedList();
00274
00275 char *name;
00276 LinkedListCursor c(odl_cls_rm);
00277 odlUpdateHint *rmHints = new odlUpdateHint(odlUpdateHint::Remove);
00278 while (c.getNext((void * &)name)) {
00279
00280 odlClassSpec *clsspec = new odlClassSpec(name, 0, name, 0);
00281 new odlAgregatClass(rmHints, odl_Struct,
00282 clsspec,
00283 new odlDeclRootList());
00284 }
00285 }
00286
00287 static Bool
00288 odl_check_renamed_from(Schema *m, LinkedList *list, Class *cls)
00289 {
00290 LinkedListCursor clx(list);
00291 odlDeclaration *decl;
00292
00293 while (clx.getNext((void *&)decl))
00294 if (decl->asAgregatClass()) {
00295 odlUpdateHint *upd_hints = decl->asAgregatClass()->upd_hints;
00296 if (upd_hints && upd_hints->type == odlUpdateHint::RenameFrom &&
00297 !strcmp(upd_hints->detail, cls->getName()))
00298 return True;
00299 }
00300
00301 return False;
00302 }
00303
00304 static void
00305 odl_check_missing(Schema *m, LinkedList *list)
00306 {
00307 LinkedListCursor cm(m->getClassList());
00308 Class *cls;
00309
00310 while (cm.getNext((void *&)cls))
00311 {
00312 if (cls->isPartiallyLoaded())
00313 {
00314 Status s = m->manageClassDeferred(cls);
00315 if (s)
00316 {
00317 odl_add_error(s);
00318 break;
00319 }
00320 }
00321
00322 if (cls->isSystem() || cls->asCollectionClass())
00323 continue;
00324
00325 LinkedListCursor cl(list);
00326 odlDeclaration *decl;
00327 Bool found = False;
00328 while (cl.getNext((void *&)decl))
00329 if (!strcmp(decl->getName(), cls->getName()) ||
00330 (decl->getAliasName() &&
00331 !strcmp(decl->getAliasName(), cls->getName())))
00332 {
00333 found = True;
00334 break;
00335 }
00336
00337 if (!found)
00338 {
00339 #define MANAGE_MISSING_CLASSES
00340
00341
00342
00343 #ifdef MANAGE_MISSING_CLASSES
00344
00345 if (!odl_gencode) {
00346 if (!odl_check_renamed_from(m, list, cls)) {
00347 #if 0
00348 list->insertObject
00349 (new odlAgregatClass(0, odl_Declare,
00350 new odlClassSpec(cls->getName(), 0, 0, 0),
00351 new odlDeclRootList()));
00352 #else
00353 new odlAgregatClass(0, odl_Declare,
00354 new odlClassSpec(cls->getName(), 0, 0, 0),
00355 new odlDeclRootList());
00356 #endif
00357
00358 }
00359 }
00360 else if (!odl_not_check_missing)
00361 #endif
00362 odl_add_error("class %s is missing in ODL\n", cls->getName());
00363 }
00364 }
00365 }
00366
00367 static Bool
00368 odl_has_attribute(const Class *origcls, const Class *cls,
00369 const char *attrname)
00370 {
00371 #if 1
00372 return True;
00373 #endif
00374 if (!cls)
00375 return False;
00376
00377 if (cls->getAttribute(attrname))
00378 {
00379 odl_add_error("attribute '%s' exists both in class '%s' and its "
00380 "superclass '%s'\n",
00381 attrname, origcls->getName(), cls->getName());
00382 return True;
00383 }
00384
00385 return odl_has_attribute(origcls, cls->getParent(), attrname);
00386 }
00387
00388
00389 static void
00390 odl_check_attributes(const Class *cls)
00391 {
00392 unsigned int attr_cnt;
00393 Attribute **attrs = (Attribute **)cls->getAttributes(attr_cnt);
00394
00395 for (int i = 0; i < attr_cnt; i++)
00396 {
00397 const Attribute *attr = attrs[i];
00398 if (!attr->isNative() && attr->getClassOwner()->compare(cls))
00399 odl_has_attribute(cls, cls->getParent(), attr->getName());
00400 }
00401 }
00402
00403 int
00404 odl_realize(Database *db, Schema *m, LinkedList *list,
00405 const char *prefix, const char *db_prefix,
00406 const char *package, Bool diff)
00407 {
00408 if (!prefix) prefix = "";
00409 if (!db_prefix) db_prefix = "";
00410 if (!package) package = "";
00411
00412 odl_prefix = prefix;
00413 odl_db_prefix = db_prefix;
00414
00415 odl_check_removed(m, list);
00416
00417 if (list && list->getCount()) {
00418 odlDeclaration *decl;
00419
00420 m->setUserData(odlUPDLIST, new LinkedList());
00421
00422 odl_check_missing(m, list);
00423 if (odl_error)
00424 return 1;
00425
00426 LinkedListCursor curs(list);
00427
00428 while (curs.getNext((void* &)decl))
00429 decl->record(db, m, prefix, db_prefix);
00430
00431 if (odl_error)
00432 return 1;
00433
00434 curs.restart();
00435 while (curs.getNext((void* &)decl))
00436 decl->realize(db, m, prefix, package, diff);
00437
00438 if (odl_error)
00439 return 1;
00440
00441 #ifdef NEW_REORDER
00442 curs.restart();
00443 while (curs.getNext((void* &)decl))
00444 if (decl->asAgregatClass())
00445 decl->asAgregatClass()->preManage(m);
00446 #endif
00447
00448 if (odl_error)
00449 return 1;
00450
00451 curs.restart();
00452 while (curs.getNext((void* &)decl))
00453 if (decl->asAgregatClass())
00454 decl->asAgregatClass()->postRealize(db, m, prefix);
00455
00456 if (odl_error)
00457 return 1;
00458
00459 curs.restart();
00460 while (curs.getNext((void* &)decl))
00461 if (decl->asAgregatClass())
00462 decl->asAgregatClass()->manageDifferences(db, m, diff);
00463 }
00464
00465 const LinkedList *_class = m->getClassList();
00466 LinkedListCursor curs(_class);
00467
00468 Class *cl;
00469
00470 if (!odl_error && !odl_diff)
00471 while (curs.getNext((void *&)cl)) {
00472 Status status = cl->checkInverse(m);
00473 if (status)
00474 odl_add_error(status);
00475
00476 odl_check_attributes(cl);
00477
00478 if (cl->getUserData())
00479 odl_copy_attr_comp_sets((Class *)cl->getUserData(), cl);
00480 }
00481
00482 if (odl_error) {
00483 odl_add_error("%d error%s found, compilation aborted\n",
00484 odl_error, (odl_error > 1 ? "s" : ""));
00485 return 1;
00486 }
00487
00488 return 0;
00489 }
00490
00491 static char *
00492 get_superclass_name(const char *prefix = "")
00493 {
00494 static char *spname;
00495
00496 if (!odlAgregatClass::superclass || spname)
00497 return spname;
00498
00499 const char *name = odlAgregatClass::superclass->getName();
00500 if (prefix && *prefix)
00501 {
00502 spname = (char *)malloc(strlen(prefix)+strlen(name)+1);
00503 strcpy(spname, prefix);
00504 strcat(spname, name);
00505 }
00506 else
00507 spname = strdup(name);
00508
00509 return spname;
00510 }
00511
00512 int
00513 odl_generate_code(Database *db, Schema *m, ProgLang lang,
00514 LinkedList *list,
00515 const char *package, const char *schname,
00516 const char *c_namespace,
00517 const char *prefix, const char *db_prefix, Bool _export,
00518 const GenCodeHints &gc_hints)
00519 {
00520 odl_gencode = True;
00521 odl_class_enums = gc_hints.class_enums;
00522
00523 if (odl_realize(db, m, list, prefix, db_prefix, package))
00524 return 1;
00525
00526 Class *superclass = NULL;
00527 if (odlAgregatClass::superclass) {
00528 superclass = m->getClass(get_superclass_name(odl_prefix));
00529 if (odlAgregatClass::superclass->getAgregSpec() == odl_RootClass)
00530 superclass->setIsRootClass();
00531 }
00532
00533 Status status = m->generateCode
00534 (lang, package, schname,
00535 c_namespace, prefix, db_prefix, gc_hints,
00536 _export,
00537 superclass,
00538 &qseq_list);
00539
00540 if (status) {
00541 odl_add_error(status);
00542 return 1;
00543 }
00544
00545 return 0;
00546 }
00547
00548 #define SWAP_CLSNAMES
00549
00550 odlClassSpec::odlClassSpec(const char *_aliasname, const char *_parentname,
00551 const char *_classname, odlCollImplSpec *_coll_impl_spec)
00552 {
00553 if (getenv("SYSTEM_UPDATE"))
00554 {
00555 classname = (_aliasname ? strdup(_aliasname) : strdup(_classname));
00556 aliasname = 0;
00557 }
00558 else
00559 {
00560 #ifdef SWAP_CLSNAMES
00561 classname = (_classname ? strdup(_classname) : strdup(_aliasname));
00562 aliasname = strdup(_aliasname);
00563 #else
00564 classname = strdup(_classname);
00565 aliasname = (_aliasname ? strdup(_aliasname) : 0);
00566 #endif
00567 }
00568
00569 parentname = (_parentname ? strdup(_parentname) : 0);
00570 coll_impl_spec = _coll_impl_spec;
00571 }
00572
00573 static void
00574 rename_classes(Schema *m)
00575 {
00576 Class *cl;
00577 LinkedListCursor c(m->getClassList());
00578
00579 while (c.getNext((void *&)cl))
00580 if (cl->asAgregatClass())
00581 cl->asAgregatClass()->completeInverse(m);
00582
00583 LinkedListCursor cx(m->getClassList());
00584
00585 while (cx.getNext((void *&)cl)) {
00586 if (strcmp(cl->getAliasName(), cl->getName()))
00587 cl->setName(cl->getAliasName());
00588 }
00589 }
00590
00591 void
00592 odl_skip_volatiles(Database *db, Schema *m)
00593 {
00594 if (!odlAgregatClass::superclass ||
00595 odlAgregatClass::superclass->getAgregSpec() != odl_RootClass)
00596 return;
00597
00598 db->transactionBegin();
00599 LinkedListCursor c(m->getClassList());
00600 Class *cl, *toSuppress = 0;
00601
00602 char name[64];
00603 sprintf(name, "%s%s", odl_prefix, get_superclass_name());
00604 while (c.getNext((void *&)cl))
00605 {
00606 if (!strcmp(cl->getName(), name))
00607 toSuppress = cl;
00608 else if (cl->getParent() && !strcmp(cl->getParent()->getName(), name))
00609 ClassPeer::setParent(cl, cl->getParent()->getParent());
00610 }
00611
00612 if (toSuppress)
00613 m->suppressClass(toSuppress);
00614
00615 rename_classes(m);
00616
00617
00618 db->transactionCommit();
00619 }
00620
00621 int odlDeclaration::check(Schema *m, const char *prefix)
00622 {
00623
00624
00625
00626
00627
00628
00629
00630
00631
00632
00633 return 0;
00634 }
00635
00636 static void
00637 odl_rename_class(Schema *m, const Class *cls, const char *name)
00638 {
00639 odlUPDLIST(m)->insertObjectLast(new odlRenameClass(cls, name));
00640 }
00641
00642 static void
00643 odl_migrate_attributes(Schema *m, const Class *cls);
00644
00645 static void
00646 odl_remove_class(Database *db, Schema *m, const Class *cls);
00647
00648 int
00649 odlAgregatClass::record(Database *db, Schema *m,
00650 const char *prefix, const char *db_prefix)
00651 {
00652 if (parentname) {
00653 parent = eyedb::getClass(m, parentname, prefix);
00654 if (!parent)
00655 odl_add_error("cannot find parent '%s' for agregat_class '%s'\n",
00656 parentname, name);
00657 }
00658 else
00659 parent = 0;
00660
00661 if (agrspec == odl_Struct || agrspec == odl_SuperClass ||
00662 agrspec == odl_RootClass) {
00663 cls = new StructClass(makeName(name, prefix), parent);
00664 cls->setUserData(odlGENCODE, AnyUserData);
00665 }
00666 else if (agrspec == odl_Declare) {
00667 cls = m->getClass(name);
00668 if (!cls)
00669 odl_add_error("cannot find declared class '%s'\n", name);
00670
00671 if (!odl_error)
00672 cls = new Class(cls->getName(), cls->getParent());
00673 }
00674 else if (agrspec == odl_NativeClass) {
00675 cls = m->getClass(name);
00676 if (!cls)
00677 odl_add_error("cannot find native class '%s'\n", name);
00678 else if (!cls->isSystem())
00679 odl_add_error("class '%s' is not native\n",
00680 name);
00681 else if (aliasname && strcmp(aliasname, name))
00682 odl_add_error("cannot set an alias name on the native"
00683 " class '%s'\n", name);
00684 else {
00685
00686
00687
00688
00689
00690
00691
00692
00693
00694
00695
00696 }
00697
00698 #if 0
00699 if (!odl_error) {
00700 printf("NATIVE CLASS %s %s -> %p [system=%d] ", cls->getName(),
00701 cls->isSystem() ? "system" : "user", cls, system);
00702 }
00703 #endif
00704 if (!odl_error) {
00705 cls = new Class(cls->getName(), cls->getParent());
00706 cls->setUserData(odlGENCOMP, AnyUserData);
00707 ClassPeer::setMType(cls, Class::System);
00708 if (db)
00709 cls->setDatabase(db);
00710 }
00711 }
00712 else {
00713 cls = new UnionClass(makeName(name, prefix), parent);
00714 cls->setUserData(odlGENCODE, AnyUserData);
00715 }
00716
00717 if (!odl_lang && upd_hints && upd_hints->type == odlUpdateHint::RenameFrom)
00718 {
00719 const char *xname = upd_hints->detail;
00720 ocls = eyedb::getClass(m, xname, prefix);
00721 if (!ocls)
00722 odl_add_error("class %s: does not exist in database\n", xname);
00723 else
00724 {
00725 odl_rename_class(m, cls, xname);
00726 ocls->setName(name);
00727 }
00728 }
00729 else
00730 ocls = eyedb::getClass(m, (aliasname ? aliasname : name), prefix);
00731
00732 if (!odl_lang && upd_hints && upd_hints->type == odlUpdateHint::Remove &&
00733 !ocls)
00734 odl_add_error("cannot remove class '%s'\n", name);
00735 else if (agrspec != odl_NativeClass && agrspec != odl_Declare)
00736 {
00737 if (aliasname)
00738 cls->setAliasName(aliasname);
00739 else if (db_prefix)
00740 cls->setAliasName(makeName(name, db_prefix));
00741
00742 assert(ocls != cls);
00743 if (ocls && ocls != cls)
00744 {
00745 m->suppressClass(ocls);
00746 cls->setUserData(ocls);
00747 cls->setExtentImplementation(ocls->getExtentImplementation(),
00748 True);
00749 ObjectPeer::setOid(cls, ocls->getOid());
00750 }
00751
00752 if (upd_hints && upd_hints->type == odlUpdateHint::Remove)
00753 {
00754 if (ocls->isSystem()) {
00755 odl_add_error("cannot remove the system class '%s'\n",
00756 ocls->getName());
00757 return 1;
00758 } else {
00759 odl_remove_class(db, m, cls);
00760 cls = 0;
00761 }
00762 }
00763 else
00764 m->addClass(cls);
00765 }
00766 else if (odl_gencode && ocls)
00767 {
00768 m->suppressClass(ocls);
00769 if (upd_hints && upd_hints->type == odlUpdateHint::Remove)
00770 {
00771 if (ocls->isSystem()) {
00772 odl_add_error("cannot remove the system class '%s'\n",
00773 ocls->getName());
00774 return 1;
00775 } else {
00776 odl_remove_class(db, m, cls);
00777 cls = 0;
00778 }
00779 }
00780 else
00781 m->addClass(cls);
00782
00783 if (!odl_error && agrspec == odl_NativeClass) {
00784
00785
00786
00787
00788 unsigned int attr_cnt;
00789 const Attribute **attrs = ocls->getAttributes(attr_cnt);
00790 Status status = cls->setAttributes((Attribute **)attrs, attr_cnt);
00791 if (status)
00792 odl_add_error(status);
00793 }
00794 }
00795
00796 if (odl_system_class && !odl_error)
00797 ClassPeer::setMType(cls, Class::System);
00798
00799 if (cls)
00800 cls->setUserData(odlSELF, this);
00801
00802 if (cls && coll_impl_spec) {
00803
00804 odlCollImplSpecItem::Type type;
00805 char *hints;
00806 if (!coll_impl_spec->make_class_prologue(cls->getName(), type, hints))
00807 return 1;
00808
00809 if (type != odlCollImplSpecItem::HashIndex &&
00810 type != odlCollImplSpecItem::BTreeIndex) {
00811 odl_add_error("class %s: extent implementation '%s' must be an hashindex or a btreeindex", cls->getName());
00812 return 1;
00813
00814 }
00815 IndexImpl *idximpl;
00816 Status s = IndexImpl::make
00817 ((db ? db : odl_get_dummy_db(m)),
00818 (type == odlCollImplSpecItem::HashIndex ? IndexImpl::Hash :
00819 IndexImpl::BTree), hints, idximpl);
00820 if (!s) {
00821 if (cls->getOid().isValid()) {
00822 IndexImpl *oidximpl = cls->getExtentImplementation();
00823 if (!oidximpl->compare(idximpl)) {
00824 odl_add_error("class %s: extent implementation '%s' cannot be "
00825 "dynamically changed to '%s' using eyedbodl\n",
00826 cls->getName(),
00827 oidximpl->getHintsString().c_str(),
00828 idximpl->getHintsString().c_str());
00829 return 1;
00830 }
00831 }
00832 else
00833 s = cls->setExtentImplementation(idximpl);
00834 }
00835
00836 if (s) {
00837 odl_add_error(s);
00838 return 1;
00839 }
00840 }
00841
00842 return 0;
00843 }
00844
00845 static void
00846 array_make(odlDeclItem *item, int* &dims, int &ndims)
00847 {
00848 if (item->array_list)
00849 {
00850 int count = item->array_list->count;
00851 odlArrayItemLink *l = item->array_list->first;
00852 dims = new int[count];
00853
00854 for (ndims = 0; ndims < count; ndims++, l = l->next)
00855 {
00856 int v = l->x;
00857 if (v>0)
00858 dims[ndims] = v;
00859 else
00860 dims[ndims] = idbVarDim(-v);
00861 }
00862 }
00863 else
00864 {
00865 dims = 0;
00866 ndims = 0;
00867 }
00868 }
00869
00870 static void
00871 sign_error(const char *method_name, const Class *cls)
00872 {
00873 odl_add_error("invalid hash method signature '%s' in "
00874 "class '%s' in index declaration: must be "
00875 "`classmethod int %s(in rawdata, in int)'.\n",
00876 method_name, cls->getName(), method_name);
00877 }
00878
00879 #define FIND_IDX_OPTIM
00880
00881 Status
00882 odlIndex::findIndex(Schema *m, Index *&idx_obj)
00883 {
00884 if (!m->getDatabase())
00885 return Success;
00886
00887 #ifdef FIND_IDX_OPTIM
00888 Status s;
00889 static ObjectArray *index_arr;
00890 static int index_arr_cnt;
00891 if (!index_arr)
00892 {
00893 index_arr = new ObjectArray();
00894 OQL q(m->getDatabase(), "select index");
00895 s = q.execute(*index_arr);
00896 if (s) return s;
00897 index_arr_cnt = index_arr->getCount();
00898 }
00899
00900
00901 const char *idxname = idx_obj->getName().c_str();
00902 for (int i = 0; i < index_arr_cnt; i++)
00903 if (!strcmp(idxname, ((Index *)(*index_arr)[i])->getName().c_str()))
00904 {
00905 idx_obj->release();
00906 idx_obj = (Index *)(*index_arr)[i];
00907 return Success;
00908 }
00909
00910 return Success;
00911 #else
00912 OQL q(m->getDatabase(), "select index.name = \"%s\"", idx_obj->getName());
00913
00914 Object *o;
00915 Bool found;
00916 Status s;
00917
00918 ObjectArray obj_arr;
00919 s = q.execute(obj_arr);
00920 if (s) return s;
00921
00922 if (obj_arr.getCount())
00923 {
00924 idx_obj->release();
00925 idx_obj = (Index *)obj_arr[0];
00926 }
00927
00928 return Success;
00929 #endif
00930 }
00931
00932 static Bool
00933 odlIsType(odlDeclItem *item, const char *type)
00934 {
00935 if (strcmp(item->typname, type) || item->isref ||
00936 !item->array_list || item->array_list->count != 1)
00937 return False;
00938
00939 return True;
00940 }
00941
00942 static Bool
00943 odlIsString(odlDeclItem *item)
00944 {
00945 return odlIsType(item, char_class_name);
00946 }
00947
00948 static Bool
00949 odlIsRawData(odlDeclItem *item)
00950 {
00951 return odlIsType(item, "byte");
00952 }
00953
00954 static Signature *
00955 makeSign(Schema *m)
00956 {
00957 Signature *sign = new Signature();
00958 ArgType *type;
00959
00960 #ifdef NO_DIRECT_SET
00961 type = sign->getRettype();
00962 *type = *ArgType::make(m, int32_class_name);
00963 #else
00964 type = ArgType::make(m, int32_class_name);
00965 #endif
00966
00967 type->setType((ArgType_Type)(type->getType() | OUT_ARG_TYPE), False);
00968
00969 #ifndef NO_DIRECT_SET
00970 sign->setRettype(type);
00971 #endif
00972 sign->setNargs(2);
00973
00974 #ifdef NO_DIRECT_SET
00975 sign->setTypesCount(2);
00976 type = sign->getTypes(0);
00977 *type = *ArgType::make(m, "rawdata");
00978 #else
00979 type = ArgType::make(m, "rawdata");
00980 #endif
00981
00982 type->setType((ArgType_Type)(type->getType() | IN_ARG_TYPE), False);
00983
00984 #ifndef NO_DIRECT_SET
00985 sign->setTypes(0, type);
00986 #endif
00987
00988 #ifdef NO_DIRECT_SET
00989 sign->setTypesCount(2);
00990 type = sign->getTypes(1);
00991 *type = *ArgType::make(m, int32_class_name);
00992 #else
00993 type = ArgType::make(m, int32_class_name);
00994 #endif
00995 type->setType((ArgType_Type)(type->getType() | IN_ARG_TYPE), False);
00996
00997 #ifndef NO_DIRECT_SET
00998 sign->setTypes(1, type);
00999 #endif
01000
01001 return sign;
01002 }
01003
01004 static Signature *
01005 getHashSignature(Schema *m)
01006 {
01007 static Signature *sign;
01008
01009 if (!sign)
01010 sign = makeSign(m);
01011
01012 return sign;
01013 }
01014
01015 odlBool
01016 odlDeclItem::hasInverseAttr() const
01017 {
01018 return inverse ? odlTrue : odlFalse;
01019 #if 0
01020 if (!attr_list)
01021 return odlFalse;
01022
01023 odlAttrItemLink *l = attr_list->first;
01024
01025 while (l)
01026 {
01027 odlAttrItem *attr = l->x;
01028 if (attr->asInverse())
01029 return odlTrue;
01030 l = l ->next;
01031 }
01032
01033 return odlFalse;
01034 #endif
01035 }
01036
01037 #if 0
01038 void
01039 odlDeclItem::attr_list_make(Schema *m, Class *cls,
01040 int& index_mode, Index *&idx_item,
01041 Index *&idx_comp,
01042 char **invcname, char **invfname,
01043 ClassComponent *comp[], int &comp_cnt)
01044 {
01045 index_mode = 0;
01046 idx_item = idx_comp = 0;
01047 *invcname = *invfname = 0;
01048
01049 int ocomp_cnt = comp_cnt;
01050
01051 if (attr_list)
01052 {
01053 odlAttrItemLink *l = attr_list->first;
01054
01055 while (l)
01056 {
01057 odlAttrItem *attr = l->x;
01058 if (attr->asInverse())
01059 {
01060 odlInverse *inv = attr->asInverse();
01061 *invcname = inv->classname;
01062 *invfname = inv->attrname;
01063 }
01064 if (attr->asCardinality())
01065 {
01066 if (!coll_spec)
01067 {
01068 odl_add_error("cannot set cardinality_constraint on a not collection item '%s'\n", attrname);
01069 }
01070 else
01071 {
01072 odlCardinality *card = attr->asCardinality();
01073 comp[comp_cnt++] =
01074 new CardinalityConstraint(0, cls, attrname,
01075 card->bottom, (int)card->bottom_excl,
01076 card->top, (int)card->top_excl);
01077 }
01078 }
01079
01080
01081
01082
01083
01084 l = l->next;
01085 }
01086 }
01087 }
01088 #endif
01089
01090 static int key_w(const char *s, const char *key)
01091 {
01092 if (!s)
01093 return 0;
01094
01095 if (!strcmp(s, key))
01096 {
01097 odl_add_error("use of invalid C++ keyword '%s' for attribute name or type name\n", s);
01098 return 1;
01099 }
01100 return 0;
01101 }
01102
01103 #define KEY_W(K) if (key_w(typname, K) || key_w(attrname, K)) return 1
01104
01105 static int
01106 check_name(Schema *m, const char *classname,
01107 const char *typname, const char *attrname,
01108 const char *prefix)
01109 {
01110 KEY_W("delete");
01111 KEY_W("operator");
01112
01113 if (getClass(m, attrname, prefix))
01114 {
01115
01116
01117 odl_add_error("cannot use a type name for an attribute name: '%s %s' in class '%s'\n", (typname ? typname : "identifier"), attrname, classname);
01118 return 1;
01119 }
01120
01121 const LinkedList *_class = m->getClassList();
01122 LinkedListCursor *c = _class->startScan();
01123
01124 Class *cl;
01125
01126 char tmp[128];
01127 sprintf(tmp, "%s%s", prefix, classname);
01128 while (_class->getNextObject(c, (void *&)cl))
01129 if (cl->asEnumClass())
01130 {
01131 if (!strcmp(cl->getName(), tmp))
01132 continue;
01133
01134 int count;
01135 const EnumItem **items = cl->asEnumClass()->getEnumItems(count);
01136 for (int i = 0; i < count; i++)
01137 if (!strcmp(attrname, items[i]->getName()))
01138 {
01139 if (!typname)
01140 odl_add_error("enum item name '%s' found in '%s' and '%s'\n",
01141 attrname, cl->getName(), tmp);
01142 else
01143 odl_add_error("cannot use a enum item name for "
01144 "an attribute name: '%s'\n", attrname);
01145 _class->endScan(c);
01146 return 1;
01147 }
01148 }
01149
01150 _class->endScan(c);
01151
01152 return 0;
01153 }
01154
01155 static void
01156 add_quoted_seq(Class *cls, const char *quoted_seq)
01157 {
01158 char *tied_code = cls->getTiedCode();
01159 int len = strlen(quoted_seq)+1;
01160
01161 if (!tied_code)
01162 tied_code = (char *)calloc(len, sizeof(char));
01163 else
01164 tied_code = (char *)realloc(tied_code, len+strlen(tied_code));
01165
01166 strcat(tied_code, quoted_seq);
01167
01168 cls->setTiedCode(tied_code);
01169 }
01170
01171
01172 struct ClassNotFound {
01173
01174 static LinkedList list;
01175
01176 static Bool get(const char *name) {
01177 LinkedListCursor c(list);
01178 char *s;
01179
01180 while (c.getNext((void *&)s))
01181 if (!strcmp(s, name))
01182 return True;
01183
01184 return False;
01185 }
01186
01187 static void error(const char *name, const char *prefix = 0) {
01188 char *x = strdup(name);
01189 if (x[strlen(x)-1] == '*')
01190 x[strlen(x)-1] = 0;
01191
01192 if (get(x))
01193 {
01194 free(x);
01195 return;
01196 }
01197
01198 if (prefix) {
01199 std::string str = std::string(prefix) + " : cannot find class '%s'\n";
01200 odl_add_error(str.c_str(), x);
01201 }
01202 else
01203 odl_add_error("cannot find class '%s'\n", x);
01204 put(x);
01205 }
01206
01207 static void put(const char *name) {
01208 list.insertObjectLast((void *)name);
01209 }
01210
01211 };
01212
01213 LinkedList ClassNotFound::list;
01214
01215
01216 std::string
01217 odlCollSpecToString(odlCollSpec *coll_spec)
01218 {
01219 #define STR(X) ((X) ? (X) : "<null>")
01220 std::string s = "collname=";
01221 s += STR(coll_spec->collname);
01222 s += " typename=";
01223
01224 if (coll_spec->typname)
01225 s += coll_spec->typname;
01226 else if (coll_spec->coll_spec)
01227 s += std::string("{") + odlCollSpecToString(coll_spec->coll_spec) + "}";
01228 else
01229 s += "<null>";
01230
01231 s += " isref=";
01232 s += str_convert((long)coll_spec->isref);
01233 s += " dim=";
01234 s += str_convert((long)coll_spec->dim);
01235 return s;
01236 }
01237
01238 AttributeComponent *
01239 odlAttrComponent::make(Database *db, Schema *m, Class *cls,
01240 const Attribute *&attr)
01241 {
01242 if (isCloned) {
01243
01244 return 0;
01245 }
01246
01247 std::string sattrpath;
01248 const char *clsname = cls->getAliasName();
01249 int len = strlen(clsname);
01250 std::string s = std::string(clsname) + ".";
01251 const char *p = strchr(attrpath, ':');
01252 if (p) {
01253 if (strncmp(attrpath, clsname, p - attrpath)) {
01254 odl_add_error("invalid syntax '%s' for attribute path: class name "
01255 "expected before scope operator\n",
01256 attrpath);
01257 return 0;
01258 }
01259 sattrpath = s + std::string(p + 2);
01260 }
01261 else if (!strncmp(attrpath, s.c_str(), len + 1))
01262 sattrpath = attrpath;
01263 else
01264 sattrpath = s + attrpath;
01265
01266 const Class *xcls;
01267 Status st = Attribute::checkAttrPath(m, xcls, attr, sattrpath.c_str());
01268 if (st) {
01269 odl_add_error(st);
01270 return 0;
01271 }
01272
01273 free(attrpath);
01274 attrpath = strdup(sattrpath.c_str());
01275 return make_realize(db, m, const_cast<Class *>(cls), attr);
01276 }
01277
01278 static odlBool
01279 is_update_attribute(odlUpdateItem *ci, const Attribute *attr)
01280 {
01281 if (!ci->asUpdateAttribute())
01282 return odlFalse;
01283
01284 const Attribute *cattr = ci->asUpdateAttribute()->item;
01285 if (cattr->getClassOwner() == attr->getClassOwner()) {
01286 return odlTrue;
01287 }
01288
01289
01290
01291
01292
01293
01294
01295
01296
01297
01298
01299
01300
01301
01302
01303 return odlFalse;
01304 }
01305
01306 static odlBool
01307 is_remove_attribute(odlUpdateItem *ci, const Attribute *attr)
01308 {
01309 return ci->asRemoveAttribute() &&
01310 ci->asRemoveAttribute()->item == attr ? odlTrue : odlFalse;
01311 }
01312
01313
01314
01315 static const Attribute *
01316 odl_is_pred_attribute(Schema *m, const Attribute *attr,
01317 odlBool (*pred)(odlUpdateItem *,
01318 const Attribute *),
01319 const char *predname)
01320 {
01321 LinkedListCursor c(odlUPDLIST(m));
01322 odlUpdateItem *ci;
01323
01324
01325 while (c.getNext((void *&)ci)) {
01326 if (pred(ci, attr))
01327 return attr;
01328
01329
01330
01331 if (!attr->isIndirect() && attr->getClass()->asAgregatClass()) {
01332 unsigned int attr_cnt;
01333 const Attribute **attrs = attr->getClass()->getAttributes(attr_cnt);
01334
01335
01336
01337
01338 for (int i = 0; i < attr_cnt; i++) {
01339 if (!attrs[i]->isNative() &&
01340 odl_is_pred_attribute(m, attrs[i], pred, predname))
01341 return attrs[i];
01342 }
01343 }
01344 }
01345
01346 return 0;
01347 }
01348
01349 static const Attribute *
01350 odl_is_update_attribute(Schema *m, const Attribute *attr)
01351 {
01352 return odl_is_pred_attribute(m, attr, is_update_attribute, "update");
01353 }
01354
01355 static const Attribute *
01356 odl_is_remove_attribute(Schema *m, const Attribute *attr)
01357 {
01358 return odl_is_pred_attribute(m, attr, is_remove_attribute, "remove");
01359 }
01360
01361 void odlAgregatClass::realize(Database *db, odlAttrComponent *odl_comp,
01362 Schema *m, const char *prefix)
01363 {
01364 if (!cls) {
01365 odl_add_error(std::string("class ") + ocls->getName() + " is removed : "
01366 "cannot add components");
01367 return ;
01368 }
01369
01370 const Attribute *attr;
01371 AttributeComponent *attr_comp = odl_comp->make
01372 (db, m, const_cast<Class *>(cls), attr);
01373
01374
01375
01376
01377
01378 if (attr_comp) {
01379 if (db && db->isOpened() && ocls) {
01380 const LinkedList *dlist;
01381
01382 Status s = const_cast<Class *>(ocls)->getAttrCompList(dlist);
01383
01384 if (s) {
01385 odl_add_error(s);
01386 return;
01387 }
01388
01389 AttributeComponent *oattr_comp = 0;
01390 s = ocls->getAttrComp(attr_comp->getName().c_str(), oattr_comp);
01391
01392 if (s) {
01393 odl_add_error(s);
01394 return;
01395 }
01396
01397 if (oattr_comp) {
01398 if (!attr_comp->getClass()->compare(oattr_comp->getClass())) {
01399 if (attr_comp->asIndex()) {
01400 if (odl_update_index)
01401 odl_add_error("index on %s has not the same implementation type "
01402 "in database : use idxupdate to change manually "
01403 "its implementation type\n",
01404 attr_comp->getAttrpath().c_str());
01405 }
01406 else
01407 odl_add_error("internal error in "
01408 "attribute component management\n");
01409 return;
01410 }
01411
01412 ObjectPeer::setOid(attr_comp, oattr_comp->getOid());
01413 }
01414 }
01415
01416 cls->add(attr_comp->getInd(), attr_comp);
01417 }
01418 }
01419
01420 int odlCollImplSpec::make_class_prologue(const char *clsname,
01421 odlCollImplSpecItem::Type &type,
01422 char *&hints) const
01423 {
01424 return make_prologue(True, clsname, type, hints, 0);
01425 }
01426
01427 int odlCollImplSpec::make_attr_prologue(const char *attrpath,
01428 odlCollImplSpecItem::Type &type,
01429 char *&hints, const Attribute *attr) const {
01430 return make_prologue(False, attrpath, type, hints, attr);
01431 }
01432
01433 int odlCollImplSpec::make_prologue(Bool isclass, const char *name,
01434 odlCollImplSpecItem::Type &type,
01435 char *&hints, const Attribute *attr) const {
01436 odlCollImplSpecItem::Type undefType = odlCollImplSpecItem::UndefType;
01437
01438 type = undefType;
01439 hints = 0;
01440
01441 for (int i = 0; i < item_cnt; i++) {
01442 odlCollImplSpecItem *item = &items[i];
01443 if (item->type != undefType) {
01444 if (type != undefType) {
01445 if (isclass)
01446 odl_add_error("class implementation'%s': collection type is "
01447 "defined twice", name);
01448 else
01449 odl_add_error("attribute '%s': collection type is defined twice",
01450 name);
01451 return 0;
01452 }
01453 type = item->type;
01454 }
01455 else if (item->hints) {
01456 if (hints) {
01457 if (isclass)
01458 odl_add_error("class implementation '%s': collection hints are "
01459 "defined twice", name);
01460 else
01461 odl_add_error("attribute '%s': collection hints are defined twice",
01462 name);
01463 return 0;
01464 }
01465 hints = item->hints;
01466 }
01467 }
01468
01469 if (type == undefType) {
01470 if (isclass) {
01471 type = odlCollImplSpecItem::HashIndex;
01472 }
01473 else {
01474 type = odlCollImplSpecItem::NoIndex;
01475 }
01476
01477
01478
01479
01480
01481
01482
01483
01484 }
01485
01486 return 1;
01487 }
01488
01489 int
01490 odlIndexImplSpec::make_prologue(const char *name,
01491 odlIndexImplSpecItem::Type &type,
01492 char *&hints,
01493 const Attribute *attr) const
01494 {
01495 odlIndexImplSpecItem::Type undefType = odlIndexImplSpecItem::UndefType;
01496
01497 type = undefType;
01498 hints = 0;
01499
01500 for (int i = 0; i < item_cnt; i++) {
01501 odlIndexImplSpecItem *item = &items[i];
01502 if (item->type != undefType) {
01503 if (type != undefType) {
01504 odl_add_error("attribute '%s': index type is defined twice",
01505 name);
01506 return 0;
01507 }
01508 type = item->type;
01509 }
01510 else if (item->hints) {
01511 if (hints) {
01512 odl_add_error("attribute '%s': index hints are defined twice", name);
01513 return 0;
01514 }
01515 hints = item->hints;
01516 }
01517 }
01518
01519 if (type == undefType) {
01520 if (attr && (attr->isString() || attr->isIndirect() ||
01521 attr->getClass()->asCollectionClass()))
01522 type = odlIndexImplSpecItem::Hash;
01523 else
01524 type = odlIndexImplSpecItem::BTree;
01525 }
01526
01527 return 1;
01528 }
01529
01530 odlBool
01531 odlAttrComponent::similar(odlAttrComponent *comp,
01532 const Class *cls1, const Class *cls2)
01533 {
01534
01535
01536
01537
01538
01539 if (!strcmp(comp->attrpath, attrpath))
01540 return odlTrue;
01541
01542 std::string s1 = std::string(cls1->getName()) + ".";
01543 std::string s2 = std::string(cls2->getName()) + ".";
01544 int len1 = strlen(s1.c_str());
01545 int len2 = strlen(s2.c_str());
01546 if (!strncmp(attrpath, s1.c_str(), len1)) {
01547 if (!strncmp(comp->attrpath, s2.c_str(), len2)) {
01548 return !strcmp(&attrpath[len1], &comp->attrpath[len2]) ?
01549 odlTrue : odlFalse;
01550 }
01551 else
01552 return !strcmp(&attrpath[len1], comp->attrpath) ?
01553 odlTrue : odlFalse;
01554 }
01555 else {
01556 if (!strncmp(comp->attrpath, s2.c_str(), len2)) {
01557 return !strcmp(attrpath, &comp->attrpath[len2]) ?
01558 odlTrue : odlFalse;
01559 }
01560 }
01561
01562 return odlFalse;
01563 }
01564
01565 odlBool
01566 odlIndex::similar(odlAttrComponent *comp,
01567 const Class *cls1, const Class *cls2)
01568 {
01569 if (!comp->asIndex())
01570 return odlFalse;
01571 return odlAttrComponent::similar(comp, cls1, cls2);
01572 }
01573
01574 odlBool
01575 odlCardinality::similar(odlAttrComponent *comp,
01576 const Class *cls1, const Class *cls2)
01577 {
01578 if (!comp->asCardinality())
01579 return odlFalse;
01580 return odlAttrComponent::similar(comp, cls1, cls2);
01581 }
01582
01583 odlBool
01584 odlImplementation::similar(odlAttrComponent *comp,
01585 const Class *cls1, const Class *cls2)
01586 {
01587 if (!comp->asImplementation())
01588 return odlFalse;
01589 return odlAttrComponent::similar(comp, cls1, cls2);
01590 }
01591
01592 odlBool
01593 odlNotnull::similar(odlAttrComponent *comp,
01594 const Class *cls1, const Class *cls2)
01595 {
01596 if (!comp->asNotnull())
01597 return odlFalse;
01598 return odlAttrComponent::similar(comp, cls1, cls2);
01599 }
01600
01601 odlBool
01602 odlUnique::similar(odlAttrComponent *comp,
01603 const Class *cls1, const Class *cls2)
01604 {
01605 if (!comp->asUnique())
01606 return odlFalse;
01607 return odlAttrComponent::similar(comp, cls1, cls2);
01608 }
01609
01610 AttributeComponent *
01611 odlIndex::make_realize(Database *db, Schema *m, Class *cls,
01612 const Attribute *attr)
01613 {
01614 odlIndexImplSpecItem::Type type;
01615 char *hints;
01616
01617 if (index_impl_spec) {
01618 if (!index_impl_spec->make_prologue(attrpath, type, hints, attr))
01619 return 0;
01620 }
01621 else {
01622 hints = 0;
01623 if (attr &&
01624 (attr->isString() || attr->isIndirect() ||
01625 attr->getClass()->asCollectionClass()))
01626 type = odlIndexImplSpecItem::Hash;
01627 else
01628 type = odlIndexImplSpecItem::BTree;
01629 }
01630
01631 Bool hasDB = IDBBOOL(db);
01632
01633 if (!db)
01634 db = odl_get_dummy_db(m);
01635
01636 Index *idx;
01637 Status s;
01638 if (type == odlIndexImplSpecItem::Hash)
01639 s = HashIndex::make(db,
01640 const_cast<Class *>(cls), attrpath,
01641 IDBBOOL(propagate), attr->isString(), hints,
01642 (HashIndex *&)idx);
01643 else
01644 s = BTreeIndex::make(db,
01645 const_cast<Class *>(cls), attrpath,
01646 IDBBOOL(propagate), attr->isString(), hints,
01647 (BTreeIndex *&)idx);
01648
01649 if (s) {
01650 odl_add_error(s);
01651 return 0;
01652 }
01653
01654 return idx;
01655 }
01656
01657 AttributeComponent *
01658 odlImplementation::make_realize(Database *db, Schema *m, Class *cls,
01659 const Attribute *attr)
01660 {
01661
01662 odlCollImplSpecItem::Type type;
01663 char *hints;
01664
01665 if (coll_impl_spec) {
01666 if (!coll_impl_spec->make_attr_prologue(attrpath, type, hints, attr))
01667 return 0;
01668 }
01669 else {
01670 hints = 0;
01671
01672 type = odlCollImplSpecItem::NoIndex;
01673 }
01674
01675 Bool hasDB = IDBBOOL(db);
01676 if (!db)
01677 db = odl_get_dummy_db(m);
01678
01679 CollAttrImpl *impl;
01680 CollImpl::Type impltype;
01681
01682 if (type == odlCollImplSpecItem::HashIndex) {
01683 impltype = CollImpl::HashIndex;
01684 }
01685 else if (type == odlCollImplSpecItem::BTreeIndex) {
01686 impltype = CollImpl::BTreeIndex;
01687 }
01688 else if (type == odlCollImplSpecItem::NoIndex) {
01689 impltype = CollImpl::NoIndex;
01690 }
01691 else {
01692 odl_add_error("unknown implementation type for attribute %s", attrpath);
01693 return 0;
01694 }
01695
01696 Status s = CollAttrImpl::make
01697 (db, const_cast<Class *>(cls), attrpath, IDBBOOL(propagate),
01698 impltype, hints, (CollAttrImpl *&)impl);
01699
01700 if (s) {
01701 odl_add_error(s);
01702 return 0;
01703 }
01704
01705 return impl;
01706 }
01707
01708 AttributeComponent *
01709 odlNotnull::make_realize(Database *db, Schema *m, Class *cls,
01710 const Attribute *)
01711 {
01712 return new NotNullConstraint(db, cls, attrpath, IDBBOOL(propagate));
01713 }
01714
01715 AttributeComponent *
01716 odlUnique::make_realize(Database *db, Schema *m, Class *cls,
01717 const Attribute *)
01718 {
01719 return new UniqueConstraint(db, cls, attrpath, IDBBOOL(propagate));
01720 }
01721
01722 AttributeComponent *
01723 odlCardinality::make_realize(Database *db, Schema *m, Class *cls,
01724 const Attribute *)
01725 {
01726 return 0;
01727 }
01728
01729 void odlAgregatClass::realize(odlDeclItem *item,
01730 Schema *m, const char *prefix,
01731 int n, ClassComponent **comp,
01732 int &comp_cnt, Attribute **agr)
01733 {
01734 Class *cl = NULL;
01735 int *dims, ndims, index_mode;
01736 Status status;
01737
01738 if (item->typname)
01739 {
01740
01741
01742
01743
01744 cl = eyedb::getClass(m, item->typname, prefix);
01745 }
01746
01747 if (item->typname && !cl)
01748 {
01749 ClassNotFound::error(item->typname,
01750 (std::string("class ") + name +
01751 ", attribute #" + str_convert((long)n+1)).c_str());
01752 return;
01753 }
01754
01755 if (check_name(m, name, item->typname, item->attrname, prefix))
01756 {
01757 odl_error++;
01758 return;
01759 }
01760
01761 array_make(item, dims, ndims);
01762
01763 char *invcname, *invfname;
01764 if (item->inverse) {
01765 invcname = item->inverse->classname;
01766 invfname = item->inverse->attrname;
01767 }
01768 else {
01769 invcname = invfname = 0;
01770 }
01771
01772 #if 0
01773 Index *idx_item, *idx_comp;
01774 item->attr_list_make(m, cls, index_mode, idx_item, idx_comp,
01775 &invcname, &invfname, comp, comp_cnt);
01776 #endif
01777
01778 if (invcname)
01779 invcname = strdup(makeName(invcname, prefix));
01780
01781 if (item->coll_spec)
01782 {
01783 odlCollSpec *coll_spec = item->coll_spec;
01784 odlCollSpec *coll_spec_arr[64];
01785 int coll_spec_cnt = 0;
01786
01787 while (coll_spec)
01788 {
01789
01790 coll_spec_arr[coll_spec_cnt++] = coll_spec;
01791 coll_spec = coll_spec->coll_spec;
01792 }
01793
01794 const char *coll_typname = coll_spec_arr[coll_spec_cnt-1]->typname;
01795 Class *mcoll = NULL;
01796
01797 for (int i = coll_spec_cnt-1; i >= 0; i--)
01798 {
01799 coll_spec = coll_spec_arr[i];
01800 cl = eyedb::getClass(m, coll_typname, prefix);
01801
01802 if (!cl) {
01803 ClassNotFound::error(coll_typname,
01804 (std::string("class ") + name).c_str());
01805 return;
01806 }
01807
01808 Exception::Mode mode = Exception::setMode(Exception::StatusMode);
01809 if (!strcmp(coll_spec->collname, "set")) {
01810 if (coll_spec->dim)
01811 mcoll = new CollSetClass(cl, coll_spec->dim);
01812 else
01813 mcoll = new CollSetClass(cl, (Bool)coll_spec->isref);
01814 }
01815 else if (!strcmp(coll_spec->collname, "bag")) {
01816 if (coll_spec->dim)
01817 mcoll = new CollBagClass(cl, coll_spec->dim);
01818 else
01819 mcoll = new CollBagClass(cl, (Bool)coll_spec->isref);
01820 }
01821 else if (!strcmp(coll_spec->collname, "array")) {
01822 if (coll_spec->dim)
01823 mcoll = new CollArrayClass(cl, coll_spec->dim);
01824 else
01825 mcoll = new CollArrayClass(cl, (Bool)coll_spec->isref);
01826 }
01827 else if (!strcmp(coll_spec->collname, "list")) {
01828 if (coll_spec->dim)
01829 mcoll = new CollListClass(cl, coll_spec->dim);
01830 else
01831 mcoll = new CollListClass(cl, (Bool)coll_spec->isref);
01832 }
01833 else {
01834 odl_add_error("invalid collection type '%s'\n",
01835 coll_spec->collname);
01836 return;
01837 }
01838
01839 mcoll->setUserData(odlGENCODE, AnyUserData);
01840 Exception::setMode(mode);
01841
01842
01843
01844
01845
01846
01847
01848
01849
01850
01851
01852 status = mcoll->asCollectionClass()->getStatus();
01853 if (status) {
01854 odl_add_error("attribute error '%s::%s': ", name, item->attrname);
01855 odl_add_error(status);
01856 odl_error--;
01857 return;
01858 }
01859
01860 Class *mcoll_old = m->getClass(mcoll->getName());
01861
01862 if (mcoll_old) {
01863 mcoll->release();
01864 mcoll = mcoll_old;
01865 }
01866 else
01867 m->addClass(mcoll);
01868
01869 coll_typname = mcoll->getName();
01870 }
01871
01872 if (invfname)
01873 {
01874 if (invcname)
01875 {
01876 if (strcmp(invcname, cl->getName()) &&
01877 strcmp(invcname, cl->getAliasName()))
01878 {
01879 odl_add_error("inverse class incoherency: got '%s', expected '%s'\n", invcname, mcoll->getName());
01880 return;
01881 }
01882 }
01883 else
01884 invcname = strdup(cl->getAliasName());
01885 }
01886
01887 agr[n] =
01888 new Attribute(mcoll, item->attrname, (Bool)item->isref, ndims, dims);
01889
01890
01891 agr[n]->setUserData(item->upd_hints);
01892
01893 status = agr[n]->check();
01894 if (status)
01895 odl_add_error(status);
01896 }
01897 else
01898 {
01899 if (invfname)
01900 {
01901 if (invcname)
01902 {
01903 if (strcmp(invcname, cl->getName()) &&
01904 strcmp(invcname, cl->getAliasName()))
01905 {
01906 odl_add_error("inverse class incoherency: got '%s', expected '%s'\n", invcname, cl->getName());
01907 return;
01908 }
01909 }
01910 else
01911 invcname = strdup(cl->getAliasName());
01912 }
01913
01914 agr[n] = new Attribute(cl, item->attrname, (Bool)item->isref,
01915 ndims, dims);
01916
01917 agr[n]->setUserData(item->upd_hints);
01918 status = agr[n]->check();
01919 if (status)
01920 odl_add_error(status);
01921 }
01922
01923 if (invcname)
01924 {
01925 status = agr[n]->setInverse(invcname, invfname);
01926
01927 if (status)
01928 odl_add_error(status);
01929 }
01930 }
01931
01932 static TriggerType
01933 makeTrigType(const char *loc)
01934 {
01935 if (!strcmp(loc, "create_before"))
01936 return TriggerCREATE_BEFORE;
01937 if (!strcmp(loc, "create_after"))
01938 return TriggerCREATE_AFTER;
01939 if (!strcmp(loc, "update_before"))
01940 return TriggerUPDATE_BEFORE;
01941 if (!strcmp(loc, "update_after"))
01942 return TriggerUPDATE_AFTER;
01943 if (!strcmp(loc, "load_before"))
01944 return TriggerLOAD_BEFORE;
01945 if (!strcmp(loc, "load_after"))
01946 return TriggerLOAD_AFTER;
01947 if (!strcmp(loc, "remove_before"))
01948 return TriggerREMOVE_BEFORE;
01949 if (!strcmp(loc, "remove_after"))
01950 return TriggerREMOVE_AFTER;
01951
01952 odl_add_error("invalid trigger localisation '%s'\n", loc);
01953 return (TriggerType)0;
01954 }
01955
01956 static Signature *
01957 makeSignature(Schema *m, const char *clsname, const char *mthname,
01958 const char *rettype, odlArgSpecList *arglist,
01959 int &missNames)
01960 {
01961 ArgType *type = ArgType::make(m, rettype);
01962
01963 if (!type)
01964 {
01965 type = ArgType::make(m, (odl_db_prefix + rettype).c_str());
01966 if (!type) {
01967 ClassNotFound::error(rettype,
01968 (std::string("method ") + clsname + "::" +
01969 mthname).c_str());
01970 return 0;
01971 }
01972 }
01973
01974 missNames = 0;
01975 type->setType((ArgType_Type)(type->getType() | OUT_ARG_TYPE), False);
01976
01977 Signature *sign = new Signature();
01978 #ifdef NO_DIRECT_SET
01979 *sign->getRettype() = *type;
01980 #endif
01981
01982 #ifndef NO_DIRECT_SET
01983 sign->setRettype(type);
01984 #endif
01985 sign->setNargs(arglist->count);
01986 odlArgSpecLink *l = arglist->first;
01987
01988 #ifdef NO_DIRECT_SET
01989 sign->setTypesCount(arglist->count);
01990 #endif
01991 char **names = new char *[arglist->count];
01992
01993 int n = 0;
01994 while (l)
01995 {
01996 type = ArgType::make(m, l->x->typname);
01997 if (!type)
01998 {
01999 type = ArgType::make(m, (odl_db_prefix + l->x->typname).c_str());
02000 if (!type) {
02001 ClassNotFound::error(l->x->typname,
02002 (std::string("method ") + clsname + "::" +
02003 mthname + ", argument #" +
02004 str_convert((long)n+1)).c_str());
02005 if (sign)
02006 sign->release();
02007 sign = 0;
02008
02009 }
02010 }
02011
02012 if (sign) {
02013 type->setType((ArgType_Type)(type->getType() | l->x->inout), False);
02014 #ifdef NO_DIRECT_SET
02015 *sign->getTypes(n) = *type;
02016 #else
02017 sign->setTypes(n, type);
02018 #endif
02019 names[n] = (l->x->varname ? strdup(l->x->varname) : 0);
02020 if (!names[n])
02021 missNames++;
02022 }
02023
02024 l = l->next;
02025 n++;
02026 }
02027
02028 if (!sign) return 0;
02029 odlSignUserData *sud = new odlSignUserData(names);
02030 sign->setUserData(sud);
02031 return sign;
02032 }
02033
02034 int
02035 odlMethodSpec::getParamNames(char **&typnames, char **&varnames)
02036 {
02037 int param_cnt = arglist->count;
02038 typnames = new char*[param_cnt];
02039 varnames = new char*[param_cnt];
02040
02041 odlArgSpecLink *l = arglist->first;
02042
02043 for (int n = 0; l; n++)
02044 {
02045 const char *s;
02046 if (l->x->inout == INOUT_ARG_TYPE)
02047 s = "inout";
02048 else if (l->x->inout == IN_ARG_TYPE)
02049 s = "in";
02050 else
02051 s = "out";
02052 typnames[n] = strdup((std::string(s) + "$" + l->x->typname).c_str());
02053 varnames[n] = l->x->varname;
02054 l = l->next;
02055 }
02056
02057 return param_cnt;
02058 }
02059
02060 std::string
02061 odlTriggerSpec::makeOQLBody(const Class *cls) const
02062 {
02063 return std::string("oql$") + cls->getAliasName() + "$" + name + "(this) ";
02064 }
02065
02066 static void
02067 compileMethod(Schema *m, const Class *cls, odlMethodSpec *mth)
02068 {
02069 if (!m->getDatabase() || !m->getDatabase()->isOpened())
02070 return;
02071
02072 char **typnames;
02073 char **varnames;
02074 int param_cnt = mth->getParamNames(typnames, varnames);
02075 std::string oqlConstruct;
02076
02077 std::string body = BEMethod_OQL::makeExtrefBody(cls, mth->oqlSpec,
02078 mth->fname,
02079 typnames, varnames,
02080 param_cnt,
02081 oqlConstruct);
02082
02083 oqmlStatus *s = oqml_realize(m->getDatabase(),
02084 (char *)oqlConstruct.c_str(), 0,
02085 oqml_True);
02086 if (s)
02087 odl_add_error("compiling '%s::%s': %s\n",
02088 cls->getAliasName(), mth->fname, s->msg);
02089
02090 free(mth->oqlSpec);
02091 mth->oqlSpec = strdup(body.c_str());
02092 }
02093
02094 static void
02095 compileTrigger(Schema *m, const Class *cls, odlTriggerSpec *trig)
02096 {
02097 std::string oqlConstruct;
02098
02099 std::string body = Trigger::makeExtrefBody(cls, trig->oqlSpec,
02100 trig->name,
02101 oqlConstruct);
02102
02103 oqmlStatus *s = oqml_realize(m->getDatabase(),
02104 (char *)oqlConstruct.c_str(), 0,
02105 oqml_True);
02106 if (s)
02107 odl_add_error("compiling trigger '%s::%s': %s\n",
02108 cls->getAliasName(), trig->name, s->msg);
02109
02110
02111
02112
02113
02114
02115
02116
02117
02118
02119
02120 free(trig->oqlSpec);
02121 trig->oqlSpec = strdup(body.c_str());
02122 }
02123
02124 void odlAgregatClass::realize(Database *db, Schema *m,
02125 odlExecSpec *ex, const char *def_extref)
02126 {
02127 ClassComponent *comp = 0;
02128 odlMethodSpec *mth;
02129 odlTriggerSpec *trig;
02130
02131 if (mth = ex->asMethodSpec()) {
02132 int missNames;
02133 Signature *sign = makeSignature(m, name, mth->fname,
02134 mth->rettype, mth->arglist,
02135 missNames);
02136
02137 if (!sign)
02138 return;
02139
02140 if (mth->oqlSpec) {
02141 if (missNames) {
02142 odl_add_error("method '%s::%s' : signatures for OQL"
02143 " methods must contains parameter names\n",
02144 cls->getName(), mth->fname);
02145 return;
02146 }
02147
02148 compileMethod(m, cls, mth);
02149
02150 comp = new BEMethod_OQL(0, cls, mth->fname, sign,
02151 (Bool)mth->isClassMethod,
02152 odl_system_class,
02153 mth->oqlSpec);
02154 }
02155 else if (mth->mth_hints.isClient)
02156 comp = new FEMethod_C(0, cls, mth->fname, sign,
02157 (Bool)mth->isClassMethod,
02158 odl_system_class,
02159 mth->extref ? mth->extref : def_extref);
02160 else
02161 comp = new BEMethod_C(0, cls, mth->fname, sign,
02162 (Bool)mth->isClassMethod,
02163 odl_system_class,
02164 mth->extref ? mth->extref : def_extref);
02165 ((odlSignUserData *)sign->getUserData())->mth_hints = &mth->mth_hints;
02166 ((odlSignUserData *)sign->getUserData())->upd_hints = mth->upd_hints;
02167 comp->setUserData(sign->getUserData());
02168 comp->asMethod()->getEx()->getSign()->setUserData(sign->getUserData());
02169 }
02170 else if (trig = ex->asTriggerSpec()) {
02171 TriggerType ttype = makeTrigType(trig->localisation);
02172 if (ttype) {
02173 if (trig->oqlSpec)
02174 compileTrigger(m, cls, trig);
02175 const char *extref;
02176 if (trig->oqlSpec)
02177 extref = trig->oqlSpec;
02178 else if (trig->extref)
02179 extref = trig->extref;
02180 else
02181 extref = def_extref;
02182
02183 comp = new Trigger(0, cls, ttype,
02184 (trig->oqlSpec ? OQL_LANG : C_LANG),
02185 odl_system_class,
02186 trig->name, trig->light ? True : False,
02187 extref);
02188
02189 odlSignUserData *sud = new odlSignUserData(0);
02190 sud->upd_hints = trig->upd_hints;
02191 comp->setUserData(sud);
02192 }
02193 }
02194 else
02195 abort();
02196
02197 if (!odl_error){
02198 if (ex->asMethodSpec()) {
02199 if (!cls->getUserData(odlMTHLIST))
02200 cls->setUserData(odlMTHLIST, new LinkedList());
02201 odlMTHLIST(cls)->insertObject(comp);
02202 }
02203 cls->add(comp->getInd(), comp);
02204 }
02205 }
02206
02207 void
02208 odl_add_component(Schema *m, ClassComponent *comp)
02209 {
02210 if (odl_error)
02211 return;
02212
02213
02214 odlUPDLIST(m)->insertObjectLast(new odlAddComponent(comp));
02215 comp->getClassOwner()->touch();
02216 }
02217
02218 void
02219 odl_add_component(Schema *m, AttributeComponent *comp)
02220 {
02221 if (odl_error)
02222 return;
02223
02224
02225 odlUPDLIST(m)->insertObjectLast(new odlAddComponent(comp));
02226
02227 }
02228
02229 void
02230 odl_remove_component(Schema *m, ClassComponent *comp)
02231 {
02232 if (odl_error)
02233 return;
02234
02235
02236 odlUPDLIST(m)->insertObjectLast(new odlRemoveComponent(comp));
02237 comp->getClassOwner()->touch();
02238 }
02239
02240 void
02241 odl_remove_component(Schema *m, AttributeComponent *comp)
02242 {
02243 if (odl_error)
02244 return;
02245
02246
02247 odlUPDLIST(m)->insertObjectLast(new odlRemoveComponent(comp));
02248 }
02249
02250 static void
02251 odl_add_relationship(Schema *m, Class *cls, const char *name,
02252 const Attribute *item,
02253 const Attribute *invitem)
02254 {
02255 cls->touch();
02256 odlUPDLIST(m)->insertObjectLast(new odlAddRelationship(item, invitem));
02257 }
02258
02259 static void
02260 odl_remove_relationship(Schema *m, Class *cls, const char *name,
02261 const Attribute *item,
02262 const Attribute *invitem)
02263 {
02264 cls->touch();
02265 odlUPDLIST(m)->insertObjectLast(new odlRemoveRelationship(item, invitem));
02266 }
02267
02268 static void
02269 odl_add_class(Schema *m, const Class *cls)
02270 {
02271 if (odl_error)
02272 return;
02273
02274 if (!odl_rootclass || strcmp(cls->getName(), odl_rootclass))
02275 odlUPDLIST(m)->insertObjectLast(new odlAddClass(cls));
02276 }
02277
02278 static void
02279 odl_remove_class(Database *db, Schema *m, const Class *cls)
02280 {
02281 if (odl_error)
02282 return;
02283
02284 odlUPDLIST(m)->insertObjectLast(new odlRemoveClass(db, cls,
02285 odlUPDLIST(m)));
02286 }
02287
02288 static void
02289 odl_migrate_attributes(Schema *m, const Class *cls)
02290 {
02291 unsigned int attr_cnt;
02292 const Attribute **attrs = cls->getAttributes(attr_cnt);
02293
02294 for (int i = 0; i < attr_cnt; i++)
02295 {
02296 const Attribute *attr = attrs[i];
02297 odlUpdateHint *upd_hints = (odlUpdateHint *)attr->getUserData();
02298 if (upd_hints && upd_hints->type == odlUpdateHint::MigrateFrom)
02299 {
02300 const Class *ocls = eyedb::getClass(m, upd_hints->detail, odl_db_prefix.c_str());
02301 if (!ocls)
02302 {
02303 ClassNotFound::error(upd_hints->detail);
02304 continue;
02305 }
02306
02307 ocls = (const Class *)ocls->getUserData();
02308 assert(ocls);
02309
02310 const Attribute *oattr = ocls->getAttribute(upd_hints->detail2);
02311 if (!oattr)
02312 {
02313 odl_add_error("attribute %s not found in class %s\n",
02314 upd_hints->detail2, upd_hints->detail);
02315 continue;
02316 }
02317
02318 const_cast<Attribute *>(oattr)->setUserData
02319 (new odlUpdateHint
02320 (odlUpdateHint::MigrateTo,
02321 cls->getName(), attr->getName(), upd_hints->detail3));
02322 }
02323 }
02324 }
02325
02326 static void
02327 odl_reparent_class(Schema *m, const Class *cls)
02328 {
02329 odlUPDLIST(m)->insertObjectLast(new odlReparentClass(cls));
02330 }
02331
02332 static void
02333 odl_add_attribute(Schema *m, const Class *cls,
02334 const Attribute *attr)
02335 {
02336
02337 odlUPDLIST(m)->insertObjectLast(new odlAddAttribute(cls, attr));
02338 }
02339
02340 static void
02341 odl_remove_attribute(Schema *m, const Class *cls,
02342 const Attribute *attr)
02343 {
02344
02345 odlUPDLIST(m)->insertObjectLast(new odlRemoveAttribute(cls, attr));
02346 }
02347
02348 static void
02349 odl_rename_attribute(Schema *m, const Class *cls,
02350 const Attribute *attr,
02351 odlUpdateHint *upd_hints)
02352 {
02353 odlUPDLIST(m)->insertObjectLast(new odlRenameAttribute(cls, attr, upd_hints));
02354 }
02355
02356 static void
02357 odl_migrate_attribute(Schema *m, const Class *cls,
02358 const Attribute *attr, odlUpdateHint *upd_hints)
02359 {
02360 odlUPDLIST(m)->insertObjectLast(new odlMigrateAttribute(cls, attr, upd_hints));
02361 }
02362 static void
02363 odl_convert_attribute(Schema *m, const Class *cls,
02364 const Attribute *oattr, const Attribute *attr,
02365 odlUpdateHint *upd_hints = 0)
02366 {
02367 odlUPDLIST(m)->insertObjectLast(new odlConvertAttribute(cls, oattr, attr, upd_hints));
02368 }
02369
02370 static Bool
02371 odl_reorder_attr(Schema *m, const Class *cls,
02372 const Attribute *attr, int newnum)
02373 {
02374 if (attr->getNum() != newnum)
02375 {
02376 odlUPDLIST(m)->insertObjectLast
02377 (new odlReorderAttribute(cls, attr, newnum, attr->getNum()));
02378 const_cast<Attribute *>(attr)->setNum(newnum);
02379 return True;
02380 }
02381
02382 return False;
02383 }
02384
02385 static int
02386 cmp_attr(const void *x1, const void *x2)
02387 {
02388 return (*(Attribute **)x1)->getNum() - (*(Attribute **)x2)->getNum();
02389 }
02390
02391 static Attribute *
02392 odl_get_renamed_attr(Attribute *attrs[], int attr_cnt,
02393 const Attribute *oattr)
02394 {
02395
02396 for (int j = 0; j < attr_cnt; j++)
02397 {
02398 const Attribute *attr = attrs[j];
02399 odlUpdateHint *upd_hints = (odlUpdateHint *)attr->getUserData();
02400 if (upd_hints && upd_hints->type == odlUpdateHint::RenameFrom &&
02401 !strcmp(upd_hints->detail, oattr->getName()))
02402 return const_cast<Attribute *>(attr);
02403 }
02404
02405 return 0;
02406 }
02407
02408 #define COMPLETE(CLS) \
02409 if ((CLS)->isPartiallyLoaded()) \
02410 { \
02411 Status s = m->manageClassDeferred((Class *)CLS); \
02412 if (s) \
02413 { \
02414 odl_add_error(s); \
02415 return; \
02416 } \
02417 }
02418
02419 #ifdef NEW_REORDER
02420 static Bool
02421 odl_class_need_reorder(const Class *ocls,
02422 Attribute **attrs, int attr_cnt)
02423 {
02424 int onum = 0;
02425 for (int i = 0; i < attr_cnt; i++)
02426 {
02427 const Attribute *attr = attrs[i];
02428 const Attribute *oattr;
02429
02430 if (oattr = ocls->getAttribute(attr->getName())) {
02431 if (oattr->getNum() < onum) {
02432
02433 return True;
02434 }
02435 onum = oattr->getNum();
02436 }
02437 }
02438
02439
02440 return False;
02441 }
02442
02443 static void
02444 odl_class_premanage(Schema *m, const Class *ocls, const Class *cls)
02445 {
02446 static const int invalid_num = -1;
02447 unsigned int attr_cnt;
02448 Attribute **attrs = (Attribute **)cls->getAttributes(attr_cnt);
02449 int i;
02450
02451 COMPLETE(cls);
02452 COMPLETE(ocls);
02453
02454 if (!odl_class_need_reorder(ocls, attrs, attr_cnt))
02455 return;
02456
02457
02458
02459
02460
02461 Bool is_renum = False;
02462 int attr_num = 0;
02463 for (i = 0; i < attr_cnt; i++)
02464 {
02465 const Attribute *attr = attrs[i];
02466 const Attribute *oattr;
02467
02468 if (oattr = ocls->getAttribute(attr->getName())) {
02469 if (odl_reorder_attr(m, cls, attr, oattr->getNum()))
02470 is_renum = True;
02471 attr_num++;
02472 }
02473 else
02474 {
02475 odlUpdateHint *upd_hints = (odlUpdateHint *)attr->getUserData();
02476 if (upd_hints && upd_hints->type == odlUpdateHint::RenameFrom)
02477 {
02478 oattr = ocls->getAttribute(upd_hints->detail);
02479 if (oattr) {
02480 if (odl_reorder_attr(m, cls, attr, oattr->getNum()))
02481 is_renum = True;
02482 attr_num++;
02483 }
02484 else
02485 const_cast<Attribute *>(attr)->setNum(invalid_num);
02486 }
02487 else
02488 const_cast<Attribute *>(attr)->setNum(invalid_num);
02489 }
02490 }
02491
02492 for (i = 0; i < attr_cnt; i++) {
02493 const Attribute *attr = attrs[i];
02494 if (attr->getNum() == invalid_num) {
02495 const_cast<Attribute *>(attr)->setNum(attr_num++);
02496 is_renum = True;
02497 }
02498 }
02499
02500 qsort(attrs, attr_cnt, sizeof(Attribute *), cmp_attr);
02501 if (is_renum) const_cast<Class *>(cls)->compile();
02502 }
02503 #endif
02504
02505 static void
02506 odl_class_compare(Schema *m, const Class *ocls, const Class *cls,
02507 odlUpdateHint *cls_hints)
02508 {
02509 unsigned int oattr_cnt, attr_cnt;
02510 Attribute **oattrs = (Attribute **)ocls->getAttributes(oattr_cnt);
02511 Attribute **attrs = (Attribute **)cls->getAttributes(attr_cnt);
02512 int i;
02513
02514 COMPLETE(cls);
02515 COMPLETE(ocls);
02516
02517
02518 for (i = 0; i < oattr_cnt; i++) {
02519 const Attribute *oattr = oattrs[i];
02520 const Attribute *attr;
02521 Bool migrate = False;
02522
02523 odlUpdateHint *upd_hints = (odlUpdateHint *)oattr->getUserData();
02524 if (upd_hints && upd_hints->type == odlUpdateHint::MigrateTo) {
02525 migrate = True;
02526 odl_migrate_attribute(m, cls, oattr, upd_hints);
02527 }
02528
02529 if (!(attr = cls->getAttribute(oattr->getName()))) {
02530 attr = odl_get_renamed_attr(attrs, attr_cnt, oattr);
02531 if (!attr) {
02532 if (!migrate) {
02533 if (cls_hints && cls_hints->type == odlUpdateHint::Extend) {
02534 if (upd_hints && upd_hints->type == odlUpdateHint::Remove)
02535 odl_remove_attribute(m, cls, oattr);
02536 }
02537 else
02538 odl_remove_attribute(m, cls, oattr);
02539 }
02540 }
02541 else if (upd_hints && upd_hints->type == odlUpdateHint::Convert)
02542 odl_convert_attribute(m, cls, oattr, attr, upd_hints);
02543 else if (!oattr->compare(m->getDatabase(), attr,
02544 False,
02545 False,
02546 False,
02547 True))
02548 odl_convert_attribute(m, cls, oattr, attr);
02549 }
02550 else if (upd_hints && upd_hints->type == odlUpdateHint::Convert)
02551 odl_convert_attribute(m, cls, oattr, attr, upd_hints);
02552 else if (!oattr->compare(m->getDatabase(), attr,
02553 False,
02554 False,
02555 False,
02556 True))
02557 odl_convert_attribute(m, cls, oattr, attr);
02558 }
02559
02560
02561 for (i = 0; i < attr_cnt; i++) {
02562 const Attribute *attr = attrs[i];
02563 const Attribute *oattr;
02564
02565 const char *name = attr->getName();
02566 odlUpdateHint *upd_hints = (odlUpdateHint *)attr->getUserData();
02567 if (upd_hints && upd_hints->type == odlUpdateHint::RenameFrom) {
02568 name = upd_hints->detail;
02569 if (oattr = ocls->getAttribute(name))
02570 odl_rename_attribute(m, cls, attr, upd_hints);
02571 else
02572 odl_add_error("class %s: no attribute named %s\n",
02573 cls->getName(), name);
02574 }
02575
02576 if (!(oattr = ocls->getAttribute(name))) {
02577 if (!upd_hints || upd_hints->type != odlUpdateHint::MigrateFrom)
02578 odl_add_attribute(m, cls, attr);
02579 }
02580 }
02581
02582 if (odl_error) return;
02583
02584 #ifndef NEW_REORDER
02585
02586 int cnt = 0;
02587 for (i = 0; i < attr_cnt; i++) {
02588 const Attribute *attr = attrs[i];
02589 const Attribute *oattr;
02590
02591 if (oattr = ocls->getAttribute(attr->getName()))
02592 odl_reorder_attr(m, cls, attr, oattr->getNum() + cnt);
02593 else {
02594 odlUpdateHint *upd_hints = (odlUpdateHint *)attr->getUserData();
02595 if (upd_hints && upd_hints->type == odlUpdateHint::RenameFrom) {
02596 oattr = ocls->getAttribute(upd_hints->detail);
02597 if (oattr)
02598 odl_reorder_attr(m, cls, attr, oattr->getNum() + cnt);
02599 else
02600 cnt++;
02601 }
02602 else
02603 cnt++;
02604 }
02605 }
02606
02607
02608 qsort(attrs, attr_cnt, sizeof(Attribute *), cmp_attr);
02609 #endif
02610 }
02611
02612 static void
02613 odl_class_parent_compare(Schema *m, const Class *ocls, const Class *cls)
02614 {
02615 const Class *parent = cls->getParent();
02616 if (odl_rootclass && !strcmp(parent->getName(), odl_rootclass))
02617 parent = parent->getParent();
02618 const Class *oparent = ocls->getParent();
02619 if (odl_rootclass && !strcmp(oparent->getName(), odl_rootclass))
02620 oparent = oparent->getParent();
02621
02622
02623
02624
02625
02626
02627 if (strcmp(parent->getName(), oparent->getName()))
02628 odl_reparent_class(m, cls);
02629 }
02630
02631 Bool
02632 odl_find_component(ClassComponent *&comp, const LinkedList *complist,
02633 Bool strictCheck, ClassComponent *&fclcomp)
02634 {
02635
02636 if (strchr(comp->getName().c_str(), '.')) {
02637 fclcomp = comp;
02638 return True;
02639 }
02640
02641 fclcomp = 0;
02642 LinkedListCursor c(complist);
02643 ClassComponent *tmpcomp;
02644 while (c.getNext((void *&)tmpcomp))
02645 {
02646 if (!strcmp(comp->getName().c_str(), tmpcomp->getName().c_str()))
02647 {
02648 if (!comp->asAgregatClassExecutable()) {
02649 fclcomp = tmpcomp;
02650 return True;
02651 }
02652
02653 Executable *ex = comp->asAgregatClassExecutable()->getEx();
02654 Executable *tmpex = tmpcomp->asAgregatClassExecutable()->getEx();
02655
02656 if (strictCheck &&
02657 strcmp(ex->getExtrefBody().c_str(), tmpex->getExtrefBody().c_str()))
02658 {
02659 tmpex->setExtrefBody(ex->getExtrefBody());
02660 if ((ex->getLang() & SYSTEM_EXEC) && !odl_system_class)
02661 {
02662 odl_add_error("cannot modify system method "
02663 "'%s'\n", comp->getName().c_str());
02664 fclcomp = tmpcomp;
02665 return True;
02666 }
02667
02668 if (ex->getLoc() != tmpex->getLoc()) {
02669 return False;
02670 }
02671
02672 comp = tmpcomp;
02673 return False;
02674 }
02675 else if (ex->getLoc() != tmpex->getLoc()) {
02676 return False;
02677 }
02678
02679 fclcomp = tmpcomp;
02680 return True;
02681 }
02682 }
02683
02684 if (comp->asAgregatClassExecutable() &&
02685 ((comp->asAgregatClassExecutable()->getEx()->getLang() &
02686 SYSTEM_EXEC) && !odl_system_class)) {
02687 fclcomp = comp;
02688 return True;
02689 }
02690
02691 return False;
02692 }
02693
02694 Bool
02695 odl_compare_index_hints(const Index *idx1, const Index *idx2)
02696 {
02697 if (idx1->getImplHintsCount() != idx2->getImplHintsCount())
02698 return False;
02699
02700 int cnt = idx1->getImplHintsCount();
02701 for (int i = 0; i < cnt; i++) {
02702 if (idx1->getImplHints(i) && idx2->getImplHints(i) &&
02703 idx1->getImplHints(i) != idx2->getImplHints(i))
02704 return False;
02705 }
02706
02707 return True;
02708 }
02709
02710 Bool
02711 odl_compare_index(const HashIndex *idx1, const HashIndex *idx2)
02712 {
02713 if (idx1->getKeyCount() && idx2->getKeyCount() &&
02714 idx1->getKeyCount() != idx2->getKeyCount())
02715 return False;
02716
02717 if (!const_cast<HashIndex *>(idx1)->compareHashMethod(const_cast<HashIndex *>(idx2)))
02718 return False;
02719
02720 return odl_compare_index_hints(idx1, idx2);
02721 }
02722
02723 Bool
02724 odl_compare_index(const BTreeIndex *idx1, const BTreeIndex *idx2)
02725 {
02726 if (idx1->getDegree() && idx2->getDegree() &&
02727 idx1->getDegree() != idx2->getDegree())
02728 return False;
02729
02730 return odl_compare_index_hints(idx1, idx2);
02731 }
02732
02733 AttributeComponent *
02734 odl_report_index_hints(const Index *idx1, Index *idx2)
02735 {
02736 int cnt1 = idx1->getImplHintsCount();
02737 int cnt2 = idx2->getImplHintsCount();
02738 for (int i = 0; i < cnt1; i++)
02739 idx2->setImplHints(i, idx1->getImplHints(i));
02740
02741 for (int i = cnt1; i < cnt2; i++)
02742 idx2->setImplHints(i, 0);
02743
02744 return idx2;
02745 }
02746
02747 AttributeComponent *
02748 odl_report_index(Index *idx1, Index *idx2)
02749 {
02750 ObjectPeer::setOid(idx1, idx2->getOid());
02751 idx1->setIdxOid(idx2->getIdxOid());
02752 return idx1;
02753 }
02754
02755 Bool
02756 odl_find_component(AttributeComponent *&comp, const LinkedList *complist,
02757 Bool strictCheck, AttributeComponent *&fattr_comp)
02758 {
02759 fattr_comp = 0;
02760 LinkedListCursor c(complist);
02761 AttributeComponent *tmpcomp;
02762 while (c.getNext((void *&)tmpcomp)) {
02763 if (!strcmp(comp->getName().c_str(), tmpcomp->getName().c_str())) {
02764 fattr_comp = tmpcomp;
02765 if (strictCheck) {
02766 if (comp->asIndex()) {
02767 BTreeIndex *bidx = comp->asBTreeIndex();
02768 BTreeIndex *tmpbidx = tmpcomp->asBTreeIndex();
02769 HashIndex *hidx = comp->asHashIndex();
02770 HashIndex *tmphidx = tmpcomp->asHashIndex();
02771
02772 if (hidx && tmphidx) {
02773 if (odl_update_index && !odl_compare_index(hidx, tmphidx)) {
02774 comp = odl_report_index(hidx, tmphidx);
02775 return False;
02776 }
02777 }
02778 else if (bidx && tmpbidx) {
02779 if (odl_update_index && !odl_compare_index(bidx, tmpbidx)) {
02780 comp = odl_report_index(bidx, tmpbidx);
02781 return False;
02782 }
02783 }
02784 else
02785 return False;
02786 }
02787
02788 if (odl_update_index && comp->getPropagate() != tmpcomp->getPropagate()) {
02789 tmpcomp->setPropagate(comp->getPropagate());
02790 comp = tmpcomp;
02791 return False;
02792 }
02793 }
02794
02795 return True;
02796 }
02797 }
02798
02799 return False;
02800 }
02801
02802 static int
02803 completeInverse(Schema *m, const char *cname,
02804 const char *fname, const Attribute *&invitem)
02805 {
02806 if (invitem)
02807 return 0;
02808
02809 if (cname && fname)
02810 {
02811 const Class *cls = m->getClass(cname);
02812 if (!cls)
02813 {
02814 odl_error++;
02815 return 1;
02816 }
02817
02818 invitem = cls->getAttribute(fname);
02819 }
02820
02821 return 0;
02822 }
02823
02824
02825
02826
02827
02828
02829
02830 #ifdef NEW_DIFF_RELSHIP
02831 int
02832 odl_remove_relationships(Database *, Schema *m, Class *ocls)
02833 {
02834
02835 if (true)
02836 return 0;
02837
02838 if (!ocls)
02839 return 0;
02840
02841 unsigned int oattr_cnt;
02842 const Attribute **oattrs = ocls->getAttributes(oattr_cnt);
02843
02844 for (int i = 0; i < oattr_cnt; i++) {
02845 const Attribute *oattr = oattrs[i];
02846
02847 const char *ocname, *ofname;
02848 const Attribute *oinvitem;
02849
02850 oattr->getInverse(&ocname, &ofname, &oinvitem);
02851 completeInverse(m, ocname, ofname, oinvitem);
02852
02853 if (oinvitem)
02854 odl_remove_relationship(m, ocls, ocls->getName(), oattr, oinvitem);
02855 }
02856
02857 return 0;
02858 }
02859
02860
02861 int
02862 odlAgregatClass::manageDiffRelationShips(Database *, Schema *m, Bool diff)
02863 {
02864 if (!ocls)
02865 return 0;
02866
02867 unsigned int oattr_cnt, attr_cnt;
02868 const Attribute **attrs = cls->getAttributes(attr_cnt);
02869 const Attribute **oattrs = ocls->getAttributes(oattr_cnt);
02870
02871 for (int i = 0; i < oattr_cnt; i++)
02872 {
02873 const Attribute *oattr = oattrs[i];
02874 const Attribute *attr;
02875
02876 if (!(attr = cls->getAttribute(oattr->getName()))) {
02877 const char *ocname, *ofname;
02878 const Attribute *oinvitem;
02879
02880 oattr->getInverse(&ocname, &ofname, &oinvitem);
02881 completeInverse(m, ocname, ofname, oinvitem);
02882
02883 if (oinvitem)
02884 odl_remove_relationship(m, cls, name, oattr, oinvitem);
02885 }
02886 }
02887
02888 for (int i = 0; i < attr_cnt; i++)
02889 {
02890 const Attribute *attr = attrs[i];
02891 const Attribute *oattr;
02892 const Attribute *invitem;
02893 const char *cname, *fname;
02894
02895 attr->getInverse(&cname, &fname, &invitem);
02896 completeInverse(m, cname, fname, invitem);
02897
02898 if (oattr = ocls->getAttribute(attr->getName())) {
02899 const char *ocname, *ofname;
02900 const Attribute *oinvitem;
02901
02902 oattr->getInverse(&ocname, &ofname, &oinvitem);
02903 completeInverse(m, ocname, ofname, oinvitem);
02904
02905 if (oinvitem && !invitem)
02906 odl_remove_relationship(m, cls, name, attr, oinvitem);
02907 else if (invitem && !oinvitem)
02908 odl_add_relationship(m, cls, name, attr, invitem);
02909 else if (invitem && oinvitem &&
02910 strcmp(invitem->getName(), oinvitem->getName())) {
02911 odl_remove_relationship(m, cls, name, attr, oinvitem);
02912 odl_add_relationship(m, cls, name, attr, invitem);
02913 }
02914 }
02915 else if (invitem)
02916 odl_add_relationship(m, cls, name, attr, invitem);
02917 }
02918
02919 return 0;
02920 }
02921 #else
02922 int
02923 odlAgregatClass::manageDiffRelationShips(Schema *m, Bool diff)
02924 {
02925 int attr_cnt, oattr_cnt;
02926 const Attribute **attrs = cls->getAttributes(attr_cnt);
02927 const Attribute **oattrs = ocls->getAttributes(oattr_cnt);
02928
02929
02930 int cnt = (attr_cnt < oattr_cnt ? attr_cnt : oattr_cnt);
02931
02932 for (int i = 0; i < cnt; i++)
02933 {
02934 const char *cname, *fname, *ocname, *ofname;
02935 const Attribute *invitem, *oinvitem;
02936
02937 attrs[i]->getInverse(&cname, &fname, &invitem);
02938 oattrs[i]->getInverse(&ocname, &ofname, &oinvitem);
02939
02940 completeInverse(m, ocname, ofname, oinvitem);
02941 completeInverse(m, cname, fname, invitem);
02942
02943 if (oinvitem && !invitem)
02944 {
02945 cls->touch();
02946 odl_remove_relationship(m, name, attrs[i], oinvitem);
02947 }
02948 else if (invitem && !oinvitem)
02949 {
02950 cls->touch();
02951 odl_add_relationship(m, name, oattrs[i], invitem);
02952 }
02953 }
02954
02955 return 0;
02956 }
02957 #endif
02958
02959 Bool
02960 odl_exec_removed(ClassComponent *comp)
02961 {
02962 if (!comp)
02963 return False;
02964
02965 if (!comp->asTrigger() && !comp->asMethod())
02966 return False;
02967
02968 odlSignUserData *sud = (odlSignUserData *)comp->getUserData();
02969 return (sud && sud->upd_hints &&
02970 sud->upd_hints->type == odlUpdateHint::Remove ?
02971 True : False);
02972 }
02973
02974 #ifdef NEW_REORDER
02975 int
02976 odlAgregatClass::preManage(Schema *m)
02977 {
02978 if (odl_gencode || !m->getDatabase() || !cls)
02979 return 0;
02980
02981 if (!ocls)
02982 {
02983 odl_add_class(m, cls);
02984 return 0;
02985 }
02986
02987
02988 if (agrspec == odl_Declare)
02989 return 0;
02990
02991 if (agrspec != odl_NativeClass) {
02992 odl_class_premanage(m, ocls, cls);
02993 if (odl_error)
02994 return 0;
02995 }
02996
02997 return 0;
02998 }
02999 #endif
03000
03001 const Attribute *
03002 odl_getattr(const Class *cls, const AttributeComponent *attr_comp)
03003 {
03004 char *s = strdup(attr_comp->getAttrpath().c_str());
03005 char *q = strchr(s, '.');
03006
03007 if (!q) {
03008 odl_add_error("unexpected attrpath '%s'\n", s);
03009 free(s);
03010 return 0;
03011 }
03012
03013 *q = 0;
03014 char *p = strchr(q+1, '.');
03015 if (p) *p = 0;
03016 const Attribute *attr = cls->getAttribute(q+1);
03017
03018 if (!attr) {
03019 odl_add_error("attribute %s not found in class %s\n", q+1, cls->getName());
03020 free(s);
03021 return 0;
03022 }
03023
03024 free(s);
03025 return attr;
03026 }
03027
03028 static int
03029 odl_remove_components(Schema *m, Class *ocls, Class *cls)
03030 {
03031 m->getDatabase()->transactionBegin();
03032
03033 const char *name = ocls->getName();
03034 const LinkedList *ocomplist = ocls->getCompList();
03035 LinkedListCursor oc(ocomplist);
03036 ClassComponent *clcomp;
03037 while (oc.getNext((void *&)clcomp)) {
03038 if (!strcmp(clcomp->getClassOwner()->getName(), name))
03039 odl_remove_component(m, clcomp);
03040 }
03041
03042 const LinkedList *attr_ocomplist;
03043 Status s = ocls->getAttrCompList(attr_ocomplist);
03044 if (s) {odl_add_error(s); return 1;}
03045
03046 AttributeComponent *attr_comp;
03047 LinkedListCursor attr_oc(attr_ocomplist);
03048
03049 while (attr_oc.getNext((void *&)attr_comp)) {
03050
03051 AttributeComponent *cattr_comp = 0;
03052 if (ocls && ocls->getDatabase() &&
03053 attr_comp->find(ocls->getDatabase(), ocls->getParent(),
03054 cattr_comp) == Success) {
03055 if (!cattr_comp || !cattr_comp->getPropagate())
03056 odl_remove_component(m, attr_comp);
03057 }
03058 else
03059 odl_remove_component(m, attr_comp);
03060 }
03061
03062 m->getDatabase()->transactionAbort();
03063 return 0;
03064 }
03065
03066 int
03067 odlAgregatClass::manageDifferences(Database *db, Schema *m, Bool diff)
03068 {
03069 if (upd_hints && upd_hints->type == odlUpdateHint::Remove &&
03070 !odl_gencode && m->getDatabase()) {
03071 int r = odl_remove_components(m, ocls, cls);
03072 if (r)
03073 return r;
03074 return odl_remove_relationships(db, m, ocls);
03075 }
03076
03077 if (odl_gencode || !m->getDatabase() || !cls)
03078 return 0;
03079
03080 odl_migrate_attributes(m, cls);
03081 if (!ocls) {
03082 #ifndef NEW_REORDER
03083 odl_add_class(m, cls);
03084 #endif
03085 return 0;
03086 }
03087
03088
03089 if (agrspec == odl_Declare)
03090 return 0;
03091
03092 if (agrspec != odl_NativeClass) {
03093 odl_class_compare(m, ocls, cls, upd_hints);
03094 if (odl_error)
03095 return 0;
03096 odl_class_parent_compare(m, ocls, cls);
03097 }
03098
03099 const LinkedList *complist = cls->getCompList();
03100 const LinkedList *ocomplist = ocls->getCompList();
03101
03102 LinkedListCursor oc(ocomplist);
03103 LinkedListCursor c(complist);
03104
03105
03106 ClassComponent *clcomp = 0, *fclcomp;
03107
03108 m->getDatabase()->transactionBegin();
03109
03110 while (oc.getNext((void *&)clcomp)) {
03111 if (clcomp->getClassOwner()->compare(ocls)) {
03112 if (!odl_find_component(clcomp, complist, False, fclcomp)) {
03113 if ((!upd_hints || upd_hints->type != odlUpdateHint::Extend) &&
03114 agrspec != odl_NativeClass)
03115 odl_remove_component(m, clcomp);
03116 }
03117 else if (odl_exec_removed(fclcomp))
03118 odl_remove_component(m, clcomp);
03119 }
03120 }
03121
03122 while (c.getNext((void *&)clcomp)) {
03123 ClassComponent *oclcomp = clcomp;
03124 if (clcomp->getClassOwner()->compare(cls)) {
03125 if (!odl_find_component(clcomp, ocomplist, True, fclcomp)) {
03126 if (!odl_exec_removed(oclcomp))
03127 odl_add_component(m, clcomp);
03128 else {
03129 fprintf(stderr, "warning: cannot remove non existing '");
03130 clcomp->m_trace(stderr, 0, 0, NoRecurs);
03131 fprintf(stderr, "'\n");
03132 }
03133 }
03134 }
03135 }
03136
03137 const LinkedList *attr_ocomplist, *attr_complist;
03138 Status s = cls->getAttrCompList(attr_complist);
03139 if (s) {odl_add_error(s); return 1;}
03140 s = ocls->getAttrCompList(attr_ocomplist);
03141 if (s) {odl_add_error(s); return 1;}
03142
03143
03144
03145
03146
03147
03148
03149
03150 LinkedListCursor attr_oc(attr_ocomplist);
03151 LinkedListCursor attr_c(attr_complist);
03152
03153 AttributeComponent *attr_comp, *fattr_comp;
03154 int err = 0;
03155 while (attr_oc.getNext((void *&)attr_comp)) {
03156 if (!odl_find_component(attr_comp, attr_complist, False,
03157 fattr_comp)) {
03158 const Attribute *attr = odl_getattr(ocls, attr_comp);
03159 if (!attr) return 1;
03160 if (attr = odl_is_remove_attribute(m, attr)) {
03161 std::string s = std::string("removed attribute '") +
03162 attr->getClassOwner()->getName () + "::" + attr->getName() +
03163 "' : must remove " +
03164 (attr_comp->asIndex() ? "index" : "constraint") +
03165 " '" + attr_comp->getAttrpath() + "' manually using '" +
03166 (attr_comp->asIndex() ? "idxdelete" : "consdelete") +
03167 "' before updating the schema\n";
03168 odl_add_error(s);
03169 err++;
03170 }
03171
03172 if (odl_rmv_undef_attrcomp &&
03173 (!upd_hints || upd_hints->type != odlUpdateHint::Extend))
03174 odl_remove_component(m, attr_comp);
03175 }
03176 }
03177 if (err) return 1;
03178
03179 LinkedList torm_list;
03180
03181 while (attr_c.getNext((void *&)attr_comp)) {
03182 AttributeComponent *oattr_comp = attr_comp;
03183 if (!odl_find_component(attr_comp, attr_ocomplist, True, fattr_comp)) {
03184
03185 odl_add_component(m, attr_comp);
03186 const Attribute *attr = odl_getattr(cls, attr_comp);
03187 if (!attr) return 1;
03188 if (odl_is_update_attribute(m, attr))
03189 torm_list.insertObject(attr_comp);
03190 }
03191 }
03192
03193 LinkedListCursor ctorm(torm_list);
03194 while (ctorm.getNext((void *&)attr_comp)) {
03195
03196 cls->suppress(attr_comp->getInd(), attr_comp);
03197 }
03198
03199 if (agrspec != odl_NativeClass && !odl_error)
03200 manageDiffRelationShips(db, m, diff);
03201
03202 m->getDatabase()->transactionAbort();
03203 return 0;
03204 }
03205
03206
03207 #define HASH_COEF 64
03208 #define DEFAULT_MAG_ORDER 60000
03209
03210
03211 #if 0
03212 unsigned int
03213 odlImplementation::getMagOrder() const
03214 {
03215 unsigned magorder;
03216 if (!strcasecmp(ident, "btree"))
03217 return IDB_COLL_BIDX_MASK;
03218
03219 if (!strcasecmp(ident, "hash"))
03220 return (nentries ? nentries * HASH_COEF : DEFAULT_MAG_ORDER);
03221
03222 odl_add_error("expected keyword 'btree' or 'hash', got '%s'", ident);
03223 return 0;
03224 }
03225 #endif
03226
03227 odlBool
03228 odlAgregatClass::hasSimilarComp(odlAttrComponent *comp,
03229 const Class *cls2)
03230 {
03231
03232 odlDeclRootLink *l = decl_list->first;
03233 while(l) {
03234 odlAttrComponent *xcomp = l->x->asAttrComponent();
03235 if (xcomp && xcomp->similar(comp, cls, cls2))
03236 return odlTrue;
03237 l = l->next;
03238 }
03239
03240 return odlFalse;
03241 }
03242
03243 void
03244 odlAgregatClass::addComp(odlAttrComponent *comp)
03245 {
03246 decl_list->add(comp->clone());
03247 }
03248
03249 int
03250 odlAgregatClass::propagateComponents(Database *db, Schema *m)
03251 {
03252 odlDeclRootLink *l = decl_list->first;
03253 if (!l)
03254 return 0;
03255
03256
03257 Class **subclasses;
03258 unsigned int subclass_cnt;
03259 Status s = cls->getSubClasses(subclasses, subclass_cnt);
03260 if (s) {
03261 odl_add_error(s);
03262 return 1;
03263 }
03264
03265 while(l) {
03266 odlAttrComponent *comp = l->x->asAttrComponent();
03267 if (comp && comp->propagate) {
03268
03269 for (int i = 0; i < subclass_cnt; i++) {
03270 Class *clsx = subclasses[i];
03271 if (clsx == cls) continue;
03272 odlAgregatClass *x = (odlAgregatClass *)clsx->getUserData(odlSELF);
03273 if (x && !x->hasSimilarComp(comp, cls)) {
03274
03275 if (odl_rmv_undef_attrcomp) {
03276
03277 odl_add_error("attribute component %s: "
03278 "when using the -rmv-undef-attrcomp option, all the "
03279 "attribute components must be defined in the ODL",
03280 comp->attrpath);
03281 return 1;
03282 }
03283
03284 x->addComp(comp);
03285 }
03286
03287
03288
03289
03290
03291 }
03292 }
03293 l = l->next;
03294 }
03295
03296 return 0;
03297 }
03298
03299 int odlAgregatClass::postRealize(Database *db, Schema *m,
03300 const char *prefix)
03301 {
03302 odlDeclRootLink *l = decl_list->first;
03303
03304 while(l) {
03305 if (l->x->asAttrComponent())
03306 realize(db, l->x->asAttrComponent(), m, prefix);
03307 l = l->next;
03308 }
03309
03310 return 0;
03311 }
03312
03313 int odlAgregatClass::realize(Database *db, Schema *m, const char *prefix,
03314 const char *package, Bool diff)
03315 {
03316 if (!cls)
03317 return 0;
03318
03319 #if 0
03320 unsigned int magorder = getMagOrder(cls, attr_list);
03321
03322 if (magorder)
03323 cls->setMagOrder(magorder);
03324 #endif
03325
03326 Attribute **agr;
03327
03328 agr = new Attribute*[decl_list->count];
03329 memset(agr, 0, sizeof(Attribute *) * decl_list->count);
03330
03331 ClassComponent **comp = new ClassComponent*[decl_list->count*8];
03332
03333 int comp_cnt = 0, agr_cnt = 0;
03334
03335 char *def_extref_fe = new char[strlen(package)+strlen("mthfe")+1];
03336 sprintf(def_extref_fe, "%smthfe", package);
03337
03338 char *def_extref_be = new char[strlen(package)+strlen("mthbe")+1];
03339 sprintf(def_extref_be, "%smthbe", package);
03340
03341 odlDeclRootLink *l = decl_list->first;
03342
03343 while(l) {
03344 if (l->x->asExecSpec()) {
03345 odlBool isClient =
03346 (l->x->asExecSpec()->asMethodSpec() ?
03347 l->x->asExecSpec()->asMethodSpec()->mth_hints.isClient : odlFalse);
03348 realize(db, m, l->x->asExecSpec(),
03349 (isClient ? def_extref_fe : def_extref_be));
03350 }
03351
03352 l = l->next;
03353 }
03354
03355 l = decl_list->first;
03356
03357 while(l) {
03358 if (l->x->asDeclItem()) {
03359 realize(l->x->asDeclItem(), m, prefix, agr_cnt, comp, comp_cnt, agr);
03360 agr_cnt++;
03361 }
03362 else if (l->x->asQuotedSeq())
03363 add_quoted_seq(cls, l->x->asQuotedSeq()->quoted_seq);
03364
03365 l = l->next;
03366 }
03367
03368 if (odl_error) {
03369 if (agrspec != odl_NativeClass && agrspec != odl_Declare)
03370 m->suppressClass(cls);
03371 return odl_error;
03372 }
03373
03374 if (agrspec != odl_NativeClass && agrspec != odl_Declare) {
03375 Status status;
03376 status = cls->setAttributes(agr, agr_cnt);
03377
03378 if (status) {
03379 odl_add_error(status);
03380 return 0;
03381 }
03382 }
03383
03384 for (int i = 0; i < comp_cnt; i++)
03385 cls->add(comp[i]->getInd(), comp[i]);
03386
03387 return propagateComponents(db, m);
03388 }
03389
03390 int
03391 odlEnumClass::record(Database *, Schema *m,
03392 const char *prefix, const char *db_prefix)
03393 {
03394 if (check(m, prefix))
03395 odl_error++;
03396
03397 cls = new EnumClass(makeName(name, prefix));
03398 cls->setUserData(odlGENCODE, AnyUserData);
03399
03400 if (aliasname)
03401 cls->setAliasName(aliasname);
03402 else if (db_prefix)
03403 cls->setAliasName(makeName(name, db_prefix));
03404
03405
03406 ocls = eyedb::getClass(m, (aliasname ? aliasname : name), prefix);
03407 if (ocls && ocls != cls)
03408 {
03409 m->suppressClass(ocls);
03410 cls->setUserData(ocls);
03411 ObjectPeer::setOid(cls, ocls->getOid());
03412 }
03413
03414
03415 m->addClass(cls);
03416 if (odl_system_class)
03417 ClassPeer::setMType(cls, Class::System);
03418 return 0;
03419 }
03420
03421 int odlEnumClass::realize(Database *db, Schema *m, const char *prefix,
03422 const char *, Bool)
03423 {
03424 EnumItem **en = new EnumItem*[enum_list->count];
03425
03426 memset(en, 0, sizeof(EnumItem *) * enum_list->count);
03427
03428 odlEnumItemLink *l = enum_list->first;
03429
03430 int n = 0;
03431 int lastvalue, value;
03432 lastvalue = 0;
03433
03434 while(l)
03435 {
03436 odlEnumItem *item = l->x;
03437
03438 if (item->novalue)
03439 value = lastvalue;
03440 else
03441 value = item->value;
03442
03443
03444 if (check_name(m, (aliasname ? aliasname : name), 0, item->name, prefix))
03445 odl_error++;
03446
03447 en[n++] = new EnumItem(item->name, item->aliasname, value);
03448
03449 lastvalue = value + 1;
03450 l = l->next;
03451 }
03452
03453 Status status;
03454 status = ((EnumClass *)cls)->setEnumItems(en, n);
03455
03456 if (status)
03457 odl_add_error(status);
03458
03459 return 0;
03460 }
03461
03462 const char *odl_get_typname(const char *typname)
03463 {
03464 if (!strcmp(typname, "int"))
03465 return int32_class_name;
03466
03467 if (!strcmp(typname, "short"))
03468 return int16_class_name;
03469
03470 if (!strcmp(typname, "long"))
03471 return int64_class_name;
03472
03473 if (!strcmp(typname, "octet"))
03474 return "byte";
03475
03476 if (!strcmp(typname, "boolean"))
03477 return int32_class_name;
03478
03479 if (!strcmp(typname, "double"))
03480 return "float";
03481
03482 if (!strcmp(typname, "sequence"))
03483 return "array";
03484
03485 return typname;
03486 }
03487
03488 int
03489 odl_generate(Schema *m, const char *ofile)
03490 {
03491 FILE *fd;
03492
03493 Class *superclass = NULL;
03494 if (odlAgregatClass::superclass)
03495 {
03496 superclass = m->getClass(get_superclass_name());
03497 if (odlAgregatClass::superclass->getAgregSpec() == odl_RootClass)
03498 superclass->setIsRootClass();
03499 }
03500
03501 if (!ofile)
03502 fd = odl_fd;
03503 else
03504 {
03505 fd = fopen(ofile, "w");
03506 if (!fd)
03507 {
03508 odl_add_error("cannot open file '%s' for reading.\n",
03509 ofile);
03510 return 1;
03511 }
03512 }
03513
03514 m->genODL(fd);
03515
03516 return 0;
03517 }
03518
03519 static int odl_echo;
03520
03521 void
03522 odl_prompt_init(FILE *fd)
03523 {
03524 odl_echo = isatty(fileno(fd));
03525 }
03526
03527 void
03528 odl_prompt(const char *prompt)
03529 {
03530 if (odl_echo)
03531 {
03532 fprintf(odl_fd, prompt);
03533 fflush(odl_fd);
03534 }
03535 }
03536
03537
03538
03539
03540
03541
03542
03543 static Status
03544 odl_post_update_non_components(Database *db, Schema *m)
03545 {
03546 LinkedList *list = odlUPDLIST(m);
03547 LinkedListCursor c(list);
03548 Status s;
03549 odlUpdateItem *ci;
03550 while (c.getNext((void *&)ci)) {
03551 if (ci->asUpdateComponent() ||
03552 ci->asUpdateRelationship() ||
03553 ci->asRemoveClass())
03554 continue;
03555
03556 s = ci->postPerform(db, m);
03557 if (s) return s;
03558 }
03559
03560 return Success;
03561 }
03562
03563 static Status
03564 odl_post_update_components_1(Database *db, Schema *m)
03565 {
03566 LinkedList *list = odlUPDLIST(m);
03567 LinkedListCursor c(list);
03568 Status s;
03569 odlUpdateItem *ci;
03570 while (c.getNext((void *&)ci)) {
03571 if (!ci->asUpdateComponent())
03572 continue;
03573
03574 ClassComponent *comp = ci->asUpdateComponent()->cls_comp;
03575
03576 if (comp && comp->asMethod()) {
03577 s = ci->postPerform(db, m);
03578 if (s) return s;
03579 }
03580 }
03581
03582 return Success;
03583 }
03584
03585 static Status
03586 odl_post_update_components_2(Database *db, Schema *m)
03587 {
03588 LinkedList *list = odlUPDLIST(m);
03589 LinkedListCursor c(list);
03590 Status s;
03591 odlUpdateItem *ci;
03592 while (c.getNext((void *&)ci)) {
03593 if (!ci->asUpdateComponent())
03594 continue;
03595
03596 ClassComponent *cls_comp = ci->asUpdateComponent()->cls_comp;
03597 AttributeComponent *attr_comp = ci->asUpdateComponent()->attr_comp;
03598
03599 if ((cls_comp && cls_comp->asMethod()) ||
03600 (attr_comp && attr_comp->asIndex()))
03601 continue;
03602
03603 s = ci->postPerform(db, m);
03604 if (s) return s;
03605 }
03606
03607 return Success;
03608 }
03609
03610 static Status
03611 odl_post_update_indexes(Database *db, Schema *m)
03612 {
03613 LinkedList *list = odlUPDLIST(m);
03614 LinkedListCursor c(list);
03615 odlUpdateItem *ci;
03616 Status s;
03617
03618 while (c.getNext((void *&)ci)) {
03619 if (!ci->asUpdateComponent())
03620 continue;
03621
03622 AttributeComponent *comp = ci->asUpdateComponent()->attr_comp;
03623
03624 if (comp && comp->asIndex()) {
03625 s = ci->postPerform(db, m);
03626 if (s) return s;
03627 }
03628 }
03629
03630 return Success;
03631 }
03632
03633 static Status
03634 odl_post_update_relships(Database *db, Schema *m)
03635 {
03636 LinkedList *list = odlUPDLIST(m);
03637 LinkedListCursor c(list);
03638 Status s;
03639 odlUpdateItem *ci;
03640 while (c.getNext((void *&)ci)) {
03641 if (!ci->asUpdateRelationship())
03642 continue;
03643
03644 const Attribute *invitem = ci->asUpdateRelationship()->invitem;
03645
03646 if (!invitem)
03647 continue;
03648
03649 s = ci->postPerform(db, m);
03650 if (s) return s;
03651 }
03652
03653 return Success;
03654 }
03655
03656 static Status
03657 odl_post_update_remove_classes(Database *db, Schema *m)
03658 {
03659 LinkedList *list = odlUPDLIST(m);
03660 LinkedListCursor c(list);
03661 Status s;
03662 odlUpdateItem *ci;
03663 while (c.getNext((void *&)ci)) {
03664 if (!ci->asRemoveClass())
03665 continue;
03666
03667 s = ci->postPerform(db, m);
03668 if (s) return s;
03669 }
03670
03671 return Success;
03672 }
03673
03674 static Status
03675 odl_post_update_components(Database *db, Schema *m)
03676 {
03677 Status s;
03678 s = odl_post_update_components_1(db, m);
03679 if (s) return s;
03680
03681 s = odl_post_update_indexes(db, m);
03682 if (s) return s;
03683
03684 s = odl_post_update_components_2(db, m);
03685 if (s) return s;
03686
03687 return odl_post_update_relships(db, m);
03688 }
03689
03690 static Status
03691 odl_post_update_items(Database *db, Schema *m)
03692 {
03693 if (odlUPDLIST(m)) {
03694 Status s;
03695 s = odl_post_update_non_components(db, m);
03696 if (s) return s;
03697
03698 s = odl_post_update_components(db, m);
03699 if (s) return s;
03700
03701 s = odl_post_update_remove_classes(db, m);
03702 if (s) return s;
03703 }
03704
03705 return odl_post_update(db);
03706 }
03707
03708 static Status
03709 odl_pre_update_items(Database *db, Schema *m)
03710 {
03711 if (!odlUPDLIST(m))
03712 return Success;
03713
03714 LinkedList *list = odlUPDLIST(m);
03715 LinkedListCursor c(list);
03716 Status s;
03717 odlUpdateItem *ci;
03718 while (c.getNext((void *&)ci))
03719 {
03720 s = ci->prePerform(db, m);
03721 if (s) return s;
03722 }
03723
03724 return Success;
03725 }
03726
03727 static void
03728 odl_diff_realize(Database *db, Schema *m, const char *odlfile)
03729 {
03730 LinkedList *list = odlUPDLIST(m);
03731
03732 if (!list)
03733 return;
03734
03735
03736
03737 LinkedListCursor c(list);
03738 odlUpdateItem *ci;
03739 while (c.getNext((void *&)ci))
03740 {
03741 odl_diff++;
03742 ci->displayDiff(db, odlfile);
03743 }
03744
03745 db->transactionAbort();
03746 }
03747
03748
03749 static int odl_finished;
03750
03751 static void *
03752 patient_thr(void *arg)
03753 {
03754 if (getenv("EYEDBNOPATIENT"))
03755 return 0;
03756
03757 sleep(4);
03758 while (!odl_finished)
03759 {
03760 fprintf(odl_fd, ".");
03761 fflush(odl_fd);
03762 sleep(1);
03763 }
03764
03765 return (void *)0;
03766 }
03767
03768 static void
03769 run_patient()
03770 {
03771 pthread_t tid;
03772 pthread_create(&tid, NULL, patient_thr, NULL);
03773 }
03774
03775 static int
03776 odl_update_realize(Database *db, Schema *m, const char *dbname,
03777 const char *schname)
03778 {
03779 odl_skip_volatiles(db, m);
03780
03781 fprintf(odl_fd, "Updating '%s' schema in database %s...", schname, dbname);
03782 fflush(odl_fd);
03783
03784 Status s;
03785
03786 if (db->getUserData() && (s = m->storeName()))
03787 {
03788 odl_add_error(s);
03789 return 1;
03790 }
03791
03792 s = odl_pre_update_items(db, m);
03793
03794 if (s)
03795 {
03796 odl_add_error(s);
03797 return 1;
03798 }
03799
03800 run_patient();
03801 s = m->realize();
03802
03803 if (s)
03804 {
03805 odl_add_error(s);
03806 return 1;
03807 }
03808
03809 s = odl_post_update_items(db, m);
03810
03811 if (s)
03812 {
03813 odl_add_error(s);
03814 return 1;
03815 }
03816
03817 if (!getenv("EYEDBABORT"))
03818 s = db->transactionCommit();
03819 odl_finished = 1;
03820
03821 if (s)
03822 {
03823 odl_add_error(s);
03824 return 1;
03825 }
03826
03827 fprintf(odl_fd, "\nDone\n");
03828
03829 return 0;
03830 }
03831
03832 static int
03833 check_odlfile(const char *file, const char *cpp_cmd, const char *cpp_flags)
03834 {
03835 odl_decl_list = new LinkedList();
03836
03837 if (file) {
03838 FILE *fd;
03839
03840 if (!strcmp(file, "-"))
03841 odlin = stdin;
03842 else {
03843 fd = fopen(file, "r");
03844 if (!fd) {
03845 odl_add_error("cannot open file '%s' for reading\n",
03846 file);
03847 return 1;
03848 }
03849
03850 if (odlin && odlin != stdin)
03851 fclose(odlin);
03852
03853 odlin = run_cpp(fd, cpp_cmd, cpp_flags, file);
03854 if (!odlin)
03855 return 1;
03856 }
03857 }
03858
03859 if (file) {
03860 odl_prompt_init(odlin);
03861 odl_prompt("ODL construct expected on standard input (end input by a ^D) :\n");
03862 odl_prompt();
03863 }
03864
03865 return 0;
03866 }
03867
03868
03869
03870
03871
03872
03873
03874
03875
03876
03877
03878
03879
03880
03881
03882
03883
03884
03885
03886
03887
03888
03889
03890 static int
03891 odl_check_db(Database *db, const char *&schname, const char *package,
03892 Schema *&m, Bool update = False)
03893 {
03894 if (!schname)
03895 schname = package;
03896
03897 if (db) {
03898 Status s;
03899 Exception::Mode mode =
03900 Exception::setMode(Exception::StatusMode);
03901
03902 if (update)
03903 s = db->transactionBeginExclusive();
03904 else
03905 s = db->transactionBegin();
03906
03907 if (s) {
03908 odl_add_error(s);
03909 return 1;
03910 }
03911
03912 Exception::setMode(mode);
03913 m = db->getSchema();
03914 if (strcmp(m->getName(), schname))
03915 db->setUserData(AnyUserData);
03916
03917 LinkedListCursor c(m->getClassList());
03918 Class *cls;
03919 while (c.getNext((void *&)cls))
03920 if (!cls->isSystem())
03921 cls->setUserData(odlGENCODE, AnyUserData);
03922 }
03923 else {
03924 m = new Schema();
03925 m->init();
03926 syscls::updateSchema(m);
03927 oqlctb::updateSchema(m);
03928 utils::updateSchema(m);
03929 }
03930
03931 m->setName(schname);
03932 return 0;
03933 }
03934
03935 Status
03936 odl_prelim(Database *db, const char *odlfile, const char *package,
03937 const char *&schname, const char *prefix, const char *db_prefix,
03938 Bool diff, const char *cpp_cmd, const char *cpp_flags,
03939 Schema *&m, Bool update = False)
03940 {
03941 odl_error = 0;
03942 odl_str_error = "";
03943
03944 int r;
03945 r = odl_check_db(db, schname, package, m, update);
03946 if (r || odl_error) return odl_status_error(r);
03947
03948 r = check_odlfile(odlfile, cpp_cmd, cpp_flags);
03949
03950 if (r || odl_error) return odl_status_error(r);
03951
03952 if (odlfile) {
03953 r = odlparse();
03954 if (r || odl_error) return odl_status_error(r);
03955 }
03956
03957 odl_realize(db, m, odl_decl_list, prefix, db_prefix, package, diff);
03958
03959 return odl_status_error();
03960 }
03961
03962 Status
03963 Database::updateSchema(const char *odlfile, const char *package,
03964 const char *schname, const char *db_prefix,
03965 FILE *fd, const char *cpp_cmd,
03966 const char *cpp_flags)
03967 {
03968 odl_fd = (fd ? fd : odl_fdnull);
03969 Schema *m;
03970 Status s;
03971 s = odl_prelim(this, odlfile, package, schname, db_prefix, db_prefix,
03972 False, cpp_cmd, cpp_flags, m, True);
03973 if (s) return s;
03974
03975 odl_update_realize(this, sch, name, schname);
03976 return odl_status_error();
03977 }
03978
03979 Status
03980 Schema::displaySchemaDiff(Database *db, const char *odlfile,
03981 const char *package,
03982 const char *db_prefix,
03983 FILE *fd, const char *cpp_cmd,
03984 const char *cpp_flags)
03985 {
03986 odl_fd = (fd ? fd : odl_fdnull);
03987 Schema *m;
03988 const char *schname = "";
03989 Status s;
03990 s = odl_prelim(db, odlfile, package, schname, db_prefix, db_prefix,
03991 True, cpp_cmd, cpp_flags, m);
03992 if (s) return s;
03993 if (odl_error) return odl_status_error();
03994 odl_diff_realize(db, m, odlfile);
03995 return odl_status_error();
03996 }
03997
03998 #ifdef SUPPORT_CORBA
03999 Status
04000 Schema::genIDL(Database *db, const char *odlfile,
04001 const char *package,
04002 const char *module,
04003 const char *schname,
04004 const char *prefix,
04005 const char *db_prefix,
04006 const char *idltarget,
04007 const char *imdlfile,
04008 Bool no_generic_idl,
04009 const char *generic_idl,
04010 Bool no_factory,
04011 Bool imdl_synchro,
04012 GenCodeHints *gc_hints,
04013 Bool comments,
04014 const char *cpp_cmd, const char *cpp_flags,
04015 const char *ofile)
04016 {
04017 if (!gc_hints) gc_hints = new GenCodeHints();
04018 Schema *m;
04019 Status s;
04020 s = odl_prelim(db, odlfile, package, schname, prefix, db_prefix,
04021 False, cpp_cmd, cpp_flags, m);
04022 if (s) return s;
04023
04024 imdl_realize(db, m, package, module, False, False,
04025 schname, prefix,
04026 db_prefix, cpp_cmd, cpp_flags,
04027 idltarget, imdlfile,
04028 no_generic_idl, generic_idl,
04029 no_factory, imdl_synchro, gc_hints, comments,
04030 ofile);
04031
04032 return odl_status_error();
04033 }
04034
04035 Status
04036 Schema::genORB(const char *orb,
04037 Database *db, const char *odlfile,
04038 const char *package,
04039 const char *module,
04040 const char *schname,
04041 const char *prefix,
04042 const char *db_prefix,
04043 const char *idltarget,
04044 const char *imdlfile,
04045 Bool no_generic_idl,
04046 const char *generic_idl,
04047 Bool no_factory,
04048 Bool imdl_synchro,
04049 GenCodeHints *gc_hints,
04050 Bool comments,
04051 const char *cpp_cmd, const char *cpp_flags)
04052 {
04053 if (!gc_hints) gc_hints = new GenCodeHints();
04054 Schema *m;
04055 Status s;
04056 s = odl_prelim(db, odlfile, package, schname, prefix, db_prefix,
04057 False, cpp_cmd, cpp_flags, m);
04058 if (s) return s;
04059
04060 Bool orbix_gen, orbacus_gen;
04061 if (!strcasecmp(orb, "orbix"))
04062 {
04063 orbix_gen = True;
04064 orbacus_gen = False;
04065 }
04066 else
04067 {
04068 orbix_gen = False;
04069 orbacus_gen = True;
04070 }
04071
04072 imdl_realize(db, m, package, module, orbix_gen, orbacus_gen,
04073 schname, prefix,
04074 db_prefix, cpp_cmd, cpp_flags,
04075 idltarget, imdlfile,
04076 no_generic_idl, generic_idl,
04077 no_factory, imdl_synchro, gc_hints, comments, 0);
04078
04079 return odl_status_error();
04080 }
04081 #endif
04082
04083 Status
04084 Schema::genC_API(Database *db, const char *odlfile,
04085 const char *package,
04086 const char *schname,
04087 const char *c_namespace,
04088 const char *prefix,
04089 const char *db_prefix,
04090 Bool _export,
04091 GenCodeHints *gc_hints,
04092 const char *cpp_cmd, const char *cpp_flags)
04093 {
04094 odl_error = 0;
04095 odl_str_error = "";
04096
04097 if (!gc_hints) gc_hints = new GenCodeHints();
04098 Schema *m;
04099 odl_check_db(db, schname, package, m);
04100
04101 int r = check_odlfile(odlfile, cpp_cmd, cpp_flags);
04102
04103 if (r || odl_error) return odl_status_error(r);
04104
04105 if (odlfile)
04106 {
04107 r = odlparse();
04108 if (r || odl_error) return odl_status_error(r);
04109 }
04110
04111 odl_generate_code(db, m, ProgLang_C,
04112 odl_decl_list,
04113 package,
04114 schname,
04115 c_namespace,
04116 prefix,
04117 db_prefix,
04118 _export,
04119 *gc_hints);
04120
04121 return odl_status_error();
04122 }
04123
04124 Status
04125 Schema::genJava_API(Database *db, const char *odlfile,
04126 const char *package,
04127 const char *schname,
04128 const char *prefix,
04129 const char *db_prefix,
04130 Bool _export,
04131 GenCodeHints *gc_hints,
04132 const char *cpp_cmd, const char *cpp_flags)
04133 {
04134 if (!gc_hints) gc_hints = new GenCodeHints();
04135 Schema *m;
04136 Status s;
04137
04138 odl_check_db(db, schname, package, m);
04139
04140 int r = check_odlfile(odlfile, cpp_cmd, cpp_flags);
04141
04142 if (r || odl_error) return odl_status_error(r);
04143
04144 if (odlfile)
04145 {
04146 r = odlparse();
04147 if (r || odl_error) return odl_status_error(r);
04148 }
04149
04150 odl_generate_code(db, m, ProgLang_Java,
04151 odl_decl_list,
04152 package,
04153 schname,
04154 NULL,
04155 prefix,
04156 db_prefix,
04157 _export,
04158 *gc_hints);
04159
04160 return odl_status_error();
04161 }
04162
04163 Status
04164 Schema::checkODL(const char *odlfile, const char *package,
04165 const char *cpp_cmd, const char *cpp_flags)
04166 {
04167 odl_error = 0;
04168 odl_str_error = "";
04169
04170 Schema *m;
04171 const char *schname = "";
04172 return odl_prelim(0, odlfile, package, schname, "", "",
04173 False, cpp_cmd, cpp_flags, m);
04174 }
04175
04176 Status
04177 Schema::genODL(Database *db,
04178 const char *odlfile,
04179 const char *package,
04180 const char *schname,
04181 const char *prefix,
04182 const char *db_prefix,
04183 const char *ofile,
04184 const char *cpp_cmd, const char *cpp_flags)
04185 {
04186 odl_error = 0;
04187 odl_str_error = "";
04188
04189 Schema *m;
04190
04191 if (odlfile)
04192 {
04193 Status s;
04194 s = odl_prelim(db, odlfile, package, schname, prefix, db_prefix,
04195 False, cpp_cmd, cpp_flags, m);
04196 if (s) return s;
04197 }
04198 else
04199 {
04200 int r = odl_check_db(db, schname, package, m);
04201 if (r || odl_error) return odl_status_error(r);
04202 }
04203
04204 odl_generate(m, ofile);
04205
04206 return odl_status_error();
04207 }
04208 }