CMS 3D CMS Logo

/data/refman/pasoursint/CMSSW_4_1_8_patch13/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         return destination;
00121       }
00122 
00123     private:
00124       DataElement m_dataElement;
00125       Reflex::Type m_type;
00126       std::auto_ptr<IRelationalReader> m_reader;
00127       std::auto_ptr<SelectOperation> m_depQuery;
00128   };
00129     
00130   class RelationalRefLoader: public IPtrLoader {
00131     public:
00132       explicit RelationalRefLoader( int refId ):
00133         m_reader(),
00134         m_refId( refId ),
00135         m_valid( false ){
00136       }
00137       
00138       virtual ~RelationalRefLoader(){
00139       }
00140       
00141     public:
00142       void build( const Reflex::Type& objectType, MappingElement& mapping, ContainerSchema& contSchema ){
00143         m_reader.build( objectType, mapping, contSchema );
00144         m_valid = true;
00145       }
00146       
00147       void* load() const {
00148         if(!m_valid){
00149           throwException("Ref Loader has been invalidate.",
00150                          "RelationalRefLoader::load");
00151         }
00152         return m_reader.read( m_refId );
00153       }
00154 
00155       void invalidate(){
00156         m_valid = false;
00157       }
00158 
00159       bool isValid() const{
00160         return m_valid;
00161       }
00162       
00163     private:
00164       mutable DependentClassReader m_reader;
00165       int m_refId;
00166       bool m_valid;
00167   };    
00168 }
00169 
00170 ora::UniqueRefWriter::UniqueRefWriter( const Reflex::Type& objectType,
00171                                        MappingElement& mapping,
00172                                        ContainerSchema& contSchema ):
00173   m_objectType( objectType ),
00174   m_mappingElement( mapping ),
00175   m_schema( contSchema ),
00176   m_dataElement( 0 ),
00177   m_relationalData( 0 ),
00178   m_operationBuffer( 0 ){
00179 }
00180 
00181 std::string ora::uniqueRefNullLabel(){
00182   static std::string nullLabel("ora::UniqueRef::Null");
00183   return nullLabel;
00184 }
00185       
00186 ora::UniqueRefWriter::~UniqueRefWriter(){
00187 }
00188 
00189 bool ora::UniqueRefWriter::build(DataElement& dataElement,
00190                                  IRelationalData& relationalData,
00191                                  RelationalBuffer& buffer){
00192   m_dataElement = &dataElement;
00193 
00194   const std::vector<std::string>& columns = m_mappingElement.columnNames();
00195   // booking for ref metadata 
00196   relationalData.addData( columns[0],typeid(std::string) );
00197   // booking for ref id 
00198   relationalData.addData( columns[1],typeid(int) );
00199   m_relationalData = &relationalData;
00200   m_operationBuffer = &buffer;
00201   return true;
00202 }
00203 
00204 void ora::UniqueRefWriter::setRecordId( const std::vector<int>& ){
00205 }
00206 
00208 void ora::UniqueRefWriter::write( int oid,
00209                                   const void* data ){
00210 
00211   if(!m_dataElement){
00212     throwException("The streamer has not been built.",
00213                    "UniqueRefWriter::write");
00214   }
00215 
00216   void* refAddress = m_dataElement->address( data );
00217 
00218   Reflex::Object refObj( m_objectType, const_cast<void*>(refAddress));
00219 
00220   bool isNull;
00221   refObj.Invoke("operator!",isNull);
00222 
00223   int refId = 0;
00224   std::string className = uniqueRefNullLabel();
00225 
00226   if(!isNull){
00227     // resolving the ref type
00228     std::type_info* refTypeInfo = 0;
00229     refObj.Invoke("typeInfo",refTypeInfo);
00230     Reflex::Type refType = ClassUtils::lookupDictionary(*refTypeInfo);
00231     className = refType.Name(Reflex::SCOPED);
00232 
00233     // getting a new valid ref id
00234     refId = m_schema.containerSequences().getNextId( MappingRules::sequenceNameForDependentClass( m_schema.containerName(),className ));
00235     
00236     // building the dependent buffer
00237     MappingElement& depMapping =  m_schema.mappingForDependentClass( refType, true );    
00238 
00239     DependentClassWriter writer;
00240     writer.build( refType, depMapping, m_schema, m_operationBuffer->addVolatileBuffer() );
00241     void* refData;
00242     refObj.Invoke("operator*",refData);
00243     writer.write( oid, refId, refData );
00244 
00245   }
00246   // writing in the parent table
00247   coral::AttributeList& parentData = m_relationalData->data();
00248   parentData[m_mappingElement.columnNames()[0]].data<std::string>()=className;
00249   parentData[m_mappingElement.columnNames()[1]].data<int>()=refId;
00250 }
00251 
00252 ora::UniqueRefUpdater::UniqueRefUpdater( const Reflex::Type& objectType,
00253                                          MappingElement& mapping,
00254                                          ContainerSchema& contSchema ):
00255   m_writer( objectType, mapping, contSchema ){
00256 }
00257       
00258 ora::UniqueRefUpdater::~UniqueRefUpdater(){
00259 }
00260 
00261 bool ora::UniqueRefUpdater::build(DataElement& dataElement,
00262                                   IRelationalData& relationalData,
00263                                   RelationalBuffer& operationBuffer){
00264   return m_writer.build( dataElement, relationalData, operationBuffer );
00265 }
00266 
00267 void ora::UniqueRefUpdater::setRecordId( const std::vector<int>& identity ){
00268   m_writer.setRecordId( identity );
00269 }
00270 
00272 void ora::UniqueRefUpdater::update( int oid,
00273                                     const void* data ){
00274   m_writer.write( oid, data );
00275 }
00276 
00277 ora::UniqueRefReader::UniqueRefReader( const Reflex::Type& objectType,
00278                                        MappingElement& mapping,
00279                                        ContainerSchema& contSchema ):
00280   m_objectType( objectType ),
00281   m_mappingElement( mapping ),
00282   m_schema( contSchema ),
00283   m_dataElement( 0 ),
00284   m_relationalData( 0 ),
00285   m_loaders(){
00286 }
00287       
00288 ora::UniqueRefReader::~UniqueRefReader(){
00289   for(std::vector<boost::shared_ptr<RelationalRefLoader> >::const_iterator iL = m_loaders.begin();
00290       iL != m_loaders.end(); ++iL ){
00291     (*iL)->invalidate();
00292   }
00293 }
00294 
00295 bool ora::UniqueRefReader::build( DataElement& dataElement,
00296                                   IRelationalData& relationalData){
00297   m_dataElement = &dataElement;
00298   const std::vector<std::string>& columns = m_mappingElement.columnNames();
00299   // booking for ref metadata 
00300   relationalData.addData( columns[0],typeid(std::string) );
00301   // booking for ref id 
00302   relationalData.addData( columns[1],typeid(int) );
00303   m_relationalData = &relationalData;
00304   return true;
00305 }
00306 
00307 void ora::UniqueRefReader::select( int ){
00308 }
00309 
00310 void ora::UniqueRefReader::setRecordId( const std::vector<int>& ){
00311 }
00312 
00314 void ora::UniqueRefReader::read( void* data ){
00315   if(!m_dataElement){
00316     throwException("The streamer has not been built.",
00317                    "UniqueRefReader::read");
00318   }
00319   coral::AttributeList& row = m_relationalData->data();
00320   std::string className = row[m_mappingElement.columnNames()[0]].data<std::string>();
00321   int refId = row[m_mappingElement.columnNames()[1]].data<int>();
00322 
00323   Reflex::Type refType = ClassUtils::lookupDictionary(className);
00324   
00325   // building the dependent buffer
00326   MappingElement& depMapping =  m_schema.mappingForDependentClass( refType );
00327   
00328   // resolving loader address
00329   Reflex::Member loaderMember = m_objectType.MemberByName("m_loader");
00330   DataElement& loaderElement = m_dataElement->addChild( loaderMember.Offset(), 0 );
00331   void* loaderAddress = loaderElement.address( data );
00332   boost::shared_ptr<IPtrLoader>* loaderPtr = static_cast<boost::shared_ptr<IPtrLoader>*>( loaderAddress );
00333   // creating new loader
00334   boost::shared_ptr<RelationalRefLoader> newLoader( new RelationalRefLoader( refId ) );
00335   newLoader->build( refType, depMapping, m_schema );
00336   m_loaders.push_back( newLoader );
00337   // installing the new loader
00338   boost::shared_ptr<IPtrLoader> tmp( newLoader );
00339   *loaderPtr = tmp;
00340 }
00341 
00342 void ora::UniqueRefReader::clear(){
00343 }
00344 
00345 ora::UniqueRefStreamer::UniqueRefStreamer( const Reflex::Type& objectType,
00346                                            MappingElement& mapping,
00347                                            ContainerSchema& contSchema ):
00348   m_objectType( objectType ),
00349   m_mapping( mapping ),
00350   m_schema( contSchema ){
00351 }
00352 
00353 ora::UniqueRefStreamer::~UniqueRefStreamer(){
00354 }
00355 
00356 ora::IRelationalWriter* ora::UniqueRefStreamer::newWriter(){
00357   return new UniqueRefWriter( m_objectType, m_mapping, m_schema );
00358 }
00359 
00360 ora::IRelationalUpdater* ora::UniqueRefStreamer::newUpdater(){
00361   return new UniqueRefUpdater( m_objectType, m_mapping, m_schema );
00362 }
00363 
00364 ora::IRelationalReader* ora::UniqueRefStreamer::newReader(){
00365   return new UniqueRefReader( m_objectType, m_mapping, m_schema );
00366 }
00367