CMS 3D CMS Logo

CMSSW_4_4_3_patch1/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 void ora::DatabaseSession::clearTransaction(){
00090   m_transactionCache.reset();
00091   m_mappingDb.reset();
00092   m_contIdSequence.reset();
00093   m_schema.reset();
00094   m_containerUpdateTable.clear();
00095 }
00096 
00097 void ora::DatabaseSession::disconnect(){
00098   if( isConnected() ){
00099     if( isTransactionActive()) rollbackTransaction();
00100   }
00101   clearTransaction();
00102   m_dbSession.close();
00103   m_connectionString.clear();
00104   if(m_monitoring) m_monitoring->stop();
00105 }
00106 
00107 bool ora::DatabaseSession::isConnected(){
00108   return m_dbSession.isValid();
00109 }
00110 
00111 const std::string& ora::DatabaseSession::connectionString(){
00112   return m_connectionString;
00113 }
00114 
00115 void ora::DatabaseSession::startTransaction( bool readOnly ){
00116   if( !m_transactionCache.get() ){
00117     m_dbSession.get().transaction().start( readOnly );
00118     m_schema.reset( IDatabaseSchema::createSchemaHandle( m_dbSession.get().nominalSchema() ));
00119     m_contIdSequence.reset( new NamedSequence( MappingRules::sequenceNameForContainerId(), *m_schema ));
00120     m_mappingDb.reset( new MappingDatabase( *m_schema ));
00121     m_transactionCache.reset( new TransactionCache );
00122     if(m_monitoring) {
00123       m_monitoring->newTransaction();
00124     }
00125   }
00126 }
00127 
00128 void ora::DatabaseSession::commitTransaction(){
00129   if( m_transactionCache.get() ){
00130     m_schema->containerHeaderTable().updateNumberOfObjects( m_containerUpdateTable.table() );
00131     m_dbSession.get().transaction().commit();
00132     clearTransaction();
00133     if(m_monitoring) {
00134       m_monitoring->stopTransaction();
00135     }
00136   }
00137 }
00138 
00139 void ora::DatabaseSession::rollbackTransaction(){
00140   if( m_transactionCache.get() ){
00141     m_dbSession.get().transaction().rollback();
00142     clearTransaction();
00143     if(m_monitoring) {
00144       m_monitoring->stopTransaction(false);
00145     }
00146   }
00147 }
00148 
00149 bool ora::DatabaseSession::isTransactionActive( bool checkIfReadOnly ){
00150   bool ret = false;
00151   if( m_dbSession.get().transaction().isActive() ){
00152     if( checkIfReadOnly ){
00153       if( m_dbSession.get().transaction().isReadOnly() ) ret = true;
00154     } else {
00155       ret = true;
00156     }
00157   }
00158   return ret;
00159 }
00160 
00161 bool ora::DatabaseSession::exists(){
00162   if(!m_transactionCache->dbExistsLoaded()){
00163     m_transactionCache->setDbExists( m_schema->exists() );
00164   }
00165   return m_transactionCache->dbExists();
00166 }
00167 
00168 void ora::DatabaseSession::create( const std::string& userSchemaVersion ){
00169   m_schema->create( userSchemaVersion );
00170   m_contIdSequence->create();
00171   m_mappingDb->setUp();
00172   m_transactionCache->setDbExists( true );
00173 }
00174 
00175 void ora::DatabaseSession::drop(){
00176   if(!testDropPermission()){
00177     throwException("Drop permission has been denied for the current user.",
00178                    "DatabaseSession::drop");
00179   }
00180   m_schema->drop();
00181   m_transactionCache->dropDatabase();
00182 }
00183 
00184 void ora::DatabaseSession::setAccessPermission( const std::string& principal, 
00185                                                 bool forWrite ){
00186   m_schema->setAccessPermission( principal, forWrite );
00187 }
00188     
00189 bool ora::DatabaseSession::testDropPermission(){
00190   if(!m_transactionCache->dropPermissionLoaded()){
00191     m_transactionCache->setDropPermission( m_schema->testDropPermission() );
00192   }
00193   return m_transactionCache->dropPermission();
00194 }
00195 
00196 void ora::DatabaseSession::open(){
00197   if(!m_transactionCache->isLoaded()){
00198     std::map<std::string, ContainerHeaderData> containersData;
00199     m_schema->containerHeaderTable().getContainerData( containersData );
00200     for(std::map<std::string, ContainerHeaderData>::iterator iC = containersData.begin();
00201         iC != containersData.end(); ++iC){
00202       Handle<DatabaseContainer> container( new DatabaseContainer( iC->second.id, iC->first,
00203                                                                   iC->second.className,
00204                                                                   iC->second.numberOfObjects, *this ) );
00205       m_transactionCache->addContainer( iC->second.id, iC->first, container );
00206     }
00207     m_schema->mainTable().getParameters( m_transactionCache->dbParams() );
00208     m_transactionCache->setLoaded();
00209   }
00210 }
00211 
00212 std::string ora::DatabaseSession::schemaVersion( bool userSchema ){
00213   std::map<std::string,std::string>& params = m_transactionCache->dbParams();
00214   std::string version("");
00215   std::string paramName = IMainTable::versionParameterName();
00216   if(userSchema ) paramName = IMainTable::userSchemaVersionParameterName();
00217   std::map<std::string,std::string>::const_iterator iPar = params.find( paramName );
00218   if( iPar != params.end() ){
00219     version = iPar->second;
00220   }
00221   return version;
00222 }
00223 
00224 ora::Handle<ora::DatabaseContainer> ora::DatabaseSession::addContainer( const std::string& containerName,
00225                                                                         const std::string& className ){
00226   int newContId = m_contIdSequence->getNextId( true );
00227   m_schema->containerHeaderTable().addContainer( newContId, containerName, className );
00228   Handle<DatabaseContainer> container( new DatabaseContainer( newContId, containerName,
00229                                                               className, 0, *this ) );
00230   m_transactionCache->addContainer( newContId, containerName, container );
00231   return container;
00232 }
00233 
00234 
00235 ora::Handle<ora::DatabaseContainer> ora::DatabaseSession::createContainer( const std::string& containerName,
00236                                                                            const Reflex::Type& type ){
00237   // create the container
00238   int newContId = m_contIdSequence->getNextId( true );
00239   Handle<DatabaseContainer> newCont ( new DatabaseContainer( newContId, containerName, type, *this ) );
00240   m_transactionCache->addContainer( newContId, containerName, newCont );
00241   newCont->create();
00242   return newCont;
00243 }
00244 
00245 void ora::DatabaseSession::dropContainer( const std::string& name ){
00246   Handle<DatabaseContainer> cont = m_transactionCache->getContainer( name );
00247   m_transactionCache->eraseContainer( cont->id(), name );
00248   cont->drop();
00249 }
00250 
00251 ora::Handle<ora::DatabaseContainer> ora::DatabaseSession::containerHandle( const std::string& name ){
00252   return m_transactionCache->getContainer( name );
00253 }
00254 
00255 ora::Handle<ora::DatabaseContainer> ora::DatabaseSession::containerHandle( int contId ){
00256   return  m_transactionCache->getContainer( contId );
00257 }
00258 
00259 const std::map<int, ora::Handle<ora::DatabaseContainer> >& ora::DatabaseSession::containers(){
00260   return m_transactionCache->containers();
00261 }
00262 
00263 void ora::DatabaseSession::setObjectName( const std::string& name, 
00264                                           int containerId, 
00265                                           int itemId ){
00266   m_schema->namingServiceTable().setObjectName( name, containerId, itemId );
00267 }
00268 
00269 bool ora::DatabaseSession::eraseObjectName( const std::string& name ){
00270   return m_schema->namingServiceTable().eraseObjectName( name );
00271 }
00272 
00273 bool ora::DatabaseSession::eraseAllNames(){
00274   return m_schema->namingServiceTable().eraseAllNames();
00275 }
00276 
00277 ora::Object ora::DatabaseSession::fetchObjectByName( const std::string& name ){
00278   ora::Object ret;
00279   std::pair<int,int> oid;
00280   if( m_schema->namingServiceTable().getObjectByName( name, oid ) ){
00281     ora::Handle<ora::DatabaseContainer> cont = containerHandle( oid.first );
00282     if( cont ) ret = Object( cont->fetchItem( oid.second ), cont->type() );
00283   }
00284   return ret;
00285 }
00286 
00287 bool ora::DatabaseSession::getItemId( const std::string& name, ora::OId& destination ){
00288   std::pair<int,int> oidData;
00289   if( m_schema->namingServiceTable().getObjectByName( name, oidData ) ){
00290     destination = OId( oidData.first, oidData.second );
00291     return true;
00292   }
00293   return false;
00294 }
00295 
00296 boost::shared_ptr<void> ora::DatabaseSession::fetchTypedObjectByName( const std::string& name, 
00297                                                                       const Reflex::Type& asType ){
00298   boost::shared_ptr<void> ret = m_transactionCache->getNamedReference( name );
00299   if( !ret.get() ){
00300     std::pair<int,int> oid;
00301     if( m_schema->namingServiceTable().getObjectByName( name, oid ) ){
00302       ora::Handle<ora::DatabaseContainer> cont = containerHandle( oid.first );
00303       void* ptr = 0;
00304       if( cont ) {
00305         ptr = cont->fetchItemAsType( oid.second, asType );
00306         if( ptr) ret = boost::shared_ptr<void>( ptr, RflxDeleter( cont->type() ) );
00307       }
00308     }
00309     if( ret.get() ) m_transactionCache->setNamedReference( name, ret );
00310   }
00311   return ret;
00312 }
00313 
00314 bool ora::DatabaseSession::getNamesForContainer( int containerId, 
00315                                                  std::vector<std::string>& destination ){
00316   return m_schema->namingServiceTable().getNamesForContainer( containerId, destination );
00317 }
00318     
00319 bool ora::DatabaseSession::getNamesForObject( int containerId, 
00320                                               int itemId, 
00321                                               std::vector<std::string>& destination ){
00322   return m_schema->namingServiceTable().getNamesForObject( containerId, itemId, destination );
00323 }
00324 
00325 bool ora::DatabaseSession::listObjectNames( std::vector<std::string>& destination ){
00326   
00327   return m_schema->namingServiceTable().getAllNames( destination );
00328 }
00329 
00330 ora::Handle<ora::DatabaseUtilitySession> ora::DatabaseSession::utility(){
00331   if( !m_transactionCache->utility() ){
00332     Handle<DatabaseUtilitySession> util ( new DatabaseUtilitySession( *this ) );
00333     m_transactionCache->setUtility( util );
00334   }
00335   return m_transactionCache->utility();
00336 }
00337 
00338 ora::IDatabaseSchema& ora::DatabaseSession::schema(){
00339   return *m_schema;  
00340 }
00341 
00342 ora::NamedSequence& ora::DatabaseSession::containerIdSequence(){
00343   return *m_contIdSequence;
00344 }
00345 
00346 ora::MappingDatabase& ora::DatabaseSession::mappingDatabase(){
00347   return *m_mappingDb;  
00348 }
00349 
00350 ora::Configuration& ora::DatabaseSession::configuration(){
00351   return m_configuration;
00352 }
00353 
00354 ora::SharedSession& ora::DatabaseSession::storageAccessSession(){
00355   return m_dbSession;
00356 }
00357 
00358 boost::shared_ptr<ora::ConnectionPool>& ora::DatabaseSession::connectionPool(){
00359   return m_connectionPool;
00360 }
00361 
00362 ora::ContainerUpdateTable& ora::DatabaseSession::containerUpdateTable(){
00363   return m_containerUpdateTable;
00364 }