CMS 3D CMS Logo

/afs/cern.ch/work/a/aaltunda/public/www/CMSSW_5_3_13_patch3/src/CondCore/ORA/src/DatabaseSession.cc

Go to the documentation of this file.
00001 #include "CondCore/ORA/interface/Exception.h"
00002 #include "CondCore/ORA/interface/Monitoring.h"
00003 #include "DatabaseSession.h"
00004 #include "IDatabaseSchema.h"
00005 #include "Sequences.h"
00006 #include "MappingDatabase.h"
00007 #include "TransactionCache.h"
00008 #include "DatabaseContainer.h"
00009 #include "ClassUtils.h"
00010 #include "MappingRules.h"
00011 #include "DatabaseUtilitySession.h"
00012 // externals
00013 #include "RelationalAccess/IConnectionServiceConfiguration.h"
00014 #include "RelationalAccess/ISessionProxy.h"
00015 #include "RelationalAccess/ITransaction.h"
00016 
00017 ora::ContainerUpdateTable::ContainerUpdateTable():
00018   m_table(){
00019 }
00020 
00021 ora::ContainerUpdateTable::~ContainerUpdateTable(){
00022 }
00023 
00024 void ora::ContainerUpdateTable::takeNote( int contId,
00025                                           unsigned int size ){
00026   std::map<int, unsigned int>::iterator iC = m_table.find( contId );
00027   if( iC == m_table.end() ){
00028     iC = m_table.insert( std::make_pair( contId, 0 ) ).first;
00029   }
00030   iC->second = size;
00031 }
00032 
00033 void ora::ContainerUpdateTable::remove(  int contId ){
00034   m_table.erase( contId );
00035 }
00036 
00037 const std::map<int, unsigned int>& ora::ContainerUpdateTable::table(){
00038   return m_table;
00039 }
00040 
00041 void ora::ContainerUpdateTable::clear(){
00042   m_table.clear();
00043 }
00044 
00045 ora::DatabaseSession::DatabaseSession():
00046   m_connectionPool( new ConnectionPool ),
00047   m_dbSession(),
00048   m_connectionString( "" ),
00049   m_schema(),
00050   m_contIdSequence(),
00051   m_mappingDb(),
00052   m_transactionCache(),
00053   m_containerUpdateTable(),
00054   m_configuration(),
00055   m_monitoring(0){
00056   // for the private connection pool does not make sense to have a real pool... 
00057   m_connectionPool->configuration().setConnectionTimeOut(0);
00058 }
00059 
00060 ora::DatabaseSession::DatabaseSession(boost::shared_ptr<ConnectionPool>& connectionPool ):
00061   m_connectionPool( connectionPool ),
00062   m_dbSession(),
00063   m_connectionString( "" ),
00064   m_schema(),
00065   m_contIdSequence(),
00066   m_mappingDb(),
00067   m_transactionCache(),
00068   m_containerUpdateTable(),
00069   m_configuration(),
00070   m_monitoring(0){
00071 }
00072 
00073 ora::DatabaseSession::~DatabaseSession(){
00074   disconnect();
00075 }
00076 
00077 bool ora::DatabaseSession::connect( const std::string& connectionString,
00078                                     bool readOnly ){
00079   m_dbSession = m_connectionPool->connect( connectionString, readOnly?coral::ReadOnly:coral::Update );
00080   if(m_dbSession.isValid()) {
00081     m_connectionString = connectionString;
00082     if( ora::Monitoring::isEnabled() ){
00083       m_monitoring = ora::Monitoring::get().startSession( connectionString );
00084     }
00085   }
00086   return isConnected();
00087 }
00088 
00089 bool ora::DatabaseSession::connect( const std::string& connectionString,
00090                                     const std::string& asRole,
00091                                     bool readOnly ){
00092   m_dbSession = m_connectionPool->connect( connectionString, asRole, readOnly?coral::ReadOnly:coral::Update );
00093   if(m_dbSession.isValid()) {
00094     m_connectionString = connectionString;
00095     if( ora::Monitoring::isEnabled() ){
00096       m_monitoring = ora::Monitoring::get().startSession( connectionString );
00097     }
00098   }
00099   return isConnected();
00100 }
00101 
00102 void ora::DatabaseSession::clearTransaction(){
00103   m_transactionCache.reset();
00104   m_mappingDb.reset();
00105   m_contIdSequence.reset();
00106   m_schema.reset();
00107   m_containerUpdateTable.clear();
00108 }
00109 
00110 void ora::DatabaseSession::disconnect(){
00111   if( isConnected() ){
00112     if( isTransactionActive()) rollbackTransaction();
00113   }
00114   clearTransaction();
00115   m_dbSession.close();
00116   m_connectionString.clear();
00117   if(m_monitoring) m_monitoring->stop();
00118 }
00119 
00120 bool ora::DatabaseSession::isConnected(){
00121   return m_dbSession.isValid();
00122 }
00123 
00124 const std::string& ora::DatabaseSession::connectionString(){
00125   return m_connectionString;
00126 }
00127 
00128 void ora::DatabaseSession::startTransaction( bool readOnly ){
00129   if( !m_transactionCache.get() ){
00130     m_dbSession.get().transaction().start( readOnly );
00131     m_schema.reset( IDatabaseSchema::createSchemaHandle( m_dbSession.get().nominalSchema() ));
00132     m_contIdSequence.reset( new NamedSequence( MappingRules::sequenceNameForContainerId(), *m_schema ));
00133     m_mappingDb.reset( new MappingDatabase( *m_schema ));
00134     m_transactionCache.reset( new TransactionCache );
00135     if(m_monitoring) {
00136       m_monitoring->newTransaction();
00137     }
00138   }
00139 }
00140 
00141 void ora::DatabaseSession::commitTransaction(){
00142   if( m_transactionCache.get() ){
00143     m_schema->containerHeaderTable().updateNumberOfObjects( m_containerUpdateTable.table() );
00144     m_dbSession.get().transaction().commit();
00145     clearTransaction();
00146     if(m_monitoring) {
00147       m_monitoring->stopTransaction();
00148     }
00149   }
00150 }
00151 
00152 void ora::DatabaseSession::rollbackTransaction(){
00153   if( m_transactionCache.get() ){
00154     m_dbSession.get().transaction().rollback();
00155     clearTransaction();
00156     if(m_monitoring) {
00157       m_monitoring->stopTransaction(false);
00158     }
00159   }
00160 }
00161 
00162 bool ora::DatabaseSession::isTransactionActive( bool checkIfReadOnly ){
00163   bool ret = false;
00164   if( m_dbSession.get().transaction().isActive() ){
00165     if( checkIfReadOnly ){
00166       if( m_dbSession.get().transaction().isReadOnly() ) ret = true;
00167     } else {
00168       ret = true;
00169     }
00170   }
00171   return ret;
00172 }
00173 
00174 bool ora::DatabaseSession::exists(){
00175   if(!m_transactionCache->dbExistsLoaded()){
00176     m_transactionCache->setDbExists( m_schema->exists() );
00177   }
00178   return m_transactionCache->dbExists();
00179 }
00180 
00181 void ora::DatabaseSession::create( const std::string& userSchemaVersion ){
00182   m_schema->create( userSchemaVersion );
00183   m_contIdSequence->create();
00184   m_mappingDb->setUp();
00185   m_transactionCache->setDbExists( true );
00186 }
00187 
00188 void ora::DatabaseSession::drop(){
00189   if(!testDropPermission()){
00190     throwException("Drop permission has been denied for the current user.",
00191                    "DatabaseSession::drop");
00192   }
00193   m_schema->drop();
00194   m_transactionCache->dropDatabase();
00195 }
00196 
00197 void ora::DatabaseSession::setAccessPermission( const std::string& principal, 
00198                                                 bool forWrite ){
00199   m_schema->setAccessPermission( principal, forWrite );
00200 }
00201     
00202 bool ora::DatabaseSession::testDropPermission(){
00203   if(!m_transactionCache->dropPermissionLoaded()){
00204     m_transactionCache->setDropPermission( m_schema->testDropPermission() );
00205   }
00206   return m_transactionCache->dropPermission();
00207 }
00208 
00209 void ora::DatabaseSession::open(){
00210   if(!m_transactionCache->isLoaded()){
00211     std::map<std::string, ContainerHeaderData> containersData;
00212     m_schema->containerHeaderTable().getContainerData( containersData );
00213     for(std::map<std::string, ContainerHeaderData>::iterator iC = containersData.begin();
00214         iC != containersData.end(); ++iC){
00215       Handle<DatabaseContainer> container( new DatabaseContainer( iC->second.id, iC->first,
00216                                                                   iC->second.className,
00217                                                                   iC->second.numberOfObjects, *this ) );
00218       m_transactionCache->addContainer( iC->second.id, iC->first, container );
00219     }
00220     m_schema->mainTable().getParameters( m_transactionCache->dbParams() );
00221     m_transactionCache->setLoaded();
00222   }
00223 }
00224 
00225 std::string ora::DatabaseSession::schemaVersion( bool userSchema ){
00226   std::map<std::string,std::string>& params = m_transactionCache->dbParams();
00227   std::string version("");
00228   std::string paramName = IMainTable::versionParameterName();
00229   if(userSchema ) paramName = IMainTable::userSchemaVersionParameterName();
00230   std::map<std::string,std::string>::const_iterator iPar = params.find( paramName );
00231   if( iPar != params.end() ){
00232     version = iPar->second;
00233   }
00234   return version;
00235 }
00236 
00237 ora::Handle<ora::DatabaseContainer> ora::DatabaseSession::addContainer( const std::string& containerName,
00238                                                                         const std::string& className ){
00239   int newContId = m_contIdSequence->getNextId( true );
00240   m_schema->containerHeaderTable().addContainer( newContId, containerName, className );
00241   Handle<DatabaseContainer> container( new DatabaseContainer( newContId, containerName,
00242                                                               className, 0, *this ) );
00243   m_transactionCache->addContainer( newContId, containerName, container );
00244   return container;
00245 }
00246 
00247 
00248 ora::Handle<ora::DatabaseContainer> ora::DatabaseSession::createContainer( const std::string& containerName,
00249                                                                            const Reflex::Type& type ){
00250   // create the container
00251   int newContId = m_contIdSequence->getNextId( true );
00252   Handle<DatabaseContainer> newCont ( new DatabaseContainer( newContId, containerName, type, *this ) );
00253   m_transactionCache->addContainer( newContId, containerName, newCont );
00254   newCont->create();
00255   return newCont;
00256 }
00257 
00258 void ora::DatabaseSession::dropContainer( const std::string& name ){
00259   Handle<DatabaseContainer> cont = m_transactionCache->getContainer( name );
00260   m_transactionCache->eraseContainer( cont->id(), name );
00261   cont->drop();
00262 }
00263 
00264 ora::Handle<ora::DatabaseContainer> ora::DatabaseSession::containerHandle( const std::string& name ){
00265   return m_transactionCache->getContainer( name );
00266 }
00267 
00268 ora::Handle<ora::DatabaseContainer> ora::DatabaseSession::containerHandle( int contId ){
00269   return  m_transactionCache->getContainer( contId );
00270 }
00271 
00272 const std::map<int, ora::Handle<ora::DatabaseContainer> >& ora::DatabaseSession::containers(){
00273   return m_transactionCache->containers();
00274 }
00275 
00276 void ora::DatabaseSession::setObjectName( const std::string& name, 
00277                                           int containerId, 
00278                                           int itemId ){
00279   m_schema->namingServiceTable().setObjectName( name, containerId, itemId );
00280 }
00281 
00282 bool ora::DatabaseSession::eraseObjectName( const std::string& name ){
00283   return m_schema->namingServiceTable().eraseObjectName( name );
00284 }
00285 
00286 bool ora::DatabaseSession::eraseAllNames(){
00287   return m_schema->namingServiceTable().eraseAllNames();
00288 }
00289 
00290 ora::Object ora::DatabaseSession::fetchObjectByName( const std::string& name ){
00291   ora::Object ret;
00292   std::pair<int,int> oid;
00293   if( m_schema->namingServiceTable().getObjectByName( name, oid ) ){
00294     ora::Handle<ora::DatabaseContainer> cont = containerHandle( oid.first );
00295     if( cont ) ret = Object( cont->fetchItem( oid.second ), cont->type() );
00296   }
00297   return ret;
00298 }
00299 
00300 bool ora::DatabaseSession::getItemId( const std::string& name, ora::OId& destination ){
00301   std::pair<int,int> oidData;
00302   if( m_schema->namingServiceTable().getObjectByName( name, oidData ) ){
00303     destination = OId( oidData.first, oidData.second );
00304     return true;
00305   }
00306   return false;
00307 }
00308 
00309 boost::shared_ptr<void> ora::DatabaseSession::fetchTypedObjectByName( const std::string& name, 
00310                                                                       const Reflex::Type& asType ){
00311   boost::shared_ptr<void> ret = m_transactionCache->getNamedReference( name );
00312   if( !ret.get() ){
00313     std::pair<int,int> oid;
00314     if( m_schema->namingServiceTable().getObjectByName( name, oid ) ){
00315       ora::Handle<ora::DatabaseContainer> cont = containerHandle( oid.first );
00316       void* ptr = 0;
00317       if( cont ) {
00318         ptr = cont->fetchItemAsType( oid.second, asType );
00319         if( ptr) ret = boost::shared_ptr<void>( ptr, RflxDeleter( cont->type() ) );
00320       }
00321     }
00322     if( ret.get() ) m_transactionCache->setNamedReference( name, ret );
00323   }
00324   return ret;
00325 }
00326 
00327 bool ora::DatabaseSession::getNamesForContainer( int containerId, 
00328                                                  std::vector<std::string>& destination ){
00329   return m_schema->namingServiceTable().getNamesForContainer( containerId, destination );
00330 }
00331     
00332 bool ora::DatabaseSession::getNamesForObject( int containerId, 
00333                                               int itemId, 
00334                                               std::vector<std::string>& destination ){
00335   return m_schema->namingServiceTable().getNamesForObject( containerId, itemId, destination );
00336 }
00337 
00338 bool ora::DatabaseSession::listObjectNames( std::vector<std::string>& destination ){
00339   
00340   return m_schema->namingServiceTable().getAllNames( destination );
00341 }
00342 
00343 ora::Handle<ora::DatabaseUtilitySession> ora::DatabaseSession::utility(){
00344   if( !m_transactionCache->utility() ){
00345     Handle<DatabaseUtilitySession> util ( new DatabaseUtilitySession( *this ) );
00346     m_transactionCache->setUtility( util );
00347   }
00348   return m_transactionCache->utility();
00349 }
00350 
00351 ora::IDatabaseSchema& ora::DatabaseSession::schema(){
00352   return *m_schema;  
00353 }
00354 
00355 ora::NamedSequence& ora::DatabaseSession::containerIdSequence(){
00356   return *m_contIdSequence;
00357 }
00358 
00359 ora::MappingDatabase& ora::DatabaseSession::mappingDatabase(){
00360   return *m_mappingDb;  
00361 }
00362 
00363 ora::Configuration& ora::DatabaseSession::configuration(){
00364   return m_configuration;
00365 }
00366 
00367 ora::SharedSession& ora::DatabaseSession::storageAccessSession(){
00368   return m_dbSession;
00369 }
00370 
00371 boost::shared_ptr<ora::ConnectionPool>& ora::DatabaseSession::connectionPool(){
00372   return m_connectionPool;
00373 }
00374 
00375 ora::ContainerUpdateTable& ora::DatabaseSession::containerUpdateTable(){
00376   return m_containerUpdateTable;
00377 }