This is possibly getting a little too jiggy, but I'm having all Depot methods

that return a collection return an XList which extends List and adds the
method:

    public <R> Iterable<R> map (Function<T, R> mapper);

which allows you to do things the following:

    return findAll(CategoryRecord.class,
                   new Where(CategoryRecord.PARENT_ID.eq(parentId))).
            map(CategoryRecord.TO_CATEGORY);

which is sufficiently awesome that I think it merits taking these liberties.
Plus it opens the door to adding other transformations that one might want to
do with a collection just loaded from the database.
This commit is contained in:
Michael Bayne
2009-07-09 20:02:00 +00:00
parent 4c697b06a4
commit 65f4c8dff4
5 changed files with 108 additions and 29 deletions
@@ -264,7 +264,7 @@ public abstract class DepotRepository
*
* @throws DatabaseException if any problem is encountered communicating with the database.
*/
protected <T extends PersistentRecord> List<T> loadAll (
protected <T extends PersistentRecord> XList<T> loadAll (
Class<T> type, Collection<? extends Comparable<?>> primaryKeys)
throws DatabaseException
{
@@ -282,10 +282,10 @@ public abstract class DepotRepository
*
* @throws DatabaseException if any problem is encountered communicating with the database.
*/
protected <T extends PersistentRecord> List<T> loadAll (Collection<Key<T>> keys)
protected <T extends PersistentRecord> XList<T> loadAll (Collection<Key<T>> keys)
throws DatabaseException
{
return (keys.size() == 0) ? Collections.<T>emptyList() :
return (keys.size() == 0) ? new XArrayList<T>() :
_ctx.invoke(new FindAllQuery.WithKeys<T>(_ctx, keys));
}
@@ -294,7 +294,7 @@ public abstract class DepotRepository
*
* @throws DatabaseException if any problem is encountered communicating with the database.
*/
protected <T extends PersistentRecord> List<T> findAll (Class<T> type, QueryClause... clauses)
protected <T extends PersistentRecord> XList<T> findAll (Class<T> type, QueryClause... clauses)
throws DatabaseException
{
return findAll(type, Arrays.asList(clauses));
@@ -313,7 +313,7 @@ public abstract class DepotRepository
*
* @throws DatabaseException if any problem is encountered communicating with the database.
*/
protected <T extends PersistentRecord> List<T> findAll (
protected <T extends PersistentRecord> XList<T> findAll (
Class<T> type, Collection<? extends QueryClause> clauses)
throws DatabaseException
{
@@ -325,7 +325,7 @@ public abstract class DepotRepository
*
* @throws DatabaseException if any problem is encountered communicating with the database.
*/
protected <T extends PersistentRecord> List<T> findAll (
protected <T extends PersistentRecord> XList<T> findAll (
Class<T> type, CacheStrategy strategy, QueryClause... clauses)
throws DatabaseException
{
@@ -337,7 +337,7 @@ public abstract class DepotRepository
*
* @throws DatabaseException if any problem is encountered communicating with the database.
*/
protected <T extends PersistentRecord> List<T> findAll (
protected <T extends PersistentRecord> XList<T> findAll (
Class<T> type, CacheStrategy cache, Collection<? extends QueryClause> clauses)
throws DatabaseException
{
@@ -395,7 +395,7 @@ public abstract class DepotRepository
*
* @throws DatabaseException if any problem is encountered communicating with the database.
*/
protected <T extends PersistentRecord> List<Key<T>> findAllKeys (
protected <T extends PersistentRecord> XList<Key<T>> findAllKeys (
Class<T> type, boolean forUpdate, QueryClause... clause)
throws DatabaseException
{
@@ -413,7 +413,7 @@ public abstract class DepotRepository
*
* @throws DatabaseException if any problem is encountered communicating with the database.
*/
protected <T extends PersistentRecord> List<Key<T>> findAllKeys (
protected <T extends PersistentRecord> XList<Key<T>> findAllKeys (
Class<T> type, boolean forUpdate, Collection<? extends QueryClause> clauses)
throws DatabaseException
{
@@ -0,0 +1,40 @@
//
// $Id$
//
// Depot library - a Java relational persistence library
// Copyright (C) 2006-2009 Michael Bayne and Pär Winzell
//
// This library is free software; you can redistribute it and/or modify it
// under the terms of the GNU Lesser General Public License as published
// by the Free Software Foundation; either version 2.1 of the License, or
// (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
package com.samskivert.depot;
import java.util.ArrayList;
import com.google.common.base.Function;
import com.google.common.collect.Iterables;
/**
* An array list specialization that implements {@link XList}. Depot returns this list from all of
* its methods to make it easy for callers to map the results to runtime records as desired.
*/
public class XArrayList<T> extends ArrayList<T>
implements XList<T>
{
// from interface XList<T>
public <R> Iterable<R> map (Function<T, R> mapper)
{
return Iterables.transform(this, mapper);
}
}
+38
View File
@@ -0,0 +1,38 @@
//
// $Id$
//
// Depot library - a Java relational persistence library
// Copyright (C) 2006-2009 Michael Bayne and Pär Winzell
//
// This library is free software; you can redistribute it and/or modify it
// under the terms of the GNU Lesser General Public License as published
// by the Free Software Foundation; either version 2.1 of the License, or
// (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
package com.samskivert.depot;
import java.util.List;
import com.google.common.base.Function;
/**
* Extends the {@link List} interface with a method {@link #map} that makes it easy to convert the
* contents of the list to an {@link Iterable} of a different type via the application of a {@link
* Function}.
*/
public interface XList<T> extends List<T>
{
/**
* Returns an iterable over a mapping of this list via the specified mapping function.
*/
public <R> Iterable<R> map (Function<T, R> mapper);
}
@@ -21,15 +21,12 @@
package com.samskivert.depot.impl;
import java.util.Collection;
import java.util.List;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import com.google.common.collect.Lists;
import com.samskivert.jdbc.DatabaseLiaison;
import com.samskivert.jdbc.JDBCUtil;
@@ -38,6 +35,8 @@ import com.samskivert.depot.Key;
import com.samskivert.depot.PersistenceContext;
import com.samskivert.depot.PersistentRecord;
import com.samskivert.depot.Stats;
import com.samskivert.depot.XArrayList;
import com.samskivert.depot.XList;
import com.samskivert.depot.clause.QueryClause;
import com.samskivert.depot.clause.SelectClause;
@@ -46,7 +45,7 @@ import static com.samskivert.depot.Log.log;
/**
* Loads all primary keys for the records matching the supplied clause.
*/
public class FindAllKeysQuery<T extends PersistentRecord> extends Query<List<Key<T>>>
public class FindAllKeysQuery<T extends PersistentRecord> extends Query<XList<Key<T>>>
{
public FindAllKeysQuery (PersistenceContext ctx, Class<T> type, boolean forUpdate,
Collection<? extends QueryClause> clauses)
@@ -66,16 +65,16 @@ public class FindAllKeysQuery<T extends PersistentRecord> extends Query<List<Key
}
@Override // from Query
public List<Key<T>> getCachedResult (PersistenceContext ctx)
public XList<Key<T>> getCachedResult (PersistenceContext ctx)
{
return null; // TODO
}
// from Query
public List<Key<T>> invoke (PersistenceContext ctx, Connection conn, DatabaseLiaison liaison)
public XList<Key<T>> invoke (PersistenceContext ctx, Connection conn, DatabaseLiaison liaison)
throws SQLException
{
List<Key<T>> keys = Lists.newArrayList();
XList<Key<T>> keys = new XArrayList<Key<T>>();
PreparedStatement stmt = _builder.prepare(conn);
try {
ResultSet rs = stmt.executeQuery();
@@ -48,6 +48,8 @@ import com.samskivert.depot.PersistenceContext;
import com.samskivert.depot.PersistentRecord;
import com.samskivert.depot.SimpleCacheKey;
import com.samskivert.depot.Stats;
import com.samskivert.depot.XArrayList;
import com.samskivert.depot.XList;
import com.samskivert.depot.clause.FieldOverride;
import com.samskivert.depot.clause.QueryClause;
import com.samskivert.depot.clause.SelectClause;
@@ -59,7 +61,7 @@ import static com.samskivert.depot.Log.log;
* This class implements the functionality required by {@link DepotRepository#findAll}: fetch
* a collection of persistent objects using one of two included strategies.
*/
public abstract class FindAllQuery<T extends PersistentRecord> extends Query<List<T>>
public abstract class FindAllQuery<T extends PersistentRecord> extends Query<XList<T>>
{
/**
* The two-pass collection query implementation. See {@link DepotRepository#findAll} for
@@ -103,7 +105,7 @@ public abstract class FindAllQuery<T extends PersistentRecord> extends Query<Lis
}
@Override // from Query
public List<T> getCachedResult (PersistenceContext ctx)
public XList<T> getCachedResult (PersistenceContext ctx)
{
if (_qkey == null) {
return null;
@@ -118,7 +120,7 @@ public abstract class FindAllQuery<T extends PersistentRecord> extends Query<Lis
}
// from Query
public List<T> invoke (PersistenceContext ctx, Connection conn, DatabaseLiaison liaison)
public XList<T> invoke (PersistenceContext ctx, Connection conn, DatabaseLiaison liaison)
throws SQLException
{
// we want this to remain null if our key set came from the cache
@@ -179,7 +181,7 @@ public abstract class FindAllQuery<T extends PersistentRecord> extends Query<Lis
}
@Override // from Query
public List<T> getCachedResult (PersistenceContext ctx)
public XList<T> getCachedResult (PersistenceContext ctx)
{
// look up what we can from the cache
_fetchKeys = loadFromCache(ctx, _keys, _entities);
@@ -189,7 +191,7 @@ public abstract class FindAllQuery<T extends PersistentRecord> extends Query<Lis
}
// from Query
public List<T> invoke (PersistenceContext ctx, Connection conn, DatabaseLiaison liaison)
public XList<T> invoke (PersistenceContext ctx, Connection conn, DatabaseLiaison liaison)
throws SQLException
{
return loadAndResolve(ctx, conn, _keys, _fetchKeys, _entities, null);
@@ -222,7 +224,7 @@ public abstract class FindAllQuery<T extends PersistentRecord> extends Query<Lis
}
@Override // from Query
public List<T> getCachedResult (PersistenceContext ctx)
public XList<T> getCachedResult (PersistenceContext ctx)
{
if (_qkey != null) {
_cachedQueries++;
@@ -232,10 +234,10 @@ public abstract class FindAllQuery<T extends PersistentRecord> extends Query<Lis
}
// from Query
public List<T> invoke (PersistenceContext ctx, Connection conn, DatabaseLiaison liaison)
public XList<T> invoke (PersistenceContext ctx, Connection conn, DatabaseLiaison liaison)
throws SQLException
{
List<T> result = Lists.newArrayList();
XList<T> result = new XArrayList<T>();
SQLBuilder builder = ctx.getSQLBuilder(DepotTypes.getDepotTypes(ctx, _select));
builder.newQuery(_select);
PreparedStatement stmt = builder.prepare(conn);
@@ -297,9 +299,9 @@ public abstract class FindAllQuery<T extends PersistentRecord> extends Query<Lis
return fetchKeys;
}
protected List<T> resolve (Iterable<Key<T>> allKeys, Map<Key<T>, T> entities)
protected XList<T> resolve (Iterable<Key<T>> allKeys, Map<Key<T>, T> entities)
{
List<T> result = Lists.newArrayList();
XList<T> result = new XArrayList<T>();
for (Key<T> key : allKeys) {
T value = entities.get(key);
if (value != null) {
@@ -309,9 +311,9 @@ public abstract class FindAllQuery<T extends PersistentRecord> extends Query<Lis
return result;
}
protected List<T> loadAndResolve (PersistenceContext ctx, Connection conn,
Iterable<Key<T>> allKeys, Set<Key<T>> fetchKeys,
Map<Key<T>, T> entities, String origStmt)
protected XList<T> loadAndResolve (PersistenceContext ctx, Connection conn,
Iterable<Key<T>> allKeys, Set<Key<T>> fetchKeys,
Map<Key<T>, T> entities, String origStmt)
throws SQLException
{
if (PersistenceContext.CACHE_DEBUG && fetchKeys.size() > 0) {