Hallo,
derzeit arbeite ich an einem IRC Bot, der bestimmte Inhalte aus einem Channel in einer Datenbank schreiben soll. Da der Bot Platformunabhängig sein soll, habe ich mich für die Sprache C++ entschieden.
Um aber überhaupt mit C/C++ MySQL nutzen zu können, kann man die MySQL++ API nutzen. Hier habe ich eine kleine Klasse geschrieben, die ein MYSQL Objekt initialisiert, zum Server eine Verbindung aufbaut und einen Query ausführt.
Wohl angemerkt: Das Ganze ist noch recht unvollständig, Grundfunktionalitäten sind aber implementiert. Außerdem, der Query ist noch nicht geschützt, SQL Injections sind also möglich!
Um die Klasse nutzen zu können, muss man unter Windows die
mysql++ API installieren und die include- und lib Pfade angeben. Außerdem ist es nötig die windows.h, noch bevor man die mysql.h included, einzufügen!
Unter Linux installiert man sich einfach das Paket mysql und teilt dem Compiler (ich habe g++ genutzt) mit die Verzeichnisse /usr/include/mysql/ und /usr/lib/mysql/ nach den Includes und Librarys zu durchsuchen.
g++ -c -I/usr/include/mysql main.cpp
g++ -o main main.o -L/usr/lib/mysql -lmysqlclient -lz
Desweiteren würde ich um etwas Feedback bitten. Was ist daran schön, was ist weniger schön programmiert? Was ließe sich besser implementieren und vorallem wie?
|
C Quellcode
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
|
/* SQL Klasse zum Zugriff auf mysql Datenbanken mit C++.
*
*/
#ifndef SQL_H
#define SQL_H
#define MAX_IRC_TEXT_LENGHT 512
#define STEP 8
#include <iostream>
#include <mysql.h>
#include <string>
using namespace std;
class sql {
private:
char *pHost;
int pHost_sz;
char *pUser;
int pUser_sz;
char *pPw;
int pPw_sz;
char *pDb;
int pDb_sz;
bool connected;
void sql_init();
void sql_error();
bool sql_connect();
void sql_disconnect();
public:
// Das MYSQL Objekt aus der mysql.h
MYSQL *my;
// Konstruktor / Destruktor
sql(char *_host, char *_user, char *_pw, char *_db);
~sql();
// Methoden
// debugging Methode
void DEBUG();
// Verbindung aufbauen
// Query ausführen
bool sql_query(string query);
};
// Konstruktor
sql::sql(char *_host, char *_user, char *_pw, char *_db) {
this->pHost = NULL;
this->pHost_sz = 0;
this->pUser = NULL;
this->pUser_sz = 0;
this->pPw = NULL;
this->pPw_sz = 0;
this->pDb = NULL;
this->pDb_sz = 0;
for(int i=0; i<=strlen(_host); i++) {
if(i >= pHost_sz) {
char *c = new char[this->pHost_sz+STEP];
for(int j=0; j<pHost_sz; j++) {
c[j] = this->pHost[j];
}
if(this->pHost == NULL)
delete[] this->pHost;
this->pHost = c;
this->pHost_sz += STEP;
}
this->pHost[i] = _host[i];
}
for(int i=0; i<=strlen(_user); i++) {
if(i >= pUser_sz) {
char *c = new char[this->pUser_sz+STEP];
for(int j=0; j<pUser_sz; j++) {
c[j] = this->pUser[j];
}
if(this->pUser == NULL)
delete[] this->pUser;
this->pUser = c;
this->pUser_sz += STEP;
}
this->pUser[i] = _user[i];
}
for(int i=0; i<=strlen(_pw); i++) {
if(i >= pPw_sz) {
char *c = new char[this->pPw_sz+STEP];
for(int j=0; j<pPw_sz; j++) {
c[j] = this->pPw[j];
}
if(this->pPw == NULL)
delete[] this->pPw;
this->pPw = c;
this->pPw_sz += STEP;
}
this->pPw[i] = _pw[i];
}
for(int i=0; i<=strlen(_db); i++) {
if(i >= pDb_sz) {
char *c = new char[this->pDb_sz+STEP];
for(int j=0; j<pDb_sz; j++) {
c[j] = this->pDb[j];
}
if(this->pDb == NULL)
delete[] this->pDb;
this->pDb = c;
this->pDb_sz += STEP;
}
this->pDb[i] = _db[i];
}
// Nachdem die Parameter gesetzt wurden, wird das Objekt initialisiert
this->sql_init();
}
sql::~sql() {
if(this->pHost != NULL) {
delete[] pHost;
}
if(this->pUser != NULL) {
delete[] pUser;
}
if(this->pPw != NULL) {
delete[] pPw;
}
if(this->pDb != NULL) {
delete[] pDb;
}
}
void sql::sql_error() {
// Selbsterklärend
cerr << "Errorcode: " << mysql_errno(my) << "\n" << mysql_error(my);
//exit(EXIT_FAILURE);
}
void sql::DEBUG() {
cout << this->pHost << endl;
cout << this->pUser << endl;
cout << this->pPw << endl;
cout << this->pDb << endl;
}
void sql::sql_init() {
this->connected = false;
if((this->my = mysql_init(NULL)) == NULL) {
cerr << "Fehler beim initialisieren.";
exit(EXIT_FAILURE);
}
}
void sql::sql_disconnect() {
if(this->connected) {
mysql_close(my);
this->connected = false;
}
}
bool sql::sql_connect() {
// Zur Datenbank verbinden:
if(this->connected == false) {
if(mysql_real_connect(
my, /* *MYSQL Handler */
this->pHost, /* Host */
this->pUser, /* User */
this->pPw, /* Passwort */
this->pDb, /* Datenbank */
0, /* Port */
NULL, /* Socket */
0) /* Flags */ == NULL) {
// Bei einem Fehler die error Methode ausführen
this->sql_error();
return false;
}
else {
this->connected = true;
return true;
}
}
}
bool sql::sql_query(string query) {
if(this->connected == false) {
if(this->sql_connect() == false) {
return false;
}
}
// in dynamic char casten
char *sql_char = NULL;
int sql_char_sz = 0;
for(int i=0; i<=query.size(); i++) {
// Ist das Query länger als der sql_char?
if(i >= sql_char_sz) {
// Joa, ist er, also ein neues - größeres - Char erzeugen
char *c = new char[sql_char_sz+STEP];
// Daten kopieren
for(int j=0; j<sql_char_sz; j++)
c[j] = sql_char[j];
// Altes Char löschen
if(sql_char != NULL)
delete[] sql_char;
// c zuweisen
sql_char = c;
sql_char_sz += STEP;
}
// Dateneintragen
sql_char[i] = query[i];
}
// Query ausführen
if(mysql_real_query(this->my, sql_char, (unsigned) (long) strlen(sql_char)))
this->sql_error();
if(this->connected == true) {
this->sql_disconnect();
}
return true;
}
#endif
|