ATLAS Offline Software
SqliteRecordset.cxx
Go to the documentation of this file.
1 /*
2  Copyright (C) 2002-2024 CERN for the benefit of the ATLAS collaboration
3 */
4 
12 #include "SqliteRecordset.h"
13 
14 #include <sqlite3.h>
15 #include <stdexcept>
16 #include <sstream>
17 #include <set>
18 
20  : AthMessaging("SqliteRecordset")
21  , m_def(std::make_shared<SqliteInpDef>())
22 {
23 }
24 
25 void SqliteRecordset::getData(sqlite3* db, const std::string& nodeName)
26 {
27  ATH_MSG_DEBUG("getData for " << nodeName);
29 
30  std::ostringstream sql;
31 
32  // First check if the table exists in the database
33  sql << "select * from " << m_nodeName;
34  sqlite3_stmt* stTable{nullptr};
35  int rc = sqlite3_prepare_v2(db, sql.str().c_str(), -1, &stTable, NULL);
36  if(rc!=SQLITE_OK) {
37  ATH_MSG_INFO(m_nodeName << " table is not found in the database");
38  return;
39  }
40 
41  sql << " order by " << m_nodeName << "_data_id";
42  sqlite3_stmt* st{nullptr};
43  rc = sqlite3_prepare_v2(db, sql.str().c_str(), -1, &st, NULL);
44  if(rc!=SQLITE_OK) {
45  ATH_MSG_ERROR("Error occurred when preparing to fetch data for " << m_nodeName);
46  ATH_MSG_ERROR("SQLite Error: " << sqlite3_errmsg(db));
47  return;
48  }
49  int ctotal = sqlite3_column_count(st);
50 
51  bool all_ok{true};
52 
53  while(true) {
54  rc = sqlite3_step(st);
55 
56  if(rc == SQLITE_ROW) {
57  SqliteRecord* rec = new SqliteRecord(m_def);
58  IRDBRecord_ptr record{rec};
59 
60  // Loop throug the fields of the retrieved record
61  for(int i=0; i<ctotal; ++i) {
62 
63  // The feature of SQLite: if in the given record some fields have NULL values,
64  // then the data type of the corresponding columns is reported as NULL.
65  // This means that we need to be able to build the Def gradually, as we read
66  // in new records of the table
67 
68  // Do we need to extend Def?
69  std::string columnName = sqlite3_column_name(st,i);
70  bool extendDef = (m_def->find(columnName)==m_def->end());
71 
72  auto columnType = sqlite3_column_type(st,i);
74  SqliteInp val;
75 
76  switch(columnType) {
77  case SQLITE_INTEGER:
78  inpType = SQLITEINP_INT;
79  val = sqlite3_column_int(st,i);
80  break;
81  case SQLITE_FLOAT:
82  inpType = SQLITEINP_DOUBLE;
83  val = sqlite3_column_double(st,i);
84  break;
85  case SQLITE_TEXT:
86  inpType = SQLITEINP_STRING;
87  val = std::string((char*)(sqlite3_column_text(st,i)));
88  break;
89  case SQLITE_BLOB:
90  inpType = SQLITEINP_STRING;
91  val = std::string((char*)(sqlite3_column_blob(st,i)));
92  break;
93  case SQLITE_NULL:
94  continue;
95  default:
96  break;
97  }
98 
99  if(inpType==SQLITEINP_UNDEF) {
100  all_ok = false;
101  ATH_MSG_ERROR("Unexpected data type in column " << columnName << " of the table " << m_nodeName);
102  break;
103  }
104 
105  if(extendDef) {
106  (*m_def)[columnName] = inpType;
107  }
108  rec->addValue(columnName,val);
109  }
110  m_records.push_back(std::move(record));
111  }
112  else if(rc == SQLITE_DONE) {
113  break;
114  }
115  else {
116  ATH_MSG_ERROR("Error occurred when fetching data for " << m_nodeName);
117  ATH_MSG_ERROR("SQLite Error: " << sqlite3_errmsg(db));
118  all_ok = false;
119  break;
120  }
121  }
122 
123  if(!all_ok) {
124  // Do memory cleanup
125  m_records.clear();
126  }
127 }
128 
129 unsigned int SqliteRecordset::size() const
130 {
131  return m_records.size();
132 }
133 
134 std::string SqliteRecordset::nodeName() const
135 {
136  return m_nodeName;
137 }
138 
139 const IRDBRecord* SqliteRecordset::operator[](unsigned int index) const
140 {
141  return m_records[index].get();
142 }
144 {
145  return m_records.begin();
146 }
147 
149 {
150  return m_records.end();
151 }
SqliteInp
std::variant< int, long, float, double, std::string > SqliteInp
Definition: SqliteRecord.h:37
SqliteRecordset.h
Declaration of the SqliteRecordset class.
ATH_MSG_INFO
#define ATH_MSG_INFO(x)
Definition: AthMsgStreamMacros.h:31
index
Definition: index.py:1
CaloCondBlobAlgs_fillNoiseFromASCII.db
db
Definition: CaloCondBlobAlgs_fillNoiseFromASCII.py:43
SqliteRecordset::m_records
RecordsVector m_records
Definition: SqliteRecordset.h:62
SqliteRecordset::getData
void getData(sqlite3 *db, const std::string &nodeName)
Constructs SQL query and retrieves data from the DB.
Definition: SqliteRecordset.cxx:25
SqliteRecordset::m_nodeName
std::string m_nodeName
Definition: SqliteRecordset.h:60
SQLITEINP_UNDEF
@ SQLITEINP_UNDEF
Definition: SqliteRecord.h:30
SQLITEINP_INT
@ SQLITEINP_INT
Definition: SqliteRecord.h:25
SqliteInpDef
std::map< std::string, SqliteInpType > SqliteInpDef
Definition: SqliteRecord.h:39
SqliteRecordset::nodeName
std::string nodeName() const override
Definition: SqliteRecordset.cxx:134
beamspotman.sql
sql
Definition: beamspotman.py:674
SqliteRecordset::begin
IRDBRecordset::const_iterator begin() const override
Definition: SqliteRecordset.cxx:143
ATH_MSG_ERROR
#define ATH_MSG_ERROR(x)
Definition: AthMsgStreamMacros.h:33
lumiFormat.i
int i
Definition: lumiFormat.py:92
SQLITEINP_DOUBLE
@ SQLITEINP_DOUBLE
Definition: SqliteRecord.h:28
ATH_MSG_DEBUG
#define ATH_MSG_DEBUG(x)
Definition: AthMsgStreamMacros.h:29
SQLITEINP_STRING
@ SQLITEINP_STRING
Definition: SqliteRecord.h:29
SqliteRecord::addValue
void addValue(const std::string &field, SqliteInp value)
Definition: SqliteRecord.cxx:102
AthMessaging
Class to provide easy MsgStream access and capabilities.
Definition: AthMessaging.h:55
SqliteRecordset::end
IRDBRecordset::const_iterator end() const override
Definition: SqliteRecordset.cxx:148
SqliteRecord
SqliteRecord is one record in the SqliteRecordset object.
Definition: SqliteRecord.h:49
SqliteInpType
SqliteInpType
Definition: SqliteRecord.h:24
DeMoScan.index
string index
Definition: DeMoScan.py:362
Pythia8_RapidityOrderMPI.val
val
Definition: Pythia8_RapidityOrderMPI.py:14
IRDBRecord
IRDBRecord is one record in the IRDBRecordset object.
Definition: IRDBRecord.h:27
SqliteRecordset::m_def
SqliteInpDef_ptr m_def
Definition: SqliteRecordset.h:61
IRDBRecord_ptr
std::unique_ptr< IRDBRecord > IRDBRecord_ptr
Definition: IRDBRecordset.h:23
SqliteRecordset::size
unsigned int size() const override
Definition: SqliteRecordset.cxx:129
SqliteRecordset::operator[]
const IRDBRecord * operator[](unsigned int index) const override
Definition: SqliteRecordset.cxx:139
SqliteRecordset::SqliteRecordset
SqliteRecordset()
Construct empty recordset.
Definition: SqliteRecordset.cxx:19
IRDBRecordset::const_iterator
RecordsVector::const_iterator const_iterator
Definition: IRDBRecordset.h:52