OPENJPA-805 JPQL iteration 1: add support for Case Expressions

git-svn-id: https://svn.apache.org/repos/asf/openjpa/trunk@725728 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Catalina Wei 2008-12-11 16:16:32 +00:00
parent 2bb40626e6
commit 979a6e373c
9 changed files with 925 additions and 0 deletions

View File

@ -0,0 +1,193 @@
/*
* 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.openjpa.jdbc.kernel.exps;
import java.sql.SQLException;
import org.apache.openjpa.jdbc.meta.JavaSQLTypes;
import org.apache.openjpa.jdbc.sql.Joins;
import org.apache.openjpa.jdbc.sql.Raw;
import org.apache.openjpa.jdbc.sql.Result;
import org.apache.openjpa.jdbc.sql.SQLBuffer;
import org.apache.openjpa.jdbc.sql.Select;
import org.apache.openjpa.kernel.Filters;
import org.apache.openjpa.kernel.exps.ExpressionVisitor;
import org.apache.openjpa.meta.ClassMetaData;
/**
* General case expression.
*
* @author Catalina Wei
*/
public class GeneralCaseExpression
extends AbstractVal {
private final Exp[] _exp;
private final Val _val;
private ClassMetaData _meta = null;
private Class _cast = null;
/**
* Constructor.
*/
public GeneralCaseExpression(Exp[] exp, Val val) {
_exp = exp;
_val = val;
}
public Exp[] getExp() {
return _exp;
}
public Val getVal() {
return _val;
}
public Class getType() {
if (_cast != null)
return _cast;
Class type = _val.getType();
for (int i = 0; i < _exp.length; i++)
type = Filters.promote(type,
((WhenCondition) _exp[i]).getVal().getType());
if (type == Raw.class)
return String.class;
return type;
}
public ExpState initialize(Select sel, ExpContext ctx, int flags) {
ExpState[] states = new ExpState[_exp.length+1];
Joins joins = null;
int i = 0;
for (; i < _exp.length; i++) {
states[i] = _exp[i].initialize(sel, ctx, null);
if (joins == null)
joins = states[i].joins;
else
joins = sel.and(joins, states[i].joins);
}
states[i] = _val.initialize(sel, ctx, 0);
if (joins == null)
joins = states[i].joins;
else
joins = sel.and(joins, states[i].joins);
return new GeneralCaseExpState(joins, states);
}
private static class GeneralCaseExpState
extends ExpState {
public ExpState[] states;
public GeneralCaseExpState(Joins joins, ExpState[] states) {
super(joins);
this.states = states;
}
}
public void appendTo(Select sel, ExpContext ctx, ExpState state,
SQLBuffer buf, int index) {
GeneralCaseExpState cstate = (GeneralCaseExpState) state;
buf.append(" CASE ");
int i = 0;
for (; i < _exp.length; i++)
_exp[i].appendTo(sel, ctx, cstate.states[i], buf);
buf.append(" ELSE ");
_val.appendTo(sel, ctx, cstate.states[i], buf, 0);
buf.append(" END ");
}
public void selectColumns(Select sel, ExpContext ctx, ExpState state,
boolean pks) {
GeneralCaseExpState cstate = (GeneralCaseExpState) state;
int i = 0;
for (; i < _exp.length; i++)
_exp[i].selectColumns(sel, ctx, cstate.states[i], pks);
_val.selectColumns(sel, ctx, cstate.states[i], pks);
}
public void acceptVisit(ExpressionVisitor visitor) {
visitor.enter(this);
for (int i = 0; i < _exp.length; i++)
_exp[i].acceptVisit(visitor);
_val.acceptVisit(visitor);
visitor.exit(this);
}
public int getId() {
return Val.SIMPLECASE_VAL;
}
public void calculateValue(Select sel, ExpContext ctx, ExpState state,
Val other, ExpState otherState) {
GeneralCaseExpState gstate = (GeneralCaseExpState) state;
for (int i = 0; i < _exp.length; i++) {
BinaryOpExpState bstate = (BinaryOpExpState) gstate.states[i];
((WhenCondition) _exp[i]).getVal().calculateValue(sel, ctx,
bstate.state2, null, null);
}
_val.calculateValue(sel, ctx, gstate.states[_exp.length], null, null);
}
public void groupBy(Select sel, ExpContext ctx, ExpState state) {
sel.groupBy(newSQLBuffer(sel, ctx, state));
}
public int length(Select sel, ExpContext ctx, ExpState state) {
return 1;
}
private SQLBuffer newSQLBuffer(Select sel, ExpContext ctx, ExpState state) {
calculateValue(sel, ctx, state, null, null);
SQLBuffer buf = new SQLBuffer(ctx.store.getDBDictionary());
appendTo(sel, ctx, state, buf, 0);
return buf;
}
public Object load(ExpContext ctx, ExpState state, Result res)
throws SQLException {
return Filters.convert(res.getObject(this,
JavaSQLTypes.JDBC_DEFAULT, null), getType());
}
public void orderBy(Select sel, ExpContext ctx, ExpState state,
boolean asc) {
sel.orderBy(newSQLBuffer(sel, ctx, state), asc, false, getSelectAs());
}
public void select(Select sel, ExpContext ctx, ExpState state, boolean pks){
sel.select(newSQLBuffer(sel, ctx, state), this);
}
public ClassMetaData getMetaData() {
return _meta;
}
public void setImplicitType(Class type) {
_cast = type;
}
public void setMetaData(ClassMetaData meta) {
_meta = meta;
}
}

