CMS 3D CMS Logo

/data/refman/pasoursint/CMSSW_5_3_1/src/CondCore/ORA/src/UniqueRefStreamer.cc

Go to the documentation of this file.
00001 #include "CondCore/ORA/interface/Exception.h"
00002 #include "CondCore/ORA/interface/UniqueRef.h"
00003 #include "UniqueRefStreamer.h"
00004 #include "RelationalOperation.h"
00005 #include "MappingElement.h"
00006 #include "MappingRules.h"
00007 #include "ContainerSchema.h"
00008 #include "ClassUtils.h"
00009 #include "RelationalStreamerFactory.h"
00010 // externals
00011 #include "CoralBase/Attribute.h"
00012 #include "Reflex/Object.h"
00013 #include "Reflex/Member.h"
00014 
00015 namespace ora {
00016   
00017   class DependentClassWriter {
00018     public:
00019 
00020       DependentClassWriter( ):
00021         m_dataElement(),
00022         m_writer(),
00023         m_depInsert( 0 ){
00024       }
00025 
00026       void build( const Reflex::Type& objectType, MappingElement& mapping,
00027                   ContainerSchema& contSchema, RelationalBuffer& operationBuffer ){
00028 
00029         m_depInsert = &operationBuffer.newInsert( mapping.tableName());
00030         const std::vector<std::string> columns = mapping.columnNames();
00031         for( std::vector<std::string>::const_iterator iC = columns.begin();
00032              iC != columns.end(); ++iC){
00033           m_depInsert->addId( *iC );
00034         }
00035 
00036         MappingElement::iterator iMe = mapping.find( objectType.Name(Reflex::SCOPED) );
00037         // the first inner mapping is the relevant...
00038         if( iMe == mapping.end()){
00039           throwException("Could not find a mapping element for class \""+
00040                          objectType.Name(Reflex::SCOPED)+"\"",
00041                          "DependentClassWriter::write");
00042         }
00043         RelationalStreamerFactory streamerFactory( contSchema );
00044         m_writer.reset( streamerFactory.newWriter( objectType, iMe->second ) );
00045         m_writer->build( m_dataElement, *m_depInsert, operationBuffer );
00046       }
00047 
00048       ~DependentClassWriter(){
00049       }
00050 
00051       void write( int oId, int refId, const void* data ){
00052         if( !m_depInsert ){
00053           throwException( "DependentClassWriter has not been built.",
00054                           "DependentClassWriter::write");
00055         }
00056         
00057         coral::AttributeList& dataBuff = m_depInsert->data();
00058         coral::AttributeList::iterator iData = dataBuff.begin();
00059         iData->data<int>()= oId;
00060         ++iData;
00061         iData->data<int>()= refId;
00062         // transfering the refId
00063         std::vector<int> recordId(1,refId);
00064         m_writer->setRecordId( recordId);
00065         m_writer->write( oId, data );
00066       }
00067 
00068     private:
00069       DataElement m_dataElement;
00070       std::auto_ptr<IRelationalWriter> m_writer;
00071       InsertOperation* m_depInsert;
00072   };
00073   
00074   class DependentClassReader {
00075     public:
00076       DependentClassReader():
00077         m_dataElement(),
00078         m_type(),
00079         m_reader(),
00080         m_depQuery(){
00081       }
00082 
00083       void build( const Reflex::Type& objectType, MappingElement& depMapping, ContainerSchema& contSchema ){
00084 
00085         m_type = objectType;
00086         m_depQuery.reset( new SelectOperation( depMapping.tableName(), contSchema.storageSchema()));
00087         m_depQuery->addWhereId(  depMapping.columnNames()[ 1 ] );
00088         MappingElement::iterator iMap = depMapping.find( m_type.Name(Reflex::SCOPED) );
00089         // the first inner mapping is the good one ...
00090         if( iMap == depMapping.end()){
00091           throwException("Could not find a mapping element for class \""+
00092                          m_type.Name(Reflex::SCOPED)+"\"",
00093                          "DependentClassReadBuffer::ReadBuffer");
00094         }
00095         MappingElement& mapping = iMap->second;
00096         RelationalStreamerFactory streamerFactory( contSchema );
00097         m_reader.reset( streamerFactory.newReader( m_type, mapping )) ;
00098         m_reader->build( m_dataElement , *m_depQuery );
00099       }
00100 
00101       ~DependentClassReader(){
00102       }
00103 
00104       void* read( int refId ){
00105         if( !m_depQuery.get() ){
00106           throwException( "DependentClassReader has not been built.",
00107                           "DependentClassReader::read");
00108         }
00109         coral::AttributeList& whereData = m_depQuery->whereData();
00110         coral::AttributeList::iterator iWData = whereData.begin();
00111         iWData->data<int>() = refId;
00112         m_depQuery->execute();
00113         m_reader->select( refId );
00114         void* destination = 0;
00115         if( m_depQuery->nextCursorRow() ){
00116           destination = ClassUtils::constructObject( m_type );
00117           m_reader->read( destination );
00118         }
00119         m_depQuery->clear();
00120         m_reader->clear();
00121         return destination;
00122       }
00123 
00124     private:
00125       DataElement m_dataElement;
00126       Reflex::Type m_type;
00127       std::auto_ptr<IRelationalReader> m_reader;
00128       std::auto_ptr<SelectOperation> m_depQuery;
00129   };
00130     
00131   class RelationalRefLoader: public IPtrLoader {
00132     public:
00133       explicit RelationalRefLoader( int refId ):
00134         m_reader(),
00135         m_refId( refId ),
00136         m_valid( false ){
00137       }
00138       
00139       virtual ~RelationalRefLoader(){
00140       }
00141       
00142     public:
00143       void build( const Reflex::Type& objectType, MappingElement& mapping, ContainerSchema& contSchema ){
00144         m_reader.build( objectType, mapping, contSchema );
00145         m_valid = true;
00146       }
00147       
00148       void* load() const {
00149         if(!m_valid){
00150           throwException("Ref Loader has been invalidate.",
00151                          "RelationalRefLoader::load");
00152         }
00153         return m_reader.read( m_refId );
00154       }
00155 
00156       void invalidate(){
00157         m_valid = false;
00158       }
00159 
00160       bool isValid() const{
00161         return m_valid;
00162       }
00163       
00164     private:
00165       mutable DependentClassReader m_reader;
00166       int m_refId;
00167       bool m_valid;
00168   };    
00169 }
00170 
00171 ora::UniqueRefWriter::UniqueRefWriter( const Reflex::Type& objectType,
00172                                        MappingElement& mapping,
00173                                        ContainerSchema& contSchema ):
00174   m_objectType( objectType ),
00175   m_mappingElement( mapping ),
00176   m_schema( contSchema ),
00177   m_dataElement( 0 ),
00178   m_relationalData( 0 ),
00179   m_operationBuffer( 0 ){
00180   m_columnIndexes[0]=-1;  
00181   m_columnIndexes[1]=-1;  
00182 }
00183 
00184 std::string ora::uniqueRefNullLabel(){
00185   static std::string nullLabel("ora::UniqueRef::Null");
00186   return nullLabel;
00187 }
00188       
00189 ora::UniqueRefWriter::~UniqueRefWriter(){
00190 }
00191 
00192 bool ora::UniqueRefWriter::build(DataElement& dataElement,
00193                                  IRelationalData& relationalData,
00194                                  RelationalBuffer& buffer){
00195   m_dataElement = &dataElement;
00196 
00197   const std::vector<std::string>& columns = m_mappingElement.columnNames();
00198   if( columns.size() < 2 ){
00199     throwException("Expected column names have not been found in the mapping.",
00200                    "UniqueRefWriter::build");    
00201   }
00202   // booking for ref metadata 
00203   m_columnIndexes[0] = relationalData.addData( columns[0],typeid(std::string) );
00204   // booking for ref id 
00205   m_columnIndexes[1] = relationalData.addData( columns[1],typeid(int) );
00206   m_relationalData = &relationalData;
00207   m_operationBuffer = &buffer;
00208   return true;
00209 }
00210 
00211 void ora::UniqueRefWriter::setRecordId( const std::vector<int>& ){
00212 }
00213 
00215 void ora::UniqueRefWriter::write( int oid,
00216                                   const void* data ){
00217 
00218   if(!m_dataElement){
00219     throwException("The streamer has not been built.",
00220                    "UniqueRefWriter::write");
00221   }
00222 
00223   void* refAddress = m_dataElement->address( data );
00224 
00225   Reflex::Object refObj( m_objectType, const_cast<void*>(refAddress));
00226 
00227   bool isNull;
00228   refObj.Invoke("operator!",isNull);
00229 
00230   int refId = 0;
00231   std::string className = uniqueRefNullLabel();
00232 
00233   if(!isNull){
00234     // resolving the ref type
00235     std::type_info* refTypeInfo = 0;
00236     refObj.Invoke("typeInfo",refTypeInfo);
00237     Reflex::Type refType = ClassUtils::lookupDictionary(*refTypeInfo);
00238     className = refType.Name(Reflex::SCOPED);
00239 
00240     // building the dependent buffer
00241     MappingElement& depMapping =  m_schema.mappingForDependentClass( refType, true );    
00242 
00243     // getting a new valid ref id
00244     refId = m_schema.containerSequences().getNextId( MappingRules::sequenceNameForDependentClass( m_schema.containerName(),className ));
00245     
00246     DependentClassWriter writer;
00247     writer.build( refType, depMapping, m_schema, m_operationBuffer->addVolatileBuffer() );
00248     void* refData;
00249     refObj.Invoke("operator*",refData);
00250     writer.write( oid, refId, refData );
00251 
00252   }
00253   // writing in the parent table
00254   coral::AttributeList& parentData = m_relationalData->data();
00255   parentData[m_columnIndexes[0]].data<std::string>()=className;
00256   parentData[m_columnIndexes[1]].data<int>()=refId;
00257 }
00258 
00259 ora::UniqueRefUpdater::UniqueRefUpdater( const Reflex::Type& objectType,
00260                                          MappingElement& mapping,
00261                                          ContainerSchema& contSchema ):
00262   m_writer( objectType, mapping, contSchema ){
00263 }
00264       
00265 ora::UniqueRefUpdater::~UniqueRefUpdater(){
00266 }
00267 
00268 bool ora::UniqueRefUpdater::build(DataElement& dataElement,
00269                                   IRelationalData& relationalData,
00270                                   RelationalBuffer& operationBuffer){
00271   return m_writer.build( dataElement, relationalData, operationBuffer );
00272 }
00273 
00274 void ora::UniqueRefUpdater::setRecordId( const std::vector<int>& identity ){
00275   m_writer.setRecordId( identity );
00276 }
00277 
00279 void ora::UniqueRefUpdater::update( int oid,
00280                                     const void* data ){
00281   m_writer.write( oid, data );
00282 }
00283 
00284 ora::UniqueRefReader::UniqueRefReader( const Reflex::Type& objectType,
00285                                        MappingElement& mapping,
00286                                        ContainerSchema& contSchema ):
00287   m_objectType( objectType ),
00288   m_mappingElement( mapping ),
00289   m_schema( contSchema ),
00290   m_dataElement( 0 ),
00291   m_relationalData( 0 ),
00292   m_loaders(){
00293   m_columnIndexes[0]=-1;  
00294   m_columnIndexes[1]=-1;  
00295 }
00296       
00297 ora::UniqueRefReader::~UniqueRefReader(){
00298   for(std::vector<boost::shared_ptr<RelationalRefLoader> >::const_iterator iL = m_loaders.begin();
00299       iL != m_loaders.end(); ++iL ){
00300     (*iL)->invalidate();
00301   }
00302 }
00303 
00304 bool ora::UniqueRefReader::build( DataElement& dataElement,
00305                                   IRelationalData& relationalData){
00306   m_dataElement = &dataElement;
00307   const std::vector<std::string>& columns = m_mappingElement.columnNames();
00308   if( columns.size() < 2 ){
00309     throwException("Expected column names have not been found in the mapping.",
00310                    "UniqueRefReader::build");    
00311   }
00312   // booking for ref metadata 
00313   m_columnIndexes[0] = relationalData.addData( columns[0],typeid(std::string) );
00314   // booking for ref id 
00315   m_columnIndexes[1] = relationalData.addData( columns[1],typeid(int) );
00316   m_relationalData = &relationalData;
00317   return true;
00318 }
00319 
00320 void ora::UniqueRefReader::select( int ){
00321 }
00322 
00323 void ora::UniqueRefReader::setRecordId( const std::vector<int>& ){
00324 }
00325 
00327 void ora::UniqueRefReader::read( void* data ){
00328   if(!m_dataElement){
00329     throwException("The streamer has not been built.",
00330                    "UniqueRefReader::read");
00331   }
00332   coral::AttributeList& row = m_relationalData->data();
00333   std::string className = row[m_columnIndexes[0]].data<std::string>();
00334   int refId = row[m_columnIndexes[1]].data<int>();
00335 
00336   Reflex::Type refType = ClassUtils::lookupDictionary(className);
00337   
00338   // building the dependent buffer
00339   MappingElement& depMapping =  m_schema.mappingForDependentClass( refType );
00340   
00341   // resolving loader address
00342   Reflex::Member loaderMember = m_objectType.MemberByName("m_loader");
00343   DataElement& loaderElement = m_dataElement->addChild( loaderMember.Offset(), 0 );
00344   void* loaderAddress = loaderElement.address( data );
00345   boost::shared_ptr<IPtrLoader>* loaderPtr = static_cast<boost::shared_ptr<IPtrLoader>*>( loaderAddress );
00346   // creating new loader
00347   boost::shared_ptr<RelationalRefLoader> newLoader( new RelationalRefLoader( refId ) );
00348   newLoader->build( refType, depMapping, m_schema );
00349   m_loaders.push_back( newLoader );
00350   // installing the new loader
00351   boost::shared_ptr<IPtrLoader> tmp( newLoader );
00352   *loaderPtr = tmp;
00353 }
00354 
00355 void ora::UniqueRefReader::clear(){
00356 }
00357 
00358 ora::UniqueRefStreamer::UniqueRefStreamer( const Reflex::Type& objectType,
00359                                            MappingElement& mapping,
00360                                            ContainerSchema& contSchema ):
00361   m_objectType( objectType ),
00362   m_mapping( mapping ),
00363   m_schema( contSchema ){
00364 }
00365 
00366 ora::UniqueRefStreamer::~UniqueRefStreamer(){
00367 }
00368 
00369 ora::IRelationalWriter* ora::UniqueRefStreamer::newWriter(){
00370   return new UniqueRefWriter( m_objectType, m_mapping, m_schema );
00371 }
00372 
00373 ora::IRelationalUpdater* ora::UniqueRefStreamer::newUpdater(){
00374   return new UniqueRefUpdater( m_objectType, m_mapping, m_schema );
00375 }
00376 
00377 ora::IRelationalReader* ora::UniqueRefStreamer::newReader(){
00378   return new UniqueRefReader( m_objectType, m_mapping, m_schema );
00379 }
00380