20#ifdef __USE_DATABASE__
22#include <sqlpp11/sqlpp11.h>
23#ifdef __USE_DATABASE_MYSQL__
24#include <sqlpp11/mysql/mysql.h>
26#ifdef __USE_DATABASE_SQLITE3__
27#include <sqlpp11/sqlite3/sqlite3.h>
29#ifdef __USE_DATABASE_POSTGRESQL__
30#include <sqlpp11/postgresql/postgresql.h>
34#include <sqlpp23/sqlpp23.h>
35#ifdef __USE_DATABASE_MYSQL__
36#include <sqlpp23/mysql/mysql.h>
38#ifdef __USE_DATABASE_SQLITE3__
39#include <sqlpp23/sqlite3/sqlite3.h>
41#ifdef __USE_DATABASE_POSTGRESQL__
42#include <sqlpp23/postgresql/postgresql.h>
48 static constexpr auto null = std::nullopt;
55constexpr bool is_null(
const std::optional<T>& opt) {
56 return !opt.has_value();
124#ifdef __USE_DATABASE_SQLITE3__
127#ifdef __USE_DATABASE_MYSQL__
130#ifdef __USE_DATABASE_POSTGRESQL__
131 , kQwDatabasePostgreSQL
137#ifdef __USE_DATABASE_SQLITE3__
138 using SQLiteConnection = std::shared_ptr<sqlpp::sqlite3::connection>;
140#ifdef __USE_DATABASE_MYSQL__
141 using MySQLConnection = std::shared_ptr<sqlpp::mysql::connection>;
143#ifdef __USE_DATABASE_POSTGRESQL__
144 using PostgreSQLConnection = std::shared_ptr<sqlpp::postgresql::connection>;
150#ifdef __USE_DATABASE_SQLITE3__
153#ifdef __USE_DATABASE_MYSQL__
156#ifdef __USE_DATABASE_POSTGRESQL__
157 , PostgreSQLConnection
162 template<
typename Statement>
165#ifdef __USE_DATABASE_SQLITE3__
166 ,
decltype((*std::declval<SQLiteConnection>())(std::declval<Statement>()))
168#ifdef __USE_DATABASE_MYSQL__
169 ,
decltype((*std::declval<MySQLConnection>())(std::declval<Statement>()))
171#ifdef __USE_DATABASE_POSTGRESQL__
172 ,
decltype((*std::declval<PostgreSQLConnection>())(std::declval<Statement>()))
186 template<EConnectionCheck CheckConnection = EConnectionCheck::kChecked,
typename Lambda>
188 return std::visit([&lambda](
auto& connection) ->
decltype(lambda(connection)) {
189 using T = std::decay_t<
decltype(connection)>;
190 if constexpr (std::is_same_v<T, std::monostate>) {
192 throw std::runtime_error(
"Database not connected (no backend available)");
195 if constexpr (std::is_void_v<
decltype(lambda(connection))>) {
198 return decltype(lambda(connection)){};
204 throw std::runtime_error(
"Database not connected");
207 return lambda(connection);
215 template<
typename Statement,
typename Lambda>
222 template<
typename QueryResult,
typename Lambda>
224 std::visit([&lambda](
auto& res) {
225 using T = std::decay_t<
decltype(res)>;
226 if constexpr (!std::is_same_v<T, std::monostate>) {
227 for (
const auto& row : res) {
236 template<
typename Statement>
247 template<
typename QueryResult>
258 template<
typename Statement,
typename Lambda>
271 template<
typename QueryResult,
typename Lambda>
284 template<
typename Statement,
typename Lambda>
287 return std::visit([&lambda](
auto& connection) -> ReturnVariant {
288 using T = std::decay_t<
decltype(connection)>;
289 if constexpr (std::is_same_v<T, std::monostate>) {
290 throw std::runtime_error(
"Database not connected (no backend available)");
293 throw std::runtime_error(
"Database not connected");
295 return ReturnVariant{lambda(connection)};
302 QwDatabase(
const string &major =
"00",
const string &minor =
"00",
const string &point =
"0000");
303 QwDatabase(
QwOptions &options,
const string &major =
"00",
const string &minor =
"00",
const string &point =
"0000");
315 using T = std::decay_t<
decltype(conn)>;
316 if constexpr (!std::is_same_v<T, std::monostate>) {
325 using T = std::decay_t<
decltype(conn)>;
326 if constexpr (std::is_same_v<T, std::monostate>) {
329 return conn !=
nullptr;
344 void ProcessOptions(
const EQwDBType& dbtype,
const TString& dbname,
const TString& username,
const TString& passwd,
const TString& dbhost=
"localhost",
const Int_t dbport = 0,
const TString& accesslevel =
"ro");
347 template<
typename Statement>
350 using T = std::decay_t<
decltype(connection)>;
351 if constexpr (!std::is_same_v<T, std::monostate>) {
352 auto result = (*connection)(statement);
354 for (
const auto& row : result) {
361 throw std::runtime_error(
"Unreachable: monostate in QueryCount lambda");
365 template<
typename Statement>
370 template<
typename Statement>
373 using T = std::decay_t<
decltype(connection)>;
374 if constexpr (!std::is_same_v<T, std::monostate>) {
375 return (*connection)(statement);
378 throw std::runtime_error(
"Unreachable: monostate in QuerySelect lambda");
382 template<
typename Statement>
385 using T = std::decay_t<
decltype(connection)>;
386 if constexpr (!std::is_same_v<T, std::monostate>) {
387 (*connection)(statement);
392 template<
typename InsertStatement>
395 using T = std::decay_t<
decltype(connection)>;
396 if constexpr (!std::is_same_v<T, std::monostate>) {
397 auto result = (*connection)(statement);
399 if constexpr (std::is_integral_v<
decltype(result)>) {
400 return static_cast<uint64_t
>(result);
402 throw std::runtime_error(
"Unexpected result type from INSERT operation - expected integral type");
406 throw std::runtime_error(
"Unreachable: monostate in QueryInsertAndGetId lambda");
ANSI color codes and color management for terminal output.
An options class which parses command line, config file and environment.
A logfile class, based on an identical class in the Hermes analyzer.
Basic data types and constants used throughout the Qweak analysis framework.
A RAII-style scoped database connection.
const QwDatabase & operator*() const
QwScopedConnection & operator=(const QwScopedConnection &)=delete
const QwDatabase * operator->() const
QwDatabase * operator->()
QwScopedConnection(QwDatabase *db)
QwScopedConnection(const QwScopedConnection &)=delete
A database interface class.
auto VisitConnection(Lambda &&lambda)
string fDBUsername
Name of account to connect to DB server with.
auto QuerySelect(const Statement &statement)
Bool_t AllowsReadAccess()
const string kValidVersionPoint
Bool_t AllowsWriteAccess()
Bool_t ValidateConnection()
Checks that given connection parameters result in a valid connection.
std::variant< std::monostate > QuerySelectReturnType
const string GetValidVersion()
void QueryExecute(const Statement &statement)
static void DefineOptions(QwOptions &options)
Defines available class options for QwOptions.
bool QueryExists(const Statement &statement)
bool StoreDBVersion()
Retrieve database schema version information from database.
const string GetVersion()
QwDatabase(const QwDatabase &rhs)
Copy Constructor (not implemented)
QwDatabase & operator=(const QwDatabase &rhs)
Assignment operator (not implemented)
const string kValidVersionMinor
void QuerySelectForEachResult(const Statement &statement, Lambda &&lambda)
Bool_t fDBInsertMissingKeys
True if missing keys should be inserted into the database automatically.
uint64_t QueryInsertAndGetId(const InsertStatement &statement)
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.
auto VisitConnectionForSelect(Lambda &&lambda) -> QuerySelectReturnType< Statement >
const string kValidVersionMajor
QwScopedConnection GetScopedConnection()
Bool_t fDBDebug
True if database debug information should be printed to stdout.
virtual ~QwDatabase()
Destructor.
size_t CountResults(QueryResult &result) const
void SetAccessLevel(string accesslevel)
Sets the access level flag based on string labels: "off", "ro", "rw".
string fDatabase
Name of database to connect to.
void ForEachResult(QueryResult &result, Lambda &&lambda) const
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.
const string GetVersionMajor()
Return a full version string for the DB schema.
UInt_t fDBPortNumber
Port number to connect to on server (mysql default port is 3306)
const string GetVersionPoint()
string fVersionMajor
Major version number of current DB schema.
string fDBPassword
DB account password.
bool QuerySelectForFirstResult(const Statement &statement, Lambda &&lambda)
std::variant< std::monostate > DatabaseConnection
const string GetVersionMinor()
Bool_t fValidConnection
True if a valid connection was established using defined connection information.
EQwDBType fDBType
Type of database backend to use.
size_t QuerySelectCountResults(const Statement &statement)
bool ForFirstResult(QueryResult &result, Lambda &&lambda) const
void ProcessOptions(QwOptions &options)
Processes the options contained in the QwOptions object.
Command-line and configuration file options processor.