00001 #include "CondCore/ORA/interface/Exception.h"
00002 #include "CondCore/ORA/interface/Reference.h"
00003 #include "CondCore/ORA/interface/IReferenceHandler.h"
00004 #include "OraReferenceStreamer.h"
00005 #include "DataElement.h"
00006 #include "MappingElement.h"
00007 #include "ContainerSchema.h"
00008 #include "RelationalOperation.h"
00009 #include "ClassUtils.h"
00010
00011 #include "CoralBase/Attribute.h"
00012 #include "Reflex/Member.h"
00013
00014 ora::OraReferenceStreamerBase::OraReferenceStreamerBase( const Reflex::Type& objectType,
00015 MappingElement& mapping,
00016 ContainerSchema& schema):
00017 m_objectType( objectType ),
00018 m_columns( mapping.columnNames() ),
00019 m_schema( schema ),
00020 m_dataElement( 0 ),
00021 m_dataElemOId0( 0 ),
00022 m_dataElemOId1( 0 ),
00023 m_relationalData( 0 ){
00024 }
00025
00026 ora::OraReferenceStreamerBase::~OraReferenceStreamerBase(){
00027 }
00028
00029
00030 bool ora::OraReferenceStreamerBase::buildDataElement(DataElement& dataElement,
00031 IRelationalData& relationalData){
00032 m_dataElement = &dataElement;
00033
00034 Reflex::Type refType = Reflex::Type::ByTypeInfo( typeid(Reference) );
00035
00036 Reflex::OffsetFunction baseOffsetFunc = 0;
00037 if( m_objectType != refType ){
00038 bool foundRef = ClassUtils::findBaseType( m_objectType, refType, baseOffsetFunc );
00039 if(!foundRef){
00040 throwException("Type \""+m_objectType.Name(Reflex::SCOPED)+"\" is not an Ora Reference.",
00041 "OraReferenceStreamerBase::buildDataElement");
00042 }
00043 }
00044 Reflex::Member contIdMember = refType.DataMemberByName("m_containerId");
00045 Reflex::Member itemIdMember = refType.DataMemberByName("m_itemId");
00046 if( !contIdMember || !itemIdMember ){
00047 throwException("Data members for class OId not found.",
00048 "OraReferenceStreamerBase::buildDataElement");
00049 }
00050 m_dataElemOId0 = &dataElement.addChild( contIdMember.Offset(), baseOffsetFunc );
00051 m_dataElemOId1 = &dataElement.addChild( itemIdMember.Offset(), baseOffsetFunc);
00052
00053 if( m_columns.size()<2 ){
00054 throwException("Expected column names have not been found in the mapping.",
00055 "OraReferenceStreamerBase::buildDataElement");
00056 }
00057 const std::type_info& attrType = typeid(int);
00058 for( std::vector<std::string>::const_iterator iCol = m_columns.begin();
00059 iCol != m_columns.end(); ++iCol ){
00060 relationalData.addData( *iCol, attrType );
00061 }
00062 m_relationalData = &relationalData;
00063 return true;
00064 }
00065
00066
00067 void ora::OraReferenceStreamerBase::bindDataForUpdate( const void* data ){
00068 if(!m_relationalData){
00069 throwException("The streamer has not been built.",
00070 "OraReferenceStreamerBase::bindDataForUpdate");
00071 }
00072
00073 void* oid0Address = m_dataElemOId0->address( data );
00074 coral::Attribute& oid0Attr = m_relationalData->data()[ m_columns[0] ];
00075 oid0Attr.data<int>()= *static_cast<int*>(oid0Address);
00076 void* oid1Address = m_dataElemOId1->address( data );
00077 coral::Attribute& oid1Attr = m_relationalData->data()[ m_columns[1] ];
00078 oid1Attr.data<int>()= *static_cast<int*>(oid1Address) ;
00079 IReferenceHandler* refHandler = m_schema.referenceHandler();
00080 void* refPtr = m_dataElement->address( data );
00081 if(refHandler) refHandler->onSave( *static_cast<Reference*>( refPtr ) );
00082 }
00083
00084 void ora::OraReferenceStreamerBase::bindDataForRead( void* data ){
00085 if(!m_relationalData){
00086 throwException("The streamer has not been built.",
00087 "OraReferenceStreamerBase::bindDataForRead");
00088 }
00089 if( m_columns.size()<2 ){
00090 throwException("Expected column names have not been found in the mapping.",
00091 "OraReferenceStreamerBase::bindDataForRead");
00092 }
00093 void* oid0Address = m_dataElemOId0->address( data );
00094 coral::Attribute& oid0Attr = m_relationalData->data()[ m_columns[0] ];
00095 *static_cast<int*>(oid0Address) = oid0Attr.data<int>();
00096 void* oid1Address = m_dataElemOId1->address( data );
00097 coral::Attribute& oid1Attr = m_relationalData->data()[ m_columns[1] ];
00098 *static_cast<int*>( oid1Address ) = oid1Attr.data<int>();
00099 IReferenceHandler* refHandler = m_schema.referenceHandler();
00100 void* refPtr = m_dataElement->address( data );
00101 if(refHandler) refHandler->onLoad( *static_cast<Reference*>( refPtr ) );
00102 }
00103
00104 ora::OraReferenceWriter::OraReferenceWriter( const Reflex::Type& objectType,
00105 MappingElement& mapping,
00106 ContainerSchema& schema ):
00107 OraReferenceStreamerBase( objectType, mapping, schema ){
00108 }
00109
00110 ora::OraReferenceWriter::~OraReferenceWriter(){
00111 }
00112
00113 bool ora::OraReferenceWriter::build(DataElement& dataElement,
00114 IRelationalData& relationalData,
00115 RelationalBuffer&){
00116 return buildDataElement( dataElement, relationalData );
00117 }
00118
00119 void ora::OraReferenceWriter::setRecordId( const std::vector<int>& ){
00120 }
00121
00122 void ora::OraReferenceWriter::write( int,
00123 const void* data ){
00124 bindDataForUpdate( data );
00125 }
00126
00127 ora::OraReferenceUpdater::OraReferenceUpdater( const Reflex::Type& objectType,
00128 MappingElement& mapping,
00129 ContainerSchema& schema):
00130 OraReferenceStreamerBase( objectType, mapping, schema ){
00131 }
00132
00133 ora::OraReferenceUpdater::~OraReferenceUpdater(){
00134 }
00135
00136 bool ora::OraReferenceUpdater::build(DataElement& dataElement,
00137 IRelationalData& relationalData,
00138 RelationalBuffer&){
00139 return buildDataElement( dataElement, relationalData );
00140 }
00141
00142 void ora::OraReferenceUpdater::setRecordId( const std::vector<int>& ){
00143 }
00144
00145 void ora::OraReferenceUpdater::update( int,
00146 const void* data ){
00147 bindDataForUpdate( data );
00148 }
00149
00150 ora::OraReferenceReader::OraReferenceReader( const Reflex::Type& objectType,
00151 MappingElement& mapping,
00152 ContainerSchema& schema ):
00153 OraReferenceStreamerBase( objectType, mapping, schema ){
00154 }
00155
00156 ora::OraReferenceReader::~OraReferenceReader(){
00157 }
00158
00159 bool ora::OraReferenceReader::build(DataElement& dataElement,
00160 IRelationalData& relationalData){
00161 return buildDataElement( dataElement, relationalData );
00162 }
00163
00164 void ora::OraReferenceReader::select( int ){
00165 }
00166
00167 void ora::OraReferenceReader::setRecordId( const std::vector<int>& ){
00168 }
00169
00170 void ora::OraReferenceReader::read( void* data ){
00171 bindDataForRead( data );
00172 }
00173
00174 void ora::OraReferenceReader::clear(){
00175 }
00176
00177
00178 ora::OraReferenceStreamer::OraReferenceStreamer( const Reflex::Type& objectType,
00179 MappingElement& mapping,
00180 ContainerSchema& schema ):
00181 m_objectType( objectType ),
00182 m_mapping( mapping ),
00183 m_schema( schema ){
00184 }
00185
00186 ora::OraReferenceStreamer::~OraReferenceStreamer(){
00187 }
00188
00189 ora::IRelationalWriter* ora::OraReferenceStreamer::newWriter(){
00190 return new OraReferenceWriter( m_objectType, m_mapping, m_schema );
00191 }
00192
00193 ora::IRelationalUpdater* ora::OraReferenceStreamer::newUpdater(){
00194 return new OraReferenceUpdater( m_objectType, m_mapping, m_schema );
00195 }
00196
00197 ora::IRelationalReader* ora::OraReferenceStreamer::newReader(){
00198 return new OraReferenceReader( m_objectType, m_mapping, m_schema );
00199 }