ATLAS Offline Software
RDBQuery.cxx
Go to the documentation of this file.
1 /*
2  Copyright (C) 2002-2024 CERN for the benefit of the ATLAS collaboration
3 */
4 
5 #include "RDBQuery.h"
6 #include "RDBAccessSvc.h"
7 #include <stdexcept>
8 
9 #include "RelationalAccess/ICursor.h"
10 #include "RelationalAccess/IQuery.h"
11 #include "RelationalAccess/ISessionProxy.h"
12 #include "RelationalAccess/ISchema.h"
13 #include "RelationalAccess/ITable.h"
14 #include "RelationalAccess/ITableDescription.h"
15 #include "RelationalAccess/IColumn.h"
16 
17 #include "RelationalAccess/SchemaException.h"
18 #include "CoralBase/Exception.h"
19 #include "CoralBase/AttributeList.h"
20 #include "CoralBase/Attribute.h"
21 
23 
25  , RDBAccessSvc* accessSvc
26  , const std::string& nodeName
27  , const std::string& tagId
28  , const std::string& connName)
29  : IRDBQuery()
30  , m_dblock (dblock)
31  , m_query(nullptr)
32  , m_queryCount(nullptr)
33  , m_accessSvc(accessSvc)
34  , m_nodeName(nodeName)
35  , m_tagId(tagId)
36  , m_connName(connName)
37  , m_size(0)
38  , m_cursor(nullptr)
39  , m_executed(false)
40 {
41 }
42 
44 {
45  delete m_query;
46  delete m_queryCount;
47 }
48 
50 {
51  if(m_executed) {
52  m_accessSvc->msg() << MSG::WARNING << "RDBQuery cannot be executed more than once! Query: "
53  << m_nodeName << ", "
54  << m_tagId << ", "
55  << m_orderField << ", "
56  << m_fields.size() << endmsg;
57  return;
58  }
59 
60  if(m_accessSvc->msg().level() <= MSG::DEBUG) {
61  m_accessSvc->msg() << MSG::DEBUG << "Query execute " << m_nodeName << ", "
62  << m_tagId << ", "
63  << m_orderField << ", "
64  << m_fields.size() << endmsg;
65  }
66 
68  m_accessSvc->msg() << MSG::ERROR << "Cannot connect to the database: "
69  << m_connName << endmsg;
70  throw std::runtime_error( "Cannot connect to the database " + m_connName);
71  }
72 
73  m_executed=true;
74  try {
75  // ... Get the node name and change to to Upper Case
76  std::string upperName = m_nodeName;
77  for (char& ch : upperName) {
78  ch = std::toupper (static_cast<unsigned int>(ch));
79  }
80 
81  // ... Create query objects
82  m_query = m_accessSvc->getSession(m_connName)->nominalSchema().newQuery();
83  m_queryCount = m_accessSvc->getSession(m_connName)->nominalSchema().newQuery();
84 
85  // Add fields
86  if(m_fields.size()>0) {
87  // Custom fields
88  for(unsigned int i=0; i<m_fields.size(); ++i) {
89  m_query->addToOutputList(upperName+"_DATA."+m_fields[i]);
90  }
91  }
92  else {
93  // All fields from the table
94  const coral::ITableDescription& dataTableDesc = m_accessSvc->getSession(m_connName)->nominalSchema().tableHandle(upperName + "_DATA").description();
95  for(int i=0; i<dataTableDesc.numberOfColumns(); ++i) {
96  m_query->addToOutputList(upperName+"_DATA."+dataTableDesc.columnDescription(i).name());
97  }
98  }
99 
100  m_queryCount->addToOutputList("COUNT("+upperName+"_DATA_ID)","SUMREC");
101 
102  // ... Define table list
103  m_query->addToTableList(upperName + "_DATA");
104  m_query->addToTableList(upperName + "_DATA2TAG");
105 
106  m_queryCount->addToTableList(upperName + "_DATA2TAG");
107 
108  // ... Define order
109  if(m_orderField.empty()) {
110  m_query->addToOrderList(upperName + "_DATA." + upperName + "_DATA_ID");
111  }
112  else {
113  m_query->addToOrderList(upperName + "_DATA." + m_orderField);
114  }
115 
116  // ... Define conditions
118  bindsData.extend<std::string>("tagID");
119 
120  std::string queryStructCondition = upperName +"_DATA2TAG." + upperName + "_TAG_ID =:tagID";
121  m_queryCount->setCondition(queryStructCondition , bindsData);
122 
123  queryStructCondition += " AND " + upperName +"_DATA." + upperName + "_DATA_ID=" + upperName + "_DATA2TAG." + upperName + "_DATA_ID";
124  m_query->setCondition(queryStructCondition , bindsData);
125 
126  bindsData[0].data<std::string>() = m_tagId;
127 
128  m_queryCount->defineOutputType("SUMREC","long");
129  m_query->setMemoryCacheSize(1);
130 
131  // ... Get size of the result set
132  coral::ICursor& cursorCount = m_queryCount->execute();
133  while(cursorCount.next()) {
134  // Just one iteration
135  m_size = cursorCount.currentRow()["SUMREC"].data<long>();
136  }
137 
138  // ... Get the data cursor
139  m_cursor = &(m_query->execute());
140  return;
141  }
142  catch(coral::SchemaException& se) {
143  m_accessSvc->msg() << MSG::WARNING << "QUERY: Schema Exception : " + std::string(se.what()) << endmsg;
144  }
145  catch(std::exception& e) {
146  m_accessSvc->msg() << MSG::WARNING << "QUERY: Exception : " + std::string(e.what()) << endmsg;
147  }
148  catch(...) {
149  m_accessSvc->msg() << MSG::WARNING << "QUERY: Exception caught... " << endmsg;
150  }
151 
152  m_size = 0; // This indicates that there was a problem with query execution
153 }
154 
156 {
157  return m_size;
158 }
159 
161 {
162  if(m_cursor) m_cursor->close();
164 }
165 
166 void RDBQuery::setOrder(const std::string& field)
167 {
169 }
170 
171 void RDBQuery::addToOutput(const std::string& field)
172 {
173  m_fields.push_back(field);
174 }
175 
177 {
178  if(m_cursor->next()) {
179  m_attrList = &(m_cursor->currentRow());
180  return true;
181  }
182  else {
183  m_attrList = 0;
184  return false;
185  }
186 }
AllowedVariables::e
e
Definition: AsgElectronSelectorTool.cxx:37
RDBQuery::m_orderField
std::string m_orderField
Definition: RDBQuery.h:61
sendEI_SPB.ch
ch
Definition: sendEI_SPB.py:35
RDBQuery::~RDBQuery
virtual ~RDBQuery() override
Definition: RDBQuery.cxx:43
RDBQuery::m_tagId
std::string m_tagId
Definition: RDBQuery.h:56
RDBAccessSvc.h
Definition of RDBAccessSvc class.
RDBAccessSvc::getSession
coral::ISessionProxy * getSession(const std::string &connName="ATLASDD")
Definition: RDBAccessSvc.cxx:495
RDBQuery::addToOutput
virtual void addToOutput(const std::string &) override
Definition: RDBQuery.cxx:171
RDBQuery::m_size
long m_size
Definition: RDBQuery.h:58
RDBAccessSvc::connect
bool connect(const std::string &connName) override
Connect to the relational DB.
Definition: RDBAccessSvc.cxx:41
RDBQuery::m_fields
std::vector< std::string > m_fields
Definition: RDBQuery.h:59
IRDBQuery::m_attrList
const coral::AttributeList * m_attrList
Definition: IRDBQuery.h:32
ReadOfcFromCool.field
field
Definition: ReadOfcFromCool.py:48
python.PyKernel.AttributeList
AttributeList
Definition: PyKernel.py:36
keylayer_zslicemap.se
se
Definition: keylayer_zslicemap.py:194
RDBQuery::m_executed
bool m_executed
Definition: RDBQuery.h:62
RDBQuery::next
virtual bool next() override
Definition: RDBQuery.cxx:176
RDBQuery::m_connName
std::string m_connName
Definition: RDBQuery.h:57
RDBQuery::RDBQuery
RDBQuery()=delete
RDBQuery::m_accessSvc
RDBAccessSvc * m_accessSvc
Definition: RDBQuery.h:54
RDBAccessSvc
RDBAccessSvc is the implementation of IRDBAccessSvc interface.
Definition: RDBAccessSvc.h:58
lumiFormat.i
int i
Definition: lumiFormat.py:85
Athena::DBLock
Common database lock.
Definition: DBLock.h:46
endmsg
#define endmsg
Definition: AnalysisConfig_Ntuple.cxx:63
IRDBQuery
Definition: IRDBQuery.h:13
calibdata.exception
exception
Definition: calibdata.py:496
RDBQuery::m_nodeName
std::string m_nodeName
Definition: RDBQuery.h:55
RDBQuery::finalize
virtual void finalize() override
Definition: RDBQuery.cxx:160
RDBQuery::size
virtual long size() override
Definition: RDBQuery.cxx:155
RDBQuery.h
RDBQuery::m_cursor
coral::ICursor * m_cursor
Definition: RDBQuery.h:60
RDBQuery::m_queryCount
coral::IQuery * m_queryCount
Definition: RDBQuery.h:53
DEBUG
#define DEBUG
Definition: page_access.h:11
RDBQuery::execute
virtual void execute() override
Definition: RDBQuery.cxx:49
ATLAS_THREAD_SAFE
#define ATLAS_THREAD_SAFE
Definition: checker_macros.h:211
RDBQuery::setOrder
virtual void setOrder(const std::string &) override
Definition: RDBQuery.cxx:166
checker_macros.h
Define macros for attributes used to control the static checker.
RDBAccessSvc::disconnect
bool disconnect(const std::string &connName) override
If the counnection counter==1 closes the connection.
Definition: RDBAccessSvc.cxx:81
RDBQuery::m_query
coral::IQuery * m_query
Definition: RDBQuery.h:52