View File

@ -23,6 +23,7 @@ import java.io.Serializable;
import org.apache.openjpa.jdbc.meta.ClassMapping;
import org.apache.openjpa.jdbc.meta.JavaSQLTypes;
import org.apache.openjpa.jdbc.sql.DBDictionary;
import org.apache.openjpa.jdbc.sql.Raw;
import org.apache.openjpa.kernel.exps.AggregateListener;
import org.apache.openjpa.kernel.exps.Arguments;
import org.apache.openjpa.kernel.exps.Expression;
@ -400,4 +401,50 @@ public class JDBCExpressionFactory
return new GetMapValue((Val) map, (Val) arg,
"gmv" + _getMapValueAlias++);
}
public Value simpleCaseExpression(Value caseOperand, Expression[] exp,
Value val1) {
Exp[] exps = new Exp[exp.length];
for (int i = 0; i < exp.length; i++)
exps[i] = (Exp) exp[i];
if (val1 instanceof Lit) {
Lit val = (Lit) val1;
StringBuffer value = new StringBuffer(val.getValue().toString());
if (val.getParseType() == Literal.TYPE_SQ_STRING)
value.insert(0, "'").append("'");
val.setValue(new Raw(value.toString()));
}
return new SimpleCaseExpression((Val) caseOperand, exps,
(Val) val1);
}
public Value generalCaseExpression(Expression[] exp,
Value val) {
Exp[] exps = new Exp[exp.length];
for (int i = 0; i < exp.length; i++)
exps[i] = (Exp) exp[i];
return new GeneralCaseExpression(exps, (Val) val);
}
public Expression whenCondition(Expression exp, Value val) {
return new WhenCondition((Exp) exp, (Val) val);
}
public Expression whenScalar(Value val1, Value val2) {
if (val1 instanceof Lit) {
Lit val = (Lit) val1;
StringBuffer value = new StringBuffer(val.getValue().toString());
if (val.getParseType() == Literal.TYPE_SQ_STRING)
value.insert(0, "'").append("'");
val.setValue(new Raw(value.toString()));
}
if (val2 instanceof Lit) {
Lit val = (Lit) val2;
StringBuffer value = new StringBuffer(val.getValue().toString());
if (val.getParseType() == Literal.TYPE_SQ_STRING)
value.insert(0, "'").append("'");
val.setValue(new Raw(value.toString()));
}
return new WhenScalar((Val) val1, (Val) val2);
}
}

