CMS 3D CMS Logo

/afs/cern.ch/work/a/aaltunda/public/www/CMSSW_5_3_14/src/CondCore/ORA/src/Database.cc

Go to the documentation of this file.
00001 #include "CondCore/ORA/interface/Database.h"
00002 #include "CondCore/ORA/interface/Transaction.h"
00003 #include "CondCore/ORA/interface/Exception.h"
00004 #include "CondCore/ORA/interface/Handle.h"
00005 #include "DatabaseSession.h"
00006 #include "DatabaseContainer.h"
00007 #include "TransactionCache.h"
00008 #include "ContainerSchema.h"
00009 #include "IDatabaseSchema.h"
00010 #include "ClassUtils.h"
00011 
00012 namespace ora {
00013 
00014   class DatabaseImpl {
00015     public:
00016       DatabaseImpl():
00017         m_session(0),
00018         m_transaction(0){
00019         m_session.reset( new DatabaseSession );
00020         m_transaction.reset( new Transaction( *m_session ));
00021       }
00022 
00023       DatabaseImpl(boost::shared_ptr<ConnectionPool>& connectionPool):
00024         m_session(0),
00025         m_transaction(0){
00026         m_session.reset( new DatabaseSession( connectionPool ) );
00027         m_transaction.reset( new Transaction( *m_session )) ;
00028       }
00029       
00030       ~DatabaseImpl(){
00031       }
00032 
00033       std::auto_ptr<DatabaseSession> m_session;
00034       std::auto_ptr<Transaction> m_transaction;      
00035   };
00036   
00037   std::string nameFromClass( const Reflex::Type& contType ){
00038     return contType.Name( Reflex::SCOPED );
00039   }
00040   
00041   Container getContainerFromSession( const std::string& name, const Reflex::Type& contType, DatabaseSession& session ){
00042     Handle<DatabaseContainer> contHandle = session.containerHandle( name );
00043     if( !contHandle ){
00044       if( session.configuration().properties().getFlag( Configuration::automaticDatabaseCreation()) ||
00045           session.configuration().properties().getFlag( Configuration::automaticContainerCreation() ) ){
00046         contHandle = session.createContainer( name, contType );
00047       } else {
00048         throwException("Container \""+name+"\" does not exist in the database.",
00049                        "Database::insertItem");
00050       }
00051     }
00052 
00053     return Container( contHandle );
00054   }
00055 }
00056 
00057 std::string ora::Database::nameForContainer( const std::type_info& typeInfo ){
00058   Reflex::Type contType = ClassUtils::lookupDictionary( typeInfo );
00059   return nameFromClass( contType );
00060 }
00061 
00062 std::string ora::Database::nameForContainer( const std::string& className ){
00063   return className;
00064 }
00065 
00066 ora::Database::Database():
00067   m_impl( new DatabaseImpl ){
00068 }
00069 
00070 ora::Database::Database( const Database& rhs ):
00071   m_impl( rhs.m_impl ){
00072 }
00073 
00074 ora::Database::Database(boost::shared_ptr<ConnectionPool>& connectionPool):
00075   m_impl( new DatabaseImpl( connectionPool) ){
00076 }
00077 
00078 ora::Database::~Database(){
00079   disconnect();
00080 }
00081 
00082 ora::Database& ora::Database::operator=( const Database& rhs ){
00083   if( this != &rhs ) m_impl = rhs.m_impl;
00084   return *this;
00085 }
00086 
00087 ora::Configuration& ora::Database::configuration(){
00088   return m_impl->m_session->configuration();
00089 }
00090 
00091 bool ora::Database::connect( const std::string& connectionString,
00092                              bool readOnly ){
00093   return m_impl->m_session->connect( connectionString, readOnly );
00094 }
00095 
00096 bool ora::Database::connect( const std::string& connectionString,
00097                              const std::string& asRole,
00098                              bool readOnly ){
00099   return m_impl->m_session->connect( connectionString, asRole, readOnly );
00100 }
00101 
00102 void ora::Database::disconnect(){
00103   m_impl->m_session->disconnect();
00104 }
00105 
00106 bool ora::Database::isConnected() {
00107   return m_impl->m_session->isConnected();
00108 }
00109 
00110 const std::string& ora::Database::connectionString() {
00111   return m_impl->m_session->connectionString();
00112 }
00113 
00114 ora::Transaction& ora::Database::transaction(){
00115   if(!m_impl->m_session->isConnected()) {
00116     throwException("No database storage connected.","Database::transaction");
00117   }
00118   return *m_impl->m_transaction;
00119 }
00120 
00121 void ora::Database::checkTransaction(){
00122   if(!m_impl->m_session->isConnected()) {
00123     throwException("No database storage connected.","Database::checkTransaction");
00124   }
00125   if(!m_impl->m_transaction->isActive()) {
00126     throwException("Transaction is not active.","Database::checkTransaction");
00127   }  
00128 }
00129 
00130 bool ora::Database::exists(){
00131   checkTransaction();
00132   return m_impl->m_session->exists();
00133 }
00134 
00135 bool ora::Database::create( std::string userSchemaVersion ){
00136   bool created = false;
00137   if( !exists()){
00138     m_impl->m_session->create( userSchemaVersion );
00139     created = true;
00140   }
00141   return created;
00142 }
00143 
00144 bool ora::Database::drop(){
00145   bool dropped = false;
00146   if( exists()){
00147     open();
00148     const std::map<int, Handle<DatabaseContainer> >& conts = m_impl->m_session->containers();
00149     for(std::map<int, Handle<DatabaseContainer> >::const_iterator iC = conts.begin();
00150         iC != conts.end(); iC++ ){
00151       iC->second->drop();
00152     }
00153     m_impl->m_session->drop();
00154     dropped = true;
00155   }
00156   return dropped;
00157 }
00158 
00159 void ora::Database::setAccessPermission( const std::string& principal, bool forWrite ){
00160   if( exists()){
00161     open();
00162     m_impl->m_session->setAccessPermission( principal, forWrite );
00163     const std::map<int, Handle<DatabaseContainer> >& conts = m_impl->m_session->containers();
00164     for(std::map<int, Handle<DatabaseContainer> >::const_iterator iC = conts.begin();
00165         iC != conts.end(); iC++ ){
00166       iC->second->setAccessPermission( principal, forWrite );
00167     }
00168   }
00169 }
00170 
00171 void ora::Database::open( bool writingAccess /*=false*/){
00172   checkTransaction();
00173   if( !m_impl->m_session->exists() ){
00174     if( writingAccess && m_impl->m_session->configuration().properties().getFlag( Configuration::automaticDatabaseCreation() ) ){
00175       m_impl->m_session->create();
00176     } else {
00177       throwException("Database does not exists in \""+m_impl->m_session->connectionString()+"\"","Database::open");
00178     }
00179   }
00180   m_impl->m_session->open();
00181 }
00182 
00183 ora::Version ora::Database::schemaVersion( bool userSchema ){
00184   checkTransaction();
00185   if( !m_impl->m_session->exists() ){
00186     throwException("Database does not exists in \""+m_impl->m_session->connectionString()+"\"","Database::schemaVersion");
00187   }
00188   return Version::fromString( m_impl->m_session->schemaVersion( userSchema ) );
00189 }
00190 
00191 std::set< std::string > ora::Database::containers() {
00192   open();
00193   std::set< std::string > contList;
00194   const std::map<int, Handle<DatabaseContainer> >& conts = m_impl->m_session->containers();
00195   for(std::map<int, Handle<DatabaseContainer> >::const_iterator iC = conts.begin();
00196       iC != conts.end(); iC++ ){
00197     contList.insert( iC->second->name() );
00198   }
00199   return contList;
00200 }
00201 
00202 ora::Container ora::Database::createContainer( const std::string& name,
00203                                                const std::type_info& typeInfo ){
00204   open( true );
00205   if( m_impl->m_session->containerHandle( name ) ){
00206     throwException("Container with name \""+name+"\" already exists in the database.",
00207                    "Database::createContainer");
00208   }
00209   Reflex::Type contType = ClassUtils::lookupDictionary( typeInfo );
00210   Handle<DatabaseContainer> cont = m_impl->m_session->createContainer( name, contType );
00211   return Container( cont );
00212 }
00213 
00214 ora::Container ora::Database::createContainer( const std::type_info& typeInfo ){
00215   open( true );
00216   Reflex::Type contType = ClassUtils::lookupDictionary( typeInfo );
00217   std::string name = nameFromClass( contType );
00218   if( m_impl->m_session->containerHandle( name ) ){
00219     throwException("Container with name \""+name+"\" already exists in the database.",
00220                    "Database::createContainer");
00221   }  
00222   Handle<DatabaseContainer> cont = m_impl->m_session->createContainer( name, contType );
00223   return Container( cont );
00224 }
00225 
00226 ora::Container ora::Database::createContainer( const std::string& className,
00227                                                std::string name ){
00228   open( true );
00229   Reflex::Type contType =  ClassUtils::lookupDictionary( className );
00230   if( name.empty() ) name = nameForContainer( className );
00231   if( m_impl->m_session->containerHandle( name ) ){
00232     throwException("Container with name \""+name+"\" already exists in the database.",
00233                    "Database::createContainer");
00234   }  
00235   Handle<DatabaseContainer> cont = m_impl->m_session->createContainer( name, contType );
00236   return Container( cont );
00237 }
00238 
00239 ora::Container ora::Database::getContainer( const std::string& containerName,
00240                                             const std::type_info&  typeInfo){
00241   open( true );
00242   Reflex::Type objType = ClassUtils::lookupDictionary( typeInfo );
00243   return getContainerFromSession( containerName, objType, *m_impl->m_session );
00244 }
00245 
00246 ora::Container ora::Database::getContainer( const std::type_info& typeInfo ){
00247   open( true );
00248   Reflex::Type objType = ClassUtils::lookupDictionary( typeInfo );
00249   std::string contName = nameFromClass( objType );
00250   return getContainerFromSession( contName, objType, *m_impl->m_session);
00251 }
00252 
00253 bool ora::Database::dropContainer( const std::string& name ){
00254   open();
00255   if( !m_impl->m_session->containerHandle( name ) ){
00256     return false;
00257   }  
00258   m_impl->m_session->dropContainer( name );
00259   return true;
00260 }
00261 
00262 bool ora::Database::lockContainer( const std::string& name ){
00263   open();
00264   Handle<DatabaseContainer> cont = m_impl->m_session->containerHandle( name );
00265   if( !cont ){
00266     throwException("Container \""+name+"\" does not exist in the database.",
00267                    "Database::lockContainer");
00268   }
00269   return cont->lock();
00270 }
00271 
00272 ora::Container ora::Database::containerHandle( const std::string& name ){
00273   open();
00274   Handle<DatabaseContainer> cont = m_impl->m_session->containerHandle( name );
00275   if( !cont ){
00276     throwException("Container \""+name+"\" does not exist in the database.",
00277                    "Database::containerHandle");
00278   }
00279   return Container( cont );
00280 }
00281 
00282 ora::Container ora::Database::containerHandle( int contId ){
00283   open();
00284   Handle<DatabaseContainer> cont = m_impl->m_session->containerHandle( contId );
00285   if( !cont ){
00286     std::stringstream messg;
00287     messg << "Container with id=" << contId << " not found in the database.";
00288     throwException(messg.str(),
00289                    "Database::containerHandle");
00290   }
00291   return Container( cont );
00292 }
00293 
00294 ora::Object ora::Database::fetchItem(const OId& oid){
00295   Container cont = containerHandle( oid.containerId() );
00296   return cont.fetchItem( oid.itemId() );
00297 }
00298 
00299 ora::OId ora::Database::insertItem(const std::string& containerName,
00300                                    const Object& dataObject ){
00301   open( true );
00302   Container cont  = getContainerFromSession( containerName, dataObject.type(), *m_impl->m_session );
00303   int itemId = cont.insertItem( dataObject );
00304   return OId( cont.id(), itemId );
00305 }
00306 
00307 void ora::Database::updateItem(const OId& oid,
00308                                const Object& dataObject ){
00309   open();
00310   Container cont = containerHandle( oid.containerId() );
00311   cont.updateItem( oid.itemId(), dataObject );
00312 }
00313 
00314 void ora::Database::erase(const OId& oid){
00315   open();
00316   Container cont = containerHandle( oid.containerId() );
00317   cont.erase( oid.itemId() );
00318 }
00319 
00320 void ora::Database::flush(){
00321   open();
00322   const std::map<int,Handle<DatabaseContainer> >& containers = m_impl->m_session->containers();
00323   for( std::map<int,Handle<DatabaseContainer> >::const_iterator iCont = containers.begin();
00324        iCont != containers.end(); ++iCont ){
00325     iCont->second->flush();
00326   }
00327 }
00328 
00329 void ora::Database::setObjectName( const std::string& name, const OId& oid ){
00330   open( true );
00331   m_impl->m_session->setObjectName( name, oid.containerId(), oid.itemId() );
00332 }
00333 
00334 bool ora::Database::eraseObjectName( const std::string& name ){
00335   open();
00336   return m_impl->m_session->eraseObjectName( name );  
00337 }
00338 
00339 bool ora::Database::eraseAllNames(){
00340   open();
00341   return m_impl->m_session->eraseAllNames();
00342 }
00343 
00344 bool ora::Database::getItemId( const std::string& name, ora::OId& destination ){
00345   open();
00346   return m_impl->m_session->getItemId( name, destination );  
00347 }
00348 
00349 boost::shared_ptr<void> ora::Database::getTypedObjectByName( const std::string& name, const std::type_info& typeInfo ){
00350   open();
00351   Reflex::Type objType = ClassUtils::lookupDictionary( typeInfo );
00352   return m_impl->m_session->fetchTypedObjectByName( name, objType );
00353 }
00354 
00355 ora::Object ora::Database::fetchItemByName( const std::string& name ){
00356   open();
00357   return  m_impl->m_session->fetchObjectByName( name );
00358 }
00359 
00360 bool ora::Database::getNamesForObject( const ora::OId& oid, 
00361                                        std::vector<std::string>& destination ){
00362   checkTransaction();
00363   if( !m_impl->m_session->exists() ){
00364     throwException("Database does not exists in \""+m_impl->m_session->connectionString()+"\"","Database::getNamesForObject");
00365   }
00366   return m_impl->m_session->getNamesForObject( oid.containerId(), oid.itemId(), destination );
00367 }
00368 
00369 bool ora::Database::listObjectNames( std::vector<std::string>& destination ){
00370   checkTransaction();
00371   if( !m_impl->m_session->exists() ){
00372     throwException("Database does not exists in \""+m_impl->m_session->connectionString()+"\"","Database::listObjectNames");
00373   }
00374   return m_impl->m_session->listObjectNames( destination );
00375 }
00376 
00377 ora::DatabaseUtility ora::Database::utility(){
00378   checkTransaction();
00379   Handle<DatabaseUtilitySession> utilSession = m_impl->m_session->utility();
00380   return DatabaseUtility( utilSession );
00381 }
00382 
00383 ora::SharedSession& ora::Database::storageAccessSession(){
00384   return m_impl->m_session->storageAccessSession();
00385 }
00386