1#include <xrpl/basics/Log.h>
2#include <xrpl/config/BasicConfig.h>
3#include <xrpl/config/Constants.h>
4#include <xrpl/core/Job.h>
5#include <xrpl/core/JobQueue.h>
6#include <xrpl/core/ServiceRegistry.h>
8#include <boost/filesystem/operations.hpp>
9#include <boost/filesystem/path.hpp>
21#pragma clang diagnostic push
22#pragma clang diagnostic ignored "-Wdeprecated"
25#include <xrpl/basics/ByteUtilities.h>
26#include <xrpl/basics/contract.h>
27#include <xrpl/rdb/DatabaseCon.h>
28#include <xrpl/rdb/SociDB.h>
30#include <soci/sqlite3/soci-sqlite3.h>
46 "Sqlite databases must specify a dir and a name. Name: " + name +
" Dir: " + dir);
48 boost::filesystem::path file(dir);
49 if (is_directory(file))
60 if (backendName !=
"sqlite")
64 auto const ext = dbName ==
"validators" || dbName ==
"peerfinder" ?
".sqlite" :
".db";
100 if (beName ==
"sqlite")
102 s.open(soci::sqlite3, connectionString);
110static sqlite_api::sqlite3*
113 sqlite_api::sqlite3* result =
nullptr;
114 auto be = s.get_backend();
115 if (
auto b =
dynamic_cast<soci::sqlite3_session_backend*
>(be))
118 if (result ==
nullptr)
129 return static_cast<size_t>(sqlite_api::sqlite3_memory_used() /
kilobytes(1));
138 int cur = 0, hiw = 0;
139 sqlite_api::sqlite3_db_status(conn, SQLITE_DBSTATUS_CACHE_USED, &cur, &hiw, 0);
149 to.
resize(from.get_len());
152 from.read(0,
reinterpret_cast<char*
>(&to[0]), from.get_len());
168 to.write(0,
reinterpret_cast<char const*
>(&from[0]), from.
size());
181 to.write(0, from.
data(), from.
size());
200class WALCheckpointer :
public Checkpointer
207 ServiceRegistry& registry)
209 , session_(
std::move(session))
211 , j_(registry.getJournal(
"WALCheckpointer"))
216 sqlite_api::sqlite3_wal_hook(conn, &sqliteWALHook,
reinterpret_cast<void*
>(id_));
220 std::pair<sqlite_api::sqlite3*, std::shared_ptr<soci::session>>
223 if (
auto p = session_.lock())
227 return {
nullptr, std::shared_ptr<soci::session>{}};
236 ~WALCheckpointer()
override =
default;
242 std::scoped_lock
const lock(mutex_);
249 if (!jobQueue_.addJob(
257 [wp = std::weak_ptr<Checkpointer>{shared_from_this()}]() {
258 if (auto self = wp.lock())
262 std::scoped_lock
const lock(mutex_);
268 checkpoint()
override
275 int log = 0, ckpt = 0;
276 int const ret = sqlite_api::sqlite3_wal_checkpoint_v2(
277 conn,
nullptr, SQLITE_CHECKPOINT_PASSIVE, &log, &ckpt);
279 auto fname = sqlite_api::sqlite3_db_filename(conn,
"main");
280 if (ret != SQLITE_OK)
282 auto jm = (ret == SQLITE_LOCKED) ? j_.trace() : j_.warn();
283 JLOG(jm) <<
"WAL(" << fname <<
"): error " << ret;
287 JLOG(j_.trace()) <<
"WAL(" << fname <<
"): frames=" <<
log <<
", written=" << ckpt;
290 std::scoped_lock
const lock(mutex_);
295 std::uintptr_t
const id_;
299 std::weak_ptr<soci::session> session_;
303 bool running_ =
false;
304 beast::Journal
const j_;
307 sqliteWALHook(
void* cpId, sqlite_api::sqlite3* conn,
char const* dbName,
int walSize)
313 checkpointer->schedule();
317 sqlite_api::sqlite3_wal_hook(conn,
nullptr,
nullptr);
326std::shared_ptr<Checkpointer>
338#if defined(__clang__)
339#pragma clang diagnostic pop
Holds unparsed configuration information.
void legacy(std::string const §ion, std::string value)
Set a value that is not a key/value pair.
Section & section(std::string const &name)
Returns the section with the given name.
DBConfig is used when a client wants to delay opening a soci::session after parsing the config parame...
void open(soci::session &s) const
std::string connectionString() const
DBConfig(std::string dbPath)
std::string connectionString_
A pool of threads to perform work.
Service registry for dependency injection.
std::string getSociSqliteInit(std::string const &name, std::string const &dir, std::string const &ext)
std::string getSociInit(BasicConfig const &config, std::string const &dbName)
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
T get(Section const §ion, std::string const &name, T const &defaultValue=T{})
Retrieve a key/value pair from a section.
std::uint32_t getKBUsedDB(soci::session &s)
static auto gCheckpointPageCount
static sqlite_api::sqlite3 * getConnection(soci::session &s)
std::uint32_t getKBUsedAll(soci::session &s)
void open(soci::session &s, BasicConfig const &config, std::string const &dbName)
Open a soci session.
constexpr auto kilobytes(T value) noexcept
std::shared_ptr< Checkpointer > makeCheckpointer(std::uintptr_t id, std::weak_ptr< soci::session >, JobQueue &, ServiceRegistry &)
Returns a new checkpointer which makes checkpoints of a soci database every checkpointPageCount pages...
void convert(soci::blob &from, std::vector< std::uint8_t > &to)
std::shared_ptr< Checkpointer > checkpointerFromId(std::uintptr_t id)
XRPL_NO_SANITIZE_ADDRESS void Throw(Args &&... args)
static constexpr auto kBackend
static constexpr auto kSqdb
static constexpr auto kDatabasePath