package jef.database.jsqlparser.visitor; import java.util.Iterator; import java.util.List; import jef.common.Pair; import jef.database.jsqlparser.Util; import jef.database.jsqlparser.expression.AllComparisonExpression; import jef.database.jsqlparser.expression.AnyComparisonExpression; import jef.database.jsqlparser.expression.BinaryExpression; import jef.database.jsqlparser.expression.CaseExpression; import jef.database.jsqlparser.expression.Column; import jef.database.jsqlparser.expression.DateValue; import jef.database.jsqlparser.expression.DoubleValue; import jef.database.jsqlparser.expression.Function; import jef.database.jsqlparser.expression.Interval; import jef.database.jsqlparser.expression.InverseExpression; import jef.database.jsqlparser.expression.JdbcParameter; import jef.database.jsqlparser.expression.JpqlParameter; import jef.database.jsqlparser.expression.LongValue; import jef.database.jsqlparser.expression.NullValue; import jef.database.jsqlparser.expression.Over; import jef.database.jsqlparser.expression.Parenthesis; import jef.database.jsqlparser.expression.StringValue; import jef.database.jsqlparser.expression.Table; import jef.database.jsqlparser.expression.TimeValue; import jef.database.jsqlparser.expression.TimestampValue; import jef.database.jsqlparser.expression.WhenClause; import jef.database.jsqlparser.expression.operators.arithmetic.Addition; import jef.database.jsqlparser.expression.operators.arithmetic.BitwiseAnd; import jef.database.jsqlparser.expression.operators.arithmetic.BitwiseOr; import jef.database.jsqlparser.expression.operators.arithmetic.BitwiseXor; import jef.database.jsqlparser.expression.operators.arithmetic.Concat; import jef.database.jsqlparser.expression.operators.arithmetic.Division; import jef.database.jsqlparser.expression.operators.arithmetic.Mod; import jef.database.jsqlparser.expression.operators.arithmetic.Multiplication; import jef.database.jsqlparser.expression.operators.arithmetic.Subtraction; import jef.database.jsqlparser.expression.operators.conditional.AndExpression; import jef.database.jsqlparser.expression.operators.conditional.OrExpression; import jef.database.jsqlparser.expression.operators.relational.Between; import jef.database.jsqlparser.expression.operators.relational.EqualsTo; import jef.database.jsqlparser.expression.operators.relational.ExistsExpression; import jef.database.jsqlparser.expression.operators.relational.ExpressionList; import jef.database.jsqlparser.expression.operators.relational.GreaterThan; import jef.database.jsqlparser.expression.operators.relational.GreaterThanEquals; import jef.database.jsqlparser.expression.operators.relational.InExpression; import jef.database.jsqlparser.expression.operators.relational.IsNullExpression; import jef.database.jsqlparser.expression.operators.relational.LikeExpression; import jef.database.jsqlparser.expression.operators.relational.MinorThan; import jef.database.jsqlparser.expression.operators.relational.MinorThanEquals; import jef.database.jsqlparser.expression.operators.relational.NotEqualsTo; import jef.database.jsqlparser.statement.create.ColumnDefinition; import jef.database.jsqlparser.statement.create.CreateTable; import jef.database.jsqlparser.statement.create.Index; import jef.database.jsqlparser.statement.delete.Delete; import jef.database.jsqlparser.statement.drop.Drop; import jef.database.jsqlparser.statement.insert.Insert; import jef.database.jsqlparser.statement.replace.Replace; import jef.database.jsqlparser.statement.select.AllColumns; import jef.database.jsqlparser.statement.select.AllTableColumns; import jef.database.jsqlparser.statement.select.Join; import jef.database.jsqlparser.statement.select.Limit; import jef.database.jsqlparser.statement.select.OrderBy; import jef.database.jsqlparser.statement.select.OrderByElement; import jef.database.jsqlparser.statement.select.PlainSelect; import jef.database.jsqlparser.statement.select.Select; import jef.database.jsqlparser.statement.select.SelectExpressionItem; import jef.database.jsqlparser.statement.select.StartWithExpression; import jef.database.jsqlparser.statement.select.SubJoin; import jef.database.jsqlparser.statement.select.SubSelect; import jef.database.jsqlparser.statement.select.Top; import jef.database.jsqlparser.statement.select.Union; import jef.database.jsqlparser.statement.select.WithItem; import jef.database.jsqlparser.statement.truncate.Truncate; import jef.database.jsqlparser.statement.update.Update; import jef.tools.StringUtils; /** * 将AST重新组装成SQL的访问者,可通过修改访问者的行为来变化SQL的组装行为。 * @author jiyi * */ public class DeParserAdapter implements SelectVisitor, ExpressionVisitor, StatementVisitor, SelectItemVisitor { protected StringBuilder sb; public DeParserAdapter(StringBuilder buffer) { this.sb = buffer; } public DeParserAdapter() { this.sb = new StringBuilder(); } public StringBuilder getBuffer() { return sb; } public void visit(Addition addition) { visitBinaryExpression(addition, " + "); } public void visit(AndExpression andExpression) { visitBinaryExpression(andExpression, " AND "); } public void visit(Between between) { between.getLeftExpression().accept(this); if (between.isNot()) sb.append(" NOT"); sb.append(" BETWEEN "); between.getBetweenExpressionStart().accept(this); sb.append(" AND "); between.getBetweenExpressionEnd().accept(this); } public void visit(Mod mod) { visitBinaryExpression(mod, " % "); } public void visit(Division division) { visitBinaryExpression(division, " / "); } public void visit(EqualsTo equalsTo) { visitBinaryExpression(equalsTo, " = "); } public void visit(GreaterThan greaterThan) { visitBinaryExpression(greaterThan, " > "); } public void visit(GreaterThanEquals greaterThanEquals) { visitBinaryExpression(greaterThanEquals, " >= "); } public void visit(InExpression inExpression) { inExpression.getLeftExpression().accept(this); if (inExpression.isNot()) sb.append(" NOT"); sb.append(" IN "); inExpression.getItemsList().accept(this); } public void visit(InverseExpression inverseExpression) { sb.append("-"); inverseExpression.getExpression().accept(this); } public void visit(IsNullExpression isNullExpression) { isNullExpression.getLeftExpression().accept(this); if (isNullExpression.isNot()) { sb.append(" IS NOT NULL"); } else { sb.append(" IS NULL"); } } public void visit(JdbcParameter jdbcParameter) { sb.append("?"); } public void visit(JpqlParameter jdbcParameter) { Object obj = jdbcParameter.getResolved(); if (obj instanceof String) { sb.append(obj); return; } Integer value = (Integer) obj; if (value == null || value < 0) {// 未解析 if (jdbcParameter.isNamedParam()) { sb.append(':').append(jdbcParameter.getName()); } else { sb.append('?').append(jdbcParameter.getIndex()); } } else if (value == 0) { sb.append('?'); } else {// value>0 sb.append('?'); StringUtils.repeat(sb, ",?", value - 1); } if (jdbcParameter.getAlias() != null) { sb.append(' ').append(jdbcParameter.getAlias()); } } public void visit(DoubleValue doubleValue) { sb.append(doubleValue.getValue()); } public void visit(LikeExpression likeExpression) { visitBinaryExpression(likeExpression, " LIKE "); } public void visit(ExistsExpression existsExpression) { if (existsExpression.isNot()) { sb.append(" NOT EXISTS "); } else { sb.append(" EXISTS "); } existsExpression.getRightExpression().accept(this); } public void visit(LongValue longValue) { sb.append(longValue.getStringValue()); } public void visit(MinorThan minorThan) { visitBinaryExpression(minorThan, " < "); } public void visit(MinorThanEquals minorThanEquals) { visitBinaryExpression(minorThanEquals, " <= "); } public void visit(Multiplication multiplication) { visitBinaryExpression(multiplication, " * "); } public void visit(NotEqualsTo notEqualsTo) { visitBinaryExpression(notEqualsTo, " <> "); } public void visit(NullValue nullValue) { sb.append("NULL"); } public void visit(OrExpression orExpression) { visitBinaryExpression(orExpression, " OR "); } public void visit(Parenthesis parenthesis) { if (parenthesis.isNot()) sb.append(" NOT "); sb.append("("); parenthesis.getExpression().accept(this); sb.append(")"); } public void visit(StringValue stringValue) { sb.append("'" + stringValue.getValue() + "'"); } public void visit(Subtraction subtraction) { visitBinaryExpression(subtraction, "-"); } private void visitBinaryExpression(BinaryExpression binaryExpression, String operator) { if (binaryExpression.isNot()) sb.append(" NOT "); binaryExpression.getLeftExpression().accept(this); sb.append(operator); binaryExpression.getRightExpression().accept(this); } public void visit(SubSelect subSelect) { sb.append("("); subSelect.getSelectBody().accept(this); sb.append(")"); } public void visit(Function function) { if (function.isEscaped()) { sb.append("{fn "); } sb.append(function.getName()); if (function.isAllColumns()) { sb.append("(*)"); } else if (function.getParameters() == null) { sb.append("()"); } else { if (function.isDistinct()) { sb.append("(DISTINCT "); } else { sb.append('('); } String between = function.getParameters().getBetween(); Iterator<Expression> iter = function.getParameters().getExpressions().iterator(); if (iter.hasNext()) { iter.next().accept(this); while (iter.hasNext()) { sb.append(between); iter.next().accept(this); } } sb.append(')'); } if (function.isEscaped()) { sb.append("}"); } } public void visit(ExpressionList expressionList) { sb.append("("); for (Iterator<Expression> iter = expressionList.getExpressions().iterator(); iter.hasNext();) { Expression expression = (Expression) iter.next(); expression.accept(this); if (iter.hasNext()) sb.append(expressionList.getBetween()); } sb.append(")"); } public void visit(DateValue dateValue) { sb.append("{d '" + dateValue.getValue().toString() + "'}"); } public void visit(TimestampValue timestampValue) { sb.append("{ts '" + timestampValue.getValue().toString() + "'}"); } public void visit(TimeValue timeValue) { sb.append("{t '" + timeValue.getValue().toString() + "'}"); } public void visit(CaseExpression caseExpression) { sb.append("CASE "); Expression switchExp = caseExpression.getSwitchExpression(); if (switchExp != null) { switchExp.accept(this); } List<WhenClause> clauses = caseExpression.getWhenClauses(); for (Iterator<WhenClause> iter = clauses.iterator(); iter.hasNext();) { Expression exp = (Expression) iter.next(); exp.accept(this); } Expression elseExp = caseExpression.getElseExpression(); if (elseExp != null) { elseExp.accept(this); } sb.append(" END"); } public void visit(WhenClause whenClause) { sb.append(" WHEN "); whenClause.getWhenExpression().accept(this); sb.append(" THEN "); whenClause.getThenExpression().accept(this); } public void visit(AllComparisonExpression allComparisonExpression) { sb.append(" ALL "); allComparisonExpression.GetSubSelect().accept((ExpressionVisitor) this); } public void visit(AnyComparisonExpression anyComparisonExpression) { sb.append(" ANY "); anyComparisonExpression.GetSubSelect().accept((ExpressionVisitor) this); } public void visit(Concat concat) { visitBinaryExpression(concat, " || "); } public void visit(BitwiseAnd bitwiseAnd) { visitBinaryExpression(bitwiseAnd, " & "); } public void visit(BitwiseOr bitwiseOr) { visitBinaryExpression(bitwiseOr, " | "); } public void visit(BitwiseXor bitwiseXor) { visitBinaryExpression(bitwiseXor, " ^ "); } public void visit(Interval interval) { interval.getValue().accept(this); } public void visit(StartWithExpression startWithExpression) { Expression start = startWithExpression.getStartExpression(); Expression connectBy = startWithExpression.getConnectExpression(); if (start != null) start.accept(this); if (connectBy != null) connectBy.accept(this); } public void visit(Over over) { sb.append(" over("); if (over.getPartition() != null && !over.getPartition().isEmpty()) { sb.append("partition by"); for (Expression exp : over.getPartition()) { exp.accept(this); } } if (over.getOrderBy() != null) { over.getOrderBy().accept(this); } sb.append(')'); } public void visit(PlainSelect plainSelect) { sb.append("select "); writeSelectItems(plainSelect); writeFromAndWhere(plainSelect); writeGroupByAndHaving(plainSelect); writeOrderAndLimit(plainSelect); } protected void writeFromAndWhere(PlainSelect plainSelect) { sb.append(" "); if (plainSelect.getFromItem() != null) { sb.append("from "); plainSelect.getFromItem().accept(this); } if (plainSelect.getJoins() != null) { for (Iterator<Join> iter = plainSelect.getJoins().iterator(); iter.hasNext();) { Join join = iter.next(); join.accept(this); } } if (plainSelect.getWhere() != null) { sb.append(" where "); plainSelect.getWhere().accept(this); } } protected void writeOrderAndLimit(PlainSelect plainSelect) { if (plainSelect.getOrderBy() != null) { plainSelect.getOrderBy().accept(this); } if (plainSelect.getLimit() != null) { plainSelect.getLimit().accept(this); } } protected void writeGroupByAndHaving(PlainSelect plainSelect) { if (plainSelect.getGroupByColumnReferences() != null) { sb.append(" group by "); for (Iterator<Expression> iter = plainSelect.getGroupByColumnReferences().iterator(); iter.hasNext();) { Expression columnReference = iter.next(); columnReference.accept(this); if (iter.hasNext()) { sb.append(","); } } } if (plainSelect.getHaving() != null) { sb.append(" having "); plainSelect.getHaving().accept(this); } } protected void writeSelectItems(PlainSelect plainSelect) { Top top = plainSelect.getTop(); if (top != null) top.toString(); if (plainSelect.getDistinct() != null) { sb.append("DISTINCT "); if (plainSelect.getDistinct().getOnSelectItems() != null) { sb.append("ON ("); for (Iterator<SelectItem> iter = plainSelect.getDistinct().getOnSelectItems().iterator(); iter.hasNext();) { SelectItem selectItem = iter.next(); selectItem.accept(this); if (iter.hasNext()) { sb.append(", "); } } sb.append(") "); } } for (Iterator<SelectItem> iter = plainSelect.getSelectItems().iterator(); iter.hasNext();) { SelectItem selectItem = iter.next(); selectItem.accept(this); if (iter.hasNext()) { sb.append(","); } } } public void visit(Union union) { for (Iterator<PlainSelect> iter = union.getPlainSelects().iterator(); iter.hasNext();) { sb.append("("); PlainSelect plainSelect = iter.next(); plainSelect.accept(this); sb.append(")"); if (iter.hasNext()) { sb.append(" UNION "); } } if (union.getOrderBy() != null) { union.getOrderBy().accept(this); } if (union.getLimit() != null) { union.getLimit().accept(this); } } public void visit(OrderByElement orderBy) { orderBy.getExpression().accept(this); if (orderBy.isAsc()) sb.append(" ASC"); else sb.append(" DESC"); } public void visit(Column column) { sb.append(column.getWholeColumnName()); } public void visit(AllColumns allColumns) { sb.append("*"); } public void visit(AllTableColumns allTableColumns) { sb.append(allTableColumns.getTable().toWholeName() + ".*"); } public void visit(SelectExpressionItem selectExpressionItem) { selectExpressionItem.getExpression().accept(this); if (selectExpressionItem.getAlias() != null) { sb.append(" AS " + selectExpressionItem.getAlias()); } } public void visit(Table tableName) { sb.append(tableName.toWholeName()); String alias = tableName.getAlias(); if (alias != null && alias.length() > 0) { sb.append(" " + alias); } } public void visit(SubJoin subjoin) { sb.append('('); subjoin.getLeft().accept(this); sb.append(' '); subjoin.getJoin().accept(this); sb.append(')'); } public void visit(OrderBy orderBy) { sb.append(" order by "); for (int i = 0; i < orderBy.getOrderByElements().size(); i++) { if (i > 0) sb.append(','); OrderByElement ele = orderBy.getOrderByElements().get(i); ele.accept(this); } } public void visit(Join join) { if (join.isSimple()) sb.append(", "); else { if (join.isRight()) sb.append("RIGHT "); else if (join.isNatural()) sb.append("NATURAL "); else if (join.isFull()) sb.append("FULL "); else if (join.isLeft()) sb.append("LEFT "); if (join.isOuter()) sb.append("OUTER "); else if (join.isInner()) sb.append("INNER "); sb.append("JOIN "); } FromItem fromItem = join.getRightItem(); fromItem.accept(this); if (join.getOnExpression() != null) { sb.append(" ON "); join.getOnExpression().accept(this); } if (join.getUsingColumns() != null) { sb.append(" USING ( "); for (Iterator<Column> iterator = join.getUsingColumns().iterator(); iterator.hasNext();) { Column column = (Column) iterator.next(); sb.append(column.getWholeColumnName()); if (iterator.hasNext()) { sb.append(" ,"); } } sb.append(")"); } } public void visit(CreateTable createTable) { sb.append("CREATE TABLE " + createTable.getTable().toWholeName()); if (createTable.getColumnDefinitions() != null) { sb.append(" { "); for (Iterator<ColumnDefinition> iter = createTable.getColumnDefinitions().iterator(); iter.hasNext();) { ColumnDefinition columnDefinition = (ColumnDefinition) iter.next(); sb.append(columnDefinition.getColumnName()); sb.append(" "); sb.append(columnDefinition.getColDataType().getDataType()); if (columnDefinition.getColDataType().getArgumentsStringList() != null) { for (Iterator<String> iterator = columnDefinition.getColDataType().getArgumentsStringList().iterator(); iterator.hasNext();) { sb.append(" "); sb.append((String) iterator.next()); } } if (columnDefinition.getColumnSpecStrings() != null) { for (Iterator<String> iterator = columnDefinition.getColumnSpecStrings().iterator(); iterator.hasNext();) { sb.append(" "); sb.append((String) iterator.next()); } } if (iter.hasNext()) sb.append(",\n"); } for (Iterator<Index> iter = createTable.getIndexes().iterator(); iter.hasNext();) { sb.append(",\n"); Index index = (Index) iter.next(); sb.append(index.getType() + " " + index.getName()); sb.append("("); for (Iterator<String> iterator = index.getColumnsNames().iterator(); iterator.hasNext();) { sb.append((String) iterator.next()); if (iterator.hasNext()) { sb.append(", "); } } sb.append(")"); if (iter.hasNext()) sb.append(",\n"); } sb.append(" \n} "); } } public void visit(Delete delete) { sb.append("DELETE FROM " + delete.getTable().toWholeName()); if (delete.getWhere() != null) { sb.append(" WHERE "); delete.getWhere().accept(this); } } public void visit(Drop drop) { } public void visit(Insert insert) { sb.append("INSERT INTO "); sb.append(insert.getTable().toWholeName()); if (insert.getColumns() != null) { sb.append("("); for (Iterator<Column> iter = insert.getColumns().iterator(); iter.hasNext();) { Column column = (Column) iter.next(); sb.append(column.getColumnName()); if (iter.hasNext()) { sb.append(", "); } } sb.append(")"); } if (insert.getItemsList() instanceof ExpressionList) { ExpressionList exps = (ExpressionList) insert.getItemsList(); sb.append(" VALUES ("); for (Iterator<Expression> iter = exps.getExpressions().iterator(); iter.hasNext();) { Expression expression = (Expression) iter.next(); expression.accept(this); if (iter.hasNext()) sb.append(", "); } sb.append(")"); } else { insert.getItemsList().accept(this); } } public void visit(Replace replace) { sb.append("REPLACE " + replace.getTable().toWholeName()); if (replace.getItemsList() != null) { if (replace.getColumns() != null) { sb.append(" ("); for (int i = 0; i < replace.getColumns().size(); i++) { Column column = (Column) replace.getColumns().get(i); sb.append(column.getWholeColumnName()); if (i < replace.getColumns().size() - 1) { sb.append(", "); } } sb.append(") "); } else { sb.append(" "); } } else { sb.append(" SET "); for (int i = 0; i < replace.getColumns().size(); i++) { Column column = (Column) replace.getColumns().get(i); sb.append(column.getWholeColumnName() + "="); Expression expression = (Expression) replace.getExpressions().get(i); expression.accept(this); if (i < replace.getColumns().size() - 1) { sb.append(", "); } } } if (replace.getItemsList() instanceof ExpressionList) { ExpressionList exps = (ExpressionList) replace.getItemsList(); sb.append(" VALUES ("); for (Iterator<Expression> iter = exps.getExpressions().iterator(); iter.hasNext();) { Expression expression = (Expression) iter.next(); expression.accept(this); if (iter.hasNext()) sb.append(", "); } sb.append(")"); } else { replace.getItemsList().accept(this); } } public void visit(Select select) { if (select.getWithItemsList() != null && !select.getWithItemsList().isEmpty()) { sb.append("WITH "); for (Iterator<WithItem> iter = select.getWithItemsList().iterator(); iter.hasNext();) { WithItem withItem = iter.next(); withItem.accept(this); if (iter.hasNext()) sb.append(","); sb.append(" "); } } select.getSelectBody().accept(this); } public void visit(Truncate truncate) { } public void visit(Update update) { sb.append("UPDATE " + update.getTable().toWholeName() + " SET "); int size = update.getSets().size(); for (int i = 0; i < size; i++) { Pair<Column, Expression> pair = update.getSets().get(i); Column column = pair.first; sb.append(column.getWholeColumnName() + "="); Expression expression = pair.second; expression.accept(this); if (i < size - 1) { sb.append(", "); } } if (update.getWhere() != null) { sb.append(" WHERE "); update.getWhere().accept(this); } } public void visit(WithItem with) { sb.append(with.getName()); if(with.getWithItemList() != null){ sb.append(' '); Util.getStringList(sb,with.getWithItemList(), ",", true); } sb.append(" AS ("); with.getSelectBody().accept(this); sb.append(')'); } @Override public String toString() { return sb.toString(); } @Override public void visit(Limit limit) { sb.append(" LIMIT "); if (limit.isRowCountJdbcParameter()) { sb.append("?"); } else if (limit.getRowCount() != 0) { sb.append(limit.getRowCount()); } else { sb.append("18446744073709551615"); } if (limit.getOffsetJdbcParameter() != null) { sb.append(" OFFSET ?"); } else if (limit.getOffset() != 0) { sb.append(" OFFSET " + limit.getOffset()); } } }