Repository: empire-db Updated Branches: refs/heads/master 3566a9786 -> 7019c8edf
EMPIREDB-242 Explicitly declare cross joins Project: http://git-wip-us.apache.org/repos/asf/empire-db/repo Commit: http://git-wip-us.apache.org/repos/asf/empire-db/commit/e90ecf1f Tree: http://git-wip-us.apache.org/repos/asf/empire-db/tree/e90ecf1f Diff: http://git-wip-us.apache.org/repos/asf/empire-db/diff/e90ecf1f Branch: refs/heads/master Commit: e90ecf1fa4f66ee30a47f3232016480c93837770 Parents: a812088 Author: Rainer Döbele <[email protected]> Authored: Tue May 10 13:02:52 2016 +0200 Committer: Rainer Döbele <[email protected]> Committed: Tue May 10 13:07:00 2016 +0200 ---------------------------------------------------------------------- .../empire/jsf2/components/RecordTag.java | 1 - .../java/org/apache/empire/db/DBCommand.java | 43 ++- .../java/org/apache/empire/db/DBJoinType.java | 7 +- .../main/java/org/apache/empire/db/DBQuery.java | 7 +- .../java/org/apache/empire/db/DBReader.java | 4 +- .../empire/db/expr/join/DBColumnJoinExpr.java | 267 +++++++++++++++++++ .../empire/db/expr/join/DBCompareJoinExpr.java | 111 ++++++++ .../empire/db/expr/join/DBCrossJoinExpr.java | 177 ++++++++++++ .../apache/empire/db/expr/join/DBJoinExpr.java | 199 ++------------ .../empire/db/expr/join/DBJoinExprEx.java | 111 -------- .../empire/db/oracle/DBCommandOracle.java | 7 +- .../db/sqlite/DBDatabaseDriverSQLite.java | 17 +- 12 files changed, 628 insertions(+), 323 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/empire-db/blob/e90ecf1f/empire-db-jsf2/src/main/java/org/apache/empire/jsf2/components/RecordTag.java ---------------------------------------------------------------------- diff --git a/empire-db-jsf2/src/main/java/org/apache/empire/jsf2/components/RecordTag.java b/empire-db-jsf2/src/main/java/org/apache/empire/jsf2/components/RecordTag.java index 78d1920..0d8052f 100644 --- a/empire-db-jsf2/src/main/java/org/apache/empire/jsf2/components/RecordTag.java +++ b/empire-db-jsf2/src/main/java/org/apache/empire/jsf2/components/RecordTag.java @@ -18,7 +18,6 @@ */ package org.apache.empire.jsf2.components; -import javax.faces.component.NamingContainer; import javax.faces.component.UIComponentBase; import org.apache.empire.commons.ObjectUtils; http://git-wip-us.apache.org/repos/asf/empire-db/blob/e90ecf1f/empire-db/src/main/java/org/apache/empire/db/DBCommand.java ---------------------------------------------------------------------- diff --git a/empire-db/src/main/java/org/apache/empire/db/DBCommand.java b/empire-db/src/main/java/org/apache/empire/db/DBCommand.java index 9284a1b..f3eff01 100644 --- a/empire-db/src/main/java/org/apache/empire/db/DBCommand.java +++ b/empire-db/src/main/java/org/apache/empire/db/DBCommand.java @@ -34,8 +34,10 @@ import org.apache.empire.commons.StringUtils; import org.apache.empire.data.DataType; import org.apache.empire.db.expr.compare.DBCompareColExpr; import org.apache.empire.db.expr.compare.DBCompareExpr; +import org.apache.empire.db.expr.join.DBColumnJoinExpr; +import org.apache.empire.db.expr.join.DBCompareJoinExpr; +import org.apache.empire.db.expr.join.DBCrossJoinExpr; import org.apache.empire.db.expr.join.DBJoinExpr; -import org.apache.empire.db.expr.join.DBJoinExprEx; import org.apache.empire.db.expr.set.DBSetExpr; import org.apache.empire.exceptions.InternalException; import org.apache.empire.exceptions.MiscellaneousErrorException; @@ -473,6 +475,19 @@ public abstract class DBCommand extends DBCommandExpr } joins.add(join); } + + /** + * Adds a cross join for two tables or views + * @param left the left RowSet + * @param right the right RowSet + * @return the join expression + */ + public DBCrossJoinExpr join(DBRowSet left, DBRowSet right) + { + DBCrossJoinExpr join = new DBCrossJoinExpr(left, right); + join(join); + return join; + } /** * Adds a join based on two columns to the list of join expressions. @@ -483,9 +498,9 @@ public abstract class DBCommand extends DBCommandExpr * * @return the join expression */ - public DBJoinExpr join(DBColumnExpr left, DBColumnExpr right, DBJoinType joinType) + public DBColumnJoinExpr join(DBColumnExpr left, DBColumnExpr right, DBJoinType joinType) { - DBJoinExpr join = new DBJoinExpr(left, right, joinType); + DBColumnJoinExpr join = new DBColumnJoinExpr(left, right, joinType); join(join); return join; } @@ -498,7 +513,7 @@ public abstract class DBCommand extends DBCommandExpr * * @return the join expresion */ - public DBJoinExpr join(DBColumnExpr left, DBColumn right) + public DBColumnJoinExpr join(DBColumnExpr left, DBColumn right) { return join(left, right, DBJoinType.INNER); } @@ -512,9 +527,9 @@ public abstract class DBCommand extends DBCommandExpr * * @return the join expresion */ - public DBJoinExpr join(DBRowSet rowset, DBCompareExpr cmp, DBJoinType joinType) + public DBCompareJoinExpr join(DBRowSet rowset, DBCompareExpr cmp, DBJoinType joinType) { - DBJoinExpr join = new DBJoinExprEx(rowset, cmp, joinType); + DBCompareJoinExpr join = new DBCompareJoinExpr(rowset, cmp, joinType); join(join); return join; } @@ -527,7 +542,7 @@ public abstract class DBCommand extends DBCommandExpr * * @return the join expresion */ - public DBJoinExpr join(DBRowSet rowset, DBCompareExpr cmp) + public DBCompareJoinExpr join(DBRowSet rowset, DBCompareExpr cmp) { return join(rowset, cmp, DBJoinType.INNER); } @@ -1163,21 +1178,21 @@ public abstract class DBCommand extends DBCommandExpr DBJoinExpr join = joins.get(i); if (i<1) { // Add Join Tables - joinTables.add(join.getLeft() .getUpdateColumn().getRowSet()); - joinTables.add(join.getRight().getUpdateColumn().getRowSet()); + joinTables.add(join.getLeftTable()); + joinTables.add(join.getRightTable()); // Remove from List - tables.remove(join.getLeft() .getUpdateColumn().getRowSet()); - tables.remove(join.getRight().getUpdateColumn().getRowSet()); + tables.remove(join.getLeftTable()); + tables.remove(join.getRightTable()); // Context context = CTX_NAME|CTX_VALUE; } else { // Extend the join - if ( joinTables.contains(join.getRight().getUpdateColumn().getRowSet())) + if ( joinTables.contains(join.getRightTable())) join.reverse(); // Add Right Table - joinTables.add(join.getRight().getUpdateColumn().getRowSet()); - tables .remove(join.getRight().getUpdateColumn().getRowSet()); + joinTables.add(join.getRightTable()); + tables .remove(join.getRightTable()); // Context context = CTX_VALUE; buf.append( "\t" ); http://git-wip-us.apache.org/repos/asf/empire-db/blob/e90ecf1f/empire-db/src/main/java/org/apache/empire/db/DBJoinType.java ---------------------------------------------------------------------- diff --git a/empire-db/src/main/java/org/apache/empire/db/DBJoinType.java b/empire-db/src/main/java/org/apache/empire/db/DBJoinType.java index 2315ebf..3f1f949 100644 --- a/empire-db/src/main/java/org/apache/empire/db/DBJoinType.java +++ b/empire-db/src/main/java/org/apache/empire/db/DBJoinType.java @@ -39,7 +39,12 @@ public enum DBJoinType /** * SQL Right join */ - RIGHT; // = 1 + RIGHT, // = 1 + + /** + * SQL Cross join + */ + CROSS; public static DBJoinType reversed(DBJoinType type) { http://git-wip-us.apache.org/repos/asf/empire-db/blob/e90ecf1f/empire-db/src/main/java/org/apache/empire/db/DBQuery.java ---------------------------------------------------------------------- diff --git a/empire-db/src/main/java/org/apache/empire/db/DBQuery.java b/empire-db/src/main/java/org/apache/empire/db/DBQuery.java index db0dbe6..ff3fa52 100644 --- a/empire-db/src/main/java/org/apache/empire/db/DBQuery.java +++ b/empire-db/src/main/java/org/apache/empire/db/DBQuery.java @@ -28,7 +28,6 @@ import org.apache.empire.commons.ObjectUtils; import org.apache.empire.commons.Options; import org.apache.empire.commons.StringUtils; import org.apache.empire.data.DataType; -import org.apache.empire.db.DBCmdParam; import org.apache.empire.db.exceptions.InvalidKeyException; import org.apache.empire.db.exceptions.NoPrimaryKeyException; import org.apache.empire.db.exceptions.QueryNoResultException; @@ -37,6 +36,7 @@ import org.apache.empire.db.exceptions.RecordUpdateFailedException; import org.apache.empire.db.exceptions.RecordUpdateInvalidException; import org.apache.empire.db.expr.compare.DBCompareColExpr; import org.apache.empire.db.expr.compare.DBCompareExpr; +import org.apache.empire.db.expr.join.DBColumnJoinExpr; import org.apache.empire.db.expr.join.DBJoinExpr; import org.apache.empire.exceptions.InvalidArgumentException; import org.apache.empire.exceptions.ItemNotFoundException; @@ -539,7 +539,10 @@ public class DBQuery extends DBRowSet // Evaluate Joins for (i = 0; cmd.joins != null && i < cmd.joins.size(); i++) { - DBJoinExpr join = cmd.joins.get(i); + DBJoinExpr jex = cmd.joins.get(i); + if (!(jex instanceof DBColumnJoinExpr)) + continue; + DBColumnJoinExpr join = (DBColumnJoinExpr)jex; DBColumn left = join.getLeft() .getUpdateColumn(); DBColumn right = join.getRight().getUpdateColumn(); if (left.getRowSet()==table && table.isKeyColumn(left)) http://git-wip-us.apache.org/repos/asf/empire-db/blob/e90ecf1f/empire-db/src/main/java/org/apache/empire/db/DBReader.java ---------------------------------------------------------------------- diff --git a/empire-db/src/main/java/org/apache/empire/db/DBReader.java b/empire-db/src/main/java/org/apache/empire/db/DBReader.java index 91f5902..484c316 100644 --- a/empire-db/src/main/java/org/apache/empire/db/DBReader.java +++ b/empire-db/src/main/java/org/apache/empire/db/DBReader.java @@ -899,8 +899,8 @@ public class DBReader extends DBRecordData // check the joins for (DBJoinExpr j : joins) { - DBRowSet rsl = j.getLeft().getUpdateColumn().getRowSet(); - DBRowSet rsr = j.getRight().getUpdateColumn().getRowSet(); + DBRowSet rsl = j.getLeftTable(); + DBRowSet rsr = j.getRightTable(); if (rsl instanceof DBQuery) { // the left join is a query subQueryParams = addSubQueryParams((DBQuery)rsl, subQueryParams); http://git-wip-us.apache.org/repos/asf/empire-db/blob/e90ecf1f/empire-db/src/main/java/org/apache/empire/db/expr/join/DBColumnJoinExpr.java ---------------------------------------------------------------------- diff --git a/empire-db/src/main/java/org/apache/empire/db/expr/join/DBColumnJoinExpr.java b/empire-db/src/main/java/org/apache/empire/db/expr/join/DBColumnJoinExpr.java new file mode 100644 index 0000000..db3f4ef --- /dev/null +++ b/empire-db/src/main/java/org/apache/empire/db/expr/join/DBColumnJoinExpr.java @@ -0,0 +1,267 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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 org.apache.empire.db.expr.join; + +import java.util.HashSet; +import java.util.Set; + +import org.apache.empire.db.DBColumn; +import org.apache.empire.db.DBColumnExpr; +import org.apache.empire.db.DBDatabase; +import org.apache.empire.db.DBJoinType; +import org.apache.empire.db.DBRowSet; +import org.apache.empire.db.expr.compare.DBCompareExpr; + +public class DBColumnJoinExpr extends DBJoinExpr +{ + private final static long serialVersionUID = 1L; + + protected DBColumnExpr left; + protected DBColumnExpr right; + + // Additional + public DBCompareExpr compExpr = null; + + /** + * Constructs a new DBJoinExpr object initialize this object with + * the left and right column and the data type of the join + * expression. + * + * @param left left value + * @param right right value + * @param type data type (JOIN_INNER, JOIN_LEFT or JOIN_RIGHT) + */ + public DBColumnJoinExpr(DBColumnExpr left, DBColumnExpr right, DBJoinType type) + { + super(type); + this.left = left; + this.right = right; + } + + /** + * Returns the current DBDatabase object. + * + * @return the current DBDatabase object + */ + @Override + public DBDatabase getDatabase() + { + return left.getDatabase(); + } + + /** + * returns the left join expression + */ + public DBColumnExpr getLeft() + { + return left; + } + + /** + * returns the right join expression + */ + public DBColumnExpr getRight() + { + return right; + } + + @Override + public DBRowSet getLeftTable() + { + return left.getUpdateColumn().getRowSet(); + } + + /** + * returns the RowSet on the right of the join + */ + @Override + public DBRowSet getRightTable() + { + return right.getUpdateColumn().getRowSet(); + } + + /** + * returns true if this join is using the given table or view or false otherwise + */ + @Override + public boolean isJoinOn(DBRowSet rowset) + { + if (rowset==null) + return false; + DBColumn l = (left !=null ? left .getUpdateColumn() : null); + DBColumn r = (right!=null ? right.getUpdateColumn() : null); + DBRowSet rsl = (l!=null ? l.getRowSet() : null); + DBRowSet rsr = (r!=null ? r.getRowSet() : null); + return rowset.equals(rsl) || rowset.equals(rsr); + } + + /** + * returns true if this join is using the given column or false otherwise + */ + @Override + public boolean isJoinOn(DBColumn column) + { + if (column==null) + return false; + // Check Update Columns + if (column.equals(left.getUpdateColumn()) || + column.equals(right.getUpdateColumn())) + return true; + if (compExpr!=null) + { // Check expression + HashSet<DBColumn> set = new HashSet<DBColumn>(); + compExpr.addReferencedColumns(set); + return set.contains(column); + } + // not found + return false; + } + + /** + * Returns the left table name if the data type= JOIN_LEFT and returns + * the right table if the data type= JOIN_RIGHT. If the + * data type = JOIN_INNER the return value is null. + * + * @return the current DBDatabase object + */ + @Override + public DBRowSet getOuterTable() + { + switch(type) + { + case LEFT: return right.getUpdateColumn().getRowSet(); + case RIGHT: return left .getUpdateColumn().getRowSet(); + default: return null; // no outer table! + } + } + + /** + * This function swaps the left and the right statements of the join expression. + */ + @Override + public void reverse() + { // Swap Type of Join + DBColumnExpr swap = left; + left = right; + right = swap; + type = DBJoinType.reversed(type); // (type * -1); + } + + /** + * Returns any additional constraints to the join + * @return a compare expression containing additional constraints or null + */ + public DBCompareExpr getWhere() + { + return compExpr; + } + + /** + * This function adds an additional constraint to the join. + * + * @param expr the compare expression + */ + public void where(DBCompareExpr expr) + { // Set Compare Expression + compExpr = expr; + } + + /** + * This function adds an additional constraint to the join. + * + * @param c1 the first column + * @param c2 the second column + * + * @return the object itself + */ + public DBJoinExpr and(DBColumnExpr c1, DBColumnExpr c2) + { // Set Compare Expression + if (compExpr==null) + compExpr = c1.is(c2); + else + compExpr = compExpr.and(c1.is(c2)); + return this; + } + + /** + * @see org.apache.empire.db.DBExpr#addReferencedColumns(Set) + */ + @Override + public void addReferencedColumns(Set<DBColumn> list) + { + left.addReferencedColumns(list); + right.addReferencedColumns(list); + // Compare Expression + if (compExpr != null) + compExpr.addReferencedColumns(list); + } + + /** Not allowed, this operation have to be done in the DBCommand object. */ + @Override + public void addSQL(StringBuilder buf, long context) + { + if ((context & CTX_NAME) != 0) + left.getUpdateColumn().getRowSet().addSQL(buf, CTX_DEFAULT | CTX_ALIAS); + if ((context & CTX_VALUE) != 0) + { // Join Type + switch(type) + { + case LEFT: buf.append(" LEFT JOIN ");break; + case INNER: buf.append(" INNER JOIN ");break; + case RIGHT: buf.append(" RIGHT JOIN ");break; + default: buf.append(" JOIN "); // should not come here! + } + right.getUpdateColumn().getRowSet().addSQL(buf, CTX_DEFAULT | CTX_ALIAS); + // compare equal + buf.append(" ON "); + right.addSQL(buf, CTX_DEFAULT); + buf.append(" = "); + left.addSQL(buf, CTX_DEFAULT); + // Compare Expression + if (compExpr != null) + { + buf.append(" AND "); + compExpr.addSQL(buf, CTX_DEFAULT); + } + } + } + + /** + * Compares two DBJoinExpr objects. + * + * @param obj other DBJoinExpr object + * @return true if the other DBJoinExpr object is equal to this object + */ + @Override + public boolean equals(Object obj) + { + if (!(obj instanceof DBColumnJoinExpr)) + return super.equals(obj); + // object + DBColumnJoinExpr other = (DBColumnJoinExpr) obj; + if (left.equals(other.left) && right.equals(other.right) && type == other.type) + return true; + // reversed + if (left.equals(other.right) && right.equals(other.left) && type == DBJoinType.reversed(other.type)) + return true; + // not equal + return false; + } + +} http://git-wip-us.apache.org/repos/asf/empire-db/blob/e90ecf1f/empire-db/src/main/java/org/apache/empire/db/expr/join/DBCompareJoinExpr.java ---------------------------------------------------------------------- diff --git a/empire-db/src/main/java/org/apache/empire/db/expr/join/DBCompareJoinExpr.java b/empire-db/src/main/java/org/apache/empire/db/expr/join/DBCompareJoinExpr.java new file mode 100644 index 0000000..029b04a --- /dev/null +++ b/empire-db/src/main/java/org/apache/empire/db/expr/join/DBCompareJoinExpr.java @@ -0,0 +1,111 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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 org.apache.empire.db.expr.join; + +import org.apache.empire.db.DBColumnExpr; +import org.apache.empire.db.DBJoinType; +import org.apache.empire.db.DBQuery; +import org.apache.empire.db.DBRowSet; +import org.apache.empire.db.expr.compare.DBCompareAndOrExpr; +import org.apache.empire.db.expr.compare.DBCompareColExpr; +import org.apache.empire.db.expr.compare.DBCompareExpr; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * This class is used for building a join expression of an SQL statement. + * <P> + * There is no need to explicitly create instances of this class.<BR> + * Instead use @link {@link org.apache.empire.db.DBCommand#join(DBRowSet, DBCompareExpr, DBJoinType)} + * <P> + * + */ +public class DBCompareJoinExpr extends DBColumnJoinExpr +{ + private final static long serialVersionUID = 1L; + private static final Logger log = LoggerFactory.getLogger(DBCompareJoinExpr.class); + + protected final DBCompareExpr cmp; + + private static DBColumnExpr findFirstColumn(DBCompareExpr expr) + { + // DBCompareORExpr + while (expr instanceof DBCompareAndOrExpr) + expr = ((DBCompareAndOrExpr)expr).getLeft(); + // Get Colum Expr + if (expr instanceof DBCompareColExpr) + return ((DBCompareColExpr)expr).getColumnExpr(); + // Error + log.error("Unknown class found for building a valid JOIN Expression"); + return null; + } + + private static DBColumnExpr firstRsetColumn(DBRowSet rset) + { + if (rset instanceof DBQuery) + return ((DBQuery)rset).getQueryColumns()[0]; + else + return rset.getColumn(0); + } + + /** + * Constructs a new DBJoinExprEx + * + * @param rset the rowset + * @param cmp the compare expression + * @param joinType the join type + */ + public DBCompareJoinExpr(DBRowSet rset, DBCompareExpr cmp, DBJoinType joinType) + { + super(firstRsetColumn(rset), findFirstColumn(cmp), joinType); + this.cmp = cmp; + } + + public DBCompareExpr getJoinConstraint() + { + return cmp; + } + + @Override + public void addSQL(StringBuilder buf, long context) + { + if ((context & CTX_NAME) != 0) + left.getUpdateColumn().getRowSet().addSQL(buf, CTX_DEFAULT | CTX_ALIAS); + if ((context & CTX_VALUE) != 0) + { // Join Type + switch(type) + { + case LEFT: buf.append(" LEFT JOIN ");break; + case INNER: buf.append(" INNER JOIN ");break; + case RIGHT: buf.append(" RIGHT JOIN ");break; + default: buf.append(" JOIN "); // should not come here! + } + right.getUpdateColumn().getRowSet().addSQL(buf, CTX_DEFAULT | CTX_ALIAS); + // compare equal + buf.append(" ON "); + cmp.addSQL(buf, CTX_DEFAULT); + // Compare Expression + if (compExpr != null) + { + buf.append(" AND "); + compExpr.addSQL(buf, CTX_DEFAULT); + } + } + } +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/empire-db/blob/e90ecf1f/empire-db/src/main/java/org/apache/empire/db/expr/join/DBCrossJoinExpr.java ---------------------------------------------------------------------- diff --git a/empire-db/src/main/java/org/apache/empire/db/expr/join/DBCrossJoinExpr.java b/empire-db/src/main/java/org/apache/empire/db/expr/join/DBCrossJoinExpr.java new file mode 100644 index 0000000..c76da2f --- /dev/null +++ b/empire-db/src/main/java/org/apache/empire/db/expr/join/DBCrossJoinExpr.java @@ -0,0 +1,177 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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 org.apache.empire.db.expr.join; + +import java.util.Set; + +import org.apache.empire.db.DBColumn; +import org.apache.empire.db.DBColumnExpr; +import org.apache.empire.db.DBDatabase; +import org.apache.empire.db.DBJoinType; +import org.apache.empire.db.DBRowSet; + +/** + * This class is used for building a join expression of an SQL statement. + * <P> + * There is no need to explicitly create instances of this class.<BR> + * Instead use @link {@link org.apache.empire.db.DBCommand#join(DBColumnExpr, DBColumn, DBJoinType)} + * <P> + * + */ +public class DBCrossJoinExpr extends DBJoinExpr +{ + private final static long serialVersionUID = 1L; + + protected DBRowSet left; + protected DBRowSet right; + + /** + * Constructs a new DBJoinExpr object initialize this object with + * the left and right column and the data type of the join + * expression. + * + * @param left left value + * @param right right value + * @param type data type (JOIN_INNER, JOIN_LEFT or JOIN_RIGHT) + */ + public DBCrossJoinExpr(DBRowSet left, DBRowSet right) + { + super(DBJoinType.CROSS); + this.left = left; + this.right = right; + } + + /** + * Returns the current DBDatabase object. + * + * @return the current DBDatabase object + */ + @Override + public DBDatabase getDatabase() + { + return left.getDatabase(); + } + + /** + * returns the RowSet on the left of the join + */ + @Override + public DBRowSet getLeftTable() + { + return left; + } + + /** + * returns the RowSet on the right of the join + */ + @Override + public DBRowSet getRightTable() + { + return right; + } + + /** + * returns true if this join is using the given table or view or false otherwise + */ + @Override + public boolean isJoinOn(DBRowSet rowset) + { + if (rowset==null) + return false; + return rowset.equals(left) || rowset.equals(right); + } + + /** + * returns true if this join is using the given column or false otherwise + */ + @Override + public boolean isJoinOn(DBColumn column) + { + return false; + } + + /** + * Returns the left table name if the data type= JOIN_LEFT and returns + * the right table if the data type= JOIN_RIGHT. If the + * data type = JOIN_INNER the return value is null. + * + * @return the current DBDatabase object + */ + @Override + public DBRowSet getOuterTable() + { + return null; // no outer table! + } + + /** + * This function swaps the left and the right statements of the join expression. + */ + @Override + public void reverse() + { // Swap Type of Join + DBRowSet swap = left; + left = right; + right = swap; + } + + /** + * @see org.apache.empire.db.DBExpr#addReferencedColumns(Set) + */ + @Override + public void addReferencedColumns(Set<DBColumn> list) + { + // No referenced columns + } + + /** Not allowed, this operation have to be done in the DBCommand object. */ + @Override + public void addSQL(StringBuilder buf, long context) + { + if ((context & CTX_NAME) != 0) + left.addSQL(buf, CTX_DEFAULT | CTX_ALIAS); + if ((context & CTX_VALUE) != 0) + { // Join Type + buf.append(" CROSS JOIN "); + right.addSQL(buf, CTX_DEFAULT | CTX_ALIAS); + } + } + + /** + * Compares two DBJoinExpr objects. + * + * @param obj other DBJoinExpr object + * @return true if the other DBJoinExpr object is equal to this object + */ + @Override + public boolean equals(Object obj) + { + if (!(obj instanceof DBCrossJoinExpr)) + return super.equals(obj); + // object + DBCrossJoinExpr other = (DBCrossJoinExpr) obj; + if (left.equals(other.left) && right.equals(other.right)) + return true; + // reversed + if (left.equals(other.right) && right.equals(other.left)) + return true; + // not equal + return false; + } + +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/empire-db/blob/e90ecf1f/empire-db/src/main/java/org/apache/empire/db/expr/join/DBJoinExpr.java ---------------------------------------------------------------------- diff --git a/empire-db/src/main/java/org/apache/empire/db/expr/join/DBJoinExpr.java b/empire-db/src/main/java/org/apache/empire/db/expr/join/DBJoinExpr.java index 1306e90..200f19f 100644 --- a/empire-db/src/main/java/org/apache/empire/db/expr/join/DBJoinExpr.java +++ b/empire-db/src/main/java/org/apache/empire/db/expr/join/DBJoinExpr.java @@ -18,16 +18,11 @@ */ package org.apache.empire.db.expr.join; -import java.util.HashSet; -import java.util.Set; - import org.apache.empire.db.DBColumn; import org.apache.empire.db.DBColumnExpr; -import org.apache.empire.db.DBDatabase; import org.apache.empire.db.DBExpr; import org.apache.empire.db.DBJoinType; import org.apache.empire.db.DBRowSet; -import org.apache.empire.db.expr.compare.DBCompareExpr; /** * This class is used for building a join expression of an SQL statement. @@ -37,17 +32,12 @@ import org.apache.empire.db.expr.compare.DBCompareExpr; * <P> * */ -public class DBJoinExpr extends DBExpr +public abstract class DBJoinExpr extends DBExpr { private final static long serialVersionUID = 1L; - protected DBColumnExpr left; - protected DBColumnExpr right; protected DBJoinType type; - // Additional - public DBCompareExpr compExpr = null; - /** * Constructs a new DBJoinExpr object initialize this object with * the left and right column and the data type of the join @@ -57,82 +47,38 @@ public class DBJoinExpr extends DBExpr * @param right right value * @param type data type (JOIN_INNER, JOIN_LEFT or JOIN_RIGHT) */ - public DBJoinExpr(DBColumnExpr left, DBColumnExpr right, DBJoinType type) + protected DBJoinExpr(DBJoinType type) { - this.left = left; - this.right = right; this.type = type; } /** - * Returns the current DBDatabase object. - * - * @return the current DBDatabase object - */ - @Override - public DBDatabase getDatabase() - { - return left.getDatabase(); - } - - /** - * returns the left join expression + * returns the join type for this join */ - public DBColumnExpr getLeft() + public DBJoinType getType() { - return left; + return type; } - + /** - * returns the right join expression + * returns the RowSet on the left of the join */ - public DBColumnExpr getRight() - { - return right; - } - + public abstract DBRowSet getLeftTable(); + /** - * returns the join type for this join + * returns the RowSet on the right of the join */ - public DBJoinType getType() - { - return type; - } + public abstract DBRowSet getRightTable(); /** * returns true if this join is using the given table or view or false otherwise */ - public boolean isJoinOn(DBRowSet rowset) - { - if (rowset==null) - return false; - DBColumn l = (left !=null ? left .getUpdateColumn() : null); - DBColumn r = (right!=null ? right.getUpdateColumn() : null); - DBRowSet rsl = (l!=null ? l.getRowSet() : null); - DBRowSet rsr = (r!=null ? r.getRowSet() : null); - return rowset.equals(rsl) || rowset.equals(rsr); - } + public abstract boolean isJoinOn(DBRowSet rowset); /** * returns true if this join is using the given column or false otherwise */ - public boolean isJoinOn(DBColumn column) - { - if (column==null) - return false; - // Check Update Columns - if (column.equals(left.getUpdateColumn()) || - column.equals(right.getUpdateColumn())) - return true; - if (compExpr!=null) - { // Check expression - HashSet<DBColumn> set = new HashSet<DBColumn>(); - compExpr.addReferencedColumns(set); - return set.contains(column); - } - // not found - return false; - } + public abstract boolean isJoinOn(DBColumn column); /** * Returns the left table name if the data type= JOIN_LEFT and returns @@ -141,126 +87,11 @@ public class DBJoinExpr extends DBExpr * * @return the current DBDatabase object */ - public DBRowSet getOuterTable() - { - switch(type) - { - case LEFT: return right.getUpdateColumn().getRowSet(); - case RIGHT: return left .getUpdateColumn().getRowSet(); - default: return null; // no outer table! - } - } + public abstract DBRowSet getOuterTable(); /** * This function swaps the left and the right statements of the join expression. */ - public void reverse() - { // Swap Type of Join - DBColumnExpr swap = left; - left = right; - right = swap; - type = DBJoinType.reversed(type); // (type * -1); - } - - /** - * Returns any additional constraints to the join - * @return a compare expression containing additional constraints or null - */ - public DBCompareExpr getWhere() - { - return compExpr; - } - - /** - * This function adds an additional constraint to the join. - * - * @param expr the compare expression - */ - public void where(DBCompareExpr expr) - { // Set Compare Expression - compExpr = expr; - } - - /** - * This function adds an additional constraint to the join. - * - * @param c1 the first column - * @param c2 the second column - * - * @return the object itself - */ - public DBJoinExpr and(DBColumnExpr c1, DBColumnExpr c2) - { // Set Compare Expression - if (compExpr==null) - compExpr = c1.is(c2); - else - compExpr = compExpr.and(c1.is(c2)); - return this; - } - - /** - * @see org.apache.empire.db.DBExpr#addReferencedColumns(Set) - */ - @Override - public void addReferencedColumns(Set<DBColumn> list) - { - left.addReferencedColumns(list); - right.addReferencedColumns(list); - // Compare Expression - if (compExpr != null) - compExpr.addReferencedColumns(list); - } - - /** Not allowed, this operation have to be done in the DBCommand object. */ - @Override - public void addSQL(StringBuilder buf, long context) - { - if ((context & CTX_NAME) != 0) - left.getUpdateColumn().getRowSet().addSQL(buf, CTX_DEFAULT | CTX_ALIAS); - if ((context & CTX_VALUE) != 0) - { // Join Type - switch(type) - { - case LEFT: buf.append(" LEFT JOIN ");break; - case INNER: buf.append(" INNER JOIN ");break; - case RIGHT: buf.append(" RIGHT JOIN ");break; - default: buf.append(" JOIN "); // should not come here! - } - right.getUpdateColumn().getRowSet().addSQL(buf, CTX_DEFAULT | CTX_ALIAS); - // compare equal - buf.append(" ON "); - right.addSQL(buf, CTX_DEFAULT); - buf.append(" = "); - left.addSQL(buf, CTX_DEFAULT); - // Compare Expression - if (compExpr != null) - { - buf.append(" AND "); - compExpr.addSQL(buf, CTX_DEFAULT); - } - } - } - - /** - * Compares two DBJoinExpr objects. - * - * @param obj other DBJoinExpr object - * @return true if the other DBJoinExpr object is equal to this object - */ - @Override - public boolean equals(Object obj) - { - if (obj==null || obj.getClass()!=getClass()) - return super.equals(obj); - // object - DBJoinExpr other = (DBJoinExpr) obj; - if (left.equals(other.left) && right.equals(other.right) && type == other.type) - return true; - // reversed - if (left.equals(other.right) && right.equals(other.left) && type == DBJoinType.reversed(other.type)) - return true; - // not equal - return false; - } + public abstract void reverse(); } \ No newline at end of file http://git-wip-us.apache.org/repos/asf/empire-db/blob/e90ecf1f/empire-db/src/main/java/org/apache/empire/db/expr/join/DBJoinExprEx.java ---------------------------------------------------------------------- diff --git a/empire-db/src/main/java/org/apache/empire/db/expr/join/DBJoinExprEx.java b/empire-db/src/main/java/org/apache/empire/db/expr/join/DBJoinExprEx.java deleted file mode 100644 index 639dd47..0000000 --- a/empire-db/src/main/java/org/apache/empire/db/expr/join/DBJoinExprEx.java +++ /dev/null @@ -1,111 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you 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 org.apache.empire.db.expr.join; - -import org.apache.empire.db.DBColumnExpr; -import org.apache.empire.db.DBJoinType; -import org.apache.empire.db.DBQuery; -import org.apache.empire.db.DBRowSet; -import org.apache.empire.db.expr.compare.DBCompareAndOrExpr; -import org.apache.empire.db.expr.compare.DBCompareColExpr; -import org.apache.empire.db.expr.compare.DBCompareExpr; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/** - * This class is used for building a join expression of an SQL statement. - * <P> - * There is no need to explicitly create instances of this class.<BR> - * Instead use @link {@link org.apache.empire.db.DBCommand#join(DBRowSet, DBCompareExpr, DBJoinType)} - * <P> - * - */ -public class DBJoinExprEx extends DBJoinExpr -{ - private final static long serialVersionUID = 1L; - private static final Logger log = LoggerFactory.getLogger(DBJoinExprEx.class); - - protected final DBCompareExpr cmp; - - private static DBColumnExpr findFirstColumn(DBCompareExpr expr) - { - // DBCompareORExpr - while (expr instanceof DBCompareAndOrExpr) - expr = ((DBCompareAndOrExpr)expr).getLeft(); - // Get Colum Expr - if (expr instanceof DBCompareColExpr) - return ((DBCompareColExpr)expr).getColumnExpr(); - // Error - log.error("Unknown class found for building a valid JOIN Expression"); - return null; - } - - private static DBColumnExpr firstRsetColumn(DBRowSet rset) - { - if (rset instanceof DBQuery) - return ((DBQuery)rset).getQueryColumns()[0]; - else - return rset.getColumn(0); - } - - /** - * Constructs a new DBJoinExprEx - * - * @param rset the rowset - * @param cmp the compare expression - * @param joinType the join type - */ - public DBJoinExprEx(DBRowSet rset, DBCompareExpr cmp, DBJoinType joinType) - { - super(firstRsetColumn(rset), findFirstColumn(cmp), joinType); - this.cmp = cmp; - } - - public DBCompareExpr getJoinConstraint() - { - return cmp; - } - - @Override - public void addSQL(StringBuilder buf, long context) - { - if ((context & CTX_NAME) != 0) - left.getUpdateColumn().getRowSet().addSQL(buf, CTX_DEFAULT | CTX_ALIAS); - if ((context & CTX_VALUE) != 0) - { // Join Type - switch(type) - { - case LEFT: buf.append(" LEFT JOIN ");break; - case INNER: buf.append(" INNER JOIN ");break; - case RIGHT: buf.append(" RIGHT JOIN ");break; - default: buf.append(" JOIN "); // should not come here! - } - right.getUpdateColumn().getRowSet().addSQL(buf, CTX_DEFAULT | CTX_ALIAS); - // compare equal - buf.append(" ON "); - cmp.addSQL(buf, CTX_DEFAULT); - // Compare Expression - if (compExpr != null) - { - buf.append(" AND "); - compExpr.addSQL(buf, CTX_DEFAULT); - } - } - } -} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/empire-db/blob/e90ecf1f/empire-db/src/main/java/org/apache/empire/db/oracle/DBCommandOracle.java ---------------------------------------------------------------------- diff --git a/empire-db/src/main/java/org/apache/empire/db/oracle/DBCommandOracle.java b/empire-db/src/main/java/org/apache/empire/db/oracle/DBCommandOracle.java index f6b91cd..01ad81b 100644 --- a/empire-db/src/main/java/org/apache/empire/db/oracle/DBCommandOracle.java +++ b/empire-db/src/main/java/org/apache/empire/db/oracle/DBCommandOracle.java @@ -31,6 +31,7 @@ import org.apache.empire.db.DBIndex; import org.apache.empire.db.DBRowSet; import org.apache.empire.db.DBTable; import org.apache.empire.db.expr.compare.DBCompareExpr; +import org.apache.empire.db.expr.join.DBColumnJoinExpr; import org.apache.empire.db.expr.join.DBJoinExpr; import org.apache.empire.db.expr.set.DBSetExpr; import org.apache.empire.exceptions.InvalidArgumentException; @@ -286,13 +287,15 @@ public class DBCommandOracle extends DBCommand DBRowSet table = set.get(0).getTable(); table.addSQL(buf, CTX_FULLNAME|CTX_ALIAS); // join (only one allowed yet) - DBJoinExpr updateJoin = null; + DBColumnJoinExpr updateJoin = null; for (DBJoinExpr jex : joins) { // The join + if (!(jex instanceof DBColumnJoinExpr)) + continue; if (jex.isJoinOn(table)==false) continue; // found the join - updateJoin = jex; + updateJoin = (DBColumnJoinExpr)jex; break; } if (updateJoin==null) http://git-wip-us.apache.org/repos/asf/empire-db/blob/e90ecf1f/empire-db/src/main/java/org/apache/empire/db/sqlite/DBDatabaseDriverSQLite.java ---------------------------------------------------------------------- diff --git a/empire-db/src/main/java/org/apache/empire/db/sqlite/DBDatabaseDriverSQLite.java b/empire-db/src/main/java/org/apache/empire/db/sqlite/DBDatabaseDriverSQLite.java index 24e345e..3f0bacb 100644 --- a/empire-db/src/main/java/org/apache/empire/db/sqlite/DBDatabaseDriverSQLite.java +++ b/empire-db/src/main/java/org/apache/empire/db/sqlite/DBDatabaseDriverSQLite.java @@ -41,6 +41,7 @@ import org.apache.empire.db.DBDriverFeature; import org.apache.empire.db.DBJoinType; import org.apache.empire.db.DBObject; import org.apache.empire.db.DBSQLScript; +import org.apache.empire.db.expr.join.DBColumnJoinExpr; import org.apache.empire.db.expr.join.DBJoinExpr; import org.apache.empire.exceptions.NotImplementedException; import org.apache.empire.exceptions.UnexpectedReturnValueException; @@ -74,13 +75,13 @@ public class DBDatabaseDriverSQLite extends DBDatabaseDriver } @Override - public DBJoinExpr join(DBColumnExpr left, DBColumnExpr right, DBJoinType joinType) + public DBColumnJoinExpr join(DBColumnExpr left, DBColumnExpr right, DBJoinType joinType) { // http://www.sqlite.org/omitted.html - if (joinType != DBJoinType.LEFT) { throw new NotImplementedException(joinType, left + " join " + right); } - DBJoinExpr join = new DBJoinExpr(left, right, joinType); - join(join); - return join; + if (joinType != DBJoinType.LEFT) { + throw new NotImplementedException(joinType, left + " join " + right); + } + return super.join(left, right, joinType); } @Override @@ -88,7 +89,11 @@ public class DBDatabaseDriverSQLite extends DBDatabaseDriver { for (DBJoinExpr joinExpr : joinExprList) { - if (joinExpr.getType() != DBJoinType.LEFT) { throw new NotImplementedException(joinExpr.getType(), joinExpr.getLeft() + " join " + joinExpr.getLeft()); } + if ((joinExpr instanceof DBColumnJoinExpr) && + (joinExpr.getType() != DBJoinType.LEFT)) { + DBColumnJoinExpr join = (DBColumnJoinExpr)joinExpr; + throw new NotImplementedException(joinExpr.getType(), join.getLeft() + " join " + join.getRight()); + } } /* * Iterator<DBJoinExpr> iterator = joinExprList.iterator(); for
