TkN 2.4
Toolkit for Nuclei
Loading...
Searching...
No Matches
tkdb_table.cpp
1/********************************************************************************
2 * Copyright (c) : Université de Lyon 1, CNRS/IN2P3, UMR5822, *
3 * IP2I, F-69622 Villeurbanne Cedex, France *
4 * Normandie Université, ENSICAEN, UNICAEN, CNRS/IN2P3, *
5 * LPC Caen, F-14000 Caen, France *
6 * Contibutor(s) : *
7 * Jérémie Dudouet jeremie.dudouet@cnrs.fr [2020] *
8 * Diego Gruyer diego.gruyer@cnrs.fr [2020] *
9 * *
10 * Licensed under the MIT License <http://opensource.org/licenses/MIT>. *
11 * SPDX-License-Identifier: MIT *
12 ********************************************************************************/
13
14#include "tkdb_table.h"
15#include "tklog.h"
16
17namespace tkn {
25}
26
27using namespace tkn;
28
29tkdb_table::tkdb_table(const char *_name, sqlite3 *_db) :
30 fName(_name),
31 fDataBase(_db)
32{
33 glog.set_class("db_table");
34 // load();
35}
36
37tkdb_table::~tkdb_table() = default;
38
40{
41 glog.set_method(tkstring::Form("get_column_list(%s)",fName.data()));
42
43 sqlite3_stmt* stmt;
44 int rc = sqlite3_prepare_v2(fDataBase, tkstring::form("PRAGMA table_info('%s');",fName.data()), -1, &stmt, nullptr);
45 if( rc!=SQLITE_OK ){
46 glog << error_v << "SQL error: " << sqlite3_errmsg(fDataBase) << " while loading table '" << fName.data() << "'" << do_endl;
47 sqlite3_free(nullptr);
48 }
49
50 while((sqlite3_step(stmt)) == SQLITE_ROW) {
51 tkstring name = sqlite3_column_text(stmt, 1);
52 tkstring type = sqlite3_column_text(stmt, 2);
53 add_column(name.data(),type.data());
54 }
55
56 sqlite3_finalize(stmt);
57}
58
59void tkdb_table::print(const tkstring &_opt)
60{
61 glog << info << blue << tkstring::form("Table '%s'",fName.data()) << do_endl;
62 print_columns(_opt);
63}
64
66{
67// glog.set_method(tkstring::Form("print_columns(%s)",fName.data()));
68
69 if(_opt.contains("verbose")) glog << info << yellow << tkstring::form("[%3d] columns in '%s' table",fColumns.size(),fName.data()) << do_endl;
70 int ii = 0;
71 for(auto &column : fColumns) {
72 if(_opt.contains("notnull")&&column.second.is_empty()) continue;
73 if(column.first.contains(_opt)) glog << info << tkstring::form("[%3d] %20s %6s %s",ii++,column.second.get_name(),column.second.get_type(),column.second.get_value().data()) << do_endl;
74 }
75}
76
77void tkdb_table::print_rows(const char *_selection, const char* _properties)
78{
79 tkstring sel = _selection;
80 tkstring pro = _properties;
81
82 std::vector<tkstring> colnames;
83
84 if(pro.equal_to("*")) colnames = fOrderedColumnNames;
85 else colnames= pro.tokenize(",");
86
87 for(auto col : colnames) glog << tkstring::form("%20s",fColumns[col.data()].get_name());
88 glog << do_endl;
89
90 begin(sel,_properties);
91 while(next())
92 {
93 for(auto col : colnames) glog << tkstring::form("%20s",fColumns[col.data()].get_value().data());
94 glog << do_endl;
95 }
96}
97
98void tkdb_table::begin(tkstring _condition, tkstring _selection)
99{
100 if(fReading)
101 {
102 glog << warning << "Previous sql statement not yet closed. Closing in to start new statement..." << do_endl;
103 end();
104 }
105
106 tkstring cmd = tkstring::form("select %s from %s where %s",_selection.data(),fName.data(),_condition.data());
107
108 int rc = sqlite3_prepare_v2(fDataBase, cmd.data(), -1, &fSQL_stmt, nullptr);
109 if( rc!=SQLITE_OK ){
110 glog << error << "SQL error: " << sqlite3_errmsg(fDataBase) << "while executing cmd : " << cmd.data() << do_endl;
112 sqlite3_free(nullptr);
113 }
114 else fReading = true;
115}
116
118{
119 if(!fReading) {
120 glog << error << "No sql statement prepared, please call begin() to prepare it " << do_endl;
121 return false;
122 }
123
124 int ret_code = sqlite3_step(fSQL_stmt);
125 if(ret_code== SQLITE_ROW) {
126 int cols = sqlite3_column_count(fSQL_stmt);
127 for (int i=0; i<cols; i++) {
128 const unsigned char* tmp = sqlite3_column_text(fSQL_stmt, i);
129 if(tmp == nullptr)
130 fColumns[sqlite3_column_name(fSQL_stmt, i)].set_value("");
131 else
132 fColumns[sqlite3_column_name(fSQL_stmt, i)].set_value(sqlite3_column_text(fSQL_stmt, i));
133 }
134 return true;
135 }
136 end();
137 return false;
138}
139
141{
142 if(!fReading) {glog << error << "No sql statement prepared to close..." << do_endl; return;}
143 sqlite3_finalize(fSQL_stmt);
144 fReading = false;
146}
147
148//tkstring db_table::get_value(const char *_property, const char *_selection)
149//{
150// tkstring sel = _selection;
151// glog.set_class("db_table");
152// glog.set_method(tkstring::Form("get_value('%s',%s)",_property,sel.data()));
153
154// sqlite3_stmt* stmt;
155// int rc = sqlite3_prepare_v2(fDataBase, tkstring::form("select %s from %s where %s",_property,fName.data(),sel.data()), -1, &stmt, 0);
156// if( rc!=SQLITE_OK ){
157// glog << error_v << "SQL error: " << sqlite3_errmsg(fDataBase) << do_endl;
158// print_columns();
159// sqlite3_free(0);
160// }
161
162// tkstring value = "";
163// int ret_code = 0;
164// while((ret_code = sqlite3_step(stmt)) == SQLITE_ROW) {
165// value = reinterpret_cast< const char* >(sqlite3_column_text(stmt, 0));
166// break;
167// }
168// sqlite3_finalize(stmt);
169// return value;
170//}
171
172void tkdb_table::add_column(const char *_colname, const char *_coltype)
173{
174 tkdb_column col(_colname,_coltype);
175 tkstring col_name(_colname);
176 fColumns.insert(std::make_pair(col_name,col));
177 fOrderedColumnNames.push_back(col_name);
178}
179
180void tkdb_table::add_constraint(const char *_constraint)
181{
182 fConstraint += _constraint;
183 fConstraint += " ";
184}
185
186bool tkdb_table::has_column(const tkstring &_col_name)
187{
188 return fColumns.count(_col_name)>0;
189}
190
192{
193 for (auto &column : fColumns)
194 column.second.set_value_str("");
195}
196
198{
199 tkstring sql = tkstring::form("INSERT INTO %s (", fName.data());
200 tkstring values = "VALUES (";
201 for(auto &column : fColumns) {
202 if(column.second.is_empty()) continue;
203 sql += column.second.get_name();
204 if(column.second.is_text()) values +="'";
205 values += column.second.get_value();
206 if(column.second.is_text()) values +="'";
207 sql +=",";
208 values +=",";
209 }
210 sql.erase(sql.length()-1);
211 values.erase(values.length()-1);
212 sql += ") ";
213 values += ");";
214 sql += values.data();
215 exec_sql(sql.data());
217}
218
220{
221// UPDATE the table. _where should contain a statment returning one column
222// like isotope_id = 27 (to be tested...)
223
224 tkstring sql = tkstring::form("UPDATE %s SET ", fName.data());
225 for(auto &column : fColumns) {
226 if(column.second.is_empty()) continue;
227 sql += column.second.get_name();
228 sql += " = ";
229 if(column.second.is_text()) sql +="'";
230 sql += column.second.get_value();
231 if(column.second.is_text()) sql +="'";
232 sql +=",";
233 }
234 sql.erase(sql.length()-1);
235 sql += " WHERE ";
236 sql += _where.data();
237 sql += ";";
238 exec_sql(sql.data());
240}
241
243{
244 tkstring sql = tkstring::form("CREATE TABLE %s (", fName.data());
245
246 for (auto it: fOrderedColumnNames) {
247 sql += fColumns[it.data()].get_name();
248 sql += " ";
249 sql += fColumns[it.data()].get_type();
250 sql +=",";
251 }
252 sql = sql.substr(0,sql.size()-1);
253 if(!fConstraint.empty()) {
254 sql += ", ";
255 sql += fConstraint.data();
256 }
257 sql +=");";
258 exec_sql(sql.data());
259}
260
262{
263 for (auto &column : fColumns)
264 column.second.set_value_str("0");
265 push_row();
266}
267
268int tkdb_table::exec_sql(const char *_cmd)
269{
270 char *zErrMsg = nullptr;
271 int rc = sqlite3_exec(fDataBase, _cmd, nullptr, nullptr, &zErrMsg);
272
273 if( rc != SQLITE_OK ) {
274 glog << error << "SQL error: " << zErrMsg << " while excuting command: " << _cmd << do_endl;
275 sqlite3_free(zErrMsg);
276 }
277 else {}
278 return rc;
279}
280
281void tkdb_table::read_measure(measure_data_struct &_struct, const tkstring &_col_base_name)
282{
283 if(!fColumns.count(_col_base_name.data())) {
284 glog << warning << "no column named: " << _col_base_name << " in database: " << fName << do_endl;
285 return;
286 }
287 tkdb_column *col = &(*this)[_col_base_name.data()];
288 if(col->is_empty()) {
289 _struct.filled = false;
290 return;
291 }
292 _struct.value = col->get_value().atof();
293 col = &(*this)[tkstring::form("%s_unit",_col_base_name.data())];
294 if(!col->is_empty()) _struct.unit = col->get_value();
295 col = &(*this)[tkstring::form("%s_unc",_col_base_name.data())];
296 if(!col->is_empty()) _struct.err = col->get_value().atof();
297 col = &(*this)[tkstring::form("%s_unc_low",_col_base_name.data())];
298 if(!col->is_empty()) _struct.err_low = col->get_value().atof();
299 col = &(*this)[tkstring::form("%s_unc_high",_col_base_name.data())];
300 if(!col->is_empty()) _struct.err_high = col->get_value().atof();
301 col = &(*this)[tkstring::form("%s_info",_col_base_name.data())];
302 if(!col->is_empty()) _struct.info = col->get_value();
303
304 _struct.filled = true;
305}
306
307
308#ifdef HAS_ROOT
310ClassImp(tkdb_table)
311#endif
312
Simple structure to store a table column.
Definition tkdb_column.h:26
tkstring get_value() const
Definition tkdb_column.h:38
Representaiton of a sqlite data table.
Definition tkdb_table.h:29
void read_measure(measure_data_struct &_struct, const tkstring &_col_base_name)
void begin(tkstring _condition, tkstring _selection="*")
bool has_column(const tkstring &_col_name)
void update_row(const tkstring &_where)
void load()
resets column values and ends the select statement
bool next()
executes the select statement
void print_columns(const tkstring &_opt="")
void add_constraint(const char *_constraint)
void write_to_database()
void print_rows(const char *_selection, const char *_properties="*")
void end()
reads the next entry coresponding to the select statement and fills columns
void print(const tkstring &_opt="")
void add_column(const char *_colname, const char *_coltype)
void reset_column_values()
virtual ~tkdb_table()
std::string with usefull tricks from TString (ROOT) and KVString (KaliVeda) and more....
Definition tkstring.h:31
static const char * form(const char *_format,...)
Definition tkstring.cpp:408
std::vector< tkstring > tokenize(const tkstring &_delim=" ") const
Create a vector of string separated by at least one delimiter.
Definition tkstring.cpp:231
static tkstring Form(const char *_format,...)
Definition tkstring.cpp:322
tkstring substr(size_type __pos=0, size_type __n=npos) const
Inlines.
Definition tkstring.h:156
bool equal_to(const char *_s, ECaseCompare _cmp=kExact) const
Returns true if the string and _s are identical.
Definition tkstring.cpp:211
bool contains(const char *_pat, ECaseCompare _cmp=kExact) const
Definition tkstring.h:174
double atof() const
Converts a string to double value.
Definition tkstring.cpp:168
Definition tklog.cpp:16
tklog & yellow(tklog &log)
Definition tklog.h:244
tklog & error_v(tklog &log)
Definition tklog.h:407
tklog & info(tklog &log)
Definition tklog.h:313
tklog & error(tklog &log)
Definition tklog.h:344
tklog & do_endl(tklog &log)
Definition tklog.h:212
tklog & warning(tklog &log)
Definition tklog.h:331
tklog & blue(tklog &log)
Definition tklog.h:247
data structure used to fill a tkmeasure object from the sqlite database
Definition tkdb_table.h:49