20 #if defined(__clang__)
21 #pragma clang diagnostic push
22 #pragma clang diagnostic ignored "-Wdeprecated"
26 #include <ripple/basics/contract.h>
27 #include <ripple/basics/ByteUtilities.h>
28 #include <ripple/core/ConfigSections.h>
29 #include <ripple/core/SociDB.h>
30 #include <ripple/core/Config.h>
32 #include <soci/sqlite3/soci-sqlite3.h>
33 #include <boost/filesystem.hpp>
48 Throw<std::runtime_error> (
49 "Sqlite databases must specify a dir and a name. Name: " +
50 name +
" Dir: " + dir);
52 boost::filesystem::path file (dir);
53 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");
69 auto const ext = dbName ==
"validators" || dbName ==
"peerfinder"
78 : connectionString_ (
std::move (init.first)),
79 backendFactory_ (init.second)
84 :
SociConfig (detail::getSociInit (config, dbName))
98 void open (soci::session& s,
109 if (beName ==
"sqlite")
110 s.open(soci::sqlite3, connectionString);
112 Throw<std::runtime_error> (
"Unsupported soci backend: " + beName);
118 sqlite_api::sqlite3* result =
nullptr;
119 auto be = s.get_backend ();
120 if (
auto b =
dynamic_cast<soci::sqlite3_session_backend*
> (be))
124 Throw<std::logic_error> (
"Didn't get a database connection.");
132 Throw<std::logic_error> (
"No connection found.");
133 return static_cast <size_t> (sqlite_api::sqlite3_memory_used () /
kilobytes(1));
141 int cur = 0, hiw = 0;
142 sqlite_api::sqlite3_db_status (
143 conn, SQLITE_DBSTATUS_CACHE_USED, &cur, &hiw, 0);
146 Throw<std::logic_error> (
"");
152 to.
resize (from.get_len ());
155 from.read (0,
reinterpret_cast<char*
>(&to[0]), from.get_len ());
168 to.write (0,
reinterpret_cast<char const*
>(&from[0]), from.
size ());
176 to.write (0, from.
data (), from.
size ());
191 class WALCheckpointer :
public Checkpointer
194 WALCheckpointer (sqlite_api::sqlite3& conn, JobQueue& q, Logs& logs)
195 : conn_ (conn), jobQueue_ (q), j_ (logs.journal (
"WALCheckpointer"))
197 sqlite_api::sqlite3_wal_hook (&conn_, &sqliteWALHook,
this);
200 ~WALCheckpointer ()
override =
default;
203 sqlite_api::sqlite3& conn_;
207 bool running_ =
false;
212 void* cp, sqlite_api::sqlite3*,
const char* dbName,
int walSize)
216 if (
auto checkpointer =
reinterpret_cast <WALCheckpointer*
> (cp))
217 checkpointer->scheduleCheckpoint();
219 Throw<std::logic_error> (
"Didn't get a WALCheckpointer");
224 void scheduleCheckpoint ()
234 if (! jobQueue_.addJob (
235 jtWAL,
"WAL", [
this] (Job&) { checkpoint(); }))
244 int log = 0, ckpt = 0;
245 int ret = sqlite3_wal_checkpoint_v2 (
246 &conn_,
nullptr, SQLITE_CHECKPOINT_PASSIVE, &log, &ckpt);
248 auto fname = sqlite3_db_filename (&conn_,
"main");
249 if (ret != SQLITE_OK)
251 auto jm = (ret == SQLITE_LOCKED) ? j_.
trace() : j_.
warn();
253 <<
"WAL(" << fname <<
"): error " << ret;
258 <<
"WAL(" << fname <<
"): frames="
259 <<
log <<
", written=" << ckpt;
273 return std::make_unique <WALCheckpointer> (*conn, queue, logs);
279 #if defined(__clang__)
280 #pragma clang diagnostic pop