Annotation of embedaddon/bmon/src/out_db.c, revision 1.1
1.1 ! misho 1: /*
! 2: * out_db.c Database Output
! 3: *
! 4: * Copyright (c) 2001-2005 Thomas Graf <tgraf@suug.ch>
! 5: *
! 6: * Permission is hereby granted, free of charge, to any person obtaining a
! 7: * copy of this software and associated documentation files (the "Software"),
! 8: * to deal in the Software without restriction, including without limitation
! 9: * the rights to use, copy, modify, merge, publish, distribute, sublicense,
! 10: * and/or sell copies of the Software, and to permit persons to whom the
! 11: * Software is furnished to do so, subject to the following conditions:
! 12: *
! 13: * The above copyright notice and this permission notice shall be included
! 14: * in all copies or substantial portions of the Software.
! 15: *
! 16: * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
! 17: * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
! 18: * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
! 19: * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
! 20: * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
! 21: * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
! 22: * DEALINGS IN THE SOFTWARE.
! 23: */
! 24:
! 25: /*
! 26: * NOTE
! 27: *
! 28: * This whole code is a realy mess and written in a hurry, most interactions
! 29: * should be cached to save traffic. It really is meant as experimental
! 30: * features.
! 31: */
! 32:
! 33: #include <bmon/bmon.h>
! 34: #include <bmon/node.h>
! 35: #include <bmon/output.h>
! 36: #include <bmon/graph.h>
! 37: #include <bmon/input.h>
! 38: #include <bmon/utils.h>
! 39:
! 40: #include <dbi/dbi.h>
! 41:
! 42: static char *c_driverdir = NULL;
! 43: static char *c_driver = "mysql";
! 44: static char *c_host = "localhost";
! 45: static char *c_username = "bmon";
! 46: static char *c_dbname = "bmon";
! 47: static char *c_mask = "mhd";
! 48: static char *c_password;
! 49: static int c_interval = 3;
! 50:
! 51: static int do_read;
! 52: static int do_sec;
! 53: static int do_min;
! 54: static int do_hour;
! 55: static int do_day;
! 56:
! 57: static dbi_conn db_conn;
! 58:
! 59: static int create_tables(void)
! 60: {
! 61: dbi_result r;
! 62:
! 63: r = dbi_conn_query(db_conn,
! 64: "CREATE TABLE IF NOT EXISTS nodes (" \
! 65: " id INT UNSIGNED NOT NULL AUTO_INCREMENT UNIQUE," \
! 66: " name TEXT NOT NULL," \
! 67: " source TEXT," \
! 68: " PRIMARY KEY (id)" \
! 69: ")");
! 70:
! 71: if (!r)
! 72: return 0;
! 73: else
! 74: dbi_result_free(r);
! 75:
! 76: r = dbi_conn_query(db_conn,
! 77: "CREATE TABLE IF NOT EXISTS items (" \
! 78: " id INT UNSIGNED NOT NULL AUTO_INCREMENT UNIQUE," \
! 79: " name TEXT NOT NULL," \
! 80: " description TEXT," \
! 81: " node INT UNSIGNED NOT NULL," \
! 82: " handle INT UNSIGNED," \
! 83: " parent INT UNSIGNED," \
! 84: " indent INT UNSIGNED," \
! 85: " rx_usage SMALLINT NOT NULL," \
! 86: " tx_usage SMALLINT NOT NULL," \
! 87: " PRIMARY KEY (id)," \
! 88: " FOREIGN KEY (node) REFERENCES nodes(id)," \
! 89: " FOREIGN KEY (parent) REFERENCES items(id)" \
! 90: ")");
! 91:
! 92: if (!r)
! 93: return 0;
! 94: else
! 95: dbi_result_free(r);
! 96:
! 97: r = dbi_conn_query(db_conn,
! 98: "CREATE TABLE IF NOT EXISTS attrs (" \
! 99: " id INT UNSIGNED NOT NULL AUTO_INCREMENT UNIQUE," \
! 100: " name CHAR(15) NOT NULL," \
! 101: " item INT UNSIGNED NOT NULL," \
! 102: " rx_rate INT UNSIGNED," \
! 103: " tx_rate INT UNSIGNED," \
! 104: " rx_counter BIGINT UNSIGNED NOT NULL," \
! 105: " tx_counter BIGINT UNSIGNED NOT NULL," \
! 106: " PRIMARY KEY (id)," \
! 107: " FOREIGN KEY (item) REFERENCES items(id)" \
! 108: ")");
! 109:
! 110: if (!r)
! 111: return 0;
! 112: else
! 113: dbi_result_free(r);
! 114:
! 115: r = dbi_conn_query(db_conn,
! 116: "CREATE TABLE IF NOT EXISTS attr_desc (" \
! 117: " id CHAR(15) NOT NULL UNIQUE," \
! 118: " is_num SMALLINT UNSIGNED NOT NULL," \
! 119: " txt TEXT NOT NULL," \
! 120: " PRIMARY KEY(id)" \
! 121: ")");
! 122:
! 123: if (!r)
! 124: return 0;
! 125: else
! 126: dbi_result_free(r);
! 127:
! 128: r = dbi_conn_query(db_conn,
! 129: "CREATE TABLE IF NOT EXISTS hist_r (" \
! 130: " attr INT UNSIGNED NOT NULL," \
! 131: " ts INT UNSIGNED NOT NULL," \
! 132: " offset INT UNSIGNED NOT NULL," \
! 133: " rx_rate INT UNSIGNED NOT NULL," \
! 134: " tx_rate INT UNSIGNED NOT NULL," \
! 135: " PRIMARY KEY (attr, ts, offset)," \
! 136: " FOREIGN KEY (attr) REFERENCES attrs(id)" \
! 137: ")");
! 138:
! 139: if (!r)
! 140: return 0;
! 141: else
! 142: dbi_result_free(r);
! 143:
! 144: r = dbi_conn_query(db_conn,
! 145: "CREATE TABLE IF NOT EXISTS hist_s (" \
! 146: " attr INT UNSIGNED NOT NULL," \
! 147: " ts INT UNSIGNED NOT NULL," \
! 148: " offset INT UNSIGNED NOT NULL," \
! 149: " rx_rate INT UNSIGNED NOT NULL," \
! 150: " tx_rate INT UNSIGNED NOT NULL," \
! 151: " PRIMARY KEY (attr, ts, offset)," \
! 152: " FOREIGN KEY (attr) REFERENCES attrs(id)" \
! 153: ")");
! 154:
! 155: if (!r)
! 156: return 0;
! 157: else
! 158: dbi_result_free(r);
! 159:
! 160: r = dbi_conn_query(db_conn,
! 161: "CREATE TABLE IF NOT EXISTS hist_m (" \
! 162: " attr INT UNSIGNED NOT NULL," \
! 163: " ts INT UNSIGNED NOT NULL," \
! 164: " offset INT UNSIGNED NOT NULL," \
! 165: " rx_rate INT UNSIGNED NOT NULL," \
! 166: " tx_rate INT UNSIGNED NOT NULL," \
! 167: " PRIMARY KEY (attr, ts, offset)," \
! 168: " FOREIGN KEY (attr) REFERENCES attrs(id)" \
! 169: ")");
! 170:
! 171: if (!r)
! 172: return 0;
! 173: else
! 174: dbi_result_free(r);
! 175:
! 176: r = dbi_conn_query(db_conn,
! 177: "CREATE TABLE IF NOT EXISTS hist_h (" \
! 178: " attr INT UNSIGNED NOT NULL," \
! 179: " ts INT UNSIGNED NOT NULL," \
! 180: " offset INT UNSIGNED NOT NULL," \
! 181: " rx_rate INT UNSIGNED NOT NULL," \
! 182: " tx_rate INT UNSIGNED NOT NULL," \
! 183: " PRIMARY KEY (attr, ts, offset)," \
! 184: " FOREIGN KEY (attr) REFERENCES attrs(id)" \
! 185: ")");
! 186:
! 187: if (!r)
! 188: return 0;
! 189: else
! 190: dbi_result_free(r);
! 191:
! 192: r = dbi_conn_query(db_conn,
! 193: "CREATE TABLE IF NOT EXISTS hist_d (" \
! 194: " attr INT UNSIGNED NOT NULL," \
! 195: " ts INT UNSIGNED NOT NULL," \
! 196: " offset INT UNSIGNED NOT NULL," \
! 197: " rx_rate INT UNSIGNED NOT NULL," \
! 198: " tx_rate INT UNSIGNED NOT NULL," \
! 199: " PRIMARY KEY (attr, ts, offset)," \
! 200: " FOREIGN KEY (attr) REFERENCES attrs(id)" \
! 201: ")");
! 202:
! 203: if (!r)
! 204: return 0;
! 205: else
! 206: dbi_result_free(r);
! 207:
! 208: return 1;
! 209: }
! 210:
! 211: static int insert_attr_desc(struct attr_type *a, void *arg)
! 212: {
! 213: dbi_result r = dbi_conn_queryf(db_conn,
! 214: "SELECT id FROM attr_desc WHERE id = '%s'", a->name);
! 215:
! 216: if (!r)
! 217: return -1;
! 218:
! 219: if (dbi_result_first_row(r) == 1) {
! 220: dbi_result_free(r);
! 221: return 0;
! 222: }
! 223:
! 224: dbi_result_free(r);
! 225:
! 226: r = dbi_conn_queryf(db_conn,
! 227: "INSERT INTO attr_desc (id, is_num, txt) VALUES " \
! 228: "('%s', %d, '%s')", a->name, a->unit == U_NUMBER,
! 229: a->desc);
! 230:
! 231: if (!r)
! 232: return -1;
! 233:
! 234: dbi_result_free(r);
! 235: return 0;
! 236: }
! 237:
! 238: static int insert_attr_descs(void)
! 239: {
! 240: return !foreach_attr_type(&insert_attr_desc, NULL);
! 241: }
! 242:
! 243: static void add_history(const char *table, int attr_id, timestamp_t *ts,
! 244: rate_cnt_t rx, rate_cnt_t tx)
! 245: {
! 246: dbi_result r = dbi_conn_queryf(db_conn,
! 247: "INSERT INTO %s (attr, ts, offset, rx_rate, tx_rate) " \
! 248: "values (%d, %u, %u, %u, %u)",
! 249: table, attr_id, (unsigned int) ts->tv_sec,
! 250: (unsigned int) ts->tv_usec, rx, tx);
! 251:
! 252: if (r)
! 253: dbi_result_free(r);
! 254: }
! 255:
! 256:
! 257: static inline int attr_exists(const char *name, int item_id)
! 258: {
! 259: int ret = -1;
! 260:
! 261: dbi_result r = dbi_conn_queryf(db_conn,
! 262: "SELECT id FROM attrs WHERE name = '%s' AND " \
! 263: "item = %d", name, item_id);
! 264:
! 265: if (r) {
! 266: if (dbi_result_first_row(r) == 1)
! 267: ret = (int) dbi_result_get_long(r, "id");
! 268: dbi_result_free(r);
! 269: }
! 270:
! 271: return ret;
! 272: }
! 273:
! 274: static inline int insert_attr(stat_attr_t *a, int item_id)
! 275: {
! 276: dbi_result r;
! 277:
! 278: r = dbi_conn_queryf(db_conn,
! 279: "INSERT INTO attrs (name, item, rx_rate, tx_rate, " \
! 280: "rx_counter, tx_counter) VALUES ('%s', %d, %d, %d, " \
! 281: "%lld, %lld)", type2name(a->a_type), item_id,
! 282: attr_get_rx_rate(a), attr_get_tx_rate(a),
! 283: attr_get_rx(a), attr_get_tx(a));
! 284:
! 285: if (!r)
! 286: return -1;
! 287:
! 288: dbi_result_free(r);
! 289: return attr_exists(type2name(a->a_type), item_id);
! 290:
! 291: }
! 292:
! 293: static inline int up_attr(stat_attr_t *a, int attr_id)
! 294: {
! 295: dbi_result r;
! 296:
! 297: r = dbi_conn_queryf(db_conn,
! 298: "UPDATE attrs SET rx_rate = %d, tx_rate = %d, " \
! 299: "rx_counter = %lld, tx_counter = %lld WHERE id = %d",
! 300: attr_get_rx_rate(a), attr_get_tx_rate(a),
! 301: attr_get_rx(a), attr_get_tx(a), attr_id);
! 302:
! 303: if (!r)
! 304: return -1;
! 305:
! 306: dbi_result_free(r);
! 307:
! 308: return 0;
! 309: }
! 310:
! 311: static inline int item_exists(item_t *it, node_t *node, int node_id)
! 312: {
! 313: int ret = -1;
! 314: dbi_result r;
! 315:
! 316: if (it->i_flags & ITEM_FLAG_IS_CHILD) {
! 317: int parent;
! 318: item_t *p = get_item(node, it->i_parent);
! 319: if (!p)
! 320: goto no_parent;
! 321:
! 322: parent = item_exists(p, node, node_id);
! 323: if (parent < 0)
! 324: goto no_parent;
! 325:
! 326: r = dbi_conn_queryf(db_conn,
! 327: "SELECT id FROM items WHERE node = %d AND " \
! 328: "name = '%s' AND handle = %d AND parent = %d",
! 329: node_id, it->i_name, it->i_handle, parent);
! 330: goto skip;
! 331: }
! 332:
! 333: no_parent:
! 334: r = dbi_conn_queryf(db_conn,
! 335: "SELECT id FROM items WHERE node = %d AND " \
! 336: "name = '%s' AND handle = %d", node_id, it->i_name, it->i_handle);
! 337:
! 338: skip:
! 339: if (r) {
! 340: if (dbi_result_first_row(r) == 1)
! 341: ret = (int) dbi_result_get_long(r, "id");
! 342: dbi_result_free(r);
! 343: }
! 344:
! 345: return ret;
! 346: }
! 347:
! 348: static inline int insert_item(item_t *it, node_t *node, int node_id)
! 349: {
! 350: dbi_result r;
! 351:
! 352: if (it->i_flags & ITEM_FLAG_IS_CHILD) {
! 353: int parent;
! 354: item_t *p = get_item(node, it->i_parent);
! 355: if (!p)
! 356: goto no_parent;
! 357:
! 358: parent = item_exists(p, node, node_id);
! 359: if (parent < 0)
! 360: goto no_parent;
! 361:
! 362: r = dbi_conn_queryf(db_conn,
! 363: "INSERT INTO items (name, node, handle, parent, " \
! 364: "indent, description) VALUES ('%s', %d, %d, %d, " \
! 365: "%d, %s%s%s)",
! 366: it->i_name, node_id, it->i_handle,
! 367: parent, it->i_level,
! 368: it->i_desc ? "'" : "",
! 369: it->i_desc ? it->i_desc : "NULL",
! 370: it->i_desc ? "'" : "");
! 371: goto skip;
! 372: }
! 373:
! 374: no_parent:
! 375: r = dbi_conn_queryf(db_conn,
! 376: "INSERT INTO items (name, node, handle) VALUES " \
! 377: "('%s', %d, %d)", it->i_name, node_id, it->i_handle);
! 378:
! 379: skip:
! 380: if (!r)
! 381: return -1;
! 382:
! 383: dbi_result_free(r);
! 384: return item_exists(it, node, node_id);
! 385: }
! 386:
! 387: static inline int up_item(item_t *it, int item_id)
! 388: {
! 389: dbi_result r;
! 390:
! 391: r = dbi_conn_queryf(db_conn,
! 392: "UPDATE attrs SET rx_usage = %d, tx_usage = %d " \
! 393: "WHERE id = %d",
! 394: it->i_rx_usage, it->i_tx_usage, item_id);
! 395:
! 396: if (!r)
! 397: return -1;
! 398:
! 399: dbi_result_free(r);
! 400:
! 401: return 0;
! 402: }
! 403:
! 404: static inline int node_exists(const char *name)
! 405: {
! 406: int ret = -1;
! 407: dbi_result r = dbi_conn_queryf(db_conn,
! 408: "SELECT id FROM nodes WHERE name = '%s'", name);
! 409:
! 410: if (r) {
! 411: if (dbi_result_first_row(r) == 1)
! 412: ret = (int) dbi_result_get_long(r, "id");
! 413: dbi_result_free(r);
! 414: }
! 415:
! 416: return ret;
! 417: }
! 418:
! 419: static inline int insert_node(const char *name, const char *source)
! 420: {
! 421: dbi_result r;
! 422:
! 423: if (source)
! 424: r = dbi_conn_queryf(db_conn,
! 425: "INSERT INTO nodes (name, source) VALUES ('%s', '%s')",
! 426: name, source);
! 427: else
! 428: r = dbi_conn_queryf(db_conn,
! 429: "INSERT INTO nodes (name) VALUES ('%s')", name);
! 430:
! 431: if (!r)
! 432: return -1;
! 433:
! 434: dbi_result_free(r);
! 435:
! 436: return node_exists(name);
! 437:
! 438: }
! 439:
! 440: static inline int cur_hist_index(int index)
! 441: {
! 442: return index == 0 ? (HISTORY_SIZE - 1) : (index - 1);
! 443: }
! 444:
! 445: struct xdata {
! 446: int node_id;
! 447: node_t *node;
! 448: };
! 449:
! 450: static void write_per_attr(stat_attr_t *a, void *arg)
! 451: {
! 452: int attr_id;
! 453: int item_id = (int) arg;
! 454:
! 455: attr_id = attr_exists(type2name(a->a_type), item_id);
! 456: if (attr_id < 0) {
! 457: attr_id = insert_attr(a, item_id);
! 458: if (attr_id < 0)
! 459: return;
! 460: } else
! 461: up_attr(a, attr_id);
! 462:
! 463: if (a->a_flags & ATTR_FLAG_HISTORY) {
! 464: history_t *h = &((stat_attr_hist_t *) a)->a_hist;
! 465:
! 466: if (do_read && get_read_interval() != 1.0f) {
! 467: int idx = cur_hist_index(h->h_read.he_index);
! 468: add_history("hist_r", attr_id,
! 469: &h->h_read.he_last_update,
! 470: h->h_read.he_rx.hd_data[idx],
! 471: h->h_read.he_tx.hd_data[idx]);
! 472: }
! 473:
! 474: if (do_sec && diff_now(&h->h_sec.he_last_update) < 0.5f) {
! 475: int idx = cur_hist_index(h->h_sec.he_index);
! 476: add_history("hist_s", attr_id,
! 477: &h->h_sec.he_last_update,
! 478: h->h_sec.he_rx.hd_data[idx],
! 479: h->h_sec.he_tx.hd_data[idx]);
! 480: }
! 481:
! 482: if (do_min && diff_now(&h->h_min.he_last_update) < 30.0f) {
! 483: int idx = cur_hist_index(h->h_min.he_index);
! 484: add_history("hist_m", attr_id,
! 485: &h->h_min.he_last_update,
! 486: h->h_min.he_rx.hd_data[idx],
! 487: h->h_min.he_tx.hd_data[idx]);
! 488: }
! 489:
! 490: if (do_hour && diff_now(&h->h_hour.he_last_update) < 1800.0f) {
! 491: int idx = cur_hist_index(h->h_hour.he_index);
! 492: add_history("hist_h", attr_id,
! 493: &h->h_hour.he_last_update,
! 494: h->h_hour.he_rx.hd_data[idx],
! 495: h->h_hour.he_tx.hd_data[idx]);
! 496: }
! 497:
! 498: if (do_day && diff_now(&h->h_day.he_last_update) < 43200.0f) {
! 499: int idx = cur_hist_index(h->h_day.he_index);
! 500: add_history("hist_d", attr_id,
! 501: &h->h_day.he_last_update,
! 502: h->h_day.he_rx.hd_data[idx],
! 503: h->h_day.he_tx.hd_data[idx]);
! 504: }
! 505: }
! 506: }
! 507:
! 508: static void write_per_item(item_t *item, void *arg)
! 509: {
! 510: int item_id;
! 511: struct xdata *x = (struct xdata *) arg;
! 512:
! 513: item_id = item_exists(item, x->node, x->node_id);
! 514: if (item_id < 0)
! 515: item_id = insert_item(item, x->node, x->node_id);
! 516:
! 517: if (item_id < 0)
! 518: return;
! 519:
! 520: up_item(item, item_id);
! 521:
! 522: foreach_attr(item, &write_per_attr, (void *) item_id);
! 523: }
! 524:
! 525: static void write_per_node(node_t *node, void *arg)
! 526: {
! 527: struct xdata x = { .node = node };
! 528:
! 529: x.node_id = node_exists(node->n_name);
! 530:
! 531: if (x.node_id < 0)
! 532: x.node_id = insert_node(node->n_name, node->n_from);
! 533:
! 534: if (x.node_id < 0)
! 535: return;
! 536:
! 537: foreach_item(node, write_per_item, &x);
! 538: }
! 539:
! 540: void db_draw(void)
! 541: {
! 542: static int rem = 1;
! 543:
! 544: if (--rem)
! 545: return;
! 546: else
! 547: rem = c_interval;
! 548:
! 549: foreach_node(write_per_node, NULL);
! 550: }
! 551:
! 552: static void print_module_help(void)
! 553: {
! 554: printf(
! 555: "DB - Database Output\n" \
! 556: "\n" \
! 557: " Writes current rate estimations into a database for\n" \
! 558: " other tools to pick up.\n" \
! 559: "\n" \
! 560: " Author: Thomas Graf <tgraf@suug.ch>\n" \
! 561: "\n" \
! 562: " Options:\n" \
! 563: " driverdir=DIR Directory containing libdi drivers\n" \
! 564: " driver=DRIVER DB driver (default: mysql)\n" \
! 565: " host=HOST Host the database is on (default: localhost)\n" \
! 566: " dbname=NAME Name of database (default: bmon)\n" \
! 567: " username=NAME Authentication username (default: bmon)\n" \
! 568: " password=TEXT Authentication password\n" \
! 569: " mask=MASK Write selection mask (default: mhd)\n" \
! 570: " interval=SEC Update interval in seconds (default: 3)\n" \
! 571: "\n" \
! 572: " Mask Attributes:\n" \
! 573: " r Read interval\n" \
! 574: " s Seconds\n" \
! 575: " m Minutes\n" \
! 576: " h Hours\n" \
! 577: " d Days\n" \
! 578: "\n" \
! 579: " Examples:\n" \
! 580: " -O 'db:password=bmon;mask=rmhd'");
! 581: }
! 582:
! 583: static void db_set_opts(tv_t *attrs)
! 584: {
! 585: while (attrs) {
! 586: if (!strcasecmp(attrs->type, "driverdir") && attrs->value)
! 587: c_driverdir = attrs->value;
! 588: else if (!strcasecmp(attrs->type, "driver") && attrs->value)
! 589: c_driver = attrs->value;
! 590: else if (!strcasecmp(attrs->type, "host") && attrs->value)
! 591: c_host = attrs->value;
! 592: else if (!strcasecmp(attrs->type, "username") && attrs->value)
! 593: c_username = attrs->value;
! 594: else if (!strcasecmp(attrs->type, "dbname") && attrs->value)
! 595: c_dbname = attrs->value;
! 596: else if (!strcasecmp(attrs->type, "password") && attrs->value)
! 597: c_password = attrs->value;
! 598: else if (!strcasecmp(attrs->type, "mask") && attrs->value)
! 599: c_mask = attrs->value;
! 600: else if (!strcasecmp(attrs->type, "interval") && attrs->value)
! 601: c_interval = strtol(attrs->value, NULL, 0);
! 602: else if (!strcasecmp(attrs->type, "help")) {
! 603: print_module_help();
! 604: exit(0);
! 605: }
! 606:
! 607: attrs = attrs->next;
! 608: }
! 609: }
! 610:
! 611: static int db_probe(void)
! 612: {
! 613: if (strchr(c_mask, 'r'))
! 614: do_read = 1;
! 615:
! 616: if (strchr(c_mask, 's'))
! 617: do_sec = 1;
! 618:
! 619: if (strchr(c_mask, 'm'))
! 620: do_min = 1;
! 621:
! 622: if (strchr(c_mask, 'h'))
! 623: do_hour = 1;
! 624:
! 625: if (strchr(c_mask, 'd'))
! 626: do_day = 1;
! 627:
! 628: if (c_password == NULL) {
! 629: fprintf(stderr, "You must specify the database password\n");
! 630: return 0;
! 631: }
! 632:
! 633: if (dbi_initialize(c_driverdir) < 0) {
! 634: fprintf(stderr, "Cannot initialize DBI layer\n");
! 635: return 0;
! 636: }
! 637:
! 638: db_conn = dbi_conn_new(c_driver);
! 639: if (db_conn == NULL) {
! 640: fprintf(stderr, "Cannot initialize connection \"%s\"\n",
! 641: c_driver);
! 642: return 0;
! 643: }
! 644:
! 645: dbi_conn_set_option(db_conn, "host", c_host);
! 646: dbi_conn_set_option(db_conn, "username", c_username);
! 647: dbi_conn_set_option(db_conn, "password", c_password);
! 648: dbi_conn_set_option(db_conn, "dbname", c_dbname);
! 649:
! 650: if (dbi_conn_connect(db_conn) < 0) {
! 651: fprintf(stderr, "Cannot open database \"%s\" connection on " \
! 652: "%s@%s\n", c_dbname, c_username, c_host);
! 653: return 0;
! 654: }
! 655:
! 656: if (!create_tables()) {
! 657: fprintf(stderr, "Could not create tables\n");
! 658: return 0;
! 659: }
! 660:
! 661: if (!insert_attr_descs()) {
! 662: fprintf(stderr, "Could not insert attribute descriptions\n");
! 663: return 0;
! 664: }
! 665:
! 666: return 1;
! 667: }
! 668:
! 669: static void db_shutdown(void)
! 670: {
! 671: if (db_conn)
! 672: dbi_conn_close(db_conn);
! 673:
! 674: dbi_shutdown();
! 675: }
! 676:
! 677: static struct output_module db_ops = {
! 678: .om_name = "db",
! 679: .om_draw = db_draw,
! 680: .om_set_opts = db_set_opts,
! 681: .om_probe = db_probe,
! 682: .om_shutdown db_shutdown,
! 683: };
! 684:
! 685: static void __init db_init(void)
! 686: {
! 687: register_secondary_output_module(&db_ops);
! 688: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>