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 #define private public
00026 #include "eyedb_p.h"
00027 #include <eyedblib/butils.h>
00028 #include "UserDataHT.h"
00029 #include <time.h>
00030 #include <sstream>
00031
00032 using std::ostringstream;
00033
00034
00035 #define NO_GARB_REALIZE
00036
00037 using namespace std;
00038
00039 namespace eyedb {
00040
00041 #define IDR_TRACE(MSG) printf("IDR: " MSG " %d => %p\n", idr_sz, idr)
00042 #undef IDR_TRACE
00043
00044 #ifdef IDR_TRACE
00045
00046 #define FREE_IDR_TRACE() if (idr) IDR_TRACE("free")
00047
00048 #define ALLOC_IDR_TRACE() if (idr_sz) IDR_TRACE("allocate")
00049
00050 #define SET_IDR_TRACE() if (idr_sz) IDR_TRACE("set")
00051
00052 #else
00053
00054 #define FREE_IDR_TRACE()
00055 #define ALLOC_IDR_TRACE()
00056 #define SET_IDR_TRACE()
00057
00058 #endif
00059
00060 Bool Object::release_cycle_detection = False;
00061
00062
00063 static std::string &getObjectTag() {
00064 static std::string ObjectTag = "eyedb::Object";
00065 return ObjectTag;
00066 }
00067
00068 void *idr_dbg;
00069
00070 void stop_alloc_dbg() {
00071 }
00072
00073 void
00074 alloc_dbg(void *idr)
00075 {
00076 if (idr != 0 && idr == idr_dbg)
00077 stop_alloc_dbg();
00078 }
00079
00080 Object::IDR::IDR(Size _idr_sz)
00081 {
00082 refcnt = 1;
00083 idr_sz = _idr_sz;
00084 idr = (unsigned char *)(idr_sz ? malloc(idr_sz) : 0);
00085 ALLOC_IDR_TRACE();
00086 alloc_dbg(idr);
00087 }
00088
00089 Object::IDR::IDR(Size _idr_sz, Data _idr)
00090 {
00091 refcnt = 1;
00092 idr_sz = _idr_sz;
00093 idr = _idr;
00094 SET_IDR_TRACE();
00095 }
00096
00097 void
00098 Object::IDR::setIDR(Size sz)
00099 {
00100 FREE_IDR_TRACE();
00101 free(idr);
00102 idr_sz = sz;
00103 idr = (unsigned char *)(idr_sz ? malloc(idr_sz) : 0);
00104 ALLOC_IDR_TRACE();
00105 alloc_dbg(idr);
00106 }
00107
00108 void
00109 Object::IDR::setIDR(Data _idr)
00110 {
00111 if (idr == _idr)
00112 return;
00113
00114 FREE_IDR_TRACE();
00115 free(idr);
00116 idr = _idr;
00117 SET_IDR_TRACE();
00118 }
00119
00120 void
00121 Object::IDR::setIDR(Size sz, Data _idr)
00122 {
00123 if (idr == _idr)
00124 {
00125 assert(idr_sz == sz);
00126 return;
00127 }
00128
00129 FREE_IDR_TRACE();
00130 free(idr);
00131
00132 idr = _idr;
00133 idr_sz = sz;
00134 SET_IDR_TRACE();
00135 }
00136
00137 Object::IDR::~IDR()
00138 {
00139 assert(refcnt <= 1);
00140 FREE_IDR_TRACE();
00141 free(idr);
00142 }
00143
00144 void Object::init(Bool _init)
00145 {
00146 state = 0;
00147 modify = False;
00148 applyingTrigger = False;
00149 dirty = False;
00150 user_data = (void *)0;
00151 user_data_ht = 0;
00152 oql_info = (void *)0;
00153 xinfo = 0;
00154
00155 dataspace = 0;
00156 dspid = Dataspace::DefaultDspid;
00157
00158 removed = False;
00159 unrealizable = False;
00160 grt_obj = False;
00161 c_time = 0;
00162 m_time = 0;
00163 master_object = 0;
00164 damaged_attr = 0;
00165
00166 if (_init) {
00167 memset(&oid, 0, sizeof(oid));
00168 db = 0;
00169 idr = new IDR(0);
00170 cls = 0;
00171 type = 0;
00172 }
00173
00174 IDB_LOG(IDB_LOG_OBJ_INIT, ("Object::init(o=%p)\n", this));
00175 }
00176
00177 void Object::initialize(Database *_db)
00178 {
00179 init(True);
00180 db = _db;
00181
00182 }
00183
00184 Object::Object(Database *_db, const Dataspace *_dataspace) : gbxObject(getObjectTag())
00185 {
00186 init(True);
00187 dataspace = _dataspace;
00188 db = _db;
00189 if (db) db->addToRegister(this);
00190 }
00191
00192 void
00193 Object::copy(const Object *o, Bool share)
00194 {
00195 IDB_LOG(IDB_LOG_OBJ_COPY, ("Object::operator=(o=%p <= %p [share=%s])\n",
00196 this, o, share ? "true" : "false"));
00197 if (!o) {
00198 init(True);
00199 return;
00200 }
00201
00202 init(False);
00203
00204 oid = o->oid;
00205 db = o->db;
00206 cls = o->cls;
00207 type = o->type;
00208 dataspace = o->dataspace;
00209 dspid = o->dspid;
00210 c_time = o->c_time;
00211 m_time = o->m_time;
00212 master_object = o->master_object;
00213
00214 if (share) {
00215 idr = o->idr;
00216 idr->incrRefCount();
00217 }
00218 else {
00219 idr = new IDR(o->idr->getSize());
00220 if (idr->getSize())
00221 memcpy(idr->getIDR(), o->idr->getIDR(), idr->getSize());
00222 }
00223
00224 if (cls)
00225 setTag(cls->getName());
00226 }
00227
00228 Object::Object(const Object *o, Bool share) : gbxObject(o)
00229 {
00230 idr = 0;
00231 copy(o, share);
00232 }
00233
00234
00235 Object::Object(const Object &o) : gbxObject(o)
00236 {
00237 idr = 0;
00238 copy(&o, False);
00239 }
00240
00241 void
00242 Object::setClass(Class *_cls)
00243 {
00244 cls = _cls;
00245 if (cls)
00246 setTag(cls->getName());
00247 }
00248
00249 void
00250 Object::setClass(const Class *_cls)
00251 {
00252 cls = const_cast<Class *>(_cls);
00253 if (cls)
00254 setTag(cls->getName());
00255 }
00256
00257 void
00258 Object::unlock_refcnt()
00259 {
00260 gbx_locked = gbxFalse;
00261 while (getRefCount() > 1)
00262 decrRefCount();
00263 }
00264
00265 Object& Object::operator=(const Object &o)
00266 {
00267 if (&o == this)
00268 return *this;
00269
00270 unlock_refcnt();
00271
00272 #ifndef NO_GARB_REALIZE
00273 garbageRealize();
00274 #endif
00275
00276 *(gbxObject *)this = gbxObject::operator=((const gbxObject &)o);
00277
00278 copy(&o, False);
00279
00280 return *this;
00281 }
00282
00283
00284
00285
00286
00287
00288
00289
00290
00291
00292
00293
00294
00295 void Object::setOid(const Oid& oid_new)
00296 {
00297 Oid oid_last = oid;
00298
00299 if (db && oid_last.isValid() && !oid_last.compare(oid_new))
00300 db->uncacheObject(this);
00301
00302 oid = oid_new;
00303 }
00304
00305 void *Object::setUserData(void *nuser_data)
00306 {
00307 void *x = user_data;
00308 user_data = nuser_data;
00309 return x;
00310 }
00311
00312 void *Object::setOQLInfo(void *noql_info)
00313 {
00314 void *x = oql_info;
00315 oql_info = noql_info;
00316 return x;
00317 }
00318
00319 void *Object::getOQLInfo()
00320 {
00321 return oql_info;
00322 }
00323
00324 Status Object::setDatabase(Database *mdb)
00325 {
00326 if (unrealizable)
00327 return Exception::make(IDB_SETDATABASE_ERROR, "object not realizable");
00328
00329 Database *odb = db;
00330
00331 if (odb &&
00332 odb != mdb &&
00333 oid.isValid() &&
00334 oid.getDbid() != mdb->getDbid())
00335 return Exception::make(IDB_SETDATABASE_ERROR,
00336 "cannot change dynamically database of "
00337 "a persistent object");
00338
00339 if (cls)
00340 {
00341 const char *name = cls->getName();
00342 cls = mdb->getSchema()->getClass(name);
00343
00344 if (!cls)
00345 return Exception::make(IDB_SETDATABASE_ERROR,
00346 "class '%s' not found in schema\n", name);
00347 }
00348
00349 if (db != mdb)
00350 {
00351 if (db)
00352 db->rmvFromRegister(this);
00353 db = mdb;
00354 if (db)
00355 db->addToRegister(this);
00356 }
00357
00358 return Success;
00359 }
00360
00361 void Object::setUnrealizable(Bool _unrealizable)
00362 {
00363 unrealizable = _unrealizable;
00364 if (unrealizable)
00365 {
00366 db = 0;
00367 setOid(*getInvalidOid());
00368 }
00369 }
00370
00371
00372
00373
00374
00375
00376
00377
00378
00379
00380
00381
00382
00383
00384
00385
00386
00387
00388 void Object::headerCode(eyedblib::int32 t, eyedblib::int32 size, eyedblib::int32 _xinfo)
00389 {
00390 ObjectHeader hdr;
00391
00392 memset(&hdr, 0, sizeof(hdr));
00393
00394 hdr.type = t;
00395 hdr.size = size;
00396 hdr.xinfo = _xinfo;
00397
00398 if (cls)
00399 hdr.oid_cl = *cls->getOid().getOid();
00400
00401 object_header_code_head(idr->getIDR(), &hdr);
00402
00403 if (eyedb_is_type(hdr, _Class_Type))
00404 memset(idr->getIDR() + IDB_CLASS_COLL_START, 0,
00405 IDB_CLASS_COLLS_CNT * sizeof(eyedbsm::Oid));
00406 }
00407
00408 void Object::classOidCode(void)
00409 {
00410 Offset offset = IDB_OBJ_HEAD_OID_MCL_INDEX;
00411 Size alloc_size = IDB_OBJ_HEAD_SIZE;
00412
00413 Data data = idr->getIDR();
00414 oid_code(&data, &offset, &alloc_size, cls->getOid().getOid());
00415 }
00416
00417 Status Object::realize(const RecMode *rcm)
00418 {
00419 if (state & Realizing)
00420 return Success;
00421
00422 CHK_OBJ(this);
00423
00424 if (master_object)
00425 return master_object->realize(rcm);
00426
00427 Status status;
00428 state |= Realizing;
00429
00430 if (!oid.isValid())
00431 status = create();
00432 else
00433 status = update();
00434
00435 if (!status)
00436 {
00437 modify = False;
00438 applyingTrigger = False;
00439 dirty = False;
00440 }
00441
00442 state &= ~Realizing;
00443 return status;
00444 }
00445
00446 Bool Object::traceRemoved(FILE *fd, const char *indent_str) const
00447 {
00448 if (removed)
00449 {
00450 fprintf(fd, "%s<object removed>\n", indent_str);
00451 return True;
00452 }
00453 return False;
00454 }
00455
00456 Status Object::remove(const RecMode *rcm)
00457 {
00458 return remove_r(rcm);
00459 }
00460
00461 Status Object::remove_r(const RecMode *rcm, unsigned int flags)
00462 {
00463 if (removed)
00464 return Exception::make(IDB_OBJECT_REMOVE_ERROR, "object %s already removed", oid.toString());
00465 if (!oid.isValid())
00466 return Exception::make(IDB_OBJECT_REMOVE_ERROR, "invalid object to remove");
00467
00468 IDB_CHECK_WRITE(db);
00469
00470 RPCStatus rpc_status;
00471
00472 rpc_status = objectDelete(db->getDbHandle(), oid.getOid(), flags);
00473
00474 if (rpc_status == RPCSuccess)
00475 {
00476 db->uncacheObject(this);
00477 removed = True;
00478 }
00479
00480 return StatusMake(rpc_status);
00481 }
00482
00483 #define ObjectMagicDeleted 6666666
00484
00485 void Object::garbage()
00486 {
00487 IDB_LOG(IDB_LOG_OBJ_GARBAGE,
00488 ("Object::garbage(o=%p, oid=%s, class=\"%s\", "
00489 "idr=%p, idr:refcnt=%d)\n",
00490 this, oid.toString(), cls ? cls->getName() : "<unknown>",
00491 idr->getIDR(), idr->getRefCount()));
00492
00493 if (db)
00494 {
00495 db->uncacheObject(this);
00496 db->rmvFromRegister(this);
00497 }
00498
00499 if (!idr->decrRefCount())
00500 {
00501 delete idr;
00502 idr = 0;
00503 }
00504
00505 delete user_data_ht;
00506 }
00507
00508
00509 Object::~Object()
00510 {
00511 garbageRealize();
00512 }
00513
00514
00515
00516
00517
00518
00519
00520
00521 void Object::touch()
00522 {
00523 modify = True;
00524
00525
00526
00527
00528 }
00529
00530 Status
00531 Object::setLock(LockMode lockmode)
00532 {
00533 return db->setObjectLock(oid, lockmode);
00534 }
00535
00536 Status
00537 Object::setLock(LockMode lockmode, LockMode &alockmode)
00538 {
00539 return db->setObjectLock(oid, lockmode, alockmode);
00540 }
00541
00542 Status
00543 Object::getLock(LockMode &lockmode)
00544 {
00545 return db->getObjectLock(oid, lockmode);
00546 }
00547
00548 eyedbsm::Oid ClassOidDecode(Data idr)
00549 {
00550 Offset offset = IDB_OBJ_HEAD_OID_MCL_INDEX;
00551 eyedbsm::Oid oid;
00552
00553 oid_decode(idr, &offset, &oid);
00554 return oid;
00555 }
00556
00557 const char *Object::getStringCTime() const
00558 {
00559 return eyedblib::setbuftime(c_time);
00560 }
00561
00562 const char *Object::getStringMTime() const
00563 {
00564 return eyedblib::setbuftime(m_time);
00565 }
00566
00567 void
00568 Object::trace_flags(FILE *fd, unsigned int flags) const
00569 {
00570 if (flags & PointerTrace)
00571 fprintf(fd, "[this = 0x%x] ", this);
00572
00573 if (oid.isValid())
00574 {
00575 if ((flags & CMTimeTrace) == CMTimeTrace)
00576 fprintf(fd, "ctime = %s / mtime = %s",
00577 getStringCTime(), getStringMTime());
00578 else if ((flags & CTimeTrace) == CTimeTrace)
00579 fprintf(fd, "ctime = %s", getStringCTime());
00580 else if ((flags & MTimeTrace) == MTimeTrace)
00581 fprintf(fd, "mtime = %s", getStringMTime());
00582 }
00583 }
00584
00585 Status
00586 Object::apply(Database *_db, Method *mth, ArgArray &argarray,
00587 Argument &retarg, Bool checkArgs)
00588 {
00589 return mth->applyTo(_db, this, argarray, retarg, checkArgs);
00590 }
00591
00592 const Object *Object::getMasterObject(bool recurs) const
00593 {
00594 return const_cast<Object *>(this)->getMasterObject(recurs);
00595 }
00596
00597 Object *Object::getMasterObject(bool recurs)
00598 {
00599 if (!recurs || !master_object)
00600 return master_object;
00601
00602 assert(recurs && master_object);
00603
00604 if (master_object->getMasterObject(false))
00605 return master_object->getMasterObject(true);
00606
00607 return master_object;
00608 }
00609
00610 Status
00611 Object::setMasterObject(Object *_master_object)
00612 {
00613 master_object = _master_object;
00614 return Success;
00615 }
00616
00617 Status
00618 Object::releaseMasterObject()
00619 {
00620 master_object = 0;
00621
00622
00623
00624
00625
00626
00627
00628
00629 return Success;
00630 }
00631
00632 Status
00633 Object::setProtection(const Oid &prot_oid)
00634 {
00635 if (!db)
00636 return Exception::make(IDB_ERROR, "no database associated with object");
00637 return db->setObjectProtection(oid, prot_oid);
00638 }
00639
00640 Status
00641 Object::setProtection(Protection *prot)
00642 {
00643 if (!db)
00644 return Exception::make(IDB_ERROR, "no database associated with object");
00645 return db->setObjectProtection(oid, prot);
00646 }
00647
00648 Status
00649 Object::getProtection(Oid &prot_oid) const
00650 {
00651 if (!db)
00652 return Exception::make(IDB_ERROR, "no database associated with object");
00653 prot_oid = oid_prot;
00654 return Success;
00655
00656 }
00657
00658 Status
00659 Object::getProtection(Protection *&prot) const
00660 {
00661 if (!db)
00662 return Exception::make(IDB_ERROR, "no database associated with object");
00663
00664 if (oid_prot.isValid())
00665 return db->loadObject(&oid_prot, (Object **)&prot);
00666
00667 prot = NULL;
00668 return Success;
00669
00670 }
00671
00672
00673
00674
00675
00676 #define TRY_GETELEMS_GC
00677
00678 ObjectArray::ObjectArray(Object **_objs, unsigned int _count)
00679 {
00680 objs = 0;
00681 count = 0;
00682 auto_garb = False;
00683 set(_objs, _count);
00684 }
00685
00686 ObjectArray::ObjectArray(bool _auto_garb, Object **_objs, unsigned int _count)
00687 {
00688 objs = 0;
00689 count = 0;
00690 auto_garb = _auto_garb;
00691 set(_objs, _count);
00692 }
00693
00694 ObjectArray::ObjectArray(const Collection *coll, bool _auto_garb)
00695 {
00696 objs = 0;
00697 count = 0;
00698 auto_garb = _auto_garb;
00699 coll->getElements(*this);
00700 }
00701
00702 void ObjectArray::set(Object **_objs, unsigned int _count)
00703 {
00704
00705 #ifdef TRY_GETELEMS_GC
00706 if (auto_garb && _count && !_objs)
00707 throw *Exception::make(IDB_ERROR,
00708 "cannot set an auto-garbaged object array "
00709 "for %d objets with no object pointer",
00710 _count);
00711
00712 #endif
00713 if (auto_garb)
00714 garbage();
00715
00716 free(objs);
00717
00718 int sz = _count * sizeof(Object *);
00719 objs = (Object **)malloc(sz);
00720 if (_objs)
00721 memcpy(objs, _objs, sz);
00722 count = _count;
00723
00724 #ifdef TRY_GETELEMS_GC
00725 if (auto_garb) {
00726 for (int n = 0; n < count; n++) {
00727 if (objs[n]) {
00728 objs[n]->incrRefCount();
00729 }
00730 }
00731 }
00732 #endif
00733 }
00734
00735 void ObjectArray::setMustRelease(bool must_release)
00736 {
00737 for (int i = 0; i < count; i++)
00738 if (objs[i])
00739 objs[i]->setMustRelease(must_release);
00740 }
00741
00742 ObjectArray::ObjectArray(const ObjectArray &objarr)
00743 {
00744 count = 0;
00745 objs = 0;
00746 auto_garb = False;
00747 *this = objarr;
00748 }
00749
00750 Status ObjectArray::setObjectAt(unsigned int ind, Object *o)
00751 {
00752 if (ind >= count)
00753 return Exception::make(IDB_ERROR, "invalid range %d (maximun is %d)",
00754 ind, count);
00755 if (objs[ind] == o)
00756 return Success;
00757
00758 #ifdef TRY_GETELEMS_GC
00759 if (auto_garb) {
00760
00761 if (objs[ind])
00762 objs[ind]->release();
00763
00764 objs[ind] = o;
00765
00766 if (objs[ind])
00767 objs[ind]->incrRefCount();
00768
00769 return Success;
00770 }
00771 #endif
00772
00773 objs[ind] = o;
00774 return Success;
00775 }
00776
00777 ObjectArray::ObjectArray(const ObjectList &list)
00778 {
00779 count = 0;
00780 auto_garb = False;
00781
00782 int cnt = list.getCount();
00783 if (!cnt)
00784 {
00785 objs = 0;
00786 return;
00787 }
00788
00789 objs = (Object **)malloc(sizeof(Object *) * cnt);
00790
00791 ObjectListCursor c(list);
00792 Object *o;
00793
00794 for (; c.getNext(o); count++) {
00795 objs[count] = o;
00796
00797
00798
00799
00800
00801
00802
00803 }
00804 }
00805
00806 ObjectArray& ObjectArray::operator=(const ObjectArray &objarr)
00807 {
00808 set(objarr.objs, objarr.count);
00809 #ifndef TRY_GETELEMS_GC
00810 auto_garb = objarr.auto_garb;
00811 #endif
00812 return *this;
00813 }
00814
00815 void ObjectArray::garbage()
00816 {
00817 for (int i = 0; i < count; i++)
00818 if (objs[i]) {
00819 objs[i]->release();
00820 objs[i] = 0;
00821 }
00822 }
00823
00824 ObjectList *
00825 ObjectArray::toList() const
00826 {
00827 return new ObjectList(*this);
00828 }
00829
00830 void ObjectArray::makeObjectPtrVector(ObjectPtrVector &obj_vect)
00831 {
00832 for (int n = 0; n < count; n++)
00833 obj_vect.push_back(objs[n]);
00834 }
00835
00836 ObjectArray::~ObjectArray()
00837 {
00838 if (auto_garb)
00839 garbage();
00840
00841 free(objs);
00842 }
00843
00844 extern ostream&
00845 tmpfile2stream(const char *file, ostream& os, FILE *fd);
00846
00847 ostream& operator<<(ostream& os, const ObjectPtr &o_ptr)
00848 {
00849 return os << o_ptr.getObject();
00850 }
00851
00852 ostream& operator<<(ostream& os, const Object &o)
00853 {
00854 return os << &o;
00855 }
00856
00857 ostream& operator<<(ostream& os, const Object *o)
00858 {
00859 if (!o)
00860 return os << "NULL\n";
00861
00862 Status s = o->trace(get_file());
00863 if (s) return os << s->getDesc();
00864 return convert_to_stream(os);
00865 }
00866
00867 std::string
00868 Object::toString(unsigned int flags, const RecMode *rcm,
00869 Status *pstatus) const
00870 {
00871 Status status = trace(get_file(), flags, rcm);
00872 if (status) {
00873 if (pstatus) *pstatus = status;
00874 return status->getDesc();
00875 }
00876
00877 ostringstream ostr;
00878 convert_to_stream(ostr);
00879
00880
00881
00882 std::string s(ostr.str());
00883 if (pstatus) *pstatus = Success;
00884 return s;
00885 }
00886
00887 void
00888 Object::freeList(LinkedList *list, Bool wipeOut)
00889 {
00890 if (!list)
00891 return;
00892
00893 if (wipeOut)
00894 {
00895 Object *o;
00896 LinkedListCursor c(list);
00897
00898 while (c.getNext((void *&)o))
00899 o->release();
00900 }
00901
00902 delete list;
00903 }
00904
00905
00906 LinkedList *
00907 Object::copyList(const LinkedList *list, Bool copy)
00908 {
00909 if (!list)
00910 return (LinkedList *)0;
00911
00912 LinkedList *rlist = new LinkedList();
00913 Object *o;
00914
00915 LinkedListCursor c(list);
00916
00917 while (c.getNext((void *&)o))
00918 rlist->insertObject(copy && o ? o->clone() : o);
00919
00920 return rlist;
00921 }
00922
00923
00924
00925
00926
00927 ObjectList::ObjectList()
00928 {
00929 list = new LinkedList();
00930 }
00931
00932 ObjectList::ObjectList(const ObjectArray &obj_array)
00933 {
00934 list = new LinkedList();
00935 for (int i = 0; i < obj_array.getCount(); i++)
00936 insertObjectLast(const_cast<Object *>(obj_array[i]));
00937 }
00938
00939 int ObjectList::getCount(void) const
00940 {
00941 return list->getCount();
00942 }
00943
00944 void
00945 ObjectList::insertObject(Object *o)
00946 {
00947 list->insertObject(o);
00948 }
00949
00950 void
00951 ObjectList::insertObjectFirst(Object *o)
00952 {
00953 list->insertObjectFirst(o);
00954 }
00955
00956 void
00957 ObjectList::insertObjectLast(Object *o)
00958 {
00959 list->insertObjectLast(o);
00960 }
00961
00962 Bool
00963 ObjectList::suppressObject(Object *o)
00964 {
00965 return list->deleteObject(o) ? True : False;
00966 }
00967
00968 Bool
00969 ObjectList::exists(const Object *o) const
00970 {
00971 return list->getPos((void *)o) >= 0 ? True : False;
00972 }
00973
00974 void
00975 ObjectList::empty()
00976 {
00977 list->empty();
00978 }
00979
00980 ObjectArray *
00981 ObjectList::toArray() const
00982 {
00983 int cnt = list->getCount();
00984 if (!cnt)
00985 return new ObjectArray();
00986 Object **arr = (Object **)malloc(sizeof(Object *) * cnt);
00987
00988 LinkedListCursor c(list);
00989 for (int i = 0; c.getNext((void *&)arr[i]); i++)
00990 ;
00991
00992 ObjectArray *obj_arr = new ObjectArray(arr, cnt);
00993 free(arr);
00994 return obj_arr;
00995 }
00996
00997 ObjectList::~ObjectList()
00998 {
00999 delete list;
01000 }
01001
01002 ObjectListCursor::ObjectListCursor(const ObjectList &oidlist)
01003 {
01004 c = new LinkedListCursor(oidlist.list);
01005 }
01006
01007 ObjectListCursor::ObjectListCursor(const ObjectList *oidlist)
01008 {
01009 c = new LinkedListCursor(oidlist->list);
01010 }
01011
01012 Bool
01013 ObjectListCursor::getNext(Object *&o)
01014 {
01015 return c->getNext((void *&)o) ? True : False;
01016 }
01017
01018 ObjectListCursor::~ObjectListCursor()
01019 {
01020 delete c;
01021 }
01022
01023 Status
01024 Object::loadPerform(const Oid&, LockMode,AttrIdxContext &idx_ctx,
01025 const RecMode*)
01026 {
01027 return Success;
01028 }
01029
01030 Status
01031 Object::removePerform(const Oid&, const Oid&, AttrIdxContext&, const RecMode*)
01032 {
01033 return Success;
01034 }
01035
01036 Status
01037 Object::realizePerform(const Oid&, const Oid&, AttrIdxContext&, const RecMode*)
01038 {
01039 CHK_OBJ(this);
01040 return Success;
01041 }
01042
01043 Status
01044 Object::getDataspace(const Dataspace *&_dataspace,
01045 Bool refetch) const
01046 {
01047
01048
01049
01050
01051
01052
01053
01054
01055
01056
01057
01058
01059
01060
01061
01062
01063
01064
01065
01066 _dataspace = 0;
01067
01068 if (oid.isValid() && ((!dataspace && dspid == Dataspace::DefaultDspid) ||
01069 refetch)) {
01070 ObjectLocation objloc;
01071 Status s = getLocation(objloc);
01072 if (s)
01073 return s;
01074 const_cast<Object *>(this)->dspid = objloc.getDspid();
01075 s = db->getDataspace(dspid, _dataspace);
01076 if (s)
01077 return s;
01078 const_cast<Object *>(this)->dataspace = _dataspace;
01079 return Success;
01080 }
01081
01082 if (dataspace) {
01083 _dataspace = dataspace;
01084 return Success;
01085 }
01086
01087 if (dspid != Dataspace::DefaultDspid) {
01088 Status s = db->getDataspace(dspid, _dataspace);
01089 if (s)
01090 return s;
01091 const_cast<Object *>(this)->dataspace = _dataspace;
01092 return Success;
01093 }
01094
01095 return Success;
01096 }
01097
01098 Status
01099 Object::getLocation(ObjectLocation &loc) const
01100 {
01101 OidArray oid_arr(&oid, 1);
01102 ObjectLocationArray locarr;
01103 Status s = db->getObjectLocations(oid_arr, locarr);
01104 if (s)
01105 return s;
01106 loc = locarr.getLocation(0);
01107 return Success;
01108 }
01109
01110
01111 Status
01112 Object::setDataspace(const Dataspace *_dataspace)
01113 {
01114
01115
01116
01117
01118
01119
01120
01121
01122
01123
01124
01125
01126 Status s = getDataspace(dataspace);
01127 if (s)
01128 return s;
01129
01130 if (oid.isValid() && dataspace && dataspace->getId() != _dataspace->getId())
01131 return Exception::make(IDB_ERROR, "use the move method to change the "
01132 "dataspace [#%d to #%d] on the already "
01133 "created object %s", dataspace->getId(),
01134 _dataspace->getId(), oid.toString());
01135
01136
01137 dataspace = _dataspace;
01138 dspid = dataspace->getId();
01139 return Success;
01140 }
01141
01142 Status
01143 Object::move(const Dataspace *_dataspace)
01144 {
01145 OidArray oid_arr(&oid, 1);
01146 return db->moveObjects(oid_arr, _dataspace);
01147
01148
01149
01150
01151 }
01152
01153 short
01154 Object::getDataspaceID() const
01155 {
01156 if (dataspace)
01157 return dataspace->getId();
01158
01159
01160
01161
01162
01163
01164
01165
01166
01167
01168
01169
01170
01171
01172 return dspid;
01173 }
01174
01175 void
01176 Object::setDspid(short _dspid)
01177 {
01178 dspid = _dspid;
01179 }
01180
01181 void *
01182 Object::setUserData(const char *s, void *x)
01183 {
01184 void *r = getUserData(s);
01185
01186 if (!user_data_ht)
01187 user_data_ht = new UserDataHT();
01188
01189 user_data_ht->insert(s, x);
01190 return r;
01191 }
01192
01193 void *
01194 Object::getUserData(const char *s)
01195 {
01196 if (!user_data_ht)
01197 return (void *)0;
01198
01199 return user_data_ht->get(s);
01200 }
01201
01202 const void *
01203 Object::getUserData(const char *s) const
01204 {
01205 if (!user_data_ht)
01206 return (void *)0;
01207
01208 return user_data_ht->get(s);
01209 }
01210
01211 void
01212 Object::getAllUserData(LinkedList *&key_list, LinkedList *&data_list) const
01213 {
01214 if (!user_data_ht) {
01215 key_list = new LinkedList();
01216 data_list = new LinkedList();
01217 return;
01218 }
01219
01220 user_data_ht->getall(key_list, data_list);
01221 }
01222
01223 gbxBool
01224 Object::grant_release()
01225 {
01226
01227 return gbxTrue;
01228 }
01229
01230 void
01231 Object::setDamaged(const Attribute *_damaged_attr)
01232 {
01233 damaged_attr = _damaged_attr;
01234
01235 }
01236
01237 Bool
01238 Object::setReleaseCycleDetection(Bool x)
01239 {
01240 Bool o = release_cycle_detection;
01241 release_cycle_detection = x;
01242 return o;
01243 }
01244
01245 ObjectReleaser::ObjectReleaser(Object *_o)
01246 {
01247 o = _o;
01248 dont_release = False;
01249 }
01250
01251 Object *
01252 ObjectReleaser::dontRelease()
01253 {
01254 dont_release = True;
01255 return o;
01256 }
01257
01258 ObjectReleaser::~ObjectReleaser()
01259 {
01260 if (!dont_release)
01261 o->release();
01262 }
01263
01264 ObjectListReleaser::ObjectListReleaser()
01265 {
01266 dont_release = False;
01267 }
01268
01269 void
01270 ObjectListReleaser::add(Object *o)
01271 {
01272 list.insertObject(o);
01273 }
01274
01275 void
01276 ObjectListReleaser::dontRelease()
01277 {
01278 dont_release = True;
01279 }
01280
01281 ObjectListReleaser::~ObjectListReleaser()
01282 {
01283 if (!dont_release) {
01284 LinkedListCursor c(list);
01285 Object *o;
01286 while (c.getNext((void *&)o))
01287 o->release();
01288 }
01289 }
01290
01291 ObjectObserver::ObjectObserver(const std::string &tag) :
01292 gbxObserver(tag)
01293 {
01294 }
01295
01296 void ObjectObserver::addObj(gbxObject *o)
01297 {
01298 if (o->getPTag() == getObjectTag()) {
01299 gbxObserver::addObj(o);
01300 }
01301 }
01302
01303 void ObjectObserver::rmvObj(gbxObject *_o)
01304 {
01305
01306
01307
01308
01309 if (_o->getPTag() == getObjectTag()) {
01310 gbxObserver::rmvObj(_o);
01311 }
01312 }
01313
01314 ObjectObserver::~ObjectObserver() {
01315 }
01316
01317 void ObjectObserver::getObjects(std::vector<Object *> &ov) const
01318 {
01319 std::map<gbxObject *, bool>::const_iterator begin = obj_map->begin();
01320 std::map<gbxObject *, bool>::const_iterator end = obj_map->end();
01321
01322 ov.erase(ov.begin(), ov.end());
01323 while (begin != end) {
01324 gbxObject *o = (*begin).first;
01325 if (o->getPTag() != getObjectTag()) {
01326
01327 std::cerr << "eyedb::Observer error: " << (void *)(*begin).first <<
01328 " is not an eyedb::Object\n";
01329 }
01330 else
01331 ov.push_back((eyedb::Object *)o);
01332 ++begin;
01333 }
01334 }
01335
01336 bool ObjectObserver::isObjectRegistered(Object *o) const
01337 {
01338 return gbxObserver::isObjectRegistered(o);
01339 }
01340
01341 }