From fca5cb2386933e86ffea5025ac6c288ad53b8afe Mon Sep 17 00:00:00 2001 From: Michael Bayne Date: Tue, 7 Dec 2010 23:41:27 +0000 Subject: [PATCH] Added QueryBuilder.delete() along with a bunch of sanity checking. I considered having a separate deleteFrom(record).where(...).delete() builder, but from(record).where(...).delete() was so much nicer that I decided that preventing the specification of invalid clauses could be deferred from compile to runtime. I could do some fiddly things with return types and have from() return a builder that then subsequently pigeon-holed you into deletability or not depending on whether you called things like orderBy(), but to do so in Java would require that I override every method to specialize its return type, which presents something of a maintenance annoyance. --- .../com/samskivert/depot/QueryBuilder.java | 68 +++++++++++++++++++ 1 file changed, 68 insertions(+) diff --git a/src/main/java/com/samskivert/depot/QueryBuilder.java b/src/main/java/com/samskivert/depot/QueryBuilder.java index 977bf94..71cd3ed 100644 --- a/src/main/java/com/samskivert/depot/QueryBuilder.java +++ b/src/main/java/com/samskivert/depot/QueryBuilder.java @@ -81,6 +81,7 @@ public class QueryBuilder */ public QueryBuilder where (SQLExpression... exprs) { + requireNull(_where, "Where clause is already configured."); switch (exprs.length) { case 0: throw new IllegalArgumentException("Must supply at least one expression."); @@ -100,6 +101,7 @@ public class QueryBuilder */ public QueryBuilder where (ColumnExp column, Comparable value) { + requireNull(_where, "Where clause is already configured."); _where = new Where(column, value); return this; } @@ -111,6 +113,7 @@ public class QueryBuilder public QueryBuilder where (ColumnExp index1, Comparable value1, ColumnExp index2, Comparable value2) { + requireNull(_where, "Where clause is already configured."); _where = new Where(index1, value1, index2, value2); return this; } @@ -120,6 +123,7 @@ public class QueryBuilder */ public QueryBuilder join (ColumnExp left, ColumnExp right) { + requireNull(_join, "Join clause is already configured."); _join = new Join(left, right); return this; } @@ -129,6 +133,7 @@ public class QueryBuilder */ public QueryBuilder groupBy (SQLExpression... exprs) { + requireNull(_groupBy, "GroupBy clause is already configured."); _groupBy = new GroupBy(exprs); return this; } @@ -138,6 +143,7 @@ public class QueryBuilder */ public QueryBuilder randomOrder () { + requireNull(_orderBy, "OrderBy clause is already configured."); _orderBy = OrderBy.random(); return this; } @@ -147,6 +153,7 @@ public class QueryBuilder */ public QueryBuilder ascending (SQLExpression value) { + requireNull(_orderBy, "OrderBy clause is already configured."); _orderBy = OrderBy.ascending(value); return this; } @@ -156,6 +163,7 @@ public class QueryBuilder */ public QueryBuilder descending (SQLExpression value) { + requireNull(_orderBy, "OrderBy clause is already configured."); _orderBy = OrderBy.descending(value); return this; } @@ -165,6 +173,7 @@ public class QueryBuilder */ public QueryBuilder limit (int count) { + requireNull(_limit, "Limit clause is already configured."); _limit = new Limit(0, count); return this; } @@ -174,6 +183,7 @@ public class QueryBuilder */ public QueryBuilder limit (int offset, int count) { + requireNull(_limit, "Limit clause is already configured."); _limit = new Limit(offset, count); return this; } @@ -183,6 +193,7 @@ public class QueryBuilder */ public QueryBuilder override (Class fromClass) { + requireNull(_fromOverride, "FromOverride clause is already configured."); _fromOverride = new FromOverride(fromClass); return this; } @@ -193,6 +204,7 @@ public class QueryBuilder public QueryBuilder override (Class fromClass1, Class fromClass2) { + requireNull(_fromOverride, "FromOverride clause is already configured."); _fromOverride = new FromOverride(fromClass1, fromClass2); return this; } @@ -202,6 +214,7 @@ public class QueryBuilder */ public QueryBuilder forUpdate () { + requireNull(_forUpdate, "ForUpdate clause is already configured."); _forUpdate = new ForUpdate(); return this; } @@ -248,6 +261,47 @@ public class QueryBuilder return _repo.load(CountRecord.class, _cache, getClauseArray()).count; } + /** + * 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 + * failure. + * + * @return the number of rows deleted by this action. + * + * @throws DatabaseException if any problem is encountered communicating with the database. + */ + public int delete () + { + requireNotNull(_where, "Where clause must be specified for delete."); + requireNull(_join, "Join clause not supported by delete."); + requireNull(_orderBy, "OrderBy clause not applicable for delete."); + requireNull(_groupBy, "GroupBy clause not applicable for delete."); + requireNull(_limit, "Limit clause not supported by delete."); + requireNull(_fromOverride, "FromOverride clause not applicable for delete."); + requireNull(_forUpdate, "ForUpdate clause not supported by delete."); + return _repo.deleteAll(_pclass, _where); + } + + /** + * Deletes the records that match the configured query clauses. The supplied cache invalidator + * is used to remove deleted records from the cache. + * + * @return the number of rows deleted by this action. + * + * @throws DatabaseException if any problem is encountered communicating with the database. + */ + public int delete (CacheInvalidator invalidator) + { + requireNotNull(_where, "Where clause must be specified for delete."); + requireNull(_join, "Join clause not supported by delete."); + requireNull(_orderBy, "OrderBy clause not applicable for delete."); + requireNull(_groupBy, "GroupBy clause not applicable for delete."); + requireNull(_limit, "Limit clause not supported by delete."); + requireNull(_fromOverride, "FromOverride clause not applicable for delete."); + requireNull(_forUpdate, "ForUpdate clause not supported by delete."); + return _repo.deleteAll(_pclass, _where, invalidator); + } + protected List getClauses () { List clauses = Lists.newArrayList(); @@ -274,6 +328,20 @@ public class QueryBuilder } } + protected void requireNotNull (Object value, String message) + { + if (value == null) { + throw new AssertionError(message); + } + } + + protected void requireNull (Object value, String message) + { + if (value != null) { + throw new AssertionError(message); + } + } + protected final DepotRepository _repo; protected final Class _pclass;