1 /*
2  * Copyright 2015-2018 HuntLabs.cn
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 module hunt.sql.dialect.mysql.visitor.MySqlShowColumnOutpuVisitor;
17 
18 import hunt.sql.SQLUtils;
19 import hunt.sql.ast.SQLExpr;
20 import hunt.sql.ast.statement.SQLColumnDefinition;
21 import hunt.sql.ast.statement.SQLCreateTableStatement;
22 import hunt.sql.ast.statement.SQLTableElement;
23 import hunt.sql.dialect.mysql.ast.MySqlUnique;
24 import hunt.sql.dialect.mysql.ast.statement.MySqlCreateTableStatement;
25 import hunt.sql.visitor.SQLASTOutputVisitor;
26 
27 import hunt.String;
28 import hunt.collection;
29 import hunt.sql.dialect.mysql.visitor.MySqlOutputVisitor;
30 import hunt.util.Appendable;
31 import hunt.util.Common;
32 import hunt.text;
33 
34 /**
35  * Created by wenshao on 27/07/2017.
36  */
37 public class MySqlShowColumnOutpuVisitor : MySqlOutputVisitor {
38 
39     alias visit = MySqlOutputVisitor.visit;
40     alias endVisit = MySqlOutputVisitor.endVisit;
41 
42     alias print = SQLASTOutputVisitor.print;
43 
44     public this(Appendable appender) {
45         super(appender);
46     }
47 
48     override public bool visit(MySqlCreateTableStatement x) {
49         List!(SQLColumnDefinition) columns = new ArrayList!(SQLColumnDefinition)();
50         List!(string) dataTypes = new ArrayList!(string)();
51         List!(string) defaultValues = new ArrayList!(string)();
52 
53         int name_len = -1, dataType_len = -1, defaultVal_len = 7, extra_len = 5;
54         foreach(SQLTableElement element ; x.getTableElementList()) {
55             if (cast(SQLColumnDefinition)(element) !is null) {
56                 SQLColumnDefinition column = cast(SQLColumnDefinition) element;
57                 columns.add(column);
58 
59                 string name = SQLUtils.normalize(column.getName().getSimpleName());
60                 if (name_len < name.length) {
61                     name_len = cast(int)(name.length);
62                 }
63 
64                 string dataType = column.getDataType().getName();
65                 if (column.getDataType().getArguments().size() > 0) {
66                     dataType ~= "(";
67                     for (int i = 0; i < column.getDataType().getArguments().size(); i++) {
68                         if (i != 0) {
69                             dataType ~= ",";
70                         }
71                         SQLExpr arg = column.getDataType().getArguments().get(i);
72                         dataType ~= (cast(Object)(arg)).toString();
73                     }
74                     dataType ~= ")";
75                 }
76 
77                 if (dataType_len < dataType.length) {
78                     dataType_len = cast(int)(dataType.length);
79                 }
80                 dataTypes.add(dataType);
81 
82                 if (column.getDefaultExpr() is null) {
83                     defaultValues.add(null);
84                 } else {
85                     string defaultVal = SQLUtils.toMySqlString(column.getDefaultExpr());
86                     if (defaultVal.length > 2 && charAt(defaultVal, 0) == '\'' && charAt(defaultVal, defaultVal.length - 1) == '\'') {
87                         defaultVal = defaultVal.substring(1, cast(int)(defaultVal.length - 1));
88                     }
89                     defaultValues.add(defaultVal);
90 
91                     if (defaultVal_len < defaultVal.length) {
92                         defaultVal_len = cast(int)(defaultVal.length);
93                     }
94                 }
95 
96                 if (column.isAutoIncrement()) {
97                     extra_len = "auto_increment".length;
98                 } else if (column.getOnUpdate() !is null) {
99                     extra_len = "on update CURRENT_TIMESTAMP".length;
100                 }
101             }
102         }
103 
104         print("+-");
105         print('-', name_len);
106         print("-+-");
107         print('-', dataType_len);
108         print("-+------+-----+-");
109         print('-', defaultVal_len);
110         print("-+-");
111         print('-', extra_len);
112         print("-+\n");
113 
114         print("| ");
115         print("Field", name_len, ' ');
116         print(" | ");
117         print("Type", dataType_len, ' ');
118         print(" | Null | Key | ");
119         print("Default", defaultVal_len, ' ');
120         print(" | ");
121         print("Extra", extra_len, ' ');
122         print(" |\n");
123 
124         print("+-");
125         print('-', name_len);
126         print("-+-");
127         print('-', dataType_len);
128         print("-+------+-----+-");
129         print('-', defaultVal_len);
130         print("-+-");
131         print('-', extra_len);
132         print("-+\n");
133 
134         for (int i = 0; i < columns.size(); i++) {
135             SQLColumnDefinition column = columns.get(i);
136             string name = SQLUtils.normalize(column.getName().getSimpleName());
137 
138             print("| ");
139             print(name, name_len, ' ');
140             print(" | ");
141 
142             print(dataTypes.get(i), dataType_len, ' ');
143             print(" | ");
144 
145             if (column.containsNotNullConstaint()) {
146                 print("NO ");
147             } else {
148                 print("YES");
149             }
150             print("  | ");
151 
152             MySqlUnique unique = null;
153             if (x.isPrimaryColumn(name)) {
154                 print("PRI");
155             } else if (x.isUNI(name)) {
156                 print("UNI");
157             } else if (x.isMUL(name)) {
158                 print("MUL");
159             } else {
160                 print("   ");
161             }
162             print(" | ");
163 
164             string defaultVal = defaultValues.get(i);
165             if (defaultVal is null) {
166                 print("NULL", defaultVal_len, ' ');
167             } else {
168                 print(defaultVal, defaultVal_len, ' ');
169             }
170             print(" | ");
171 
172             if (column.isAutoIncrement()) {
173                 print("auto_increment", extra_len, ' ');
174             } else if (column.getOnUpdate() !is null) {
175                 print("on update CURRENT_TIMESTAMP", extra_len, ' ');
176             } else {
177                 print(' ', extra_len);
178             }
179             print(" |");
180             print("\n");
181         }
182         print("+-");
183         print('-', name_len);
184         print("-+-");
185         print('-', dataType_len);
186         print("-+------+-----+-");
187         print('-', defaultVal_len);
188         print("-+-");
189         print('-', extra_len);
190         print("-+\n");
191         
192         return false;
193     }
194 
195     void print(char ch, int count) {
196         for (int i = 0; i < count; ++i)  {
197             print(ch);
198         }
199     }
200 
201     void print(string text, int columnSize, char ch) {
202         print(text);
203         print(' ', columnSize - cast(int)(text.length));
204     }
205 }