View File

@ -0,0 +1,228 @@
/*
* 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.openjpa.jdbc.kernel.exps;
import java.sql.SQLException;
import org.apache.openjpa.jdbc.meta.JavaSQLTypes;
import org.apache.openjpa.jdbc.sql.DBDictionary;
import org.apache.openjpa.jdbc.sql.Joins;
import org.apache.openjpa.jdbc.sql.Raw;
import org.apache.openjpa.jdbc.sql.Result;
import org.apache.openjpa.jdbc.sql.SQLBuffer;
import org.apache.openjpa.jdbc.sql.Select;
import org.apache.openjpa.kernel.Filters;
import org.apache.openjpa.kernel.exps.ExpressionVisitor;
import org.apache.openjpa.meta.ClassMetaData;
/**
* Simple case expression.
*
* @author Catalina Wei
*/
public class SimpleCaseExpression
extends AbstractVal {
private final Val _caseOperand;
private final Exp[] _exp;
private final Val _val;
private ClassMetaData _meta = null;
private Class _cast = null;
/**
* Constructor.
*/
public SimpleCaseExpression(Val caseOperand, Exp[] exp, Val val) {
_caseOperand = caseOperand;
_exp = exp;
_val = val;
}
public Val getCaseOperand() {
return _caseOperand;
}
public Exp[] getExp() {
return _exp;
}
public Val getVal() {
return _val;
}
public Class getType() {
if (_cast != null)
return _cast;
Class type = _val.getType();
for (int i = 0; i < _exp.length; i++)
type = Filters.promote(type,
((WhenScalar) _exp[i]).getVal2().getType());
if (type == Raw.class)
return String.class;
return type;
}
public ExpState initialize(Select sel, ExpContext ctx, int flags) {
ExpState[] states = new ExpState[_exp.length+2];
Joins joins = null;
states[0] = _caseOperand.initialize(sel, ctx, 0);
if (joins == null)
joins = states[0].joins;
else
joins = sel.and(joins, states[0].joins);
for (int i = 0; i < _exp.length; i++) {
states[i+1] = _exp[i].initialize(sel, ctx, null);
if (joins == null)
joins = states[i+1].joins;
else
joins = sel.and(joins, states[i+1].joins);
}
states[_exp.length+1] = _val.initialize(sel, ctx, 0);
if (joins == null)
joins = states[_exp.length+1].joins;
else
joins = sel.and(joins, states[_exp.length+1].joins);
return new SimpleCaseExpState(joins, states);
}
private static class SimpleCaseExpState
extends ExpState {
public ExpState[] states;
public SimpleCaseExpState(Joins joins, ExpState[] states) {
super(joins);
this.states = states;
}
}
public void appendTo(Select sel, ExpContext ctx, ExpState state,
SQLBuffer buf, int index) {
SimpleCaseExpState cstate = (SimpleCaseExpState) state;
DBDictionary dict = ctx.store.getDBDictionary();
buf.append(" CASE ");
for (int i = 0; i < _exp.length; i++) {
// if back-end does not support simple case expression,
// pushdown sql as general case expression.
if (!dict.supportsSimpleCaseExpression)
buf.append(" WHEN ");
if (i == 0 || !dict.supportsSimpleCaseExpression)
_caseOperand.appendTo(sel, ctx, cstate.states[0], buf, 0);
if (!dict.supportsSimpleCaseExpression)
buf.append(" = ");
else
buf.append(" WHEN ");
_exp[i].appendTo(sel, ctx, cstate.states[i+1], buf);
}
buf.append(" ELSE ");
_val.appendTo(sel, ctx, cstate.states[_exp.length+1], buf, 0);
buf.append(" END ");
}
public void selectColumns(Select sel, ExpContext ctx, ExpState state,
boolean pks) {
SimpleCaseExpState cstate = (SimpleCaseExpState) state;
_caseOperand.selectColumns(sel, ctx, cstate.states[0], pks);
for (int i = 0; i < _exp.length; i++)
_exp[i].selectColumns(sel, ctx, cstate.states[i+1], pks);
_val.selectColumns(sel, ctx, cstate.states[_exp.length+1], pks);
}
public void acceptVisit(ExpressionVisitor visitor) {
visitor.enter(this);
_caseOperand.acceptVisit(visitor);
for (int i = 0; i < _exp.length; i++)
_exp[i].acceptVisit(visitor);
_val.acceptVisit(visitor);
visitor.exit(this);
}
public int getId() {
return Val.SIMPLECASE_VAL;
}
public void calculateValue(Select sel, ExpContext ctx, ExpState state,
Val other, ExpState otherState) {
SimpleCaseExpState cstate = (SimpleCaseExpState) state;
_caseOperand.calculateValue(sel, ctx, cstate.states[0], other,
otherState);
for (int i = 0; i < _exp.length; i++) {
BinaryOpExpState bstate = (BinaryOpExpState) cstate.states[i+1];
((WhenScalar) _exp[i]).getVal1().calculateValue(sel, ctx,
bstate.state1, null, null);
((WhenScalar) _exp[i]).getVal2().calculateValue(sel, ctx,
bstate.state2, null, null);
}
_val.calculateValue(sel, ctx, cstate.states[_exp.length+1], other,
otherState);
}
public void groupBy(Select sel, ExpContext ctx, ExpState state) {
sel.groupBy(newSQLBuffer(sel, ctx, state));
}
public int length(Select sel, ExpContext ctx, ExpState state) {
return 1;
}
private SQLBuffer newSQLBuffer(Select sel, ExpContext ctx, ExpState state) {
calculateValue(sel, ctx, state, null, null);
SQLBuffer buf = new SQLBuffer(ctx.store.getDBDictionary());
appendTo(sel, ctx, state, buf, 0);
return buf;
}
public Object load(ExpContext ctx, ExpState state, Result res)
throws SQLException {
return Filters.convert(res.getObject(this,
JavaSQLTypes.JDBC_DEFAULT, null), getType());
}
public void orderBy(Select sel, ExpContext ctx, ExpState state,
boolean asc) {
sel.orderBy(newSQLBuffer(sel, ctx, state), asc, false, getSelectAs());
}
public void select(Select sel, ExpContext ctx, ExpState state, boolean pks){
sel.select(newSQLBuffer(sel, ctx, state), this);
}
public ClassMetaData getMetaData() {
return _meta;
}
public void setImplicitType(Class type) {
_cast = type;
}
public void setMetaData(ClassMetaData meta) {
_meta = meta;
}
}

