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
![]() |
|||||||
37 | 8 | $MySQLType = $this->getMySQLType(); |
|||||
0 ignored issues
–
show
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
![]() |
|||||||
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
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
![]() 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
![]() |
|||||||
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
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
![]() |
|||||||
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
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
![]() |
|||||||
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
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
![]() |
|||||||
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
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
![]() |
|||||||
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 |