Skip to content

Commit cbea6d2

Browse files
Antonio Forniespark404
authored andcommitted
Fix and test GroupBy SQL query creation
Signed-off-by: Ian Southam <isoutham@schubergphilis.com> Signed-off-by: Hugo Trippaers <htrippaers@schubergphilis.com>
1 parent 8649fa0 commit cbea6d2

3 files changed

Lines changed: 125 additions & 55 deletions

File tree

framework/db/src/com/cloud/utils/db/GroupBy.java

Lines changed: 18 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -28,44 +28,48 @@ public class GroupBy<J extends SearchBase<?, T, R>, T, R> {
2828
List<Pair<Func, Attribute>> _groupBys;
2929
Having _having;
3030

31-
public GroupBy(J builder) {
31+
public GroupBy(final J builder) {
32+
init(builder);
33+
}
34+
35+
protected void init(final J builder) {
3236
_builder = builder;
3337
_groupBys = new ArrayList<Pair<Func, Attribute>>();
3438
_having = null;
35-
for (Attribute attr : _builder.getSpecifiedAttributes()) {
39+
for (final Attribute attr : _builder.getSpecifiedAttributes()) {
3640
_groupBys.add(new Pair<Func, Attribute>(null, attr));
3741
}
3842
_builder.getSpecifiedAttributes().clear();
3943
}
4044

41-
public GroupBy<J, T, R> group(Object useless) {
45+
public GroupBy<J, T, R> group(final Object useless) {
4246
_groupBys.add(new Pair<Func, Attribute>(null, _builder.getSpecifiedAttributes().get(0)));
4347
_builder.getSpecifiedAttributes().clear();
4448
return this;
4549
}
4650

47-
public GroupBy<J, T, R> group(Func func, Object useless) {
51+
public GroupBy<J, T, R> group(final Func func, final Object useless) {
4852
_groupBys.add(new Pair<Func, Attribute>(func, _builder.getSpecifiedAttributes().get(0)));
4953
_builder.getSpecifiedAttributes().clear();
5054
return this;
5155
}
5256

53-
public J having(Func func, Object obj, Op op, Object value) {
57+
public J having(final Func func, final Object obj, final Op op, final Object value) {
5458
assert (_having == null) : "You can only specify one having in a group by";
55-
List<Attribute> attrs = _builder.getSpecifiedAttributes();
59+
final List<Attribute> attrs = _builder.getSpecifiedAttributes();
5660
assert attrs.size() == 1 : "You didn't specified an attribute";
5761

5862
_having = new Having(func, attrs.get(0), op, value);
5963
_builder.getSpecifiedAttributes().clear();
6064
return _builder;
6165
}
6266

63-
public void toSql(StringBuilder builder) {
67+
public void toSql(final StringBuilder builder) {
6468
builder.append(" GROUP BY ");
65-
for (Pair<Func, Attribute> groupBy : _groupBys) {
69+
for (final Pair<Func, Attribute> groupBy : _groupBys) {
6670
if (groupBy.first() != null) {
6771
String func = groupBy.first().toString();
68-
func.replaceFirst("@", groupBy.second().table + "." + groupBy.second().columnName);
72+
func = func.replaceFirst("@", groupBy.second().table + "." + groupBy.second().columnName);
6973
builder.append(func);
7074
} else {
7175
builder.append(groupBy.second().table + "." + groupBy.second().columnName);
@@ -86,18 +90,19 @@ protected class Having {
8690
public Op op;
8791
public Object value;
8892

89-
public Having(Func func, Attribute attr, Op op, Object value) {
93+
public Having(final Func func, final Attribute attr, final Op op, final Object value) {
9094
this.func = func;
9195
this.attr = attr;
9296
this.op = op;
9397
this.value = value;
9498
}
9599

96-
public void toSql(StringBuilder builder) {
100+
public void toSql(final StringBuilder builder) {
101+
builder.append(" HAVING ");
97102
if (func != null) {
98103
String f = func.toString();
99-
f.replaceFirst("@", attr.toString());
100-
builder.append(func);
104+
f = f.replaceFirst("@", attr.toString());
105+
builder.append(f);
101106
} else {
102107
builder.append(attr.toString());
103108
}

framework/db/src/com/cloud/utils/db/SearchBase.java

Lines changed: 45 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -52,21 +52,25 @@
5252
*/
5353
public abstract class SearchBase<J extends SearchBase<?, T, K>, T, K> {
5454

55-
final Map<String, Attribute> _attrs;
56-
final Class<T> _entityBeanType;
57-
final Class<K> _resultType;
58-
final GenericDaoBase<? extends T, ? extends Serializable> _dao;
55+
Map<String, Attribute> _attrs;
56+
Class<T> _entityBeanType;
57+
Class<K> _resultType;
58+
GenericDaoBase<? extends T, ? extends Serializable> _dao;
5959

60-
final ArrayList<Condition> _conditions;
61-
final ArrayList<Attribute> _specifiedAttrs;
60+
ArrayList<Condition> _conditions;
61+
ArrayList<Attribute> _specifiedAttrs;
6262

6363
protected HashMap<String, JoinBuilder<SearchBase<?, ?, ?>>> _joins;
6464
protected ArrayList<Select> _selects;
6565
protected GroupBy<J, T, K> _groupBy = null;
6666
protected SelectType _selectType;
6767
T _entity;
6868

69-
SearchBase(Class<T> entityType, Class<K> resultType) {
69+
SearchBase(final Class<T> entityType, final Class<K> resultType) {
70+
init(entityType, resultType);
71+
}
72+
73+
protected void init(final Class<T> entityType, final Class<K> resultType) {
7074
_dao = (GenericDaoBase<? extends T, ? extends Serializable>)GenericDaoBase.getDao(entityType);
7175
if (_dao == null) {
7276
throw new CloudRuntimeException("Unable to find DAO for " + entityType);
@@ -81,7 +85,6 @@ public abstract class SearchBase<J extends SearchBase<?, T, K>, T, K> {
8185
_joins = null;
8286
_specifiedAttrs = new ArrayList<Attribute>();
8387
}
84-
8588
/**
8689
* Specifies how the search query should be grouped
8790
*
@@ -90,7 +93,7 @@ public abstract class SearchBase<J extends SearchBase<?, T, K>, T, K> {
9093
* @see GroupBy
9194
*/
9295
@SuppressWarnings("unchecked")
93-
public GroupBy<J, T, K> groupBy(Object... fields) {
96+
public GroupBy<J, T, K> groupBy(final Object... fields) {
9497
assert _groupBy == null : "Can't do more than one group bys";
9598
_groupBy = new GroupBy<J, T, K>((J)this);
9699
return _groupBy;
@@ -106,7 +109,7 @@ public GroupBy<J, T, K> groupBy(Object... fields) {
106109
* @return itself to build more search parts.
107110
*/
108111
@SuppressWarnings("unchecked")
109-
public J select(String fieldName, Func func, Object field, Object... params) {
112+
public J select(final String fieldName, final Func func, final Object field, final Object... params) {
110113
if (_entity == null) {
111114
throw new RuntimeException("SearchBuilder cannot be modified once it has been setup");
112115
}
@@ -126,9 +129,9 @@ public J select(String fieldName, Func func, Object field, Object... params) {
126129
try {
127130
declaredField = _resultType.getDeclaredField(fieldName);
128131
declaredField.setAccessible(true);
129-
} catch (SecurityException e) {
132+
} catch (final SecurityException e) {
130133
throw new RuntimeException("Unable to find " + fieldName, e);
131-
} catch (NoSuchFieldException e) {
134+
} catch (final NoSuchFieldException e) {
132135
throw new RuntimeException("Unable to find " + fieldName, e);
133136
}
134137
} else {
@@ -138,7 +141,7 @@ public J select(String fieldName, Func func, Object field, Object... params) {
138141
}
139142
}
140143

141-
Select select = new Select(func, _specifiedAttrs.size() == 0 ? null : _specifiedAttrs.get(0), declaredField, params);
144+
final Select select = new Select(func, _specifiedAttrs.size() == 0 ? null : _specifiedAttrs.get(0), declaredField, params);
142145
_selects.add(select);
143146

144147
_specifiedAttrs.clear();
@@ -153,7 +156,7 @@ public J select(String fieldName, Func func, Object field, Object... params) {
153156
* @return itself
154157
*/
155158
@SuppressWarnings("unchecked")
156-
public J selectFields(Object... fields) {
159+
public J selectFields(final Object... fields) {
157160
if (_entity == null) {
158161
throw new RuntimeException("SearchBuilder cannot be modified once it has been setup");
159162
}
@@ -165,13 +168,13 @@ public J selectFields(Object... fields) {
165168
_selects = new ArrayList<Select>();
166169
}
167170

168-
for (Attribute attr : _specifiedAttrs) {
171+
for (final Attribute attr : _specifiedAttrs) {
169172
Field field = null;
170173
try {
171174
field = _resultType.getDeclaredField(attr.field.getName());
172175
field.setAccessible(true);
173-
} catch (SecurityException e) {
174-
} catch (NoSuchFieldException e) {
176+
} catch (final SecurityException e) {
177+
} catch (final NoSuchFieldException e) {
175178
}
176179
_selects.add(new Select(Func.NATIVE, attr, field, null));
177180
}
@@ -192,14 +195,14 @@ public J selectFields(Object... fields) {
192195
* @return itself
193196
*/
194197
@SuppressWarnings("unchecked")
195-
public J join(String name, SearchBase<?, ?, ?> builder, Object joinField1, Object joinField2, JoinBuilder.JoinType joinType) {
198+
public J join(final String name, final SearchBase<?, ?, ?> builder, final Object joinField1, final Object joinField2, final JoinBuilder.JoinType joinType) {
196199
assert _entity != null : "SearchBuilder cannot be modified once it has been setup";
197200
assert _specifiedAttrs.size() == 1 : "You didn't select the attribute.";
198201
assert builder._entity != null : "SearchBuilder cannot be modified once it has been setup";
199202
assert builder._specifiedAttrs.size() == 1 : "You didn't select the attribute.";
200203
assert builder != this : "You can't add yourself, can you? Really think about it!";
201204

202-
JoinBuilder<SearchBase<?, ?, ?>> t = new JoinBuilder<SearchBase<?, ?, ?>>(builder, _specifiedAttrs.get(0), builder._specifiedAttrs.get(0), joinType);
205+
final JoinBuilder<SearchBase<?, ?, ?>> t = new JoinBuilder<SearchBase<?, ?, ?>>(builder, _specifiedAttrs.get(0), builder._specifiedAttrs.get(0), joinType);
203206
if (_joins == null) {
204207
_joins = new HashMap<String, JoinBuilder<SearchBase<?, ?, ?>>>();
205208
}
@@ -214,8 +217,8 @@ public SelectType getSelectType() {
214217
return _selectType;
215218
}
216219

217-
protected void set(String name) {
218-
Attribute attr = _attrs.get(name);
220+
protected void set(final String name) {
221+
final Attribute attr = _attrs.get(name);
219222
assert (attr != null) : "Searching for a field that's not there: " + name;
220223
_specifiedAttrs.add(attr);
221224
}
@@ -239,12 +242,12 @@ protected List<Attribute> getSpecifiedAttributes() {
239242
return _specifiedAttrs;
240243
}
241244

242-
protected Condition constructCondition(String conditionName, String cond, Attribute attr, Op op) {
245+
protected Condition constructCondition(final String conditionName, final String cond, final Attribute attr, final Op op) {
243246
assert _entity != null : "SearchBuilder cannot be modified once it has been setup";
244247
assert op == null || _specifiedAttrs.size() == 1 : "You didn't select the attribute.";
245248
assert op != Op.SC : "Call join";
246249

247-
Condition condition = new Condition(conditionName, cond, attr, op);
250+
final Condition condition = new Condition(conditionName, cond, attr, op);
248251
_conditions.add(condition);
249252
_specifiedAttrs.clear();
250253
return condition;
@@ -304,7 +307,7 @@ public J and() {
304307
*/
305308
@SuppressWarnings("unchecked")
306309
public J cp() {
307-
Condition condition = new Condition(null, " ) ", null, Op.RP);
310+
final Condition condition = new Condition(null, " ) ", null, Op.RP);
308311
_conditions.add(condition);
309312
return (J)this;
310313
}
@@ -315,7 +318,7 @@ public J cp() {
315318
*/
316319
@SuppressWarnings("unchecked")
317320
public J op() {
318-
Condition condition = new Condition(null, " ( ", null, Op.RP);
321+
final Condition condition = new Condition(null, " ( ", null, Op.RP);
319322
_conditions.add(condition);
320323
return (J)this;
321324
}
@@ -326,13 +329,13 @@ public J op() {
326329
@Override
327330
protected synchronized void finalize() {
328331
if (_entity != null) {
329-
Factory factory = (Factory)_entity;
332+
final Factory factory = (Factory)_entity;
330333
factory.setCallback(0, null);
331334
_entity = null;
332335
}
333336

334337
if (_joins != null) {
335-
for (JoinBuilder<SearchBase<?, ?, ?>> join : _joins.values()) {
338+
for (final JoinBuilder<SearchBase<?, ?, ?>> join : _joins.values()) {
336339
join.getT().finalize();
337340
}
338341
}
@@ -343,7 +346,7 @@ protected synchronized void finalize() {
343346
return;
344347
}
345348

346-
for (Select select : _selects) {
349+
for (final Select select : _selects) {
347350
if (select.field == null) {
348351
assert (_selects.size() == 1) : "You didn't specify any fields to put the result in but you're specifying more than one select so where should I put the selects?";
349352
_selectType = SelectType.Single;
@@ -365,11 +368,11 @@ protected static class Condition {
365368
protected final Attribute attr;
366369
protected Object[] presets;
367370

368-
protected Condition(String name) {
371+
protected Condition(final String name) {
369372
this(name, null, null, null);
370373
}
371374

372-
public Condition(String name, String cond, Attribute attr, Op op) {
375+
public Condition(final String name, final String cond, final Attribute attr, final Op op) {
373376
this.name = name;
374377
this.attr = attr;
375378
this.cond = cond;
@@ -381,15 +384,15 @@ public boolean isPreset() {
381384
return presets != null;
382385
}
383386

384-
public void setPresets(Object... presets) {
387+
public void setPresets(final Object... presets) {
385388
this.presets = presets;
386389
}
387390

388391
public Object[] getPresets() {
389392
return presets;
390393
}
391394

392-
public void toSql(StringBuilder sql, Object[] params, int count) {
395+
public void toSql(final StringBuilder sql, final Object[] params, final int count) {
393396
if (count > 0) {
394397
sql.append(cond);
395398
}
@@ -438,12 +441,12 @@ public int hashCode() {
438441
}
439442

440443
@Override
441-
public boolean equals(Object obj) {
444+
public boolean equals(final Object obj) {
442445
if (!(obj instanceof Condition)) {
443446
return false;
444447
}
445448

446-
Condition condition = (Condition)obj;
449+
final Condition condition = (Condition)obj;
447450
return name.equals(condition.name);
448451
}
449452
}
@@ -457,7 +460,7 @@ protected static class Select {
457460
protected Select() {
458461
}
459462

460-
public Select(Func func, Attribute attr, Field field, Object[] params) {
463+
public Select(final Func func, final Attribute attr, final Field field, final Object[] params) {
461464
this.func = func;
462465
this.attr = attr;
463466
this.params = params;
@@ -467,22 +470,22 @@ public Select(Func func, Attribute attr, Field field, Object[] params) {
467470

468471
protected class Interceptor implements MethodInterceptor {
469472
@Override
470-
public Object intercept(Object object, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
471-
String name = method.getName();
473+
public Object intercept(final Object object, final Method method, final Object[] args, final MethodProxy methodProxy) throws Throwable {
474+
final String name = method.getName();
472475
if (method.getAnnotation(Transient.class) == null) {
473476
if (name.startsWith("get")) {
474-
String fieldName = Character.toLowerCase(name.charAt(3)) + name.substring(4);
477+
final String fieldName = Character.toLowerCase(name.charAt(3)) + name.substring(4);
475478
set(fieldName);
476479
return null;
477480
} else if (name.startsWith("is")) {
478-
String fieldName = Character.toLowerCase(name.charAt(2)) + name.substring(3);
481+
final String fieldName = Character.toLowerCase(name.charAt(2)) + name.substring(3);
479482
set(fieldName);
480483
return null;
481484
} else {
482-
Column ann = method.getAnnotation(Column.class);
485+
final Column ann = method.getAnnotation(Column.class);
483486
if (ann != null) {
484-
String colName = ann.name();
485-
for (Map.Entry<String, Attribute> attr : _attrs.entrySet()) {
487+
final String colName = ann.name();
488+
for (final Map.Entry<String, Attribute> attr : _attrs.entrySet()) {
486489
if (colName.equals(attr.getValue().columnName)) {
487490
set(attr.getKey());
488491
return null;

0 commit comments

Comments
 (0)