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
00026 #include "eyedb_p.h"
00027 #include "IteratorBE.h"
00028 #include "CollectionBE.h"
00029 #include <assert.h>
00030 #include "Attribute_p.h"
00031 #include "eyedb/gbxcyctx.h"
00032
00033 namespace eyedb {
00034
00035 #define foreach_item(X) \
00036 { \
00037 int i; \
00038 \
00039 Status status; \
00040 \
00041 for (i = 0; i < items_cnt; i++) \
00042 if (!items[i]->isNative() && ((status = items[i]->X))) \
00043 return status; \
00044 }
00045
00046
00047
00048
00049
00050 void AgregatClass::init(void)
00051 {
00052 }
00053
00054 void AgregatClass::_release(void)
00055 {
00056 }
00057
00058 Status AgregatClass::getValue(unsigned char**) const
00059 {
00060 return Success;
00061 }
00062
00063 Status AgregatClass::setValue(unsigned char*)
00064 {
00065 return Success;
00066 }
00067
00068 Status
00069 AgregatClass::setName(const char *s)
00070 {
00071 return setNameRealize(s);
00072 }
00073
00074 void
00075 AgregatClass::touch()
00076 {
00077 Class::touch();
00078 LinkedList *cl_list = IteratorBE::getMclList();
00079 if (cl_list)
00080 cl_list->insertObjectLast(this);
00081 }
00082
00083 Status AgregatClass::trace(FILE *fd, unsigned int flags, const RecMode *rcm) const
00084 {
00085 return trace_realize(fd, INDENT_INC, flags, rcm);
00086 }
00087
00088 void stop_now1() { }
00089
00090 void AgregatClass::_init(Class *_parent)
00091 {
00092 setClass(AgregatClass_Class);
00093 parent = (_parent ? _parent : Agregat_Class);
00094
00095 AttrNative::copy(ObjectITEMS, items, items_cnt, this);
00096 post_create_offset = 0;
00097 }
00098
00099 AgregatClass::AgregatClass(const char *s, Class *p) :
00100 Class(s, p)
00101 {
00102 _init(p);
00103 }
00104
00105 AgregatClass::AgregatClass(const char *s, const Oid *poid) :
00106 Class(s, poid)
00107 {
00108 _init(0);
00109 }
00110
00111 AgregatClass::AgregatClass(Database *_db, const char *s,
00112 Class *p) : Class(_db, s, p)
00113 {
00114 _init(p);
00115 }
00116
00117 AgregatClass::AgregatClass(Database *_db, const char *s,
00118 const Oid *poid) : Class(_db, s, poid)
00119 {
00120 parent = 0;
00121 setClass( AgregatClass_Class);
00122 post_create_offset = 0;
00123 }
00124
00125 AgregatClass::AgregatClass(const AgregatClass &cl)
00126 : Class(cl)
00127 {
00128 _init(0);
00129 }
00130
00131 AgregatClass::AgregatClass(const Oid &_oid, const char *_name)
00132 : Class(_oid, _name)
00133 {
00134 post_create_offset = 0;
00135 }
00136
00137 AgregatClass &AgregatClass::operator=(const AgregatClass &cl)
00138 {
00139 _init(0);
00140 this->Class::operator=(cl);
00141 return *this;
00142 }
00143
00144 Status AgregatClass::compile(void)
00145 {
00146 int n;
00147 int offset;
00148 int size, inisize;
00149 Status status;
00150
00151 offset = IDB_OBJ_HEAD_SIZE;
00152
00153 if (asUnionClass())
00154 offset += sizeof(eyedblib::int16);
00155
00156 size = 0;
00157
00158 for (n = 0; n < items_cnt; n++)
00159 if ((status = items[n]->compile_perst(this, &offset, &size, &inisize)))
00160 return status;
00161
00162 if (asUnionClass())
00163 {
00164 idr_psize = size + IDB_OBJ_HEAD_SIZE + sizeof(eyedblib::int16);
00165 offset = idr_psize;
00166 }
00167 else
00168 idr_psize = offset;
00169
00170 size = 0;
00171 idr_inisize = inisize;
00172
00173 for (n = 0; n < items_cnt; n++)
00174 if ((status = items[n]->compile_volat(this, &offset, &size)))
00175 return status;
00176
00177 if (asUnionClass())
00178 idr_vsize = size;
00179 else
00180 idr_vsize = offset - idr_psize;
00181
00182 idr_objsz = idr_psize + idr_vsize;
00183
00184
00185
00186
00187
00188
00189
00190
00191
00192 fflush(stdout);
00193
00194 return Success;
00195 }
00196
00197 void
00198 AgregatClass::newObjRealize(Object *agr) const
00199 {
00200 if (!attrs_complete)
00201 ((AgregatClass *)this)->attrsComplete();
00202
00203 for (int n = 0; n < items_cnt; n++)
00204 items[n]->newObjRealize(agr);
00205 }
00206
00207 Status
00208 AgregatClass::checkInversePath(const Schema *m,
00209 const Attribute *item,
00210 const Attribute *&invitem,
00211 Bool mandatory) const
00212 {
00213 const char *cinvname, *finvname;
00214 invitem = NULL;
00215
00216 item->getInverse(&cinvname, &finvname, &invitem);
00217
00218
00219
00220
00221
00222
00223
00224
00225 if ((!cinvname || !finvname) && !invitem)
00226 {
00227 if (mandatory)
00228 return Exception::make(IDB_ATTRIBUTE_INVERSE_ERROR,
00229 "attribute '%s::%s': "
00230 "has no inverse directive",
00231 item->getClassOwner()->getName(),
00232 item->getName());
00233
00234 return Success;
00235 }
00236
00237 if (invitem)
00238 return Success;
00239
00240 Class *cl = ((Schema *)m)->getClass(cinvname);
00241 if (!cl)
00242 return Exception::make(IDB_ATTRIBUTE_INVERSE_ERROR,
00243 "attribute '%s::%s': "
00244 "inverse class '%s' "
00245 "does not exist.",
00246 item->getClassOwner()->getName(),
00247 item->getName(), cinvname);
00248
00249 invitem = cl->getAttribute(finvname);
00250
00251 if (!invitem)
00252 return Exception::make(IDB_ATTRIBUTE_INVERSE_ERROR,
00253 "attribute '%s::%s': "
00254 "inverse attribute '%s::%s' "
00255 "does not exist.",
00256 item->getClassOwner()->getName(),
00257 item->getName(),
00258 cinvname, finvname);
00259
00260 return Success;
00261 }
00262
00263 Status AgregatClass::checkInverse(const Schema *m) const
00264 {
00265 Status s;
00266
00267 for (int i = 0; i < items_cnt; i++)
00268 {
00269 const Attribute *item = items[i];
00270 const Attribute *invitem;
00271
00272 if (s = checkInversePath(m, item, invitem, False))
00273 return s;
00274
00275 if (!invitem)
00276 continue;
00277
00278 const Attribute *invinvitem;
00279 if (s = checkInversePath(m, invitem, invinvitem, True))
00280 return s;
00281
00282 if (!invinvitem->compare(db, item))
00283 return Exception::make(IDB_ATTRIBUTE_INVERSE_ERROR,
00284 "attribute '%s::%s': "
00285 "inverse directive attribute '%s::%s' "
00286 "does not match.",
00287 name,
00288 item->getName(),
00289 invitem->getClassOwner()->getName(),
00290 invitem->getName());
00291 }
00292
00293 return Success;
00294 }
00295
00296 Status AgregatClass::create()
00297 {
00298 if (oid.isValid())
00299 return Exception::make(IDB_OBJECT_ALREADY_CREATED, "creating agregat_class '%s'", name);
00300
00301 IDB_CHECK_WRITE(db);
00302
00303 #ifdef OPTOPEN_TRACE
00304 printf("creating class %s this=%p\n", name, this);
00305 #endif
00306
00307 RPCStatus rpc_status;
00308 eyedblib::int16 kk;
00309 Size alloc_size;
00310 Offset offset, ioff;
00311 Status status;
00312
00313 alloc_size = 0;
00314 idr->setIDR((Size)0);
00315 Data data = 0;
00316 offset = IDB_CLASS_IMPL_TYPE;
00317 Status s = IndexImpl::code(data, offset, alloc_size, idximpl);
00318 if (s) return s;
00319
00320 offset = IDB_CLASS_MTYPE;
00321 eyedblib::int32 mt = m_type;
00322 int32_code (&data, &offset, &alloc_size, &mt);
00323
00324 offset = IDB_CLASS_DSPID;
00325 eyedblib::int16 dspid = get_instdspid();
00326 int16_code (&data, &offset, &alloc_size, &dspid);
00327
00328 offset = IDB_CLASS_HEAD_SIZE;
00329
00330 status = class_name_code(db->getDbHandle(), getDataspaceID(), &data, &offset,
00331 &alloc_size, name);
00332 if (status) return status;
00333
00334 if (parent && !parent->getOid().isValid() && !parent->getDatabase())
00335 parent = db->getSchema()->getClass(parent->getName());
00336
00337 if (parent && !parent->getOid().isValid()) {
00338 Status status = parent->create();
00339 if (status) return status;
00340 }
00341
00342 if (parent)
00343 oid_code (&data, &offset, &alloc_size, parent->getOid().getOid());
00344 else
00345 oid_code (&data, &offset, &alloc_size, getInvalidOid());
00346
00347 int32_code (&data, &offset, &alloc_size, (eyedblib::int32 *)&idr_psize);
00348 int32_code (&data, &offset, &alloc_size, (eyedblib::int32 *)&idr_vsize);
00349 int32_code (&data, &offset, &alloc_size, (eyedblib::int32 *)&idr_objsz);
00350 int32_code (&data, &offset, &alloc_size, (eyedblib::int32 *)&items_cnt);
00351
00352 ioff = offset;
00353 post_create_offset = ioff;
00354
00355 int i;
00356 for (i = 0; i < items_cnt; i++)
00357 items[i]->codeIDR(db, &data, &offset, &alloc_size);
00358
00359 Size idr_sz = offset;
00360 idr->setIDR(idr_sz, data);
00361 headerCode((asStructClass() ? _StructClass_Type : _UnionClass_Type),
00362 idr_sz, xinfo);
00363
00364 codeExtentCompOids(alloc_size);
00365
00366
00367 if (oid.isValid())
00368 rpc_status = objectWrite(db->getDbHandle(), data, oid.getOid());
00369 else
00370 rpc_status = objectCreate(db->getDbHandle(), getDataspaceID(),
00371 data, oid.getOid());
00372
00373 if (rpc_status == RPCSuccess) {
00374 status = ClassPeer::makeColls(db, this, data, &oid);
00375 if (status)
00376 return status;
00377 }
00378
00379 if (rpc_status == RPCSuccess) {
00380 offset = ioff;
00381 for (i = 0; i < items_cnt; i++) {
00382 Attribute *item = items[i];
00383 if (item->isNative())
00384 continue;
00385 if (!item->cls->getOid().isValid()) {
00386 if (item->cls->isUnrealizable()) {
00387 item->cls =
00388 db->getSchema()->getClass(item->cls->getName());
00389 assert(item->cls);
00390 }
00391 Status status;
00392 status = const_cast<Class *>(item->cls)->setDatabase(db);
00393 if (status)
00394 return status;
00395
00396 status = const_cast<Class *>(item->cls)->create();
00397 if (status) {
00398 if (status->getStatus() == IDB_OBJECT_ALREADY_CREATED)
00399 continue;
00400 return status;
00401 }
00402 }
00403
00404 item->codeClassOid(data, &offset);
00405
00406
00407 status = item->completeInverse(db);
00408 if (status)
00409 return status;
00410 }
00411
00412 offset = ioff;
00413 for (i = 0; i < items_cnt; i++)
00414 items[i]->codeIDR(db, &data, &offset, &alloc_size);
00415
00416 rpc_status = objectWrite(db->getDbHandle(), data, oid.getOid());
00417 }
00418
00419 return StatusMake(rpc_status);
00420 }
00421
00422 Status AgregatClass::postCreate()
00423 {
00424 if (!post_create_offset)
00425 return Success;
00426
00427 RPCStatus rpc_status;
00428 Size alloc_size;
00429 Offset offset;
00430 Status status;
00431
00432 if (!getUserData("eyedb:odl::update") && (status = createIndexes()))
00433 return status;
00434
00435 offset = post_create_offset;
00436 alloc_size = idr->getSize();
00437 Data data = idr->getIDR();
00438
00439 for (int i = 0; i < items_cnt; i++)
00440 items[i]->codeIDR(db, &data, &offset, &alloc_size);
00441
00442 if (idr->getSize() - post_create_offset > 0)
00443 rpc_status = dataWrite(db->getDbHandle(),
00444 post_create_offset,
00445 idr->getSize() - post_create_offset,
00446 idr->getIDR()+post_create_offset, oid.getOid());
00447 else
00448 rpc_status = RPCSuccess;
00449
00450 post_create_offset = 0;
00451 mustCreateComps = True;
00452
00453
00454
00455
00456
00457
00458 return StatusMake(rpc_status);
00459 }
00460
00461 Status
00462 AgregatClass::completeInverse(Schema *m)
00463 {
00464 for (int i = 0; i < items_cnt; i++)
00465 {
00466 Status s = items[i]->completeInverse(m);
00467 if (s)
00468 return s;
00469 }
00470
00471 return Success;
00472 }
00473
00474 Status AgregatClass::attrsComplete()
00475 {
00476 if (!db)
00477 return Success;
00478
00479 int err = 0;
00480 Status s = Class::attrsComplete();
00481
00482 if (s)
00483 err++;
00484
00485 setSchema(db->getSchema());
00486 BufferString buf;
00487
00488 for (int i = 0; i < items_cnt; i++)
00489 {
00490 Attribute *item = items[i];
00491 if (item->isNative())
00492 continue;
00493 Bool inv_error = False;
00494
00495 #if 0
00496 printf("attribute %s {\n", item->getName());
00497 printf("\tclass: %s ", item->oid_cl.toString());
00498 if (item->cls) {
00499 printf("vs. %s", item->cls->getOid().toString());
00500
00501
00502
00503
00504
00505
00506 }
00507 printf("\n\tclass_owner: %s ", item->oid_cl_own.toString());
00508 if (item->class_owner) {
00509 printf("vs. %s", item->class_owner->getOid().toString());
00510
00511
00512
00513
00514
00515
00516 }
00517 printf("\n}\n");
00518 #endif
00519 if (!item->cls)
00520 item->cls = getSchema()->getClass(item->oid_cl, True);
00521 assert(!item->cls || !item->cls->isRemoved());
00522 if (!item->class_owner)
00523 item->class_owner = getSchema()->getClass(item->oid_cl_own, True);
00524 assert(!item->class_owner || !item->class_owner->isRemoved());
00525 if (item->inv_spec.oid_cl.isValid())
00526 {
00527 Class *cl_inv;
00528 cl_inv = getSchema()->getClass(item->inv_spec.oid_cl);
00529
00530 if (cl_inv)
00531 item->inv_spec.item = ((AgregatClass *)cl_inv)->getAttributes()[item->inv_spec.num];
00532 else
00533 inv_error = True;
00534 }
00535
00536 if (!item->cls || !item->class_owner || inv_error)
00537 {
00538 if (!buf.length())
00539 buf.append((std::string("attributes of agregat_class '") +
00540 name + "' are incomplete: ").c_str());
00541 else
00542 buf.append(", ");
00543
00544 buf.append(item->name);
00545 if (!item->cls) buf.append(" (class attribute is missing)");
00546 else if (!item->class_owner) buf.append(" (class owner is missing)");
00547 else if (inv_error) buf.append(" (class of inverse attribute is missing)");
00548 err++;
00549 }
00550
00551 Status status = item->completeInverse(db);
00552 if (status)
00553 return status;
00554 }
00555
00556 attrs_complete = (err ? False : True);
00557
00558 if (err)
00559 return Exception::make(IDB_CLASS_COMPLETION_ERROR, buf.getString());
00560
00561 return Success;
00562 }
00563
00564 Status AgregatClass::setDatabase(Database *mdb)
00565 {
00566 Status status = Class::setDatabase(mdb);
00567
00568 if (status == Success)
00569 {
00570 for (int i = 0; i < items_cnt; i++)
00571 {
00572 Attribute *item = items[i];
00573 if (item->cls && !item->cls->getOid().isValid())
00574 {
00575 if (item->cls->isUnrealizable())
00576 {
00577 item->cls =
00578 db->getSchema()->getClass(item->cls->getName());
00579 assert(item->cls);
00580 }
00581 }
00582 }
00583 }
00584 return status;
00585 }
00586
00587 Status AgregatClass::update()
00588 {
00589 if (!modify)
00590 return Success;
00591
00592 Status status;
00593
00594 status = wholeComplete();
00595 if (status)
00596 return status;
00597
00598 RPCStatus rpc_status;
00599 eyedblib::int16 kk;
00600 Size alloc_size;
00601 Offset offset, ioff;
00602
00603 alloc_size = idr->getSize();
00604 Data data = idr->getIDR();
00605
00606
00607
00608
00609 offset = IDB_CLASS_IMPL_TYPE;
00610 status = IndexImpl::code(data, offset, alloc_size, idximpl);
00611 if (status) return status;
00612
00613 offset = IDB_CLASS_MTYPE;
00614 eyedblib::int32 mt = m_type;
00615 int32_code (&data, &offset, &alloc_size, &mt);
00616
00617 offset = IDB_CLASS_DSPID;
00618 eyedblib::int16 dspid = get_instdspid();
00619 int16_code (&data, &offset, &alloc_size, &dspid);
00620
00621 offset = IDB_CLASS_HEAD_SIZE;
00622
00623 status = class_name_code(db->getDbHandle(), getDataspaceID(), &data,
00624 &offset, &alloc_size, name);
00625 if (status) return status;
00626
00627 if (parent && !parent->getOid().isValid())
00628 {
00629 status = parent->create();
00630 if (status) return status;
00631 }
00632
00633 if (parent)
00634 oid_code (&data, &offset, &alloc_size, parent->getOid().getOid());
00635 else
00636 oid_code (&data, &offset, &alloc_size, getInvalidOid());
00637
00638 int32_code (&data, &offset, &alloc_size, (eyedblib::int32 *)&idr_psize);
00639 int32_code (&data, &offset, &alloc_size, (eyedblib::int32 *)&idr_vsize);
00640 int32_code (&data, &offset, &alloc_size, (eyedblib::int32 *)&idr_objsz);
00641 int32_code (&data, &offset, &alloc_size, (eyedblib::int32 *)&items_cnt);
00642
00643 ioff = offset;
00644
00645 int i;
00646 for (i = 0; i < items_cnt; i++) {
00647 status = items[i]->completeInverse(db);
00648 if (status) return status;
00649 }
00650
00651 for (i = 0; i < items_cnt; i++) {
00652 status = items[i]->codeIDR(db, &data, &offset, &alloc_size);
00653 if (status) return status;
00654 }
00655
00656 #if 1
00657
00658 Size idr_sz = offset;
00659
00660 if (!idr->getSize())
00661 idr->setIDR(idr_sz, data);
00662
00663 assert(idr_sz == idr->getSize());
00664 if (!getClass()->getOid().isValid())
00665 setClass(db->getSchema()->getClass(getClass()->getName()));
00666 headerCode((asStructClass() ? _StructClass_Type : _UnionClass_Type),
00667 idr_sz, xinfo);
00668 #else
00669
00670 ObjectHeader hdr;
00671 object_header_decode_head(idr->idr, &hdr);
00672 if (hdr.type != _AgregatClass_Type)
00673 {
00674 hdr.type = _AgregatClass_Type;
00675 object_header_code_head(idr->idr, &hdr);
00676 }
00677
00678 #endif
00679
00680 offset = ioff;
00681
00682 for (i = 0; i < items_cnt; i++)
00683 items[i]->codeIDR(db, &data, &offset, &alloc_size);
00684
00685 unsigned int objsize = 0;
00686 rpc_status = dataSizeGet(db->getDbHandle(), oid.getOid(), &objsize);
00687 if (!rpc_status) {
00688 if (idr->getSize() != objsize) {
00689 rpc_status = objectSizeModify(db->getDbHandle(), idr->getSize(),
00690 oid.getOid());
00691 }
00692
00693 if (!rpc_status)
00694 rpc_status = objectWrite(db->getDbHandle(), data, oid.getOid());
00695 }
00696
00697 if (!rpc_status)
00698 modify = False;
00699
00700 return StatusMake(rpc_status);
00701 }
00702
00703 void
00704 AgregatClass::revert(Bool rev)
00705 {
00706 for (int i = 0; i < items_cnt; i++)
00707 items[i]->revert(rev);
00708 }
00709
00710 Status AgregatClass::remove(const RecMode *rcm)
00711 {
00712 return Class::remove(rcm);
00713 }
00714
00715 Status AgregatClass::trace_realize(FILE *fd, int indent, unsigned int flags, const RecMode *rcm) const
00716 {
00717 return Class::trace_realize(fd, indent, flags, rcm);
00718 }
00719
00720
00721
00722
00723
00724
00725
00726
00727
00728
00729
00730
00731
00732
00733
00734
00735
00736
00737
00738
00739
00740
00741
00742
00743 Bool
00744 AgregatClass::compare_perform(const Class *cl,
00745 Bool compClassOwner,
00746 Bool compNum,
00747 Bool compName,
00748 Bool inDepth) const
00749 {
00750 if (!cl->asAgregatClass())
00751 return False;
00752
00753 const AgregatClass *ma = (AgregatClass *)cl;
00754
00755 if (asUnionClass() != ma->asUnionClass())
00756 return False;
00757
00758 if (items_cnt != ma->items_cnt)
00759 return False;
00760
00761 for (int i = 0; i < items_cnt; i++)
00762 if (!items[i]->compare(db, ma->items[i], compClassOwner, compNum,
00763 compName, inDepth))
00764 return False;
00765
00766 return True;
00767 }
00768
00769 Status
00770 agregatClassMake(Database *db, const Oid *oid, Object **o,
00771 const RecMode *rcm, const ObjectHeader *hdr,
00772 Data idr, LockMode lockmode, const Class*)
00773 {
00774 RPCStatus rpc_status;
00775 Status status;
00776 Data temp;
00777
00778 if (ObjectPeer::isRemoved(*hdr))
00779 {
00780 *o = new StructClass("<removed_class>");
00781 return Success;
00782 }
00783
00784 if (!idr)
00785 {
00786 temp = (unsigned char *)malloc(hdr->size);
00787 object_header_code_head(temp, hdr);
00788
00789 rpc_status = objectRead(db->getDbHandle(), temp, 0, 0, oid->getOid(),
00790 0, lockmode, 0);
00791 }
00792 else
00793 {
00794 temp = idr;
00795 rpc_status = RPCSuccess;
00796 }
00797
00798 if (rpc_status == RPCSuccess)
00799 {
00800 eyedblib::int16 code;
00801 eyedblib::int32 cnt;
00802 char *s;
00803 AgregatClass *ma;
00804 Offset offset;
00805
00806
00807
00808
00809
00810
00811 IndexImpl *idximpl;
00812 offset = IDB_CLASS_IMPL_TYPE;
00813 Status status = IndexImpl::decode(db, temp, offset, idximpl);
00814 if (status) return status;
00815
00816 eyedblib::int32 mt;
00817 offset = IDB_CLASS_MTYPE;
00818 int32_decode (temp, &offset, &mt);
00819
00820 eyedblib::int16 dspid;
00821 offset = IDB_CLASS_DSPID;
00822 int16_decode (temp, &offset, &dspid);
00823
00824 offset = IDB_CLASS_HEAD_SIZE;
00825 status = class_name_decode(db->getDbHandle(), temp, &offset, &s);
00826 if (status) return status;
00827
00828
00829 eyedbsm::Oid parent_oid, *poid;
00830 oid_decode(temp, &offset, &parent_oid);
00831
00832 if (isOidValid(&parent_oid))
00833 poid = &parent_oid;
00834 else
00835 poid = 0;
00836
00837 Oid ppoid(poid);
00838 if (hdr->type == _StructClass_Type)
00839 ma = new StructClass(s, &ppoid);
00840 else if (hdr->type == _UnionClass_Type)
00841 ma = new UnionClass(s, &ppoid);
00842 else
00843 return Exception::make(IDB_CLASS_READ, "agregat_class '%s' unknown code `%d'", s, code);
00844
00845 free(s); s = 0;
00846 ma->setExtentImplementation(idximpl, True);
00847 if (idximpl)
00848 idximpl->release();
00849 ma->setInstanceDspid(dspid);
00850
00851 ClassPeer::setMType(ma, (Class::MType)mt);
00852 int32_decode(temp, &offset, (eyedblib::int32 *)&ma->idr_psize);
00853 int32_decode(temp, &offset, (eyedblib::int32 *)&ma->idr_vsize);
00854 int32_decode(temp, &offset, (eyedblib::int32 *)&ma->idr_objsz);
00855 int32_decode(temp, &offset, &cnt);
00856
00857 unsigned int native_cnt;
00858 const Attribute **items_nat = ma->getAttributes(native_cnt);
00859
00860 ma->items = (Attribute **)malloc(sizeof(Attribute *) * cnt);
00861 ma->items_cnt = cnt;
00862
00863 int i;
00864
00865 #if 1
00866
00867 for (i = 0; i < native_cnt; i++)
00868 ma->items[i] = (Attribute *)items_nat[i];
00869 #else
00870 for (i = 0; i < native_cnt; i++)
00871 ma->items[i] = new AttrNative((AttrNative *)items_nat[i],
00872 items_nat[i]->getClass(),
00873 items_nat[i]->getClassOwner(),
00874 ma, i);
00875 #endif
00876
00877 free(items_nat);
00878
00879 for (i = native_cnt; i < cnt; i++)
00880 ma->items[i] = makeAttribute(db, temp, &offset, ma, i);
00881
00882 *o = (Object *)ma;
00883
00884 ObjectPeer::setOid(ma, *oid);
00885 if (!db->isOpeningState() && !db->isBackEnd()) {
00886 status = ma->setDatabase(db);
00887 if (status)
00888 return status;
00889 }
00890
00891 status = ClassPeer::makeColls(db, (Class *)*o, temp);
00892
00893 if (status != Success) {
00894 if (!idr)
00895 free(temp);
00896 return status;
00897 }
00898 }
00899
00900 if (!idr)
00901 {
00902 if (!rpc_status)
00903 ObjectPeer::setIDR(*o, temp, hdr->size);
00904 }
00905
00906 return StatusMake(rpc_status);
00907 }
00908
00909
00910 Status AgregatClass::createIndexes(void)
00911 {
00912
00913
00914
00915
00916
00917
00918
00919 return Success;
00920 }
00921
00922
00923
00924
00925 Status AgregatClass::openIndexes_realize(Database *_db)
00926 {
00927 assert(0);
00928
00929
00930
00931
00932 return Success;
00933 }
00934
00935 Status
00936 AgregatClass::createNestedIndex(AttrIdxContext &attr_idx_ctx,
00937 const AttrIdxContext *tg_idx_ctx,
00938 int _mode)
00939 {
00940 assert(0);
00941
00942
00943
00944 return Success;
00945 }
00946
00947 Status
00948 AgregatClass::removeNestedIndex(AttrIdxContext &attr_idx_ctx,
00949 const AttrIdxContext *tg_idx_ctx,
00950 int _mode)
00951 {
00952 assert(0);
00953
00954
00955
00956 return Success;
00957 }
00958
00959 static inline Oid
00960 getClassOid(Data idr)
00961 {
00962 eyedbsm::Oid oid;
00963 Oid roid;
00964 Offset offset = IDB_OBJ_HEAD_OID_MCL_INDEX;
00965 oid_decode(idr, &offset, &oid);
00966 roid.setOid(oid);
00967 return roid;
00968 }
00969
00970
00971
00972 #ifdef PERF_POOL
00973 struct CreateIndexArgs {
00974 Database *db;
00975 Data idr;
00976 const Oid *oid;
00977 AttrIdxContext *idx_ctx;
00978 const Oid *cloid;
00979 int offset;
00980 Bool novd;
00981 int count;
00982 int size;
00983 CreateIndexArgs(Database *_db, Data _idr,
00984 const Oid *_oid, AttrIdxContext *_idx_ctx,
00985 const Oid *_cloid, int _offset, Bool _novd,
00986 int _count, int _size) :
00987 db(_db), idr(_idr), oid(_oid), idx_ctx(_idx_ctx),
00988 cloid(_cloid), offset(_offset), novd(_novd), count(_count),
00989 size(_size) { }
00990 };
00991
00992 PerformerArg
00993 createIndexEntryWrapper(PerformerArg xarg)
00994 {
00995 Attribute *attr = (Attribute *)xarg.data;
00996 CreateIndexArgs *arg = (CreateIndexArgs *)attr->getUserData();
00997 AttrIdxContext idx_ctx(arg->idx_ctx);
00998 Status s = attr->createIndexEntry_realize(arg->db, arg->idr,
00999 arg->oid,
01000 arg->cloid, arg->offset,
01001 arg->novd, idx_ctx,
01002 arg->count, arg->size);
01003 return PerformerArg((void *)s);
01004 }
01005
01006 Status
01007 AgregatClass::createIndexEntries_realize(Database *_db,
01008 Data _idr,
01009 const Oid *_oid,
01010 AttrIdxContext &idx_ctx,
01011 const Oid *cloid,
01012 int offset, Bool novd,
01013 int count, int size)
01014 {
01015 Oid stoid;
01016 if (!cloid) {stoid = getClassOid(_idr); cloid = &stoid; }
01017
01018 Performer *perfs[100];
01019 CreateIndexArgs idxargs(_db, _idr, _oid, &idx_ctx, cloid, offset, novd,
01020 count, size);
01021 PerformerPool *perfpool = idbPerformerPoolManager::getPerfPool();
01022 #ifdef POOL_TRACE
01023 printf("%s: CREATE GETTING performer pool %p #1\n", name, perfpool);
01024 #endif
01025
01026 for (int i = 0; i < items_cnt; i++)
01027 if (!items[i]->isNative()) {
01028 items[i]->setUserData(&idxargs);
01029 perfs[i] = perfpool->start(createIndexEntryWrapper, items[i]);
01030 }
01031
01032 #ifdef POOL_TRACE
01033 printf("%s: CREATE GETTING performer pool %p #2\n", name, perfpool);
01034 #endif
01035 for (int i = 0; i < items_cnt; i++)
01036 if (!items[i]->isNative()) {
01037 PerformerArg arg = perfpool->wait(perfs[i]);
01038 if (arg.data) {
01039 perfpool->waitAll();
01040 if (!idx_ctx.getLevel())
01041 idx_ctx.realizeIdxOP(False);
01042 return (Status)arg.data;
01043 }
01044 }
01045
01046 if (perfpool->isProfiled()) {
01047 static int prof_cnt = 0;
01048 if (!(++prof_cnt % 20)) {
01049 unsigned int cnt;
01050 eyedblib::Thread::Profile **profiles = perfpool->getProfiles(cnt);
01051 cout << profiles << endl;
01052
01053 for (int i = 0; i < cnt; i++)
01054 delete profiles[i];
01055 delete[] profiles;
01056 }
01057 }
01058 #ifdef POOL_TRACE
01059 printf("%s: CREATE GETTING performer pool %p #3\n", name, perfpool);
01060 #endif
01061 return idx_ctx.getLevel() ? Success : idx_ctx.realizeIdxOP(True);
01062 }
01063
01064 #else
01065 Status
01066 AgregatClass::createIndexEntries_realize(Database *_db,
01067 Data _idr,
01068 const Oid *_oid,
01069 AttrIdxContext &idx_ctx,
01070 const Oid *cloid,
01071 int offset, Bool novd,
01072 int count, int size)
01073 {
01074 Oid stoid;
01075 if (!cloid) {stoid = getClassOid(_idr); cloid = &stoid; }
01076
01077 Status status;
01078 for (int i = 0; i < items_cnt; i++)
01079 if (!items[i]->isNative() && ((status = items[i]->createIndexEntry_realize(_db, _idr, _oid, cloid, offset, novd, idx_ctx, count, size))))
01080 {
01081 if (!idx_ctx.getLevel())
01082 idx_ctx.realizeIdxOP(False);
01083 return status;
01084 }
01085
01086 return idx_ctx.getLevel() ? Success : idx_ctx.realizeIdxOP(True);
01087 }
01088 #endif
01089
01090 #ifdef PERF_POOL
01091 struct UpdateIndexArgs {
01092 Database *db;
01093 Data idr;
01094 const Oid *oid;
01095 AttrIdxContext *idx_ctx;
01096 const Oid *cloid;
01097 int offset;
01098 Bool novd;
01099 const Oid *data_oid;
01100 int count;
01101 UpdateIndexArgs(Database *_db, Data _idr,
01102 const Oid *_oid, AttrIdxContext *_idx_ctx,
01103 const Oid *_cloid, int _offset, Bool _novd,
01104 const Oid *_data_oid, int _count) :
01105 db(_db), idr(_idr), oid(_oid), idx_ctx(_idx_ctx),
01106 cloid(_cloid), offset(_offset), novd(_novd), data_oid(_data_oid),
01107 count(_count) { }
01108 };
01109
01110 PerformerArg
01111 updateIndexEntryWrapper(PerformerArg xarg)
01112 {
01113 Attribute *attr = (Attribute *)xarg.data;
01114 UpdateIndexArgs *arg = (UpdateIndexArgs *)attr->getUserData();
01115 AttrIdxContext idx_ctx(arg->idx_ctx);
01116 Status s = attr->updateIndexEntry_realize(arg->db, arg->idr,
01117 arg->oid,
01118 arg->cloid, arg->offset,
01119 arg->novd, arg->data_oid,
01120 idx_ctx,
01121 arg->count);
01122 return PerformerArg((void *)s);
01123 }
01124
01125 Status
01126 AgregatClass::updateIndexEntries_realize(Database *_db,
01127 Data _idr,
01128 const Oid *_oid,
01129 AttrIdxContext &idx_ctx,
01130 const Oid *cloid,
01131 int offset, Bool novd,
01132 const Oid *data_oid,
01133 int count)
01134 {
01135 Oid stoid;
01136 if (!cloid) {stoid = getClassOid(_idr); cloid = &stoid; }
01137
01138 Performer *perfs[100];
01139 UpdateIndexArgs idxargs(_db, _idr, _oid, &idx_ctx, cloid, offset, novd,
01140 data_oid, count);
01141 PerformerPool *perfpool = idbPerformerPoolManager::getPerfPool();
01142 #ifdef POOL_TRACE
01143 printf("%s: UPDATE GETTING performer pool %p #1\n", name, perfpool);
01144 #endif
01145
01146 for (int i = 0; i < items_cnt; i++)
01147 if (!items[i]->isNative()) {
01148 items[i]->setUserData(&idxargs);
01149 perfs[i] = perfpool->start(updateIndexEntryWrapper, items[i]);
01150 }
01151
01152 #ifdef POOL_TRACE
01153 printf("%s: UPDATE GETTING performer pool %p #2\n", name, perfpool);
01154 #endif
01155 for (int i = 0; i < items_cnt; i++)
01156 if (!items[i]->isNative()) {
01157 PerformerArg arg = perfpool->wait(perfs[i]);
01158 if (arg.data) {
01159 perfpool->waitAll();
01160 if (!idx_ctx.getLevel())
01161 idx_ctx.realizeIdxOP(False);
01162 return (Status)arg.data;
01163 }
01164 }
01165
01166 #ifdef POOL_TRACE
01167 printf("%s: UPDATE GETTING performer pool %p #3\n", name, perfpool);
01168 #endif
01169 return idx_ctx.getLevel() ? Success : idx_ctx.realizeIdxOP(True);
01170 }
01171 #else
01172 Status
01173 AgregatClass::updateIndexEntries_realize(Database *_db,
01174 Data _idr,
01175 const Oid *_oid,
01176 AttrIdxContext &idx_ctx,
01177 const Oid *cloid,
01178 int offset, Bool novd,
01179 const Oid *data_oid,
01180 int count)
01181 {
01182 Oid stoid;
01183 if (!cloid) {stoid = getClassOid(_idr); cloid = &stoid; }
01184
01185 Status status;
01186 for (int i = 0; i < items_cnt; i++)
01187 if (!items[i]->isNative() &&
01188 ((status = items[i]->updateIndexEntry_realize
01189 (_db, _idr, _oid, cloid, offset, novd,
01190 data_oid, idx_ctx, count))))
01191 {
01192 if (!idx_ctx.getLevel())
01193 idx_ctx.realizeIdxOP(False);
01194 return status;
01195 }
01196
01197 return idx_ctx.getLevel() ? Success : idx_ctx.realizeIdxOP(True);
01198 }
01199 #endif
01200
01201 Status
01202 AgregatClass::removeIndexEntries_realize(Database *_db,
01203 Data _idr,
01204 const Oid *_oid,
01205 AttrIdxContext &idx_ctx,
01206 const Oid *cloid,
01207 int offset, Bool novd,
01208 const Oid *data_oid,
01209 int count)
01210 {
01211 Oid stoid;
01212 if (!cloid) {stoid = getClassOid(_idr); cloid = &stoid; }
01213
01214 foreach_item(removeIndexEntry_realize(_db, _idr, _oid, cloid, offset, novd,
01215 data_oid, idx_ctx, count));
01216
01217 return idx_ctx.getLevel() ? Success : idx_ctx.realizeIdxOP(True);
01218 }
01219
01220
01221
01222
01223
01224 Status AgregatClass::createInverses_realize(Database *_db, Data _idr, const Oid *_oid)
01225 {
01226 if (asUnionClass())
01227 {
01228 Attribute *item = (Attribute *)Union::decodeCurrentItem(this, _idr);
01229 if (item)
01230 item->createInverse_realize(_db, _idr, _oid);
01231 }
01232 else
01233 foreach_item(createInverse_realize(_db, _idr, _oid));
01234 return Success;
01235 }
01236
01237 Status AgregatClass::updateInverses_realize(Database *_db, Data _idr, const Oid *_oid)
01238 {
01239 if (asUnionClass())
01240 {
01241 Attribute *item = (Attribute *)Union::decodeCurrentItem(this, _idr);
01242 if (item)
01243 item->updateInverse_realize(_db, _idr, _oid);
01244 }
01245 else
01246 foreach_item(updateInverse_realize(_db, _idr, _oid));
01247 return Success;
01248 }
01249
01250 Status AgregatClass::removeInverses_realize(Database *_db, Data _idr, const Oid *_oid)
01251 {
01252 if (asUnionClass())
01253 {
01254 Attribute *item = (Attribute *)Union::decodeCurrentItem(this, _idr);
01255 if (item)
01256 item->removeInverse_realize(_db, _idr, _oid);
01257 }
01258 else
01259 foreach_item(removeInverse_realize(_db, _idr, _oid));
01260 return Success;
01261 }
01262
01263 void AgregatClass::garbage()
01264 {
01265 Class::garbage();
01266 }
01267
01268 AgregatClass::~AgregatClass()
01269 {
01270 garbageRealize();
01271 }
01272 }