mirror of
https://github.com/Xahau/xahaud.git
synced 2025-12-06 17:27:52 +00:00
Use soci in some places:
* Brings the soci subtree into rippled. * Validator, peerfinder, and SHAMapStore use new soci backend. * Optional postgresql backend for soci (if POSTGRESQL_ROOT env var is set).
This commit is contained in:
59
src/ripple/app/data/DummySociDynamicBackend.cpp
Normal file
59
src/ripple/app/data/DummySociDynamicBackend.cpp
Normal file
@@ -0,0 +1,59 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
This file is part of rippled: https://github.com/ripple/rippled
|
||||
Copyright (c) 2012-2015 Ripple Labs Inc.
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
/** Stub functions for soci dynamic backends.
|
||||
|
||||
Ripple does not use dynamic backends, and inclduing soci's
|
||||
dynamic backends compilcates the build (it requires a generated
|
||||
header file and some macros to be defines.)
|
||||
*/
|
||||
|
||||
#include <BeastConfig.h>
|
||||
|
||||
#include <ripple/app/data/SociDB.h>
|
||||
|
||||
// dummy soci-backend
|
||||
namespace soci {
|
||||
namespace dynamic_backends {
|
||||
// used internally by session
|
||||
backend_factory const& get (std::string const& name)
|
||||
{
|
||||
throw std::runtime_error ("Not Supported");
|
||||
backend_factory* nullBF{nullptr};
|
||||
return *nullBF; // deref nullptr - but we already threw
|
||||
};
|
||||
|
||||
// provided for advanced user-level management
|
||||
std::vector<std::string>& search_paths ()
|
||||
{
|
||||
static std::vector<std::string> empty;
|
||||
return empty;
|
||||
};
|
||||
void register_backend (std::string const&, std::string const&){};
|
||||
void register_backend (std::string const&, backend_factory const&){};
|
||||
std::vector<std::string> list_all ()
|
||||
{
|
||||
return {};
|
||||
};
|
||||
void unload (std::string const&){};
|
||||
void unload_all (){};
|
||||
|
||||
} // namespace dynamic_backends
|
||||
} // namespace soci
|
||||
|
||||
173
src/ripple/app/data/SociDB.cpp
Normal file
173
src/ripple/app/data/SociDB.cpp
Normal file
@@ -0,0 +1,173 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
This file is part of rippled: https://github.com/ripple/rippled
|
||||
Copyright (c) 2012-2015 Ripple Labs Inc.
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
/** An embedded database wrapper with an intuitive, type-safe interface.
|
||||
|
||||
This collection of classes let's you access embedded SQLite databases
|
||||
using C++ syntax that is very similar to regular SQL.
|
||||
|
||||
This module requires the @ref beast_sqlite external module.
|
||||
*/
|
||||
|
||||
#include <BeastConfig.h>
|
||||
|
||||
#include <ripple/core/ConfigSections.h>
|
||||
#include <ripple/app/data/SociDB.h>
|
||||
#include <ripple/core/Config.h>
|
||||
#include <beast/cxx14/memory.h> // <memory>
|
||||
#include <backends/sqlite3/soci-sqlite3.h>
|
||||
#if ENABLE_SOCI_POSTGRESQL
|
||||
#include <backends/postgresql/soci-postgresql.h>
|
||||
#endif
|
||||
#include <boost/filesystem.hpp>
|
||||
|
||||
namespace ripple {
|
||||
namespace detail {
|
||||
|
||||
std::pair<std::string, soci::backend_factory const&>
|
||||
getSociSqliteInit (std::string const& name,
|
||||
std::string const& dir,
|
||||
std::string const& ext)
|
||||
{
|
||||
if (dir.empty () || name.empty ())
|
||||
{
|
||||
throw std::runtime_error (
|
||||
"Sqlite databases must specify a dir and a name. Name: " +
|
||||
name + " Dir: " + dir);
|
||||
}
|
||||
boost::filesystem::path file (dir);
|
||||
if (is_directory (file))
|
||||
file /= name + ext;
|
||||
return std::make_pair (file.string (), std::ref(soci::sqlite3));
|
||||
}
|
||||
|
||||
#if ENABLE_SOCI_POSTGRESQL
|
||||
std::pair<std::string, soci::backend_factory const&>
|
||||
getSociPostgresqlInit (Section const& configSection,
|
||||
std::string const& name)
|
||||
{
|
||||
if (name.empty ())
|
||||
{
|
||||
throw std::runtime_error (
|
||||
"Missing required value for postgresql backend: database name");
|
||||
}
|
||||
|
||||
std::string const host(get <std::string> (configSection, "host", ""));
|
||||
if (!host.empty())
|
||||
{
|
||||
throw std::runtime_error (
|
||||
"Missing required value in config for postgresql backend: host");
|
||||
}
|
||||
|
||||
std::string const user(get <std::string> (configSection, "user", ""));
|
||||
if (user.empty ())
|
||||
{
|
||||
throw std::runtime_error (
|
||||
"Missing required value in config for postgresql backend: user");
|
||||
}
|
||||
|
||||
int const port = [&configSection]
|
||||
{
|
||||
std::string const portAsString (
|
||||
get <std::string> (configSection, "port", ""));
|
||||
if (portAsString.empty ())
|
||||
{
|
||||
throw std::runtime_error (
|
||||
"Missing required value in config for postgresql backend: "
|
||||
"user");
|
||||
}
|
||||
try
|
||||
{
|
||||
return std::stoi (portAsString);
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
throw std::runtime_error (
|
||||
"The port value in the config for the postgresql backend must "
|
||||
"be an integer. Got: " +
|
||||
portAsString);
|
||||
}
|
||||
}();
|
||||
|
||||
std::stringstream s;
|
||||
s << "host=" << host << " port=" << port << " dbname=" << name
|
||||
<< " user=" << user;
|
||||
return std::make_pair (s.str (), std::ref(soci::postgresql));
|
||||
}
|
||||
#endif // ENABLE_SOCI_POSTGRESQL
|
||||
|
||||
std::pair<std::string, soci::backend_factory const&>
|
||||
getSociInit (BasicConfig const& config,
|
||||
std::string const& dbName)
|
||||
{
|
||||
static const std::string sectionName ("sqdb");
|
||||
static const std::string keyName ("backend");
|
||||
auto const& section = config.section (sectionName);
|
||||
std::string const backendName(get(section, keyName, std::string("sqlite")));
|
||||
|
||||
if (backendName == "sqlite")
|
||||
{
|
||||
std::string const path = config.legacy ("database_path");
|
||||
std::string const ext =
|
||||
(dbName == "validators" || dbName == "peerfinder") ? ".sqlite"
|
||||
: ".db";
|
||||
return detail::getSociSqliteInit(dbName, path, ext);
|
||||
}
|
||||
#if ENABLE_SOCI_POSTGRESQL
|
||||
else if (backendName == "postgresql")
|
||||
{
|
||||
return detail::getSociPostgresqlInit(section, dbName);
|
||||
}
|
||||
#endif
|
||||
else
|
||||
{
|
||||
throw std::runtime_error ("Unsupported soci backend: " + backendName);
|
||||
}
|
||||
}
|
||||
} // detail
|
||||
|
||||
SociConfig::SociConfig(std::pair<std::string, soci::backend_factory const&> init)
|
||||
:connectionString_(std::move(init.first)),
|
||||
backendFactory_(init.second){}
|
||||
|
||||
SociConfig::SociConfig(BasicConfig const& config,
|
||||
std::string const& dbName)
|
||||
: SociConfig(detail::getSociInit(config, dbName))
|
||||
{
|
||||
}
|
||||
|
||||
std::string SociConfig::connectionString () const
|
||||
{
|
||||
return connectionString_;
|
||||
}
|
||||
|
||||
void SociConfig::open(soci::session& s) const
|
||||
{
|
||||
s.open (backendFactory_, connectionString ());
|
||||
}
|
||||
|
||||
void open(soci::session& s,
|
||||
BasicConfig const& config,
|
||||
std::string const& dbName)
|
||||
{
|
||||
SociConfig c(config, dbName);
|
||||
c.open(s);
|
||||
}
|
||||
}
|
||||
|
||||
79
src/ripple/app/data/SociDB.h
Normal file
79
src/ripple/app/data/SociDB.h
Normal file
@@ -0,0 +1,79 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
This file is part of rippled: https://github.com/ripple/rippled
|
||||
Copyright (c) 2012-2015 Ripple Labs Inc.
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
#ifndef RIPPLE_SOCIDB_H_INCLUDED
|
||||
#define RIPPLE_SOCIDB_H_INCLUDED
|
||||
|
||||
/** An embedded database wrapper with an intuitive, type-safe interface.
|
||||
|
||||
This collection of classes let's you access embedded SQLite databases
|
||||
using C++ syntax that is very similar to regular SQL.
|
||||
|
||||
This module requires the @ref beast_sqlite external module.
|
||||
*/
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning(push)
|
||||
#pragma warning( \
|
||||
disable : 4355) // 'this' : used in base member initializer list
|
||||
#endif
|
||||
|
||||
#include <core/soci.h>
|
||||
|
||||
namespace ripple {
|
||||
class BasicConfig;
|
||||
|
||||
/**
|
||||
* SociConfig is used when a client wants to delay opening a soci::session after
|
||||
* parsing the config parameters. If a client want to open a session immediately,
|
||||
* use the free function "open" below.
|
||||
*/
|
||||
class SociConfig final
|
||||
{
|
||||
std::string connectionString_;
|
||||
soci::backend_factory const& backendFactory_;
|
||||
SociConfig(std::pair<std::string, soci::backend_factory const&> init);
|
||||
public:
|
||||
SociConfig(BasicConfig const& config,
|
||||
std::string const& dbName);
|
||||
std::string connectionString () const;
|
||||
void open(soci::session& s) const;
|
||||
};
|
||||
|
||||
/**
|
||||
* Open a soci session.
|
||||
*
|
||||
* @param s Session to open.
|
||||
* @param config Parameters to pick the soci backend and how to connect to that
|
||||
* backend.
|
||||
* @param dbName Name of the database. This has different meaning for different backends.
|
||||
* Sometimes it is part of a filename (sqlite3), othertimes it is a
|
||||
* database name (postgresql).
|
||||
*/
|
||||
void open(soci::session& s,
|
||||
BasicConfig const& config,
|
||||
std::string const& dbName);
|
||||
|
||||
}
|
||||
|
||||
#if _MSC_VER
|
||||
#pragma warning(pop)
|
||||
#endif
|
||||
|
||||
#endif
|
||||
197
src/ripple/app/data/tests/SociDB.test.cpp
Normal file
197
src/ripple/app/data/tests/SociDB.test.cpp
Normal file
@@ -0,0 +1,197 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
This file is part of rippled: https://github.com/ripple/rippled
|
||||
Copyright (c) 2012-2015 Ripple Labs Inc.
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
#include <BeastConfig.h>
|
||||
|
||||
#include <ripple/app/data/SociDB.h>
|
||||
#include <ripple/core/ConfigSections.h>
|
||||
#include <ripple/basics/TestSuite.h>
|
||||
#include <ripple/basics/BasicConfig.h>
|
||||
#include <boost/filesystem.hpp>
|
||||
#include <boost/algorithm/string.hpp>
|
||||
|
||||
namespace ripple {
|
||||
class SociDB_test final : public TestSuite
|
||||
{
|
||||
private:
|
||||
static void setupSQLiteConfig (BasicConfig& config,
|
||||
boost::filesystem::path const& dbPath)
|
||||
{
|
||||
config.overwrite ("sqdb", "backend", "sqlite");
|
||||
auto value = dbPath.string ();
|
||||
if (!value.empty ())
|
||||
config.legacy ("database_path", value);
|
||||
}
|
||||
|
||||
static void setupPostgresqlConfig (BasicConfig& config,
|
||||
std::string const& host,
|
||||
std::string const& user,
|
||||
std::string const& port)
|
||||
{
|
||||
config.overwrite ("sqdb", "backend", "postgresql");
|
||||
if (!host.empty ())
|
||||
config.overwrite ("sqdb", "host", host);
|
||||
if (!user.empty ())
|
||||
config.overwrite ("sqdb", "user", user);
|
||||
if (!port.empty ())
|
||||
config.overwrite ("sqdb", "port", port);
|
||||
}
|
||||
|
||||
static void cleanupDatabaseDir (boost::filesystem::path const& dbPath)
|
||||
{
|
||||
using namespace boost::filesystem;
|
||||
if (!exists (dbPath) || !is_directory (dbPath) || !is_empty (dbPath))
|
||||
return;
|
||||
remove (dbPath);
|
||||
}
|
||||
|
||||
static void setupDatabaseDir (boost::filesystem::path const& dbPath)
|
||||
{
|
||||
using namespace boost::filesystem;
|
||||
if (!exists (dbPath))
|
||||
{
|
||||
create_directory (dbPath);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!is_directory (dbPath))
|
||||
{
|
||||
// someone created a file where we want to put out directory
|
||||
throw std::runtime_error ("Cannot create directory: " +
|
||||
dbPath.string ());
|
||||
}
|
||||
}
|
||||
static boost::filesystem::path getDatabasePath ()
|
||||
{
|
||||
return boost::filesystem::current_path () / "socidb_test_databases";
|
||||
}
|
||||
|
||||
public:
|
||||
SociDB_test ()
|
||||
{
|
||||
try
|
||||
{
|
||||
setupDatabaseDir (getDatabasePath ());
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
}
|
||||
}
|
||||
~SociDB_test ()
|
||||
{
|
||||
try
|
||||
{
|
||||
cleanupDatabaseDir (getDatabasePath ());
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
}
|
||||
}
|
||||
void testSQLiteFileNames ()
|
||||
{
|
||||
// confirm that files are given the correct exensions
|
||||
testcase ("sqliteFileNames");
|
||||
BasicConfig c;
|
||||
setupSQLiteConfig (c, getDatabasePath ());
|
||||
std::vector<std::pair<const char*, const char*>> const d (
|
||||
{{"peerfinder", ".sqlite"},
|
||||
{"state", ".db"},
|
||||
{"random", ".db"},
|
||||
{"validators", ".sqlite"}});
|
||||
|
||||
for (auto const& i : d)
|
||||
{
|
||||
SociConfig sc (c, i.first);
|
||||
expect (boost::ends_with (sc.connectionString (),
|
||||
std::string (i.first) + i.second));
|
||||
}
|
||||
}
|
||||
void testSQLiteSession ()
|
||||
{
|
||||
testcase ("open");
|
||||
BasicConfig c;
|
||||
setupSQLiteConfig (c, getDatabasePath ());
|
||||
SociConfig sc (c, "SociTestDB");
|
||||
std::vector<std::string> const stringData (
|
||||
{"String1", "String2", "String3"});
|
||||
std::vector<int> const intData ({1, 2, 3});
|
||||
auto checkValues = [this, &stringData, &intData](soci::session& s)
|
||||
{
|
||||
// Check values in db
|
||||
std::vector<std::string> stringResult (20 * stringData.size ());
|
||||
std::vector<int> intResult (20 * intData.size ());
|
||||
s << "SELECT StringData, IntData FROM SociTestTable",
|
||||
soci::into (stringResult), soci::into (intResult);
|
||||
expect (stringResult.size () == stringData.size () &&
|
||||
intResult.size () == intData.size ());
|
||||
for (int i = 0; i < stringResult.size (); ++i)
|
||||
{
|
||||
auto si = std::distance (stringData.begin (),
|
||||
std::find (stringData.begin (),
|
||||
stringData.end (),
|
||||
stringResult[i]));
|
||||
auto ii = std::distance (
|
||||
intData.begin (),
|
||||
std::find (intData.begin (), intData.end (), intResult[i]));
|
||||
expect (si == ii && si < stringResult.size ());
|
||||
}
|
||||
};
|
||||
|
||||
{
|
||||
soci::session s;
|
||||
sc.open (s);
|
||||
s << "CREATE TABLE IF NOT EXISTS SociTestTable ("
|
||||
" Key INTEGER PRIMARY KEY,"
|
||||
" StringData TEXT,"
|
||||
" IntData INTEGER"
|
||||
");";
|
||||
|
||||
s << "INSERT INTO SociTestTable (StringData, IntData) VALUES "
|
||||
"(:stringData, :intData);",
|
||||
soci::use (stringData), soci::use (intData);
|
||||
checkValues (s);
|
||||
}
|
||||
{
|
||||
// Check values in db after session was closed
|
||||
soci::session s;
|
||||
sc.open (s);
|
||||
checkValues (s);
|
||||
}
|
||||
{
|
||||
using namespace boost::filesystem;
|
||||
// Remove the database
|
||||
path dbPath (sc.connectionString ());
|
||||
if (is_regular_file (dbPath))
|
||||
remove (dbPath);
|
||||
}
|
||||
}
|
||||
void testSQLite ()
|
||||
{
|
||||
testSQLiteFileNames ();
|
||||
testSQLiteSession ();
|
||||
}
|
||||
void run ()
|
||||
{
|
||||
testSQLite ();
|
||||
}
|
||||
};
|
||||
|
||||
BEAST_DEFINE_TESTSUITE (SociDB, app, ripple);
|
||||
|
||||
} // ripple
|
||||
@@ -329,7 +329,7 @@ public:
|
||||
, m_shaMapStore (make_SHAMapStore (setup_SHAMapStore (
|
||||
getConfig()), *this, m_nodeStoreScheduler,
|
||||
m_logs.journal ("SHAMapStore"), m_logs.journal ("NodeObject"),
|
||||
m_txMaster))
|
||||
m_txMaster, getConfig()))
|
||||
|
||||
, m_nodeStore (m_shaMapStore->makeDatabase ("NodeStore.main", 4))
|
||||
|
||||
@@ -394,7 +394,7 @@ public:
|
||||
, m_sntpClient (SNTPClient::New (*this))
|
||||
|
||||
, m_validators (Validators::make_Manager(*this, get_io_service(),
|
||||
getConfig ().getModuleDatabasePath (), m_logs.journal("UVL")))
|
||||
m_logs.journal("UVL"), getConfig ()))
|
||||
|
||||
, m_amendmentTable (make_AmendmentTable
|
||||
(weeks(2), MAJORITY_FRACTION,
|
||||
@@ -797,9 +797,8 @@ public:
|
||||
//
|
||||
// if (!getConfig ().RUN_STANDALONE)
|
||||
m_overlay = make_Overlay (setup_Overlay(getConfig()), *m_jobQueue,
|
||||
*serverHandler_, *m_resourceManager,
|
||||
getConfig ().getModuleDatabasePath (), *m_resolver,
|
||||
get_io_service());
|
||||
*serverHandler_, *m_resourceManager, *m_resolver, get_io_service(),
|
||||
getConfig());
|
||||
add (*m_overlay); // add to PropertyStream
|
||||
|
||||
{
|
||||
|
||||
@@ -161,13 +161,14 @@ void printHelp (const po::options_description& desc)
|
||||
|
||||
static
|
||||
void
|
||||
setupConfigForUnitTests (Config* config)
|
||||
setupConfigForUnitTests (Config& config)
|
||||
{
|
||||
config->overwrite (ConfigSection::nodeDatabase (), "type", "memory");
|
||||
config->overwrite (ConfigSection::nodeDatabase (), "path", "main");
|
||||
|
||||
config->deprecatedClearSection (ConfigSection::tempNodeDatabase ());
|
||||
config->deprecatedClearSection (ConfigSection::importNodeDatabase ());
|
||||
config.legacy("database_path", "DummyForUnitTests");
|
||||
}
|
||||
|
||||
static int runShutdownTests ()
|
||||
@@ -201,7 +202,7 @@ static int runUnitTests (std::string const& pattern,
|
||||
std::string const& argument)
|
||||
{
|
||||
// Config needs to be set up before creating Application
|
||||
setupConfigForUnitTests (&getConfig ());
|
||||
setupConfigForUnitTests (getConfig ());
|
||||
// VFALCO TODO Remove dependence on constructing Application object
|
||||
std::unique_ptr <Application> app (make_Application (deprecatedLogs()));
|
||||
using namespace beast::unit_test;
|
||||
|
||||
@@ -85,7 +85,8 @@ make_SHAMapStore(SHAMapStore::Setup const& s,
|
||||
NodeStore::Scheduler& scheduler,
|
||||
beast::Journal journal,
|
||||
beast::Journal nodeStoreJournal,
|
||||
TransactionMaster& transactionMaster);
|
||||
TransactionMaster& transactionMaster,
|
||||
BasicConfig const& conf);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -18,92 +18,85 @@
|
||||
//==============================================================================
|
||||
|
||||
#include <BeastConfig.h>
|
||||
|
||||
#include <ripple/app/misc/SHAMapStoreImp.h>
|
||||
#include <ripple/app/ledger/LedgerMaster.h>
|
||||
#include <ripple/app/main/Application.h>
|
||||
#include <ripple/core/ConfigSections.h>
|
||||
#include <boost/format.hpp>
|
||||
#include <beast/cxx14/memory.h> // <memory>
|
||||
#include <boost/format.hpp>
|
||||
|
||||
namespace ripple {
|
||||
|
||||
void
|
||||
SHAMapStoreImp::SavedStateDB::init (std::string const& databasePath,
|
||||
std::string const& dbName)
|
||||
void SHAMapStoreImp::SavedStateDB::init (BasicConfig const& config,
|
||||
std::string const& dbName)
|
||||
{
|
||||
boost::filesystem::path pathName = databasePath;
|
||||
pathName /= dbName;
|
||||
std::lock_guard<std::mutex> lock (mutex_);
|
||||
|
||||
std::lock_guard <std::mutex> lock (mutex_);
|
||||
open(session_, config, dbName);
|
||||
|
||||
auto error = session_.open (pathName.string());
|
||||
checkError (error);
|
||||
session_ << "PRAGMA synchronous=FULL;";
|
||||
|
||||
session_.once (error) << "PRAGMA synchronous=FULL;";
|
||||
checkError (error);
|
||||
session_ <<
|
||||
"CREATE TABLE IF NOT EXISTS DbState ("
|
||||
" Key INTEGER PRIMARY KEY,"
|
||||
" WritableDb TEXT,"
|
||||
" ArchiveDb TEXT,"
|
||||
" LastRotatedLedger INTEGER"
|
||||
");"
|
||||
;
|
||||
|
||||
session_.once (error) <<
|
||||
"CREATE TABLE IF NOT EXISTS DbState ("
|
||||
" Key INTEGER PRIMARY KEY,"
|
||||
" WritableDb TEXT,"
|
||||
" ArchiveDb TEXT,"
|
||||
" LastRotatedLedger INTEGER"
|
||||
");"
|
||||
;
|
||||
checkError (error);
|
||||
|
||||
session_.once (error) <<
|
||||
"CREATE TABLE IF NOT EXISTS CanDelete ("
|
||||
" Key INTEGER PRIMARY KEY,"
|
||||
" CanDeleteSeq INTEGER"
|
||||
");"
|
||||
;
|
||||
session_ <<
|
||||
"CREATE TABLE IF NOT EXISTS CanDelete ("
|
||||
" Key INTEGER PRIMARY KEY,"
|
||||
" CanDeleteSeq INTEGER"
|
||||
");"
|
||||
;
|
||||
|
||||
std::int64_t count = 0;
|
||||
beast::sqdb::statement st = (session_.prepare <<
|
||||
soci::statement st = (session_.prepare <<
|
||||
"SELECT COUNT(Key) FROM DbState WHERE Key = 1;"
|
||||
, beast::sqdb::into (count)
|
||||
, soci::into (count)
|
||||
);
|
||||
st.execute_and_fetch (error);
|
||||
checkError (error);
|
||||
st.execute ();
|
||||
if (!st.fetch ())
|
||||
{
|
||||
throw std::runtime_error("Failed to fetch Key Count from DbState.");
|
||||
}
|
||||
|
||||
if (!count)
|
||||
{
|
||||
session_.once (error) <<
|
||||
session_ <<
|
||||
"INSERT INTO DbState VALUES (1, '', '', 0);";
|
||||
checkError (error);
|
||||
}
|
||||
|
||||
st = (session_.prepare <<
|
||||
"SELECT COUNT(Key) FROM CanDelete WHERE Key = 1;"
|
||||
, beast::sqdb::into (count)
|
||||
);
|
||||
st.execute_and_fetch (error);
|
||||
checkError (error);
|
||||
"SELECT COUNT(Key) FROM CanDelete WHERE Key = 1;"
|
||||
, soci::into (count)
|
||||
);
|
||||
st.execute ();
|
||||
if (!st.fetch ())
|
||||
{
|
||||
throw std::runtime_error ("Failed to fetch Key Count from CanDelete.");
|
||||
}
|
||||
|
||||
if (!count)
|
||||
{
|
||||
session_.once (error) <<
|
||||
session_ <<
|
||||
"INSERT INTO CanDelete VALUES (1, 0);";
|
||||
checkError (error);
|
||||
}
|
||||
}
|
||||
|
||||
LedgerIndex
|
||||
SHAMapStoreImp::SavedStateDB::getCanDelete()
|
||||
{
|
||||
beast::Error error;
|
||||
LedgerIndex seq;
|
||||
std::lock_guard<std::mutex> lock (mutex_);
|
||||
|
||||
{
|
||||
std::lock_guard <std::mutex> lock (mutex_);
|
||||
|
||||
session_.once (error) <<
|
||||
"SELECT CanDeleteSeq FROM CanDelete WHERE Key = 1;"
|
||||
, beast::sqdb::into (seq);
|
||||
;
|
||||
}
|
||||
checkError (error);
|
||||
session_ <<
|
||||
"SELECT CanDeleteSeq FROM CanDelete WHERE Key = 1;"
|
||||
, soci::into (seq);
|
||||
;
|
||||
|
||||
return seq;
|
||||
}
|
||||
@@ -111,16 +104,12 @@ SHAMapStoreImp::SavedStateDB::getCanDelete()
|
||||
LedgerIndex
|
||||
SHAMapStoreImp::SavedStateDB::setCanDelete (LedgerIndex canDelete)
|
||||
{
|
||||
beast::Error error;
|
||||
{
|
||||
std::lock_guard <std::mutex> lock (mutex_);
|
||||
std::lock_guard<std::mutex> lock (mutex_);
|
||||
|
||||
session_.once (error) <<
|
||||
"UPDATE CanDelete SET CanDeleteSeq = ? WHERE Key = 1;"
|
||||
, beast::sqdb::use (canDelete)
|
||||
;
|
||||
}
|
||||
checkError (error);
|
||||
session_ <<
|
||||
"UPDATE CanDelete SET CanDeleteSeq = :canDelete WHERE Key = 1;"
|
||||
, soci::use (canDelete)
|
||||
;
|
||||
|
||||
return canDelete;
|
||||
}
|
||||
@@ -128,21 +117,16 @@ SHAMapStoreImp::SavedStateDB::setCanDelete (LedgerIndex canDelete)
|
||||
SHAMapStoreImp::SavedState
|
||||
SHAMapStoreImp::SavedStateDB::getState()
|
||||
{
|
||||
beast::Error error;
|
||||
SavedState state;
|
||||
|
||||
{
|
||||
std::lock_guard <std::mutex> lock (mutex_);
|
||||
std::lock_guard<std::mutex> lock (mutex_);
|
||||
|
||||
session_.once (error) <<
|
||||
"SELECT WritableDb, ArchiveDb, LastRotatedLedger"
|
||||
" FROM DbState WHERE Key = 1;"
|
||||
, beast::sqdb::into (state.writableDb)
|
||||
, beast::sqdb::into (state.archiveDb)
|
||||
, beast::sqdb::into (state.lastRotated)
|
||||
;
|
||||
}
|
||||
checkError (error);
|
||||
session_ <<
|
||||
"SELECT WritableDb, ArchiveDb, LastRotatedLedger"
|
||||
" FROM DbState WHERE Key = 1;"
|
||||
, soci::into (state.writableDb), soci::into (state.archiveDb)
|
||||
, soci::into (state.lastRotated)
|
||||
;
|
||||
|
||||
return state;
|
||||
}
|
||||
@@ -150,48 +134,28 @@ SHAMapStoreImp::SavedStateDB::getState()
|
||||
void
|
||||
SHAMapStoreImp::SavedStateDB::setState (SavedState const& state)
|
||||
{
|
||||
beast::Error error;
|
||||
|
||||
{
|
||||
std::lock_guard <std::mutex> lock (mutex_);
|
||||
session_.once (error) <<
|
||||
"UPDATE DbState"
|
||||
" SET WritableDb = ?,"
|
||||
" ArchiveDb = ?,"
|
||||
" LastRotatedLedger = ?"
|
||||
" WHERE Key = 1;"
|
||||
, beast::sqdb::use (state.writableDb)
|
||||
, beast::sqdb::use (state.archiveDb)
|
||||
, beast::sqdb::use (state.lastRotated)
|
||||
;
|
||||
}
|
||||
checkError (error);
|
||||
std::lock_guard<std::mutex> lock (mutex_);
|
||||
session_ <<
|
||||
"UPDATE DbState"
|
||||
" SET WritableDb = :writableDb,"
|
||||
" ArchiveDb = :archiveDb,"
|
||||
" LastRotatedLedger = :lastRotated"
|
||||
" WHERE Key = 1;"
|
||||
, soci::use (state.writableDb)
|
||||
, soci::use (state.archiveDb)
|
||||
, soci::use (state.lastRotated)
|
||||
;
|
||||
}
|
||||
|
||||
void
|
||||
SHAMapStoreImp::SavedStateDB::setLastRotated (LedgerIndex seq)
|
||||
{
|
||||
beast::Error error;
|
||||
{
|
||||
std::lock_guard <std::mutex> lock (mutex_);
|
||||
session_.once (error) <<
|
||||
"UPDATE DbState SET LastRotatedLedger = ?"
|
||||
" WHERE Key = 1;"
|
||||
, beast::sqdb::use (seq)
|
||||
;
|
||||
}
|
||||
checkError (error);
|
||||
}
|
||||
|
||||
void
|
||||
SHAMapStoreImp::SavedStateDB::checkError (beast::Error const& error)
|
||||
{
|
||||
if (error)
|
||||
{
|
||||
journal_.fatal << "state database error: " << error.code()
|
||||
<< ": " << error.getReasonText();
|
||||
throw std::runtime_error ("State database error.");
|
||||
}
|
||||
std::lock_guard<std::mutex> lock (mutex_);
|
||||
session_ <<
|
||||
"UPDATE DbState SET LastRotatedLedger = :seq"
|
||||
" WHERE Key = 1;"
|
||||
, soci::use (seq)
|
||||
;
|
||||
}
|
||||
|
||||
SHAMapStoreImp::SHAMapStoreImp (Setup const& setup,
|
||||
@@ -199,7 +163,8 @@ SHAMapStoreImp::SHAMapStoreImp (Setup const& setup,
|
||||
NodeStore::Scheduler& scheduler,
|
||||
beast::Journal journal,
|
||||
beast::Journal nodeStoreJournal,
|
||||
TransactionMaster& transactionMaster)
|
||||
TransactionMaster& transactionMaster,
|
||||
BasicConfig const& config)
|
||||
: SHAMapStore (parent)
|
||||
, setup_ (setup)
|
||||
, scheduler_ (scheduler)
|
||||
@@ -223,7 +188,7 @@ SHAMapStoreImp::SHAMapStoreImp (Setup const& setup,
|
||||
std::to_string (setup_.ledgerHistory) + ")");
|
||||
}
|
||||
|
||||
state_db_.init (setup_.databasePath, dbName_);
|
||||
state_db_.init (config, dbName_);
|
||||
|
||||
dbPaths();
|
||||
}
|
||||
@@ -718,10 +683,12 @@ make_SHAMapStore (SHAMapStore::Setup const& s,
|
||||
NodeStore::Scheduler& scheduler,
|
||||
beast::Journal journal,
|
||||
beast::Journal nodeStoreJournal,
|
||||
TransactionMaster& transactionMaster)
|
||||
TransactionMaster& transactionMaster,
|
||||
BasicConfig const& config)
|
||||
{
|
||||
return std::make_unique<SHAMapStoreImp> (s, parent, scheduler,
|
||||
journal, nodeStoreJournal, transactionMaster);
|
||||
return std::make_unique<SHAMapStoreImp>(s, parent, scheduler,
|
||||
journal, nodeStoreJournal, transactionMaster,
|
||||
config);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -23,9 +23,9 @@
|
||||
#include <ripple/app/data/DatabaseCon.h>
|
||||
#include <ripple/app/misc/SHAMapStore.h>
|
||||
#include <ripple/app/misc/NetworkOPs.h>
|
||||
#include <ripple/app/data/SociDB.h>
|
||||
#include <ripple/nodestore/impl/Tuning.h>
|
||||
#include <ripple/nodestore/DatabaseRotating.h>
|
||||
#include <beast/module/sqdb/sqdb.h>
|
||||
#include <iostream>
|
||||
#include <condition_variable>
|
||||
#include <thread>
|
||||
|
||||
Reference in New Issue
Block a user