summaryrefslogtreecommitdiff
path: root/base/stats
diff options
context:
space:
mode:
authorNathan Binkert <binkertn@umich.edu>2004-05-21 13:57:44 -0400
committerNathan Binkert <binkertn@umich.edu>2004-05-21 13:57:44 -0400
commitfee1e1ec0a9c1122f3c42fdef9482c64389949fc (patch)
tree445583609f8f81f0cffac71606db9fecd278c3c7 /base/stats
parentb4405682d9f0d7bd01ff461a7e457f8dbbfff1a0 (diff)
downloadgem5-fee1e1ec0a9c1122f3c42fdef9482c64389949fc.tar.xz
Add support for event tracking. Esentially this puts a sequence
of events into the database for a given run. base/stats/mysql.cc: base/stats/mysql.hh: reorganize mysql stat stuff so that other stuff can use the same database connection base/traceflags.py: Trace flag to print out events --HG-- extra : convert_revision : 4d502532ed0ba40b42baefee46b2c99defcc620c
Diffstat (limited to 'base/stats')
-rw-r--r--base/stats/events.cc105
-rw-r--r--base/stats/events.hh63
-rw-r--r--base/stats/mysql.cc199
-rw-r--r--base/stats/mysql.hh44
-rw-r--r--base/stats/mysql_run.hh63
5 files changed, 319 insertions, 155 deletions
diff --git a/base/stats/events.cc b/base/stats/events.cc
new file mode 100644
index 000000000..3a858611f
--- /dev/null
+++ b/base/stats/events.cc
@@ -0,0 +1,105 @@
+/*
+ * Copyright (c) 2004 The Regents of The University of Michigan
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met: redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer;
+ * redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution;
+ * neither the name of the copyright holders nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifdef USE_MYSQL
+#include "base/cprintf.hh"
+#include "base/misc.hh"
+#include "base/mysql.hh"
+#include "base/stats/events.hh"
+#include "base/stats/mysql.hh"
+#include "base/stats/mysql_run.hh"
+#include "base/str.hh"
+#endif
+
+#include "sim/host.hh"
+#include "sim/universe.hh"
+
+using namespace std;
+
+namespace Stats {
+
+Tick EventStart = ULL(0xffffffffffffffff);
+
+#ifdef USE_MYSQL
+typedef map<string, uint32_t> event_map_t;
+event_map_t event_map;
+
+void
+__event(const string &stat)
+{
+ MySQL::Connection &mysql = MySqlDB.conn();
+ uint16_t run = MySqlDB.run();
+ assert(mysql.connected());
+
+ event_map_t::iterator i = event_map.find(stat);
+ uint32_t event;
+ if (i == event_map.end()) {
+ mysql.query(
+ csprintf("SELECT en_id "
+ "from event_names "
+ "where en_name=\"%s\"",
+ stat));
+
+ MySQL::Result result = mysql.store_result();
+ if (result) {
+ assert(result.num_fields() == 1);
+ MySQL::Row row = result.fetch_row();
+ if (!row)
+ panic("could not get a run\n%s\n", mysql.error);
+ if (!to_number(row[0], event))
+ panic("invalid event id: %s\n", row[0]);
+ } else {
+ mysql.query(
+ csprintf("INSERT INTO "
+ "event_names(en_name)"
+ "values(\"%s\")",
+ stat));
+
+ if (mysql.error)
+ panic("could not get a run\n%s\n", mysql.error);
+
+ event = mysql.insert_id();
+ }
+
+ } else {
+ event = (*i).second;
+ }
+
+ mysql.query(
+ csprintf("INSERT INTO "
+ "events(ev_event, ev_run, ev_tick)"
+ "values(%d, %d, %d)",
+ event, run, curTick));
+
+ if (mysql.error)
+ panic("could not get a run\n%s\n", mysql.error);
+
+}
+#endif
+
+/* namespace Stats */ }
diff --git a/base/stats/events.hh b/base/stats/events.hh
new file mode 100644
index 000000000..49c060645
--- /dev/null
+++ b/base/stats/events.hh
@@ -0,0 +1,63 @@
+/*
+ * Copyright (c) 2004 The Regents of The University of Michigan
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met: redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer;
+ * redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution;
+ * neither the name of the copyright holders nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef __BASE_STATS_EVENTS_HH__
+#define __BASE_STATS_EVENTS_HH__
+
+#include <string>
+
+#include "base/trace.hh"
+
+namespace Stats {
+
+extern Tick EventStart;
+
+#ifdef USE_MYSQL
+void __event(const std::string &stat);
+bool MySqlConnected();
+#endif
+
+inline void
+recordEvent(const std::string &stat)
+{
+ if (EventStart > curTick)
+ return;
+
+ DPRINTF(StatEvents, "Statistics Event: %s\n", stat);
+
+#ifdef USE_MYSQL
+ if (!MySqlConnected())
+ return;
+
+ __event(stat);
+#endif
+}
+
+/* namespace Stats */ }
+
+#endif // __BASE_STATS_EVENTS_HH__
diff --git a/base/stats/mysql.cc b/base/stats/mysql.cc
index c16332d1b..05808c211 100644
--- a/base/stats/mysql.cc
+++ b/base/stats/mysql.cc
@@ -37,6 +37,7 @@
#include "base/statistics.hh"
#include "base/stats/flags.hh"
#include "base/stats/mysql.hh"
+#include "base/stats/mysql_run.hh"
#include "base/stats/statdb.hh"
#include "base/stats/types.hh"
#include "base/str.hh"
@@ -46,17 +47,33 @@ using namespace std;
namespace Stats {
-struct MySqlData
+MySqlRun MySqlDB;
+
+bool
+MySqlConnected()
{
- map<int, int> idmap;
- MySQL::Connection conn;
-};
+ return MySqlDB.connected();
+}
-int
-SetupRun(MySqlData *data, const string &name, const string &user,
- const string &project)
+void
+MySqlRun::connect(const string &host, const string &user, const string &passwd,
+ const string &db, const string &name, const string &project)
+{
+ if (connected())
+ panic("can only get one database connection at this time!");
+
+ mysql.connect(host, user, passwd, db);
+ if (mysql.error)
+ panic("could not connect to database server\n%s\n", mysql.error);
+
+ remove(name);
+ cleanup();
+ setup(name, user, project);
+}
+
+void
+MySqlRun::setup(const string &name, const string &user, const string &project)
{
- MySQL::Connection &mysql = data->conn;
assert(mysql.connected());
stringstream insert;
@@ -71,13 +88,12 @@ SetupRun(MySqlData *data, const string &name, const string &user,
if (mysql.error)
panic("could not get a run\n%s\n", mysql.error);
- return mysql.insert_id();
+ run_id = mysql.insert_id();
}
void
-DeleteRun(MySqlData *data, const string &name)
+MySqlRun::remove(const string &name)
{
- MySQL::Connection &mysql = data->conn;
assert(mysql.connected());
stringstream sql;
ccprintf(sql, "DELETE FROM runs WHERE rn_name=\"%s\"", name);
@@ -85,9 +101,8 @@ DeleteRun(MySqlData *data, const string &name)
}
void
-Cleanup(MySqlData *data)
+MySqlRun::cleanup()
{
- MySQL::Connection &mysql = data->conn;
assert(mysql.connected());
mysql.query("DELETE data "
@@ -142,9 +157,9 @@ SetupStat::init()
}
unsigned
-SetupStat::operator()(MySqlData *data)
+SetupStat::setup()
{
- MySQL::Connection &mysql = data->conn;
+ MySQL::Connection &mysql = MySqlDB.conn();
stringstream insert;
ccprintf(insert,
@@ -245,9 +260,9 @@ SetupStat::operator()(MySqlData *data)
}
unsigned
-SetupBin(MySqlData *data, const string &bin)
+SetupBin(const string &bin)
{
- MySQL::Connection &mysql = data->conn;
+ MySQL::Connection &mysql = MySqlDB.conn();
assert(mysql.connected());
using namespace MySQL;
@@ -292,8 +307,9 @@ void
InsertData::flush()
{
if (size) {
- assert(mysql && mysql->connected());
- mysql->query(query);
+ MySQL::Connection &mysql = MySqlDB.conn();
+ assert(mysql.connected());
+ mysql.query(query);
}
query[0] = '\0';
@@ -319,7 +335,8 @@ InsertData::insert()
first = false;
size += sprintf(query + size, "(%u,%d,%d,%u,%llu,%u,\"%f\")",
- stat, x, y, run, (unsigned long long)sample, bin, data);
+ stat, x, y, MySqlDB.run(), (unsigned long long)sample,
+ bin, data);
}
struct InsertSubData
@@ -330,13 +347,13 @@ struct InsertSubData
string name;
string descr;
- void operator()(MySqlData *data);
+ void setup();
};
void
-InsertSubData::operator()(MySqlData *data)
+InsertSubData::setup()
{
- MySQL::Connection &mysql = data->conn;
+ MySQL::Connection &mysql = MySqlDB.conn();
assert(mysql.connected());
stringstream insert;
ccprintf(insert,
@@ -348,10 +365,9 @@ InsertSubData::operator()(MySqlData *data)
}
void
-InsertFormula(MySqlData *data, uint16_t stat, uint16_t run,
- const string &formula)
+InsertFormula(uint16_t stat, const string &formula)
{
- MySQL::Connection &mysql = data->conn;
+ MySQL::Connection &mysql = MySqlDB.conn();
assert(mysql.connected());
stringstream insert_formula;
ccprintf(insert_formula,
@@ -363,15 +379,15 @@ InsertFormula(MySqlData *data, uint16_t stat, uint16_t run,
stringstream insert_ref;
ccprintf(insert_ref,
"INSERT INTO formula_ref(fr_stat,fr_run) values(%d, %d)",
- stat, run);
+ stat, MySqlDB.run());
mysql.query(insert_ref);
}
void
-UpdatePrereq(MySqlData *data, uint16_t stat, uint16_t prereq)
+UpdatePrereq(uint16_t stat, uint16_t prereq)
{
- MySQL::Connection &mysql = data->conn;
+ MySQL::Connection &mysql = MySqlDB.conn();
assert(mysql.connected());
stringstream update;
ccprintf(update, "UPDATE stats SET st_prereq=%d WHERE st_id=%d",
@@ -379,98 +395,6 @@ UpdatePrereq(MySqlData *data, uint16_t stat, uint16_t prereq)
mysql.query(update);
}
-#if 0
-class InsertData
-{
- private:
- MySQL::Connection &mysql;
- MySQL::Statement stmt;
-
- public:
- InsertData(MySqlData *data)
- : mysql(data->conn)
- {
- stmt.prepare("INSERT INTO "
- "data(dt_stat,dt_x,dt_y,dt_run,dt_sample,dt_bin,dt_data) "
- "values(?,?,?,?,?,?,?)");
- assert(stmt.count() == 7 && "param count invalid");
-
- stmt[0].buffer = stat;
- stmt[1].buffer = x;
- stmt[2].buffer = y;
- stmt[3].buffer = run;
- stmt[4].buffer = sample;
- stmt[5].buffer = bin;
- stmt[6].buffer = data;
-
- stmt.bind(bind);
- if (stmt.error)
- panic("bind param failed\n%s\n", stmt.error);
- }
-
- public:
- uint64_t sample;
- uint64_t data;
- uint16_t stat;
- uint16_t bin;
- int16_t x;
- int16_t y;
-
- void operator()(MySQL::Connection &mysql)
- {
- assert(mysql.connected())
- stmt();
- }
-};
-#endif
-
-
-MySql::MySql()
- : mysql(NULL), configured(false)
-{
-}
-
-MySql::~MySql()
-{
- if (mysql)
- delete mysql;
-}
-
-void
-MySql::insert(int sim_id, int db_id)
-{
- mysql->idmap.insert(make_pair(sim_id, db_id));
-}
-
-int
-MySql::find(int sim_id)
-{
- map<int,int>::const_iterator i = mysql->idmap.find(sim_id);
- assert(i != mysql->idmap.end());
- return (*i).second;
-}
-
-bool
-MySql::valid() const
-{
- return mysql && mysql->conn.connected();
-}
-
-void
-MySql::connect(const string &host, const string &user, const string &passwd,
- const string &db, const string &name, const string &project)
-{
- mysql = new MySqlData;
- newdata.mysql = &mysql->conn;
- mysql->conn.connect(host, user, passwd, db);
- if (mysql->conn.error)
- panic("could not connect to database server\n%s\n", mysql->conn.error);
-
- DeleteRun(mysql, name);
- Cleanup(mysql);
- run_id = SetupRun(mysql, name, user, project);
-}
-
void
MySql::configure()
{
@@ -489,7 +413,7 @@ MySql::configure()
uint16_t prereq_id = find(data->prereq->id);
assert(stat_id && prereq_id);
- UpdatePrereq(mysql, stat_id, prereq_id);
+ UpdatePrereq(stat_id, prereq_id);
}
}
@@ -517,14 +441,14 @@ void
MySql::configure(const ScalarData &data)
{
configure(data, "SCALAR");
- insert(data.id, stat(mysql));
+ insert(data.id, stat.setup());
}
void
MySql::configure(const VectorData &data)
{
configure(data, "VECTOR");
- uint16_t statid = stat(mysql);
+ uint16_t statid = stat.setup();
if (!data.subnames.empty()) {
InsertSubData subdata;
@@ -536,7 +460,7 @@ MySql::configure(const VectorData &data)
subdata.descr = data.subdescs.empty() ? "" : data.subdescs[i];
if (!subdata.name.empty() || !subdata.descr.empty())
- subdata(mysql);
+ subdata.setup();
}
}
@@ -553,7 +477,7 @@ MySql::configure(const DistData &data)
stat.max = data.data.max;
stat.bktsize = data.data.bucket_size;
}
- insert(data.id, stat(mysql));
+ insert(data.id, stat.setup());
}
void
@@ -568,7 +492,7 @@ MySql::configure(const VectorDistData &data)
stat.bktsize = data.data[0].bucket_size;
}
- uint16_t statid = stat(mysql);
+ uint16_t statid = stat.setup();
if (!data.subnames.empty()) {
InsertSubData subdata;
@@ -579,7 +503,7 @@ MySql::configure(const VectorDistData &data)
subdata.name = data.subnames[i];
subdata.descr = data.subdescs.empty() ? "" : data.subdescs[i];
if (!subdata.name.empty() || !subdata.descr.empty())
- subdata(mysql);
+ subdata.setup();
}
}
@@ -590,7 +514,7 @@ void
MySql::configure(const Vector2dData &data)
{
configure(data, "VECTOR2D");
- uint16_t statid = stat(mysql);
+ uint16_t statid = stat.setup();
if (!data.subnames.empty()) {
InsertSubData subdata;
@@ -601,7 +525,7 @@ MySql::configure(const Vector2dData &data)
subdata.name = data.subnames[i];
subdata.descr = data.subdescs.empty() ? "" : data.subdescs[i];
if (!subdata.name.empty() || !subdata.descr.empty())
- subdata(mysql);
+ subdata.setup();
}
}
@@ -614,7 +538,7 @@ MySql::configure(const Vector2dData &data)
subdata.y = i;
subdata.name = data.y_subnames[i];
if (!subdata.name.empty())
- subdata(mysql);
+ subdata.setup();
}
}
@@ -625,20 +549,26 @@ void
MySql::configure(const FormulaData &data)
{
configure(data, "FORMULA");
- insert(data.id, stat(mysql));
+ insert(data.id, stat.setup());
}
void
MySql::output(const string &bin)
{
// set up new bin in database if there is a bin name
- newdata.bin = bin.empty() ? 0 : SetupBin(mysql, bin);
+ newdata.bin = bin.empty() ? 0 : SetupBin(bin);
Database::stat_list_t::const_iterator i, end = Database::stats().end();
for (i = Database::stats().begin(); i != end; ++i)
(*i)->visit(*this);
}
+bool
+MySql::valid() const
+{
+ return MySqlDB.connected();
+}
+
void
MySql::output()
{
@@ -649,7 +579,6 @@ MySql::output()
configure();
// store sample #
- newdata.run = run_id;
newdata.sample = curTick;
if (bins().empty()) {
@@ -781,7 +710,7 @@ MySql::output(const Vector2dData &data)
void
MySql::output(const FormulaData &data)
{
- InsertFormula(mysql, find(data.id), run_id, data.str());
+ InsertFormula(find(data.id), data.str());
}
/*
diff --git a/base/stats/mysql.hh b/base/stats/mysql.hh
index dd88f5724..4671b89dd 100644
--- a/base/stats/mysql.hh
+++ b/base/stats/mysql.hh
@@ -29,15 +29,17 @@
#ifndef __BASE_STATS_MYSQL_HH__
#define __BASE_STATS_MYSQL_HH__
+#include <map>
#include <string>
#include "base/stats/output.hh"
-namespace MySQL { class Connection; }
namespace Stats {
class DistDataData;
-class MySqlData;
+class MySqlRun;
+bool MySqlConnected();
+extern MySqlRun MySqlDB;
struct SetupStat
{
@@ -58,7 +60,7 @@ struct SetupStat
uint16_t size;
void init();
- unsigned operator()(MySqlData *data);
+ unsigned setup();
};
class InsertData
@@ -70,14 +72,13 @@ class InsertData
static const int maxsize = 1024*1024;
public:
- MySQL::Connection *mysql;
+ MySqlRun *run;
public:
uint64_t sample;
double data;
uint16_t stat;
uint16_t bin;
- uint16_t run;
int16_t x;
int16_t y;
@@ -92,25 +93,28 @@ class InsertData
class MySql : public Output
{
protected:
- std::list<FormulaData *> formulas;
- MySqlData *mysql;
- bool configured;
- uint16_t run_id;
-
SetupStat stat;
InsertData newdata;
+ std::list<FormulaData *> formulas;
+ bool configured;
- void insert(int sim_id, int db_id);
- int find(int sim_id);
-
+ protected:
+ std::map<int, int> idmap;
+
+ void insert(int sim_id, int db_id)
+ {
+ using namespace std;
+ idmap.insert(make_pair(sim_id, db_id));
+ }
+
+ int find(int sim_id)
+ {
+ using namespace std;
+ map<int,int>::const_iterator i = idmap.find(sim_id);
+ assert(i != idmap.end());
+ return (*i).second;
+ }
public:
- MySql();
- ~MySql();
-
- void connect(const std::string &host, const std::string &user,
- const std::string &passwd, const std::string &db,
- const std::string &name, const std::string &project);
-
// Implement Visit
virtual void visit(const ScalarData &data);
virtual void visit(const VectorData &data);
diff --git a/base/stats/mysql_run.hh b/base/stats/mysql_run.hh
new file mode 100644
index 000000000..0f8d84297
--- /dev/null
+++ b/base/stats/mysql_run.hh
@@ -0,0 +1,63 @@
+/*
+ * Copyright (c) 2004 The Regents of The University of Michigan
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met: redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer;
+ * redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution;
+ * neither the name of the copyright holders nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef __BASE_STATS_MYSQL_RUN_HH__
+#define __BASE_STATS_MYSQL_RUN_HH__
+
+#include <string>
+
+#include "base/mysql.hh"
+#include "sim/host.hh"
+
+namespace Stats {
+
+struct MySqlRun
+{
+ private:
+ MySQL::Connection mysql;
+ uint16_t run_id;
+
+ public:
+ bool connected() const { return mysql.connected(); }
+ void connect(const std::string &host, const std::string &user,
+ const std::string &passwd, const std::string &db,
+ const std::string &name, const std::string &project);
+
+ void setup(const std::string &name, const std::string &user,
+ const std::string &project);
+
+ void remove(const std::string &name);
+ void cleanup();
+
+ MySQL::Connection &conn() { return mysql; }
+ uint16_t run() const { return run_id; }
+};
+
+/* namespace Stats */ }
+
+#endif // __BASE_STATS_MYSQL_RUN_HH__