Passed
Pull Request — master (#1939)
by
unknown
02:54
created

AbstractAdapter::hasSchemaTable()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 0
Metric Value
dl 0
loc 4
ccs 0
cts 0
cp 0
rs 10
c 0
b 0
f 0
cc 1
nc 1
nop 0
crap 2
1
<?php
2
3
/**
4
 * MIT License
5
 * For full license information, please view the LICENSE file that was distributed with this source code.
6
 */
7
8
namespace Phinx\Db\Adapter;
9
10
use Exception;
11
use InvalidArgumentException;
12
use Phinx\Db\Table;
13
use Phinx\Db\Table\Column;
14
use Phinx\Util\Literal;
15
use Symfony\Component\Console\Input\InputInterface;
16
use Symfony\Component\Console\Output\NullOutput;
17
use Symfony\Component\Console\Output\OutputInterface;
18
19
/**
20
 * Base Abstract Database Adapter.
21
 */
22
abstract class AbstractAdapter implements AdapterInterface
23
{
24
    /**
25
     * @var array
26
     */
27
    protected $options = [];
28
29
    /**
30
     * @var \Symfony\Component\Console\Input\InputInterface
31
     */
32
    protected $input;
33
34
    /**
35
     * @var \Symfony\Component\Console\Output\OutputInterface
36
     */
37
    protected $output;
38
39
    /**
40
     * @var string[]
41
     */
42
    protected $createdTables = [];
43
44
    /**
45
     * @var string
46
     */
47
    protected $schemaTableName = 'phinxlog';
48
49
    /**
50
     * @var array
51
     */
52
    protected $dataDomain = [];
53
54
    /**
55
     * Class Constructor.
56
     *
57
     * @param array $options Options
58
     * @param \Symfony\Component\Console\Input\InputInterface|null $input Input Interface
59
     * @param \Symfony\Component\Console\Output\OutputInterface|null $output Output Interface
60
     */
61
    public function __construct(array $options, InputInterface $input = null, OutputInterface $output = null)
62
    {
63
        $this->setOptions($options);
64
        if ($input !== null) {
65
            $this->setInput($input);
66
        }
67
        if ($output !== null) {
68
            $this->setOutput($output);
69 341
        }
70
    }
71 341
72 341
    /**
73 264
     * @inheritDoc
74 264
     */
75 341
    public function setOptions(array $options)
76 264
    {
77 264
        $this->options = $options;
78 341
79
        if (isset($options['default_migration_table'])) {
80
            $this->setSchemaTableName($options['default_migration_table']);
81
        }
82
83 287
        if (isset($options['data_domain'])) {
84
            $this->setDataDomain($options['data_domain']);
85 287
        }
86
87 287
        return $this;
88 6
    }
89 6
90
    /**
91 287
     * @inheritDoc
92
     */
93
    public function getOptions()
94
    {
95
        return $this->options;
96
    }
97 196
98
    /**
99 196
     * @inheritDoc
100
     */
101
    public function hasOption($name)
102
    {
103
        return isset($this->options[$name]);
104
    }
105 8
106
    /**
107 8
     * @inheritDoc
108
     */
109
    public function getOption($name)
110
    {
111
        if (!$this->hasOption($name)) {
112
            return null;
113
        }
114
115
        return $this->options[$name];
116
    }
117
118
    /**
119
     * @inheritDoc
120
     */
121
    public function setInput(InputInterface $input)
122
    {
123
        $this->input = $input;
124 269
125
        return $this;
126 269
    }
127 269
128
    /**
129
     * @inheritDoc
130
     */
131
    public function getInput()
132
    {
133 218
        return $this->input;
134
    }
135 218
136
    /**
137
     * @inheritDoc
138
     */
139
    public function setOutput(OutputInterface $output)
140
    {
141 269
        $this->output = $output;
142
143 269
        return $this;
144 269
    }
145
146
    /**
147
     * @inheritDoc
148
     */
149
    public function getOutput()
150 8
    {
151
        if ($this->output === null) {
152 8
            $output = new NullOutput();
153
            $this->setOutput($output);
154
        }
155
156 8
        return $this->output;
157
    }
158
159
    /**
160
     * @inheritDoc
161
     *
162
     * @return array
163
     */
164
    public function getVersions()
165
    {
166
        $rows = $this->getVersionLog();
167
168
        return array_keys($rows);
169
    }
170
171
    /**
172
     * Gets the schema table name.
173
     *
174
     * @return string
175
     */
176 195
    public function getSchemaTableName()
177
    {
178 195
        return $this->schemaTableName;
179
    }
180
181
    /**
182
     * Sets the schema table name.
183
     *
184
     * @param string $schemaTableName Schema Table Name
185
     *
186
     * @return $this
187 7
     */
188
    public function setSchemaTableName($schemaTableName)
189 7
    {
190 7
        $this->schemaTableName = $schemaTableName;
191
192
        return $this;
193
    }
194
195
    /**
196 193
     * Gets the data domain.
197
     *
198 193
     * @return array
199
     */
200
    public function getDataDomain()
201
    {
202
        return $this->dataDomain;
203
    }
204 191
205
    /**
206
     * Sets the data domain.
207
     *
208 191
     * @param array $dataDomain Array for the data domain
209
     * @return $this
210 191
     */
211
    public function setDataDomain(array $dataDomain)
212 191
    {
213 191
        $this->dataDomain = [];
214 191
215 191
        // Iterate over data domain field definitions and perform initial and
216 191
        // simple normalization. We make sure the definition as a base 'type'
217 191
        // and it is compatible with the base Phinx types.
218 191
        foreach ($dataDomain as $type => $options) {
219 191
            if (!isset($options['type'])) {
220
                throw new \InvalidArgumentException(sprintf(
221
                    'You must specify a type for data domain type "%s".',
222 191
                    $type
223
                ));
224
            }
225
226
            // Replace type if it's the name of a Phinx constant
227
            if (defined('static::' . $options['type'])) {
228
                $options['type'] = constant('static::' . $options['type']);
229
            }
230
231
            if (!in_array($options['type'], $this->getColumnTypes(), true)) {
232
                throw new \InvalidArgumentException(sprintf(
233
                    'An invalid column type "%s" was specified for data domain type "%s".',
234
                    $options['type'],
235 208
                    $type
236
                ));
237 208
            }
238
239
            $internal_type = $options['type'];
240
            unset($options['type']);
241
242
            // Do a simple replacement for the 'length' / 'limit' option and
243
            // detect hinting values for 'limit'.
244
            if (isset($options['length'])) {
245 218
                $options['limit'] = $options['length'];
246
                unset($options['length']);
247 218
            }
248
249 218
            if (isset($options['limit']) && !is_numeric($options['limit'])) {
250
                if (!defined('static::' . $options['limit'])) {
251
                    throw new \InvalidArgumentException(sprintf(
252
                        'An invalid limit value "%s" was specified for data domain type "%s".',
253
                        $options['limit'],
254
                        $type
255
                    ));
256
                }
257
258
                $options['limit'] = constant('static::' . $options['limit']);
259
            }
260
261
            // Save the data domain types in a more suitable format
262
            $this->dataDomain[$type] = [
263
                'type' => $internal_type,
264
                'options' => $options,
265
            ];
266
        }
267
268
        return $this;
269
    }
270
271
    /**
272
     * @inheritdoc
273
     */
274
    public function getColumnForType($columnName, $type, array $options)
275
    {
276
        $column = new Column();
277
        $column->setName($columnName);
278
279
        if (array_key_exists($type, $this->getDataDomain())) {
280
            $column->setType($this->dataDomain[$type]['type']);
281
            $column->setOptions($this->dataDomain[$type]['options']);
282
        } else {
283
            $column->setType($type);
284
        }
285
286
        $column->setOptions($options);
287
288
        return $column;
289
    }
290
291
    /**
292
     * @inheritDoc
293
     *
294
     * @throws \InvalidArgumentException
295
     *
296
     * @return void
297
     */
298
    public function createSchemaTable()
299
    {
300
        try {
301
            $options = [
302
                'id' => false,
303
                'primary_key' => 'version',
304
            ];
305
306
            $table = new Table($this->getSchemaTableName(), $options, $this);
307
            $table->addColumn('version', 'biginteger', ['null' => false])
308
                ->addColumn('migration_name', 'string', ['limit' => 100, 'default' => null, 'null' => true])
309
                ->addColumn('start_time', 'timestamp', ['default' => null, 'null' => true])
310
                ->addColumn('end_time', 'timestamp', ['default' => null, 'null' => true])
311
                ->addColumn('breakpoint', 'boolean', ['default' => false])
312
                ->save();
313
        } catch (Exception $exception) {
314
            throw new InvalidArgumentException(
315
                'There was a problem creating the schema table: ' . $exception->getMessage(),
316
                (int)$exception->getCode(),
317
                $exception
318
            );
319
        }
320
    }
321
322
    /**
323
     * @inheritDoc
324
     */
325
    public function getAdapterType()
326
    {
327
        return $this->getOption('adapter');
328
    }
329
330
    /**
331
     * @inheritDoc
332
     */
333
    public function isValidColumnType(Column $column)
334
    {
335
        return $column->getType() instanceof Literal || in_array($column->getType(), $this->getColumnTypes(), true);
336
    }
337
338
    /**
339
     * Determines if instead of executing queries a dump to standard output is needed
340
     *
341
     * @return bool
342
     */
343
    public function isDryRunEnabled()
344
    {
345
        /** @var \Symfony\Component\Console\Input\InputInterface|null $input */
346
        $input = $this->getInput();
347
348
        return ($input && $input->hasOption('dry-run')) ? (bool)$input->getOption('dry-run') : false;
349
    }
350
351
    /**
352
     * Adds user-created tables (e.g. not phinxlog) to a cached list
353
     *
354
     * @param string $tableName The name of the table
355
     *
356
     * @return void
357
     */
358
    protected function addCreatedTable($tableName)
359
    {
360
        $tableName = $this->quoteTableName($tableName);
361
        if (substr_compare($tableName, 'phinxlog', -strlen('phinxlog')) !== 0) {
362
            $this->createdTables[] = $tableName;
363
        }
364
    }
365
366
    /**
367
     * Updates the name of the cached table
368
     *
369
     * @param string $tableName Original name of the table
370
     * @param string $newTableName New name of the table
371
     *
372
     * @return void
373
     */
374
    protected function updateCreatedTableName($tableName, $newTableName)
375
    {
376
        $tableName = $this->quoteTableName($tableName);
377
        $newTableName = $this->quoteTableName($newTableName);
378
        $key = array_search($tableName, $this->createdTables, true);
379
        if ($key !== false) {
380
            $this->createdTables[$key] = $newTableName;
381
        }
382
    }
383
384
    /**
385
     * Removes table from the cached created list
386
     *
387
     * @param string $tableName The name of the table
388
     *
389
     * @return void
390
     */
391
    protected function removeCreatedTable($tableName)
392
    {
393
        $tableName = $this->quoteTableName($tableName);
394
        $key = array_search($tableName, $this->createdTables, true);
395
        if ($key !== false) {
396
            unset($this->createdTables[$key]);
397
        }
398
    }
399
400
    /**
401
     * Check if the table is in the cached list of created tables
402
     *
403
     * @param string $tableName The name of the table
404
     *
405
     * @return bool
406
     */
407
    protected function hasCreatedTable($tableName)
408
    {
409
        $tableName = $this->quoteTableName($tableName);
410
411
        return in_array($tableName, $this->createdTables, true);
412
    }
413
}
414