1
|
|
|
<?php |
2
|
|
|
|
3
|
|
|
namespace ByJG\AnyDataset\Dataset; |
4
|
|
|
|
5
|
|
|
use ByJG\AnyDataset\Exception\IteratorException; |
6
|
|
|
use ForceUTF8\Encoding; |
7
|
|
|
use PDO; |
8
|
|
|
use PDOStatement; |
9
|
|
|
|
10
|
|
|
class DbIterator extends GenericIterator |
11
|
|
|
{ |
12
|
|
|
|
13
|
|
|
const RECORD_BUFFER = 50; |
14
|
|
|
|
15
|
|
|
private $rowBuffer; |
16
|
|
|
private $currentRow = 0; |
17
|
|
|
|
18
|
|
|
/** |
19
|
|
|
* @var PDOStatement |
20
|
|
|
*/ |
21
|
|
|
private $statement; |
22
|
|
|
|
23
|
|
|
/** |
24
|
|
|
* @param PDOStatement $recordset |
25
|
|
|
*/ |
26
|
8 |
|
public function __construct($recordset) |
27
|
|
|
{ |
28
|
8 |
|
$this->statement = $recordset; |
29
|
8 |
|
$this->rowBuffer = array(); |
30
|
8 |
|
} |
31
|
|
|
|
32
|
|
|
/** |
33
|
|
|
* @return int |
34
|
|
|
*/ |
35
|
|
|
public function count() |
36
|
|
|
{ |
37
|
|
|
return $this->statement->rowCount(); |
38
|
|
|
} |
39
|
|
|
|
40
|
|
|
/** |
41
|
|
|
* @return bool |
42
|
|
|
*/ |
43
|
8 |
|
public function hasNext() |
44
|
|
|
{ |
45
|
8 |
|
if (count($this->rowBuffer) >= DbIterator::RECORD_BUFFER) { |
46
|
|
|
return true; |
47
|
|
|
} |
48
|
|
|
|
49
|
8 |
|
if (is_null($this->statement)) { |
50
|
6 |
|
return (count($this->rowBuffer) > 0); |
51
|
|
|
} |
52
|
|
|
|
53
|
8 |
|
$rowArray = $this->statement->fetch(PDO::FETCH_ASSOC); |
54
|
8 |
|
if (!empty($rowArray)) { |
55
|
6 |
|
foreach ($rowArray as $key => $value) { |
56
|
6 |
|
if (is_null($value)) { |
57
|
|
|
$rowArray[$key] = ""; |
58
|
6 |
|
} elseif (is_object($value)) { |
59
|
|
|
$rowArray[$key] = "[OBJECT]"; |
60
|
|
|
} else { |
61
|
6 |
|
$rowArray[$key] = Encoding::toUTF8($value); |
62
|
|
|
} |
63
|
6 |
|
} |
64
|
6 |
|
$singleRow = new Row($rowArray); |
65
|
|
|
|
66
|
|
|
// Enfileira o registo |
67
|
6 |
|
array_push($this->rowBuffer, $singleRow); |
68
|
|
|
// Traz novos até encher o Buffer |
69
|
6 |
|
if (count($this->rowBuffer) < DbIterator::RECORD_BUFFER) { |
70
|
6 |
|
$this->hasNext(); |
71
|
6 |
|
} |
72
|
|
|
|
73
|
6 |
|
return true; |
74
|
|
|
} |
75
|
|
|
|
76
|
8 |
|
$this->statement->closeCursor(); |
77
|
8 |
|
$this->statement = null; |
78
|
|
|
|
79
|
8 |
|
return (count($this->rowBuffer) > 0); |
80
|
|
|
} |
81
|
|
|
|
82
|
|
|
/** |
83
|
|
|
* @return Row |
84
|
|
|
* @throws IteratorException |
85
|
|
|
*/ |
86
|
6 |
View Code Duplication |
public function moveNext() |
|
|
|
|
87
|
|
|
{ |
88
|
6 |
|
if (!$this->hasNext()) { |
89
|
|
|
throw new IteratorException("No more records. Did you used hasNext() before moveNext()?"); |
90
|
|
|
} else { |
91
|
6 |
|
$singleRow = array_shift($this->rowBuffer); |
92
|
6 |
|
$this->currentRow++; |
93
|
6 |
|
return $singleRow; |
94
|
|
|
} |
95
|
|
|
} |
96
|
|
|
|
97
|
|
|
public function key() |
98
|
|
|
{ |
99
|
|
|
return $this->currentRow; |
100
|
|
|
} |
101
|
|
|
} |
102
|
|
|
|
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.
You can also find more detailed suggestions in the “Code” section of your repository.