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