DBfiles moved to a seprate folder and compilation fixes

https://github.com/moneroexamples/openmonero/issues/125
new_rpc
moneroexamples 5 years ago
parent 085731f343
commit 4939545c02

@ -0,0 +1,636 @@
//
// Created by mwo on 7/01/17.
//
#define MYSQLPP_SSQLS_NO_STATICS 1
#include "MySqlAccounts.h"
//#include "TxSearch.h"
#include "../CurrentBlockchainStatus.h"
#include "ssqlses.h"
namespace xmreg
{
MysqlInputs::MysqlInputs(shared_ptr<MySqlConnector> _conn)
: conn {_conn}
{}
bool
MysqlInputs::select_for_out(const uint64_t& output_id, vector<XmrInput>& ins)
{
try
{
conn->check_if_connected();
Query query = conn->query(XmrInput::SELECT_STMT4);
query.parse();
query.storein(ins, output_id);
return !ins.empty();
}
catch (std::exception const& e)
{
MYSQL_EXCEPTION_MSG(e);
//throw e;
}
return false;
}
MysqlOutpus::MysqlOutpus(shared_ptr<MySqlConnector> _conn): conn {_conn}
{}
bool
MysqlOutpus::exist(const string& output_public_key_str, XmrOutput& out)
{
try
{
conn->check_if_connected();
Query query = conn->query(XmrOutput::EXIST_STMT);
query.parse();
vector<XmrOutput> outs;
query.storein(outs, output_public_key_str);
if (outs.empty())
return false;
out = std::move(outs.at(0));
}
catch (std::exception const& e)
{
MYSQL_EXCEPTION_MSG(e);
return false;
}
return true;
}
MysqlTransactions::MysqlTransactions(shared_ptr<MySqlConnector> _conn): conn {_conn}
{}
uint64_t
MysqlTransactions::mark_spendable(const uint64_t& tx_id_no, bool spendable)
{
try
{
conn->check_if_connected();
Query query = conn->query(spendable ?
XmrTransaction::MARK_AS_SPENDABLE_STMT
: XmrTransaction::MARK_AS_NONSPENDABLE_STMT);
query.parse();
SimpleResult sr = query.execute(tx_id_no);
return sr.rows();
}
catch (std::exception const& e)
{
MYSQL_EXCEPTION_MSG(e);
//throw e;
}
return 0;
}
uint64_t
MysqlTransactions::delete_tx(const uint64_t& tx_id_no)
{
try
{
conn->check_if_connected();
Query query = conn->query(XmrTransaction::DELETE_STMT);
query.parse();
SimpleResult sr = query.execute(tx_id_no);
return sr.rows();
}
catch (std::exception const& e)
{
MYSQL_EXCEPTION_MSG(e);
//throw e;
}
return 0;
}
bool
MysqlTransactions::exist(const uint64_t& account_id, const string& tx_hash_str, XmrTransaction& tx)
{
try
{
conn->check_if_connected();
Query query = conn->query(XmrTransaction::EXIST_STMT);
query.parse();
vector<XmrTransaction> outs;
query.storein(outs, account_id, tx_hash_str);
if (outs.empty())
return false;
tx = outs.at(0);
}
catch (std::exception const& e)
{
MYSQL_EXCEPTION_MSG(e);
return false;
}
return true;
}
bool
MysqlTransactions::get_total_recieved(const uint64_t& account_id, uint64_t& amount)
{
try
{
conn->check_if_connected();
Query query = conn->query(XmrTransaction::SUM_XMR_RECIEVED);
query.parse();
StoreQueryResult sqr = query.store(account_id);
if (!sqr.empty())
{
amount = sqr.at(0)["total_received"];
return true;
}
}
catch (std::exception const& e)
{
MYSQL_EXCEPTION_MSG(e);
}
return false;
}
MysqlPayments::MysqlPayments(shared_ptr<MySqlConnector> _conn): conn {_conn}
{}
bool
MysqlPayments::select_by_payment_id(const string& payment_id, vector<XmrPayment>& payments)
{
try
{
conn->check_if_connected();
Query query = conn->query(XmrPayment::SELECT_STMT2);
query.parse();
payments.clear();
query.storein(payments, payment_id);
return !payments.empty();
}
catch (std::exception const& e)
{
MYSQL_EXCEPTION_MSG(e);
//throw e;
}
return false;
}
MySqlAccounts::MySqlAccounts(shared_ptr<CurrentBlockchainStatus> _current_bc_status)
: current_bc_status {_current_bc_status}
{
// create connection to the mysql
conn = make_shared<MySqlConnector>();
_init();
}
MySqlAccounts::MySqlAccounts(shared_ptr<CurrentBlockchainStatus> _current_bc_status,
shared_ptr<MySqlConnector> _conn)
: current_bc_status {_current_bc_status}
{
conn = _conn;
_init();
}
bool
MySqlAccounts::select(const string& address, XmrAccount& account)
{
try
{
conn->check_if_connected();
Query query = conn->query(XmrAccount::SELECT_STMT2);
query.parse();
vector<XmrAccount> res;
query.storein(res, address);
if (!res.empty())
{
account = std::move(res.at(0));
return true;
}
}
catch (std::exception const& e)
{
MYSQL_EXCEPTION_MSG(e);
//throw e;
}
return false;
}
template <typename T>
uint64_t
MySqlAccounts::insert(const T& data_to_insert)
{
try
{
conn->check_if_connected();
Query query = conn->query();
query.insert(data_to_insert);
SimpleResult sr = query.execute();
if (sr.rows() == 1)
return sr.insert_id();
}
catch (std::exception const& e)
{
MYSQL_EXCEPTION_MSG(e);;
}
return 0;
}
// Explicitly instantiate insert template for our tables
template
uint64_t MySqlAccounts::insert<XmrAccount>(const XmrAccount& data_to_insert);
template
uint64_t MySqlAccounts::insert<XmrTransaction>(const XmrTransaction& data_to_insert);
template
uint64_t MySqlAccounts::insert<XmrOutput>(const XmrOutput& data_to_insert);
template
uint64_t MySqlAccounts::insert<XmrInput>(const XmrInput& data_to_insert);
template
uint64_t MySqlAccounts::insert<XmrPayment>(const XmrPayment& data_to_insert);
template <typename T>
uint64_t
MySqlAccounts::insert(const vector<T>& data_to_insert)
{
try
{
conn->check_if_connected();
Query query = conn->query();
query.insert(data_to_insert.begin(), data_to_insert.end());
SimpleResult sr = query.execute();
return sr.rows();
}
catch (std::exception const& e)
{
MYSQL_EXCEPTION_MSG(e);
}
return 0;
}
// Explicitly instantiate insert template for our tables
template
uint64_t MySqlAccounts::insert<XmrOutput>(const vector<XmrOutput>& data_to_insert);
template
uint64_t MySqlAccounts::insert<XmrInput>(const vector<XmrInput>& data_to_insert);
template <typename T, size_t query_no>
bool
MySqlAccounts::select(uint64_t account_id, vector<T>& selected_data)
{
try
{
conn->check_if_connected();
Query query = conn->query((query_no == 1 ? T::SELECT_STMT : T::SELECT_STMT2));
query.parse();
selected_data.clear();
query.storein(selected_data, account_id);
return !selected_data.empty();
}
catch (std::exception const& e)
{
MYSQL_EXCEPTION_MSG(e);
}
return false;
}
template
bool MySqlAccounts::select<XmrAccount>(uint64_t account_id, vector<XmrAccount>& selected_data);
template
bool MySqlAccounts::select<XmrTransaction>(uint64_t account_id, vector<XmrTransaction>& selected_data);
template
bool MySqlAccounts::select<XmrOutput>(uint64_t account_id, vector<XmrOutput>& selected_data);
template // this will use SELECT_STMT2 which selectes based on transaction id, not account_id,
bool MySqlAccounts::select<XmrOutput, 2>(uint64_t tx_id, vector<XmrOutput>& selected_data);
template
bool MySqlAccounts::select<XmrInput>(uint64_t account_id, vector<XmrInput>& selected_data);
template
bool MySqlAccounts::select<XmrPayment>(uint64_t account_id, vector<XmrPayment>& selected_data);
template // this will use SELECT_STMT2 which selectes based on transaction id, not account_id,
bool MySqlAccounts::select<XmrInput, 2>(uint64_t tx_id, vector<XmrInput>& selected_data);
template <typename T>
bool
MySqlAccounts::update(T const& orginal_row, T const& new_row)
{
try
{
conn->check_if_connected();
Query query = conn->query();
query.update(orginal_row, new_row);
SimpleResult sr = query.execute();
return sr.rows() == 1;
}
catch (std::exception const& e)
{
MYSQL_EXCEPTION_MSG(e);
}
return false;
}
template
bool MySqlAccounts::update<XmrAccount>(XmrAccount const& orginal_row, XmrAccount const& new_row);
template
bool MySqlAccounts::update<XmrPayment>(XmrPayment const& orginal_row, XmrPayment const& new_row);
template <typename T>
bool
MySqlAccounts::select_for_tx(uint64_t tx_id, vector<T>& selected_data)
{
return select<T, 2>(tx_id, selected_data);
}
template // this will use SELECT_STMT2 which selectes based on transaction id, not account_id,
bool MySqlAccounts::select_for_tx<XmrOutput>(uint64_t tx_id, vector<XmrOutput>& selected_data);
template // this will use SELECT_STMT2 which selectes based on transaction id, not account_id,
bool MySqlAccounts::select_for_tx<XmrInput>(uint64_t tx_id, vector<XmrInput>& selected_data);
template <typename T>
bool
MySqlAccounts::select_by_primary_id(uint64_t id, T& selected_data)
{
try
{
conn->check_if_connected();
Query query = conn->query(T::SELECT_STMT3);
query.parse();
vector<T> outs;
query.storein(outs, id);
if (!outs.empty())
{
selected_data = std::move(outs.at(0));
return true;
}
}
catch (std::exception const& e)
{
MYSQL_EXCEPTION_MSG(e);
//throw e;
}
return false;
}
//template
//bool MySqlAccounts::select_by_primary_id<XmrTransaction>(uint64_t id, XmrTransaction& selected_data);
template
bool MySqlAccounts::select_by_primary_id<XmrInput>(uint64_t id, XmrInput& selected_data);
template
bool MySqlAccounts::select_by_primary_id<XmrOutput>(uint64_t id, XmrOutput& selected_data);
template
bool MySqlAccounts::select_by_primary_id<XmrPayment>(uint64_t id, XmrPayment& selected_data);
bool
MySqlAccounts::select_txs_for_account_spendability_check(
const uint64_t& account_id, vector<XmrTransaction>& txs)
{
for (auto it = txs.begin(); it != txs.end(); )
{
// first we check if txs stored in db are already spendable
// it means if they are older than 10 blocks. If yes,
// we mark them as spendable, as we assume that blocks
// older than 10 blocks are permanent, i.e, they wont get
// orphaned.
XmrTransaction& tx = *it;
if (bool {tx.spendable} == false)
{
if (current_bc_status->is_tx_unlocked(tx.unlock_time, tx.height))
{
// this tx was before marked as unspendable, but now
// it is spendable. Meaning, that its older than 10 blocks.
// so mark it as spendable in mysql, so that its permanet.
uint64_t no_row_updated = mark_tx_spendable(tx.id.data);
if (no_row_updated != 1)
{
cerr << "no_row_updated != 1 due to xmr_accounts->mark_tx_spendable(tx.id)\n";
return false;
}
tx.spendable = true;
}
else
{
// tx was marked as non-spendable, i.e., younger than 10 blocks
// so we still are going to use this txs, but we need to double
// check if its still valid, i.e., it's block did not get orphaned.
// we do this by checking if txs still exists in the blockchain
// and if its blockchain_tx_id is same as what we have in our mysql.
uint64_t blockchain_tx_id {0};
current_bc_status->tx_exist(tx.hash, blockchain_tx_id);
if (blockchain_tx_id != tx.blockchain_tx_id)
{
// tx does not exist in blockchain, or its blockchain_id changed
// for example, it was orhpaned, and then readded.
uint64_t no_row_updated = delete_tx(tx.id.data);
if (no_row_updated != 1)
{
cerr << "no_row_updated != 1 due to xmr_accounts->delete_tx(tx.id)\n";
return false;
}
// because txs does not exist in blockchain anymore,
// we assume its back to mempool, and it will be rescanned
// by tx search thread once added again to some block.
// so we remove it from txs vector
it = txs.erase(it);
continue;
}
// set unlock_time field so that frontend displies it
// as a locked tx, if unlock_time is zero.
// coinbtase txs have this set already. regular tx
// have unlock_time set to zero by default, but they cant
// be spent anyway.
if (tx.unlock_time == 0)
tx.unlock_time = tx.height + CRYPTONOTE_DEFAULT_TX_SPENDABLE_AGE;
} // else
} // if (bool {tx.spendable} == false)
++it;
} // for (auto it = txs.begin(); it != txs.end(); )
return true;
}
bool
MySqlAccounts::select_inputs_for_out(const uint64_t& output_id, vector<XmrInput>& ins)
{
return mysql_in->select_for_out(output_id, ins);
}
bool
MySqlAccounts::output_exists(const string& output_public_key_str, XmrOutput& out)
{
return mysql_out->exist(output_public_key_str, out);
}
bool
MySqlAccounts::tx_exists(const uint64_t& account_id, const string& tx_hash_str, XmrTransaction& tx)
{
return mysql_tx->exist(account_id, tx_hash_str, tx);
}
uint64_t
MySqlAccounts::mark_tx_spendable(const uint64_t& tx_id_no)
{
return mysql_tx->mark_spendable(tx_id_no);
}
uint64_t
MySqlAccounts::mark_tx_nonspendable(const uint64_t& tx_id_no)
{
return mysql_tx->mark_spendable(tx_id_no, false);
}
uint64_t
MySqlAccounts::delete_tx(const uint64_t& tx_id_no)
{
return mysql_tx->delete_tx(tx_id_no);
}
bool
MySqlAccounts::select_payment_by_id(const string& payment_id, vector<XmrPayment>& payments)
{
return mysql_payment->select_by_payment_id(payment_id, payments);
}
bool
MySqlAccounts::get_total_recieved(const uint64_t& account_id, uint64_t& amount)
{
return mysql_tx->get_total_recieved(account_id, amount);
}
void
MySqlAccounts::disconnect()
{
get_connection()->get_connection().disconnect();
}
shared_ptr<MySqlConnector>
MySqlAccounts::get_connection()
{
return conn;
}
void
MySqlAccounts::set_bc_status_provider(shared_ptr<CurrentBlockchainStatus> bc_status_provider)
{
current_bc_status = bc_status_provider;
}
void
MySqlAccounts::_init()
{
// use same connection when working with other tables
mysql_tx = make_shared<MysqlTransactions>(conn);
mysql_out = make_shared<MysqlOutpus>(conn);
mysql_in = make_shared<MysqlInputs>(conn);
mysql_payment = make_shared<MysqlPayments>(conn);
}
}

@ -0,0 +1,248 @@
//
// Created by mwo on 16/12/16.
//
#ifndef RESTBED_XMR_MYSQLACCOUNTS_H
#define RESTBED_XMR_MYSQLACCOUNTS_H
#include "../tools.h"
#include "MySqlConnector.h"
#include <iostream>
#include <memory>
namespace xmreg
{
using namespace mysqlpp;
using namespace std;
using namespace nlohmann;
class XmrTransactionWithOutsAndIns;
class XmrInput;
class XmrOutput;
class XmrTransaction;
class XmrPayment;
class XmrAccount;
class Table;
class CurrentBlockchainStatus;
class MysqlInputs
{
shared_ptr<MySqlConnector> conn;
public:
MysqlInputs(shared_ptr<MySqlConnector> _conn);
bool
select_for_out(const uint64_t& output_id, vector<XmrInput>& ins);
};
class MysqlOutpus
{
shared_ptr<MySqlConnector> conn;
public:
MysqlOutpus(shared_ptr<MySqlConnector> _conn);
bool
exist(const string& output_public_key_str, XmrOutput& out);
};
class MysqlTransactions
{
shared_ptr<MySqlConnector> conn;
public:
MysqlTransactions(shared_ptr<MySqlConnector> _conn);
uint64_t
mark_spendable(const uint64_t& tx_id_no, bool spendable = true);
uint64_t
delete_tx(const uint64_t& tx_id_no);
bool
exist(const uint64_t& account_id, const string& tx_hash_str, XmrTransaction& tx);
bool
get_total_recieved(const uint64_t& account_id, uint64_t& amount);
};
class MysqlPayments
{
shared_ptr<MySqlConnector> conn;
public:
MysqlPayments(shared_ptr<MySqlConnector> _conn);
bool
select_by_payment_id(const string& payment_id, vector<XmrPayment>& payments);
};
class MySqlAccounts
{
shared_ptr<MySqlConnector> conn;
shared_ptr<MysqlTransactions> mysql_tx;
shared_ptr<MysqlOutpus> mysql_out;
shared_ptr<MysqlInputs> mysql_in;
shared_ptr<MysqlPayments> mysql_payment;
shared_ptr<CurrentBlockchainStatus> current_bc_status;
public:
MySqlAccounts(shared_ptr<CurrentBlockchainStatus> _current_bc_status);
MySqlAccounts(shared_ptr<CurrentBlockchainStatus> _current_bc_status,
shared_ptr<MySqlConnector> _conn);
bool
select(const string& address, XmrAccount& account);
template <typename T>
uint64_t
insert(const T& data_to_insert);
template <typename T>
uint64_t
insert(const vector<T>& data_to_insert);
/**
*
* @tparam T
* @tparam query_no which query to use, for SELECT_STMT or SELECT_STMT2
* @param account_id
* @param selected_data
* @return
*/
template <typename T, size_t query_no = 1>
bool
select(uint64_t account_id, vector<T>& selected_data);
template <typename T>
bool
update(T const& orginal_row, T const& new_row);
template <typename T>
bool
select_for_tx(uint64_t tx_id, vector<T>& selected_data);
template <typename T>
bool
select_by_primary_id(uint64_t id, T& selected_data);
bool
select_txs_for_account_spendability_check(const uint64_t& account_id,
vector<XmrTransaction>& txs);
bool
select_inputs_for_out(const uint64_t& output_id, vector<XmrInput>& ins);
bool
output_exists(const string& output_public_key_str, XmrOutput& out);
bool
tx_exists(const uint64_t& account_id, const string& tx_hash_str, XmrTransaction& tx);
uint64_t
mark_tx_spendable(const uint64_t& tx_id_no);
uint64_t
mark_tx_nonspendable(const uint64_t& tx_id_no);
uint64_t
delete_tx(const uint64_t& tx_id_no);
bool
select_payment_by_id(const string& payment_id, vector<XmrPayment>& payments);
bool
update_payment(XmrPayment& payment_orginal, XmrPayment& payment_new);
bool
get_total_recieved(const uint64_t& account_id, uint64_t& amount);
void
disconnect();
shared_ptr<MySqlConnector>
get_connection();
/**
* DONT use!!!
*
* Its only useful in unit tests when you know that nothing will insert
* any row between calling this and using the returned id
*
* @tparam T
* @param table_class
* @return
*/
template <typename T>
uint64_t
get_next_primary_id(T&& table_class)
{
static_assert(std::is_base_of<Table, std::decay_t<T>>::value, "given class is not Table");
string sql {"SELECT `auto_increment` FROM INFORMATION_SCHEMA.TABLES WHERE table_name = '"};
sql += table_class.table_name() + "' AND table_schema = '" + MySqlConnector::dbname + "'";
Query query = conn->query(sql);
query.parse();
try
{
conn->check_if_connected();
StoreQueryResult sr = query.store();
if (!sr.empty())
return sr[0][0];
}
catch (std::exception const& e)
{
MYSQL_EXCEPTION_MSG(e);
}
return 0;
}
// this is useful in unit tests, as we can inject mock CurrentBlockchainStatus
// after an instance of MySqlAccounts has been created.
void
set_bc_status_provider(shared_ptr<CurrentBlockchainStatus> bc_status_provider);
private:
void _init();
};
}
#endif //RESTBED_XMR_MYSQLACCOUNTS_H

@ -0,0 +1,98 @@
//
// Created by mwo on 7/01/17.
//
#include "MySqlConnector.h"
#include <mysql++/mysql++.h>
#include <mysql++/ssqls.h>
#include <iostream>
#include <memory>
namespace xmreg {
string MySqlConnector::url;
size_t MySqlConnector::port;
string MySqlConnector::username;
string MySqlConnector::password;
string MySqlConnector::dbname;
MySqlConnector::MySqlConnector()
{
_init();
}
MySqlConnector::MySqlConnector(Option* _option)
{
conn.set_option(_option);
_init();
}
bool
MySqlConnector::connect()
{
if (conn.connected())
return true;
try
{
conn.connect(dbname.c_str(),
url.c_str(),
username.c_str(),
password.c_str(),
port);
}
catch (mysqlpp::ConnectionFailed const& e)
{
MYSQL_EXCEPTION_MSG(e);
return false;
}
return true;
}
bool
MySqlConnector::ping()
{
return conn.ping();
}
Query
MySqlConnector::query(const char *qstr)
{
return conn.query(qstr);
}
Query
MySqlConnector::query(const std::string &qstr)
{
return conn.query(qstr);
}
Connection&
MySqlConnector::get_connection()
{
return conn;
}
MySqlConnector::~MySqlConnector()
{
conn.disconnect();
};
void
MySqlConnector::_init()
{
if (!connect())
{
cerr << "Connection to Mysql failed!" << endl;
throw std::runtime_error("Connection to Mysql failed!");
}
}
}

@ -0,0 +1,94 @@
//
// Created by mwo on 9/12/16.
//
#ifndef RESTBED_XMR_MYSQLCONNECTOR_H
#define RESTBED_XMR_MYSQLCONNECTOR_H
//#include "tools.h"
#include <mysql++/mysql++.h>
#include <mysql++/ssqls.h>
#include <iostream>
namespace xmreg
{
using namespace mysqlpp;
using namespace std;
#define MYSQL_EXCEPTION_MSG(sql_excetption) cerr << "# ERR: SQLException in " << __FILE__ \
<< "(" << __FUNCTION__ << ") on line " << __LINE__ << endl \
<< "# ERR: " << sql_excetption.what() \
<< endl;
/*
* This is that creates connections
* our mysql database.
*
* Each thread has its own connection.
* This way when something breaks in one thread,
* other threads can still operate on the mysql.
*
*/
class MySqlConnector
{
Connection conn;
public:
static string url;
static size_t port;
static string username;
static string password;
static string dbname;
MySqlConnector();
MySqlConnector(Option* _option);
// dont want any copies of connection object.
// pass it around through shared or unique pointer
MySqlConnector (const MySqlConnector&) = delete;
MySqlConnector& operator= (const MySqlConnector&) = delete;
Query
query(const char* qstr = 0);
Query
query(const std::string& qstr);
virtual bool
connect();
bool
ping();
Connection&
get_connection();
// this throws exception if not connected
inline void
check_if_connected()
{
if (!conn.connected())
throw std::runtime_error("No connection to the mysqldb");
}
virtual ~MySqlConnector();
protected:
void _init();
};
}
#endif //RESTBED_XMR_MYSQLCONNECTOR_H

@ -0,0 +1,49 @@
//
// Created by mwo on 12/07/18.
//
#include "easylogging++.h"
#include "../om_log.h"
#include "MysqlPing.h"
namespace xmreg
{
MysqlPing::MysqlPing(
std::shared_ptr<MySqlConnector> _conn,
seconds _ping_time)
: conn {_conn}, ping_time {_ping_time}
{}
void
MysqlPing::operator()()
{
while (keep_looping)
{
std::this_thread::sleep_for(chrono::seconds(ping_time));
if (auto c = conn.lock())
{
if (!c->ping())
{
OMERROR << "Pinging mysql failed. Stoping mysql pinging thread.";
why_stoped = StopReason::PingFailed;
break;
}
OMINFO << "Mysql ping successful." ;
}
else
{
OMERROR << "std::weak_ptr<MySqlConnector> conn expired!";
why_stoped = StopReason::PointerExpired;
break;
}
++counter;
}
}
}

@ -0,0 +1,47 @@
//
// Created by mwo on 12/07/18.
//
#ifndef OPENMONERO_MYSQLPING_H
#define OPENMONERO_MYSQLPING_H
#include "MySqlConnector.h"
#include <memory>
#include <thread>
#include <atomic>
namespace xmreg
{
using chrono::seconds;
using namespace literals::chrono_literals;
class MysqlPing
{
public:
enum class StopReason {NotYetStopped, PingFailed, PointerExpired};
MysqlPing(std::shared_ptr<MySqlConnector> _conn,
seconds _ping_time = 300s);
void operator()();
void stop() {keep_looping = false;}
uint64_t get_counter() const {return counter;}
StopReason get_stop_reason() const {return why_stoped;};
MysqlPing(MysqlPing&&) = default;
MysqlPing& operator=(MysqlPing&&) = default;
private:
std::weak_ptr<MySqlConnector> conn;
seconds ping_time; // in seconds
atomic<bool> keep_looping {true};
atomic<uint64_t> counter {0};
atomic<StopReason> why_stoped {StopReason::NotYetStopped};
};
}
#endif //OPENMONERO_MYSQLPING_H

@ -0,0 +1,140 @@
//
// Created by mwo on 7/01/17.
//
#include "ssqlses.h"
namespace xmreg
{
ostream& operator<< (std::ostream& os, const Table& data)
{
os << data.table_name() << ": " << data.to_json().dump() << '\n';
return os;
};
json
XmrAccount::to_json() const
{
json j {{"id" , id.data},
{"address" , address},
{"viewkey" , viewkey},
{"scanned_block_height" , scanned_block_height},
{"scanned_block_timestamp", static_cast<uint64_t>(scanned_block_timestamp)},
{"start_height" , start_height}
};
return j;
}
json
XmrTransaction::to_json() const
{
json j {{"id" , id.data},
{"hash" , hash},
{"prefix_hash" , prefix_hash},
{"tx_pub_key" , tx_pub_key},
{"account_id" , account_id},
{"total_received" , total_received},
{"total_sent" , total_sent},
{"height" , height},
{"payment_id" , payment_id},
{"unlock_time" , unlock_time},
{"coinbase" , bool {coinbase}},
{"is_rct" , bool {is_rct}},
{"rct_type" , rct_type},
{"spendable" , bool {spendable}},
{"mixin" , mixin},
{"timestamp" , static_cast<uint64_t>(timestamp)}
};
return j;
}
DateTime
XmrTransaction::timestamp_to_DateTime(time_t timestamp)
{
return DateTime(timestamp);
}
ostream& operator<< (std::ostream& os, const XmrTransaction& acc)
{
os << "XmrTransactions: " << acc.to_json().dump() << '\n';
return os;
};
json
XmrOutput::to_json() const
{
json j {{"id" , id.data},
{"account_id" , account_id},
{"tx_id" , tx_id},
{"out_pub_key" , out_pub_key},
{"tx_pub_key" , tx_pub_key},
{"amount" , amount},
{"global_index" , global_index},
{"out_index" , out_index},
{"mixin" , mixin},
{"timestamp" , static_cast<uint64_t>(timestamp)}
};
return j;
}
ostream& operator<< (std::ostream& os, const XmrOutput& out) {
os << "XmrOutputs: " << out.to_json().dump() << '\n';
return os;
};
json
XmrInput::to_json() const
{
json j {{"id" , id.data},
{"account_id" , account_id},
{"tx_id" , tx_id},
{"output_id" , output_id},
{"key_image" , key_image},
{"amount" , amount},
{"timestamp" , static_cast<uint64_t>(timestamp)}
};
return j;
}
ostream& operator<< (std::ostream& os, const XmrInput& out)
{
os << "XmrInput: " << out.to_json().dump() << '\n';
return os;
};
json
XmrPayment::to_json() const
{
json j {{"id" , id.data},
{"account_id" , account_id},
{"payment_id" , payment_id},
{"tx_hash" , tx_hash},
{"request_fulfilled", bool {request_fulfilled}},
{"import_fee" , import_fee},
{"payment_address" , payment_address},
};
return j;
}
ostream& operator<< (std::ostream& os, const XmrPayment& out) {
os << "XmrPayment: " << out.to_json().dump() << '\n';
return os;
};
}

@ -0,0 +1,329 @@
//
// Created by mwo on 14/12/16.
//
#ifndef RESTBED_XMR_SSQLSES_H
#define RESTBED_XMR_SSQLSES_H
#include "../../ext/json.hpp"
#include <mysql++/mysql++.h>
#include <mysql++/ssqls.h>
namespace xmreg
{
using namespace std;
using namespace nlohmann;
using namespace mysqlpp;
/**
* Base class for all mysql table based classes that we use.
*/
class Table
{
public:
virtual string table_name() const = 0;
virtual json to_json() const = 0;
friend std::ostream& operator<< (std::ostream& stream, const Table& data);
};
sql_create_8(Accounts, 1, 6,
sql_bigint_unsigned_null, id,
sql_varchar , address,
sql_char , viewkey_hash,
sql_bigint_unsigned, scanned_block_height,
sql_timestamp , scanned_block_timestamp,
sql_bigint_unsigned, start_height,
sql_timestamp , created,
sql_timestamp , modified);
struct XmrAccount : public Accounts, Table
{
static constexpr const char* SELECT_STMT = R"(
SELECT * FROM `Accounts` WHERE `id` = (%0q)
)";
static constexpr const char* SELECT_STMT2 = R"(
SELECT * FROM `Accounts` WHERE `address` = (%0q)
)";
// SELECT_STMT3 same as SELECT_STMT which is fine
// easier to work with templates later
static constexpr const char* SELECT_STMT3 = R"(
SELECT * FROM `Accounts` WHERE `id` = (%0q)
)";
static constexpr const char* INSERT_STMT = R"(
INSERT INTO `Accounts` (`address`, `viewkey_hash`,
`scanned_block_height`,
`scanned_block_timestamp`, `start_height`)
VALUES
(%0q, %1q, %2q, %3q, %4q);
)";
using Accounts::Accounts;
// viewkey is not stored in mysql db or anywhere
// so need to be populated when user logs in.
string viewkey;
string table_name() const override { return this->table();};
json to_json() const override;
};
sql_create_17(Transactions, 1, 17,
sql_bigint_unsigned_null, id,
sql_varchar , hash,
sql_varchar , prefix_hash,
sql_varchar , tx_pub_key,
sql_bigint_unsigned , account_id,
sql_bigint_unsigned , blockchain_tx_id,
sql_bigint_unsigned , total_received,
sql_bigint_unsigned , total_sent,
sql_bigint_unsigned , unlock_time,
sql_bigint_unsigned , height,
sql_bool , coinbase,
sql_bool , is_rct,
sql_int , rct_type,
sql_bool , spendable,
sql_varchar , payment_id,
sql_bigint_unsigned , mixin,
sql_timestamp , timestamp);
struct XmrTransaction : public Transactions, Table
{
static constexpr const char* SELECT_STMT = R"(
SELECT * FROM `Transactions` WHERE `account_id` = (%0q)
)";
static constexpr const char* SELECT_STMT2 = R"(
SELECT * FROM `Transactions` WHERE `id` = (%0q)
)";
// same as SELECT_STMT2 for similicity later on
static constexpr const char* SELECT_STMT3 = R"(
SELECT * FROM `Transactions` WHERE `id` = (%0q)
)";
static constexpr const char* EXIST_STMT = R"(
SELECT * FROM `Transactions` WHERE `account_id` = (%0q) AND `hash` = (%1q)
)";
static constexpr const char* DELETE_STMT = R"(
DELETE FROM `Transactions` WHERE `id` = (%0q)
)";
static constexpr const char* INSERT_STMT = R"(
INSERT IGNORE INTO `Transactions` (`hash`, `prefix_hash`, `tx_pub_key`, `account_id`,
`blockchain_tx_id`,
`total_received`, `total_sent`, `unlock_time`,
`height`, `coinbase`, `is_rct`, `rct_type`,
`spendable`,
`payment_id`, `mixin`, `timestamp`)
VALUES (%0q, %1q, %2q, %3q,
%4q,
%5q, %6q, %7q,
%8q, %9q, %10q, %11q,
%12q,
%13q, %14q, %15q);
)";
static constexpr const char* MARK_AS_SPENDABLE_STMT = R"(
UPDATE `Transactions` SET `spendable` = 1, `timestamp` = CURRENT_TIMESTAMP
WHERE `id` = %0q;
)";
static constexpr const char* MARK_AS_NONSPENDABLE_STMT = R"(
UPDATE `Transactions` SET `spendable` = 0, `timestamp` = CURRENT_TIMESTAMP
WHERE `id` = %0q;
)";
static constexpr const char* SUM_XMR_RECIEVED = R"(
SELECT SUM(`total_received`) AS total_received
FROM `Transactions`
WHERE `account_id` = %0q
GROUP BY `account_id`
)";
using Transactions::Transactions;
static DateTime
timestamp_to_DateTime(time_t timestamp);
string table_name() const override { return this->table();};
json to_json() const override;
};
sql_create_13(Outputs, 1, 13,
sql_bigint_unsigned_null, id, // this is null so that we can set it to mysqlpp:null when inserting rows
sql_bigint_unsigned, account_id, // this way auto_increment of the id will take place and we can
sql_bigint_unsigned, tx_id, // use vector of outputs to write at once to mysql
sql_varchar , out_pub_key,
sql_varchar , rct_outpk,
sql_varchar , rct_mask,
sql_varchar , rct_amount,
sql_varchar , tx_pub_key,
sql_bigint_unsigned, amount,
sql_bigint_unsigned, global_index,
sql_bigint_unsigned, out_index,
sql_bigint_unsigned, mixin,
sql_timestamp , timestamp);
struct XmrOutput : public Outputs, Table
{
static constexpr const char* SELECT_STMT = R"(
SELECT * FROM `Outputs` WHERE `account_id` = (%0q)
)";
static constexpr const char* SELECT_STMT2 = R"(
SELECT * FROM `Outputs` WHERE `tx_id` = (%0q)
)";
static constexpr const char* SELECT_STMT3 = R"(
SELECT * FROM `Outputs` WHERE `id` = (%0q)
)";
static constexpr const char* EXIST_STMT = R"(
SELECT * FROM `Outputs` WHERE `out_pub_key` = (%0q)
)";
static constexpr const char* INSERT_STMT = R"(
INSERT IGNORE INTO `Outputs` (`account_id`, `tx_id`, `out_pub_key`,
`tx_pub_key`,
`rct_outpk`, `rct_mask`, `rct_amount`,
`amount`, `global_index`,
`out_index`, `mixin`, `timestamp`)
VALUES (%0q, %1q, %2q,
%3q,
%4q, %5q, %6q,
%7q, %8q,
%9q, %10q, %11q);
)";
using Outputs::Outputs;
string
get_rct() const
{
return rct_outpk + rct_mask + rct_amount;
}
string table_name() const override { return this->table();};
json to_json() const override;
};
sql_create_7(Inputs, 1, 7,
sql_bigint_unsigned_null, id,
sql_bigint_unsigned , account_id,
sql_bigint_unsigned , tx_id,
sql_bigint_unsigned , output_id,
sql_varchar , key_image,
sql_bigint_unsigned , amount,
sql_timestamp , timestamp);
struct XmrInput : public Inputs, Table
{
static constexpr const char* SELECT_STMT = R"(
SELECT * FROM `Inputs` WHERE `account_id` = (%0q)
)";
static constexpr const char* SELECT_STMT2 = R"(
SELECT * FROM `Inputs` WHERE `tx_id` = (%0q)
)";
static constexpr const char* SELECT_STMT3 = R"(
SELECT * FROM `Inputs` WHERE `id` = (%0q)
)";
static constexpr const char* SELECT_STMT4 = R"(
SELECT * FROM `Inputs` WHERE `output_id` = (%0q)
)";
static constexpr const char* INSERT_STMT = R"(
INSERT IGNORE INTO `Inputs` (`account_id`, `tx_id`, `output_id`,
`key_image`, `amount` , `timestamp`)
VALUES (%0q, %1q, %2q,
%3q, %4q, %5q);
)";
using Inputs::Inputs;
string table_name() const override { return this->table();};
json to_json() const override;
};
sql_create_9(Payments, 1, 7,
sql_bigint_unsigned_null, id,
sql_bigint_unsigned , account_id,
sql_varchar , payment_id,
sql_varchar , tx_hash,
sql_boolean , request_fulfilled,
sql_bigint_unsigned , import_fee,
sql_varchar , payment_address,
sql_timestamp , created,
sql_timestamp , modified);
struct XmrPayment : public Payments, Table
{
static constexpr const char* SELECT_STMT = R"(
SELECT * FROM `Payments` WHERE `account_id` = (%0q)
)";
static constexpr const char* SELECT_STMT2 = R"(
SELECT * FROM `Payments` WHERE `payment_id` = (%0q)
)";
static constexpr const char* SELECT_STMT3 = R"(
SELECT * FROM `Payments` WHERE `id` = (%0q)
)";
static constexpr const char* INSERT_STMT = R"(
INSERT IGNORE INTO `Payments` (`account_id`, `payment_id`, `tx_hash`,
`request_fulfilled`, `import_fee`,
`payment_address`)
VALUES (%0q, %1q, %2q, %3q, %4q, %5q);
)";
using Payments::Payments;
string table_name() const override { return this->table();};
json to_json() const override;
};
}
#endif //RESTBED_XMR_SSQLSES_H
Loading…
Cancel
Save