CMS 3D CMS Logo

/data/refman/pasoursint/CMSSW_5_3_1/src/CondCore/DBCommon/src/DbSession.cc

Go to the documentation of this file.
00001 //local includes
00002 #include "CondCore/DBCommon/interface/DbSession.h"
00003 #include "CondCore/DBCommon/interface/DbConnection.h"
00004 #include "CondCore/DBCommon/interface/DbTransaction.h"
00005 #include "CondCore/DBCommon/interface/Exception.h"
00006 #include "CondCore/DBCommon/interface/BlobStreamerPluginFactory.h"
00007 // CMSSW includes
00008 #include "FWCore/PluginManager/interface/PluginFactory.h"
00009 #include "CondCore/DBCommon/interface/TechnologyProxyFactory.h"
00010 #include "CondCore/ORA/interface/ConnectionPool.h"
00011 // coral includes
00012 #include "RelationalAccess/ISessionProxy.h"
00013 
00014 namespace cond {
00015 
00016   inline std::auto_ptr<cond::TechnologyProxy> buildTechnologyProxy(const std::string&userconnect, 
00017                                                                    const DbConnection& connection){
00018     std::string protocol;
00019     std::size_t pos=userconnect.find_first_of(':');
00020     if( pos!=std::string::npos ){
00021       protocol=userconnect.substr(0,pos);
00022       std::size_t p=protocol.find_first_of('_');
00023       if(p!=std::string::npos){
00024         protocol=protocol.substr(0,p);
00025       }
00026     }else{
00027       throw cond::Exception(userconnect +":connection string format error");
00028     }
00029     std::auto_ptr<cond::TechnologyProxy> ptr(cond::TechnologyProxyFactory::get()->create(protocol));
00030     (*ptr).initialize(userconnect,connection);
00031     return ptr;
00032   }
00033   
00034   class SessionImpl {
00035     public:
00036       SessionImpl():
00037         connection(),
00038         blobStreamingService( "COND/Services/BlobStreamingService" ),
00039         database(),
00040         transaction(),
00041         isOpen(false){
00042       }
00043 
00044       explicit SessionImpl( const DbConnection& connection ):
00045         connection(new DbConnection(connection)),
00046         blobStreamingService( "COND/Services/BlobStreamingService" ),
00047         database(),
00048         transaction(),
00049         isOpen(false){
00050       }
00051       
00052     
00053       virtual ~SessionImpl(){
00054         close();
00055       }
00056     
00057     void open( const std::string& connectionString, 
00058                const std::string& role,
00059                bool readOnly ){
00060         close();
00061         if( connection.get() ){
00062           if(!connection->isOpen()){
00063             throw cond::Exception("DbSession::open: cannot open session. Underlying connection is closed.");
00064           }
00065           boost::shared_ptr<ora::ConnectionPool> connPool = connection->connectionPool();
00066           database.reset( new ora::Database( connPool ) );
00067  
00068           ora::IBlobStreamingService* blobStreamer = cond::BlobStreamerPluginFactory::get()->create(  blobStreamingService );
00069           if(!blobStreamer) throw cond::Exception("DbSession::open: cannot find required plugin. No instance of ora::IBlobStreamingService has been loaded..");
00070           database->configuration().setBlobStreamingService( blobStreamer );
00071           //database->configuration().properties().setFlag( ora::Configuration::automaticDatabaseCreation() );
00072           database->configuration().properties().setFlag( ora::Configuration::automaticContainerCreation() );
00073           // open the db connection
00074           technologyProxy = buildTechnologyProxy(connectionString, *connection);
00075           std::string connStr = (*technologyProxy).getRealConnectString();
00076           database->connect( connStr, role, readOnly );
00077           transaction.reset( new cond::DbTransaction( database->transaction() ) );
00078           isOpen = true;
00079         }
00080       }
00081 
00082       void close(){
00083         transaction.reset();
00084         database.reset();
00085         isOpen = false;
00086       }
00087 
00088       std::auto_ptr<DbConnection> connection;
00089       std::auto_ptr<cond::TechnologyProxy> technologyProxy;
00090       std::string const blobStreamingService;
00091       std::auto_ptr<ora::Database> database;
00092       std::auto_ptr<DbTransaction> transaction;
00093       bool isOpen;
00094   };
00095 
00096 }
00097 
00098 const char* cond::DbSession::COND_SCHEMA_VERSION = "2.0.0";   
00099 const char* cond::DbSession::CHANGE_SCHEMA_VERSION = "2.0.0";
00100 
00101 cond::DbSession::DbSession():
00102   m_implementation( new SessionImpl ){ 
00103 }
00104 
00105 cond::DbSession::DbSession( const DbConnection& connection ):
00106   m_implementation( new SessionImpl ( connection ) ){
00107 }
00108 
00109 cond::DbSession::DbSession( const DbSession& rhs ):
00110   m_implementation( rhs.m_implementation ){ 
00111 }
00112 
00113 cond::DbSession::~DbSession(){
00114 }
00115 
00116 cond::DbSession& cond::DbSession::operator=( const cond::DbSession& rhs ){
00117   if(this!=&rhs) m_implementation = rhs.m_implementation;
00118   return *this;
00119 }
00120 
00121 void cond::DbSession::open( const std::string& connectionString, bool readOnly )
00122 {
00123   std::string emptyRole("");
00124   m_implementation->open( connectionString, emptyRole, readOnly );
00125 }
00126 
00127 void cond::DbSession::open( const std::string& connectionString, const std::string& asRole, bool readOnly )
00128 {
00129   m_implementation->open( connectionString, asRole, readOnly );
00130 }
00131 
00132 void cond::DbSession::close()
00133 {
00134   m_implementation->close();
00135 }
00136 
00137 bool cond::DbSession::isOpen() const {
00138   return m_implementation->isOpen;
00139 }
00140 
00141 const std::string& cond::DbSession::connectionString() const {
00142   if(!m_implementation->database.get())
00143     throw cond::Exception("DbSession::connectionString: cannot get connection string. Session has not been open.");
00144   return m_implementation->database->connectionString();
00145 }
00146 
00147 cond::DbConnection const & cond::DbSession::connection() const {
00148   return *(m_implementation->connection);
00149 }
00150 
00151 
00152 bool cond::DbSession::isTransactional() const {
00153   return m_implementation->technologyProxy->isTransactional();
00154 }
00155 
00156 const std::string& cond::DbSession::blobStreamingService() const 
00157 {
00158   return m_implementation->blobStreamingService;
00159 }
00160 
00161 cond::DbTransaction& cond::DbSession::transaction()
00162 {
00163   if(!m_implementation->connection.get() || !m_implementation->connection->isOpen())
00164     throw cond::Exception("DbSession::transaction: cannot open transaction. Underlying connection is closed.");
00165   if(!m_implementation->transaction.get())
00166     throw cond::Exception("DbSession::transaction: cannot get transaction. Session has not been open.");
00167   return *m_implementation->transaction;
00168 }
00169 
00170 ora::Database& cond::DbSession::storage(){
00171   if(!m_implementation->connection.get() || !m_implementation->connection->isOpen())
00172     throw cond::Exception("DbSession::storage: cannot access the storage. Underlying connection is closed.");
00173   if(!m_implementation->database.get())
00174     throw cond::Exception("DbSession::storage: cannot access the database. Session has not been open.");
00175   return *m_implementation->database;
00176 }
00177 
00178 bool cond::DbSession::createDatabase(){
00179   bool created = false;
00180   if ( !storage().exists() ){
00181     created = true;
00182     storage().create( std::string(COND_SCHEMA_VERSION) );
00183   }  
00184   return created;
00185 }
00186 
00187 bool cond::DbSession::isOldSchema()
00188 {
00189   ora::Version dbVer = storage().schemaVersion();
00190   if (dbVer == ora::Version::poolSchemaVersion()) return true;
00191   dbVer = storage().schemaVersion( true );
00192   return dbVer < ora::Version::fromString( std::string( CHANGE_SCHEMA_VERSION ) );
00193 }
00194 
00195 coral::ISchema& cond::DbSession::schema( const std::string& schemaName )
00196 {
00197   return storage().storageAccessSession().get().schema( schemaName );
00198 }
00199 
00200 coral::ISchema& cond::DbSession::nominalSchema()
00201 {
00202   return storage().storageAccessSession().get().nominalSchema(); 
00203 }
00204 
00205 bool cond::DbSession::deleteMapping( const std::string& mappingVersion ){
00206   ora::DatabaseUtility utility = storage().utility();
00207   utility.eraseMapping( mappingVersion );
00208   return true;
00209 }
00210 
00211 bool cond::DbSession::importMapping( const std::string& sourceConnectionString,
00212                                      const std::string& contName ){ 
00213   ora::DatabaseUtility utility = storage().utility();
00214   std::auto_ptr<cond::TechnologyProxy> technologyProxy = buildTechnologyProxy(sourceConnectionString, *(m_implementation->connection));
00215   utility.importContainerSchema( (*technologyProxy).getRealConnectString(), contName );
00216   return true;
00217 }
00218 
00219 std::string cond::DbSession::storeObject( const ora::Object& object, const std::string& containerName  ){
00220   ora::OId oid = storage().insertItem( containerName, object );
00221   storage().flush();
00222   return oid.toString();
00223 }
00224 
00225 ora::Object  cond::DbSession::getObject( const std::string& objectId ){
00226   ora::OId oid;
00227   oid.fromString( objectId );
00228   return storage().fetchItem( oid );
00229 }
00230 
00231 bool cond::DbSession::deleteObject( const std::string& objectId ){
00232   ora::OId oid;
00233   oid.fromString( objectId );
00234   storage().erase( oid );
00235   storage().flush();
00236   return true;
00237 }
00238 
00239 std::string cond::DbSession::importObject( cond::DbSession& fromDatabase, const std::string& objectId ){
00240   ora::OId oid;
00241   oid.fromString( objectId );
00242   ora::Object data = fromDatabase.getObject( objectId );
00243   ora::Container cont = fromDatabase.storage().containerHandle( oid.containerId() );
00244   std::string ret = storeObject( data, cont.name() );
00245   data.destruct();
00246   return ret;
00247 }
00248 
00249 std::string cond::DbSession::classNameForItem( const std::string& objectId ){
00250   ora::OId oid;
00251   oid.fromString( objectId );
00252   std::string ret("");
00253   if( !oid.isInvalid() ){
00254     ora::Container cont = storage().containerHandle( oid.containerId() );
00255     ret = cont.className();
00256   }
00257   return ret; 
00258 }
00259 
00260 void cond::DbSession::flush(){
00261   storage().flush();
00262 }
00263 
00264 cond::PoolTokenParser::PoolTokenParser( ora::Database& db ):
00265   m_db( db ){
00266 }
00267 
00268 ora::OId cond::PoolTokenParser::parse( const std::string& poolToken ){
00269   std::pair<std::string,int> oidData = parseToken( poolToken );
00270   if( oidData.first.empty() ){
00271     throwException("Could not resolve Container name from token=\""+poolToken+"\".","PoolTokenParser::parse");
00272   }
00273   ora::Container cont = m_db.containerHandle(  oidData.first );
00274   return ora::OId( cont.id(), oidData.second );
00275 }
00276 
00277 std::string cond::PoolTokenParser::className( const std::string& oraToken ){
00278   ora::OId oid;
00279   oid.fromString( oraToken );
00280   ora::Container cont = m_db.containerHandle(  oid.containerId() );
00281   return cont.className();
00282 }
00283 
00284 cond::PoolTokenWriter::PoolTokenWriter( ora::Database& db ):
00285   m_db( db ){
00286 }
00287 
00288 std::string cond::PoolTokenWriter::write( const ora::OId& oid ){
00289   ora::Container cont = m_db.containerHandle( oid.containerId() );
00290   return writeToken( cont.name(), oid.containerId(), oid.itemId(), cont.className() );
00291 }