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