diff --git a/Builds/VisualStudio2013/RippleD.vcxproj b/Builds/VisualStudio2013/RippleD.vcxproj
index a772a4eec0..042aea9eb5 100644
--- a/Builds/VisualStudio2013/RippleD.vcxproj
+++ b/Builds/VisualStudio2013/RippleD.vcxproj
@@ -795,85 +795,6 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- True
-
-
- True
-
-
- True
-
-
- True
-
-
- True
-
-
- True
-
-
- True
-
-
- True
-
-
- True
-
-
- True
-
-
- True
-
-
- True
-
-
-
-
- True
-
@@ -1535,6 +1456,20 @@
+
+ True
+ True
+ ..\..\src\soci\src\core;..\..\src\sqlite;%(AdditionalIncludeDirectories)
+ ..\..\src\soci\src\core;..\..\src\sqlite;%(AdditionalIncludeDirectories)
+
+
+ True
+ True
+ ..\..\src\soci\src\core;..\..\src\sqlite;%(AdditionalIncludeDirectories)
+ ..\..\src\soci\src\core;..\..\src\sqlite;%(AdditionalIncludeDirectories)
+
+
+
True
True
@@ -1543,6 +1478,12 @@
+
+ True
+ True
+ ..\..\src\soci\src\core;..\..\src\sqlite;%(AdditionalIncludeDirectories)
+ ..\..\src\soci\src\core;..\..\src\sqlite;%(AdditionalIncludeDirectories)
+
True
True
@@ -4382,8 +4323,182 @@
+
+
+
+ True
+
+
+ True
+
+
+
+
+ True
+
+
+ True
+
+
+ True
+
+
+
+
+ True
+
+
+ True
+
+
+ True
+
+
+ True
+
+
+ True
+
+
+
+
+
+
+ True
+
+
+
+
+
+
+
+
+
+
+
+
+ True
+
+
+
+
+ True
+
+
+
+
+ True
+
+
+
+
+
+
+ True
+
+
+
+
+
+
+ True
+
+
+
+
+ True
+
+
+
+
+ True
+
+
+
+
+
+
+ True
+
+
+
+
+ True
+
+
+
+
+
+
+ True
+
+
+
+
+
+
+ True
+
+
+
+
+
+
+ True
+
+
+
+
+
+
+
+
+
+
+ True
+
+
+
+
+
+
+ True
+
+
+
+
+ True
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ True
+
+
+
+
+
+
+
+
+ True
+
+
+
+
+
diff --git a/Builds/VisualStudio2013/RippleD.vcxproj.filters b/Builds/VisualStudio2013/RippleD.vcxproj.filters
index db4b3ac713..8a60aa5d16 100644
--- a/Builds/VisualStudio2013/RippleD.vcxproj.filters
+++ b/Builds/VisualStudio2013/RippleD.vcxproj.filters
@@ -139,18 +139,6 @@
{FEAEA931-9FBB-1723-2676-9115C88A7A91}
-
- {C0E15D88-0464-5647-4456-2B7D1D035D96}
-
-
- {9D06F3E0-B69D-2375-0CDB-EFADCCB10AA7}
-
-
- {4A5C6976-0040-11F9-2847-EF7966479B6D}
-
-
- {DE6FE26E-81A4-F99F-CCA4-6E59C53026D1}
-
{81C8331F-4768-BDE6-D058-29BDEE8F322C}
@@ -280,6 +268,9 @@
{44B63F90-BC60-A7C7-24A1-632A358E285B}
+
+ {29C76FB9-636F-FBFC-3CFA-2979281BC279}
+
{17F94278-7CDE-3EBE-7CD3-372F08902314}
@@ -550,9 +541,21 @@
{5A1D8022-39F2-67E1-FFBE-EA7D5BF9FBDB}
+
+ {AA927DBA-1AF8-6600-04B7-D1C1EBFB4103}
+
+
+ {5D2927A9-CC6E-DDE0-1654-5316177082DD}
+
+
+ {75E6832F-A6F7-8360-FA3A-7427A06A9959}
+
{D4BF99B9-6486-2124-6103-825710EDD595}
+
+ {FA8496D0-0D5F-AC6F-3422-DEAB4BA19ACA}
+
{EE7AC8C9-27EB-C05E-C986-EECB0174B997}
@@ -1377,105 +1380,6 @@
beast\module\core\time
-
- beast\module\sqdb\api
-
-
- beast\module\sqdb\api
-
-
- beast\module\sqdb\api
-
-
- beast\module\sqdb\api
-
-
- beast\module\sqdb\api
-
-
- beast\module\sqdb\api
-
-
- beast\module\sqdb\api
-
-
- beast\module\sqdb\api
-
-
- beast\module\sqdb\detail
-
-
- beast\module\sqdb\detail
-
-
- beast\module\sqdb\detail
-
-
- beast\module\sqdb\detail
-
-
- beast\module\sqdb\detail
-
-
- beast\module\sqdb\detail
-
-
- beast\module\sqdb\detail
-
-
- beast\module\sqdb\detail
-
-
- beast\module\sqdb\detail
-
-
- beast\module\sqdb\detail
-
-
- beast\module\sqdb\detail
-
-
- beast\module\sqdb\source
-
-
- beast\module\sqdb\source
-
-
- beast\module\sqdb\source
-
-
- beast\module\sqdb\source
-
-
- beast\module\sqdb\source
-
-
- beast\module\sqdb\source
-
-
- beast\module\sqdb\source
-
-
- beast\module\sqdb\source
-
-
- beast\module\sqdb\source
-
-
- beast\module\sqdb\source
-
-
- beast\module\sqdb\source
-
-
- beast\module\sqdb\source
-
-
- beast\module\sqdb
-
-
- beast\module\sqdb
-
beast\module\sqlite
@@ -2286,12 +2190,24 @@
ripple\app\data
+
+ ripple\app\data
+
+
+ ripple\app\data
+
+
+ ripple\app\data
+
ripple\app\data
ripple\app\data
+
+ ripple\app\data\tests
+
ripple\app\impl
@@ -5148,9 +5064,228 @@
snappy\snappy
+
+ soci\src\backends\postgresql
+
+
+ soci\src\backends\sqlite3
+
+
+ soci\src\backends\sqlite3
+
+
+ soci\src\backends\sqlite3
+
+
+ soci\src\backends\sqlite3
+
+
+ soci\src\backends\sqlite3
+
+
+ soci\src\backends\sqlite3
+
+
+ soci\src\backends\sqlite3
+
+
+ soci\src\backends\sqlite3
+
+
+ soci\src\backends\sqlite3
+
+
+ soci\src\backends\sqlite3
+
+
+ soci\src\backends\sqlite3
+
+
+ soci\src\backends\sqlite3
+
+
+ soci\src\core
+
+
+ soci\src\core
+
+
+ soci\src\core
+
+
+ soci\src\core
+
+
+ soci\src\core
+
+
+ soci\src\core
+
+
+ soci\src\core
+
+
+ soci\src\core
+
+
+ soci\src\core
+
+
+ soci\src\core
+
+
+ soci\src\core
+
+
+ soci\src\core
+
+
+ soci\src\core
+
+
+ soci\src\core
+
+
+ soci\src\core
+
+
+ soci\src\core
+
+
+ soci\src\core
+
+
+ soci\src\core
+
+
+ soci\src\core
+
+
+ soci\src\core
+
+
+ soci\src\core
+
+
+ soci\src\core
+
+
+ soci\src\core
+
+
+ soci\src\core
+
+
+ soci\src\core
+
+
+ soci\src\core
+
+
+ soci\src\core
+
+
+ soci\src\core
+
+
+ soci\src\core
+
+
+ soci\src\core
+
+
+ soci\src\core
+
+
+ soci\src\core
+
+
+ soci\src\core
+
+
+ soci\src\core
+
+
+ soci\src\core
+
+
+ soci\src\core
+
+
+ soci\src\core
+
+
+ soci\src\core
+
+
+ soci\src\core
+
+
+ soci\src\core
+
+
+ soci\src\core
+
+
+ soci\src\core
+
+
+ soci\src\core
+
+
+ soci\src\core
+
+
+ soci\src\core
+
+
+ soci\src\core
+
+
+ soci\src\core
+
+
+ soci\src\core
+
+
+ soci\src\core
+
+
+ soci\src\core
+
+
+ soci\src\core
+
+
+ soci\src\core
+
+
+ soci\src\core
+
+
+ soci\src\core
+
+
+ soci\src\core
+
+
+ soci\src\core
+
+
+ soci\src\core
+
+
+ soci\src\core
+
+
+ soci\src\core
+
soci\src\core
+
+ sqlite
+
websocketpp\websocketpp\base64
diff --git a/src/ripple/app/data/DummySociDynamicBackend.cpp b/src/ripple/app/data/DummySociDynamicBackend.cpp
new file mode 100644
index 0000000000..37bef26cbc
--- /dev/null
+++ b/src/ripple/app/data/DummySociDynamicBackend.cpp
@@ -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
+
+#include
+
+// 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& search_paths ()
+{
+ static std::vector empty;
+ return empty;
+};
+void register_backend (std::string const&, std::string const&){};
+void register_backend (std::string const&, backend_factory const&){};
+std::vector list_all ()
+{
+ return {};
+};
+void unload (std::string const&){};
+void unload_all (){};
+
+} // namespace dynamic_backends
+} // namespace soci
+
diff --git a/src/ripple/app/data/SociDB.cpp b/src/ripple/app/data/SociDB.cpp
new file mode 100644
index 0000000000..2a79487999
--- /dev/null
+++ b/src/ripple/app/data/SociDB.cpp
@@ -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
+
+#include
+#include
+#include
+#include //
+#include
+#if ENABLE_SOCI_POSTGRESQL
+#include
+#endif
+#include
+
+namespace ripple {
+namespace detail {
+
+std::pair
+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
+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 (configSection, "host", ""));
+ if (!host.empty())
+ {
+ throw std::runtime_error (
+ "Missing required value in config for postgresql backend: host");
+ }
+
+ std::string const user(get (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 (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
+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 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);
+}
+}
+
diff --git a/src/ripple/app/data/SociDB.h b/src/ripple/app/data/SociDB.h
new file mode 100644
index 0000000000..8c4e1566c5
--- /dev/null
+++ b/src/ripple/app/data/SociDB.h
@@ -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
+
+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 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
diff --git a/src/ripple/app/data/tests/SociDB.test.cpp b/src/ripple/app/data/tests/SociDB.test.cpp
new file mode 100644
index 0000000000..e10a44b826
--- /dev/null
+++ b/src/ripple/app/data/tests/SociDB.test.cpp
@@ -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
+
+#include
+#include
+#include
+#include
+#include
+#include
+
+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> 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 const stringData (
+ {"String1", "String2", "String3"});
+ std::vector const intData ({1, 2, 3});
+ auto checkValues = [this, &stringData, &intData](soci::session& s)
+ {
+ // Check values in db
+ std::vector stringResult (20 * stringData.size ());
+ std::vector 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
diff --git a/src/ripple/app/main/Application.cpp b/src/ripple/app/main/Application.cpp
index d4520f9c33..c582b811c2 100644
--- a/src/ripple/app/main/Application.cpp
+++ b/src/ripple/app/main/Application.cpp
@@ -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
{
diff --git a/src/ripple/app/main/Main.cpp b/src/ripple/app/main/Main.cpp
index cb703613ef..9650d90f28 100644
--- a/src/ripple/app/main/Main.cpp
+++ b/src/ripple/app/main/Main.cpp
@@ -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 app (make_Application (deprecatedLogs()));
using namespace beast::unit_test;
diff --git a/src/ripple/app/misc/SHAMapStore.h b/src/ripple/app/misc/SHAMapStore.h
index 5a1977ddaa..a07ec0d3e7 100644
--- a/src/ripple/app/misc/SHAMapStore.h
+++ b/src/ripple/app/misc/SHAMapStore.h
@@ -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
diff --git a/src/ripple/app/misc/SHAMapStoreImp.cpp b/src/ripple/app/misc/SHAMapStoreImp.cpp
index 570a91f45e..c223771eb0 100644
--- a/src/ripple/app/misc/SHAMapStoreImp.cpp
+++ b/src/ripple/app/misc/SHAMapStoreImp.cpp
@@ -18,92 +18,85 @@
//==============================================================================
#include
+
#include
#include
#include
#include
#include
#include //
+#include
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 lock (mutex_);
- std::lock_guard 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 lock (mutex_);
- {
- std::lock_guard 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 lock (mutex_);
+ std::lock_guard 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 lock (mutex_);
+ std::lock_guard 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 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 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 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 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 (s, parent, scheduler,
- journal, nodeStoreJournal, transactionMaster);
+ return std::make_unique(s, parent, scheduler,
+ journal, nodeStoreJournal, transactionMaster,
+ config);
}
}
diff --git a/src/ripple/app/misc/SHAMapStoreImp.h b/src/ripple/app/misc/SHAMapStoreImp.h
index 8163ca59a3..3bafa80fbc 100644
--- a/src/ripple/app/misc/SHAMapStoreImp.h
+++ b/src/ripple/app/misc/SHAMapStoreImp.h
@@ -23,9 +23,9 @@
#include
#include
#include
+#include
#include
#include
-#include
#include
#include
#include
diff --git a/src/ripple/core/ConfigSections.h b/src/ripple/core/ConfigSections.h
index 7c2d42b780..e3cde6de71 100644
--- a/src/ripple/core/ConfigSections.h
+++ b/src/ripple/core/ConfigSections.h
@@ -20,6 +20,8 @@
#ifndef RIPPLE_CORE_CONFIGSECTIONS_H_INCLUDED
#define RIPPLE_CORE_CONFIGSECTIONS_H_INCLUDED
+#include
+
namespace ripple {
// VFALCO DEPRECATED in favor of the BasicConfig interface
diff --git a/src/ripple/core/tests/Config.test.cpp b/src/ripple/core/tests/Config.test.cpp
index 573b14f3a4..23b0f27e93 100644
--- a/src/ripple/core/tests/Config.test.cpp
+++ b/src/ripple/core/tests/Config.test.cpp
@@ -20,6 +20,7 @@
#include
#include
#include
+#include
#include
#include
#include
diff --git a/src/ripple/overlay/impl/OverlayImpl.cpp b/src/ripple/overlay/impl/OverlayImpl.cpp
index 43b8f0959f..af7c93dfd3 100644
--- a/src/ripple/overlay/impl/OverlayImpl.cpp
+++ b/src/ripple/overlay/impl/OverlayImpl.cpp
@@ -121,9 +121,9 @@ OverlayImpl::OverlayImpl (
Stoppable& parent,
ServerHandler& serverHandler,
Resource::Manager& resourceManager,
- beast::File const& pathToDbFileOrDirectory,
Resolver& resolver,
- boost::asio::io_service& io_service)
+ boost::asio::io_service& io_service,
+ BasicConfig const& config)
: Overlay (parent)
, io_service_ (io_service)
, work_ (boost::in_place(std::ref(io_service_)))
@@ -133,8 +133,7 @@ OverlayImpl::OverlayImpl (
, serverHandler_(serverHandler)
, m_resourceManager (resourceManager)
, m_peerFinder (PeerFinder::make_Manager (*this, io_service,
- pathToDbFileOrDirectory, get_seconds_clock(),
- deprecatedLogs().journal("PeerFinder")))
+ get_seconds_clock(), deprecatedLogs().journal("PeerFinder"), config))
, m_resolver (resolver)
, next_id_(1)
{
@@ -752,12 +751,12 @@ make_Overlay (
beast::Stoppable& parent,
ServerHandler& serverHandler,
Resource::Manager& resourceManager,
- beast::File const& pathToDbFileOrDirectory,
Resolver& resolver,
- boost::asio::io_service& io_service)
+ boost::asio::io_service& io_service,
+ BasicConfig const& config)
{
return std::make_unique (setup, parent, serverHandler,
- resourceManager, pathToDbFileOrDirectory, resolver, io_service);
+ resourceManager, resolver, io_service, config);
}
}
diff --git a/src/ripple/overlay/impl/OverlayImpl.h b/src/ripple/overlay/impl/OverlayImpl.h
index cf412ab133..45ce13dfd1 100644
--- a/src/ripple/overlay/impl/OverlayImpl.h
+++ b/src/ripple/overlay/impl/OverlayImpl.h
@@ -44,6 +44,7 @@
namespace ripple {
class PeerImp;
+class BasicConfig;
class OverlayImpl : public Overlay
{
@@ -122,8 +123,8 @@ private:
public:
OverlayImpl (Setup const& setup, Stoppable& parent,
ServerHandler& serverHandler, Resource::Manager& resourceManager,
- beast::File const& pathToDbFileOrDirectory,
- Resolver& resolver, boost::asio::io_service& io_service);
+ Resolver& resolver, boost::asio::io_service& io_service,
+ BasicConfig const& config);
~OverlayImpl();
diff --git a/src/ripple/overlay/make_Overlay.h b/src/ripple/overlay/make_Overlay.h
index 0408249ea0..12aaa7f5b7 100644
--- a/src/ripple/overlay/make_Overlay.h
+++ b/src/ripple/overlay/make_Overlay.h
@@ -41,9 +41,9 @@ make_Overlay (
beast::Stoppable& parent,
ServerHandler& serverHandler,
Resource::Manager& resourceManager,
- beast::File const& pathToDbFileOrDirectory,
Resolver& resolver,
- boost::asio::io_service& io_service);
+ boost::asio::io_service& io_service,
+ BasicConfig const& config);
} // ripple
diff --git a/src/ripple/peerfinder/impl/Manager.cpp b/src/ripple/peerfinder/impl/Manager.cpp
index 6770ea9866..d8f1a2e8c8 100644
--- a/src/ripple/peerfinder/impl/Manager.cpp
+++ b/src/ripple/peerfinder/impl/Manager.cpp
@@ -23,6 +23,7 @@
#include
#include
#include
+#include
#include
#include
#include //
@@ -37,33 +38,31 @@ class ManagerImp
public:
boost::asio::io_service &io_service_;
boost::optional work_;
- beast::File m_databaseFile;
clock_type& m_clock;
beast::Journal m_journal;
StoreSqdb m_store;
Checker checker_;
Logic m_logic;
+ SociConfig m_sociConfig;
//--------------------------------------------------------------------------
ManagerImp (
Stoppable& stoppable,
boost::asio::io_service& io_service,
- beast::File const& pathToDbFileOrDirectory,
clock_type& clock,
- beast::Journal journal)
+ beast::Journal journal,
+ BasicConfig const& config)
: Manager (stoppable)
, io_service_(io_service)
, work_(boost::in_place(std::ref(io_service_)))
- , m_databaseFile (pathToDbFileOrDirectory)
, m_clock (clock)
, m_journal (journal)
, m_store (journal)
, checker_ (io_service_)
, m_logic (clock, m_store, checker_, journal)
+ , m_sociConfig (config, "peerfinder")
{
- if (m_databaseFile.isDirectory ())
- m_databaseFile = m_databaseFile.getChildFile("peerfinder.sqlite");
}
~ManagerImp()
@@ -214,12 +213,8 @@ public:
void
onPrepare ()
{
- beast::Error error (m_store.open (m_databaseFile));
- if (error)
- m_journal.fatal <<
- "Failed to open '" << m_databaseFile.getFullPathName() << "'";
- if (! error)
- m_logic.load ();
+ m_store.open (m_sociConfig);
+ m_logic.load ();
}
void
@@ -255,10 +250,10 @@ Manager::Manager (Stoppable& parent)
std::unique_ptr
make_Manager (beast::Stoppable& parent, boost::asio::io_service& io_service,
- beast::File const& databaseFile, clock_type& clock, beast::Journal journal)
+ clock_type& clock, beast::Journal journal, BasicConfig const& config)
{
return std::make_unique (
- parent, io_service, databaseFile, clock, journal);
+ parent, io_service, clock, journal, config);
}
}
diff --git a/src/ripple/peerfinder/impl/StoreSqdb.h b/src/ripple/peerfinder/impl/StoreSqdb.h
index 81163a758b..91864daee6 100644
--- a/src/ripple/peerfinder/impl/StoreSqdb.h
+++ b/src/ripple/peerfinder/impl/StoreSqdb.h
@@ -20,7 +20,7 @@
#ifndef RIPPLE_PEERFINDER_STORESQDB_H_INCLUDED
#define RIPPLE_PEERFINDER_STORESQDB_H_INCLUDED
-#include
+#include
#include
namespace ripple {
@@ -32,8 +32,7 @@ class StoreSqdb
{
private:
beast::Journal m_journal;
- beast::sqdb::session m_session;
-
+ soci::session m_session;
public:
enum
{
@@ -50,19 +49,15 @@ public:
{
}
- beast::Error open (beast::File const& file)
+ void open (SociConfig const& sociConfig)
{
- beast::Error error (m_session.open (file.getFullPathName ()));
+ sociConfig.open (m_session);
- m_journal.info << "Opening database at '" << file.getFullPathName() << "'";
+ m_journal.info << "Opening database at '" << sociConfig.connectionString ()
+ << "'";
- if (! error)
- error = init ();
-
- if (! error)
- error = update ();
-
- return error;
+ init ();
+ update ();
}
// Loads the bootstrap cache, calling the callback for each entry
@@ -70,42 +65,34 @@ public:
std::size_t load (load_callback const& cb)
{
std::size_t n (0);
- beast::Error error;
std::string s;
int valence;
- beast::sqdb::statement st = (m_session.prepare <<
+ soci::statement st = (m_session.prepare <<
"SELECT "
" address, "
" valence "
"FROM PeerFinder_BootstrapCache "
- , beast::sqdb::into (s)
- , beast::sqdb::into (valence)
+ , soci::into (s)
+ , soci::into (valence)
);
- if (st.execute_and_fetch (error))
+ st.execute ();
+ while (st.fetch ())
{
- do
+ beast::IP::Endpoint const endpoint (
+ beast::IP::Endpoint::from_string (s));
+
+ if (!is_unspecified (endpoint))
{
- beast::IP::Endpoint const endpoint (
- beast::IP::Endpoint::from_string (s));
-
- if (! is_unspecified (endpoint))
- {
- cb (endpoint, valence);
- ++n;
- }
- else
- {
- m_journal.error <<
- "Bad address string '" << s << "' in Bootcache table";
- }
+ cb (endpoint, valence);
+ ++n;
+ }
+ else
+ {
+ m_journal.error <<
+ "Bad address string '" << s << "' in Bootcache table";
}
- while (st.fetch (error));
}
-
- if (error)
- report (error, __FILE__, __LINE__);
-
return n;
}
@@ -113,306 +100,237 @@ public:
//
void save (std::vector const& v)
{
- beast::Error error;
- beast::sqdb::transaction tr (m_session);
- m_session.once (error) <<
+ soci::transaction tr (m_session);
+ m_session <<
"DELETE FROM PeerFinder_BootstrapCache";
- if (! error)
+ std::string s;
+ int valence;
+
+ soci::statement st = (m_session.prepare <<
+ "INSERT INTO PeerFinder_BootstrapCache ( "
+ " address, "
+ " valence "
+ ") VALUES ( "
+ " :s, :valence "
+ ");"
+ , soci::use (s)
+ , soci::use (valence)
+ );
+
+ for (auto const& e : v)
{
- std::string s;
- int valence;
-
- beast::sqdb::statement st = (m_session.prepare <<
- "INSERT INTO PeerFinder_BootstrapCache ( "
- " address, "
- " valence "
- ") VALUES ( "
- " ?, ? "
- ");"
- , beast::sqdb::use (s)
- , beast::sqdb::use (valence)
- );
-
- for (auto const& e : v)
- {
- s = to_string (e.endpoint);
- valence = e.valence;
- st.execute_and_fetch (error);
- if (error)
- break;
- }
+ s = to_string (e.endpoint);
+ valence = e.valence;
+ st.execute ();
+ st.fetch ();
}
- if (! error)
- error = tr.commit();
-
- if (error)
- {
- tr.rollback ();
- report (error, __FILE__, __LINE__);
- }
+ tr.commit ();
}
// Convert any existing entries from an older schema to the
// current one, if appropriate.
- //
- beast::Error update ()
+ void update ()
{
- beast::Error error;
-
- beast::sqdb::transaction tr (m_session);
-
+ soci::transaction tr (m_session);
// get version
int version (0);
- if (! error)
{
- m_session.once (error) <<
+ m_session <<
"SELECT "
" version "
"FROM SchemaVersion WHERE "
" name = 'PeerFinder'"
- ,beast::sqdb::into (version)
+ , soci::into (version)
;
- if (! error)
- {
- if (!m_session.got_data())
- version = 0;
+ if (!m_session.got_data ())
+ version = 0;
- m_journal.info <<
- "Opened version " << version << " database";
- }
+ m_journal.info <<
+ "Opened version " << version << " database";
}
- if (!error)
{
if (version < currentSchemaVersion)
m_journal.info <<
"Updating database to version " << currentSchemaVersion;
else if (version > currentSchemaVersion)
- error.fail (__FILE__, __LINE__,
+ {
+ throw std::runtime_error (
"The PeerFinder database version is higher than expected");
+ }
}
- if (! error && version < 4)
+ if (version < 4)
{
//
// Remove the "uptime" column from the bootstrap table
//
- if (! error)
- m_session.once (error) <<
- "CREATE TABLE IF NOT EXISTS PeerFinder_BootstrapCache_Next ( "
- " id INTEGER PRIMARY KEY AUTOINCREMENT, "
- " address TEXT UNIQUE NOT NULL, "
- " valence INTEGER"
- ");"
- ;
-
- if (! error)
- m_session.once (error) <<
- "CREATE INDEX IF NOT EXISTS "
- " PeerFinder_BootstrapCache_Next_Index ON "
- " PeerFinder_BootstrapCache_Next "
- " ( address ); "
- ;
-
- std::size_t count;
- if (! error)
- m_session.once (error) <<
- "SELECT COUNT(*) FROM PeerFinder_BootstrapCache "
- ,beast::sqdb::into (count)
- ;
-
- std::vector list;
-
- if (! error)
- {
- list.reserve (count);
- std::string s;
- int valence;
- beast::sqdb::statement st = (m_session.prepare <<
- "SELECT "
- " address, "
- " valence "
- "FROM PeerFinder_BootstrapCache "
- , beast::sqdb::into (s)
- , beast::sqdb::into (valence)
- );
-
- if (st.execute_and_fetch (error))
- {
- do
- {
- Store::Entry entry;
- entry.endpoint = beast::IP::Endpoint::from_string (s);
- if (! is_unspecified (entry.endpoint))
- {
- entry.valence = valence;
- list.push_back (entry);
- }
- else
- {
- m_journal.error <<
- "Bad address string '" << s << "' in Bootcache table";
- }
- }
- while (st.fetch (error));
- }
- }
-
- if (! error)
- {
- std::string s;
- int valence;
- beast::sqdb::statement st = (m_session.prepare <<
- "INSERT INTO PeerFinder_BootstrapCache_Next ( "
- " address, "
- " valence "
- ") VALUES ( "
- " ?, ?"
- ");"
- , beast::sqdb::use (s)
- , beast::sqdb::use (valence)
- );
-
- for (auto iter (list.cbegin());
- !error && iter != list.cend(); ++iter)
- {
- s = to_string (iter->endpoint);
- valence = iter->valence;
- st.execute_and_fetch (error);
- }
-
- }
-
- if (! error)
- m_session.once (error) <<
- "DROP TABLE IF EXISTS PeerFinder_BootstrapCache";
-
- if (! error)
- m_session.once (error) <<
- "DROP INDEX IF EXISTS PeerFinder_BootstrapCache_Index";
-
- if (! error)
- m_session.once (error) <<
- "ALTER TABLE PeerFinder_BootstrapCache_Next "
- " RENAME TO PeerFinder_BootstrapCache";
-
- if (! error)
- m_session.once (error) <<
- "CREATE INDEX IF NOT EXISTS "
- " PeerFinder_BootstrapCache_Index ON PeerFinder_BootstrapCache "
- " ( "
- " address "
- " ); "
- ;
- }
-
- if (! error && version < 3)
- {
- //
- // Remove legacy endpoints from the schema
- //
-
- if (! error)
- m_session.once (error) <<
- "DROP TABLE IF EXISTS LegacyEndpoints";
-
- if (! error)
- m_session.once (error) <<
- "DROP TABLE IF EXISTS PeerFinderLegacyEndpoints";
-
- if (! error)
- m_session.once (error) <<
- "DROP TABLE IF EXISTS PeerFinder_LegacyEndpoints";
-
- if (! error)
- m_session.once (error) <<
- "DROP TABLE IF EXISTS PeerFinder_LegacyEndpoints_Index";
- }
-
- if (! error)
- {
- int const version (currentSchemaVersion);
- m_session.once (error) <<
- "INSERT OR REPLACE INTO SchemaVersion ("
- " name "
- " ,version "
- ") VALUES ( "
- " 'PeerFinder', ? "
- ")"
- ,beast::sqdb::use(version);
- }
-
- if (! error)
- error = tr.commit();
-
- if (error)
- {
- tr.rollback();
- report (error, __FILE__, __LINE__);
- }
-
- return error;
- }
-
-private:
- beast::Error init ()
- {
- beast::Error error;
- beast::sqdb::transaction tr (m_session);
-
- if (! error)
- m_session.once (error) <<
- "PRAGMA encoding=\"UTF-8\"";
-
- if (! error)
- m_session.once (error) <<
- "CREATE TABLE IF NOT EXISTS SchemaVersion ( "
- " name TEXT PRIMARY KEY, "
- " version INTEGER"
- ");"
- ;
-
- if (! error)
- m_session.once (error) <<
- "CREATE TABLE IF NOT EXISTS PeerFinder_BootstrapCache ( "
+ m_session <<
+ "CREATE TABLE IF NOT EXISTS PeerFinder_BootstrapCache_Next ( "
" id INTEGER PRIMARY KEY AUTOINCREMENT, "
" address TEXT UNIQUE NOT NULL, "
" valence INTEGER"
");"
;
- if (! error)
- m_session.once (error) <<
+ m_session <<
"CREATE INDEX IF NOT EXISTS "
- " PeerFinder_BootstrapCache_Index ON PeerFinder_BootstrapCache "
+ " PeerFinder_BootstrapCache_Next_Index ON "
+ " PeerFinder_BootstrapCache_Next "
+ " ( address ); "
+ ;
+
+ std::size_t count;
+ m_session <<
+ "SELECT COUNT(*) FROM PeerFinder_BootstrapCache "
+ , soci::into (count)
+ ;
+
+ std::vector list;
+
+ {
+ list.reserve (count);
+ std::string s;
+ int valence;
+ soci::statement st = (m_session.prepare <<
+ "SELECT "
+ " address, "
+ " valence "
+ "FROM PeerFinder_BootstrapCache "
+ , soci::into (s)
+ , soci::into (valence)
+ );
+
+ st.execute ();
+ while (st.fetch ())
+ {
+ Store::Entry entry;
+ entry.endpoint = beast::IP::Endpoint::from_string (s);
+ if (!is_unspecified (entry.endpoint))
+ {
+ entry.valence = valence;
+ list.push_back (entry);
+ }
+ else
+ {
+ m_journal.error <<
+ "Bad address string '" << s << "' in Bootcache table";
+ }
+ }
+ }
+
+ {
+ std::string s;
+ int valence;
+ soci::statement st = (m_session.prepare <<
+ "INSERT INTO PeerFinder_BootstrapCache_Next ( "
+ " address, "
+ " valence "
+ ") VALUES ( "
+ " :s, :valence"
+ ");"
+ , soci::use (s)
+ , soci::use (valence)
+ );
+
+ for (auto iter (list.cbegin ());
+ iter != list.cend (); ++iter)
+ {
+ s = to_string (iter->endpoint);
+ valence = iter->valence;
+ st.execute ();
+ st.fetch ();
+ }
+ }
+
+ m_session <<
+ "DROP TABLE IF EXISTS PeerFinder_BootstrapCache";
+
+ m_session <<
+ "DROP INDEX IF EXISTS PeerFinder_BootstrapCache_Index";
+
+ m_session <<
+ "ALTER TABLE PeerFinder_BootstrapCache_Next "
+ " RENAME TO PeerFinder_BootstrapCache";
+
+ m_session <<
+ "CREATE INDEX IF NOT EXISTS "
+ " PeerFinder_BootstrapCache_Index ON "
+ "PeerFinder_BootstrapCache "
" ( "
" address "
" ); "
;
-
- if (! error)
- error = tr.commit();
-
- if (error)
- {
- tr.rollback ();
- report (error, __FILE__, __LINE__);
}
- return error;
+ if (version < 3)
+ {
+ //
+ // Remove legacy endpoints from the schema
+ //
+
+ m_session <<
+ "DROP TABLE IF EXISTS LegacyEndpoints";
+
+ m_session <<
+ "DROP TABLE IF EXISTS PeerFinderLegacyEndpoints";
+
+ m_session <<
+ "DROP TABLE IF EXISTS PeerFinder_LegacyEndpoints";
+
+ m_session <<
+ "DROP TABLE IF EXISTS PeerFinder_LegacyEndpoints_Index";
+ }
+
+ {
+ int const version (currentSchemaVersion);
+ m_session <<
+ "INSERT OR REPLACE INTO SchemaVersion ("
+ " name "
+ " ,version "
+ ") VALUES ( "
+ " 'PeerFinder', :version "
+ ")"
+ , soci::use (version);
+ }
+
+ tr.commit ();
}
- void report (beast::Error const& error, char const* fileName, int lineNumber)
+private:
+ void init ()
{
- if (error)
- {
- m_journal.error <<
- "Failure: '"<< error.getReasonText() << "' " <<
- " at " << beast::Debug::getSourceLocation (fileName, lineNumber);
- }
+ soci::transaction tr (m_session);
+ m_session << "PRAGMA encoding=\"UTF-8\"";
+
+ m_session <<
+ "CREATE TABLE IF NOT EXISTS SchemaVersion ( "
+ " name TEXT PRIMARY KEY, "
+ " version INTEGER"
+ ");"
+ ;
+
+ m_session <<
+ "CREATE TABLE IF NOT EXISTS PeerFinder_BootstrapCache ( "
+ " id INTEGER PRIMARY KEY AUTOINCREMENT, "
+ " address TEXT UNIQUE NOT NULL, "
+ " valence INTEGER"
+ ");"
+ ;
+
+ m_session <<
+ "CREATE INDEX IF NOT EXISTS "
+ " PeerFinder_BootstrapCache_Index ON "
+ "PeerFinder_BootstrapCache "
+ " ( "
+ " address "
+ " ); "
+ ;
+
+ tr.commit ();
}
};
diff --git a/src/ripple/peerfinder/make_Manager.h b/src/ripple/peerfinder/make_Manager.h
index aaf6d507fe..9cc8e681e9 100644
--- a/src/ripple/peerfinder/make_Manager.h
+++ b/src/ripple/peerfinder/make_Manager.h
@@ -30,8 +30,7 @@ namespace PeerFinder {
/** Create a new Manager. */
std::unique_ptr
make_Manager (beast::Stoppable& parent, boost::asio::io_service& io_service,
- beast::File const& pathToDbFileOrDirectory,
- clock_type& clock, beast::Journal journal);
+ clock_type& clock, beast::Journal journal, BasicConfig const& config);
}
}
diff --git a/src/ripple/unity/beast.cpp b/src/ripple/unity/beast.cpp
index 046e41ab91..0bf92635ce 100644
--- a/src/ripple/unity/beast.cpp
+++ b/src/ripple/unity/beast.cpp
@@ -30,7 +30,6 @@
// Include this to get all the basic includes included, to prevent errors
#include
#include
-#include
#include
#include
diff --git a/src/ripple/unity/soci.cpp b/src/ripple/unity/soci.cpp
new file mode 100644
index 0000000000..f889dfdd01
--- /dev/null
+++ b/src/ripple/unity/soci.cpp
@@ -0,0 +1,51 @@
+//------------------------------------------------------------------------------
+/*
+ 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
+
+// Core soci
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+#include
+#include
diff --git a/src/ripple/unity/soci_ripple.cpp b/src/ripple/unity/soci_ripple.cpp
new file mode 100644
index 0000000000..9a9af2ad1d
--- /dev/null
+++ b/src/ripple/unity/soci_ripple.cpp
@@ -0,0 +1,24 @@
+//------------------------------------------------------------------------------
+/*
+ This file is part of rippled: https://github.com/ripple/rippled
+ Copyright (c) 2012, 2013 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
+
+#include
+#include
+#include
diff --git a/src/ripple/unity/socipostgresql.cpp b/src/ripple/unity/socipostgresql.cpp
new file mode 100644
index 0000000000..b8e00c50eb
--- /dev/null
+++ b/src/ripple/unity/socipostgresql.cpp
@@ -0,0 +1,48 @@
+//------------------------------------------------------------------------------
+/*
+ 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.
+*/
+//==============================================================================
+
+#if ENABLE_SOCI_POSTGRESQL
+
+#if BEAST_INCLUDE_BEASTCONFIG
+#include
+#endif
+
+#include
+
+#if BEAST_MSVC
+#define SOCI_LIB_PREFIX ""
+#define SOCI_LIB_SUFFIX ".dll"
+#else
+#define SOCI_LIB_PREFIX "lib"
+#define SOCI_LIB_SUFFIX ".so"
+#endif
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+#endif // ENABLE_SOCI_POSTGRESQL
diff --git a/src/ripple/validators/impl/Manager.cpp b/src/ripple/validators/impl/Manager.cpp
index 0b45680575..4b854db965 100644
--- a/src/ripple/validators/impl/Manager.cpp
+++ b/src/ripple/validators/impl/Manager.cpp
@@ -206,24 +206,21 @@ public:
boost::asio::basic_waitable_timer<
std::chrono::steady_clock> timer_;
beast::Journal journal_;
- beast::File dbFile_;
StoreSqdb store_;
Logic logic_;
+ SociConfig sociConfig_;
ManagerImp (Stoppable& parent, boost::asio::io_service& io_service,
- beast::File const& pathToDbFileOrDirectory, beast::Journal journal)
+ beast::Journal journal, BasicConfig const& config)
: Stoppable ("Validators::Manager", parent)
, io_service_(io_service)
, strand_(io_service_)
, timer_(io_service_)
, journal_ (journal)
- , dbFile_ (pathToDbFileOrDirectory)
, store_ (journal_)
, logic_ (store_, journal_)
+ , sociConfig_ (config, "validators")
{
- if (dbFile_.isDirectory ())
- dbFile_ = dbFile_.getChildFile("validators.sqlite");
-
}
~ManagerImp()
@@ -293,12 +290,8 @@ public:
void init()
{
- beast::Error error (store_.open (dbFile_));
-
- if (! error)
- {
- logic_.load ();
- }
+ store_.open (sociConfig_);
+ logic_.load ();
}
void
@@ -331,12 +324,11 @@ Manager::Manager ()
std::unique_ptr
make_Manager(beast::Stoppable& parent,
boost::asio::io_service& io_service,
- beast::File const& pathToDbFileOrDirectory,
- beast::Journal journal)
+ beast::Journal journal,
+ BasicConfig const& config)
{
- return std::make_unique (parent,
- io_service, pathToDbFileOrDirectory, journal);
-}
-
+ return std::make_unique(parent,
+ io_service, journal, config);
+}
}
}
diff --git a/src/ripple/validators/impl/StoreSqdb.cpp b/src/ripple/validators/impl/StoreSqdb.cpp
index ed97d49ad2..9efbb244db 100644
--- a/src/ripple/validators/impl/StoreSqdb.cpp
+++ b/src/ripple/validators/impl/StoreSqdb.cpp
@@ -35,19 +35,12 @@ StoreSqdb::~StoreSqdb ()
{
}
-beast::Error
-StoreSqdb::open (beast::File const& file)
+void
+StoreSqdb::open (SociConfig const& sociConfig)
{
- beast::Error error (m_session.open (file.getFullPathName ()));
+ sociConfig.open (m_session);
- m_journal.info <<
- "Opening " << file.getFullPathName();
-
- if (error)
- m_journal.error <<
- "Failed opening database: " << error.what();
-
- return error;
+ m_journal.info << "Opening " << sociConfig.connectionString ();
}
}
diff --git a/src/ripple/validators/impl/StoreSqdb.h b/src/ripple/validators/impl/StoreSqdb.h
index 863438b1a0..4df8dbb614 100644
--- a/src/ripple/validators/impl/StoreSqdb.h
+++ b/src/ripple/validators/impl/StoreSqdb.h
@@ -22,9 +22,8 @@
#include
#include
-#include
-#include
#include
+#include
namespace ripple {
namespace Validators {
@@ -34,7 +33,7 @@ class StoreSqdb : public Store
{
private:
beast::Journal m_journal;
- beast::sqdb::session m_session;
+ soci::session m_session;
public:
enum
@@ -48,8 +47,8 @@ public:
~StoreSqdb();
- beast::Error
- open (beast::File const& file);
+ void
+ open (SociConfig const& sociConfig);
};
}
diff --git a/src/ripple/validators/make_Manager.h b/src/ripple/validators/make_Manager.h
index 07ca2cb47b..8e53b2d2e8 100644
--- a/src/ripple/validators/make_Manager.h
+++ b/src/ripple/validators/make_Manager.h
@@ -28,13 +28,14 @@
#include
namespace ripple {
+class BasicConfig;
namespace Validators {
std::unique_ptr
make_Manager (beast::Stoppable& stoppableParent,
boost::asio::io_service& io_service,
- beast::File const& pathToDbFileOrDirectory,
- beast::Journal journal);
+ beast::Journal journal,
+ BasicConfig const& config);
}
}
diff --git a/src/sqlite/sqlite3.h b/src/sqlite/sqlite3.h
new file mode 100644
index 0000000000..54740f0237
--- /dev/null
+++ b/src/sqlite/sqlite3.h
@@ -0,0 +1 @@
+#include