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.repository.Schema; 17 18 import hunt.sql.SQLUtils; 19 import hunt.sql.ast.SQLDataType; 20 import hunt.sql.ast.SQLExpr; 21 import hunt.sql.ast.SQLName; 22 import hunt.sql.ast.SQLStatement; 23 import hunt.sql.ast.expr.SQLAggregateExpr; 24 import hunt.sql.ast.expr.SQLAllColumnExpr; 25 import hunt.sql.ast.expr.SQLIdentifierExpr; 26 import hunt.sql.ast.expr.SQLPropertyExpr; 27 import hunt.sql.ast.statement; 28 import hunt.sql.dialect.mysql.ast.statement.MySqlCreateTableStatement; 29 import hunt.sql.dialect.mysql.visitor.MySqlASTVisitorAdapter; 30 // import hunt.sql.dialect.oracle.ast.stmt.OracleCreateTableStatement; 31 // import hunt.sql.dialect.oracle.visitor.OracleASTVisitorAdapter; 32 import hunt.sql.visitor.SQLASTVisitor; 33 import hunt.sql.util.FnvHash; 34 import hunt.sql.util.DBType; 35 import hunt.sql.repository.SchemaObjectType; 36 37 import hunt.collection; 38 import hunt.Long; 39 import hunt.String; 40 import hunt.sql.repository.SchemaObject; 41 import std.uni; 42 import hunt.sql.repository.SchemaRepository; 43 import hunt.text; 44 /** 45 * Created by wenshao on 21/07/2017. 46 */ 47 public class Schema { 48 private string name; 49 50 public Map!(Long, SchemaObject) objects; 51 52 public Map!(Long, SchemaObject) _functions; 53 54 private SchemaRepository repository; 55 56 this() 57 { 58 objects = new HashMap!(Long, SchemaObject)(); 59 _functions = new HashMap!(Long, SchemaObject)(); 60 } 61 62 public this(SchemaRepository repository) { 63 this(repository, null); 64 } 65 66 public this(SchemaRepository repository, string name) { 67 this(); 68 this.repository = repository; 69 this.name = name; 70 } 71 72 public string getName() { 73 return name; 74 } 75 76 public void setName(string name) { 77 this.name = name; 78 } 79 80 81 public SchemaObject findTable(string tableName) { 82 long hashCode64 = FnvHash.hashCode64(tableName); 83 return findTable(hashCode64); 84 } 85 86 public SchemaObject findTable(long nameHashCode64) { 87 SchemaObject object = objects.get(new Long(nameHashCode64)); 88 89 if (object !is null && object.getType() == SchemaObjectType.Table) { 90 return object; 91 } 92 93 return null; 94 } 95 96 public SchemaObject findTableOrView(string tableName) { 97 long hashCode64 = FnvHash.hashCode64(tableName); 98 return findTableOrView(hashCode64); 99 } 100 101 public SchemaObject findTableOrView(long hashCode64) { 102 SchemaObject object = objects.get(new Long(hashCode64)); 103 104 if (object is null) { 105 return null; 106 } 107 108 SchemaObjectType type = object.getType(); 109 if (type == SchemaObjectType.Table || type == SchemaObjectType.View) { 110 return object; 111 } 112 113 return null; 114 } 115 116 public SchemaObject findFunction(string _functionName) { 117 _functionName = SQLUtils.normalize(_functionName); 118 string lowerName = toLower(_functionName); 119 return _functions.get(new Long(lowerName)); 120 } 121 122 public bool isSequence(string name) { 123 long nameHashCode64 = FnvHash.hashCode64(name); 124 SchemaObject object = objects.get(new Long(nameHashCode64)); 125 return object !is null 126 && object.getType() == SchemaObjectType.Sequence; 127 } 128 129 130 public SchemaObject findTable(SQLTableSource tableSource, string _alias) { 131 if (cast(SQLExprTableSource)(tableSource) !is null) { 132 if (equalsIgnoreCase(_alias, tableSource.computeAlias())) { 133 SQLExprTableSource exprTableSource = cast(SQLExprTableSource) tableSource; 134 135 SchemaObject tableObject = exprTableSource.getSchemaObject(); 136 if (tableObject !is null) { 137 return tableObject; 138 } 139 140 SQLExpr expr = exprTableSource.getExpr(); 141 if (cast(SQLIdentifierExpr)(expr) !is null) { 142 long tableNameHashCode64 = (cast(SQLIdentifierExpr) expr).nameHashCode64(); 143 144 tableObject = findTable(tableNameHashCode64); 145 if (tableObject !is null) { 146 exprTableSource.setSchemaObject(tableObject); 147 } 148 return tableObject; 149 } 150 151 if (cast(SQLPropertyExpr)(expr) !is null) { 152 long tableNameHashCode64 = (cast(SQLPropertyExpr) expr).nameHashCode64(); 153 154 tableObject = findTable(tableNameHashCode64); 155 if (tableObject !is null) { 156 exprTableSource.setSchemaObject(tableObject); 157 } 158 return tableObject; 159 } 160 } 161 return null; 162 } 163 164 if (cast(SQLJoinTableSource)(tableSource) !is null) { 165 SQLJoinTableSource join = cast(SQLJoinTableSource) tableSource; 166 SQLTableSource left = join.getLeft(); 167 168 SchemaObject tableObject = findTable(left, _alias); 169 if (tableObject !is null) { 170 return tableObject; 171 } 172 173 SQLTableSource right = join.getRight(); 174 tableObject = findTable(right, _alias); 175 return tableObject; 176 } 177 178 return null; 179 } 180 181 public SQLColumnDefinition findColumn(SQLTableSource tableSource, SQLSelectItem selectItem) { 182 if (selectItem is null) { 183 return null; 184 } 185 186 return findColumn(tableSource, selectItem.getExpr()); 187 } 188 189 public SQLColumnDefinition findColumn(SQLTableSource tableSource, SQLExpr expr) { 190 SchemaObject object = findTable(tableSource, expr); 191 if (object !is null) { 192 if (cast(SQLAggregateExpr)(expr) !is null) { 193 SQLAggregateExpr aggregateExpr = cast(SQLAggregateExpr) expr; 194 string _function = aggregateExpr.getMethodName(); 195 if ("min".equalsIgnoreCase(_function) 196 || "max".equalsIgnoreCase(_function)) { 197 SQLExpr arg = aggregateExpr.getArguments().get(0); 198 expr = arg; 199 } 200 } 201 202 if (cast(SQLName)(expr) !is null) { 203 return object.findColumn((cast(SQLName) expr).getSimpleName()); 204 } 205 } 206 207 return null; 208 } 209 210 public SchemaObject findTable(SQLTableSource tableSource, SQLSelectItem selectItem) { 211 if (selectItem is null) { 212 return null; 213 } 214 215 return findTable(tableSource, selectItem.getExpr()); 216 } 217 218 public SchemaObject findTable(SQLTableSource tableSource, SQLExpr expr) { 219 if (cast(SQLAggregateExpr)(expr) !is null) { 220 SQLAggregateExpr aggregateExpr = cast(SQLAggregateExpr) expr; 221 string _function = aggregateExpr.getMethodName(); 222 if ("min".equalsIgnoreCase(_function) 223 || "max".equalsIgnoreCase(_function)) { 224 SQLExpr arg = aggregateExpr.getArguments().get(0); 225 return findTable(tableSource, arg); 226 } 227 } 228 229 if (cast(SQLPropertyExpr)(expr) !is null) { 230 string ownerName = (cast(SQLPropertyExpr) expr).getOwnernName(); 231 return findTable(tableSource, ownerName); 232 } 233 234 if (cast(SQLAllColumnExpr)(expr) !is null || cast(SQLIdentifierExpr)(expr) !is null) { 235 if (cast(SQLExprTableSource)(tableSource) !is null) { 236 return findTable(tableSource, tableSource.computeAlias()); 237 } 238 239 if (cast(SQLJoinTableSource)(tableSource) !is null) { 240 SQLJoinTableSource join = cast(SQLJoinTableSource) tableSource; 241 242 SchemaObject table = findTable(join.getLeft(), expr); 243 if (table is null) { 244 table = findTable(join.getRight(), expr); 245 } 246 return table; 247 } 248 return null; 249 } 250 251 return null; 252 } 253 254 public Map!(string, SchemaObject) getTables(SQLTableSource x) { 255 Map!(string, SchemaObject) tables = new LinkedHashMap!(string, SchemaObject)(); 256 computeTables(x, tables); 257 return tables; 258 } 259 260 protected void computeTables(SQLTableSource x, Map!(string, SchemaObject) tables) { 261 if (x is null) { 262 return; 263 } 264 265 if (cast(SQLExprTableSource)(x) !is null) { 266 SQLExprTableSource exprTableSource = cast(SQLExprTableSource) x; 267 268 SQLExpr expr = exprTableSource.getExpr(); 269 if (cast(SQLIdentifierExpr)(expr) !is null) { 270 long tableNameHashCode64 = (cast(SQLIdentifierExpr) expr).nameHashCode64(); 271 string tableName = (cast(SQLIdentifierExpr) expr).getName(); 272 273 SchemaObject table = exprTableSource.getSchemaObject(); 274 if (table is null) { 275 table = findTable(tableNameHashCode64); 276 277 if (table !is null) { 278 exprTableSource.setSchemaObject(table); 279 } 280 } 281 282 if (table !is null) { 283 tables.put(tableName, table); 284 285 string _alias = x.getAlias(); 286 if (_alias !is null && !equalsIgnoreCase(_alias, tableName)) { 287 tables.put(_alias, table); 288 } 289 } 290 } 291 292 return; 293 } 294 295 if (cast(SQLJoinTableSource)(x) !is null) { 296 SQLJoinTableSource join = cast(SQLJoinTableSource) x; 297 computeTables(join.getLeft(), tables); 298 computeTables(join.getRight(), tables); 299 } 300 } 301 302 public int getTableCount() { 303 int count = 0; 304 foreach(SchemaObject object ; this.objects.values()) { 305 if (object.getType() == SchemaObjectType.Table) { 306 count++; 307 } 308 } 309 return count; 310 } 311 312 public SchemaObject[] getObjects() { 313 return (this.objects.values()); 314 } 315 316 public int getViewCount() { 317 int count = 0; 318 foreach(SchemaObject object ; this.objects.values()) { 319 if (object.getType() == SchemaObjectType.View) { 320 count++; 321 } 322 } 323 return count; 324 } 325 326 public List!(string) showTables() { 327 List!(string) tables = new ArrayList!(string)(objects.size()); 328 foreach(SchemaObject object ; objects.values()) { 329 if (object.getType() == SchemaObjectType.Table) { 330 tables.add(object.getName()); 331 } 332 } 333 //Collections.sort(tables); //@gxc 334 return tables; 335 } 336 }