View File

@ -0,0 +1,94 @@
/*
* 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.openjpa.jdbc.kernel.exps;
import java.util.Map;
import org.apache.openjpa.jdbc.sql.SQLBuffer;
import org.apache.openjpa.jdbc.sql.Select;
import org.apache.openjpa.kernel.exps.ExpressionVisitor;
/**
* Value produced by a when_clause of a case expression.
*
* @author Catalina Wei
*/
public class WhenCondition
implements Exp {
private final Exp _exp;
private final Val _val;
/**
* Constructor.
*/
public WhenCondition(Exp exp, Val val) {
_exp = exp;
_val = val;
}
public Exp getExp() {
return _exp;
}
public Val getVal() {
return _val;
}
public Class getType() {
return _val.getType();
}
public ExpState initialize(Select sel, ExpContext ctx, Map contains) {
ExpState s1 = _exp.initialize(sel, ctx, contains);
ExpState s2 = _val.initialize(sel, ctx, 0);
return new BinaryOpExpState(sel.and(s1.joins, s2.joins), s1, s2);
}
public void appendTo(Select sel, ExpContext ctx, ExpState state,
SQLBuffer buf) {
BinaryOpExpState bstate = (BinaryOpExpState) state;
buf.append(" WHEN ");
_exp.appendTo(sel, ctx, bstate.state1, buf);
buf.append(" THEN ");
_val.appendTo(sel, ctx, bstate.state2, buf, 0);
}
public void selectColumns(Select sel, ExpContext ctx, ExpState state,
boolean pks) {
BinaryOpExpState bstate = (BinaryOpExpState) state;
_exp.selectColumns(sel, ctx, bstate.state1, pks);
_val.selectColumns(sel, ctx, bstate.state2, pks);
}
public void acceptVisit(ExpressionVisitor visitor) {
visitor.enter(this);
_exp.acceptVisit(visitor);
_val.acceptVisit(visitor);
visitor.exit(this);
}
public int getId() {
return Val.WHENCONDITION_VAL;
}
}

