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>
28std::vector<std::string>
split(
const std::string&
s,
char delim) {
29 std::vector<std::string>
elems;
30 std::stringstream
ss(
s);
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) {
74 std::string
tbl = (*it)->title();
75 if (tbl_names_.count(
tbl) == 0) {
78 if (stmts_.count(
tbl) == 0) {
84 db_.
Execute(
"END TRANSACTION;");
87 db_.
Execute(
"END TRANSACTION;");
93std::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];
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)
143 rtn[
qr.fields[i]] =
qr.types[i];
151 std::string
sql =
"SELECT name FROM sqlite_master WHERE type='table';";
154 while (
stmt->Step()) {
157 rtn.erase(
"FieldTypes");
165QueryResult SqliteBack::GetTableInfo(std::string table) {
166 std::string
sql =
"SELECT Field,Type FROM FieldTypes WHERE TableName = '" +
173 for (i = 0;
stmt->Step(); ++i) {
178 throw ValueError(
"Invalid table name " + table);
187void SqliteBack::BuildStmt(
Datum*
d) {
188 std::string name =
d->title();
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;
204void SqliteBack::CreateTable(Datum*
d) {
205 std::string
name =
d->title();
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) <<
"');";
217 std::string
cmd =
"CREATE TABLE " +
name +
" (";
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) <<
"');";
235void 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>());
289 std::string
s =
v.cast<Blob>().str();
290 stmt->BindBlob(index,
s.c_str(),
s.size());
294 stmt->BindText(index,
v.cast<std::string>().c_str());
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>);
317 std::map<std::string
CYCLUS_COMMA std::vector<double> >);
320 std::map<std::string
CYCLUS_COMMA std::map<int CYCLUS_COMMA double> >);
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> > > >);
336 std::pair<std::string
CYCLUS_COMMA std::vector<double> > > );
342 std::map<std::string
CYCLUS_COMMA std::map<std::string CYCLUS_COMMA int> >);
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 > );
356 std::map<std::string
CYCLUS_COMMA std::map<std::string CYCLUS_COMMA double> >);
359 throw ValueError(
"attempted to retrieve unsupported sqlite backend type");
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));
401 v = std::string(
stmt->GetText(col,
NULL));
405 char*
s =
stmt->GetText(col, &n);
406 v = Blob(std::string(
s, n));
409 boost::uuids::uuid
u;
427 std::map<std::string CYCLUS_COMMA std::string>);
429 std::map<std::string
CYCLUS_COMMA std::vector<double> >);
432 std::map<std::string
CYCLUS_COMMA std::map<int CYCLUS_COMMA double> >);
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> > > >);
448 std::pair<std::string
CYCLUS_COMMA std::vector<double> > > );
454 std::map<std::string
CYCLUS_COMMA std::map<std::string CYCLUS_COMMA int> >);
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 > );
468 std::map<std::string
CYCLUS_COMMA std::map<std::string CYCLUS_COMMA double> >);
471 throw ValueError(
"Attempted to retrieve unsupported backend type");
498 bool operator()(
const std::type_info*
a,
const std::type_info* b)
const {
499 return a->before(*b);
503static std::map<const std::type_info*, DbTypes, compare>
type_map;
527 type_map[&
typeid(std::map<std::string, std::vector<double> >)] =
529 type_map[&
typeid(std::map<std::string, std::map<int, double> >)] =
531 type_map[&
typeid(std::map<std::string,
532 std::pair<double, std::map<int, double> > >)] =
534 type_map[&
typeid(std::map<int, std::map<std::string, double> >)] =
537 std::map<std::string,
538 std::vector<std::pair<
int, std::pair<std::string,
539 std::string> > > >)] =
543 std::map<std::string,
544 std::pair<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();
568 throw ValueError(std::string(
"unsupported backend type ") +
ti->name());
A type to represent variable-length array of bytes for dumping to a cyclus output database.
Represents a condition used to filter rows returned by a query.
std::string field
table column name
Used to specify and send a collection of key-value pairs to the Recorder for recording.
std::vector< Entry > Vals
A generic mechanism to manually manage exceptions.
Meta data and results of a query.
std::vector< std::string > fields
names of each field returned by a query
boost::shared_ptr< SqlStatement > Ptr
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.
virtual void Notify(DatumList data)
Writes Datum objects immediately to the database as a single transaction.
virtual std::set< std::string > Tables()
Return a set of all table names currently in the database.
virtual QueryResult Query(std::string table, std::vector< Cond > *conds)
Return a set of rows from the specificed table that match all given conditions.
std::string Name()
Returns a unique name for this backend.
SqliteDb & db()
Returns the underlying sqlite database.
SqliteBack(std::string path)
Creates a new sqlite backend that will write to the database file specified by path.
void Flush()
Executes all pending commands.
An abstraction over the Sqlite native C interface to simplify database creation and data insertion.
void open()
Opens the sqlite database by either opening/creating a file (default) or creating/overwriting a file ...
void close()
Finishes any incomplete operations and closes the database.
void Execute(std::string cmd)
Execute an SQL command.
SqlStatement::Ptr Prepare(std::string sql)
Creates a sqlite prepared statement for the given sql.
For values that are too big, too small, etc.
Code providing rudimentary logging capability for the Cyclus core.
taken directly from OsiSolverInterface.cpp on 2/17/14 from https://projects.coin-or....
std::vector< std::string > split(const std::string &s, char delim)
std::vector< Datum * > DatumList
@ LEV_ERROR
Use for errors that require agent code or input file modification (use extremely sparingly)
DbTypes
This is the primary list of all supported database types.
@ VECTOR_PAIR_PAIR_DOUBLE_DOUBLE_MAP_STRING_DOUBLE
@ MAP_STRING_MAP_STRING_DOUBLE
@ MAP_INT_MAP_STRING_DOUBLE
@ MAP_STRING_VECTOR_DOUBLE
@ MAP_STRING_VECTOR_PAIR_INT_PAIR_STRING_STRING
@ MAP_STRING_MAP_STRING_INT
@ MAP_PAIR_STRING_STRING_INT
@ MAP_STRING_PAIR_DOUBLE_MAP_INT_DOUBLE
@ MAP_STRING_PAIR_STRING_VECTOR_DOUBLE
@ MAP_STRING_MAP_INT_DOUBLE
std::vector< boost::spirit::hold_any > QueryRow
static std::map< const std::type_info *, DbTypes, compare > type_map
T OptionalQuery(InfileTree *tree, std::string query, T default_val)
a query method for optional parameters
std::string name(int nuc)
#define CYCLUS_BINDVAL(D, T)
#define CYCLUS_LOADVAL(D, T)
Represents column information.
bool operator()(const std::type_info *a, const std::type_info *b) const