CMS 3D CMS Logo

CMSSW_4_4_3_patch1/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 void ora::Database::disconnect(){
00097   m_impl->m_session->disconnect();
00098 }
00099 
00100 bool ora::Database::isConnected() {
00101   return m_impl->m_session->isConnected();
00102 }
00103 
00104 const std::string& ora::Database::connectionString() {
00105   return m_impl->m_session->connectionString();
00106 }
00107 
00108 ora::Transaction& ora::Database::transaction(){
00109   if(!m_impl->m_session->isConnected()) {
00110     throwException("No database storage connected.","Database::transaction");
00111   }
00112   return *m_impl->m_transaction;
00113 }
00114 
00115 void ora::Database::checkTransaction(){
00116   if(!m_impl->m_session->isConnected()) {
00117     throwException("No database storage connected.","Database::checkTransaction");
00118   }
00119   if(!m_impl->m_transaction->isActive()) {
00120     throwException("Transaction is not active.","Database::checkTransaction");
00121   }  
00122 }
00123 
00124 bool ora::Database::exists(){
00125   checkTransaction();
00126   return m_impl->m_session->exists();
00127 }
00128 
00129 bool ora::Database::create( std::string userSchemaVersion ){
00130   bool created = false;
00131   if( !exists()){
00132     m_impl->m_session->create( userSchemaVersion );
00133     created = true;
00134   }
00135   return created;
00136 }
00137 
00138 bool ora::Database::drop(){
00139   bool dropped = false;
00140   if( exists()){
00141     open();
00142     const std::map<int, Handle<DatabaseContainer> >& conts = m_impl->m_session->containers();
00143     for(std::map<int, Handle<DatabaseContainer> >::const_iterator iC = conts.begin();
00144         iC != conts.end(); iC++ ){
00145       iC->second->drop();
00146     }
00147     m_impl->m_session->drop();
00148     dropped = true;
00149   }
00150   return dropped;
00151 }
00152 
00153 void ora::Database::setAccessPermission( const std::string& principal, bool forWrite ){
00154   if( exists()){
00155     open();
00156     m_impl->m_session->setAccessPermission( principal, forWrite );
00157     const std::map<int, Handle<DatabaseContainer> >& conts = m_impl->m_session->containers();
00158     for(std::map<int, Handle<DatabaseContainer> >::const_iterator iC = conts.begin();
00159         iC != conts.end(); iC++ ){
00160       iC->second->setAccessPermission( principal, forWrite );
00161     }
00162   }
00163 }
00164 
00165 void ora::Database::open( bool writingAccess /*=false*/){
00166   checkTransaction();
00167   if( !m_impl->m_session->exists() ){
00168     if( writingAccess && m_impl->m_session->configuration().properties().getFlag( Configuration::automaticDatabaseCreation() ) ){
00169       m_impl->m_session->create();
00170     } else {
00171       throwException("Database does not exists in \""+m_impl->m_session->connectionString()+"\"","Database::open");
00172     }
00173   }
00174   m_impl->m_session->open();
00175 }
00176 
00177 ora::Version ora::Database::schemaVersion( bool userSchema ){
00178   checkTransaction();
00179   if( !m_impl->m_session->exists() ){
00180     throwException("Database does not exists in \""+m_impl->m_session->connectionString()+"\"","Database::schemaVersion");
00181   }
00182   return Version::fromString( m_impl->m_session->schemaVersion( userSchema ) );
00183 }
00184 
00185 std::set< std::string > ora::Database::containers() {
00186   open();
00187   std::set< std::string > contList;
00188   const std::map<int, Handle<DatabaseContainer> >& conts = m_impl->m_session->containers();
00189   for(std::map<int, Handle<DatabaseContainer> >::const_iterator iC = conts.begin();
00190       iC != conts.end(); iC++ ){
00191     contList.insert( iC->second->name() );
00192   }
00193   return contList;
00194 }
00195 
00196 ora::Container ora::Database::createContainer( const std::string& name,
00197                                                const std::type_info& typeInfo ){
00198   open( true );
00199   if( m_impl->m_session->containerHandle( name ) ){
00200     throwException("Container with name \""+name+"\" already exists in the database.",
00201                    "Database::createContainer");
00202   }
00203   Reflex::Type contType = ClassUtils::lookupDictionary( typeInfo );
00204   Handle<DatabaseContainer> cont = m_impl->m_session->createContainer( name, contType );
00205   return Container( cont );
00206 }
00207 
00208 ora::Container ora::Database::createContainer( const std::type_info& typeInfo ){
00209   open( true );
00210   Reflex::Type contType = ClassUtils::lookupDictionary( typeInfo );
00211   std::string name = nameFromClass( contType );
00212   if( m_impl->m_session->containerHandle( name ) ){
00213     throwException("Container with name \""+name+"\" already exists in the database.",
00214                    "Database::createContainer");
00215   }  
00216   Handle<DatabaseContainer> cont = m_impl->m_session->createContainer( name, contType );
00217   return Container( cont );
00218 }
00219 
00220 ora::Container ora::Database::createContainer( const std::string& className,
00221                                                std::string name ){
00222   open( true );
00223   Reflex::Type contType =  ClassUtils::lookupDictionary( className );
00224   if( name.empty() ) name = nameForContainer( className );
00225   if( m_impl->m_session->containerHandle( name ) ){
00226     throwException("Container with name \""+name+"\" already exists in the database.",
00227                    "Database::createContainer");
00228   }  
00229   Handle<DatabaseContainer> cont = m_impl->m_session->createContainer( name, contType );
00230   return Container( cont );
00231 }
00232 
00233 ora::Container ora::Database::getContainer( const std::string& containerName,
00234                                             const std::type_info&  typeInfo){
00235   open( true );
00236   Reflex::Type objType = ClassUtils::lookupDictionary( typeInfo );
00237   return getContainerFromSession( containerName, objType, *m_impl->m_session );
00238 }
00239 
00240 ora::Container ora::Database::getContainer( const std::type_info& typeInfo ){
00241   open( true );
00242   Reflex::Type objType = ClassUtils::lookupDictionary( typeInfo );
00243   std::string contName = nameFromClass( objType );
00244   return getContainerFromSession( contName, objType, *m_impl->m_session);
00245 }
00246 
00247 bool ora::Database::dropContainer( const std::string& name ){
00248   open();
00249   if( !m_impl->m_session->containerHandle( name ) ){
00250     return false;
00251   }  
00252   m_impl->m_session->dropContainer( name );
00253   return true;
00254 }
00255 
00256 bool ora::Database::lockContainer( const std::string& name ){
00257   open();
00258   Handle<DatabaseContainer> cont = m_impl->m_session->containerHandle( name );
00259   if( !cont ){
00260     throwException("Container \""+name+"\" does not exist in the database.",
00261                    "Database::lockContainer");
00262   }
00263   return cont->lock();
00264 }
00265 
00266 ora::Container ora::Database::containerHandle( const std::string& name ){
00267   open();
00268   Handle<DatabaseContainer> cont = m_impl->m_session->containerHandle( name );
00269   if( !cont ){
00270     throwException("Container \""+name+"\" does not exist in the database.",
00271                    "Database::containerHandle");
00272   }
00273   return Container( cont );
00274 }
00275 
00276 ora::Container ora::Database::containerHandle( int contId ){
00277   open();
00278   Handle<DatabaseContainer> cont = m_impl->m_session->containerHandle( contId );
00279   if( !cont ){
00280     std::stringstream messg;
00281     messg << "Container with id=" << contId << " not found in the database.";
00282     throwException(messg.str(),
00283                    "Database::containerHandle");
00284   }
00285   return Container( cont );
00286 }
00287 
00288 ora::Object ora::Database::fetchItem(const OId& oid){
00289   Container cont = containerHandle( oid.containerId() );
00290   return cont.fetchItem( oid.itemId() );
00291 }
00292 
00293 ora::OId ora::Database::insertItem(const std::string& containerName,
00294                                    const Object& dataObject ){
00295   open( true );
00296   Container cont  = getContainerFromSession( containerName, dataObject.type(), *m_impl->m_session );
00297   int itemId = cont.insertItem( dataObject );
00298   return OId( cont.id(), itemId );
00299 }
00300 
00301 void ora::Database::updateItem(const OId& oid,
00302                                const Object& dataObject ){
00303   open();
00304   Container cont = containerHandle( oid.containerId() );
00305   cont.updateItem( oid.itemId(), dataObject );
00306 }
00307 
00308 void ora::Database::erase(const OId& oid){
00309   open();
00310   Container cont = containerHandle( oid.containerId() );
00311   cont.erase( oid.itemId() );
00312 }
00313 
00314 void ora::Database::flush(){
00315   open();
00316   const std::map<int,Handle<DatabaseContainer> >& containers = m_impl->m_session->containers();
00317   for( std::map<int,Handle<DatabaseContainer> >::const_iterator iCont = containers.begin();
00318        iCont != containers.end(); ++iCont ){
00319     iCont->second->flush();
00320   }
00321 }
00322 
00323 void ora::Database::setObjectName( const std::string& name, const OId& oid ){
00324   open( true );
00325   m_impl->m_session->setObjectName( name, oid.containerId(), oid.itemId() );
00326 }
00327 
00328 bool ora::Database::eraseObjectName( const std::string& name ){
00329   open();
00330   return m_impl->m_session->eraseObjectName( name );  
00331 }
00332 
00333 bool ora::Database::eraseAllNames(){
00334   open();
00335   return m_impl->m_session->eraseAllNames();
00336 }
00337 
00338 bool ora::Database::getItemId( const std::string& name, ora::OId& destination ){
00339   open();
00340   return m_impl->m_session->getItemId( name, destination );  
00341 }
00342 
00343 boost::shared_ptr<void> ora::Database::getTypedObjectByName( const std::string& name, const std::type_info& typeInfo ){
00344   open();
00345   Reflex::Type objType = ClassUtils::lookupDictionary( typeInfo );
00346   return m_impl->m_session->fetchTypedObjectByName( name, objType );
00347 }
00348 
00349 ora::Object ora::Database::fetchItemByName( const std::string& name ){
00350   open();
00351   return  m_impl->m_session->fetchObjectByName( name );
00352 }
00353 
00354 bool ora::Database::getNamesForObject( const ora::OId& oid, 
00355                                        std::vector<std::string>& destination ){
00356   open();
00357   return m_impl->m_session->getNamesForObject( oid.containerId(), oid.itemId(), destination );
00358 }
00359 
00360 bool ora::Database::listObjectNames( std::vector<std::string>& destination ){
00361   open();
00362   return m_impl->m_session->listObjectNames( destination );
00363 }
00364 
00365 ora::DatabaseUtility ora::Database::utility(){
00366   checkTransaction();
00367   Handle<DatabaseUtilitySession> utilSession = m_impl->m_session->utility();
00368   return DatabaseUtility( utilSession );
00369 }
00370 
00371 ora::SharedSession& ora::Database::storageAccessSession(){
00372   return m_impl->m_session->storageAccessSession();
00373 }
00374