CMS 3D CMS Logo

/data/refman/pasoursint/CMSSW_4_1_8_patch9/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(){
00130   bool created = false;
00131   if( !exists()){
00132     m_impl->m_session->create();
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::open( bool writingAccess /*=false*/){
00154   checkTransaction();
00155   if( !m_impl->m_session->exists() ){
00156     if( writingAccess && m_impl->m_session->configuration().properties().getFlag( Configuration::automaticDatabaseCreation() ) ){
00157       m_impl->m_session->create();
00158     } else {
00159       throwException("Database does not exists in \""+m_impl->m_session->connectionString()+"\"","Database::open");
00160     }
00161   }
00162   m_impl->m_session->open();
00163 }
00164 
00165 std::set< std::string > ora::Database::containers() {
00166   open();
00167   std::set< std::string > contList;
00168   const std::map<int, Handle<DatabaseContainer> >& conts = m_impl->m_session->containers();
00169   for(std::map<int, Handle<DatabaseContainer> >::const_iterator iC = conts.begin();
00170       iC != conts.end(); iC++ ){
00171     contList.insert( iC->second->name() );
00172   }
00173   return contList;
00174 }
00175 
00176 ora::Container ora::Database::createContainer( const std::string& name,
00177                                                const std::type_info& typeInfo ){
00178   open( true );
00179   if( m_impl->m_session->containerHandle( name ) ){
00180     throwException("Container with name \""+name+"\" already exists in the database.",
00181                    "Database::createContainer");
00182   }
00183   Reflex::Type contType = ClassUtils::lookupDictionary( typeInfo );
00184   Handle<DatabaseContainer> cont = m_impl->m_session->createContainer( name, contType );
00185   return Container( cont );
00186 }
00187 
00188 ora::Container ora::Database::createContainer( const std::type_info& typeInfo ){
00189   open( true );
00190   Reflex::Type contType = ClassUtils::lookupDictionary( typeInfo );
00191   std::string name = nameFromClass( contType );
00192   if( m_impl->m_session->containerHandle( name ) ){
00193     throwException("Container with name \""+name+"\" already exists in the database.",
00194                    "Database::createContainer");
00195   }  
00196   Handle<DatabaseContainer> cont = m_impl->m_session->createContainer( name, contType );
00197   return Container( cont );
00198 }
00199 
00200 ora::Container ora::Database::createContainer( const std::string& className,
00201                                                std::string name ){
00202   open( true );
00203   Reflex::Type contType =  ClassUtils::lookupDictionary( className );
00204   if( name.empty() ) name = nameForContainer( className );
00205   if( m_impl->m_session->containerHandle( name ) ){
00206     throwException("Container with name \""+name+"\" already exists in the database.",
00207                    "Database::createContainer");
00208   }  
00209   Handle<DatabaseContainer> cont = m_impl->m_session->createContainer( name, contType );
00210   return Container( cont );
00211 }
00212 
00213 ora::Container ora::Database::getContainer( const std::string& containerName,
00214                                             const std::type_info&  typeInfo){
00215   open( true );
00216   Reflex::Type objType = ClassUtils::lookupDictionary( typeInfo );
00217   return getContainerFromSession( containerName, objType, *m_impl->m_session );
00218 }
00219 
00220 ora::Container ora::Database::getContainer( const std::type_info& typeInfo ){
00221   open( true );
00222   Reflex::Type objType = ClassUtils::lookupDictionary( typeInfo );
00223   std::string contName = nameFromClass( objType );
00224   return getContainerFromSession( contName, objType, *m_impl->m_session);
00225 }
00226 
00227 bool ora::Database::dropContainer( const std::string& name ){
00228   open();
00229   if( !m_impl->m_session->containerHandle( name ) ){
00230     return false;
00231   }  
00232   m_impl->m_session->dropContainer( name );
00233   return true;
00234 }
00235 
00236 ora::Container ora::Database::containerHandle( const std::string& name ){
00237   open();
00238   Handle<DatabaseContainer> cont = m_impl->m_session->containerHandle( name );
00239   if( !cont ){
00240     throwException("Container \""+name+"\" does not exist in the database.",
00241                    "Database::containerHandle");
00242   }
00243   return Container( cont );
00244 }
00245 
00246 ora::Container ora::Database::containerHandle( int contId ){
00247   open();
00248   Handle<DatabaseContainer> cont = m_impl->m_session->containerHandle( contId );
00249   if( !cont ){
00250     std::stringstream messg;
00251     messg << "Container with id=" << contId << " not found in the database.";
00252     throwException(messg.str(),
00253                    "Database::containerHandle");
00254   }
00255   return Container( cont );
00256 }
00257 
00258 ora::Object ora::Database::fetchItem(const OId& oid){
00259   Container cont = containerHandle( oid.containerId() );
00260   return cont.fetchItem( oid.itemId() );
00261 }
00262 
00263 ora::OId ora::Database::insertItem(const std::string& containerName,
00264                                    const Object& dataObject ){
00265   open( true );
00266   Container cont  = getContainerFromSession( containerName, dataObject.type(), *m_impl->m_session );
00267   int itemId = cont.insertItem( dataObject );
00268   return OId( cont.id(), itemId );
00269 }
00270 
00271 void ora::Database::updateItem(const OId& oid,
00272                                const Object& dataObject ){
00273   open();
00274   Container cont = containerHandle( oid.containerId() );
00275   cont.updateItem( oid.itemId(), dataObject );
00276 }
00277 
00278 void ora::Database::erase(const OId& oid){
00279   open();
00280   Container cont = containerHandle( oid.containerId() );
00281   cont.erase( oid.itemId() );
00282 }
00283 
00284 void ora::Database::flush(){
00285   open();
00286   const std::map<int,Handle<DatabaseContainer> >& containers = m_impl->m_session->containers();
00287   for( std::map<int,Handle<DatabaseContainer> >::const_iterator iCont = containers.begin();
00288        iCont != containers.end(); ++iCont ){
00289     iCont->second->flush();
00290   }
00291 }
00292 
00293 void ora::Database::setObjectName( const std::string& name, const OId& oid ){
00294   open( true );
00295   m_impl->m_session->setObjectName( name, oid.containerId(), oid.itemId() );
00296 }
00297 
00298 bool ora::Database::eraseObjectName( const std::string& name ){
00299   open();
00300   return m_impl->m_session->eraseObjectName( name );  
00301 }
00302 
00303 bool ora::Database::eraseAllNames(){
00304   open();
00305   return m_impl->m_session->eraseAllNames();
00306 }
00307 
00308 bool ora::Database::getItemId( const std::string& name, ora::OId& destination ){
00309   open();
00310   return m_impl->m_session->getItemId( name, destination );  
00311 }
00312 
00313 boost::shared_ptr<void> ora::Database::getTypedObjectByName( const std::string& name, const std::type_info& typeInfo ){
00314   open();
00315   Reflex::Type objType = ClassUtils::lookupDictionary( typeInfo );
00316   return m_impl->m_session->fetchTypedObjectByName( name, objType );
00317 }
00318 
00319 ora::Object ora::Database::fetchItemByName( const std::string& name ){
00320   open();
00321   return  m_impl->m_session->fetchObjectByName( name );
00322 }
00323 
00324 bool ora::Database::getNamesForObject( const ora::OId& oid, 
00325                                        std::vector<std::string>& destination ){
00326   open();
00327   return m_impl->m_session->getNamesForObject( oid.containerId(), oid.itemId(), destination );
00328 }
00329 
00330 bool ora::Database::listObjectNames( std::vector<std::string>& destination ){
00331   open();
00332   return m_impl->m_session->listObjectNames( destination );
00333 }
00334 
00335 ora::DatabaseUtility ora::Database::utility(){
00336   checkTransaction();
00337   Handle<DatabaseUtilitySession> utilSession = m_impl->m_session->utility();
00338   return DatabaseUtility( utilSession );
00339 }
00340 
00341 ora::SharedSession& ora::Database::storageAccessSession(){
00342   return m_impl->m_session->storageAccessSession();
00343 }
00344