Passed
Push — master ( 4ac1c9...d5cfad )
by Doug
01:39
created

DDLGeneration   A

Complexity

Total Complexity 23

Size/Duplication

Total Lines 105
Duplicated Lines 0 %

Test Coverage

Coverage 92.42%

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 70
c 1
b 0
f 0
dl 0
loc 105
ccs 61
cts 66
cp 0.9242
rs 10
wmc 23

2 Methods

Rating   Name   Duplication   Size   Complexity  
A getOracleColumnDef() 0 21 5
D getMySQLColumnDef() 0 74 18
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
/**
12
 * Metadata about a database column.
13
 * @author Doug Wright
14
 */
15
trait DDLGeneration
16
{
17
    /**
18
     * Get MySQL column definition.
19
     */
20 8
    public function getMySQLColumnDef(): string
21
    {
22 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

22
        $def = '`' . strtolower($this->/** @scrutinizer ignore-call */ getName()) . '` ';
Loading history...
23 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

23
        /** @scrutinizer ignore-call */ 
24
        $MySQLType = $this->getMySQLType();
Loading history...
24 8
        if (strpos($MySQLType, 'UNSIGNED') !== false) {
25 4
            $unsigned = true;
26 4
            $MySQLType = substr($MySQLType, 0, -9);
27
        } else {
28 8
            $unsigned = false;
29
        }
30
31 8
        if (in_array($MySQLType, ['ENUM', 'SET'])) {
32 4
            $query = sprintf('SHOW COLUMNS FROM %s.%s LIKE %s',
33 4
                $this->connection->quoteIdentifier($this->database),
34 4
                $this->connection->quoteIdentifier($this->table),
35 4
                $this->connection->escape($this->name));
36
37 4
            $statement = $this->connection->query($query);
38 4
            $values = $statement->fetchAssoc(false)['Type'];
39 4
            $values = explode("','", substr($values, strpos($values, '(') + 2, -2));
40 4
            $values = array_intersect_key($values, array_unique(array_map('strtolower', $values)));
41 4
            asort($values);
42
43 4
            $def .= $MySQLType;
44 4
            $def .= '(' . implode(', ', array_map(function ($c) {return "'" . addslashes($c) . "'"; }, $values)) . ')';
45 8
        } elseif (in_array($MySQLType, ['CHAR', 'VARCHAR']) && $this->getLength() < 64 && $this->getDistinctValueCount() <= 16) {
0 ignored issues
show
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

45
        } elseif (in_array($MySQLType, ['CHAR', 'VARCHAR']) && $this->getLength() < 64 && $this->/** @scrutinizer ignore-call */ getDistinctValueCount() <= 16) {
Loading history...
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

45
        } elseif (in_array($MySQLType, ['CHAR', 'VARCHAR']) && $this->/** @scrutinizer ignore-call */ getLength() < 64 && $this->getDistinctValueCount() <= 16) {
Loading history...
46 4
            $query = sprintf('SELECT DISTINCT %s FROM %s.%s WHERE %s IS NOT NULL ORDER BY %s ASC',
47 4
                $this->connection->quoteIdentifier($this->name),
48 4
                $this->connection->quoteIdentifier($this->database),
49 4
                $this->connection->quoteIdentifier($this->table),
50 4
                $this->connection->quoteIdentifier($this->name),
51 4
                $this->connection->quoteIdentifier($this->name));
52 4
            $values = [];
53 4
            foreach ($this->connection->query($query) as $value) {
54 4
                $values[] = trim($value[$this->name]);
55
            }
56 4
            $values = array_intersect_key($values, array_unique(array_map('strtolower', $values)));
57 4
            asort($values);
58
59 4
            if ($values) {
60 4
                $def .= 'ENUM';
61 4
                $def .= '(' . implode(', ', array_map(function ($c) {return "'" . addslashes($c) . "'"; }, $values)) . ')';
62
            } else {
63 4
                $def .= $MySQLType;
64 4
                if ($this->getLength() > 0) {
65 4
                    $def .= '(' . $this->getLength() . ')';
66
                }
67
            }
68 8
        } elseif (in_array($MySQLType, ['DATETIME', 'TIMESTAMP', 'TIME'])) {
69
            $def .= $MySQLType;
70
            $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

70
            $def .= '(' . (int) $this->/** @scrutinizer ignore-call */ getScale() . ')';
Loading history...
71
        } else {
72 8
            $def .= $MySQLType;
73
74 8
            if ($this->getScale() && !in_array($MySQLType, ['DATE'])) {
75
                $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

75
                $def .= '(' . $this->/** @scrutinizer ignore-call */ getPrecision() . ',' . $this->getScale() . ')';
Loading history...
76 8
            } elseif ($this->getPrecision() && !in_array($MySQLType, ['TINYINT', 'SMALLINT', 'MEDIUMINT', 'INT', 'BIGINT'])) {
77
                $def .= '(' . $this->getPrecision() . ')';
78 8
            } elseif ($this->getLength() > 0 && !in_array($MySQLType, ['TINYINT', 'SMALLINT', 'MEDIUMINT', 'INT', 'BIGINT'])) {
79 4
                $def .= '(' . $this->getLength() . ')';
80
            }
81
82 8
            if ($unsigned) {
83 4
                $def .= ' UNSIGNED';
84
            }
85
        }
86
87 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

87
        if ($this->/** @scrutinizer ignore-call */ isNullable()) {
Loading history...
88 8
            $def .= ' NULL';
89
        } else {
90 8
            $def .= ' NOT NULL';
91
        }
92
93 8
        return $def;
94
    }
95
96
    /**
97
     * Get Oracle column definition.
98
     */
99 8
    public function getOracleColumnDef(): string
100
    {
101 8
        $def = '`' . strtolower($this->getName()) . '` ';
102
103 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

103
        $def .= $this->/** @scrutinizer ignore-call */ getOracleType();
Loading history...
104
105 8
        if ($this->getScale()) {
106
            $def .= '(' . $this->getPrecision() . ',' . $this->getScale() . ')';
107 8
        } elseif ($this->getPrecision()) {
108 4
            $def .= '(' . $this->getPrecision() . ')';
109 4
        } elseif ($this->getLength()) {
110 4
            $def .= '(' . $this->getLength() . ')';
111
        }
112
113 8
        if ($this->isNullable()) {
114 8
            $def .= ' NULL';
115
        } else {
116 8
            $def .= ' NOT NULL';
117
        }
118
119 8
        return $def;
120
    }
121
}
122