00001 #include "CondCore/ORA/interface/Exception.h"
00002 #include "CondCore/ORA/interface/NamedRef.h"
00003 #include "NamedRefStreamer.h"
00004 #include "RelationalOperation.h"
00005 #include "MappingElement.h"
00006 #include "ContainerSchema.h"
00007 #include "DatabaseSession.h"
00008 #include "ClassUtils.h"
00009 #include "RelationalStreamerFactory.h"
00010
00011 #include "CoralBase/Attribute.h"
00012 #include "Reflex/Member.h"
00013
00014 std::string ora::namedRefNullLabel(){
00015 static std::string nullLabel("ora::NamedRef::Null");
00016 return nullLabel;
00017 }
00018
00019 ora::NamedReferenceStreamerBase::NamedReferenceStreamerBase( const Reflex::Type& objectType,
00020 MappingElement& mapping,
00021 ContainerSchema& schema):
00022 m_objectType( objectType ),
00023 m_mapping( mapping ),
00024 m_columnIndex( -1 ),
00025 m_schema( schema ),
00026 m_dataElement( 0 ),
00027 m_refNameDataElement( 0 ),
00028 m_ptrDataElement( 0 ),
00029 m_flagDataElement( 0 ),
00030 m_relationalData( 0 ){
00031 }
00032
00033 ora::NamedReferenceStreamerBase::~NamedReferenceStreamerBase(){
00034 }
00035
00036
00037 bool ora::NamedReferenceStreamerBase::buildDataElement(DataElement& dataElement,
00038 IRelationalData& relationalData){
00039 m_dataElement = &dataElement;
00040 m_objectType.UpdateMembers();
00041 Reflex::Member nameMember = m_objectType.DataMemberByName("m_name");
00042 if( !nameMember ){
00043 throwException("Data member \"m_name\" not found in class \""+m_objectType.Name()+"\".",
00044 "NamedReferenceStreamerBase::buildDataElement");
00045 }
00046 m_refNameDataElement = &dataElement.addChild( nameMember.Offset(), 0 );
00047 Reflex::Member ptrMember = m_objectType.DataMemberByName("m_ptr");
00048 if( !ptrMember ){
00049 throwException("Data member \"m_ptr\" not found in class \""+m_objectType.Name()+"\".",
00050 "NamedReferenceStreamerBase::buildDataElement");
00051 }
00052 m_ptrDataElement = &dataElement.addChild( ptrMember.Offset(), 0 );
00053 Reflex::Member flagMember = m_objectType.DataMemberByName("m_isPersistent");
00054 if( !flagMember ){
00055 throwException("Data member \"m_isPersistent\" not found in class \""+m_objectType.Name()+"\".",
00056 "NamedReferenceStreamerBase::buildDataElement");
00057 }
00058 m_flagDataElement = &dataElement.addChild( flagMember.Offset(), 0 );
00059
00060 const std::vector<std::string>& columns = m_mapping.columnNames();
00061 if( columns.size()==0 ){
00062 throwException("No columns found in the mapping element",
00063 "NamedReferenceStreamerBase::buildDataElement");
00064 }
00065 m_columnIndex = relationalData.addData( columns[0], typeid(std::string) );
00066 m_relationalData = &relationalData;
00067 return true;
00068 }
00069
00070 void ora::NamedReferenceStreamerBase::bindDataForUpdate( const void* data ){
00071 if(!m_relationalData){
00072 throwException("The streamer has not been built.",
00073 "NamedReferenceStreamerBase::bindDataForUpdate");
00074 }
00075
00076 void* refNameAddress = m_refNameDataElement->address( data );
00077 coral::Attribute& refNameAttr = m_relationalData->data()[ m_columnIndex ];
00078 std::string name = *static_cast<std::string*>(refNameAddress);
00079 if( name.empty() ) name = namedRefNullLabel();
00080 refNameAttr.data<std::string>()= name;
00081 }
00082
00083 void ora::NamedReferenceStreamerBase::bindDataForRead( void* data ){
00084 if(!m_relationalData){
00085 throwException("The streamer has not been built.",
00086 "NamedReferenceStreamerBase::bindDataForRead");
00087 }
00088 void* refNameAddress = m_refNameDataElement->address( data );
00089 void* ptrAddress = m_ptrDataElement->address( data );
00090 void* flagAddress = m_flagDataElement->address( data );
00091 coral::Attribute& refNameAttr = m_relationalData->data()[ m_columnIndex ];
00092 std::string name = refNameAttr.data<std::string>();
00093 if( name == namedRefNullLabel() ){
00094 name = std::string("");
00095 }
00096 if(!name.empty()){
00097 Reflex::Type namedRefType = m_objectType.TemplateArgumentAt(0);
00098 boost::shared_ptr<void> ptr = m_schema.dbSession().fetchTypedObjectByName( name, namedRefType );
00099 *static_cast<boost::shared_ptr<void>*>(ptrAddress) = ptr;
00100 *static_cast<bool*>(flagAddress) = true;
00101 }
00102 *static_cast<std::string*>(refNameAddress) = name;
00103 }
00104
00105 ora::NamedRefWriter::NamedRefWriter( const Reflex::Type& objectType,
00106 MappingElement& mapping,
00107 ContainerSchema& contSchema ):
00108 NamedReferenceStreamerBase( objectType, mapping, contSchema ){
00109 }
00110
00111 ora::NamedRefWriter::~NamedRefWriter(){
00112 }
00113
00114 bool ora::NamedRefWriter::build(DataElement& dataElement,
00115 IRelationalData& relationalData,
00116 RelationalBuffer& operationBuffer){
00117 return buildDataElement( dataElement, relationalData );
00118 }
00119
00120 void ora::NamedRefWriter::setRecordId( const std::vector<int>& identity ){
00121 }
00122
00124 void ora::NamedRefWriter::write( int oid,
00125 const void* data ){
00126 bindDataForUpdate( data );
00127 }
00128
00129 ora::NamedRefUpdater::NamedRefUpdater( const Reflex::Type& objectType,
00130 MappingElement& mapping,
00131 ContainerSchema& contSchema ):
00132 NamedReferenceStreamerBase( objectType, mapping, contSchema ){
00133 }
00134
00135 ora::NamedRefUpdater::~NamedRefUpdater(){
00136 }
00137
00138 bool ora::NamedRefUpdater::build(DataElement& dataElement,
00139 IRelationalData& relationalData,
00140 RelationalBuffer& operationBuffer){
00141 return buildDataElement( dataElement, relationalData );
00142 }
00143
00144 void ora::NamedRefUpdater::setRecordId( const std::vector<int>& identity ){
00145 }
00146
00148 void ora::NamedRefUpdater::update( int oid,
00149 const void* data ){
00150 bindDataForUpdate( data );
00151 }
00152
00153 ora::NamedRefReader::NamedRefReader( const Reflex::Type& objectType,
00154 MappingElement& mapping,
00155 ContainerSchema& contSchema ):
00156 NamedReferenceStreamerBase( objectType, mapping, contSchema ){
00157 }
00158
00159 ora::NamedRefReader::~NamedRefReader(){
00160 }
00161
00162 bool ora::NamedRefReader::build( DataElement& dataElement,
00163 IRelationalData& relationalData ){
00164 return buildDataElement( dataElement, relationalData );
00165 }
00166
00167 void ora::NamedRefReader::select( int oid ){
00168 }
00169
00170 void ora::NamedRefReader::setRecordId( const std::vector<int>& identity ){
00171 }
00172
00174 void ora::NamedRefReader::read( void* data ){
00175 bindDataForRead( data );
00176 }
00177
00178 void ora::NamedRefReader::clear(){
00179 }
00180
00181
00182 ora::NamedRefStreamer::NamedRefStreamer( const Reflex::Type& objectType,
00183 MappingElement& mapping,
00184 ContainerSchema& contSchema ):
00185 m_objectType( objectType ),
00186 m_mapping( mapping ),
00187 m_schema( contSchema ){
00188 }
00189
00190 ora::NamedRefStreamer::~NamedRefStreamer(){
00191 }
00192
00193 ora::IRelationalWriter* ora::NamedRefStreamer::newWriter(){
00194 return new NamedRefWriter( m_objectType, m_mapping, m_schema );
00195 }
00196
00197 ora::IRelationalUpdater* ora::NamedRefStreamer::newUpdater(){
00198 return new NamedRefUpdater( m_objectType, m_mapping, m_schema );
00199 }
00200
00201 ora::IRelationalReader* ora::NamedRefStreamer::newReader(){
00202 return new NamedRefReader( m_objectType, m_mapping, m_schema );
00203 }
00204