DbalReader::count()   A
last analyzed

Complexity

Conditions 4
Paths 4

Size

Total Lines 15

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 20

Importance

Changes 0
Metric Value
dl 0
loc 15
ccs 0
cts 14
cp 0
rs 9.7666
c 0
b 0
f 0
cc 4
nc 4
nop 0
crap 20
1
<?php
2
3
namespace Mathielen\DataImport\Reader;
4
5
use Ddeboer\DataImport\Reader\CountableReaderInterface;
6
use Doctrine\DBAL\Connection;
7
use Doctrine\DBAL\Statement;
8
9
class DbalReader implements CountableReaderInterface
10
{
11
    /** @var Connection */
12
    private $connection;
13
14
    private $data;
15
16
    /** @var Statement */
17
    private $stmt;
18
19
    /** @var string */
20
    private $sql;
21
    /** @var array */
22
    private $params;
23
24
    /** @var integer */
25
    private $rowCount;
26
    /** @var bool */
27
    private $rowCountCalculated = true;
28
29
    private $key;
30
31
    /**
32
     * Constructor
33
     *
34
     * @param Connection $connection Database connection
35
     * @param string     $sql        SQL statement
36
     * @param array      $params     SQL statement parameters
37
     */
38
    public function __construct(Connection $connection, $sql, array $params = array())
39
    {
40
        $this->connection = $connection;
41
42
        $this->setSql($sql, $params);
43
    }
44
45
    /**
46
     * Do calculate row count?
47
     *
48
     * @param bool $calculate
49
     *
50
     * @return $this
51
     */
52
    public function setRowCountCalculated($calculate = true)
53
    {
54
        $this->rowCountCalculated = (bool) $calculate;
55
56
        return $this;
57
    }
58
59
    /**
60
     * Is row count calculated?
61
     *
62
     * @return bool
63
     */
64
    public function isRowCountCalculated()
65
    {
66
        return $this->rowCountCalculated;
67
    }
68
69
    /**
70
     * {@inheritdoc}
71
     */
72
    public function getFields()
73
    {
74
        if (null === $this->data) {
75
            $this->rewind();
76
        }
77
        if (false === $this->data) {
78
            return array();
79
        }
80
81
        return array_keys((array) $this->data);
82
    }
83
84
    /**
85
     * Set Query string with Parameters
86
     *
87
     * @param string $sql
88
     * @param array  $params
89
     *
90
     * @return $this
91
     */
92
    public function setSql($sql, array $params = array())
93
    {
94
        $this->sql = (string) $sql;
95
96
        $this->setSqlParameters($params);
97
98
        return $this;
99
    }
100
101
    /**
102
     * Set SQL parameters
103
     *
104
     * @param array  $params
105
     *
106
     * @return $this
107
     */
108
    public function setSqlParameters(array $params)
109
    {
110
        $this->params = $params;
111
112
        $this->stmt = null;
113
        $this->rowCount = null;
114
115
        return $this;
116
    }
117
118
    /**
119
     * {@inheritdoc}
120
     */
121
    public function current()
122
    {
123
        if (null === $this->data) {
124
            $this->rewind();
125
        }
126
127
        return $this->data;
128
    }
129
130
    /**
131
     * {@inheritdoc}
132
     */
133
    public function next()
134
    {
135
        $this->key++;
136
        $this->data = $this->stmt->fetch(\PDO::FETCH_ASSOC);
0 ignored issues
show
Deprecated Code introduced by
The method Doctrine\DBAL\Statement::fetch() has been deprecated with message: Use fetchNumeric(), fetchAssociative() or fetchOne() instead.

This method has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the method will be removed from the class and what other method or class to use instead.

Loading history...
137
    }
138
139
    /**
140
     * {@inheritdoc}
141
     */
142
    public function key()
143
    {
144
        return $this->key;
145
    }
146
147
    /**
148
     * {@inheritdoc}
149
     */
150
    public function valid()
151
    {
152
        if (null === $this->data) {
153
            $this->rewind();
154
        }
155
156
        return (false !== $this->data);
157
    }
158
159
    /**
160
     * {@inheritdoc}
161
     */
162
    public function rewind()
163
    {
164
        if (null === $this->stmt) {
165
            $this->stmt = $this->prepare($this->sql, $this->params);
166
        }
167
        if (0 !== $this->key) {
168
            $this->stmt->execute();
169
            $this->data = $this->stmt->fetch(\PDO::FETCH_ASSOC);
0 ignored issues
show
Deprecated Code introduced by
The method Doctrine\DBAL\Statement::fetch() has been deprecated with message: Use fetchNumeric(), fetchAssociative() or fetchOne() instead.

This method has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the method will be removed from the class and what other method or class to use instead.

Loading history...
170
            $this->key = 0;
171
        }
172
    }
173
174
    /**
175
     * {@inheritdoc}
176
     */
177
    public function count()
178
    {
179
        if (null === $this->rowCount) {
180
            if ($this->rowCountCalculated) {
181
                $this->doCalcRowCount();
182
            } else {
183
                if (null === $this->stmt) {
184
                    $this->rewind();
185
                }
186
                $this->rowCount = $this->stmt->rowCount();
187
            }
188
        }
189
190
        return $this->rowCount;
191
    }
192
193
    private function doCalcRowCount()
194
    {
195
        $statement = $this->prepare('SELECT COUNT(*) FROM ('.$this->sql.') AS cnt', $this->params);
196
        $statement->execute();
197
198
        $this->rowCount = (int) $statement->fetchColumn(0);
0 ignored issues
show
Deprecated Code introduced by
The method Doctrine\DBAL\Statement::fetchColumn() has been deprecated with message: Use fetchOne() instead.

This method has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the method will be removed from the class and what other method or class to use instead.

Loading history...
199
    }
200
201
    /**
202
     * Prepare given statement
203
     *
204
     * @param string $sql
205
     * @param array  $params
206
     *
207
     * @return Statement
208
     */
209
    private function prepare($sql, array $params)
210
    {
211
        $statement = $this->connection->prepare($sql);
212
        foreach ($params as $key => $value) {
213
            $statement->bindValue($key, $value);
214
        }
215
216
        return $statement;
217
    }
218
}
219