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 Status Object::store(const RecMode *recmode)
00362 {
00363 bool realizeBlock = db && recmode != RecMode::NoRecurs;
00364 if (realizeBlock) {
00365 db->beginRealize();
00366 }
00367
00368 Status s = realize(recmode);
00369 if (realizeBlock) {
00370 db->endRealize();
00371 }
00372 return s;
00373 }
00374
00375 void Object::setUnrealizable(Bool _unrealizable)
00376 {
00377 unrealizable = _unrealizable;
00378 if (unrealizable) {
00379 db = 0;
00380 setOid(*getInvalidOid());
00381 }
00382 }
00383
00384
00385
00386
00387
00388
00389
00390
00391
00392
00393
00394
00395
00396
00397
00398
00399
00400
00401 void Object::headerCode(eyedblib::int32 t, eyedblib::int32 size, eyedblib::int32 _xinfo)
00402 {
00403 ObjectHeader hdr;
00404
00405 memset(&hdr, 0, sizeof(hdr));
00406
00407 hdr.type = t;
00408 hdr.size = size;
00409 hdr.xinfo = _xinfo;
00410
00411 if (cls)
00412 hdr.oid_cl = *cls->getOid().getOid();
00413
00414 object_header_code_head(idr->getIDR(), &hdr);
00415
00416 if (eyedb_is_type(hdr, _Class_Type))
00417 memset(idr->getIDR() + IDB_CLASS_COLL_START, 0,
00418 IDB_CLASS_COLLS_CNT * sizeof(eyedbsm::Oid));
00419 }
00420
00421 void Object::classOidCode(void)
00422 {
00423 Offset offset = IDB_OBJ_HEAD_OID_MCL_INDEX;
00424 Size alloc_size = IDB_OBJ_HEAD_SIZE;
00425
00426 Data data = idr->getIDR();
00427 oid_code(&data, &offset, &alloc_size, cls->getOid().getOid());
00428 }
00429
00430 Status Object::realize(const RecMode *rcm)
00431 {
00432 if (state & Realizing)
00433 return Success;
00434
00435 CHK_OBJ(this);
00436
00437 if (master_object)
00438 return master_object->realize(rcm);
00439
00440 Status status;
00441 state |= Realizing;
00442
00443 if (!oid.isValid())
00444 status = create();
00445 else
00446 status = update();
00447
00448 if (!status)
00449 {
00450 modify = False;
00451 applyingTrigger = False;
00452 dirty = False;
00453 }
00454
00455 state &= ~Realizing;
00456 return status;
00457 }
00458
00459 Bool Object::traceRemoved(FILE *fd, const char *indent_str) const
00460 {
00461 if (removed)
00462 {
00463 fprintf(fd, "%s<object removed>\n", indent_str);
00464 return True;
00465 }
00466 return False;
00467 }
00468
00469 Status Object::remove(const RecMode *rcm)
00470 {
00471 return remove_r(rcm);
00472 }
00473
00474 Status Object::remove_r(const RecMode *rcm, unsigned int flags)
00475 {
00476 if (removed)
00477 return Exception::make(IDB_OBJECT_REMOVE_ERROR, "object %s already removed", oid.toString());
00478 if (!oid.isValid())
00479 return Exception::make(IDB_OBJECT_REMOVE_ERROR, "invalid object to remove");
00480
00481 IDB_CHECK_WRITE(db);
00482
00483 RPCStatus rpc_status;
00484
00485 rpc_status = objectDelete(db->getDbHandle(), oid.getOid(), flags);
00486
00487 if (rpc_status == RPCSuccess)
00488 {
00489 db->uncacheObject(this);
00490 removed = True;
00491 }
00492
00493 return StatusMake(rpc_status);
00494 }
00495
00496 #define ObjectMagicDeleted 6666666
00497
00498 void Object::garbage()
00499 {
00500 IDB_LOG(IDB_LOG_OBJ_GARBAGE,
00501 ("Object::garbage(o=%p, oid=%s, class=\"%s\", "
00502 "idr=%p, idr:refcnt=%d)\n",
00503 this, oid.toString(), cls ? cls->getName() : "<unknown>",
00504 idr->getIDR(), idr->getRefCount()));
00505
00506 if (db)
00507 {
00508 db->uncacheObject(this);
00509 db->rmvFromRegister(this);
00510 }
00511
00512 if (!idr->decrRefCount())
00513 {
00514 delete idr;
00515 idr = 0;
00516 }
00517
00518 delete user_data_ht;
00519 }
00520
00521
00522 Object::~Object()
00523 {
00524 garbageRealize();
00525 }
00526
00527
00528
00529
00530
00531
00532
00533
00534 void Object::touch()
00535 {
00536 modify = True;
00537
00538
00539
00540
00541 }
00542
00543 Status
00544 Object::setLock(LockMode lockmode)
00545 {
00546 return db->setObjectLock(oid, lockmode);
00547 }
00548
00549 Status
00550 Object::setLock(LockMode lockmode, LockMode &alockmode)
00551 {
00552 return db->setObjectLock(oid, lockmode, alockmode);
00553 }
00554
00555 Status
00556 Object::getLock(LockMode &lockmode)
00557 {
00558 return db->getObjectLock(oid, lockmode);
00559 }
00560
00561 eyedbsm::Oid ClassOidDecode(Data idr)
00562 {
00563 Offset offset = IDB_OBJ_HEAD_OID_MCL_INDEX;
00564 eyedbsm::Oid oid;
00565
00566 oid_decode(idr, &offset, &oid);
00567 return oid;
00568 }
00569
00570 const char *Object::getStringCTime() const
00571 {
00572 return eyedblib::setbuftime(c_time);
00573 }
00574
00575 const char *Object::getStringMTime() const
00576 {
00577 return eyedblib::setbuftime(m_time);
00578 }
00579
00580 void
00581 Object::trace_flags(FILE *fd, unsigned int flags) const
00582 {
00583 if (flags & PointerTrace)
00584 fprintf(fd, "[this = 0x%x] ", this);
00585
00586 if (oid.isValid())
00587 {
00588 if ((flags & CMTimeTrace) == CMTimeTrace)
00589 fprintf(fd, "ctime = %s / mtime = %s",
00590 getStringCTime(), getStringMTime());
00591 else if ((flags & CTimeTrace) == CTimeTrace)
00592 fprintf(fd, "ctime = %s", getStringCTime());
00593 else if ((flags & MTimeTrace) == MTimeTrace)
00594 fprintf(fd, "mtime = %s", getStringMTime());
00595 }
00596 }
00597
00598 Status
00599 Object::apply(Database *_db, Method *mth, ArgArray &argarray,
00600 Argument &retarg, Bool checkArgs)
00601 {
00602 return mth->applyTo(_db, this, argarray, retarg, checkArgs);
00603 }
00604
00605 const Object *Object::getMasterObject(bool recurs) const
00606 {
00607 return const_cast<Object *>(this)->getMasterObject(recurs);
00608 }
00609
00610 Object *Object::getMasterObject(bool recurs)
00611 {
00612 if (!recurs || !master_object)
00613 return master_object;
00614
00615 assert(recurs && master_object);
00616
00617 if (master_object->getMasterObject(false))
00618 return master_object->getMasterObject(true);
00619
00620 return master_object;
00621 }
00622
00623 Status
00624 Object::setMasterObject(Object *_master_object)
00625 {
00626 master_object = _master_object;
00627 return Success;
00628 }
00629
00630 Status
00631 Object::releaseMasterObject()
00632 {
00633 master_object = 0;
00634
00635
00636
00637
00638
00639
00640
00641
00642 return Success;
00643 }
00644
00645 Status
00646 Object::setProtection(const Oid &prot_oid)
00647 {
00648 if (!db)
00649 return Exception::make(IDB_ERROR, "no database associated with object");
00650 return db->setObjectProtection(oid, prot_oid);
00651 }
00652
00653 Status
00654 Object::setProtection(Protection *prot)
00655 {
00656 if (!db)
00657 return Exception::make(IDB_ERROR, "no database associated with object");
00658 return db->setObjectProtection(oid, prot);
00659 }
00660
00661 Status
00662 Object::getProtection(Oid &prot_oid) const
00663 {
00664 if (!db)
00665 return Exception::make(IDB_ERROR, "no database associated with object");
00666 prot_oid = oid_prot;
00667 return Success;
00668
00669 }
00670
00671 Status
00672 Object::getProtection(Protection *&prot) const
00673 {
00674 if (!db)
00675 return Exception::make(IDB_ERROR, "no database associated with object");
00676
00677 if (oid_prot.isValid())
00678 return db->loadObject(&oid_prot, (Object **)&prot);
00679
00680 prot = NULL;
00681 return Success;
00682
00683 }
00684
00685
00686
00687
00688
00689 #define TRY_GETELEMS_GC
00690
00691 ObjectArray::ObjectArray(Object **_objs, unsigned int _count)
00692 {
00693 objs = 0;
00694 count = 0;
00695 auto_garb = False;
00696 set(_objs, _count);
00697 }
00698
00699 ObjectArray::ObjectArray(bool _auto_garb, Object **_objs, unsigned int _count)
00700 {
00701 objs = 0;
00702 count = 0;
00703 auto_garb = _auto_garb;
00704 set(_objs, _count);
00705 }
00706
00707 ObjectArray::ObjectArray(const Collection *coll, bool _auto_garb)
00708 {
00709 objs = 0;
00710 count = 0;
00711 auto_garb = _auto_garb;
00712 coll->getElements(*this);
00713 }
00714
00715 void ObjectArray::set(Object **_objs, unsigned int _count)
00716 {
00717
00718 #ifdef TRY_GETELEMS_GC
00719 if (auto_garb && _count && !_objs)
00720 throw *Exception::make(IDB_ERROR,
00721 "cannot set an auto-garbaged object array "
00722 "for %d objets with no object pointer",
00723 _count);
00724
00725 #endif
00726 if (auto_garb)
00727 garbage();
00728
00729 free(objs);
00730
00731 int sz = _count * sizeof(Object *);
00732 objs = (Object **)malloc(sz);
00733 if (_objs)
00734 memcpy(objs, _objs, sz);
00735 count = _count;
00736
00737 #ifdef TRY_GETELEMS_GC
00738 if (auto_garb) {
00739 for (int n = 0; n < count; n++) {
00740 if (objs[n]) {
00741 objs[n]->incrRefCount();
00742 }
00743 }
00744 }
00745 #endif
00746 }
00747
00748 void ObjectArray::setMustRelease(bool must_release)
00749 {
00750 for (int i = 0; i < count; i++)
00751 if (objs[i])
00752 objs[i]->setMustRelease(must_release);
00753 }
00754
00755 ObjectArray::ObjectArray(const ObjectArray &objarr)
00756 {
00757 count = 0;
00758 objs = 0;
00759 auto_garb = False;
00760 *this = objarr;
00761 }
00762
00763 Status ObjectArray::setObjectAt(unsigned int ind, Object *o)
00764 {
00765 if (ind >= count)
00766 return Exception::make(IDB_ERROR, "invalid range %d (maximun is %d)",
00767 ind, count);
00768 if (objs[ind] == o)
00769 return Success;
00770
00771 #ifdef TRY_GETELEMS_GC
00772 if (auto_garb) {
00773
00774 if (objs[ind])
00775 objs[ind]->release();
00776
00777 objs[ind] = o;
00778
00779 if (objs[ind])
00780 objs[ind]->incrRefCount();
00781
00782 return Success;
00783 }
00784 #endif
00785
00786 objs[ind] = o;
00787 return Success;
00788 }
00789
00790 ObjectArray::ObjectArray(const ObjectList &list)
00791 {
00792 count = 0;
00793 auto_garb = False;
00794
00795 int cnt = list.getCount();
00796 if (!cnt)
00797 {
00798 objs = 0;
00799 return;
00800 }
00801
00802 objs = (Object **)malloc(sizeof(Object *) * cnt);
00803
00804 ObjectListCursor c(list);
00805 Object *o;
00806
00807 for (; c.getNext(o); count++) {
00808 objs[count] = o;
00809
00810
00811
00812
00813
00814
00815
00816 }
00817 }
00818
00819 ObjectArray& ObjectArray::operator=(const ObjectArray &objarr)
00820 {
00821 set(objarr.objs, objarr.count);
00822 #ifndef TRY_GETELEMS_GC
00823 auto_garb = objarr.auto_garb;
00824 #endif
00825 return *this;
00826 }
00827
00828 void ObjectArray::garbage()
00829 {
00830 for (int i = 0; i < count; i++)
00831 if (objs[i]) {
00832 objs[i]->release();
00833 objs[i] = 0;
00834 }
00835 }
00836
00837 ObjectList *
00838 ObjectArray::toList() const
00839 {
00840 return new ObjectList(*this);
00841 }
00842
00843 void ObjectArray::makeObjectPtrVector(ObjectPtrVector &obj_vect)
00844 {
00845 for (int n = 0; n < count; n++)
00846 obj_vect.push_back(objs[n]);
00847 }
00848
00849 ObjectArray::~ObjectArray()
00850 {
00851 if (auto_garb)
00852 garbage();
00853
00854 free(objs);
00855 }
00856
00857 extern ostream&
00858 tmpfile2stream(const char *file, ostream& os, FILE *fd);
00859
00860 ostream& operator<<(ostream& os, const ObjectPtr &o_ptr)
00861 {
00862 return os << o_ptr.getObject();
00863 }
00864
00865 ostream& operator<<(ostream& os, const Object &o)
00866 {
00867 return os << &o;
00868 }
00869
00870 ostream& operator<<(ostream& os, const Object *o)
00871 {
00872 if (!o)
00873 return os << "NULL\n";
00874
00875 Status s = o->trace(get_file());
00876 if (s) return os << s->getDesc();
00877 return convert_to_stream(os);
00878 }
00879
00880 std::string
00881 Object::toString(unsigned int flags, const RecMode *rcm,
00882 Status *pstatus) const
00883 {
00884 Status status = trace(get_file(), flags, rcm);
00885 if (status) {
00886 if (pstatus) *pstatus = status;
00887 return status->getDesc();
00888 }
00889
00890 ostringstream ostr;
00891 convert_to_stream(ostr);
00892
00893
00894
00895 std::string s(ostr.str());
00896 if (pstatus) *pstatus = Success;
00897 return s;
00898 }
00899
00900 void
00901 Object::freeList(LinkedList *list, Bool wipeOut)
00902 {
00903 if (!list)
00904 return;
00905
00906 if (wipeOut)
00907 {
00908 Object *o;
00909 LinkedListCursor c(list);
00910
00911 while (c.getNext((void *&)o))
00912 o->release();
00913 }
00914
00915 delete list;
00916 }
00917
00918
00919 LinkedList *
00920 Object::copyList(const LinkedList *list, Bool copy)
00921 {
00922 if (!list)
00923 return (LinkedList *)0;
00924
00925 LinkedList *rlist = new LinkedList();
00926 Object *o;
00927
00928 LinkedListCursor c(list);
00929
00930 while (c.getNext((void *&)o))
00931 rlist->insertObject(copy && o ? o->clone() : o);
00932
00933 return rlist;
00934 }
00935
00936
00937
00938
00939
00940 ObjectList::ObjectList()
00941 {
00942 list = new LinkedList();
00943 }
00944
00945 ObjectList::ObjectList(const ObjectArray &obj_array)
00946 {
00947 list = new LinkedList();
00948 for (int i = 0; i < obj_array.getCount(); i++)
00949 insertObjectLast(const_cast<Object *>(obj_array[i]));
00950 }
00951
00952 int ObjectList::getCount(void) const
00953 {
00954 return list->getCount();
00955 }
00956
00957 void
00958 ObjectList::insertObject(Object *o)
00959 {
00960 list->insertObject(o);
00961 }
00962
00963 void
00964 ObjectList::insertObjectFirst(Object *o)
00965 {
00966 list->insertObjectFirst(o);
00967 }
00968
00969 void
00970 ObjectList::insertObjectLast(Object *o)
00971 {
00972 list->insertObjectLast(o);
00973 }
00974
00975 Bool
00976 ObjectList::suppressObject(Object *o)
00977 {
00978 return list->deleteObject(o) ? True : False;
00979 }
00980
00981 Bool
00982 ObjectList::exists(const Object *o) const
00983 {
00984 return list->getPos((void *)o) >= 0 ? True : False;
00985 }
00986
00987 void
00988 ObjectList::empty()
00989 {
00990 list->empty();
00991 }
00992
00993 ObjectArray *
00994 ObjectList::toArray() const
00995 {
00996 int cnt = list->getCount();
00997 if (!cnt)
00998 return new ObjectArray();
00999 Object **arr = (Object **)malloc(sizeof(Object *) * cnt);
01000
01001 LinkedListCursor c(list);
01002 for (int i = 0; c.getNext((void *&)arr[i]); i++)
01003 ;
01004
01005 ObjectArray *obj_arr = new ObjectArray(arr, cnt);
01006 free(arr);
01007 return obj_arr;
01008 }
01009
01010 ObjectList::~ObjectList()
01011 {
01012 delete list;
01013 }
01014
01015 ObjectListCursor::ObjectListCursor(const ObjectList &oidlist)
01016 {
01017 c = new LinkedListCursor(oidlist.list);
01018 }
01019
01020 ObjectListCursor::ObjectListCursor(const ObjectList *oidlist)
01021 {
01022 c = new LinkedListCursor(oidlist->list);
01023 }
01024
01025 Bool
01026 ObjectListCursor::getNext(Object *&o)
01027 {
01028 return c->getNext((void *&)o) ? True : False;
01029 }
01030
01031 ObjectListCursor::~ObjectListCursor()
01032 {
01033 delete c;
01034 }
01035
01036 Status
01037 Object::loadPerform(const Oid&, LockMode,AttrIdxContext &idx_ctx,
01038 const RecMode*)
01039 {
01040 return Success;
01041 }
01042
01043 Status
01044 Object::removePerform(const Oid&, const Oid&, AttrIdxContext&, const RecMode*)
01045 {
01046 return Success;
01047 }
01048
01049 Status
01050 Object::realizePerform(const Oid&, const Oid&, AttrIdxContext&, const RecMode*)
01051 {
01052 CHK_OBJ(this);
01053 return Success;
01054 }
01055
01056 Status
01057 Object::getDataspace(const Dataspace *&_dataspace,
01058 Bool refetch) const
01059 {
01060
01061
01062
01063
01064
01065
01066
01067
01068
01069
01070
01071
01072
01073
01074
01075
01076
01077
01078
01079 _dataspace = 0;
01080
01081 if (oid.isValid() && ((!dataspace && dspid == Dataspace::DefaultDspid) ||
01082 refetch)) {
01083 ObjectLocation objloc;
01084 Status s = getLocation(objloc);
01085 if (s)
01086 return s;
01087 const_cast<Object *>(this)->dspid = objloc.getDspid();
01088 s = db->getDataspace(dspid, _dataspace);
01089 if (s)
01090 return s;
01091 const_cast<Object *>(this)->dataspace = _dataspace;
01092 return Success;
01093 }
01094
01095 if (dataspace) {
01096 _dataspace = dataspace;
01097 return Success;
01098 }
01099
01100 if (dspid != Dataspace::DefaultDspid) {
01101 Status s = db->getDataspace(dspid, _dataspace);
01102 if (s)
01103 return s;
01104 const_cast<Object *>(this)->dataspace = _dataspace;
01105 return Success;
01106 }
01107
01108 return Success;
01109 }
01110
01111 Status
01112 Object::getLocation(ObjectLocation &loc) const
01113 {
01114 OidArray oid_arr(&oid, 1);
01115 ObjectLocationArray locarr;
01116 Status s = db->getObjectLocations(oid_arr, locarr);
01117 if (s)
01118 return s;
01119 loc = locarr.getLocation(0);
01120 return Success;
01121 }
01122
01123
01124 Status
01125 Object::setDataspace(const Dataspace *_dataspace)
01126 {
01127
01128
01129
01130
01131
01132
01133
01134
01135
01136
01137
01138
01139 Status s = getDataspace(dataspace);
01140 if (s)
01141 return s;
01142
01143 if (oid.isValid() && dataspace && dataspace->getId() != _dataspace->getId())
01144 return Exception::make(IDB_ERROR, "use the move method to change the "
01145 "dataspace [#%d to #%d] on the already "
01146 "created object %s", dataspace->getId(),
01147 _dataspace->getId(), oid.toString());
01148
01149
01150 dataspace = _dataspace;
01151 dspid = dataspace->getId();
01152 return Success;
01153 }
01154
01155 Status
01156 Object::move(const Dataspace *_dataspace)
01157 {
01158 OidArray oid_arr(&oid, 1);
01159 return db->moveObjects(oid_arr, _dataspace);
01160
01161
01162
01163
01164 }
01165
01166 short
01167 Object::getDataspaceID() const
01168 {
01169 if (dataspace)
01170 return dataspace->getId();
01171
01172
01173
01174
01175
01176
01177
01178
01179
01180
01181
01182
01183
01184
01185 return dspid;
01186 }
01187
01188 void
01189 Object::setDspid(short _dspid)
01190 {
01191 dspid = _dspid;
01192 }
01193
01194 void *
01195 Object::setUserData(const char *s, void *x)
01196 {
01197 void *r = getUserData(s);
01198
01199 if (!user_data_ht)
01200 user_data_ht = new UserDataHT();
01201
01202 user_data_ht->insert(s, x);
01203 return r;
01204 }
01205
01206 void *
01207 Object::getUserData(const char *s)
01208 {
01209 if (!user_data_ht)
01210 return (void *)0;
01211
01212 return user_data_ht->get(s);
01213 }
01214
01215 const void *
01216 Object::getUserData(const char *s) const
01217 {
01218 if (!user_data_ht)
01219 return (void *)0;
01220
01221 return user_data_ht->get(s);
01222 }
01223
01224 void
01225 Object::getAllUserData(LinkedList *&key_list, LinkedList *&data_list) const
01226 {
01227 if (!user_data_ht) {
01228 key_list = new LinkedList();
01229 data_list = new LinkedList();
01230 return;
01231 }
01232
01233 user_data_ht->getall(key_list, data_list);
01234 }
01235
01236 gbxBool
01237 Object::grant_release()
01238 {
01239
01240 return gbxTrue;
01241 }
01242
01243 void
01244 Object::setDamaged(const Attribute *_damaged_attr)
01245 {
01246 damaged_attr = _damaged_attr;
01247
01248 }
01249
01250 Bool
01251 Object::setReleaseCycleDetection(Bool x)
01252 {
01253 Bool o = release_cycle_detection;
01254 release_cycle_detection = x;
01255 return o;
01256 }
01257
01258 ObjectReleaser::ObjectReleaser(Object *_o)
01259 {
01260 o = _o;
01261 dont_release = False;
01262 }
01263
01264 Object *
01265 ObjectReleaser::dontRelease()
01266 {
01267 dont_release = True;
01268 return o;
01269 }
01270
01271 ObjectReleaser::~ObjectReleaser()
01272 {
01273 if (!dont_release)
01274 o->release();
01275 }
01276
01277 ObjectListReleaser::ObjectListReleaser()
01278 {
01279 dont_release = False;
01280 }
01281
01282 void
01283 ObjectListReleaser::add(Object *o)
01284 {
01285 list.insertObject(o);
01286 }
01287
01288 void
01289 ObjectListReleaser::dontRelease()
01290 {
01291 dont_release = True;
01292 }
01293
01294 ObjectListReleaser::~ObjectListReleaser()
01295 {
01296 if (!dont_release) {
01297 LinkedListCursor c(list);
01298 Object *o;
01299 while (c.getNext((void *&)o))
01300 o->release();
01301 }
01302 }
01303
01304 ObjectObserver::ObjectObserver(const std::string &tag) :
01305 gbxObserver(tag)
01306 {
01307 }
01308
01309 void ObjectObserver::addObj(gbxObject *o)
01310 {
01311 if (o->getPTag() == getObjectTag()) {
01312 gbxObserver::addObj(o);
01313 }
01314 }
01315
01316 void ObjectObserver::rmvObj(gbxObject *_o)
01317 {
01318
01319
01320
01321
01322 if (_o->getPTag() == getObjectTag()) {
01323 gbxObserver::rmvObj(_o);
01324 }
01325 }
01326
01327 ObjectObserver::~ObjectObserver() {
01328 }
01329
01330 void ObjectObserver::getObjects(std::vector<Object *> &ov) const
01331 {
01332 std::map<gbxObject *, bool>::const_iterator begin = obj_map->begin();
01333 std::map<gbxObject *, bool>::const_iterator end = obj_map->end();
01334
01335 ov.erase(ov.begin(), ov.end());
01336 while (begin != end) {
01337 gbxObject *o = (*begin).first;
01338 if (o->getPTag() != getObjectTag()) {
01339
01340 std::cerr << "eyedb::Observer error: " << (void *)(*begin).first <<
01341 " is not an eyedb::Object\n";
01342 }
01343 else
01344 ov.push_back((eyedb::Object *)o);
01345 ++begin;
01346 }
01347 }
01348
01349 bool ObjectObserver::isObjectRegistered(Object *o) const
01350 {
01351 return gbxObserver::isObjectRegistered(o);
01352 }
01353
01354 }