New directory structure:
[gem5.git] / src / base / stats / mysql.cc
1 /*
2 * Copyright (c) 2004-2005 The Regents of The University of Michigan
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are
7 * met: redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer;
9 * redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution;
12 * neither the name of the copyright holders nor the names of its
13 * contributors may be used to endorse or promote products derived from
14 * this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28
29 #include <cassert>
30 #include <map>
31 #include <sstream>
32 #include <string>
33 #include <vector>
34
35 #include "base/misc.hh"
36 #include "base/mysql.hh"
37 #include "base/statistics.hh"
38 #include "base/stats/flags.hh"
39 #include "base/stats/mysql.hh"
40 #include "base/stats/mysql_run.hh"
41 #include "base/stats/statdb.hh"
42 #include "base/stats/types.hh"
43 #include "base/str.hh"
44 #include "sim/host.hh"
45
46 using namespace std;
47
48 namespace Stats {
49
50 MySqlRun MySqlDB;
51
52 bool
53 MySqlConnected()
54 {
55 return MySqlDB.connected();
56 }
57
58 void
59 MySqlRun::connect(const string &host, const string &user, const string &passwd,
60 const string &db, const string &name, const string &sample,
61 const string &project)
62 {
63 if (connected())
64 panic("can only get one database connection at this time!");
65
66 mysql.connect(host, user, passwd, db);
67 if (mysql.error)
68 panic("could not connect to database server\n%s\n", mysql.error);
69
70 if (mysql.autocommit(false))
71 panic("could not set autocommit\n%s\n", mysql.error);
72
73 remove(name);
74 //cleanup();
75 setup(name, sample, user, project);
76 }
77
78 void
79 MySqlRun::setup(const string &name, const string &sample, const string &user,
80 const string &project)
81 {
82 assert(mysql.connected());
83
84 stringstream insert;
85 ccprintf(insert,
86 "INSERT INTO "
87 "runs(rn_name,rn_sample,rn_user,rn_project,rn_date,rn_expire)"
88 "values(\"%s\", \"%s\", \"%s\", \"%s\", NOW(),"
89 "DATE_ADD(CURDATE(), INTERVAL 31 DAY))",
90 name, sample, user, project);
91
92 mysql.query(insert);
93 if (mysql.error)
94 panic("could not get a run\n%s\n", mysql.error);
95
96 run_id = mysql.insert_id();
97 if (mysql.commit())
98 panic("could not commit transaction\n%s\n", mysql.error);
99 }
100
101 void
102 MySqlRun::remove(const string &name)
103 {
104 assert(mysql.connected());
105 stringstream sql;
106 ccprintf(sql, "DELETE FROM runs WHERE rn_name=\"%s\"", name);
107 mysql.query(sql);
108 if (mysql.error)
109 panic("could not delete run\n%s\n", mysql.error);
110 if (mysql.commit())
111 panic("could not commit transaction\n%s\n", mysql.error);
112 }
113
114 void
115 MySqlRun::cleanup()
116 {
117 assert(mysql.connected());
118
119 mysql.query("DELETE data "
120 "FROM data "
121 "LEFT JOIN runs ON dt_run=rn_id "
122 "WHERE rn_id IS NULL");
123
124 if (mysql.commit())
125 panic("could not commit transaction\n%s\n", mysql.error);
126
127 mysql.query("DELETE formula_ref "
128 "FROM formula_ref "
129 "LEFT JOIN runs ON fr_run=rn_id "
130 "WHERE rn_id IS NULL");
131
132 if (mysql.commit())
133 panic("could not commit transaction\n%s\n", mysql.error);
134
135 mysql.query("DELETE formulas "
136 "FROM formulas "
137 "LEFT JOIN formula_ref ON fm_stat=fr_stat "
138 "WHERE fr_stat IS NULL");
139
140 if (mysql.commit())
141 panic("could not commit transaction\n%s\n", mysql.error);
142
143 mysql.query("DELETE stats "
144 "FROM stats "
145 "LEFT JOIN data ON st_id=dt_stat "
146 "WHERE dt_stat IS NULL");
147
148 if (mysql.commit())
149 panic("could not commit transaction\n%s\n", mysql.error);
150
151 mysql.query("DELETE subdata "
152 "FROM subdata "
153 "LEFT JOIN data ON sd_stat=dt_stat "
154 "WHERE dt_stat IS NULL");
155
156 if (mysql.commit())
157 panic("could not commit transaction\n%s\n", mysql.error);
158
159 mysql.query("DELETE bins "
160 "FROM bins "
161 "LEFT JOIN data ON bn_id=dt_bin "
162 "WHERE dt_bin IS NULL");
163
164 if (mysql.commit())
165 panic("could not commit transaction\n%s\n", mysql.error);
166
167 mysql.query("DELETE events"
168 "FROM events"
169 "LEFT JOIN runs ON ev_run=rn_id"
170 "WHERE rn_id IS NULL");
171
172 if (mysql.commit())
173 panic("could not commit transaction\n%s\n", mysql.error);
174
175 mysql.query("DELETE event_names"
176 "FROM event_names"
177 "LEFT JOIN events ON en_id=ev_event"
178 "WHERE ev_event IS NULL");
179
180 if (mysql.commit())
181 panic("could not commit transaction\n%s\n", mysql.error);
182 }
183
184 void
185 SetupStat::init()
186 {
187 name = "";
188 descr = "";
189 type = "";
190 print = false;
191 prereq = 0;
192 prec = -1;
193 nozero = false;
194 nonan = false;
195 total = false;
196 pdf = false;
197 cdf = false;
198 min = 0;
199 max = 0;
200 bktsize = 0;
201 size = 0;
202 }
203
204 unsigned
205 SetupStat::setup()
206 {
207 MySQL::Connection &mysql = MySqlDB.conn();
208
209 stringstream insert;
210 ccprintf(insert,
211 "INSERT INTO "
212 "stats(st_name, st_descr, st_type, st_print, st_prereq, "
213 "st_prec, st_nozero, st_nonan, st_total, st_pdf, st_cdf, "
214 "st_min, st_max, st_bktsize, st_size)"
215 "values(\"%s\",\"%s\",\"%s\","
216 " %d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d)",
217 name, descr, type, print, prereq, (int)prec, nozero, nonan,
218 total, pdf, cdf,
219 min, max, bktsize, size);
220
221 mysql.query(insert);
222 if (!mysql.error) {
223 int id = mysql.insert_id();
224 if (mysql.commit())
225 panic("could not commit transaction\n%s\n", mysql.error);
226 return id;
227 }
228
229 stringstream select;
230 ccprintf(select, "SELECT * FROM stats WHERE st_name=\"%s\"", name);
231
232 mysql.query(select);
233 MySQL::Result result = mysql.store_result();
234 if (!result)
235 panic("could not find stat\n%s\n", mysql.error);
236
237 assert(result.num_fields() == 16);
238 MySQL::Row row = result.fetch_row();
239 if (!row)
240 panic("could not get stat row\n%s\n", mysql.error);
241
242 bool tb;
243 int8_t ti8;
244 uint16_t tu16;
245 int64_t ti64;
246 uint64_t tu64;
247
248 if (name != (char *)row[1])
249 panic("failed stat check on %s:name. %s != %s\n",
250 name, name, row[1]);
251
252 if (descr != (char *)row[2])
253 panic("failed stat check on %s:descr. %s != %s\n",
254 name, descr, row[2]);
255
256 if (type != (char *)row[3])
257 panic("failed stat check on %s:type. %s != %s\n",
258 name, type, row[3]);
259
260 if (!to_number(row[4], tb) || print != tb)
261 panic("failed stat check on %s:print. %d != %d\n",
262 name, print, tb);
263
264 if (!to_number(row[6], ti8) || prec != ti8)
265 panic("failed stat check on %s:prec. %d != %d\n",
266 name, prec, ti8);
267
268 if (!to_number(row[7], tb) || nozero != tb)
269 panic("failed stat check on %s:nozero. %d != %d\n",
270 name, nozero, tb);
271
272 if (!to_number(row[8], tb) || nonan != tb)
273 panic("failed stat check on %s:nonan. %d != %d\n",
274 name, nonan, tb);
275
276 if (!to_number(row[9], tb) || total != tb)
277 panic("failed stat check on %s:total. %d != %d\n",
278 name, total, tb);
279
280 if (!to_number(row[10], tb) || pdf != tb)
281 panic("failed stat check on %s:pdf. %d != %d\n",
282 name, pdf, tb);
283
284 if (!to_number(row[11], tb) || cdf != tb)
285 panic("failed stat check on %s:cdf. %d != %d\n",
286 name, cdf, tb);
287
288 if (!to_number(row[12], ti64) || min != ti64)
289 panic("failed stat check on %s:min. %d != %d\n",
290 name, min, ti64);
291
292 if (!to_number(row[13], ti64) || max != ti64)
293 panic("failed stat check on %s:max. %d != %d\n",
294 name, max, ti64);
295
296 if (!to_number(row[14], tu64) || bktsize != tu64)
297 panic("failed stat check on %s:bktsize. %d != %d\n",
298 name, bktsize, tu64);
299
300 if (!to_number(row[15], tu16) || size != tu16)
301 panic("failed stat check on %s:size. %d != %d\n",
302 name, size, tu16);
303
304 to_number(row[5], prereq);
305 uint16_t statid;
306 to_number(row[0], statid);
307 return statid;
308 }
309
310 unsigned
311 SetupBin(const string &bin)
312 {
313 static map<string, int> binmap;
314
315 using namespace MySQL;
316 map<string,int>::const_iterator i = binmap.find(bin);
317 if (i != binmap.end())
318 return (*i).second;
319
320 Connection &mysql = MySqlDB.conn();
321 assert(mysql.connected());
322
323 uint16_t bin_id;
324
325 stringstream select;
326 stringstream insert;
327 ccprintf(select, "SELECT bn_id FROM bins WHERE bn_name=\"%s\"", bin);
328
329 mysql.query(select);
330 MySQL::Result result = mysql.store_result();
331 if (result) {
332 assert(result.num_fields() == 1);
333 MySQL::Row row = result.fetch_row();
334 if (row) {
335 to_number(row[0], bin_id);
336 goto exit;
337 }
338 }
339
340 ccprintf(insert, "INSERT INTO bins(bn_name) values(\"%s\")", bin);
341
342 mysql.query(insert);
343 if (mysql.error)
344 panic("could not get a bin\n%s\n", mysql.error);
345
346 bin_id = mysql.insert_id();
347 if (mysql.commit())
348 panic("could not commit transaction\n%s\n", mysql.error);
349
350 binmap.insert(make_pair(bin, bin_id));
351
352 exit:
353 return bin_id;
354 }
355
356 InsertData::InsertData()
357 {
358 query = new char[maxsize + 1];
359 size = 0;
360 flush();
361 }
362
363 InsertData::~InsertData()
364 {
365 delete [] query;
366 }
367
368 void
369 InsertData::flush()
370 {
371 if (size) {
372 MySQL::Connection &mysql = MySqlDB.conn();
373 assert(mysql.connected());
374 mysql.query(query);
375 if (mysql.error)
376 panic("could not insert data\n%s\n", mysql.error);
377 if (mysql.commit())
378 panic("could not commit transaction\n%s\n", mysql.error);
379 }
380
381 query[0] = '\0';
382 size = 0;
383 first = true;
384 strcpy(query, "INSERT INTO "
385 "data(dt_stat,dt_x,dt_y,dt_run,dt_tick,dt_bin,dt_data) "
386 "values");
387 size = strlen(query);
388 }
389
390 void
391 InsertData::insert()
392 {
393 if (size + 1024 > maxsize)
394 flush();
395
396 if (!first) {
397 query[size++] = ',';
398 query[size] = '\0';
399 }
400
401 first = false;
402
403 size += sprintf(query + size, "(%u,%d,%d,%u,%llu,%u,\"%f\")",
404 stat, x, y, MySqlDB.run(), (unsigned long long)tick,
405 bin, data);
406 }
407
408 struct InsertSubData
409 {
410 uint16_t stat;
411 int16_t x;
412 int16_t y;
413 string name;
414 string descr;
415
416 void setup();
417 };
418
419 void
420 InsertSubData::setup()
421 {
422 MySQL::Connection &mysql = MySqlDB.conn();
423 assert(mysql.connected());
424 stringstream insert;
425 ccprintf(insert,
426 "INSERT INTO subdata(sd_stat,sd_x,sd_y,sd_name,sd_descr) "
427 "values(%d,%d,%d,\"%s\",\"%s\")",
428 stat, x, y, name, descr);
429
430 mysql.query(insert);
431 // if (mysql.error)
432 // panic("could not insert subdata\n%s\n", mysql.error);
433
434 if (mysql.commit())
435 panic("could not commit transaction\n%s\n", mysql.error);
436 }
437
438 void
439 InsertFormula(uint16_t stat, const string &formula)
440 {
441 MySQL::Connection &mysql = MySqlDB.conn();
442 assert(mysql.connected());
443 stringstream insert_formula;
444 ccprintf(insert_formula,
445 "INSERT INTO formulas(fm_stat,fm_formula) values(%d, \"%s\")",
446 stat, formula);
447
448 mysql.query(insert_formula);
449 // if (mysql.error)
450 // panic("could not insert formula\n%s\n", mysql.error);
451
452 stringstream insert_ref;
453 ccprintf(insert_ref,
454 "INSERT INTO formula_ref(fr_stat,fr_run) values(%d, %d)",
455 stat, MySqlDB.run());
456
457 mysql.query(insert_ref);
458 // if (mysql.error)
459 // panic("could not insert formula reference\n%s\n", mysql.error);
460
461 if (mysql.commit())
462 panic("could not commit transaction\n%s\n", mysql.error);
463 }
464
465 void
466 UpdatePrereq(uint16_t stat, uint16_t prereq)
467 {
468 MySQL::Connection &mysql = MySqlDB.conn();
469 assert(mysql.connected());
470 stringstream update;
471 ccprintf(update, "UPDATE stats SET st_prereq=%d WHERE st_id=%d",
472 prereq, stat);
473 mysql.query(update);
474 if (mysql.error)
475 panic("could not update prereq\n%s\n", mysql.error);
476
477 if (mysql.commit())
478 panic("could not commit transaction\n%s\n", mysql.error);
479 }
480
481 void
482 MySql::configure()
483 {
484 /*
485 * set up all stats!
486 */
487 using namespace Database;
488
489 MySQL::Connection &mysql = MySqlDB.conn();
490
491 stat_list_t::const_iterator i, end = stats().end();
492 for (i = stats().begin(); i != end; ++i) {
493 (*i)->visit(*this);
494 }
495
496 for (i = stats().begin(); i != end; ++i) {
497 StatData *data = *i;
498 if (data->prereq) {
499 uint16_t stat_id = find(data->id);
500 uint16_t prereq_id = find(data->prereq->id);
501 assert(stat_id && prereq_id);
502
503 UpdatePrereq(stat_id, prereq_id);
504 }
505 }
506
507 if (mysql.commit())
508 panic("could not commit transaction\n%s\n", mysql.error);
509
510 configured = true;
511 }
512
513
514 bool
515 MySql::configure(const StatData &data, string type)
516 {
517 stat.init();
518 stat.name = data.name;
519 stat.descr = data.desc;
520 stat.type = type;
521 stat.print = data.flags & print;
522 stat.prec = data.precision;
523 stat.nozero = data.flags & nozero;
524 stat.nonan = data.flags & nonan;
525 stat.total = data.flags & total;
526 stat.pdf = data.flags & pdf;
527 stat.cdf = data.flags & cdf;
528
529 return stat.print;
530 }
531
532 void
533 MySql::configure(const ScalarData &data)
534 {
535 if (!configure(data, "SCALAR"))
536 return;
537
538 insert(data.id, stat.setup());
539 }
540
541 void
542 MySql::configure(const VectorData &data)
543 {
544 if (!configure(data, "VECTOR"))
545 return;
546
547 uint16_t statid = stat.setup();
548
549 if (!data.subnames.empty()) {
550 InsertSubData subdata;
551 subdata.stat = statid;
552 subdata.y = 0;
553 for (int i = 0; i < data.subnames.size(); ++i) {
554 subdata.x = i;
555 subdata.name = data.subnames[i];
556 subdata.descr = data.subdescs.empty() ? "" : data.subdescs[i];
557
558 if (!subdata.name.empty() || !subdata.descr.empty())
559 subdata.setup();
560 }
561 }
562
563 insert(data.id, statid);
564 }
565
566 void
567 MySql::configure(const DistData &data)
568 {
569 if (!configure(data, "DIST"))
570 return;
571
572 if (!data.data.fancy) {
573 stat.size = data.data.size;
574 stat.min = data.data.min;
575 stat.max = data.data.max;
576 stat.bktsize = data.data.bucket_size;
577 }
578 insert(data.id, stat.setup());
579 }
580
581 void
582 MySql::configure(const VectorDistData &data)
583 {
584 if (!configure(data, "VECTORDIST"))
585 return;
586
587 if (!data.data[0].fancy) {
588 stat.size = data.data[0].size;
589 stat.min = data.data[0].min;
590 stat.max = data.data[0].max;
591 stat.bktsize = data.data[0].bucket_size;
592 }
593
594 uint16_t statid = stat.setup();
595
596 if (!data.subnames.empty()) {
597 InsertSubData subdata;
598 subdata.stat = statid;
599 subdata.y = 0;
600 for (int i = 0; i < data.subnames.size(); ++i) {
601 subdata.x = i;
602 subdata.name = data.subnames[i];
603 subdata.descr = data.subdescs.empty() ? "" : data.subdescs[i];
604 if (!subdata.name.empty() || !subdata.descr.empty())
605 subdata.setup();
606 }
607 }
608
609 insert(data.id, statid);
610 }
611
612 void
613 MySql::configure(const Vector2dData &data)
614 {
615 if (!configure(data, "VECTOR2D"))
616 return;
617
618 uint16_t statid = stat.setup();
619
620 if (!data.subnames.empty()) {
621 InsertSubData subdata;
622 subdata.stat = statid;
623 subdata.y = -1;
624 for (int i = 0; i < data.subnames.size(); ++i) {
625 subdata.x = i;
626 subdata.name = data.subnames[i];
627 subdata.descr = data.subdescs.empty() ? "" : data.subdescs[i];
628 if (!subdata.name.empty() || !subdata.descr.empty())
629 subdata.setup();
630 }
631 }
632
633 if (!data.y_subnames.empty()) {
634 InsertSubData subdata;
635 subdata.stat = statid;
636 subdata.x = -1;
637 subdata.descr = "";
638 for (int i = 0; i < data.y_subnames.size(); ++i) {
639 subdata.y = i;
640 subdata.name = data.y_subnames[i];
641 if (!subdata.name.empty())
642 subdata.setup();
643 }
644 }
645
646 insert(data.id, statid);
647 }
648
649 void
650 MySql::configure(const FormulaData &data)
651 {
652 configure(data, "FORMULA");
653 insert(data.id, stat.setup());
654 InsertFormula(find(data.id), data.str());
655 }
656
657 void
658 MySql::output(MainBin *bin)
659 {
660 MySQL::Connection &mysql = MySqlDB.conn();
661
662 if (bin) {
663 bin->activate();
664 newdata.bin = SetupBin(bin->name());
665 } else {
666 newdata.bin = 0;
667 }
668
669 Database::stat_list_t::const_iterator i, end = Database::stats().end();
670 for (i = Database::stats().begin(); i != end; ++i) {
671 StatData *stat = *i;
672 if (bin && stat->binned() || !bin && !stat->binned()) {
673 stat->visit(*this);
674 if (mysql.commit())
675 panic("could not commit transaction\n%s\n", mysql.error);
676 }
677 }
678 }
679
680 bool
681 MySql::valid() const
682 {
683 return MySqlDB.connected();
684 }
685
686 void
687 MySql::output()
688 {
689 using namespace Database;
690 assert(valid());
691
692 if (!configured)
693 configure();
694
695 // store sample #
696 newdata.tick = curTick;
697
698 output(NULL);
699 if (!bins().empty()) {
700 bin_list_t::iterator i, end = bins().end();
701 for (i = bins().begin(); i != end; ++i)
702 output(*i);
703 }
704
705 newdata.flush();
706 }
707
708 void
709 MySql::output(const ScalarData &data)
710 {
711 if (!(data.flags & print))
712 return;
713
714 newdata.stat = find(data.id);
715 newdata.x = 0;
716 newdata.y = 0;
717 newdata.data = data.value();
718
719 newdata.insert();
720 }
721
722 void
723 MySql::output(const VectorData &data)
724 {
725 if (!(data.flags & print))
726 return;
727
728 newdata.stat = find(data.id);
729 newdata.y = 0;
730
731 const VCounter &cvec = data.value();
732 int size = data.size();
733 for (int x = 0; x < size; x++) {
734 newdata.x = x;
735 newdata.data = cvec[x];
736 newdata.insert();
737 }
738 }
739
740 void
741 MySql::output(const DistDataData &data)
742 {
743 const int db_sum = -1;
744 const int db_squares = -2;
745 const int db_samples = -3;
746 const int db_min_val = -4;
747 const int db_max_val = -5;
748 const int db_underflow = -6;
749 const int db_overflow = -7;
750
751 newdata.x = db_sum;
752 newdata.data = data.sum;
753 newdata.insert();
754
755 newdata.x = db_squares;
756 newdata.data = data.squares;
757 newdata.insert();
758
759 newdata.x = db_samples;
760 newdata.data = data.samples;
761 newdata.insert();
762
763 if (data.samples && !data.fancy) {
764 newdata.x = db_min_val;
765 newdata.data = data.min_val;
766 newdata.insert();
767
768 newdata.x = db_max_val;
769 newdata.data = data.max_val;
770 newdata.insert();
771
772 newdata.x = db_underflow;
773 newdata.data = data.underflow;
774 newdata.insert();
775
776 newdata.x = db_overflow;
777 newdata.data = data.overflow;
778 newdata.insert();
779
780 int size = data.cvec.size();
781 for (int x = 0; x < size; x++) {
782 newdata.x = x;
783 newdata.data = data.cvec[x];
784 newdata.insert();
785 }
786 }
787 }
788
789
790 void
791 MySql::output(const DistData &data)
792 {
793 if (!(data.flags & print))
794 return;
795
796 newdata.stat = find(data.id);
797 newdata.y = 0;
798 output(data.data);
799 }
800
801 void
802 MySql::output(const VectorDistData &data)
803 {
804 if (!(data.flags & print))
805 return;
806
807 newdata.stat = find(data.id);
808
809 int size = data.data.size();
810 for (int y = 0; y < size; ++y) {
811 newdata.y = y;
812 output(data.data[y]);
813 }
814 }
815
816 void
817 MySql::output(const Vector2dData &data)
818 {
819 if (!(data.flags & print))
820 return;
821
822 newdata.stat = find(data.id);
823
824 int index = 0;
825 for (int x = 0; x < data.x; x++) {
826 newdata.x = x;
827 for (int y = 0; y < data.y; y++) {
828 newdata.y = y;
829 newdata.data = data.cvec[index++];
830 newdata.insert();
831 }
832 }
833 }
834
835 void
836 MySql::output(const FormulaData &data)
837 {
838 }
839
840 /*
841 * Implement the visitor
842 */
843 void
844 MySql::visit(const ScalarData &data)
845 {
846 if (!configured)
847 configure(data);
848 else
849 output(data);
850 }
851
852 void
853 MySql::visit(const VectorData &data)
854 {
855 if (!configured)
856 configure(data);
857 else
858 output(data);
859 }
860
861 void
862 MySql::visit(const DistData &data)
863 {
864 return;
865 if (!configured)
866 configure(data);
867 else
868 output(data);
869 }
870
871 void
872 MySql::visit(const VectorDistData &data)
873 {
874 return;
875 if (!configured)
876 configure(data);
877 else
878 output(data);
879 }
880
881 void
882 MySql::visit(const Vector2dData &data)
883 {
884 return;
885 if (!configured)
886 configure(data);
887 else
888 output(data);
889 }
890
891 void
892 MySql::visit(const FormulaData &data)
893 {
894 if (!configured)
895 configure(data);
896 else
897 output(data);
898 }
899
900 /* namespace Stats */ }