Makefile: Add default LDFLAGS and make it overridable
[nagios-reports-module.git] / sql.c
blobc1a15a3464da3f8e41b6bc7197161b865eb38e0f
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 len = strlen(str);
36 if (len > MAX_ESC_STRING) {
37 lwarn("Unescaped string too large (%d bytes, %d is allowed)",
38 len, MAX_ESC_STRING);
39 return "";
42 if (bufsize[idx] < len * 2) {
43 uint size = len * 2;
44 if (size < 16384)
45 size = 16384;
47 buf_ary[idx] = realloc(buf_ary[idx], size);
48 if (!buf_ary[idx]) {
49 bufsize[idx] = 0;
50 lwarn("Failed to allocate %d bytes for sql escape buffer", size);
51 return "";
53 bufsize[idx] = size;
55 buf = buf_ary[idx];
56 idx = (idx + 1) & (ESC_BUFS - 1);
57 mysql_real_escape_string(db.link, buf, str, len);
59 return buf;
63 * these two functions are only here to allow callers
64 * access to error reporting without having to expose
65 * the db-link to theh callers. It's also nifty as we
66 * want to remain database layer agnostic
68 const char *sql_error()
70 if (db.link)
71 return mysql_error(db.link);
73 return "unknown error (no link)";
76 int sql_errno(void)
78 if (db.link)
79 return mysql_errno(db.link);
81 return -1;
84 SQL_RESULT *sql_get_result(void)
86 if (db.link)
87 return mysql_use_result(db.link);
89 return NULL;
92 SQL_ROW sql_fetch_row(MYSQL_RES *result)
94 if (result)
95 return mysql_fetch_row(result);
97 return NULL;
100 void sql_free_result(SQL_RESULT *result)
102 if (result)
103 mysql_free_result(result);
106 int sql_query(const char *fmt, ...)
108 char *query;
109 int len, result = 0;
110 va_list ap;
112 va_start(ap, fmt);
113 len = vasprintf(&query, fmt, ap);
114 va_end(ap);
116 if (len == -1 || !query) {
117 lerr("sql_query: Failed to build query from format-string '%s'", fmt);
118 return -1;
120 if ((result = mysql_real_query(db.link, query, len))) {
121 lerr("mysql_query(): Retrying failed query [%s]: %s",
122 query, sql_error());
124 sql_close();
125 if (sql_init() < 0 || (result = mysql_real_query(db.link, query, len)))
126 lerr("mysql_query(): Dropping failed query [%s]: %s",
127 query, sql_error());
130 free(query);
132 return result;
135 int sql_init(void)
137 if (!(db.link = mysql_init(NULL)))
138 return -1;
140 if (!db.host) {
141 db.host = "";
142 db.port = 0;
145 if (!(mysql_real_connect(db.link, db.host, db.user, db.pass,
146 db.name, db.port, NULL, 0)))
148 lerr("Failed to connect to '%s' at '%s':'%d' using %s:%s as credentials: %s",
149 db.name, db.host, db.port, db.user, db.pass, sql_error());
151 db.link = NULL;
152 return -1;
155 return 0;
158 int sql_close(void)
160 if (db.link)
161 mysql_close(db.link);
163 return 0;
166 const char *sql_table_name(void)
168 if (!db.table)
169 return "report_data";
171 return db.table;
174 int sql_config(const char *key, const char *value)
176 if (!prefixcmp(key, "db_database"))
177 db.name = strdup(value);
178 else if (!prefixcmp(key, "db_user"))
179 db.user = strdup(value);
180 else if (!prefixcmp(key, "db_pass"))
181 db.pass = strdup(value);
182 else if (!prefixcmp(key, "db_host"))
183 db.host = strdup(value);
184 else if (!prefixcmp(key, "db_table")) {
185 db.table = strdup(value);
187 else if (!prefixcmp(key, "db_port")) {
188 char *endp;
190 db.port = (unsigned int)strtoul(value, &endp, 0);
192 if (endp == value || *endp != 0)
193 return -1;
195 else
196 return -1; /* config error */
198 return 0;