CMS 3D CMS Logo

/data/refman/pasoursint/CMSSW_4_1_8_patch12/src/CondCore/ORA/src/OraPtrStreamer.cc

Go to the documentation of this file.
00001 #include "CondCore/ORA/interface/Exception.h"
00002 #include "CondCore/ORA/interface/Ptr.h"
00003 #include "OraPtrStreamer.h"
00004 #include "RelationalOperation.h"
00005 #include "MappingElement.h"
00006 #include "ContainerSchema.h"
00007 #include "ClassUtils.h"
00008 #include "RelationalStreamerFactory.h"
00009 // externals
00010 #include "CoralBase/Attribute.h"
00011 #include "Reflex/Object.h"
00012 #include "Reflex/Member.h"
00013 
00014 namespace ora {
00015   class OraPtrReadBuffer {
00016     public:
00017       OraPtrReadBuffer( const Reflex::Type& objectType, MappingElement& mapping, ContainerSchema& contSchema ):
00018         m_objectType( objectType ),
00019         m_mapping( mapping ),
00020         m_schema( contSchema ),
00021         m_localElement(),
00022         m_query( mapping.tableName(), contSchema.storageSchema() ),
00023         m_dataElement( 0 ),
00024         m_reader(){
00025       }
00026 
00027       ~OraPtrReadBuffer(){
00028       }
00029       
00030       bool build( DataElement& dataElement ){
00031         m_dataElement = &dataElement;
00032         m_localElement.clear();
00033 
00034         const std::vector<std::string>& columns = m_mapping.columnNames();
00035         size_t cols = columns.size();
00036         for( size_t i=0; i<cols; i++ ){
00037           m_query.addWhereId( columns[ i ] );
00038         }
00039         
00040         // Check the  type
00041         Reflex::Type ptrType = m_objectType.TemplateArgumentAt(0);
00042         Reflex::Type ptrResolvedType = ClassUtils::resolvedType(ptrType);
00043         // Check the component type
00044         if ( ! ptrType || !ptrResolvedType ) {
00045           throwException( "Missing dictionary information for the type of the pointer \"" +
00046                           m_objectType.Name(Reflex::SCOPED|Reflex::FINAL) + "\"",
00047                           "OraPtrReadBuffer::build" );
00048         }
00049 
00050         std::string ptrTypeName = ptrType.Name();
00051         // Retrieve the relevant mapping element
00052         MappingElement::iterator iMe = m_mapping.find( ptrTypeName );
00053         if ( iMe == m_mapping.end() ) {
00054           throwException( "Item for \"" + ptrTypeName + "\" not found in the mapping element",
00055                           "OraPtrReadBuffer::build" );
00056         }
00057         RelationalStreamerFactory streamerFactory( m_schema );
00058         m_reader.reset( streamerFactory.newReader( ptrResolvedType, iMe->second ) );
00059         return m_reader->build( m_localElement, m_query );     
00060       }
00061       
00062       void* read( const std::vector<int>& fullId ){
00063         if(!m_dataElement) throwException( "Read buffer has not been built.","OraPtrReadBuffer::read");
00064 
00065         if(!fullId.size()) throwException( "Object id set is empty.","OraPtrReadBuffer::read"); 
00066         
00067         coral::AttributeList& whereBuff = m_query.whereData();
00068         coral::AttributeList::iterator iCol = whereBuff.begin();
00069         size_t i=0;
00070         for( coral::AttributeList::iterator iCol = whereBuff.begin(); iCol != whereBuff.end(); ++iCol ){
00071           if( i<fullId.size() ){
00072             iCol->data<int>() = fullId[i];
00073           }
00074           i++;
00075         }
00076         
00077         std::vector<int> recordId( fullId.size()-1 );
00078         for( size_t i=0; i<fullId.size()-1; i++ ){
00079           recordId[i] = fullId[i+1];
00080           ++i;
00081         }
00082         
00083         m_query.execute();
00084         m_reader->select( fullId[0] );
00085         void* destination = 0;
00086         if( m_query.nextCursorRow() ){
00087           destination = ClassUtils::constructObject( m_objectType.TemplateArgumentAt(0) );
00088           m_reader->setRecordId( recordId );
00089           m_reader->read( destination );
00090         }
00091         m_query.clear();
00092         return destination;
00093       }
00094       
00095     private:
00096       Reflex::Type m_objectType;
00097       MappingElement& m_mapping;
00098       ContainerSchema& m_schema;
00099       DataElement m_localElement;
00100       SelectOperation m_query;
00101       DataElement* m_dataElement;
00102       std::auto_ptr<IRelationalReader> m_reader;
00103   };
00104     
00105   class RelationalPtrLoader: public IPtrLoader {
00106     public:
00107       RelationalPtrLoader( OraPtrReadBuffer& buffer, const std::vector<int>& fullId ):
00108         m_buffer( buffer ),
00109         m_fullId( fullId ),
00110         m_valid( true ){
00111       }
00112       
00113       virtual ~RelationalPtrLoader(){
00114       }
00115       
00116     public:
00117       void* load() const {
00118         if(!m_valid){
00119           throwException("Ptr Loader has been invalidate.",
00120                          "RelationalPtrLoader::load");
00121         }
00122         return m_buffer.read( m_fullId );
00123       }
00124 
00125       void invalidate(){
00126         m_valid = false;
00127       }
00128 
00129       bool isValid() const{
00130         return m_valid;
00131       }
00132       
00133     private:
00134       OraPtrReadBuffer& m_buffer;
00135       std::vector<int> m_fullId;
00136       bool m_valid;
00137   };    
00138 }
00139 
00140 ora::OraPtrWriter::OraPtrWriter( const Reflex::Type& objectType,
00141                                  MappingElement& mapping,
00142                                  ContainerSchema& contSchema ):
00143   m_objectType( objectType ),
00144   m_mappingElement( mapping ),
00145   m_schema( contSchema ),
00146   m_localElement(),
00147   m_dataElement( 0 ),
00148   m_writer(){
00149 }
00150       
00151 ora::OraPtrWriter::~OraPtrWriter(){
00152 }
00153 
00154 bool ora::OraPtrWriter::build(DataElement& dataElement,
00155                               IRelationalData& relationalData,
00156                               RelationalBuffer& operationBuffer){
00157   m_dataElement = &dataElement;
00158   m_localElement.clear();
00159   
00160   // Check the  type
00161   Reflex::Type ptrType = m_objectType.TemplateArgumentAt(0);
00162   Reflex::Type ptrResolvedType = ClassUtils::resolvedType(ptrType);
00163   // Check the component type
00164   if ( ! ptrType || !ptrResolvedType ) {
00165     throwException( "Missing dictionary information for the type of the pointer \"" +
00166                     m_objectType.Name(Reflex::SCOPED|Reflex::FINAL) + "\"",
00167                     "OraPtrWriter::build" );
00168   }
00169 
00170   std::string ptrTypeName = ptrType.Name();
00171 // Retrieve the relevant mapping element
00172   MappingElement::iterator iMe = m_mappingElement.find( ptrTypeName );
00173   if ( iMe == m_mappingElement.end() ) {
00174     throwException( "Item for \"" + ptrTypeName + "\" not found in the mapping element",
00175                     "OraPtrWriter::build" );
00176   }
00177   RelationalStreamerFactory streamerFactory( m_schema );
00178   m_writer.reset( streamerFactory.newWriter( ptrResolvedType, iMe->second ));
00179   return m_writer->build( m_localElement, relationalData, operationBuffer );
00180 }
00181 
00182 void ora::OraPtrWriter::setRecordId( const std::vector<int>& identity ){
00183   m_writer->setRecordId( identity );
00184 }
00185 
00187 void ora::OraPtrWriter::write( int oid,
00188                                const void* data ){
00189 
00190   if(!m_dataElement){
00191     throwException("The streamer has not been built.",
00192                    "OraPtrWriter::write");    
00193   }
00194   
00195   Reflex::Object ptrObject( m_objectType, m_dataElement->address( data ) );
00196   // first load if required
00197   ptrObject.Invoke("load",0);
00198   // then get the data...
00199   void* ptrAddress = 0;
00200   ptrObject.Invoke("address",ptrAddress);
00201   m_writer->write( oid, ptrAddress );
00202 }
00203 
00204 ora::OraPtrUpdater::OraPtrUpdater( const Reflex::Type& objectType,
00205                                    MappingElement& mapping,
00206                                    ContainerSchema& contSchema ):
00207   m_objectType( objectType ),
00208   m_mappingElement( mapping ),
00209   m_schema( contSchema ), 
00210   m_localElement(),
00211   m_dataElement( 0 ),
00212   m_updater(){
00213 }
00214       
00215 ora::OraPtrUpdater::~OraPtrUpdater(){
00216 }
00217 
00218 bool ora::OraPtrUpdater::build(DataElement& dataElement,
00219                                IRelationalData& relationalData,
00220                                RelationalBuffer& operationBuffer){
00221   m_dataElement = &dataElement;
00222   m_localElement.clear();
00223   
00224   // Check the  type
00225   Reflex::Type ptrType = m_objectType.TemplateArgumentAt(0);
00226   Reflex::Type ptrResolvedType = ClassUtils::resolvedType(ptrType);
00227   // Check the component type
00228   if ( ! ptrType || !ptrResolvedType ) {
00229     throwException( "Missing dictionary information for the type of the pointer \"" +
00230                     m_objectType.Name(Reflex::SCOPED|Reflex::FINAL) + "\"",
00231                     "OraPtrUpdater::build" );
00232   }
00233 
00234   std::string ptrTypeName = ptrType.Name();
00235 // Retrieve the relevant mapping element
00236   MappingElement::iterator iMe = m_mappingElement.find( ptrTypeName );
00237   if ( iMe == m_mappingElement.end() ) {
00238     throwException( "Item for \"" + ptrTypeName + "\" not found in the mapping element",
00239                     "OraPtrUpdater::build" );
00240   }
00241   RelationalStreamerFactory streamerFactory( m_schema );
00242   m_updater.reset( streamerFactory.newUpdater( ptrResolvedType, iMe->second ) );
00243   return m_updater->build( m_localElement, relationalData, operationBuffer );
00244 }
00245 
00246 void ora::OraPtrUpdater::setRecordId( const std::vector<int>& identity ){
00247   m_updater->setRecordId( identity );
00248 }
00249 
00251 void ora::OraPtrUpdater::update( int oid,
00252                                  const void* data ){
00253   if(!m_dataElement){
00254     throwException("The streamer has not been built.",
00255                    "OraPtrUpdater::update");    
00256   }
00257   Reflex::Object ptrObject( m_objectType, m_dataElement->address( data ) );
00258   // first load if required
00259   ptrObject.Invoke("load",0);
00260   void* ptrAddress = 0;
00261   ptrObject.Invoke("address",ptrAddress);
00262   m_updater->update( oid, ptrAddress );
00263 }
00264 
00265 ora::OraPtrReader::OraPtrReader( const Reflex::Type& objectType,
00266                                  MappingElement& mapping,
00267                                  ContainerSchema& contSchema ):
00268   m_objectType( objectType ),
00269   m_dataElement( 0 ),
00270   m_readBuffer(),
00271   m_loaders(),
00272   m_tmpIds(){
00273   m_readBuffer.reset( new OraPtrReadBuffer( objectType, mapping, contSchema ));
00274 }
00275       
00276 ora::OraPtrReader::~OraPtrReader(){
00277   for(std::vector<boost::shared_ptr<IPtrLoader> >::const_iterator iL = m_loaders.begin();
00278       iL != m_loaders.end(); ++iL ){
00279     (*iL)->invalidate();
00280   }
00281 }
00282 
00283 bool ora::OraPtrReader::build( DataElement& dataElement,
00284                                IRelationalData& ){
00285   m_dataElement = &dataElement;
00286   m_tmpIds.clear();
00287   m_tmpIds.push_back(0);
00288   return m_readBuffer->build( dataElement );
00289 }
00290 
00291 void ora::OraPtrReader::select( int oid ){
00292   if(!m_dataElement) throwException( "The streamer has not been built.","OraPtrReader::select");
00293   m_tmpIds[0] = oid;
00294 }
00295 
00296 void ora::OraPtrReader::setRecordId( const std::vector<int>& identity ){
00297   m_tmpIds.resize( 1+identity.size() );
00298   for( size_t i=0;i<identity.size();i++){
00299     m_tmpIds[1+i] = identity[i];
00300   }
00301 }
00302 
00304 void ora::OraPtrReader::read( void* data ){
00305   if(!m_dataElement){
00306     throwException("The streamer has not been built.",
00307                    "OraPtrReader::read");    
00308   }
00309   // resolving loader address
00310   Reflex::Member loaderMember = m_objectType.MemberByName("m_loader");
00311   DataElement& loaderElement = m_dataElement->addChild( loaderMember.Offset(), 0 );
00312   void* loaderAddress = loaderElement.address( data );
00313   boost::shared_ptr<IPtrLoader>* loaderPtr = static_cast<boost::shared_ptr<IPtrLoader>*>( loaderAddress );
00314   // creating new loader
00315   boost::shared_ptr<IPtrLoader> newLoader( new RelationalPtrLoader( *m_readBuffer, m_tmpIds ) );
00316   m_loaders.push_back( newLoader );
00317   // installing the new loader
00318   *loaderPtr = newLoader;
00319 }
00320 
00321 void ora::OraPtrReader::clear(){
00322 }
00323 
00324 
00325 ora::OraPtrStreamer::OraPtrStreamer( const Reflex::Type& objectType,
00326                                      MappingElement& mapping,
00327                                      ContainerSchema& contSchema ):
00328   m_objectType( objectType ),
00329   m_mapping( mapping ),
00330   m_schema( contSchema ){
00331 }
00332 
00333 ora::OraPtrStreamer::~OraPtrStreamer(){
00334 }
00335 
00336 ora::IRelationalWriter* ora::OraPtrStreamer::newWriter(){
00337   return new OraPtrWriter( m_objectType, m_mapping, m_schema );
00338 }
00339 
00340 ora::IRelationalUpdater* ora::OraPtrStreamer::newUpdater(){
00341   return new OraPtrUpdater( m_objectType, m_mapping, m_schema );
00342 }
00343 
00344 ora::IRelationalReader* ora::OraPtrStreamer::newReader(){
00345   return new OraPtrReader( m_objectType, m_mapping, m_schema );
00346 }
00347