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