Passed
Push — master ( 31c00c...9c46e7 )
by 世昌
02:43
created

MySQLTableCreator   A

Complexity

Total Complexity 34

Size/Duplication

Total Lines 155
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
eloc 74
dl 0
loc 155
rs 9.68
c 0
b 0
f 0
wmc 34

10 Methods

Rating   Name   Duplication   Size   Complexity  
A create() 0 5 1
A toSQL() 0 18 4
A __construct() 0 5 1
A parseLength() 0 10 5
B createField() 0 19 7
A parseKeys() 0 8 3
A parseIndexKeys() 0 8 3
A parsePrimaryKeys() 0 12 4
A parseUniqueKeys() 0 8 3
A parseForeignKeys() 0 8 3
1
<?php
2
namespace suda\orm\connection\creator;
3
4
use function implode;
5
use PDO;
6
use PDOException;
7
use suda\orm\struct\Field;
8
use suda\orm\struct\Fields;
9
use suda\orm\statement\Statement;
10
use suda\orm\connection\Connection;
11
use suda\orm\exception\SQLException;
12
use suda\orm\statement\QueryStatement;
13
14
/**
15
 * 数据表链接对象
16
 *
17
 */
18
class MySQLTableCreator
19
{
20
    /**
21
     * 连接
22
     *
23
     * @var Connection
24
     */
25
    protected $connection;
26
27
    /**
28
     * 字段
29
     *
30
     * @var Fields
31
     */
32
    protected $fields;
33
34
    const ENGINE_MyISAM = 'MyISAM';
35
    const ENGINE_InnoDB = 'InnoDB';
36
37
    protected $name;
38
    protected $engine = self::ENGINE_InnoDB;
39
    protected $comment;
40
41
    protected $collate;
42
    protected $charset = 'utf8';
43
    
44
    protected $auto;
45
46
    public function __construct(Connection $connection, Fields $fields)
47
    {
48
        $this->name = $fields->getName();
49
        $this->fields = $fields;
50
        $this->connection = $connection;
51
    }
52
53
    public function create()
54
    {
55
        $statement = new QueryStatement($this->toSQL());
56
        $statement->isWrite(true);
57
        return $this->connection->query($statement) > 0;
58
    }
59
60
    protected function toSQL()
61
    {
62
        $content = [];
63
        foreach ($this->fields->all() as $field) {
64
            $content[] = $this->createField($field);
65
        }
66
        $content[] = $this->parsePrimaryKeys();
67
        $content = $this->parseUniqueKeys($content);
68
        $content = $this->parseIndexKeys($content);
69
        $content = $this->parseKeys($content);
70
        $content = $this->parseForeignKeys($content);
71
        $table = $this->connection->rawTableName($this->name);
72
        $sql = "CREATE TABLE IF NOT EXISTS `{$table}` (\r\n\t";
73
        $sql .= implode(",\r\n\t", array_filter($content, 'strlen'));
74
        $auto = null === $this->auto?'':'AUTO_INCREMENT='.$this->auto;
75
        $collate = null === $this->collate?'':'COLLATE '.$this->collate;
76
        $sql .= "\r\n) ENGINE={$this->engine} {$collate} {$auto} DEFAULT CHARSET={$this->charset};";
77
        return $sql;
78
    }
79
80
81
    protected function parsePrimaryKeys()
82
    {
83
        $primary = [];
84
        foreach ($this->fields->all() as  $field) {
85
            if ($field->getType() === Field::PRIMARY) {
86
                $primary[] = '`'.$field->getName().'`';
87
            }
88
        }
89
        if (count($primary)) {
90
            return 'PRIMARY KEY ('. implode(',', $primary).')';
91
        }
92
        return  '';
93
    }
94
95
96
    protected function parseUniqueKeys(array $content)
97
    {
98
        foreach ($this->fields->all() as  $field) {
99
            if ($field->getType() === Field::UNIQUE) {
100
                $content[] = 'UNIQUE KEY `'.$field->getName().'` (`'.$field->getName().'`)';
101
            }
102
        }
103
        return $content;
104
    }
105
106
107
    protected function parseIndexKeys(array $content)
108
    {
109
        foreach ($this->fields->all() as  $field) {
110
            if ($field->getType() === Field::INDEX) {
111
                $content[] = 'INDEX (`'.$field->getName().'`)';
112
            }
113
        }
114
        return $content;
115
    }
116
117
    protected function parseKeys(array $content)
118
    {
119
        foreach ($this->fields->all() as  $field) {
120
            if ($field->getType() === Field::INDEX) {
121
                $content[] = 'KEY `'.$field->getName().'` (`'.$field->getName().'`)';
122
            }
123
        }
124
        return $content;
125
    }
126
127
128
    protected function parseForeignKeys(array $content)
129
    {
130
        foreach ($this->fields->all() as $field) {
131
            if ($field->getForeignKey() !== null) {
132
                $content[] = 'FOREIGN KEY (`'.$field->getName().'`) REFERENCES  `#{'.$field->getTableName().'}` (`'.$field->getName().'`)';
133
            }
134
        }
135
        return $content;
136
    }
137
138
    /**
139
     * @param $length
140
     * @return string
141
     */
142
    protected function parseLength($length) {
143
        if ($length !== null) {
144
            if (is_string($length) || is_int($length)) {
145
                return '('.$length.')';
146
            }
147
            if (is_array($length)) {
148
                return '('.implode(',',$length).')';
149
            }
150
        }
151
        return  '';
152
    }
153
154
    protected function createField(Field $field)
155
    {
156
        $type = strtoupper($field->getValueType()).$this->parseLength($field->getLength());
157
        $auto = $field->getAuto() ?'AUTO_INCREMENT':'';
158
        $null = $field->isNullable() ?'NULL':'NOT NULL';
159
        $attr = $field->getAttribute() ?strtoupper($field->getAttribute()):'';
160
        $comment = $field->getComment() ?('COMMENT \''.addcslashes($field->getComment(), '\'').'\''):'';
161
        // default设置
162
        if ($field->hasDefault()) {
163
            if (null === $field->getDefault()) {
164
                $default = 'DEFAULT NULL';
165
            } else {
166
                $default = 'DEFAULT \''.addcslashes($field->getDefault(), '\'').'\'';
167
            }
168
        } else {
169
            $default = '';
170
        }
171
        $list = ['`'.$field->getName().'`', $type, $attr, $field->getCharset(), $null, $default, $auto, $comment];
172
        return implode(' ', array_filter(array_map('trim', $list), 'strlen'));
173
    }
174
}
175