Completed
Push — master ( 406540...d6cfd6 )
by Markus
12:09
created

DbalReader::setSql()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 8
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 0
Metric Value
dl 0
loc 8
ccs 0
cts 6
cp 0
rs 9.4285
c 0
b 0
f 0
cc 1
eloc 4
nc 1
nop 2
crap 2
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);
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);
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);
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