ATLAS Offline Software
Loading...
Searching...
No Matches
RDBRecordset.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2024 CERN for the benefit of the ATLAS collaboration
3*/
4
14
15#include "RDBAccessSvc.h"
16#include "RDBRecordset.h"
17#include "RDBRecord.h"
18
19#include "RelationalAccess/ISessionProxy.h"
20#include "RelationalAccess/ICursor.h"
21#include "RelationalAccess/ITableDescription.h"
22#include "RelationalAccess/IQuery.h"
23#include "RelationalAccess/ISchema.h"
24#include "RelationalAccess/ITable.h"
25#include "RelationalAccess/IColumn.h"
26#include "RelationalAccess/SchemaException.h"
27
29
30#include "CoralBase/Attribute.h"
31#include "CoralBase/AttributeList.h"
32
33#include "GaudiKernel/MsgStream.h"
34
35#include <stdexcept>
36#include <iostream>
37#include <set>
38
39void RDBRecordset::getData(coral::ISessionProxy* session
40 , const std::string& nodeName
41 , const std::string& tagName
42 , const std::string& tagId)
43{
44 if(m_accessSvc->msg().level() <= MSG::DEBUG) {
45 m_accessSvc->msg() << MSG::DEBUG << "Recordset get data " << nodeName << ", "
46 << tagName << ", "
47 << tagId << endmsg;
48 }
49
50 if(session==0) {
51 m_accessSvc->msg() << MSG::ERROR << "RT: No connection to database!" << endmsg;
52 return;
53 }
54
55 try
56 {
58
59 if(tagId.empty()) {
60 if(m_accessSvc->msg().level() <= MSG::DEBUG)
61 m_accessSvc->msg() << MSG::DEBUG << "RT: Could not get the tag for " << m_tableName
62 << " node. Returning empty recordset" << endmsg;
63 return;
64 }
65
67
68 // change table name to upper case
69 std::string upperName = m_tableName;
70 for (char& ch : upperName) {
71 ch = std::toupper (static_cast<unsigned int>(ch));
72 }
73
74 coral::IQuery* queryStructure = session->nominalSchema().newQuery();
75
76 // Compose the list of output fields for queryStructure
77 const coral::ITableDescription& dataTableDesc = session->nominalSchema().tableHandle(upperName + "_DATA").description();
78 for(int i=0; i<dataTableDesc.numberOfColumns(); i++) {
79 queryStructure->addToOutputList(upperName + "_DATA." + dataTableDesc.columnDescription(i).name());
80 }
81
82 // Create table list for query >> data and data2vers tables
83 queryStructure->addToTableList(upperName + "_DATA");
84 queryStructure->addToTableList(upperName + "_DATA2TAG");
85
86 coral::AttributeList bindsData ATLAS_THREAD_SAFE;
87 bindsData.extend<std::string>("tagID");
88
89 // Compose condition for structure query
90 std::string queryStructCondition = upperName +"_DATA2TAG." + upperName + "_TAG_ID =:tagID";
91 queryStructCondition += " AND " + upperName +"_DATA." + upperName + "_DATA_ID=" + upperName + "_DATA2TAG." + upperName + "_DATA_ID";
92
93 queryStructure->setCondition(queryStructCondition , bindsData);
94 bindsData[0].data<std::string>() = tagId;
95
96 queryStructure->addToOrderList(upperName + "_DATA." + upperName + "_DATA_ID");
97 queryStructure->setMemoryCacheSize(1);
98
99 coral::ICursor& cursorStructure = queryStructure->execute();
100
101 // Process Query results
102 while(cursorStructure.next()) {
103 const coral::AttributeList& row = cursorStructure.currentRow();
104 m_records.push_back(IRDBRecord_ptr(new RDBRecord(row,upperName + "_DATA")));
105 }
106
107 delete queryStructure;
108 }
109 catch(coral::SchemaException& se) {
110 m_accessSvc->msg() << MSG::ERROR<< "RT: Schema Exception : " << se.what() << endmsg;
111 }
112 catch(std::exception& e) {
113 m_accessSvc->msg() << MSG::ERROR << e.what() << endmsg;
114 }
115 catch(...) {
116 m_accessSvc->msg() << MSG::ERROR << "RT: Exception caught(...)" << endmsg;
117 }
118
119}
120
121unsigned int RDBRecordset::size() const
122{
123 return m_records.size();
124}
125
126std::string RDBRecordset::nodeName() const
127{
128 return m_tableName;
129}
130
131std::string RDBRecordset::tagName() const
132{
133 return m_tagName;
134}
135
136const IRDBRecord* RDBRecordset::operator[](unsigned int index) const
137{
138 return m_records[index].get();
139}
141{
142 return m_records.begin();
143}
144
149
151{
152 if(m_records.size()!=rhs.m_records.size()) return true;
153
154 for(size_t i=0; i<m_records.size(); ++i) {
155 RDBRecord* rec1 = dynamic_cast<RDBRecord*>(m_records[i].get());
156 RDBRecord* rec2 = dynamic_cast<RDBRecord*>(rhs.m_records[i].get());
157 if(rec1!=0
158 && rec2!=0
159 && *rec1!=*rec2) return true;
160 }
161
162 return false;
163}
164
165void RDBRecordset::compare(const RDBRecordset& rec, std::ostream& os) const
166{
167 if(m_tableName!=rec.m_tableName) {
168 os << "Recordsets correspond to different nodes" << std::endl;
169 return;
170 }
171
172 if(m_tagName!=rec.m_tagName) {
173 os << "Recordsets correspond to different tags" << std::endl;
174 return;
175 }
176
177 std::set<size_t> uniq0, uniq1;
178 std::vector<long> dataId0, dataId1;
179
180 // change table name to upper case
181 std::string upperName = m_tableName;
182 for (char& ch : upperName) {
183 ch = std::toupper (static_cast<unsigned int>(ch));
184 }
185
186 // Collect data_id's for both recordsets
187 for(size_t i=0; i<m_records.size(); ++i) {
188 dataId0.push_back(m_records[i]->getLong(upperName+"_DATA_ID"));
189 }
190
191 for(size_t i=0; i<rec.m_records.size(); ++i) {
192 dataId1.push_back(rec.m_records[i]->getLong(upperName+"_DATA_ID"));
193 }
194
195 // print out possible diffs of recordsets with same data id's
196 // collect indices of records with data_id's unique to rec0 (this)
197 bool diffFound = false;
198 for(size_t i=0; i<dataId0.size(); ++i) {
199 long id0 = dataId0[i];
200 bool found = false;
201 size_t i1(0);
202 for(size_t ii=0; ii<dataId1.size(); ++ii) {
203 if(id0==dataId1[ii]) {
204 found = true;
205 i1 = ii;
206 break;
207 }
208 }
209 if(found) {
210 RDBRecord* record0 = dynamic_cast<RDBRecord*>(m_records[i].get());
211 RDBRecord* record1 = dynamic_cast<RDBRecord*>(rec.m_records[i1].get());
212 if(record0!=0
213 && record1!=0
214 && *record0!=*record1) {
215 if(!diffFound) {
216 os << "Records with the same data id and different contents:" << std::endl;
217 diffFound = true;
218 }
219 os << "< " << *record0 << std::endl;
220 os << "> " << *record1 << std::endl;
221 os << "--" << std::endl;
222 }
223 }
224 else
225 uniq0.insert(i);
226 }
227
228 // collect indices of records with data_id's unique to rec1
229 for(size_t i=0; i<dataId1.size(); ++i) {
230 long id1 = dataId1[i];
231 bool found = false;
232 for(size_t ii=0; ii<dataId0.size(); ++ii) {
233 if(id1==dataId0[ii]) {
234 found = true;
235 break;
236 }
237 }
238 if(!found) {
239 uniq1.insert(i);
240 }
241 }
242
243 // print out results
244 if(uniq0.size()>0) {
245 os << "Records with the following data ids are present in recordset 0 and missing in recordset 1: " << std::endl;
246 std::set<size_t>::const_iterator it = uniq0.begin();
247 for(; it!=uniq0.end(); ++it) {
248 os << m_records[*it]->getLong(upperName+"_DATA_ID") << " ";
249 }
250 os << std::endl;
251 }
252 if(uniq1.size()>0) {
253 os << "Records with the following data ids are present in recordset 1 and missing in recordset 0: " << std::endl;
254 std::set<size_t>::const_iterator it = uniq1.begin();
255 for(; it!=uniq1.end(); ++it) {
256 os << rec.m_records[*it]->getLong(upperName+"_DATA_ID") << " ";
257 }
258 os << std::endl;
259 }
260
261}
262
263void RDBRecordset::setNodeName(const std::string& nodeName)
264{
265 if(m_tableName.empty()) m_tableName = nodeName;
266}
#define endmsg
std::unique_ptr< IRDBRecord > IRDBRecord_ptr
Definition of RDBAccessSvc class.
Definition of RDBRecord class.
Definition of RDBRecordset class.
Define macros for attributes used to control the static checker.
#define ATLAS_THREAD_SAFE
IRDBRecord is one record in the IRDBRecordset object.
Definition IRDBRecord.h:27
RecordsVector::const_iterator const_iterator
RDBRecord is one record in the RDBRecordset object.
Definition RDBRecord.h:35
std::string nodeName() const override
IRDBRecordset::const_iterator end() const override
IRDBRecordset::const_iterator begin() const override
void compare(const RDBRecordset &rec, std::ostream &os) const
bool operator!=(const RDBRecordset &rhs) const
void setNodeName(const std::string &nodeName)
std::string m_tableName
std::string m_tagName
unsigned int size() const override
std::string tagName() const override
const IRDBRecord * operator[](unsigned int index) const override
RDBRecordset(RDBAccessSvc *accessSvc)
Construct empty recordset.
RecordsVector m_records
RDBAccessSvc * m_accessSvc
void getData(coral::ISessionProxy *session, const std::string &nodeName, const std::string &tagName, const std::string &tagId)
Constructs SQL query and retrieves the data from DB.
Definition index.py:1