A Discrete-Event Network Simulator
API
sqlite-data-output.cc
Go to the documentation of this file.
1 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2 /*
3  * Copyright (c) 2008 Drexel University
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License version 2 as
7  * published by the Free Software Foundation;
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software
16  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17  *
18  * Author: Joe Kopena (tjkopena@cs.drexel.edu)
19  */
20 
21 #include <sstream>
22 
23 #include <sqlite3.h>
24 
25 #include "ns3/log.h"
26 #include "ns3/nstime.h"
27 
28 #include "data-collector.h"
29 #include "data-calculator.h"
30 #include "sqlite-data-output.h"
31 
32 using namespace ns3;
33 
34 NS_LOG_COMPONENT_DEFINE ("SqliteDataOutput");
35 
36 //--------------------------------------------------------------
37 //----------------------------------------------
39 {
40  NS_LOG_FUNCTION (this);
41 
42  m_filePrefix = "data";
43 }
45 {
46  NS_LOG_FUNCTION (this);
47 }
48 /* static */
49 TypeId
51 {
52  static TypeId tid = TypeId ("ns3::SqliteDataOutput")
54  .SetGroupName ("Stats")
55  .AddConstructor<SqliteDataOutput> ();
56  return tid;
57 }
58 
59 void
61 {
62  NS_LOG_FUNCTION (this);
63 
65  // end SqliteDataOutput::DoDispose
66 }
67 
68 int
69 SqliteDataOutput::Exec (std::string exe) {
70  NS_LOG_FUNCTION (this << exe);
71 
72  int res;
73  char **result;
74  int nrows, ncols;
75  char *errMsg = 0;
76 
77  NS_LOG_INFO ("executing '" << exe << "'");
78 
79  res = sqlite3_get_table (m_db,
80  exe.c_str (),
81  &result, &nrows, &ncols,
82  &errMsg);
83 
84  if (res != SQLITE_OK) {
85  NS_LOG_ERROR ("sqlite3 error: \"" << errMsg << "\"");
86  /*
87  } else {
88  // std::cout << "nrows " << nrows << " ncols " << ncols << std::endl;
89 
90  if (nrows > 0) {
91  for (int i = 0; i < ncols; i++) {
92  std::cout << " " << result[i];
93  }
94  std::cout << std::endl;
95 
96  for (int r = 1; r <= nrows; r++) {
97  for (int c = 0; c < ncols; c++) {
98  std::cout << " " << result[(r*ncols)+c];
99  }
100  std::cout << std::endl;
101  }
102  std::cout << std::endl;
103  }
104  */
105  }
106 
107  sqlite3_free_table (result);
108  return res;
109 
110  // end SqliteDataOutput::Exec
111 }
112 
113 //----------------------------------------------
114 void
116 {
117  NS_LOG_FUNCTION (this << &dc);
118 
119  std::string m_dbFile = m_filePrefix + ".db";
120 
121  if (sqlite3_open (m_dbFile.c_str (), &m_db)) {
122  NS_LOG_ERROR ("Could not open sqlite3 database \"" << m_dbFile << "\"");
123  NS_LOG_ERROR ("sqlite3 error \"" << sqlite3_errmsg (m_db) << "\"");
124  sqlite3_close (m_db);
126  return;
127  }
128 
129  Exec ("create table if not exists Experiments (run, experiment, strategy, input, description text)");
130 
131  sqlite3_stmt *stmt;
132  sqlite3_prepare_v2 (m_db,
133  "insert into Experiments (run, experiment, strategy, input, description) values (?, ?, ?, ?, ?)",
134  -1,
135  &stmt,
136  NULL
137  );
138 
139  std::string run = dc.GetRunLabel ();
140  sqlite3_bind_text (stmt, 1, run.c_str (), run.length (), SQLITE_TRANSIENT);
141  sqlite3_bind_text (stmt, 2, dc.GetExperimentLabel ().c_str (),
142  dc.GetExperimentLabel ().length (), SQLITE_TRANSIENT);
143  sqlite3_bind_text (stmt, 3, dc.GetStrategyLabel ().c_str (),
144  dc.GetStrategyLabel ().length (), SQLITE_TRANSIENT);
145  sqlite3_bind_text (stmt, 4, dc.GetInputLabel ().c_str (),
146  dc.GetInputLabel ().length (), SQLITE_TRANSIENT);
147  sqlite3_bind_text (stmt, 5, dc.GetDescription ().c_str (),
148  dc.GetDescription ().length (), SQLITE_TRANSIENT);
149  sqlite3_step (stmt);
150  sqlite3_finalize (stmt);
151 
152  Exec ("create table if not exists Metadata ( run text, key text, value)");
153 
154  sqlite3_prepare_v2 (m_db,
155  "insert into Metadata (run, key, value) values (?, ?, ?)",
156  -1,
157  &stmt,
158  NULL
159  );
160  for (MetadataList::iterator i = dc.MetadataBegin ();
161  i != dc.MetadataEnd (); i++) {
162  std::pair<std::string, std::string> blob = (*i);
163 
164  sqlite3_reset (stmt);
165  sqlite3_bind_text (stmt, 1, run.c_str (),
166  run.length (), SQLITE_TRANSIENT);
167  sqlite3_bind_text (stmt, 2, blob.first.c_str (),
168  blob.first.length (), SQLITE_TRANSIENT);
169  sqlite3_bind_text (stmt, 3, blob.second.c_str (),
170  blob.second.length (), SQLITE_TRANSIENT);
171  sqlite3_step (stmt);
172  }
173  sqlite3_finalize (stmt);
174 
175  Exec ("BEGIN");
176  SqliteOutputCallback callback (this, run);
177  for (DataCalculatorList::iterator i = dc.DataCalculatorBegin ();
178  i != dc.DataCalculatorEnd (); i++) {
179  (*i)->Output (callback);
180  }
181  Exec ("COMMIT");
182 
183  sqlite3_close (m_db);
184 
185  // end SqliteDataOutput::Output
186 }
187 
189  (Ptr<SqliteDataOutput> owner, std::string run) :
190  m_owner (owner),
191  m_runLabel (run)
192 {
193  NS_LOG_FUNCTION (this << owner << run);
194 
195  m_owner->Exec ("create table if not exists Singletons ( run text, name text, variable text, value )");
196 
197  sqlite3_prepare_v2 (m_owner->m_db,
198  "insert into Singletons (run, name, variable, value) values (?, ?, ?, ?)",
199  -1,
200  &m_insertSingletonStatement,
201  NULL
202  );
203  sqlite3_bind_text (m_insertSingletonStatement, 1, m_runLabel.c_str (), m_runLabel.length (), SQLITE_TRANSIENT);
204 
205  // end SqliteDataOutput::SqliteOutputCallback::SqliteOutputCallback
206 }
207 
209 {
210  sqlite3_finalize (m_insertSingletonStatement);
211 }
212 
213 void
215  std::string variable,
216  const StatisticalSummary *statSum)
217 {
218  NS_LOG_FUNCTION (this << key << variable << statSum);
219 
220  OutputSingleton (key,variable+"-count", (double)statSum->getCount ());
221  if (!isNaN (statSum->getSum ()))
222  OutputSingleton (key,variable+"-total", statSum->getSum ());
223  if (!isNaN (statSum->getMax ()))
224  OutputSingleton (key,variable+"-max", statSum->getMax ());
225  if (!isNaN (statSum->getMin ()))
226  OutputSingleton (key,variable+"-min", statSum->getMin ());
227  if (!isNaN (statSum->getSqrSum ()))
228  OutputSingleton (key,variable+"-sqrsum", statSum->getSqrSum ());
229  if (!isNaN (statSum->getStddev ()))
230  OutputSingleton (key,variable+"-stddev", statSum->getStddev ());
231 }
232 
233 
234 void
236  std::string variable,
237  int val)
238 {
239  NS_LOG_FUNCTION (this << key << variable << val);
240 
241  sqlite3_reset (m_insertSingletonStatement);
242  sqlite3_bind_text (m_insertSingletonStatement, 2, key.c_str (), key.length (), SQLITE_TRANSIENT);
243  sqlite3_bind_text (m_insertSingletonStatement, 3, variable.c_str (), variable.length (), SQLITE_TRANSIENT);
244  sqlite3_bind_int (m_insertSingletonStatement, 4, val);
245  sqlite3_step (m_insertSingletonStatement);
246 }
247 void
249  std::string variable,
250  uint32_t val)
251 {
252  NS_LOG_FUNCTION (this << key << variable << val);
253 
254  sqlite3_reset (m_insertSingletonStatement);
255  sqlite3_bind_text (m_insertSingletonStatement, 2, key.c_str (), key.length (), SQLITE_TRANSIENT);
256  sqlite3_bind_text (m_insertSingletonStatement, 3, variable.c_str (), variable.length (), SQLITE_TRANSIENT);
257  sqlite3_bind_int64 (m_insertSingletonStatement, 4, val);
258  sqlite3_step (m_insertSingletonStatement);
259 }
260 
261 void
263  std::string variable,
264  double val)
265 {
266  NS_LOG_FUNCTION (this << key << variable << val);
267 
268  sqlite3_reset (m_insertSingletonStatement);
269  sqlite3_bind_text (m_insertSingletonStatement, 2, key.c_str (), key.length (), SQLITE_TRANSIENT);
270  sqlite3_bind_text (m_insertSingletonStatement, 3, variable.c_str (), variable.length (), SQLITE_TRANSIENT);
271  sqlite3_bind_double (m_insertSingletonStatement, 4, val);
272  sqlite3_step (m_insertSingletonStatement);
273 }
274 
275 void
277  std::string variable,
278  std::string val)
279 {
280  NS_LOG_FUNCTION (this << key << variable << val);
281 
282  sqlite3_reset (m_insertSingletonStatement);
283  sqlite3_bind_text (m_insertSingletonStatement, 2, key.c_str (), key.length (), SQLITE_TRANSIENT);
284  sqlite3_bind_text (m_insertSingletonStatement, 3, variable.c_str (), variable.length (), SQLITE_TRANSIENT);
285  sqlite3_bind_text (m_insertSingletonStatement, 4, val.c_str (), val.length (), SQLITE_TRANSIENT);
286  sqlite3_step (m_insertSingletonStatement);
287 }
288 
289 void
291  std::string variable,
292  Time val)
293 {
294  NS_LOG_FUNCTION (this << key << variable << val);
295 
296  sqlite3_reset (m_insertSingletonStatement);
297  sqlite3_bind_text (m_insertSingletonStatement, 2, key.c_str (), key.length (), SQLITE_TRANSIENT);
298  sqlite3_bind_text (m_insertSingletonStatement, 3, variable.c_str (), variable.length (), SQLITE_TRANSIENT);
299  sqlite3_bind_int64 (m_insertSingletonStatement, 4, val.GetTimeStep ());
300  sqlite3_step (m_insertSingletonStatement);
301 }
DataCalculatorList::iterator DataCalculatorEnd()
Returns an iterator to the past-the-end of the DataCalculator list.
Simulation virtual time values and global simulation resolution.
Definition: nstime.h:102
Abstract Data Output Interface class s.
Smart pointer class similar to boost::intrusive_ptr.
Definition: ptr.h:73
#define NS_LOG_FUNCTION(parameters)
If log level LOG_FUNCTION is enabled, this macro will output all input parameters separated by "...
virtual double getMin() const =0
Returns the minimum of the values.
Abstract class for calculating statistical data.
virtual double getSqrSum() const =0
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:201
std::string GetRunLabel() const
Return the runID label.
#define NS_LOG_INFO(msg)
Use NS_LOG to output a message of level LOG_INFO.
Definition: log.h:244
sqlite3_stmt * m_insertSingletonStatement
Prepared singleton insert statement.
Class to generate OMNeT output.
virtual double getStddev() const =0
Returns the standard deviation of the (weighted) observations.
MetadataList::iterator MetadataBegin()
Returns an iterator to the beginning of the metadata list.
virtual double getMax() const =0
Returns the maximum of the values.
virtual void DoDispose()
Destructor implementation.
std::string GetStrategyLabel() const
Return the strategy label.
std::string GetExperimentLabel() const
Return the experiment label.
SqliteOutputCallback(Ptr< SqliteDataOutput > owner, std::string run)
Constructor.
std::string m_filePrefix
File prefix for the DataOutputInterface.
Every class exported by the ns3 library is enclosed in the ns3 namespace.
Outputs data in a format compatible with SQLite.
int64_t GetTimeStep(void) const
Get the raw time value, in the current resolution unit.
Definition: nstime.h:377
virtual double getSum() const =0
static TypeId GetTypeId(void)
Register this type.
void OutputSingleton(std::string key, std::string variable, int val)
Generates a single data output.
Collects data.
std::string GetDescription() const
Return the description label.
virtual void DoDispose()
Destructor implementation.
DataCalculatorList::iterator DataCalculatorBegin()
Returns an iterator to the beginning of the DataCalculator list.
sqlite3 * m_db
pointer to the SQL database
bool isNaN(double x)
true if x is NaN
#define NS_LOG_ERROR(msg)
Use NS_LOG to output a message of level LOG_ERROR.
Definition: log.h:220
void OutputStatistic(std::string key, std::string variable, const StatisticalSummary *statSum)
Generates data statistics.
std::string GetInputLabel() const
Return the input label.
int Exec(std::string exe)
Execute a sqlite3 query.
virtual long getCount() const =0
Returns the number of observations.
virtual void Output(DataCollector &dc)
Outputs information from the provided DataCollector.
a unique identifier for an interface.
Definition: type-id.h:58
MetadataList::iterator MetadataEnd()
Returns an iterator to the past-the-end of the metadata list.
TypeId SetParent(TypeId tid)
Set the parent TypeId.
Definition: type-id.cc:904