Added a mechanism for selecting results into a simple result class that relies

only on a matching public constructor. This version is not type-safe, but I'll
also be adding an additional mechanism to do selections like this that uses a
type-safe builder approach, which comes at the cost of a healthy dose of
boilerplate code.
This commit is contained in:
Michael Bayne
2010-12-10 21:12:57 +00:00
parent dd6dec7b9a
commit 4b59373559
3 changed files with 63 additions and 5 deletions
@@ -465,6 +465,15 @@ public class Query<T extends PersistentRecord>
getClauses()));
}
/**
* Returns just the supplied expression from the rows matching the query.
*/
public <V> List<V> selectInto (Class<V> resultClass, SQLExpression<?>... selexps)
{
Projector<T,V> proj = Projector.create(_pclass, resultClass, selexps);
return _ctx.invoke(new FindAllQuery.Projection<T,V>(_ctx, proj, getClauses()));
}
/**
* Deletes the records that match the configured query clauses. Note that only the where
* clauses are used to evaluate a deletion. Attempts to use other clauses will result in
@@ -20,6 +20,10 @@
package com.samskivert.depot.impl;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import com.samskivert.depot.DatabaseException;
import com.samskivert.depot.PersistentRecord;
import com.samskivert.depot.expression.SQLExpression;
import com.samskivert.depot.util.*; // TupleN
@@ -33,7 +37,7 @@ public abstract class Projector<T extends PersistentRecord,R>
public static <T extends PersistentRecord, V> Projector<T,V> create (
Class<T> ptype, SQLExpression<V> column)
{
return new Projector<T, V>(ptype, new SQLExpression[] { column }) {
return new Projector<T, V>(ptype, new SQLExpression<?>[] { column }) {
public V createObject (Object[] results) {
@SuppressWarnings("unchecked") V result = (V)results[0];
return result;
@@ -44,7 +48,7 @@ public abstract class Projector<T extends PersistentRecord,R>
public static <T extends PersistentRecord, V1, V2> Projector<T,Tuple2<V1,V2>> create (
Class<T> ptype, SQLExpression<V1> col1, SQLExpression<V2> col2)
{
return new Projector<T, Tuple2<V1,V2>>(ptype, new SQLExpression[] { col1, col2 }) {
return new Projector<T, Tuple2<V1,V2>>(ptype, new SQLExpression<?>[] { col1, col2 }) {
public Tuple2<V1,V2> createObject (Object[] results) {
@SuppressWarnings("unchecked") V1 r1 = (V1)results[0];
@SuppressWarnings("unchecked") V2 r2 = (V2)results[1];
@@ -56,7 +60,8 @@ public abstract class Projector<T extends PersistentRecord,R>
public static <T extends PersistentRecord, V1, V2, V3> Projector<T,Tuple3<V1,V2,V3>> create (
Class<T> ptype, SQLExpression<V1> col1, SQLExpression<V2> col2, SQLExpression<V3> col3)
{
return new Projector<T, Tuple3<V1,V2,V3>>(ptype, new SQLExpression[] { col1, col2, col3 }) {
return new Projector<T, Tuple3<V1,V2,V3>>(
ptype, new SQLExpression<?>[] { col1, col2, col3 }) {
public Tuple3<V1,V2,V3> createObject (Object[] results) {
@SuppressWarnings("unchecked") V1 r1 = (V1)results[0];
@SuppressWarnings("unchecked") V2 r2 = (V2)results[1];
@@ -72,7 +77,7 @@ public abstract class Projector<T extends PersistentRecord,R>
SQLExpression<V4> col4)
{
return new Projector<T, Tuple4<V1,V2,V3,V4>>(
ptype, new SQLExpression[] { col1, col2, col3, col4 }) {
ptype, new SQLExpression<?>[] { col1, col2, col3, col4 }) {
public Tuple4<V1,V2,V3,V4> createObject (Object[] results) {
@SuppressWarnings("unchecked") V1 r1 = (V1)results[0];
@SuppressWarnings("unchecked") V2 r2 = (V2)results[1];
@@ -89,7 +94,7 @@ public abstract class Projector<T extends PersistentRecord,R>
SQLExpression<V4> col4, SQLExpression<V5> col5)
{
return new Projector<T, Tuple5<V1,V2,V3,V4,V5>>(
ptype, new SQLExpression[] { col1, col2, col3, col4, col5 }) {
ptype, new SQLExpression<?>[] { col1, col2, col3, col4, col5 }) {
public Tuple5<V1,V2,V3,V4,V5> createObject (Object[] results) {
@SuppressWarnings("unchecked") V1 r1 = (V1)results[0];
@SuppressWarnings("unchecked") V2 r2 = (V2)results[1];
@@ -101,6 +106,31 @@ public abstract class Projector<T extends PersistentRecord,R>
};
}
public static <T extends PersistentRecord, V> Projector<T,V> create (
Class<T> ptype, final Class<V> resultType, SQLExpression<?>... selexps)
{
return new Projector<T, V>(ptype, selexps) {
public V createObject (Object[] results) {
try {
return _ctor.newInstance(results);
} catch (InstantiationException e) {
throw new DatabaseException("Invalid constructor supplied for projection", e);
} catch (IllegalAccessException e) {
throw new DatabaseException("Invalid constructor supplied for projection", e);
} catch (InvocationTargetException e) {
Throwable t = e.getCause();
if (t instanceof RuntimeException) {
throw (RuntimeException)t;
} else {
throw new DatabaseException("Error constructing result object", t);
}
}
}
@SuppressWarnings("unchecked")
protected Constructor<V> _ctor = (Constructor<V>)resultType.getConstructors()[0];
};
}
public final Class<T> ptype;
public final SQLExpression<?>[] selexps;