import.c: Never print more than 60 seconds
[nagios-reports-module.git] / sql.c
blobc97e69d86da87a8da3bc9da7d1d93476bc8a063f
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 #define esc(s) sql_escape(s)
22 char *sql_escape(const char *str)
24 static int idx = 0;
25 static char *buf_ary[ESC_BUFS] = { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL };
26 static size_t bufsize[ESC_BUFS] = { 0, 0, 0, 0, 0, 0, 0, 0 };
27 char *buf;
28 int len;
30 if (!str || !*str)
31 return "";
33 len = strlen(str);
34 if (len > MAX_ESC_STRING) {
35 lwarn("Unescaped string too large (%d bytes, %d is allowed)",
36 len, MAX_ESC_STRING);
37 return "";
40 if (bufsize[idx] < len * 2) {
41 size_t size = len * 2;
42 if (size < 16384)
43 size = 16384;
45 buf_ary[idx] = realloc(buf_ary[idx], size);
46 if (!buf_ary[idx]) {
47 bufsize[idx] = 0;
48 lwarn("Failed to allocate %d bytes for sql escape buffer", size);
49 return "";
51 bufsize[idx] = size;
53 buf = buf_ary[idx];
54 idx = (idx + 1) & (ESC_BUFS - 1);
55 mysql_real_escape_string(db.link, buf, str, len);
57 return buf;
61 * these two functions are only here to allow callers
62 * access to error reporting without having to expose
63 * the db-link to theh callers. It's also nifty as we
64 * want to remain database layer agnostic
66 const char *sql_error()
68 if (db.link)
69 return mysql_error(db.link);
71 return "unknown error (no link)";
74 int sql_errno(void)
76 if (db.link)
77 return mysql_errno(db.link);
79 return -1;
82 SQL_RESULT *sql_get_result(void)
84 if (db.link)
85 return mysql_use_result(db.link);
87 return NULL;
90 SQL_ROW sql_fetch_row(MYSQL_RES *result)
92 if (result)
93 return mysql_fetch_row(result);
95 return NULL;
98 void sql_free_result(SQL_RESULT *result)
100 if (result)
101 mysql_free_result(result);
104 int sql_query(const char *fmt, ...)
106 char *query;
107 int len, result = 0;
108 va_list ap;
110 va_start(ap, fmt);
111 len = vasprintf(&query, fmt, ap);
112 va_end(ap);
114 if (len == -1 || !query) {
115 lerr("sql_query: Failed to build query from format-string '%s'", fmt);
116 return -1;
118 if ((result = mysql_real_query(db.link, query, len))) {
119 lerr("mysql_query(): Retrying failed query [%s]: %s",
120 query, mysql_error(db.link));
122 sql_close();
123 sql_init();
124 if ((result = mysql_real_query(db.link, query, len)))
125 lerr("mysql_query(): Dropping failed query [%s]: %s",
126 query, mysql_error(db.link));
129 free(query);
131 return result;
134 int sql_init(void)
136 if (!(db.link = mysql_init(NULL)))
137 return -1;
139 if (!db.host) {
140 db.host = "";
141 db.port = 0;
144 if (!(mysql_real_connect(db.link, db.host, db.user, db.pass,
145 db.name, db.port, NULL, 0)))
147 lerr("Failed to connect to '%s' at '%s':'%d' using %s:%s as credentials: %s",
148 db.name, db.host, db.port, db.user, db.pass, mysql_error(db.link));
150 db.link = NULL;
151 return -1;
154 return 0;
157 int sql_close(void)
159 if (db.link)
160 mysql_close(db.link);
162 return 0;
165 const char *sql_table_name(void)
167 if (!db.table)
168 return "report_data";
170 return db.table;
173 int sql_config(const char *key, const char *value)
175 if (!prefixcmp(key, "db_database"))
176 db.name = strdup(value);
177 else if (!prefixcmp(key, "db_user"))
178 db.user = strdup(value);
179 else if (!prefixcmp(key, "db_pass"))
180 db.pass = strdup(value);
181 else if (!prefixcmp(key, "db_host"))
182 db.host = strdup(value);
183 else if (!prefixcmp(key, "db_table")) {
184 db.table = strdup(value);
186 else if (!prefixcmp(key, "db_port")) {
187 char *endp;
189 db.port = (unsigned int)strtoul(value, &endp, 0);
191 if (endp == value || *endp != 0)
192 return -1;
194 else
195 return -1; /* config error */
197 return 0;