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.SchemaRepository;
17 
18 import std.exception;
19 import hunt.sql.SQLUtils;
20 import hunt.sql.ast;
21 import hunt.sql.ast.expr.SQLAllColumnExpr;
22 import hunt.sql.ast.expr.SQLIdentifierExpr;
23 import hunt.sql.ast.expr.SQLPropertyExpr;
24 import hunt.sql.ast.statement;
25 import hunt.sql.dialect.mysql.ast.statement;
26 import hunt.sql.dialect.mysql.visitor.MySqlASTVisitorAdapter;
27 import hunt.sql.repository.SchemaResolveVisitorFactory;
28 // import hunt.sql.dialect.oracle.ast.stmt.OracleCreateTableStatement;
29 // import hunt.sql.dialect.oracle.visitor.OracleASTVisitorAdapter;
30 import hunt.sql.visitor.SQLASTVisitor;
31 import hunt.sql.visitor.SQLASTVisitorAdapter;
32 // import hunt.sql.support.logging.Log;
33 // import hunt.sql.support.logging.LogFactory;
34 import hunt.sql.util.DBType;
35 import hunt.logging;
36 import hunt.sql.repository.SchemaObjectType;
37 import hunt.sql.repository.Schema;
38 import hunt.sql.repository.SchemaObject;
39 import hunt.sql.repository.SchemaResolveVisitor;
40 import hunt.collection;
41 import std.uni;
42 import hunt.sql.repository.SchemaObjectImpl;
43 import hunt.Long;
44 import hunt.util.Appendable;
45 import hunt.util.StringBuilder;
46 
47 
48 /**
49  * Created by wenshao on 03/06/2017.
50  */
51 public class SchemaRepository {
52     // private static Log LOG = LogFactory.getLog(SchemaRepository.class);
53     private Schema defaultSchema;
54     protected string dbType;
55     protected SQLASTVisitor consoleVisitor;
56 
57     public this() {
58         schemas = new LinkedHashMap!(string, Schema)();
59     }
60 
61     public this(string dbType) {
62         this();
63         this.dbType = dbType;
64 
65         if (DBType.MYSQL.opEquals(dbType)) {
66             consoleVisitor = new MySqlConsoleSchemaVisitor();
67         } else if (DBType.ORACLE.opEquals(dbType)) {
68             // consoleVisitor = new OracleConsoleSchemaVisitor();
69         } else {
70             consoleVisitor = new DefaultConsoleSchemaVisitor();
71         }
72     }
73 
74     private Map!(string, Schema) schemas;
75 
76     public string getDbType() {
77         return dbType;
78     }
79 
80     public string getDefaultSchemaName() {
81         return getDefaultSchema().getName();
82     }
83 
84     public void setDefaultSchema(string name) {
85         if (name is null) {
86             defaultSchema = null;
87             return;
88         }
89 
90         string normalizedName = toLower(SQLUtils.normalize(name));
91 
92         Schema defaultSchema = schemas.get(normalizedName);
93         if (defaultSchema !is null) {
94             this.defaultSchema = defaultSchema;
95             return;
96         }
97 
98         if (defaultSchema is null) {
99             if (this.defaultSchema !is null
100                     && this.defaultSchema.getName() is null) {
101                 this.defaultSchema.setName(name);
102 
103                 schemas.put(normalizedName, this.defaultSchema);
104                 return;
105             }
106 
107             defaultSchema = new Schema(this);
108             defaultSchema.setName(name);
109             schemas.put(normalizedName, defaultSchema);
110             this.defaultSchema = defaultSchema;
111         }
112     }
113 
114     public Schema findSchema(string schema) {
115         return findSchema(schema, false);
116     }
117 
118     protected Schema findSchema(string name, bool create) {
119         if (name is null || name.length == 0) {
120             return getDefaultSchema();
121         }
122 
123         name = SQLUtils.normalize(name);
124         string normalizedName = toLower(name);
125 
126         if (getDefaultSchema() !is null && defaultSchema.getName() is null) {
127             defaultSchema.setName(name);
128             schemas.put(normalizedName, defaultSchema);
129             return defaultSchema;
130         }
131 
132         Schema schema = schemas.get(normalizedName);
133         if (schema is null) {
134             schema = new Schema(this, name);
135             schemas.put(normalizedName, schema);
136         }
137         return schema;
138     }
139 
140     public Schema getDefaultSchema() {
141         if (defaultSchema is null) {
142             defaultSchema = new Schema(this);
143         }
144 
145         return defaultSchema;
146     }
147 
148     public void setDefaultSchema(Schema schema) {
149         this.defaultSchema = schema;
150     }
151 
152     public SchemaObject findTable(string tableName) {
153         return getDefaultSchema().findTable(tableName);
154     }
155 
156     public SchemaObject findTableOrView(string tableName) {
157         return findTableOrView(tableName, true);
158     }
159 
160     public SchemaObject findTableOrView(string tableName, bool onlyCurrent) {
161         Schema schema = getDefaultSchema();
162 
163         SchemaObject object = schema.findTableOrView(tableName);
164         if (object !is null) {
165             return object;
166         }
167 
168         foreach(Schema s ; this.schemas.values()) {
169             if (s == schema) {
170                 continue;
171             }
172 
173             object = schema.findTableOrView(tableName);
174             if (object !is null) {
175                 return object;
176             }
177         }
178 
179         return null;
180     }
181 
182     public Schema[] getSchemas() {
183         return schemas.values();
184     }
185 
186     public SchemaObject findFunction(string functionName) {
187         return getDefaultSchema().findFunction(functionName);
188     }
189 
190     public void acceptDDL(string ddl) {
191         acceptDDL(ddl, dbType);
192     }
193 
194     public void acceptDDL(string ddl, string dbType) {
195         List!(SQLStatement) stmtList = SQLUtils.parseStatements(ddl, dbType);
196         foreach(SQLStatement stmt ; stmtList) {
197             accept(stmt);
198         }
199     }
200 
201     public void accept(SQLStatement stmt) {
202         stmt.accept(consoleVisitor);
203     }
204 
205     public bool isSequence(string name) {
206         return getDefaultSchema().isSequence(name);
207     }
208 
209     public SchemaObject findTable(SQLTableSource tableSource, string _alias) {
210         return getDefaultSchema().findTable(tableSource, _alias);
211     }
212 
213     public SQLColumnDefinition findColumn(SQLTableSource tableSource, SQLSelectItem selectItem) {
214         return getDefaultSchema().findColumn(tableSource, selectItem);
215     }
216 
217     public SQLColumnDefinition findColumn(SQLTableSource tableSource, SQLExpr expr) {
218         return getDefaultSchema().findColumn(tableSource, expr);
219     }
220 
221     public SchemaObject findTable(SQLTableSource tableSource, SQLSelectItem selectItem) {
222         return getDefaultSchema().findTable(tableSource, selectItem);
223     }
224 
225     public SchemaObject findTable(SQLTableSource tableSource, SQLExpr expr) {
226         return getDefaultSchema().findTable(tableSource, expr);
227     }
228 
229     public Map!(string, SchemaObject) getTables(SQLTableSource x) {
230         return getDefaultSchema().getTables(x);
231     }
232 
233     public int getTableCount() {
234         return getDefaultSchema().getTableCount();
235     }
236 
237     public SchemaObject[] getObjects() {
238         return getDefaultSchema().getObjects();
239     }
240 
241     public int getViewCount() {
242         return getDefaultSchema().getViewCount();
243     }
244 
245     public void resolve(SQLSelectStatement stmt, SchemaResolveVisitor.Option[] options...) {
246         if (stmt is null) {
247             return;
248         }
249 
250         SchemaResolveVisitor resolveVisitor = createResolveVisitor(options);
251         resolveVisitor.visit(stmt);
252     }
253 
254     public void resolve(SQLStatement stmt, SchemaResolveVisitor.Option[] options...) {
255         if (stmt is null) {
256             return;
257         }
258 
259         SchemaResolveVisitor resolveVisitor = createResolveVisitor(options);
260         stmt.accept(resolveVisitor);
261     }
262 
263     private SchemaResolveVisitor createResolveVisitor(SchemaResolveVisitor.Option[] options...) {
264         int optionsValue = SchemaResolveVisitor.Option.of(options);
265 
266         SchemaResolveVisitor resolveVisitor;
267         if (DBType.MYSQL.opEquals(dbType)
268                 || DBType.SQLITE.opEquals(dbType)) {
269             resolveVisitor = new SchemaResolveVisitorFactory.MySqlResolveVisitor(this, optionsValue);
270         } else if (DBType.ORACLE.opEquals(dbType)) {
271             // resolveVisitor = new SchemaResolveVisitorFactory.OracleResolveVisitor(this, optionsValue);
272         } else if (DBType.DB2.opEquals(dbType)) {
273             // resolveVisitor = new SchemaResolveVisitorFactory.DB2ResolveVisitor(this, optionsValue);
274         } else if (DBType.ODPS.opEquals(dbType)) {
275             // resolveVisitor = new SchemaResolveVisitorFactory.OdpsResolveVisitor(this, optionsValue);
276         } else if (DBType.HIVE.opEquals(dbType)) {
277             // resolveVisitor = new SchemaResolveVisitorFactory.HiveResolveVisitor(this, optionsValue);
278         } else if (DBType.POSTGRESQL.opEquals(dbType)) {
279             resolveVisitor = new SchemaResolveVisitorFactory.PGResolveVisitor(this, optionsValue);
280         } else if (DBType.SQL_SERVER.opEquals(dbType)) {
281             // resolveVisitor = new SchemaResolveVisitorFactory.SQLServerResolveVisitor(this, optionsValue);
282         } else {
283             // resolveVisitor = new SchemaResolveVisitorFactory.SQLResolveVisitor(this, optionsValue);
284         }
285         return resolveVisitor;
286     }
287 
288     public string resolve(string input) {
289         SchemaResolveVisitor visitor
290                 = createResolveVisitor(
291                     SchemaResolveVisitor.Option.ResolveAllColumn,
292                     SchemaResolveVisitor.Option.ResolveIdentifierAlias);
293 
294         List!(SQLStatement) stmtList = SQLUtils.parseStatements(input, dbType);
295 
296         foreach(SQLStatement stmt ; stmtList) {
297             stmt.accept(visitor);
298         }
299 
300         return SQLUtils.toSQLString(stmtList, dbType);
301     }
302 
303     public string console(string input) {
304         try {
305             StringBuilder buf = new StringBuilder();
306 
307             List!(SQLStatement) stmtList = SQLUtils.parseStatements(input, dbType);
308 
309             foreach(SQLStatement stmt ; stmtList) {
310                 if (cast(MySqlShowColumnsStatement)(stmt) !is null) {
311                     MySqlShowColumnsStatement showColumns = (cast(MySqlShowColumnsStatement) stmt);
312                     SQLName db = showColumns.getDatabase();
313                     Schema schema;
314                     if (db is null) {
315                         schema = getDefaultSchema();
316                     } else {
317                         schema = findSchema(db.getSimpleName());
318                     }
319 
320                     SQLName table = null;
321                     SchemaObject schemaObject = null;
322                     if (schema !is null) {
323                         table = showColumns.getTable();
324                         schemaObject = schema.findTable(table.nameHashCode64());
325                     }
326 
327                     if (schemaObject is null) {
328                         buf.append("ERROR 1146 (42S02): Table '" ~ table.stringof ~ "' doesn't exist\n");
329                     } else {
330                         MySqlCreateTableStatement createTableStmt = cast(MySqlCreateTableStatement) schemaObject.getStatement();
331                         createTableStmt.showCoumns(buf);
332                     }
333                 } else if (cast(MySqlShowCreateTableStatement)(stmt) !is null) {
334                     MySqlShowCreateTableStatement showCreateTableStmt = cast(MySqlShowCreateTableStatement) stmt;
335                     SQLName table = showCreateTableStmt.getName();
336                     SchemaObject schemaObject = findTable(table);
337                     if (schemaObject is null) {
338                         buf.append("ERROR 1146 (42S02): Table '" ~ table.stringof ~ "' doesn't exist\n");
339                     } else {
340                         MySqlCreateTableStatement createTableStmt = cast(MySqlCreateTableStatement) schemaObject.getStatement();
341                         createTableStmt.output(buf);
342                     }
343                 } else if (cast(MySqlRenameTableStatement)(stmt) !is null) {
344                     MySqlRenameTableStatement renameStmt = cast(MySqlRenameTableStatement) stmt;
345                     foreach(MySqlRenameTableStatement.Item item ; renameStmt.getItems()) {
346                         renameTable(item.getName(), item.getTo());
347                     }
348                 } else if (cast(SQLShowTablesStatement)(stmt) !is null) {
349                     SQLShowTablesStatement showTables = cast(SQLShowTablesStatement) stmt;
350                     SQLName database = showTables.getDatabase();
351 
352                     Schema schema;
353                     if (database is null) {
354                         schema = getDefaultSchema();
355                     } else {
356                         schema = findSchema(database.getSimpleName());
357                     }
358                     if (schema !is null) {
359                         foreach(string table ; schema.showTables()) {
360                             buf.append(table);
361                             buf.append('\n');
362                         }
363                     }
364                 } else {
365                     stmt.accept(consoleVisitor);
366                 }
367             }
368 
369             if (buf.length == 0) {
370                 return "\n";
371             }
372 
373             return buf.toString();
374         } catch (Exception ex) {
375             throw new Exception("exeucte command error.", ex);
376         }
377     }
378 
379     public SchemaObject findTable(SQLName name) {
380         if (cast(SQLIdentifierExpr)(name) !is null) {
381             return findTable((cast(SQLIdentifierExpr) name).getName());
382         }
383 
384         if (cast(SQLPropertyExpr)(name) !is null) {
385             SQLPropertyExpr propertyExpr = cast(SQLPropertyExpr) name;
386             string schema = propertyExpr.getOwnernName();
387             long tableHashCode64 = propertyExpr.nameHashCode64();
388 
389             Schema schemaObj = findSchema(schema);
390             if (schemaObj is null) {
391                 return null;
392             }
393 
394             return schemaObj.findTable(tableHashCode64);
395         }
396 
397         return null;
398     }
399 
400     private bool renameTable(SQLName name, SQLName to) {
401         Schema schema;
402         if (cast(SQLPropertyExpr)(name) !is null) {
403             string schemaName = (cast(SQLPropertyExpr) name).getOwnernName();
404             schema = findSchema(schemaName);
405         } else {
406             schema = getDefaultSchema();
407         }
408 
409         if (schema is null) {
410             return false;
411         }
412 
413         long nameHashCode64 = name.nameHashCode64();
414         SchemaObject schemaObject = schema.findTable(nameHashCode64);
415         if (schemaObject !is null) {
416             MySqlCreateTableStatement createTableStmt = cast(MySqlCreateTableStatement) schemaObject.getStatement();
417             if (createTableStmt !is null) {
418                 createTableStmt.setName(to.clone());
419             }
420 
421             schema.objects.put(new Long(to.hashCode64()), schemaObject);
422             schema.objects.remove(new Long(nameHashCode64));
423         }
424         return true;
425     }
426 
427 
428     public SchemaObject findTable(SQLExprTableSource x) {
429         if (x is null) {
430             return null;
431         }
432 
433         SQLExpr expr = x.getExpr();
434         if (cast(SQLName)(expr) !is null) {
435             return findTable(cast(SQLName) expr);
436         }
437 
438         return null;
439     }
440 
441     public class MySqlConsoleSchemaVisitor : MySqlASTVisitorAdapter {
442         alias endVisit = MySqlASTVisitorAdapter.endVisit;
443       alias visit = MySqlASTVisitorAdapter.visit;
444         override public bool visit(SQLDropSequenceStatement x) {
445             acceptDropSequence(x);
446             return false;
447         }
448 
449         override public bool visit(SQLCreateSequenceStatement x) {
450             acceptCreateSequence(x);
451             return false;
452         }
453 
454         override public bool visit(MySqlCreateTableStatement x) {
455             acceptCreateTable(x);
456             return false;
457         }
458 
459         override public bool visit(SQLCreateTableStatement x) {
460             acceptCreateTable(x);
461             return false;
462         }
463 
464         override public bool visit(SQLDropTableStatement x) {
465             acceptDropTable(x);
466             return false;
467         }
468 
469         override public bool visit(SQLCreateViewStatement x) {
470             acceptView(x);
471             return false;
472         }
473 
474         override public bool visit(SQLAlterViewStatement x) {
475             acceptView(x);
476             return false;
477         }
478 
479         override public bool visit(SQLCreateIndexStatement x) {
480             acceptCreateIndex(x);
481             return false;
482         }
483 
484         override public bool visit(SQLCreateFunctionStatement x) {
485             acceptCreateFunction(x);
486             return false;
487         }
488 
489         override public bool visit(SQLAlterTableStatement x) {
490             acceptAlterTable(x);
491             return false;
492         }
493 
494         override public bool visit(SQLUseStatement x) {
495             string schema = x.getDatabase().getSimpleName();
496             setDefaultSchema(schema);
497             return false;
498         }
499 
500         override public bool visit(SQLDropIndexStatement x) {
501             acceptDropIndex(x);
502             return false;
503         }
504     }
505 
506     // public class OracleConsoleSchemaVisitor : OracleASTVisitorAdapter {
507     //     public bool visit(SQLDropSequenceStatement x) {
508     //         acceptDropSequence(x);
509     //         return false;
510     //     }
511 
512     //     public bool visit(SQLCreateSequenceStatement x) {
513     //         acceptCreateSequence(x);
514     //         return false;
515     //     }
516 
517     //     public bool visit(OracleCreateTableStatement x) {
518     //         visit(cast(SQLCreateTableStatement) x);
519     //         return false;
520     //     }
521 
522     //     public bool visit(SQLCreateTableStatement x) {
523     //         acceptCreateTable(x);
524     //         return false;
525     //     }
526 
527     //     public bool visit(SQLDropTableStatement x) {
528     //         acceptDropTable(x);
529     //         return false;
530     //     }
531 
532     //     public bool visit(SQLCreateViewStatement x) {
533     //         acceptView(x);
534     //         return false;
535     //     }
536 
537     //     public bool visit(SQLAlterViewStatement x) {
538     //         acceptView(x);
539     //         return false;
540     //     }
541 
542     //     public bool visit(SQLCreateIndexStatement x) {
543     //         acceptCreateIndex(x);
544     //         return false;
545     //     }
546 
547     //     public bool visit(SQLCreateFunctionStatement x) {
548     //         acceptCreateFunction(x);
549     //         return false;
550     //     }
551 
552     //     public bool visit(SQLAlterTableStatement x) {
553     //         acceptAlterTable(x);
554     //         return false;
555     //     }
556 
557     //     public bool visit(SQLUseStatement x) {
558     //         string schema = x.getDatabase().getSimpleName();
559     //         setDefaultSchema(schema);
560     //         return false;
561     //     }
562 
563     //     public bool visit(SQLDropIndexStatement x) {
564     //         acceptDropIndex(x);
565     //         return false;
566     //     }
567     // }
568 
569     public class DefaultConsoleSchemaVisitor : SQLASTVisitorAdapter {
570 
571         alias endVisit = SQLASTVisitorAdapter.endVisit;
572         alias visit = SQLASTVisitorAdapter.visit;
573 
574         override public bool visit(SQLDropSequenceStatement x) {
575             acceptDropSequence(x);
576             return false;
577         }
578 
579         override public bool visit(SQLCreateSequenceStatement x) {
580             acceptCreateSequence(x);
581             return false;
582         }
583 
584         override public bool visit(SQLCreateTableStatement x) {
585             acceptCreateTable(x);
586             return false;
587         }
588 
589         override public bool visit(SQLDropTableStatement x) {
590             acceptDropTable(x);
591             return false;
592         }
593 
594         override public bool visit(SQLCreateViewStatement x) {
595             acceptView(x);
596             return false;
597         }
598 
599         override public bool visit(SQLAlterViewStatement x) {
600             acceptView(x);
601             return false;
602         }
603 
604         override public bool visit(SQLCreateIndexStatement x) {
605             acceptCreateIndex(x);
606             return false;
607         }
608 
609         override public bool visit(SQLCreateFunctionStatement x) {
610             acceptCreateFunction(x);
611             return false;
612         }
613 
614         override public bool visit(SQLAlterTableStatement x) {
615             acceptAlterTable(x);
616             return false;
617         }
618 
619         override public bool visit(SQLDropIndexStatement x) {
620             acceptDropIndex(x);
621             return false;
622         }
623     }
624 
625     bool acceptCreateTable(MySqlCreateTableStatement x) {
626         SQLExprTableSource like = x.getLike();
627         if (like !is null) {
628             SchemaObject table = findTable(cast(SQLName) like.getExpr());
629             if (table !is null) {
630                 MySqlCreateTableStatement stmt = cast(MySqlCreateTableStatement) table.getStatement();
631                 MySqlCreateTableStatement stmtCloned = stmt.clone();
632                 stmtCloned.setName(x.getName().clone());
633                 acceptCreateTable(cast(SQLCreateTableStatement) stmtCloned);
634                 return false;
635             }
636         }
637 
638         return acceptCreateTable(cast(SQLCreateTableStatement) x);
639     }
640 
641     bool acceptCreateTable(SQLCreateTableStatement x) {
642         SQLCreateTableStatement x1 = x.clone();
643         string schemaName = x1.getSchema();
644 
645         Schema schema = findSchema(schemaName, true);
646 
647         SQLSelect select = x1.getSelect();
648         if (select !is null) {
649             select.accept(createResolveVisitor(SchemaResolveVisitor.Option.ResolveAllColumn));
650 
651             SQLSelectQueryBlock queryBlock = select.getFirstQueryBlock();
652             if (queryBlock !is null) {
653                 List!(SQLSelectItem) selectList = queryBlock.getSelectList();
654                 foreach(SQLSelectItem selectItem ; selectList) {
655                     SQLExpr selectItemExpr = selectItem.getExpr();
656                     if (cast(SQLAllColumnExpr)(selectItemExpr) !is null
657                             || (cast(SQLPropertyExpr)(selectItemExpr) !is null && (cast(SQLPropertyExpr) selectItemExpr).getName() == ("*"))) {
658                         continue;
659                     }
660 
661                     string name = selectItem.computeAlias();
662                     SQLDataType dataType = selectItem.computeDataType();
663                     SQLColumnDefinition column = new SQLColumnDefinition();
664                     column.setName(name);
665                     column.setDataType(dataType);
666                     column.setDbType(dbType);
667                     x1.getTableElementList().add(column);
668                 }
669                 if (x1.getTableElementList().size() > 0) {
670                     x1.setSelect(null);
671                 }
672             }
673         }
674 
675         SQLExprTableSource like = x1.getLike();
676         if (like !is null) {
677             SchemaObject tableObject = null;
678 
679             SQLName name = like.getName();
680             if (name !is null) {
681                 tableObject = findTable(name);
682             }
683 
684             SQLCreateTableStatement tableStmt = null;
685             if (tableObject !is null) {
686                 SQLStatement stmt = tableObject.getStatement();
687                 if (cast(SQLCreateTableStatement)(stmt) !is null) {
688                     tableStmt = cast(SQLCreateTableStatement) stmt;
689                 }
690             }
691 
692             if (tableStmt !is null) {
693                 SQLName tableName = x1.getName();
694                 tableStmt.cloneTo(x1);
695                 x1.setName(tableName);
696                 x1.setLike(cast(SQLExprTableSource) null);
697             }
698         }
699 
700         x1.setSchema(null);
701 
702         string name = x1.computeName();
703         SchemaObject table = schema.findTableOrView(name);
704         if (table !is null) {
705             info("replaced table '" ~ name ~ "'");
706         }
707 
708         table = new SchemaObjectImpl(name, SchemaObjectType.Table, x1);
709         schema.objects.put(new Long(table.nameHashCode64()), table);
710         return true;
711     }
712 
713     bool acceptDropTable(SQLDropTableStatement x) {
714         foreach(SQLExprTableSource table ; x.getTableSources()) {
715             string schemaName = table.getSchema();
716             Schema schema = findSchema(schemaName, false);
717             if (schema is null) {
718                 continue;
719             }
720             long nameHashCode64 = table.getName().nameHashCode64();
721             schema.objects.remove(new Long(nameHashCode64));
722         }
723         return true;
724     }
725 
726     bool acceptView(SQLCreateViewStatement x) {
727         string schemaName = x.getSchema();
728 
729         Schema schema = findSchema(schemaName, true);
730 
731         string name = x.computeName();
732         SchemaObject view = schema.findTableOrView(name);
733         if (view !is null) {
734             return false;
735         }
736 
737         SchemaObject object = new SchemaObjectImpl(name, SchemaObjectType.View, x.clone());
738         schema.objects.put(new Long(object.nameHashCode64()), object);
739         return true;
740     }
741 
742     bool acceptView(SQLAlterViewStatement x) {
743         string schemaName = x.getSchema();
744 
745         Schema schema = findSchema(schemaName, true);
746 
747         string name = x.computeName();
748         SchemaObject view = schema.findTableOrView(name);
749         if (view !is null) {
750             return false;
751         }
752 
753         SchemaObject object = new SchemaObjectImpl(name, SchemaObjectType.View, x.clone());
754         schema.objects.put(new Long(object.nameHashCode64()), object);
755         return true;
756     }
757 
758     bool acceptDropIndex(SQLDropIndexStatement x) {
759         SQLName table = x.getTableName().getName();
760         SchemaObject object = findTable(table);
761 
762         if (object !is null) {
763             SQLCreateTableStatement stmt = cast(SQLCreateTableStatement) object.getStatement();
764             if (stmt !is null) {
765                 stmt.apply(x);
766                 return true;
767             }
768         }
769 
770         return false;
771     }
772 
773     bool acceptCreateIndex(SQLCreateIndexStatement x) {
774         string schemaName = x.getSchema();
775 
776         Schema schema = findSchema(schemaName, true);
777 
778         string name = x.getName().getSimpleName();
779         SchemaObject object = new SchemaObjectImpl(name, SchemaObjectType.Index, x.clone());
780         schema.objects.put(new Long(object.nameHashCode64()), object);
781 
782         return true;
783     }
784 
785     bool acceptCreateFunction(SQLCreateFunctionStatement x) {
786         string schemaName = x.getSchema();
787         Schema schema = findSchema(schemaName, true);
788 
789         string name = x.getName().getSimpleName();
790         SchemaObject object = new SchemaObjectImpl(name, SchemaObjectType.Function, x.clone());
791         schema._functions.put(new Long(object.nameHashCode64()), object);
792 
793         return true;
794     }
795 
796     bool acceptAlterTable(SQLAlterTableStatement x) {
797         string schemaName = x.getSchema();
798         Schema schema = findSchema(schemaName, true);
799 
800         SchemaObject object = schema.findTable(x.nameHashCode64());
801         if (object !is null) {
802             SQLCreateTableStatement stmt = cast(SQLCreateTableStatement) object.getStatement();
803             if (stmt !is null) {
804                 stmt.apply(x);
805                 return true;
806             }
807         }
808 
809         return false;
810     }
811 
812     public bool acceptCreateSequence(SQLCreateSequenceStatement x) {
813         string schemaName = x.getSchema();
814         Schema schema = findSchema(schemaName, true);
815 
816         string name = x.getName().getSimpleName();
817         SchemaObject object = new SchemaObjectImpl(name, SchemaObjectType.Sequence);
818         schema.objects.put(new Long(object.nameHashCode64()), object);
819         return false;
820     }
821 
822     public bool acceptDropSequence(SQLDropSequenceStatement x) {
823         string schemaName = x.getSchema();
824         Schema schema = findSchema(schemaName, true);
825 
826         long nameHashCode64 = x.getName().nameHashCode64();
827         schema.objects.remove(new Long(nameHashCode64));
828         return false;
829     }
830 }