DDLGeneration::getMySQLColumnDef()   D
last analyzed

Complexity

Conditions 18
Paths 52

Size

Total Lines 74
Code Lines 56

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 48
CRAP Score 18.2716

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 18
eloc 56
c 1
b 0
f 0
nc 52
nop 0
dl 0
loc 74
ccs 48
cts 53
cp 0.9057
crap 18.2716
rs 4.8666

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
declare(strict_types=1);
4
/**
5
 * Database Access Layer.
6
 * @author Doug Wright
7
 */
8
9
namespace DVDoug\DB;
10
11
use function addslashes;
12
use function array_intersect_key;
13
use function array_map;
14
use function array_unique;
15
use function asort;
16
use function explode;
17
use function implode;
18
use function in_array;
19
use function sprintf;
20
use function strpos;
21
use function strtolower;
22
use function substr;
23
use function trim;
24
25
/**
26
 * Metadata about a database column.
27
 * @author Doug Wright
28
 */
29
trait DDLGeneration
30
{
31
    /**
32
     * Get MySQL column definition.
33
     */
34 8
    public function getMySQLColumnDef(): string
35
    {
36 8
        $def = '`' . strtolower($this->getName()) . '` ';
0 ignored issues
show
Bug introduced by
It seems like getName() must be provided by classes using this trait. How about adding it as abstract method to this trait? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

36
        $def = '`' . strtolower($this->/** @scrutinizer ignore-call */ getName()) . '` ';
Loading history...
37 8
        $MySQLType = $this->getMySQLType();
0 ignored issues
show
Bug introduced by
It seems like getMySQLType() must be provided by classes using this trait. How about adding it as abstract method to this trait? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

37
        /** @scrutinizer ignore-call */ 
38
        $MySQLType = $this->getMySQLType();
Loading history...
38 8
        if (strpos($MySQLType, 'UNSIGNED') !== false) {
39 4
            $unsigned = true;
40 4
            $MySQLType = substr($MySQLType, 0, -9);
41
        } else {
42 8
            $unsigned = false;
43
        }
44
45 8
        if (in_array($MySQLType, ['ENUM', 'SET'])) {
46 4
            $query = sprintf('SHOW COLUMNS FROM %s.%s LIKE %s',
47 4
                $this->connection->quoteIdentifier($this->database),
48 4
                $this->connection->quoteIdentifier($this->table),
49 4
                $this->connection->escape($this->name));
50
51 4
            $statement = $this->connection->query($query);
52 4
            $values = $statement->fetchAssoc(false)['Type'];
53 4
            $values = explode("','", substr($values, strpos($values, '(') + 2, -2));
54 4
            $values = array_intersect_key($values, array_unique(array_map('strtolower', $values)));
55 4
            asort($values);
56
57 4
            $def .= $MySQLType;
58 4
            $def .= '(' . implode(', ', array_map(function ($c) {return "'" . addslashes($c) . "'"; }, $values)) . ')';
59 8
        } elseif (in_array($MySQLType, ['CHAR', 'VARCHAR']) && $this->getLength() < 64 && $this->getDistinctValueCount() <= 16) {
0 ignored issues
show
Bug introduced by
It seems like getLength() must be provided by classes using this trait. How about adding it as abstract method to this trait? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

59
        } elseif (in_array($MySQLType, ['CHAR', 'VARCHAR']) && $this->/** @scrutinizer ignore-call */ getLength() < 64 && $this->getDistinctValueCount() <= 16) {
Loading history...
Bug introduced by
It seems like getDistinctValueCount() must be provided by classes using this trait. How about adding it as abstract method to this trait? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

59
        } elseif (in_array($MySQLType, ['CHAR', 'VARCHAR']) && $this->getLength() < 64 && $this->/** @scrutinizer ignore-call */ getDistinctValueCount() <= 16) {
Loading history...
60 4
            $query = sprintf('SELECT DISTINCT %s FROM %s.%s WHERE %s IS NOT NULL ORDER BY %s ASC',
61 4
                $this->connection->quoteIdentifier($this->name),
62 4
                $this->connection->quoteIdentifier($this->database),
63 4
                $this->connection->quoteIdentifier($this->table),
64 4
                $this->connection->quoteIdentifier($this->name),
65 4
                $this->connection->quoteIdentifier($this->name));
66 4
            $values = [];
67 4
            foreach ($this->connection->query($query) as $value) {
68 4
                $values[] = trim($value[$this->name]);
69
            }
70 4
            $values = array_intersect_key($values, array_unique(array_map('strtolower', $values)));
71 4
            asort($values);
72
73 4
            if ($values) {
74 4
                $def .= 'ENUM';
75 4
                $def .= '(' . implode(', ', array_map(function ($c) {return "'" . addslashes($c) . "'"; }, $values)) . ')';
76
            } else {
77 4
                $def .= $MySQLType;
78 4
                if ($this->getLength() > 0) {
79 4
                    $def .= '(' . $this->getLength() . ')';
80
                }
81
            }
82
        } elseif (in_array($MySQLType, ['DATETIME', 'TIMESTAMP', 'TIME'])) {
83
            $def .= $MySQLType;
84
            $def .= '(' . (int) $this->getScale() . ')';
0 ignored issues
show
Bug introduced by
It seems like getScale() must be provided by classes using this trait. How about adding it as abstract method to this trait? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

84
            $def .= '(' . (int) $this->/** @scrutinizer ignore-call */ getScale() . ')';
Loading history...
85
        } else {
86 8
            $def .= $MySQLType;
87
88 8
            if ($this->getScale() && !in_array($MySQLType, ['DATE'])) {
89
                $def .= '(' . $this->getPrecision() . ',' . $this->getScale() . ')';
0 ignored issues
show
Bug introduced by
It seems like getPrecision() must be provided by classes using this trait. How about adding it as abstract method to this trait? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

89
                $def .= '(' . $this->/** @scrutinizer ignore-call */ getPrecision() . ',' . $this->getScale() . ')';
Loading history...
90 8
            } elseif ($this->getPrecision() && !in_array($MySQLType, ['TINYINT', 'SMALLINT', 'MEDIUMINT', 'INT', 'BIGINT'])) {
91
                $def .= '(' . $this->getPrecision() . ')';
92 8
            } elseif ($this->getLength() > 0 && !in_array($MySQLType, ['TINYINT', 'SMALLINT', 'MEDIUMINT', 'INT', 'BIGINT'])) {
93 4
                $def .= '(' . $this->getLength() . ')';
94
            }
95
96 8
            if ($unsigned) {
97 4
                $def .= ' UNSIGNED';
98
            }
99
        }
100
101 8
        if ($this->isNullable()) {
0 ignored issues
show
Bug introduced by
It seems like isNullable() must be provided by classes using this trait. How about adding it as abstract method to this trait? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

101
        if ($this->/** @scrutinizer ignore-call */ isNullable()) {
Loading history...
102 8
            $def .= ' NULL';
103
        } else {
104 8
            $def .= ' NOT NULL';
105
        }
106
107 8
        return $def;
108
    }
109
110
    /**
111
     * Get Oracle column definition.
112
     */
113 8
    public function getOracleColumnDef(): string
114
    {
115 8
        $def = '`' . strtolower($this->getName()) . '` ';
116
117 8
        $def .= $this->getOracleType();
0 ignored issues
show
Bug introduced by
It seems like getOracleType() must be provided by classes using this trait. How about adding it as abstract method to this trait? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

117
        $def .= $this->/** @scrutinizer ignore-call */ getOracleType();
Loading history...
118
119 8
        if ($this->getScale()) {
120
            $def .= '(' . $this->getPrecision() . ',' . $this->getScale() . ')';
121 8
        } elseif ($this->getPrecision()) {
122 4
            $def .= '(' . $this->getPrecision() . ')';
123 4
        } elseif ($this->getLength()) {
124 4
            $def .= '(' . $this->getLength() . ')';
125
        }
126
127 8
        if ($this->isNullable()) {
128 8
            $def .= ' NULL';
129
        } else {
130 8
            $def .= ' NOT NULL';
131
        }
132
133 8
        return $def;
134
    }
135
}
136