Completed
Push — master ( d748e1...415000 )
by Mark
18s queued 13s
created

AbstractAdapter::getDataDomain()   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 View Code Duplication
    public function __construct(array $options, InputInterface $input = null, OutputInterface $output = null)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
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())) {
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
    public function hasSchemaTable()
295
    {
296
        return $this->hasTable($this->getSchemaTableName());
297
    }
298
299
    /**
300
     * @inheritDoc
301
     *
302
     * @throws \InvalidArgumentException
303
     *
304
     * @return void
305
     */
306
    public function createSchemaTable()
307
    {
308
        try {
309
            $options = [
310
                'id' => false,
311
                'primary_key' => 'version',
312
            ];
313
314
            $table = new Table($this->getSchemaTableName(), $options, $this);
315
            $table->addColumn('version', 'biginteger')
316
                ->addColumn('migration_name', 'string', ['limit' => 100, 'default' => null, 'null' => true])
317
                ->addColumn('start_time', 'timestamp', ['default' => null, 'null' => true])
318
                ->addColumn('end_time', 'timestamp', ['default' => null, 'null' => true])
319
                ->addColumn('breakpoint', 'boolean', ['default' => false])
320
                ->save();
321
        } catch (Exception $exception) {
322
            throw new InvalidArgumentException(
323
                'There was a problem creating the schema table: ' . $exception->getMessage(),
324
                (int)$exception->getCode(),
325
                $exception
326
            );
327
        }
328
    }
329
330
    /**
331
     * @inheritDoc
332
     */
333
    public function getAdapterType()
334
    {
335
        return $this->getOption('adapter');
336
    }
337
338
    /**
339
     * @inheritDoc
340
     */
341
    public function isValidColumnType(Column $column)
342
    {
343
        return $column->getType() instanceof Literal || in_array($column->getType(), $this->getColumnTypes());
344
    }
345
346
    /**
347
     * Determines if instead of executing queries a dump to standard output is needed
348
     *
349
     * @return bool
350
     */
351
    public function isDryRunEnabled()
352
    {
353
        /** @var \Symfony\Component\Console\Input\InputInterface|null $input */
354
        $input = $this->getInput();
355
356
        return ($input && $input->hasOption('dry-run')) ? (bool)$input->getOption('dry-run') : false;
357
    }
358
359
    /**
360
     * Adds user-created tables (e.g. not phinxlog) to a cached list
361
     *
362
     * @param string $tableName The name of the table
363
     *
364
     * @return void
365
     */
366
    protected function addCreatedTable($tableName)
367
    {
368
        if (substr_compare($tableName, 'phinxlog', -strlen('phinxlog')) !== 0) {
369
            $this->createdTables[] = $tableName;
370
        }
371
    }
372
373
    /**
374
     * Updates the name of the cached table
375
     *
376
     * @param string $tableName Original name of the table
377
     * @param string $newTableName New name of the table
378
     *
379
     * @return void
380
     */
381 View Code Duplication
    protected function updateCreatedTableName($tableName, $newTableName)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
382
    {
383
        $key = array_search($tableName, $this->createdTables);
384
        if ($key !== false) {
385
            $this->createdTables[$key] = $newTableName;
386
        }
387
    }
388
389
    /**
390
     * Removes table from the cached created list
391
     *
392
     * @param string $tableName The name of the table
393
     *
394
     * @return void
395
     */
396 View Code Duplication
    protected function removeCreatedTable($tableName)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
397
    {
398
        $key = array_search($tableName, $this->createdTables);
399
        if ($key !== false) {
400
            unset($this->createdTables[$key]);
401
        }
402
    }
403
404
    /**
405
     * Check if the table is in the cached list of created tables
406
     *
407
     * @param string $tableName The name of the table
408
     *
409
     * @return bool
410
     */
411
    protected function hasCreatedTable($tableName)
412
    {
413
        return in_array($tableName, $this->createdTables);
414
    }
415
}
416