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