gambit is hosted by Hepforge, IPPP Durham
GAMBIT  v1.5.0-2191-ga4742ac
a Global And Modular Bsm Inference Tool

SQLite base class for both reader and writer. More...

#include <sqlitebase.hpp>

Inheritance diagram for Gambit::Printers::SQLiteBase:
Collaboration diagram for Gambit::Printers::SQLiteBase:

Public Member Functions

 SQLiteBase ()
 
 ~SQLiteBase ()
 

Protected Member Functions

std::string get_database_file ()
 
std::string get_table_name ()
 
void set_table_name (const std::string &table_name)
 
void require_output_ready ()
 
void open_db (const std::string &, char access='r')
 
void close_db ()
 
sqlite3 * get_db ()
 
void cout_row (sqlite3_stmt *tmp_stmt)
 
void check_table_exists ()
 
void set_table_exists ()
 
std::map< std::string, std::string, Utils::ci_lessget_column_info ()
 
int submit_sql (const std::string &local_info, const std::string &sqlstr, bool allow_fail=false, sql_callback_fptr callback=NULL, void *data=NULL, char **zErrMsg=NULL)
 

Private Attributes

std::string database_file
 
std::string table_name
 
sqlite3 * db
 
bool db_is_open
 
bool table_exists
 

Detailed Description

SQLite base class for both reader and writer.

Definition at line 93 of file sqlitebase.hpp.

Constructor & Destructor Documentation

◆ SQLiteBase()

Gambit::Printers::SQLiteBase::SQLiteBase ( )

Definition at line 149 of file sqlitebase.cpp.

150  : database_file("uninitialised")
151  , table_name("uninitialised")
152  , db(NULL)
153  , db_is_open(false)
154  , table_exists(false)
155  {}

◆ ~SQLiteBase()

Gambit::Printers::SQLiteBase::~SQLiteBase ( )

Definition at line 158 of file sqlitebase.cpp.

References close_db().

159  {
160  close_db();
161  }
Here is the call graph for this function:

Member Function Documentation

◆ check_table_exists()

void Gambit::Printers::SQLiteBase::check_table_exists ( )
protected

Definition at line 338 of file sqlitebase.cpp.

References Gambit::LogTags::err, get_database_file(), get_db(), get_table_name(), LOCAL_INFO, Gambit::Printers::printer_error(), and set_table_exists().

Referenced by Gambit::Printers::SQLiteReader::SQLiteReader().

339  {
340  std::stringstream sql;
341  sql<<"SELECT name FROM sqlite_master WHERE type='table' AND name='"<<get_table_name()<<"';";
342  std::size_t count(0);
343 
344  /* Execute SQL statement and iterate through results*/
345  sqlite3_stmt *temp_stmt;
346  int rc = sqlite3_prepare_v2(get_db(), sql.str().c_str(), -1, &temp_stmt, NULL);
347  if (rc != SQLITE_OK) {
348  std::stringstream err;
349  err<<"Encountered SQLite error while preparing statement to check if table '"<<get_table_name()<<"' exists in file '"<<get_database_file()<<"': "<<sqlite3_errmsg(get_db());
350  printer_error().raise(LOCAL_INFO, err.str());
351  }
352  while ((rc = sqlite3_step(temp_stmt)) == SQLITE_ROW) {
353  count+=1; // Will be one row for each table with a name matching 'get_table_name()'. Should be 1 or 0.
354  }
355  if (rc != SQLITE_DONE) {
356  std::stringstream err;
357  err<<"Encountered SQLite error while checking if table '"<<get_table_name()<<"' exists in file '"<<get_database_file()<<": "<<sqlite3_errmsg(get_db());
358  printer_error().raise(LOCAL_INFO, err.str());
359  }
360  sqlite3_finalize(temp_stmt);
361 
362  if(count==0)
363  {
364  std::stringstream err;
365  err<<"Requested input table '"<<get_table_name()<<"' could not be found in file '"<<get_database_file()<<"! Please check that the requested table name is correct!";
366  printer_error().raise(LOCAL_INFO, err.str());
367  }
368  else if(count>1)
369  {
370  std::stringstream err;
371  err<<"Weird error encountered while checking that input table '"<<get_table_name()<<"' exists in file '"<<get_database_file()<<". We apparently found "<<count<<" tables with this name! This doesn't make sense, so there is probably a bug in the SQLiteBase class, please report it.";
372  printer_error().raise(LOCAL_INFO, err.str());
373  }
374  // Else the table exists, no problem.
375  set_table_exists();
376  }
EXPORT_SYMBOLS error & printer_error()
Printer errors.
#define LOCAL_INFO
Definition: local_info.hpp:34
Here is the call graph for this function:
Here is the caller graph for this function:

