Completed
Push — master ( 1e376d...b0060a )
by Changwan
05:50
created

ColumnExpression::__construct()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 6
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 5
CRAP Score 1

Importance

Changes 0
Metric Value
cc 1
eloc 4
nc 1
nop 3
dl 0
loc 6
ccs 5
cts 5
cp 1
crap 1
rs 9.4285
c 0
b 0
f 0
1
<?php
2
namespace Wandu\Database\Query\Expression;
3
4
use Wandu\Database\Contracts\ExpressionInterface;
5
use Wandu\Database\Support\Attributes;
6
use Wandu\Database\Support\Helper;
7
8
/**
9
 * @see http://dev.mysql.com/doc/refman/5.7/en/create-table.html
10
 *
11
 * ColumnExpression:
12
 *     col_name column_definition
13
 *     [FIRST | AFTER col_name ] ............. (for alter table)
14
 * 
15
 * column_definition:
16
 *     data_type [NOT NULL | NULL] [DEFAULT default_value]
17
 *         [AUTO_INCREMENT] [UNIQUE [KEY] | [PRIMARY] KEY]
18
 *         [ReferenceExpression]
19
 * 
20
 * data_type:
21
 *     BIT[(length)]
22
 *   | TINYINT[(length)] [UNSIGNED] [ZEROFILL]
23
 *   | SMALLINT[(length)] [UNSIGNED] [ZEROFILL]
24
 *   | MEDIUMINT[(length)] [UNSIGNED] [ZEROFILL]
25
 *   | INT[(length)] [UNSIGNED] [ZEROFILL]
26
 *   | INTEGER[(length)] [UNSIGNED] [ZEROFILL]
27
 *   | BIGINT[(length)] [UNSIGNED] [ZEROFILL]
28
 *   | REAL[(length,decimals)] [UNSIGNED] [ZEROFILL]
29
 *   | DOUBLE[(length,decimals)] [UNSIGNED] [ZEROFILL]
30
 *   | FLOAT[(length,decimals)] [UNSIGNED] [ZEROFILL]
31
 *   | DECIMAL[(length[,decimals])] [UNSIGNED] [ZEROFILL]
32
 *   | NUMERIC[(length[,decimals])] [UNSIGNED] [ZEROFILL]
33
 *   | DATE
34
 *   | TIME[(fsp)]
35
 *   | TIMESTAMP[(fsp)]
36
 *   | DATETIME[(fsp)]
37
 *   | YEAR
38
 *   | CHAR[(length)] [BINARY] [CHARACTER SET charset_name] [COLLATE collation_name]
39
 *   | VARCHAR(length) [BINARY] [CHARACTER SET charset_name] [COLLATE collation_name]
40
 *   | BINARY[(length)]
41
 *   | VARBINARY(length)
42
 *   | TINYBLOB
43
 *   | BLOB
44
 *   | MEDIUMBLOB
45
 *   | LONGBLOB
46
 *   | TINYTEXT [BINARY] [CHARACTER SET charset_name] [COLLATE collation_name]
47
 *   | TEXT [BINARY] [CHARACTER SET charset_name] [COLLATE collation_name]
48
 *   | MEDIUMTEXT [BINARY] [CHARACTER SET charset_name] [COLLATE collation_name]
49
 *   | LONGTEXT [BINARY] [CHARACTER SET charset_name] [COLLATE collation_name]
50
 *   | ENUM(value1,value2,value3,...) [CHARACTER SET charset_name] [COLLATE collation_name]
51
 *   | SET(value1,value2,value3,...) [CHARACTER SET charset_name] [COLLATE collation_name]
52
 *   | JSON
53
 *   | spatial_type
54
 *
55
 * @method \Wandu\Database\Query\Expression\ColumnExpression nullable()
56
 * @method \Wandu\Database\Query\Expression\ColumnExpression default(mixed $value)
57
 * @method \Wandu\Database\Query\Expression\ColumnExpression autoIncrement()
58
 * @method \Wandu\Database\Query\Expression\ColumnExpression unique()
59
 * @method \Wandu\Database\Query\Expression\ColumnExpression primary()
60
 *
61
 * @method \Wandu\Database\Query\Expression\ColumnExpression length(int $length)
62
 * @method \Wandu\Database\Query\Expression\ColumnExpression decimal(int $decimal)
63
 * @method \Wandu\Database\Query\Expression\ColumnExpression fsp($fsp)
64
 * @method \Wandu\Database\Query\Expression\ColumnExpression values(array $values)
65
 * @method \Wandu\Database\Query\Expression\ColumnExpression unsigned()
66
 * @method \Wandu\Database\Query\Expression\ColumnExpression binary()
67
 * @method \Wandu\Database\Query\Expression\ColumnExpression charset()
68
 * @method \Wandu\Database\Query\Expression\ColumnExpression collation()
69
 *
70
 * @method \Wandu\Database\Query\Expression\ColumnExpression first()
71
 * @method \Wandu\Database\Query\Expression\ColumnExpression after(string $column)
72
 */
