Completed
Pull Request — master (#1231)
by
unknown
01:42
created

PdoAdapter::connect()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

Changes 0
Metric Value
dl 0
loc 3
ccs 2
cts 2
cp 1
rs 10
c 0
b 0
f 0
cc 1
eloc 1
nc 1
nop 0
crap 1
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
     * Sets the database connection.
49
     *
50
     * @param \PDO $connection Connection
51 287
     * @return \Phinx\Db\Adapter\AdapterInterface
52
     */
53 287
    public function setConnection(\PDO $connection)
54
    {
55 287
        $this->connection = $connection;
56 3
57 3
        // Create the schema table if it doesn't already exist
58
        if (!$this->hasSchemaTable()) {
59 287
            $this->createSchemaTable();
60
        } else {
61
            $table = new Table($this->getSchemaTableName(), [], $this);
62
            if (!$table->hasColumn('migration_name')) {
63
                $table
64
                    ->addColumn(
65
                        'migration_name',
66
                        'string',
67
                        ['limit' => 100, 'after' => 'version', 'default' => null, 'null' => true]
68 193
                    )
69
                    ->save();
70 193
            }
71
            if (!$table->hasColumn('breakpoint')) {
72
                $table
73 193
                    ->addColumn('breakpoint', 'boolean', ['default' => false])
74 191
                    ->save();
75 191
            }
76 74
        }
77 74
78
        return $this;
79
    }
80
81
    /**
82
     * Gets the database connection
83
     *
84
     * @return \PDO
85
     */
86 74
    public function getConnection()
87
    {
88
        if ($this->connection === null) {
89
            if (isset($options['connection'])) {
0 ignored issues
show
Bug introduced by
The variable $options seems to never exist, and therefore isset should always return false. Did you maybe rename this variable?

This check looks for calls to isset(...) or empty() on variables that are yet undefined. These calls will always produce the same result and can be removed.

This is most likely caused by the renaming of a variable or the removal of a function/method parameter.

Loading history...
90
                $this->setConnection($options['connection']);
91
            } else {
92
                $this->connect();
93 193
            }
94
        }
95
96
        return $this->connection;
97
    }
98
99
    /**
100
     * {@inheritdoc}
101 191
     */
102
    public function connect()
103 191
    {
104 189
    }
105 189
106 191
    /**
107
     * {@inheritdoc}
108
     */
109
    public function disconnect()
110
    {
111
    }
112 1
113
    /**
114 1
     * {@inheritdoc}
115
     */
116
    public function execute($sql)
117
    {
118
        if ($this->isDryRunEnabled()) {
119
            $this->getOutput()->writeln($sql);
120
121
            return 0;
122
        }
123
124
        return $this->getConnection()->exec($sql);
125
    }
126 218
127
    /**
128 218
     * Executes a query and returns PDOStatement.
129 3
     *
130 3
     * @param string $sql SQL
131
     * @return \PDOStatement
132
     */
133 217
    public function query($sql)
134
    {
135
        return $this->getConnection()->query($sql);
136
    }
137
138
    /**
139
     * {@inheritdoc}
140
     */
141
    public function fetchRow($sql)
142 220
    {
143
        $result = $this->query($sql);
144 220
145
        return $result->fetch();
146
    }
147
148
    /**
149
     * {@inheritdoc}
150 151
     */
151
    public function fetchAll($sql)
152 151
    {
153 151
        $rows = [];
154
        $result = $this->query($sql);
155
        while ($row = $result->fetch()) {
156
            $rows[] = $row;
157
        }
158
159 213
        return $rows;
160
    }
161 213
162 213
    /**
163 213
     * {@inheritdoc}
164 208
     */
165 208
    public function insert(Table $table, $row)
166 213
    {
167
        $sql = sprintf(
168
            "INSERT INTO %s ",
169
            $this->quoteTableName($table->getName())
170
        );
171
172 1
        $columns = array_keys($row);
173
        $sql .= "(" . implode(', ', array_map([$this, 'quoteColumnName'], $columns)) . ")";
174 1
        $sql .= " VALUES (" . implode(', ', array_fill(0, count($columns), '?')) . ")";
175 1
176 1
        $stmt = $this->getConnection()->prepare($sql);
177 1
        $stmt->execute(array_values($row));
178
    }
179 1
180 1
    /**
181 1
     * {@inheritdoc}
182
     */
183 1
    public function bulkinsert(Table $table, $rows)
184 1
    {
185 1
        $sql = sprintf(
186
            "INSERT INTO %s ",
187
            $this->quoteTableName($table->getName())
188
        );
189
190 11
        $current = current($rows);
191
        $keys = array_keys($current);
192 11
        $sql .= "(" . implode(', ', array_map([$this, 'quoteColumnName'], $keys)) . ") VALUES";
193 11
194 11
        $vals = [];
195 11
        foreach ($rows as $row) {
196
            foreach ($row as $v) {
197 11
                $vals[] = $v;
198 11
            }
199 11
        }
200
201 11
        $count_keys = count($keys);
202 11
        $query = "(" . implode(', ', array_fill(0, $count_keys, '?')) . ")";
203 11
204 11
        $count_vars = count($rows);
205 11
        $queries = array_fill(0, $count_vars, $query);
206 11
        $sql .= implode(',', $queries);
207
208 11
        $stmt = $this->getConnection()->prepare($sql);
209 11
        $stmt->execute($vals);
210
    }
211 11
212 11
    /**
213 11
     * {@inheritdoc}
214
     */
215 11
    public function getVersions()
216 11
    {
217 11
        $rows = $this->getVersionLog();
218
219
        return array_keys($rows);
220
    }
221
222 5
    /**
223
     * {@inheritdoc}
224 5
     */
225
    public function getVersionLog()
226 5
    {
227
        $result = [];
228
229
        switch ($this->options['version_order']) {
230
            case \Phinx\Config\Config::VERSION_ORDER_CREATION_TIME:
231
                $orderBy = 'version ASC';
232 8
                break;
233
            case \Phinx\Config\Config::VERSION_ORDER_EXECUTION_TIME:
234 8
                $orderBy = 'start_time ASC, version ASC';
235
                break;
236 8
            default:
237 8
                throw new \RuntimeException('Invalid version_order configuration option');
238 6
        }
239 6
240 2
        $rows = $this->fetchAll(sprintf('SELECT * FROM %s ORDER BY %s', $this->getSchemaTableName(), $orderBy));
241 1
        foreach ($rows as $version) {
242 1
            $result[$version['version']] = $version;
243 1
        }
244 1
245 8
        return $result;
246
    }
247 7
248 7
    /**
249 7
     * {@inheritdoc}
250 7
     */
251
    public function migrated(MigrationInterface $migration, $direction, $startTime, $endTime)
252 7
    {
253
        if (strcasecmp($direction, MigrationInterface::UP) === 0) {
254
            // up
255
            $sql = sprintf(
256
                "INSERT INTO %s (%s, %s, %s, %s, %s) VALUES ('%s', '%s', '%s', '%s', %s);",
257
                $this->getSchemaTableName(),
258 5
                $this->quoteColumnName('version'),
259
                $this->quoteColumnName('migration_name'),
260 5
                $this->quoteColumnName('start_time'),
261
                $this->quoteColumnName('end_time'),
262 5
                $this->quoteColumnName('breakpoint'),
263 5
                $migration->getVersion(),
264 5
                substr($migration->getName(), 0, 100),
265 5
                $startTime,
266 5
                $endTime,
267 5
                $this->castToBool(false)
268 5
            );
269 5
270 5
            $this->execute($sql);
271 5
        } else {
272 5
            // down
273 5
            $sql = sprintf(
274 5
                "DELETE FROM %s WHERE %s = '%s'",
275 5
                $this->getSchemaTableName(),
276
                $this->quoteColumnName('version'),
277 5
                $migration->getVersion()
278 5
            );
279
280 3
            $this->execute($sql);
281 3
        }
282 3
283 3
        return $this;
284 3
    }
285 3
286
    /**
287 3
     * @inheritDoc
288
     */
289
    public function toggleBreakpoint(MigrationInterface $migration)
290 5
    {
291
        $this->query(
292
            sprintf(
293
                '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\';',
294
                $this->getSchemaTableName(),
295
                $this->quoteColumnName('breakpoint'),
296 1
                $this->castToBool(true),
297
                $this->castToBool(false),
298 1
                $this->quoteColumnName('version'),
299 1
                $migration->getVersion(),
300 1
                $this->quoteColumnName('start_time')
301 1
            )
302 1
        );
303 1
304 1
        return $this;
305 1
    }
306 1
307 1
    /**
308 1
     * @inheritDoc
309 1
     */
310
    public function resetAllBreakpoints()
311 1
    {
312
        return $this->execute(
313
            sprintf(
314
                'UPDATE %1$s SET %2$s = %3$s, %4$s = %4$s WHERE %2$s <> %3$s;',
315
                $this->getSchemaTableName(),
316
                $this->quoteColumnName('breakpoint'),
317 1
                $this->castToBool(false),
318
                $this->quoteColumnName('start_time')
319 1
            )
320 1
        );
321 1
    }
322 1
323 1
    /**
324 1
     * {@inheritdoc}
325 1
     */
326 1
    public function createSchema($schemaName = 'public')
327 1
    {
328
        throw new BadMethodCallException('Creating a schema is not supported');
329
    }
330
331
    /**
332
     * {@inheritdoc}
333
     */
334
    public function dropSchema($name)
335
    {
336
        throw new BadMethodCallException('Dropping a schema is not supported');
337
    }
338
339
    /**
340
     * {@inheritdoc}
341
     */
342
    public function getColumnTypes()
343
    {
344
        return [
345
            'string',
346
            'char',
347
            'text',
348
            'integer',
349 208
            'biginteger',
350
            'float',
351
            'decimal',
352 208
            'datetime',
353 208
            'timestamp',
354 208
            'time',
355 208
            'date',
356 208
            'blob',
357 208
            'binary',
358 208
            'varbinary',
359 208
            'boolean',
360 208
            'uuid',
361 208
            // Geospatial data types
362 208
            'geometry',
363 208
            'point',
364 208
            'linestring',
365 208
            'polygon',
366 208
        ];
367 208
    }
368
369 208
    /**
370 208
     * {@inheritdoc}
371 208
     */
372 208
    public function castToBool($value)
373 208
    {
374
        return (bool)$value ? 1 : 0;
375
    }
376
}
377