Class.cc

00001 /* 
00002    EyeDB Object Database Management System
00003    Copyright (C) 1994-2008 SYSRA
00004    
00005    EyeDB is free software; you can redistribute it and/or
00006    modify it under the terms of the GNU Lesser General Public
00007    License as published by the Free Software Foundation; either
00008    version 2.1 of the License, or (at your option) any later version.
00009    
00010    EyeDB is distributed in the hope that it will be useful,
00011    but WITHOUT ANY WARRANTY; without even the implied warranty of
00012    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00013    Lesser General Public License for more details.
00014    
00015    You should have received a copy of the GNU Lesser General Public
00016    License along with this library; if not, write to the Free Software
00017    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA 
00018 */
00019 
00020 /*
00021    Author: Eric Viara <viara@sysra.com>
00022 */
00023 
00024 
00025 #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 //#define COMP_TRACE
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     //assert(!cl->setup_complete);
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       if (!list)
00171       return;
00172 
00173       ClassComponent *comp;
00174       LinkedListCursor c(list);
00175   
00176       while (c.getNext((void *&)comp))
00177       if (comp->getClassOwner()->getOid() == cl->getOid())
00178       comp->release();
00179   
00180       delete list;
00181     */
00182     assert(0);
00183   }
00184 
00185   Class& Class::operator=(const Class &cl)
00186   {
00187     assert(cl.getRefCount());
00188     assert(getRefCount());
00189     //garbage(); => will be done in Object::operator=()
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     //freeCompList(complist, this);
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       printf("contruct #2 %s %p [%d]\n",
00264       name, this, setup_complete);
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   // added 18/05/05
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     // syscls
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     // utils
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     //if (!strcmp(name, "CURL"))
00541     //return prefix + (prefix_sep ? "utils." : "") + "CURL";
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     // oqlctb
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))) { // WARNING : does not work if DEF_PREFIX is ""
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         // 13/2/2: ce test ne semble plus d'actualité
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   // tries to make class not abstract
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         // EV 23/05/01: changed rcm to norecurs
01321         // because of a fatal and non resolved recursion error
01322         //Status s = comp->m_trace(fd, indent, flags, rcm);
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       if (flags & NativeTrace)
01359       fprintf(fd, "ObjectSize = %d ", idr_objsz);
01360     */
01361 
01362     trace_flags(fd, flags);
01363     fprintf(fd, "\n");
01364 
01365     //  trace_comps(fd, indent, flags, rcm);
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               // EV 23/05/01: changed rcm to norecurs
01376               // because of a fatal and non resolved recursion error
01377               //agreg->trace(this, fd, &indent, flags|0x100, rcm);
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     #define ATTR_PR() \
01391     if (!attr_list) {attr_list = True; fprintf(fd, " (");} \
01392     else {fprintf(fd, ", ");}
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       if (attr_list)
01439       fprintf(fd, ")");
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         //if (s) return s;
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         //if (s) return s;
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"); // was 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       if (flags & NativeTrace)
01659       fprintf(fd, "object sizes = %dp, %dt bytes / ", idr_objsz, idr_psize);
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           if (attr_list)
01741           fprintf(fd, ")");
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       //printf("codeExtentOid -> %s\n", extent_oid.toString());
01794       oid_code (&data, &offset, &alloc_size, extent_oid.getOid());
01795     }
01796 
01797     if (comp_oid.isValid()) {
01798       offset = IDB_CLASS_COMPONENTS;
01799       //printf("codeCompOid -> %s\n", comp_oid.toString());
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             printf("%s: realizing component %p %s %s class:create %s\n",
01920             name, comp, comp->getName(),
01921             comp->getOid().toString(),
01922             comp->getClassOwner()->getOid().toString());
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       printf("class %s setting extent_oid to %s %s\n", name, extent_oid.toString(),
01940       comp_oid.toString());
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     //printf("Class::createComps(%p, %s)\n", this, name);
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         printf("%s: realizing class component %s %s class:createComps %s\n",
01973         name, cls_comp->getName(),
01974         cls_comp->getOid().toString(),
01975         cls_comp->getClassOwner()->getOid().toString());
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         printf("%s: realizing attribute component %s %s class:createComps %s\n",
01999         name, attr_comp->getName(),
02000         attr_comp->getOid().toString(),
02001         attr_comp->getClassOwner()->getOid().toString());
02002       */
02003 
02004       s = attr_comp->realize();
02005       if (s) return s;
02006     }
02007 
02008     mustCreateComps = False;
02009     // added the 5/02/02 to force report of attr_comp_set_oid in IDB_classWrite
02010     // in case of a class creation after the creation of attribute components
02011 #if 1
02012     touch();
02013     return update();
02014 #else
02015     return Success;
02016 #endif
02017   }
02018 
02019   Status Class::postCreate()
02020   {
02021     //return createComps();
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     static Class *
02067   getClassFromName(const char *name)
02068   {
02069     // must improve this function !! hash code
02070     if (!strcmp("object", name))
02071       return Object_Class;
02072 
02073     if (!strcmp("class", name))
02074       return Class_Class;
02075     if (!strcmp("basic_class", name))
02076       return BasicClass_Class;
02077     if (!strcmp("enum_class", name))
02078       return EnumClass_Class;
02079     if (!strcmp("agregat_class", name))
02080       return AgregatClass_Class;
02081     if (!strcmp("struct_class", name))
02082       return StructClass_Class;
02083     if (!strcmp("union_class", name))
02084       return UnionClass_Class;
02085 
02086     if (!strcmp("instance", name))
02087       return Instance_Class;
02088     if (!strcmp("basic", name))
02089       return Basic_Class;
02090     if (!strcmp("enum", name))
02091       return Enum_Class;
02092     if (!strcmp("agregat", name))
02093       return Agregat_Class;
02094     if (!strcmp("struct", name))
02095       return Struct_Class;
02096     if (!strcmp("union", name))
02097       return Union_Class;
02098 
02099     if (!strcmp("schema", name))
02100       return Schema_Class;
02101 
02102     if (!strcmp(XBOOL, name))
02103       return Bool_Class;
02104 
02105     if (!strcmp("collection_class", name))
02106       return CollectionClass_Class;
02107     if (!strcmp("set_class", name))
02108       return CollSetClass_Class;
02109     if (!strcmp("bag_class", name))
02110       return CollBagClass_Class;
02111     if (!strcmp("list_class", name))
02112       return CollListClass_Class;
02113     if (!strcmp("array_class", name))
02114       return CollArrayClass_Class;
02115 
02116     if (!strcmp("collection", name))
02117       return Collection_Class;
02118     if (!strcmp("set", name))
02119       return CollSet_Class;
02120     if (!strcmp("bag", name))
02121       return CollBag_Class;
02122     if (!strcmp("list", name))
02123       return CollList_Class;
02124     if (!strcmp("array", name))
02125       return CollArray_Class;
02126 
02127     return 0;
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(); // added the 17/10/00
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             //assert(0);
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); // prevent deleting
02508         //printf("Class::add(this=%p, %s, %p, %s)\n", this, name, comp, comp->getName());
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     // added the 21/05/01
02523 #if 0
02524     ObjectPeer::decrRefCount(comp);
02525 #endif
02526     //printf("Class::suppress(%p => %d)\n", comp, comp->getRefCount());
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       printf("scanComponents %s, components %x %d %s\n", name, components,
02545       components->getCount(), components->getOid().toString());
02546     */
02547 
02548     Status status;
02549     Bool found;
02550     Iterator *q;
02551     ClassComponent *comp;
02552     //  Bool is_trs = db->isInTransaction();
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         //      if (status = add(comp->getInd(), comp, False))
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     // MIND: must add an argument: Bool force, to force
02594     // the scan even if components->getCount() == 0
02595 
02596     if ((state & Realizing))
02597       return Success;
02598 
02599     if (setup_complete && !rescan)
02600       return Success;
02601 
02602     state |= Realizing; // to avoid recursion
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     //  if (!db || !components || (!components->getCount() && !force))
02619     // HACK ADDED THE 21/11/00
02620     if (!db || !components || components == (Collection *)1 ||
02621         (!components->getCount() && !force))
02622       {
02623         state &= ~Realizing;
02624         return Success;
02625       }
02626 
02627     //freeCompList(complist, this);
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     //Object::freeList(attr_complist, True);
02638 
02639     makeAttrCompList();
02640     /*
02641       attr_complist = new LinkedList();
02642 
02643       for (int i = 0; i < AttrComponentCount_C; i++)
02644       delete attr_clist[i];
02645 
02646       memset(attr_clist, 0, sizeof(LinkedList *) * AttrComponentCount_C);
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     // added the 5/01/00
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         // added the 5/01/00
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             //oid comparison optimisation added on 11/10/00
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         //Status s = const_cast<Class *>(this)->setupComplete();
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         //Status s = const_cast<Class *>(this)->setupComplete();
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       // 31/08/05: added !comp->isRemoved()
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     // persistance
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     // persistance
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     // persistance
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     // to back end
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         printf("setting extent implementation %s %p %s\n",
03030         name, this, (const char *)_idximpl->getHintsString());
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       //Oid xoid = extent->getOid();
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     // 7/05/02
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       //Oid xoid = components->getOid();
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) { // ouh ouh la: was 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     // 7/05/02
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         // disconnected the 19/06/00: components seem to be already 
03163         // released in Schema::gargabe()
03164 
03165         if (!db || !db->getSchema()->dont_delete_comps) {
03166           Object::freeList(complist, True);
03167           //Object::freeList(attr_complist, True);
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     if (this == cl)
03227       return True;
03228 
03229     if (!compare_l(cl))
03230       return False;
03231 
03232     if (state & Realizing)
03233       return True;
03234 
03235     ((Class *)this)->state |= Realizing;
03236     Bool r = compare_perform(cl);
03237     ((Class *)this)->state &= ~Realizing;
03238     return r;
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   Bool Class::compare_perform(const Class *cl) const
03270   {
03271     return True;
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   Status
03412   Class::isObjectOfClass(const Object *o, Bool *is, Bool issub) const
03413   {
03414     /* if multi-database, be laxist for now! */
03415 #if 0
03416     if (o->getOid().getDbid() != db->getDbid())
03417       {
03418         *is = True;
03419         printf("multi database object %s : class '%s'\n",
03420                o->getOid().getString(), o->getClass()->getName());
03421         return Success;
03422       }
03423 #endif
03424 
03425     if (UnreadableObject::isUnreadableObject(o))
03426       {
03427         *is = True;
03428         return Success;
03429       }
03430 
03431     if (issub)
03432       return isSuperClassOf(o->getClass(), is);
03433 
03434     *is = compare(o->getClass());
03435     return Success;
03436   }
03437 
03438   Status
03439   Class::isObjectOfClass(const Oid *o_oid, Bool *is, Bool issub,
03440                          Class **po_class) const
03441   {
03442     Status status;
03443     Class *o_class;
03444 
03445     *is = False;
03446 
03447     if (!db)
03448       return Exception::make(IDB_IS_OBJECT_OF_CLASS_ERROR, "database is not opened for class '%s', cannot performed isObjectOfClass(%s)", name, o_oid->getString());
03449 
03450     status = db->getObjectClass(*o_oid, o_class);
03451 
03452     if (UnreadableObject::isUnreadableObject(o_class))
03453       {
03454         *is = True;
03455         return Success;
03456       }
03457 
03458     if (status)
03459       return status;
03460     if (po_class)
03461       *po_class = o_class;
03462 
03463     if (issub)
03464       return isSuperClassOf(o_class, is);
03465 
03466     *is = compare(o_class);
03467     return Success;
03468   }
03469 
03470   Status Class::generateCode_Java(Schema *,
03471                                   const char *,
03472                                   const GenCodeHints &,
03473                                   FILE *)
03474   {
03475     return Success;
03476   }
03477 
03478   void Class::newObjRealize(Object *) const
03479   {
03480   }
03481 
03482   Status Class::checkInverse(const Schema *) const
03483   {
03484     return Success;
03485   }
03486 
03487   Status
03488   Class::makeClass(Database *db, const Oid &oid, int hdr_type,
03489                    const char *name, Bool& newClass, Class *&cl)
03490   {
03491 #ifdef OPTOPEN_TRACE
03492     printf("begin Class::makeClass(%s, %s)\n", oid.getString(), name);
03493 #endif
03494     newClass = True;
03495     Status s;
03496     switch(hdr_type)
03497       {
03498       case _StructClass_Type:
03499         cl = new StructClass(oid, name);
03500         break;
03501 
03502       case _Class_Type:
03503         cl = db->getSchema()->getClass(name);
03504         newClass = False;
03505         cl->setPartiallyLoaded(True);
03506         break;
03507 
03508       case _BasicClass_Type:
03509         cl = db->getSchema()->getClass(name);
03510         newClass = False;
03511         cl->setPartiallyLoaded(True);
03512         break;
03513 
03514       case _CollSetClass_Type:
03515         if (!strcmp(name, "set<object*>"))
03516           {
03517             cl = new CollSetClass(db->getSchema()->getClass("object"),
03518                                   True);
03519             cl->setPartiallyLoaded(True);
03520           }
03521         else
03522           cl = new CollSetClass(oid, name);
03523         break;
03524 
03525       case _CollBagClass_Type:
03526         cl = new CollBagClass(oid, name);
03527         break;
03528 
03529       case _CollArrayClass_Type:
03530         cl = new CollArrayClass(oid, name);
03531         break;
03532 
03533       case _CollListClass_Type:
03534         cl = new CollListClass(oid, name);
03535         break;
03536 
03537       case _EnumClass_Type:
03538         if (Class::isBoolClass(name)) {
03539           cl = db->getSchema()->getClass(name);
03540           newClass = False;
03541           cl->setPartiallyLoaded(True);
03542         }
03543         else
03544           cl = new EnumClass(oid, name);
03545         break;
03546 
03547       case _UnionClass_Type:
03548         //cl = new UnionClass(oid, name);
03549         break;
03550 
03551       default:
03552         assert(0);
03553       }
03554 
03555     if (!cl->getOid().isValid())
03556       ObjectPeer::setOid(cl, oid);
03557 #ifdef OPTOPEN_TRACE
03558     printf("Class::makeClass(%s, %s, class=%p)\n", oid.getString(),
03559            cl->getName(), cl);
03560 #endif
03561 
03562     return Success;
03563   }
03564 
03565   Status
03566   Class::getDefaultInstanceDataspace(const Dataspace *&_instance_dataspace) const
03567   {
03568     if (instance_dataspace) {
03569       _instance_dataspace = instance_dataspace;
03570       return Success;
03571     }
03572 
03573     if (instance_dspid == Dataspace::DefaultDspid) {
03574       _instance_dataspace = 0;
03575       return Success;
03576     }
03577 
03578     Status s = db->getDataspace(instance_dspid, _instance_dataspace);
03579     if (s) return s;
03580     const_cast<Class *>(this)->instance_dataspace = _instance_dataspace;
03581     return Success;
03582   }
03583 
03584   Status
03585   Class::setDefaultInstanceDataspace(const Dataspace *_instance_dataspace)
03586   {
03587     if (!instance_dataspace && instance_dspid != Dataspace::DefaultDspid) {
03588       Status s = db->getDataspace(instance_dspid, instance_dataspace);
03589       if (s) return s;
03590     }
03591 
03592     if (instance_dataspace != _instance_dataspace) {
03593       instance_dataspace = _instance_dataspace;
03594       instance_dspid = (instance_dataspace ? instance_dataspace->getId() : Dataspace::DefaultDspid);
03595       touch();
03596       return store();
03597     }
03598 
03599     return Success;
03600   }
03601 
03602   Status
03603   Class::getInstanceLocations(ObjectLocationArray &locarr, Bool inclsub)
03604   {
03605     RPCStatus rpc_status =
03606       getInstanceClassLocations(db->getDbHandle(), oid.getOid(), inclsub,
03607                                     (Data *)&locarr);
03608     return StatusMake(rpc_status);
03609   }
03610 
03611   Status
03612   Class::moveInstances(const Dataspace *dataspace, Bool inclsub)
03613   {
03614     RPCStatus rpc_status =
03615       moveInstanceClass(db->getDbHandle(), oid.getOid(), inclsub,
03616                             dataspace->getId());
03617     return StatusMake(rpc_status);
03618   }
03619 
03620   void
03621   Class::setInstanceDspid(short _instance_dspid)
03622   {
03623     instance_dspid = _instance_dspid;
03624   }
03625 
03626   Status
03627   Class::manageDataspace(short dspid)
03628   {
03629     if (dspid == Dataspace::DefaultDspid)
03630       return Success;
03631     const Dataspace *dataspace;
03632     Status s;
03633     s = db->getDataspace(dspid, dataspace);
03634     if (s) return s;
03635     return setDefaultInstanceDataspace(dataspace);
03636   }
03637 
03638   short
03639   Class::get_instdspid() const
03640   {
03641     return (instance_dataspace ? instance_dataspace->getId() : Dataspace::DefaultDspid);
03642   }
03643 
03644 
03645   // XDR
03646   //#define E_XDR_TRACE
03647 
03648   void
03649   Class::decode(void * hdata, // to
03650                 const void * xdata, // from
03651                 Size incsize, // temporarely necessary 
03652                 unsigned int nb) const
03653   {
03654 #ifdef E_XDR_TRACE
03655     cout << "Class::decode " << name << endl;
03656 #endif
03657     CHECK_INCSIZE("decode", incsize, idr_psize - IDB_OBJ_HEAD_SIZE);
03658 
03659     memcpy(hdata, xdata, nb * incsize);
03660   }
03661 
03662   void
03663   Class::encode(void * xdata, // to
03664                 const void * hdata, // from
03665                 Size incsize, // temporarely necessary 
03666                 unsigned int nb) const
03667   {
03668 #ifdef E_XDR_TRACE
03669     cout << "Class::encode " << name << endl;
03670 #endif
03671     CHECK_INCSIZE("encode", incsize, idr_psize - IDB_OBJ_HEAD_SIZE);
03672 
03673     memcpy(xdata, hdata, nb * incsize);
03674   }
03675 
03676 
03677   int
03678   Class::cmp(const void * xdata,
03679              const void * hdata,
03680              Size incsize, // temporarely necessary 
03681              unsigned int nb) const
03682   {
03683 #ifdef E_XDR_TRACE
03684     cout << "Class::cmp " << name;
03685 #endif
03686     CHECK_INCSIZE("cmp", incsize, idr_psize - IDB_OBJ_HEAD_SIZE);
03687 
03688     int r = memcmp(xdata, hdata, nb * incsize);
03689 #ifdef E_XDR_TRACE
03690     cout << " -> " << r << endl;
03691 #endif
03692     return r;
03693   }
03694 
03695 }
03696   

Generated on Mon Dec 22 18:15:51 2008 for eyedb by  doxygen 1.5.3