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