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