18c60b2a2354d0b6621b8cc76bda6608371dd861
[brisk.git] / web / Obj / dbase_pgsql.phh
1 <?php
2   /*
3    *  brisk - dbase_pgsql.phh
4    *
5    *  Copyright (C) 2006-2012 Matteo Nastasi
6    *                          mailto: nastasi@alternativeoutput.it
7    *                                  matteo.nastasi@milug.org
8    *                          web: http://www.alternativeoutput.it
9    *
10    * This program is free software; you can redistribute it and/or modify
11    * it under the terms of the GNU General Public License as published by
12    * the Free Software Foundation; either version 2 of the License, or
13    * (at your option) any later version.
14    *
15    * This program is distributed in the hope that it will be useful, but
16    * WITHOUT ANY WARRANTY; without even the implied warranty of
17    * MERCHANTABLILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18    * General Public License for more details. You should have received a
19    * copy of the GNU General Public License along with this program; if
20    * not, write to the Free Software Foundation, Inc, 59 Temple Place -
21    * Suite 330, Boston, MA 02111-1307, USA.
22    *
23    */
24
25 require_once("${G_base}Obj/dbase_base.phh");
26
27 $escsql_from = array( "\\",   "'"   );
28 $escsql_to   = array( "\\\\", "\\'" );
29
30 function escsql($s)
31 {
32     GLOBAL $escsql_from, $escsql_to;
33
34     return str_replace($escsql_from, $escsql_to, $s);
35 }
36
37 class DBConn
38 {
39     static $dbcnnx = FALSE;
40     var $db = FALSE;
41
42     function DBConn()
43     {
44         $this->db = DBConn::$dbcnnx;
45     }
46
47     static function create()
48     {
49         GLOBAL $G_dbauth;
50
51         if (DBConn::$dbcnnx == FALSE) {
52             if (!(DBConn::$dbcnnx = @pg_connect ($G_dbauth, PGSQL_CONNECT_FORCE_NEW))) {
53                 return (FALSE);
54             }
55         }
56
57         $out = new DBConn();
58
59         return $out;
60     }
61
62     static function destroy()
63     {
64         if (DBConn::$dbcnnx != FALSE) {
65             DBConn::$dbcnnx = FALSE;
66             return (pg_close(DBConn::$dbcnnx));
67         }
68         return TRUE;
69     }
70
71     static function recover()
72     {
73         self::destroy();
74         return (self::create());
75     }
76
77     function db()
78     {
79         return ($this->db);
80     }
81 }
82
83 class BriskDB
84 {
85     var $dbconn;
86     var $item;
87     var $item_n;
88
89     function BriskDB($dbconn)
90     {
91         $this->dbconn = $dbconn;
92     }
93
94     static function create()
95     {
96         GLOBAL $DOCUMENT_ROOT, $G_dbpfx;
97
98         $ret = FALSE;
99
100         log_main("BriskDB create:start");
101
102         do {
103             if (($dbconn = DBConn::create()) == FALSE) {
104                 break;
105             }
106
107             $ret = new BriskDB($dbconn);
108         } while (0);
109
110         return ($ret);
111     }
112
113     function query($sql)
114     {
115         if (($res = pg_query($this->dbconn->db(), $sql)) == FALSE) {
116             // try to recover the connection
117             if (($this->dbconn = DBConn::recover()) == FALSE)
118                 return FALSE;
119             return (pg_query($this->dbconn->db(), $sql));
120         }
121
122         return ($res);
123     }
124
125     function users_load()
126     {
127     }
128
129     function login_exists($login)
130     {
131         GLOBAL $G_dbpfx;
132
133         /* check the existence of the nick in the BriskDB */
134         log_main("login_exists: ".$login);
135
136         $user_sql = sprintf("SELECT * FROM %susers WHERE login = lower('%s') AND (type & CAST (X'%08x' as integer)) = 0;",
137                             $G_dbpfx, escsql($login), USER_FLAG_TY_DISABLE);
138         if (($user_pg = $this->query($user_sql)) != FALSE)
139             if (pg_numrows($user_pg) == 1)
140                 return TRUE;
141
142         return FALSE;
143     }
144
145     function getrecord_bylogin($login) {
146         GLOBAL $G_dbpfx;
147
148         $user_sql = sprintf("SELECT * FROM %susers WHERE login = lower('%s') AND (type & CAST (X'%08x' as integer)) = 0;",  $G_dbpfx, escsql($login), USER_FLAG_TY_DISABLE);
149         if (($user_pg  = $this->query($user_sql)) == FALSE) {
150             return FALSE;
151         }
152         if (pg_numrows($user_pg) != 1)
153             return FALSE;
154
155         $user_obj = pg_fetch_object($user_pg, 0);
156
157         return ($user_obj);
158     }
159
160     function user_add($login, $pass, $email, $type, $disa_reas, $guar_code) {
161         GLOBAL $G_dbpfx;
162
163         $usr_sql = sprintf("INSERT INTO %susers (login, pass, email, type, disa_reas, guar_code, lintm)
164                             VALUES ('%s', '%s', '%s', %d, %d, %d, now()) RETURNING *;",
165                            $G_dbpfx, escsql(strtolower($login)), escsql($pass), escsql($email),
166                            $type, $disa_reas, $guar_code);
167
168         if (! (($usr_pg  = $this->query($usr_sql)) != FALSE && pg_affected_rows($usr_pg) == 1) ) {
169             return FALSE;
170         }
171         $usr_obj = pg_fetch_object($usr_pg, 0);
172
173         return $usr_obj;
174     }
175
176     function transaction($cmd) {
177         if ($cmd != "BEGIN" && $cmd != "COMMIT" && $cmd != "ROLLBACK")
178             return FALSE;
179
180         $trans_sql = sprintf("%s;", $cmd);
181         if (($trans_pg  = $this->query($trans_sql)) == FALSE) {
182             return FALSE;
183         }
184
185         return (TRUE);
186     }
187
188     /*
189       to be able to add mail record code into the record itself I must reserve it before.
190      */
191     function mail_reserve_code() {
192         GLOBAL $G_dbpfx;
193
194         $mail_sql = sprintf("SELECT nextval('%smails_code_seq'::regclass) AS nextval;", $G_dbpfx);
195         if (($mail_pg  = $this->query($mail_sql)) == FALSE) {
196             return FALSE;
197         }
198         if (pg_numrows($mail_pg) != 1)
199             return FALSE;
200
201         $mail_obj = pg_fetch_object($mail_pg, 0);
202
203         return ($mail_obj->nextval);
204     }
205
206     function check_record_by_login_or_email($login, $email) {
207         GLOBAL $G_dbpfx;
208
209         $arr_fie = array('login', 'email');
210         $arr_val = array($login, $email);
211
212         for ($i = 0 ; $i < 2 ; $i++) {
213             $user_sql = sprintf("SELECT * FROM %susers WHERE %s = lower('%s');",
214                                 $G_dbpfx, $arr_fie[$i], escsql($arr_val[$i]));
215             if (($user_pg  = $this->query($user_sql)) == FALSE) {
216                 fprintf(STDERR, "QUERY [%s]_ FALSE", $user_sql);
217                 return (3);
218             }
219             if (pg_numrows($user_pg) == 1) {
220                 return ($i + 1);
221             }
222         }
223
224         return (0);
225     }
226
227     function getrecord_bycode($code) {
228         GLOBAL $G_dbpfx;
229
230         $user_sql = sprintf("SELECT * FROM %susers WHERE code = %d;",  $G_dbpfx, $code);
231         if (($user_pg  = $this->query($user_sql)) == FALSE) {
232             return FALSE;
233         }
234         if (pg_numrows($user_pg) != 1)
235             return FALSE;
236
237         $user_obj = pg_fetch_object($user_pg, 0);
238
239         return ($user_obj);
240     }
241
242     function user_update_login_time($code, $lintm)
243     {
244         GLOBAL $G_dbpfx;
245
246         $user_sql = sprintf("UPDATE %susers SET (lintm) = (date 'epoch' + %d * INTERVAL '1 second') WHERE code = %d;", $G_dbpfx, $lintm, $code);
247
248         if ( ! (($user_pg  = $this->query($user_sql)) != FALSE && pg_affected_rows($user_pg) == 1) ) {
249              return FALSE;
250         }
251
252         return TRUE;
253     }
254
255     function user_update_flag_ty($code, $old_type, $old_reas, $type, $reas)
256     {
257         GLOBAL $G_dbpfx;
258
259         // (u.type & (CAST (X'00ff0000' as integer)))
260
261         $user_sql = sprintf("UPDATE %susers SET (type, disa_reas) = ((%d & (CAST (X'00ff0000' as integer))), %d)
262 WHERE code = %d AND (type & CAST (X'%08x' as integer)) != 0 AND disa_reas = %d;",
263                             $G_dbpfx, $type, $reas, $code, $old_type, $old_reas);
264
265         if ( ! (($user_pg  = $this->query($user_sql)) != FALSE && pg_affected_rows($user_pg) == 1) ) {
266              return FALSE;
267         }
268
269         return TRUE;
270     }
271
272     function user_update_passwd($code, $passwd)
273     {
274         GLOBAL $G_dbpfx;
275
276         $user_sql = sprintf("UPDATE %susers SET (pass) = (md5('%s')) WHERE code = %d;",
277                             $G_dbpfx, $passwd, $code);
278
279         if ( ! (($user_pg  = $this->query($user_sql)) != FALSE && pg_affected_rows($user_pg) == 1) ) {
280              return FALSE;
281         }
282
283         return TRUE;
284     }
285
286     function user_prefs_update($code, $flags, $supp_comp)
287     {
288         GLOBAL $G_dbpfx;
289
290         $user_sql = sprintf("UPDATE %susers SET (type, supp_comp) = (%d, '%s') WHERE code = %d;",
291                             $G_dbpfx, $flags, escsql($supp_comp), $code);
292         fprintf(STDERR, "REQUEST [%s]\n", $user_sql);
293         if ( ! (($user_pg  = $this->query($user_sql)) != FALSE && pg_affected_rows($user_pg) == 1) ) {
294              return FALSE;
295         }
296         fprintf(STDERR, "REQUEST GOOD [%s]\n", $user_sql);
297
298         return TRUE;
299     }
300
301     function user_state_update($code, $flags, $disa_reas)
302     {
303         GLOBAL $G_dbpfx;
304
305         $user_sql = sprintf("UPDATE %susers SET (type, disa_reas) = (%d, %d) WHERE code = %d;",
306                             $G_dbpfx, $flags, $disa_reas, $code);
307         fprintf(STDERR, "REQUEST [%s]\n", $user_sql);
308         if ( ! (($user_pg  = $this->query($user_sql)) != FALSE && pg_affected_rows($user_pg) == 1) ) {
309              return FALSE;
310         }
311         fprintf(STDERR, "REQUEST GOOD [%s]\n", $user_sql);
312
313         return TRUE;
314     }
315
316     function user_tos_update($code, $tos_vers)
317     {
318         GLOBAL $G_dbpfx;
319
320         $user_sql = sprintf("UPDATE %susers SET (tos_vers) = ('%s') WHERE code = %d;",
321                             $G_dbpfx, escsql($tos_vers), $code);
322         fprintf(STDERR, "REQUEST [%s]\n", $user_sql);
323         if ( ! (($user_pg  = $this->query($user_sql)) != FALSE && pg_affected_rows($user_pg) == 1) ) {
324              return FALSE;
325         }
326         fprintf(STDERR, "REQUEST GOOD [%s]\n", $user_sql);
327
328         return TRUE;
329     }
330
331     /*
332       if success return a LoginDBItem object
333      */
334     function login_verify($login, $pass)
335     {
336         GLOBAL $G_dbpfx;
337
338         $ret = FALSE;
339
340         log_main("login_verify: ".$login);
341
342         //O /* check the existence of the nick in the BriskDB */
343         //O for ($i = 0 ; $i < $this->item_n ; $i++) {
344         //O log_main("login_verify: BEGIN");
345
346         if (($user_obj = $this->getrecord_bylogin($login)) == FALSE) {
347             return FALSE;
348         }
349
350         log_main("login[".$user_obj->code."]: ".$user_obj->login);
351
352         /* if it exists check for a valid challenge */
353         if (($a_sem = Challenges::lock_data(TRUE)) != FALSE) {
354             if (($chals = &Challenges::load_data()) != FALSE) {
355                 for ($e = 0 ; $e < $chals->item_n ; $e++) {
356                     log_main("challenge[".$e."]: ".$chals->item[$e]->login);
357                     if (strcmp($login, $chals->item[$e]->login) == 0) {
358                         log_main("login_verify [".$pass."] with [".md5($chals->item[$e]->token.$user_obj->pass)."]");
359
360                         if (strcmp($pass, md5($chals->item[$e]->token.$user_obj->pass)) == 0) {
361                             log_main("login_verify SUCCESS for ".$login);
362
363                             $chals->rem($login);
364                             $this->user_update_login_time($user_obj->code, time());
365                             $ret = LoginDBItem::LoginDBItemFromRecord($user_obj);
366                             break;
367                         }
368                     }
369                 } // end for ($e = 0 ...
370             }
371
372             if ($chals->ismod()) {
373                 Challenges::save_data(&$chals);
374             }
375
376             Challenges::unlock_data($a_sem);
377         }
378         //O break;
379         // O } //  if (strcasecmp($this->item[$i]->login, ...
380         //O }
381
382         return ($ret);
383     }
384
385     function getitem_bylogin($login, &$id) {
386         $ret = FALSE;
387         $id = -1;
388
389         log_main("getitem_bylogin: ".$login);
390
391         if (($user_obj = $this->getrecord_bylogin($login)) == FALSE)
392             return $ret;
393
394         $id = $user_obj->code;
395         return (LoginDBItem::LoginDBItemFromRecord($user_obj));
396     }
397
398     function getitem_bycode($code) {
399         $ret = FALSE;
400
401         log_main("getitem_bycode: ".$code);
402
403         if (($user_obj = $this->getrecord_bycode($code)) == FALSE)
404             return $ret;
405
406         return (LoginDBItem::LoginDBItemFromRecord($user_obj));
407     }
408
409     // TODO FOR DB
410     function getmail($login)
411     {
412         log_main("getmail");
413
414         if (($ret = $this->getrecord_bylogin($login)) == FALSE)
415             return FALSE;
416
417         return ($ret->email);
418     }
419
420     function addusers_from_olddb($olddb, &$cont)
421     {
422         GLOBAL $G_dbpfx;
423
424         for ($i = 0 ; $i < $olddb->count() ; $i++) {
425             $user_sql = sprintf("INSERT INTO %susers ( login, pass, email, type) VALUES ('%s', '%s', '%s', %d);",
426                                 $G_dbpfx, escsql(strtolower($olddb->item[$i]->login)), escsql($olddb->item[$i]->pass),
427                                 escsql($olddb->item[$i]->email), $olddb->item[$i]->type & USER_FLAG_TY_ALL);
428
429             if ( ! (($user_pg  = $this->query($user_sql)) != FALSE && pg_affected_rows($user_pg) == 1) ) {
430                 $cont .= sprintf("ERROR IN LINE: %s\n", eschtml($user_sql));
431
432                 return FALSE;
433             }
434         }
435         return TRUE;
436     }
437
438     function getdbconn()
439     {
440         return ($this->dbconn);
441     }
442
443     // return array of array('code', 'login' [, 'first', 'last', 'tidx']) ordered by table position
444     function users_get($match_code, $with_minmaxtidx, $is_newmatch)
445     {
446         GLOBAL $G_dbpfx;
447
448         if ($is_newmatch) { // is new
449             $usr_sql = sprintf("SELECT u.code AS code, u.login AS login%s
450                                   FROM %sbin5_matches AS m, %sbin5_games AS g, %sbin5_points AS p,
451                                        %susers AS u, %sbin5_table_orders AS o
452                                   WHERE m.code = g.mcode AND g.code = p.gcode AND u.code = p.ucode
453                                        AND m.code = o.mcode AND u.code = o.ucode AND m.code = %d
454                                   GROUP BY u.code, u.login%s, o.pos
455                                   ORDER BY o.pos;",
456                                ($with_minmaxtidx ? ", min(g.tstamp) AS first, max(g.tstamp) AS last, m.tidx AS tidx" : ""),
457                                $G_dbpfx, $G_dbpfx, $G_dbpfx, $G_dbpfx, $G_dbpfx, $match_code,
458                                ($with_minmaxtidx ? ", m.tidx" : ""));
459         }
460         else { // is old
461             $usr_sql = sprintf("SELECT u.code AS code, u.login AS login%s
462                                   FROM %sbin5_matches AS m, %sbin5_games AS g, %sbin5_points AS p, %susers AS u
463                                   WHERE m.code = g.mcode AND g.code = p.gcode AND u.code = p.ucode AND m.code = %d
464                                   GROUP BY u.code, u.login%s;",
465                                ($with_minmaxtidx ? ", min(g.tstamp) AS first, max(g.tstamp) AS last, m.tidx AS tidx" : ""),
466                                $G_dbpfx, $G_dbpfx, $G_dbpfx, $G_dbpfx, $match_code,
467                                ($with_minmaxtidx ? ", m.tidx" : ""));
468         }
469
470         if (($usr_pg  = pg_query($this->dbconn->db(), $usr_sql)) == FALSE ) {
471             log_crit(sprintf("%s::%s: pg_query usr_sql failed [%s]", __CLASS__, __FUNCTION__, $usr_sql));
472             return (FALSE);
473         }
474         $usr_n = pg_numrows($usr_pg);
475         if ($usr_n != BIN5_PLAYERS_N) {
476             log_crit(sprintf("%s::%s: wrong number of players [%s] %d", __CLASS__, __FUNCTION__, $usr_sql, $usr_n));
477             return (FALSE);
478         }
479         $users = array();
480
481         if ($with_minmaxtidx)
482             $fields = array('code', 'login', 'first', 'last', 'tidx');
483         else
484             $fields = array('code', 'login');
485
486         for ($u = 0 ; $u < $usr_n ; $u++) {
487             $usr_obj = pg_fetch_object($usr_pg, $u);
488             $users[$u] = array();
489             foreach($fields as $field) {
490                 $users[$u][$field] = $usr_obj->$field;
491             }
492         }
493         return ($users);
494     }
495
496     // out: tab->{points,points_n,old_reason}, in: tab->ttok
497     function match_continue($match_code, $table, $tidx)
498     {
499         GLOBAL $G_dbpfx;
500         $sql_ttok = escsql($table->table_token);
501
502         if (($users = $this->users_get($match_code, FALSE /*without minmaxidx*/, TRUE /*new game*/)) == FALSE) {
503             log_crit(sprintf("%s::%s: retrieve users fails", __CLASS__, __FUNCTION__));
504             return (FALSE);
505         }
506
507         $num_sql = sprintf("SELECT count(*) AS points_n FROM %sbin5_games WHERE mcode = %d;", $G_dbpfx, $match_code);
508         if (($num_pg  = $this->query($num_sql)) == FALSE || pg_numrows($num_pg) != 1) {
509             log_crit(sprintf("%s::%s: get games number fails", __CLASS__, __FUNCTION__));
510             return (FALSE);
511         }
512         $num_obj = pg_fetch_object($num_pg, 0);
513         $table->points_n = $num_obj->points_n;
514
515         // TAG: POINTS_MANAGEMENT
516         $tot_sql = sprintf("SELECT sum(p.pts * (2^g.mult)) AS pts
517                             FROM %sbin5_games AS g, %sbin5_points AS p, %susers AS u,
518                                  %sbin5_table_orders AS o
519                             WHERE g.mcode = %d AND g.code = p.gcode AND p.ucode = u.code
520                                   AND p.ucode = o.ucode AND g.mcode = o.mcode
521                             GROUP BY p.ucode, o.pos
522                             ORDER BY o.pos;",
523                            $G_dbpfx, $G_dbpfx, $G_dbpfx, $G_dbpfx, $match_code);
524         if (($tot_pg  = pg_query($this->dbconn->db(), $tot_sql)) == FALSE
525             || pg_numrows($tot_pg) != BIN5_PLAYERS_N) {
526             log_crit(sprintf("%s::%s: get games totals fails", __CLASS__, __FUNCTION__));
527             return(FALSE);
528         }
529
530         $u = 0;
531         foreach ($users as $user) {
532             // TAG: POINTS_MANAGEMENT
533             $pts_sql = sprintf("SELECT p.pts AS pts, g.mult AS mult
534                                     FROM %sbin5_points as p, %sbin5_games as g
535                                     WHERE p.gcode = g.code AND g.mcode = %d AND p.ucode = %d
536                                     ORDER BY g.tstamp ASC
537                                     LIMIT %d OFFSET %d;",
538                                $G_dbpfx, $G_dbpfx, $match_code, $user['code'],
539                                MAX_POINTS,
540                                ($num_obj->points_n < MAX_POINTS ? 0 : $num_obj->points_n - MAX_POINTS));
541
542             // points of the match for each user
543             if (($pts_pg  = $this->query($pts_sql)) == FALSE) {
544                 log_crit(sprintf("%s::%s: get points fails", __CLASS__, __FUNCTION__));
545                 return (FALSE);
546             }
547             $pts_n = pg_numrows($pts_pg);
548             if ($pts_n > $table->points_n) {
549                 // inconsistent scenario number of points great than number of games
550                 log_crit(sprintf("%s::%s: number of points great than number of games", __CLASS__, __FUNCTION__));
551                 return (FALSE);
552             }
553             // TAG: POINTS_MANAGEMENT
554             for ($i = 0 , $ct = $table->points_n - $pts_n; $ct < $table->points_n ; $ct++, $i++) {
555                 $pts_obj = pg_fetch_object($pts_pg, $i);
556                 $table->points[$ct % MAX_POINTS][$u] = $pts_obj->pts * pow(2, $pts_obj->mult);
557             }
558             $tot_obj = pg_fetch_object($tot_pg, $u);
559             $table->total[$u] = $tot_obj->pts;
560
561             $u++;
562         }
563
564         $gam_sql = sprintf("SELECT * FROM %sbin5_games WHERE mcode = %d ORDER BY tstamp DESC LIMIT 1;", $G_dbpfx, $match_code);
565         if (($gam_pg  = $this->query($gam_sql)) == FALSE || pg_numrows($gam_pg) != 1) {
566             log_crit(sprintf("%s::%s: get last game fails", __CLASS__, __FUNCTION__));
567             return (FALSE);
568         }
569         $gam_obj = pg_fetch_object($gam_pg, 0);
570
571         $table->old_reason = game_description($gam_obj->act, 'html', $gam_obj->mult,
572                                               $gam_obj->asta_win, ($gam_obj->asta_win != -1 ?
573                                                                    $users[$gam_obj->asta_win]['login'] : ""),
574                                               $gam_obj->friend, ($gam_obj->friend != -1 ?
575                                                                  $users[$gam_obj->friend]['login'] : ""),
576                                               $gam_obj->pnt, $gam_obj->asta_pnt);
577
578         // update matches with new ttok and table idx
579         $mtc_sql = sprintf("UPDATE %sbin5_matches SET (ttok, tidx) = ('%s', %d) WHERE code = %d RETURNING *;",
580                            $G_dbpfx, $sql_ttok, $tidx, $match_code);
581         if (($mtc_pg  = $this->query($mtc_sql)) == FALSE || pg_numrows($mtc_pg) != 1) {
582             log_crit(sprintf("%s::%s: update matches table failed", __CLASS__, __FUNCTION__));
583             return (FALSE);
584         }
585
586         return (TRUE);
587     }
588
589     function match_order_get(&$match_data, $match_code, $exp_num)
590     {
591         GLOBAL $G_dbpfx;
592
593         $ord_sql = sprintf("SELECT ucode FROM %sbin5_table_orders WHERE mcode = %d ORDER BY pos ASC;",
594                            $G_dbpfx, $match_code);
595
596         if (($ord_pg  = $this->query($ord_sql)) == FALSE || pg_numrows($ord_pg) != $exp_num) {
597             log_crit(sprintf("%s: fails for id or users number", __FUNCTION__));
598             return (FALSE);
599         }
600
601         $ucodes = array();
602         for ($i = 0 ; $i < $exp_num ; $i++) {
603             $ord_obj = pg_fetch_object($ord_pg, $i);
604             $ucodes[$i] = $ord_obj->ucode;
605         }
606
607         if ($match_data !== NULL) {
608             $mtdt_sql = sprintf("SELECT * FROM %sbin5_matches WHERE code = %d;",
609                                 $G_dbpfx, $match_code);
610
611             if (($mtdt_pg  = $this->query($mtdt_sql)) == FALSE || pg_numrows($mtdt_pg) != 1) {
612                 log_crit(sprintf("%s: fails retrieve match_data values [%d]", __FUNCTION__, $match_code));
613                 return (FALSE);
614             }
615
616             $mtdt_obj = pg_fetch_object($mtdt_pg, 0);
617
618             foreach (array('ttok', 'tidx', 'mult_next', 'mazzo_next', 'tcode') as $match_name) {
619                 $match_data[$match_name] = $mtdt_obj->$match_name;
620             }
621         }
622
623         return ($ucodes);
624     }
625
626     //   ttok   text UNIQUE,
627     //   tidx
628     function bin5_points_save($date, $table, $tidx, $action, $ucodes, $pts)
629     {
630         GLOBAL $G_dbpfx;
631         $sql_ttok = escsql($table->table_token);
632
633         $is_trans = FALSE;
634         $ret = FALSE;
635
636         $n = count($ucodes);
637         /* check the existence of the nick in the BriskDB */
638         log_main("bin5_points_save: ");
639
640         do {
641             if ($this->query("BEGIN") == FALSE) {
642                 break;
643             }
644             $is_trans = TRUE;
645
646             /*
647              * matches management
648              */
649             $mtc_sql = sprintf("UPDATE %sbin5_matches SET (mazzo_next, mult_next) = (%d, %d) WHERE ttok = '%s' RETURNING *;",
650                                $G_dbpfx, $table->mazzo, $table->mult, $sql_ttok);
651             if (($mtc_pg  = $this->query($mtc_sql)) == FALSE || pg_numrows($mtc_pg) != 1) {
652
653                 // match not exists, insert it
654                 $mtc_sql = sprintf("INSERT INTO %sbin5_matches (ttok, tidx, mazzo_next, mult_next) VALUES ('%s', %d, %d, %d) RETURNING *;",
655                                    $G_dbpfx, $sql_ttok, $tidx, $table->mazzo, $table->mult);
656                 if (($mtc_pg  = $this->query($mtc_sql)) == FALSE || pg_affected_rows($mtc_pg) != 1) {
657                     log_crit(sprintf("bin5_points_save: failed at insert match [%s]", $mtc_sql));
658                     break;
659                 }
660                 $mtc_obj = pg_fetch_object($mtc_pg, 0);
661
662                 for ($i = 0 ; $i < $n ; $i++) {
663                     $ord_sql = sprintf("INSERT INTO %sbin5_table_orders (mcode, ucode, pos) VALUES (%d, %d, %d);",
664                                        $G_dbpfx, $mtc_obj->code, $ucodes[$i], $i);
665                     if (($ord_pg = $this->query($ord_sql)) == FALSE || pg_affected_rows($ord_pg) != 1 ) {
666                         log_crit(sprintf("bin5_points_save: failed at insert table order [%s]", $ord_sql));
667                         break;
668                     }
669                 }
670                 if ($i < $n)
671                     break;
672             }
673             else {
674                 $mtc_obj = pg_fetch_object($mtc_pg,0);
675             }
676
677             /*
678              * games management
679              */
680             $gam_sql = sprintf("INSERT INTO %sbin5_games (mcode, tstamp, act, asta_pnt, pnt, asta_win, friend, mazzo, mult)
681                                                VALUES (%d, to_timestamp(%d), %d, %d, %d, %d, %d, %d, %d) RETURNING *;",
682                                $G_dbpfx, $mtc_obj->code, $date, $action,
683                                $table->old_asta_pnt, $table->old_pnt,
684                                $table->old_asta_win,
685                                $table->old_friend,
686                                $table->old_mazzo, $table->old_mult);
687             if (($gam_pg  = $this->query($gam_sql)) == FALSE || pg_affected_rows($gam_pg) != 1) {
688                 log_crit(sprintf("bin5_points_save: failed at insert game [%s]", $gam_sql));
689                 break;
690             }
691
692             $gam_obj = pg_fetch_object($gam_pg,0);
693
694             /*
695              * points management
696              */
697             for ($i = 0 ; $i < $n ; $i++) {
698                 /* put points */
699                 $pts_sql = sprintf("INSERT INTO %sbin5_points (gcode, ucode, pts)
700                                                VALUES (%d, %d, %d);",
701                                    $G_dbpfx, $gam_obj->code, $ucodes[$i], $pts[$i]);
702                 if (($pts_pg  = $this->query($pts_sql)) == FALSE || pg_affected_rows($pts_pg) != 1) {
703                     log_crit(sprintf("bin5_points_save: failed at insert point [%s]", $pts_sql));
704                     break;
705                 }
706             }
707             if ($i < $n)
708                 break;
709
710             if ($this->query("COMMIT") == FALSE) {
711                 break;
712             }
713
714             $is_trans = FALSE;
715
716             $table->match_id = $mtc_obj->code;
717             $ret = TRUE;
718         } while (0);
719
720         if ($is_trans)
721             $this->query("ROLLBACK");
722
723         return $ret;
724     }
725
726     function mail_add_fromitem($mail) {
727         GLOBAL $G_dbpfx;
728
729         $usr_sql = sprintf("
730 INSERT INTO %smails (code, ucode, type, tstamp, subj, body_txt, body_htm, hash)
731             VALUES (%d, %d, %d, to_timestamp(%d), '%s', '%s', '%s', '%s') RETURNING *;",
732                            $G_dbpfx, $mail->code, $mail->ucode, $mail->type, $mail->tstamp,
733                            escsql($mail->subj), escsql($mail->body_txt), escsql($mail->body_htm),
734                            ($mail->hash == NULL ? "" : escsql($mail->hash))
735                            );
736
737         if (! (($usr_pg  = $this->query($usr_sql)) != FALSE && pg_affected_rows($usr_pg) == 1) ) {
738             return FALSE;
739         }
740         $usr_obj = pg_fetch_object($usr_pg, 0);
741
742         return $usr_obj;
743     }
744
745     function mail_check($code, $type, $hash)
746     {
747         GLOBAL $G_dbpfx;
748
749         $mai_sql = sprintf("SELECT * FROM %smails WHERE code = %d AND type = %d AND hash = '%s';",
750                            $G_dbpfx, $code, $type, escsql($hash));
751         if (($mai_pg  = $this->query($mai_sql)) == FALSE || pg_numrows($mai_pg) != 1) {
752             // check failed
753             return (FALSE);
754         }
755
756         $mai_obj = pg_fetch_object($mai_pg, 0);
757         return ($mai_obj);
758     }
759
760     function mail_delete($code)
761     {
762         GLOBAL $G_dbpfx;
763
764         $mai_sql = sprintf("DELETE FROM %smails WHERE code = %d;", $G_dbpfx, $code);
765
766         if (($mai_pg = $this->query($mai_sql)) == FALSE || pg_affected_rows($mai_pg) != 1) {
767             return (FALSE);
768         }
769         return (TRUE);
770     }
771
772
773 } // End class BriskDB
774
775 class LoginDBOld
776 {
777     var $item;
778     var $item_n;
779
780     function LoginDBOld($filename)
781     {
782         GLOBAL $DOCUMENT_ROOT;
783         log_main("LoginDBOld create:start");
784
785         if (file_exists("$DOCUMENT_ROOT/Etc/".$filename)) {
786             require("$DOCUMENT_ROOT/Etc/".$filename);
787         }
788         else {
789             return (FALSE);
790         }
791         $this->item_n = count($this->item);
792         log_main("LoginDBOld create:end");
793     }
794
795     function count()
796     {
797         return ($this->item_n);
798     }
799
800 } // End class LoginDBOld
801
802 ?>