Analysis Software
Documentation for sPHENIX simulation software
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
PktSizeDBodbc.cc
Go to the documentation of this file. Or view the newest version in sPHENIX GitHub for file PktSizeDBodbc.cc
1 #include "PktSizeDBodbc.h"
2 
3 #include <phool/phool.h>
4 
5 #include <odbc++/connection.h>
6 #include <odbc++/drivermanager.h>
7 #include <odbc++/errorhandler.h>
8 #include <odbc++/resultset.h>
10 #include <odbc++/setup.h>
11 #include <odbc++/types.h>
12 #include <sql.h>
13 #include <iostream>
14 
15 #include <algorithm>
16 #include <cctype>
17 #include <ctime>
18 #include <fstream>
19 #include <set>
20 #include <sstream>
21 
22 static odbc::Connection* con = nullptr;
23 
25  : OnlMonBase(name)
26  , tableprefix(name)
27 {
28 }
29 
31 {
32  delete con;
33  con = nullptr;
34 }
35 
36 int PktSizeDBodbc::CheckAndCreateTable(const std::string& name, const std::map<unsigned int, unsigned int>& packetsize)
37 {
38  if (GetConnection())
39  {
40  return -1;
41  }
42 
43  // Postgres version
44  // std::cout << con->getMetaData()-> getDatabaseProductVersion() << std::endl;
45  odbc::Statement* stmt = con->createStatement();
46  std::ostringstream cmd;
47  // cmd << "SELECT COUNT(*) FROM " << name << " WHERE 1 = 2" ;
48  // cmd << "select " << name << " from pg_tables where schemaname='public";
49  std::string lowname = name;
50  // The bizarre cast here is needed for newer gccs
51  transform(lowname.begin(), lowname.end(), lowname.begin(), (int (*)(int)) tolower);
52  cmd << "select * from pg_tables where tablename = '" << lowname << "'";
53  // cmd << "SELECT * FROM " << name << " LIMIT 1" ;
54  if (verbosity > 0)
55  {
56  std::cout << "cmd: " << cmd.str() << std::endl;
57  }
58 
59  odbc::ResultSet* rs = nullptr;
60  try
61  {
62  rs = stmt->executeQuery(cmd.str());
63  }
64  catch (odbc::SQLException& e)
65  {
66  std::cout << name << " does not exist, creating it" << std::endl;
67  }
68  int iret = 0;
69 
70  cmd.str("");
71  if (!rs->next())
72  {
73  delete rs;
74  rs = nullptr;
75  cmd << "CREATE TABLE " << name << "(runnumber int NOT NULL, events int NOT NULL";
76  std::map<unsigned int, unsigned int>::const_iterator iter;
77  for (iter = packetsize.begin(); iter != packetsize.end(); ++iter)
78  {
79  cmd << ", p_" << iter->first << " float DEFAULT 0";
80  }
81  cmd << ", primary key(runnumber))";
82  if (verbosity > 0)
83  {
84  std::cout << "Executing " << cmd.str() << std::endl;
85  }
86  try
87  {
88  iret = stmt->executeUpdate(cmd.str());
89  }
90  catch (odbc::SQLException& e)
91  {
92  std::cout << "Exception caught, Message: " << e.getMessage() << std::endl;
93  }
94  }
95  delete stmt;
96  return iret;
97 }
98 
99 int PktSizeDBodbc::AddRow(const std::string& granulename, const int runnumber, const int nevnts, const std::map<unsigned int, unsigned int>& packetsize)
100 {
101  std::string table = tableprefix + granulename;
102 
103  CheckAndCreateTable(table, packetsize);
104 
105  int iret = 0;
106  std::ostringstream cmd;
107 
108  if (GetConnection())
109  {
110  return -1;
111  }
112 
113  odbc::Statement* stmt = con->createStatement();
114 
115  // check if an entry for this run exists already
116  cmd << "SELECT events FROM " << table << " where runnumber = "
117  << runnumber;
118  odbc::ResultSet* rs;
119  try
120  {
121  rs = stmt->executeQuery(cmd.str());
122  }
123  catch (odbc::SQLException& e)
124  {
125  std::cout << "Exception caught, Message: " << e.getMessage() << std::endl;
126  return -1;
127  }
128  if (rs->next())
129  {
130  int events = rs->getInt("events");
131  if (nevnts <= events)
132  {
133  std::cout << "Run " << runnumber << " already in table "
134  << table << " extracted from " << events << " Events"
135  << std::endl;
136  std::cout << "Run more events than " << events
137  << " if you want to overwrite this entry" << std::endl;
138  delete rs;
139  return 0;
140  }
141  else
142  {
143  cmd.str("");
144  cmd << "DELETE FROM " << table << " WHERE runnumber = " << runnumber;
145  odbc::Statement* stmt2 = con->createStatement();
146  stmt2->executeUpdate(cmd.str());
147  }
148  }
149  delete rs;
150  // update columns in table in case there is a new packet
151  CheckAndAddColumns(table, packetsize);
152 
153  // now add the content
154  std::map<unsigned int, unsigned int>::const_iterator iter;
155  cmd.str("");
156  std::ostringstream cmd1, cmd2;
157  cmd1 << "INSERT INTO " << table
158  << " (runnumber, events";
159  cmd2 << " VALUES(" << runnumber << ", " << nevnts;
160  float size_in_bytes;
161  for (iter = packetsize.begin(); iter != packetsize.end(); ++iter)
162  {
163  cmd1 << ", p_" << iter->first;
164  size_in_bytes = (float) (iter->second) / (float) (nevnts);
165  size_in_bytes *= 4; // convert from 32 bit words to bytes
166  cmd2 << ", " << size_in_bytes;
167  }
168  cmd1 << ")";
169  cmd2 << ")";
170  cmd << cmd1.str() << cmd2.str();
171  try
172  {
173  stmt->executeUpdate(cmd.str());
174  }
175  catch (odbc::SQLException& e)
176  {
177  std::cout << "Exception caught, Message: " << e.getMessage() << std::endl;
178  }
179 
180  return iret;
181 }
182 
183 int PktSizeDBodbc::GetPacketContent(std::map<unsigned int, float>& packetsize, const int runnumber, const std::string& granulename)
184 {
185  if (GetConnection())
186  {
187  return -1;
188  }
189  int iret = 0;
190  std::string table = tableprefix + granulename;
191 
192  odbc::Statement* query = con->createStatement();
193  std::ostringstream cmd;
194  cmd << "SELECT * FROM " << table << " WHERE runnumber = " << runnumber;
195 
196  if (verbosity > 0)
197  {
198  std::cout << "command: " << cmd.str() << std::endl;
199  }
200 
201  odbc::ResultSet* rs;
202  try
203  {
204  rs = query->executeQuery(cmd.str());
205  }
206  catch (odbc::SQLException& e)
207  {
208  const std::string& errmsg = e.getMessage();
209  if (errmsg.find("does not exist") == std::string::npos)
210  {
211  std::cout << "Exception caught, when accessing table "
212  << table << std::endl;
213  std::cout << "Message: " << e.getMessage() << std::endl;
214  }
215  return -1;
216  }
217  if (rs->next())
218  {
219  for (int i = 1; i <= rs->getMetaData()->getColumnCount(); i++)
220  {
221  std::string colname = rs->getMetaData()->getColumnName(i);
222  if (colname == "runnumber" || colname == "events")
223  {
224  continue;
225  }
226  std::string packet = colname.substr(colname.find_last_of('_') + 1);
227  std::istringstream istr(packet);
228  unsigned int ipkt;
229  istr >> ipkt;
230  float size = rs->getFloat(colname);
231  if (rs->wasNull() || size <= 1.)
232  {
233  continue;
234  }
235  packetsize[ipkt] = size / 4.; // convert from bytes to long words
236  }
237  delete rs;
238  }
239  return iret;
240 }
241 
243 {
244  if (con)
245  {
246  return 0;
247  }
248  try
249  {
250  con = odbc::DriverManager::getConnection(dbname.c_str(), dbowner.c_str(), dbpasswd.c_str());
251  }
252  catch (odbc::SQLException& e)
253  {
254  std::cout << PHWHERE
255  << " Exception caught during DriverManager::getConnection" << std::endl;
256  std::cout << "Message: " << e.getMessage() << std::endl;
257  if (con)
258  {
259  delete con;
260  con = nullptr;
261  }
262  return -1;
263  }
264  printf("opened DB connection\n");
265  return 0;
266 }
267 
268 int PktSizeDBodbc::CheckAndAddColumns(const std::string& table, const std::map<unsigned int, unsigned int>& packetsize)
269 {
270  if (GetConnection())
271  {
272  return -1;
273  }
274  odbc::Statement* stmt = con->createStatement();
275  std::ostringstream cmd;
276  cmd << "SELECT * FROM " << table << " limit 1 ";
277  odbc::ResultSet* rs;
278  try
279  {
280  rs = stmt->executeQuery(cmd.str());
281  }
282  catch (odbc::SQLException& e)
283  {
284  std::cout << "Exception caught, Message: " << e.getMessage() << std::endl;
285  return -1;
286  }
287  std::map<unsigned int, unsigned int>::const_iterator iter;
288  std::set<unsigned int> packetids;
289  for (iter = packetsize.begin(); iter != packetsize.end(); ++iter)
290  {
291  packetids.insert(iter->first);
292  }
293  for (int i = 1; i <= rs->getMetaData()->getColumnCount(); i++)
294  {
295  std::string colname = rs->getMetaData()->getColumnName(i);
296  if (colname == "runnumber" || colname == "events")
297  {
298  continue;
299  }
300  std::string packet = colname.substr(colname.find_last_of('_') + 1);
301  std::istringstream istr(packet);
302  unsigned int ipkt;
303  istr >> ipkt;
304  packetids.erase(ipkt);
305  }
306  delete rs;
307  std::set<unsigned int>::const_iterator siter;
308  for (siter = packetids.begin(); siter != packetids.end(); ++siter)
309  {
310  std::ostringstream newcol;
311  newcol.str("");
312  newcol << "p_" << *siter;
313  cmd.str("");
314  cmd << "ALTER TABLE " << table << " ADD COLUMN " << newcol.str()
315  << " float DEFAULT 0";
316  try
317  {
318  stmt->executeUpdate(cmd.str());
319  }
320  catch (odbc::SQLException& e)
321  {
322  std::cout << "Exception caught, Message: " << e.getMessage() << std::endl;
323  }
324  }
325  return 0;
326 }