◆ close_db()

void Gambit::Printers::SQLiteBase::close_db ( )
protected

Definition at line 211 of file sqlitebase.cpp.

References db_is_open, and get_db().

Referenced by ~SQLiteBase().

212  {
213  sqlite3_close(get_db()); // Check error code?
214  db_is_open = false;
215  }
Here is the call graph for this function:
Here is the caller graph for this function:

◆ cout_row()

void Gambit::Printers::SQLiteBase::cout_row ( sqlite3_stmt *  tmp_stmt)
protected

Definition at line 327 of file sqlitebase.cpp.

Referenced by Gambit::Printers::SQLiteReader::get_dataset_length().

328  {
329  int ncols = sqlite3_data_count(tmp_stmt);
330  for(int i=0; i<ncols; i++)
331  {
332  std::cout<<" "<<sqlite3_column_text(tmp_stmt, i)<<",";
333  }
334  }
Here is the caller graph for this function:

◆ get_column_info()

std::map< std::string, std::string, Utils::ci_less > Gambit::Printers::SQLiteBase::get_column_info ( )
protected

Definition at line 300 of file sqlitebase.cpp.

References Gambit::Printers::col_name_callback(), Gambit::LogTags::err, get_table_name(), LOCAL_INFO, Gambit::Printers::printer_error(), and submit_sql().

Referenced by Gambit::Printers::SQLiteReader::SQLiteReader().

301  {
302  std::stringstream sql;
303  sql<<"PRAGMA table_info("<<get_table_name()<<");";
304 
305  /* Execute SQL statement */
306  int rc;
307  char *zErrMsg = 0;
308  std::map<std::string, std::string, Utils::ci_less> colnames; // Will be passed to and filled by the callback function
309  rc = submit_sql(LOCAL_INFO, sql.str(), true, &col_name_callback, &colnames, &zErrMsg);
310 
311  if( rc != SQLITE_OK ){
312  std::stringstream err;
313  err << "Failed to retrieve information about SQL column names in target table!"<<std::endl;
314  err << " The attempted SQL statement was:"<<std::endl;
315  err << sql.str() << std::endl;
316  sqlite3_free(zErrMsg);
317  printer_error().raise(LOCAL_INFO,err.str());
318  }
319  return colnames;
320  }
int submit_sql(const std::string &local_info, const std::string &sqlstr, bool allow_fail=false, sql_callback_fptr callback=NULL, void *data=NULL, char **zErrMsg=NULL)
Definition: sqlitebase.cpp:258
EXPORT_SYMBOLS error & printer_error()
Printer errors.
#define LOCAL_INFO
Definition: local_info.hpp:34
int col_name_callback(void *colmap_in, int, char **data, char **)
Definition: sqlitebase.cpp:43
Here is the call graph for this function:
Here is the caller graph for this function:

◆ get_database_file()

std::string Gambit::Printers::SQLiteBase::get_database_file ( )
protected

◆ get_db()

sqlite3 * Gambit::Printers::SQLiteBase::get_db ( )
protected

Definition at line 217 of file sqlitebase.cpp.

References db, Gambit::LogTags::err, LOCAL_INFO, and Gambit::Printers::printer_error().

Referenced by check_table_exists(), close_db(), Gambit::Printers::SQLiteReader::get_dataset_length(), Gambit::Printers::SQLiteReader::move_to_next_point(), Gambit::Printers::SQLiteReader::reset(), Gambit::Printers::SQLitePrinter::SQLitePrinter(), and submit_sql().

