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 "eyedb_p.h"
00026 #include "CollectionBE.h"
00027 #include <dlfcn.h>
00028 #include <assert.h>
00029 #include "AttrNative.h"
00030 #include "Attribute_p.h"
00031
00032 #define XBOOL "bool"
00033
00034 #define DEF_PREFIX "eyedb::"
00035 #define DEF_PREFIX1 "eyedb::"
00036
00037 using namespace std;
00038
00039
00040
00041 namespace eyedb {
00042 int Class::RemoveInstances = 0x12;
00043
00044 static inline const IndexImpl *
00045 getDefaultIndexImpl()
00046 {
00047 static IndexImpl *defIndexImpl;
00048 if (!defIndexImpl)
00049 defIndexImpl = new IndexImpl(IndexImpl::Hash, 0, 2048, 0, 0, 0);
00050 return defIndexImpl;
00051 }
00052
00053 void Class::_init(const char *s)
00054 {
00055 name = NULL;
00056 num = 0;
00057 aliasname = NULL;
00058 canonname = NULL;
00059 setPName(s);
00060 mustCreateComps = False;
00061
00062 subclass_set = False;
00063 subclass_count = 0;
00064 subclasses = NULL;
00065 sch = 0;
00066
00067 setClass(Class_Class);
00068 if (!getClass())
00069 setClass(this);
00070
00071 idr_objsz = 0;
00072 idr_psize = 0;
00073 idr_vsize = 0;
00074 idr_inisize = 0;
00075 extent = NULL;
00076 components = NULL;
00077 complist = NULL;
00078 memset(clist, 0, sizeof(LinkedList *)*ComponentCount_C);
00079 attr_complist = NULL;
00080 memset(attr_clist, 0, sizeof(LinkedList *)*AttrComponentCount_C);
00081 complist = new LinkedList();
00082 type = _Class_Type;
00083 items_cnt = 0;
00084 items = 0;
00085 items_set = False;
00086 m_type = User;
00087 isFlat = False;
00088 isFlatSet = False;
00089 is_root = False;
00090 tied_code = 0;
00091 attrs_complete = False;
00092 partially_loaded = False;
00093 setup_complete = False;
00094 instance_dataspace = 0;
00095 instance_dspid = Dataspace::DefaultDspid;
00096 idximpl = getDefaultIndexImpl()->clone();
00097 }
00098
00099 Class::Class(const char *s, Class *p) : Object()
00100 {
00101 _init(s);
00102
00103 parent = (p ? p : Instance_Class);
00104 parent_oid.invalidate();
00105 }
00106
00107 Class::Class(const char *s, const Oid *poid) : Object()
00108 {
00109 _init(s);
00110
00111 if (poid)
00112 parent_oid = *poid;
00113 else
00114 parent_oid.invalidate();
00115
00116 parent = 0;
00117 }
00118
00119 Class::Class(Database *_db, const char *s, Class *p) : Object(_db)
00120 {
00121 _init(s);
00122
00123 parent = (p ? p : Instance_Class);
00124 parent_oid.invalidate();
00125 }
00126
00127 Class::Class(Database *_db, const char *s, const Oid *poid) : Object(_db)
00128 {
00129 _init(s);
00130
00131 if (poid)
00132 parent_oid = *poid;
00133 else
00134 parent_oid.invalidate();
00135
00136 parent = 0;
00137 }
00138
00139 Class::Class(const Class &cl) : Object(cl)
00140 {
00141 _init(cl.getName());
00142 *this = cl;
00143 }
00144
00145 Class::Class(const Oid &_oid, const char *_name) : Object()
00146 {
00147 _init(_name);
00148 oid = _oid;
00149 partially_loaded = True;
00150 parent = 0;
00151 }
00152
00153 #define STRDUP(X) ((X) ? strdup(X) : 0)
00154
00155 Status
00156 Class::loadComplete(const Class *cl)
00157 {
00158
00159 assert(cl->getRefCount());
00160 assert(this != cl);
00161 *this = *cl;
00162
00163 return Success;
00164 }
00165
00166 static void
00167 freeCompList(LinkedList *list, Class *cl)
00168 {
00169
00170
00171
00172
00173
00174
00175
00176
00177
00178
00179
00180
00181
00182 assert(0);
00183 }
00184
00185 Class& Class::operator=(const Class &cl)
00186 {
00187 assert(cl.getRefCount());
00188 assert(getRefCount());
00189
00190 *(Object *)this = (const Object &)cl;
00191
00192 name = STRDUP(cl.name);
00193 aliasname = STRDUP(cl.aliasname);
00194 canonname = STRDUP(cl.canonname);
00195
00196 parent = cl.parent;
00197 parent_oid = parent ? parent->getOid() : cl.parent_oid;
00198 idximpl = cl.idximpl->clone();
00199
00200 subclass_set = cl.subclass_set;
00201 subclass_count = cl.subclass_count;
00202 subclasses = (Class **)malloc(sizeof(Class *) * subclass_count);
00203 for (int i = 0; i < subclass_count; i++)
00204 subclasses[i] = cl.subclasses[i];
00205
00206 sch = cl.sch;
00207
00208 setClass(cl.getClass());
00209
00210 idr_objsz = cl.idr_objsz;
00211 idr_psize = cl.idr_psize;
00212 idr_vsize = cl.idr_vsize;
00213
00214 idr_inisize = cl.idr_inisize;
00215
00216 attrs_complete = cl.attrs_complete;
00217 extent = (cl.extent ? cl.extent->clone()->asCollection() : 0);
00218 extent_oid = cl.extent_oid;
00219 components = (cl.components ? cl.components->clone()->asCollection() : 0);
00220 comp_oid = cl.comp_oid;
00221 instance_dspid = cl.instance_dspid;
00222 instance_dataspace = cl.instance_dataspace;
00223
00224 Object::freeList(complist, True);
00225
00226
00227 int k;
00228 for (k = 0; k < ComponentCount_C; k++)
00229 Object::freeList(clist[k], False);
00230
00231 complist = Object::copyList(cl.complist, True);
00232
00233 for (k = 0; k < ComponentCount_C; k++)
00234 clist[k] = Object::copyList(cl.clist[k], False);
00235
00236 for (k = 0; k < AttrComponentCount_C; k++)
00237 Object::freeList(attr_clist[k], False);
00238
00239 attr_complist = Object::copyList(cl.attr_complist, True);
00240
00241 for (k = 0; k < AttrComponentCount_C; k++)
00242 attr_clist[k] = Object::copyList(cl.attr_clist[k], False);
00243
00244 type = cl.type;
00245 items_cnt = cl.items_cnt;
00246
00247 items = (Attribute **)malloc(sizeof(Attribute *) * items_cnt);
00248 for (int j = 0; j < items_cnt; j++)
00249 items[j] = cl.items[j]->clone(db);
00250
00251 items_set = cl.items_set;
00252
00253 m_type = cl.m_type;
00254 isFlat = cl.isFlat;
00255 isFlatSet = cl.isFlatSet;
00256 is_root = cl.is_root;
00257 tied_code = STRDUP(cl.tied_code);
00258
00259 partially_loaded = False;
00260 setup_complete = False;
00261
00262
00263
00264
00265
00266 return *this;
00267 }
00268
00269 void Class::setPName(const char *s)
00270 {
00271 free(name);
00272 name = strdup(s);
00273 }
00274
00275 Status
00276 Class::setName(const char *s)
00277 {
00278 if (strcmp(s, name)) {
00279 if ((!strcmp(s, "short") && !strcmp(name, "int16"))
00280 || (!strcmp(s, "int16") && !strcmp(name, "short")))
00281 return Success;
00282
00283 if ((!strcmp(s, "long") && !strcmp(name, "int64"))
00284 || (!strcmp(s, "int64") && !strcmp(name, "long")))
00285 return Success;
00286
00287 if ((!strcmp(s, "int") && !strcmp(name, "int32"))
00288 || (!strcmp(s, "int32") && !strcmp(name, "int")))
00289 return Success;
00290
00291 return Exception::make(IDB_ERROR,
00292 "cannot change name of class '%s' to '%s'",
00293 name, s);
00294 }
00295 return Success;
00296 }
00297
00298 Status
00299 Class::setNameRealize(const char *s)
00300 {
00301 if (strcmp(s, name))
00302 {
00303 setPName(s);
00304 if (db)
00305 db->getSchema()->computeHashTable();
00306 }
00307
00308 return Success;
00309 }
00310
00311 static int
00312 pre(char *name, const char *pre)
00313 {
00314 int len = strlen(pre);
00315 if (!strncmp(name, pre, len))
00316 {
00317 name[len] += 'A' - 'a';
00318 return 1;
00319 }
00320 return 0;
00321 }
00322
00323 const char *
00324 Class::classNameToCName(const char *name)
00325 {
00326 if (!strcmp("agregat_class", name))
00327 return "eyedb::AgregatClass";
00328
00329 if (!strcmp("agregat", name))
00330 return "eyedb::Agregat";
00331
00332 if (!strcmp("array_class", name))
00333 return "eyedb::CollArrayClass";
00334
00335 if (!strcmp("array", name))
00336 return "eyedb::CollArray";
00337
00338 if (!strcmp("bag_class", name))
00339 return "eyedb::CollBagClass";
00340
00341 if (!strcmp("bag", name))
00342 return "eyedb::CollBag";
00343
00344 if (!strcmp("basic_class", name))
00345 return "eyedb::BasicClass";
00346
00347 if (!strcmp("basic", name))
00348 return "eyedb::Basic";
00349
00350 if (!strcmp("class", name))
00351 return "eyedb::Class";
00352
00353 if (!strcmp("collection_class", name))
00354 return "eyedb::CollectionClass";
00355
00356 if (!strcmp("enum_class", name))
00357 return "eyedb::EnumClass";
00358
00359 if (!strcmp("enum", name))
00360 return "eyedb::Enum";
00361
00362 if (!strcmp("instance", name))
00363 return "eyedb::Instance";
00364
00365 if (!strcmp("object", name))
00366 return "eyedb::Object";
00367
00368 if (!strcmp("schema", name))
00369 return "eyedb::Schema";
00370
00371 if (!strcmp("set_class", name))
00372 return "eyedb::CollSetClass";
00373
00374 if (!strcmp("set", name))
00375 return "eyedb::CollSet";
00376
00377 if (!strcmp("struct_class", name))
00378 return "eyedb::StructClass";
00379
00380 if (!strcmp("struct", name))
00381 return "eyedb::Struct";
00382
00383 return name;
00384 #if 1
00385 static char sname[64];
00386
00387 static const char class_suffix[] = "_class";
00388 static const int class_suffix_len = strlen(class_suffix);
00389 static const int prefix_len = strlen(DEF_PREFIX);
00390 static const char coll_prefix[] = "_class";
00391 static const int coll_prefix_len = strlen(coll_prefix);
00392
00393 int len = strlen(name);
00394
00395 if (len > class_suffix_len &&
00396 !strncmp(&name[len-class_suffix_len], "_class", class_suffix_len)) {
00397 char s[64];
00398 strncpy(s, name, len-class_suffix_len);
00399 s[len-class_suffix_len] = 0;
00400 sprintf(sname, "%s%sClass", DEF_PREFIX, s);
00401 }
00402 else
00403 sprintf(sname, "%s%s", DEF_PREFIX, name);
00404
00405 sname[prefix_len] += 'A' - 'a';
00406
00407 if (!strncmp(name, coll_prefix, coll_prefix_len))
00408 sname[coll_prefix_len] += 'A' - 'a';
00409
00410 printf("class name : %s -> %s\n", name, sname);
00411 return sname;
00412 #endif
00413 }
00414
00415
00416 const char *
00417 classNameToJavaName(const char *name)
00418 {
00419 static char sname[64];
00420 static const char class_suffix[] = "_class";
00421 static const int class_suffix_len = strlen(class_suffix);
00422 static const int prefix_len = strlen("org.eyedb.");
00423 static const char coll_prefix[] = "_class";
00424 static const int coll_prefix_len = strlen(coll_prefix);
00425
00426 int len = strlen(name);
00427
00428 if (len > class_suffix_len &&
00429 !strncmp(&name[len-class_suffix_len], "_class", class_suffix_len))
00430 {
00431 char s[64];
00432 strncpy(s, name, len-class_suffix_len);
00433 s[len-class_suffix_len] = 0;
00434 sprintf(sname, "org.eyedb.%sClass", s);
00435 }
00436 else
00437 sprintf(sname, "org.eyedb.%s", name);
00438
00439 sname[prefix_len] += 'A' - 'a';
00440
00441 if (!strncmp(name, coll_prefix, coll_prefix_len))
00442 sname[coll_prefix_len] += 'A' - 'a';
00443
00444 return sname;
00445 }
00446
00447 static std::string
00448 getSCName_2(const char *name, const std::string &prefix,
00449 const char *prefix_sep = 0)
00450 {
00451 #if 1
00452 if (!strcmp(name, "bool"))
00453 return prefix + "Bool";
00454
00455
00456 if (!strcmp(name, "attribute_component"))
00457 return prefix + (prefix_sep ? "syscls." : "") + "AttributeComponent";
00458 if (!strcmp(name, "attribute_component_set"))
00459 return prefix + (prefix_sep ? "syscls." : "") + "AttributeComponentSet";
00460 if (!strcmp(name, "class_component"))
00461 return prefix + (prefix_sep ? "syscls." : "") + "ClassComponent";
00462 if (!strcmp(name, "agregat_class_component"))
00463 return prefix + (prefix_sep ? "syscls." : "") + "AgregatClassComponent";
00464 if (!strcmp(name, "class_variable"))
00465 return prefix + (prefix_sep ? "syscls." : "") + "ClassVariable";
00466 if (!strcmp(name, "index"))
00467 return prefix + (prefix_sep ? "syscls." : "") + "Index";
00468 if (!strcmp(name, "hashindex"))
00469 return prefix + (prefix_sep ? "syscls." : "") + "HashIndex";
00470 if (!strcmp(name, "btreeindex"))
00471 return prefix + (prefix_sep ? "syscls." : "") + "BTreeIndex";
00472 if (!strcmp(name, "index_type"))
00473 return prefix + (prefix_sep ? "syscls." : "") + "IndexType";
00474 if (!strcmp(name, "collection_attribute_implementation"))
00475 return prefix + (prefix_sep ? "syscls." : "") + "CollAttrImpl";
00476 if (!strcmp(name, "executable_lang"))
00477 return prefix + (prefix_sep ? "syscls." : "") + "ExecutableLang";
00478 if (!strcmp(name, "argtype_type"))
00479 return prefix + (prefix_sep ? "syscls." : "") + "ArgType_Type";
00480 if (!strcmp(name, "argtype"))
00481 return prefix + (prefix_sep ? "syscls." : "") + "ArgType";
00482 if (!strcmp(name, "executable_localisation"))
00483 return prefix + (prefix_sep ? "syscls." : "") + "ExecutableLocalisation";
00484 if (!strcmp(name, "executable_type"))
00485 return prefix + (prefix_sep ? "syscls." : "") + "ExecutableType";
00486 if (!strcmp(name, "trigger_type"))
00487 return prefix + (prefix_sep ? "syscls." : "") + "TriggerType";
00488 if (!strcmp(name, "signature"))
00489 return prefix + (prefix_sep ? "syscls." : "") + "Signature";
00490 if (!strcmp(name, "executable"))
00491 return prefix + (prefix_sep ? "syscls." : "") + "Executable";
00492 if (!strcmp(name, "agregat_class_executable"))
00493 return prefix + (prefix_sep ? "syscls." : "") + "AgregatClassExecutable";
00494 if (!strcmp(name, "method"))
00495 return prefix + (prefix_sep ? "syscls." : "") + "Method";
00496 if (!strcmp(name, "fe_method"))
00497 return prefix + (prefix_sep ? "syscls." : "") + "FEMethod";
00498 if (!strcmp(name, "fe_method_C"))
00499 return prefix + (prefix_sep ? "syscls." : "") + "FEMethod_C";
00500 if (!strcmp(name, "be_method"))
00501 return prefix + (prefix_sep ? "syscls." : "") + "BEMethod";
00502 if (!strcmp(name, "be_method_C"))
00503 return prefix + (prefix_sep ? "syscls." : "") + "BEMethod_C";
00504 if (!strcmp(name, "be_method_OQL"))
00505 return prefix + (prefix_sep ? "syscls." : "") + "BEMethod_OQL";
00506 if (!strcmp(name, "trigger"))
00507 return prefix + (prefix_sep ? "syscls." : "") + "Trigger";
00508 if (!strcmp(name, "unique_constraint"))
00509 return prefix + (prefix_sep ? "syscls." : "") + "UniqueConstraint";
00510 if (!strcmp(name, "notnull_constraint"))
00511 return prefix + (prefix_sep ? "syscls." : "") + "NotNullConstraint";
00512 if (!strcmp(name, "cardinality_description"))
00513 return prefix + (prefix_sep ? "syscls." : "") + "CardinalityDescription";
00514 if (!strcmp(name, "cardinality_constraint"))
00515 return prefix + (prefix_sep ? "syscls." : "") + "CardinalityConstraint";
00516 if (!strcmp(name, "cardinality_constraint_test"))
00517 return prefix + (prefix_sep ? "syscls." : "") + "CardinalityConstraint_Test";
00518 if (!strcmp(name, "protection_mode"))
00519 return prefix + (prefix_sep ? "syscls." : "") + "ProtectionMode";
00520 if (!strcmp(name, "protection_user"))
00521 return prefix + (prefix_sep ? "syscls." : "") + "ProtectionUser";
00522 if (!strcmp(name, "protection"))
00523 return prefix + (prefix_sep ? "syscls." : "") + "Protection";
00524 if (!strcmp(name, "unreadable_object"))
00525 return prefix + (prefix_sep ? "syscls." : "") + "UnreadableObject";
00526 if (!strcmp(name, "class_update_type"))
00527 return prefix + (prefix_sep ? "syscls." : "") + "ClassUpdateType";
00528 if (!strcmp(name, "attribute_convert_type"))
00529 return prefix + (prefix_sep ? "syscls." : "") + "AttributeConvertType";
00530 if (!strcmp(name, "class_conversion"))
00531 return prefix + (prefix_sep ? "syscls." : "") + "ClassConversion";
00532
00533
00534 if (!strcmp(name, "image_type"))
00535 return prefix + (prefix_sep ? "utils." : "") + "ImageType";
00536 if (!strcmp(name, "image"))
00537 return prefix + (prefix_sep ? "utils." : "") + "Image";
00538 if (!strcmp(name, "URL"))
00539 return prefix + (prefix_sep ? "utils." : "") + "CURL";
00540
00541
00542 if (!strcmp(name, "w_config"))
00543 return prefix + (prefix_sep ? "utils." : "") + "WConfig";
00544 if (!strcmp(name, "month"))
00545 return prefix + (prefix_sep ? "utils." : "") + "Month";
00546 if (!strcmp(name, "weekday"))
00547 return prefix + (prefix_sep ? "utils." : "") + "Weekday";
00548 if (!strcmp(name, "date"))
00549 return prefix + (prefix_sep ? "utils." : "") + "Date";
00550 if (!strcmp(name, "time"))
00551 return prefix + (prefix_sep ? "utils." : "") + "Time";
00552 if (!strcmp(name, "time_stamp"))
00553 return prefix + (prefix_sep ? "utils." : "") + "TimeStamp";
00554 if (!strcmp(name, "time_interval"))
00555 return prefix + (prefix_sep ? "utils." : "") + "TimeInterval";
00556 if (!strcmp(name, "ostring"))
00557 return prefix + (prefix_sep ? "utils." : "") + "OString";
00558
00559
00560 if (!strcmp(name, "database_open_mode"))
00561 return prefix + (prefix_sep ? "oqlctb." : "") + "OqlCtbDatabaseOpenMode";
00562 if (!strcmp(name, "lock_mode"))
00563 return prefix + (prefix_sep ? "oqlctb." : "") + "OqlCtbLockMode";
00564 if (!strcmp(name, "transaction_mode"))
00565 return prefix + (prefix_sep ? "oqlctb." : "") + "OqlCtbTransactionMode";
00566 if (!strcmp(name, "transaction_lockmode"))
00567 return prefix + (prefix_sep ? "oqlctb." : "") + "OqlCtbTransactionLockMode";
00568 if (!strcmp(name, "recovery_mode"))
00569 return prefix + (prefix_sep ? "oqlctb." : "") + "OqlCtbRecoveryMode";
00570 if (!strcmp(name, "tostring_flags"))
00571 return prefix + (prefix_sep ? "oqlctb." : "") + "OqlCtbToStringFlags";
00572 if (!strcmp(name, "MapType"))
00573 return prefix + (prefix_sep ? "oqlctb." : "") + "OqlCtbMapType";
00574 if (!strcmp(name, "DatType"))
00575 return prefix + (prefix_sep ? "oqlctb." : "") + "OqlCtbDatType";
00576 if (!strcmp(name, "datafile"))
00577 return prefix + (prefix_sep ? "oqlctb." : "") + "OqlCtbDatafile";
00578 if (!strcmp(name, "dataspace"))
00579 return prefix + (prefix_sep ? "oqlctb." : "") + "OqlCtbDataspace";
00580 if (!strcmp(name, "eyedb"))
00581 return prefix + (prefix_sep ? "oqlctb." : "") + "OqlCtbEyedb";
00582 if (!strcmp(name, "connection"))
00583 return prefix + (prefix_sep ? "oqlctb." : "") + "OqlCtbConnection";
00584 if (!strcmp(name, "database"))
00585 return prefix + (prefix_sep ? "oqlctb." : "") + "OqlCtbDatabase";
00586 if (!strcmp(name, "math"))
00587 return prefix + (prefix_sep ? "oqlctb." : "") + "OqlCtbMath";
00588 #else
00589 if (!strcmp(name, "class_component"))
00590 return "ClassComponent";
00591
00592 if (!strcmp(name, "agregat_class_component"))
00593 return "AgregatClassComponent";
00594
00595 if (!strcmp(name, "class_variable"))
00596 return "ClassVariable";
00597
00598 if (!strcmp(name, "attribute_index_mode"))
00599 return "AttributeIndexMode";
00600
00601 if (!strcmp(name, "attribute_component"))
00602 return "AttributeComponent";
00603
00604 if (!strcmp(name, "attribute_component_set"))
00605 return "AttributeComponentSet";
00606
00607 if (!strcmp(name, "index"))
00608 return DEF_PREFIX1 "Index";
00609
00610 if (!strcmp(name, "multi_index"))
00611 return DEF_PREFIX1 "MultiIndex";
00612
00613 if (!strcmp(name, "hashindex"))
00614 return DEF_PREFIX1 "HashIndex";
00615
00616 if (!strcmp(name, "btreeindex"))
00617 return DEF_PREFIX1 "BTreeIndex";
00618
00619 if (!strcmp(name, "executable_lang"))
00620 return DEF_PREFIX1 "ExecutableLang";
00621
00622 if (!strcmp(name, "argtype_type"))
00623 return DEF_PREFIX1 "ArgType_Type";
00624
00625 if (!strcmp(name, "argtype"))
00626 return DEF_PREFIX1 "ArgType";
00627
00628 if (!strcmp(name, "executable_localisation"))
00629 return DEF_PREFIX1 "ExecutableLocalisation";
00630
00631 if (!strcmp(name, "executable_type"))
00632 return DEF_PREFIX1 "ExecutableType";
00633
00634 if (!strcmp(name, "trigger_type"))
00635 return DEF_PREFIX1 "TriggerType";
00636
00637 if (!strcmp(name, "signature"))
00638 return DEF_PREFIX1 "Signature";
00639
00640 if (!strcmp(name, "executable"))
00641 return DEF_PREFIX1 "Executable";
00642
00643 if (!strcmp(name, "agregat_class_executable"))
00644 return "AgregatClassExecutable";
00645
00646 if (!strcmp(name, "method"))
00647 return DEF_PREFIX1 "Method";
00648
00649 if (!strcmp(name, "fe_method"))
00650 return DEF_PREFIX1 "FEMethod";
00651
00652 if (!strcmp(name, "fe_method_C"))
00653 return DEF_PREFIX1 "FEMethod_C";
00654
00655 if (!strcmp(name, "be_method"))
00656 return DEF_PREFIX1 "BEMethod";
00657
00658 if (!strcmp(name, "be_method_C"))
00659 return DEF_PREFIX1 "BEMethod_C";
00660
00661 if (!strcmp(name, "be_method_OQL"))
00662 return DEF_PREFIX1 "BEMethod_OQL";
00663
00664 if (!strcmp(name, "trigger"))
00665 return DEF_PREFIX1 "Trigger";
00666
00667 if (!strcmp(name, "check_constraint"))
00668 return DEF_PREFIX1 "CheckConstraint";
00669
00670 if (!strcmp(name, "unique_constraint"))
00671 return DEF_PREFIX1 "UniqueConstraint";
00672
00673 if (!strcmp(name, "notnull_constraint"))
00674 return DEF_PREFIX1 "NotNullConstraint";
00675
00676 if (!strcmp(name, "cardinality_description"))
00677 return DEF_PREFIX1 "CardinalityDescription";
00678
00679 if (!strcmp(name, "cardinality_constraint"))
00680 return DEF_PREFIX1 "CardinalityConstraint";
00681
00682 if (!strcmp(name, "inverse"))
00683 return DEF_PREFIX1 "Inverse";
00684
00685 if (!strcmp(name, "protection_mode"))
00686 return DEF_PREFIX1 "ProtectionMode";
00687
00688 if (!strcmp(name, "protection_user"))
00689 return DEF_PREFIX1 "ProtectionUser";
00690
00691 if (!strcmp(name, "protection"))
00692 return DEF_PREFIX1 "Protection";
00693
00694 if (!strcmp(name, "unreadable_object"))
00695 return DEF_PREFIX1 "UnreadableObject";
00696
00697 if (!strcmp(name, "class_update_type"))
00698 return "ClassUpdateType";
00699
00700 if (!strcmp(name, "attribute_convert_type"))
00701 return "AttributeConvertType";
00702
00703 if (!strcmp(name, "class_conversion"))
00704 return "ClassConversion";
00705
00706 if (!strcmp(name, XBOOL))
00707 return DEF_PREFIX1 "Bool";
00708
00709 if (!strcmp(name, "database_open_mode"))
00710 return "OqlCtbDatabaseOpenMode";
00711
00712 if (!strcmp(name, "lock_mode"))
00713 return DEF_PREFIX1 "OqlCtbLockMode";
00714
00715 if (!strcmp(name, "transaction_mode"))
00716 return "OqlCtbTransactionMode";
00717
00718 if (!strcmp(name, "transaction_lockmode"))
00719 return "OqlCtbTransactionLockMode";
00720
00721 if (!strcmp(name, "recovery_mode"))
00722 return DEF_PREFIX1 "OqlCtbRecoveryMode";
00723
00724 if (!strcmp(name, "tostring_flags"))
00725 return DEF_PREFIX1 "OqlCtbToStringFlags";
00726
00727 if (!strcmp(name, "eyedb"))
00728 return "OqlCtbeyedb";
00729
00730 if (!strcmp(name, "connection"))
00731 return "OqlCtbConnection";
00732
00733 if (!strcmp(name, "database"))
00734 return "OqlCtbDatabase";
00735
00736 if (!strcmp(name, "math"))
00737 return DEF_PREFIX1 "OqlCtbMath";
00738
00739 if (!strcmp(name, "image_type"))
00740 return DEF_PREFIX1 "ImageType";
00741
00742 if (!strcmp(name, "image"))
00743 return DEF_PREFIX1 "Image";
00744
00745 if (!strcmp(name, "datafile"))
00746 return "OqlCtbDatafile";
00747
00748 oups
00749 if (!strcmp(name, "URL"))
00750 return DEF_PREFIX1 "URL";
00751
00752 if (!strcmp(name, "w_config"))
00753 return DEF_PREFIX1 "WConfig";
00754
00755 if (!strcmp(name, "cstring"))
00756 return DEF_PREFIX1 "CString";
00757
00758 if (!strcmp(name, "month"))
00759 return DEF_PREFIX1 "Month";
00760
00761 if (!strcmp(name, "weekday"))
00762 return DEF_PREFIX1 "Weekday";
00763
00764 if (!strcmp(name, "date"))
00765 return DEF_PREFIX1 "Date";
00766
00767 if (!strcmp(name, "time"))
00768 return DEF_PREFIX1 "Time";
00769
00770 if (!strcmp(name, "time_stamp"))
00771 return DEF_PREFIX1 "TimeStamp";
00772
00773 if (!strcmp(name, "time_interval"))
00774 return DEF_PREFIX1 "TimeInterval";
00775
00776 if (!strcmp(name, "ostring"))
00777 return DEF_PREFIX1 "OString";
00778 #endif
00779
00780 return "";
00781 }
00782
00783 const char *
00784 Class::getSCName(const char *name)
00785 {
00786 std::string str = getSCName_2(name, DEF_PREFIX);
00787 if (str.length() == 0)
00788 return 0;
00789 static char sname[128];
00790 sprintf(sname, "%s", str.c_str());
00791 return sname;
00792
00793 }
00794
00795 const char *getJavaName(const Class *cls)
00796 {
00797 static char *buf = new char[256];
00798 const char *cname = cls->getCName();
00799 if (!strncmp(cname, DEF_PREFIX, strlen(DEF_PREFIX))) {
00800 strcpy(buf, "org.eyedb.");
00801 strcat(buf, &cname[strlen(DEF_PREFIX)]);
00802 }
00803 else
00804 strcpy(buf, cname);
00805 return buf;
00806 }
00807
00808 const char *Class::getCName(Bool skip_nmsp) const
00809 {
00810 for (int i = 0; i < idbLAST_Type; i++)
00811 if (!strcmp(name, class_info[i].name))
00812 return Class::classNameToCName(name);
00813
00814 const char *sCName = getSCName(name);
00815
00816 if (!sCName)
00817 sCName = name;
00818
00819 return sCName;
00820 }
00821
00822 Class *Class::getParent()
00823 {
00824 return parent;
00825 }
00826
00827 Status
00828 Class::getParent(Database *db, Class *&rparent)
00829 {
00830 if (parent) {
00831 rparent = parent;
00832 return Success;
00833 }
00834
00835 if (!parent_oid.isValid()) {
00836 rparent = 0;
00837 return Success;
00838 }
00839
00840 return db->loadObject(parent_oid, (Object *&)rparent);
00841 }
00842
00843 const Class *Class::getParent() const
00844 {
00845 return parent;
00846 }
00847
00848 Schema *Class::getSchema()
00849 {
00850 return sch;
00851 }
00852
00853 const Schema *Class::getSchema() const
00854 {
00855 return sch;
00856 }
00857
00858 Status Class::setValue(Data)
00859 {
00860 return Success;
00861 }
00862
00863 Status Class::getValue(Data*) const
00864 {
00865 return Success;
00866 }
00867
00868 Status
00869 Class::clean(Database *db)
00870 {
00871 for (int i = 0; i < items_cnt; i++) {
00872 Status s = items[i]->clean(db);
00873 if (s) return s;
00874 }
00875
00876 return Success;
00877 }
00878
00879 void Class::free_items(void)
00880 {
00881 for (int i = 0; i < items_cnt; i++)
00882 delete items[i];
00883
00884 free(items);
00885 items = NULL;
00886 }
00887
00888 void Class::pre_release(void)
00889 {
00890 for (int i = 0; i < items_cnt; i++)
00891 items[i]->pre_release();
00892 }
00893
00894 Status
00895 Class::check_items(Attribute **agr, int base_n)
00896 {
00897 char **items_str = (char **)malloc(base_n * sizeof(char *));
00898 int i, j;
00899
00900 int nitems = 0;
00901
00902 for (i = 0; i < base_n; i++, nitems++)
00903 {
00904
00905 items_str[nitems] = (char *)agr[i]->getName();
00906 }
00907
00908 for (i = 0; i < base_n; i++)
00909 for (j = i+1; j < base_n; j++)
00910 if (!strcmp(items_str[i], items_str[j]))
00911 {
00912 char *s = items_str[i];
00913 free(items_str);
00914 return Exception::make(IDB_ATTRIBUTE_ERROR, "duplicate name '%s' in agregat_class '%s' [attribute #%d and #%d]", s, name, i, j);
00915 }
00916
00917 free(items_str);
00918 return Success;
00919 }
00920
00921 Status Class::setAttributes(Attribute **agr, unsigned int base_n)
00922 {
00923 if (items_set)
00924 return Exception::make(IDB_ATTRIBUTE_ERROR, "class '%s' has already its attributes set", name);
00925
00926 Status status;
00927
00928 status = check_items(agr, base_n);
00929
00930 if (status)
00931 return status;
00932
00933 const Class *p;
00934
00935 int native_cnt = items_cnt;
00936 int n = base_n + native_cnt;
00937
00938 if ((p = getParent()) && p->asAgregatClass())
00939 n += p->items_cnt - native_cnt;
00940
00941 items_cnt = n;
00942
00943 Attribute **items_new = (Attribute**)malloc(sizeof(Attribute *) *
00944 items_cnt);
00945
00946 int i;
00947 #if 0
00948 printf("setting attribute for %p %s\n", this, name);
00949 if (!asAgregatClass()) {
00950 printf("copying native attributes\n");
00951 for (i = 0; i < native_cnt; i++)
00952 items_new[i] = new AttrNative((AttrNative *)items[i],
00953 items[i]->getClass(),
00954 items[i]->getClassOwner(),
00955 this, i);
00956 }
00957 else
00958 #endif
00959 for (i = 0; i < native_cnt; i++)
00960 items_new[i] = items[i];
00961
00962 free(items);
00963 items = items_new;
00964
00965 int nitems = native_cnt;
00966
00967 if ((p = getParent()) && p->asAgregatClass())
00968 for (i = native_cnt; i < p->items_cnt; i++, nitems++)
00969 items[nitems] = makeAttribute(p->items[i],
00970 p->items[i]->getClass(),
00971 p->items[i]->getClassOwner(),
00972 this, nitems);
00973
00974 for (i = 0; i < base_n; i++, nitems++)
00975 items[nitems] = makeAttribute(agr[i], agr[i]->getClass(), this, this,
00976 nitems);
00977
00978 items_set = True;
00979 isFlat = isFlatStructure();
00980 isFlatSet = True;
00981 return compile();
00982 }
00983
00984 Status Class::compile()
00985 {
00986 return Success;
00987 }
00988
00989 const Attribute *Class::getAttribute(unsigned int n) const
00990 {
00991 if (n >= 0 && n < items_cnt)
00992 return items[n];
00993 else
00994 return 0;
00995 }
00996
00997 unsigned int Class::getAttributesCount(void) const
00998 {
00999 return items_cnt;
01000 }
01001
01002 static int inline
01003 get_scope(const char *nm)
01004 {
01005 for (int idx = 0; *nm; idx++)
01006 {
01007 char c = *nm++;
01008 if (c == ':' && *nm == ':')
01009 return idx;
01010 }
01011
01012 return -1;
01013 }
01014
01015 const Attribute *Class::getAttribute(const char *nm) const
01016 {
01017 int idx = get_scope(nm);
01018 if (idx >= 0)
01019 {
01020 if (!db || !db->getSchema())
01021 return (const Attribute *)0;
01022
01023 char *clname = (char *)malloc(idx+1);
01024 strncpy(clname, nm, idx);
01025 clname[idx] = 0;
01026
01027 Class *cl = db->getSchema()->getClass(clname);
01028 if (!cl)
01029 {
01030 free(clname);
01031 return (const Attribute *)0;
01032 }
01033
01034 char *fname = strdup(&nm[idx+2]);
01035
01036 const Attribute *item = 0;
01037 int _items_cnt = cl->items_cnt;
01038 Attribute **_items = cl->items;
01039
01040 for (int i = _items_cnt - 1; i >= 0; i--)
01041 if (!strcmp(_items[i]->name, fname) &&
01042 !strcmp(_items[i]->class_owner->name, clname))
01043 {
01044 item = _items[i];
01045 break;
01046 }
01047
01048 free(clname);
01049 free(fname);
01050 return item;
01051 }
01052
01053 for (int i = items_cnt - 1; i >= 0; i--)
01054 if (!strcmp(items[i]->getName(), nm))
01055 return items[i];
01056
01057 return (const Attribute *)0;
01058 }
01059
01060 InstanceInfo class_info[idbLAST_Type];
01061
01062 Class
01063 *Object_Class,
01064
01065 *Class_Class,
01066 *BasicClass_Class,
01067 *EnumClass_Class,
01068 *AgregatClass_Class,
01069 *StructClass_Class,
01070 *UnionClass_Class,
01071
01072 *Instance_Class,
01073 *Basic_Class,
01074 *Enum_Class,
01075 *Agregat_Class,
01076 *Struct_Class,
01077 *Union_Class,
01078 *Schema_Class,
01079 *Bool_Class,
01080
01081 *CollectionClass_Class,
01082 *CollSetClass_Class,
01083 *CollBagClass_Class,
01084 *CollListClass_Class,
01085 *CollArrayClass_Class,
01086
01087 *Collection_Class,
01088 *CollSet_Class,
01089 *CollBag_Class,
01090 *CollList_Class,
01091 *CollArray_Class;
01092
01093 static void inline class_make(const char *name, Class **cls,
01094 int type, Class *parent)
01095 {
01096 class_info[type].name = name;
01097 *cls = new Class(class_info[type].name, parent);
01098 ClassPeer::setMType(*cls, Class::System);
01099 ObjectPeer::setUnrealizable(*cls, True);
01100 }
01101
01102 static void inline class_make(Class *cls, int type)
01103 {
01104 cls->setAttributes((Attribute **)class_info[type].items,
01105 class_info[type].items_cnt);
01106 }
01107
01108 EnumClass *
01109 Class::makeBoolClass()
01110 {
01111 EnumClass *cls = new EnumClass(XBOOL);
01112
01113 EnumItem *en[2];
01114 en[0] = new EnumItem("FALSE", "False_", (unsigned int)0);
01115 en[1] = new EnumItem("TRUE", "True_", (unsigned int)1);
01116
01117 cls->setEnumItems(en, 2);
01118
01119 delete en[0];
01120 delete en[1];
01121
01122 ClassPeer::setMType(cls, Class::System);
01123 return cls;
01124 }
01125
01126 Bool
01127 Class::isBoolClass(const char *name)
01128 {
01129 return IDBBOOL(!strcmp(name, XBOOL));
01130 }
01131
01132 void Class::init(void)
01133 {
01134 class_make("object", &Object_Class, Object_Type,
01135 (Class *)0);
01136 Object_Class->parent = (Class *)0;
01137
01138 class_make("class", &Class_Class, Class_Type,
01139 Object_Class);
01140 Object_Class->setClass(Class_Class);
01141
01142 class_make("basic_class", &BasicClass_Class, BasicClass_Type,
01143 Class_Class);
01144 class_make("enum_class", &EnumClass_Class, EnumClass_Type,
01145 Class_Class);
01146
01147 class_make("agregat_class", &AgregatClass_Class, AgregatClass_Type,
01148 Class_Class);
01149
01150 class_make("struct_class", &StructClass_Class, StructClass_Type,
01151 AgregatClass_Class);
01152
01153 class_make("union_class", &UnionClass_Class, UnionClass_Type,
01154 AgregatClass_Class);
01155
01156 class_make("instance", &Instance_Class, Instance_Type,
01157 Object_Class);
01158
01159 class_make("basic", &Basic_Class, Basic_Type,
01160 Instance_Class);
01161
01162 class_make("enum", &Enum_Class, Enum_Type,
01163 Instance_Class);
01164
01165 class_make("agregat", &Agregat_Class, Agregat_Type,
01166 Instance_Class);
01167
01168 class_make("struct", &Struct_Class, Struct_Type,
01169 Agregat_Class);
01170
01171 class_make("union", &Union_Class, Union_Type,
01172 Agregat_Class);
01173
01174 class_make("schema", &Schema_Class, Schema_Type,
01175 Instance_Class);
01176
01177 class_make("collection_class", &CollectionClass_Class, CollectionClass_Type,
01178 Class_Class);
01179
01180 class_make("bag_class", &CollBagClass_Class, CollBagClass_Type,
01181 CollectionClass_Class);
01182
01183 class_make("set_class", &CollSetClass_Class, CollSetClass_Type,
01184 CollectionClass_Class);
01185
01186 class_make("list_class", &CollListClass_Class, CollListClass_Type,
01187 CollectionClass_Class);
01188
01189 class_make("array_class", &CollArrayClass_Class, CollArrayClass_Type,
01190 CollectionClass_Class);
01191
01192 class_make("collection", &Collection_Class, Collection_Type,
01193 Instance_Class);
01194
01195 class_make("bag", &CollBag_Class, CollBag_Type,
01196 Collection_Class);
01197
01198 class_make("set", &CollSet_Class, CollSet_Type,
01199 Collection_Class);
01200
01201 class_make("list", &CollList_Class, CollList_Type,
01202 Collection_Class);
01203
01204 class_make("array", &CollArray_Class, CollArray_Type,
01205 Collection_Class);
01206
01207 Char_Class = new CharClass();
01208 Byte_Class = new ByteClass();
01209 OidP_Class = new OidClass();
01210 Int16_Class = new Int16Class();
01211 Int32_Class = new Int32Class();
01212 Int64_Class = new Int64Class();
01213 Float_Class = new FloatClass();
01214
01215 Bool_Class = Class::makeBoolClass();
01216 ObjectPeer::setUnrealizable(Bool_Class, True);
01217
01218 AttrNative::init();
01219
01220 class_make(Object_Class, Object_Type);
01221 class_make(Class_Class, Class_Type);
01222 class_make(BasicClass_Class, BasicClass_Type);
01223 class_make(EnumClass_Class, EnumClass_Type);
01224 class_make(AgregatClass_Class, AgregatClass_Type);
01225 class_make(StructClass_Class, StructClass_Type);
01226 class_make(UnionClass_Class, UnionClass_Type);
01227 class_make(Instance_Class, Instance_Type);
01228 class_make(Basic_Class, Basic_Type);
01229 class_make(Enum_Class, Enum_Type);
01230 class_make(Agregat_Class, Agregat_Type);
01231 class_make(Struct_Class, Struct_Type);
01232 class_make(Union_Class, Union_Type);
01233 class_make(Schema_Class, Schema_Type);
01234 class_make(CollectionClass_Class, CollectionClass_Type);
01235 class_make(CollBagClass_Class, CollBagClass_Type);
01236 class_make(CollSetClass_Class, CollSetClass_Type);
01237 class_make(CollListClass_Class, CollListClass_Type);
01238 class_make(CollArrayClass_Class, CollArrayClass_Type);
01239 class_make(Collection_Class, Collection_Type);
01240 class_make(CollBag_Class, CollBag_Type);
01241 class_make(CollSet_Class, CollSet_Type);
01242 class_make(CollList_Class, CollList_Type);
01243 class_make(CollArray_Class, CollArray_Type);
01244 class_make(Char_Class, Basic_Type);
01245 class_make(Byte_Class, Basic_Type);
01246 class_make(OidP_Class, Basic_Type);
01247 class_make(Int16_Class, Basic_Type);
01248 class_make(Int32_Class, Basic_Type);
01249 class_make(Int64_Class, Basic_Type);
01250 class_make(Float_Class, Basic_Type);
01251 }
01252
01253 void Class::_release(void)
01254 {
01255 #if 1
01256 AttrNative::_release();
01257 #endif
01258
01259 Object_Class->release();
01260 Class_Class->release();
01261 BasicClass_Class->release();
01262 EnumClass_Class->release();
01263 AgregatClass_Class->release();
01264 StructClass_Class->release();
01265 UnionClass_Class->release();
01266 Instance_Class->release();
01267 Basic_Class->release();
01268 Enum_Class->release();
01269 Agregat_Class->release();
01270 Struct_Class->release();
01271 Union_Class->release();
01272 Schema_Class->release();
01273 CollectionClass_Class->release();
01274 CollBagClass_Class->release();
01275 CollSetClass_Class->release();
01276 CollListClass_Class->release();
01277 CollArrayClass_Class->release();
01278 Collection_Class->release();
01279 CollBag_Class->release();
01280 CollSet_Class->release();
01281 CollList_Class->release();
01282 CollArray_Class->release();
01283 }
01284
01285
01286
01287 Object * Class::newObj(Database *) const
01288 {
01289 return 0;
01290 }
01291
01292 Object * Class::newObj(Data, Bool) const
01293 {
01294 return 0;
01295 }
01296
01297 Status
01298 Class::trace_comps(FILE *fd, int indent,
01299 unsigned int flags,
01300 const RecMode *rcm) const
01301 {
01302 Status s;
01303 ClassComponent *comp;
01304 LinkedListCursor c(complist);
01305
01306 char *indent_str = make_indent(indent);
01307 Bool nl = False;
01308
01309 while (c.getNext((void *&)comp)) {
01310 IDB_CHECK_INTR();
01311
01312 if ((flags & CompOidTrace) ||
01313 ((flags & SysExecTrace) ||
01314 !comp->asMethod() ||
01315 (comp->asMethod() &&
01316 !(comp->asMethod()->getEx()->getLang() &
01317 SYSTEM_EXEC)))) {
01318 if (!nl) {nl = True; fprintf(fd, "\n");}
01319 fprintf(fd, "%s", indent_str);
01320
01321
01322
01323 s = comp->m_trace(fd, indent, flags&~ContentsFlag, NoRecurs);
01324 if (s) return s;
01325 fprintf(fd, ";\n", indent_str);
01326 }
01327 }
01328
01329 s = const_cast<Class *>(this)->makeAttrCompList();
01330 if (s) return s;
01331
01332 if ((flags & AttrCompTrace) || (flags & AttrCompDetailTrace)) {
01333 if (attr_complist && attr_complist->getCount())
01334 fprintf(fd, "\n");
01335 LinkedListCursor cx(attr_complist);
01336 AttributeComponent *attr_comp;
01337 while (cx.getNext((void *&)attr_comp)) {
01338 IDB_CHECK_INTR();
01339 fprintf(fd, "%s", indent_str);
01340 s = attr_comp->m_trace(fd, indent, flags&~ContentsFlag, NoRecurs);
01341 if (s) return s;
01342 fprintf(fd, ";\n", indent_str);
01343 }
01344 }
01345
01346 delete_indent(indent_str);
01347 return Success;
01348 }
01349
01350 Status Class::trace(FILE *fd, unsigned int flags, const RecMode *rcm) const
01351 {
01352 return trace_realize(fd, INDENT_INC, flags, rcm);
01353 }
01354
01355 Status Class::trace_common(FILE *fd, int indent, unsigned int flags, const RecMode *rcm) const
01356 {
01357
01358
01359
01360
01361
01362 trace_flags(fd, flags);
01363 fprintf(fd, "\n");
01364
01365
01366 if ((flags & NativeTrace) == NativeTrace)
01367 {
01368 unsigned int _items_cnt;
01369 const Attribute **_items = getClass()->getAttributes(_items_cnt);
01370
01371 for (int n = 0; n < _items_cnt; n++)
01372 {
01373 const Attribute *agreg = _items[n];
01374 if (agreg->isNative()) {
01375
01376
01377
01378 Status s = agreg->trace(this, fd, &indent,
01379 (flags&~ContentsFlag)|0x100,
01380 NoRecurs);
01381 if (s) return s;
01382 }
01383 }
01384 }
01385
01386 return Success;
01387 }
01388
01389
01390
01391
01392
01393
01394
01395 #define ATTR_PR()
01396
01397 void
01398 Class::genODL(FILE *fd, Schema *m, Attribute *attr) const
01399 {
01400 Bool attr_list = False;
01401 Index *idx = 0;
01402
01403 Bool strdim = attr->isString();
01404
01405 if (idx) {
01406 ATTR_PR();
01407 idx->s_trace(fd, strdim);
01408 }
01409
01410 const Attribute *inv_item = NULL;
01411
01412 if (attr->inv_spec.oid_cl.isValid() && !attr->inv_spec.item)
01413 inv_item = m->getClass(attr->inv_spec.oid_cl)->getAttributes()[attr->inv_spec.num];
01414 else
01415 inv_item = attr->inv_spec.item;
01416
01417 if (inv_item)
01418 {
01419 ATTR_PR();
01420 fprintf(fd, " inverse %s::%s", inv_item->class_owner->getName(),
01421 inv_item->name);
01422 }
01423
01424 LinkedListCursor c(complist);
01425 ClassComponent *comp;
01426
01427 while (c.getNext((void *&)comp))
01428 if (comp->asCardinalityConstraint()) {
01429 if (!strcmp(comp->asCardinalityConstraint()->getAttrname().c_str(),
01430 attr->getName())) {
01431 ATTR_PR();
01432 CardinalityConstraint *card = comp->asCardinalityConstraint();
01433 fprintf(fd, card->getCardDesc()->getString());
01434 }
01435 }
01436
01437
01438
01439
01440
01441 fprintf(fd, ";\n");
01442 }
01443
01444 int
01445 Class::genODL(FILE *fd, Schema *m) const
01446 {
01447 extern Bool odl_system_class;
01448
01449 Status status = Success;
01450
01451 if (const_cast<Class *>(this)->wholeComplete())
01452 return 0;
01453
01454 if ((isSystem() && !odl_system_class) || isRootClass())
01455 return 0;
01456
01457 if (asUnionClass())
01458 fprintf(fd, "union");
01459 else if (asAgregatClass())
01460 fprintf(fd, "class");
01461 else
01462 fprintf(fd, "native");
01463
01464 fprintf(fd, " %s%s", (isSystem() ? "@" : ""), name);
01465
01466 fprintf(fd, " (implementation <%s, hints = \"%s\">)",
01467 idximpl->getStringType(),
01468 idximpl->getHintsString().c_str());
01469
01470 const Class *p;
01471
01472 if (getParent() && !getParent()->isRootClass() &&
01473 strcmp(getParent()->getName(), "struct"))
01474 fprintf(fd, " extends %s%s", (isSystem() ? "@" : ""),
01475 getParent()->getName());
01476
01477 fprintf(fd, " {\n");
01478
01479 for (int n = 0; n < items_cnt; n++)
01480 {
01481 Attribute *attr = items[n];
01482
01483 if (attr->isNative() || !attr->getClassOwner()->compare(this))
01484 continue;
01485
01486 Bool strdim = attr->isString();
01487 if (strdim)
01488 {
01489 fprintf(fd, "\tattribute string");
01490 if (attr->typmod.ndims == 1 &&
01491 attr->typmod.dims[0] > 0)
01492 fprintf(fd, "<%d>", attr->typmod.dims[0]);
01493 }
01494 else
01495 {
01496 fprintf(fd, "\t%s %s",
01497 (attr->inv_spec.oid_cl.isValid() ? "relationship" :
01498 "attribute"),
01499 attr->cls->getName());
01500
01501 if (attr->isIndirect())
01502 fprintf(fd, "*");
01503 }
01504
01505 if (strcmp(attr->class_owner->getName(), name))
01506 fprintf(fd, " %s::%s", attr->class_owner->getName(), attr->name);
01507 else
01508 fprintf(fd, " %s", attr->name);
01509
01510 if (!strdim)
01511 for (int j = 0; j < attr->typmod.ndims; j++)
01512 {
01513 if (attr->typmod.dims[j] < 0)
01514 fprintf(fd, "[]");
01515 else
01516 fprintf(fd, "[%d]", attr->typmod.dims[j]);
01517 }
01518
01519 genODL(fd, m, attr);
01520 }
01521
01522 ClassComponent *comp;
01523 LinkedListCursor c(complist);
01524
01525 Bool nl = False;
01526
01527 while (c.getNext((void *&)comp))
01528 if ((comp->asMethod() || comp->asTrigger())
01529 && comp->getClassOwner()->compare(this)) {
01530 if (!nl) {nl = True; fprintf(fd, "\n");}
01531 fprintf(fd, "\t");
01532 Status s = comp->m_trace(fd, 0, NoScope|ExecBodyTrace, NoRecurs);
01533 if (s) return 0;
01534 fprintf(fd, ";\n");
01535 }
01536
01537 const_cast<Class *>(this)->makeAttrCompList();
01538
01539 if (attr_complist && attr_complist->getCount())
01540 fprintf(fd, "\n");
01541 AttributeComponent *attr_comp;
01542 LinkedListCursor cx(attr_complist);
01543
01544 while (cx.getNext((void *&)attr_comp)) {
01545 fprintf(fd, "\t");
01546 const Class *xcls;
01547 const Attribute *xattr;
01548 Status s = Attribute::checkAttrPath(m, xcls, xattr, attr_comp->getAttrpath().c_str());
01549 if (s) return 0;
01550 s = attr_comp->m_trace(fd, 0,
01551 (AttrCompDetailTrace
01552 |(xattr->isString() ? IDB_ATTR_IS_STRING : 0)),
01553 NoRecurs);
01554 if (s) return 0;
01555 fprintf(fd, ";\n");
01556 }
01557
01558 fprintf(fd, "};\n");
01559 return 1;
01560 }
01561
01562 Status
01563 Class::wholeComplete()
01564 {
01565 if (removed)
01566 return Exception::make(IDB_ERROR,
01567 "class %s is removed", oid.toString());
01568 Status s;
01569
01570 if (!parent && !attrs_complete)
01571 {
01572 s = Class::attrsComplete();
01573
01574 }
01575
01576 if (parent)
01577 {
01578 s = parent->wholeComplete();
01579 if (s) return s;
01580 }
01581
01582 if (!attrs_complete)
01583 {
01584 s = attrsComplete();
01585
01586 }
01587
01588 if (isPartiallyLoaded() && db && db->isOpened()) {
01589 s = db->getSchema()->manageClassDeferred(this);
01590 if (s) return s;
01591 }
01592
01593 if (!setup_complete)
01594 {
01595 s = setupComplete();
01596 if (s) return s;
01597 }
01598
01599 return Success;
01600 }
01601
01602 static bool debug_trace = getenv("EYEDB_DEBUG_TRACE") ? true : false;
01603
01604 Status Class::trace_realize(FILE *fd, int indent, unsigned int flags, const RecMode *rcm) const
01605 {
01606 IDB_CHECK_INTR();
01607
01608 Status status = Success;
01609 char *indent_str = make_indent(indent);
01610 int n = 0;
01611 Schema *m = (db ? db->getSchema() : NULL);
01612 const Class *p = 0;
01613
01614 if (state & Tracing)
01615 {
01616 fprintf(fd, "%s%s;\n", indent_str, oid.getString());
01617 delete_indent(indent_str);
01618 return Success;
01619 }
01620
01621 char *lastindent_str = make_indent(indent - INDENT_INC);
01622
01623 status = const_cast<Class *>(this)->wholeComplete();
01624 if (status) return status;
01625
01626 const_cast<Class *>(this)->state |= Tracing;
01627
01628 if (asAgregatClass())
01629 fprintf(fd, "%s",
01630 (((Class *)this)->asStructClass() ? "struct" : "union"));
01631 else
01632 fprintf(fd, "class");
01633
01634 fprintf(fd, " %s", name);
01635 fprintf(fd, " {%s}", oid.getString());
01636
01637 if (flags & NativeTrace)
01638 fprintf(fd, " (implementation <%s, hints = \"%s\">)",
01639 idximpl->getStringType(),
01640 idximpl->getHintsString().c_str());
01641
01642 p = getParent();
01643 while (p)
01644 {
01645 fprintf(fd, " : %s", p->getName());
01646 if (!p->getParent() && p->parent_oid.isValid())
01647 ((Class *)p)->attrsComplete();
01648 p = p->getParent();
01649 }
01650
01651 fprintf(fd, " { ");
01652 if (debug_trace) {
01653 fprintf(fd, "// psize %d, vsize %d, inisize %d, objsize %d ",
01654 idr_psize, idr_vsize, idr_inisize, idr_objsz);
01655 }
01656
01657
01658
01659
01660
01661
01662 status = trace_common(fd, indent, flags, rcm);
01663 if (status) goto out;
01664
01665 for (n = 0; n < items_cnt; n++)
01666 {
01667 Attribute *attr = items[n];
01668
01669 if (attr->isNative())
01670 continue;
01671
01672 Bool strdim = attr->isString();
01673 if (strdim)
01674 {
01675 fprintf(fd, "%sattribute string", indent_str);
01676 if (attr->typmod.ndims == 1 &&
01677 attr->typmod.dims[0] > 0)
01678 fprintf(fd, "<%d>", attr->typmod.dims[0]);
01679 }
01680 else
01681 {
01682 fprintf(fd, "%s%s %s", indent_str,
01683 (attr->inv_spec.oid_cl.isValid() ? "relationship" :
01684 "attribute"),
01685 attr->cls->getName());
01686
01687 if (attr->isIndirect())
01688 fprintf(fd, "*");
01689 }
01690
01691 if (strcmp(attr->class_owner->getName(), name))
01692 fprintf(fd, " %s::%s", attr->class_owner->getName(), attr->name);
01693 else
01694 fprintf(fd, " %s", attr->name);
01695
01696 if (!strdim)
01697 for (int j = 0; j < attr->typmod.ndims; j++)
01698 {
01699 if (attr->typmod.dims[j] < 0)
01700 fprintf(fd, "[]");
01701 else
01702 fprintf(fd, "[%d]", attr->typmod.dims[j]);
01703 }
01704
01705 Bool attr_list = False;
01706
01707 const Attribute *inv_item;
01708 if (m && attr->inv_spec.oid_cl.isValid() && !attr->inv_spec.item)
01709 inv_item = m->getClass(attr->inv_spec.oid_cl)->
01710 getAttributes()[attr->inv_spec.num];
01711 else
01712 inv_item = attr->inv_spec.item;
01713
01714 if (inv_item)
01715 {
01716 ATTR_PR();
01717 fprintf(fd, " inverse %s::%s", inv_item->class_owner->getName(),
01718 inv_item->name);
01719 }
01720
01721 if (complist && complist->getCount())
01722 {
01723 LinkedListCursor c(complist);
01724 ClassComponent *comp;
01725
01726 while (c.getNext((void *&)comp))
01727 if (comp->asCardinalityConstraint())
01728 {
01729 if (!strcmp(comp->asCardinalityConstraint()->getAttrname().c_str(),
01730 attr->getName()))
01731 {
01732 ATTR_PR();
01733 CardinalityConstraint *card = comp->asCardinalityConstraint();
01734 fprintf(fd, card->getCardDesc()->getString());
01735 }
01736 }
01737 }
01738
01739
01740
01741
01742
01743
01744 #if 0
01745 if (flags & CompOidTrace)
01746 fprintf(fd, " [attr_comp_set_oid = %s]", attr->getAttrCompSetOid().toString());
01747 #endif
01748
01749 fprintf(fd, ";");
01750 if (debug_trace) {
01751 Offset poff, voff;
01752 Size item_psize, psize, inisize, item_vsize, vsize;
01753
01754 attr->getPersistentIDR(poff, item_psize, psize, inisize);
01755 attr->getVolatileIDR(voff, item_vsize, vsize);
01756 fprintf(fd,
01757 " // poff %d, item_psize %d, psize %d, inisize %d, "
01758 "voff %d, item_vsize %d, vsize %d",
01759 poff, item_psize, psize, inisize, voff, item_vsize,
01760 vsize);
01761
01762 }
01763
01764 fprintf(fd, "\n");
01765 }
01766
01767 status = trace_comps(fd, indent, flags, rcm);
01768
01769 out:
01770 const_cast<Class *>(this)->state &= ~Tracing;
01771 fprintf(fd, "%s};\n", lastindent_str);
01772 delete_indent(indent_str);
01773 delete_indent(lastindent_str);
01774
01775 return status;
01776 }
01777
01778 #define DEF_MAGORDER 100000
01779 unsigned int
01780 Class::getMagorder() const
01781 {
01782 return idximpl->getMagorder(DEF_MAGORDER);
01783 }
01784
01785 void
01786 Class::codeExtentCompOids(Size alloc_size)
01787 {
01788 Offset offset;
01789
01790 Data data = idr->getIDR();
01791 if (extent_oid.isValid()) {
01792 offset = IDB_CLASS_EXTENT;
01793
01794 oid_code (&data, &offset, &alloc_size, extent_oid.getOid());
01795 }
01796
01797 if (comp_oid.isValid()) {
01798 offset = IDB_CLASS_COMPONENTS;
01799
01800 oid_code (&data, &offset, &alloc_size, comp_oid.getOid());
01801 }
01802 }
01803
01804 Status
01805 class_name_code(DbHandle *dbh, short dspid, Data *idr,
01806 Offset *offset,
01807 Size *alloc_size, const char *name)
01808 {
01809 int len = strlen(name);
01810 if (len >= IDB_CLASS_NAME_LEN)
01811 {
01812 eyedbsm::Oid data_oid;
01813 RPCStatus rpc_status = dataCreate(dbh, dspid, len+1,
01814 (Data)name, &data_oid);
01815 if (rpc_status) return StatusMake(rpc_status);
01816 char c = IDB_NAME_OUT_PLACE;
01817 char_code(idr, offset, alloc_size, &c);
01818 oid_code (idr, offset, alloc_size, &data_oid);
01819 bound_string_code (idr, offset, alloc_size,
01820 IDB_CLASS_NAME_PAD, 0);
01821 return Success;
01822 }
01823
01824 char c = IDB_NAME_IN_PLACE;
01825 char_code(idr, offset, alloc_size, &c);
01826 bound_string_code(idr, offset, alloc_size, IDB_CLASS_NAME_LEN,
01827 name);
01828 return Success;
01829 }
01830
01831 Status
01832 class_name_decode(DbHandle *dbh, Data idr, Offset *offset,
01833 char **name)
01834 {
01835 char c;
01836 char_decode(idr, offset, &c);
01837
01838 if (c == IDB_NAME_OUT_PLACE)
01839 {
01840 eyedbsm::Oid data_oid;
01841 RPCStatus rpc_status;
01842
01843 oid_decode (idr, offset, &data_oid);
01844 unsigned int size;
01845 rpc_status = dataSizeGet(dbh, &data_oid, &size);
01846 if (rpc_status) return StatusMake(rpc_status);
01847 *name = (char *)malloc(size);
01848 rpc_status = dataRead(dbh, 0, size, (Data)*name, 0, &data_oid);
01849 if (rpc_status) return StatusMake(rpc_status);
01850 bound_string_decode (idr, offset, IDB_CLASS_NAME_PAD, 0);
01851 return Success;
01852 }
01853
01854 assert(c == IDB_NAME_IN_PLACE);
01855 char *s;
01856 bound_string_decode(idr, offset, IDB_CLASS_NAME_LEN, &s);
01857 *name = strdup(s);
01858 return Success;
01859 }
01860
01861 Status Class::create()
01862 {
01863 if (oid.isValid())
01864 return Exception::make(IDB_OBJECT_ALREADY_CREATED, "creating class '%s'", name);
01865
01866 IDB_CHECK_WRITE(db);
01867
01868 RPCStatus rpc_status;
01869 Size alloc_size;
01870 Offset offset;
01871 ObjectHeader hdr;
01872 Status s;
01873
01874 attrsComplete();
01875
01876 idr->setIDR((Size)0);
01877 alloc_size = 0;
01878 Data data = 0;
01879
01880 offset = IDB_CLASS_IMPL_TYPE;
01881 s = IndexImpl::code(data, offset, alloc_size, idximpl);
01882 if (s) return s;
01883
01884 offset = IDB_CLASS_MTYPE;
01885 eyedblib::int32 mt = m_type;
01886 int32_code (&data, &offset, &alloc_size, &mt);
01887
01888 offset = IDB_CLASS_DSPID;
01889 eyedblib::int16 dspid = get_instdspid();
01890 int16_code (&data, &offset, &alloc_size, &dspid);
01891
01892 offset = IDB_CLASS_HEAD_SIZE;
01893
01894 s = class_name_code(db->getDbHandle(), getDataspaceID(), &data, &offset,
01895 &alloc_size, name);
01896 if (s) return s;
01897
01898 int idr_sz = offset;
01899 idr->setIDR(idr_sz, data);
01900 headerCode(_Class_Type, idr_sz);
01901
01902 codeExtentCompOids(alloc_size);
01903
01904 rpc_status = objectCreate(db->getDbHandle(), getDataspaceID(), data,
01905 oid.getOid());
01906
01907 if (rpc_status == RPCSuccess)
01908 {
01909 gbx_locked = gbxTrue;
01910
01911 ClassComponent *comp;
01912 LinkedListCursor c(complist);
01913
01914 while (c.getNext((void *&)comp)) {
01915 if (!comp->getClassOwner())
01916 comp->setClassOwner(this);
01917 comp->setClassOwnerOid(comp->getClassOwner()->getOid());
01918
01919
01920
01921
01922
01923
01924 s = comp->realize();
01925 if (s)
01926 return s;
01927 }
01928 }
01929
01930 return StatusMake(rpc_status);
01931 }
01932
01933 void
01934 Class::setExtentCompOid(const Oid &_extent_oid, const Oid &_comp_oid)
01935 {
01936 extent_oid = _extent_oid;
01937 comp_oid = _comp_oid;
01938
01939
01940
01941
01942 }
01943
01944 Status Class::update()
01945 {
01946 Status status;
01947
01948 return Success;
01949 }
01950
01951 Status
01952 Class::createComps()
01953 {
01954 if (!mustCreateComps)
01955 return Success;
01956
01957
01958 gbx_locked = gbxTrue;
01959
01960 ClassComponent *cls_comp;
01961 LinkedListCursor c(complist);
01962
01963 Status s;
01964 while (c.getNext((void *&)cls_comp)) {
01965 cls_comp->setDatabase(db);
01966
01967 if (!cls_comp->getClassOwner())
01968 cls_comp->setClassOwner(this);
01969 cls_comp->setClassOwnerOid(cls_comp->getClassOwner()->getOid());
01970
01971
01972
01973
01974
01975
01976
01977
01978 s = cls_comp->realize();
01979 if (s) return s;
01980 }
01981
01982 cls_comp = 0;
01983
01984 s = makeAttrCompList();
01985 if (s) return s;
01986
01987 LinkedListCursor cx(attr_complist);
01988 AttributeComponent *attr_comp;
01989 while (cx.getNext((void *&)attr_comp)) {
01990 if (attr_comp->getOid().isValid())
01991 continue;
01992 attr_comp->setDatabase(db);
01993 if (!attr_comp->getClassOwner())
01994 attr_comp->setClassOwner(this);
01995 attr_comp->setClassOwnerOid(attr_comp->getClassOwner()->getOid());
01996
01997
01998
01999
02000
02001
02002
02003
02004 s = attr_comp->realize();
02005 if (s) return s;
02006 }
02007
02008 mustCreateComps = False;
02009
02010
02011 #if 1
02012 touch();
02013 return update();
02014 #else
02015 return Success;
02016 #endif
02017 }
02018
02019 Status Class::postCreate()
02020 {
02021
02022 mustCreateComps = True;
02023 return Success;
02024 }
02025
02026 Status Class::realize(const RecMode*rcm)
02027 {
02028 return Object::realize(rcm);
02029 }
02030
02031 Status Class::remove(const RecMode*)
02032 {
02033 return Exception::make(IDB_ERROR, "cannot delete the class '%s' this way",
02034 name);
02035 }
02036
02037 Size
02038 Class::getIDRObjectSize(Size *psize, Size *vsize,
02039 Size *isize) const
02040 {
02041 if (psize)
02042 *psize = idr_psize;
02043
02044 if (vsize)
02045 *vsize = idr_vsize;
02046
02047 if (isize)
02048 *isize = idr_inisize;
02049
02050 return idr_objsz;
02051 }
02052
02053 Status Class::attrsComplete()
02054 {
02055 if (db && parent_oid.isValid()) {
02056 parent = db->getSchema()->getClass(parent_oid, True);
02057 if (!parent)
02058 return Exception::make(IDB_ERROR, "cannot complete parent '%s'",
02059 parent_oid.getString());
02060 }
02061
02062 return Success;
02063 }
02064
02065
02066
02067
02068
02069
02070
02071
02072
02073
02074
02075
02076
02077
02078
02079
02080
02081
02082
02083
02084
02085
02086
02087
02088
02089
02090
02091
02092
02093
02094
02095
02096
02097
02098
02099
02100
02101
02102
02103
02104
02105
02106
02107
02108
02109
02110
02111
02112
02113
02114
02115
02116
02117
02118
02119
02120
02121
02122
02123
02124
02125
02126
02127
02128
02129
02130
02131 Status
02132 classMake(Database *db, const Oid *oid, Object **o,
02133 const RecMode *rcm, const ObjectHeader *hdr,
02134 Data idr, LockMode lockmode, const Class*)
02135 {
02136 RPCStatus rpc_status;
02137 Data temp;
02138
02139 if (!idr)
02140 {
02141 temp = (unsigned char *)malloc(hdr->size);
02142 object_header_code_head(temp, hdr);
02143 rpc_status = objectRead(db->getDbHandle(), temp, 0, 0, oid->getOid(),
02144 0, lockmode, 0);
02145 }
02146 else
02147 {
02148 temp = idr;
02149 rpc_status = RPCSuccess;
02150 }
02151
02152 if (rpc_status == RPCSuccess)
02153 {
02154 Offset offset;
02155 char *s;
02156
02157 IndexImpl *idximpl;
02158 offset = IDB_CLASS_IMPL_TYPE;
02159 Status status = IndexImpl::decode(db, temp, offset, idximpl);
02160 if (status) return status;
02161
02162 eyedblib::int32 mt;
02163 offset = IDB_CLASS_MTYPE;
02164 int32_decode (temp, &offset, &mt);
02165
02166 eyedblib::int16 dspid;
02167 offset = IDB_CLASS_DSPID;
02168 int16_decode (temp, &offset, &dspid);
02169
02170 offset = IDB_CLASS_HEAD_SIZE;
02171
02172 status = class_name_decode(db->getDbHandle(), temp, &offset, &s);
02173 if (status) return status;
02174
02175 *o = db->getSchema()->getClass(s);
02176 (*o)->incrRefCount();
02177 free(s); s = 0;
02178 (*o)->asClass()->setExtentImplementation(idximpl, True);
02179 if (idximpl)
02180 idximpl->release();
02181 (*o)->asClass()->setInstanceDspid(dspid);
02182
02183 ClassPeer::setMType((Class *)*o, (Class::MType)mt);
02184
02185 status = ClassPeer::makeColls(db, (Class *)*o, temp);
02186
02187 if (status != Success)
02188 {
02189 if (!idr)
02190 free(temp);
02191 return status;
02192 }
02193 }
02194
02195 if (!idr)
02196 {
02197 if (!rpc_status)
02198 ObjectPeer::setIDR(*o, temp, hdr->size);
02199 }
02200 return StatusMake(rpc_status);
02201 }
02202
02203 Status Class::setDatabase(Database *mdb)
02204 {
02205 Status status = Object::setDatabase(mdb);
02206
02207 if (status == Success && parent)
02208 {
02209 const char *_name = parent->getName();
02210 parent = mdb->getSchema()->getClass(_name);
02211
02212 if (!parent)
02213 {
02214
02215 return Exception::make(IDB_SETDATABASE_ERROR, "class '%s': parent class '%s' not found in schema\n", name, _name);
02216 }
02217 }
02218 return status;
02219 }
02220
02221 Status
02222 Class::triggerManage(Trigger *trig)
02223 {
02224 if (trig->getEx()->getLang() == OQL_LANG)
02225 {
02226 Status s = trig->runtimeInit();
02227 if (db->getOpenFlag() & _DBAdmin)
02228 return Success;
02229 return s;
02230 }
02231
02232 if (!db->trig_dl)
02233 {
02234 const char *schname = db->getSchema()->getName();
02235 char file[64];
02236 sprintf(file, "%smthbe", schname);
02237 db->trig_dl = Executable::_dlopen(file);
02238 if (!db->trig_dl)
02239 {
02240 if (db->getOpenFlag() & _DBAdmin)
02241 return Success;
02242 std::string s = std::string("class `") + name +
02243 "' : trigger(s) check failed : " + dlerror();
02244 return Exception::make(IDB_EXECUTABLE_ERROR, s);
02245 }
02246 }
02247
02248 trig->csym = (Status (*)(TriggerType, Database *,
02249 const Oid &, Object *))
02250 dlsym(db->trig_dl, trig->getCSym());
02251
02252 if (!trig->csym)
02253 {
02254 if (db->getOpenFlag() & _DBAdmin)
02255 return Success;
02256 return Exception::make(IDB_EXECUTABLE_ERROR,
02257 "trigger '%s' not found for database '%s'",
02258 trig->getCSym(), db->getName());
02259 }
02260
02261 return Success;
02262 }
02263
02264 Status
02265 Class::getComp(const char *mcname, ClassComponent *&rcomp) const
02266 {
02267 rcomp = 0;
02268 const LinkedList *list = getCompList();
02269 if (!list)
02270 return Success;
02271
02272 ClassComponent *comp;
02273 LinkedListCursor c(complist);
02274 while (c.getNext((void *&)comp))
02275 {
02276 Bool isnull;
02277 Status s = Success;
02278 const char *compname = comp->getName(&isnull, &s).c_str();
02279 if (s) return s;
02280 if (!strcmp(compname, mcname))
02281 {
02282 rcomp = comp;
02283 return Success;
02284 }
02285 }
02286
02287 return Success;
02288 }
02289
02290 static ClassComponent **
02291 make_array(const LinkedList *list, unsigned int &cnt,
02292 ClassComponent **prev = 0,
02293 unsigned int prev_cnt = 0)
02294 {
02295 cnt = (list ? list->getCount() : 0) + prev_cnt;
02296
02297 if (!cnt)
02298 return NULL;
02299
02300 ClassComponent **comp_arr = (ClassComponent **)
02301 malloc(sizeof(ClassComponent *) * cnt);
02302
02303 int i;
02304 for (i = 0; i < prev_cnt; i++)
02305 comp_arr[i] = prev[i];
02306
02307 if (prev)
02308 delete[] prev;
02309
02310 if (!list)
02311 return comp_arr;
02312
02313 LinkedListCursor c(list);
02314 for (i = prev_cnt; c.getNext((void *&)comp_arr[i]); i++)
02315 ;
02316
02317 return comp_arr;
02318 }
02319
02320 Method **
02321 Class::getMethods(unsigned int& cnt)
02322 {
02323 return (Method **)make_array(getCompList(Method_C), cnt);
02324 }
02325
02326 const Method **
02327 Class::getMethods(unsigned int& cnt) const
02328 {
02329 return (const Method **)make_array(getCompList(Method_C), cnt);
02330 }
02331
02332 Status
02333 Class::getMethod(const char *_name, Method *&rmth, Signature *sign)
02334 {
02335 rmth = 0;
02336 const LinkedList *list = getCompList(Method_C);
02337 if (!list)
02338 return Success;
02339
02340 LinkedListCursor c(list);
02341 Method *mth;
02342 while (c.getNext((void *&)mth))
02343 {
02344 Bool isnull;
02345 Status s = Success;
02346 const char *exname = mth->getEx()->getExname(&isnull, &s).c_str();
02347 if (s) return s;
02348 if (!strcmp(exname, _name) &&
02349 (!sign || (*sign == *mth->getEx()->getSign())))
02350 {
02351 rmth = mth;
02352 return Success;
02353 }
02354 }
02355
02356 return Success;
02357 }
02358
02359 Status
02360 Class::getMethod(const char *_name, const Method *&mth,
02361 Signature *sign) const
02362 {
02363 return const_cast<Class *>(this)->getMethod
02364 (_name, (const Method *&)mth, sign);
02365 }
02366
02367 Status
02368 Class::getMethodCount(const char *_name, unsigned int &cnt) const
02369 {
02370 cnt = 0;
02371 const LinkedList *list = getCompList(Method_C);
02372 if (!list)
02373 return Success;
02374
02375 LinkedListCursor c(list);
02376 Method *mth;
02377 while (c.getNext((void *&)mth))
02378 {
02379 Status s = Success;
02380 Bool isnull;
02381 const char *mthname = mth->getEx()->getExname(&isnull, &s).c_str();
02382 if (s) return s;
02383
02384 if (!strcmp(mth->getEx()->getExname().c_str(), _name))
02385 cnt++;
02386 }
02387
02388 return Success;
02389 }
02390
02391 unsigned int
02392 Class::getMethodCount() const
02393 {
02394 const LinkedList *list = getCompList(Method_C);
02395 return (list ? list->getCount() : 0);
02396 }
02397
02398 Trigger **
02399 Class::getTriggers(unsigned int& cnt)
02400 {
02401 ClassComponent **arr;
02402 arr = make_array(getCompList(TrigCreateBefore_C), cnt);
02403 arr = make_array(getCompList(TrigCreateAfter_C), cnt, arr, cnt);
02404 arr = make_array(getCompList(TrigUpdateBefore_C), cnt, arr, cnt);
02405 arr = make_array(getCompList(TrigUpdateAfter_C), cnt, arr, cnt);
02406 arr = make_array(getCompList(TrigLoadBefore_C), cnt, arr, cnt);
02407 arr = make_array(getCompList(TrigLoadAfter_C), cnt, arr, cnt);
02408 arr = make_array(getCompList(TrigRemoveBefore_C), cnt, arr, cnt);
02409 return (Trigger **)
02410 make_array(getCompList(TrigRemoveAfter_C), cnt, arr, cnt);
02411 }
02412
02413 const Trigger **
02414 Class::getTriggers(unsigned int& cnt) const
02415 {
02416 return (const Trigger **)((Class *)this)->getTriggers(cnt);
02417 }
02418
02419
02420 ClassVariable **
02421 Class::getVariables(unsigned int& cnt)
02422 {
02423 return (ClassVariable **)make_array(getCompList(Variable_C), cnt);
02424 }
02425
02426 const ClassVariable **
02427 Class::getVariables(unsigned int& cnt) const
02428 {
02429 return (const ClassVariable **)make_array(getCompList(Variable_C), cnt);
02430 }
02431
02432 Status
02433 Class::getVariable(const char *_name, ClassVariable *&rvar)
02434 {
02435 rvar = 0;
02436 const LinkedList *list = getCompList(Variable_C);
02437 if (!list)
02438 return Success;
02439
02440 LinkedListCursor c(list);
02441 ClassVariable *var;
02442 while (c.getNext((void *&)var))
02443 {
02444 Status s = Success;
02445 Bool isnull;
02446 const char *vname = var->getVname(&isnull, &s).c_str();
02447 if (s) return s;
02448 if (!strcmp(vname, _name))
02449 {
02450 rvar = var;
02451 return Success;
02452 }
02453 }
02454
02455 return Success;
02456 }
02457
02458 Status
02459 Class::getVariable(const char *_name, const ClassVariable *&rvar) const
02460 {
02461 return const_cast<Class *>(this)->getVariable(_name, (const ClassVariable *&)rvar);
02462 }
02463
02464 Status Class::add(unsigned int w, AttributeComponent *comp)
02465 {
02466 Status s = makeAttrCompList();
02467 if (s) return s;
02468
02469 if (attr_complist->getPos(comp) < 0) {
02470 if (!attr_clist[w])
02471 attr_clist[w] = new LinkedList();
02472
02473 attr_clist[w]->insertObject(comp);
02474 attr_complist->insertObject(comp);
02475 }
02476
02477 return Success;
02478 }
02479
02480 Status Class::add(unsigned int w, ClassComponent *comp, Bool incrRefCount)
02481 {
02482 Status status;
02483
02484 if (db && ((db->isBackEnd() && !db->isLocal()) ||
02485 (!db->isBackEnd() && db->isLocal())) && comp->asTrigger())
02486 {
02487 status = triggerManage(comp->asTrigger());
02488 if (status)
02489 return status;
02490 }
02491
02492 status = comp->make(this);
02493
02494 if (status)
02495 return status;
02496
02497 if (complist->getPos(comp) < 0)
02498 {
02499 if (!clist[w])
02500 clist[w] = new LinkedList();
02501
02502 LinkedList *list = clist[w];
02503
02504 list->insertObject(comp);
02505 complist->insertObject(comp);
02506 if (incrRefCount)
02507 ObjectPeer::incrRefCount(comp);
02508
02509 }
02510 else if (!clist[w])
02511 abort();
02512
02513 touch();
02514 return Success;
02515 }
02516
02517 Status Class::suppress(unsigned int w, ClassComponent *comp)
02518 {
02519 if (clist[w])
02520 clist[w]->deleteObject(comp);
02521 complist->deleteObject(comp);
02522
02523 #if 0
02524 ObjectPeer::decrRefCount(comp);
02525 #endif
02526
02527 assert(comp->getRefCount());
02528 touch();
02529 return Success;
02530 }
02531
02532 Status Class::suppress(unsigned int w, AttributeComponent *comp)
02533 {
02534 if (attr_clist[w])
02535 attr_clist[w]->deleteObject(comp);
02536 if (attr_complist)
02537 attr_complist->deleteObject(comp);
02538 return Success;
02539 }
02540
02541 Status Class::scanComponents()
02542 {
02543
02544
02545
02546
02547
02548 Status status;
02549 Bool found;
02550 Iterator *q;
02551 ClassComponent *comp;
02552
02553 Bool is_trs = True;
02554
02555 if (!is_trs)
02556 db->transactionBegin();
02557
02558 status = getComponents(components);
02559 if (status) return status;
02560
02561 q = new Iterator(components);
02562
02563 if (q->getStatus())
02564 {
02565 status = q->getStatus();
02566 goto out;
02567 }
02568
02569 for (;;)
02570 {
02571 comp = 0;
02572 if (status = q->scanNext(&found, (Object **)&comp))
02573 goto out;
02574
02575 if (!found)
02576 break;
02577
02578
02579
02580 if (status = add(comp->getInd(), comp))
02581 goto out;
02582 }
02583
02584 out:
02585 delete q;
02586 if (!is_trs)
02587 db->transactionCommit();
02588 return status;
02589 }
02590
02591 Status Class::setup(Bool force, Bool rescan)
02592 {
02593
02594
02595
02596 if ((state & Realizing))
02597 return Success;
02598
02599 if (setup_complete && !rescan)
02600 return Success;
02601
02602 state |= Realizing;
02603
02604 Status s = getComponents(components);
02605 if (s)
02606 {
02607 state &= ~Realizing;
02608 return s;
02609 }
02610
02611 #ifdef COMP_TRACE
02612 printf("Class::setup(this=%p, name=%s, oid=%s, components=%p, count=%d, db=%p, idr=%p, loaded=%d)\n",
02613 this, name, oid.toString(), components,
02614 (components && components != (Collection*)1 ?
02615 components->getCount() : 0), db, idr->getIDR(), partially_loaded);
02616 #endif
02617
02618
02619
02620 if (!db || !components || components == (Collection *)1 ||
02621 (!components->getCount() && !force))
02622 {
02623 state &= ~Realizing;
02624 return Success;
02625 }
02626
02627
02628 Object::freeList(complist, True);
02629
02630 complist = new LinkedList();
02631
02632 for (int i = 0; i < ComponentCount_C; i++)
02633 delete clist[i];
02634
02635 memset(clist, 0, sizeof(LinkedList *) * ComponentCount_C);
02636
02637
02638
02639 makeAttrCompList();
02640
02641
02642
02643
02644
02645
02646
02647
02648
02649 s = scanComponents();
02650 if (s)
02651 {
02652 state &= ~Realizing;
02653 return s;
02654 }
02655
02656 s = setupInherit();
02657 if (s)
02658 {
02659 state &= ~Realizing;
02660 return s;
02661 }
02662
02663 setup_complete = True;
02664 state &= ~Realizing;
02665 return Success;
02666 }
02667
02668 static Bool
02669 comp_find(LinkedList *list, const Oid &oid)
02670 {
02671 if (!list)
02672 return False;
02673
02674 LinkedListCursor c(list);
02675 ClassComponent *comp;
02676
02677 while (c.getNext((void *&)comp))
02678 if (comp->isInherit() && comp->getOid().compare(oid))
02679 return True;
02680
02681 return False;
02682 }
02683
02684 Status Class::setupInherit()
02685 {
02686 Class *cl;
02687 Status status;
02688
02689 assert(!isRemoved());
02690
02691 #ifdef COMP_TRACE
02692 printf("Class::setupInherit(this=%p, name=%s)\n", this, name);
02693 #endif
02694 cl = parent;
02695
02696
02697 if (cl && !cl->setup_complete && !cl->getOid().isValid() && db)
02698 cl = db->getSchema()->getClass(cl->getName());
02699
02700 while (cl)
02701 {
02702 assert(!cl->isRemoved());
02703
02704 ClassComponent *comp;
02705
02706 #ifdef COMP_TRACE
02707 printf("\tClass::setupInherit(this=%p, name=%s, parent=%p, %s, db=%p, comp=%d, oid=%s)\n",
02708 this, name, cl, cl->getName(), cl->getDatabase(), cl->setup_complete, cl->getOid().toString());
02709 #endif
02710
02711
02712 if (!cl->setup_complete && (status = cl->setup(False)))
02713 return status;
02714
02715 LinkedList *list = cl->complist;
02716 LinkedListCursor c(list);
02717 while (c.getNext((void *&)comp))
02718 {
02719 #ifdef COMP_TRACE
02720 printf("\tcomp=%s, inherit=%d oids=%s %s\n",
02721 comp->getName(), comp->isInherit(),
02722 comp->getClassOwner()->getOid().toString(), cl->getOid().toString());
02723 #endif
02724
02725
02726 if (comp->isInherit() &&
02727 comp->getClassOwner()->getOid() == cl->getOid())
02728 {
02729 int ind = comp->getInd();
02730 #ifdef COMP_TRACE
02731 printf("\tcompclass=%p %p [%s %s]\n",
02732 comp->getClassOwner(),
02733 cl,
02734 comp->getClassOwner()->getOid().toString(),
02735 cl->getOid().toString());
02736 #endif
02737 if (!comp_find(clist[ind], comp->getOid()))
02738 {
02739 #ifdef COMP_TRACE
02740 printf("\tcomponent not find: we addit.\n");
02741 #endif
02742 if ((status = add(ind, comp)) || (status = comp->make(this)))
02743 return status;
02744 }
02745 }
02746
02747 }
02748 cl = cl->parent;
02749 }
02750
02751 return Success;
02752 }
02753
02754 Status
02755 Class::setupComplete()
02756 {
02757 #ifdef COMP_TRACE
02758 printf("Class::setupComplete(this=%p, name=%s, %d)\n",
02759 this, name, setup_complete);
02760 #endif
02761
02762 if (setup_complete)
02763 return Success;
02764
02765 Status s;
02766
02767 s = setup(True);
02768 if (s) return s;
02769
02770 return Success;
02771 }
02772
02773 const LinkedList *
02774 Class::getCompList() const
02775 {
02776 if (!setup_complete && db && db->isOpened())
02777 {
02778
02779 Status s = const_cast<Class *>(this)->wholeComplete();
02780 if (s) throw *s;
02781 }
02782 return complist;
02783 }
02784
02785 const LinkedList *
02786 Class::getCompList(CompIdx idx) const
02787 {
02788 if (!setup_complete)
02789 {
02790
02791 Status s = const_cast<Class *>(this)->wholeComplete();
02792 if (s) throw *s;
02793 }
02794 return clist[idx];
02795 }
02796
02797 Status
02798 Class::getAttrCompList(AttrCompIdx idx, const LinkedList *&list)
02799 {
02800 Status s = makeAttrCompList();
02801 if (s) return s;
02802 list = attr_clist[idx];
02803 return Success;
02804 }
02805
02806 void
02807 Class::unmakeAttrCompList()
02808 {
02809 for (int i = 0; i < AttrComponentCount_C; i++) {
02810 delete attr_clist[i];
02811 attr_clist[i] = new LinkedList();
02812 }
02813
02814 delete attr_complist;
02815 attr_complist = 0;
02816 }
02817
02818 Status
02819 Class::makeAttrCompList()
02820 {
02821 if (attr_complist)
02822 return Success;
02823
02824 attr_complist = new LinkedList();
02825 for (int i = 0; i < items_cnt; i++) {
02826 Status s = items[i]->getAttrComponents(db, this, *attr_complist);
02827 if (s) return s;
02828 }
02829
02830 for (int k = 0; k < AttrComponentCount_C; k++) {
02831 delete attr_clist[k];
02832 attr_clist[k] = new LinkedList();
02833 }
02834
02835 LinkedListCursor c(attr_complist);
02836 AttributeComponent *comp;
02837 while (c.getNext((void *&)comp)) {
02838 attr_clist[comp->getInd()]->insertObject(comp);
02839 }
02840
02841 return Success;
02842 }
02843
02844 Status
02845 Class::getAttrCompList(const LinkedList *&list)
02846 {
02847 Status s = makeAttrCompList();
02848 if (s) return s;
02849
02850 list = attr_complist;
02851 return Success;
02852 }
02853
02854 Status
02855 Class::getAttrComp(const char *mcname, AttributeComponent *&rcomp) const
02856 {
02857 Status s = const_cast<Class *>(this)->makeAttrCompList();
02858 if (s) return s;
02859
02860 LinkedListCursor c(attr_complist);
02861 AttributeComponent *comp;
02862 while (c.getNext((void *&)comp)) {
02863
02864 if (!comp->isRemoved() && !strcmp(comp->getName().c_str(), mcname)) {
02865 rcomp = comp;
02866 return Success;
02867 }
02868 }
02869
02870 rcomp = 0;
02871 return Success;
02872 }
02873
02874 Status
02875 Class::setInSubClasses(ClassComponent *comp, Bool added)
02876 {
02877 int ind = comp->getInd();
02878 const LinkedList *_class = db->getSchema()->getClassList();
02879 Status status;
02880 Class *cl;
02881
02882 LinkedListCursor c(_class);
02883
02884 while (c.getNext((void *&)cl))
02885 if ((!added && !compare(cl)) || (added && cl != this))
02886 {
02887 Bool found;
02888 status = isSuperClassOf(cl, &found);
02889 if (status)
02890 return status;
02891
02892 if (found)
02893 {
02894 if (added)
02895 status = cl->add(ind, comp);
02896 else
02897 status = cl->suppress(ind, comp);
02898
02899 if (status)
02900 return status;
02901 }
02902 }
02903
02904 return Success;
02905 }
02906
02907 Status Class::add(ClassComponent *comp, Bool incrRefCount)
02908 {
02909 Status status;
02910
02911
02912
02913 status = getComponents(components);
02914 if (status) return status;
02915
02916 if (!components)
02917 return Exception::make(IDB_ERROR, "internal error in class::add: "
02918 "no component collection in class %s %s",
02919 name, oid.toString());
02920
02921 if (status = components->insert(comp))
02922 return status;
02923
02924 status = add(comp->getInd(), comp, incrRefCount);
02925 if (status)
02926 return status;
02927
02928 if (comp->isInherit())
02929 {
02930 if (status = setInSubClasses(comp, True))
02931 return status;
02932 }
02933
02934
02935 if (status = components->realize(NoRecurs))
02936 {
02937 #if 1
02938 return status;
02939 #else
02940 suppress(comp->getInd(), comp);
02941 return components->suppress(comp);
02942 #endif
02943 }
02944
02945 return Success;
02946 }
02947
02948 Status Class::suppress(ClassComponent *comp)
02949 {
02950 if (isRemoved())
02951 return Exception::make(IDB_ERROR, "internal error in class::suppress: "
02952 "class %s is removed",
02953 oid.toString());
02954
02955 Status status;
02956
02957 status = getComponents(components);
02958 if (status) return status;
02959
02960 if (!components)
02961 return Exception::make(IDB_ERROR, "internal error in class::suppress: "
02962 "no component collection in class %s %s",
02963 name, oid.toString());
02964
02965 if (status = components->suppress(comp))
02966 return status;
02967
02968 suppress(comp->getInd(), comp);
02969
02970 if (comp->isInherit() && (status = setInSubClasses(comp, False)))
02971 return components->insert(comp);
02972
02973
02974 if (status = components->realize(NoRecurs))
02975 {
02976 #if 1
02977 return status;
02978 #else
02979
02980 status = add(comp->getInd(), comp);
02981 if (status)
02982 return status;
02983
02984 return components->insert(comp);
02985 #endif
02986 }
02987
02988 #if 0
02989
02990 RPCstatus rpc_status = compSet(db->getDbHandle(), False,
02991 &oid.getOid(),
02992 &comp->getOid().getOid());
02993 if (rpc_status)
02994 {
02995 comp->supp(this);
02996 components->suppress(comp);
02997 components->realize(NoRecurs);
02998 }
02999 return Exception::make(rpc_status);
03000 #else
03001 return Success;
03002 #endif
03003 }
03004
03005 IndexImpl *
03006 Class::getExtentImplementation() const
03007 {
03008 return idximpl->clone();
03009 }
03010
03011 Status
03012 Class::setExtentImplementation(const IndexImpl *_idximpl)
03013 {
03014 if (oid.isValid())
03015 return Exception::make(IDB_ERROR, "class %s: extent implementation "
03016 "cannot be set when class is created",
03017 name);
03018 setExtentImplementation(_idximpl, True);
03019 return Success;
03020 }
03021
03022 void
03023 Class::setExtentImplementation(const IndexImpl *_idximpl, Bool)
03024 {
03025 if (!idximpl || !idximpl->compare(_idximpl)) {
03026 if (idximpl)
03027 idximpl->release();
03028
03029
03030
03031
03032 idximpl = _idximpl->clone();
03033 }
03034 }
03035
03036 #define GBX_NEW
03037 Status
03038 Class::getExtent(Collection*& _extent, Bool reload) const
03039 {
03040 if (reload && extent_oid.isValid()) {
03041
03042 if (extent) {
03043 extent->release();
03044 ((Class *)this)->extent = 0;
03045 }
03046 Status status = db->reloadObject(&extent_oid, (Object **)&extent);
03047 if (status) return status;
03048 }
03049 else if (!extent && db && idr->getIDR()) {
03050 _extent = 0;
03051
03052 Status status =
03053 ClassPeer::makeColl(db, (Collection **)&extent, idr->getIDR(),
03054 IDB_CLASS_EXTENT);
03055 if (status) return status;
03056
03057 if (!extent) {
03058 (void)dataRead(db->getDbHandle(), IDB_CLASS_EXTENT,
03059 sizeof(Oid), idr->getIDR() + IDB_CLASS_EXTENT,
03060 0, oid.getOid());
03061
03062 status = ClassPeer::makeColl(db, (Collection **)&extent,
03063 idr->getIDR(), IDB_CLASS_EXTENT);
03064 if (status) return status;
03065 }
03066 }
03067
03068
03069 #ifdef GBX_NEW
03070 if (extent)
03071 extent->keep();
03072 #endif
03073 if (extent)
03074 const_cast<Class *>(this)->extent_oid = extent->getOid();
03075
03076 _extent = extent;
03077 return Success;
03078 }
03079
03080 Status
03081 Class::getComponents(Collection *&_components, Bool reload) const
03082 {
03083 #ifdef COMP_TRACE
03084 printf("Class::getComponents(%p, name=%s, components=%p, reload=%p)\n",
03085 this, name, components, reload);
03086 #endif
03087
03088 if (reload && comp_oid.isValid()) {
03089
03090 if (components) {
03091 components->release();
03092 ((Class *)this)->components = 0;
03093 }
03094 Status status = db->reloadObject(&comp_oid, (Object **)&components);
03095 if (status) return status;
03096 }
03097 else if (!components && db && idr->getIDR()) {
03098 _components = 0;
03099
03100 Status status =
03101 ClassPeer::makeColl(db, (Collection **)&components, idr->getIDR(),
03102 IDB_CLASS_COMPONENTS);
03103 if (status) return status;
03104
03105 if (!components) {
03106 (void)dataRead(db->getDbHandle(), IDB_CLASS_COMPONENTS,
03107 sizeof(Oid), idr->getIDR() + IDB_CLASS_COMPONENTS,
03108 0, oid.getOid());
03109
03110 status = ClassPeer::makeColl(db, (Collection **)&components,
03111 idr->getIDR(), IDB_CLASS_COMPONENTS);
03112 if (status) return status;
03113 }
03114 }
03115
03116
03117 #ifdef GBX_NEW
03118 if (components)
03119 components->keep();
03120 #endif
03121
03122 if (components)
03123 const_cast<Class *>(this)->comp_oid = components->getOid();
03124
03125 _components = components;
03126 return Success;
03127 }
03128
03129 void
03130 Class::setTiedCode(char *_tied_code)
03131 {
03132 tied_code = _tied_code;
03133 }
03134
03135 char *
03136 Class::getTiedCode()
03137 {
03138 return tied_code;
03139 }
03140
03141 void Class::garbage()
03142 {
03143 free_items();
03144 free(name);
03145 free(aliasname);
03146 free(canonname);
03147 free(tied_code);
03148 free(subclasses);
03149
03150 for (int i = 0; i < ComponentCount_C; i++) {
03151 delete clist[i];
03152 clist[i] = 0;
03153 }
03154
03155 for (int i = 0; i < AttrComponentCount_C; i++) {
03156 delete attr_clist[i];
03157 attr_clist[i] = 0;
03158 }
03159
03160 if (complist)
03161 {
03162
03163
03164
03165 if (!db || !db->getSchema()->dont_delete_comps) {
03166 Object::freeList(complist, True);
03167
03168 }
03169 else {
03170 delete complist;
03171 delete attr_complist;
03172 }
03173
03174 complist = 0;
03175 attr_complist = 0;
03176 }
03177
03178 if (extent)
03179 extent->release();
03180 if (components)
03181 components->release();
03182 if (idximpl)
03183 idximpl->release();
03184 Object::garbage();
03185 }
03186
03187 Class::~Class()
03188 {
03189 garbageRealize();
03190 }
03191
03192 Bool Class::isClass(Database *db, const Oid& cl_oid,
03193 const Oid& oid)
03194 {
03195 if (cl_oid.compare(oid))
03196 return True;
03197
03198 Class *cl = db->getSchema()->getClass(oid);
03199
03200 while (cl)
03201 {
03202 if (cl->getOid().compare(cl_oid))
03203 return True;
03204 cl = cl->getParent();
03205 }
03206
03207 return False;
03208 }
03209
03210 Bool
03211 Class::compare_l(const Class *cl) const
03212 {
03213 if (strcmp(getAliasName(), cl->getAliasName()))
03214 return False;
03215
03216 if (type != cl->get_Type())
03217 return False;
03218
03219 return True;
03220 }
03221
03222 Bool
03223 Class::compare(const Class *cl) const
03224 {
03225
03226
03227
03228
03229
03230
03231
03232
03233
03234
03235
03236
03237
03238
03239
03240 return compare(cl, True, True, True, True);
03241 }
03242
03243 Bool Class::compare(const Class *cl,
03244 Bool compClassOwner,
03245 Bool compNum,
03246 Bool compName,
03247 Bool inDepth) const
03248 {
03249 if (this == cl)
03250 return True;
03251
03252 if (strcmp(getAliasName(), cl->getAliasName()))
03253 return False;
03254
03255 if (type != cl->get_Type())
03256 return False;
03257
03258 if (state & Realizing)
03259 return True;
03260
03261 ((Class *)this)->state |= Realizing;
03262 Bool r = compare_perform(cl, compClassOwner, compNum, compName, inDepth);
03263 ((Class *)this)->state &= ~Realizing;
03264 return r;
03265 }
03266
03267
03268
03269
03270
03271
03272
03273
03274
03275 Bool Class::compare_perform(const Class *cl,
03276 Bool compClassOwner,
03277 Bool compNum,
03278 Bool compName,
03279 Bool inDepth) const
03280 {
03281 return True;
03282 }
03283
03284 Bool
03285 Class::isFlatStructure() const
03286 {
03287 if (isFlatSet)
03288 return isFlat;
03289
03290 for (int i = 0; i < items_cnt; i++)
03291 if (!items[i]->isNative() && !items[i]->isFlat())
03292 return False;
03293
03294 return True;
03295 }
03296
03297 static int
03298 sort_down_to_top_cmp(const void *xcls1, const void *xcls2)
03299 {
03300 Bool is;
03301 (*(Class **)xcls1)->isSuperClassOf(*(Class **)xcls2, &is);
03302 if (is) return 1;
03303 (*(Class **)xcls2)->isSuperClassOf(*(Class **)xcls1, &is);
03304 if (is) return -1;
03305 return 0;
03306 }
03307
03308 static int
03309 sort_top_to_down_cmp(const void *xcls1, const void *xcls2)
03310 {
03311 Bool is;
03312 (*(Class **)xcls2)->isSuperClassOf(*(Class **)xcls1, &is);
03313 if (is) return 1;
03314 (*(Class **)xcls1)->isSuperClassOf(*(Class **)xcls2, &is);
03315 if (is) return -1;
03316 return 0;
03317 }
03318
03319 Status
03320 Class::sort(Bool _sort_down_to_top) const
03321 {
03322 ((Class *)this)->sort_down_to_top = _sort_down_to_top;
03323 ::qsort(subclasses, subclass_count, sizeof(Class *),
03324 (sort_down_to_top ? sort_down_to_top_cmp :
03325 sort_top_to_down_cmp));
03326 return Success;
03327 }
03328
03329 Status
03330 Class::getSubClasses(Class **&_subclasses, unsigned int &_subclass_count,
03331 Bool _sort_down_to_top) const
03332 {
03333 Schema *msch = 0;
03334 _subclass_count = 0;
03335 if (!sch)
03336 {
03337 if (!db)
03338 return Exception::make(IDB_ERROR, "class '%s': cannot get "
03339 "subclasses when database is not set", name);
03340 msch = db->getSchema();
03341 }
03342 else
03343 msch = sch;
03344
03345 if (subclass_set)
03346 {
03347 if (_sort_down_to_top == sort_down_to_top)
03348 {
03349 _subclass_count = subclass_count;
03350 _subclasses = subclasses;
03351 return Success;
03352 }
03353
03354 return sort(_sort_down_to_top);
03355 }
03356
03357 Class *this_mutable = (Class *)this;
03358 LinkedListCursor c(msch->getClassList());
03359 Class *xcls;
03360 this_mutable->subclasses = 0;
03361 this_mutable->subclass_count = 0;
03362
03363 while (c.getNext((void *&)xcls))
03364 {
03365 Bool is;
03366 Status status;
03367
03368 if (status = isSuperClassOf(xcls, &is))
03369 return status;
03370
03371 if (is)
03372 {
03373 this_mutable->subclasses = (Class **)
03374 realloc(subclasses, (subclass_count+1)*sizeof(Class *));
03375
03376 this_mutable->subclasses[this_mutable->subclass_count++] = xcls;
03377 }
03378 }
03379
03380 this_mutable->subclass_set = True;
03381 _subclasses = subclasses;
03382 _subclass_count = subclass_count;
03383
03384 return sort(_sort_down_to_top);
03385 }
03386
03387 Status
03388 Class::isSubClassOf(const Class *cl, Bool *is) const
03389 {
03390 return cl->isSuperClassOf(this, is);
03391 }
03392
03393 Status
03394 Class::isSuperClassOf(const Class *cl, Bool *is) const
03395 {
03396 *is = False;
03397
03398 while (cl)
03399 {
03400 if (compare(cl))
03401 {
03402 *is = True;
03403 break;
03404 }
03405 cl = cl->parent;
03406 }
03407
03408 return Success;
03409 }
03410
03411 static const char *NO_CLASS_CHECK = getenv("NO_CLASS_CHECK");
03412
03413 Status
03414 Class::isObjectOfClass(const Object *o, Bool *is, Bool issub) const
03415 {
03416 if (NO_CLASS_CHECK) {
03417 *is = True;
03418 return Success;
03419 }
03420
03421
03422 #if 0
03423 if (o->getOid().getDbid() != db->getDbid()) {
03424 *is = True;
03425 printf("multi database object %s : class '%s'\n",
03426 o->getOid().getString(), o->getClass()->getName());
03427 return Success;
03428 }
03429 #endif
03430
03431 if (UnreadableObject::isUnreadableObject(o)) {
03432 *is = True;
03433 return Success;
03434 }
03435
03436 if (issub) {
03437 return isSuperClassOf(o->getClass(), is);
03438 }
03439
03440 *is = compare(o->getClass());
03441 return Success;
03442 }
03443
03444 Status
03445 Class::isObjectOfClass(const Oid *o_oid, Bool *is, Bool issub,
03446 Class **po_class) const
03447 {
03448 if (NO_CLASS_CHECK) {
03449 *is = True;
03450 return Success;
03451 }
03452
03453 Status status;
03454 Class *o_class;
03455
03456 *is = False;
03457
03458 if (!db)
03459 return Exception::make(IDB_IS_OBJECT_OF_CLASS_ERROR, "database is not opened for class '%s', cannot performed isObjectOfClass(%s)", name, o_oid->getString());
03460
03461 status = db->getObjectClass(*o_oid, o_class);
03462
03463 if (UnreadableObject::isUnreadableObject(o_class)) {
03464 *is = True;
03465 return Success;
03466 }
03467
03468 if (status)
03469 return status;
03470 if (po_class)
03471 *po_class = o_class;
03472
03473 if (issub)
03474 return isSuperClassOf(o_class, is);
03475
03476 *is = compare(o_class);
03477 return Success;
03478 }
03479
03480 Status Class::generateCode_Java(Schema *,
03481 const char *,
03482 const GenCodeHints &,
03483 FILE *)
03484 {
03485 return Success;
03486 }
03487
03488 void Class::newObjRealize(Object *) const
03489 {
03490 }
03491
03492 Status Class::checkInverse(const Schema *) const
03493 {
03494 return Success;
03495 }
03496
03497 Status
03498 Class::makeClass(Database *db, const Oid &oid, int hdr_type,
03499 const char *name, Bool& newClass, Class *&cl)
03500 {
03501 #ifdef OPTOPEN_TRACE
03502 printf("begin Class::makeClass(%s, %s)\n", oid.getString(), name);
03503 #endif
03504 newClass = True;
03505 Status s;
03506 switch(hdr_type)
03507 {
03508 case _StructClass_Type:
03509 cl = new StructClass(oid, name);
03510 break;
03511
03512 case _Class_Type:
03513 cl = db->getSchema()->getClass(name);
03514 newClass = False;
03515 cl->setPartiallyLoaded(True);
03516 break;
03517
03518 case _BasicClass_Type:
03519 cl = db->getSchema()->getClass(name);
03520 newClass = False;
03521 cl->setPartiallyLoaded(True);
03522 break;
03523
03524 case _CollSetClass_Type:
03525 if (!strcmp(name, "set<object*>"))
03526 {
03527 cl = new CollSetClass(db->getSchema()->getClass("object"),
03528 True);
03529 cl->setPartiallyLoaded(True);
03530 }
03531 else
03532 cl = new CollSetClass(oid, name);
03533 break;
03534
03535 case _CollBagClass_Type:
03536 cl = new CollBagClass(oid, name);
03537 break;
03538
03539 case _CollArrayClass_Type:
03540 cl = new CollArrayClass(oid, name);
03541 break;
03542
03543 case _CollListClass_Type:
03544 cl = new CollListClass(oid, name);
03545 break;
03546
03547 case _EnumClass_Type:
03548 if (Class::isBoolClass(name)) {
03549 cl = db->getSchema()->getClass(name);
03550 newClass = False;
03551 cl->setPartiallyLoaded(True);
03552 }
03553 else
03554 cl = new EnumClass(oid, name);
03555 break;
03556
03557 case _UnionClass_Type:
03558
03559 break;
03560
03561 default:
03562 assert(0);
03563 }
03564
03565 if (!cl->getOid().isValid())
03566 ObjectPeer::setOid(cl, oid);
03567 #ifdef OPTOPEN_TRACE
03568 printf("Class::makeClass(%s, %s, class=%p)\n", oid.getString(),
03569 cl->getName(), cl);
03570 #endif
03571
03572 return Success;
03573 }
03574
03575 Status
03576 Class::getDefaultInstanceDataspace(const Dataspace *&_instance_dataspace) const
03577 {
03578 if (instance_dataspace) {
03579 _instance_dataspace = instance_dataspace;
03580 return Success;
03581 }
03582
03583 if (instance_dspid == Dataspace::DefaultDspid) {
03584 _instance_dataspace = 0;
03585 return Success;
03586 }
03587
03588 Status s = db->getDataspace(instance_dspid, _instance_dataspace);
03589 if (s) return s;
03590 const_cast<Class *>(this)->instance_dataspace = _instance_dataspace;
03591 return Success;
03592 }
03593
03594 Status
03595 Class::setDefaultInstanceDataspace(const Dataspace *_instance_dataspace)
03596 {
03597 if (!instance_dataspace && instance_dspid != Dataspace::DefaultDspid) {
03598 Status s = db->getDataspace(instance_dspid, instance_dataspace);
03599 if (s) return s;
03600 }
03601
03602 if (instance_dataspace != _instance_dataspace) {
03603 instance_dataspace = _instance_dataspace;
03604 instance_dspid = (instance_dataspace ? instance_dataspace->getId() : Dataspace::DefaultDspid);
03605 touch();
03606 return store();
03607 }
03608
03609 return Success;
03610 }
03611
03612 Status
03613 Class::getInstanceLocations(ObjectLocationArray &locarr, Bool inclsub)
03614 {
03615 RPCStatus rpc_status =
03616 getInstanceClassLocations(db->getDbHandle(), oid.getOid(), inclsub,
03617 (Data *)&locarr);
03618 return StatusMake(rpc_status);
03619 }
03620
03621 Status
03622 Class::moveInstances(const Dataspace *dataspace, Bool inclsub)
03623 {
03624 RPCStatus rpc_status =
03625 moveInstanceClass(db->getDbHandle(), oid.getOid(), inclsub,
03626 dataspace->getId());
03627 return StatusMake(rpc_status);
03628 }
03629
03630 void
03631 Class::setInstanceDspid(short _instance_dspid)
03632 {
03633 instance_dspid = _instance_dspid;
03634 }
03635
03636 Status
03637 Class::manageDataspace(short dspid)
03638 {
03639 if (dspid == Dataspace::DefaultDspid)
03640 return Success;
03641 const Dataspace *dataspace;
03642 Status s;
03643 s = db->getDataspace(dspid, dataspace);
03644 if (s) return s;
03645 return setDefaultInstanceDataspace(dataspace);
03646 }
03647
03648 short
03649 Class::get_instdspid() const
03650 {
03651 return (instance_dataspace ? instance_dataspace->getId() : Dataspace::DefaultDspid);
03652 }
03653
03654
03655
03656
03657
03658 void
03659 Class::decode(void * hdata,
03660 const void * xdata,
03661 Size incsize,
03662 unsigned int nb) const
03663 {
03664 #ifdef E_XDR_TRACE
03665 cout << "Class::decode " << name << endl;
03666 #endif
03667 CHECK_INCSIZE("decode", incsize, idr_psize - IDB_OBJ_HEAD_SIZE);
03668
03669 memcpy(hdata, xdata, nb * incsize);
03670 }
03671
03672 void
03673 Class::encode(void * xdata,
03674 const void * hdata,
03675 Size incsize,
03676 unsigned int nb) const
03677 {
03678 #ifdef E_XDR_TRACE
03679 cout << "Class::encode " << name << endl;
03680 #endif
03681 CHECK_INCSIZE("encode", incsize, idr_psize - IDB_OBJ_HEAD_SIZE);
03682
03683 memcpy(xdata, hdata, nb * incsize);
03684 }
03685
03686
03687 int
03688 Class::cmp(const void * xdata,
03689 const void * hdata,
03690 Size incsize,
03691 unsigned int nb) const
03692 {
03693 #ifdef E_XDR_TRACE
03694 cout << "Class::cmp " << name;
03695 #endif
03696 CHECK_INCSIZE("cmp", incsize, idr_psize - IDB_OBJ_HEAD_SIZE);
03697
03698 int r = memcmp(xdata, hdata, nb * incsize);
03699 #ifdef E_XDR_TRACE
03700 cout << " -> " << r << endl;
03701 #endif
03702 return r;
03703 }
03704
03705 }
03706