1 /*
2 * Copyright (C) 2002 TheUndying
3 * Copyright (C) 2002 zap-zero
4 * Copyright (C) 2002,2003,2005 Dizzy
5 * Copyright (C) 2002 Zzzoom
6 *
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License
9 * as published by the Free Software Foundation; either version 2
10 * of the License, or (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
20 */
21
22 #include "common/setup_before.h"
23 #ifdef WITH_SQL
24 #include <stdio.h>
25
26 #ifdef STDC_HEADERS
27 # include <stdlib.h>
28 #else
29 # ifdef HAVE_MALLOC_H
30 # include <malloc.h>
31 # endif
32 #endif
33
34 #ifdef HAVE_STRING_H
35 # include <string.h>
36 #else
37 # ifdef HAVE_STRINGS_H
38 # include <strings.h>
39 # endif
40 #endif
41
42 #include "compat/strdup.h"
43 #include "compat/strcasecmp.h"
44 #include "compat/strncasecmp.h"
45 #include "compat/strtoul.h"
46 #include "compat/snprintf.h"
47
48 #ifdef TIME_WITH_SYS_TIME
49 # include <sys/time.h>
50 # include <time.h>
51 #else
52 # ifdef HAVE_SYS_TIME_H
53 # include <sys/time.h>
54 # else
55 # include <time.h>
56 # endif
57 #endif
58
59 #include "common/eventlog.h"
60 #include "prefs.h"
61 #include "common/util.h"
62
63 #define CLAN_INTERNAL_ACCESS
64 #define TEAM_INTERNAL_ACCESS
65 #include "team.h"
66 #include "account.h"
67 #include "connection.h"
68 #include "clan.h"
69 #undef TEAM_INTERNAL_ACCESS
70 #undef CLAN_INTERNAL_ACCESS
71 #include "common/tag.h"
72 #include "common/xalloc.h"
73 #include "common/flags.h"
74 #include "sql_dbcreator.h"
75 #define SQL_INTERNAL
76 # include "sql_common.h"
77 #undef SQL_INTERNAL
78 #ifdef WITH_SQL_MYSQL
79 #include "sql_mysql.h"
80 #endif
81 #ifdef WITH_SQL_PGSQL
82 #include "sql_pgsql.h"
83 #endif
84 #ifdef WITH_SQL_SQLITE3
85 #include "sql_sqlite3.h"
86 #endif
87 #ifdef WITH_SQL_ODBC
88 #include "sql_odbc.h"
89 #endif
90 #include "common/elist.h"
91 #include "common/setup_after.h"
92
93 unsigned int sql_defacct;
94 t_sql_engine *sql = NULL;
95
96 #ifndef SQL_ON_DEMAND
97 char *sql_tables[] = { "BNET", "Record", "profile", "friend", "Team", NULL };
98 #endif /* SQL_ON_DEMAND */
99
100 const char* tab_prefix = SQL_DEFAULT_PREFIX;
101
102 static char query[1024];
103
sql_init(const char * dbpath)104 extern int sql_init(const char *dbpath)
105 {
106 char *tok, *path, *tmp, *p;
107 const char *dbhost = NULL;
108 const char *dbname = NULL;
109 const char *dbuser = NULL;
110 const char *dbpass = NULL;
111 const char *driver = NULL;
112 const char *dbport = NULL;
113 const char *dbsocket = NULL;
114 const char *def = NULL;
115 const char *pref = NULL;
116
117 path = xstrdup(dbpath);
118 tmp = path;
119 while ((tok = strtok(tmp, ";")) != NULL)
120 {
121 tmp = NULL;
122 if ((p = strchr(tok, '=')) == NULL)
123 {
124 eventlog(eventlog_level_error, __FUNCTION__, "invalid storage_path, no '=' present in token");
125 xfree((void *) path);
126 return -1;
127 }
128 *p = '\0';
129 if (strcasecmp(tok, "host") == 0)
130 dbhost = p + 1;
131 else if (strcasecmp(tok, "mode") == 0)
132 driver = p + 1;
133 else if (strcasecmp(tok, "name") == 0)
134 dbname = p + 1;
135 else if (strcasecmp(tok, "port") == 0)
136 dbport = p + 1;
137 else if (strcasecmp(tok, "socket") == 0)
138 dbsocket = p + 1;
139 else if (strcasecmp(tok, "user") == 0)
140 dbuser = p + 1;
141 else if (strcasecmp(tok, "pass") == 0)
142 dbpass = p + 1;
143 else if (strcasecmp(tok, "default") == 0)
144 def = p + 1;
145 else if (strcasecmp(tok, "prefix") == 0)
146 pref = p + 1;
147 else
148 eventlog(eventlog_level_warn, __FUNCTION__, "unknown token in storage_path : '%s'", tok);
149 }
150
151 if (driver == NULL)
152 {
153 eventlog(eventlog_level_error, __FUNCTION__, "no mode specified");
154 xfree((void *) path);
155 return -1;
156 }
157
158 if (def == NULL)
159 sql_defacct = STORAGE_SQL_DEFAULT_UID;
160 else
161 sql_defacct = atoi(def);
162
163 if (pref == NULL)
164 tab_prefix = SQL_DEFAULT_PREFIX;
165 else
166 tab_prefix = xstrdup(pref);
167
168 do
169 {
170 #ifdef WITH_SQL_MYSQL
171 if (strcasecmp(driver, "mysql") == 0)
172 {
173 sql = &sql_mysql;
174 if (sql->init(dbhost, dbport, dbsocket, dbname, dbuser, dbpass))
175 {
176 eventlog(eventlog_level_error, __FUNCTION__, "got error init db");
177 sql = NULL;
178 xfree((void *) path);
179 return -1;
180 }
181 break;
182 }
183 #endif /* WITH_SQL_MYSQL */
184 #ifdef WITH_SQL_PGSQL
185 if (strcasecmp(driver, "pgsql") == 0)
186 {
187 sql = &sql_pgsql;
188 if (sql->init(dbhost, dbport, dbsocket, dbname, dbuser, dbpass))
189 {
190 eventlog(eventlog_level_error, __FUNCTION__, "got error init db");
191 sql = NULL;
192 xfree((void *) path);
193 return -1;
194 }
195 break;
196 }
197 #endif /* WITH_SQL_PGSQL */
198 #ifdef WITH_SQL_SQLITE3
199 if (strcasecmp(driver, "sqlite3") == 0)
200 {
201 sql = &sql_sqlite3;
202 if (sql->init(NULL, 0, NULL, dbname, NULL, NULL))
203 {
204 eventlog(eventlog_level_error, __FUNCTION__, "got error init db");
205 sql = NULL;
206 xfree((void *) path);
207 return -1;
208 }
209 break;
210 }
211 #endif /* WITH_SQL_SQLITE3 */
212 #ifdef WITH_SQL_ODBC
213 if (strcasecmp(driver, "odbc") == 0)
214 {
215 sql = &sql_odbc;
216 if (sql->init(dbhost, dbport, dbsocket, dbname, dbuser, dbpass))
217 {
218 eventlog(eventlog_level_error, __FUNCTION__, "got error init db");
219 sql = NULL;
220 free((void *) path);
221 return -1;
222 }
223 break;
224 }
225 #endif /* WITH_SQL_ODBC */
226 eventlog(eventlog_level_error, __FUNCTION__, "no driver found for '%s'", driver);
227 xfree((void *) path);
228 return -1;
229 }
230 while (0);
231
232 xfree((void *) path);
233
234 sql_dbcreator(sql);
235
236 return 0;
237 }
238
sql_close(void)239 extern int sql_close(void)
240 {
241 if (sql == NULL)
242 {
243 eventlog(eventlog_level_error, __FUNCTION__, "sql not initilized");
244 return -1;
245 }
246
247 sql->close();
248 sql = NULL;
249 if (tab_prefix != SQL_DEFAULT_PREFIX) {
250 xfree((void*)tab_prefix);
251 tab_prefix = NULL;
252 }
253
254 return 0;
255 }
256
sql_read_maxuserid(void)257 extern unsigned sql_read_maxuserid(void)
258 {
259 t_sql_res *result;
260 t_sql_row *row;
261 long maxuid;
262
263 if (sql == NULL)
264 {
265 eventlog(eventlog_level_error, __FUNCTION__, "sql not initilized");
266 return 0;
267 }
268
269 snprintf(query, sizeof(query), "SELECT max("SQL_UID_FIELD") FROM %sBNET", tab_prefix);
270 if ((result = sql->query_res(query)) == NULL) {
271 eventlog(eventlog_level_error, __FUNCTION__, "error trying query: \"SELECT max("SQL_UID_FIELD") FROM %sBNET\"", tab_prefix);
272 return 0;
273 }
274
275 row = sql->fetch_row(result);
276 if (row == NULL || row[0] == NULL)
277 {
278 sql->free_result(result);
279 eventlog(eventlog_level_error, __FUNCTION__, "got NULL max");
280 return 0;
281 }
282
283 maxuid = atol(row[0]);
284 sql->free_result(result);
285 if (maxuid < 0)
286 {
287 eventlog(eventlog_level_error, __FUNCTION__, "got invalid maxuserid");
288 return 0;
289 }
290
291 return maxuid;
292 }
293
sql_read_accounts(int flag,t_read_accounts_func cb,void * data)294 extern int sql_read_accounts(int flag,t_read_accounts_func cb, void *data)
295 {
296 t_sql_res *result = NULL;
297 t_sql_row *row;
298 t_storage_info *info;
299
300 if (!sql)
301 {
302 eventlog(eventlog_level_error, __FUNCTION__, "sql layer not initilized");
303 return -1;
304 }
305
306 if (cb == NULL)
307 {
308 eventlog(eventlog_level_error, __FUNCTION__, "get NULL callback");
309 return -1;
310 }
311
312 /* don't actually load anything here if ST_FORCE is not set as SQL is indexed */
313 if (!FLAG_ISSET(flag,ST_FORCE)) return 1;
314
315 snprintf(query, sizeof(query), "SELECT DISTINCT("SQL_UID_FIELD") FROM %sBNET", tab_prefix);
316 if ((result = sql->query_res(query)) != NULL)
317 {
318 if (sql->num_rows(result) <= 1)
319 {
320 sql->free_result(result);
321 return 0; /* empty user list */
322 }
323
324 while ((row = sql->fetch_row(result)) != NULL)
325 {
326 if (row[0] == NULL)
327 {
328 eventlog(eventlog_level_error, __FUNCTION__, "got NULL uid from db");
329 continue;
330 }
331
332 if ((unsigned int) atoi(row[0]) == sql_defacct)
333 continue; /* skip default account */
334
335 info = xmalloc(sizeof(t_sql_info));
336 *((unsigned int *) info) = atoi(row[0]);
337 cb(info, data);
338 }
339 sql->free_result(result);
340 } else
341 {
342 eventlog(eventlog_level_error, __FUNCTION__, "error query db (query:\"%s\")", query);
343 return -1;
344 }
345
346 return 0;
347 }
348
sql_cmp_info(t_storage_info * info1,t_storage_info * info2)349 extern int sql_cmp_info(t_storage_info * info1, t_storage_info * info2)
350 {
351 return *((unsigned int *) info1) != *((unsigned int *) info2);
352 }
353
sql_free_info(t_storage_info * info)354 extern int sql_free_info(t_storage_info * info)
355 {
356 if (info)
357 xfree((void *) info);
358
359 return 0;
360 }
361
sql_get_defacct(void)362 extern t_storage_info *sql_get_defacct(void)
363 {
364 t_storage_info *info;
365
366 info = xmalloc(sizeof(t_sql_info));
367 *((unsigned int *) info) = sql_defacct;
368
369 return info;
370 }
371
sql_load_clans(t_load_clans_func cb)372 extern int sql_load_clans(t_load_clans_func cb)
373 {
374 t_sql_res *result;
375 t_sql_res *result2;
376 t_sql_row *row;
377 t_sql_row *row2;
378 t_clan *clan;
379 int member_uid;
380 t_clanmember *member;
381
382 if (!sql)
383 {
384 eventlog(eventlog_level_error, __FUNCTION__, "sql layer not initilized");
385 return -1;
386 }
387
388 if (cb == NULL)
389 {
390 eventlog(eventlog_level_error, __FUNCTION__, "get NULL callback");
391 return -1;
392 }
393
394 snprintf(query, sizeof(query), "SELECT cid, short, name, motd, creation_time FROM %sclan WHERE cid > 0", tab_prefix);
395 if ((result = sql->query_res(query)) != NULL)
396 {
397 if (sql->num_rows(result) < 1)
398 {
399 sql->free_result(result);
400 return 0; /* empty clan list */
401 }
402
403 while ((row = sql->fetch_row(result)) != NULL)
404 {
405 if (row[0] == NULL)
406 {
407 eventlog(eventlog_level_error, __FUNCTION__, "got NULL cid from db");
408 continue;
409 }
410
411 clan = xmalloc(sizeof(t_clan));
412
413 if (!(clan->clanid = atoi(row[0])))
414 {
415 eventlog(eventlog_level_error, __FUNCTION__, "got bad cid");
416 sql->free_result(result);
417 return -1;
418 }
419
420 clan->clantag = atoi(row[1]);
421
422 clan->clanname = xstrdup(row[2]);
423 clan->clan_motd = xstrdup(row[3]);
424 clan->creation_time = atoi(row[4]);
425 clan->created = 1;
426 clan->modified = 0;
427 clan->channel_type = prefs_get_clan_channel_default_private();
428 clan->members = list_create();
429
430 snprintf(query, sizeof(query), "SELECT "SQL_UID_FIELD", status, join_time FROM %sclanmember WHERE cid='%u'", tab_prefix, clan->clanid);
431
432 if ((result2 = sql->query_res(query)) != NULL)
433 {
434 if (sql->num_rows(result2) >= 1)
435 while ((row2 = sql->fetch_row(result2)) != NULL)
436 {
437 member = xmalloc(sizeof(t_clanmember));
438 if (row2[0] == NULL)
439 {
440 eventlog(eventlog_level_error, __FUNCTION__, "got NULL uid from db");
441 continue;
442 }
443 if (!(member_uid = atoi(row2[0])))
444 continue;
445 if (!(member->memberacc = accountlist_find_account_by_uid(member_uid)))
446 {
447 eventlog(eventlog_level_error, __FUNCTION__, "cannot find uid %u", member_uid);
448 xfree((void *) member);
449 continue;
450 }
451 member->status = atoi(row2[1]);
452 member->join_time = atoi(row2[2]);
453 member->clan = clan;
454
455 if ((member->status == CLAN_NEW) && (time(NULL) - member->join_time > prefs_get_clan_newer_time() * 3600))
456 {
457 member->status = CLAN_PEON;
458 clan->modified = 1;
459 member->modified = 1;
460 }
461
462 list_append_data(clan->members, member);
463
464 account_set_clanmember(member->memberacc, member);
465 eventlog(eventlog_level_trace, __FUNCTION__, "added member: uid: %i status: %c join_time: %u", member_uid, member->status + '0', (unsigned) member->join_time);
466 }
467 sql->free_result(result2);
468 cb(clan);
469 } else
470 eventlog(eventlog_level_error, __FUNCTION__, "error query db (query:\"%s\")", query);
471 }
472
473 sql->free_result(result);
474 } else
475 {
476 eventlog(eventlog_level_error, __FUNCTION__, "error query db (query:\"%s\")", query);
477 return -1;
478 }
479 return 0;
480 }
481
sql_write_clan(void * data)482 extern int sql_write_clan(void *data)
483 {
484 char esc_motd[CLAN_MOTD_MAX * 2 + 1];
485 t_sql_res *result;
486 t_sql_row *row;
487 t_elem *curr;
488 t_clanmember *member;
489 t_clan *clan = (t_clan *) data;
490 int num;
491
492 if (!sql)
493 {
494 eventlog(eventlog_level_error, __FUNCTION__, "sql layer not initilized");
495 return -1;
496 }
497
498 snprintf(query, sizeof(query), "SELECT count(*) FROM %sclan WHERE cid='%u'", tab_prefix, clan->clanid);
499 if ((result = sql->query_res(query)) != NULL)
500 {
501 row = sql->fetch_row(result);
502 if (row == NULL || row[0] == NULL)
503 {
504 sql->free_result(result);
505 eventlog(eventlog_level_error, __FUNCTION__, "got NULL count");
506 return -1;
507 }
508 num = atol(row[0]);
509 sql->free_result(result);
510 sql->escape_string(esc_motd, clan->clan_motd, strlen(clan->clan_motd));
511 if (num < 1)
512 snprintf(query, sizeof(query), "INSERT INTO %sclan (cid, short, name, motd, creation_time) VALUES('%u', '%d', '%s', '%s', '%u')", tab_prefix, clan->clanid, clan->clantag, clan->clanname, esc_motd, (unsigned) clan->creation_time);
513 else
514 snprintf(query, sizeof(query), "UPDATE %sclan SET short='%d', name='%s', motd='%s', creation_time='%u' WHERE cid='%u'", tab_prefix, clan->clantag, clan->clanname, esc_motd, (unsigned) clan->creation_time, clan->clanid);
515 if (sql->query(query) < 0)
516 {
517 eventlog(eventlog_level_error, __FUNCTION__, "error trying query: \"%s\"", query);
518 return -1;
519 }
520 LIST_TRAVERSE(clan->members, curr)
521 {
522 unsigned int uid;
523
524 if (!(member = elem_get_data(curr)))
525 {
526 eventlog(eventlog_level_error, __FUNCTION__, "got NULL elem in list");
527 continue;
528 }
529 if ((member->status == CLAN_NEW) && (time(NULL) - member->join_time > prefs_get_clan_newer_time() * 3600))
530 {
531 member->status = CLAN_PEON;
532 member->modified = 1;
533 }
534 if (member->modified)
535 {
536 uid = account_get_uid(member->memberacc);
537 snprintf(query, sizeof(query), "SELECT count(*) FROM %sclanmember WHERE "SQL_UID_FIELD"='%u'", tab_prefix, uid);
538 if ((result = sql->query_res(query)) != NULL)
539 {
540 row = sql->fetch_row(result);
541 if (row == NULL || row[0] == NULL)
542 {
543 sql->free_result(result);
544 eventlog(eventlog_level_error, __FUNCTION__, "got NULL count");
545 return -1;
546 }
547 num = atol(row[0]);
548 sql->free_result(result);
549 if (num < 1)
550 snprintf(query, sizeof(query), "INSERT INTO %sclanmember (cid, "SQL_UID_FIELD", status, join_time) VALUES('%u', '%u', '%d', '%u')", tab_prefix, clan->clanid, uid, member->status, (unsigned) member->join_time);
551 else
552 snprintf(query, sizeof(query), "UPDATE %sclanmember SET cid='%u', status='%d', join_time='%u' WHERE "SQL_UID_FIELD"='%u'", tab_prefix, clan->clanid, member->status, (unsigned) member->join_time, uid);
553 if (sql->query(query) < 0)
554 {
555 eventlog(eventlog_level_error, __FUNCTION__, "error trying query: \"%s\"", query);
556 return -1;
557 }
558 } else
559 {
560 eventlog(eventlog_level_error, __FUNCTION__, "error trying query: \"%s\"", query);
561 return -1;
562 }
563 member->modified = 0;
564 }
565 }
566 } else
567 {
568 eventlog(eventlog_level_error, __FUNCTION__, "error trying query: \"%s\"", query);
569 return -1;
570 }
571
572 return 0;
573 }
574
sql_remove_clan(int clantag)575 extern int sql_remove_clan(int clantag)
576 {
577 t_sql_res *result;
578 t_sql_row *row;
579
580 if (!sql)
581 {
582 eventlog(eventlog_level_error, __FUNCTION__, "sql layer not initilized");
583 return -1;
584 }
585
586 snprintf(query, sizeof(query), "SELECT cid FROM %sclan WHERE short = '%d'", tab_prefix, clantag);
587 if (!(result = sql->query_res(query)))
588 {
589 eventlog(eventlog_level_error, __FUNCTION__, "error query db (query:\"%s\")", query);
590 return -1;
591 }
592
593 if (sql->num_rows(result) != 1)
594 {
595 sql->free_result(result);
596 return -1; /*clan not found or found more than 1 */
597 }
598
599 if ((row = sql->fetch_row(result)))
600 {
601 unsigned int cid = atoi(row[0]);
602 snprintf(query, sizeof(query), "DELETE FROM %sclanmember WHERE cid='%u'", tab_prefix, cid);
603 if (sql->query(query) != 0)
604 return -1;
605 snprintf(query, sizeof(query), "DELETE FROM %sclan WHERE cid='%u'", tab_prefix, cid);
606 if (sql->query(query) != 0)
607 return -1;
608 }
609
610 sql->free_result(result);
611
612 return 0;
613 }
614
sql_remove_clanmember(int uid)615 extern int sql_remove_clanmember(int uid)
616 {
617 if (!sql)
618 {
619 eventlog(eventlog_level_error, __FUNCTION__, "sql layer not initilized");
620 return -1;
621 }
622
623 snprintf(query, sizeof(query), "DELETE FROM %sclanmember WHERE "SQL_UID_FIELD"='%u'", tab_prefix, uid);
624 if (sql->query(query) != 0)
625 {
626 eventlog(eventlog_level_error, __FUNCTION__, "error trying query: \"%s\"", query);
627 return -1;
628 }
629
630 return 0;
631 }
632
sql_load_teams(t_load_teams_func cb)633 extern int sql_load_teams(t_load_teams_func cb)
634 {
635 t_sql_res *result;
636 t_sql_row *row;
637 t_team *team;
638 int i;
639
640 if (!sql)
641 {
642 eventlog(eventlog_level_error, __FUNCTION__, "sql layer not initilized");
643 return -1;
644 }
645
646 if (cb == NULL)
647 {
648 eventlog(eventlog_level_error, __FUNCTION__, "get NULL callback");
649 return -1;
650 }
651
652 snprintf(query, sizeof(query), "SELECT teamid, size, clienttag, lastgame, member1, member2, member3, member4, wins,losses, xp, level, rank FROM %sarrangedteam WHERE teamid > 0", tab_prefix);
653 if ((result = sql->query_res(query)) != NULL)
654 {
655 if (sql->num_rows(result) < 1)
656 {
657 sql->free_result(result);
658 return 0; /* empty team list */
659 }
660
661 while ((row = sql->fetch_row(result)) != NULL)
662 {
663 if (row[0] == NULL)
664 {
665 eventlog(eventlog_level_error, __FUNCTION__, "got NULL teamid from db");
666 continue;
667 }
668
669 team = xmalloc(sizeof(t_team));
670
671 if (!(team->teamid = atoi(row[0])))
672 {
673 eventlog(eventlog_level_error, __FUNCTION__, "got bad teamid");
674 sql->free_result(result);
675 return -1;
676 }
677
678 team->size = atoi(row[1]);
679 team->clienttag=tag_str_to_uint(row[2]);
680 team->lastgame = strtoul(row[3],NULL,10);
681 team->teammembers[0] = strtoul(row[4],NULL,10);
682 team->teammembers[1] = strtoul(row[5],NULL,10);
683 team->teammembers[2] = strtoul(row[6],NULL,10);
684 team->teammembers[3] = strtoul(row[7],NULL,10);
685
686 for (i=0; i<MAX_TEAMSIZE;i++)
687 {
688 if (i<team->size)
689 {
690 if ((team->teammembers[i]==0))
691 {
692 eventlog(eventlog_level_error,__FUNCTION__,"invalid team data: too few members");
693 free((void *)team);
694 goto load_team_failure;
695 }
696 }
697 else
698 {
699 if ((team->teammembers[i]!=0))
700 {
701 eventlog(eventlog_level_error,__FUNCTION__,"invalid team data: too many members");
702 free((void *)team);
703 goto load_team_failure;
704 }
705
706 }
707 team->members[i] = NULL;
708 }
709
710 team->wins = atoi(row[8]);
711 team->losses = atoi(row[9]);
712 team->xp = atoi(row[10]);
713 team->level = atoi(row[11]);
714 team->rank = atoi(row[12]);
715
716 eventlog(eventlog_level_trace,__FUNCTION__,"succesfully loaded team %u",team->teamid);
717 cb(team);
718 load_team_failure:
719 ;
720 }
721
722 sql->free_result(result);
723 } else
724 {
725 eventlog(eventlog_level_error, __FUNCTION__, "error query db (query:\"%s\")", query);
726 return -1;
727 }
728 return 0;
729 }
730
sql_write_team(void * data)731 extern int sql_write_team(void *data)
732 {
733 t_sql_res *result;
734 t_sql_row *row;
735 t_team *team = (t_team *) data;
736 int num;
737
738 if (!sql)
739 {
740 eventlog(eventlog_level_error, __FUNCTION__, "sql layer not initilized");
741 return -1;
742 }
743
744 snprintf(query, sizeof(query), "SELECT count(*) FROM %sarrangedteam WHERE teamid='%u'", tab_prefix, team->teamid);
745 if ((result = sql->query_res(query)) != NULL)
746 {
747 row = sql->fetch_row(result);
748 if (row == NULL || row[0] == NULL)
749 {
750 sql->free_result(result);
751 eventlog(eventlog_level_error, __FUNCTION__, "got NULL count");
752 return -1;
753 }
754 num = atol(row[0]);
755 sql->free_result(result);
756 if (num < 1)
757 snprintf(query, sizeof(query), "INSERT INTO %sarrangedteam (teamid, size, clienttag, lastgame, member1, member2, member3, member4, wins,losses, xp, level, rank) VALUES('%u', '%c', '%s', '%u', '%u', '%u', '%u', '%u', '%d', '%d', '%d', '%d', '%d')", tab_prefix, team->teamid, team->size + '0', clienttag_uint_to_str(team->clienttag),(unsigned int)team->lastgame, team->teammembers[0], team->teammembers[1], team->teammembers[2], team->teammembers[3], team->wins, team->losses, team->xp, team->level, team->rank);
758 else
759 snprintf(query, sizeof(query), "UPDATE %sarrangedteam SET size='%c', clienttag='%s', lastgame='%u', member1='%u', member2='%u', member3='%u', member4='%u', wins='%d', losses='%d', xp='%d', level='%d', rank='%d' WHERE teamid='%u'", tab_prefix, team->size + '0', clienttag_uint_to_str(team->clienttag),(unsigned int)team->lastgame, team->teammembers[0], team->teammembers[1], team->teammembers[2], team->teammembers[3], team->wins, team->losses, team->xp, team->level, team->rank, team->teamid);
760 if (sql->query(query) < 0)
761 {
762 eventlog(eventlog_level_error, __FUNCTION__, "error trying query: \"%s\"", query);
763 return -1;
764 }
765 } else
766 {
767 eventlog(eventlog_level_error, __FUNCTION__, "error trying query: \"%s\"", query);
768 return -1;
769 }
770
771 return 0;
772 }
773
sql_remove_team(unsigned int teamid)774 extern int sql_remove_team(unsigned int teamid)
775 {
776 if (!sql)
777 {
778 eventlog(eventlog_level_error, __FUNCTION__, "sql layer not initilized");
779 return -1;
780 }
781
782 snprintf(query, sizeof(query), "DELETE FROM %sarrangedteam WHERE teamid='%u'", tab_prefix, teamid);
783 if (sql->query(query) != 0)
784 return -1;
785
786 return 0;
787 }
788
789 #endif /* WITH_SQL */
790