20 #if defined(__clang__)
21 #pragma clang diagnostic push
22 #pragma clang diagnostic ignored "-Wdeprecated"
25 #include <ripple/basics/ByteUtilities.h>
26 #include <ripple/basics/contract.h>
27 #include <ripple/core/Config.h>
28 #include <ripple/core/ConfigSections.h>
29 #include <ripple/core/SociDB.h>
30 #include <boost/filesystem.hpp>
32 #include <soci/sqlite3/soci-sqlite3.h>
48 Throw<std::runtime_error>(
49 "Sqlite databases must specify a dir and a name. Name: " + name +
52 boost::filesystem::path file(dir);
53 if (is_directory(file))
61 auto const& section = config.
section(
"sqdb");
62 auto const backendName =
get(section,
"backend",
"sqlite");
64 if (backendName !=
"sqlite")
65 Throw<std::runtime_error>(
"Unsupported soci backend: " + backendName);
67 auto const path = config.
legacy(
"database_path");
69 dbName ==
"validators" || dbName ==
"peerfinder" ?
".sqlite" :
".db";
77 : connectionString_(
std::move(init.first)), backendFactory_(init.second)
82 :
SociConfig(detail::getSociInit(config, dbName))
110 if (beName ==
"sqlite")
111 s.open(soci::sqlite3, connectionString);
113 Throw<std::runtime_error>(
"Unsupported soci backend: " + beName);
116 static sqlite_api::sqlite3*
119 sqlite_api::sqlite3* result =
nullptr;
120 auto be = s.get_backend();
121 if (
auto b =
dynamic_cast<soci::sqlite3_session_backend*
>(be))
125 Throw<std::logic_error>(
"Didn't get a database connection.");
134 Throw<std::logic_error>(
"No connection found.");
135 return static_cast<size_t>(
136 sqlite_api::sqlite3_memory_used() /
kilobytes(1));
145 int cur = 0, hiw = 0;
146 sqlite_api::sqlite3_db_status(
147 conn, SQLITE_DBSTATUS_CACHE_USED, &cur, &hiw, 0);
150 Throw<std::logic_error>(
"");
157 to.
resize(from.get_len());
160 from.read(0,
reinterpret_cast<char*
>(&to[0]), from.get_len());
175 to.write(0,
reinterpret_cast<char const*
>(&from[0]), from.
size());
184 to.write(0, from.
data(), from.
size());
199 class WALCheckpointer :
public Checkpointer
202 WALCheckpointer(sqlite_api::sqlite3& conn, JobQueue& q, Logs& logs)
203 : conn_(conn), jobQueue_(q), j_(logs.journal(
"WALCheckpointer"))
205 sqlite_api::sqlite3_wal_hook(&conn_, &sqliteWALHook,
this);
208 ~WALCheckpointer()
override =
default;
211 sqlite_api::sqlite3& conn_;
215 bool running_ =
false;
221 sqlite_api::sqlite3*,
227 if (
auto checkpointer =
reinterpret_cast<WALCheckpointer*
>(cp))
228 checkpointer->scheduleCheckpoint();
230 Throw<std::logic_error>(
"Didn't get a WALCheckpointer");
246 if (!jobQueue_.addJob(
jtWAL,
"WAL", [
this](Job&) { checkpoint(); }))
256 int log = 0, ckpt = 0;
257 int ret = sqlite3_wal_checkpoint_v2(
258 &conn_,
nullptr, SQLITE_CHECKPOINT_PASSIVE, &log, &ckpt);
260 auto fname = sqlite3_db_filename(&conn_,
"main");
261 if (ret != SQLITE_OK)
263 auto jm = (ret == SQLITE_LOCKED) ? j_.
trace() : j_.
warn();
264 JLOG(jm) <<
"WAL(" << fname <<
"): error " << ret;
268 JLOG(j_.
trace()) <<
"WAL(" << fname <<
"): frames=" <<
log
269 <<
", written=" << ckpt;
283 return std::make_unique<WALCheckpointer>(*conn, queue, logs);
289 #if defined(__clang__)
290 #pragma clang diagnostic pop