On 02/06/2007, at 11:29 AM, Michael Gentry wrote:
Also, the query would most likely
need to be SQLTemplate-compatible, not an Expression or Query
(although maybe this can be done -- I'll have to explore). Keep in
mind this is going outside of the ORM arena to a degree. A row count
isn't being mapped to Java classes with relationships/attributes/etc.
You can't persist it back to the DB. :-)
How about something like this? (Completely untested but looks right)
ObjectContext oc; // assume exists
int count = new StatsQuery.Count(SomeClass.class[,
anExpression]).intResult(oc);
int max = new StatsQuery.Max(SomeClass.class, "age"[,
anExpression]).intResult(oc);
int min = new StatsQuery.Min(SomeClass.class, "age"[,
anExpression]).intResult(oc);
int sum = new StatsQuery.Sum(SomeClass.class, "age"[,
anExpression]).intResult(oc);
with regards,
--
Lachlan Deck
import java.util.Map;
import org.apache.cayenne.CayenneRuntimeException;
import org.apache.cayenne.ObjectContext;
import org.apache.cayenne.exp.Expression;
import org.apache.cayenne.map.DbEntity;
import org.apache.cayenne.map.EntityResolver;
import org.apache.cayenne.map.ObjAttribute;
import org.apache.cayenne.map.ObjEntity;
import org.apache.cayenne.query.IndirectQuery;
import org.apache.cayenne.query.Query;
import org.apache.cayenne.query.SQLTemplate;
/**
* @author ldeck
*/
public abstract class StatsQuery extends IndirectQuery {
protected Class objClass;
protected Expression expression;
protected String statsType;
protected String attributeName;
protected StatsQuery(Class objClass, Expression e, String statsType) {
this(objClass, e, statsType, "*");
}
protected StatsQuery(Class objClass, Expression e, String statsType,
String attributeName) {
this.objClass = objClass;
this.expression = e;
this.statsType = statsType;
this.attributeName = attributeName;
}
protected Query createReplacementQuery(EntityResolver resolver) {
ObjEntity objEntity = resolver.lookupObjEntity(this.objClass);
if (objEntity == null)
throw new CayenneRuntimeException("No ObjEntity is mapped for java
class: " + this.objClass.getName());
DbEntity dbEntity = objEntity.getDbEntity();
if (dbEntity == null)
throw new CayenneRuntimeException("No DbEntity is mapped for java
class: " + this.objClass.getName());
String dbAttributeName = ((ObjAttribute) objEntity.getAttribute
(this.attributeName)).getDbAttribute().getName();
StringBuffer sql = new StringBuffer().append("SELECT #result('" +
this.statsType + "(" + dbAttributeName + ")' 'int' 'C') FROM " +
dbEntity.getName());
// TODO: (lachlan) determine if expression needs translating to
dbAttribute equivalent keys
if (this.expression != null)
sql.append(" WHERE " + objEntity.translateToDbPath
(this.expression).toString());
SQLTemplate replacement = new SQLTemplate(dbEntity,
sql.toString());
replacement.setFetchingDataRows(true);
return replacement;
}
public int intResult(ObjectContext oc) {
return queryResult(oc).intValue();
}
public Number queryResult(ObjectContext oc) {
Map row = (Map) oc.performQuery(this).get(0);
return (Number) row.get("C");
}
//-------------------------------------------------------
// Statistical helpers
//-------------------------------------------------------
public static class Count extends StatsQuery {
public Count(Class objClass) {
this(objClass, null);
}
public Count(Class objClass, Expression exp) {
super(objClass, exp, "count");
}
}
public static class Max extends StatsQuery {
public Max(Class objClass, String attributeName) {
this(objClass, null, attributeName);
}
public Max(Class objClass, String attributeName, Expression
exp) {
super(objClass, exp, "max", attributeName);
}
}
public static class Min extends StatsQuery {
public Min(Class objClass, String attributeName) {
this(objClass, null, attributeName);
}
public Min(Class objClass, String attributeName, Expression
exp) {
super(objClass, exp, "min", attributeName);
}
}
public static class Sum extends StatsQuery {
public Sum(Class objClass, String attributeName) {
this(objClass, null, attributeName);
}
public Sum(Class objClass, String attributeName, Expression
exp) {
super(objClass, exp, "sum", attributeName);
}
}
}