diff --git a/src/java/com/samskivert/depot/DepotRepository.java b/src/java/com/samskivert/depot/DepotRepository.java index a3261a1..484e7ea 100644 --- a/src/java/com/samskivert/depot/DepotRepository.java +++ b/src/java/com/samskivert/depot/DepotRepository.java @@ -309,68 +309,10 @@ public abstract class DepotRepository * the latest data. */ protected List> findAllKeys ( - final Class type, boolean forUpdate, Collection clauses) + Class type, boolean forUpdate, Collection clauses) throws DatabaseException { - final List> keys = Lists.newArrayList(); - final DepotMarshaller marsh = _ctx.getMarshaller(type); - SelectClause select = new SelectClause(type, marsh.getPrimaryKeyFields(), clauses); - final SQLBuilder builder = _ctx.getSQLBuilder(DepotTypes.getDepotTypes(_ctx, select)); - builder.newQuery(select); - - if (forUpdate) { - _ctx.invoke(new Modifier(null) { - @Override - protected int invoke (Connection conn, DatabaseLiaison liaison) throws SQLException { - PreparedStatement stmt = builder.prepare(conn); - try { - ResultSet rs = stmt.executeQuery(); - while (rs.next()) { - keys.add(marsh.makePrimaryKey(rs)); - } - // TODO: cache this result? - if (PersistenceContext.CACHE_DEBUG) { - log.info("Loaded " + StringUtil.shortClassName(type) + " keys", - "count", keys.size()); - } - return 0; - } finally { - JDBCUtil.close(stmt); - } - } - @Override public void updateStats (Stats stats) { - stats.noteQuery(0, 1, 0, 0); // one uncached query - } - }); - - } else { - _ctx.invoke(new Query.Trivial() { - @Override - public Void invoke (PersistenceContext ctx, Connection conn, - DatabaseLiaison liaison) throws SQLException { - PreparedStatement stmt = builder.prepare(conn); - try { - ResultSet rs = stmt.executeQuery(); - while (rs.next()) { - keys.add(marsh.makePrimaryKey(rs)); - } - // TODO: cache this result? - if (PersistenceContext.CACHE_DEBUG) { - log.info("Loaded " + StringUtil.shortClassName(type) + " keys", - "count", keys.size()); - } - return null; - } finally { - JDBCUtil.close(stmt); - } - } - public void updateStats (Stats stats) { - stats.noteQuery(0, 1, 0, 0); // one uncached query - } - }); - } - - return keys; + return _ctx.invoke(new FindAllKeysQuery(_ctx, type, forUpdate, clauses)); } /** diff --git a/src/java/com/samskivert/depot/FindAllKeysQuery.java b/src/java/com/samskivert/depot/FindAllKeysQuery.java new file mode 100644 index 0000000..4a7aea7 --- /dev/null +++ b/src/java/com/samskivert/depot/FindAllKeysQuery.java @@ -0,0 +1,100 @@ +// +// $Id$ +// +// Depot library - a Java relational persistence library +// Copyright (C) 2006-2008 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.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; + +import com.samskivert.depot.clause.QueryClause; +import com.samskivert.depot.clause.SelectClause; + +import static com.samskivert.depot.Log.log; + +/** + * Loads all primary keys for the records matching the supplied clause. + */ +public class FindAllKeysQuery extends Query>> +{ + public FindAllKeysQuery (PersistenceContext ctx, Class type, boolean forUpdate, + Collection clauses) + throws DatabaseException + { + _forUpdate = forUpdate; + _marsh = ctx.getMarshaller(type); + _select = new SelectClause(type, _marsh.getPrimaryKeyFields(), clauses); + _builder = ctx.getSQLBuilder(DepotTypes.getDepotTypes(ctx, _select)); + _builder.newQuery(_select); + } + + @Override // from Query + public boolean isReadOnly () + { + return !_forUpdate; + } + + @Override // from Query + public List> getCachedResult (PersistenceContext ctx) + { + return null; // TODO + } + + @Override // from Query + public List> invoke (PersistenceContext ctx, Connection conn, DatabaseLiaison liaison) + throws SQLException + { + List> keys = Lists.newArrayList(); + PreparedStatement stmt = _builder.prepare(conn); + try { + ResultSet rs = stmt.executeQuery(); + while (rs.next()) { + keys.add(_marsh.makePrimaryKey(rs)); + } + // TODO: cache this result? + if (PersistenceContext.CACHE_DEBUG) { + log.info("Loaded " + _marsh.getTableName(), "count", keys.size()); + } + return keys; + } finally { + JDBCUtil.close(stmt); + } + } + + @Override // from Query + public void updateStats (Stats stats) + { + stats.noteQuery(0, 1, 0, 0); // one uncached query + } + + protected boolean _forUpdate; + protected SQLBuilder _builder; + protected DepotMarshaller _marsh; + protected SelectClause _select; +} diff --git a/src/java/com/samskivert/depot/FindAllQuery.java b/src/java/com/samskivert/depot/FindAllQuery.java index 7c41d7f..de6f9fa 100644 --- a/src/java/com/samskivert/depot/FindAllQuery.java +++ b/src/java/com/samskivert/depot/FindAllQuery.java @@ -49,8 +49,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 - implements Query> +public abstract class FindAllQuery extends Query> { /** * The two-pass collection query implementation. See {@link DepotRepository#findAll} for @@ -76,7 +75,7 @@ public abstract class FindAllQuery } _select = new SelectClause(_type, _marsh.getPrimaryKeyFields(), clauses); - _builder = _ctx.getSQLBuilder(DepotTypes.getDepotTypes(ctx, _select)); + _builder = ctx.getSQLBuilder(DepotTypes.getDepotTypes(ctx, _select)); _builder.newQuery(_select); } @@ -95,7 +94,7 @@ public abstract class FindAllQuery Key key = _marsh.makePrimaryKey(rs); allKeys.add(key); - T value = _ctx.cacheLookup(key); + T value = ctx.cacheLookup(key); if (value != null) { @SuppressWarnings("unchecked") T newValue = (T) value.clone(); entities.put(key, newValue); @@ -124,7 +123,6 @@ public abstract class FindAllQuery stats.noteQuery(0, 1, _cachedRecords, _uncachedRecords); // one uncached query } - protected SelectClause _select; protected int _cachedRecords, _uncachedRecords; } @@ -148,7 +146,7 @@ public abstract class FindAllQuery Map, T> entities = Maps.newHashMap(); Set> fetchKeys = Sets.newHashSet(); for (Key key : _keys) { - T value = _ctx.cacheLookup(key); + T value = ctx.cacheLookup(key); if (value != null) { @SuppressWarnings("unchecked") T newValue = (T) value.clone(); entities.put(key, newValue); @@ -213,49 +211,28 @@ public abstract class FindAllQuery stats.noteQuery(0, 1, 0, _uncachedRecords); } - protected SelectClause _select; protected int _uncachedRecords; } - public FindAllQuery (PersistenceContext ctx, Class type) - throws DatabaseException - { - _ctx = ctx; - _type = type; - _marsh = _ctx.getMarshaller(type); - } - - // from interface Query + @Override // from Query public List getCachedResult (PersistenceContext ctx) { return null; // TODO } -// // from interface Query -// public List transformCacheHit (CacheKey key, List bits) -// { -// if (bits == null) { -// return bits; -// } - -// List result = Lists.newArrayList(); -// for (T bit : bits) { -// if (bit != null) { -// @SuppressWarnings("unchecked") T cbit = (T) bit.clone(); -// result.add(cbit); -// } else { -// result.add(null); -// } -// } -// return result; -// } - - // from interface Operation + @Override // from Operation public void updateStats (Stats stats) { // TODO } + protected FindAllQuery (PersistenceContext ctx, Class type) + throws DatabaseException + { + _type = type; + _marsh = ctx.getMarshaller(type); + } + protected List loadAndResolve (PersistenceContext ctx, Connection conn, Collection> allKeys, Set> fetchKeys, Map, T> entities, String origStmt) @@ -346,8 +323,8 @@ public abstract class FindAllQuery return builder.append(")").toString(); } - protected PersistenceContext _ctx; protected SQLBuilder _builder; protected DepotMarshaller _marsh; protected Class _type; + protected SelectClause _select; } diff --git a/src/java/com/samskivert/depot/FindOneQuery.java b/src/java/com/samskivert/depot/FindOneQuery.java index 9c698fa..144ada7 100644 --- a/src/java/com/samskivert/depot/FindOneQuery.java +++ b/src/java/com/samskivert/depot/FindOneQuery.java @@ -37,8 +37,7 @@ import static com.samskivert.depot.Log.log; /** * The implementation of {@link DepotRepository#load} functionality. */ -public class FindOneQuery - implements Query +public class FindOneQuery extends Query { public FindOneQuery (PersistenceContext ctx, Class type, QueryClause[] clauses) throws DatabaseException @@ -53,7 +52,7 @@ public class FindOneQuery _builder.newQuery(_select); } - // from interface Query + @Override // from Query public T getCachedResult (PersistenceContext ctx) { CacheKey key = getCacheKey(); @@ -70,7 +69,7 @@ public class FindOneQuery return cvalue; } - // from interface Query + @Override // from Query public T invoke (PersistenceContext ctx, Connection conn, DatabaseLiaison liaison) throws SQLException { @@ -110,7 +109,7 @@ public class FindOneQuery } } - // from interface Operation + @Override // from Operation public void updateStats (Stats stats) { stats.noteQuery(0, 0, _cachedRecords, 1-_cachedRecords); diff --git a/src/java/com/samskivert/depot/Modifier.java b/src/java/com/samskivert/depot/Modifier.java index 44594e4..9b9b375 100644 --- a/src/java/com/samskivert/depot/Modifier.java +++ b/src/java/com/samskivert/depot/Modifier.java @@ -117,6 +117,12 @@ public abstract class Modifier implements Operation _invalidator = invalidator; } + // from interface Operation + public boolean isReadOnly () + { + return false; + } + // from interface Operation public Integer invoke (PersistenceContext ctx, Connection conn, DatabaseLiaison liaison) throws SQLException diff --git a/src/java/com/samskivert/depot/Operation.java b/src/java/com/samskivert/depot/Operation.java index bbb18cf..1864d7a 100644 --- a/src/java/com/samskivert/depot/Operation.java +++ b/src/java/com/samskivert/depot/Operation.java @@ -30,6 +30,11 @@ import com.samskivert.jdbc.DatabaseLiaison; */ public interface Operation { + /** + * Indicates whether or not this operation is safe to invoke on a database mirror. + */ + public boolean isReadOnly (); + /** * Performs the actual JDBC interactions associated with this operation. */ diff --git a/src/java/com/samskivert/depot/PersistenceContext.java b/src/java/com/samskivert/depot/PersistenceContext.java index 3aa336d..e628ba3 100644 --- a/src/java/com/samskivert/depot/PersistenceContext.java +++ b/src/java/com/samskivert/depot/PersistenceContext.java @@ -523,7 +523,7 @@ public class PersistenceContext { checkAreInitialized(); // le check du sanity - boolean isReadOnly = !(op instanceof Modifier); + boolean isReadOnly = op.isReadOnly(); Connection conn; long preConnect = System.nanoTime(); try { diff --git a/src/java/com/samskivert/depot/Query.java b/src/java/com/samskivert/depot/Query.java index 0879502..a9f362b 100644 --- a/src/java/com/samskivert/depot/Query.java +++ b/src/java/com/samskivert/depot/Query.java @@ -29,21 +29,16 @@ import com.samskivert.depot.PersistenceContext.CacheListener; /** * The base of all read-only queries. */ -public interface Query extends Operation +public abstract class Query + implements Operation { /** A simple base class for non-complex queries. */ - public abstract class Trivial implements Query + public static abstract class Trivial extends Query { - public abstract T invoke (PersistenceContext ctx, Connection conn, DatabaseLiaison liaison) - throws SQLException; - + @Override // from Query public T getCachedResult (PersistenceContext ctx) { return null; } - - public T transformCacheHit (CacheKey key, T value) { - return value; - } } /** @@ -51,5 +46,11 @@ public interface Query extends Operation * method. If null is returned, the query will be {@link #invoke}d to obtain its result from * persistent storage. */ - public T getCachedResult (PersistenceContext ctx); + public abstract T getCachedResult (PersistenceContext ctx); + + // from interface Operation + public boolean isReadOnly () + { + return true; + } }