16#include <sqlpp11/select.h>
17#include <sqlpp11/functions.h>
20#include <sqlpp23/core/clause/select.h>
21#include <sqlpp23/core/function.h>
25#include "QwParitySchema.h"
33 QwError <<
"QwScopedConnection: Failed to establish database connection" <<
QwLog::endl;
47 other.fDatabase =
nullptr;
48 other.fConnected =
false;
63 other.fDatabase =
nullptr;
64 other.fConnected =
false;
121 QwDebug <<
"QwDatabase::~QwDatabase() : Good-bye World from QwDatabase destructor!" <<
QwLog::endl;
147 QwError <<
"QwDatabase::ValidateConnection() : No database supplied. Unable to connect." <<
QwLog::endl;
150#ifdef __USE_DATABASE_SQLITE3__
151 if (
fDBType != kQwDatabaseSQLite3) {
157 QwError <<
"QwDatabase::ValidateConnection() : No database username supplied. Unable to connect." <<
QwLog::endl;
161 QwError <<
"QwDatabase::ValidateConnection() : No database password supplied. Unable to connect." <<
QwLog::endl;
165 QwMessage <<
"QwDatabase::ValidateConnection() : No database server supplied. Attempting localhost." <<
QwLog::endl;
176#ifdef __USE_DATABASE_MYSQL__
177 case kQwDatabaseMySQL: {
179 sqlpp::mysql::connection_config config;
185#ifdef __USE_SQLPP11__
188#ifdef __USE_SQLPP23__
190 config.debug = sqlpp::debug_logger({sqlpp::log_category::all}, [](
const std::string& msg) {
195 fDBConnection = std::make_shared<sqlpp::mysql::connection>(config);
199#ifdef __USE_DATABASE_SQLITE3__
200 case kQwDatabaseSQLite3: {
201 QwDebug <<
"QwDatabase::ValidateConnection() : Using SQLite3 backend." <<
QwLog::endl;
202 sqlpp::sqlite3::connection_config config;
206 config.flags = SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE;
207#ifdef __USE_SQLPP11__
210#ifdef __USE_SQLPP23__
212 config.debug = sqlpp::debug_logger({sqlpp::log_category::all}, [](
const std::string& msg) {
217 fDBConnection = std::make_shared<sqlpp::sqlite3::connection>(config);
221#ifdef __USE_DATABASE_POSTGRESQL__
222 case kQwDatabasePostgreSQL: {
223 QwDebug <<
"QwDatabase::ValidateConnection() : Using PostgreSQL backend." <<
QwLog::endl;
224 sqlpp::postgresql::connection_config config;
230#ifdef __USE_SQLPP11__
233#ifdef __USE_SQLPP23__
235 config.debug = sqlpp::debug_logger({sqlpp::log_category::all}, [](
const std::string& msg) {
240 fDBConnection = std::make_shared<sqlpp::postgresql::connection>(config);
245 QwError <<
"QwDatabase::ValidateConnection() : Unsupported database type." <<
QwLog::endl;
250 }
catch (std::exception
const& e) {
263 QwDebug <<
"QwDatabase::ValidateConnection() : Made it past connect() call." <<
QwLog::endl;
269 QwMessage <<
"QwDatabase::ValidateConnection() : Successfully connected to requested database." <<
QwLog::endl;
271 QwError <<
"QwDatabase::ValidateConnection() : Unsuccessfully connected to requested database." <<
QwLog::endl;
289 QwError <<
"QwDatabase::ValidConnection() : Connected database schema inconsistent with current version of analyzer." <<
QwLog::endl;
292 QwError <<
" Please connect to a database supporting the required schema version." <<
QwLog::endl;
326#ifdef __USE_DATABASE_MYSQL__
327 case kQwDatabaseMySQL: {
329 sqlpp::mysql::connection_config config;
335#ifdef __USE_SQLPP11__
338#ifdef __USE_SQLPP23__
340 config.debug = sqlpp::debug_logger({sqlpp::log_category::all}, [](
const std::string& msg) {
345 fDBConnection = std::make_shared<sqlpp::mysql::connection>(config);
349#ifdef __USE_DATABASE_SQLITE3__
350 case kQwDatabaseSQLite3: {
351 QwDebug <<
"QwDatabase::ValidateConnection() : Using SQLite3 backend." <<
QwLog::endl;
352 sqlpp::sqlite3::connection_config config;
356 config.flags = SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE;
357#ifdef __USE_SQLPP11__
360#ifdef __USE_SQLPP23__
362 config.debug = sqlpp::debug_logger({sqlpp::log_category::all}, [](
const std::string& msg) {
367 fDBConnection = std::make_shared<sqlpp::sqlite3::connection>(config);
371#ifdef __USE_DATABASE_POSTGRESQL__
372 case kQwDatabasePostgreSQL: {
373 QwDebug <<
"QwDatabase::ValidateConnection() : Using PostgreSQL backend." <<
QwLog::endl;
374 sqlpp::postgresql::connection_config config;
380 fDBConnection = std::make_shared<sqlpp::postgresql::connection>(config);
385 QwError <<
"QwDatabase::ValidateConnection() : Unsupported database type." <<
QwLog::endl;
389 }
catch (
const std::exception& e) {
397 QwError <<
"QwDatabase::Connect() : Must establish valid connection to database." <<
QwLog::endl;
413 options.
AddOptions(
"Database options")(
"QwDatabase.accesslevel", po::value<string>(),
"database access level (OFF,RO,RW)");
414 options.
AddOptions(
"Database options")(
"QwDatabase.dbname", po::value<string>(),
"database name or path");
415 options.
AddOptions(
"Database options")(
"QwDatabase.dbserver", po::value<string>(),
"database server name");
416 options.
AddOptions(
"Database options")(
"QwDatabase.dbusername", po::value<string>(),
"database username");
417 options.
AddOptions(
"Database options")(
"QwDatabase.dbpassword", po::value<string>(),
"database password");
418 options.
AddOptions(
"Database options")(
"QwDatabase.dbport", po::value<int>()->default_value(0),
"database server port number (defaults to standard mysql port)");
419 options.
AddOptions(
"Database options")(
"QwDatabase.debug", po::value<bool>()->default_value(
false),
"enable database debug output (default false)");
420 options.
AddOptions(
"Database options")(
"QwDatabase.insert-missing-keys", po::value<bool>()->default_value(
false),
"insert missing keys into the database (default false)");
422 std::stringstream dbtypes;
424#ifdef __USE_DATABASE_SQLITE3__
425 dbtypes <<
",sqlite3";
427#ifdef __USE_DATABASE_MYSQL__
430#ifdef __USE_DATABASE_POSTGRESQL__
431 dbtypes <<
",postgresql";
433 std::stringstream desc;
434 desc <<
"database type (" << dbtypes.str() <<
")";
435 options.
AddOptions(
"Database options")(
"QwDatabase.dbtype", po::value<string>()->default_value(
"none"), desc.str().c_str());
445 if (options.
HasValue(
"QwDatabase.accesslevel")) {
446 string access = options.
GetValue<
string>(
"QwDatabase.accesslevel");
450 QwWarning <<
"QwDatabase::ProcessOptions : No access level specified; database access is OFF" <<
QwLog::endl;
453 if (options.
HasValue(
"QwDatabase.dbtype")) {
454 string dbtype = options.
GetValue<
string>(
"QwDatabase.dbtype");
456#ifdef __USE_DATABASE_MYSQL__
457 if (dbtype ==
"mysql") {
461#ifdef __USE_DATABASE_SQLITE3__
462 if (dbtype ==
"sqlite3") {
466#ifdef __USE_DATABASE_POSTGRESQL__
467 if (dbtype ==
"postgresql") {
468 fDBType = kQwDatabasePostgreSQL;
472 QwWarning <<
"QwDatabase::ProcessOptions : Unrecognized database type \"" << dbtype <<
"\"; using none" <<
QwLog::endl;
478 if (options.
HasValue(
"QwDatabase.dbport")) {
481 if (options.
HasValue(
"QwDatabase.dbname")) {
484 if (options.
HasValue(
"QwDatabase.dbusername")) {
487 if (options.
HasValue(
"QwDatabase.dbpassword")) {
490 if (options.
HasValue(
"QwDatabase.dbserver")) {
493 if (options.
HasValue(
"QwDatabase.debug")) {
496 if (options.
HasValue(
"QwDatabase.insert-missing-keys")) {
501void QwDatabase::ProcessOptions(
const EQwDBType& dbtype,
const TString& dbname,
const TString& username,
const TString& passwd,
const TString& dbhost,
const Int_t dbport,
const TString& accesslevel)
514 TString level = accesslevel.c_str();
520 QwWarning <<
"QwDatabase::SetAccessLevel : Unrecognized access level \""
521 << accesslevel <<
"\"; setting database access OFF"
535 printf(
"\nQwDatabase MySQL ");
546 printf(
"There is no connection.\n");
571 QwParitySchema::db_schema db_schema;
573 sqlpp::select(sqlpp::all_of(db_schema))
575 .where(sqlpp::value(
true))
577 QwDebug <<
"QwDatabase::StoreDBVersion => Number of rows returned: " << record_count <<
QwLog::endl;
580 if (record_count > 1)
590 if (record_count == 1)
593 sqlpp::select(sqlpp::all_of(db_schema))
595 .where(sqlpp::value(
true))
599 [
this](
const auto& row) {
600 QwDebug <<
"QwDatabase::StoreDBVersion => db_schema_id = " << row.db_schema_id <<
QwLog::endl;
609 catch (
const std::exception& er)
A class for handling connections to the Qweak database.
#define QwError
Predefined log drain for errors.
#define QwWarning
Predefined log drain for warnings.
#define QwMessage
Predefined log drain for regular messages.
#define QwDebug
Predefined log drain for debugging output.
QwScopedConnection & operator=(const QwScopedConnection &)=delete
QwScopedConnection(QwDatabase *db)
A database interface class.
string fDBUsername
Name of account to connect to DB server with.
auto QuerySelect(const Statement &statement)
const string kValidVersionPoint
Bool_t ValidateConnection()
Checks that given connection parameters result in a valid connection.
const string GetValidVersion()
static void DefineOptions(QwOptions &options)
Defines available class options for QwOptions.
bool StoreDBVersion()
Retrieve database schema version information from database.
const string GetVersion()
const string kValidVersionMinor
Bool_t fDBInsertMissingKeys
True if missing keys should be inserted into the database automatically.
const string GetServerVersion()
string fDBServer
Name of server carrying DB to connect to.
Bool_t Connect()
Open a connection to the database using the predefined parameters.
string fVersionPoint
Point version number of current DB schema.
QwDatabase(const string &major="00", const string &minor="00", const string &point="0000")
Simple constructor.
const string kValidVersionMajor
Bool_t fDBDebug
True if database debug information should be printed to stdout.
virtual ~QwDatabase()
Destructor.
void SetAccessLevel(string accesslevel)
Sets the access level flag based on string labels: "off", "ro", "rw".
string fDatabase
Name of database to connect to.
EQwDBAccessLevel fAccessLevel
Access level of the database instance.
Bool_t Connected()
Get a scoped connection that automatically disconnects when destroyed.
DatabaseConnection fDBConnection
size_t QueryCount(const Statement &statement)
string fVersionMinor
Minor version number of current DB schema.
UInt_t fDBPortNumber
Port number to connect to on server (mysql default port is 3306)
string fVersionMajor
Major version number of current DB schema.
string fDBPassword
DB account password.
Bool_t fValidConnection
True if a valid connection was established using defined connection information.
EQwDBType fDBType
Type of database backend to use.
bool ForFirstResult(QueryResult &result, Lambda &&lambda) const
void ProcessOptions(QwOptions &options)
Processes the options contained in the QwOptions object.
static std::ostream & endl(std::ostream &)
End of the line.
Command-line and configuration file options processor.
T GetValue(const std::string &key)
Get a templated value.
bool HasValue(const std::string &key)
Has this key been defined.
po::options_description_easy_init AddOptions(const std::string &blockname="Specialized options")
Add an option to a named block or create new block.