Skip to content

Instantly share code, notes, and snippets.

@zhouyl
Created July 17, 2014 04:34
Show Gist options
  • Select an option

  • Save zhouyl/ae8fbc130045bd74fcb9 to your computer and use it in GitHub Desktop.

Select an option

Save zhouyl/ae8fbc130045bd74fcb9 to your computer and use it in GitHub Desktop.
Kohana Database Iterator
<?php defined('SYSPATH') or die('No direct script access.');
/**
* 数据库迭代器
*/
class Database_Iterator implements SeekableIterator, Countable
{
/**
* select 查询语句
*
* @var Database_Query_Builder_Select
*/
protected $select = NULL;
/**
* 数据库实例名
*
* @var string
*/
protected $db = NULL;
/**
* 迭代步长
*
* @var int
*/
protected $step = 20;
/**
* 总页数
*
* @var int
*/
protected $count = NULL;
/**
* 总记录数
*
* @var int
*/
protected $total = NULL;
/**
* 数据指针
*
* @var int
*/
protected $position = 0;
/**
* 构造方法
*
* @param Database_Query_Builder_Select $select
* @param string $db
* @param int $step
*/
public function __construct(Database_Query_Builder_Select $select, $db = NULL, $step = NULL)
{
$this->select = $select;
$this->db = $db;
if ( ! is_null($step))
{
$this->step($step);
}
}
/**
* 设置迭代步长
*
* @param int $step
* @throws Exception
*/
public function step($step)
{
if ( ! (is_numeric($step) AND $step > 0))
{
throw new Exception('数据库迭代器 (DB_Iterator) 的步长必须为数字且大于 0');
}
// 重置游标与数据
if ($step !== $this->step)
{
$this->position = 0;
}
$this->step = $step;
}
/**
* 获取当前的数据迭代器
*
* @return array
*/
public function current()
{
return $this->select->limit($this->step)
->offset($this->position * $this->step)
->execute($this->db)
->as_array();
}
/**
* 将指针下移,并返回数据
*
* @throws Exception
*/
public function next()
{
if ($this->position >= $this->count())
{
throw new Exception('当前指针已指向记录最底部');
}
$this->position++;
}
/**
* 返回当前指针
*
* @return int
*/
public function key()
{
return $this->position;
}
/**
* 重置内部指针
*/
public function rewind()
{
$this->position = 0;
}
/**
* 返回当前位置是否有数据
*
* @return bool
*/
public function valid()
{
return ($this->position < $this->count());
}
/**
* 定位指针位置
*
* @param int $position
* @throws Exception
*/
public function seek($position)
{
if ($position >= $this->count() OR $position < 0)
{
throw new Exception('无效的指针位置');
}
$this->position = $position;
}
/**
* 实现 Countable 接口,获取迭代总步长 (总页数)
*
* @return int
*/
public function count()
{
if ($this->count === NULL)
{
$this->count = ceil($this->total() / $this->step);
}
return $this->count;
}
/**
* 统计记录总数
*
* @reutrn int
*/
public function total()
{
if ($this->total === NULL)
{
$this->total = $this->select->count_all($this->db);
}
return $this->total;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment