37#include "tkdb_table.h"
52tkdb_table::tkdb_table(
const char *_name, sqlite3 *_db) :
56 glog.set_class(
"db_table");
64 glog.set_method(
tkstring::Form(
"get_column_list(%s)",fName.data()));
67 int rc = sqlite3_prepare_v2(fDataBase,
tkstring::form(
"PRAGMA table_info('%s');",fName.data()), -1, &stmt,
nullptr);
69 glog <<
error_v <<
"SQL error: " << sqlite3_errmsg(fDataBase) <<
" while loading table '" << fName.data() <<
"'" <<
do_endl;
70 sqlite3_free(
nullptr);
73 while((sqlite3_step(stmt)) == SQLITE_ROW) {
74 tkstring name = sqlite3_column_text(stmt, 1);
75 tkstring type = sqlite3_column_text(stmt, 2);
79 sqlite3_finalize(stmt);
94 for(
auto &column : fColumns) {
95 if(_opt.
contains(
"notnull")&&column.second.is_empty())
continue;
96 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;
105 std::vector<tkstring> colnames;
107 if(pro.
equal_to(
"*")) colnames = fOrderedColumnNames;
110 for(
auto col : colnames) glog <<
tkstring::form(
"%20s",fColumns[col.data()].get_name());
113 begin(sel,_properties);
116 for(
auto col : colnames) glog <<
tkstring::form(
"%20s",fColumns[col.data()].get_value().data());
125 glog <<
warning <<
"Previous sql statement not yet closed. Closing in to start new statement..." <<
do_endl;
129 tkstring cmd =
tkstring::form(
"select %s from %s where %s",_selection.data(),fName.data(),_condition.data());
131 int rc = sqlite3_prepare_v2(fDataBase, cmd.data(), -1, &fSQL_stmt,
nullptr);
133 glog <<
error <<
"SQL error: " << sqlite3_errmsg(fDataBase) <<
"while executing cmd : " << cmd.data() <<
do_endl;
135 sqlite3_free(
nullptr);
137 else fReading =
true;
143 glog <<
error <<
"No sql statement prepared, please call begin() to prepare it " <<
do_endl;
147 int ret_code = sqlite3_step(fSQL_stmt);
148 if(ret_code== SQLITE_ROW) {
149 int cols = sqlite3_column_count(fSQL_stmt);
150 for (
int i=0; i<cols; i++) {
151 const unsigned char* tmp = sqlite3_column_text(fSQL_stmt, i);
153 fColumns[sqlite3_column_name(fSQL_stmt, i)].set_value(
"");
155 fColumns[sqlite3_column_name(fSQL_stmt, i)].set_value(sqlite3_column_text(fSQL_stmt, i));
165 if(!fReading) {glog <<
error <<
"No sql statement prepared to close..." <<
do_endl;
return;}
166 sqlite3_finalize(fSQL_stmt);
199 fColumns.insert(std::make_pair(col_name,col));
200 fOrderedColumnNames.push_back(col_name);
205 fConstraint += _constraint;
211 return fColumns.count(_col_name)>0;
216 for (
auto &column : fColumns)
217 column.second.set_value_str(
"");
224 for(
auto &column : fColumns) {
225 if(column.second.is_empty())
continue;
226 sql += column.second.get_name();
227 if(column.second.is_text()) values +=
"'";
228 values += column.second.get_value();
229 if(column.second.is_text()) values +=
"'";
233 sql.erase(sql.length()-1);
234 values.erase(values.length()-1);
237 sql += values.data();
238 exec_sql(sql.data());
248 for(
auto &column : fColumns) {
249 if(column.second.is_empty())
continue;
250 sql += column.second.get_name();
252 if(column.second.is_text()) sql +=
"'";
253 sql += column.second.get_value();
254 if(column.second.is_text()) sql +=
"'";
257 sql.erase(sql.length()-1);
259 sql += _where.data();
261 exec_sql(sql.data());
269 for (
auto it: fOrderedColumnNames) {
270 sql += fColumns[it.data()].get_name();
272 sql += fColumns[it.data()].get_type();
275 sql = sql.
substr(0,sql.size()-1);
276 if(!fConstraint.empty()) {
278 sql += fConstraint.data();
281 exec_sql(sql.data());
286 for (
auto &column : fColumns)
287 column.second.set_value_str(
"0");
291int tkdb_table::exec_sql(
const char *_cmd)
293 char *zErrMsg =
nullptr;
294 int rc = sqlite3_exec(fDataBase, _cmd,
nullptr,
nullptr, &zErrMsg);
296 if( rc != SQLITE_OK ) {
297 glog <<
error <<
"SQL error: " << zErrMsg <<
" while excuting command: " << _cmd <<
do_endl;
298 sqlite3_free(zErrMsg);
306 if(!fColumns.count(_col_base_name.data())) {
307 glog <<
warning <<
"no column named: " << _col_base_name <<
" in database: " << fName <<
do_endl;
310 tkdb_column *col = &(*this)[_col_base_name.data()];
320 col = &(*this)[
tkstring::form(
"%s_unc_low",_col_base_name.data())];
322 col = &(*this)[
tkstring::form(
"%s_unc_high",_col_base_name.data())];
Simple structure to store a table column.
tkstring get_value() const
Representaiton of a sqlite data table.
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 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()
std::string with usefull tricks from TString (ROOT) and KVString (KaliVeda) and more....
static const char * form(const char *_format,...)
std::vector< tkstring > tokenize(const tkstring &_delim=" ") const
Create a vector of string separated by at least one delimiter.
static tkstring Form(const char *_format,...)
tkstring substr(size_type __pos=0, size_type __n=npos) const
Inlines.
bool equal_to(const char *_s, ECaseCompare _cmp=kExact) const
Returns true if the string and _s are identical.
bool contains(const char *_pat, ECaseCompare _cmp=kExact) const
double atof() const
Converts a string to double value.
tklog & yellow(tklog &log)
tklog & error_v(tklog &log)
tklog & error(tklog &log)
tklog & do_endl(tklog &log)
tklog & warning(tklog &log)
data structure used to fill a tkmeasure object from the sqlite database