rippled
DatabaseCon.h
1 //------------------------------------------------------------------------------
2 /*
3  This file is part of rippled: https://github.com/ripple/rippled
4  Copyright (c) 2012, 2013 Ripple Labs Inc.
5 
6  Permission to use, copy, modify, and/or distribute this software for any
7  purpose with or without fee is hereby granted, provided that the above
8  copyright notice and this permission notice appear in all copies.
9 
10  THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11  WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12  MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13  ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14  WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15  ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16  OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17 */
18 //==============================================================================
19 
20 #ifndef RIPPLE_APP_DATA_DATABASECON_H_INCLUDED
21 #define RIPPLE_APP_DATA_DATABASECON_H_INCLUDED
22 
23 #include <ripple/app/main/DBInit.h>
24 #include <ripple/core/Config.h>
25 #include <ripple/core/SociDB.h>
26 #include <boost/filesystem/path.hpp>
27 #include <boost/optional.hpp>
28 #include <mutex>
29 #include <string>
30 
31 namespace soci {
32 class session;
33 }
34 
35 namespace ripple {
36 
38 {
39 public:
41 
42 private:
45 
46 public:
48  : session_(std::move(it)), lock_(m)
49  {
50  }
52  : session_(std::move(rhs.session_)), lock_(std::move(rhs.lock_))
53  {
54  }
55  LockedSociSession() = delete;
56  LockedSociSession(LockedSociSession const& rhs) = delete;
58  operator=(LockedSociSession const& rhs) = delete;
59 
60  soci::session*
61  get()
62  {
63  return session_.get();
64  }
65  soci::session&
67  {
68  return *session_;
69  }
70  soci::session*
72  {
73  return session_.get();
74  }
75  explicit operator bool() const
76  {
77  return bool(session_);
78  }
79 };
80 
82 {
83 public:
84  struct Setup
85  {
86  explicit Setup() = default;
87 
89  bool standAlone = false;
90  boost::filesystem::path dataDir;
91  // Indicates whether or not to return the `globalPragma`
92  // from commonPragma()
93  bool useGlobalPragma = false;
94 
96  commonPragma() const
97  {
98  assert(!useGlobalPragma || globalPragma);
100  : nullptr;
101  }
102 
104  };
105 
107  {
110  };
111 
112  template <std::size_t N, std::size_t M>
114  Setup const& setup,
115  std::string const& dbName,
116  std::array<char const*, N> const& pragma,
117  std::array<char const*, M> const& initSQL)
118  // Use temporary files or regular DB files?
119  : DatabaseCon(
120  setup.standAlone && setup.startUp != Config::LOAD &&
121  setup.startUp != Config::LOAD_FILE &&
122  setup.startUp != Config::REPLAY
123  ? ""
124  : (setup.dataDir / dbName),
125  setup.commonPragma(),
126  pragma,
127  initSQL)
128  {
129  }
130 
131  // Use this constructor to setup checkpointing
132  template <std::size_t N, std::size_t M>
134  Setup const& setup,
135  std::string const& dbName,
136  std::array<char const*, N> const& pragma,
137  std::array<char const*, M> const& initSQL,
138  CheckpointerSetup const& checkpointerSetup)
139  : DatabaseCon(setup, dbName, pragma, initSQL)
140  {
141  setupCheckpointing(checkpointerSetup.jobQueue, *checkpointerSetup.logs);
142  }
143 
144  template <std::size_t N, std::size_t M>
146  boost::filesystem::path const& dataDir,
147  std::string const& dbName,
148  std::array<char const*, N> const& pragma,
149  std::array<char const*, M> const& initSQL)
150  : DatabaseCon(dataDir / dbName, nullptr, pragma, initSQL)
151  {
152  }
153 
154  // Use this constructor to setup checkpointing
155  template <std::size_t N, std::size_t M>
157  boost::filesystem::path const& dataDir,
158  std::string const& dbName,
159  std::array<char const*, N> const& pragma,
160  std::array<char const*, M> const& initSQL,
161  CheckpointerSetup const& checkpointerSetup)
162  : DatabaseCon(dataDir, dbName, pragma, initSQL)
163  {
164  setupCheckpointing(checkpointerSetup.jobQueue, *checkpointerSetup.logs);
165  }
166 
167  ~DatabaseCon();
168 
169  soci::session&
171  {
172  return *session_;
173  }
174 
177  {
179  }
180 
181 private:
182  void
184 
185  template <std::size_t N, std::size_t M>
187  boost::filesystem::path const& pPath,
188  std::vector<std::string> const* commonPragma,
189  std::array<char const*, N> const& pragma,
190  std::array<char const*, M> const& initSQL)
191  : session_(std::make_shared<soci::session>())
192  {
193  open(*session_, "sqlite", pPath.string());
194 
195  if (commonPragma)
196  {
197  for (auto const& p : *commonPragma)
198  {
199  soci::statement st = session_->prepare << p;
200  st.execute(true);
201  }
202  }
203  for (auto const& p : pragma)
204  {
205  soci::statement st = session_->prepare << p;
206  st.execute(true);
207  }
208  for (auto const& sql : initSQL)
209  {
210  soci::statement st = session_->prepare << sql;
211  st.execute(true);
212  }
213  }
214 
216 
217  // checkpointer may outlive the DatabaseCon when the checkpointer jobQueue
218  // callback locks a weak pointer and the DatabaseCon is then destroyed. In
219  // this case, the checkpointer needs to make sure it doesn't use an already
220  // destroyed session. Thus this class keeps a shared_ptr to the session (so
221  // the checkpointer can keep a weak_ptr) and the checkpointer is a
222  // shared_ptr in this class. session_ will never be null.
225 };
226 
227 // Return the checkpointer from its id. If the checkpointer no longer exists, an
228 // nullptr is returned
231 
234  Config const& c,
235  boost::optional<beast::Journal> j = boost::none);
236 
237 } // namespace ripple
238 
239 #endif
ripple::DatabaseCon::CheckpointerSetup::logs
Logs * logs
Definition: DatabaseCon.h:109
ripple::Config::NORMAL
@ NORMAL
Definition: Config.h:123
ripple::DatabaseCon::CheckpointerSetup::jobQueue
JobQueue * jobQueue
Definition: DatabaseCon.h:108
ripple::DatabaseCon::Setup::globalPragma
static std::unique_ptr< std::vector< std::string > const > globalPragma
Definition: DatabaseCon.h:103
std::string
STL class.
ripple::DatabaseCon::DatabaseCon
DatabaseCon(boost::filesystem::path const &pPath, std::vector< std::string > const *commonPragma, std::array< char const *, N > const &pragma, std::array< char const *, M > const &initSQL)
Definition: DatabaseCon.h:186
std::shared_ptr< soci::session >
ripple::DatabaseCon::DatabaseCon
DatabaseCon(boost::filesystem::path const &dataDir, std::string const &dbName, std::array< char const *, N > const &pragma, std::array< char const *, M > const &initSQL, CheckpointerSetup const &checkpointerSetup)
Definition: DatabaseCon.h:156
ripple::Logs
Manages partitions for logging.
Definition: Log.h:48
ripple::DatabaseCon::Setup
Definition: DatabaseCon.h:84
ripple::DatabaseCon::Setup::startUp
Config::StartUpType startUp
Definition: DatabaseCon.h:88
std::vector< std::string >
ripple::LockedSociSession::LockedSociSession
LockedSociSession()=delete
ripple::DatabaseCon::CheckpointerSetup
Definition: DatabaseCon.h:106
ripple::checkpointerFromId
std::shared_ptr< Checkpointer > checkpointerFromId(std::uintptr_t id)
Definition: DatabaseCon.cpp:79
std::recursive_mutex
STL class.
std::shared_ptr::get
T get(T... args)
ripple::DatabaseCon::Setup::dataDir
boost::filesystem::path dataDir
Definition: DatabaseCon.h:90
ripple::Config::StartUpType
StartUpType
Definition: Config.h:123
ripple::LockedSociSession::session_
std::shared_ptr< soci::session > session_
Definition: DatabaseCon.h:43
ripple::DatabaseCon::Setup::commonPragma
std::vector< std::string > const * commonPragma() const
Definition: DatabaseCon.h:96
ripple::DatabaseCon::setupCheckpointing
void setupCheckpointing(JobQueue *, Logs &)
Definition: DatabaseCon.cpp:234
soci
Definition: DatabaseCon.h:31
ripple::DatabaseCon::Setup::useGlobalPragma
bool useGlobalPragma
Definition: DatabaseCon.h:93
ripple::DatabaseCon::lock_
LockedSociSession::mutex lock_
Definition: DatabaseCon.h:215
ripple::DatabaseCon::Setup::standAlone
bool standAlone
Definition: DatabaseCon.h:89
ripple::DatabaseCon::checkoutDb
LockedSociSession checkoutDb()
Definition: DatabaseCon.h:176
ripple::Config
Definition: Config.h:67
ripple::DatabaseCon::session_
const std::shared_ptr< soci::session > session_
Definition: DatabaseCon.h:223
std::unique_lock
STL class.
ripple::LockedSociSession::operator->
soci::session * operator->()
Definition: DatabaseCon.h:71
std::array
STL class.
ripple::DatabaseCon::DatabaseCon
DatabaseCon(boost::filesystem::path const &dataDir, std::string const &dbName, std::array< char const *, N > const &pragma, std::array< char const *, M > const &initSQL)
Definition: DatabaseCon.h:145
std::uintptr_t
ripple::DatabaseCon::DatabaseCon
DatabaseCon(Setup const &setup, std::string const &dbName, std::array< char const *, N > const &pragma, std::array< char const *, M > const &initSQL, CheckpointerSetup const &checkpointerSetup)
Definition: DatabaseCon.h:133
ripple::LockedSociSession::operator*
soci::session & operator*()
Definition: DatabaseCon.h:66
ripple::JobQueue
A pool of threads to perform work.
Definition: JobQueue.h:55
ripple::DatabaseCon::getSession
soci::session & getSession()
Definition: DatabaseCon.h:170
ripple::DatabaseCon::~DatabaseCon
~DatabaseCon()
Definition: DatabaseCon.cpp:84
ripple::setup_DatabaseCon
DatabaseCon::Setup setup_DatabaseCon(Config const &c, boost::optional< beast::Journal > j=boost::none)
Definition: DatabaseCon.cpp:93
ripple
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
Definition: RCLCensorshipDetector.h:29
ripple::LockedSociSession
Definition: DatabaseCon.h:37
ripple::LockedSociSession::LockedSociSession
LockedSociSession(LockedSociSession &&rhs) noexcept
Definition: DatabaseCon.h:51
ripple::DatabaseCon::Setup::Setup
Setup()=default
std
STL namespace.
ripple::DatabaseCon::DatabaseCon
DatabaseCon(Setup const &setup, std::string const &dbName, std::array< char const *, N > const &pragma, std::array< char const *, M > const &initSQL)
Definition: DatabaseCon.h:113
ripple::DatabaseCon
Definition: DatabaseCon.h:81
ripple::LockedSociSession::operator=
LockedSociSession & operator=(LockedSociSession const &rhs)=delete
ripple::LockedSociSession::LockedSociSession
LockedSociSession(std::shared_ptr< soci::session > it, mutex &m)
Definition: DatabaseCon.h:47
mutex
ripple::LockedSociSession::get
soci::session * get()
Definition: DatabaseCon.h:61
std::unique_ptr
STL class.
ripple::DatabaseCon::checkpointer_
std::shared_ptr< Checkpointer > checkpointer_
Definition: DatabaseCon.h:224
ripple::LockedSociSession::lock_
std::unique_lock< mutex > lock_
Definition: DatabaseCon.h:44
ripple::open
void open(soci::session &s, BasicConfig const &config, std::string const &dbName)
Open a soci session.
Definition: SociDB.cpp:100
string