PageRenderTime 41ms CodeModel.GetById 11ms app.highlight 24ms RepoModel.GetById 1ms app.codeStats 0ms

/application/libraries/adodb5/session/adodb-session.php

https://code.google.com/
PHP | 934 lines | 604 code | 150 blank | 180 comment | 119 complexity | ab6c269f92326c7d70ba2fabff571b61 MD5 | raw file
  1<?php
  2
  3
  4/*
  5V5.11 5 May 2010   (c) 2000-2010 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
 28if (!defined('_ADODB_LAYER')) {
 29	require realpath(dirname(__FILE__) . '/../adodb.inc.php');
 30}
 31
 32if (defined('ADODB_SESSION')) return 1;
 33
 34define('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*/
 46function 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*/
 60function 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*/
 94function 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*/
110class 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
919ADODB_Session::_init();
920if (empty($ADODB_SESSION_READONLY))
921	register_shutdown_function('session_write_close');
922
923// for backwards compatability only
924function 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
929function adodb_sess_gc($t)
930{	
931	return ADODB_Session::gc($t);
932}
933
934?>