Files
rippled/src/ripple/app/data/SociDB.h

151 lines
4.9 KiB
C++

//------------------------------------------------------------------------------
/*
This file is part of rippled: https://github.com/ripple/rippled
Copyright (c) 2012-2015 Ripple Labs Inc.
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
//==============================================================================
#ifndef RIPPLE_SOCIDB_H_INCLUDED
#define RIPPLE_SOCIDB_H_INCLUDED
/** An embedded database wrapper with an intuitive, type-safe interface.
This collection of classes let's you access embedded SQLite databases
using C++ syntax that is very similar to regular SQL.
This module requires the @ref beast_sqlite external module.
*/
#include <ripple/basics/Log.h>
#include <ripple/core/JobQueue.h>
#include <beast/threads/Thread.h>
#define SOCI_USE_BOOST
#include <core/soci.h>
// #include <core/unsigned-types.h>
#include <string>
#include <cstdint>
#include <vector>
namespace sqlite_api {
struct sqlite3;
}
namespace ripple {
template <class T, class C>
T rangeCheckedCast (C c)
{
if ((c > std::numeric_limits<T>::max ()) ||
(!std::numeric_limits<T>::is_signed && c < 0) ||
(std::numeric_limits<T>::is_signed &&
std::numeric_limits<C>::is_signed &&
c < std::numeric_limits<T>::lowest ()))
{
WriteLog (lsERROR, RangeCheckedCast)
<< "Range error. Min: " << std::numeric_limits<T>::lowest ()
<< " Max: " << std::numeric_limits<T>::max () << " Got: " << c;
}
return static_cast<T>(c);
}
}
namespace ripple {
class BasicConfig;
/**
* SociConfig is used when a client wants to delay opening a soci::session after
* parsing the config parameters. If a client want to open a session immediately,
* use the free function "open" below.
*/
class SociConfig
{
std::string connectionString_;
soci::backend_factory const& backendFactory_;
SociConfig(std::pair<std::string, soci::backend_factory const&> init);
public:
SociConfig(BasicConfig const& config,
std::string const& dbName);
std::string connectionString () const;
void open(soci::session& s) const;
};
/**
* Open a soci session.
*
* @param s Session to open.
* @param config Parameters to pick the soci backend and how to connect to that
* backend.
* @param dbName Name of the database. This has different meaning for different backends.
* Sometimes it is part of a filename (sqlite3), othertimes it is a
* database name (postgresql).
*/
void open(soci::session& s,
BasicConfig const& config,
std::string const& dbName);
/**
* Open a soci session.
*
* @param s Session to open.
* @param beName Backend name.
* @param connectionString Connection string to forward to soci::open.
* see the soci::open documentation for how to use this.
*
*/
void open(soci::session& s,
std::string const& beName,
std::string const& connectionString);
size_t getKBUsedAll (soci::session& s);
size_t getKBUsedDB (soci::session& s);
void convert(soci::blob& from, std::vector<std::uint8_t>& to);
void convert(soci::blob& from, std::string& to);
void convert(std::vector<std::uint8_t> const& from, soci::blob& to);
/** Run a thread to checkpoint the write ahead log (wal) for
the given soci::session every 1000 pages. This is only implemented
for sqlite databases.
Note: According to: https://www.sqlite.org/wal.html#ckpt this
is the default behavior of sqlite. We may be able to remove this
class.
*/
class WALCheckpointer
:private beast::Thread
{
friend int SqliteWALHook (void* s, sqlite_api::sqlite3*,
const char* dbName, int walSize);
public:
WALCheckpointer (std::shared_ptr<soci::session> const& s,
JobQueue* q);
~WALCheckpointer ();
private:
void doHook (const char* db, int walSize);
void setupCheckpointing (JobQueue*);
void run ();
void runWal ();
std::shared_ptr<soci::session> session_;
sqlite_api::sqlite3* conn_ = nullptr;
using LockType = std::mutex;
using ScopedLockType = std::lock_guard<LockType>;
LockType mutex_;
JobQueue* q_ = nullptr;
bool running_ = false;
};
}
#endif