View File

@ -0,0 +1,90 @@
/*
* 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.openjpa.jdbc.kernel.exps;
import java.util.Map;
import org.apache.openjpa.jdbc.sql.SQLBuffer;
import org.apache.openjpa.jdbc.sql.Select;
import org.apache.openjpa.kernel.exps.ExpressionVisitor;
/**
* Value produced by a when_clause of a case expression.
*
* @author Catalina Wei
*/
public class WhenScalar
implements Exp {
private final Val _val1;
private final Val _val2;
/**
* Constructor.
*/
public WhenScalar(Val val1, Val val2) {
_val1 = val1;
_val2 = val2;
}
public Val getVal1() {
return _val1;
}
public Val getVal2() {
return _val2;
}
public Class getType() {
return _val2.getType();
}
public ExpState initialize(Select sel, ExpContext ctx, Map contains) {
ExpState s1 = _val1.initialize(sel, ctx, 0);
ExpState s2 = _val2.initialize(sel, ctx, 0);
return new BinaryOpExpState(sel.and(s1.joins, s2.joins), s1, s2);
}
public void appendTo(Select sel, ExpContext ctx, ExpState state,
SQLBuffer buf) {
BinaryOpExpState bstate = (BinaryOpExpState) state;
_val1.appendTo(sel, ctx, bstate.state1, buf, 0);
buf.append(" THEN ");
_val2.appendTo(sel, ctx, bstate.state2, buf, 0);
}
public void selectColumns(Select sel, ExpContext ctx, ExpState state,
boolean pks) {
BinaryOpExpState bstate = (BinaryOpExpState) state;
_val1.selectColumns(sel, ctx, bstate.state1, pks);
_val2.selectColumns(sel, ctx, bstate.state2, pks);
}
public void acceptVisit(ExpressionVisitor visitor) {
visitor.enter(this);
_val1.acceptVisit(visitor);
_val2.acceptVisit(visitor);
visitor.exit(this);
}
public int getId() {
return Val.WHENSCALAR_VAL;
}
}

View File

@ -407,4 +407,25 @@ public interface ExpressionFactory {
* Return the object id of the given value.
*/
public Value getObjectId (Value val);
/**
* Return a simple case expression
*/
public Value simpleCaseExpression(Value caseOperand,
Expression[] exp, Value val);
/**
* Return a general case expression
*/
public Value generalCaseExpression(Expression[] exp, Value val);
/**
* Return a when condidional clause
*/
public Expression whenCondition(Expression exp, Value val);
/**
* Return a when scalar_expression clause
*/
public Expression whenScalar(Value val1, Value val2);
}

View File

