Last active
December 17, 2022 17:18
-
-
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.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#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