Skip to content
This repository
Browse code

Refactoring of CDataProviderIterator

  • Loading branch information...
commit 7150d84ac1eac5e82cac6e7fe6f33451aaceb61d 1 parent 93e0d8f
Carsten Brandt authored November 14, 2012
138  framework/web/CDataProviderIterator.php
@@ -12,9 +12,9 @@
12 12
  * CDataProviderIterator allows iteration over large data sets without holding the entire set in memory.
13 13
  *
14 14
  * CDataProviderIterator iterates over the results of a data provider, starting at the first page
15  
- * of results and ending at the last page. It is usually only suited for use with CActiveDataProvider.
  15
+ * of results and ending at the last page. It is usually only suited for use with {@link CActiveDataProvider}.
16 16
  *
17  
- * For example, the following code will iterate through all registered users without
  17
+ * For example, the following code will iterate over all registered users (active record class User) without
18 18
  * running out of memory, even if there are millions of users in the database.
19 19
  * <pre>
20 20
  * $dataProvider = new CActiveDataProvider("User");
@@ -24,128 +24,70 @@
24 24
  * }
25 25
  * </pre>
26 26
  *
27  
- * @property array $items the currently loaded items
28  
- * @property integer $currentIndex the 0 based current index
29  
- * @property integer $totalItems the total number of items in the iterator
  27
+ * @property CDataProvider $dataProvider the data provider to iterate over
  28
+ * @property integer $totalItemCount the total number of items in the iterator
30 29
  *
31 30
  * @author Charles Pick <charles.pick@gmail.com>
  31
+ * @author Carsten Brandt <mail@cebe.cc>
32 32
  * @package system.web
33  
- * @since 1.1.11
  33
+ * @since 1.1.13
34 34
  */
35  
-class CDataProviderIterator implements Iterator, Countable
  35
