CMS 3D CMS Logo

/afs/cern.ch/work/a/aaltunda/public/www/CMSSW_5_3_13_patch3/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 std::string& className, 
00179                                               const std::string& classVersion, 
00180                                               int containerId, 
00181                                               MappingTree& destination  ){
00182   bool ret = false;
00183   // The classId parameter
00184   std::string classId = MappingRules::classId( className, classVersion );
00185 
00186   std::string version("");
00187   bool found = m_schema.mappingSchema().selectMappingVersion( classId, containerId, version );
00188 
00189   if( found ){
00190     ret = getMappingByVersion( version, destination );
00191     if( !ret ){
00192       throwException("Mapping version \""+version+"\" not found.",
00193                      "MappingDatabase::getMappingForContainer");
00194     }
00195     if( destination.className() != className ){
00196       throwException("Mapping inconsistency detected for version=\""+version+"\"",
00197                      "MappingDatabase::getMappingForContainer");
00198     }
00199   }
00200   return ret;
00201 }
00202 
00203 bool ora::MappingDatabase::getBaseMappingForContainer( const std::string& className,
00204                                                        int containerId,
00205                                                        MappingTree& destination  ){
00206   bool ret = false;
00207   std::string classId = MappingRules::baseIdForClass( className );
00208   std::string mappingVersion("");
00209   bool found = m_schema.mappingSchema().selectMappingVersion( classId, containerId, mappingVersion );
00210 
00211   if( found ){
00212     ret = getMappingByVersion( mappingVersion, destination );
00213     if( !ret ){
00214       throwException("Mapping version \""+mappingVersion+"\" not found.",
00215                      "MappingDatabase::getBaseMappingForContainer");
00216     }
00217     if( destination.className() != className ){
00218       throwException("Mapping inconsistency detected for version=\""+mappingVersion+"\"",
00219                      "MappingDatabase::getBaseMappingForContainer");
00220     }
00221   }
00222   return ret;
00223 }
00224 
00225 bool ora::MappingDatabase::getDependentMappingsForContainer( int containerId,
00226                                                              std::vector<MappingElement>& destination  ){
00227   bool ret = false;
00228   std::set<std::string> versions;
00229   if( m_schema.mappingSchema().getMappingVersionListForContainer( containerId, versions, true ) ){
00230     ret = true;
00231     for( std::set<std::string>::iterator iM = versions.begin();
00232          iM != versions.end(); ++iM ){
00233       MappingTree mapping;
00234       if( ! getMappingByVersion( *iM, mapping )){
00235         throwException("Mapping version \""+*iM+"\" not found.",
00236                        "MappingDatabase::getDependentMappingsForContainer");
00237         
00238       }
00239       destination.push_back( mapping.topElement() );
00240     }
00241   }
00242   return ret;
00243 }
00244 
00245 bool ora::MappingDatabase::getClassVersionListForMappingVersion( const std::string& mappingVersion,
00246                                                                  std::set<std::string>& destination ){
00247   return m_schema.mappingSchema().getClassVersionListForMappingVersion( mappingVersion, destination );
00248 }
00249 
00250 void ora::MappingDatabase::insertClassVersion( const std::string& className,
00251                                                const std::string& classVersion,
00252                                                int dependencyIndex,
00253                                                int containerId,
00254                                                const std::string& mappingVersion,
00255                                                bool asBase ){
00256   std::string classId = MappingRules::classId( className, classVersion );
00257   m_schema.mappingSchema().insertClassVersion( className, classVersion, classId, dependencyIndex, containerId, mappingVersion );  
00258   if( asBase ){
00259     m_schema.mappingSchema().insertClassVersion( className, MappingRules::baseClassVersion(), MappingRules::baseIdForClass( className ), dependencyIndex, containerId, mappingVersion );
00260   }
00261 }
00262 
00263 bool ora::MappingDatabase::getClassVersionListForContainer( int containerId,
00264                                                             std::map<std::string,std::string>& versionMap ){
00265   
00266   return m_schema.mappingSchema().getClassVersionListForContainer( containerId, versionMap );
00267 }
00268 
00269 void ora::MappingDatabase::insertClassVersion( const Reflex::Type& dictionaryEntry,
00270                                                int depIndex,
00271                                                int containerId,
00272                                                const std::string& mappingVersion,
00273                                                bool asBase  ){
00274   std::string className = dictionaryEntry.Name( Reflex::SCOPED );
00275   std::string classVersion = versionOfClass( dictionaryEntry );
00276   insertClassVersion( className, classVersion, depIndex, containerId, mappingVersion, asBase );
00277 }
00278 
00279 void ora::MappingDatabase::setMappingVersionForClass( const Reflex::Type& dictionaryEntry,
00280                                                       int containerId,
00281                                                       const std::string& mappingVersion,
00282                                                       bool dependency ){
00283   std::string className = dictionaryEntry.Name( Reflex::SCOPED );
00284   std::string classVersion = versionOfClass( dictionaryEntry );
00285   std::string classId = MappingRules::classId( className, classVersion );
00286   std::string mv("");
00287   bool found = m_schema.mappingSchema().selectMappingVersion( classId, containerId, mv );
00288   if( !found ){
00289     int depIndex = 0;
00290     if( dependency ) depIndex = 1;
00291     m_schema.mappingSchema().insertClassVersion( className, classVersion, classId, depIndex, containerId, mappingVersion );
00292   } else {
00293     m_schema.mappingSchema().setMappingVersion( classId, containerId, mappingVersion );
00294   }
00295 }
00296 
00297 void ora::MappingDatabase::storeMapping( const MappingTree& mapping ){
00298   MappingRawData rowMapping( mapping.version() );
00299   unfoldElement( mapping.topElement(), rowMapping );
00300   m_mappingSequence.sinchronize();
00301   m_schema.mappingSchema().storeMapping( rowMapping );  
00302 }
00303 
00304 bool ora::MappingDatabase::getMappingVersionsForContainer( int containerId, std::set<std::string>& versionList ){
00305   return m_schema.mappingSchema().getMappingVersionListForContainer( containerId, versionList );
00306 }
00307 
00308 const std::set<std::string>& ora::MappingDatabase::versions(){
00309   if(!m_isLoaded){
00310     m_schema.mappingSchema().getVersionList( m_versions );
00311     m_isLoaded = true;
00312   }
00313   return m_versions;
00314 }
00315 
00316 bool ora::MappingDatabase::getDependentClassesForContainer( int containerId,
00317                                                             std::set<std::string>& list ){
00318   return m_schema.mappingSchema().getDependentClassesInContainerMapping( containerId, list );
00319 }
00320 
00321 void ora::MappingDatabase::clear(){
00322   m_versions.clear();
00323   m_isLoaded = false;
00324 }
00325