]> CyberLeo.Net >> Repos - SourceForge/phpwiki.git/blob - lib/WikiDB/adodb/session/adodb-session2.php
Update adodb to adodb519
[SourceForge/phpwiki.git] / lib / WikiDB / adodb / session / adodb-session2.php
1 <?php
2
3
4 /*
5 V5.19  23-Apr-2014  (c) 2000-2014 John Lim (jlim#natsoft.com). All rights reserved.
6          Contributed by Ross Smith (adodb@netebb.com).
7   Released under both BSD license and Lesser GPL library license.
8   Whenever there is any discrepancy between the two licenses,
9   the BSD license will take precedence.
10           Set tabs to 4 for best viewing.
11
12
13 */
14
15 /*
16
17 CREATE Table SCripts
18
19 Oracle
20 ======
21
22 CREATE TABLE SESSIONS2
23 (
24   SESSKEY    VARCHAR2(48 BYTE)                  NOT NULL,
25   EXPIRY     DATE                               NOT NULL,
26   EXPIREREF  VARCHAR2(200 BYTE),
27   CREATED    DATE                               NOT NULL,
28   MODIFIED   DATE                               NOT NULL,
29   SESSDATA   CLOB,
30   PRIMARY KEY(SESSKEY)
31 );
32
33
34 CREATE INDEX SESS2_EXPIRY ON SESSIONS2(EXPIRY);
35 CREATE UNIQUE INDEX SESS2_PK ON SESSIONS2(SESSKEY);
36 CREATE INDEX SESS2_EXP_REF ON SESSIONS2(EXPIREREF);
37
38
39
40  MySQL
41  =====
42
43 CREATE TABLE sessions2(
44         sesskey VARCHAR( 64 ) NOT NULL DEFAULT '',
45         expiry TIMESTAMP NOT NULL ,
46         expireref VARCHAR( 250 ) DEFAULT '',
47         created TIMESTAMP NOT NULL ,
48         modified TIMESTAMP NOT NULL ,
49         sessdata LONGTEXT DEFAULT '',
50         PRIMARY KEY ( sesskey ) ,
51         INDEX sess2_expiry( expiry ),
52         INDEX sess2_expireref( expireref )
53 )
54
55
56 */
57
58 if (!defined('_ADODB_LAYER')) {
59         require realpath(dirname(__FILE__) . '/../adodb.inc.php');
60 }
61
62 if (defined('ADODB_SESSION')) return 1;
63
64 define('ADODB_SESSION', dirname(__FILE__));
65 define('ADODB_SESSION2', ADODB_SESSION);
66
67 /*
68         Unserialize session data manually. See http://phplens.com/lens/lensforum/msgs.php?id=9821
69
70         From Kerr Schere, to unserialize session data stored via ADOdb.
71         1. Pull the session data from the db and loop through it.
72         2. Inside the loop, you will need to urldecode the data column.
73         3. After urldecode, run the serialized string through this function:
74
75 */
76 function adodb_unserialize( $serialized_string )
77 {
78         $variables = array( );
79         $a = preg_split( "/(\w+)\|/", $serialized_string, -1, PREG_SPLIT_NO_EMPTY | PREG_SPLIT_DELIM_CAPTURE );
80         for( $i = 0; $i < count( $a ); $i = $i+2 ) {
81                 $variables[$a[$i]] = unserialize( $a[$i+1] );
82         }
83         return( $variables );
84 }
85
86 /*
87         Thanks Joe Li. See http://phplens.com/lens/lensforum/msgs.php?id=11487&x=1
88         Since adodb 4.61.
89 */
90 function adodb_session_regenerate_id()
91 {
92         $conn = ADODB_Session::_conn();
93         if (!$conn) return false;
94
95         $old_id = session_id();
96         if (function_exists('session_regenerate_id')) {
97                 session_regenerate_id();
98         } else {
99                 session_id(md5(uniqid(rand(), true)));
100                 $ck = session_get_cookie_params();
101                 setcookie(session_name(), session_id(), false, $ck['path'], $ck['domain'], $ck['secure']);
102                 //@session_start();
103         }
104         $new_id = session_id();
105         $ok = $conn->Execute('UPDATE '. ADODB_Session::table(). ' SET sesskey='. $conn->qstr($new_id). ' WHERE sesskey='.$conn->qstr($old_id));
106
107         /* it is possible that the update statement fails due to a collision */
108         if (!$ok) {
109                 session_id($old_id);
110                 if (empty($ck)) $ck = session_get_cookie_params();
111                 setcookie(session_name(), session_id(), false, $ck['path'], $ck['domain'], $ck['secure']);
112                 return false;
113         }
114
115         return true;
116 }
117
118 /*
119     Generate database table for session data
120     @see http://phplens.com/lens/lensforum/msgs.php?id=12280
121     @return 0 if failure, 1 if errors, 2 if successful.
122         @author Markus Staab http://www.public-4u.de
123 */
124 function adodb_session_create_table($schemaFile=null,$conn = null)
125 {
126     // set default values
127     if ($schemaFile===null) $schemaFile = ADODB_SESSION . '/session_schema2.xml';
128     if ($conn===null) $conn = ADODB_Session::_conn();
129
130         if (!$conn) return 0;
131
132     $schema = new adoSchema($conn);
133     $schema->ParseSchema($schemaFile);
134     return $schema->ExecuteSchema();
135 }
136
137 /*!
138         \static
139 */
140 class ADODB_Session {
141         /////////////////////
142         // getter/setter methods
143         /////////////////////
144
145         /*
146
147         function Lock($lock=null)
148         {
149         static $_lock = false;
150
151                 if (!is_null($lock)) $_lock = $lock;
152                 return $lock;
153         }
154         */
155         /*!
156         */
157         static function driver($driver = null)
158         {
159                 static $_driver = 'mysql';
160                 static $set = false;
161
162                 if (!is_null($driver)) {
163                         $_driver = trim($driver);
164                         $set = true;
165                 } elseif (!$set) {
166                         // backwards compatibility
167                         if (isset($GLOBALS['ADODB_SESSION_DRIVER'])) {
168                                 return $GLOBALS['ADODB_SESSION_DRIVER'];
169                         }
170                 }
171
172                 return $_driver;
173         }
174
175         /*!
176         */
177         static function host($host = null) {
178                 static $_host = 'localhost';
179                 static $set = false;
180
181                 if (!is_null($host)) {
182                         $_host = trim($host);
183                         $set = true;
184                 } elseif (!$set) {
185                         // backwards compatibility
186                         if (isset($GLOBALS['ADODB_SESSION_CONNECT'])) {
187                                 return $GLOBALS['ADODB_SESSION_CONNECT'];
188                         }
189                 }
190
191                 return $_host;
192         }
193
194         /*!
195         */
196         static function user($user = null)
197         {
198                 static $_user = 'root';
199                 static $set = false;
200
201                 if (!is_null($user)) {
202                         $_user = trim($user);
203                         $set = true;
204                 } elseif (!$set) {
205                         // backwards compatibility
206                         if (isset($GLOBALS['ADODB_SESSION_USER'])) {
207                                 return $GLOBALS['ADODB_SESSION_USER'];
208                         }
209                 }
210
211                 return $_user;
212         }
213
214         /*!
215         */
216         static function password($password = null)
217         {
218                 static $_password = '';
219                 static $set = false;
220
221                 if (!is_null($password)) {
222                         $_password = $password;
223                         $set = true;
224                 } elseif (!$set) {
225                         // backwards compatibility
226                         if (isset($GLOBALS['ADODB_SESSION_PWD'])) {
227                                 return $GLOBALS['ADODB_SESSION_PWD'];
228                         }
229                 }
230
231                 return $_password;
232         }
233
234         /*!
235         */
236         static function database($database = null)
237         {
238                 static $_database = '';
239                 static $set = false;
240
241                 if (!is_null($database)) {
242                         $_database = trim($database);
243                         $set = true;
244                 } elseif (!$set) {
245                         // backwards compatibility
246                         if (isset($GLOBALS['ADODB_SESSION_DB'])) {
247                                 return $GLOBALS['ADODB_SESSION_DB'];
248                         }
249                 }
250                 return $_database;
251         }
252
253         /*!
254         */
255         static function persist($persist = null)
256         {
257                 static $_persist = true;
258
259                 if (!is_null($persist)) {
260                         $_persist = trim($persist);
261                 }
262
263                 return $_persist;
264         }
265
266         /*!
267         */
268         static function lifetime($lifetime = null)
269         {
270                 static $_lifetime;
271                 static $set = false;
272
273                 if (!is_null($lifetime)) {
274                         $_lifetime = (int) $lifetime;
275                         $set = true;
276                 } elseif (!$set) {
277                         // backwards compatibility
278                         if (isset($GLOBALS['ADODB_SESS_LIFE'])) {
279                                 return $GLOBALS['ADODB_SESS_LIFE'];
280                         }
281                 }
282                 if (!$_lifetime) {
283                         $_lifetime = ini_get('session.gc_maxlifetime');
284                         if ($_lifetime <= 1) {
285                                 // bug in PHP 4.0.3 pl 1  -- how about other versions?
286                                 //print "<h3>Session Error: PHP.INI setting <i>session.gc_maxlifetime</i>not set: $lifetime</h3>";
287                                 $_lifetime = 1440;
288                         }
289                 }
290
291                 return $_lifetime;
292         }
293
294         /*!
295         */
296         static function debug($debug = null)
297         {
298                 static $_debug = false;
299                 static $set = false;
300
301                 if (!is_null($debug)) {
302                         $_debug = (bool) $debug;
303
304                         $conn = ADODB_Session::_conn();
305                         if ($conn) {
306                                 #$conn->debug = $_debug;
307                         }
308                         $set = true;
309                 } elseif (!$set) {
310                         // backwards compatibility
311                         if (isset($GLOBALS['ADODB_SESS_DEBUG'])) {
312                                 return $GLOBALS['ADODB_SESS_DEBUG'];
313                         }
314                 }
315
316                 return $_debug;
317         }
318
319         /*!
320         */
321         static function expireNotify($expire_notify = null)
322         {
323                 static $_expire_notify;
324                 static $set = false;
325
326                 if (!is_null($expire_notify)) {
327                         $_expire_notify = $expire_notify;
328                         $set = true;
329                 } elseif (!$set) {
330                         // backwards compatibility
331                         if (isset($GLOBALS['ADODB_SESSION_EXPIRE_NOTIFY'])) {
332                                 return $GLOBALS['ADODB_SESSION_EXPIRE_NOTIFY'];
333                         }
334                 }
335
336                 return $_expire_notify;
337         }
338
339         /*!
340         */
341         static function table($table = null)
342         {
343                 static $_table = 'sessions2';
344                 static $set = false;
345
346                 if (!is_null($table)) {
347                         $_table = trim($table);
348                         $set = true;
349                 } elseif (!$set) {
350                         // backwards compatibility
351                         if (isset($GLOBALS['ADODB_SESSION_TBL'])) {
352                                 return $GLOBALS['ADODB_SESSION_TBL'];
353                         }
354                 }
355
356                 return $_table;
357         }
358
359         /*!
360         */
361         static function optimize($optimize = null)
362         {
363                 static $_optimize = false;
364                 static $set = false;
365
366                 if (!is_null($optimize)) {
367                         $_optimize = (bool) $optimize;
368                         $set = true;
369                 } elseif (!$set) {
370                         // backwards compatibility
371                         if (defined('ADODB_SESSION_OPTIMIZE')) {
372                                 return true;
373                         }
374                 }
375
376                 return $_optimize;
377         }
378
379         /*!
380         */
381         static function syncSeconds($sync_seconds = null) {
382                 //echo ("<p>WARNING: ADODB_SESSION::syncSeconds is longer used, please remove this function for your code</p>");
383
384                 return 0;
385         }
386
387         /*!
388         */
389         static function clob($clob = null) {
390                 static $_clob = false;
391                 static $set = false;
392
393                 if (!is_null($clob)) {
394                         $_clob = strtolower(trim($clob));
395                         $set = true;
396                 } elseif (!$set) {
397                         // backwards compatibility
398                         if (isset($GLOBALS['ADODB_SESSION_USE_LOBS'])) {
399                                 return $GLOBALS['ADODB_SESSION_USE_LOBS'];
400                         }
401                 }
402
403                 return $_clob;
404         }
405
406         /*!
407         */
408         static function dataFieldName($data_field_name = null) {
409                 //echo ("<p>WARNING: ADODB_SESSION::dataFieldName() is longer used, please remove this function for your code</p>");
410                 return '';
411         }
412
413         /*!
414         */
415         static function filter($filter = null) {
416                 static $_filter = array();
417
418                 if (!is_null($filter)) {
419                         if (!is_array($filter)) {
420                                 $filter = array($filter);
421                         }
422                         $_filter = $filter;
423                 }
424
425                 return $_filter;
426         }
427
428         /*!
429         */
430         static function encryptionKey($encryption_key = null) {
431                 static $_encryption_key = 'CRYPTED ADODB SESSIONS ROCK!';
432
433                 if (!is_null($encryption_key)) {
434                         $_encryption_key = $encryption_key;
435                 }
436
437                 return $_encryption_key;
438         }
439
440         /////////////////////
441         // private methods
442         /////////////////////
443
444         /*!
445         */
446         static function _conn($conn=null) {
447                 return isset($GLOBALS['ADODB_SESS_CONN']) ? $GLOBALS['ADODB_SESS_CONN'] : false;
448         }
449
450         /*!
451         */
452         static function _crc($crc = null) {
453                 static $_crc = false;
454
455                 if (!is_null($crc)) {
456                         $_crc = $crc;
457                 }
458
459                 return $_crc;
460         }
461
462         /*!
463         */
464         static function _init() {
465                 session_module_name('user');
466                 session_set_save_handler(
467                         array('ADODB_Session', 'open'),
468                         array('ADODB_Session', 'close'),
469                         array('ADODB_Session', 'read'),
470                         array('ADODB_Session', 'write'),
471                         array('ADODB_Session', 'destroy'),
472                         array('ADODB_Session', 'gc')
473                 );
474         }
475
476
477         /*!
478         */
479         static function _sessionKey() {
480                 // use this function to create the encryption key for crypted sessions
481                 // crypt the used key, ADODB_Session::encryptionKey() as key and session_id() as salt
482                 return crypt(ADODB_Session::encryptionKey(), session_id());
483         }
484
485         /*!
486         */
487         static function _dumprs(&$rs) {
488                 $conn   = ADODB_Session::_conn();
489                 $debug  = ADODB_Session::debug();
490
491                 if (!$conn) {
492                         return;
493                 }
494
495                 if (!$debug) {
496                         return;
497                 }
498
499                 if (!$rs) {
500                         echo "<br />\$rs is null or false<br />\n";
501                         return;
502                 }
503
504                 //echo "<br />\nAffected_Rows=",$conn->Affected_Rows(),"<br />\n";
505
506                 if (!is_object($rs)) {
507                         return;
508                 }
509                 $rs = $conn->_rs2rs($rs);
510
511                 require_once ADODB_SESSION.'/../tohtml.inc.php';
512                 rs2html($rs);
513                 $rs->MoveFirst();
514         }
515
516         /////////////////////
517         // public methods
518         /////////////////////
519
520         static function config($driver, $host, $user, $password, $database=false,$options=false)
521         {
522                 ADODB_Session::driver($driver);
523                 ADODB_Session::host($host);
524                 ADODB_Session::user($user);
525                 ADODB_Session::password($password);
526                 ADODB_Session::database($database);
527
528                 if (strncmp($driver, 'oci8', 4) == 0) $options['lob'] = 'CLOB';
529
530                 if (isset($options['table'])) ADODB_Session::table($options['table']);
531                 if (isset($options['lob'])) ADODB_Session::clob($options['lob']);
532                 if (isset($options['debug'])) ADODB_Session::debug($options['debug']);
533         }
534
535         /*!
536                 Create the connection to the database.
537
538                 If $conn already exists, reuse that connection
539         */
540         static function open($save_path, $session_name, $persist = null)
541         {
542                 $conn = ADODB_Session::_conn();
543
544                 if ($conn) {
545                         return true;
546                 }
547
548                 $database       = ADODB_Session::database();
549                 $debug          = ADODB_Session::debug();
550                 $driver         = ADODB_Session::driver();
551                 $host           = ADODB_Session::host();
552                 $password       = ADODB_Session::password();
553                 $user           = ADODB_Session::user();
554
555                 if (!is_null($persist)) {
556                         ADODB_Session::persist($persist);
557                 } else {
558                         $persist = ADODB_Session::persist();
559                 }
560
561 # these can all be defaulted to in php.ini
562 #               assert('$database');
563 #               assert('$driver');
564 #               assert('$host');
565
566                 $conn = ADONewConnection($driver);
567
568                 if ($debug) {
569                         $conn->debug = true;
570                         ADOConnection::outp( " driver=$driver user=$user db=$database ");
571                 }
572
573                 if (empty($conn->_connectionID)) { // not dsn
574                         if ($persist) {
575                                 switch($persist) {
576                                 default:
577                                 case 'P': $ok = $conn->PConnect($host, $user, $password, $database); break;
578                                 case 'C': $ok = $conn->Connect($host, $user, $password, $database); break;
579                                 case 'N': $ok = $conn->NConnect($host, $user, $password, $database); break;
580                                 }
581                         } else {
582                                 $ok = $conn->Connect($host, $user, $password, $database);
583                         }
584                 }
585
586                 if ($ok) $GLOBALS['ADODB_SESS_CONN'] = $conn;
587                 else
588                         ADOConnection::outp('<p>Session: connection failed</p>', false);
589
590
591                 return $ok;
592         }
593
594         /*!
595                 Close the connection
596         */
597         static function close()
598         {
599 /*
600                 $conn = ADODB_Session::_conn();
601                 if ($conn) $conn->Close();
602 */
603                 return true;
604         }
605
606         /*
607                 Slurp in the session variables and return the serialized string
608         */
609         static function read($key)
610         {
611                 $conn   = ADODB_Session::_conn();
612                 $filter = ADODB_Session::filter();
613                 $table  = ADODB_Session::table();
614
615                 if (!$conn) {
616                         return '';
617                 }
618
619                 //assert('$table');
620
621                 $binary = $conn->dataProvider === 'mysql' ? '/*! BINARY */' : '';
622
623                 global $ADODB_SESSION_SELECT_FIELDS;
624                 if (!isset($ADODB_SESSION_SELECT_FIELDS)) $ADODB_SESSION_SELECT_FIELDS = 'sessdata';
625                 $sql = "SELECT $ADODB_SESSION_SELECT_FIELDS FROM $table WHERE sesskey = $binary ".$conn->Param(0)." AND expiry >= " . $conn->sysTimeStamp;
626
627                 /* Lock code does not work as it needs to hold transaction within whole page, and we don't know if
628                   developer has commited elsewhere... :(
629                  */
630                 #if (ADODB_Session::Lock())
631                 #       $rs = $conn->RowLock($table, "$binary sesskey = $qkey AND expiry >= " . time(), sessdata);
632                 #else
633                         $rs = $conn->Execute($sql, array($key));
634                 //ADODB_Session::_dumprs($rs);
635                 if ($rs) {
636                         if ($rs->EOF) {
637                                 $v = '';
638                         } else {
639                                 $v = reset($rs->fields);
640                                 $filter = array_reverse($filter);
641                                 foreach ($filter as $f) {
642                                         if (is_object($f)) {
643                                                 $v = $f->read($v, ADODB_Session::_sessionKey());
644                                         }
645                                 }
646                                 $v = rawurldecode($v);
647                         }
648
649                         $rs->Close();
650
651                         ADODB_Session::_crc(strlen($v) . crc32($v));
652                         return $v;
653                 }
654
655                 return '';
656         }
657
658         /*!
659                 Write the serialized data to a database.
660
661                 If the data has not been modified since the last read(), we do not write.
662         */
663         static function write($key, $oval)
664         {
665         global $ADODB_SESSION_READONLY;
666
667                 if (!empty($ADODB_SESSION_READONLY)) return;
668
669                 $clob                   = ADODB_Session::clob();
670                 $conn                   = ADODB_Session::_conn();
671                 $crc                    = ADODB_Session::_crc();
672                 $debug                  = ADODB_Session::debug();
673                 $driver                 = ADODB_Session::driver();
674                 $expire_notify  = ADODB_Session::expireNotify();
675                 $filter                 = ADODB_Session::filter();
676                 $lifetime               = ADODB_Session::lifetime();
677                 $table                  = ADODB_Session::table();
678
679                 if (!$conn) {
680                         return false;
681                 }
682                 if ($debug) $conn->debug = 1;
683                 $sysTimeStamp = $conn->sysTimeStamp;
684
685                 //assert('$table');
686
687                 $expiry = $conn->OffsetDate($lifetime/(24*3600),$sysTimeStamp);
688
689                 $binary = $conn->dataProvider === 'mysql' ? '/*! BINARY */' : '';
690
691                 // crc32 optimization since adodb 2.1
692                 // now we only update expiry date, thx to sebastian thom in adodb 2.32
693                 if ($crc !== '00' && $crc !== false && $crc == (strlen($oval) . crc32($oval))) {
694                         if ($debug) {
695                                 echo '<p>Session: Only updating date - crc32 not changed</p>';
696                         }
697
698                         $expirevar = '';
699                         if ($expire_notify) {
700                                 $var = reset($expire_notify);
701                                 global $$var;
702                                 if (isset($$var)) {
703                                         $expirevar = $$var;
704                                 }
705                         }
706
707
708                         $sql = "UPDATE $table SET expiry = $expiry ,expireref=".$conn->Param('0').", modified = $sysTimeStamp WHERE $binary sesskey = ".$conn->Param('1')." AND expiry >= $sysTimeStamp";
709                         $rs = $conn->Execute($sql,array($expirevar,$key));
710                         return true;
711                 }
712                 $val = rawurlencode($oval);
713                 foreach ($filter as $f) {
714                         if (is_object($f)) {
715                                 $val = $f->write($val, ADODB_Session::_sessionKey());
716                         }
717                 }
718
719                 $expireref = '';
720                 if ($expire_notify) {
721                         $var = reset($expire_notify);
722                         global $$var;
723                         if (isset($$var)) {
724                                 $expireref = $$var;
725                         }
726                 }
727
728                 if (!$clob) {   // no lobs, simply use replace()
729                         $rs = $conn->Execute("SELECT COUNT(*) AS cnt FROM $table WHERE $binary sesskey = ".$conn->Param(0),array($key));
730                         if ($rs) $rs->Close();
731
732                         if ($rs && reset($rs->fields) > 0) {
733                                 $sql = "UPDATE $table SET expiry=$expiry, sessdata=".$conn->Param(0).", expireref= ".$conn->Param(1).",modified=$sysTimeStamp WHERE sesskey = ".$conn->Param(2);
734
735                         } else {
736                                 $sql = "INSERT INTO $table (expiry, sessdata, expireref, sesskey, created, modified)
737                                         VALUES ($expiry,".$conn->Param('0').", ". $conn->Param('1').", ".$conn->Param('2').", $sysTimeStamp, $sysTimeStamp)";
738                         }
739
740
741                         $rs = $conn->Execute($sql,array($val,$expireref,$key));
742
743                 } else {
744                         // what value shall we insert/update for lob row?
745                         if (strncmp($driver, 'oci8', 4) == 0) $lob_value = sprintf('empty_%s()', strtolower($clob));
746                         else $lob_value = 'null';
747
748                         $conn->StartTrans();
749
750                         $rs = $conn->Execute("SELECT COUNT(*) AS cnt FROM $table WHERE $binary sesskey = ".$conn->Param(0),array($key));
751
752                         if ($rs && reset($rs->fields) > 0) {
753                                 $sql = "UPDATE $table SET expiry=$expiry, sessdata=$lob_value, expireref= ".$conn->Param(0).",modified=$sysTimeStamp WHERE sesskey = ".$conn->Param('1');
754
755                         } else {
756                                 $sql = "INSERT INTO $table (expiry, sessdata, expireref, sesskey, created, modified)
757                                         VALUES ($expiry,$lob_value, ". $conn->Param('0').", ".$conn->Param('1').", $sysTimeStamp, $sysTimeStamp)";
758                         }
759
760                         $rs = $conn->Execute($sql,array($expireref,$key));
761
762                         $qkey = $conn->qstr($key);
763                         $rs2 = $conn->UpdateBlob($table, 'sessdata', $val, " sesskey=$qkey", strtoupper($clob));
764                         if ($debug) echo "<hr>",htmlspecialchars($oval), "<hr>";
765                         $rs = @$conn->CompleteTrans();
766
767
768                 }
769
770                 if (!$rs) {
771                         ADOConnection::outp('<p>Session Replace: ' . $conn->ErrorMsg() . '</p>', false);
772                         return false;
773                 }  else {
774                         // bug in access driver (could be odbc?) means that info is not committed
775                         // properly unless select statement executed in Win2000
776                         if ($conn->databaseType == 'access') {
777                                 $sql = "SELECT sesskey FROM $table WHERE $binary sesskey = $qkey";
778                                 $rs = $conn->Execute($sql);
779                                 ADODB_Session::_dumprs($rs);
780                                 if ($rs) {
781                                         $rs->Close();
782                                 }
783                         }
784                 }/*
785                 if (ADODB_Session::Lock()) {
786                         $conn->CommitTrans();
787                 }*/
788                 return $rs ? true : false;
789         }
790
791         /*!
792         */
793         static function destroy($key) {
794                 $conn                   = ADODB_Session::_conn();
795                 $table                  = ADODB_Session::table();
796                 $expire_notify  = ADODB_Session::expireNotify();
797
798                 if (!$conn) {
799                         return false;
800                 }
801                 $debug                  = ADODB_Session::debug();
802                 if ($debug) $conn->debug = 1;
803                 //assert('$table');
804
805                 $qkey = $conn->quote($key);
806                 $binary = $conn->dataProvider === 'mysql' ? '/*! BINARY */' : '';
807
808                 if ($expire_notify) {
809                         reset($expire_notify);
810                         $fn = next($expire_notify);
811                         $savem = $conn->SetFetchMode(ADODB_FETCH_NUM);
812                         $sql = "SELECT expireref, sesskey FROM $table WHERE $binary sesskey = $qkey";
813                         $rs = $conn->Execute($sql);
814                         ADODB_Session::_dumprs($rs);
815                         $conn->SetFetchMode($savem);
816                         if (!$rs) {
817                                 return false;
818                         }
819                         if (!$rs->EOF) {
820                                 $ref = $rs->fields[0];
821                                 $key = $rs->fields[1];
822                                 //assert('$ref');
823                                 //assert('$key');
824                                 $fn($ref, $key);
825                         }
826                         $rs->Close();
827                 }
828
829                 $sql = "DELETE FROM $table WHERE $binary sesskey = $qkey";
830                 $rs = $conn->Execute($sql);
831                 if ($rs) {
832                         $rs->Close();
833                 }
834
835                 return $rs ? true : false;
836         }
837
838         /*!
839         */
840         static function gc($maxlifetime)
841         {
842                 $conn                   = ADODB_Session::_conn();
843                 $debug                  = ADODB_Session::debug();
844                 $expire_notify  = ADODB_Session::expireNotify();
845                 $optimize               = ADODB_Session::optimize();
846                 $table                  = ADODB_Session::table();
847
848                 if (!$conn) {
849                         return false;
850                 }
851
852
853                 $debug                  = ADODB_Session::debug();
854                 if ($debug) {
855                         $conn->debug = 1;
856                         $COMMITNUM = 2;
857                 } else {
858                         $COMMITNUM = 20;
859                 }
860
861                 //assert('$table');
862
863                 $time = $conn->OffsetDate(-$maxlifetime/24/3600,$conn->sysTimeStamp);
864                 $binary = $conn->dataProvider === 'mysql' ? '/*! BINARY */' : '';
865
866                 if ($expire_notify) {
867                         reset($expire_notify);
868                         $fn = next($expire_notify);
869                 } else {
870                         $fn = false;
871                 }
872
873                 $savem = $conn->SetFetchMode(ADODB_FETCH_NUM);
874                 $sql = "SELECT expireref, sesskey FROM $table WHERE expiry < $time ORDER BY 2"; # add order by to prevent deadlock
875                 $rs = $conn->SelectLimit($sql,1000);
876                 if ($debug) ADODB_Session::_dumprs($rs);
877                 $conn->SetFetchMode($savem);
878                 if ($rs) {
879                         $tr = $conn->hasTransactions;
880                         if ($tr) $conn->BeginTrans();
881                         $keys = array();
882                         $ccnt = 0;
883                         while (!$rs->EOF) {
884                                 $ref = $rs->fields[0];
885                                 $key = $rs->fields[1];
886                                 if ($fn) $fn($ref, $key);
887                                 $del = $conn->Execute("DELETE FROM $table WHERE sesskey=".$conn->Param('0'),array($key));
888                                 $rs->MoveNext();
889                                 $ccnt += 1;
890                                 if ($tr && $ccnt % $COMMITNUM == 0) {
891                                         if ($debug) echo "Commit<br>\n";
892                                         $conn->CommitTrans();
893                                         $conn->BeginTrans();
894                                 }
895                         }
896                         $rs->Close();
897
898                         if ($tr) $conn->CommitTrans();
899                 }
900
901
902                 // suggested by Cameron, "GaM3R" <gamr@outworld.cx>
903                 if ($optimize) {
904                         $driver = ADODB_Session::driver();
905
906                         if (preg_match('/mysql/i', $driver)) {
907                                 $sql = "OPTIMIZE TABLE $table";
908                         }
909                         if (preg_match('/postgres/i', $driver)) {
910                                 $sql = "VACUUM $table";
911                         }
912                         if (!empty($sql)) {
913                                 $conn->Execute($sql);
914                         }
915                 }
916
917
918                 return true;
919         }
920 }
921
922 ADODB_Session::_init();
923 if (empty($ADODB_SESSION_READONLY))
924         register_shutdown_function('session_write_close');
925
926 // for backwards compatability only
927 function adodb_sess_open($save_path, $session_name, $persist = true) {
928         return ADODB_Session::open($save_path, $session_name, $persist);
929 }
930
931 // for backwards compatability only
932 function adodb_sess_gc($t)
933 {
934         return ADODB_Session::gc($t);
935 }