AbstractAdapter::setInput()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 5
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 1
CRAP Score 1

Importance

Changes 0
Metric Value
eloc 2
dl 0
loc 5
c 0
b 0
f 0
ccs 1
cts 1
cp 1
rs 10
cc 1
nc 1
nop 1
crap 1
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
     * @return array
162
     */
163
    public function getVersions()
164
    {
165
        $rows = $this->getVersionLog();
166
167
        return array_keys($rows);
168
    }
169
170
    /**
171
     * Gets the schema table name.
172
     *
173
     * @return string
174
     */
175
    public function getSchemaTableName()
176 195
    {
177
        return $this->schemaTableName;
178 195
    }
179
180
    /**
181
     * Sets the schema table name.
182
     *
183
     * @param string $schemaTableName Schema Table Name
184
     * @return $this
185
     */
186
    public function setSchemaTableName($schemaTableName)
187 7
    {
188
        $this->schemaTableName = $schemaTableName;
189 7
190 7
        return $this;
191
    }
192
193
    /**
194
     * Gets the data domain.
195
     *
196 193
     * @return array
197
     */
198 193
    public function getDataDomain()
199
    {
200
        return $this->dataDomain;
201
    }
202
203
    /**
204 191
     * Sets the data domain.
205
     *
206
     * @param array $dataDomain Array for the data domain
207
     * @return $this
208 191
     */
209
    public function setDataDomain(array $dataDomain)
210 191
    {
211
        $this->dataDomain = [];
212 191
213 191
        // Iterate over data domain field definitions and perform initial and
214 191
        // simple normalization. We make sure the definition as a base 'type'
215 191
        // and it is compatible with the base Phinx types.
216 191
        foreach ($dataDomain as $type => $options) {
217 191
            if (!isset($options['type'])) {
218 191
                throw new \InvalidArgumentException(sprintf(
219 191
                    'You must specify a type for data domain type "%s".',
220
                    $type
221
                ));
222 191
            }
223
224
            // Replace type if it's the name of a Phinx constant
225
            if (defined('static::' . $options['type'])) {
226
                $options['type'] = constant('static::' . $options['type']);
227
            }
228
229
            if (!in_array($options['type'], $this->getColumnTypes(), true)) {
230
                throw new \InvalidArgumentException(sprintf(
231
                    'An invalid column type "%s" was specified for data domain type "%s".',
232
                    $options['type'],
233
                    $type
234
                ));
235 208
            }
236
237 208
            $internal_type = $options['type'];
238
            unset($options['type']);
239
240
            // Do a simple replacement for the 'length' / 'limit' option and
241
            // detect hinting values for 'limit'.
242
            if (isset($options['length'])) {
243
                $options['limit'] = $options['length'];
244
                unset($options['length']);
245 218
            }
246
247 218
            if (isset($options['limit']) && !is_numeric($options['limit'])) {
248
                if (!defined('static::' . $options['limit'])) {
249 218
                    throw new \InvalidArgumentException(sprintf(
250
                        'An invalid limit value "%s" was specified for data domain type "%s".',
251
                        $options['limit'],
252
                        $type
253
                    ));
254
                }
255
256
                $options['limit'] = constant('static::' . $options['limit']);
257
            }
258
259
            // Save the data domain types in a more suitable format
260
            $this->dataDomain[$type] = [
261
                'type' => $internal_type,
262
                'options' => $options,
263
            ];
264
        }
265
266
        return $this;
267
    }
268
269
    /**
270
     * @inheritdoc
271
     */
272
    public function getColumnForType($columnName, $type, array $options)
273
    {
274
        $column = new Column();
275
        $column->setName($columnName);
276
277
        if (array_key_exists($type, $this->getDataDomain())) {
278
            $column->setType($this->dataDomain[$type]['type']);
279
            $column->setOptions($this->dataDomain[$type]['options']);
280
        } else {
281
            $column->setType($type);
282
        }
283
284
        $column->setOptions($options);
285
286
        return $column;
287
    }
288
289
    /**
290
     * @inheritdoc
291
     */
292
    public function hasSchemaTable()
293
    {
294
        return $this->hasTable($this->getSchemaTableName());
295
    }
296
297
    /**
298
     * @inheritDoc
299
     * @throws \InvalidArgumentException
300
     * @return void
301
     */
302
    public function createSchemaTable()
303
    {
304
        try {
305
            $options = [
306
                'id' => false,
307
                'primary_key' => 'version',
308
            ];
309
310
            $table = new Table($this->getSchemaTableName(), $options, $this);
311
            $table->addColumn('version', 'biginteger')
312
                ->addColumn('migration_name', 'string', ['limit' => 100, 'default' => null, 'null' => true])
313
                ->addColumn('start_time', 'timestamp', ['default' => null, 'null' => true])
314
                ->addColumn('end_time', 'timestamp', ['default' => null, 'null' => true])
315
                ->addColumn('breakpoint', 'boolean', ['default' => false])
316
                ->save();
317
        } catch (Exception $exception) {
318
            throw new InvalidArgumentException(
319
                'There was a problem creating the schema table: ' . $exception->getMessage(),
320
                (int)$exception->getCode(),
321
                $exception
322
            );
323
        }
324
    }
325
326
    /**
327
     * @inheritDoc
328
     */
329
    public function getAdapterType()
330
    {
331
        return $this->getOption('adapter');
332
    }
333
334
    /**
335
     * @inheritDoc
336
     */
337
    public function isValidColumnType(Column $column)
338
    {
339
        return $column->getType() instanceof Literal || in_array($column->getType(), $this->getColumnTypes(), true);
340
    }
341
342
    /**
343
     * Determines if instead of executing queries a dump to standard output is needed
344
     *
345
     * @return bool
346
     */
347
    public function isDryRunEnabled()
348
    {
349
        /** @var \Symfony\Component\Console\Input\InputInterface|null $input */
350
        $input = $this->getInput();
351
352
        return $input && $input->hasOption('dry-run') ? (bool)$input->getOption('dry-run') : false;
353
    }
354
355
    /**
356
     * Adds user-created tables (e.g. not phinxlog) to a cached list
357
     *
358
     * @param string $tableName The name of the table
359
     * @return void
360
     */
361
    protected function addCreatedTable($tableName)
362
    {
363
        $tableName = $this->quoteTableName($tableName);
364
        if (substr_compare($tableName, 'phinxlog', -strlen('phinxlog')) !== 0) {
365
            $this->createdTables[] = $tableName;
366
        }
367
    }
368
369
    /**
370
     * Updates the name of the cached table
371
     *
372
     * @param string $tableName Original name of the table
373
     * @param string $newTableName New name of the table
374
     * @return void
375
     */
376
    protected function updateCreatedTableName($tableName, $newTableName)
377
    {
378
        $tableName = $this->quoteTableName($tableName);
379
        $newTableName = $this->quoteTableName($newTableName);
380
        $key = array_search($tableName, $this->createdTables, true);
381
        if ($key !== false) {
382
            $this->createdTables[$key] = $newTableName;
383
        }
384
    }
385
386
    /**
387
     * Removes table from the cached created list
388
     *
389
     * @param string $tableName The name of the table
390
     * @return void
391
     */
392
    protected function removeCreatedTable($tableName)
393
    {
394
        $tableName = $this->quoteTableName($tableName);
395
        $key = array_search($tableName, $this->createdTables, true);
396
        if ($key !== false) {
397
            unset($this->createdTables[$key]);
398
        }
399
    }
400
401
    /**
402
     * Check if the table is in the cached list of created tables
403
     *
404
     * @param string $tableName The name of the table
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