@ -725,4 +725,24 @@ public class InMemoryExpressionFactory
}
}
}
public Value generalCaseExpression(Expression[] exp, Value val) {
// TODO Auto-generated method stub
return null;
}
public Value simpleCaseExpression(Value caseOperand, Expression[] exp, Value val) {
// TODO Auto-generated method stub
return null;
}
public Expression whenCondition(Expression exp, Value val) {
// TODO Auto-generated method stub
return null;
}
public Expression whenScalar(Value val1, Value val2) {
// TODO Auto-generated method stub
return null;
}
}

View File

@ -745,6 +745,27 @@ public class JPQLExpressionBuilder
case JJTSCALAREXPRESSION:
return eval(onlyChild(node));
case JJTTYPE:
return eval(onlyChild(node));
case JJTCLASSNAME:
return getPathOrConstant(node);
case JJTCASE:
return eval(onlyChild(node));
case JJTSCASE:
return getSimpleCaseExpression(node);
case JJTGCASE:
return getGeneralCaseExpression(node);
case JJTWHEN:
return getWhenCondition(node);
case JJTWHENSCALAR:
return getWhenScalar(node);
case JJTWHERE: // top-level WHERE clause
return getExpression(onlyChild(node));
@ -1439,6 +1460,48 @@ public class JPQLExpressionBuilder
return (Expression) exp;
}
/**
* Returns a Simple Case Expression for the given node by eval'ing it.
*/
private Value getSimpleCaseExpression(JPQLNode node) {
Object caseOperand = eval(node.getChild(0));
int nChild = node.getChildCount();
Object val = eval(lastChild(node));
Object exp[] = new Expression[nChild - 2];
for (int i = 1; i < nChild - 1; i++)
exp[i-1] = eval(node.children[i]);
return factory.simpleCaseExpression((Value) caseOperand,
(Expression[]) exp, (Value) val);
}
/**
* Returns a General Case Expression for the given node by eval'ing it.
*/
private Value getGeneralCaseExpression(JPQLNode node) {
int nChild = node.getChildCount();
Object val = eval(lastChild(node));
Object exp[] = new Expression[nChild - 1];
for (int i = 0; i < nChild - 1; i++)
exp[i] = (Expression) eval(node.children[i]);
return factory.generalCaseExpression((Expression[]) exp, (Value) val);
}
private Expression getWhenCondition(JPQLNode node) {
Object exp = eval(firstChild(node));
Object val = eval(secondChild(node));
return factory.whenCondition((Expression) exp, (Value) val);
}
private Expression getWhenScalar(JPQLNode node) {
Object val1 = eval(firstChild(node));
Object val2 = eval(secondChild(node));
return factory.whenScalar((Value) val1, (Value) val2);
}
private Value getValue(JPQLNode node) {
return getValue(node, VAR_PATH);
}

View File

