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
)
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 };
39 if (len
> MAX_ESC_STRING
) {
40 lwarn("Unescaped string too large (%d bytes, %d is allowed)",
45 if (bufsize
[idx
] < len
* 2) {
50 buf_ary
[idx
] = realloc(buf_ary
[idx
], size
);
53 lwarn("Failed to allocate %d bytes for sql escape buffer", size
);
59 idx
= (idx
+ 1) & (ESC_BUFS
- 1);
60 mysql_real_escape_string(db
.link
, buf
, str
, len
);
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()
74 return mysql_error(db
.link
);
76 return "unknown error (no link)";
82 return mysql_errno(db
.link
);
87 SQL_RESULT
*sql_get_result(void)
90 return mysql_use_result(db
.link
);
95 SQL_ROW
sql_fetch_row(MYSQL_RES
*result
)
98 return mysql_fetch_row(result
);
103 void sql_free_result(SQL_RESULT
*result
)
106 mysql_free_result(result
);
109 int sql_query(const char *fmt
, ...)
119 len
= vasprintf(&query
, fmt
, ap
);
122 if (len
== -1 || !query
) {
123 lerr("sql_query: Failed to build query from format-string '%s'", fmt
);
126 if ((result
= mysql_real_query(db
.link
, query
, len
))) {
127 lerr("mysql_query(): Retrying failed query [%s]: %s",
131 if (sql_init() < 0 || (result
= mysql_real_query(db
.link
, query
, len
)))
132 lerr("mysql_query(): Dropping failed query [%s]: %s",
143 if (!(db
.link
= mysql_init(NULL
)))
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());
167 mysql_close(db
.link
);
172 const char *sql_db_name(void)
175 return "monitor_reports";
180 const char *sql_table_name(void)
183 return "report_data";
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")) {
204 db
.port
= (unsigned int)strtoul(value
, &endp
, 0);
206 if (endp
== value
|| *endp
!= 0)
210 return -1; /* config error */