CMS 3D CMS Logo

/data/doxygen/doxygen-1.7.3/gen/CMSSW_4_2_8/src/CondCore/ORA/src/DatabaseUtilitySession.cc

Go to the documentation of this file.
00001 #include "CondCore/ORA/interface/Exception.h"
00002 #include "DatabaseUtilitySession.h"
00003 #include "DatabaseSession.h"
00004 #include "DatabaseContainer.h"
00005 #include "MappingRules.h"
00006 #include "MappingDatabase.h"
00007 #include "MappingToSchema.h"
00008 #include "IDatabaseSchema.h"
00009 #include "MappingTree.h"
00010 // externals
00011 #include "Reflex/Type.h"
00012 
00013 ora::DatabaseUtilitySession::DatabaseUtilitySession(  DatabaseSession& dbSession ):
00014   m_session( dbSession ){
00015 }
00016 
00017 ora::DatabaseUtilitySession::~DatabaseUtilitySession(){
00018 }
00019 
00020 std::set<std::string> ora::DatabaseUtilitySession::listMappingVersions( int containerId ){
00021   std::set<std::string> mappingList;
00022   m_session.mappingDatabase().getMappingVersionsForContainer( containerId, mappingList );
00023   return mappingList;
00024 }
00025 
00026 std::map<std::string,std::string> ora::DatabaseUtilitySession::listMappings( int containerId ){
00027   std::map<std::string,std::string> versionMap;
00028   m_session.mappingDatabase().getClassVersionListForContainer( containerId, versionMap );
00029   return versionMap;
00030 }
00031 
00032 bool ora::DatabaseUtilitySession::dumpMapping( const std::string& mappingVersion,
00033                                                std::ostream& outputStream ){
00034   MappingTree dest;
00035   if(m_session.mappingDatabase().getMappingByVersion( mappingVersion, dest )){
00036     dest.printXML( outputStream );
00037     return true;
00038   }
00039   return false;
00040 }
00041 
00042 ora::Handle<ora::DatabaseContainer> ora::DatabaseUtilitySession::importContainerSchema( const std::string& containerName,
00043                                                                                         DatabaseSession& sourceSession){
00044   if(!m_session.exists()){
00045     if( m_session.configuration().properties().getFlag( Configuration::automaticDatabaseCreation() )){
00046       m_session.create();
00047       m_session.open();
00048     } else {
00049       throwException( "ORA Database not found in \""+m_session.connectionString()+"\".",
00050                       "DatabaseUtilitySession::importContainerSchema");      
00051     }
00052   } else {
00053     m_session.open();
00054     if( existsContainer( containerName ) ){
00055       throwException( "A Container named \""+containerName+"\" already exists in the database.",
00056                       "DatabaseUtilitySession::importContainerSchema" );
00057     }
00058   }
00059   sourceSession.open();
00060   Handle<ora::DatabaseContainer> cont = sourceSession.containerHandle( containerName );
00061   // first create the container locally:
00062   Handle<ora::DatabaseContainer> newCont = m_session.addContainer( containerName, cont->className() );
00063   cont->className();
00064   MappingToSchema mapping2Schema( m_session.schema().storageSchema() );
00065   std::set<std::string> existingVersions = m_session.mappingDatabase().versions();
00066   std::set<std::string> baseVersions;
00067   // first create the cont base schema
00068   MappingTree baseMapping;
00069   if(!sourceSession.mappingDatabase().getBaseMappingForContainer( cont->className(), cont->id(), baseMapping )){
00070     throwException( "Base mapping for class \""+cont->className()+"\" has not been found in the database.",
00071                     "DatabaseUtilitySession::importContainerSchema");
00072   }
00073   std::set<std::string> classVersions;
00074   if(!sourceSession.mappingDatabase().getClassVersionListForMappingVersion( baseMapping.version(), classVersions )){
00075     throwException( "No class versions found for mapping \""+baseMapping.version()+"\".",
00076                     "DatabaseUtilitySession::importContainerSchema");
00077   }
00078   if( existingVersions.find( baseMapping.version() )!= existingVersions.end() ){
00079     throwException("Mapping version \""+baseMapping.version()+"\" for base mapping of class \""+cont->className()+"\" already exists in the database.","DatabaseUtilitySession::importContainerSchema");
00080   }
00081   if( !mapping2Schema.check( baseMapping ) ){
00082     throwException("Schema base for class \""+baseMapping.className()+"\" cannot be replicated, because some schema objects have been found with the same name.","DatabaseUtilitySession::importContainerSchema");    
00083   }
00084   baseVersions.insert( baseMapping.version() );
00085   existingVersions.insert( baseMapping.version() );
00086   m_session.mappingDatabase().storeMapping( baseMapping );
00087   bool first = true;
00088   for( std::set<std::string>::const_iterator iCv = classVersions.begin(); iCv != classVersions.end(); ++iCv ){
00089     m_session.mappingDatabase().insertClassVersion( cont->className(), *iCv , 0, newCont->id(), baseMapping.version(), first );
00090     first = false;
00091   }
00092   mapping2Schema.create( baseMapping );
00093   // second create the base dependencies if any
00094   std::set<std::string> dependentClasses;
00095   sourceSession.mappingDatabase().getDependentClassesForContainer( cont->id(), dependentClasses );
00096   for( std::set<std::string>::const_iterator iCl = dependentClasses.begin(); iCl != dependentClasses.end(); ++iCl ){
00097     MappingTree baseDepMapping;
00098     if(!sourceSession.mappingDatabase().getBaseMappingForContainer( *iCl, cont->id(), baseDepMapping )){
00099       throwException( "Base mapping for class \""+*iCl+"\" has not been found in the database.",
00100                     "DatabaseUtilitySession::importContainerSchema");      
00101     }
00102     std::set<std::string> depClassVersions;
00103     if(!sourceSession.mappingDatabase().getClassVersionListForMappingVersion( baseDepMapping.version(), depClassVersions )){
00104       throwException( "No class versions found for mapping \""+baseDepMapping.version()+"\".",
00105                       "DatabaseUtilitySession::importContainerSchema");
00106     }
00107     if( existingVersions.find( baseDepMapping.version() )!= existingVersions.end() ){
00108       throwException("Mapping version \""+baseDepMapping.version()+"\" for base mapping of class \""+*iCl+"\" already exists in the database.","DatabaseUtilitySession::importContainerSchema");
00109     }
00110     if( !mapping2Schema.check( baseDepMapping ) ){
00111       throwException("Schema base for class \""+baseDepMapping.className()+"\" cannot be replicated, because some schema objects have been found with the same name.","DatabaseUtilitySession::importContainerSchema");
00112     }
00113     baseVersions.insert( baseDepMapping.version() );
00114     existingVersions.insert( baseDepMapping.version() );
00115     m_session.mappingDatabase().storeMapping( baseDepMapping );
00116     first = true;
00117     for( std::set<std::string>::const_iterator iCv = depClassVersions.begin(); iCv != depClassVersions.end(); ++iCv ){
00118       m_session.mappingDatabase().insertClassVersion( *iCl, *iCv , 1, newCont->id(), baseDepMapping.version(), first );
00119       first = false;
00120     }
00121     mapping2Schema.create( baseDepMapping );
00122   }
00124   std::set<std::string> allVersions;
00125   if(!sourceSession.mappingDatabase().getMappingVersionsForContainer( cont->id(), allVersions )){
00126     std::stringstream mess;
00127     mess << "No mapping versions found for container id="<<cont->id();
00128     throwException( mess.str(), "DatabaseUtilitySession::importContainerSchema");
00129   }
00130   for( std::set<std::string>::const_iterator iVer = allVersions.begin(); iVer != allVersions.end(); ++iVer ){
00131     // skip the bases
00132     if( baseVersions.find( *iVer )== baseVersions.end() ){
00133       MappingTree evMapping;
00134       if(!sourceSession.mappingDatabase().getMappingByVersion( *iVer, evMapping) ){
00135         throwException("Mapping version \""+*iVer+"\" has not been found in the database.",
00136                        "DatabaseUtilitySession::importContainerSchema");
00137       }
00138       std::set<std::string> cvs;
00139       if(!sourceSession.mappingDatabase().getClassVersionListForMappingVersion( evMapping.version(), cvs )){
00140         throwException( "No class versions found for mapping \""+evMapping.version()+"\".",
00141                         "DatabaseUtilitySession::importContainerSchema");
00142       }
00143       if( existingVersions.find( *iVer )!= existingVersions.end() ){
00144         throwException("Mapping version \""+*iVer+"\" for mapping of class \""+evMapping.className()+"\" already exists in the database.","DatabaseUtilitySession::importContainerSchema");
00145       }
00146       if( !mapping2Schema.check( evMapping ) ){
00147         throwException("Evolved schema for class \""+evMapping.className()+"\" cannot be replicated, because some schema objects have been found with the same name.","DatabaseUtilitySession::importContainerSchema");
00148       }
00149       m_session.mappingDatabase().storeMapping( evMapping );
00150       existingVersions.insert( evMapping.version() );
00151       int depIndex = 0;
00152       std::string className = evMapping.className();
00153       if( evMapping.className() != baseMapping.className() ){
00154         // dependencies
00155         depIndex = 1;
00156       }
00157       for( std::set<std::string>::const_iterator iCv = cvs.begin(); iCv != cvs.end(); ++iCv ){
00158         m_session.mappingDatabase().insertClassVersion( evMapping.className(), *iCv , depIndex, newCont->id(), evMapping.version() );
00159       }
00160       // then evolve the schema
00161       mapping2Schema.alter( evMapping );
00162     }
00163   }
00164   return newCont;
00165 }
00166 
00167 void ora::DatabaseUtilitySession::importContainerSchema( const std::string& sourceConnectionString,
00168                                                          const std::string& containerName ){
00169   DatabaseSession sourceSession( m_session.connectionPool() );
00170   sourceSession.connect(sourceConnectionString, true );
00171   sourceSession.startTransaction( true );
00172   importContainerSchema(containerName, sourceSession );
00173   sourceSession.commitTransaction();
00174 }
00175 
00176 
00177 bool ora::DatabaseUtilitySession::existsContainer( const std::string& containerName ){
00178   bool found = false;
00179   for( std::map<int, Handle<DatabaseContainer> >::const_iterator iC = m_session.containers().begin();
00180        iC != m_session.containers().end(); ++iC ){
00181     if( iC->second->name() == containerName ) {
00182       found = true;
00183       break;
00184     }
00185   }
00186   return found;
00187 }
00188 
00189 void ora::DatabaseUtilitySession::importContainer( const std::string& sourceConnectionString,
00190                                                    const std::string& containerName ){
00191   DatabaseSession sourceSession( m_session.connectionPool() );
00192   sourceSession.connect(sourceConnectionString, true );
00193   sourceSession.startTransaction( true );
00194   Handle<ora::DatabaseContainer> newCont = importContainerSchema(containerName, sourceSession );
00195   Handle<ora::DatabaseContainer> cont = sourceSession.containerHandle( containerName );
00196   Handle<IteratorBuffer> iterator = cont->iteratorBuffer();
00197   std::vector<void*> objects;
00198   const Reflex::Type& contType = cont->type();
00199   while( iterator->next() ){
00200     void* data = iterator->getItem();
00201     objects.push_back( data );
00202     newCont->insertItem( data, contType );
00203   }
00204   newCont->flush();
00205   for( std::vector<void*>::const_iterator iO = objects.begin(); iO != objects.end(); iO++ ){
00206     contType.Destruct( *iO );
00207   }
00208   sourceSession.commitTransaction();
00209 }
00210 
00211 void ora::DatabaseUtilitySession::eraseMapping( const std::string& mappingVersion ){
00212   if( !m_session.exists() ){
00213     throwException( "ORA Database not found in \""+m_session.connectionString()+"\".",
00214                     "DatabaseUtilitySession::eraseMapping");      
00215 
00216   }
00217   m_session.mappingDatabase().removeMapping( mappingVersion );
00218 }
00219 
00220 ora::Handle<ora::DatabaseContainer> ora::DatabaseUtilitySession::containerHandle( const std::string& name ){
00221   if( !m_session.exists() ){
00222     throwException( "ORA Database not found in \""+m_session.connectionString()+"\".",
00223                     "DatabaseUtilitySession::containerHandle");      
00224 
00225   }
00226   m_session.open();
00227   return m_session.containerHandle( name );
00228 }
00229