Page MenuHomec4science

quantities_manager.hh
No OneTemporary

File Metadata

Created
Thu, May 9, 14:05

quantities_manager.hh

/*
author : Nicolas RICHART <nicolas.richart@epfl.ch>
*/
#ifndef __BLACKDYNAMITE_QUANTITIES_MANAGER_HH__
#define __BLACKDYNAMITE_QUANTITIES_MANAGER_HH__
#include "blackdynamite.hh"
#include <map>
namespace BlackDynamite {
class SQLConnectionManager;
class QuantitiesManager {
public:
QuantitiesManager(SQLConnectionManager & connection_manager, const std::string & sql_schema, UInt run_id);
~QuantitiesManager();
/// Get the id associated to a quantity
template<typename T> UInt getQuantityID(const std::string & name);
/// push a quantity in the database
template<typename T> void pushQuantity(const std::string & name, const T & value, UInt step);
/// push a string quantity in the database
void pushQuantity(const std::string & name, const std::string & value);
private:
typedef std::map<std::string, UInt> quantities_map;
class QueryQuantitiesRetreiver;
template<typename T> class QueryCreateQuantity;
protected:
SQLConnectionManager & connection_manager;
UInt run_id;
std::string schema;
quantities_map quantities;
static UInt quantities_manager_counter;
};
}
/* -------------------------------------------------------------------------- */
#include "sql_connection_manager.hh"
#include "common_types.hh"
#include "sql_query.hh"
namespace BlackDynamite {
/* ------------------------------------------------------------------------ */
/* Template implementation */
/* ------------------------------------------------------------------------ */
class QuantitiesManager::QueryQuantitiesRetreiver : public SQLQuery<bd_transaction> {
public:
QueryQuantitiesRetreiver(quantities_map & quantities) : quantities(quantities) { }
protected:
pqxx::result execute(pqxx::transaction_base & trans) {
pqxx::result r = trans.prepared("get_quantities").exec();
for(pqxx::result::size_type i = 0; i < r.size(); ++i) {
const pqxx::result::tuple & t = r[i];
UInt id; t[0].to(id);
std::string name; t[1].to(name);
this->quantities[name] = id;
}
return r;
}
protected:
quantities_map & quantities;
};
template<typename T>
class QuantitiesManager::QueryCreateQuantity : public SQLQuery<bd_transaction> {
public:
QueryCreateQuantity(const std::string & name, UInt & id) : name(name), id(id) { }
protected:
pqxx::result execute(pqxx::transaction_base & trans) {
bool is_vector = is_std_vector<T>::value;
bool is_integer = is_vector_of_integer<T>::value || std::is_integral<T>::value;
BLACKDYNAMITE_DEBUG("QuantitiesManager", "Create the quantity " + name);
pqxx::result q = trans.prepared("get_quantity")(name).exec();
if(q.empty()) {
pqxx::result r = trans.prepared("create_quantity")(name)(is_integer)(is_vector).exec();
r[0][0].to(this->id);
} else {
q[0][0].to(this->id);
}
return q;
}
protected:
std::string name;
UInt & id;
};
template<typename T>
UInt QuantitiesManager::getQuantityID(const std::string & name) {
quantities_map::const_iterator qit = this->quantities.find(name);
UInt quantity_id;
if (qit == this->quantities.end()) {
QueryCreateQuantity<T> query(name, quantity_id);
this->connection_manager.getConnection().perform(query);
this->quantities[name] = quantity_id;
} else {
quantity_id = qit->second;
}
return quantity_id;
}
/* ------------------------------------------------------------------------ */
template<typename T>
void QuantitiesManager::pushQuantity(const std::string & name, const T & value, UInt step) {
std::string query_name = "push_";
if(is_std_vector<T>::value) query_name += "vector_";
else query_name += "scalar_";
if (is_vector_of_integer<T>::value || std::is_integral<T>::value)
query_name += "integer";
else query_name += "real";
UInt quantity_id = getQuantityID<T>(name);
this->connection_manager.getConnection().perform(SQLPreparedQuery<bd_transaction, UInt, T, UInt>(query_name,
quantity_id,
value,
step));
}
}
#endif //__BLACKDYNAMITE_QUANTITIES_MANAGER_HH__

Event Timeline