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']);
|
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() {
|
public function current() {
|
||||||
|
if (! $this->_current_entry)
|
||||||
|
return array();
|
||||||
|
|
||||||
if ($this->_as_object === TRUE) {
|
if ($this->_as_object === TRUE) {
|
||||||
// Return an stdClass
|
// Return an stdClass
|
||||||
throw HTTP_Exception::factory(501,'Not implemented');
|
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);
|
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) {
|
public function seek($dn) {
|
||||||
$this->_current_entry = ldap_first_entry($this->_result['l'],$this->_result['r']);
|
$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
|
// We didnt find it
|
||||||
return FALSE;
|
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
|
} // 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 $_time_limit = '60'; // LDAP Search Time Limit
|
||||||
private $_db_pending = array(); // LDAP Query Filter to compile
|
private $_db_pending = array(); // LDAP Query Filter to compile
|
||||||
|
|
||||||
|
// Execute the query during a cache hit
|
||||||
|
protected $_force_execute = FALSE;
|
||||||
|
|
||||||
// Cache lifetime
|
// Cache lifetime
|
||||||
protected $_lifetime = NULL;
|
protected $_lifetime = NULL;
|
||||||
|
|
||||||
@ -126,6 +129,26 @@ abstract class Kohana_Database_LDAP_Search {
|
|||||||
return isset($u['']['namingcontexts']) ? $u['']['namingcontexts'] : array();
|
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) {
|
public function deref($val) {
|
||||||
$this->_deref = $val;
|
$this->_deref = $val;
|
||||||
|
|
||||||
@ -147,21 +170,21 @@ abstract class Kohana_Database_LDAP_Search {
|
|||||||
|
|
||||||
$result = array();
|
$result = array();
|
||||||
foreach ($this->_base as $base) {
|
foreach ($this->_base as $base) {
|
||||||
$search = NULL;
|
$result[$base] = NULL;
|
||||||
|
|
||||||
if ($this->_lifetime !== NULL AND $this->_db->caching()) {
|
if ($this->_lifetime !== NULL AND $this->_db->caching()) {
|
||||||
// Set the cache key based on the database instance name and SQL
|
// Set the cache key based on the database instance name and SQL
|
||||||
$cache_key = 'Database::query("'.$this->_db.'","'.$base.'","'.$this->_scope.'","'.$this->_filter.'")';
|
$cache_key = 'Database::query("'.$this->_db.'","'.$base.'","'.$this->_scope.'","'.$this->_filter.'")';
|
||||||
|
|
||||||
// Read the cache first to delete a possible hit with lifetime <= 0
|
// 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
|
// 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
|
// Search is not cached, OR caching is disabled, so we'll query
|
||||||
if (! $search) {
|
if (! $result[$base]) {
|
||||||
switch ($this->_scope) {
|
switch ($this->_scope) {
|
||||||
case 'base':
|
case 'base':
|
||||||
$search = ldap_read($this->_db->connection(),$base,$this->_filter,$this->_attrs,$attrs_only,$this->_size_limit,$this->_time_limit,$this->_deref);
|
$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);
|
$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
|
* @dataProvider hosts
|
||||||
*/
|
*/
|
||||||
function testConnect($host,$port,$instance,$expect) {
|
function testConnect($host,$port,$instance,$expect) {
|
||||||
$connection = array(
|
$connection = Arr::merge(Kohana::$config->load('database.default'),array(
|
||||||
'type'=>'LDAP',
|
|
||||||
'connection'=>array('hostname'=>$host,'port'=>$port),
|
'connection'=>array('hostname'=>$host,'port'=>$port),
|
||||||
);
|
));
|
||||||
|
|
||||||
$x = LDAP::factory($instance,NULL,$connection);
|
$x = LDAP::factory($instance,NULL,$connection);
|
||||||
$x->connect();
|
$x->connect();
|
||||||
@ -79,8 +78,7 @@ Class LDAPConnection extends Unittest_TestCase {
|
|||||||
* @depends testConnect
|
* @depends testConnect
|
||||||
*/
|
*/
|
||||||
function testAuthConfiguration($user,$password,$expect) {
|
function testAuthConfiguration($user,$password,$expect) {
|
||||||
$connection = array(
|
$connection = Arr::merge(Kohana::$config->load('database.default'),array(
|
||||||
'type'=>'LDAP',
|
|
||||||
'login_attr'=>'uid',
|
'login_attr'=>'uid',
|
||||||
'connection'=>array(
|
'connection'=>array(
|
||||||
'hostname'=>'localhost',
|
'hostname'=>'localhost',
|
||||||
@ -88,7 +86,7 @@ Class LDAPConnection extends Unittest_TestCase {
|
|||||||
'username'=>$user,
|
'username'=>$user,
|
||||||
'password'=>$password
|
'password'=>$password
|
||||||
),
|
),
|
||||||
);
|
));
|
||||||
|
|
||||||
// Ensure we start with a clean auth connection.
|
// Ensure we start with a clean auth connection.
|
||||||
LDAP::factory('auth')->disconnect();
|
LDAP::factory('auth')->disconnect();
|
||||||
|
Reference in New Issue
Block a user