Subversion-Projekte lars-tiefland.prado

Revision

Details | Letzte Änderung | Log anzeigen | RSS feed

Revision Autor Zeilennr. Zeile
1 lars 1
<?php
2
/**
3
 * TSqlMapPagedList class file.
4
 *
5
 * @author Wei Zhuo <weizhuo[at]gmail[dot]com>
6
 * @link http://www.pradosoft.com/
7
 * @copyright Copyright &copy; 2005-2008 PradoSoft
8
 * @license http://www.pradosoft.com/license/
9
 * @version $Id: TSqlMapPagedList.php 2541 2008-10-21 15:05:13Z qiang.xue $
10
 * @package System.Data.SqlMap
11
 */
12
 
13
Prado::using('System.Collections.TPagedList');
14
 
15
/**
16
 * TSqlMapPagedList implements a list with paging functionality that retrieves
17
 * data from a SqlMap statement.
18
 *
19
 * The maximum number of records fetched is 3 times the page size. It fetches
20
 * the current, the previous and the next page at a time. This allows the paged
21
 * list to determine if the page is a the begin, the middle or the end of the list.
22
 *
23
 * The paged list does not need to know about the total number of records.
24
 *
25
 * @author Wei Zhuo <weizhuo[at]gmail[dot]com>
26
 * @version $Id: TSqlMapPagedList.php 2541 2008-10-21 15:05:13Z qiang.xue $
27
 * @package System.Data.SqlMap
28
 * @since 3.1
29
 */
30
class TSqlMapPagedList extends TPagedList
31
{
32
	private $_statement;
33
	private $_parameter;
34
	private $_prevPageList;
35
	private $_nextPageList;
36
	private $_delegate=null;
37
 
38
	/**
39
	 * Create a new SqlMap paged list.
40
	 * @param IMappedStatement SqlMap statement.
41
	 * @param mixed query parameters
42
	 * @param int page size
43
	 * @param mixed delegate for each data row retrieved.
44
	 * @param int number of page to fetch on initialization
45
	 */
46
	public function __construct(IMappedStatement $statement,$parameter, $pageSize, $delegate=null, $page=0)
47
	{
48
		parent::__construct();
49
		parent::setCustomPaging(true);
50
		$this->initialize($statement,$parameter, $pageSize, $page);
51
		$this->_delegate=$delegate;
52
	}
53
 
54
	/**
55
	 * Initialize the paged list.
56
	 * @param IMappedStatement SqlMap statement.
57
	 * @param mixed query parameters
58
	 * @param int page size.
59
	 * @param int number of page.
60
	 */
61
	protected function initialize($statement, $parameter, $pageSize, $page)
62
	{
63
		$this->_statement = $statement;
64
		$this->_parameter = $parameter;
65
		$this->setPageSize($pageSize);
66
		$this->attachEventHandler('OnFetchData', array($this, 'fetchDataFromStatement'));
67
		$this->gotoPage($page);
68
	}
69
 
70
	/**
71
	 * @throws TSqlMapException custom paging must be enabled.
72
	 */
73
	public function setCustomPaging($value)
74
	{
75
		throw new TSqlMapException('sqlmap_must_enable_custom_paging');
76
	}
77
 
78
	/**
79
	 * Fetch data by executing the SqlMap statement.
80
	 * @param TPageList current object.
81
	 * @param TPagedListFetchDataEventParameter fetch parameters
82
	 */
83
	protected function fetchDataFromStatement($sender, $param)
84
	{
85
		$limit = $this->getOffsetAndLimit($param);
86
		$connection = $this->_statement->getManager()->getDbConnection();
87
		$data = $this->_statement->executeQueryForList($connection,
88
						$this->_parameter, null, $limit[0], $limit[1], $this->_delegate);
89
		$this->populateData($param, $data);
90
	}
91
 
92
	/**
93
	 * Switches to the next page.
94
	 * @return integer|boolean the new page index, false if next page is not availabe.
95
	 */
96
	public function nextPage()
97
	{
98
		return $this->getIsNextPageAvailable() ? parent::nextPage() : false;
99
	}
100
 
101
	/**
102
	 * Switches to the previous page.
103
	 * @return integer|boolean the new page index, false if previous page is not availabe.
104
	 */
105
	public function previousPage()
106
	{
107
		return $this->getIsPreviousPageAvailable() ? parent::previousPage() : false;
108
	}
109
 
110
	/**
111
	 * Populate the list with the fetched data.
112
	 * @param TPagedListFetchDataEventParameter fetch parameters
113
	 * @param array fetched data.
114
	 */
115
	protected function populateData($param, $data)
116
	{
117
		$total = $data instanceof TList ? $data->getCount() : count($data);
118
		$pageSize = $this->getPageSize();
119
		if($total < 1)
120
		{
121
			$param->setData($data);
122
			$this->_prevPageList = null;
123
			$this->_nextPageList = null;
124
			return;
125
		}
126
 
127
		if($param->getNewPageIndex() < 1)
128
		{
129
			$this->_prevPageList = null;
130
			if($total <= $pageSize)
131
			{
132
				$param->setData($data);
133
				$this->_nextPageList = null;
134
			}
135
			else
136
			{
137
				$param->setData(array_slice($data, 0, $pageSize));
138
				$this->_nextPageList = array_slice($data, $pageSize-1,$total);
139
			}
140
		}
141
		else
142
		{
143
			if($total <= $pageSize)
144
			{
145
				$this->_prevPageList = array_slice($data, 0, $total);
146
				$param->setData(array());
147
				$this->_nextPageList = null;
148
			}
149
			else if($total <= $pageSize*2)
150
			{
151
				$this->_prevPageList = array_slice($data, 0, $pageSize);
152
				$param->setData(array_slice($data, $pageSize, $total));
153
				$this->_nextPageList = null;
154
			}
155
			else
156
			{
157
				$this->_prevPageList = array_slice($data, 0, $pageSize);
158
				$param->setData(array_slice($data, $pageSize, $pageSize));
159
				$this->_nextPageList = array_slice($data, $pageSize*2, $total-$pageSize*2);
160
			}
161
		}
162
	}
163
 
164
	/**
165
	 * Calculate the data fetch offsets and limits.
166
	 * @param TPagedListFetchDataEventParameter fetch parameters
167
	 * @return array 1st element is the offset, 2nd element is the limit.
168
	 */
169
	protected function getOffsetAndLimit($param)
170
	{
171
		$index = $param->getNewPageIndex();
172
		$pageSize = $this->getPageSize();
173
		return $index < 1 ? array($index, $pageSize*2) : array(($index-1)*$pageSize, $pageSize*3);
174
	}
175
 
176
	/**
177
	 * @return boolean true if the next page is available, false otherwise.
178
	 */
179
	public function getIsNextPageAvailable()
180
	{
181
		return !is_null($this->_nextPageList);
182
	}
183
 
184
	/**
185
	 * @return boolean true if the previous page is available, false otherwise.
186
	 */
187
	public function getIsPreviousPageAvailable()
188
	{
189
		return !is_null($this->_prevPageList);
190
	}
191
 
192
	/**
193
	 * @return boolean true if is the very last page, false otherwise.
194
	 */
195
	public function getIsLastPage()
196
	{
197
		return is_null($this->_nextPageList) || $this->_nextPageList->getCount() < 1;
198
	}
199
 
200
	/**
201
	 * @return boolean true if is not first nor last page, false otherwise.
202
	 */
203
	public function getIsMiddlePage()
204
	{
205
		return !($this->getIsFirstPage() || $this->getIsLastPage());
206
	}
207
}
208