<?php
/**
* class oLimit implements Iterator
* @author johan <johan.barbier@gmail.com>
* @version 20061205
*/
abstract class oLimit implements Iterator {
/**
* Number of items to retrieve
*
* @var integer
*/
protected $iCount;
/**
* Starting offset
*
* @var integer
*/
protected $iOffset;
/**
* Total number of items for the request
*
* @var unknown_type
*/
protected $iMax;
/**
* Current internal position
* @var integer
*/
protected $iPos = 0;
/**
* Exception messages
*
*/
const ERROR_COUNT_EMPTY = 'iCount cannot be equal to 0';
const ERROR_NO_INTEGER = 'iCount and iOffset parameters must be integer';
const ERROR_NEGATIVE = 'iOffset cannot be negative';
/**
* Constructor
* set some parameters
*
* @param integer $iOffset
* @param integer $iCount
*/
protected function __construct ($iOffset = 0, $iCount = -1) {
if (!is_int ($iOffset) || !is_int ($iCount)) {
throw new Exception (self::ERROR_NO_INTEGER);
}
if ($iOffset < 0) {
throw new Exception (self::ERROR_NEGATIVE);
}
if ($iCount === 0) {
throw new Exception (self::ERROR_COUNT_EMPTY);
}
$this -> iOffset = $iOffset;
$this -> iCount = $iCount;
$this -> iMax = $this -> countMax ();
}
/**
* Iterator method
* Moves the internal cursor to the next position
*
*/
public function next () {
$this -> iPos ++;
}
/**
* Iterator method
* Checks the validity of the current position
* If iCount === -1, then we go up to the end of the request (total number of items iMax)
* If not, we check if the current position iPos is equal or greater than the number of items to retrieve (iCount)
*
* @return boolean
*/
public function valid () {
if (($this -> iOffset + $this -> iPos) > $this -> iMax) {
return false;
}
if ($this -> iCount > -1 && $this -> iPos >= $this -> iCount) {
return false;
}
return true;
}
/**
* Returns the current internal position
*
* @return integer
*/
public function getInternalPos () {
return $this -> iPos;
}
/**
* Returns the current request position
*
* @return integer
*/
public function getExternalPos () {
return $this -> iPos + $this -> iOffset;
}
/**
* Returns the total number of items in the request
*
* @return integer
*/
public function getExternalCount () {
return $this -> iMax + 1;
}
abstract protected function countMax ();
}
/**
* class mysqlLimit extends oLimit
* @author johan <johan.barbier@gmail.com>
* @version 20061205
*/
class mysqlLimit extends oLimit {
/**
* request resource
*
* @var mysql result resource (comes from mysql_query)
*/
private $rRes;
/**
* Exception messages
*
*/
const ERROR_NO_RESOURCE = 'rRes must be a valid mysql resource';
/**
* Constructor
* Sets some parameters, and set the current position via data_seek
*
* @param mysql result resource $rRes
* @param integer $iOffset
* @param integer $iCount
*/
public function __construct ($rRes, $iOffset = 0, $iCount = -1) {
if (!is_resource ($rRes) || 'mysql result' !== get_resource_type ($rRes)) {
throw new Exception (self::ERROR_NO_RESOURCE);
}
$this -> rRes = $rRes;
parent::__construct ($iOffset, $iCount);
mysql_data_seek ($this -> rRes, $this -> iOffset + $this -> iPos);
}
/**
* Returns the current result array at the current position
*
* @return array
*/
public function current () {
return mysql_fetch_assoc ($this -> rRes);
}
/**
* Checks validity of the current position
*
* @return boolean
*/
public function valid () {
return parent::valid ();
}
/**
* Reset the resource result to the starting offset
*
*/
public function rewind () {
mysql_data_seek ($this -> rRes, $this -> iOffset);
}
/**
* Do not know what do return here
*
* @return void
*/
public function key () {
return false;
//return mysql_fetch_assoc ($this -> rRes);
}
/**
* Returns the total number of items of the query
*
* @return integer
*/
protected function countMax () {
return mysql_num_rows ($this -> rRes) - 1;
}
}
/**
* class mssqlLimit extends oLimit
* see mysqlLimit for documentation
* @author johan <johan.barbier@gmail.com>
* @version 20061205
*/
class mssqlLimit extends oLimit {
private $rRes;
const ERROR_NO_RESOURCE = 'rRes must be a valid mssql resource';
public function __construct ($rRes, $iOffset = 0, $iCount = -1) {
if (!is_int ($rRes) && (!is_resource ($rRes) || 'mssql result' !== get_resource_type ($rRes))) {
throw new Exception (self::ERROR_NO_RESOURCE);
}
$this -> rRes = $rRes;
parent::__construct ($iOffset, $iCount);
mssql_data_seek ($this -> rRes, $this -> iOffset + $this -> iPos);
}
public function current () {
return mssql_fetch_assoc($this -> rRes);
}
public function valid () {
return parent::valid ();
}
public function rewind () {
mssql_data_seek ($this -> rRes, $this -> iOffset);
}
public function key () {
return false;
//return mssql_fetch_assoc ($this -> rRes);
}
protected function countMax () {
return mssql_num_rows ($this -> rRes) - 1;
}
}
/**
* class arrayLimit extends LimitIterator
* @author johan <johan.barbier@gmail.com>
* @version 20061205
*/
class arrayLimit extends LimitIterator {
/**
* Exception messages
*
*/
const ERROR_NO_ARRAY = 'aRes must be an array';
/**
* Constructor
* Sets some parameters and get LimitIterator constructor
*
* @param array $aRes
* @param integer $iOffset
* @param integer $iCount
*/
public function __construct ($aRes, $iOffset = 0, $iCount = -1) {
if (!is_array ($aRes)) {
throw new Exception (self::ERROR_NO_ARRAY);
}
$aIt = new ArrayIterator ($aRes);
parent::__construct ($aIt, $iOffset, $iCount);
$this -> rewind ();
}
}
/**
* class LimitFactory
* factory for the oLimit package (optional)
* @author johan <johan.barbier@gmail.com>
* @version 20061205
*/
class LimitFactory {
/**
* Array of implemented oLimit classes
*
* @var array
*/
private static $aTypes = array (
'MYSQL' => 'mysqlLimit',
'MSSQL' => 'mssqlLimit',
'ARRAY' => 'arrayLimit'
);
/**
* Exception messages
*
*/
const ERROR_NO_VALID_TYPE = '{__TYPE__} is not a valid type';
const ERROR_CLASS_NOT_FOUND = 'class {__CLASS__} has not been found';
/**
* Factory : get the correct object given an implemented oLimit class
*
* @param string $sType
* @param mixed $mRes
* @param integer $iOffset
* @param integer $iCount
* @return object
*/
public static function factory ($sType, $mRes, $iOffset = 0, $iCount = -1) {
if (!array_key_exists ($sType, self::$aTypes)) {
throw new Exception (str_replace ('{__TYPE__}', $sType, self::ERROR_NO_VALID_TYPE));
}
if (!class_exists (self::$aTypes[$sType])) {
throw new Exception (str_replace ('{__CLASS__}', self::$aTypes[$sType], self::ERROR_CLASS_NOT_FOUND));
}
return new self::$aTypes[$sType] ($mRes, $iOffset, $iCount);
}
}
?>
|