sql: Introduce sql_db_name()
[nagios-reports-module.git] / sql.c
blob3faa8073ead9ef13a9f7a5e658afab86ec650bbb
1 #include "ndbneb.h"
2 #include <stdarg.h>
3 #include <stdio.h>
4 #include "sql.h"
5 #include "logging.h"
7 static struct {
8 char *host;
9 char *name;
10 char *user;
11 char *pass;
12 char *table;
13 unsigned int port;
14 MYSQL *link;
15 } db;
17 #undef ESC_BUFS
18 #define ESC_BUFS 8 /* must be a power of 2 */
19 #define MAX_ESC_STRING 65536
21 typedef unsigned int uint;
23 #define esc(s) sql_escape(s)
24 char *sql_escape(const char *str)
26 static int idx = 0;
27 static char *buf_ary[ESC_BUFS] = { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL };
28 static uint bufsize[ESC_BUFS] = { 0, 0, 0, 0, 0, 0, 0, 0 };
29 char *buf;
30 int len;
32 if (!str || !*str)
33 return "";
35 if (!db.link)
36 return NULL;
38 len = strlen(str);
39 if (len > MAX_ESC_STRING) {
40 lwarn("Unescaped string too large (%d bytes, %d is allowed)",
41 len, MAX_ESC_STRING);
42 return "";
45 if (bufsize[idx] < len * 2) {
46 uint size = len * 2;
47 if (size < 16384)
48 size = 16384;
50 buf_ary[idx] = realloc(buf_ary[idx], size);
51 if (!buf_ary[idx]) {
52 bufsize[idx] = 0;
53 lwarn("Failed to allocate %d bytes for sql escape buffer", size);
54 return "";
56 bufsize[idx] = size;
58 buf = buf_ary[idx];
59 idx = (idx + 1) & (ESC_BUFS - 1);
60 mysql_real_escape_string(db.link, buf, str, len);
62 return buf;
66 * these two functions are only here to allow callers
67 * access to error reporting without having to expose
68 * the db-link to theh callers. It's also nifty as we
69 * want to remain database layer agnostic
71 const char *sql_error()
73 if (db.link)
74 return mysql_error(db.link);
76 return "unknown error (no link)";
79 int sql_errno(void)
81 if (db.link)
82 return mysql_errno(db.link);
84 return -1;
87 SQL_RESULT *sql_get_result(void)
89 if (db.link)
90 return mysql_use_result(db.link);
92 return NULL;
95 SQL_ROW sql_fetch_row(MYSQL_RES *result)
97 if (result)
98 return mysql_fetch_row(result);
100 return NULL;
103 void sql_free_result(SQL_RESULT *result)
105 if (result)
106 mysql_free_result(result);
109 int sql_query(const char *fmt, ...)
111 char *query;
112 int len, result = 0;
113 va_list ap;
115 if (!db.link)
116 return -1;
118 va_start(ap, fmt);
119 len = vasprintf(&query, fmt, ap);
120 va_end(ap);
122 if (len == -1 || !query) {
123 lerr("sql_query: Failed to build query from format-string '%s'", fmt);
124 return -1;
126 if ((result = mysql_real_query(db.link, query, len))) {
127 lerr("mysql_query(): Retrying failed query [%s]: %s",
128 query, sql_error());
130 sql_close();
131 if (sql_init() < 0 || (result = mysql_real_query(db.link, query, len)))
132 lerr("mysql_query(): Dropping failed query [%s]: %s",
133 query, sql_error());
136 free(query);
138 return result;
141 int sql_init(void)
143 if (!(db.link = mysql_init(NULL)))
144 return -1;
146 if (!db.host) {
147 db.host = "";
148 db.port = 0;
151 if (!(mysql_real_connect(db.link, db.host, db.user, db.pass,
152 db.name, db.port, NULL, 0)))
154 lerr("Failed to connect to '%s' at '%s':'%d' using %s:%s as credentials: %s",
155 db.name, db.host, db.port, db.user, db.pass, sql_error());
157 db.link = NULL;
158 return -1;
161 return 0;
164 int sql_close(void)
166 if (db.link)
167 mysql_close(db.link);
169 return 0;
172 const char *sql_db_name(void)
174 if (!db.name)
175 return "monitor_reports";
177 return db.name;
180 const char *sql_table_name(void)
182 if (!db.table)
183 return "report_data";
185 return db.table;
188 int sql_config(const char *key, const char *value)
190 if (!prefixcmp(key, "db_database"))
191 db.name = strdup(value);
192 else if (!prefixcmp(key, "db_user"))
193 db.user = strdup(value);
194 else if (!prefixcmp(key, "db_pass"))
195 db.pass = strdup(value);
196 else if (!prefixcmp(key, "db_host"))
197 db.host = strdup(value);
198 else if (!prefixcmp(key, "db_table")) {
199 db.table = strdup(value);
201 else if (!prefixcmp(key, "db_port")) {
202 char *endp;
204 db.port = (unsigned int)strtoul(value, &endp, 0);
206 if (endp == value || *endp != 0)
207 return -1;
209 else
210 return -1; /* config error */
212 return 0;