[TASK] Update ADOdb to 5.18
[Packages/TYPO3.CMS.git] / typo3 / sysext / adodb / adodb / session / adodb-session2.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
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 ($driver == 'oci8' || $driver == 'oci8po') $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 switch ($driver) {
746 // empty_clob or empty_lob for oracle dbs
747 case 'oracle':
748 case 'oci8':
749 case 'oci8po':
750 case 'oci805':
751 $lob_value = sprintf('empty_%s()', strtolower($clob));
752 break;
753
754 // null for all other
755 default:
756 $lob_value = 'null';
757 break;
758 }
759
760 $conn->StartTrans();
761
762 $rs = $conn->Execute("SELECT COUNT(*) AS cnt FROM $table WHERE $binary sesskey = ".$conn->Param(0),array($key));
763
764 if ($rs && reset($rs->fields) > 0) {
765 $sql = "UPDATE $table SET expiry=$expiry, sessdata=$lob_value, expireref= ".$conn->Param(0).",modified=$sysTimeStamp WHERE sesskey = ".$conn->Param('1');
766
767 } else {
768 $sql = "INSERT INTO $table (expiry, sessdata, expireref, sesskey, created, modified)
769 VALUES ($expiry,$lob_value, ". $conn->Param('0').", ".$conn->Param('1').", $sysTimeStamp, $sysTimeStamp)";
770 }
771
772 $rs = $conn->Execute($sql,array($expireref,$key));
773
774 $qkey = $conn->qstr($key);
775 $rs2 = $conn->UpdateBlob($table, 'sessdata', $val, " sesskey=$qkey", strtoupper($clob));
776 if ($debug) echo "<hr>",htmlspecialchars($oval), "<hr>";
777 $rs = @$conn->CompleteTrans();
778
779
780 }
781
782 if (!$rs) {
783 ADOConnection::outp('<p>Session Replace: ' . $conn->ErrorMsg() . '</p>', false);
784 return false;
785 } else {
786 // bug in access driver (could be odbc?) means that info is not committed
787 // properly unless select statement executed in Win2000
788 if ($conn->databaseType == 'access') {
789 $sql = "SELECT sesskey FROM $table WHERE $binary sesskey = $qkey";
790 $rs = $conn->Execute($sql);
791 ADODB_Session::_dumprs($rs);
792 if ($rs) {
793 $rs->Close();
794 }
795 }
796 }/*
797 if (ADODB_Session::Lock()) {
798 $conn->CommitTrans();
799 }*/
800 return $rs ? true : false;
801 }
802
803 /*!
804 */
805 static function destroy($key) {
806 $conn = ADODB_Session::_conn();
807 $table = ADODB_Session::table();
808 $expire_notify = ADODB_Session::expireNotify();
809
810 if (!$conn) {
811 return false;
812 }
813 $debug = ADODB_Session::debug();
814 if ($debug) $conn->debug = 1;
815 //assert('$table');
816
817 $qkey = $conn->quote($key);
818 $binary = $conn->dataProvider === 'mysql' ? '/*! BINARY */' : '';
819
820 if ($expire_notify) {
821 reset($expire_notify);
822 $fn = next($expire_notify);
823 $savem = $conn->SetFetchMode(ADODB_FETCH_NUM);
824 $sql = "SELECT expireref, sesskey FROM $table WHERE $binary sesskey = $qkey";
825 $rs = $conn->Execute($sql);
826 ADODB_Session::_dumprs($rs);
827 $conn->SetFetchMode($savem);
828 if (!$rs) {
829 return false;
830 }
831 if (!$rs->EOF) {
832 $ref = $rs->fields[0];
833 $key = $rs->fields[1];
834 //assert('$ref');
835 //assert('$key');
836 $fn($ref, $key);
837 }
838 $rs->Close();
839 }
840
841 $sql = "DELETE FROM $table WHERE $binary sesskey = $qkey";
842 $rs = $conn->Execute($sql);
843 if ($rs) {
844 $rs->Close();
845 }
846
847 return $rs ? true : false;
848 }
849
850 /*!
851 */
852 static function gc($maxlifetime)
853 {
854 $conn = ADODB_Session::_conn();
855 $debug = ADODB_Session::debug();
856 $expire_notify = ADODB_Session::expireNotify();
857 $optimize = ADODB_Session::optimize();
858 $table = ADODB_Session::table();
859
860 if (!$conn) {
861 return false;
862 }
863
864
865 $debug = ADODB_Session::debug();
866 if ($debug) {
867 $conn->debug = 1;
868 $COMMITNUM = 2;
869 } else {
870 $COMMITNUM = 20;
871 }
872
873 //assert('$table');
874
875 $time = $conn->OffsetDate(-$maxlifetime/24/3600,$conn->sysTimeStamp);
876 $binary = $conn->dataProvider === 'mysql' ? '/*! BINARY */' : '';
877
878 if ($expire_notify) {
879 reset($expire_notify);
880 $fn = next($expire_notify);
881 } else {
882 $fn = false;
883 }
884
885 $savem = $conn->SetFetchMode(ADODB_FETCH_NUM);
886 $sql = "SELECT expireref, sesskey FROM $table WHERE expiry < $time ORDER BY 2"; # add order by to prevent deadlock
887 $rs = $conn->SelectLimit($sql,1000);
888 if ($debug) ADODB_Session::_dumprs($rs);
889 $conn->SetFetchMode($savem);
890 if ($rs) {
891 $tr = $conn->hasTransactions;
892 if ($tr) $conn->BeginTrans();
893 $keys = array();
894 $ccnt = 0;
895 while (!$rs->EOF) {
896 $ref = $rs->fields[0];
897 $key = $rs->fields[1];
898 if ($fn) $fn($ref, $key);
899 $del = $conn->Execute("DELETE FROM $table WHERE sesskey=".$conn->Param('0'),array($key));
900 $rs->MoveNext();
901 $ccnt += 1;
902 if ($tr && $ccnt % $COMMITNUM == 0) {
903 if ($debug) echo "Commit<br>\n";
904 $conn->CommitTrans();
905 $conn->BeginTrans();
906 }
907 }
908 $rs->Close();
909
910 if ($tr) $conn->CommitTrans();
911 }
912
913
914 // suggested by Cameron, "GaM3R" <gamr@outworld.cx>
915 if ($optimize) {
916 $driver = ADODB_Session::driver();
917
918 if (preg_match('/mysql/i', $driver)) {
919 $sql = "OPTIMIZE TABLE $table";
920 }
921 if (preg_match('/postgres/i', $driver)) {
922 $sql = "VACUUM $table";
923 }
924 if (!empty($sql)) {
925 $conn->Execute($sql);
926 }
927 }
928
929
930 return true;
931 }
932 }
933
934 ADODB_Session::_init();
935 if (empty($ADODB_SESSION_READONLY))
936 register_shutdown_function('session_write_close');
937
938 // for backwards compatability only
939 function adodb_sess_open($save_path, $session_name, $persist = true) {
940 return ADODB_Session::open($save_path, $session_name, $persist);
941 }
942
943 // for backwards compatability only
944 function adodb_sess_gc($t)
945 {
946 return ADODB_Session::gc($t);
947 }
948
949 ?>