@ -0,0 +1,169 @@
/*
* 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.openjpa.persistence.jpql.expressions;
import java.util.List;
import javax.persistence.EntityManager;
import org.apache.openjpa.persistence.common.apps.*;
import org.apache.openjpa.persistence.common.utils.AbstractTestCase;
public class TestJPQLScalarExpressions extends AbstractTestCase {
private int userid1, userid2, userid3, userid4, userid5, userid6;
public TestJPQLScalarExpressions(String name) {
super(name, "jpqlclausescactusapp");
}
public void setUp() {
deleteAll(CompUser.class);
EntityManager em = currentEntityManager();
startTx(em);
Address[] add = new Address[]{
new Address("43 Sansome", "SF", "United-Kingdom", "94104"),
new Address("24 Mink", "ANTIOCH", "USA", "94513"),
new Address("23 Ogbete", "CoalCamp", "NIGERIA", "00000"),
new Address("10 Wilshire", "Worcester", "CANADA", "80080"),
new Address("23 Bellflower", "Ogui", null, "02000"),
new Address("22 Montgomery", "SF", null, "50054") };
CompUser user1 = createUser("Seetha", "MAC", add[0], 36, true);
CompUser user2 = createUser("Shannon ", "PC", add[1], 36, false);
CompUser user3 = createUser("Ugo", "PC", add[2], 19, true);
CompUser user4 = createUser("_Jacob", "LINUX", add[3], 10, true);
CompUser user5 = createUser("Famzy", "UNIX", add[4], 29, false);
CompUser user6 = createUser("Shade", "UNIX", add[5], 23, false);
em.persist(user1);
userid1 = user1.getUserid();
em.persist(user2);
userid2 = user2.getUserid();
em.persist(user3);
userid3 = user3.getUserid();
em.persist(user4);
userid4 = user4.getUserid();
em.persist(user5);
userid5 = user5.getUserid();
em.persist(user6);
userid6 = user6.getUserid();
endTx(em);
endEm(em);
}
public void testSimpleCaseExpressions() {
EntityManager em = currentEntityManager();
CompUser user = em.find(CompUser.class, userid1);
assertNotNull("user is null", user);
assertEquals("the name is not seetha", "Seetha", user.getName());
String query = "SELECT e.name, e.age+1 as cage, " +
"CASE e.address.country WHEN 'USA'" +
" THEN 'us' " +
" ELSE 'non-us' END as d2," +
" e.address.country " +
" FROM CompUser e ORDER BY cage, d2 DESC";
List rs = em.createQuery(query).getResultList();
Object[] result = (Object[]) rs.get(rs.size()-1);
assertEquals("the name is not seetha", "Seetha", result[0]);
String query2 = "SELECT e.name, e.age+1 as cage, " +
"CASE e.address.country WHEN 'USA'" +
" THEN 'United-States' " +
" ELSE e.address.country END as d2," +
" e.address.country " +
" FROM CompUser e ORDER BY cage, d2 DESC";
List rs2 = em.createQuery(query2).getResultList();
Object[] result2 = (Object[]) rs2.get(rs2.size()-1);
assertEquals("the name is not seetha", "Seetha", result2[0]);
// TODO: needs entity-type-expression
String query3 = "SELECT e.name, " +
" CASE TYPE(e) WHEN FemaleUser THEN 'Female' " +
" ELSE 'Male' " +
" END " +
" FROM CompUser e";
endEm(em);
}
public void testGeneralCaseExpressions() {
EntityManager em = currentEntityManager();
startTx(em);
CompUser user = em.find(CompUser.class, userid1);
assertNotNull("user is null", user);
assertEquals("the name is not seetha", "Seetha", user.getName());
String query = "SELECT e.name, e.age, " +
" CASE WHEN e.age > 30 THEN e.age - 1 " +
" WHEN e.age < 15 THEN e.age + 1 " +
" ELSE e.age + 0 " +
" END AS cage " +
" FROM CompUser e ORDER BY cage";
List rs = em.createQuery(query).getResultList();
String update = "UPDATE CompUser e SET e.age = " +
"CASE WHEN e.age > 30 THEN e.age - 1 " +
"WHEN e.age < 15 THEN e.age + 1 " +
"ELSE e.age + 0 " +
"END";
int result = em.createQuery(update).executeUpdate();
assertEquals("the result is not 6", 6, result);
endTx(em);
endEm(em);
}
public void testMathFuncOrderByAlias() {
EntityManager em = currentEntityManager();
String query = "SELECT e.age * 2 as cAge FROM CompUser e ORDER BY cAge";
List result = em.createQuery(query).getResultList();
assertNotNull(result);
assertEquals(6, result.size());
endEm(em);
}
public CompUser createUser(String name, String cName, Address add, int age,
boolean isMale) {
CompUser user = null;
if (isMale) {
user = new MaleUser();
user.setName(name);
user.setComputerName(cName);
user.setAddress(add);
user.setAge(age);
} else {
user = new FemaleUser();
user.setName(name);
user.setComputerName(cName);
user.setAddress(add);
user.setAge(age);
}
return user;
}
}