Added support for limit to deleteAll.
I would have prefered to only add this support to the Query interface, and not clutter up DepotRepository with two additional overloaded methods. However, that would not have been possible without duplicating a bunch of logic from DepotRepository. Yet another reason why the Query builder approach is awesome and the fuckloads of overloaded methods approach isn't.
This commit is contained in:
@@ -24,6 +24,7 @@ import com.samskivert.util.ArrayUtil;
|
||||
|
||||
import com.samskivert.depot.clause.FieldOverride;
|
||||
import com.samskivert.depot.clause.InsertClause;
|
||||
import com.samskivert.depot.clause.Limit;
|
||||
import com.samskivert.depot.clause.QueryClause;
|
||||
import com.samskivert.depot.clause.WhereClause;
|
||||
import com.samskivert.depot.expression.ColumnExp;
|
||||
@@ -673,20 +674,34 @@ public abstract class DepotRepository
|
||||
*
|
||||
* @throws DatabaseException if any problem is encountered communicating with the database.
|
||||
*/
|
||||
public <T extends PersistentRecord> int deleteAll (Class<T> type, final WhereClause where)
|
||||
public <T extends PersistentRecord> int deleteAll (Class<T> type, WhereClause where)
|
||||
throws DatabaseException
|
||||
{
|
||||
return deleteAll(type, where, null, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Deletes all persistent objects from the database that match the supplied where clause, up to
|
||||
* the specified limit.
|
||||
*
|
||||
* @return the number of rows deleted by this action.
|
||||
*
|
||||
* @throws DatabaseException if any problem is encountered communicating with the database.
|
||||
*/
|
||||
public <T extends PersistentRecord> int deleteAll (Class<T> type, WhereClause where, Limit lim)
|
||||
throws DatabaseException
|
||||
{
|
||||
if (where instanceof CacheInvalidator) {
|
||||
// our where clause knows how to do its own deletion, yay!
|
||||
return deleteAll(type, where, (CacheInvalidator)where);
|
||||
return deleteAll(type, where, lim, (CacheInvalidator)where);
|
||||
} else if (_ctx.getMarshaller(type).hasPrimaryKey()) {
|
||||
// look up the primary keys for all matching rows matching and delete using those
|
||||
KeySet<T> pwhere = KeySet.newKeySet(type, findAllKeys(type, true, where));
|
||||
KeySet<T> pwhere = KeySet.newKeySet(type, findAllKeys(type, true, where, lim));
|
||||
return deleteAll(type, pwhere, pwhere);
|
||||
} else {
|
||||
// otherwise just do the delete directly as we can't have cached a record that has no
|
||||
// primary key in the first place
|
||||
return deleteAll(type, where, null);
|
||||
return deleteAll(type, where, lim, null);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -698,7 +713,22 @@ public abstract class DepotRepository
|
||||
* @throws DatabaseException if any problem is encountered communicating with the database.
|
||||
*/
|
||||
public <T extends PersistentRecord> int deleteAll (
|
||||
final Class<T> type, final WhereClause where, CacheInvalidator invalidator)
|
||||
Class<T> type, WhereClause where, CacheInvalidator invalidator)
|
||||
throws DatabaseException
|
||||
{
|
||||
return deleteAll(type, where, null, invalidator);
|
||||
}
|
||||
|
||||
/**
|
||||
* Deletes all persistent objects from the database that match the supplied key, up to the
|
||||
* supplied limit.
|
||||
*
|
||||
* @return the number of rows deleted by this action.
|
||||
*
|
||||
* @throws DatabaseException if any problem is encountered communicating with the database.
|
||||
*/
|
||||
public <T extends PersistentRecord> int deleteAll (
|
||||
final Class<T> type, WhereClause where, Limit limit, CacheInvalidator invalidator)
|
||||
throws DatabaseException
|
||||
{
|
||||
if (invalidator instanceof ValidatingCacheInvalidator) {
|
||||
@@ -706,7 +736,7 @@ public abstract class DepotRepository
|
||||
}
|
||||
where.validateQueryType(type); // and another
|
||||
|
||||
DeleteClause delete = new DeleteClause(type, where);
|
||||
DeleteClause delete = new DeleteClause(type, where, limit);
|
||||
final SQLBuilder builder = _ctx.getSQLBuilder(DepotTypes.getDepotTypes(_ctx, delete));
|
||||
builder.newQuery(delete);
|
||||
|
||||
|
||||
@@ -523,8 +523,8 @@ public class Query<T extends PersistentRecord>
|
||||
}
|
||||
|
||||
/**
|
||||
* 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
|
||||
* Deletes the records that match the configured query clauses. Note that only the where and
|
||||
* limit clauses are used to evaluate a deletion. Attempts to use other clauses will result in
|
||||
* failure.
|
||||
*
|
||||
* @return the number of rows deleted by this action.
|
||||
@@ -534,12 +534,16 @@ public class Query<T extends PersistentRecord>
|
||||
public int delete ()
|
||||
{
|
||||
assertValidDelete();
|
||||
return _repo.deleteAll(_pclass, _where);
|
||||
return _repo.deleteAll(_pclass, _where, _limit);
|
||||
}
|
||||
|
||||
/**
|
||||
* Deletes the records that match the configured query clauses. The supplied cache invalidator
|
||||
* is used to remove deleted records from the cache.
|
||||
* Deletes the records that match the configured query clauses. Note that only the where and
|
||||
* limit clauses are used to evaluate a deletion. Attempts to use other clauses will result in
|
||||
* failure.
|
||||
*
|
||||
* @param invalidator if non-null, used to remove deleted records from the cache; if null, no
|
||||
* cache deletion will be performed.
|
||||
*
|
||||
* @return the number of rows deleted by this action.
|
||||
*
|
||||
@@ -548,7 +552,7 @@ public class Query<T extends PersistentRecord>
|
||||
public int delete (CacheInvalidator invalidator)
|
||||
{
|
||||
assertValidDelete();
|
||||
return _repo.deleteAll(_pclass, _where, invalidator);
|
||||
return _repo.deleteAll(_pclass, _where, _limit, invalidator);
|
||||
}
|
||||
|
||||
protected Query (PersistenceContext ctx, DepotRepository repo, Class<T> pclass)
|
||||
@@ -602,7 +606,6 @@ public class Query<T extends PersistentRecord>
|
||||
checkState(_joins == null, "Join clauses not supported by delete.");
|
||||
checkState(_orderBy == null, "OrderBy clause not applicable for delete.");
|
||||
checkState(_groupBy == null, "GroupBy clause not applicable for delete.");
|
||||
checkState(_limit == null, "Limit clause not supported by delete.");
|
||||
checkState(_fromOverride == null, "FromOverride clause not applicable for delete.");
|
||||
checkState(_fieldDefs == null, "FieldDefinition clauses not applicable for delete.");
|
||||
checkState(_forUpdate == null, "ForUpdate clause not supported by delete.");
|
||||
|
||||
@@ -469,6 +469,9 @@ public abstract class BuildVisitor implements FragmentVisitor<Void>
|
||||
appendTableAbbreviation(deleteClause.getPersistentClass());
|
||||
_builder.append(" ");
|
||||
deleteClause.getWhereClause().accept(this);
|
||||
if (deleteClause.getLimit() != null) {
|
||||
deleteClause.getLimit().accept(this);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
@@ -52,6 +52,9 @@ public class MySQLBuilder
|
||||
_types.setUseTableAbbreviations(false);
|
||||
try {
|
||||
deleteClause.getWhereClause().accept(this);
|
||||
if (deleteClause.getLimit() != null) {
|
||||
deleteClause.getLimit().accept(this);
|
||||
}
|
||||
} finally {
|
||||
_types.setUseTableAbbreviations(savedFlag);
|
||||
}
|
||||
|
||||
@@ -7,6 +7,7 @@ package com.samskivert.depot.impl.clause;
|
||||
import java.util.Collection;
|
||||
|
||||
import com.samskivert.depot.PersistentRecord;
|
||||
import com.samskivert.depot.clause.Limit;
|
||||
import com.samskivert.depot.clause.QueryClause;
|
||||
import com.samskivert.depot.clause.WhereClause;
|
||||
|
||||
@@ -18,10 +19,11 @@ import com.samskivert.depot.impl.FragmentVisitor;
|
||||
public class DeleteClause
|
||||
implements QueryClause
|
||||
{
|
||||
public DeleteClause (Class<? extends PersistentRecord> pClass, WhereClause where)
|
||||
public DeleteClause (Class<? extends PersistentRecord> pClass, WhereClause where, Limit limit)
|
||||
{
|
||||
_pClass = pClass;
|
||||
_where = where;
|
||||
_limit = limit;
|
||||
}
|
||||
|
||||
public Class<? extends PersistentRecord> getPersistentClass ()
|
||||
@@ -34,6 +36,11 @@ public class DeleteClause
|
||||
return _where;
|
||||
}
|
||||
|
||||
public Limit getLimit ()
|
||||
{
|
||||
return _limit;
|
||||
}
|
||||
|
||||
// from SQLFragment
|
||||
public void addClasses (Collection<Class<? extends PersistentRecord>> classSet)
|
||||
{
|
||||
@@ -51,4 +58,7 @@ public class DeleteClause
|
||||
|
||||
/** The where clause. */
|
||||
protected WhereClause _where;
|
||||
|
||||
/** An optional limit clause. */
|
||||
protected Limit _limit;
|
||||
}
|
||||
|
||||
@@ -94,6 +94,24 @@ public class QueryTest extends TestBase
|
||||
// _repo.deleteAll(TestRecord.class, KeySet.newSimpleKeySet(TestRecord.class, ids));
|
||||
}
|
||||
|
||||
@Test public void testLimitedDelete ()
|
||||
{
|
||||
for (int ii = 1; ii <= CREATE_RECORDS; ii++) {
|
||||
TestRecord record = createTestRecord(ii);
|
||||
record.name = "Spam! " + ii;
|
||||
record.age = RandomUtil.getInt(100);
|
||||
record.awesomeness = RandomUtil.getFloat(1.0F);
|
||||
record.homeTown = "Over there";
|
||||
_repo.insert(record);
|
||||
}
|
||||
|
||||
_repo.from(TestRecord.class).whereTrue().limit(50).delete();
|
||||
assertEquals(CREATE_RECORDS-50, _repo.findAll(TestRecord.class).size());
|
||||
|
||||
_repo.from(TestRecord.class).whereTrue().delete();
|
||||
assertEquals(0, _repo.findAll(TestRecord.class).size());
|
||||
}
|
||||
|
||||
// the HSQL in-memory database persists for the lifetime of the VM, which means we have to
|
||||
// clean up after ourselves in every test; thus we go ahead and share a repository
|
||||
protected TestRepository _repo = createTestRepository();
|
||||
|
||||
Reference in New Issue
Block a user