1e1d8d5e767f14411d3d09600a869017a9a9a642
[NeonServV5.git] / src / mysqlConn.c
1
2 #include "mysqlConn.h"
3 #define DATABASE_VERSION "2"
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     printf("%d \n", version);
86     if(!version) {
87         //CREATE DATABASE
88         FILE *f = fopen("database.sql", "r");
89         mysql_set_server_option(mysql_conn, MYSQL_OPTION_MULTI_STATEMENTS_ON);
90         if (f) {
91             char line[512];
92             char query_buffer[8192];
93             int query_buffer_pos = 0;
94             while (fgets(line, sizeof(line), f)) {
95                 query_buffer_pos += sprintf(query_buffer + query_buffer_pos, " %s", line);
96                 if(line[(strlen(line) - 2)] == ';') {
97                     if(mysql_query(mysql_conn, query_buffer))
98                         show_mysql_error();
99                     query_buffer_pos = 0;
100                 }
101             }
102             fclose(f);
103         }
104         f = fopen("database.defaults.sql", "r");
105         if (f) {
106             char line[4096];
107             char query_buffer[131072];
108             int query_buffer_pos = 0;
109             while (fgets(line, sizeof(line), f)) {
110                 query_buffer_pos += sprintf(query_buffer + query_buffer_pos, " %s", line);
111                 if(line[(strlen(line) - 2)] == ';') {
112                     if(mysql_query(mysql_conn, query_buffer))
113                         show_mysql_error();
114                     query_buffer_pos = 0;
115                 }
116             }
117             fclose(f);
118         }
119         mysql_set_server_option(mysql_conn, MYSQL_OPTION_MULTI_STATEMENTS_OFF);
120         mysql_query(mysql_conn, "INSERT INTO `version` (`database_version`) VALUES ('" DATABASE_VERSION "')");
121     }
122     else if(version < atoi(DATABASE_VERSION)) {
123         //UPDATE DATABASE
124         FILE *f = fopen("database.upgrade.sql", "r");
125         mysql_set_server_option(mysql_conn, MYSQL_OPTION_MULTI_STATEMENTS_ON);
126         if (f) {
127             char line[512];
128             char query_buffer[8192];
129             int query_buffer_pos = 0, use_querys = 0;
130             sprintf(query_buffer, "-- version: %d", version);
131             while (fgets(line, sizeof(line), f)) {
132                 if(use_querys) {
133                     query_buffer_pos += sprintf(query_buffer + query_buffer_pos, " %s", line);
134                     if(line[strlen(line) - 1] == ';') {
135                         mysql_query(mysql_conn, query_buffer);
136                         query_buffer_pos = 0;
137                     }
138                 } else if(!stricmp(query_buffer, line)) {
139                     use_querys = 1;
140                 }
141             }
142             if(query_buffer_pos) {
143                 if(mysql_query(mysql_conn, query_buffer))
144                     show_mysql_error();
145             }
146             fclose(f);
147         } else
148             perror("database.sql missing!");
149         mysql_set_server_option(mysql_conn, MYSQL_OPTION_MULTI_STATEMENTS_OFF);
150         mysql_query(mysql_conn, "UPDATE `version` SET `database_version` = '" DATABASE_VERSION "'");
151     }
152 }
153
154 void free_mysql() {
155     mysql_close(mysql_conn);
156 }
157
158 void show_mysql_error() {
159     //show mysql_error()
160     printf("MySQL Error: %s\n", mysql_error(mysql_conn));
161 }
162
163 void printf_mysql_query(const char *text, ...) {
164     va_list arg_list;
165     char queryBuf[MYSQLMAXLEN];
166     int pos;
167     queryBuf[0] = '\0';
168     va_start(arg_list, text);
169     pos = vsnprintf(queryBuf, MYSQLMAXLEN - 2, text, arg_list);
170     va_end(arg_list);
171     if (pos < 0 || pos > (MYSQLMAXLEN - 2)) pos = MYSQLMAXLEN - 2;
172     queryBuf[pos] = '\0';
173     printf("MySQL: %s\n", queryBuf);
174     if(mysql_query(mysql_conn, queryBuf)) {
175         check_mysql();
176         if(mysql_query(mysql_conn, queryBuf)) {
177             show_mysql_error();
178         }
179     }
180 }
181
182 char* escape_string(const char *str) {
183     struct escaped_string *escapedstr = malloc(sizeof(*escapedstr));
184     if (!escapedstr) {
185         return NULL;
186     }
187     char escaped[strlen(str)*2+1];
188     mysql_real_escape_string(mysql_conn, escaped, str, strlen(str));
189     escapedstr->string = strdup(escaped);
190     escapedstr->next = escaped_strings;
191     escaped_strings = escapedstr;
192     return escapedstr->string;
193 }