partial commit of new saving points schema
[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_update_login_time($code, $lintm)
161     {
162         GLOBAL $G_dbpfx;
163
164         $user_sql = sprintf("UPDATE %susers SET (lintm) = (date 'epoch' + %d * INTERVAL '1 second') WHERE code = %d;", $G_dbpfx, $lintm, $code);
165
166         // $user_pg = $this->query($user_sql);
167         // $row_n = pg_affected_rows($user_pg);
168         // fprintf(STDERR, "query: %s   NUM: %d\n", ($user_pg == FALSE ? "FALSE" : "TRUE"), $row_n);
169         if ( ! (($user_pg  = $this->query($user_sql)) != FALSE && pg_affected_rows($user_pg) == 1) ) {
170              return FALSE;
171         }
172
173         return TRUE;
174     }
175
176     function user_prefs_update($code, $flags, $supp_comp)
177     {
178         GLOBAL $G_dbpfx;
179
180         $user_sql = sprintf("UPDATE %susers SET (type, supp_comp) = (%d, '%s') WHERE code = %d;",
181                             $G_dbpfx, $flags, $supp_comp, $code);
182         fprintf(STDERR, "REQUEST [%s]\n", $user_sql);
183         if ( ! (($user_pg  = $this->query($user_sql)) != FALSE && pg_affected_rows($user_pg) == 1) ) {
184              return FALSE;
185         }
186         fprintf(STDERR, "REQUEST GOOD [%s]\n", $user_sql);
187
188         return TRUE;
189     }
190     
191     function login_verify($login, $pass)
192     {
193         GLOBAL $G_dbpfx;
194         
195         $ret = FALSE;
196         
197         log_main("login_verify: ".$login);
198         
199         
200         //O /* check the existence of the nick in the BriskDB */
201         //O for ($i = 0 ; $i < $this->item_n ; $i++) {
202         //O log_main("login_verify: BEGIN");
203         
204         if (($user_obj = $this->getrecord_bylogin($login)) == FALSE) {
205             return FALSE;
206         }
207
208         log_main("login[".$user_obj->code."]: ".$user_obj->login);
209         
210         /* if it exists check for a valid challenge */
211         if (($a_sem = Challenges::lock_data(TRUE)) != FALSE) { 
212             if (($chals = &Challenges::load_data()) != FALSE) {
213                 for ($e = 0 ; $e < $chals->item_n ; $e++) {
214                     log_main("challenge[".$e."]: ".$chals->item[$e]->login);
215                     if (strcmp($login, $chals->item[$e]->login) == 0) {
216                         log_main("login_verify [".$pass."] with [".md5($chals->item[$e]->token.$user_obj->pass)."]");
217                         
218                         if (strcmp($pass, md5($chals->item[$e]->token.$user_obj->pass)) == 0) {
219                             log_main("login_verify SUCCESS for ".$login);
220                             
221                             $chals->rem($login);
222                             $this->user_update_login_time($user_obj->code, time());
223                             $ret = LoginDBItem::LoginDBItemFromRecord($user_obj);
224                             break;
225                         }
226                     }
227                 } // end for ($e = 0 ...
228             }
229             
230             if ($chals->ismod()) {
231                 Challenges::save_data(&$chals);
232             }
233             
234             Challenges::unlock_data($a_sem);
235         }
236         //O break;
237         // O } //  if (strcasecmp($this->item[$i]->login, ...
238         //O }
239     
240         return ($ret);
241     }
242
243     function getitem_bylogin($login, &$id) {
244         $ret = FALSE;
245         $id = -1;
246         
247         log_main("getitem_bylogin: ".$login);
248         
249         if (($user_obj = $this->getrecord_bylogin($login)) == FALSE)
250             return $ret;
251
252         $id = $user_obj->code;
253         return (LoginDBItem::LoginDBItemFromRecord($user_obj));
254     }
255     
256     // TODO FOR DB
257     function getmail($login)
258     {
259         log_main("getmail");
260
261         if (($ret = $this->getrecord_bylogin($login)) == FALSE)
262             return FALSE;
263         
264         return ($ret->email);
265     }
266
267     function addusers_from_olddb($olddb, &$cont)
268     {
269         GLOBAL $G_dbpfx;
270
271         for ($i = 0 ; $i < $olddb->count() ; $i++) {
272             $user_sql = sprintf("INSERT INTO %susers ( login, pass, email, type) VALUES ('%s', '%s', '%s', %d);",
273                                 $G_dbpfx, escsql(strtolower($olddb->item[$i]->login)), escsql($olddb->item[$i]->pass),
274                                 escsql($olddb->item[$i]->email), $olddb->item[$i]->type & USER_FLAG_TY_ALL); 
275
276             if ( ! (($user_pg  = $this->query($user_sql)) != FALSE && pg_affected_rows($user_pg) == 1) ) {
277                 $cont .= sprintf("ERROR IN LINE: %s\n", eschtml($user_sql));
278
279                 return FALSE;
280             }
281         }
282         return TRUE;
283     }
284
285     function getdbconn()
286     {
287         return ($this->dbconn);
288     }
289
290     //   ttok   text UNIQUE,      
291     //   tidx   
292     function bin5_points_save($date, $table, $tidx, $ucodes, $pts)
293     {
294         GLOBAL $G_dbpfx;
295         $sql_ttok = escsql($table->table_token);
296
297         $is_trans = FALSE;
298         $ret = FALSE;
299
300         $n = count($ucodes);
301         /* check the existence of the nick in the BriskDB */
302         log_main("bin5_points_save: ");
303         
304         do {
305             if ($this->query("BEGIN") == FALSE) {
306                 break;
307             }
308             $is_trans = TRUE;
309
310             /*
311              * matches management
312              */
313             $mtc_sql = sprintf("UPDATE %sbin5_matches SET (mazzo_next, mult_next) = (%d, %d) WHERE ttok = '%s' RETURNING *;",
314                                $G_dbpfx, $table->mazzo, $table->mult, $sql_ttok);
315             if (($mtc_pg  = $this->query($mtc_sql)) == FALSE || pg_numrows($mtc_pg) != 1) {
316                 // match not exists, insert it
317                 $mtc_sql = sprintf("INSERT INTO %sbin5_matches (ttok, tidx, mazzo_next, mult_next) VALUES ('%s', %d, %d, %d) RETURNING *;",
318                                    $G_dbpfx, $sql_ttok, $tidx, $table->mazzo, $table->mult);
319                 if (($mtc_pg  = $this->query($mtc_sql)) == FALSE || pg_affected_rows($mtc_pg) != 1) {
320                     log_crit(sprintf("bin5_points_save: failed at insert match [%s]", $mtc_sql));
321                     break;
322                 }
323                 for ($i = 0 ; $i < $n ; $i++) {
324                     $ord_sql = sprintf("INSERT INTO %sbin5_table_order (mcode, ucode, pos) VALUES (%d, %d, %d);",
325                                        $G_dbpfx, $G_dbpfx, $sql_ttok, $ucode[$i], $i);
326                     if (($ord_pg = $this->query($ord_sql)) == FALSE || pg_affected_rows($ord_pg) != 1 ) {
327                         log_crit(sprintf("bin5_points_save: failed at insert table order [%s]", $ord_sql));
328                         break;
329                     }
330                 }
331                 if ($i < $n)
332                     break;
333             }
334             $mtc_obj = pg_fetch_object($mtc_pg,0);
335
336             /*
337              * games management
338              */
339             $gam_sql = sprintf("INSERT INTO %sbin5_games (mcode, tstamp) 
340                                                VALUES (%d, to_timestamp(%d)) RETURNING *;",
341                                $G_dbpfx, $mtc_obj->code, $date);
342             if (($gam_pg  = $this->query($gam_sql)) == FALSE || pg_affected_rows($gam_pg) != 1) {
343                 log_crit(sprintf("bin5_points_save: failed at insert game [%s]", $gam_sql));
344                 break;
345             }
346         
347             $gam_obj = pg_fetch_object($gam_pg,0);
348
349             /*
350              * points management
351              */
352             for ($i = 0 ; $i < $n ; $i++) {
353                 /* put points */
354                 $pts_sql = sprintf("INSERT INTO %sbin5_points (gcode, ucode, pts) 
355                                                VALUES (%d, %d, %d);",
356                                    $G_dbpfx, $gam_obj->code, $ucodes[$i], $pts[$i]);
357                 if (($pts_pg  = $this->query($pts_sql)) == FALSE || pg_affected_rows($pts_pg) != 1) {
358                     log_crit(sprintf("bin5_points_save: failed at insert point [%s]", $pts_sql));
359                     break;
360                 }
361             }
362             if ($i < $n)
363                 break;
364             
365             if ($this->query("COMMIT") == FALSE) {
366                 break;
367             }
368              
369             $is_trans = FALSE;
370
371             $ret =  TRUE;
372         } while (0);
373         
374         if ($is_trans)
375             $this->query("ROLLBACK");
376         
377         return $ret;
378     }
379
380 } // End class BriskDB
381
382 class LoginDBOld 
383 {
384     var $item;
385     var $item_n;
386
387     function LoginDBOld($filename)
388     {
389         GLOBAL $DOCUMENT_ROOT;
390         log_main("LoginDBOld create:start");
391
392         if (file_exists("$DOCUMENT_ROOT/Etc/".$filename)) {
393             require("$DOCUMENT_ROOT/Etc/".$filename);
394         }
395         else {
396             return (FALSE);
397         }
398         $this->item_n = count($this->item);
399         log_main("LoginDBOld create:end");
400     }
401
402     function count()
403     {
404         return ($this->item_n);
405     }
406
407 } // End class LoginDBOld
408
409 ?>