MySQLTableCreator   A
last analyzed

Complexity

Total Complexity 34

Size/Duplication

Total Lines 214
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
eloc 79
dl 0
loc 214
rs 9.68
c 0
b 0
f 0
wmc 34

9 Methods

Rating   Name   Duplication   Size   Complexity  
A parseUniqueKeys() 0 8 3
A parseForeignKeys() 0 13 3
A parseLength() 0 11 5
A parsePrimaryKeys() 0 12 4
A create() 0 8 1
A parseKeys() 0 8 3
A toSQL() 0 18 4
B createField() 0 19 8
A parseIndexKeys() 0 8 3
1
<?php
2
namespace suda\application\database\creator;
3
4
use suda\database\struct\Field;
5
use suda\database\struct\TableStruct;
6
use suda\database\connection\Connection;
7
use suda\database\exception\SQLException;
8
use suda\application\database\TableCreator;
9
use suda\database\statement\QueryStatement;
10
11
/**
12
 * 数据表链接对象
13
 *
14
 */
15
class MySQLTableCreator extends TableCreator
16
{
17
    /**
18
     * 连接
19
     *
20
     * @var Connection
21
     */
22
    protected $connection;
23
24
    /**
25
     * 字段
26
     *
27
     * @var TableStruct
28
     */
29
    protected $fields;
30
31
    /**
32
     *
33
     */
34
    const ENGINE_MYISAM = 'MyISAM';
35
36
    /**
37
     *
38
     */
39
    const ENGINE_INNODB = 'InnoDB';
40
41
    /**
42
     * @var string
43
     */
44
    protected $name;
45
    /**
46
     * @var string
47
     */
48
    protected $engine = self::ENGINE_INNODB;
49
    /**
50
     * @var
51
     */
52
    protected $comment;
53
54
    /**
55
     * @var
56
     */
57
    protected $collate;
58
    /**
59
     * @var string
60
     */
61
    protected $charset = 'utf8mb4';
62
63
    /**
64
     * @var
65
     */
66
    protected $auto;
67
68
    /**
69
     * @param Connection $connection
70
     * @param TableStruct $fields
71
     * @return bool
72
     * @throws SQLException
73
     */
74
    public function create(Connection $connection, TableStruct $fields)
75
    {
76
        $this->name = $fields->getName();
77
        $this->fields = $fields;
78
        $this->connection = $connection;
79
        $statement = new QueryStatement($this->toSQL());
80
        $statement->setType(QueryStatement::WRITE);
81
        return $this->connection->query($statement) > 0;
82
    }
83
84
    /**
85
     * @return string
86
     */
87
    public function toSQL()
88
    {
89
        $content = [];
90
        foreach ($this->fields->all() as $field) {
91
            $content[] = $this->createField($field);
92
        }
93
        $content[] = $this->parsePrimaryKeys();
94
        $content = $this->parseUniqueKeys($content);
95
        $content = $this->parseIndexKeys($content);
96
        $content = $this->parseKeys($content);
97
        $content = $this->parseForeignKeys($content);
98
        $table = $this->fields->getRealTableName($this->connection);
99
        $sql = "CREATE TABLE IF NOT EXISTS `{$table}` (\r\n\t";
100
        $sql .= implode(",\r\n\t", array_filter($content, 'strlen'));
101
        $auto = null === $this->auto?'':'AUTO_INCREMENT='.$this->auto;
102
        $collate = null === $this->collate?'':'COLLATE '.$this->collate;
103
        $sql .= "\r\n) ENGINE={$this->engine} {$collate} {$auto} DEFAULT CHARSET={$this->charset};";
104
        return $sql;
105
    }
106
107
108
    /**
109
     * @return string
110
     */
111
    protected function parsePrimaryKeys()
112
    {
113
        $primary = [];
114
        foreach ($this->fields->all() as $field) {
115
            if ($field->getType() === Field::PRIMARY) {
116
                $primary[] = '`'.$field->getName().'`';
117
            }
118
        }
119
        if (count($primary)) {
120
            return 'PRIMARY KEY ('. implode(',', $primary).')';
121
        }
122
        return  '';
123
    }
124
125
126
    /**
127
     * @param array $content
128
     * @return array
129
     */
130
    protected function parseUniqueKeys(array $content)
131
    {
132
        foreach ($this->fields->all() as $field) {
133
            if ($field->getType() === Field::UNIQUE) {
134
                $content[] = 'UNIQUE KEY `'.$field->getName().'` (`'.$field->getName().'`)';
135
            }
136
        }
137
        return $content;
138
    }
139
140
141
    /**
142
     * @param array $content
143
     * @return array
144
     */
145
    protected function parseIndexKeys(array $content)
146
    {
147
        foreach ($this->fields->all() as $field) {
148
            if ($field->getType() === Field::INDEX) {
149
                $content[] = 'INDEX (`'.$field->getName().'`)';
150
            }
151
        }
152
        return $content;
153
    }
154
155
    /**
156
     * @param array $content
157
     * @return array
158
     */
159
    protected function parseKeys(array $content)
160
    {
161
        foreach ($this->fields->all() as $field) {
162
            if ($field->getType() === Field::KEY) {
163
                $content[] = 'KEY `'.$field->getName().'` (`'.$field->getName().'`)';
164
            }
165
        }
166
        return $content;
167
    }
168
169
170
    /**
171
     * @param array $content
172
     * @return array
173
     */
174
    protected function parseForeignKeys(array $content)
175
    {
176
        foreach ($this->fields->all() as $field) {
177
            if ($field->getForeignKey() !== null) {
178
                $content[] = sprintf(
179
                    "FOREIGN KEY (`%s`) REFERENCES  `_:%s` (`%s`)",
180
                    $field->getName(),
181
                    $field->getTableName(),
182
                    $field->getName()
183
                );
184
            }
185
        }
186
        return $content;
187
    }
188
189
    /**
190
     * @param $length
191
     * @return string
192
     */
193
    protected function parseLength($length)
194
    {
195
        if ($length !== null) {
196
            if (is_string($length) || is_int($length)) {
197
                return '('.$length.')';
198
            }
199
            if (is_array($length)) {
200
                return '('.implode(',', $length).')';
201
            }
202
        }
203
        return  '';
204
    }
205
206
    /**
207
     * @param Field $field
208
     * @return string
209
     */
210
    protected function createField(Field $field)
211
    {
212
        $type = strtoupper($field->getValueType()).$this->parseLength($field->getLength());
213
        $auto = $field->getAuto() ?'AUTO_INCREMENT':'';
214
        $null = $field->isNullable() === null? '': $field->isNullable() === true ? 'NULL':'NOT NULL';
215
        $attr = $field->getAttribute() ?strtoupper($field->getAttribute()):'';
216
        $comment = $field->getComment() ?('COMMENT \''.addcslashes($field->getComment(), '\'').'\''):'';
217
        // default设置
218
        if ($field->hasDefault()) {
219
            if (null === $field->getDefault()) {
220
                $default = 'DEFAULT NULL';
221
            } else {
222
                $default = 'DEFAULT \''.addcslashes($field->getDefault(), '\'').'\'';
223
            }
224
        } else {
225
            $default = '';
226
        }
227
        $list = ['`'.$field->getName().'`', $type, $attr, $field->getCharset(), $null, $default, $auto, $comment];
228
        return implode(' ', array_filter(array_map('trim', $list), 'strlen'));
229
    }
230
}
231