Merge pull request #861 from wenshao/master

new feature : sql builder
This commit is contained in:
高铁
2015-06-07 22:31:45 +08:00
32 changed files with 921 additions and 125 deletions
+3 -3
View File
@@ -407,7 +407,7 @@
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis-spring</artifactId>
<version>1.1.1</version>
<version>1.2.2</version>
<scope>provided</scope>
<optional>true</optional>
</dependency>
@@ -446,7 +446,7 @@
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.24</version>
<version>5.1.35</version>
<scope>provided</scope>
</dependency>
<dependency>
@@ -568,7 +568,7 @@
<dependency>
<groupId>org.nutz</groupId>
<artifactId>nutz</artifactId>
<version>1.b.47</version>
<version>1.b.52</version>
<scope>test</scope>
</dependency>
@@ -26,9 +26,11 @@ import com.alibaba.druid.sql.ast.expr.SQLBinaryOpExpr;
import com.alibaba.druid.sql.ast.expr.SQLBinaryOperator;
import com.alibaba.druid.sql.ast.statement.SQLDeleteStatement;
import com.alibaba.druid.sql.ast.statement.SQLSelectItem;
import com.alibaba.druid.sql.ast.statement.SQLSelectOrderByItem;
import com.alibaba.druid.sql.ast.statement.SQLSelectQuery;
import com.alibaba.druid.sql.ast.statement.SQLSelectQueryBlock;
import com.alibaba.druid.sql.ast.statement.SQLSelectStatement;
import com.alibaba.druid.sql.ast.statement.SQLUpdateSetItem;
import com.alibaba.druid.sql.ast.statement.SQLUpdateStatement;
import com.alibaba.druid.sql.dialect.db2.visitor.DB2OutputVisitor;
import com.alibaba.druid.sql.dialect.db2.visitor.DB2SchemaStatVisitor;
@@ -175,6 +177,39 @@ public class SQLUtils {
return expr;
}
public static SQLSelectOrderByItem toOrderByItem(String sql, String dbType) {
SQLExprParser parser = SQLParserUtils.createExprParser(sql, dbType);
SQLSelectOrderByItem orderByItem = parser.parseSelectOrderByItem();
if (parser.getLexer().token() != Token.EOF) {
throw new ParserException("illegal sql expr : " + sql);
}
return orderByItem;
}
public static SQLUpdateSetItem toUpdateSetItem(String sql, String dbType) {
SQLExprParser parser = SQLParserUtils.createExprParser(sql, dbType);
SQLUpdateSetItem updateSetItem = parser.parseUpdateSetItem();
if (parser.getLexer().token() != Token.EOF) {
throw new ParserException("illegal sql expr : " + sql);
}
return updateSetItem;
}
public static SQLSelectItem toSelectItem(String sql, String dbType) {
SQLExprParser parser = SQLParserUtils.createExprParser(sql, dbType);
SQLSelectItem selectItem = parser.parseSelectItem();
if (parser.getLexer().token() != Token.EOF) {
throw new ParserException("illegal sql expr : " + sql);
}
return selectItem;
}
public static List<SQLStatement> toStatementList(String sql, String dbType) {
SQLStatementParser parser = SQLParserUtils.createSQLStatementParser(sql, dbType);
@@ -406,7 +441,7 @@ public class SQLUtils {
SQLSelectQuery query = ((SQLSelectStatement) stmt).getSelect().getQuery();
if (query instanceof SQLSelectQueryBlock) {
SQLSelectQueryBlock queryBlock = (SQLSelectQueryBlock) query;
SQLExpr newCondition = buildNewCondition(op, condition, left, queryBlock.getWhere());
SQLExpr newCondition = buildCondition(op, condition, left, queryBlock.getWhere());
queryBlock.setWhere(newCondition);
} else {
throw new IllegalArgumentException("add condition not support " + stmt.getClass().getName());
@@ -418,7 +453,7 @@ public class SQLUtils {
if (stmt instanceof SQLDeleteStatement) {
SQLDeleteStatement delete = (SQLDeleteStatement) stmt;
SQLExpr newCondition = buildNewCondition(op, condition, left, delete.getWhere());
SQLExpr newCondition = buildCondition(op, condition, left, delete.getWhere());
delete.setWhere(newCondition);
return;
@@ -427,7 +462,7 @@ public class SQLUtils {
if (stmt instanceof SQLUpdateStatement) {
SQLUpdateStatement update = (SQLUpdateStatement) stmt;
SQLExpr newCondition = buildNewCondition(op, condition, left, update.getWhere());
SQLExpr newCondition = buildCondition(op, condition, left, update.getWhere());
update.setWhere(newCondition);
return;
@@ -436,7 +471,7 @@ public class SQLUtils {
throw new IllegalArgumentException("add condition not support " + stmt.getClass().getName());
}
protected static SQLExpr buildNewCondition(SQLBinaryOperator op, SQLExpr condition, boolean left, SQLExpr where) {
public static SQLExpr buildCondition(SQLBinaryOperator op, SQLExpr condition, boolean left, SQLExpr where) {
if (where == null) {
return condition;
}
@@ -31,8 +31,7 @@ public class SQLOrderBy extends SQLObjectImpl {
public SQLOrderBy(SQLExpr expr){
SQLSelectOrderByItem item = new SQLSelectOrderByItem(expr);
item.setParent(this);
this.items.add(item);
addItem(item);
}
public void addItem(SQLSelectOrderByItem item) {
@@ -71,5 +70,14 @@ public class SQLOrderBy extends SQLObjectImpl {
return items.equals(other.items);
}
public void addItem(SQLExpr expr, SQLOrderingSpecification type) {
SQLSelectOrderByItem item = createItem();
item.setExpr(expr);
item.setType(type);
addItem(item);
}
protected SQLSelectOrderByItem createItem() {
return new SQLSelectOrderByItem();
}
}
@@ -27,7 +27,12 @@ public class SQLExprTableSource extends SQLTableSourceImpl {
}
public SQLExprTableSource(SQLExpr expr){
this(expr, null);
}
public SQLExprTableSource(SQLExpr expr, String alias){
this.setExpr(expr);
this.setAlias(alias);
}
public SQLExpr getExpr() {
@@ -82,6 +82,11 @@ public class SQLSelectQueryBlock extends SQLObjectImpl implements SQLSelectQuery
public List<SQLSelectItem> getSelectList() {
return this.selectList;
}
public void addSelectItem(SQLSelectItem item) {
this.selectList.add(item);
item.setParent(this);
}
public SQLTableSource getFrom() {
return this.from;
@@ -75,6 +75,11 @@ public class SQLUpdateStatement extends SQLStatementImpl {
public List<SQLUpdateSetItem> getItems() {
return items;
}
public void addItem(SQLUpdateSetItem item) {
this.items.add(item);
item.setParent(this);
}
@Override
public void output(StringBuffer buf) {
@@ -0,0 +1,6 @@
package com.alibaba.druid.sql.builder;
public interface SQLBuilder {
}
@@ -0,0 +1,39 @@
package com.alibaba.druid.sql.builder;
import com.alibaba.druid.sql.builder.impl.SQLDeleteBuilderImpl;
import com.alibaba.druid.sql.builder.impl.SQLSelectBuilderImpl;
import com.alibaba.druid.sql.builder.impl.SQLUpdateBuilderImpl;
import com.alibaba.druid.sql.builder.impl.dialect.MySqlSelectBuilderImpl;
import com.alibaba.druid.sql.builder.impl.dialect.PGSelectBuilderImpl;
import com.alibaba.druid.util.JdbcConstants;
public class SQLBuilderFactory {
public static SQLSelectBuilder createSelectSQLBuilder(String dbType) {
if (JdbcConstants.MYSQL.equals(dbType)) {
return new MySqlSelectBuilderImpl();
}
if (JdbcConstants.POSTGRESQL.equals(dbType)) {
return new PGSelectBuilderImpl();
}
if (JdbcConstants.SQL_SERVER.equals(dbType)) {
return new PGSelectBuilderImpl();
}
if (JdbcConstants.ORACLE.equals(dbType)) {
return new PGSelectBuilderImpl();
}
return new SQLSelectBuilderImpl(dbType);
}
public static SQLDeleteBuilder createDeleteBuilder(String dbType) {
return new SQLDeleteBuilderImpl(dbType);
}
public static SQLUpdateBuilder createUpdateBuilder(String dbType) {
return new SQLUpdateBuilderImpl(dbType);
}
}
@@ -0,0 +1,18 @@
package com.alibaba.druid.sql.builder;
public interface SQLDeleteBuilder {
SQLDeleteBuilder from(String table);
SQLDeleteBuilder from(String table, String alias);
SQLDeleteBuilder limit(int rowCount);
SQLDeleteBuilder limit(int rowCount, int offset);
SQLDeleteBuilder where(String sql);
SQLDeleteBuilder whereAnd(String sql);
SQLDeleteBuilder whereOr(String sql);
}
@@ -0,0 +1,36 @@
package com.alibaba.druid.sql.builder;
import com.alibaba.druid.sql.ast.statement.SQLSelectStatement;
public interface SQLSelectBuilder {
SQLSelectStatement getSQLSelectStatement();
SQLSelectBuilder select(String... column);
SQLSelectBuilder selectWithAlias(String column, String alias);
SQLSelectBuilder from(String table);
SQLSelectBuilder from(String table, String alias);
SQLSelectBuilder orderBy(String... columns);
SQLSelectBuilder groupBy(String expr);
SQLSelectBuilder having(String expr);
SQLSelectBuilder into(String expr);
SQLSelectBuilder limit(int rowCount);
SQLSelectBuilder limit(int rowCount, int offset);
SQLSelectBuilder where(String sql);
SQLSelectBuilder whereAnd(String sql);
SQLSelectBuilder whereOr(String sql);
String toString();
}
@@ -0,0 +1,20 @@
package com.alibaba.druid.sql.builder;
public interface SQLUpdateBuilder {
SQLUpdateBuilder from(String table);
SQLUpdateBuilder from(String table, String alias);
SQLUpdateBuilder limit(int rowCount);
SQLUpdateBuilder limit(int rowCount, int offset);
SQLUpdateBuilder where(String sql);
SQLUpdateBuilder whereAnd(String sql);
SQLUpdateBuilder whereOr(String sql);
SQLUpdateBuilder set(String... items);
}
@@ -0,0 +1,18 @@
package com.alibaba.druid.sql.builder;
public interface UpdateBuilder {
UpdateBuilder from(String table);
UpdateBuilder from(String table, String alias);
UpdateBuilder limit(int rowCount);
UpdateBuilder limit(int rowCount, int offset);
UpdateBuilder where(String sql);
UpdateBuilder whereAnd(String sql);
UpdateBuilder whereOr(String sql);
}
@@ -0,0 +1,8 @@
package com.alibaba.druid.sql.builder.impl;
import com.alibaba.druid.sql.builder.SQLBuilder;
public class SQLBuilderImpl implements SQLBuilder {
}
@@ -0,0 +1,94 @@
package com.alibaba.druid.sql.builder.impl;
import com.alibaba.druid.sql.SQLUtils;
import com.alibaba.druid.sql.ast.SQLExpr;
import com.alibaba.druid.sql.ast.expr.SQLBinaryOperator;
import com.alibaba.druid.sql.ast.expr.SQLIdentifierExpr;
import com.alibaba.druid.sql.ast.statement.SQLDeleteStatement;
import com.alibaba.druid.sql.ast.statement.SQLExprTableSource;
import com.alibaba.druid.sql.builder.SQLDeleteBuilder;
public class SQLDeleteBuilderImpl implements SQLDeleteBuilder {
private SQLDeleteStatement stmt;
private String dbType;
public SQLDeleteBuilderImpl(String dbType){
this.dbType = dbType;
}
public SQLDeleteBuilderImpl(SQLDeleteStatement stmt, String dbType){
this.stmt = stmt;
this.dbType = dbType;
}
@Override
public SQLDeleteBuilderImpl limit(int rowCount) {
throw new UnsupportedOperationException();
}
@Override
public SQLDeleteBuilderImpl limit(int rowCount, int offset) {
throw new UnsupportedOperationException();
}
@Override
public SQLDeleteBuilder from(String table) {
return from(table, null);
}
@Override
public SQLDeleteBuilder from(String table, String alias) {
SQLDeleteStatement delete = getSQLDeleteStatement();
SQLExprTableSource from = new SQLExprTableSource(new SQLIdentifierExpr(table), alias);
delete.setTableSource(from);
return this;
}
@Override
public SQLDeleteBuilder where(String expr) {
SQLDeleteStatement delete = getSQLDeleteStatement();
SQLExpr exprObj = SQLUtils.toSQLExpr(expr, dbType);
delete.setWhere(exprObj);
return this;
}
@Override
public SQLDeleteBuilder whereAnd(String expr) {
SQLDeleteStatement delete = getSQLDeleteStatement();
SQLExpr exprObj = SQLUtils.toSQLExpr(expr, dbType);
SQLExpr newCondition = SQLUtils.buildCondition(SQLBinaryOperator.BooleanAnd, exprObj, false, delete.getWhere());
delete.setWhere(newCondition);
return this;
}
@Override
public SQLDeleteBuilder whereOr(String expr) {
SQLDeleteStatement delete = getSQLDeleteStatement();
SQLExpr exprObj = SQLUtils.toSQLExpr(expr, dbType);
SQLExpr newCondition = SQLUtils.buildCondition(SQLBinaryOperator.BooleanOr, exprObj, false, delete.getWhere());
delete.setWhere(newCondition);
return this;
}
public SQLDeleteStatement getSQLDeleteStatement() {
if (stmt == null) {
stmt = createSQLDeleteStatement();
}
return stmt;
}
public SQLDeleteStatement createSQLDeleteStatement() {
return new SQLDeleteStatement();
}
public String toString() {
return SQLUtils.toSQLString(stmt, dbType);
}
}
@@ -0,0 +1,217 @@
package com.alibaba.druid.sql.builder.impl;
import com.alibaba.druid.sql.SQLUtils;
import com.alibaba.druid.sql.ast.SQLExpr;
import com.alibaba.druid.sql.ast.SQLOrderBy;
import com.alibaba.druid.sql.ast.expr.SQLBinaryOperator;
import com.alibaba.druid.sql.ast.expr.SQLIdentifierExpr;
import com.alibaba.druid.sql.ast.statement.SQLExprTableSource;
import com.alibaba.druid.sql.ast.statement.SQLSelect;
import com.alibaba.druid.sql.ast.statement.SQLSelectGroupByClause;
import com.alibaba.druid.sql.ast.statement.SQLSelectItem;
import com.alibaba.druid.sql.ast.statement.SQLSelectOrderByItem;
import com.alibaba.druid.sql.ast.statement.SQLSelectQuery;
import com.alibaba.druid.sql.ast.statement.SQLSelectQueryBlock;
import com.alibaba.druid.sql.ast.statement.SQLSelectStatement;
import com.alibaba.druid.sql.builder.SQLSelectBuilder;
public class SQLSelectBuilderImpl implements SQLSelectBuilder {
private SQLSelectStatement stmt;
private String dbType;
public SQLSelectBuilderImpl(String dbType){
this(new SQLSelectStatement(), dbType);
}
public SQLSelectBuilderImpl(SQLSelectStatement stmt, String dbType){
this.stmt = stmt;
this.dbType = dbType;
}
public SQLSelect getSQLSelect() {
if (stmt.getSelect() == null) {
stmt.setSelect(createSelect());
}
return stmt.getSelect();
}
@Override
public SQLSelectStatement getSQLSelectStatement() {
return stmt;
}
public SQLSelectBuilderImpl select(String... columns) {
SQLSelectQueryBlock queryBlock = getQueryBlock();
for (String column : columns) {
SQLSelectItem selectItem = SQLUtils.toSelectItem(column, dbType);
queryBlock.addSelectItem(selectItem);
}
return this;
}
@Override
public SQLSelectBuilderImpl selectWithAlias(String column, String alias) {
SQLSelectQueryBlock queryBlock = getQueryBlock();
SQLExpr columnExpr = SQLUtils.toSQLExpr(column, dbType);
SQLSelectItem selectItem = new SQLSelectItem(columnExpr, alias);
queryBlock.addSelectItem(selectItem);
return this;
}
@Override
public SQLSelectBuilderImpl from(String table) {
return from(table, null);
}
@Override
public SQLSelectBuilderImpl from(String table, String alias) {
SQLSelectQueryBlock queryBlock = getQueryBlock();
SQLExprTableSource from = new SQLExprTableSource(new SQLIdentifierExpr(table), alias);
queryBlock.setFrom(from);
return this;
}
@Override
public SQLSelectBuilderImpl orderBy(String... columns) {
SQLSelect select = this.getSQLSelect();
SQLOrderBy orderBy = select.getOrderBy();
if (orderBy == null) {
orderBy = createOrderBy();
select.setOrderBy(orderBy);
}
for (String column : columns) {
SQLSelectOrderByItem orderByItem = SQLUtils.toOrderByItem(column, dbType);
orderBy.addItem(orderByItem);
}
return this;
}
@Override
public SQLSelectBuilderImpl groupBy(String expr) {
SQLSelectQueryBlock queryBlock = getQueryBlock();
SQLSelectGroupByClause groupBy = queryBlock.getGroupBy();
if (groupBy == null) {
groupBy = createGroupBy();
queryBlock.setGroupBy(groupBy);
}
SQLExpr exprObj = SQLUtils.toSQLExpr(expr, dbType);
groupBy.addItem(exprObj);
return this;
}
@Override
public SQLSelectBuilderImpl having(String expr) {
SQLSelectQueryBlock queryBlock = getQueryBlock();
SQLSelectGroupByClause groupBy = queryBlock.getGroupBy();
if (groupBy == null) {
groupBy = createGroupBy();
queryBlock.setGroupBy(groupBy);
}
SQLExpr exprObj = SQLUtils.toSQLExpr(expr, dbType);
groupBy.setHaving(exprObj);
return this;
}
@Override
public SQLSelectBuilderImpl into(String expr) {
SQLSelectQueryBlock queryBlock = getQueryBlock();
SQLExpr exprObj = SQLUtils.toSQLExpr(expr, dbType);
queryBlock.setInto(exprObj);
return this;
}
@Override
public SQLSelectBuilderImpl where(String expr) {
SQLSelectQueryBlock queryBlock = getQueryBlock();
SQLExpr exprObj = SQLUtils.toSQLExpr(expr, dbType);
queryBlock.setWhere(exprObj);
return this;
}
@Override
public SQLSelectBuilderImpl whereAnd(String expr) {
SQLSelectQueryBlock queryBlock = getQueryBlock();
SQLExpr exprObj = SQLUtils.toSQLExpr(expr, dbType);
SQLExpr newCondition = SQLUtils.buildCondition(SQLBinaryOperator.BooleanAnd, exprObj, false, queryBlock.getWhere());
queryBlock.setWhere(newCondition);
return this;
}
@Override
public SQLSelectBuilderImpl whereOr(String expr) {
SQLSelectQueryBlock queryBlock = getQueryBlock();
SQLExpr exprObj = SQLUtils.toSQLExpr(expr, dbType);
SQLExpr newCondition = SQLUtils.buildCondition(SQLBinaryOperator.BooleanOr, exprObj, false, queryBlock.getWhere());
queryBlock.setWhere(newCondition);
return this;
}
@Override
public SQLSelectBuilderImpl limit(int rowCount) {
throw new UnsupportedOperationException();
}
@Override
public SQLSelectBuilderImpl limit(int rowCount, int offset) {
throw new UnsupportedOperationException();
}
protected SQLSelectQueryBlock getQueryBlock() {
SQLSelect select = getSQLSelect();
SQLSelectQuery query = select.getQuery();
if (query == null) {
query = createSelectQueryBlock();
select.setQuery(query);
}
if (!(query instanceof SQLSelectQueryBlock)) {
throw new IllegalStateException("not support from, class : " + query.getClass().getName());
}
SQLSelectQueryBlock queryBlock = (SQLSelectQueryBlock) query;
return queryBlock;
}
protected SQLSelect createSelect() {
return new SQLSelect();
}
protected SQLSelectQuery createSelectQueryBlock() {
return new SQLSelectQueryBlock();
}
protected SQLOrderBy createOrderBy() {
return new SQLOrderBy();
}
protected SQLSelectGroupByClause createGroupBy() {
return new SQLSelectGroupByClause();
}
public String toString() {
return SQLUtils.toSQLString(stmt, dbType);
}
}
@@ -0,0 +1,105 @@
package com.alibaba.druid.sql.builder.impl;
import com.alibaba.druid.sql.SQLUtils;
import com.alibaba.druid.sql.ast.SQLExpr;
import com.alibaba.druid.sql.ast.expr.SQLBinaryOperator;
import com.alibaba.druid.sql.ast.expr.SQLIdentifierExpr;
import com.alibaba.druid.sql.ast.statement.SQLExprTableSource;
import com.alibaba.druid.sql.ast.statement.SQLUpdateSetItem;
import com.alibaba.druid.sql.ast.statement.SQLUpdateStatement;
import com.alibaba.druid.sql.builder.SQLUpdateBuilder;
public class SQLUpdateBuilderImpl implements SQLUpdateBuilder {
private SQLUpdateStatement stmt;
private String dbType;
public SQLUpdateBuilderImpl(String dbType){
this.dbType = dbType;
}
public SQLUpdateBuilderImpl(SQLUpdateStatement stmt, String dbType){
this.stmt = stmt;
this.dbType = dbType;
}
@Override
public SQLUpdateBuilderImpl limit(int rowCount) {
throw new UnsupportedOperationException();
}
@Override
public SQLUpdateBuilderImpl limit(int rowCount, int offset) {
throw new UnsupportedOperationException();
}
@Override
public SQLUpdateBuilderImpl from(String table) {
return from(table, null);
}
@Override
public SQLUpdateBuilderImpl from(String table, String alias) {
SQLUpdateStatement update = getSQLUpdateStatement();
SQLExprTableSource from = new SQLExprTableSource(new SQLIdentifierExpr(table), alias);
update.setTableSource(from);
return this;
}
@Override
public SQLUpdateBuilderImpl where(String expr) {
SQLUpdateStatement update = getSQLUpdateStatement();
SQLExpr exprObj = SQLUtils.toSQLExpr(expr, dbType);
update.setWhere(exprObj);
return this;
}
@Override
public SQLUpdateBuilderImpl whereAnd(String expr) {
SQLUpdateStatement update = getSQLUpdateStatement();
SQLExpr exprObj = SQLUtils.toSQLExpr(expr, dbType);
SQLExpr newCondition = SQLUtils.buildCondition(SQLBinaryOperator.BooleanAnd, exprObj, false, update.getWhere());
update.setWhere(newCondition);
return this;
}
@Override
public SQLUpdateBuilderImpl whereOr(String expr) {
SQLUpdateStatement update = getSQLUpdateStatement();
SQLExpr exprObj = SQLUtils.toSQLExpr(expr, dbType);
SQLExpr newCondition = SQLUtils.buildCondition(SQLBinaryOperator.BooleanOr, exprObj, false, update.getWhere());
update.setWhere(newCondition);
return this;
}
public SQLUpdateBuilderImpl set(String... items) {
SQLUpdateStatement update = getSQLUpdateStatement();
for (String item : items) {
SQLUpdateSetItem updateSetItem = SQLUtils.toUpdateSetItem(item, dbType);
update.addItem(updateSetItem);
}
return this;
}
public SQLUpdateStatement getSQLUpdateStatement() {
if (stmt == null) {
stmt = createSQLUpdateStatement();
}
return stmt;
}
public SQLUpdateStatement createSQLUpdateStatement() {
return new SQLUpdateStatement();
}
public String toString() {
return SQLUtils.toSQLString(stmt, dbType);
}
}
@@ -0,0 +1,23 @@
package com.alibaba.druid.sql.builder.impl.dialect;
import com.alibaba.druid.sql.ast.statement.SQLSelectGroupByClause;
import com.alibaba.druid.sql.ast.statement.SQLSelectQuery;
import com.alibaba.druid.sql.builder.impl.SQLSelectBuilderImpl;
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlSelectGroupBy;
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlSelectQueryBlock;
import com.alibaba.druid.util.JdbcConstants;
public class MySqlSelectBuilderImpl extends SQLSelectBuilderImpl {
public MySqlSelectBuilderImpl(){
super(JdbcConstants.MYSQL);
}
protected SQLSelectQuery createSelectQueryBlock() {
return new MySqlSelectQueryBlock();
}
protected SQLSelectGroupByClause createGroupBy() {
return new MySqlSelectGroupBy();
}
}
@@ -0,0 +1,26 @@
package com.alibaba.druid.sql.builder.impl.dialect;
import com.alibaba.druid.sql.builder.impl.SQLSelectBuilderImpl;
import com.alibaba.druid.sql.dialect.oracle.ast.OracleOrderBy;
import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleSelect;
import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleSelectQueryBlock;
import com.alibaba.druid.util.JdbcConstants;
public class OracleSelectBuilderImpl extends SQLSelectBuilderImpl {
public OracleSelectBuilderImpl(){
super(JdbcConstants.ORACLE);
}
protected OracleSelectQueryBlock createSelectQueryBlock() {
return new OracleSelectQueryBlock();
}
protected OracleSelect createSelect() {
return new OracleSelect();
}
protected OracleOrderBy createOrderBy() {
return new OracleOrderBy();
}
}
@@ -0,0 +1,22 @@
package com.alibaba.druid.sql.builder.impl.dialect;
import com.alibaba.druid.sql.builder.impl.SQLSelectBuilderImpl;
import com.alibaba.druid.sql.dialect.postgresql.ast.PGOrderBy;
import com.alibaba.druid.sql.dialect.postgresql.ast.stmt.PGSelectQueryBlock;
import com.alibaba.druid.sql.dialect.postgresql.ast.stmt.PGSelectStatement;
import com.alibaba.druid.util.JdbcConstants;
public class PGSelectBuilderImpl extends SQLSelectBuilderImpl {
public PGSelectBuilderImpl(){
super(new PGSelectStatement(), JdbcConstants.POSTGRESQL);
}
protected PGSelectQueryBlock createSelectQueryBlock() {
return new PGSelectQueryBlock();
}
protected PGOrderBy createOrderBy() {
return new PGOrderBy();
}
}
@@ -0,0 +1,21 @@
package com.alibaba.druid.sql.builder.impl.dialect;
import com.alibaba.druid.sql.builder.impl.SQLSelectBuilderImpl;
import com.alibaba.druid.sql.dialect.sqlserver.ast.SQLServerSelect;
import com.alibaba.druid.sql.dialect.sqlserver.ast.SQLServerSelectQueryBlock;
import com.alibaba.druid.util.JdbcConstants;
public class SQLServerSelectBuilderImpl extends SQLSelectBuilderImpl {
public SQLServerSelectBuilderImpl(){
super(JdbcConstants.SQL_SERVER);
}
protected SQLServerSelectQueryBlock createSelectQueryBlock() {
return new SQLServerSelectQueryBlock();
}
protected SQLServerSelect createSelect() {
return new SQLServerSelect();
}
}
@@ -25,7 +25,6 @@ import com.alibaba.druid.sql.ast.SQLOrderBy;
import com.alibaba.druid.sql.ast.SQLStatement;
import com.alibaba.druid.sql.ast.expr.SQLCharExpr;
import com.alibaba.druid.sql.ast.expr.SQLIntegerExpr;
import com.alibaba.druid.sql.ast.expr.SQLListExpr;
import com.alibaba.druid.sql.ast.expr.SQLLiteralExpr;
import com.alibaba.druid.sql.ast.expr.SQLNCharExpr;
import com.alibaba.druid.sql.ast.expr.SQLQueryExpr;
@@ -2666,24 +2665,8 @@ public class MySqlStatementParser extends SQLStatementParser {
accept(Token.SET);
for (;;) {
SQLUpdateSetItem item = new SQLUpdateSetItem();
if (lexer.token() == (Token.LPAREN)) {
lexer.nextToken();
SQLListExpr list = new SQLListExpr();
this.exprParser.exprList(list.getItems(), list);
accept(Token.RPAREN);
item.setColumn(list);
} else {
item.setColumn(this.exprParser.primary());
}
if (lexer.token() == Token.COLONEQ) {
lexer.nextToken();
} else {
accept(Token.EQ);
}
item.setValue(this.exprParser.expr());
update.getItems().add(item);
SQLUpdateSetItem item = this.exprParser.parseUpdateSetItem();
update.addItem(item);
if (lexer.token() != Token.COMMA) {
break;
@@ -17,8 +17,12 @@ package com.alibaba.druid.sql.dialect.odps.parser;
import com.alibaba.druid.sql.ast.SQLExpr;
import com.alibaba.druid.sql.ast.expr.SQLCharExpr;
import com.alibaba.druid.sql.ast.expr.SQLIdentifierExpr;
import com.alibaba.druid.sql.ast.statement.SQLSelectItem;
import com.alibaba.druid.sql.dialect.odps.ast.OdpsUDTFSQLSelectItem;
import com.alibaba.druid.sql.parser.Lexer;
import com.alibaba.druid.sql.parser.SQLExprParser;
import com.alibaba.druid.sql.parser.Token;
public class OdpsExprParser extends SQLExprParser {
@@ -47,4 +51,53 @@ public class OdpsExprParser extends SQLExprParser {
protected SQLExpr parseAliasExpr(String alias) {
return new SQLCharExpr(alias);
}
@Override
public SQLSelectItem parseSelectItem() {
SQLExpr expr;
if (lexer.token() == Token.IDENTIFIER) {
expr = new SQLIdentifierExpr(lexer.stringVal());
lexer.nextTokenComma();
if (lexer.token() != Token.COMMA) {
expr = this.primaryRest(expr);
expr = this.exprRest(expr);
}
} else {
expr = expr();
}
if (lexer.token() == Token.AS) {
lexer.nextToken();
if (lexer.token() == Token.LPAREN) {
lexer.nextToken();
OdpsUDTFSQLSelectItem selectItem = new OdpsUDTFSQLSelectItem();
selectItem.setExpr(expr);
for (;;) {
String alias = lexer.stringVal();
lexer.nextToken();
selectItem.getAliasList().add(alias);
if (lexer.token() == Token.COMMA) {
lexer.nextToken();
continue;
}
break;
}
accept(Token.RPAREN);
return selectItem;
}
}
final String alias = as();
return new SQLSelectItem(expr, alias);
}
}
@@ -15,13 +15,9 @@
*/
package com.alibaba.druid.sql.dialect.odps.parser;
import com.alibaba.druid.sql.ast.SQLExpr;
import com.alibaba.druid.sql.ast.SQLSetQuantifier;
import com.alibaba.druid.sql.ast.expr.SQLIdentifierExpr;
import com.alibaba.druid.sql.ast.statement.SQLSelectItem;
import com.alibaba.druid.sql.ast.statement.SQLSelectQuery;
import com.alibaba.druid.sql.dialect.odps.ast.OdpsSelectQueryBlock;
import com.alibaba.druid.sql.dialect.odps.ast.OdpsUDTFSQLSelectItem;
import com.alibaba.druid.sql.parser.SQLExprParser;
import com.alibaba.druid.sql.parser.SQLSelectParser;
import com.alibaba.druid.sql.parser.Token;
@@ -81,52 +77,4 @@ public class OdpsSelectParser extends SQLSelectParser {
return queryRest(queryBlock);
}
@Override
protected SQLSelectItem parseSelectItem() {
SQLExpr expr;
if (lexer.token() == Token.IDENTIFIER) {
expr = new SQLIdentifierExpr(lexer.stringVal());
lexer.nextTokenComma();
if (lexer.token() != Token.COMMA) {
expr = this.exprParser.primaryRest(expr);
expr = this.exprParser.exprRest(expr);
}
} else {
expr = expr();
}
if (lexer.token() == Token.AS) {
lexer.nextToken();
if (lexer.token() == Token.LPAREN) {
lexer.nextToken();
OdpsUDTFSQLSelectItem selectItem = new OdpsUDTFSQLSelectItem();
selectItem.setExpr(expr);
for (;;) {
String alias = lexer.stringVal();
lexer.nextToken();
selectItem.getAliasList().add(alias);
if (lexer.token() == Token.COMMA) {
lexer.nextToken();
continue;
}
break;
}
accept(Token.RPAREN);
return selectItem;
}
}
final String alias = as();
return new SQLSelectItem(expr, alias);
}
}
@@ -16,6 +16,7 @@
package com.alibaba.druid.sql.dialect.oracle.ast;
import com.alibaba.druid.sql.ast.SQLOrderBy;
import com.alibaba.druid.sql.ast.statement.SQLSelectOrderByItem;
import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleOrderByItem;
import com.alibaba.druid.sql.dialect.oracle.visitor.OracleASTVisitor;
import com.alibaba.druid.sql.visitor.SQLASTVisitor;
@@ -67,4 +68,8 @@ public class OracleOrderBy extends SQLOrderBy {
((OracleOrderByItem) this.items.get(i)).output(buf);
}
}
protected SQLSelectOrderByItem createItem() {
return new OracleOrderByItem();
}
}
@@ -1137,12 +1137,10 @@ public class OracleStatementParser extends SQLStatementParser {
accept(Token.SET);
for (;;) {
SQLUpdateSetItem item = new SQLUpdateSetItem();
item.setColumn(this.exprParser.name());
accept(Token.EQ);
item.setValue(this.exprParser.expr());
SQLUpdateSetItem item = this.exprParser.parseUpdateSetItem();
updateClause.getItems().add(item);
item.setParent(updateClause);
if (lexer.token() == (Token.COMMA)) {
lexer.nextToken();
@@ -174,7 +174,7 @@ public class SQLServerExprParser extends SQLExprParser {
return null;
}
protected SQLSelectItem parseSelectItem() {
public SQLSelectItem parseSelectItem() {
SQLExpr expr;
if (lexer.token() == Token.IDENTIFIER) {
expr = new SQLIdentifierExpr(lexer.stringVal());
@@ -76,8 +76,10 @@ import com.alibaba.druid.sql.ast.statement.SQLForeignKeyImpl;
import com.alibaba.druid.sql.ast.statement.SQLPrimaryKey;
import com.alibaba.druid.sql.ast.statement.SQLPrimaryKeyImpl;
import com.alibaba.druid.sql.ast.statement.SQLSelect;
import com.alibaba.druid.sql.ast.statement.SQLSelectItem;
import com.alibaba.druid.sql.ast.statement.SQLSelectOrderByItem;
import com.alibaba.druid.sql.ast.statement.SQLUnique;
import com.alibaba.druid.sql.ast.statement.SQLUpdateSetItem;
public class SQLExprParser extends SQLParser {
@@ -1001,6 +1003,28 @@ public class SQLExprParser extends SQLParser {
return item;
}
public SQLUpdateSetItem parseUpdateSetItem() {
SQLUpdateSetItem item = new SQLUpdateSetItem();
if (lexer.token() == (Token.LPAREN)) {
lexer.nextToken();
SQLListExpr list = new SQLListExpr();
this.exprList(list.getItems(), list);
accept(Token.RPAREN);
item.setColumn(list);
} else {
item.setColumn(this.primary());
}
if (lexer.token() == Token.COLONEQ) {
lexer.nextToken();
} else {
accept(Token.EQ);
}
item.setValue(this.expr());
return item;
}
public final SQLExpr bitAnd() {
SQLExpr expr = shift();
@@ -1743,4 +1767,27 @@ public class SQLExprParser extends SQLParser {
protected SQLForeignKeyConstraint createForeignKey() {
return new SQLForeignKeyImpl();
}
public SQLSelectItem parseSelectItem() {
SQLExpr expr;
boolean connectByRoot = false;
if (lexer.token() == Token.IDENTIFIER) {
if (identifierEquals("CONNECT_BY_ROOT")) {
connectByRoot = true;
lexer.nextToken();
}
expr = new SQLIdentifierExpr(lexer.stringVal());
lexer.nextTokenComma();
if (lexer.token() != Token.COMMA) {
expr = this.primaryRest(expr);
expr = this.exprRest(expr);
}
} else {
expr = expr();
}
final String alias = as();
return new SQLSelectItem(expr, alias, connectByRoot);
}
}
@@ -64,7 +64,7 @@ public class SQLSelectParser extends SQLParser {
select.setOrderBy(parseOrderBy());
}
while(lexer.token() == Token.HINT) {
while (lexer.token() == Token.HINT) {
this.exprParser.parseHints(select.getHints());
}
@@ -269,11 +269,12 @@ public class SQLSelectParser extends SQLParser {
}
}
protected final void parseSelectList(SQLSelectQueryBlock queryBlock) {
protected void parseSelectList(SQLSelectQueryBlock queryBlock) {
final List<SQLSelectItem> selectList = queryBlock.getSelectList();
for (;;) {
final SQLSelectItem selectItem = parseSelectItem();
final SQLSelectItem selectItem = this.exprParser.parseSelectItem();
selectList.add(selectItem);
selectItem.setParent(queryBlock);
if (lexer.token() != Token.COMMA) {
break;
@@ -283,29 +284,6 @@ public class SQLSelectParser extends SQLParser {
}
}
protected SQLSelectItem parseSelectItem() {
SQLExpr expr;
boolean connectByRoot = false;
if (lexer.token() == Token.IDENTIFIER) {
if (identifierEquals("CONNECT_BY_ROOT")) {
connectByRoot = true;
lexer.nextToken();
}
expr = new SQLIdentifierExpr(lexer.stringVal());
lexer.nextTokenComma();
if (lexer.token() != Token.COMMA) {
expr = this.exprParser.primaryRest(expr);
expr = this.exprParser.exprRest(expr);
}
} else {
expr = expr();
}
final String alias = as();
return new SQLSelectItem(expr, alias, connectByRoot);
}
public void parseFrom(SQLSelectQueryBlock queryBlock) {
if (lexer.token() != Token.FROM) {
return;
@@ -1539,20 +1539,8 @@ public class SQLStatementParser extends SQLParser {
accept(Token.SET);
for (;;) {
SQLUpdateSetItem item = new SQLUpdateSetItem();
if (lexer.token() == (Token.LPAREN)) {
lexer.nextToken();
SQLListExpr list = new SQLListExpr();
this.exprParser.exprList(list.getItems(), list);
accept(Token.RPAREN);
item.setColumn(list);
} else {
item.setColumn(this.exprParser.primary());
}
accept(Token.EQ);
item.setValue(this.exprParser.expr());
update.getItems().add(item);
SQLUpdateSetItem item = this.exprParser.parseUpdateSetItem();
update.addItem(item);
if (lexer.token() != Token.COMMA) {
break;
@@ -0,0 +1,26 @@
package com.alibaba.druid.bvt.sql.builder;
import junit.framework.TestCase;
import org.junit.Assert;
import com.alibaba.druid.sql.builder.SQLBuilderFactory;
import com.alibaba.druid.sql.builder.SQLDeleteBuilder;
import com.alibaba.druid.util.JdbcConstants;
public class BuilderDeleteTest extends TestCase {
public void test_0() throws Exception {
SQLDeleteBuilder builder = SQLBuilderFactory.createDeleteBuilder(JdbcConstants.MYSQL);
builder //
.from("mytable") //
.whereAnd("f1 > 0") //
;
String sql = builder.toString();
System.out.println(sql);
Assert.assertEquals("DELETE FROM mytable" //
+ "\nWHERE f1 > 0", sql);
}
}
@@ -0,0 +1,32 @@
package com.alibaba.druid.bvt.sql.builder;
import junit.framework.TestCase;
import org.junit.Assert;
import com.alibaba.druid.sql.builder.SQLBuilderFactory;
import com.alibaba.druid.sql.builder.SQLSelectBuilder;
import com.alibaba.druid.util.JdbcConstants;
public class BuilderSelectTest extends TestCase {
public void test_0() throws Exception {
SQLSelectBuilder builder = SQLBuilderFactory.createSelectSQLBuilder(JdbcConstants.MYSQL);
builder.from("mytable");
builder.select("f1", "f2", "f3 F3", "count(*) cnt");
builder.groupBy("f1");
builder.having("count(*) > 1");
builder.orderBy("f1", "f2 desc");
builder.whereAnd("f1 > 0");
String sql = builder.toString();
System.out.println(sql);
Assert.assertEquals("SELECT f1, f2, f3 AS F3, COUNT(*) AS cnt" //
+ "\nFROM mytable"//
+ "\nWHERE f1 > 0"//
+ "\nGROUP BY f1"//
+ "\nHAVING COUNT(*) > 1"//
+ "\nORDER BY f1, f2 DESC", sql);
}
}
@@ -0,0 +1,27 @@
package com.alibaba.druid.bvt.sql.builder;
import junit.framework.TestCase;
import org.junit.Assert;
import com.alibaba.druid.sql.builder.SQLBuilderFactory;
import com.alibaba.druid.sql.builder.SQLUpdateBuilder;
import com.alibaba.druid.util.JdbcConstants;
public class BuilderUpdateTest extends TestCase {
public void test_0() throws Exception {
SQLUpdateBuilder builder = SQLBuilderFactory.createUpdateBuilder(JdbcConstants.MYSQL);
builder //
.from("mytable") //
.whereAnd("f1 > 0") //
.set("f1 = f1 + 1", "f2 = ?");
String sql = builder.toString();
System.out.println(sql);
Assert.assertEquals("UPDATE mytable" //
+ "\nSET f1 = f1 + 1, f2 = ?" //
+ "\nWHERE f1 > 0", sql);
}
}