]>
jfr.im git - irc/thales.git/blob - src/db.c
1 /* Thales - IRC to Relational Database Gateway
2 * Copyright (C) 2002 Lucas Nussbaum <lucas@lucas-nussbaum.net>
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 /* Thales' database interface */
23 #ifdef HASHLISTSUPPORT
27 extern char *MysqlServer
;
28 extern char *MysqlDatabase
;
29 extern char *MysqlUser
;
30 extern char *MysqlPassword
;
32 extern unsigned int nbusers_max
;
33 extern unsigned int nbusers
;
34 extern unsigned int nbchans_max
;
35 extern unsigned int nbchans
;
41 #ifdef HASHLISTSUPPORT
47 /* last time we cleaned the server table */
48 static int ServerLastClean
= -1;
49 extern int ServerCleanFreq
;
50 extern int ServerCacheTime
;
52 /* last time we cleaned the user table */
53 static int UserLastClean
= -1;
54 extern int UserCleanFreq
;
55 extern int UserCacheTime
;
63 /* connecting to MySQL */
64 myptr
= mysql_init(NULL
);
65 if (!mysql_real_connect
66 (myptr
, MysqlServer
, MysqlUser
, MysqlPassword
, MysqlDatabase
, 0,
68 fatal("Failed to connect to database : %s\n", mysql_error(myptr
));
70 /* Cleaning up the database */
71 db_query("DELETE FROM " TBL_CHAN
);
72 db_query("DELETE FROM " TBL_ISON
);
73 db_query("DELETE FROM " TBL_SERV
);
74 db_query("DELETE FROM " TBL_USER
);
76 db_query("SELECT val FROM " TBL_MAXV
" WHERE type=\'users\'");
77 resptr
= mysql_store_result(myptr
);
78 if (mysql_num_rows(resptr
))
79 nbusers_max
= atoi(*mysql_fetch_row(resptr
));
81 db_query("INSERT INTO " TBL_MAXV
" VALUES ('users', '0', NOW())");
82 mysql_free_result(resptr
);
84 db_query("SELECT val FROM " TBL_MAXV
" WHERE type=\'channels\'");
85 resptr
= mysql_store_result(myptr
);
86 if (mysql_num_rows(resptr
))
87 nbchans_max
= atoi(*mysql_fetch_row(resptr
));
89 db_query("INSERT INTO " TBL_MAXV
" VALUES ('channels', '0', NOW())");
90 mysql_free_result(resptr
);
92 #ifdef HASHLISTSUPPORT
93 /* init the hash lists */
94 hashnicks
= newhashlist();
95 hashchans
= newhashlist();
96 hashservs
= newhashlist();
100 /* escape the string */
101 char *db_escape(char *ch
)
107 size
= (strlen(ch
)) * 2 + 1;
108 buf
= (char *) malloc(sizeof(char) * size
);
110 mysql_real_escape_string(myptr
, buf
, ch
, strlen(ch
));
117 /* send an SQL query to the database */
118 int db_query(const char *fmt
, ...)
121 char buf
[2048]; /* should be enough for long queries (don't underestimate :o)) */
123 vsprintf(buf
, fmt
, args
);
125 log(">SQL : %s", buf
);
126 if (mysql_real_query(myptr
, buf
, strlen(buf
)))
127 fatal("Query failed: %s", mysql_error(myptr
));
131 /* serv should be db_escape'd before call */
132 /* -1 if server not found, servid else */
133 int db_checkserver(char *serv
)
137 db_query("SELECT servid FROM " TBL_SERV
" WHERE server=\"%s\"", serv
);
138 resptr
= mysql_store_result(myptr
);
139 if (mysql_num_rows(resptr
))
140 servid
= atoi(*mysql_fetch_row(resptr
));
141 mysql_free_result(resptr
);
145 /* serv should be db_escape'd before call */
146 int db_getserver(char *serv
)
148 #ifdef HASHLISTSUPPORT
150 return hash_find(hashservs
, serv
, KEYOTHER
);
155 db_query("SELECT servid FROM " TBL_SERV
" WHERE server=\'%s\'", serv
);
156 resptr
= mysql_store_result(myptr
);
157 if (mysql_num_rows(resptr
))
158 res
= atoi(*mysql_fetch_row(resptr
));
159 mysql_free_result(resptr
);
164 /* changes a nick in the hashlist */
165 void db_chgnick(char *newnick
, char *oldnick
)
167 #ifdef HASHLISTSUPPORT
168 /* people often change from NICK-sthing to NICK-sthing */
171 hash_update(hashnicks
, newnick
, oldnick
, KEYOTHER
);
175 /* remove a server from the hashlist */
176 void db_delserver(char *server
)
178 #ifdef HASHLISTSUPPORT
180 hash_del(hashservs
, server
, KEYOTHER
);
184 /* add a server to the hashlist */
185 void db_addserver(char *server
, int servid
)
187 #ifdef HASHLISTSUPPORT
189 hash_add(hashservs
, server
, servid
, KEYOTHER
);
193 /* add a nick to the hashlist */
194 void db_addnick(char *nick
, int nickid
)
196 #ifdef HASHLISTSUPPORT
198 hash_add(hashnicks
, nick
, nickid
, KEYOTHER
);
202 /* add a nick to the hashlist */
203 void db_delnick(char *nick
)
205 #ifdef HASHLISTSUPPORT
207 hash_del(hashnicks
, nick
, KEYOTHER
);
211 /* nick should be db_escape'd before call */
212 /* -1 if nick not found, nickid else */
213 int db_checknick(char *nick
)
215 #ifdef HASHLISTSUPPORT
217 char *nicklow
= strdup(nick
);
219 res
= hash_find_unsure(hashnicks
, nicklow
, KEYOTHER
);
225 db_query("SELECT nickid FROM " TBL_USER
" WHERE nick=\"%s\"", nick
);
226 resptr
= mysql_store_result(myptr
);
227 if (mysql_num_rows(resptr
))
228 nickid
= atoi(*mysql_fetch_row(resptr
));
229 mysql_free_result(resptr
);
234 /* nick should be db_escape'd before call */
235 int db_getnick(char *nick
)
237 #ifdef HASHLISTSUPPORT
239 char *nicklow
= strdup(nick
);
241 res
= hash_find(hashnicks
, nicklow
, KEYOTHER
);
248 db_query("SELECT nickid FROM " TBL_USER
" WHERE nick=\'%s\'", nick
);
249 resptr
= mysql_store_result(myptr
);
250 if (mysql_num_rows(resptr
))
251 res
= atoi(*mysql_fetch_row(resptr
));
253 fatal("nickname not found !");
254 mysql_free_result(resptr
);
259 int db_getservfromnick(char *nick
)
263 db_query("SELECT servid FROM " TBL_USER
" WHERE nick=\'%s\'", nick
);
264 resptr
= mysql_store_result(myptr
);
265 if (mysql_num_rows(resptr
))
266 res
= atoi(*mysql_fetch_row(resptr
));
268 fatal("nickname not found !");
269 mysql_free_result(resptr
);
275 return mysql_insert_id(myptr
);
278 void db_removenick(char *nick
)
280 int nickid
= db_getnick(nick
);
284 db_removefromchans(nickid
);
286 db_query("UPDATE " TBL_USER
287 " SET online=\"N\", lastquit=NOW(), servid=NULL WHERE nickid=\"%d\"",
290 db_query("DELETE FROM " TBL_USER
" WHERE nickid=\'%d\'", nickid
);
294 void db_removefromchans(int nickid
)
298 db_query("SELECT " TBL_ISON
".chanid, channel FROM " TBL_ISON
", "
299 TBL_CHAN
" WHERE nickid=\'%d\' AND " TBL_CHAN
".chanid = "
300 TBL_ISON
".chanid", nickid
);
301 resptr
= mysql_store_result(myptr
);
302 db_query("DELETE FROM " TBL_ISON
" WHERE nickid=\'%d\'", nickid
);
303 while ((res
= mysql_fetch_row(resptr
)))
305 char *chan
= db_escape(res
[1]);
306 db_checkemptychan(atoi(res
[0]), chan
);
309 mysql_free_result(resptr
);
312 void db_checkemptychan(int chanid
, char *chan
)
315 db_query("SELECT chanid FROM " TBL_ISON
" WHERE chanid=\'%d\'", chanid
);
316 resptr2
= mysql_store_result(myptr
);
317 if (!mysql_num_rows(resptr2
))
319 db_query("DELETE FROM " TBL_CHAN
" WHERE chanid=\'%d\'", chanid
);
320 #ifdef HASHLISTSUPPORT
321 hash_del(hashchans
, chan
, KEYCHAN
);
325 mysql_free_result(resptr2
);
328 int db_getlusers(int type
)
335 db_query("SELECT COUNT(*) FROM " TBL_USER
" WHERE mode_li=\'N\'");
337 case LUSERS_USERSINV
:
338 db_query("SELECT COUNT(*) FROM " TBL_USER
" WHERE mode_li=\'Y\'");
341 db_query("SELECT COUNT(*) FROM " TBL_USER
" WHERE mode_lo=\'Y\'");
344 db_query("SELECT COUNT(*) FROM " TBL_CHAN
);
347 db_query("SELECT COUNT(*) FROM " TBL_SERV
);
349 case LUSERS_USERSGLOB
:
350 db_query("SELECT COUNT(*) FROM " TBL_USER
);
352 case LUSERS_USERSMAX
:
353 db_query("SELECT val FROM " TBL_MAXV
" WHERE type='users'");
356 resptr
= mysql_store_result(myptr
);
357 if (mysql_num_rows(resptr
))
358 retcode
= atoi(*mysql_fetch_row(resptr
));
361 mysql_free_result(resptr
);
365 /* chan should be db_escape'd before call */
366 int db_getchannel(char *chan
)
368 #ifdef HASHLISTSUPPORT
370 return hash_find(hashchans
, chan
, KEYCHAN
);
376 db_query("SELECT chanid FROM " TBL_CHAN
" WHERE channel=\'%s\'", chan
);
377 resptr
= mysql_store_result(myptr
);
378 if (mysql_num_rows(resptr
))
379 res
= atoi(*mysql_fetch_row(resptr
));
381 fatal("channel not found !");
382 mysql_free_result(resptr
);
387 /* chan should be db_escape'd before call */
388 /* chan is created if not exists */
389 int db_getchancreate(char *chan
)
393 #ifdef HASHLISTSUPPORT
395 res
= hash_find_unsure(hashchans
, chan
, KEYCHAN
);
399 db_query("SELECT chanid FROM " TBL_CHAN
" WHERE channel=\'%s\'", chan
);
400 resptr
= mysql_store_result(myptr
);
401 if (mysql_num_rows(resptr
))
402 res
= atoi(*mysql_fetch_row(resptr
));
403 mysql_free_result(resptr
);
408 db_query("INSERT INTO " TBL_CHAN
" (channel) VALUES (\'%s\')", chan
);
410 #ifdef HASHLISTSUPPORT
411 hash_add(hashchans
, chan
, res
, KEYCHAN
);
414 do_checknbchansmax();
419 /* close connection to DBMS */
427 /* cleanup the server table, removing old entries */
428 void db_cleanserver()
431 int curtime
= time(NULL
);
433 if (ServerLastClean
== -1)
434 ServerLastClean
= curtime
;
435 if (curtime
> (ServerLastClean
+ ServerCleanFreq
))
437 ServerLastClean
= curtime
;
438 db_query("SELECT server FROM " TBL_SERV
439 " WHERE online=\"N\" AND lastsplit<FROM_UNIXTIME(\"%d\")",
440 curtime
- ServerCacheTime
);
441 resptr
= mysql_store_result(myptr
);
442 if (mysql_num_rows(resptr
))
444 while ((res
= mysql_fetch_row(resptr
)))
446 char *server
= db_escape(res
[0]);
447 db_delserver(server
);
450 mysql_free_result(resptr
);
451 db_query("DELETE FROM " TBL_SERV
452 " WHERE online=\"N\" AND lastsplit<FROM_UNIXTIME(\"%d\")",
453 curtime
- ServerCacheTime
);
458 /* cleanup the user table, removing old entries */
462 int curtime
= time(NULL
);
464 if (UserLastClean
== -1)
465 UserLastClean
= curtime
;
466 if (curtime
> (UserLastClean
+ UserCleanFreq
))
468 UserLastClean
= curtime
;
469 db_query("SELECT nick FROM " TBL_USER
470 " WHERE online=\"N\" AND lastquit<FROM_UNIXTIME(\"%d\")",
471 curtime
- UserCacheTime
);
473 resptr
= mysql_store_result(myptr
);
474 if (mysql_num_rows(resptr
))
476 while ((res
= mysql_fetch_row(resptr
)))
478 char *nick
= db_escape(res
[0]);
482 mysql_free_result(resptr
);
483 db_query("DELETE FROM " TBL_USER
484 " WHERE online=\"N\" AND lastquit<FROM_UNIXTIME(\"%d\")",
485 curtime
- UserCacheTime
);