From 602128674bba3c7d97d03b10c4805e9a82ad85df Mon Sep 17 00:00:00 2001 From: wenshao Date: Sun, 7 Jun 2015 23:53:12 +0800 Subject: [PATCH] improved sql builder --- .../com/alibaba/druid/sql/PagerUtils.java | 51 +++-- .../alibaba/druid/sql/builder/SQLBuilder.java | 16 ++ .../druid/sql/builder/SQLBuilderFactory.java | 48 +++-- .../druid/sql/builder/SQLDeleteBuilder.java | 19 +- .../druid/sql/builder/SQLSelectBuilder.java | 15 ++ .../druid/sql/builder/SQLUpdateBuilder.java | 21 +- .../druid/sql/builder/UpdateBuilder.java | 15 ++ .../sql/builder/impl/SQLBuilderImpl.java | 15 ++ .../builder/impl/SQLDeleteBuilderImpl.java | 50 +++++ .../builder/impl/SQLSelectBuilderImpl.java | 190 ++++++++++++++++-- .../builder/impl/SQLUpdateBuilderImpl.java | 55 +++++ .../impl/dialect/MySqlSelectBuilderImpl.java | 23 --- .../impl/dialect/OracleSelectBuilderImpl.java | 26 --- .../impl/dialect/PGSelectBuilderImpl.java | 22 -- .../dialect/SQLServerSelectBuilderImpl.java | 21 -- .../ast/statement/MySqlSelectQueryBlock.java | 4 + 16 files changed, 434 insertions(+), 157 deletions(-) delete mode 100644 src/main/java/com/alibaba/druid/sql/builder/impl/dialect/MySqlSelectBuilderImpl.java delete mode 100644 src/main/java/com/alibaba/druid/sql/builder/impl/dialect/OracleSelectBuilderImpl.java delete mode 100644 src/main/java/com/alibaba/druid/sql/builder/impl/dialect/PGSelectBuilderImpl.java delete mode 100644 src/main/java/com/alibaba/druid/sql/builder/impl/dialect/SQLServerSelectBuilderImpl.java diff --git a/src/main/java/com/alibaba/druid/sql/PagerUtils.java b/src/main/java/com/alibaba/druid/sql/PagerUtils.java index 158d46e595..ee08bb5137 100644 --- a/src/main/java/com/alibaba/druid/sql/PagerUtils.java +++ b/src/main/java/com/alibaba/druid/sql/PagerUtils.java @@ -26,6 +26,7 @@ import com.alibaba.druid.sql.ast.expr.SQLAllColumnExpr; import com.alibaba.druid.sql.ast.expr.SQLBinaryOpExpr; import com.alibaba.druid.sql.ast.expr.SQLBinaryOperator; import com.alibaba.druid.sql.ast.expr.SQLIdentifierExpr; +import com.alibaba.druid.sql.ast.expr.SQLIntegerExpr; import com.alibaba.druid.sql.ast.expr.SQLNumberExpr; import com.alibaba.druid.sql.ast.expr.SQLPropertyExpr; import com.alibaba.druid.sql.ast.statement.SQLSelect; @@ -113,30 +114,27 @@ public class PagerUtils { return limitMySqlQueryBlock((MySqlSelectQueryBlock) queryBlock, dbType, offset, count); } - if (JdbcConstants.POSTGRESQL.equals(dbType)) - { - return limitPostgreSQLQueryBlock((PGSelectQueryBlock) queryBlock, dbType, offset, count); + if (JdbcConstants.POSTGRESQL.equals(dbType)) { + return limitPostgreSQLQueryBlock((PGSelectQueryBlock) queryBlock, dbType, offset, count); } throw new UnsupportedOperationException(); } - private static String limitPostgreSQLQueryBlock(PGSelectQueryBlock queryBlock, String dbType, - int offset, int count) { - if (queryBlock.getLimit() != null) - { - throw new IllegalArgumentException("limit already exists."); - } + private static String limitPostgreSQLQueryBlock(PGSelectQueryBlock queryBlock, String dbType, int offset, int count) { + if (queryBlock.getLimit() != null) { + throw new IllegalArgumentException("limit already exists."); + } - PGLimit limit = new PGLimit(); - if (offset > 0) - { - limit.setOffset(new SQLNumberExpr(offset)); - } - limit.setRowCount(new SQLNumberExpr(count)); - queryBlock.setLimit(limit); + PGLimit limit = new PGLimit(); + if (offset > 0) { + limit.setOffset(new SQLIntegerExpr(offset)); + } + limit.setRowCount(new SQLIntegerExpr(count)); + queryBlock.setLimit(limit); + + return SQLUtils.toSQLString(queryBlock, dbType); + } - return SQLUtils.toSQLString(queryBlock, dbType); - } private static String limitDB2(SQLSelect select, String dbType, int offset, int count) { SQLSelectQuery query = select.getQuery(); @@ -202,13 +200,13 @@ public class PagerUtils { SQLBinaryOpExpr gt = new SQLBinaryOpExpr(new SQLIdentifierExpr("ROWNUM"), // SQLBinaryOperator.GreaterThan, // new SQLNumberExpr(offset), // - JdbcConstants.SQL_SERVER - ); + JdbcConstants.SQL_SERVER); SQLBinaryOpExpr lteq = new SQLBinaryOpExpr(new SQLIdentifierExpr("ROWNUM"), // SQLBinaryOperator.LessThanOrEqual, // new SQLNumberExpr(count + offset), // JdbcConstants.SQL_SERVER); - SQLBinaryOpExpr pageCondition = new SQLBinaryOpExpr(gt, SQLBinaryOperator.BooleanAnd, lteq, JdbcConstants.SQL_SERVER); + SQLBinaryOpExpr pageCondition = new SQLBinaryOpExpr(gt, SQLBinaryOperator.BooleanAnd, lteq, + JdbcConstants.SQL_SERVER); if (query instanceof SQLSelectQueryBlock) { SQLServerSelectQueryBlock queryBlock = (SQLServerSelectQueryBlock) query; @@ -233,18 +231,17 @@ public class PagerUtils { return SQLUtils.toSQLString(countQueryBlock, dbType); } - SQLServerSelectQueryBlock countQueryBlock = new SQLServerSelectQueryBlock(); countQueryBlock.getSelectList().add(new SQLSelectItem(new SQLPropertyExpr(new SQLIdentifierExpr("XX"), "*"))); countQueryBlock.setFrom(new SQLSubqueryTableSource(select, "XX")); - + if (offset <= 0) { countQueryBlock.setTop(new SQLServerTop(new SQLNumberExpr(count))); return SQLUtils.toSQLString(countQueryBlock, dbType); } - + SQLAggregateExpr aggregateExpr = new SQLAggregateExpr("ROW_NUMBER"); SQLOrderBy orderBy = select.getOrderBy(); aggregateExpr.setOver(new SQLOver(orderBy)); @@ -268,16 +265,14 @@ public class PagerUtils { SQLExpr condition = new SQLBinaryOpExpr(new SQLIdentifierExpr("ROWNUM"), // SQLBinaryOperator.LessThanOrEqual, // new SQLNumberExpr(count), // - JdbcConstants.ORACLE - ); + JdbcConstants.ORACLE); if (queryBlock.getWhere() == null) { queryBlock.setWhere(condition); } else { queryBlock.setWhere(new SQLBinaryOpExpr(queryBlock.getWhere(), // SQLBinaryOperator.BooleanAnd, // condition, // - JdbcConstants.ORACLE - )); + JdbcConstants.ORACLE)); } return SQLUtils.toSQLString(select, dbType); diff --git a/src/main/java/com/alibaba/druid/sql/builder/SQLBuilder.java b/src/main/java/com/alibaba/druid/sql/builder/SQLBuilder.java index 0f7cd19215..84a3516b57 100644 --- a/src/main/java/com/alibaba/druid/sql/builder/SQLBuilder.java +++ b/src/main/java/com/alibaba/druid/sql/builder/SQLBuilder.java @@ -1,3 +1,19 @@ +/* + * Copyright 1999-2011 Alibaba Group Holding Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package com.alibaba.druid.sql.builder; diff --git a/src/main/java/com/alibaba/druid/sql/builder/SQLBuilderFactory.java b/src/main/java/com/alibaba/druid/sql/builder/SQLBuilderFactory.java index b49451d3e1..435552aa41 100644 --- a/src/main/java/com/alibaba/druid/sql/builder/SQLBuilderFactory.java +++ b/src/main/java/com/alibaba/druid/sql/builder/SQLBuilderFactory.java @@ -1,39 +1,47 @@ +/* + * Copyright 1999-2011 Alibaba Group Holding Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ 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 SQLSelectBuilder createSelectSQLBuilder(String sql, String dbType) { + return new SQLSelectBuilderImpl(sql, dbType); + } + public static SQLDeleteBuilder createDeleteBuilder(String dbType) { return new SQLDeleteBuilderImpl(dbType); } + public static SQLDeleteBuilder createDeleteBuilder(String sql, String dbType) { + return new SQLDeleteBuilderImpl(sql, dbType); + } + public static SQLUpdateBuilder createUpdateBuilder(String dbType) { return new SQLUpdateBuilderImpl(dbType); } + + public static SQLUpdateBuilder createUpdateBuilder(String sql, String dbType) { + return new SQLUpdateBuilderImpl(sql, dbType); + } } diff --git a/src/main/java/com/alibaba/druid/sql/builder/SQLDeleteBuilder.java b/src/main/java/com/alibaba/druid/sql/builder/SQLDeleteBuilder.java index 01fc38e6ea..f26911d8c4 100644 --- a/src/main/java/com/alibaba/druid/sql/builder/SQLDeleteBuilder.java +++ b/src/main/java/com/alibaba/druid/sql/builder/SQLDeleteBuilder.java @@ -1,11 +1,26 @@ +/* + * Copyright 1999-2011 Alibaba Group Holding Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ 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); diff --git a/src/main/java/com/alibaba/druid/sql/builder/SQLSelectBuilder.java b/src/main/java/com/alibaba/druid/sql/builder/SQLSelectBuilder.java index 3c12527cda..6e6185c592 100644 --- a/src/main/java/com/alibaba/druid/sql/builder/SQLSelectBuilder.java +++ b/src/main/java/com/alibaba/druid/sql/builder/SQLSelectBuilder.java @@ -1,3 +1,18 @@ +/* + * Copyright 1999-2011 Alibaba Group Holding Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package com.alibaba.druid.sql.builder; import com.alibaba.druid.sql.ast.statement.SQLSelectStatement; diff --git a/src/main/java/com/alibaba/druid/sql/builder/SQLUpdateBuilder.java b/src/main/java/com/alibaba/druid/sql/builder/SQLUpdateBuilder.java index 6a2ad480a0..fd15f0f645 100644 --- a/src/main/java/com/alibaba/druid/sql/builder/SQLUpdateBuilder.java +++ b/src/main/java/com/alibaba/druid/sql/builder/SQLUpdateBuilder.java @@ -1,11 +1,26 @@ +/* + * Copyright 1999-2011 Alibaba Group Holding Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ 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); @@ -15,6 +30,6 @@ public interface SQLUpdateBuilder { SQLUpdateBuilder whereAnd(String sql); SQLUpdateBuilder whereOr(String sql); - + SQLUpdateBuilder set(String... items); } diff --git a/src/main/java/com/alibaba/druid/sql/builder/UpdateBuilder.java b/src/main/java/com/alibaba/druid/sql/builder/UpdateBuilder.java index 9f73886360..11324d3557 100644 --- a/src/main/java/com/alibaba/druid/sql/builder/UpdateBuilder.java +++ b/src/main/java/com/alibaba/druid/sql/builder/UpdateBuilder.java @@ -1,3 +1,18 @@ +/* + * Copyright 1999-2011 Alibaba Group Holding Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package com.alibaba.druid.sql.builder; diff --git a/src/main/java/com/alibaba/druid/sql/builder/impl/SQLBuilderImpl.java b/src/main/java/com/alibaba/druid/sql/builder/impl/SQLBuilderImpl.java index 4e98289d7d..485629e99e 100644 --- a/src/main/java/com/alibaba/druid/sql/builder/impl/SQLBuilderImpl.java +++ b/src/main/java/com/alibaba/druid/sql/builder/impl/SQLBuilderImpl.java @@ -1,3 +1,18 @@ +/* + * Copyright 1999-2011 Alibaba Group Holding Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package com.alibaba.druid.sql.builder.impl; import com.alibaba.druid.sql.builder.SQLBuilder; diff --git a/src/main/java/com/alibaba/druid/sql/builder/impl/SQLDeleteBuilderImpl.java b/src/main/java/com/alibaba/druid/sql/builder/impl/SQLDeleteBuilderImpl.java index d15bceafc7..ad2cd72c51 100644 --- a/src/main/java/com/alibaba/druid/sql/builder/impl/SQLDeleteBuilderImpl.java +++ b/src/main/java/com/alibaba/druid/sql/builder/impl/SQLDeleteBuilderImpl.java @@ -1,12 +1,34 @@ +/* + * Copyright 1999-2011 Alibaba Group Holding Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package com.alibaba.druid.sql.builder.impl; +import java.util.List; + import com.alibaba.druid.sql.SQLUtils; import com.alibaba.druid.sql.ast.SQLExpr; +import com.alibaba.druid.sql.ast.SQLStatement; 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; +import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlDeleteStatement; +import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleDeleteStatement; +import com.alibaba.druid.sql.dialect.postgresql.ast.stmt.PGDeleteStatement; +import com.alibaba.druid.util.JdbcConstants; public class SQLDeleteBuilderImpl implements SQLDeleteBuilder { @@ -16,6 +38,22 @@ public class SQLDeleteBuilderImpl implements SQLDeleteBuilder { public SQLDeleteBuilderImpl(String dbType){ this.dbType = dbType; } + + public SQLDeleteBuilderImpl(String sql, String dbType){ + List stmtList = SQLUtils.parseStatements(sql, dbType); + + if (stmtList.size() == 0) { + throw new IllegalArgumentException("not support empty-statement :" + sql); + } + + if (stmtList.size() > 1) { + throw new IllegalArgumentException("not support multi-statement :" + sql); + } + + SQLDeleteStatement stmt = (SQLDeleteStatement) stmtList.get(0); + this.stmt = stmt; + this.dbType = dbType; + } public SQLDeleteBuilderImpl(SQLDeleteStatement stmt, String dbType){ this.stmt = stmt; @@ -85,6 +123,18 @@ public class SQLDeleteBuilderImpl implements SQLDeleteBuilder { } public SQLDeleteStatement createSQLDeleteStatement() { + if (JdbcConstants.ORACLE.equals(dbType)) { + return new OracleDeleteStatement(); + } + + if (JdbcConstants.MYSQL.equals(dbType)) { + return new MySqlDeleteStatement(); + } + + if (JdbcConstants.POSTGRESQL.equals(dbType)) { + return new PGDeleteStatement(); + } + return new SQLDeleteStatement(); } diff --git a/src/main/java/com/alibaba/druid/sql/builder/impl/SQLSelectBuilderImpl.java b/src/main/java/com/alibaba/druid/sql/builder/impl/SQLSelectBuilderImpl.java index 597d79ceb3..f6f4da8078 100644 --- a/src/main/java/com/alibaba/druid/sql/builder/impl/SQLSelectBuilderImpl.java +++ b/src/main/java/com/alibaba/druid/sql/builder/impl/SQLSelectBuilderImpl.java @@ -1,10 +1,29 @@ +/* + * Copyright 1999-2011 Alibaba Group Holding Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package com.alibaba.druid.sql.builder.impl; +import java.util.List; + 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.SQLStatement; import com.alibaba.druid.sql.ast.expr.SQLBinaryOperator; import com.alibaba.druid.sql.ast.expr.SQLIdentifierExpr; +import com.alibaba.druid.sql.ast.expr.SQLIntegerExpr; import com.alibaba.druid.sql.ast.statement.SQLExprTableSource; import com.alibaba.druid.sql.ast.statement.SQLSelect; import com.alibaba.druid.sql.ast.statement.SQLSelectGroupByClause; @@ -14,6 +33,21 @@ 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; +import com.alibaba.druid.sql.dialect.db2.ast.stmt.DB2SelectQueryBlock; +import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlSelectGroupBy; +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.odps.ast.OdpsSelectQueryBlock; +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.sql.dialect.postgresql.ast.PGOrderBy; +import com.alibaba.druid.sql.dialect.postgresql.ast.stmt.PGSelectQueryBlock; +import com.alibaba.druid.sql.dialect.postgresql.ast.stmt.PGSelectQueryBlock.PGLimit; +import com.alibaba.druid.sql.dialect.sqlserver.ast.SQLServerSelect; +import com.alibaba.druid.sql.dialect.sqlserver.ast.SQLServerSelectQueryBlock; +import com.alibaba.druid.sql.dialect.sqlserver.ast.SQLServerTop; +import com.alibaba.druid.util.JdbcConstants; public class SQLSelectBuilderImpl implements SQLSelectBuilder { @@ -23,6 +57,22 @@ public class SQLSelectBuilderImpl implements SQLSelectBuilder { public SQLSelectBuilderImpl(String dbType){ this(new SQLSelectStatement(), dbType); } + + public SQLSelectBuilderImpl(String sql, String dbType){ + List stmtList = SQLUtils.parseStatements(sql, dbType); + + if (stmtList.size() == 0) { + throw new IllegalArgumentException("not support empty-statement :" + sql); + } + + if (stmtList.size() > 1) { + throw new IllegalArgumentException("not support multi-statement :" + sql); + } + + SQLSelectStatement stmt = (SQLSelectStatement) stmtList.get(0); + this.stmt = stmt; + this.dbType = dbType; + } public SQLSelectBuilderImpl(SQLSelectStatement stmt, String dbType){ this.stmt = stmt; @@ -136,46 +186,127 @@ public class SQLSelectBuilderImpl implements SQLSelectBuilder { 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()); + 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()); + SQLExpr newCondition = SQLUtils.buildCondition(SQLBinaryOperator.BooleanOr, exprObj, false, + queryBlock.getWhere()); queryBlock.setWhere(newCondition); - + return this; } @Override public SQLSelectBuilderImpl limit(int rowCount) { - throw new UnsupportedOperationException(); + return limit(rowCount, 0); } @Override public SQLSelectBuilderImpl limit(int rowCount, int offset) { + SQLSelectQueryBlock queryBlock = getQueryBlock(); + + if (queryBlock instanceof MySqlSelectQueryBlock) { + MySqlSelectQueryBlock mySqlQueryBlock = (MySqlSelectQueryBlock) queryBlock; + + Limit limit = new Limit(); + limit.setRowCount(new SQLIntegerExpr(rowCount)); + if (offset > 0) { + limit.setOffset(new SQLIntegerExpr(offset)); + } + + mySqlQueryBlock.setLimit(limit); + + return this; + } + + if (queryBlock instanceof SQLServerSelectQueryBlock) { + SQLServerSelectQueryBlock sqlserverQueryBlock = (SQLServerSelectQueryBlock) queryBlock; + if (offset <= 0) { + SQLServerTop top = new SQLServerTop(); + top.setExpr(new SQLIntegerExpr(rowCount)); + sqlserverQueryBlock.setTop(top); + } else { + throw new UnsupportedOperationException("not support offset"); + } + + return this; + } + + if (queryBlock instanceof PGSelectQueryBlock) { + PGSelectQueryBlock pgQueryBlock = (PGSelectQueryBlock) queryBlock; + PGLimit limit = new PGLimit(); + if (offset > 0) { + limit.setOffset(new SQLIntegerExpr(offset)); + } + limit.setRowCount(new SQLIntegerExpr(rowCount)); + pgQueryBlock.setLimit(limit); + + return this; + } + + if (queryBlock instanceof DB2SelectQueryBlock) { + DB2SelectQueryBlock db2QueryBlock = (DB2SelectQueryBlock) queryBlock; + if (offset <= 0) { + SQLExpr rowCountExpr = new SQLIntegerExpr(rowCount); + db2QueryBlock.setFirst(rowCountExpr); + } else { + throw new UnsupportedOperationException("not support offset"); + } + + return this; + } + + if (queryBlock instanceof OracleSelectQueryBlock) { + OracleSelectQueryBlock oracleQueryBlock = (OracleSelectQueryBlock) queryBlock; + if (offset <= 0) { + SQLExpr rowCountExpr = new SQLIntegerExpr(rowCount); + SQLExpr newCondition = SQLUtils.buildCondition(SQLBinaryOperator.BooleanAnd, rowCountExpr, false, + oracleQueryBlock.getWhere()); + queryBlock.setWhere(newCondition); + } else { + throw new UnsupportedOperationException("not support offset"); + } + + return this; + } + + if (queryBlock instanceof OdpsSelectQueryBlock) { + OdpsSelectQueryBlock odpsQueryBlock = (OdpsSelectQueryBlock) queryBlock; + + if (offset > 0) { + throw new UnsupportedOperationException("not support offset"); + } + + odpsQueryBlock.setLimit(new SQLIntegerExpr(rowCount)); + + return this; + } + throw new UnsupportedOperationException(); } @@ -196,18 +327,53 @@ public class SQLSelectBuilderImpl implements SQLSelectBuilder { } protected SQLSelect createSelect() { + if (JdbcConstants.SQL_SERVER.equals(dbType)) { + return new SQLServerSelect(); + } + if (JdbcConstants.ORACLE.equals(dbType)) { + return new OracleSelect(); + } + return new SQLSelect(); } protected SQLSelectQuery createSelectQueryBlock() { + if (JdbcConstants.MYSQL.equals(dbType)) { + return new MySqlSelectQueryBlock(); + } + + if (JdbcConstants.POSTGRESQL.equals(dbType)) { + return new PGSelectQueryBlock(); + } + + if (JdbcConstants.SQL_SERVER.equals(dbType)) { + return new SQLServerSelectQueryBlock(); + } + + if (JdbcConstants.ORACLE.equals(dbType)) { + return new OracleSelectQueryBlock(); + } + return new SQLSelectQueryBlock(); } protected SQLOrderBy createOrderBy() { + if (JdbcConstants.POSTGRESQL.equals(dbType)) { + return new PGOrderBy(); + } + + if (JdbcConstants.ORACLE.equals(dbType)) { + return new OracleOrderBy(); + } + return new SQLOrderBy(); } protected SQLSelectGroupByClause createGroupBy() { + if (JdbcConstants.MYSQL.equals(dbType)) { + return new MySqlSelectGroupBy(); + } + return new SQLSelectGroupByClause(); } diff --git a/src/main/java/com/alibaba/druid/sql/builder/impl/SQLUpdateBuilderImpl.java b/src/main/java/com/alibaba/druid/sql/builder/impl/SQLUpdateBuilderImpl.java index 51785b0a24..45c966f268 100644 --- a/src/main/java/com/alibaba/druid/sql/builder/impl/SQLUpdateBuilderImpl.java +++ b/src/main/java/com/alibaba/druid/sql/builder/impl/SQLUpdateBuilderImpl.java @@ -1,13 +1,36 @@ +/* + * Copyright 1999-2011 Alibaba Group Holding Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package com.alibaba.druid.sql.builder.impl; +import java.util.List; + import com.alibaba.druid.sql.SQLUtils; import com.alibaba.druid.sql.ast.SQLExpr; +import com.alibaba.druid.sql.ast.SQLStatement; 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; +import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlUpdateStatement; +import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleUpdateStatement; +import com.alibaba.druid.sql.dialect.postgresql.ast.stmt.PGUpdateStatement; +import com.alibaba.druid.sql.dialect.sqlserver.ast.stmt.SQLServerUpdateStatement; +import com.alibaba.druid.util.JdbcConstants; public class SQLUpdateBuilderImpl implements SQLUpdateBuilder { @@ -17,6 +40,22 @@ public class SQLUpdateBuilderImpl implements SQLUpdateBuilder { public SQLUpdateBuilderImpl(String dbType){ this.dbType = dbType; } + + public SQLUpdateBuilderImpl(String sql, String dbType){ + List stmtList = SQLUtils.parseStatements(sql, dbType); + + if (stmtList.size() == 0) { + throw new IllegalArgumentException("not support empty-statement :" + sql); + } + + if (stmtList.size() > 1) { + throw new IllegalArgumentException("not support multi-statement :" + sql); + } + + SQLUpdateStatement stmt = (SQLUpdateStatement) stmtList.get(0); + this.stmt = stmt; + this.dbType = dbType; + } public SQLUpdateBuilderImpl(SQLUpdateStatement stmt, String dbType){ this.stmt = stmt; @@ -96,6 +135,22 @@ public class SQLUpdateBuilderImpl implements SQLUpdateBuilder { } public SQLUpdateStatement createSQLUpdateStatement() { + if (JdbcConstants.MYSQL.equals(dbType)) { + return new MySqlUpdateStatement(); + } + + if (JdbcConstants.ORACLE.equals(dbType)) { + return new OracleUpdateStatement(); + } + + if (JdbcConstants.POSTGRESQL.equals(dbType)) { + return new PGUpdateStatement(); + } + + if (JdbcConstants.SQL_SERVER.equals(dbType)) { + return new SQLServerUpdateStatement(); + } + return new SQLUpdateStatement(); } diff --git a/src/main/java/com/alibaba/druid/sql/builder/impl/dialect/MySqlSelectBuilderImpl.java b/src/main/java/com/alibaba/druid/sql/builder/impl/dialect/MySqlSelectBuilderImpl.java deleted file mode 100644 index cb1424bb7e..0000000000 --- a/src/main/java/com/alibaba/druid/sql/builder/impl/dialect/MySqlSelectBuilderImpl.java +++ /dev/null @@ -1,23 +0,0 @@ -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(); - } -} diff --git a/src/main/java/com/alibaba/druid/sql/builder/impl/dialect/OracleSelectBuilderImpl.java b/src/main/java/com/alibaba/druid/sql/builder/impl/dialect/OracleSelectBuilderImpl.java deleted file mode 100644 index 58f0f3209f..0000000000 --- a/src/main/java/com/alibaba/druid/sql/builder/impl/dialect/OracleSelectBuilderImpl.java +++ /dev/null @@ -1,26 +0,0 @@ -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(); - } -} diff --git a/src/main/java/com/alibaba/druid/sql/builder/impl/dialect/PGSelectBuilderImpl.java b/src/main/java/com/alibaba/druid/sql/builder/impl/dialect/PGSelectBuilderImpl.java deleted file mode 100644 index a438626399..0000000000 --- a/src/main/java/com/alibaba/druid/sql/builder/impl/dialect/PGSelectBuilderImpl.java +++ /dev/null @@ -1,22 +0,0 @@ -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(); - } -} diff --git a/src/main/java/com/alibaba/druid/sql/builder/impl/dialect/SQLServerSelectBuilderImpl.java b/src/main/java/com/alibaba/druid/sql/builder/impl/dialect/SQLServerSelectBuilderImpl.java deleted file mode 100644 index f4690df0b4..0000000000 --- a/src/main/java/com/alibaba/druid/sql/builder/impl/dialect/SQLServerSelectBuilderImpl.java +++ /dev/null @@ -1,21 +0,0 @@ -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(); - } -} diff --git a/src/main/java/com/alibaba/druid/sql/dialect/mysql/ast/statement/MySqlSelectQueryBlock.java b/src/main/java/com/alibaba/druid/sql/dialect/mysql/ast/statement/MySqlSelectQueryBlock.java index 161b843c52..606096ffb8 100644 --- a/src/main/java/com/alibaba/druid/sql/dialect/mysql/ast/statement/MySqlSelectQueryBlock.java +++ b/src/main/java/com/alibaba/druid/sql/dialect/mysql/ast/statement/MySqlSelectQueryBlock.java @@ -272,6 +272,10 @@ public class MySqlSelectQueryBlock extends SQLSelectQueryBlock implements MySqlO public Limit(){ } + + public Limit(SQLExpr rowCount){ + this.setRowCount(rowCount); + } private SQLExpr rowCount; private SQLExpr offset;