Skip to content

Instantly share code, notes, and snippets.

@opsJson
Last active December 17, 2022 17:18
Show Gist options
  • Save opsJson/ff1deaa8c3855dcb450f4966a17ea0ee to your computer and use it in GitHub Desktop.
Save opsJson/ff1deaa8c3855dcb450f4966a17ea0ee to your computer and use it in GitHub Desktop.
Really Easy MYSQL C API interface. Features: printf like arguments, auto escape arguments, multiple statement execution and auto reconnection.
#ifndef _EASY_SQL_H_
#define _EASY_SQL_H_
#include <mysql.h>
#include <stdio.h>
#include <string.h>
typedef my_ulonglong MYSQL_COUNT;
MYSQL *sql_open(char *host, int port, char *user, char *pass, char *db);
int sql_execute(
MYSQL *mysql,
int (*on_result)(MYSQL_ROW row, MYSQL_COUNT count, void *userdata),
void *userdata,
char *format,
...);
void sql_close(MYSQL *mysql);
#if defined(_WIN32) || defined(_WIN64) || defined(__CYGWIN__)
#include <winuser.h>
#define MYSQL_SHOW_ERROR(title, msg) MessageBox(NULL, msg, title, MB_ICONERROR)
#define MYSQL_INIT_ERROR() MessageBox(NULL, "Could not init mysql library.", "MYSQL ERROR!", MB_ICONERROR);
#else
#define MYSQL_SHOW_ERROR(title, msg) fprintf(stderr, "%s %s\n", title, msg)
#define MYSQL_INIT_ERROR() fprintf(stderr, "MYSQL ERROR: Could not init mysql library.\n")
#endif
static void _sql_error(MYSQL *mysql) {
char title[32];
snprintf(title, sizeof(title)-1, "MYSQL ERROR %u", mysql_errno(mysql));
MYSQL_SHOW_ERROR(title, mysql_error(mysql));
}
MYSQL *sql_open(char *host, int port, char *user, char *pass, char *db) {
MYSQL *mysql;
my_bool option = 1;
if (!host || !user || !pass || !db) return NULL;
if ((mysql = mysql_init(NULL)) == NULL) {
MYSQL_INIT_ERROR();
return NULL;
}
if (mysql_options(mysql, MYSQL_OPT_RECONNECT, &option) != 0) goto error;
if (mysql_real_connect(mysql, host, user, pass, db, port, NULL, CLIENT_MULTI_STATEMENTS) == NULL) goto error;
return mysql;
error:
_sql_error(mysql);
mysql_close(mysql);
return NULL;
}
int sql_execute(MYSQL *mysql, int (*on_result)(MYSQL_ROW row, MYSQL_COUNT count, void *userdata), void *userdata, char *format, ...) {
MYSQL_COUNT i, j, rows_count, columns_count, format_size, args_size;
MYSQL_RES *res = NULL;
MYSQL_ROW row;
char *query, *arg, temp[32];
va_list args;
int ret;
if (!mysql || !format) return 1;
va_start(args, format);
format_size = strlen(format);
args_size = 0;
for (i=0; i<format_size; i++) {
if (format[i] == '%') {
i++;
if (format[i] == 's') {
arg = va_arg(args, char*);
while (*arg) {
if (*arg == '\'' || *arg == '\"') args_size++;
args_size++;
arg++;
}
}
else if (format[i] == 'w') {
arg = va_arg(args, char*);
while (*arg) {
if (*arg == '\'' || *arg == '\"') args_size++;
args_size++;
arg += 2;
}
}
else if (format[i] == 'i' || format[i] == 'd' || format[i] == 'u') {
snprintf(temp, sizeof(temp)-1, "%i", va_arg(args, int));
args_size += strlen(temp);
}
else if (format[i] == 'c') {
snprintf(temp, sizeof(temp)-1, "%c", va_arg(args, int));
args_size += strlen(temp);
}
else if (format[i] == 'f') {
snprintf(temp, sizeof(temp)-1, "%lf", va_arg(args, double));
args_size += strlen(temp);
}
else if (format[i] == 'p') {
snprintf(temp, sizeof(temp)-1, "%p", va_arg(args, void*));
args_size += strlen(temp);
}
else if (format[i] == 'x') {
snprintf(temp, sizeof(temp)-1, "%x", va_arg(args, int));
args_size += strlen(temp);
}
else if (format[i] == '%') {
args_size += 1;
}
else return 1;
args_size -= 2;
}
}
va_end(args);
if ((query = malloc(format_size + args_size + 1)) == NULL) return 1;
va_start(args, format);
for (i=0,j=0; i<format_size; i++) {
if (format[i] == '%') {
i++;
if (format[i] == 's') {
arg = va_arg(args, char*);
while (*arg) {
if (*arg == '\'' || *arg == '\"') {
query[j++] = '\\';
query[j++] = *arg;
}
else query[j++] = *arg;
arg++;
}
}
else if (format[i] == 'w') {
arg = va_arg(args, char*);
while (*arg) {
if (*arg == '\'' || *arg == '\"') {
query[j++] = '\\';
query[j++] = *arg;
}
else query[j++] = *arg;
arg += 2;
}
}
else if (format[i] == 'i' || format[i] == 'd' || format[i] == 'u') {
snprintf(temp, sizeof(temp)-1, "%i", va_arg(args, int));
strcpy(query + j, temp);
j += strlen(temp);
}
else if (format[i] == 'c') {
snprintf(temp, sizeof(temp)-1, "%c", va_arg(args, int));
strcpy(query + j, temp);
j += strlen(temp);
}
else if (format[i] == 'f') {
snprintf(temp, sizeof(temp)-1, "%lf", va_arg(args, double));
strcpy(query + j, temp);
j += strlen(temp);
}
else if (format[i] == 'p') {
snprintf(temp, sizeof(temp)-1, "%p", va_arg(args, void*));
strcpy(query + j, temp);
j += strlen(temp);
}
else if (format[i] == 'x') {
snprintf(temp, sizeof(temp)-1, "%x", va_arg(args, int));
strcpy(query + j, temp);
j += strlen(temp);
}
else if (format[i] == '%') {
query[j++] = format[i];
}
else {
free(query);
return 1;
}
}
else query[j++] = format[i];
}
query[j] = 0;
va_end(args);
if (mysql_real_query(mysql, query, format_size + args_size) != 0) goto error;
if (!on_result) {
free(query);
return 0;
}
do {
if ((res = mysql_store_result(mysql)) == NULL) {
if (mysql_errno(mysql) != 0) goto error;
free(query);
return on_result(NULL, 0, userdata);
}
rows_count = mysql_num_rows(res);
columns_count = mysql_num_fields(res);
if (rows_count == 0) {
free(query);
return on_result(NULL, 0, userdata);
}
for (i=1; i<=rows_count; i++) {
if ((row = mysql_fetch_row(res)) == NULL) {
mysql_free_result(res);
goto error;
}
if ((ret = on_result(row, columns_count, userdata)) != 0) {
mysql_free_result(res);
free(query);
return ret;
}
mysql_data_seek(res, i);
}
mysql_free_result(res);
} while(mysql_next_result(mysql) == 0);
free(query);
return 0;
error:
_sql_error(mysql);
free(query);
return 1;
}
void sql_close(MYSQL *mysql) {
if (!mysql) return;
mysql_close(mysql);
}
#endif /* _EASY_SQL_H_ */
/*///////////////////////////////////
Testing:
///////////////////////////////////*/
int on_result(MYSQL_ROW row, MYSQL_COUNT count, void *userdata) {
MYSQL_COUNT i;
(void)userdata;
for (i=0; i<count; i++) {
printf("%s |", row[i]);
}
printf("\n--------------------------------------------------------\n");
return 0;
}
int main(void) {
MYSQL *mysql;
mysql = sql_open("localhost", 3306, "root", "password", "database");
sql_execute(mysql, on_result, NULL, "select %s from table where id = %i;", "field", 69);
sql_close(mysql);
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment