Completed
Pull Request — master (#1005)
by Nikola
01:59
created

PdoAdapter::fetchAll()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 10
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 5
CRAP Score 2

Importance

Changes 0
Metric Value
dl 0
loc 10
ccs 5
cts 5
cp 1
rs 9.4285
c 0
b 0
f 0
cc 2
eloc 6
nc 2
nop 1
crap 2
1
<?php
2
/**
3
 * Phinx
4
 *
5
 * (The MIT license)
6
 * Copyright (c) 2015 Rob Morgan
7
 *
8
 * Permission is hereby granted, free of charge, to any person obtaining a copy
9
 * of this software and associated * documentation files (the "Software"), to
10
 * deal in the Software without restriction, including without limitation the
11
 * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
12
 * sell copies of the Software, and to permit persons to whom the Software is
13
 * furnished to do so, subject to the following conditions:
14
 *
15
 * The above copyright notice and this permission notice shall be included in
16
 * all copies or substantial portions of the Software.
17
 *
18
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
23
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
24
 * IN THE SOFTWARE.
25
 *
26
 * @package    Phinx
27
 * @subpackage Phinx\Db\Adapter
28
 */
29
namespace Phinx\Db\Adapter;
30
31
use BadMethodCallException;
32
use Phinx\Db\Table;
33
use Phinx\Migration\MigrationInterface;
34
35
/**
36
 * Phinx PDO Adapter.
37
 *
38
 * @author Rob Morgan <[email protected]>
39
 */
40
abstract class PdoAdapter extends AbstractAdapter
41
{
42
    /**
43
     * @var \PDO|null
44
     */
45
    protected $connection;
46
47
    /**
48
     * {@inheritdoc}
49
     */
50
    public function setOptions(array $options)
51 287
    {
52
        parent::setOptions($options);
53 287
54
        if (isset($options['connection'])) {
55 287
            $this->setConnection($options['connection']);
56 3
        }
57 3
58
        return $this;
59 287
    }
60
61
    /**
62
     * Sets the database connection.
63
     *
64
     * @param \PDO $connection Connection
65
     * @return \Phinx\Db\Adapter\AdapterInterface
66
     */
67
    public function setConnection(\PDO $connection)
68 193
    {
69
        $this->connection = $connection;
70 193
71
        // Create the schema table if it doesn't already exist
72
        if (!$this->hasSchemaTable()) {
73 193
            $this->createSchemaTable();
74 191
        } else {
75 191
            $table = new Table($this->getSchemaTableName(), [], $this);
76 74
            if (!$table->hasColumn('migration_name')) {
77 74
                $table
78
                    ->addColumn(
79
                        'migration_name',
80
                        'string',
81
                        ['limit' => 100, 'after' => 'version', 'default' => null, 'null' => true]
82
                    )
83
                    ->save();
84
            }
85
            if (!$table->hasColumn('breakpoint')) {
86 74
                $table
87
                    ->addColumn('breakpoint', 'boolean', ['default' => false])
88
                    ->save();
89
            }
90
        }
91
92
        return $this;
93 193
    }
94
95
    /**
96
     * Gets the database connection
97
     *
98
     * @return \PDO
99
     */
100
    public function getConnection()
101 191
    {
102
        if ($this->connection === null) {
103 191
            $this->connect();
104 189
        }
105 189
106 191
        return $this->connection;
107
    }
108
109
    /**
110
     * {@inheritdoc}
111
     */
112 1
    public function connect()
113
    {
114 1
    }
115
116
    /**
117
     * {@inheritdoc}
118
     */
119
    public function disconnect()
120
    {
121
    }
122
123
    /**
124
     * {@inheritdoc}
125
     */
126 218
    public function execute($sql)
127
    {
128 218
        if ($this->isDryRunEnabled()) {
129 3
            $this->getOutput()->writeln($sql);
130 3
131
            return 0;
132
        }
133 217
134
        if ($this->isVerbosityEnabled()) {
135
            $this->getOutput()->writeln($sql);
136
        }
137
138
        return $this->getConnection()->exec($sql);
139
    }
140
141
    /**
142 220
     * Executes a query and returns PDOStatement.
143
     *
144 220
     * @param string $sql SQL
145
     * @return \PDOStatement
146
     */
147
    public function query($sql)
148
    {
149
        if ($this->isVerbosityEnabled()) {
150 151
            $this->getOutput()->writeln($sql);
151
        }
152 151
153 151
        return $this->getConnection()->query($sql);
154
    }
155
156
    /**
157
     * {@inheritdoc}
158
     */
159 213
    public function fetchRow($sql)
160
    {
161 213
        $result = $this->query($sql);
162 213
163 213
        return $result->fetch();
164 208
    }
165 208
166 213
    /**
167
     * {@inheritdoc}
168
     */
169
    public function fetchAll($sql)
170
    {
171
        $rows = [];
172 1
        $result = $this->query($sql);
173
        while ($row = $result->fetch()) {
174 1
            $rows[] = $row;
175 1
        }
176 1
177 1
        return $rows;
178
    }
179 1
180 1
    /**
181 1
     * {@inheritdoc}
182
     */
183 1
    public function insert(Table $table, $row)
184 1
    {
185 1
        $sql = sprintf(
186
            "INSERT INTO %s ",
187
            $this->quoteTableName($table->getName())
188
        );
189
190 11
        $columns = array_keys($row);
191
        $sql .= "(" . implode(', ', array_map([$this, 'quoteColumnName'], $columns)) . ")";
192 11
        $sql .= " VALUES (" . implode(', ', array_fill(0, count($columns), '?')) . ")";
193 11
194 11
        $stmt = $this->getConnection()->prepare($sql);
195 11
        $stmt->execute(array_values($row));
196
    }
197 11
198 11
    /**
199 11
     * {@inheritdoc}
200
     */
201 11
    public function bulkinsert(Table $table, $rows)
202 11
    {
203 11
        $sql = sprintf(
204 11
            "INSERT INTO %s ",
205 11
            $this->quoteTableName($table->getName())
206 11
        );
207
208 11
        $current = current($rows);
209 11
        $keys = array_keys($current);
210
        $sql .= "(" . implode(', ', array_map([$this, 'quoteColumnName'], $keys)) . ") VALUES";
211 11
212 11
        $vals = [];
213 11
        foreach ($rows as $row) {
214
            foreach ($row as $v) {
215 11
                $vals[] = $v;
216 11
            }
217 11
        }
218
219
        $count_keys = count($keys);
220
        $query = "(" . implode(', ', array_fill(0, $count_keys, '?')) . ")";
221
222 5
        $count_vars = count($rows);
223
        $queries = array_fill(0, $count_vars, $query);
224 5
        $sql .= implode(',', $queries);
225
226 5
        $stmt = $this->getConnection()->prepare($sql);
227
        $stmt->execute($vals);
228
    }
229
230
    /**
231
     * {@inheritdoc}
232 8
     */
233
    public function getVersions()
234 8
    {
235
        $rows = $this->getVersionLog();
236 8
237 8
        return array_keys($rows);
238 6
    }
239 6
240 2
    /**
241 1
     * {@inheritdoc}
242 1
     */
243 1
    public function getVersionLog()
244 1
    {
245 8
        $result = [];
246
247 7
        switch ($this->options['version_order']) {
248 7
            case \Phinx\Config\Config::VERSION_ORDER_CREATION_TIME:
249 7
                $orderBy = 'version ASC';
250 7
                break;
251
            case \Phinx\Config\Config::VERSION_ORDER_EXECUTION_TIME:
252 7
                $orderBy = 'start_time ASC, version ASC';
253
                break;
254
            default:
255
                throw new \RuntimeException('Invalid version_order configuration option');
256
        }
257
258 5
        $rows = $this->fetchAll(sprintf('SELECT * FROM %s ORDER BY %s', $this->getSchemaTableName(), $orderBy));
259
        foreach ($rows as $version) {
260 5
            $result[$version['version']] = $version;
261
        }
262 5
263 5
        return $result;
264 5
    }
265 5
266 5
    /**
267 5
     * {@inheritdoc}
268 5
     */
269 5
    public function migrated(MigrationInterface $migration, $direction, $startTime, $endTime)
270 5
    {
271 5
        if (strcasecmp($direction, MigrationInterface::UP) === 0) {
272 5
            // up
273 5
            $sql = sprintf(
274 5
                "INSERT INTO %s (%s, %s, %s, %s, %s) VALUES ('%s', '%s', '%s', '%s', %s);",
275 5
                $this->getSchemaTableName(),
276
                $this->quoteColumnName('version'),
277 5
                $this->quoteColumnName('migration_name'),
278 5
                $this->quoteColumnName('start_time'),
279
                $this->quoteColumnName('end_time'),
280 3
                $this->quoteColumnName('breakpoint'),
281 3
                $migration->getVersion(),
282 3
                substr($migration->getName(), 0, 100),
283 3
                $startTime,
284 3
                $endTime,
285 3
                $this->castToBool(false)
286
            );
287 3
288
            $this->execute($sql);
289
        } else {
290 5
            // down
291
            $sql = sprintf(
292
                "DELETE FROM %s WHERE %s = '%s'",
293
                $this->getSchemaTableName(),
294
                $this->quoteColumnName('version'),
295
                $migration->getVersion()
296 1
            );
297
298 1
            $this->execute($sql);
299 1
        }
300 1
301 1
        return $this;
302 1
    }
303 1
304 1
    /**
305 1
     * @inheritDoc
306 1
     */
307 1
    public function toggleBreakpoint(MigrationInterface $migration)
308 1
    {
309 1
        $this->query(
310
            sprintf(
311 1
                'UPDATE %1$s SET %2$s = CASE %2$s WHEN %3$s THEN %4$s ELSE %3$s END, %7$s = %7$s WHERE %5$s = \'%6$s\';',
312
                $this->getSchemaTableName(),
313
                $this->quoteColumnName('breakpoint'),
314
                $this->castToBool(true),
315
                $this->castToBool(false),
316
                $this->quoteColumnName('version'),
317 1
                $migration->getVersion(),
318
                $this->quoteColumnName('start_time')
319 1
            )
320 1
        );
321 1
322 1
        return $this;
323 1
    }
324 1
325 1
    /**
326 1
     * @inheritDoc
327 1
     */
328
    public function resetAllBreakpoints()
329
    {
330
        return $this->execute(
331
            sprintf(
332
                'UPDATE %1$s SET %2$s = %3$s, %4$s = %4$s WHERE %2$s <> %3$s;',
333
                $this->getSchemaTableName(),
334
                $this->quoteColumnName('breakpoint'),
335
                $this->castToBool(false),
336
                $this->quoteColumnName('start_time')
337
            )
338
        );
339
    }
340
341
    /**
342
     * {@inheritdoc}
343
     */
344
    public function createSchema($schemaName = 'public')
345
    {
346
        throw new BadMethodCallException('Creating a schema is not supported');
347
    }
348
349 208
    /**
350
     * {@inheritdoc}
351
     */
352 208
    public function dropSchema($name)
353 208
    {
354 208
        throw new BadMethodCallException('Dropping a schema is not supported');
355 208
    }
356 208
357 208
    /**
358 208
     * {@inheritdoc}
359 208
     */
360 208
    public function getColumnTypes()
361 208
    {
362 208
        return [
363 208
            'string',
364 208
            'char',
365 208
            'text',
366 208
            'integer',
367 208
            'biginteger',
368
            'float',
369 208
            'decimal',
370 208
            'datetime',
371 208
            'timestamp',
372 208
            'time',
373 208
            'date',
374
            'blob',
375
            'binary',
376
            'varbinary',
377
            'boolean',
378
            'uuid',
379 121
            // Geospatial data types
380
            'geometry',
381 121
            'point',
382
            'linestring',
383
            'polygon',
384
        ];
385
    }
386
387
    /**
388
     * {@inheritdoc}
389
     */
390
    public function castToBool($value)
391
    {
392
        return (bool)$value ? 1 : 0;
393
    }
394
}
395