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/DatabaseCon.h>
30 #include <ripple/core/SociDB.h>
31 #include <boost/filesystem.hpp>
33 #include <soci/sqlite3/soci-sqlite3.h>
49 Throw<std::runtime_error>(
50 "Sqlite databases must specify a dir and a name. Name: " + name +
53 boost::filesystem::path file(dir);
54 if (is_directory(file))
62 auto const& section = config.
section(
"sqdb");
63 auto const backendName =
get(section,
"backend",
"sqlite");
65 if (backendName !=
"sqlite")
66 Throw<std::runtime_error>(
"Unsupported soci backend: " + backendName);
68 auto const path = config.
legacy(
"database_path");
70 dbName ==
"validators" || dbName ==
"peerfinder" ?
".sqlite" :
".db";
78 : connectionString_(
std::move(init.first)), backendFactory_(init.second)
83 :
SociConfig(detail::getSociInit(config, dbName))
111 if (beName ==
"sqlite")
112 s.open(soci::sqlite3, connectionString);
114 Throw<std::runtime_error>(
"Unsupported soci backend: " + beName);
117 static sqlite_api::sqlite3*
120 sqlite_api::sqlite3* result =
nullptr;
121 auto be = s.get_backend();
122 if (
auto b =
dynamic_cast<soci::sqlite3_session_backend*
>(be))
126 Throw<std::logic_error>(
"Didn't get a database connection.");
135 Throw<std::logic_error>(
"No connection found.");
136 return static_cast<size_t>(
137 sqlite_api::sqlite3_memory_used() /
kilobytes(1));
146 int cur = 0, hiw = 0;
147 sqlite_api::sqlite3_db_status(
148 conn, SQLITE_DBSTATUS_CACHE_USED, &cur, &hiw, 0);
151 Throw<std::logic_error>(
"");
158 to.
resize(from.get_len());
161 from.read(0,
reinterpret_cast<char*
>(&to[0]), from.get_len());
176 to.write(0,
reinterpret_cast<char const*
>(&from[0]), from.
size());
185 to.write(0, from.
data(), from.
size());
201 class WALCheckpointer :
public Checkpointer
210 , session_(
std::move(session))
212 , j_(logs.journal(
"WALCheckpointer"))
217 sqlite_api::sqlite3_wal_hook(
218 conn, &sqliteWALHook,
reinterpret_cast<void*
>(id_));
225 if (
auto p = session_.lock())
238 ~WALCheckpointer()
override =
default;
251 if (!jobQueue_.addJob(
260 if (auto self = wp.lock())
270 checkpoint()
override
277 int log = 0, ckpt = 0;
278 int ret = sqlite3_wal_checkpoint_v2(
279 conn,
nullptr, SQLITE_CHECKPOINT_PASSIVE, &log, &ckpt);
281 auto fname = sqlite3_db_filename(conn,
"main");
282 if (ret != SQLITE_OK)
284 auto jm = (ret == SQLITE_LOCKED) ? j_.
trace() : j_.
warn();
285 JLOG(jm) <<
"WAL(" << fname <<
"): error " << ret;
289 JLOG(j_.
trace()) <<
"WAL(" << fname <<
"): frames=" <<
log
290 <<
", written=" << ckpt;
306 bool running_ =
false;
312 sqlite_api::sqlite3* conn,
318 if (
auto checkpointer =
321 checkpointer->schedule();
325 sqlite_api::sqlite3_wal_hook(conn,
nullptr,
nullptr);
341 return std::make_shared<WALCheckpointer>(
342 id, std::move(session), queue, logs);
347 #if defined(__clang__)
348 #pragma clang diagnostic pop