5965e6aafa6d171434bbc11bb3262279f7340a5c
[NeonServV5.git] / src / mysqlConn.c
1
2 #include "mysqlConn.h"
3 #define DATABASE_VERSION "1"
4
5 struct used_result {
6     MYSQL_RES *result;
7     struct used_result *next;
8 };
9
10 struct escaped_string {
11     char *string;
12     struct escaped_string *next;
13 };
14
15 MYSQL *mysql_conn = NULL;
16 static struct used_result *used_results;
17 static struct escaped_string *escaped_strings;
18 static int mysql_serverport;
19 static char *mysql_host, *mysql_user, *mysql_pass, *mysql_base;
20
21 void check_mysql() {
22     int errid;
23     if((errid = mysql_ping(mysql_conn))) {
24         if(mysql_errno(mysql_conn) == CR_SERVER_GONE_ERROR) {
25             if(!mysql_real_connect(mysql_conn, mysql_host, mysql_user, mysql_pass, mysql_base, mysql_serverport, NULL, 0)) {
26                 show_mysql_error();
27             }
28         } else {
29             //mysql error
30             show_mysql_error();
31         }
32     }
33 }
34
35 MYSQL_RES *mysql_use() {
36     MYSQL_RES *res = mysql_store_result(mysql_conn);
37     struct used_result *result = malloc(sizeof(*result));
38     if (!result) {
39         mysql_free_result(res);
40         return NULL;
41     }
42     result->result = res;
43     result->next = used_results;
44     used_results = result;
45     return res;
46 }
47
48 void mysql_free() {
49     struct used_result *result, *next_result;
50     for(result = used_results; result; result = next_result) {
51         next_result = result->next;
52         mysql_free_result(result->result);
53         free(result);
54     }
55     used_results = NULL;
56     struct escaped_string *escaped, *next_escaped;
57     for(escaped = escaped_strings; escaped; escaped = next_escaped) {
58         next_escaped = escaped->next;
59         free(escaped->string);
60         free(escaped);
61     }
62     escaped_strings = NULL;
63 }
64
65 void init_mysql(char *host, int port, char *user, char *pass, char *base) {
66     mysql_host = strdup(host);
67     mysql_serverport = port;
68     mysql_user = strdup(user);
69     mysql_pass = strdup(pass);
70     mysql_base = strdup(base);
71     mysql_conn = mysql_init(NULL);
72     if (!mysql_real_connect(mysql_conn, mysql_host, mysql_user, mysql_pass, mysql_base, mysql_serverport, NULL, 0)) {
73         //error
74         show_mysql_error();
75     }
76     //check database version...
77     int version = 0;
78     if(!mysql_query(mysql_conn, "SELECT `database_version` FROM `version`")) {
79         MYSQL_RES *res = mysql_use();
80         MYSQL_ROW row;
81         if((row = mysql_fetch_row(res))) {
82             version = atoi(row[0]);
83         }
84     }
85     if(!version) {
86         //CREATE DATABASE
87         FILE *f = fopen("database.sql", "r");
88         mysql_set_server_option(mysql_conn, MYSQL_OPTION_MULTI_STATEMENTS_ON);
89         if (f) {
90             char line[512];
91             char query_buffer[8192];
92             int query_buffer_pos = 0;
93             while (fgets(line, sizeof(line), f)) {
94                 query_buffer_pos += sprintf(query_buffer + query_buffer_pos, " %s", line);
95                 if(line[(strlen(line) - 1)] == ';') {
96                     mysql_query(mysql_conn, query_buffer);
97                     query_buffer_pos = 0;
98                 }
99             }
100             fclose(f);
101         }
102         f = fopen("database.defaults.sql", "r");
103         mysql_set_server_option(mysql_conn, MYSQL_OPTION_MULTI_STATEMENTS_ON);
104         if (f) {
105             char line[2048];
106             char query_buffer[65536];
107             int query_buffer_pos = 0;
108             while (fgets(line, sizeof(line), f)) {
109                 query_buffer_pos += sprintf(query_buffer + query_buffer_pos, " %s", line);
110                 if(line[(strlen(line) - 1)] == ';') {
111                     mysql_query(mysql_conn, query_buffer);
112                     query_buffer_pos = 0;
113                 }
114             }
115             fclose(f);
116         }
117         mysql_set_server_option(mysql_conn, MYSQL_OPTION_MULTI_STATEMENTS_OFF);
118         mysql_query(mysql_conn, "UPDATE `version` SET `database_version` = '" DATABASE_VERSION "'");
119     }
120     else if(version < atoi(DATABASE_VERSION)) {
121         //UPDATE DATABASE
122         FILE *f = fopen("database.upgrade.sql", "r");
123         mysql_set_server_option(mysql_conn, MYSQL_OPTION_MULTI_STATEMENTS_ON);
124         if (f) {
125             char line[512];
126             char query_buffer[8192];
127             int query_buffer_pos = 0, use_querys = 0;
128             sprintf(query_buffer, "-- version: %d", version);
129             while (fgets(line, sizeof(line), f)) {
130                 if(use_querys) {
131                     query_buffer_pos += sprintf(query_buffer + query_buffer_pos, " %s", line);
132                     if(line[strlen(line) - 1] == ';') {
133                         mysql_query(mysql_conn, query_buffer);
134                         query_buffer_pos = 0;
135                     }
136                 } else if(!stricmp(query_buffer, line)) {
137                     use_querys = 1;
138                 }
139             }
140             fclose(f);
141         }
142         mysql_set_server_option(mysql_conn, MYSQL_OPTION_MULTI_STATEMENTS_OFF);
143         mysql_query(mysql_conn, "UPDATE `version` SET `database_version` = '" DATABASE_VERSION "'");
144     }
145 }
146
147 void free_mysql() {
148     mysql_close(mysql_conn);
149 }
150
151 void show_mysql_error() {
152     //show mysql_error()
153     printf("MySQL Error: %s\n", mysql_error(mysql_conn));
154 }
155
156 void printf_mysql_query(const char *text, ...) {
157     va_list arg_list;
158     char queryBuf[MYSQLMAXLEN];
159     int pos;
160     queryBuf[0] = '\0';
161     va_start(arg_list, text);
162     pos = vsnprintf(queryBuf, MYSQLMAXLEN - 2, text, arg_list);
163     va_end(arg_list);
164     if (pos < 0 || pos > (MYSQLMAXLEN - 2)) pos = MYSQLMAXLEN - 2;
165     queryBuf[pos] = '\0';
166     printf("MySQL: %s\n", queryBuf);
167     if(mysql_query(mysql_conn, queryBuf)) {
168         check_mysql();
169         if(mysql_query(mysql_conn, queryBuf)) {
170             show_mysql_error();
171         }
172     }
173 }
174
175 char* escape_string(const char *str) {
176     struct escaped_string *escapedstr = malloc(sizeof(*escapedstr));
177     if (!escapedstr) {
178         return NULL;
179     }
180     char escaped[strlen(str)*2+1];
181     mysql_real_escape_string(mysql_conn, escaped, str, strlen(str));
182     escapedstr->string = strdup(escaped);
183     escapedstr->next = escaped_strings;
184     escaped_strings = escapedstr;
185     return escapedstr->string;
186 }