+class CDataProviderIterator extends CComponent implements Iterator, Countable
36 36
 {
37  
-
38  
-	/**
39  
-	 * The data provider to iterate over
40  
-	 *
41  
-	 * @var CDataProvider
42  
-	 */
43  
-	public $dataProvider;
44  
-
45  
-	/**
46  
-	 * The current index
47  
-	 *
48  
-	 * @var integer
49  
-	 */
  37
+	private $_dataProvider;
50 38
 	private $_currentIndex=-1;
51  
-
52  
-	/**
53  
-	 * The current page in the pagination
54  
-	 *
55  
-	 * @var integer
56  
-	 */
57 39
 	private $_currentPage=0;
58  
-
59  
-	/**
60  
-	 * The total number of items
61  
-	 *
62  
-	 * @var integer
63  
-	 */
64  
-	private $_totalItems=-1;
65  
-
66  
-	/**
67  
-	 * The current set of items
68  
-	 *
69  
-	 * @var array
70  
-	 */
  40
+	private $_totalItemCount=-1;
71 41
 	private $_items;
72 42
 
73 43
 	/**
74  
-	 * Constructor. Sets the data provider to iterator over
75  
-	 *
  44
+	 * Constructor.
76 45
 	 * @param CDataProvider $dataProvider the data provider to iterate over
  46
+	 * @param integer $pageSize pageSize to use for iteration. This is the number of objects loaded into memory at the same time.
77 47
 	 */
78  
-	public function __construct(CDataProvider $dataProvider)
  48
+	public function __construct(CDataProvider $dataProvider, $pageSize=null)
79 49
 	{
80  
-		$this->dataProvider=$dataProvider;
81  
-		$this->_totalItems=$dataProvider->getTotalItemCount();
82  
-	}
83  
-
84  
-	/**
85  
-	 * Sets the current index position
86  
-	 *
87  
-	 * @param integer $currentIndex the current index positon
88  
-	 */
89  
-	public function setCurrentIndex($currentIndex)
90  
-	{
91  
-		$this->_currentIndex=$currentIndex;
92  
-	}
  50
+		$this->_dataProvider=$dataProvider;
  51
+		$this->_totalItemCount=$dataProvider->getTotalItemCount();
93 52
 
94  
-	/**
95  
-	 * Gets the zero based current index position
96  
-	 *
97  
-	 * @return integer index position
98  
-	 */
99  
-	public function getCurrentIndex()
100  
-	{
101  
-		return $this->_currentIndex;
102  
-	}
  53
+		if(($pagination=$this->_dataProvider->getPagination())===false)
  54
+			$this->_dataProvider->setPagination(new CPagination());
103 55
 
104  
-	/**
105  
-	 * Gets the current set of items to iterate over
106  
-	 *
107  
-	 * @return array the current set items to iterate over
108  
-	 */
109  
-	public function getItems()
110  
-	{
111  
-		return $this->_items;
  56
+		if($pageSize!==null)
  57
+			$pagination->setPageSize($pageSize);
112 58
 	}
113 59
 
114 60
 	/**
115  
-	 * Sets the total number of items to iterate over
116  
-	 *
117  
-	 * @param int $totalItems the total number of items to iterate over
  61
+	 * Returns the data provider to iterate over
  62
+	 * @return CDataProvider the data provider to iterate over
118 63
 	 */
119  
-	public function setTotalItems($totalItems)
  64
+	public function getDataProvider()
120 65
 	{
121  
-		$this->_totalItems=$totalItems;
  66
+		return $this->_dataProvider;
122 67
 	}
123 68
 
124 69
 	/**
125 70
 	 * Gets the total number of items to iterate over
126  
-	 *
127 71
 	 * @return integer the total number of items to iterate over
128 72
 	 */
129  
-	public function getTotalItems()
  73
+	public function getTotalItemCount()
130 74
 	{
131  
-		return $this->_totalItems;
  75
+		return $this->_totalItemCount;
132 76
 	}
133 77
 
134 78
 	/**
135  
-	 * Loads the page of results
136  
-	 *
  79
+	 * Loads a page of items
137 80
 	 * @return array the items from the next page of results
138 81
 	 */
139 82
 	protected function loadPage()
140 83
 	{
141  
-		$this->dataProvider->getPagination()->setCurrentPage($this->_currentPage);
  84
+		$this->_dataProvider->getPagination()->setCurrentPage($this->_currentPage);
142 85
 		return $this->_items=$this->dataProvider->getData(true);
143 86
 	}
144 87
 
145 88
 	/**
146 89
 	 * Gets the current item in the list.
147  
-	 * This method is required by the Iterator interface
148  
-	 *
  90
+	 * This method is required by the Iterator interface.
149 91
 	 * @return mixed the current item in the list
150 92
 	 */
151 93
 	public function current()
@@ -155,26 +97,24 @@ public function current()
155 97
 
156 98
 	/**
157 99
 	 * Gets the key of the current item.
158  
-	 * This method is required by the Iterator interface
159  
-	 *
  100
+	 * This method is required by the Iterator interface.
160 101
 	 * @return integer the key of the current item
161 102
 	 */
162 103
 	public function key()
163 104
 	{
164  
-		$pagination=$this->dataProvider->getPagination();
165  
-		$pageSize=$pagination->getPageSize();
  105
+		$pageSize=$this->_dataProvider->getPagination()->getPageSize();
166 106
 		return $this->_currentPage*$pageSize+$this->_currentIndex;
167 107
 	}
168 108
 
169 109
 	/**
170 110
 	 * Moves the pointer to the next item in the list.
171  
-	 * This method is required by the Iterator interface
  111
+	 * This method is required by the Iterator interface.
172 112
 	 */
173 113
 	public function next()
174 114
 	{
175  
-		$pagination=$this->dataProvider->getPagination();
  115
+		$pageSize=$this->_dataProvider->getPagination()->getPageSize();
176 116
 		$this->_currentIndex++;
177  
-		if($this->_currentIndex>=$pagination->getPageSize())
  117
+		if($this->_currentIndex >= $pageSize)
178 118
 		{
179 119
 			$this->_currentPage++;
180 120
 			$this->_currentIndex=0;
@@ -184,7 +124,7 @@ public function next()
184 124
 
185 125
 	/**
186 126
 	 * Rewinds the iterator to the start of the list.
187  
-	 * This method is required by the Iterator interface
  127
+	 * This method is required by the Iterator interface.
188 128
 	 */
189 129
 	public function rewind()
190 130
 	{
@@ -195,23 +135,21 @@ public function rewind()
195 135
 
196 136
 	/**
197 137
 	 * Checks if the current position is valid or not.
198  
-	 * This method is required by the Iterator interface
199  
-	 *
  138
+	 * This method is required by the Iterator interface.
200 139
 	 * @return boolean true if this index is valid
201 140
 	 */
202 141
 	public function valid()
203 142
 	{
204  
-		return $this->key()<$this->_totalItems;
  143
+		return $this->key() < $this->_totalItemCount;
205 144
 	}
206 145
 
207 146
 	/**
208  
-	 * Gets the total number of items in the dataProvider
209  
-	 * This method is required by the Countable interface
210  
-	 *
  147
+	 * Gets the total number of items in the dataProvider.
  148
+	 * This method is required by the Countable interface.
211 149
 	 * @return integer the total number of items
212 150
 	 */
213 151
 	public function count()
214 152
 	{
215  
-		return $this->_totalItems;
  153
+		return $this->_totalItemCount;
216 154
 	}
217 155
 }
31  tests/framework/web/CDataProviderIteratorTest.php
@@ -2,25 +2,42 @@
2 2
 Yii::import("system.web.*");
3 3
 /**
4 4
  * Tests for the {@link CDataProviderIterator} class
5  
- * @author Charles Pick
  5
+ * @author Charles Pick <charles.pick@gmail.com>
6 6
  */
7 7
 class CDataProviderIteratorTest extends CTestCase
8 8
 {
  9
+	public function pageSizes()
  10
+	{
  11
+		return array(
  12
+			array(null),
  13
+			array(1),
  14
+			array(10),
  15
+			array(110),
  16
+		);
  17
+	}
  18
+
9 19
 	/**
10 20
 	 * Tests the iterator
  21
+	 *
  22
+	 * @dataProvider pageSizes
11 23
 	 */
12  
-	public function testIterator()
  24
+	public function testIterator($pageSize)
13 25
 	{
14  
-		$dataProvider = new CArrayDataProvider($this->generateData());
15  
-		$iterator = new CDataProviderIterator($dataProvider);
16  
-		$this->assertEquals(100, $iterator->getTotalItems());
  26
+		$dataProvider = new CArrayDataProvider($this->generateData(100));
  27
+		$iterator = new CDataProviderIterator($dataProvider, $pageSize);
  28
+
  29
+		$this->assertTrue($iterator->getDataProvider()===$dataProvider);
  30
+
  31
+		$this->assertEquals(100, $iterator->getTotalItemCount());
17 32
 		$this->assertEquals(100, count($iterator));
  33
+
18 34
 		$n = 0;
19 35
 		foreach($iterator as $item) {
20 36
 			$this->assertEquals("Item ".$n,$item['name']);
21 37
 			$n++;
22  
-
23 38
 		}
  39
+
  40
+		$this->assertEquals(100, $n);
24 41
 	}
25 42
 
26 43
 	/**
@@ -28,7 +45,7 @@ public function testIterator()
28 45
 	 * @param integer $totalItems the total number of items to generate
29 46
 	 * @return array the data
30 47
 	 */
31  
-	protected function generateData($totalItems = 100)
  48
+	protected function generateData($totalItems)
32 49
 	{
33 50
 		$data = array();
34 51
 		for($i = 0; $i < $totalItems; $i++) {

0 notes on commit 7150d84

Please sign in to comment.
Something went wrong with that request. Please try again.