218  {
219  if(db==NULL)
220  {
221  std::stringstream err;
222  err << "Attempted to access SQLite database pointer, but it is NULL! This means that some SQLitePrinter/Reader routine called 'get_db()' before the database was opened (or after it was closed)! This is a bug, please report it.";
223  printer_error().raise(LOCAL_INFO,err.str());
224  }
225  return db;
226  }
EXPORT_SYMBOLS error & printer_error()
Printer errors.
#define LOCAL_INFO
Definition: local_info.hpp:34
Here is the call graph for this function:
Here is the caller graph for this function:

◆ get_table_name()

◆ open_db()

void Gambit::Printers::SQLiteBase::open_db ( const std::string &  path,
char  access = 'r' 
)
protected

Definition at line 164 of file sqlitebase.cpp.

References database_file, db, db_is_open, Gambit::LogTags::err, LOCAL_INFO, and Gambit::Printers::printer_error().

Referenced by Gambit::Printers::SQLitePrinter::SQLitePrinter(), and Gambit::Printers::SQLiteReader::SQLiteReader().

165  {
166  // Check if we already have an open database
167  if(db!=NULL)
168  {
169  std::stringstream err;
170  err << "Refused to open database file '"<<path<<"'; a database file pointer has already been attached to the SQLite printer!";
171  printer_error().raise(LOCAL_INFO,err.str());
172  }
173 
174  if(db_is_open)
175  {
176  std::stringstream err;
177  err << "Refused to open database file '"<<path<<"'; a database file is already flagged by the SQLite printer as open!";
178  printer_error().raise(LOCAL_INFO,err.str());
179  }
180 
181  int sql_access;
182  switch(access) {
183  case 'r' :
184  sql_access = SQLITE_OPEN_READONLY;
185  break;
186  case 'w':
187  sql_access = SQLITE_OPEN_READWRITE;
188  break;
189  case '+':
190  sql_access = SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE;
191  break;
192  }
193 
194  int rc; // return code
195  //rc = sqlite3_open(path.c_str(), &db);
196  rc = sqlite3_open_v2(path.c_str(), &db, sql_access, NULL);
197 
198  if( rc )
199  {
200  std::stringstream err;
201  err << "Failed to open database file '"<<path<<"' (are you sure it exists?). SQLite error was: " << sqlite3_errmsg(db);
202  printer_error().raise(LOCAL_INFO, err.str());
203  }
204  else
205  {
206  db_is_open = true;
207  database_file = path;
208  }
209  }
EXPORT_SYMBOLS error & printer_error()
Printer errors.
#define LOCAL_INFO
Definition: local_info.hpp:34
Here is the call graph for this function:
Here is the caller graph for this function:

◆ require_output_ready()

void Gambit::Printers::SQLiteBase::require_output_ready ( )
protected

Definition at line 230 of file sqlitebase.cpp.

References db, db_is_open, Gambit::LogTags::err, LOCAL_INFO, Gambit::Printers::printer_error(), and table_exists.

Referenced by Gambit::Printers::SQLiteReader::build_column_map(), Gambit::Printers::SQLitePrinter::dump_buffer(), and Gambit::Printers::SQLitePrinter::ensure_column_exists().

231  {
232  if(db==NULL || !db_is_open || !table_exists)
233  {
234  std::stringstream err;
235  // Something was not ready, check further and throw an error
236  if(db==NULL)
237  {
238  err << "Output readiness check failed! Database pointer was NULL!";
239  printer_error().raise(LOCAL_INFO,err.str());
240  }
241 
242  if(!db_is_open)
243  {
244  err << "Output readiness check failed! Database is not flagged as open!";
245  printer_error().raise(LOCAL_INFO,err.str());
246  }
247 
248  if(!table_exists)
249  {
250  err << "Output readiness check failed! Results table is not flagged as existing!";
251  printer_error().raise(LOCAL_INFO,err.str());
252  }
253  }
254  // Else we are good to go!
255  }
EXPORT_SYMBOLS error & printer_error()
Printer errors.
#define LOCAL_INFO
Definition: local_info.hpp:34
Here is the call graph for this function:
Here is the caller graph for this function:

◆ set_table_exists()

void Gambit::Printers::SQLiteBase::set_table_exists ( )
protected

Definition at line 379 of file sqlitebase.cpp.

References table_exists.

Referenced by check_table_exists(), and Gambit::Printers::SQLitePrinter::make_table().

Here is the caller graph for this function:

◆ set_table_name()

void Gambit::Printers::SQLiteBase::set_table_name ( const std::string &  table_name)
protected

Definition at line 324 of file sqlitebase.cpp.

References table_name.

Referenced by Gambit::Printers::SQLitePrinter::SQLitePrinter(), and Gambit::Printers::SQLiteReader::SQLiteReader().

324 {table_name=t;}
Here is the caller graph for this function:

◆ submit_sql()

int Gambit::Printers::SQLiteBase::submit_sql ( const std::string &  local_info,
const std::string &  sqlstr,
bool  allow_fail = false,
sql_callback_fptr  callback = NULL,
void data = NULL,
char **  zErrMsg = NULL 
)
protected

Definition at line 258 of file sqlitebase.cpp.

References Gambit::GreAT::data, Gambit::LogTags::err, get_db(), and Gambit::Printers::printer_error().

Referenced by Gambit::Printers::SQLitePrinter::dump_buffer_as_INSERT(), Gambit::Printers::SQLitePrinter::dump_buffer_as_UPDATE(), Gambit::Printers::SQLitePrinter::ensure_column_exists(), get_column_info(), Gambit::Printers::SQLitePrinter::make_table(), and Gambit::Printers::SQLitePrinter::reset().

259  {
260  int rc;
261  char *zErrMsg;
262  char **zErrMsg_ptr;
263  if(zErrMsg_in==NULL)
264  {
265  zErrMsg_ptr = &zErrMsg;
266  }
267  else
268  {
269  zErrMsg_ptr = zErrMsg_in;
270  }
271 
272  do
273  {
274  rc = sqlite3_exec(get_db(), sqlstr.c_str(), callback, data, zErrMsg_ptr);
275  if(rc==SQLITE_BUSY)
276  {
277  // Wait at least a short time to avoid slamming the filesystem too much
278  std::chrono::milliseconds timespan(10);
279  std::this_thread::sleep_for(timespan);
280  }
281  }
282  while (rc == SQLITE_BUSY);
283 
284  // if allow_fail is true then we don't catch this error, we allow the caller of this function to hander it.
285  if( (rc != SQLITE_OK) and not allow_fail ){
286  std::stringstream err;
287  err << "SQL error: " << *zErrMsg_ptr << std::endl;
288 #ifdef SQL_DEBUG
289  err << "The attempted SQL statement was:"<<std::endl;
290  err << sqlstr << std::endl;;
291 #endif
292  sqlite3_free(*zErrMsg_ptr);
293  printer_error().raise(local_info,err.str());
294  }
295  return rc;
296  }
greatScanData data
Definition: great.cpp:38
EXPORT_SYMBOLS error & printer_error()
Printer errors.
Here is the call graph for this function:
Here is the caller graph for this function:

Member Data Documentation

◆ database_file

std::string Gambit::Printers::SQLiteBase::database_file
private

◆ db

sqlite3* Gambit::Printers::SQLiteBase::db
private

Definition at line 142 of file sqlitebase.hpp.

Referenced by get_db(), open_db(), and require_output_ready().

◆ db_is_open

bool Gambit::Printers::SQLiteBase::db_is_open
private

Definition at line 145 of file sqlitebase.hpp.

Referenced by close_db(), open_db(), and require_output_ready().

◆ table_exists

bool Gambit::Printers::SQLiteBase::table_exists
private

Definition at line 148 of file sqlitebase.hpp.

Referenced by require_output_ready(), and set_table_exists().

◆ table_name

std::string Gambit::Printers::SQLiteBase::table_name
private

The documentation for this class was generated from the following files: