6 #include <boost/lexical_cast.hpp> 7 #include <boost/uuid/uuid_io.hpp> 8 #include <boost/algorithm/string.hpp> 9 #include <boost/archive/tmpdir.hpp> 10 #include <boost/archive/xml_iarchive.hpp> 11 #include <boost/archive/xml_oarchive.hpp> 12 #include <boost/serialization/base_object.hpp> 13 #include <boost/serialization/utility.hpp> 14 #include <boost/serialization/list.hpp> 15 #include <boost/serialization/set.hpp> 16 #include <boost/serialization/vector.hpp> 17 #include <boost/serialization/map.hpp> 18 #include <boost/serialization/assume_abstract.hpp> 29 std::vector<std::string> elems;
30 std::stringstream ss(s);
32 while (std::getline(ss, item, delim)) {
33 elems.push_back(item);
51 db_.
Execute(
"PRAGMA synchronous=OFF;");
52 db_.
Execute(
"PRAGMA journal_mode=MEMORY;");
53 db_.
Execute(
"PRAGMA temp_store=MEMORY;");
57 stmt = db_.
Prepare(
"SELECT name FROM sqlite_master WHERE type='table';");
59 for (
int i = 0; stmt->Step(); ++i) {
60 tbl_names_.insert(stmt->GetText(0, NULL));
63 if (tbl_names_.count(
"FieldTypes") == 0) {
64 std::string cmd =
"CREATE TABLE IF NOT EXISTS FieldTypes";
65 cmd +=
"(TableName TEXT,Field TEXT,Type INTEGER);";
71 db_.
Execute(
"BEGIN TRANSACTION;");
73 for (DatumList::iterator it = data.begin(); it != data.end(); ++it) {
75 if (tbl_names_.count(tbl) == 0) {
78 if (stmts_.count(tbl) == 0) {
84 db_.
Execute(
"END TRANSACTION;");
87 db_.
Execute(
"END TRANSACTION;");
93 std::list<ColumnInfo> SqliteBack::Schema(
std::string table) {
94 std::list<ColumnInfo> schema;
96 for (
int i = 0; i < qr.
fields.size(); ++i) {
98 schema.push_back(info);
106 std::stringstream sql;
107 sql <<
"SELECT * FROM " << table;
110 for (
int i = 0; i < conds->size(); ++i) {
114 Cond c = (*conds)[i];
115 sql << c.
field <<
" " << c.
op <<
" ?";
123 for (
int i = 0; i < conds->size(); ++i) {
125 Bind(v, Type(v), stmt, i+1);
129 for (
int i = 0; stmt->Step(); ++i) {
131 for (
int j = 0; j < q.
fields.size(); ++j) {
132 r.push_back(ColAsVal(stmt, j, q.
types[j]));
141 std::map<std::string, DbTypes> rtn;
142 for (
int i = 0; i < qr.
fields.size(); ++i)
151 std::string sql =
"SELECT name FROM sqlite_master WHERE type='table';";
154 while (stmt->Step()) {
155 rtn.insert(stmt->GetText(0, NULL));
157 rtn.erase(
"FieldTypes");
166 std::string sql =
"SELECT Field,Type FROM FieldTypes WHERE TableName = '" +
173 for (i = 0; stmt->Step(); ++i) {
174 info.
fields.push_back(stmt->GetText(0, NULL));
178 throw ValueError(
"Invalid table name " + table);
187 void SqliteBack::BuildStmt(
Datum* d) {
190 std::vector<DbTypes> schema;
192 schema.push_back(Type(vals[0].second));
193 std::string insert =
"INSERT INTO " + name +
" VALUES (?";
194 for (
int i = 1; i < vals.size(); ++i) {
195 schema.push_back(Type(vals[i].second));
200 schemas_[
name] = schema;
204 void SqliteBack::CreateTable(
Datum* d) {
206 tbl_names_.insert(name);
209 Datum::Vals::iterator it = vals.begin();
211 std::stringstream types;
212 types <<
"INSERT INTO FieldTypes VALUES ('" 213 << name <<
"','" << it->first <<
"','" 214 << Type(it->second) <<
"');";
218 cmd +=
std::string(it->first) +
" " + SqlType(it->second);
221 while (it != vals.end()) {
222 cmd +=
", " +
std::string(it->first) +
" " + SqlType(it->second);
223 std::stringstream types;
224 types <<
"INSERT INTO FieldTypes VALUES ('" 225 << name <<
"','" << it->first <<
"','" 226 << Type(it->second) <<
"');";
235 void SqliteBack::WriteDatum(
Datum* d) {
238 std::vector<DbTypes> schema = schemas_[d->
title()];
240 for (
int i = 0; i < vals.size(); ++i) {
242 Bind(v, schema[i], stmt, i+1);
256 #define CYCLUS_COMMA , 257 #define CYCLUS_BINDVAL(D, T) \ 259 T vect = v.cast<T>(); \ 260 std::stringstream ss; \ 262 boost::archive::xml_oarchive ar(ss); \ 263 ar & BOOST_SERIALIZATION_NVP(vect); \ 266 std::string s = ss.str(); \ 267 stmt->BindBlob(index, s.c_str(), s.size()); \ 273 stmt->BindInt(index, v.
cast<
int>());
277 stmt->BindInt(index, v.
cast<
bool>());
281 stmt->BindDouble(index, v.
cast<
double>());
285 stmt->BindDouble(index, v.
cast<
float>());
290 stmt->BindBlob(index, s.c_str(), s.size());
298 boost::uuids::uuid ui = v.
cast<boost::uuids::uuid>();
299 stmt->BindBlob(index, ui.data, 16);
315 std::map<std::string CYCLUS_COMMA std::string>);
323 double CYCLUS_COMMA std::map<int CYCLUS_COMMA double> > >);
326 std::map<std::string CYCLUS_COMMA double> >);
331 std::pair<std::string CYCLUS_COMMA std::string> > > >);
346 std::vector<std::pair<
348 std::map<std::string CYCLUS_COMMA double> > > );
352 std::map<std::pair<std::string CYCLUS_COMMA std::string>
CYCLUS_COMMA int > );
359 throw ValueError(
"attempted to retrieve unsupported sqlite backend type");
362 #undef CYCLUS_BINDVAL 374 #define CYCLUS_COMMA , 375 #define CYCLUS_LOADVAL(D, T) \ 377 char* data = stmt->GetText(col, NULL); \ 378 std::stringstream ss; \ 380 boost::archive::xml_iarchive ar(ss); \ 382 ar & BOOST_SERIALIZATION_NVP(vect); \ 389 v = stmt->GetInt(col);
392 v =
static_cast<bool>(stmt->GetInt(col));
395 v = stmt->GetDouble(col);
398 v =
static_cast<float>(stmt->GetDouble(col));
405 char* s = stmt->GetText(col, &n);
409 boost::uuids::uuid u;
410 memcpy(&u, stmt->GetText(col, NULL), 16);
427 std::map<std::string CYCLUS_COMMA std::string>);
435 double CYCLUS_COMMA std::map<int CYCLUS_COMMA double> > >);
438 std::map<std::string CYCLUS_COMMA double> >);
443 std::pair<std::string CYCLUS_COMMA std::string> > > >);
458 std::vector<std::pair<
460 std::map<std::string CYCLUS_COMMA double> > > );
464 std::map<std::pair<std::string CYCLUS_COMMA std::string>
CYCLUS_COMMA int > );
471 throw ValueError(
"Attempted to retrieve unsupported backend type");
474 #undef CYCLUS_LOADVAL 498 bool operator()(
const std::type_info* a,
const std::type_info*
b)
const {
499 return a->before(*b);
503 static std::map<const std::type_info*, DbTypes, compare>
type_map;
506 if (type_map.size() == 0) {
507 type_map[&
typeid(int)] =
INT;
508 type_map[&
typeid(double)] =
DOUBLE;
509 type_map[&
typeid(float)] =
FLOAT;
510 type_map[&
typeid(bool)] =
BOOL;
512 type_map[&
typeid(boost::uuids::uuid)] =
UUID;
514 type_map[&
typeid(std::set<int>)] =
SET_INT;
515 type_map[&
typeid(std::set<std::string>)] =
SET_STRING;
516 type_map[&
typeid(std::vector<int>)] =
VECTOR_INT;
519 type_map[&
typeid(std::list<int>)] =
LIST_INT;
520 type_map[&
typeid(std::list<std::string>)] =
LIST_STRING;
521 type_map[&
typeid(std::map<int, int>)] =
MAP_INT_INT;
527 type_map[&
typeid(std::map<std::string, std::vector<double> >)] =
529 type_map[&
typeid(std::map<std::string, std::map<int, double> >)] =
532 std::pair<double, std::map<int, double> > >)] =
534 type_map[&
typeid(std::map<int, std::map<std::string, double> >)] =
539 std::string> > > >)] =
545 std::vector<double> > >)] =
548 type_map[&
typeid(std::map<std::string, std::map<std::string,int> >)] =
554 std::vector<std::pair<std::pair<double, double>,
555 std::map<std::string, double> > > )] =
559 std::map<std::pair<std::string, std::string>,
int > )] =
562 type_map[&
typeid(std::map<std::string, std::map<std::string,double> >)] =
566 const std::type_info* ti = &v.
type();
567 if (type_map.count(ti) == 0) {
const Vals & vals()
Returns a vector of all field-value pairs that have been added to this datum.
std::string title()
Returns the datum's title as specified during the datum's creation.
std::string op
One of: "<", ">", "<=", ">=", "==", "!=".
double b(int nuc)
Computes the scattering length [cm] from the coherent and incoherent components.
A generic mechanism to manually manage exceptions.
Meta data and results of a query.
boost::detail::sp_typeinfo const & type() const
An abstraction over the Sqlite native C interface to simplify database creation and data insertion...
#define CYCLUS_LOADVAL(D, T)
For values that are too big, too small, etc.
std::string Name()
Returns a unique name for this backend.
std::string name(int nuc)
SqlStatement::Ptr Prepare(std::string sql)
Creates a sqlite prepared statement for the given sql.
DbTypes
This is the master list of all supported database types.
def memcpy(dest, src, size)
virtual void Notify(DatumList data)
Writes Datum objects immediately to the database as a single transaction.
static std::map< const std::type_info *, DbTypes, compare > type_map
void open()
Opens the sqlite database by either opening/creating a file (default) or creating/overwriting a file ...
virtual QueryResult Query(std::string table, std::vector< Cond > *conds)
Return a set of rows from the specificed table that match all given conditions.
SqliteBack(std::string path)
Creates a new sqlite backend that will write to the database file specified by path.
Used to specify and send a collection of key-value pairs to the Recorder for recording.
std::vector< boost::spirit::hold_any > QueryRow
std::vector< std::string > fields
names of each field returned by a query
virtual std::set< std::string > Tables()
Return a set of all table names currently in the database.
std::vector< Entry > Vals
void Flush()
Executes all pending commands.
bool operator()(const std::type_info *a, const std::type_info *b) const
std::vector< DbTypes > types
types of each field returned by a query.
std::string field
table column name
boost::shared_ptr< SqlStatement > Ptr
Code providing rudimentary logging capability for the Cyclus core.
taken directly from OsiSolverInterface.cpp on 2/17/14 from https://projects.coin-or.org/Osi/browser/trunk.
A type to represent variable-length array of bytes for dumping to a cyclus output database...
std::vector< QueryRow > rows
ordered results of a query
Represents a condition used to filter rows returned by a query.
void close()
Finishes any incomplete operations and closes the database.
virtual const char * what() const
Returns the error message associated with this Error.
#define CYCLUS_BINDVAL(D, T)
std::vector< Datum * > DatumList
Use for errors that require agent code or input file modification (use extremely sparingly) ...
virtual std::map< std::string, DbTypes > ColumnTypes(std::string table)
Return a map of column names of the specified table to the associated database type.
SqliteDb & db()
Returns the underlying sqlite database.
Represents column information.
void Execute(std::string cmd)
Execute an SQL command.
std::vector< std::string > split(const std::string &s, char delim)