CMS 3D CMS Logo

CMSSW_4_4_3_patch1/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         m_reader->clear();
00093         return destination;
00094       }
00095       
00096     private:
00097       Reflex::Type m_objectType;
00098       MappingElement& m_mapping;
00099       ContainerSchema& m_schema;
00100       DataElement m_localElement;
00101       SelectOperation m_query;
00102       DataElement* m_dataElement;
00103       std::auto_ptr<IRelationalReader> m_reader;
00104   };
00105     
00106   class RelationalPtrLoader: public IPtrLoader {
00107     public:
00108       RelationalPtrLoader( OraPtrReadBuffer& buffer, const std::vector<int>& fullId ):
00109         m_buffer( buffer ),
00110         m_fullId( fullId ),
00111         m_valid( true ){
00112       }
00113       
00114       virtual ~RelationalPtrLoader(){
00115       }
00116       
00117     public:
00118       void* load() const {
00119         if(!m_valid){
00120           throwException("Ptr Loader has been invalidate.",
00121                          "RelationalPtrLoader::load");
00122         }
00123         return m_buffer.read( m_fullId );
00124       }
00125 
00126       void invalidate(){
00127         m_valid = false;
00128       }
00129 
00130       bool isValid() const{
00131         return m_valid;
00132       }
00133       
00134     private:
00135       OraPtrReadBuffer& m_buffer;
00136       std::vector<int> m_fullId;
00137       bool m_valid;
00138   };    
00139 }
00140 
00141 ora::OraPtrWriter::OraPtrWriter( const Reflex::Type& objectType,
00142                                  MappingElement& mapping,
00143                                  ContainerSchema& contSchema ):
00144   m_objectType( objectType ),
00145   m_mappingElement( mapping ),
00146   m_schema( contSchema ),
00147   m_localElement(),
00148   m_dataElement( 0 ),
00149   m_writer(){
00150 }
00151       
00152 ora::OraPtrWriter::~OraPtrWriter(){
00153 }
00154 
00155 bool ora::OraPtrWriter::build(DataElement& dataElement,
00156                               IRelationalData& relationalData,
00157                               RelationalBuffer& operationBuffer){
00158   m_dataElement = &dataElement;
00159   m_localElement.clear();
00160   
00161   // Check the  type
00162   Reflex::Type ptrType = m_objectType.TemplateArgumentAt(0);
00163   Reflex::Type ptrResolvedType = ClassUtils::resolvedType(ptrType);
00164   // Check the component type
00165   if ( ! ptrType || !ptrResolvedType ) {
00166     throwException( "Missing dictionary information for the type of the pointer \"" +
00167                     m_objectType.Name(Reflex::SCOPED|Reflex::FINAL) + "\"",
00168                     "OraPtrWriter::build" );
00169   }
00170 
00171   std::string ptrTypeName = ptrType.Name();
00172 // Retrieve the relevant mapping element
00173   MappingElement::iterator iMe = m_mappingElement.find( ptrTypeName );
00174   if ( iMe == m_mappingElement.end() ) {
00175     throwException( "Item for \"" + ptrTypeName + "\" not found in the mapping element",
00176                     "OraPtrWriter::build" );
00177   }
00178   RelationalStreamerFactory streamerFactory( m_schema );
00179   m_writer.reset( streamerFactory.newWriter( ptrResolvedType, iMe->second ));
00180   return m_writer->build( m_localElement, relationalData, operationBuffer );
00181 }
00182 
00183 void ora::OraPtrWriter::setRecordId( const std::vector<int>& identity ){
00184   m_writer->setRecordId( identity );
00185 }
00186 
00188 void ora::OraPtrWriter::write( int oid,
00189                                const void* data ){
00190 
00191   if(!m_dataElement){
00192     throwException("The streamer has not been built.",
00193                    "OraPtrWriter::write");    
00194   }
00195   
00196   Reflex::Object ptrObject( m_objectType, m_dataElement->address( data ) );
00197   // first load if required
00198   ptrObject.Invoke("load",0);
00199   // then get the data...
00200   void* ptrAddress = 0;
00201   ptrObject.Invoke("address",ptrAddress);
00202   m_writer->write( oid, ptrAddress );
00203 }
00204 
00205 ora::OraPtrUpdater::OraPtrUpdater( const Reflex::Type& objectType,
00206                                    MappingElement& mapping,
00207                                    ContainerSchema& contSchema ):
00208   m_objectType( objectType ),
00209   m_mappingElement( mapping ),
00210   m_schema( contSchema ), 
00211   m_localElement(),
00212   m_dataElement( 0 ),
00213   m_updater(){
00214 }
00215       
00216 ora::OraPtrUpdater::~OraPtrUpdater(){
00217 }
00218 
00219 bool ora::OraPtrUpdater::build(DataElement& dataElement,
00220                                IRelationalData& relationalData,
00221                                RelationalBuffer& operationBuffer){
00222   m_dataElement = &dataElement;
00223   m_localElement.clear();
00224   
00225   // Check the  type
00226   Reflex::Type ptrType = m_objectType.TemplateArgumentAt(0);
00227   Reflex::Type ptrResolvedType = ClassUtils::resolvedType(ptrType);
00228   // Check the component type
00229   if ( ! ptrType || !ptrResolvedType ) {
00230     throwException( "Missing dictionary information for the type of the pointer \"" +
00231                     m_objectType.Name(Reflex::SCOPED|Reflex::FINAL) + "\"",
00232                     "OraPtrUpdater::build" );
00233   }
00234 
00235   std::string ptrTypeName = ptrType.Name();
00236 // Retrieve the relevant mapping element
00237   MappingElement::iterator iMe = m_mappingElement.find( ptrTypeName );
00238   if ( iMe == m_mappingElement.end() ) {
00239     throwException( "Item for \"" + ptrTypeName + "\" not found in the mapping element",
00240                     "OraPtrUpdater::build" );
00241   }
00242   RelationalStreamerFactory streamerFactory( m_schema );
00243   m_updater.reset( streamerFactory.newUpdater( ptrResolvedType, iMe->second ) );
00244   return m_updater->build( m_localElement, relationalData, operationBuffer );
00245 }
00246 
00247 void ora::OraPtrUpdater::setRecordId( const std::vector<int>& identity ){
00248   m_updater->setRecordId( identity );
00249 }
00250 
00252 void ora::OraPtrUpdater::update( int oid,
00253                                  const void* data ){
00254   if(!m_dataElement){
00255     throwException("The streamer has not been built.",
00256                    "OraPtrUpdater::update");    
00257   }
00258   Reflex::Object ptrObject( m_objectType, m_dataElement->address( data ) );
00259   // first load if required
00260   ptrObject.Invoke("load",0);
00261   void* ptrAddress = 0;
00262   ptrObject.Invoke("address",ptrAddress);
00263   m_updater->update( oid, ptrAddress );
00264 }
00265 
00266 ora::OraPtrReader::OraPtrReader( const Reflex::Type& objectType,
00267                                  MappingElement& mapping,
00268                                  ContainerSchema& contSchema ):
00269   m_objectType( objectType ),
00270   m_dataElement( 0 ),
00271   m_readBuffer(),
00272   m_loaders(),
00273   m_tmpIds(){
00274   m_readBuffer.reset( new OraPtrReadBuffer( objectType, mapping, contSchema ));
00275 }
00276       
00277 ora::OraPtrReader::~OraPtrReader(){
00278   for(std::vector<boost::shared_ptr<IPtrLoader> >::const_iterator iL = m_loaders.begin();
00279       iL != m_loaders.end(); ++iL ){
00280     (*iL)->invalidate();
00281   }
00282 }
00283 
00284 bool ora::OraPtrReader::build( DataElement& dataElement,
00285                                IRelationalData& ){
00286   m_dataElement = &dataElement;
00287   m_tmpIds.clear();
00288   m_tmpIds.push_back(0);
00289   return m_readBuffer->build( dataElement );
00290 }
00291 
00292 void ora::OraPtrReader::select( int oid ){
00293   if(!m_dataElement) throwException( "The streamer has not been built.","OraPtrReader::select");
00294   m_tmpIds[0] = oid;
00295 }
00296 
00297 void ora::OraPtrReader::setRecordId( const std::vector<int>& identity ){
00298   m_tmpIds.resize( 1+identity.size() );
00299   for( size_t i=0;i<identity.size();i++){
00300     m_tmpIds[1+i] = identity[i];
00301   }
00302 }
00303 
00305 void ora::OraPtrReader::read( void* data ){
00306   if(!m_dataElement){
00307     throwException("The streamer has not been built.",
00308                    "OraPtrReader::read");    
00309   }
00310   // resolving loader address
00311   Reflex::Member loaderMember = m_objectType.MemberByName("m_loader");
00312   DataElement& loaderElement = m_dataElement->addChild( loaderMember.Offset(), 0 );
00313   void* loaderAddress = loaderElement.address( data );
00314   boost::shared_ptr<IPtrLoader>* loaderPtr = static_cast<boost::shared_ptr<IPtrLoader>*>( loaderAddress );
00315   // creating new loader
00316   boost::shared_ptr<IPtrLoader> newLoader( new RelationalPtrLoader( *m_readBuffer, m_tmpIds ) );
00317   m_loaders.push_back( newLoader );
00318   // installing the new loader
00319   *loaderPtr = newLoader;
00320 }
00321 
00322 void ora::OraPtrReader::clear(){
00323 }
00324 
00325 
00326 ora::OraPtrStreamer::OraPtrStreamer( const Reflex::Type& objectType,
00327                                      MappingElement& mapping,
00328                                      ContainerSchema& contSchema ):
00329   m_objectType( objectType ),
00330   m_mapping( mapping ),
00331   m_schema( contSchema ){
00332 }
00333 
00334 ora::OraPtrStreamer::~OraPtrStreamer(){
00335 }
00336 
00337 ora::IRelationalWriter* ora::OraPtrStreamer::newWriter(){
00338   return new OraPtrWriter( m_objectType, m_mapping, m_schema );
00339 }
00340 
00341 ora::IRelationalUpdater* ora::OraPtrStreamer::newUpdater(){
00342   return new OraPtrUpdater( m_objectType, m_mapping, m_schema );
00343 }
00344 
00345 ora::IRelationalReader* ora::OraPtrStreamer::newReader(){
00346   return new OraPtrReader( m_objectType, m_mapping, m_schema );
00347 }
00348