73
class ColumnExpression implements ExpressionInterface
74
{
75
    use Attributes;
76
    
77
    /** @var array */
78
    protected static $typesHavingLength = [
79
        'bit',
80
        'tinyint',
81
        'smallint',
82
        'mediumint',
83
        'int',
84
        'integer',
85
        'bigint',
86
        'char',
87
        'varchar',
88
        'binary',
89
        'varbinary',
90
    ];
91
92
    /** @var array */
93
    protected static $typesHavingUnsigned = [
94
        'bit',
95
        'tinyint',
96
        'smallint',
97
        'mediumint',
98
        'int',
99
        'integer',
100
        'bigint',
101
        'real',
102
        'double',
103
        'float',
104
        'decimal',
105
        'numeric',
106
    ];
107
108
    /** @var array */
109
    protected static $typesHavingDecimal = [
110
        'real',
111
        'double',
112
        'float',
113
        'decimal',
114
        'numeric',
115
    ];
116
    
117
    /** @var array */
118
    protected static $typesHavingBinary = [
119
        'char',
120
        'varchar',
121
        'tinytext',
122
        'text',
123
        'mediumtext',
124
        'longtext',
125
    ];
126
127
    /** @var array */
128
    protected static $typesHavingFsp = [
129
        'time',
130
        'timestamp',
131
        'datetime',
132
    ];
133
134
    /** @var array */
135
    protected static $typesHavingValues = [
136
        'enum',
137
        'set',
138
    ];
139
140
    /** @var string */
141
    protected $name;
142
143
    /** @var string */
144
    protected $type;
145
    
146
    /** @var \Wandu\Database\Query\Expression\ReferenceExpression */
147
    protected $reference;
148
149
    /**
150
     * @param string $name
151
     * @param string $type
152
     * @param array $attributes
153
     */
154 2
    public function __construct($name, $type, array $attributes = [])
155
    {
156 2
        $this->name = $name;
157 2
        $this->type = $type;
158 2
        $this->attributes = $attributes;
159 2
    }
160
161
    /**
162
     * @param string $table
163
     * @param string|array $column
164
     * @return \Wandu\Database\Query\Expression\ReferenceExpression
165
     */
166 1
    public function reference($table, $column)
167
    {
168 1
        return $this->reference = new ReferenceExpression($table, is_array($column) ? $column : [$column]);
169
    }
170
171
    /**
172
     * {@inheritdoc}
173
     */
174 2
    public function toSql()
175
    {
176 2
        $stringToReturn = "`{$this->name}` " . $this->getTypeString();
177 2
        if (isset($this->attributes['nullable']) && $this->attributes['nullable']) {
178 2
            $stringToReturn .= ' NULL';
179 2
        } else {
180 2
            $stringToReturn .= ' NOT NULL';
181
        }
182 2
        if (isset($this->attributes['default'])) {
183 2
            $stringToReturn .= " DEFAULT ";
184 2
            if ($this->attributes['default'] instanceof ExpressionInterface) {
185 2
                $stringToReturn .= $this->attributes['default']->toSql();
186 2
            } else {
187 1
                $stringToReturn .= "'" . addslashes($this->attributes['default']) . "'";
188
            }
189 2
        }
190 2
        if (isset($this->attributes['auto_increment'])) {
191 2
            $stringToReturn .= " AUTO_INCREMENT";
192 2
        }
193 2
        if (isset($this->attributes['unique'])) {
194
            $stringToReturn .= ' UNIQUE KEY';
195
        }
196 2
        if (isset($this->attributes['primary'])) {
197 1
            $stringToReturn .= ' PRIMARY KEY';
198 1
        }
199 2
        if (isset($this->reference)) {
200 1
            $referenceString = $this->reference->toSql();
201 1
            if ($referenceString) {
202 1
                $stringToReturn .= " {$referenceString}";
203 1
            }
204 1
        }
205 2
        return $stringToReturn;
206
    }
207
208 2
    protected function getTypeString()
209
    {
210 2
        $stringToReturn = strtoupper($this->type);
211 2
        $lowerType = strtolower($this->type);
212 2
        $enableLength = in_array($lowerType, static::$typesHavingLength) && isset($this->attributes['length']);
213 2
        $enableDecimal = in_array($lowerType, static::$typesHavingDecimal) && isset($this->attributes['decimal']);
214 2
        $enableFsp = in_array($lowerType, static::$typesHavingFsp) && isset($this->attributes['fsp']);
215 2
        $enableValues = in_array($lowerType, static::$typesHavingValues) && isset($this->attributes['values']);
216 2
        if ($enableLength || $enableDecimal || $enableFsp || $enableValues) {
217 2
            $stringToReturn .= '(';
218 2
            if ($enableLength && $enableDecimal) {
219
                $stringToReturn .= $this->attributes['length'] . ", " . $this->attributes['decimal'];
220 2
            } elseif ($enableLength) {
221 2
                $stringToReturn .= $this->attributes['length'];
222 2
            } elseif ($enableFsp) {
223
                $stringToReturn .= $this->attributes['fsp'];
224 1
            } elseif ($enableValues) {
225 1
                $stringToReturn .= Helper::arrayImplode(", ", $this->attributes['values'], '\'', '\'');
226 1
            }
227 2
            $stringToReturn .= ')';
228 2
        }
229 2
        if (in_array($lowerType, static::$typesHavingUnsigned) && isset($this->attributes['unsigned'])) {
230 2
            $stringToReturn .= " UNSIGNED";
231 2
        }
232 2
        if (in_array($lowerType, static::$typesHavingBinary)) {
233 2
            if (isset($this->attributes['binary'])) {
234
                $stringToReturn .= " BINARY";
235
            }
236 2
            if (isset($this->attributes['charset'])) {
237
                $stringToReturn .= " CHARACTER SET {$this->attributes['charset']}";
238
            }
239 2
            if (isset($this->attributes['collation'])) {
240
                $stringToReturn .= " COLLATE {$this->attributes['collation']}";
241
            }
242 2
        }
243 2
        if (isset($this->attributes['first']) && $this->attributes['first']) {
244
            $stringToReturn .= ' FIRST';
245
        }
246 2
        if (isset($this->attributes['after'])) {
247
            $stringToReturn .= " AFTER `{$this->attributes['after']}`";
248
        }
249 2
        return $stringToReturn;
250
    }
251
252
    /**
253
     * {@inheritdoc}
254
     */
255
    public function getBindings()
256
    {
257
        return [];
258
    }
259
}
260