diff --git a/src/main/java/com/alibaba/druid/mapping/spi/ExportParameterVisitor.java b/src/main/java/com/alibaba/druid/mapping/spi/ExportParameterVisitor.java new file mode 100644 index 0000000000..2dd22c2645 --- /dev/null +++ b/src/main/java/com/alibaba/druid/mapping/spi/ExportParameterVisitor.java @@ -0,0 +1,8 @@ +package com.alibaba.druid.mapping.spi; + +import com.alibaba.druid.sql.visitor.SQLASTVisitor; + + +public interface ExportParameterVisitor extends SQLASTVisitor { + +} diff --git a/src/main/java/com/alibaba/druid/mapping/spi/ExportParameterVisitorUtils.java b/src/main/java/com/alibaba/druid/mapping/spi/ExportParameterVisitorUtils.java new file mode 100644 index 0000000000..18031fa2cc --- /dev/null +++ b/src/main/java/com/alibaba/druid/mapping/spi/ExportParameterVisitorUtils.java @@ -0,0 +1,87 @@ +package com.alibaba.druid.mapping.spi; + +import java.util.List; + +import com.alibaba.druid.sql.ast.SQLExpr; +import com.alibaba.druid.sql.ast.expr.SQLBetweenExpr; +import com.alibaba.druid.sql.ast.expr.SQLBinaryOpExpr; +import com.alibaba.druid.sql.ast.expr.SQLCharExpr; +import com.alibaba.druid.sql.ast.expr.SQLLiteralExpr; +import com.alibaba.druid.sql.ast.expr.SQLNumericLiteralExpr; +import com.alibaba.druid.sql.ast.expr.SQLVariantRefExpr; +import com.alibaba.druid.sql.dialect.mysql.ast.expr.MySqlBooleanExpr; + +public class ExportParameterVisitorUtils { + + public static boolean exportParamterAndAccept(final List parameters, List list) { + for (int i = 0, size = list.size(); i < size; ++i) { + SQLExpr param = list.get(i); + + SQLExpr result = exportParameter(parameters, param); + if (result != param) { + list.set(i, result); + } + } + + return false; + } + + public static SQLExpr exportParameter(final List parameters, final SQLExpr param) { + if (param instanceof SQLCharExpr) { + Object value = ((SQLCharExpr) param).getText(); + parameters.add(value); + return new SQLVariantRefExpr("?"); + } + + if (param instanceof MySqlBooleanExpr) { + Object value = ((MySqlBooleanExpr) param).getValue(); + parameters.add(value); + return new SQLVariantRefExpr("?"); + } + + if (param instanceof SQLNumericLiteralExpr) { + Object value = ((SQLNumericLiteralExpr) param).getNumber(); + parameters.add(value); + return new SQLVariantRefExpr("?"); + } + + return param; + } + + public static void exportParameter(final List parameters, SQLBinaryOpExpr x) { + if (x.getLeft() instanceof SQLLiteralExpr && x.getRight() instanceof SQLLiteralExpr) { + return; + } + + { + SQLExpr leftResult = ExportParameterVisitorUtils.exportParameter(parameters, x.getLeft()); + if (leftResult != x.getLeft()) { + x.setLeft(leftResult); + } + } + + { + SQLExpr rightResult = exportParameter(parameters, x.getRight()); + if (rightResult != x.getRight()) { + x.setRight(rightResult); + } + } + } + + public static void exportParameter(final List parameters, SQLBetweenExpr x) { + { + SQLExpr result = exportParameter(parameters, x.getBeginExpr()); + if (result != x.getBeginExpr()) { + x.setBeginExpr(result); + } + } + + { + SQLExpr result = exportParameter(parameters, x.getEndExpr()); + if (result != x.getBeginExpr()) { + x.setEndExpr(result); + } + } + + } +} diff --git a/src/main/java/com/alibaba/druid/mapping/spi/MSSQLServerExportParameterVisitor.java b/src/main/java/com/alibaba/druid/mapping/spi/MSSQLServerExportParameterVisitor.java new file mode 100644 index 0000000000..4772e64b35 --- /dev/null +++ b/src/main/java/com/alibaba/druid/mapping/spi/MSSQLServerExportParameterVisitor.java @@ -0,0 +1,66 @@ +package com.alibaba.druid.mapping.spi; + +import java.util.List; + +import com.alibaba.druid.sql.ast.SQLOrderBy; +import com.alibaba.druid.sql.ast.expr.SQLBetweenExpr; +import com.alibaba.druid.sql.ast.expr.SQLBinaryOpExpr; +import com.alibaba.druid.sql.ast.expr.SQLInListExpr; +import com.alibaba.druid.sql.ast.expr.SQLMethodInvokeExpr; +import com.alibaba.druid.sql.ast.statement.SQLSelectGroupByClause; +import com.alibaba.druid.sql.ast.statement.SQLSelectItem; +import com.alibaba.druid.sql.dialect.sqlserver.visitor.SQLServerASTVisitorAdapter; + +public class MSSQLServerExportParameterVisitor extends SQLServerASTVisitorAdapter implements ExportParameterVisitor { + + private final List parameters; + + public MSSQLServerExportParameterVisitor(List parameters){ + this.parameters = parameters; + } + + public List getParameters() { + return parameters; + } + + @Override + public boolean visit(SQLSelectItem x) { + return false; + } + + @Override + public boolean visit(SQLOrderBy x) { + return false; + } + + @Override + public boolean visit(SQLSelectGroupByClause x) { + return false; + } + + @Override + public boolean visit(SQLMethodInvokeExpr x) { + ExportParameterVisitorUtils.exportParamterAndAccept(this.parameters, x.getParameters()); + + return true; + } + + @Override + public boolean visit(SQLInListExpr x) { + ExportParameterVisitorUtils.exportParamterAndAccept(this.parameters, x.getTargetList()); + + return true; + } + + @Override + public boolean visit(SQLBetweenExpr x) { + ExportParameterVisitorUtils.exportParameter(this.parameters, x); + return true; + } + + public boolean visit(SQLBinaryOpExpr x) { + ExportParameterVisitorUtils.exportParameter(this.parameters, x); + return true; + } + +} diff --git a/src/main/java/com/alibaba/druid/mapping/spi/MSSQLServerMappingProvider.java b/src/main/java/com/alibaba/druid/mapping/spi/MSSQLServerMappingProvider.java index 48bddcdffe..0ace040dc6 100644 --- a/src/main/java/com/alibaba/druid/mapping/spi/MSSQLServerMappingProvider.java +++ b/src/main/java/com/alibaba/druid/mapping/spi/MSSQLServerMappingProvider.java @@ -1,5 +1,7 @@ package com.alibaba.druid.mapping.spi; +import java.util.List; + import com.alibaba.druid.mapping.MappingEngine; import com.alibaba.druid.sql.ast.expr.SQLNumberExpr; import com.alibaba.druid.sql.ast.expr.SQLNumericLiteralExpr; @@ -65,4 +67,9 @@ public class MSSQLServerMappingProvider implements MappingProvider { PGSQLStatementParser parser = new PGSQLStatementParser(sql); return (SQLInsertStatement) parser.parseInsert(); } + + @Override + public ExportParameterVisitor createExportParameterVisitor(List parameters) { + return new MSSQLServerExportParameterVisitor(parameters); + } } diff --git a/src/main/java/com/alibaba/druid/mapping/spi/MappingProvider.java b/src/main/java/com/alibaba/druid/mapping/spi/MappingProvider.java index ebdf6fe154..4b4e52cec2 100644 --- a/src/main/java/com/alibaba/druid/mapping/spi/MappingProvider.java +++ b/src/main/java/com/alibaba/druid/mapping/spi/MappingProvider.java @@ -1,5 +1,7 @@ package com.alibaba.druid.mapping.spi; +import java.util.List; + import com.alibaba.druid.mapping.MappingEngine; import com.alibaba.druid.sql.ast.statement.SQLDeleteStatement; import com.alibaba.druid.sql.ast.statement.SQLInsertStatement; @@ -10,6 +12,8 @@ import com.alibaba.druid.sql.visitor.SQLASTOutputVisitor; public interface MappingProvider { MappingVisitor createMappingVisitor(MappingEngine engine); + + ExportParameterVisitor createExportParameterVisitor(List parameters); SQLASTOutputVisitor createOutputVisitor(MappingEngine engine, Appendable out); diff --git a/src/main/java/com/alibaba/druid/mapping/spi/MappingVisitorUtils.java b/src/main/java/com/alibaba/druid/mapping/spi/MappingVisitorUtils.java index b5d8829e7f..9e91c559c0 100644 --- a/src/main/java/com/alibaba/druid/mapping/spi/MappingVisitorUtils.java +++ b/src/main/java/com/alibaba/druid/mapping/spi/MappingVisitorUtils.java @@ -121,4 +121,5 @@ public class MappingVisitorUtils { return entity; } + } diff --git a/src/main/java/com/alibaba/druid/mapping/spi/MySqlExportParameterVisitor.java b/src/main/java/com/alibaba/druid/mapping/spi/MySqlExportParameterVisitor.java new file mode 100644 index 0000000000..e699a5f5b0 --- /dev/null +++ b/src/main/java/com/alibaba/druid/mapping/spi/MySqlExportParameterVisitor.java @@ -0,0 +1,72 @@ +package com.alibaba.druid.mapping.spi; + +import java.util.List; + +import com.alibaba.druid.sql.ast.SQLOrderBy; +import com.alibaba.druid.sql.ast.expr.SQLBetweenExpr; +import com.alibaba.druid.sql.ast.expr.SQLBinaryOpExpr; +import com.alibaba.druid.sql.ast.expr.SQLInListExpr; +import com.alibaba.druid.sql.ast.expr.SQLMethodInvokeExpr; +import com.alibaba.druid.sql.ast.statement.SQLSelectGroupByClause; +import com.alibaba.druid.sql.ast.statement.SQLSelectItem; +import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlSelectQueryBlock.Limit; +import com.alibaba.druid.sql.dialect.mysql.visitor.MySqlASTVisitorAdapter; + +public class MySqlExportParameterVisitor extends MySqlASTVisitorAdapter implements ExportParameterVisitor { + + private final List parameters; + + public MySqlExportParameterVisitor(List parameters){ + this.parameters = parameters; + } + + public List getParameters() { + return parameters; + } + + @Override + public boolean visit(SQLSelectItem x) { + return false; + } + + @Override + public boolean visit(Limit x) { + return false; + } + + @Override + public boolean visit(SQLOrderBy x) { + return false; + } + + @Override + public boolean visit(SQLSelectGroupByClause x) { + return false; + } + + @Override + public boolean visit(SQLMethodInvokeExpr x) { + ExportParameterVisitorUtils.exportParamterAndAccept(this.parameters, x.getParameters()); + + return true; + } + + @Override + public boolean visit(SQLInListExpr x) { + ExportParameterVisitorUtils.exportParamterAndAccept(this.parameters, x.getTargetList()); + + return true; + } + + @Override + public boolean visit(SQLBetweenExpr x) { + ExportParameterVisitorUtils.exportParameter(this.parameters, x); + return true; + } + + public boolean visit(SQLBinaryOpExpr x) { + ExportParameterVisitorUtils.exportParameter(this.parameters, x); + return true; + } + +} diff --git a/src/main/java/com/alibaba/druid/mapping/spi/MySqlMappingProvider.java b/src/main/java/com/alibaba/druid/mapping/spi/MySqlMappingProvider.java index eb7a28f252..fdc5d36e2f 100644 --- a/src/main/java/com/alibaba/druid/mapping/spi/MySqlMappingProvider.java +++ b/src/main/java/com/alibaba/druid/mapping/spi/MySqlMappingProvider.java @@ -1,5 +1,7 @@ package com.alibaba.druid.mapping.spi; +import java.util.List; + import com.alibaba.druid.mapping.MappingEngine; import com.alibaba.druid.sql.ast.expr.SQLIntegerExpr; import com.alibaba.druid.sql.ast.expr.SQLNumericLiteralExpr; @@ -63,4 +65,9 @@ public class MySqlMappingProvider implements MappingProvider { MySqlStatementParser parser = new MySqlStatementParser(sql); return (SQLInsertStatement) parser.parseInsert(); } + + @Override + public ExportParameterVisitor createExportParameterVisitor(List parameters) { + return new MySqlExportParameterVisitor(parameters); + } } diff --git a/src/main/java/com/alibaba/druid/mapping/spi/OracleExportParameterVisitor.java b/src/main/java/com/alibaba/druid/mapping/spi/OracleExportParameterVisitor.java new file mode 100644 index 0000000000..76fad0caa4 --- /dev/null +++ b/src/main/java/com/alibaba/druid/mapping/spi/OracleExportParameterVisitor.java @@ -0,0 +1,66 @@ +package com.alibaba.druid.mapping.spi; + +import java.util.List; + +import com.alibaba.druid.sql.ast.SQLOrderBy; +import com.alibaba.druid.sql.ast.expr.SQLBetweenExpr; +import com.alibaba.druid.sql.ast.expr.SQLBinaryOpExpr; +import com.alibaba.druid.sql.ast.expr.SQLInListExpr; +import com.alibaba.druid.sql.ast.expr.SQLMethodInvokeExpr; +import com.alibaba.druid.sql.ast.statement.SQLSelectGroupByClause; +import com.alibaba.druid.sql.ast.statement.SQLSelectItem; +import com.alibaba.druid.sql.dialect.oracle.visitor.OracleASTVIsitorAdapter; + +public class OracleExportParameterVisitor extends OracleASTVIsitorAdapter implements ExportParameterVisitor { + + private final List parameters; + + public OracleExportParameterVisitor(List parameters){ + this.parameters = parameters; + } + + public List getParameters() { + return parameters; + } + + @Override + public boolean visit(SQLSelectItem x) { + return false; + } + + @Override + public boolean visit(SQLOrderBy x) { + return false; + } + + @Override + public boolean visit(SQLSelectGroupByClause x) { + return false; + } + + @Override + public boolean visit(SQLMethodInvokeExpr x) { + ExportParameterVisitorUtils.exportParamterAndAccept(this.parameters, x.getParameters()); + + return true; + } + + @Override + public boolean visit(SQLInListExpr x) { + ExportParameterVisitorUtils.exportParamterAndAccept(this.parameters, x.getTargetList()); + + return true; + } + + @Override + public boolean visit(SQLBetweenExpr x) { + ExportParameterVisitorUtils.exportParameter(this.parameters, x); + return true; + } + + public boolean visit(SQLBinaryOpExpr x) { + ExportParameterVisitorUtils.exportParameter(this.parameters, x); + return true; + } + +} diff --git a/src/main/java/com/alibaba/druid/mapping/spi/OracleMappingProvider.java b/src/main/java/com/alibaba/druid/mapping/spi/OracleMappingProvider.java index d159e93079..8717f7ac6b 100644 --- a/src/main/java/com/alibaba/druid/mapping/spi/OracleMappingProvider.java +++ b/src/main/java/com/alibaba/druid/mapping/spi/OracleMappingProvider.java @@ -1,5 +1,7 @@ package com.alibaba.druid.mapping.spi; +import java.util.List; + import com.alibaba.druid.mapping.MappingEngine; import com.alibaba.druid.sql.ast.statement.SQLInsertStatement; import com.alibaba.druid.sql.ast.statement.SQLSelectQueryBlock; @@ -45,4 +47,9 @@ public class OracleMappingProvider implements MappingProvider { OracleStatementParser parser = new OracleStatementParser(sql); return (SQLInsertStatement) parser.parseInsert(); } + + @Override + public ExportParameterVisitor createExportParameterVisitor(List parameters) { + return new OracleExportParameterVisitor(parameters); + } } diff --git a/src/main/java/com/alibaba/druid/sql/ast/expr/SQLLiteralExpr.java b/src/main/java/com/alibaba/druid/sql/ast/expr/SQLLiteralExpr.java index 996a741bbd..124c2232eb 100644 --- a/src/main/java/com/alibaba/druid/sql/ast/expr/SQLLiteralExpr.java +++ b/src/main/java/com/alibaba/druid/sql/ast/expr/SQLLiteralExpr.java @@ -24,4 +24,5 @@ public abstract class SQLLiteralExpr extends SQLExprImpl { public SQLLiteralExpr(){ } + }