/* * This file is part of rasdaman community. * * Rasdaman community is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Rasdaman community is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with rasdaman community. If not, see . * * Copyright 2003, 2004, 2005, 2006, 2007, 2008, 2009 Peter Baumann / rasdaman GmbH. * * For more information please see * or contact Peter Baumann via . */ /************************************************************* * * * PURPOSE: * DBRef is a smart pointer for managing objects derived from * the DbObject class. * * * COMMENTS: * ************************************************************/ #include "dbref.hh" #include #include #include "raslib/rmdebug.hh" #include "objectbroker.hh" #include "indexmgr/indexds.hh" #include "relindexif/dbrcindexds.hh" #include "relindexif/dbtcindex.hh" #include "indexmgr/hierindexds.hh" #include "debug/debug.hh" template bool DBRef::pointerCaching = true; /*for testing bool DBRef::pointerCaching = false; bool DBRef::pointerCaching = false; bool DBRef::pointerCaching = false; */ template void DBRef::setPointerCaching(bool useIt) { RMDBGONCE(10, RMDebug::module_adminif, "DBRef", "setPointerCaching(" << useIt << ") " << pointerCaching ); pointerCaching = useIt; } template bool DBRef::getPointerCaching() { RMDBGONCE(10, RMDebug::module_adminif, "DBRef", "getPointerCaching() " << pointerCaching ); return pointerCaching; } template DBRef::DBRef(void) : object(0), objId(DBOBJID_NONE), pointerValid(false) { RMDBGONCE(11, RMDebug::module_adminif, "DBRef", "DBRef()"); } template DBRef::DBRef(const OId &id) : object(0), pointerValid(false), objId(id) { RMDBGONCE(11, RMDebug::module_adminif, "DBRef", "DBRef(" << id << ")"); } template DBRef::DBRef(double id) : object(0), pointerValid(false), objId(id) { RMDBGONCE(11, RMDebug::module_adminif, "DBRef", "DBRef(double " << id << ")"); } template DBRef::DBRef(const DBRef &src) : object(0), pointerValid(src.pointerValid), objId(src.objId) { RMDBGENTER(11, RMDebug::module_adminif, "DBRef", "DBRef(const DBRef) src.OId=" << src.objId); if (pointerCaching) { if (src.object) { object = src.object; objId = object->getOId(); object->incrementReferenceCount(); } } else { if (pointerValid && src.object) { object = src.object; } } RMDBGEXIT(11, RMDebug::module_adminif, "DBRef", "DBRef(const DBRef) " << objId); } template DBRef::DBRef(T *ptr) : object(ptr), pointerValid(true), objId(DBOBJID_NONE) { RMDBGENTER(11, RMDebug::module_adminif, "DBRef", "DBRef(const T* " << ptr << ")"); if (object != 0) { objId = object->getOId(); object->incrementReferenceCount(); RMDBGMIDDLE(11, RMDebug::module_adminif, "DBRef", "DBRef(T* " << ptr->getOId() << ")"); } else { pointerValid = false; RMDBGMIDDLE(11, RMDebug::module_adminif, "DBRef", "DBRef(T* 0) " << objId); } } template DBRef::~DBRef(void) { RMDBGENTER(11, RMDebug::module_adminif, "DBRef", "~DBRef() " << objId); if ((object != 0) && pointerCaching) object->decrementReferenceCount(); object = 0; RMDBGEXIT(11, RMDebug::module_adminif, "DBRef", "~DBRef() " << objId); } template bool DBRef::operator<(const DBRef& other) const { RMDBGENTER(3, RMDebug::module_adminif, "DBRef", "DBRef::operator<(" << other.objId << ", " << (r_Ptr)other.object << ") " << objId << ", " << (r_Ptr)object); int ret = operator==(other); return (ret == -1); } template bool operator< (const DBRef &me, const DBRef &him) { RMDBGENTER(3, RMDebug::module_adminif, "DBRef", "operator<({" << me.getOId() << "}, {" << him.getOId() << "})"); return me.operator<(him); } template int DBRef::operator==(const DBRef &src) const { RMDBGENTER(3, RMDebug::module_adminif, "DBRef", "operator==(" << src.objId << ", " << (r_Ptr)src.object << ") " << objId << ", " << (r_Ptr)object); int retval = 0; if (isInitialised()) { if (src.isInitialised()) { if (object) { if (object->isPersistent()) {//this persistent if (src.object) { if (src.object->isPersistent()) { if (object->getOId() < src.object->getOId()) retval = -1; else if (object->getOId() > src.object->getOId()) retval = +1; //else == -> 0 } else {//src is transient retval = +1; } } else {//src is persistent if (object->getOId() < src.objId) { retval = -1; } else { if (object->getOId() > src.objId) retval = +1; //else == -> 0 } } } else {//this transient if (src.object) { if (src.object->isPersistent()) { retval = -1; } else {//src is transient if (object < src.object) retval = -1; else if (object > src.object) retval = +1; //else == -> 0 } } else {//src is persistent retval = -1; } } } else {//this is persistent if (src.object) { if (src.object->isPersistent()) { if (objId < src.object->getOId()) { retval = -1; } else { if (objId > src.object->getOId()) retval = +1; //else == -> 0 } } else {//src not persistent retval = +1; } } else {//src is persistent if (objId < src.objId) { retval = -1; } else { if (objId > src.objId) retval = +1; //else == -> 0 } } } } else { retval = +1; } } else { if (src.isInitialised()) { retval = -1; } //else is 0 } RMDBGEXIT(11, RMDebug::module_adminif, "DBRef", "operator==(" << src.objId << ") " << retval); return retval; } template DBRef &DBRef::operator=(const DBRef &src) { RMDBGENTER(11, RMDebug::module_adminif, "DBRef", "operator=(" << src.objId << ") " << objId); if ((object != 0) && pointerCaching) { object->decrementReferenceCount(); } object = src.object; pointerValid = src.pointerValid; objId = src.objId; if (pointerCaching) { if (object) { objId = object->getOId(); object->incrementReferenceCount(); } } else { if (object && pointerValid) objId = object->getOId(); } RMDBGEXIT(11, RMDebug::module_adminif, "DBRef", "operator=(" << src.objId << ") " << objId); return *this; } template DBRef &DBRef::operator=(T *ptr) { RMDBGENTER(11, RMDebug::module_adminif, "DBRef", "operator=( at " << ptr << " ) " << objId); if ((object != 0) && pointerCaching) object->decrementReferenceCount(); object = ptr; if (object == 0) { objId = DBOBJID_NONE; pointerValid = false; } else { objId = object->getOId(); object->incrementReferenceCount(); pointerValid = true; } RMDBGEXIT(11, RMDebug::module_adminif, "DBRef", "operator=( at " << ptr << " ) " << objId); return *this; } template T &DBRef::operator *(void) throw ( r_Error ) { RMDBGENTER(11, RMDebug::module_adminif, "DBRef", "operator*() " << objId); if (is_null()) { TALK( "DBRef::operator*(): object not found " << objId); RMDBGMIDDLE(2, RMDebug::module_adminif, "DBRef", "object was not found " << objId); r_Error err = r_Error(r_Error::r_Error_RefNull); throw err; } RMDBGEXIT(11, RMDebug::module_adminif, "DBRef", "operator*() " << objId); return *object; } template const T &DBRef::operator *(void) const throw ( r_Error ) { RMDBGENTER(11, RMDebug::module_adminif, "DBRef", "operator*() const " << objId); if (is_null()) { TALK( "DBRef::operator*(): object not found " << objId); RMDBGMIDDLE(2, RMDebug::module_adminif, "DBRef", "object was not found " << objId); r_Error err = r_Error(r_Error::r_Error_RefNull); throw err; } RMDBGEXIT(11, RMDebug::module_adminif, "DBRef", "operator*() " << objId); return *object; } #ifndef __GNUG__ template T &DBRef::operator[](int idx) const throw(r_Error) { RMDBGENTER(11, RMDebug::module_adminif, "DBRef", "operator[](" << idx << ") " << objId); if (is_null()) { TALK( "DBRef::operator[](): object not found " << objId); RMDBGMIDDLE(2, RMDebug::module_adminif, "DBRef", "object was not found " << objId); r_Error err = r_Error(r_Error::r_Error_RefNull); throw err; } RMDBGEXIT(11, RMDebug::module_adminif, "DBRef", "operator[](" << idx << ") " << objId); return *((this + idx).object); } #endif template T *DBRef::operator->(void) throw(r_Error) { RMDBGENTER(11, RMDebug::module_adminif, "DBRef", "operator->() " << objId); if (is_null()) { TALK( "DBRef::operator->(): object not found " << objId); RMDBGMIDDLE(2, RMDebug::module_adminif, "DBRef", "object was not found " << objId); r_Error err = r_Error(r_Error::r_Error_RefNull); throw err; } RMDBGEXIT(11, RMDebug::module_adminif, "DBRef", "operator->() " << objId); return object; } template const T *DBRef::operator->(void) const throw(r_Error) { RMDBGENTER(11, RMDebug::module_adminif, "DBRef", "operator->() const " << objId); if (is_null()) { TALK( "DBRef::operator->(): object not found " << objId); RMDBGMIDDLE(2, RMDebug::module_adminif, "DBRef", "object was not found " << objId); r_Error err = r_Error(r_Error::r_Error_RefNull); throw err; } RMDBGEXIT(11, RMDebug::module_adminif, "DBRef", "operator->() const " << objId); return object; } template T *DBRef::ptr(void) throw(r_Error) { RMDBGENTER(11, RMDebug::module_adminif, "DBRef", "ptr() " << objId); if (is_null()) { TALK( "DBRef::ptr(): object not found " << objId); RMDBGMIDDLE(2, RMDebug::module_adminif, "DBRef", "object was not found " << objId); r_Error err = r_Error(r_Error::r_Error_RefNull); throw err; } RMDBGEXIT(11, RMDebug::module_adminif, "DBRef", "ptr() " << objId); return object; } template const T *DBRef::ptr(void) const throw(r_Error) { RMDBGENTER(11, RMDebug::module_adminif, "DBRef", "ptr() " << objId); if (is_null()) { TALK( "DBRef::ptr(): object not found " << objId); RMDBGMIDDLE(2, RMDebug::module_adminif, "DBRef", "object was not found " << objId); r_Error err = r_Error(r_Error::r_Error_RefNull); throw err; } RMDBGEXIT(11, RMDebug::module_adminif, "DBRef", "ptr() " << objId); return object; } template DBRef::operator T*() throw (r_Error) { RMDBGENTER(11, RMDebug::module_adminif, "DBRef", "operator T*() " << objId); if (is_null()) { TALK( "DBRef::T*(): object not found " << objId); RMDBGMIDDLE(2, RMDebug::module_adminif, "DBRef", "object was not found " << objId); r_Error err = r_Error(r_Error::r_Error_RefNull); throw err; } RMDBGEXIT(11, RMDebug::module_adminif, "DBRef", "operator T*() " << objId); return object; } template DBRef::operator const T*() const throw (r_Error) { RMDBGENTER(11, RMDebug::module_adminif, "DBRef", "operator const T*() const" << objId); if (is_null()) { TALK( "DBRef::T*(): object not found " << objId); RMDBGMIDDLE(2, RMDebug::module_adminif, "DBRef", "object was not found " << objId); r_Error err = r_Error(r_Error::r_Error_RefNull); throw err; } RMDBGEXIT(11, RMDebug::module_adminif, "DBRef", "operator const T*() " << objId); return object; } template OId DBRef::getOId(void) const { if (object && pointerCaching) ((DBRef)*this).objId = object->getOId(); return objId; } template void DBRef::delete_object(void) { if (!is_null()) { object->setPersistent(false); object->decrementReferenceCount(); object = 0; objId = DBOBJID_NONE; } else { r_Error err; if (objId.getType() == OId::INVALID) { err = r_Error(r_Error::r_Error_OIdInvalid); } else { err = r_Error(r_Error::r_Error_ObjectUnknown); } RMDBGONCE(0, RMDebug::module_adminif, "DBRef", "delete_object() " << objId << " not ok") throw err; } } template bool DBRef::isInitialised() const { bool retval=false; if (object) retval=true; else { if (objId.getType() != OId::INVALID) retval=true; } return retval; } template bool DBRef::is_valid(void) const { bool retval=false; if (!is_null()) retval=true; return retval; } template void DBRef::release() { RMDBGENTER(11, RMDebug::module_adminif, "DBRef", "release() " << objId); if ((object != 0) && pointerCaching) { object->decrementReferenceCount(); } object = 0; RMDBGEXIT(11, RMDebug::module_adminif, "DBRef", "release() " << objId); } template DBRef::operator DBRef() const { RMDBGENTER(11, RMDebug::module_adminif, "DBRef", "operator DBRef() " << objId); if (object && pointerCaching) { RMDBGEXIT(11, RMDebug::module_adminif, "DBRef", "operator DBRef(" << object << ") " << objId); return DBRef(object); } else { RMDBGEXIT(11, RMDebug::module_adminif, "DBRef", "operator DBRef(" << objId << ") " << objId); return DBRef(objId); } } template DBRef::operator DBRef() const throw (r_Error) { RMDBGENTER(11, RMDebug::module_adminif, "DBRef", "operator DBRef() " << objId); if (object && pointerCaching) { if (object->getObjectType() == OId::INLINETILEOID) { RMDBGEXIT(11, RMDebug::module_adminif, "DBRef", "operator DBRef() " << objId); return DBRef((InlineTile*)object); } } else { if (objId.getType() == OId::INLINETILEOID) { RMDBGEXIT(11, RMDebug::module_adminif, "DBRef", "operator DBRef() " << objId); return DBRef(objId); } } TALK( "DBRef::(): operator mismatch" << objId); RMDBGEXIT(0, RMDebug::module_adminif, "DBRef", "operator DBRef() mismatch " << objId); throw r_Error(r_Error::r_Error_DatabaseClassMismatch); } template DBRef::operator DBRef() const throw (r_Error) { RMDBGENTER(11, RMDebug::module_adminif, "DBRef", "operator DBRef() " << objId << "; object=" << (long) object ); TALK( "DBRef::DBRef(): object=" << (long) object ); if (object && pointerCaching) { if ((object->getObjectType() == OId::BLOBOID) || (object->getObjectType() == OId::INLINETILEOID)) { RMDBGEXIT(11, RMDebug::module_adminif, "DBRef", "operator DBRef() " << objId); return DBRef((DBTile*)object); } } else { if ((objId.getType() == OId::BLOBOID) || (objId.getType() == OId::INLINETILEOID)) { RMDBGEXIT(11, RMDebug::module_adminif, "DBRef", "operator DBRef() " << objId); return DBRef(objId); } } if (object) { TALK( "DBRef::DBRef(): object->getObjectType()=" << object->getObjectType() ); } TALK( "DBRef::DBRef(): objId->getObjectType()=" << objId.getType() ); TALK( "DBRef::DBRef(): operator mismatch" << objId ); if (object) { RMDBGMIDDLE(0, RMDebug::module_adminif, "DBRef", "object->getObjectType()=" << object->getObjectType() ); } RMDBGMIDDLE(0, RMDebug::module_adminif, "DBRef", "objId->getObjectType()=" << objId.getType() ); RMDBGEXIT(0, RMDebug::module_adminif, "DBRef", "operator DBRef() mismatch " << objId); throw r_Error(r_Error::r_Error_DatabaseClassMismatch); } template DBRef::operator DBRef() const throw (r_Error) { RMDBGENTER(11, RMDebug::module_adminif, "DBRef", "operator DBRef() " << objId); if (object && pointerCaching) { if (object->getObjectType() == OId::BLOBOID || (object->getObjectType() == OId::INLINETILEOID)) { RMDBGEXIT(11, RMDebug::module_adminif, "DBRef", "operator DBRef() " << objId); return DBRef((BLOBTile*)object); } } else { if ((objId.getType() == OId::BLOBOID) || (objId.getType() == OId::INLINETILEOID)) { RMDBGEXIT(11, RMDebug::module_adminif, "DBRef", "operator DBRef() " << objId); return DBRef(objId); } } TALK( "DBRef::DBRef(): operator mismatch" << objId); RMDBGEXIT(0, RMDebug::module_adminif, "DBRef", "operator DBRef() mismatch " << objId); throw r_Error(r_Error::r_Error_DatabaseClassMismatch); } template DBRef::operator DBRef() const throw (r_Error) { RMDBGENTER(11, RMDebug::module_adminif, "DBRef", "operator DBRef() " << objId); if (object && pointerCaching) { if (object->getObjectType() == OId::DBTCINDEXOID) { RMDBGEXIT(11, RMDebug::module_adminif, "DBRef", "operator DBRef() " << objId); return DBRef((DBTCIndex*)object); } } else { if (objId.getType() == OId::DBTCINDEXOID) { RMDBGEXIT(11, RMDebug::module_adminif, "DBRef", "operator DBRef() " << objId); return DBRef(objId); } } TALK( "DBRef::DBRef(): operator mismatch" << objId); RMDBGEXIT(0, RMDebug::module_adminif, "DBRef", "operator DBRef() mismatch " << objId); throw r_Error(r_Error::r_Error_DatabaseClassMismatch); } template DBRef::operator DBRef() const throw (r_Error) { RMDBGENTER(11, RMDebug::module_adminif, "DBRef", "operator DBRef() " << objId); if (object && pointerCaching) { if ((object->getObjectType() == OId::MDDHIERIXOID) || (object->getObjectType() == OId::DBTCINDEXOID)) { RMDBGEXIT(11, RMDebug::module_adminif, "DBRef", "operator DBRef() " << objId); return DBRef((DBHierIndex*)object); } } else { if ((objId.getType() == OId::MDDHIERIXOID) || (objId.getType() == OId::DBTCINDEXOID)) { RMDBGEXIT(11, RMDebug::module_adminif, "DBRef", "operator DBRef() " << objId); return DBRef(objId); } } TALK( "DBRef::DBRef(): operator mismatch" << objId); RMDBGEXIT(0, RMDebug::module_adminif, "DBRef", "operator DBRef() mismatch " << objId); throw r_Error(r_Error::r_Error_DatabaseClassMismatch); } template DBRef::operator DBRef() const throw (r_Error) { RMDBGENTER(11, RMDebug::module_adminif, "DBRef", "operator DBRef() " << objId); if (object && pointerCaching) { if (object->getObjectType() == OId::MDDRCIXOID) { RMDBGEXIT(11, RMDebug::module_adminif, "DBRef", "operator DBRef() " << objId); return DBRef((DBRCIndexDS*)object); } } else { if (objId.getType() == OId::MDDRCIXOID) { RMDBGEXIT(11, RMDebug::module_adminif, "DBRef", "operator DBRef() " << objId); return DBRef(objId); } } TALK( "DBRef::DBRef(): operator mismatch" << objId); RMDBGEXIT(0, RMDebug::module_adminif, "DBRef", "operator DBRef() mismatch " << objId); throw r_Error(r_Error::r_Error_DatabaseClassMismatch); } template DBRef::operator HierIndexDS*() const throw (r_Error) { RMDBGENTER(11, RMDebug::module_adminif, "DBRef", "operator HierIndexDS*() " << objId); if (object && pointerCaching) { if ((object->getObjectType() == OId::MDDHIERIXOID) || (object->getObjectType() == OId::DBTCINDEXOID)) { RMDBGEXIT(11, RMDebug::module_adminif, "DBRef", "operator HierIndexDS*() " << objId); return (HierIndexDS*)object; } } else { if (objId.getType() == OId::MDDHIERIXOID) { RMDBGEXIT(11, RMDebug::module_adminif, "DBRef", "operator IndexDS*() DBHierIndexId" << objId); DBRef t(objId); return (HierIndexDS*)t.ptr(); } else { if (objId.getType() == OId::DBTCINDEXOID) { RMDBGEXIT(11, RMDebug::module_adminif, "DBRef", "operator IndexDS*() DBTCIndexId" << objId); DBRef t(objId); return (HierIndexDS*)t.ptr(); } } } TALK( "DBRef::HierIndexDS*(): operator mismatch" << objId); RMDBGEXIT(0, RMDebug::module_adminif, "DBRef", "operator HierIndexDS*() mismatch " << objId); throw r_Error(r_Error::r_Error_DatabaseClassMismatch); } template DBRef::operator IndexDS*() const throw (r_Error) { RMDBGENTER(11, RMDebug::module_adminif, "DBRef", "operator IndexDS*() " << objId); if (object && pointerCaching) { if ((object->getObjectType() == OId::MDDHIERIXOID) || (object->getObjectType() == OId::DBTCINDEXOID) || (object->getObjectType() == OId::MDDRCIXOID)) { RMDBGEXIT(11, RMDebug::module_adminif, "DBRef", "operator IndexDS*() " << objId); return (IndexDS*)object; } } else { if (objId.getType() == OId::MDDHIERIXOID) { RMDBGEXIT(11, RMDebug::module_adminif, "DBRef", "operator IndexDS*() DBHierIndexId" << objId); DBRef t(objId); return (IndexDS*)t.ptr(); } else { if (objId.getType() == OId::DBTCINDEXOID) { RMDBGEXIT(11, RMDebug::module_adminif, "DBRef", "operator IndexDS*() DBTCIndexId" << objId); DBRef t(objId); return (IndexDS*)t.ptr(); } else { if (objId.getType() == OId::MDDRCIXOID) { RMDBGEXIT(11, RMDebug::module_adminif, "DBRef", "operator IndexDS*() DBRCIndexId" << objId); DBRef t(objId); return (IndexDS*)t.ptr(); } } } } TALK( "DBRef::IndexDS*(): operator mismatch" << objId); RMDBGEXIT(0, RMDebug::module_adminif, "DBRef", "operator IndexDS*() mismatch " << objId); throw r_Error(r_Error::r_Error_DatabaseClassMismatch); } template bool DBRef::is_null(void) const { RMDBGENTER(11, RMDebug::module_adminif, "DBRef", "is_null() " << objId); bool retval = false; T* t = 0; if (object == 0) { if (objId.getType() == OId::INVALID) { throw r_Error(r_Error::r_Error_OIdInvalid); } else { try { t = (T*)ObjectBroker::getObjectByOId(objId); RMDBGMIDDLE(11, RMDebug::module_adminif, "DBRef", "found object"); t->incrementReferenceCount(); ((DBRef*)this)->object = t; RMDBGMIDDLE(11, RMDebug::module_adminif, "DBRef", "object is at: " << object << " found object was at: " << t); } catch (r_Error& err) { if (err.get_kind() == r_Error::r_Error_ObjectUnknown) retval = true; else throw; } } } else { if (pointerCaching == false) { if (pointerValid == false) { try { t = (T*)ObjectBroker::getObjectByOId(objId); RMDBGMIDDLE(11, RMDebug::module_adminif, "DBRef", "found object"); t->incrementReferenceCount(); ((DBRef*)this)->object = t; RMDBGMIDDLE(11, RMDebug::module_adminif, "DBRef", "object is at: " << object << " found object was at: " << t); } catch (r_Error& err) { if (err.get_kind() == r_Error::r_Error_ObjectUnknown) retval = true; else throw; } } else { //retval = false; is done in initialize } } else { //retval = false; is done in initialize } } RMDBGEXIT(11, RMDebug::module_adminif, "DBRef", "is_null() " << objId << " " << retval); return retval; }