/* * 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: * Code with embedded SQL for relational DBMS * * * COMMENTS: * none * ***********************************************************************/ // mainly for ostringstream: #include #include #include #include #include using namespace std; #include "objectbroker.hh" #include "dbobject.hh" #include "adminif.hh" #include "externs.h" #include "raslib/rmdebug.hh" #include "raslib/error.hh" #include "eoid.hh" #ifdef RMANBENCHMARK RMTimer DBObject::readTimer = RMTimer("DBObject","read"); RMTimer DBObject::updateTimer = RMTimer("DBObject","update"); RMTimer DBObject::insertTimer = RMTimer("DBObject","insert"); RMTimer DBObject::deleteTimer = RMTimer("DBObject","delete"); #endif const char* BinaryRepresentation::fileTag = "RMAN"; void DBObject::printStatus(unsigned int level, std::ostream& stream) const { char* indent = new char[level*2 +1]; for (int j = 0; j < level*2 ; j++) indent[j] = ' '; indent[level*2] = '\0'; stream << indent; stream << myOId; delete[] indent; indent=0; } r_Bytes DBObject::getTotalStorageSize() const { return 0; } r_Bytes DBObject::getMemorySize() const { return sizeof(DBObject); } void DBObject::setCached(bool newCached) { RMDBGONCE(10, RMDebug::module_adminif, "DBObject", "setCached(" << (int)newCached << ") " << myOId); _isCached = newCached; } bool DBObject::isCached() const { RMDBGONCE(10, RMDebug::module_adminif, "DBObject", "isCached()" << (int) _isCached) return _isCached; } void DBObject::destroy() { RMDBGENTER(10, RMDebug::module_adminif, "DBObject", "destroy() " << myOId); #ifdef RMANDEBUG OId tempid(myOId); #endif if (referenceCount == 0) { if (!_isCached) { //exception may be possible when !isModified() if (!AdminIf::isReadOnlyTA()) { RMDBGMIDDLE(10, RMDebug::module_adminif, "DBObject", "deleting object " << myOId); delete this;//is dynamic and may be deleted } else { if (!_isPersistent) { RMDBGMIDDLE(10, RMDebug::module_adminif, "DBObject", "deleting object " << myOId); //is dynamic and may be deleted delete this; } } } } #ifdef RMANDEBUG RMDBGEXIT(10, RMDebug::module_adminif, "DBObject", "destroy() " << tempid); #else RMDBGEXIT(10, RMDebug::module_adminif, "DBObject", "destroy()"); #endif } void DBObject::release() { RMDBGONCE(10, RMDebug::module_adminif, "DBObject", "release() "); //no dynamic memory } void DBObject::incrementReferenceCount(void) { RMDBGONCE(10, RMDebug::module_adminif, "DBObject", "incrementReferenceCount() " << referenceCount); referenceCount++; } void DBObject::decrementReferenceCount(void) { RMDBGONCE(10, RMDebug::module_adminif, "DBObject", "decrementReferenceCount() " <updateInDb(); #ifdef RMANBENCHMARK updateTimer.pause(); #endif } else { RMDBGMIDDLE(11, RMDebug::module_adminif, "DBObject", "is not persistent and in database"); #ifdef RMANBENCHMARK deleteTimer.resume(); #endif this->deleteFromDb(); #ifdef RMANBENCHMARK deleteTimer.pause(); #endif } } else { if (_isPersistent) { RMDBGMIDDLE(11, RMDebug::module_adminif, "DBObject", "is persistent and modified and not in database"); #ifdef RMANBENCHMARK insertTimer.resume(); #endif this->insertInDb(); #ifdef RMANBENCHMARK insertTimer.pause(); #endif } else { //donīt do anything: not in db and not persistent } } } else { //donīt do anything: is aborted } } else { //donīt do anything: is read only } } else { //donīt do anything: not modified } RMDBGEXIT(9, RMDebug::module_adminif, "DBObject", "validate() " << myOId); } void DBObject::setModified() throw (r_Error) { RMDBGENTER(8, RMDebug::module_adminif, "DBObject", "setModified() " << myOId); if (!AdminIf::isReadOnlyTA()) _isModified = true; else { RMDBGMIDDLE(5, RMDebug::module_adminif, "DBObject", "readonly transaction " << myOId); //this happens really a lot. //RMInit::logOut << "DBObject::setModified() read only transaction" << endl; //throw r_Error(r_Error::r_Error_TransactionReadOnly); _isModified = true; } RMDBGEXIT(8, RMDebug::module_adminif, "DBObject", "setModified() " << myOId); } bool DBObject::isModified() const { RMDBGONCE(8, RMDebug::module_adminif, "DBObject", "isModified() " << (int)_isModified); return _isModified; } OId DBObject::getOId() const { RMDBGONCE(8, RMDebug::module_adminif, "DBObject", "getOId() " << myOId); return myOId; } EOId DBObject::getEOId() const { RMDBGONCE(8, RMDebug::module_adminif, "DBObject", "getEOId() " << myOId); return EOId(myOId); } OId::OIdType DBObject::getObjectType() const { RMDBGONCE(8, RMDebug::module_adminif, "DBObject", "getObjectType() " << objecttype); return objecttype; } DBObject::~DBObject() { RMDBGENTER(10, RMDebug::module_adminif, "DBObject", "~DBObject() " << myOId); ObjectBroker::deregisterDBObject(myOId); RMDBGEXIT(10, RMDebug::module_adminif, "DBObject", "~DBObject() " << myOId); } void DBObject::updateInDb() throw (r_Error) { RMDBGENTER(10, RMDebug::module_adminif, "DBObject", "updateInDb() " << myOId); _isModified = false; _isInDatabase = true; _isPersistent = true; RMDBGEXIT(10, RMDebug::module_adminif, "DBObject", "updateInDb() " << myOId); } //writes the object into the database. the object must not be in the database. void DBObject::insertInDb() throw (r_Error) { RMDBGENTER(10, RMDebug::module_adminif, "DBObject", "insertInDb() " << myOId); _isModified = false; _isInDatabase = true; _isPersistent = true; RMDBGEXIT(10, RMDebug::module_adminif, "DBObject", "insertInDb() " << myOId); } void DBObject::deleteFromDb() throw (r_Error) { RMDBGENTER(10, RMDebug::module_adminif, "DBObject", "deleteFromDb() " << myOId); _isModified = false; _isInDatabase = false; _isPersistent = false; RMDBGEXIT(10, RMDebug::module_adminif, "DBObject", "deleteFromDb() " << myOId); } void DBObject::readFromDb() throw (r_Error) { RMDBGENTER(10, RMDebug::module_adminif, "DBObject", "readFromDb() " << myOId); _isPersistent = true; _isModified = false; _isInDatabase = true; RMDBGEXIT(10, RMDebug::module_adminif, "DBObject", "readFromDb() " << myOId); } BinaryRepresentation DBObject::getBinaryRepresentation() const throw (r_Error) { RMInit::logOut << "getBinaryRepresentation() for " << objecttype << " not implemented" << endl; throw r_Error(BINARYEXPORTNOTSUPPORTEDFOROBJECT); } void DBObject::setBinaryRepresentation(const BinaryRepresentation& br) throw (r_Error) { RMInit::logOut << "setBinaryRepresentation() for " << objecttype << " not implemented" << endl; throw r_Error(BINARYIMPORTNOTSUPPORTEDFOROBJECT); } char* DBObject::getBinaryName() const { //if we use 64bit oids we have at most 20 digits + "_" + type ostringstream o; o << (int)objecttype << '_' << myOId.getCounter() << ".raw"; const char* temp = o.str().c_str(); char* retval = new char[strlen(temp) + 1]; memcpy(retval, temp, strlen(temp) + 1); return retval; }