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 <assert.h>
00027 #include "AttrNative.h"
00028 #include "CollectionBE.h"
00029
00030 using namespace std;
00031
00032
00033
00034
00035
00036 namespace eyedb {
00037
00038 const char *
00039 CollectionClass::make_name(const char *prefix, Class* coll_class,
00040 Bool isref, int dim, Bool _alias)
00041 {
00042 static char name[256];
00043 const char *s = _alias ? coll_class->getAliasName() : coll_class->getName();
00044 if (dim <= 1)
00045 sprintf(name, "%s<%s%s>", prefix, s , (isref ? "*" : ""));
00046 else
00047 sprintf(name, "%s<%s%s[%d]>", prefix, s, (isref ? "*" : ""), dim);
00048 return name;
00049 }
00050
00051 const char *CollectionClass::getCName(Bool) const
00052 {
00053 #define NN 12
00054 static char c_name[NN][128];
00055 static int which;
00056
00057 if (which >= NN)
00058 which = 0;
00059
00060 char *sname = c_name[which++];
00061 sprintf(sname, "%s_%s%s", getClass()->getName(),
00062 coll_class->asBasicClass() ? coll_class->getName() :
00063 coll_class->getCName(), (isref ? "_ref" : ""));
00064
00065 if (dim > 1)
00066 {
00067 char tok[32];
00068 sprintf(tok, "_%d", dim);
00069 strcat(sname, tok);
00070 }
00071
00072 return sname;
00073 }
00074
00075 int
00076 get_item_size(const Class *coll_class, int dim)
00077 {
00078 Size psize, vsize, isize;
00079 coll_class->getIDRObjectSize(&psize, &vsize, &isize);
00080 return (psize - isize - IDB_OBJ_HEAD_SIZE) * dim;
00081 }
00082
00083 Status
00084 CollectionClass::check(Class *_coll_class, Bool _isref, int _dim)
00085 {
00086 Status s = Success;
00087
00088 if (_dim <= 0)
00089 s = Exception::make(IDB_COLLECTION_ERROR,
00090 "invalid dimension: %d", _dim);
00091 else if (_dim > 1 && (!_coll_class || !_coll_class->asCharClass()))
00092 s = Exception::make(IDB_COLLECTION_ERROR,
00093 "dimension > 1 are supported only for collection of bounded strings");
00094 else if (_coll_class &&
00095 !_isref &&
00096 !_coll_class->asBasicClass() &&
00097 !_coll_class->asEnumClass()) {
00098
00099 unsigned int attr_cnt;
00100 const Attribute **attrs = _coll_class->getAttributes(attr_cnt);
00101 for (int n = 0; n < attr_cnt; n++)
00102 if (attrs[n]->isVarDim()) {
00103 s = Exception::make(IDB_COLLECTION_ERROR,
00104 "variable dimension attribute %s::%s is not supported in collection of litterals", _coll_class->getName(),
00105 attrs[n]->getName());
00106 break;
00107 }
00108 }
00109
00110 return s;
00111 }
00112
00113 CollectionClass::CollectionClass(Class *_coll_class, Bool _isref, const char *prefix) : Class("")
00114 {
00115 Exception::Mode mode = Exception::setMode(Exception::StatusMode);
00116 _status = check(_coll_class, _isref, 1);
00117 Exception::setMode(mode);
00118
00119 if (_status)
00120 return;
00121
00122 coll_class = _coll_class;
00123 if (coll_class && coll_class->isSystem())
00124 m_type = System;
00125
00126 isref = _isref;
00127 dim = 1;
00128 free(name);
00129
00130 name = strdup(make_name(prefix, coll_class, isref, 1, False));
00131 aliasname = strdup(make_name(prefix, coll_class, isref, 1, True));
00132
00133 cl_oid.invalidate();
00134
00135 if (isref)
00136 item_size = sizeof(Oid);
00137 else
00138 item_size = get_item_size(coll_class, dim);
00139
00140 AttrNative::copy(CollectionITEMS, items, items_cnt, this);
00141
00142
00143
00144
00145 idr_psize = IDB_OBJ_HEAD_SIZE + sizeof(Oid);
00146 idr_vsize = sizeof(Object *);
00147 idr_inisize = 0;
00148 idr_objsz = idr_vsize + idr_psize;
00149 }
00150
00151 CollectionClass::CollectionClass(Class *_coll_class, int _dim, const char *prefix) : Class("")
00152 {
00153 Exception::Mode mode = Exception::setMode(Exception::StatusMode);
00154 _status = check(_coll_class, False, _dim);
00155 Exception::setMode(mode);
00156
00157 if (_status)
00158 return;
00159
00160 coll_class = _coll_class;
00161 if (coll_class && coll_class->isSystem())
00162 m_type = System;
00163
00164 isref = False;
00165 dim = _dim;
00166 free(name);
00167 name = strdup(make_name(prefix, coll_class, isref, dim, False));
00168 aliasname = strdup(make_name(prefix, coll_class, isref, dim, True));
00169
00170 parent = Class_Class;
00171 cl_oid.invalidate();
00172
00173 item_size = get_item_size(coll_class, dim);
00174
00175 AttrNative::copy(CollectionITEMS, items, items_cnt, this);
00176
00177 idr_psize = IDB_OBJ_HEAD_SIZE + sizeof(Oid);
00178 idr_vsize = sizeof(Object *);
00179 idr_inisize = 0;
00180 idr_objsz = idr_vsize + idr_psize;
00181 }
00182
00183 void
00184 CollectionClass::copy_realize(const CollectionClass &cl)
00185 {
00186 coll_class = cl.coll_class;
00187 if (coll_class && coll_class->isSystem())
00188 m_type = System;
00189 isref = cl.isref;
00190 dim = cl.dim;
00191 cl_oid = cl.cl_oid;
00192 item_size = cl.item_size;
00193 _status = cl._status;
00194 }
00195
00196 CollectionClass::CollectionClass(const CollectionClass &cl)
00197 : Class(cl)
00198 {
00199 coll_class = 0;
00200 isref = False;
00201 dim = 0;
00202 cl_oid.invalidate();
00203 item_size = 0;
00204 _status = NULL;
00205
00206 copy_realize(cl);
00207 }
00208
00209 Status
00210 CollectionClass::loadComplete(const Class *cl)
00211 {
00212 assert(cl->asCollectionClass());
00213 Status s = Class::loadComplete(cl);
00214 if (s) return s;
00215 copy_realize(*cl->asCollectionClass());
00216 return Success;
00217 }
00218
00219 CollectionClass::CollectionClass(const Oid &_oid, const char *_name) :
00220 Class(_oid, _name)
00221 {
00222 }
00223
00224 CollectionClass& CollectionClass::operator=(const CollectionClass &cl)
00225 {
00226 this->Class::operator=(cl);
00227 copy_realize(cl);
00228 return *this;
00229 }
00230
00231 #define RECURS_BUG // added the 11/06/99
00232
00233 Bool CollectionClass::compare_perform(const Class *cl,
00234 Bool compClassOwner,
00235 Bool compNum,
00236 Bool compName,
00237 Bool inDepth) const
00238 {
00239 if (!cl->asCollectionClass())
00240 return False;
00241
00242 #ifdef RECURS_BUG
00243 if (state & Realizing)
00244 return True;
00245 #endif
00246
00247 #ifdef RECURS_BUG
00248 ((CollectionClass *)this)->state |= Realizing;
00249 #endif
00250
00251 Bool cl_isref;
00252 eyedblib::int16 cl_dim, cl_item_size;
00253 const Class *cl_collclass = cl->asCollectionClass()->
00254 getCollClass(&cl_isref, &cl_dim, &cl_item_size);
00255
00256 if (cl_isref != isref || cl_dim != dim || cl_item_size != item_size)
00257 {
00258 #ifdef RECURS_BUG
00259 ((CollectionClass *)this)->state &= ~Realizing;
00260 #endif
00261 return False;
00262 }
00263
00264 Bool r = coll_class->compare(cl_collclass, compClassOwner,
00265 compNum, compName, inDepth);
00266 #ifdef RECURS_BUG
00267 ((CollectionClass *)this)->state &= ~Realizing;
00268 #endif
00269 return r;
00270 }
00271
00272 Status
00273 CollectionClass::create()
00274 {
00275 if (oid.isValid())
00276 return Exception::make(IDB_OBJECT_ALREADY_CREATED, "creating collection_class '%s'", name);
00277
00278 IDB_CHECK_WRITE(db);
00279
00280
00281
00282
00283 RPCStatus rpc_status;
00284 Size alloc_size;
00285 Offset offset, cl_oid_offset;
00286 ObjectHeader hdr;
00287 Status status;
00288
00289 alloc_size = 0;
00290
00291 idr->setIDR((Size)0);
00292 Data data = 0;
00293
00294
00295
00296
00297
00298 offset = IDB_CLASS_IMPL_TYPE;
00299 status = IndexImpl::code(data, offset, alloc_size, idximpl);
00300 if (status) return status;
00301
00302 offset = IDB_CLASS_MTYPE;
00303 eyedblib::int32 mt = m_type;
00304 int32_code (&data, &offset, &alloc_size, &mt);
00305
00306 offset = IDB_CLASS_DSPID;
00307 eyedblib::int16 dspid = get_instdspid();
00308 int16_code (&data, &offset, &alloc_size, &dspid);
00309
00310 offset = IDB_CLASS_HEAD_SIZE;
00311
00312 if (!cl_oid.isValid())
00313 {
00314 coll_class = db->getSchema()->getClass(coll_class->getName());
00315 if (!coll_class)
00316 return Exception::make(IDB_ERROR, "creating collection_class '%s'",
00317 name);
00318 cl_oid = coll_class->getOid();
00319 if (!cl_oid.isValid() && !db->isBackEnd())
00320 {
00321 Status s = coll_class->create();
00322 if (s)
00323 return s;
00324 cl_oid = coll_class->getOid();
00325 }
00326 }
00327
00328
00329 if (oid.isValid())
00330 return Success;
00331
00332 status = class_name_code(db->getDbHandle(), getDataspaceID(), &data, &offset,
00333 &alloc_size, name);
00334 if (status) return status;
00335
00336 cl_oid_offset = offset;
00337 oid_code (&data, &offset, &alloc_size, cl_oid.getOid());
00338
00339 char kc = (char)isref;
00340 char_code (&data, &offset, &alloc_size, &kc);
00341
00342
00343 int16_code (&data, &offset, &alloc_size, &dim);
00344
00345 int idr_sz = offset;
00346 idr->setIDR(idr_sz, data);
00347 headerCode(type, idr_sz);
00348
00349 rpc_status = objectCreate(db->getDbHandle(), getDataspaceID(), data, oid.getOid());
00350
00351 if (rpc_status == RPCSuccess && !cl_oid.isValid() && strcmp(coll_class->getName(), "object"))
00352 {
00353 Status status;
00354
00355 if (status = coll_class->setDatabase(db))
00356 return status;
00357
00358 if (status = coll_class->create())
00359 return status;
00360
00361 cl_oid = coll_class->getOid();
00362 offset = cl_oid_offset;
00363 oid_code (&data, &offset, &alloc_size, cl_oid.getOid());
00364 rpc_status = objectWrite(db->getDbHandle(), data, oid.getOid());
00365 }
00366
00367 if (rpc_status == RPCSuccess)
00368 gbx_locked = gbxTrue;
00369
00370 return StatusMake(rpc_status);
00371 }
00372
00373 void
00374 CollectionClass::invalidateCollClassOid()
00375 {
00376
00377 cl_oid.invalidate();
00378 touch();
00379 }
00380
00381 Status
00382 CollectionClass::update()
00383 {
00384
00385
00386
00387
00388
00389 if (cl_oid.isValid() && !modify)
00390 return Success;
00391
00392 Offset offset = 0;
00393 Size alloc_size = sizeof(eyedblib::int16);
00394 unsigned char data[sizeof(eyedblib::int16)];
00395 unsigned char *pdata = data;
00396
00397 eyedblib::int16 dspid = get_instdspid();
00398 int16_code (&pdata, &offset, &alloc_size, &dspid);
00399
00400
00401 offset = IDB_CLASS_DSPID;
00402 RPCStatus rpc_status =
00403 dataWrite(db->getDbHandle(), offset, sizeof(eyedblib::int16),
00404 data, oid.getOid());
00405 if (rpc_status) return StatusMake(rpc_status);
00406
00407 if (cl_oid.isValid())
00408 return Success;
00409
00410 if (!coll_class) {
00411 Status s = wholeComplete();
00412 if (s) return s;
00413 if (!coll_class)
00414 return Exception::make(IDB_ERROR, "updating collection_class '%s'",
00415 name);
00416 }
00417
00418 string clsName = coll_class->getName();
00419 coll_class = db->getSchema()->getClass(coll_class->getName());
00420 if (!coll_class)
00421 return Exception::make(IDB_ERROR, "updating collection_class '%s' [class '%s']",
00422 name, clsName.c_str());
00423
00424 if (!coll_class->getOid().isValid())
00425 {
00426
00427 Status status;
00428 if (status = coll_class->setDatabase(db))
00429 return status;
00430
00431 if (status = coll_class->create())
00432 return status;
00433 }
00434
00435 cl_oid = coll_class->getOid();
00436
00437 offset = IDB_CLASS_HEAD_SIZE + IDB_CLASS_NAME_TOTAL_LEN;
00438
00439 #ifdef E_XDR
00440 eyedbsm::Oid oid_x;
00441 eyedbsm::h2x_oid(&oid_x, cl_oid.getOid());
00442 #else
00443 eyedbsm::Oid oid_x = *cl_oid.getOid();
00444 #endif
00445 rpc_status =
00446 dataWrite(db->getDbHandle(), offset, sizeof(eyedbsm::Oid),
00447 (Data)&oid_x, oid.getOid());
00448 return StatusMake(rpc_status);
00449 }
00450
00451 Status CollectionClass::trace(FILE* fd, unsigned int flags, const RecMode *rcm) const
00452 {
00453 fprintf(fd, "%s ", oid.getString());
00454 return trace_realize(fd, INDENT_INC, flags, rcm);
00455 }
00456
00457 Status CollectionClass::trace_realize(FILE* fd, int indent, unsigned int flags, const RecMode *rcm) const
00458 {
00459 char *indent_str = make_indent(indent);
00460
00461 if (state & Tracing)
00462 {
00463 fprintf(fd, "%s%s;\n", indent_str, oid.getString());
00464 delete_indent(indent_str);
00465 return Success;
00466 }
00467
00468 Status status = Success;
00469 char *lastindent_str = make_indent(indent - INDENT_INC);
00470
00471 const_cast<CollectionClass *>(this)->state |= Tracing;
00472
00473 fprintf(fd, "%s%s", lastindent_str, name);
00474
00475 const Class *p = getParent();
00476 while (p)
00477 {
00478 fprintf(fd, " : %s", p->getName());
00479 p = p->getParent();
00480 }
00481
00482 fprintf(fd, " { ");
00483 status = trace_common(fd, indent, flags, rcm);
00484 if (status) goto out;
00485
00486 if (dim > 1)
00487 fprintf(fd, "%sclass = \"%s[%d]\";\n", indent_str,
00488 coll_class->getName(), dim);
00489 else
00490 fprintf(fd, "%scoll_class = \"%s%s\";\n", indent_str,
00491 coll_class->getName(), (isref ? "*" : ""));
00492
00493 fprintf(fd, "%s};\n", lastindent_str);
00494
00495 out:
00496 delete_indent(indent_str);
00497 delete_indent(lastindent_str);
00498 const_cast<CollectionClass *>(this)->state &= ~Tracing;
00499 return status;
00500 }
00501
00502 Status
00503 CollectionClass::remove(const RecMode*rcm)
00504 {
00505 return Class::remove(rcm);
00506 }
00507
00508 Class *CollectionClass::getCollClass(Bool *_isref, eyedblib::int16 *_dim,
00509 eyedblib::int16 *_item_size)
00510 {
00511 if (_isref)
00512 *_isref = isref;
00513
00514 if (_dim)
00515 *_dim = dim;
00516
00517 if (_item_size)
00518 *_item_size = item_size;
00519
00520 return coll_class;
00521 }
00522
00523 const Class *
00524 CollectionClass::getCollClass(Bool *_isref, eyedblib::int16 *_dim,
00525 eyedblib::int16 *_item_size) const
00526 {
00527 if (_isref)
00528 *_isref = isref;
00529
00530 if (_dim)
00531 *_dim = dim;
00532
00533 if (_item_size)
00534 *_item_size = item_size;
00535
00536 return coll_class;
00537 }
00538
00539 Status
00540 CollectionClass::make(Database *db, Class **cls)
00541 {
00542 assert(*cls);
00543
00544 Class *cl;
00545 if (cl = db->getSchema()->getClass((*cls)->getName())) {
00546 *cls = cl;
00547 return Success;
00548 }
00549
00550 if ((*cls)->isUnrealizable()) {
00551 int type = (*cls)->get_Type();
00552 CollectionClass *mcoll = (CollectionClass *)*cls;
00553 if (mcoll->dim == 1) {
00554 switch(type) {
00555 case _CollSetClass_Type:
00556 *cls = new CollSetClass(mcoll->coll_class, mcoll->isref);
00557 break;
00558
00559 case _CollBagClass_Type:
00560 *cls = new CollBagClass(mcoll->coll_class, mcoll->isref);
00561 break;
00562
00563 case _CollArrayClass_Type:
00564 *cls = new CollArrayClass(mcoll->coll_class, mcoll->isref);
00565 break;
00566
00567 case _CollListClass_Type:
00568 *cls = new CollListClass(mcoll->coll_class, mcoll->isref);
00569 break;
00570
00571 default:
00572 assert(0);
00573 }
00574 }
00575 else {
00576 switch(type) {
00577 case _CollSetClass_Type:
00578 *cls = new CollSetClass(mcoll->coll_class, mcoll->dim);
00579 break;
00580
00581 case _CollBagClass_Type:
00582 *cls = new CollBagClass(mcoll->coll_class, mcoll->dim);
00583 break;
00584
00585 case _CollArrayClass_Type:
00586 *cls = new CollArrayClass(mcoll->coll_class, mcoll->dim);
00587 break;
00588
00589 case _CollListClass_Type:
00590 *cls = new CollListClass(mcoll->coll_class, mcoll->dim);
00591 break;
00592
00593 default:
00594 assert(0);
00595 }
00596 }
00597 }
00598
00599 Status status;
00600 status = (*cls)->setDatabase(db);
00601
00602 if (status)
00603 return status;
00604
00605 ClassPeer::setMType(*cls, Class::System);
00606
00607 status = db->getSchema()->addClass(*cls);
00608 return status;
00609 }
00610
00611 LinkedList *CollectionClass::mcoll_list;
00612
00613 void
00614 CollectionClass::init()
00615 {
00616 mcoll_list = new LinkedList();
00617 }
00618
00619 struct CollClassLink {
00620 char *name;
00621 CollectionClass *coll;
00622
00623 CollClassLink(const char *_name, CollectionClass *_coll) {
00624 name = strdup(_name);
00625 coll = _coll;
00626 }
00627
00628 ~CollClassLink() {
00629 free(name);
00630 coll->release();
00631 }
00632 };
00633
00634 void
00635 CollectionClass::_release()
00636 {
00637 CollClassLink *l;
00638
00639 LinkedListCursor c(mcoll_list);
00640
00641 while (mcoll_list->getNextObject(&c, (void *&)l))
00642 delete l;
00643
00644 delete mcoll_list;
00645 }
00646
00647 void
00648 CollectionClass::set(const char *prefix, Class *coll_class,
00649 Bool isref, int dim, CollectionClass *coll)
00650 {
00651 const char *_name = make_name(prefix, coll_class, isref, dim, False);
00652
00653 ObjectPeer::setUnrealizable(coll, True);
00654 mcoll_list->insertObjectLast(new CollClassLink(_name, coll));
00655
00656 }
00657
00658 int
00659 CollectionClass::genODL(FILE *fd, Schema *) const
00660 {
00661 return 0;
00662 }
00663
00664 CollectionClass *
00665 CollectionClass::get(const char *prefix, Class *coll_class,
00666 Bool isref, int dim)
00667 {
00668 const char *name = make_name(prefix, coll_class, isref, dim, False);
00669 Status status;
00670
00671 CollClassLink *l;
00672
00673 LinkedListCursor c(mcoll_list);
00674 while (c.getNext((void *&)l))
00675 if (!strcmp(l->name, name))
00676 return l->coll;
00677
00678
00679 return 0;
00680 }
00681
00682
00683
00684
00685
00686 CollectionClass *
00687 CollBagClass::make(Class *coll_class, Bool isref, int dim, Status &status)
00688 {
00689 status = 0;
00690 CollectionClass *coll;
00691 if (coll = get("bag", coll_class, isref, dim))
00692 return coll;
00693
00694 if (dim > 1)
00695 coll = new CollBagClass(coll_class, dim);
00696 else
00697 coll = new CollBagClass(coll_class, isref);
00698
00699 if (coll->getStatus()) {
00700 status = coll->getStatus();
00701 return 0;
00702 }
00703
00704 set("bag", coll_class, isref, dim, coll);
00705 return coll;
00706 }
00707
00708 CollBagClass::CollBagClass(Class *_coll_class, Bool _isref) :
00709 CollectionClass(_coll_class, _isref, "bag")
00710 {
00711 type = _CollBagClass_Type;
00712 setClass(CollBagClass_Class);
00713 parent = CollBag_Class;
00714 }
00715
00716 CollBagClass::CollBagClass(Class *_coll_class, int _dim) :
00717 CollectionClass(_coll_class, _dim, "bag")
00718 {
00719 type = _CollBagClass_Type;
00720 setClass(CollBagClass_Class);
00721 parent = CollBag_Class;
00722 }
00723
00724 CollBagClass::CollBagClass(const CollBagClass &cl)
00725 : CollectionClass(cl)
00726 {
00727 }
00728
00729 CollBagClass::CollBagClass(const Oid &_oid, const char *_name) :
00730 CollectionClass(_oid, _name)
00731 {
00732 type = _CollBagClass_Type;
00733 }
00734
00735 CollBagClass& CollBagClass::operator=(const CollBagClass &cl)
00736 {
00737 this->CollectionClass::operator=(cl);
00738 return *this;
00739 }
00740
00741 Object *CollBagClass::newObj(Database *_db) const
00742 {
00743 CollBag *t;
00744
00745 if (isref) t = new CollBag(_db, "", coll_class, True);
00746 else t = new CollBag(_db, "", coll_class, dim );
00747
00748 ObjectPeer::make(t, this, 0, _CollBag_Type, idr_objsz,
00749 idr_psize, idr_vsize);
00750 return t;
00751 }
00752
00753 Object *CollBagClass::newObj(Data data, Bool _copy) const
00754 {
00755 CollBag *t;
00756
00757 if (isref) t = new CollBag("", coll_class, True);
00758 else t = new CollBag("", coll_class, dim );
00759
00760 ObjectPeer::make(t, this, data, _CollBag_Type, idr_objsz,
00761 idr_psize, idr_vsize, _copy);
00762 return t;
00763 }
00764
00765
00766
00767
00768
00769 CollectionClass *
00770 CollArrayClass::make(Class *coll_class, Bool isref, int dim, Status &status)
00771 {
00772 status = 0;
00773 CollectionClass *coll;
00774 if (coll = get("array", coll_class, isref, dim))
00775 return coll;
00776
00777 if (dim > 1)
00778 coll = new CollArrayClass(coll_class, dim);
00779 else
00780 coll = new CollArrayClass(coll_class, isref);
00781
00782 if (coll->getStatus()) {
00783 status = coll->getStatus();
00784 return 0;
00785 }
00786
00787 set("array", coll_class, isref, dim, coll);
00788 return coll;
00789 }
00790
00791 CollArrayClass::CollArrayClass(Class *_coll_class, Bool _isref) :
00792 CollectionClass(_coll_class, _isref, "array")
00793 {
00794 type = _CollArrayClass_Type;
00795 setClass(CollArrayClass_Class);
00796 parent = CollArray_Class;
00797 }
00798
00799 CollArrayClass::CollArrayClass(Class *_coll_class, int _dim) :
00800 CollectionClass(_coll_class, _dim, "array")
00801 {
00802 type = _CollArrayClass_Type;
00803 setClass(CollArrayClass_Class);
00804 parent = CollArray_Class;
00805 }
00806
00807 CollArrayClass::CollArrayClass(const CollArrayClass &cl)
00808 : CollectionClass(cl)
00809 {
00810 }
00811
00812 CollArrayClass::CollArrayClass(const Oid &_oid, const char *_name) :
00813 CollectionClass(_oid, _name)
00814 {
00815 type = _CollArrayClass_Type;
00816 }
00817
00818 CollArrayClass& CollArrayClass::operator=(const CollArrayClass &cl)
00819 {
00820 this->CollectionClass::operator=(cl);
00821 return *this;
00822 }
00823
00824 Object *CollArrayClass::newObj(Database *_db) const
00825 {
00826 CollArray *t;
00827
00828 if (isref) t = new CollArray(_db, "", coll_class, True);
00829 else t = new CollArray(_db, "", coll_class, dim );
00830
00831 ObjectPeer::make(t, this, 0, _CollArray_Type, idr_objsz,
00832 idr_psize, idr_vsize);
00833 return t;
00834 }
00835
00836 Object *CollArrayClass::newObj(Data data, Bool _copy) const
00837 {
00838 CollArray *t;
00839
00840 if (isref) t = new CollArray("", coll_class, True);
00841 else t = new CollArray("", coll_class, dim );
00842
00843 ObjectPeer::make(t, this, data, _CollArray_Type, idr_objsz,
00844 idr_psize, idr_vsize, _copy);
00845 return t;
00846 }
00847
00848
00849
00850
00851
00852 CollectionClass *
00853 CollSetClass::make(Class *coll_class, Bool isref, int dim, Status &status)
00854 {
00855 status = 0;
00856 CollectionClass *coll;
00857 if (coll = get("set", coll_class, isref, dim))
00858 return coll;
00859
00860 if (dim > 1)
00861 coll = new CollSetClass(coll_class, dim);
00862 else
00863 coll = new CollSetClass(coll_class, isref);
00864
00865 if (coll->getStatus()) {
00866 status = coll->getStatus();
00867 return 0;
00868 }
00869
00870 set("set", coll_class, isref, dim, coll);
00871 return coll;
00872 }
00873
00874 CollSetClass::CollSetClass(Class *_coll_class, Bool _isref) :
00875 CollectionClass(_coll_class, _isref, "set")
00876 {
00877 type = _CollSetClass_Type;
00878 setClass(CollSetClass_Class);
00879 parent = CollSet_Class;
00880 }
00881
00882 CollSetClass::CollSetClass(Class *_coll_class, int _dim) :
00883 CollectionClass(_coll_class, _dim, "set")
00884 {
00885 type = _CollSetClass_Type;
00886 setClass(CollSetClass_Class);
00887 parent = CollSet_Class;
00888 }
00889
00890 CollSetClass::CollSetClass(const CollSetClass &cl)
00891 : CollectionClass(cl)
00892 {
00893 }
00894
00895 CollSetClass::CollSetClass(const Oid &_oid, const char *_name) :
00896 CollectionClass(_oid, _name)
00897 {
00898 type = _CollSetClass_Type;
00899 }
00900
00901 CollSetClass& CollSetClass::operator=(const CollSetClass &cl)
00902 {
00903 this->CollectionClass::operator=(cl);
00904 return *this;
00905 }
00906
00907 Object *CollSetClass::newObj(Database *_db) const
00908 {
00909 CollSet *t;
00910
00911 if (isref) t = new CollSet(_db, "", coll_class, True);
00912 else t = new CollSet(_db, "", coll_class, dim );
00913
00914 ObjectPeer::make(t, this, 0, _CollSet_Type, idr_objsz,
00915 idr_psize, idr_vsize);
00916 return t;
00917 }
00918
00919 Object *CollSetClass::newObj(Data data, Bool _copy) const
00920 {
00921 CollSet *t;
00922
00923 if (isref) t = new CollSet("", coll_class, True);
00924 else t = new CollSet("", coll_class, dim );
00925
00926 ObjectPeer::make(t, this, data, _CollSet_Type, idr_objsz,
00927 idr_psize, idr_vsize, _copy);
00928 return t;
00929 }
00930
00931
00932
00933
00934
00935 CollectionClass *
00936 CollListClass::make(Class *coll_class, Bool isref, int dim, Status &status)
00937 {
00938 status = 0;
00939 CollectionClass *coll;
00940 if (coll = get("list", coll_class, isref, dim))
00941 return coll;
00942
00943 if (dim > 1)
00944 coll = new CollListClass(coll_class, dim);
00945 else
00946 coll = new CollListClass(coll_class, isref);
00947
00948 if (coll->getStatus()) {
00949 status = coll->getStatus();
00950 return 0;
00951 }
00952
00953 set("list", coll_class, isref, dim, coll);
00954 return coll;
00955 }
00956
00957 CollListClass::CollListClass(Class *_coll_class, Bool _isref) :
00958 CollectionClass(_coll_class, _isref, "list")
00959 {
00960 type = _CollListClass_Type;
00961 setClass(CollListClass_Class);
00962 parent = CollList_Class;
00963 }
00964
00965 CollListClass::CollListClass(Class *_coll_class, int _dim) :
00966 CollectionClass(_coll_class, _dim, "list")
00967 {
00968 type = _CollListClass_Type;
00969 setClass(CollListClass_Class);
00970 parent = CollList_Class;
00971 }
00972
00973 CollListClass::CollListClass(const CollListClass &cl)
00974 : CollectionClass(cl)
00975 {
00976 }
00977
00978 CollListClass::CollListClass(const Oid &_oid, const char *_name) :
00979 CollectionClass(_oid, _name)
00980 {
00981 type = _CollListClass_Type;
00982 }
00983
00984 CollListClass& CollListClass::operator=(const CollListClass &cl)
00985 {
00986 this->CollectionClass::operator=(cl);
00987 return *this;
00988 }
00989
00990 Object *CollListClass::newObj(Database *_db) const
00991 {
00992 CollList *t;
00993
00994 if (isref) t = new CollList(_db, "", coll_class, True);
00995 else t = new CollList(_db, "", coll_class, dim );
00996
00997 ObjectPeer::make(t, this, 0, _CollList_Type, idr_objsz,
00998 idr_psize, idr_vsize);
00999 return t;
01000 }
01001
01002 Object *CollListClass::newObj(Data data, Bool _copy) const
01003 {
01004 CollList *t;
01005
01006 if (isref) t = new CollList("", coll_class, True);
01007 else t = new CollList("", coll_class, dim );
01008
01009 ObjectPeer::make(t, this, data, _CollList_Type, idr_objsz,
01010 idr_psize, idr_vsize, _copy);
01011 return t;
01012 }
01013
01014 Status
01015 CollectionClass::setName(const char *s)
01016 {
01017 return setNameRealize(s);
01018 }
01019
01020
01021
01022
01023
01024 Status
01025 collectionClassMake(Database *db, const Oid *oid, Object **o,
01026 const RecMode *rcm, const ObjectHeader *hdr,
01027 Data idr, LockMode lockmode, const Class*)
01028 {
01029 RPCStatus rpc_status;
01030 Status status;
01031 Data temp;
01032
01033 if (!idr)
01034 {
01035 temp = (unsigned char *)malloc(hdr->size);
01036 object_header_code_head(temp, hdr);
01037
01038 rpc_status = objectRead(db->getDbHandle(), temp, 0, 0, oid->getOid(),
01039 0, lockmode, 0);
01040 }
01041 else
01042 {
01043 temp = idr;
01044 rpc_status = RPCSuccess;
01045 }
01046
01047 if (rpc_status != RPCSuccess)
01048 return StatusMake(rpc_status);
01049
01050 if (hdr && (hdr->xinfo & IDB_XINFO_REMOVED))
01051 return Exception::make(IDB_INTERNAL_ERROR,
01052 "collection class %s is removed", oid->toString());
01053
01054 char *s;
01055 Offset offset;
01056
01057
01058
01059
01060
01061
01062
01063 IndexImpl *idximpl;
01064 offset = IDB_CLASS_IMPL_TYPE;
01065 status = IndexImpl::decode(db, temp, offset, idximpl);
01066 if (status) return status;
01067
01068 eyedblib::int32 mt;
01069 offset = IDB_CLASS_MTYPE;
01070 int32_decode (temp, &offset, &mt);
01071
01072 eyedblib::int16 dspid;
01073 offset = IDB_CLASS_DSPID;
01074 int16_decode (temp, &offset, &dspid);
01075
01076 offset = IDB_CLASS_HEAD_SIZE;
01077
01078 status = class_name_decode(db->getDbHandle(), temp, &offset, &s);
01079 if (status) return status;
01080
01081 CollectionClass *mcoll;
01082
01083 eyedbsm::Oid _cl_oid;
01084 oid_decode(temp, &offset, &_cl_oid);
01085 Oid cl_oid(_cl_oid);
01086
01087 Class *coll_class;
01088
01089 coll_class = db->getSchema()->getClass(cl_oid, True);
01090
01091 if (!coll_class)
01092 coll_class = Object_Class;
01093
01094 char isref;
01095 char_decode(temp, &offset, &isref);
01096 eyedblib::int16 dim;
01097 int16_decode(temp, &offset, &dim);
01098
01099 switch(hdr->type)
01100 {
01101 case _CollSetClass_Type:
01102 if (dim > 1)
01103 mcoll = new CollSetClass(coll_class, (int)dim);
01104 else
01105 mcoll = new CollSetClass(coll_class, (Bool)isref);
01106 break;
01107
01108 case _CollBagClass_Type:
01109 if (dim > 1)
01110 mcoll = new CollBagClass(coll_class, (int)dim);
01111 else
01112 mcoll = new CollBagClass(coll_class, (Bool)isref);
01113 break;
01114
01115 case _CollArrayClass_Type:
01116 if (dim > 1)
01117 mcoll = new CollArrayClass(coll_class, (int)dim);
01118 else
01119 mcoll = new CollArrayClass(coll_class, (Bool)isref);
01120 break;
01121
01122 case _CollListClass_Type:
01123 if (dim > 1)
01124 mcoll = new CollListClass(coll_class, (int)dim);
01125 else
01126 mcoll = new CollListClass(coll_class, (Bool)isref);
01127 break;
01128
01129 default:
01130 abort();
01131 }
01132
01133 mcoll->setExtentImplementation(idximpl, True);
01134 if (idximpl)
01135 idximpl->release();
01136
01137 mcoll->setInstanceDspid(dspid);
01138
01139 Bool addedClass = False;
01140 if (!db->getSchema()->getClass(*oid))
01141 {
01142 ObjectPeer::setOid(mcoll, *oid);
01143 db->getSchema()->addClass_nocheck(mcoll, True);
01144 addedClass = True;
01145 }
01146
01147 Class *cl = NULL;
01148 Bool classAdded = False;
01149 if (!db->isOpeningState() && !db->isBackEnd())
01150 {
01151 status = mcoll->setDatabase(db);
01152 if (status)
01153 return status;
01154 }
01155 else
01156 {
01157
01158
01159 Exception::Mode mode = Exception::setMode(Exception::StatusMode);
01160 void (*handler)(Status, void *) = Exception::getHandler();
01161 Exception::setHandler(NULL);
01162
01163 Exception::setHandler(handler);
01164 Exception::setMode(mode);
01165 }
01166
01167 status = ClassPeer::makeColls(db, mcoll, temp);
01168
01169 if (addedClass)
01170 db->getSchema()->suppressClass(mcoll);
01171
01172 *o = (Object *)mcoll;
01173
01174 if (!idr)
01175 {
01176 if (!status)
01177 ObjectPeer::setIDR(*o, temp, hdr->size);
01178 }
01179
01180 free(s); s = 0;
01181 return status;
01182 }
01183
01184 #include "CollectionBE.h"
01185
01186 Status classCollectionMake(Database *db, const Oid &colloid,
01187 Collection **coll)
01188 {
01189 if (!colloid.isValid())
01190 {
01191 *coll = 0;
01192 return Success;
01193 }
01194
01195 ObjectHeader hdr;
01196
01197 RPCStatus rpc_status;
01198
01199 rpc_status = objectHeaderRead(db->getDbHandle(), colloid.getOid(), &hdr);
01200
01201 if (rpc_status != RPCSuccess)
01202 return StatusMake(rpc_status);
01203
01204 return collectionMake(db, &colloid, (Object **)coll, 0, &hdr, 0,
01205 DefaultLock, 0);
01206 }
01207 }