Enabled result caching
This commit is contained in:
parent
a82edbf64c
commit
2997f6ada0
4
classes/Database/LDAP/Result/Cached.php
Normal file
4
classes/Database/LDAP/Result/Cached.php
Normal file
@ -0,0 +1,4 @@
|
||||
<?php defined('SYSPATH') or die('No direct access allowed.');
|
||||
|
||||
class Database_LDAP_Result_Cached extends Kohana_Database_LDAP_Result_Cached {}
|
||||
?>
|
@ -27,7 +27,37 @@ class Kohana_Database_LDAP_Result extends Database_Result {
|
||||
ldap_free_result($this->_result['r']);
|
||||
}
|
||||
|
||||
public function as_array($key=NULL,$value=NULL) {
|
||||
$result = array();
|
||||
|
||||
if ($key === NULL AND $value === NULL) {
|
||||
// Indexed rows
|
||||
foreach ($this as $dn => $row)
|
||||
$result[$dn] = $row;
|
||||
|
||||
} elseif ($key === NULL) {
|
||||
throw HTTP_Exception::factory(501,'Not implemented');
|
||||
|
||||
// Indexed columns
|
||||
|
||||
} elseif ($value === NULL) {
|
||||
throw HTTP_Exception::factory(501,'Not implemented');
|
||||
|
||||
// Associative rows
|
||||
|
||||
} else {
|
||||
throw HTTP_Exception::factory(501,'Not implemented');
|
||||
|
||||
// Associative columns
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
public function current() {
|
||||
if (! $this->_current_entry)
|
||||
return array();
|
||||
|
||||
if ($this->_as_object === TRUE) {
|
||||
// Return an stdClass
|
||||
throw HTTP_Exception::factory(501,'Not implemented');
|
||||
@ -67,6 +97,28 @@ class Kohana_Database_LDAP_Result extends Database_Result {
|
||||
return ldap_get_dn($this->_result['l'],$this->_current_entry);
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements [Iterator::next], moves to the next row.
|
||||
*
|
||||
* next($result);
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function next() {
|
||||
$this->_current_entry = ldap_next_entry($this->_result['l'],$this->_current_entry);
|
||||
++$this->_current_row;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function offsetExists($offset) {
|
||||
return $this->valid();
|
||||
}
|
||||
|
||||
public function prev() {
|
||||
throw new Kohana_Exception('Cant go backwards');
|
||||
}
|
||||
|
||||
public function seek($dn) {
|
||||
$this->_current_entry = ldap_first_entry($this->_result['l'],$this->_result['r']);
|
||||
|
||||
@ -82,4 +134,23 @@ class Kohana_Database_LDAP_Result extends Database_Result {
|
||||
// We didnt find it
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
public function rewind() {
|
||||
if ($this->_total_rows)
|
||||
$this->_current_entry = ldap_first_entry($this->_result['l'],$this->_result['r']);
|
||||
|
||||
$this->_current_row = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements [Iterator::valid], checks if the current row exists.
|
||||
*
|
||||
* [!!] This method is only used internally.
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public function valid() {
|
||||
return (boolean)$this->_current_entry;
|
||||
}
|
||||
|
||||
} // End Database_LDAP_Result
|
||||
|
69
classes/Kohana/Database/LDAP/Result/Cached.php
Normal file
69
classes/Kohana/Database/LDAP/Result/Cached.php
Normal file
@ -0,0 +1,69 @@
|
||||
<?php defined('SYSPATH') OR die('No direct script access.');
|
||||
/**
|
||||
* Object used for caching the results of select queries. See [Results](/database/results#select-cached) for usage and examples.
|
||||
*
|
||||
* @package Kohana/LDAP
|
||||
* @category Query/Result
|
||||
* @author Deon George
|
||||
* @copyright (c) 2013 phpLDAPadmin Development Team
|
||||
* @license http://dev.phpldapadmin.org/license.html
|
||||
*/
|
||||
class Kohana_Database_LDAP_Result_Cached extends Database_Result_Cached {
|
||||
|
||||
public function __construct(array $result, $sql, $as_object = NULL)
|
||||
{
|
||||
parent::__construct($result, $sql, $as_object);
|
||||
|
||||
// Find the number of rows in the result
|
||||
$this->_total_rows = count($result);
|
||||
$this->_current_row = key($result);
|
||||
}
|
||||
|
||||
public function __destruct() {
|
||||
// Cached results do not use resources
|
||||
}
|
||||
|
||||
public function cached() {
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function current() {
|
||||
// Return an array of the row
|
||||
return $this->valid() ? $this->_result[$this->_current_row] : NULL;
|
||||
}
|
||||
|
||||
public function key() {
|
||||
return $this->_current_row;
|
||||
}
|
||||
|
||||
public function next() {
|
||||
next($this->_result);
|
||||
$this->_current_row = key($this->_result);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function offsetExists($offset) {
|
||||
return isset($this->_result[$offset]);
|
||||
}
|
||||
|
||||
public function rewind() {
|
||||
// We dont index by numbers, so we can just return
|
||||
reset($this->_result);
|
||||
$this->_current_row = key($this->_result);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function seek($offset) {
|
||||
if (isset($this->_result[$offset])) {
|
||||
$this->_current_row = $offset;
|
||||
|
||||
return TRUE;
|
||||
|
||||
} else {
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
} // End Database_LDAP_Result_Cached
|
@ -21,6 +21,9 @@ abstract class Kohana_Database_LDAP_Search {
|
||||
private $_time_limit = '60'; // LDAP Search Time Limit
|
||||
private $_db_pending = array(); // LDAP Query Filter to compile
|
||||
|
||||
// Execute the query during a cache hit
|
||||
protected $_force_execute = FALSE;
|
||||
|
||||
// Cache lifetime
|
||||
protected $_lifetime = NULL;
|
||||
|
||||
@ -126,6 +129,26 @@ abstract class Kohana_Database_LDAP_Search {
|
||||
return isset($u['']['namingcontexts']) ? $u['']['namingcontexts'] : array();
|
||||
}
|
||||
|
||||
/**
|
||||
* Enables the query to be cached for a specified amount of time.
|
||||
*
|
||||
* @param integer $lifetime number of seconds to cache, 0 deletes it from the cache
|
||||
* @param boolean whether or not to execute the query during a cache hit
|
||||
* @return $this
|
||||
* @uses Kohana::$cache_life
|
||||
*/
|
||||
public function cached($lifetime=NULL,$force=FALSE) {
|
||||
if ($lifetime === NULL) {
|
||||
// Use the global setting
|
||||
$lifetime = Kohana::$cache_life;
|
||||
}
|
||||
|
||||
$this->_force_execute = $force;
|
||||
$this->_lifetime = $lifetime;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function deref($val) {
|
||||
$this->_deref = $val;
|
||||
|
||||
@ -147,21 +170,21 @@ abstract class Kohana_Database_LDAP_Search {
|
||||
|
||||
$result = array();
|
||||
foreach ($this->_base as $base) {
|
||||
$search = NULL;
|
||||
$result[$base] = NULL;
|
||||
|
||||
if ($this->_lifetime !== NULL AND $this->_db->caching()) {
|
||||
// Set the cache key based on the database instance name and SQL
|
||||
$cache_key = 'Database::query("'.$this->_db.'","'.$base.'","'.$this->_scope.'","'.$this->_filter.'")';
|
||||
|
||||
// Read the cache first to delete a possible hit with lifetime <= 0
|
||||
if (($result = Kohana::cache($cache_key, NULL, $this->_lifetime)) !== NULL AND ! $this->_force_execute) {
|
||||
if (($search = Kohana::cache($cache_key, NULL, $this->_lifetime)) !== NULL AND ! $this->_force_execute) {
|
||||
// Return a cached result
|
||||
$search = new Database_Result_Cached($result, array('b'=>$base,'s'=>$this->_scope,'f'=>$this->_filter), $as_object, $object_params);
|
||||
$result[$base] = new Database_LDAP_Result_Cached($search, array('b'=>$base,'s'=>$this->_scope,'f'=>$this->_filter), $as_object, $object_params);
|
||||
}
|
||||
}
|
||||
|
||||
// Search is not cached, OR caching is disabled, so we'll query
|
||||
if (! $search) {
|
||||
if (! $result[$base]) {
|
||||
switch ($this->_scope) {
|
||||
case 'base':
|
||||
$search = ldap_read($this->_db->connection(),$base,$this->_filter,$this->_attrs,$attrs_only,$this->_size_limit,$this->_time_limit,$this->_deref);
|
||||
@ -178,6 +201,10 @@ abstract class Kohana_Database_LDAP_Search {
|
||||
}
|
||||
|
||||
$result[$base] = new Database_LDAP_Result(array('l'=>$this->_db->connection(),'r'=>$search),array('b'=>$base,'s'=>$this->_scope,'f'=>$this->_filter),$as_object,$object_params);
|
||||
|
||||
// Cache the result array
|
||||
if (isset($cache_key) AND $this->_lifetime > 0)
|
||||
Kohana::cache($cache_key,$result[$base]->as_array(),$this->_lifetime);
|
||||
}
|
||||
}
|
||||
|
||||
|
58
tests/classes/LDAPCaching.php
Normal file
58
tests/classes/LDAPCaching.php
Normal file
@ -0,0 +1,58 @@
|
||||
<?php defined('SYSPATH') or die('No direct access allowed.');
|
||||
|
||||
/**
|
||||
* This should test all LDAP server caching configuration
|
||||
*
|
||||
* @package Kohana/LDAP
|
||||
* @category Test
|
||||
* @author Deon George
|
||||
* @copyright (c) 2013 phpLDAPadmin Development Team
|
||||
* @license http://dev.phpldapadmin.org/license.html
|
||||
* @group ldap
|
||||
* @group ldap.server
|
||||
*/
|
||||
Class LDAPCaching extends Unittest_TestCase {
|
||||
function hosts() {
|
||||
return array(
|
||||
array(FALSE,TRUE,FALSE,60),
|
||||
array(TRUE,TRUE,FALSE,0),
|
||||
array(TRUE,FALSE,FALSE,60),
|
||||
array(TRUE,FALSE,FALSE,0),
|
||||
array(TRUE,FALSE,TRUE,60),
|
||||
array(TRUE,FALSE,TRUE,0),
|
||||
array(TRUE,TRUE,TRUE,60),
|
||||
array(TRUE,TRUE,TRUE,0),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test that we can connect to an LDAP server
|
||||
* @dataProvider hosts
|
||||
*/
|
||||
function testCache($expect,$caching,$force,$cached) {
|
||||
$connection = Arr::merge(Kohana::$config->load('database.default'),array(
|
||||
'caching'=>$caching,
|
||||
));
|
||||
|
||||
$x = LDAP::factory('user',NULL,$connection);
|
||||
$x->connect();
|
||||
|
||||
// We'll do a query first.
|
||||
$u = $x->search(array(''))
|
||||
->scope('base')
|
||||
->cached($cached,$force)
|
||||
->run();
|
||||
|
||||
$u = $x->search(array(''))
|
||||
->scope('base')
|
||||
->cached($cached,$force)
|
||||
->run();
|
||||
|
||||
if ($expect)
|
||||
$this->assertInstanceOf('Database_LDAP_Result',$u['']);
|
||||
else
|
||||
$this->assertInstanceOf('Database_LDAP_Result_Cached',$u['']);
|
||||
|
||||
$x->disconnect();
|
||||
}
|
||||
}
|
@ -27,10 +27,9 @@ Class LDAPConnection extends Unittest_TestCase {
|
||||
* @dataProvider hosts
|
||||
*/
|
||||
function testConnect($host,$port,$instance,$expect) {
|
||||
$connection = array(
|
||||
'type'=>'LDAP',
|
||||
$connection = Arr::merge(Kohana::$config->load('database.default'),array(
|
||||
'connection'=>array('hostname'=>$host,'port'=>$port),
|
||||
);
|
||||
));
|
||||
|
||||
$x = LDAP::factory($instance,NULL,$connection);
|
||||
$x->connect();
|
||||
@ -79,8 +78,7 @@ Class LDAPConnection extends Unittest_TestCase {
|
||||
* @depends testConnect
|
||||
*/
|
||||
function testAuthConfiguration($user,$password,$expect) {
|
||||
$connection = array(
|
||||
'type'=>'LDAP',
|
||||
$connection = Arr::merge(Kohana::$config->load('database.default'),array(
|
||||
'login_attr'=>'uid',
|
||||
'connection'=>array(
|
||||
'hostname'=>'localhost',
|
||||
@ -88,7 +86,7 @@ Class LDAPConnection extends Unittest_TestCase {
|
||||
'username'=>$user,
|
||||
'password'=>$password
|
||||
),
|
||||
);
|
||||
));
|
||||
|
||||
// Ensure we start with a clean auth connection.
|
||||
LDAP::factory('auth')->disconnect();
|
||||
|
Reference in New Issue
Block a user