xrpld
Loading...
Searching...
No Matches
DatabaseCon.h
1#pragma once
2
3#include <xrpl/beast/utility/instrumentation.h>
4#include <xrpl/core/PerfLog.h>
5#include <xrpl/core/ServiceRegistry.h>
6#include <xrpl/core/StartUpType.h>
7#include <xrpl/rdb/SociDB.h>
8
9#include <soci/statement.h>
10
11#include <array>
12#include <cstddef>
13#include <cstdint>
14#include <filesystem>
15#include <functional>
16#include <memory>
17#include <mutex>
18#include <string>
19#include <utility>
20#include <vector>
21
22namespace soci {
23class session;
24} // namespace soci
25
26namespace xrpl {
27
29{
30public:
32
33private:
36
37public:
43 : session_(std::move(rhs.session_)), lock_(std::move(rhs.lock_))
44 {
45 }
49 operator=(LockedSociSession const& rhs) = delete;
50
51 soci::session*
53 {
54 return session_.get();
55 }
56 soci::session&
58 {
59 return *session_;
60 }
61 soci::session*
63 {
64 return session_.get();
65 }
66 explicit
67 operator bool() const
68 {
69 return bool(session_);
70 }
71};
72
74{
75public:
76 struct Setup
77 {
78 explicit Setup() = default;
79
81 bool standAlone = false;
83 // Indicates whether or not to return the `globalPragma`
84 // from commonPragma()
85 bool useGlobalPragma = false;
86
87 [[nodiscard]] std::vector<std::string> const*
89 {
90 XRPL_ASSERT(
92 "xrpl::DatabaseCon::Setup::commonPragma : consistent global "
93 "pragma");
94 return useGlobalPragma && globalPragma ? globalPragma.get() : nullptr;
95 }
96
100 };
101
102 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-member-init)
108
109 template <std::size_t N, std::size_t M>
111 Setup const& setup,
112 std::string const& dbName,
113 std::array<std::string, N> const& pragma,
114 std::array<char const*, M> const& initSQL,
115 beast::Journal journal)
116 // Use temporary files or regular DB files?
117 : DatabaseCon(
118 setup.standAlone && setup.startUp != StartUpType::Load &&
119 setup.startUp != StartUpType::LoadFile && setup.startUp != StartUpType::Replay
120 ? ""
121 : (setup.dataDir / dbName),
122 setup.commonPragma(),
123 pragma,
124 initSQL,
125 journal)
126 {
127 }
128
129 // Use this constructor to setup checkpointing
130 template <std::size_t N, std::size_t M>
132 Setup const& setup,
133 std::string const& dbName,
134 std::array<std::string, N> const& pragma,
135 std::array<char const*, M> const& initSQL,
136 CheckpointerSetup const& checkpointerSetup,
137 beast::Journal journal)
138 : DatabaseCon(setup, dbName, pragma, initSQL, journal)
139 {
140 setupCheckpointing(checkpointerSetup.jobQueue, checkpointerSetup.registry.get());
141 }
142
143 template <std::size_t N, std::size_t M>
145 std::filesystem::path const& dataDir,
146 std::string const& dbName,
147 std::array<std::string, N> const& pragma,
148 std::array<char const*, M> const& initSQL,
149 beast::Journal journal)
150 : DatabaseCon(dataDir / dbName, nullptr, pragma, initSQL, journal)
151 {
152 }
153
154 // Use this constructor to setup checkpointing
155 template <std::size_t N, std::size_t M>
157 std::filesystem::path const& dataDir,
158 std::string const& dbName,
159 std::array<std::string, N> const& pragma,
160 std::array<char const*, M> const& initSQL,
161 CheckpointerSetup const& checkpointerSetup,
162 beast::Journal journal)
163 : DatabaseCon(dataDir, dbName, pragma, initSQL, journal)
164 {
165 setupCheckpointing(checkpointerSetup.jobQueue, checkpointerSetup.registry.get());
166 }
167
168 ~DatabaseCon();
169
170 soci::session&
172 {
173 return *session_;
174 }
175
178 {
179 using namespace std::chrono_literals;
181 [&]() { return LockedSociSession(session_, lock_); }, "checkoutDb", 10ms, j_);
182
183 return session;
184 }
185
186private:
187 void
189
190 template <std::size_t N, std::size_t M>
192 std::filesystem::path const& pPath,
193 std::vector<std::string> const* commonPragma,
194 std::array<std::string, N> const& pragma,
195 std::array<char const*, M> const& initSQL,
196 beast::Journal journal)
197 : session_(std::make_shared<soci::session>()), j_(journal)
198 {
199 open(*session_, "sqlite", pPath.string());
200
201 for (auto const& p : pragma)
202 {
203 soci::statement st = session_->prepare << p;
204 st.execute(true);
205 }
206
207 if (commonPragma)
208 {
209 for (auto const& p : *commonPragma)
210 {
211 soci::statement st = session_->prepare << p;
212 st.execute(true);
213 }
214 }
215
216 for (auto const& sql : initSQL)
217 {
218 soci::statement st = session_->prepare << sql;
219 st.execute(true);
220 }
221 }
222
224
225 // checkpointer may outlive the DatabaseCon when the checkpointer jobQueue
226 // callback locks a weak pointer and the DatabaseCon is then destroyed. In
227 // this case, the checkpointer needs to make sure it doesn't use an already
228 // destroyed session. Thus this class keeps a shared_ptr to the session (so
229 // the checkpointer can keep a weak_ptr) and the checkpointer is a
230 // shared_ptr in this class. session_ will never be null.
233
235};
236
237// Return the checkpointer from its id. If the checkpointer no longer exists, an
238// nullptr is returned
241
242} // namespace xrpl
A generic endpoint for log messages.
Definition Journal.h:44
void setupCheckpointing(JobQueue *, ServiceRegistry &)
std::shared_ptr< soci::session > const session_
beast::Journal const j_
DatabaseCon(std::filesystem::path const &dataDir, std::string const &dbName, std::array< std::string, N > const &pragma, std::array< char const *, M > const &initSQL, beast::Journal journal)
std::shared_ptr< Checkpointer > checkpointer_
soci::session & getSession()
DatabaseCon(Setup const &setup, std::string const &dbName, std::array< std::string, N > const &pragma, std::array< char const *, M > const &initSQL, CheckpointerSetup const &checkpointerSetup, beast::Journal journal)
LockedSociSession checkoutDb()
DatabaseCon(Setup const &setup, std::string const &dbName, std::array< std::string, N > const &pragma, std::array< char const *, M > const &initSQL, beast::Journal journal)
DatabaseCon(std::filesystem::path const &pPath, std::vector< std::string > const *commonPragma, std::array< std::string, N > const &pragma, std::array< char const *, M > const &initSQL, beast::Journal journal)
LockedSociSession::mutex lock_
DatabaseCon(std::filesystem::path const &dataDir, std::string const &dbName, std::array< std::string, N > const &pragma, std::array< char const *, M > const &initSQL, CheckpointerSetup const &checkpointerSetup, beast::Journal journal)
A pool of threads to perform work.
Definition JobQueue.h:60
std::recursive_mutex mutex
Definition DatabaseCon.h:31
soci::session * get()
Definition DatabaseCon.h:52
std::shared_ptr< soci::session > session_
Definition DatabaseCon.h:34
LockedSociSession(std::shared_ptr< soci::session > it, mutex &m)
Definition DatabaseCon.h:38
soci::session * operator->()
Definition DatabaseCon.h:62
LockedSociSession(LockedSociSession const &rhs)=delete
std::unique_lock< mutex > lock_
Definition DatabaseCon.h:35
LockedSociSession & operator=(LockedSociSession const &rhs)=delete
LockedSociSession(LockedSociSession &&rhs) noexcept
Definition DatabaseCon.h:42
soci::session & operator*()
Definition DatabaseCon.h:57
Service registry for dependency injection.
STL namespace.
auto measureDurationAndLog(Func &&func, std::string const &actionDescription, std::chrono::duration< Rep, Period > maxDelay, beast::Journal const &journal)
Definition PerfLog.h:162
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
Definition algorithm.h:5
void open(soci::session &s, BasicConfig const &config, std::string const &dbName)
Open a soci session.
Definition SociDB.cpp:90
StartUpType
Definition StartUpType.h:8
std::shared_ptr< Checkpointer > checkpointerFromId(std::uintptr_t id)
std::reference_wrapper< ServiceRegistry > registry
std::array< std::string, 4 > txPragma
Definition DatabaseCon.h:98
static std::unique_ptr< std::vector< std::string > const > globalPragma
Definition DatabaseCon.h:97
std::filesystem::path dataDir
Definition DatabaseCon.h:82
std::array< std::string, 1 > lgrPragma
Definition DatabaseCon.h:99
std::vector< std::string > const * commonPragma() const
Definition DatabaseCon.h:88