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