From 42caa77deec6d6ada4b6a0ddee164fd3abb89092 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=B8=A9=E5=B0=91?= Date: Mon, 12 Mar 2012 20:42:56 +0800 Subject: [PATCH] add mapping support --- .../alibaba/druid/mapping/MappingEngine.java | 50 +++++++------------ .../druid/mapping/MappingProvider.java | 13 +++++ .../alibaba/druid/mapping/MappingVisitor.java | 18 ++++--- .../druid/mapping/MySqlMappingProvider.java | 45 +++++++++++++++++ .../druid/mapping/OracleMappingProvider.java | 28 +++++++++++ 5 files changed, 113 insertions(+), 41 deletions(-) create mode 100644 src/main/java/com/alibaba/druid/mapping/MappingProvider.java create mode 100644 src/main/java/com/alibaba/druid/mapping/MySqlMappingProvider.java create mode 100644 src/main/java/com/alibaba/druid/mapping/OracleMappingProvider.java diff --git a/src/main/java/com/alibaba/druid/mapping/MappingEngine.java b/src/main/java/com/alibaba/druid/mapping/MappingEngine.java index 8257f4c5e9..669da5faae 100644 --- a/src/main/java/com/alibaba/druid/mapping/MappingEngine.java +++ b/src/main/java/com/alibaba/druid/mapping/MappingEngine.java @@ -2,17 +2,14 @@ package com.alibaba.druid.mapping; import java.util.LinkedHashMap; -import com.alibaba.druid.sql.SQLUtils; -import com.alibaba.druid.sql.ast.expr.SQLNumberExpr; -import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlSelectQueryBlock; -import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlSelectQueryBlock.Limit; -import com.alibaba.druid.sql.dialect.mysql.parser.MySqlSelectParser; -import com.alibaba.druid.sql.visitor.SQLASTVisitor; +import com.alibaba.druid.sql.ast.statement.SQLSelectQueryBlock; +import com.alibaba.druid.sql.visitor.SQLASTOutputVisitor; public class MappingEngine { private LinkedHashMap entities = new LinkedHashMap(); private Integer maxLimit; + private MappingProvider provider; public Integer getMaxLimit() { return maxLimit; @@ -30,36 +27,23 @@ public class MappingEngine { this.entities.put(entity.getName(), entity); } - public SQLASTVisitor createMySqlMappingVisitor() { - return new MySqlMappingVisitor(entities); + public MappingVisitor createMappingVisitor() { + return provider.createMappingVisitor(this); } - public String explainToMySql(String sql) { - MySqlSelectQueryBlock query = explainToMySqlObject(sql); - - query.accept(this.createMySqlMappingVisitor()); - - return SQLUtils.toMySqlString(query); + public SQLASTOutputVisitor createOutputVisitor(Appendable out) { + return provider.createOutputVisitor(this, out); } - public MySqlSelectQueryBlock explainToMySqlObject(String sql) { - MySqlSelectParser selectParser = new MySqlSelectParser(sql); - MySqlSelectQueryBlock query = (MySqlSelectQueryBlock) selectParser.query(); - - if (this.maxLimit != null) { - if (query.getLimit() == null) { - Limit limit = new Limit(); - limit.setRowCount(new SQLNumberExpr(maxLimit)); - query.setLimit(limit); - } else { - SQLNumberExpr rowCountExpr = (SQLNumberExpr) query.getLimit().getRowCount(); - int rowCount = rowCountExpr.getNumber().intValue(); - if (rowCount > maxLimit.intValue()) { - rowCountExpr.setNumber(maxLimit); - } - } - } - - return query; + public String explainToSQL(String sql) { + SQLSelectQueryBlock query = provider.explainToSQLObject(this, sql); + + query.accept(this.createMappingVisitor()); + + StringBuilder out = new StringBuilder(); + SQLASTOutputVisitor outputVisitor = createOutputVisitor(out); + query.accept(outputVisitor); + + return out.toString(); } } diff --git a/src/main/java/com/alibaba/druid/mapping/MappingProvider.java b/src/main/java/com/alibaba/druid/mapping/MappingProvider.java new file mode 100644 index 0000000000..160fb2164a --- /dev/null +++ b/src/main/java/com/alibaba/druid/mapping/MappingProvider.java @@ -0,0 +1,13 @@ +package com.alibaba.druid.mapping; + +import com.alibaba.druid.sql.ast.statement.SQLSelectQueryBlock; +import com.alibaba.druid.sql.visitor.SQLASTOutputVisitor; + +public interface MappingProvider { + + MappingVisitor createMappingVisitor(MappingEngine engine); + + SQLASTOutputVisitor createOutputVisitor(MappingEngine engine, Appendable out); + + SQLSelectQueryBlock explainToSQLObject(MappingEngine engine, String sql); +} diff --git a/src/main/java/com/alibaba/druid/mapping/MappingVisitor.java b/src/main/java/com/alibaba/druid/mapping/MappingVisitor.java index 4436c3e296..534b946477 100644 --- a/src/main/java/com/alibaba/druid/mapping/MappingVisitor.java +++ b/src/main/java/com/alibaba/druid/mapping/MappingVisitor.java @@ -3,13 +3,15 @@ package com.alibaba.druid.mapping; import java.util.Map; import com.alibaba.druid.sql.ast.statement.SQLTableSource; +import com.alibaba.druid.sql.visitor.SQLASTVisitor; -public interface MappingVisitor { - Entity getFirstEntity(); - - Entity getEntity(String name); - - Map getEntities(); - - Map getTableSources(); +public interface MappingVisitor extends SQLASTVisitor { + + Entity getFirstEntity(); + + Entity getEntity(String name); + + Map getEntities(); + + Map getTableSources(); } diff --git a/src/main/java/com/alibaba/druid/mapping/MySqlMappingProvider.java b/src/main/java/com/alibaba/druid/mapping/MySqlMappingProvider.java new file mode 100644 index 0000000000..4048e4d550 --- /dev/null +++ b/src/main/java/com/alibaba/druid/mapping/MySqlMappingProvider.java @@ -0,0 +1,45 @@ +package com.alibaba.druid.mapping; + +import com.alibaba.druid.sql.ast.expr.SQLNumberExpr; +import com.alibaba.druid.sql.ast.statement.SQLSelectQueryBlock; +import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlSelectQueryBlock; +import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlSelectQueryBlock.Limit; +import com.alibaba.druid.sql.dialect.mysql.parser.MySqlSelectParser; +import com.alibaba.druid.sql.dialect.mysql.visitor.MySqlOutputVisitor; +import com.alibaba.druid.sql.visitor.SQLASTOutputVisitor; + +public class MySqlMappingProvider implements MappingProvider { + + @Override + public MappingVisitor createMappingVisitor(MappingEngine engine) { + return new MySqlMappingVisitor(engine.getEntities()); + } + + @Override + public SQLASTOutputVisitor createOutputVisitor(MappingEngine engine, Appendable out) { + return new MySqlOutputVisitor(out); + } + + public SQLSelectQueryBlock explainToSQLObject(MappingEngine engine, String sql) { + MySqlSelectParser selectParser = new MySqlSelectParser(sql); + MySqlSelectQueryBlock query = (MySqlSelectQueryBlock) selectParser.query(); + + Integer maxLimit = engine.getMaxLimit(); + + if (maxLimit != null) { + if (query.getLimit() == null) { + Limit limit = new Limit(); + limit.setRowCount(new SQLNumberExpr(maxLimit)); + query.setLimit(limit); + } else { + SQLNumberExpr rowCountExpr = (SQLNumberExpr) query.getLimit().getRowCount(); + int rowCount = rowCountExpr.getNumber().intValue(); + if (rowCount > maxLimit.intValue()) { + rowCountExpr.setNumber(maxLimit); + } + } + } + + return query; + } +} diff --git a/src/main/java/com/alibaba/druid/mapping/OracleMappingProvider.java b/src/main/java/com/alibaba/druid/mapping/OracleMappingProvider.java new file mode 100644 index 0000000000..d4225a84ad --- /dev/null +++ b/src/main/java/com/alibaba/druid/mapping/OracleMappingProvider.java @@ -0,0 +1,28 @@ +package com.alibaba.druid.mapping; + +import com.alibaba.druid.sql.ast.statement.SQLSelectQueryBlock; +import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleSelectQueryBlock; +import com.alibaba.druid.sql.dialect.oracle.parser.OracleSelectParser; +import com.alibaba.druid.sql.dialect.oracle.visitor.OracleOutputVisitor; +import com.alibaba.druid.sql.visitor.SQLASTOutputVisitor; + +public class OracleMappingProvider implements MappingProvider { + + @Override + public MappingVisitor createMappingVisitor(MappingEngine engine) { + return new OracleMappingVisitor(engine.getEntities()); + } + + @Override + public SQLASTOutputVisitor createOutputVisitor(MappingEngine engine, Appendable out) { + return new OracleOutputVisitor(out); + } + + public SQLSelectQueryBlock explainToSQLObject(MappingEngine engine, String sql) { + OracleSelectParser selectParser = new OracleSelectParser(sql); + OracleSelectQueryBlock query = (OracleSelectQueryBlock) selectParser.query(); + + return query; + } + +}