CMS 3D CMS Logo

CMSSW_4_4_3_patch1/src/CondCore/ORA/src/MappingDatabase.cc

Go to the documentation of this file.
00001 #include "CondCore/ORA/interface/Exception.h"
00002 #include "MappingDatabase.h"
00003 #include "IDatabaseSchema.h"
00004 #include "MappingTree.h"
00005 #include "MappingRules.h"
00006 //
00007 #include <sstream>
00008 // externals
00009 #include "Reflex/Type.h"
00010 
00011 std::string
00012 ora::MappingDatabase::versionOfClass( const Reflex::Type& dictionary ){
00013   std::string className = dictionary.Name(Reflex::SCOPED);
00014   Reflex::PropertyList classProps = dictionary.Properties();
00015   std::string classVersion = MappingRules::defaultClassVersion(className);
00016   if(classProps.HasProperty(MappingRules::classVersionPropertyNameInDictionary())){
00017     classVersion = classProps.PropertyAsString(MappingRules::classVersionPropertyNameInDictionary());
00018   }
00019   return classVersion;
00020 }
00021 
00022 void ora::MappingDatabase::buildElement( MappingElement& parentElement,
00023                                          const std::string& scopeName,
00024                                          std::map<std::string, std::vector<MappingRawElement> >& innerElements ){
00025   std::map<std::string,std::vector<MappingRawElement> >::iterator iScope = innerElements.find(scopeName);
00026   if(iScope != innerElements.end()){
00027     for( std::vector<MappingRawElement>::const_iterator iM = iScope->second.begin();
00028          iM != iScope->second.end(); ++iM ){
00029       MappingElement& element = parentElement.appendSubElement( iM->elementType,
00030                                                                 iM->variableName,
00031                                                                 iM->variableType,
00032                                                                 iM->tableName );
00033       element.setColumnNames(iM->columns);
00034       std::string nextScope(scopeName);
00035       nextScope.append("::").append(iM->variableName);
00036       buildElement( element, nextScope, innerElements );
00037     }
00038   }
00039   innerElements.erase(scopeName);
00040 }
00041 
00042 void ora::MappingDatabase::unfoldElement( const MappingElement& element, MappingRawData& destination ){
00043   int newElemId = m_mappingSequence.getNextId();
00044   MappingRawElement&  elem = destination.addElement( newElemId );
00045   elem.elementType = MappingElement::elementTypeAsString( element.elementType() );
00046   elem.scopeName = element.scopeName();
00047   if(elem.scopeName.empty()) elem.scopeName = MappingRawElement::emptyScope();
00048   elem.variableName = element.variableName();
00049   elem.variableType = element.variableType();
00050   elem.tableName = element.tableName();
00051   elem.columns = element.columnNames();
00052   for ( MappingElement::const_iterator iSubEl = element.begin();
00053         iSubEl != element.end(); ++iSubEl) {
00054     unfoldElement( iSubEl->second, destination );
00055   }
00056 }
00057 
00058 ora::MappingDatabase::MappingDatabase( ora::IDatabaseSchema& schema ):
00059   m_schema( schema ),
00060   m_mappingSequence( MappingRules::sequenceNameForMapping(), schema ),
00061   m_versions(),
00062   m_isLoaded( false ){
00063 }
00064 
00065 
00066 ora::MappingDatabase::~MappingDatabase(){
00067 }
00068 
00069 void ora::MappingDatabase::setUp(){
00070   m_mappingSequence.create();
00071 }
00072 
00073 std::string
00074 ora::MappingDatabase::newMappingVersionForContainer( const std::string& containerName ){
00075   if(!m_isLoaded){
00076     m_schema.mappingSchema().getVersionList( m_versions );
00077     m_isLoaded = true;
00078   }
00079   
00080   std::string newMappingVersion = "";
00081   for ( int iteration = 0;; ++iteration ) {
00082     newMappingVersion = MappingRules::newMappingVersionForContainer( containerName, iteration );
00083     bool found = false;
00084     for ( std::set<std::string>::reverse_iterator iVersion = m_versions.rbegin();
00085           iVersion != m_versions.rend(); ++iVersion ) {
00086       if ( *iVersion == newMappingVersion ) {
00087         found = true;
00088         break;
00089       }
00090     }
00091     if ( ! found ){
00092       m_versions.insert( newMappingVersion );
00093       break;
00094     }
00095     
00096   }
00097   return newMappingVersion;
00098 }
00099 
00100 std::string
00101 ora::MappingDatabase::newMappingVersionForDependentClass( const std::string& containerName, const std::string& className ){
00102   if(!m_isLoaded){
00103     m_schema.mappingSchema().getVersionList( m_versions );
00104     m_isLoaded = true;
00105   }
00106   
00107   std::string newMappingVersion = "";
00108   for ( int iteration = 0;; ++iteration ) {
00109     newMappingVersion = MappingRules::newMappingVersionForDependentClass( containerName, className, iteration );
00110     bool found = false;
00111     for ( std::set<std::string>::reverse_iterator iVersion = m_versions.rbegin();
00112           iVersion != m_versions.rend(); ++iVersion ) {
00113       if ( *iVersion == newMappingVersion ) {
00114         found = true;
00115         break;
00116       }
00117     }
00118     if ( ! found ){
00119       m_versions.insert( newMappingVersion );
00120       break;
00121     }
00122     
00123   }
00124   return newMappingVersion;
00125 }
00126 
00127 bool ora::MappingDatabase::getMappingByVersion( const std::string& version, MappingTree& destination  ){
00128   bool ret = false;
00129   MappingRawData mapData;
00130   if(m_schema.mappingSchema().getMapping( version, mapData )){
00131     ret = true;
00132     MappingRawElement topLevelElement;
00133     bool topLevelFound = false;
00134     bool dependency = false;
00135     std::map<std::string, std::vector<MappingRawElement> > innerElements;
00136     for( std::map< int, MappingRawElement>::iterator iElem = mapData.elements.begin();
00137          iElem != mapData.elements.end(); iElem++ ){
00138       // first loading the top level elements
00139       if( iElem->second.scopeName == MappingRawElement::emptyScope() ){
00140         if( iElem->second.elementType == MappingElement::classMappingElementType() ||
00141             iElem->second.elementType == MappingElement::dependencyMappingElementType() ){
00142           if( topLevelFound ){
00143             throwException("Mapping inconsistent.More then one top level element found.",
00144                            "MappingDatabase::getMappingByVersion");
00145           }
00146           topLevelElement = iElem->second;
00147           if( topLevelElement.elementType == MappingElement::dependencyMappingElementType() ) dependency = true;
00148           topLevelFound = true;
00149         } 
00150       } else {
00151         std::map<std::string, std::vector<MappingRawElement> >::iterator iN = innerElements.find( iElem->second.scopeName );
00152         if(iN==innerElements.end()){
00153           innerElements.insert( std::make_pair( iElem->second.scopeName, std::vector<MappingRawElement>(1,iElem->second) ) );
00154         } else {
00155           iN->second.push_back( iElem->second );
00156         }
00157       }
00158     }
00159     if( !topLevelFound ){
00160       throwException( "Could not find top element for mapping version \""+version+"\".",
00161                       "MappingDatabase::getMappingByVersion" );
00162     }
00163     MappingElement& topElement = destination.setTopElement( topLevelElement.variableName,
00164                                                             topLevelElement.tableName,
00165                                                             dependency );
00166     topElement.setColumnNames( topLevelElement.columns);
00167     buildElement( topElement, topLevelElement.variableName, innerElements  );
00168     destination.setVersion( version );
00169   }
00170   return ret;
00171 }
00172 
00173 void ora::MappingDatabase::removeMapping( const std::string& version ){
00174   m_schema.mappingSchema().removeMapping( version );
00175 }
00176 
00177 bool
00178 ora::MappingDatabase::getMappingForContainer( const Reflex::Type& containerClass,
00179                                               int containerId,
00180                                               MappingTree& destination ){
00181 
00182   bool ret = false;
00183   // The class parameters
00184   std::string className = containerClass.Name(Reflex::SCOPED);
00185   std::string classVersion = versionOfClass( containerClass );
00186   std::string classId = MappingRules::classId( className, classVersion );
00187 
00188   std::string version("");
00189   bool found = m_schema.mappingSchema().selectMappingVersion( classId, containerId, version );
00190 
00191   if( found ){
00192     ret = getMappingByVersion( version, destination );
00193     if( !ret ){
00194       throwException("Mapping version \""+version+"\" not found.",
00195                      "MappingDatabase::getMappingForContainer");
00196     }
00197     if( destination.className() != className ){
00198       throwException("Mapping inconsistency detected for version=\""+version+"\"",
00199                      "MappingDatabase::getMappingForContainer");
00200     }
00201   }
00202   return ret;
00203 }
00204 
00205 bool ora::MappingDatabase::getBaseMappingForContainer( const std::string& className,
00206                                                        int containerId,
00207                                                        MappingTree& destination  ){
00208   bool ret = false;
00209   std::string classId = MappingRules::baseIdForClass( className );
00210   std::string mappingVersion("");
00211   bool found = m_schema.mappingSchema().selectMappingVersion( classId, containerId, mappingVersion );
00212 
00213   if( found ){
00214     ret = getMappingByVersion( mappingVersion, destination );
00215     if( !ret ){
00216       throwException("Mapping version \""+mappingVersion+"\" not found.",
00217                      "MappingDatabase::getBaseMappingForContainer");
00218     }
00219     if( destination.className() != className ){
00220       throwException("Mapping inconsistency detected for version=\""+mappingVersion+"\"",
00221                      "MappingDatabase::getBaseMappingForContainer");
00222     }
00223   }
00224   return ret;
00225 }
00226 
00227 bool ora::MappingDatabase::getDependentMappingsForContainer( int containerId,
00228                                                              std::vector<MappingElement>& destination  ){
00229   bool ret = false;
00230   std::set<std::string> versions;
00231   if( m_schema.mappingSchema().getMappingVersionListForContainer( containerId, versions, true ) ){
00232     ret = true;
00233     for( std::set<std::string>::iterator iM = versions.begin();
00234          iM != versions.end(); ++iM ){
00235       MappingTree mapping;
00236       if( ! getMappingByVersion( *iM, mapping )){
00237         throwException("Mapping version \""+*iM+"\" not found.",
00238                        "MappingDatabase::getDependentMappingsForContainer");
00239         
00240       }
00241       destination.push_back( mapping.topElement() );
00242     }
00243   }
00244   return ret;
00245 }
00246 
00247 bool ora::MappingDatabase::getClassVersionListForMappingVersion( const std::string& mappingVersion,
00248                                                                  std::set<std::string>& destination ){
00249   return m_schema.mappingSchema().getClassVersionListForMappingVersion( mappingVersion, destination );
00250 }
00251 
00252 void ora::MappingDatabase::insertClassVersion( const std::string& className,
00253                                                const std::string& classVersion,
00254                                                int dependencyIndex,
00255                                                int containerId,
00256                                                const std::string& mappingVersion,
00257                                                bool asBase ){
00258   std::string classId = MappingRules::classId( className, classVersion );
00259   m_schema.mappingSchema().insertClassVersion( className, classVersion, classId, dependencyIndex, containerId, mappingVersion );  
00260   if( asBase ){
00261     m_schema.mappingSchema().insertClassVersion( className, MappingRules::baseClassVersion(), MappingRules::baseIdForClass( className ), dependencyIndex, containerId, mappingVersion );
00262   }
00263 }
00264 
00265 bool ora::MappingDatabase::getClassVersionListForContainer( int containerId,
00266                                                             std::map<std::string,std::string>& versionMap ){
00267   
00268   return m_schema.mappingSchema().getClassVersionListForContainer( containerId, versionMap );
00269 }
00270 
00271 void ora::MappingDatabase::insertClassVersion( const Reflex::Type& dictionaryEntry,
00272                                                int depIndex,
00273                                                int containerId,
00274                                                const std::string& mappingVersion,
00275                                                bool asBase  ){
00276   std::string className = dictionaryEntry.Name( Reflex::SCOPED );
00277   std::string classVersion = versionOfClass( dictionaryEntry );
00278   insertClassVersion( className, classVersion, depIndex, containerId, mappingVersion, asBase );
00279 }
00280 
00281 void ora::MappingDatabase::setMappingVersionForClass( const Reflex::Type& dictionaryEntry,
00282                                                       int containerId,
00283                                                       const std::string& mappingVersion,
00284                                                       bool dependency ){
00285   std::string className = dictionaryEntry.Name( Reflex::SCOPED );
00286   std::string classVersion = versionOfClass( dictionaryEntry );
00287   std::string classId = MappingRules::classId( className, classVersion );
00288   std::string mv("");
00289   bool found = m_schema.mappingSchema().selectMappingVersion( classId, containerId, mv );
00290   if( !found ){
00291     int depIndex = 0;
00292     if( dependency ) depIndex = 1;
00293     m_schema.mappingSchema().insertClassVersion( className, classVersion, classId, depIndex, containerId, mappingVersion );
00294   } else {
00295     m_schema.mappingSchema().setMappingVersion( classId, containerId, mappingVersion );
00296   }
00297 }
00298 
00299 void ora::MappingDatabase::storeMapping( const MappingTree& mapping ){
00300   MappingRawData rowMapping( mapping.version() );
00301   unfoldElement( mapping.topElement(), rowMapping );
00302   m_mappingSequence.sinchronize();
00303   m_schema.mappingSchema().storeMapping( rowMapping );  
00304 }
00305 
00306 bool ora::MappingDatabase::getMappingVersionsForContainer( int containerId, std::set<std::string>& versionList ){
00307   return m_schema.mappingSchema().getMappingVersionListForContainer( containerId, versionList );
00308 }
00309 
00310 const std::set<std::string>& ora::MappingDatabase::versions(){
00311   if(!m_isLoaded){
00312     m_schema.mappingSchema().getVersionList( m_versions );
00313     m_isLoaded = true;
00314   }
00315   return m_versions;
00316 }
00317 
00318 bool ora::MappingDatabase::getDependentClassesForContainer( int containerId,
00319                                                             std::set<std::string>& list ){
00320   return m_schema.mappingSchema().getDependentClassesInContainerMapping( containerId, list );
00321 }
00322 
00323 void ora::MappingDatabase::clear(){
00324   m_versions.clear();
00325   m_isLoaded = false;
00326 }
00327