CMS 3D CMS Logo

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