00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 #include "eyedb_p.h"
00026 #include "IteratorBE.h"
00027 #include "CollectionBE.h"
00028 #include <iostream>
00029
00030
00031
00032
00033
00034 namespace eyedb {
00035
00036 EnumClass::EnumClass(const char *s) : Class(s)
00037 {
00038 items_cnt = 0;
00039 items = 0;
00040
00041 parent = Enum_Class;
00042 setClass(EnumClass_Class);
00043 #ifdef IDB_UNDEF_ENUM_HINT
00044 idr_objsz = IDB_OBJ_HEAD_SIZE + sizeof(char) + sizeof(eyedblib::int32);
00045 #else
00046 idr_objsz = IDB_OBJ_HEAD_SIZE + sizeof(eyedblib::int32);
00047 #endif
00048 idr_psize = idr_objsz;
00049 idr_vsize = 0;
00050 type = _EnumClass_Type;
00051 }
00052
00053 EnumClass::EnumClass(Database *_db, const char *s) : Class(_db, s)
00054 {
00055 items_cnt = 0;
00056 items = 0;
00057
00058 parent = Enum_Class;
00059 setClass(EnumClass_Class);
00060 #ifdef IDB_UNDEF_ENUM_HINT
00061 idr_objsz = IDB_OBJ_HEAD_SIZE + sizeof(char) + sizeof(eyedblib::int32);
00062 #else
00063 idr_objsz = IDB_OBJ_HEAD_SIZE + sizeof(eyedblib::int32);
00064 #endif
00065 idr_psize = idr_objsz;
00066 idr_vsize = 0;
00067 type = _EnumClass_Type;
00068 }
00069
00070 void
00071 EnumClass::copy_realize(const EnumClass &cl)
00072 {
00073 items_cnt = cl.items_cnt;
00074 items = (EnumItem **)malloc(sizeof(EnumItem*)*items_cnt);
00075 for (int i = 0; i < items_cnt; i++)
00076 items[i] = cl.items[i]->clone();
00077 }
00078
00079 EnumClass::EnumClass(const EnumClass &cl)
00080 : Class(cl)
00081 {
00082 copy_realize(cl);
00083 }
00084
00085 EnumClass::EnumClass(const Oid &_oid, const char *_name)
00086 : Class(_oid, _name)
00087 {
00088 items_cnt = 0;
00089 items = 0;
00090 type = _EnumClass_Type;
00091 }
00092
00093 Status
00094 EnumClass::loadComplete(const Class *cl)
00095 {
00096 assert(cl->asEnumClass());
00097 Status s = Class::loadComplete(cl);
00098 if (s) return s;
00099 copy_realize(*cl->asEnumClass());
00100 return Success;
00101 }
00102
00103 EnumClass& EnumClass::operator=(const EnumClass &cl)
00104 {
00105 this->Class::operator=(cl);
00106 copy_realize(cl);
00107
00108 return *this;
00109 }
00110
00111 int EnumClass::getEnumItemsCount(void) const
00112 {
00113 return items_cnt;
00114 }
00115
00116 const EnumItem *EnumClass::getEnumItem(int n) const
00117 {
00118 if (n >= 0 && n < items_cnt)
00119 return items[n];
00120 else
00121 return 0;
00122 }
00123
00124 const EnumItem *EnumClass::getEnumItemFromName(const char *nm) const
00125 {
00126 for (int i = 0; i < items_cnt; i++)
00127 if (!strcmp(items[i]->name, nm))
00128 return items[i];
00129
00130 return (const EnumItem *)0;
00131 }
00132
00133 const EnumItem *EnumClass::getEnumItemFromVal(unsigned int val) const
00134 {
00135 for (int i = 0; i < items_cnt; i++)
00136 if (items[i]->value == val)
00137 return items[i];
00138
00139 return (const EnumItem *)0;
00140 }
00141
00142 void EnumClass::free_items(void)
00143 {
00144 if (items_cnt)
00145 {
00146 for (int i = 0; i < items_cnt; i++)
00147 delete items[i];
00148
00149 free(items);
00150 }
00151 }
00152
00153 Status EnumClass::setEnumItems(EnumItem **nitems, int cnt)
00154 {
00155 free_items();
00156
00157 items_cnt = cnt;
00158
00159 if (items_cnt)
00160 {
00161 items = (EnumItem**)malloc(sizeof(EnumItem*)*items_cnt);
00162 for (int i = 0; i < items_cnt; i++)
00163 items[i] = new EnumItem(nitems[i], i);
00164 }
00165
00166 return Success;
00167 }
00168
00169 const EnumItem **EnumClass::getEnumItems(int& cnt) const
00170 {
00171 cnt = items_cnt;
00172 return (const EnumItem **)items;
00173 }
00174
00175 Bool
00176 EnumClass::compare_perform(const Class *cl,
00177 Bool compClassOwner,
00178 Bool compNum,
00179 Bool compName,
00180 Bool inDepth) const
00181 {
00182 const EnumClass *me = (EnumClass *)cl;
00183 if (items_cnt != me->items_cnt)
00184 return False;
00185
00186 for (int i = 0; i < items_cnt; i++)
00187 if (!items[i]->compare(me->items[i]))
00188 return False;
00189
00190 return True;
00191 }
00192
00193 Object *EnumClass::newObj(Database *_db) const
00194 {
00195 if (!idr_objsz)
00196 return 0;
00197
00198 Enum *t = new Enum(_db);
00199
00200 ObjectPeer::make(t, this, 0, _Enum_Type, idr_objsz,
00201 idr_psize, idr_vsize);
00202 return t;
00203 }
00204
00205 Object *EnumClass::newObj(Data data, Bool _copy) const
00206 {
00207 if (!idr_objsz)
00208 return 0;
00209
00210 Enum *t = new Enum();
00211
00212 ObjectPeer::make(t, this, data, _Enum_Type, idr_objsz,
00213 idr_psize, idr_vsize, _copy);
00214 return t;
00215 }
00216
00217 void EnumClass::_setCSDRSize(Size, Size)
00218 {
00219 }
00220
00221 Status
00222 EnumClass::setName(const char *s)
00223 {
00224 return setNameRealize(s);
00225 }
00226
00227 Status EnumClass::trace(FILE *fd, unsigned int flags, const RecMode *rcm) const
00228 {
00229 if (const_cast<EnumClass *>(this)->wholeComplete())
00230 return 0;
00231
00232 char *indent_str = make_indent(INDENT_INC);
00233 EnumItem **item;
00234 int n;
00235
00236 fprintf(fd, "%s enum %s { ", oid.getString(), name);
00237
00238 Status status = Success;
00239 status = trace_common(fd, INDENT_INC, flags, rcm);
00240 if (status) goto out;
00241
00242 for (n = 0, item = items; n < items_cnt; n++, item++)
00243 fprintf(fd, "%s%s = %d%s\n", indent_str, (*item)->name, (*item)->value,
00244 ((n != items_cnt - 1) ? "," : ""));
00245
00246 status = trace_comps(fd, INDENT_INC, flags, rcm);
00247 if (status) goto out;
00248
00249 fprintf(fd, "};\n");
00250
00251 out:
00252 delete_indent(indent_str);
00253 return status;
00254 }
00255
00256 static int global_check_enum_value =
00257 getenv("EYEDBNOCHECKENUM") ? False : True;
00258
00259 Status EnumClass::setRawData(Data xdata, Data hdata, int nb,
00260 Bool& mod, Bool check_value)
00261 {
00262 #ifdef E_XDR_TRACE
00263 cout << "EnumClass::setRawData " << name << endl;
00264 #endif
00265 mod = False;
00266 #ifdef IDB_UNDEF_ENUM_HINT
00267 xdata += sizeof(char);
00268 #endif
00269 #ifdef IDB_UNDEF_ENUM_HINT
00270 for (int i = 0; i < nb; i++, xdata += sizeof(char) + sizeof(eyedblib::int32),
00271 hdata += sizeof(eyedblib::int32))
00272 #else
00273 for (int i = 0; i < nb; i++, xdata += sizeof(eyedblib::int32),
00274 hdata += sizeof(eyedblib::int32)) {
00275 #endif
00276 eyedblib::int32 l;
00277 x2h_32_cpy(&l, xdata);
00278 if (memcmp(&l, hdata, sizeof(eyedblib::int32))) {
00279 if (check_value && global_check_enum_value) {
00280 eyedblib::int32 val;
00281 eyedblib_mcp(&val, hdata, sizeof(eyedblib::int32));
00282 if (!getEnumItemFromVal(val))
00283 return Exception::make(IDB_ERROR, "invalid value '%d' for "
00284 "enum class %s", val, name);
00285 }
00286 h2x_32_cpy(xdata, hdata);
00287
00288 mod = True;
00289 }
00290 }
00291
00292 return Success;
00293 }
00294
00295 Status EnumClass::getRawData(Data hdata, Data xdata, int nb) const
00296 {
00297 #ifdef E_XDR_TRACE
00298 cout << "EnumClass::getRawData " << name << endl;
00299 #endif
00300 #ifdef IDB_UNDEF_ENUM_HINT
00301 xdata += sizeof(char);
00302 for (int i = 0; i < nb; i++, hdata += sizeof(eyedblib::int32),
00303 xdata += sizeof(char) + sizeof(eyedblib::int32))
00304 memcpy(hdata, xdata, sizeof(eyedblib::int32));
00305 #else
00306 for (int i = 0; i < nb; i++, hdata += sizeof(eyedblib::int32),
00307 xdata += sizeof(eyedblib::int32)) {
00308 #ifdef E_XDR
00309 x2h_32_cpy(hdata, xdata);
00310 #else
00311 memcpy(hdata, xdata, sizeof(eyedblib::int32));
00312 #endif
00313 }
00314 #endif
00315
00316 return Success;
00317 }
00318
00319 Status EnumClass::traceData(FILE *fd, int, Data inidata, Data data, TypeModifier *tmod) const
00320 {
00321 int i;
00322 if (data)
00323 {
00324 #ifdef IDB_UNDEF_ENUM_HINT
00325 data += sizeof(char);
00326 #endif
00327 const EnumItem *it;
00328 eyedblib::int32 j;
00329 if (tmod)
00330 {
00331 if (tmod->pdims > 1)
00332 {
00333 fprintf(fd, "{");
00334 for (i = 0; i < tmod->pdims; i++)
00335 {
00336 if (i)
00337 fprintf(fd, ", ");
00338 #ifdef E_XDR
00339 x2h_32_cpy(&j, data);
00340 #else
00341 memcpy(&j, data, sizeof(eyedblib::int32));
00342 #endif
00343 it = getEnumItemFromVal(j);
00344 if (it)
00345 fprintf(fd, "%s", it->name);
00346 else
00347 {
00348 fprintf(fd, "%d", j);
00349 if (j)
00350 fprintf(fd, " [%XH 0%o]", j, j);
00351 }
00352
00353 #ifdef IDB_UNDEF_ENUM_HINT
00354 data += sizeof(eyedblib::int32) + sizeof(char);
00355 #else
00356 data += sizeof(eyedblib::int32);
00357 #endif
00358 }
00359 fprintf(fd, "}");
00360 }
00361 else
00362 {
00363 #ifdef E_XDR
00364 x2h_32_cpy(&j, data);
00365 #else
00366 memcpy(&j, data, sizeof(eyedblib::int32));
00367 #endif
00368 it = getEnumItemFromVal(j);
00369 if (it)
00370 fprintf(fd, "%s", it->name);
00371 else
00372 {
00373 fprintf(fd, "%d", j);
00374 if (j)
00375 fprintf(fd, " [%XH 0%o]", j, j);
00376 }
00377 }
00378 }
00379 else
00380 {
00381 #ifdef E_XDR
00382 x2h_32_cpy(&j, data);
00383 #else
00384 memcpy(&j, data, sizeof(eyedblib::int32));
00385 #endif
00386 it = getEnumItemFromVal(j);
00387 if (it)
00388 fprintf(fd, "%s", it->name);
00389 else
00390 {
00391 fprintf(fd, "%d", j);
00392 if (j)
00393 fprintf(fd, " [%XH 0%o]", j, j);
00394 }
00395 }
00396 }
00397 else
00398 fprintf(fd, "null");
00399
00400 return Success;
00401 }
00402
00403 Status EnumClass::setValue(Data)
00404 {
00405 return Success;
00406 }
00407
00408 Status EnumClass::getValue(Data*) const
00409 {
00410 return Success;
00411 }
00412
00413 Status EnumClass::create()
00414 {
00415 if (oid.isValid())
00416 return Exception::make(IDB_OBJECT_ALREADY_CREATED, "creating enum class '%s'", name);
00417
00418 IDB_CHECK_WRITE(db);
00419
00420 Size alloc_size;
00421 Offset offset;
00422 Status status;
00423
00424 alloc_size = 0;
00425 Data data = 0;
00426 offset = IDB_CLASS_IMPL_TYPE;
00427 Status s = IndexImpl::code(data, offset, alloc_size, idximpl);
00428 if (s) return s;
00429
00430 offset = IDB_CLASS_MTYPE;
00431 eyedblib::int32 mt = m_type;
00432 int32_code (&data, &offset, &alloc_size, &mt);
00433
00434 offset = IDB_CLASS_DSPID;
00435 eyedblib::int16 dspid = get_instdspid();
00436 int16_code (&data, &offset, &alloc_size, &dspid);
00437
00438 offset = IDB_CLASS_HEAD_SIZE;
00439
00440 status = class_name_code(db->getDbHandle(), getDataspaceID(), &data, &offset,
00441 &alloc_size, name);
00442 if (status) return status;
00443
00444 int32_code (&data, &offset, &alloc_size, &items_cnt);
00445
00446 for (int i = 0; i < items_cnt; i++)
00447 {
00448 EnumItem *item = items[i];
00449 string_code (&data, &offset, &alloc_size, item->name);
00450 int32_code (&data, &offset, &alloc_size, (eyedblib::int32 *)&item->value);
00451 }
00452
00453 int idr_sz = offset;
00454 idr->setIDR(idr_sz, data);
00455 headerCode(_EnumClass_Type, idr_sz);
00456
00457 RPCStatus rpc_status;
00458 rpc_status = objectCreate(db->getDbHandle(), getDataspaceID(), data, oid.getOid());
00459
00460 if (rpc_status == RPCSuccess)
00461 {
00462 Status status;
00463
00464 status = ClassPeer::makeColls(db, this, data, &oid);
00465 if (status != Success)
00466 return status;
00467 }
00468
00469 if (rpc_status == RPCSuccess)
00470 gbx_locked = gbxTrue;
00471 return StatusMake(rpc_status);
00472 }
00473
00474 Status EnumClass::update()
00475 {
00476 return Success;
00477 }
00478
00479 Status EnumClass::remove(const RecMode*)
00480 {
00481 return Success;
00482 }
00483
00484 Status EnumClass::trace_realize(FILE*, int, unsigned int flags, const RecMode *rcm) const
00485 {
00486 return Success;
00487 }
00488
00489 int
00490 EnumClass::genODL(FILE *fd, Schema *) const
00491 {
00492 extern Bool odl_system_class;
00493
00494 if (const_cast<EnumClass *>(this)->wholeComplete())
00495 return 0;
00496
00497 if (isSystem() && !odl_system_class)
00498 return 0;
00499
00500 fprintf(fd, "enum %s {\n", name);
00501
00502 EnumItem **item;
00503 int n;
00504
00505 for (n = 0, item = items; n < items_cnt; n++, item++)
00506 fprintf(fd, "\t%s = %d%s\n", (*item)->name, (*item)->value,
00507 ((n != items_cnt - 1) ? "," : ""));
00508 fprintf(fd, "};\n");
00509 return 1;
00510 }
00511
00512 void
00513 EnumClass::touch()
00514 {
00515 Class::touch();
00516 LinkedList *cl_list = IteratorBE::getMclList();
00517 if (cl_list)
00518 cl_list->insertObjectLast(this);
00519 }
00520
00521 void EnumClass::garbage()
00522 {
00523 free_items();
00524 Class::garbage();
00525 }
00526
00527 EnumClass::~EnumClass()
00528 {
00529 garbageRealize();
00530 }
00531
00532 EnumItem::EnumItem(const char *nm, unsigned int val, int _num)
00533 {
00534 name = strdup(nm);
00535 aliasname = 0;
00536 value = val;
00537 num = _num;
00538 }
00539
00540 EnumItem::EnumItem(const char *nm, const char *_aliasname,
00541 unsigned int val, int _num)
00542 {
00543 name = strdup(nm);
00544 aliasname = _aliasname ? strdup(_aliasname) : 0;
00545 value = val;
00546 num = _num;
00547 }
00548
00549 EnumItem::EnumItem(const EnumItem *item, int n)
00550 {
00551 name = strdup(item->name);
00552 aliasname = item->aliasname ? strdup(item->aliasname) : 0;
00553 value = item->value;
00554 num = n;
00555 }
00556
00557 EnumItem *
00558 EnumItem::clone() const
00559 {
00560 return new EnumItem(name, aliasname, value, num);
00561 }
00562
00563 Bool
00564 EnumItem::compare(const EnumItem *item) const
00565 {
00566 if (num != item->num)
00567 return False;
00568 if (value != item->value)
00569 return False;
00570 if (strcmp(name, item->name))
00571 return False;
00572
00573
00574
00575
00576
00577 return True;
00578 }
00579
00580
00581 EnumItem::~EnumItem()
00582 {
00583 free(name);
00584 free(aliasname);
00585 }
00586 }