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