Skip to content

Commit

Permalink
feat: allow for SQLite DBMS for RCDB (#288)
Browse files Browse the repository at this point in the history
  • Loading branch information
c-dilks authored Oct 29, 2024
1 parent ed204b9 commit e31a651
Show file tree
Hide file tree
Showing 12 changed files with 79 additions and 24 deletions.
5 changes: 5 additions & 0 deletions .github/install-dependency-packages.sh
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ GENERAL_PACKAGE_LIST_LINUX=(
davix
### RCDB dependencies
mariadb
sqlite
)
IGUANA_PACKAGE_LIST_LINUX=(
fmt
Expand All @@ -60,6 +61,7 @@ GENERAL_PACKAGE_LIST_MACOS=(
gsl
### RCDB dependencies
mariadb
sqlite
)
IGUANA_PACKAGE_LIST_MACOS=(
fmt
Expand Down Expand Up @@ -143,6 +145,9 @@ case $runner in
### link homebrew's gcc, for gfortran
brew unlink gcc
brew link gcc
### link homebrew's sqlite, for RCDB
brew unlink sqlite
brew link --force sqlite
### kluge ssl linker issue (see, e.g., https://github.com/brianmario/mysql2/issues/795)
echo "LIBRARY_PATH=${LIBRARY_PATH:+${LIBRARY_PATH}:}$(pkg-config libssl --variable libdir)" | tee -a $GITHUB_ENV
;;
Expand Down
1 change: 1 addition & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -445,6 +445,7 @@ jobs:
# echo '- to compare to the report from the `main` branch, see <https://jeffersonlab.github.io/iguana/coverage-report>' >> $GITHUB_STEP_SUMMARY
### test relocatability
- name: test relocatability
if: ${{ matrix.id == 'cpp' }} # don't bother re-running santizers, etc.
run: |
mv iguana relocated
source relocated/bin/this_iguana.sh --verbose # do not use --githubCI option, since we want this environment to be for only this step
Expand Down
1 change: 1 addition & 0 deletions meson.build
Original file line number Diff line number Diff line change
Expand Up @@ -189,6 +189,7 @@ project_test_env.set(
'halt_on_error=1',
'abort_on_error=1',
'print_summary=1',
'suppressions=' + meson.project_source_root() / 'meson' / 'asan.supp',
)
project_test_env.set(
'LSAN_OPTIONS',
Expand Down
2 changes: 2 additions & 0 deletions meson/asan.supp
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
# RCDB's SQLite header
odr_violation:SQLite::*
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ namespace iguana::physics {
i_targetM = result_schema.getEntryOrder("targetM");

// instantiate RCDB reader
m_rcdb = std::make_unique<RCDBReader>("RCDB|" + GetName());
m_rcdb = std::make_unique<RCDBReader>("RCDB|" + GetName(), m_log->GetLevel());

// parse config file
ParseYAMLConfig();
Expand Down
1 change: 1 addition & 0 deletions src/iguana/services/GlobalParam.cc
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ namespace iguana {

// default param values
GlobalParam<std::string> GlobalConcurrencyModel{"none"};
GlobalParam<std::string> GlobalRcdbUrl{""};

// template specializations
template class GlobalParam<std::string>;
Expand Down
4 changes: 4 additions & 0 deletions src/iguana/services/GlobalParam.h
Original file line number Diff line number Diff line change
Expand Up @@ -64,4 +64,8 @@ namespace iguana {
/// option will be _chosen_ by `ConcurrentParamFactory::Create` instead
extern GlobalParam<std::string> GlobalConcurrencyModel;

/// @brief Path to the RCDB
/// @see `iguana::RCDBReader` for details
extern GlobalParam<std::string> GlobalRcdbUrl;

}
4 changes: 2 additions & 2 deletions src/iguana/services/Object.cc
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@

namespace iguana {

Object::Object(std::string_view name)
Object::Object(std::string_view name, Logger::Level lev)
: m_name(name)
, m_log(std::make_unique<Logger>(m_name))
, m_log(std::make_unique<Logger>(m_name, lev))
{}

std::unique_ptr<Logger>& Object::Log()
Expand Down
3 changes: 2 additions & 1 deletion src/iguana/services/Object.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,8 @@ namespace iguana {
public:

/// @param name the name of this object
Object(std::string_view name = "");
/// @param lev the log level
Object(std::string_view name = "", Logger::Level lev = Logger::DEFAULT_LEVEL);
~Object() {}

/// Get the logger
Expand Down
28 changes: 24 additions & 4 deletions src/iguana/services/RCDBReader.cc
Original file line number Diff line number Diff line change
@@ -1,14 +1,34 @@
#include "RCDBReader.h"
#include "GlobalParam.h"

namespace iguana {

RCDBReader::RCDBReader(std::string_view name) : Object(name)
RCDBReader::RCDBReader(std::string_view name, Logger::Level lev) : Object(name, lev)
{
#ifdef USE_RCDB
auto url_ptr = std::getenv("RCDB_CONNECTION");
m_url = url_ptr != nullptr ? std::string(url_ptr) : default_url;
m_log->Debug("RCDB URL: {}", m_url);

// choose the RCDB URL, from the following priority ordering
// 1. try `GlobalRcdbUrl`
m_url = GlobalRcdbUrl();
if(!m_url.empty())
m_log->Debug("RCDB URL set from 'iguana::GlobalRcdbUrl': {:?}", m_url);
else {
// 2. try env var `RCDB_CONNECTION`
if(auto url_ptr{std::getenv("RCDB_CONNECTION")}; url_ptr != nullptr)
m_url = std::string(url_ptr);
if(!m_url.empty())
m_log->Debug("RCDB URL set from env var 'RCDB_CONNECTION': {:?}", m_url);
else {
// 3. fallback to default value
m_log->Warn("RCDB URL not set; you may choose a URL with the environment variable 'RCDB_CONNECTION' or with the global parameter 'iguana::GlobalRcdbUrl'; for now, let's proceed with the URL set to {:?}", m_default_url);
m_url = m_default_url;
m_log->Debug("RCDB URL set from default fallback: {:?}", m_url);
}
}

// then start the connection
m_rcdb_connection = std::make_unique<rcdb::Connection>(m_url, true);

#endif
}

Expand Down
17 changes: 15 additions & 2 deletions src/iguana/services/RCDBReader.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,22 +10,35 @@
namespace iguana {

/// @brief RCDB reader
///
/// This class interfaces to the RCDB. The database connection path is chosen from one of the following, in order:
/// - The global variable `iguana::GlobalRcdbUrl`; by default this is not set to any value (its type is `iguana::GlobalParam`)
/// - The environment variable `RCDB_CONNECTION` (which is likely set if you are on `ifarm`)
/// - A default URL, which will be printed in a warning; see `iguana::RCDBReader::m_default_url`
///
/// RCDB will automatically use `mariadb` / `mysql` or `sqlite`, depending on the above RCDB database path,
/// and whether you have satisfied the dependencies.
class RCDBReader : public Object
{

public:

/// @param name the name of this reader
RCDBReader(std::string_view name = "rcdb");
/// @param lev the log level
RCDBReader(std::string_view name = "rcdb", Logger::Level lev = Logger::DEFAULT_LEVEL);

/// @param runnum run number
/// @returns the beam energy in GeV
double GetBeamEnergy(int const runnum);

protected:

/// @brief default RCDB URL, used as a last resort
std::string const m_default_url = "mysql://[email protected]/rcdb";

private:

std::string m_url;
std::string const default_url = "mysql://[email protected]/rcdb";
std::once_flag m_error_once;

#ifdef USE_RCDB
Expand Down
35 changes: 21 additions & 14 deletions subprojects/rcdb/meson.build
Original file line number Diff line number Diff line change
Expand Up @@ -18,19 +18,26 @@ else
error(f'RCDB not found; set build option "rcdb:home" to the RCDB installation (e.g., to "$RCDB_HOME"); @require_message@')
endif

# RCDB dependencies: either mysql or sqlite
# - looking for mysql here, since clas12root uses this
# - prioritizing mariadb, an open source fork of mysql
backend_list = ['mariadb', 'mysql', 'mysqlclient']
foreach backend_name : backend_list
rcdb_backend_dep = dependency(backend_name, required: false)
if rcdb_backend_dep.found()
message(f'using "@backend_name@" for the RCDB backend')
break
endif
# RCDB dependencies: a database management system (DBMS), mysql and/or sqlite
dbms_args = []
dbms_deps = []
dbms_dict = {
'mysql': [ 'mariadb', 'mysql', 'mysqlclient' ], # prioritizing mariadb, an open source fork of mysql
'sqlite': [ 'sqlite3' ],
}
foreach dbms, pkgs : dbms_dict
foreach pkg : pkgs
dep = dependency(pkg, required: false)
if dep.found()
dbms_deps += dep
dbms_args += { 'mysql': '-DRCDB_MYSQL', 'sqlite': '-DRCDB_SQLITE' }[dbms]
message(f'using @pkg@ for RCDB DBMS')
break
endif
endforeach
endforeach
if not rcdb_backend_dep.found()
error('none of the backends (' + ', '.join(backend_list) + ') were found, so RCDB will not be used in this build; ' + require_message)
if dbms_deps.length() == 0
error('none of the DBMSs (' + ', '.join(dbms_dict.keys()) + ') were found, so RCDB will not be used in this build; ' + require_message)
endif

rcdb_dep = declare_dependency(
Expand All @@ -43,6 +50,6 @@ rcdb_dep = declare_dependency(
rcdb_includedir,
is_system: true, # suppress consumer warnings
),
compile_args: ['-DRCDB_MYSQL' ],
dependencies: [ rcdb_backend_dep ],
compile_args: dbms_args,
dependencies: dbms_deps,
)

0 comments on commit e31a651

Please sign in to comment.