EMMA Coverage Report (generated Mon Apr 21 23:56:41 GMT 2008)
[all classes][org.sqlorm.querybuilder]

COVERAGE SUMMARY FOR SOURCE FILE [SelectBuilder.java]

nameclass, %method, %block, %line, %
SelectBuilder.java100% (1/1)65%  (34/52)83%  (612/737)86%  (130/151)

COVERAGE BREAKDOWN BY CLASS AND METHOD

nameclass, %method, %block, %line, %
     
class SelectBuilder100% (1/1)65%  (34/52)83%  (612/737)86%  (130/151)
SelectBuilder (): void 100% (1/1)100% (56/56)100% (13/13)
addList (Object, List): Object 100% (1/1)100% (20/20)100% (6/6)
crossJoin (ITableName): MultiJoinOnExpr 0%   (0/1)0%   (0/5)0%   (0/1)
crossJoin (ITableName, String): MultiJoinOnExpr 0%   (0/1)0%   (0/6)0%   (0/1)
crossJoin (String): MultiJoinOnExpr 100% (1/1)100% (11/11)100% (1/1)
crossJoin (String, String): MultiJoinOnExpr 100% (1/1)100% (12/12)100% (1/1)
distinct (): ItfSelectBuilder 100% (1/1)100% (5/5)100% (2/2)
from (ITableName): ItfSelectBuilder 0%   (0/1)0%   (0/5)0%   (0/1)
from (ITableName, String): ItfSelectBuilder 0%   (0/1)0%   (0/6)0%   (0/1)
from (ItfSelectBuilder, String): ItfSelectBuilder 100% (1/1)100% (17/17)100% (4/4)
from (String): ItfSelectBuilder 100% (1/1)100% (17/17)100% (4/4)
from (String, String): ItfSelectBuilder 100% (1/1)100% (18/18)100% (4/4)
groupBy (ITableName): ItfSelectBuilder 0%   (0/1)0%   (0/10)0%   (0/1)
groupBy (String []): ItfSelectBuilder 100% (1/1)100% (23/23)100% (3/3)
having (): SurogateAndOrListSelectBuilder 100% (1/1)100% (3/3)100% (1/1)
innerJoin (ITableName): MultiJoinOnExpr 0%   (0/1)0%   (0/5)0%   (0/1)
innerJoin (ITableName, String): MultiJoinOnExpr 0%   (0/1)0%   (0/6)0%   (0/1)
innerJoin (String): MultiJoinOnExpr 100% (1/1)100% (11/11)100% (1/1)
innerJoin (String, String): MultiJoinOnExpr 100% (1/1)100% (12/12)100% (1/1)
internal_setAlias (String): ItfSelectBuilder 100% (1/1)100% (5/5)100% (2/2)
internal_setIsNestedSelect (): ItfSelectBuilder 100% (1/1)100% (5/5)100% (2/2)
leftJoin (ITableName): MultiJoinOnExpr 0%   (0/1)0%   (0/5)0%   (0/1)
leftJoin (ITableName, String): MultiJoinOnExpr 0%   (0/1)0%   (0/6)0%   (0/1)
leftJoin (String): MultiJoinOnExpr 100% (1/1)100% (11/11)100% (1/1)
leftJoin (String, String): MultiJoinOnExpr 100% (1/1)100% (12/12)100% (1/1)
orderBy (ITableName): ItfSelectBuilder 0%   (0/1)0%   (0/5)0%   (0/1)
orderBy (String): ItfSelectBuilder 100% (1/1)100% (8/8)100% (2/2)
orderByAsc (ITableName): ItfSelectBuilder 0%   (0/1)0%   (0/5)0%   (0/1)
orderByAsc (String): ItfSelectBuilder 100% (1/1)100% (8/8)100% (2/2)
orderByDesc (ITableName): ItfSelectBuilder 0%   (0/1)0%   (0/5)0%   (0/1)
orderByDesc (String): ItfSelectBuilder 100% (1/1)100% (8/8)100% (2/2)
outerJoin (ITableName): MultiJoinOnExpr 0%   (0/1)0%   (0/5)0%   (0/1)
outerJoin (ITableName, String): MultiJoinOnExpr 0%   (0/1)0%   (0/6)0%   (0/1)
outerJoin (String): MultiJoinOnExpr 100% (1/1)100% (11/11)100% (1/1)
outerJoin (String, String): MultiJoinOnExpr 100% (1/1)100% (12/12)100% (1/1)
rightJoin (ITableName): MultiJoinOnExpr 0%   (0/1)0%   (0/5)0%   (0/1)
rightJoin (ITableName, String): MultiJoinOnExpr 0%   (0/1)0%   (0/6)0%   (0/1)
rightJoin (String): MultiJoinOnExpr 100% (1/1)100% (11/11)100% (1/1)
rightJoin (String, String): MultiJoinOnExpr 100% (1/1)100% (12/12)100% (1/1)
select (IColumnName): ItfSelectBuilder 0%   (0/1)0%   (0/5)0%   (0/1)
select (IColumnName, String): ItfSelectBuilder 0%   (0/1)0%   (0/6)0%   (0/1)
select (String): ItfSelectBuilder 100% (1/1)100% (17/17)100% (4/4)
select (String, String): ItfSelectBuilder 100% (1/1)100% (18/18)100% (4/4)
toSql (): String 100% (1/1)100% (11/11)100% (3/3)
toSql (StringBuilder, String): void 100% (1/1)100% (71/71)100% (14/14)
toSqlFrom (StringBuilder, String): void 100% (1/1)71%  (56/79)82%  (14/17)
toSqlGroupBy (StringBuilder, String): void 100% (1/1)100% (26/26)100% (7/7)
toSqlHaving (StringBuilder, String): void 100% (1/1)100% (23/23)100% (7/7)
toSqlOrderBy (StringBuilder, String): void 100% (1/1)100% (6/6)100% (2/2)
toSqlSelect (StringBuilder, String): void 100% (1/1)100% (50/50)100% (10/10)
toSqlWhere (StringBuilder, String): void 100% (1/1)100% (23/23)100% (7/7)
where (): SurogateAndOrListSelectBuilder 100% (1/1)100% (3/3)100% (1/1)

1package org.sqlorm.querybuilder;
2 
3import java.util.ArrayList;
4import java.util.List;
5 
6import org.sqlorm.metadatadumper.IColumnName;
7import org.sqlorm.metadatadumper.ITableName;
8 
9import spiffy.core.lang.StringHelper;
10 
11/**
12 * A class to easily create dynamic SELECT SQL
13 * 
14 * @author kasper graversen
15 * @extends IPositionSelectFrom because you may put a SELECT..FROM..WHERE in a FROM part of a query
16 */
17public class SelectBuilder implements ItfSelectBuilder {
18 
19static final String indentDelta = "    ";
20 
21private final List<IPositionSelectColumn> selectColumns = new ArrayList<IPositionSelectColumn>();
22private final List<IPositionSelectFrom> froms = new ArrayList<IPositionSelectFrom>();
23private final SurogateAndOrListSelectBuilder wheres = new SurogateAndOrListSelectBuilder(this, new AndOrList());
24private final List<String> groupByTableNames = new ArrayList<String>();
25private final SurogateAndOrListSelectBuilder havings = new SurogateAndOrListSelectBuilder(this, new AndOrList());
26private final OrderByList orderBys = new OrderByList();
27 
28private boolean isDistinct = false;
29 
30/** field used when this select-object is a sub-select, e.g. in a from clause where it can be aliased */
31private String selectAlias = "";
32 
33/**
34 * if true, do not add "()" around the entries of the list
35 */
36private boolean isNestedSelect = false;
37 
38public SelectBuilder() {
39        wheres.internal_setIsOutermostList(); // avoid "()" in the where-block
40        havings.internal_setIsOutermostList(); // avoid "()" in the having-block
41}
42 
43private <T> T addList(final T expr, final List<T> list) {
44        T result;
45        final int foundPos = list.indexOf(expr);
46        if(foundPos > -1) {
47                result = list.get(foundPos);
48        }
49        else {
50                list.add(expr);
51                result = expr;
52        }
53        return result;
54}
55 
56public MultiJoinOnExpr crossJoin(ITableName table) {
57        return crossJoin(table.toString());
58}
59 
60public MultiJoinOnExpr crossJoin(ITableName table, String alias) {
61        return crossJoin(table.toString(), alias);
62}
63 
64public MultiJoinOnExpr crossJoin(final String table) {
65        return (MultiJoinOnExpr) addList(new MultiJoinOnExpr(MultiJoinOnExpr.JoinType.CROSS_JOIN, table), froms);
66}
67 
68public MultiJoinOnExpr crossJoin(final String table, final String alias) {
69        return (MultiJoinOnExpr) addList(new MultiJoinOnExpr(MultiJoinOnExpr.JoinType.CROSS_JOIN, table, alias), froms);
70}
71 
72public ItfSelectBuilder distinct() {
73        isDistinct = true;
74        return this;
75}
76 
77public ItfSelectBuilder from(ITableName from) {
78        return from(from.toString());
79}
80 
81public ItfSelectBuilder from(ITableName from, String alias) {
82        return from(from.toString(), alias);
83}
84 
85public ItfSelectBuilder from(final ItfSelectBuilder subSelect, final String alias) {
86        ItfSelectBuilder expr = subSelect.internal_setAlias(alias).internal_setIsNestedSelect();
87        if(froms.contains(expr) == false) {
88                froms.add(expr);
89        }
90        return this;
91 
92}
93 
94public ItfSelectBuilder from(final String from) {
95        TableIdentifierExpr expr = new TableIdentifierExpr(from);
96        if(froms.contains(expr) == false) {
97                froms.add(expr);
98        }
99        return this;
100}
101 
102public ItfSelectBuilder from(final String from, final String alias) {
103        TableIdentifierExpr expr = new TableIdentifierExpr(from, alias);
104        if(froms.contains(expr) == false) {
105                froms.add(expr);
106        }
107        return this;
108}
109 
110public ItfSelectBuilder groupBy(ITableName table) {
111        return groupBy(table.toString());
112}
113 
114/**
115 * @param string
116 * @return
117 */
118public ItfSelectBuilder groupBy(final String... tableNames) {
119        for(final String name : tableNames) {
120                groupByTableNames.add(name);
121        }
122        return this;
123}
124 
125public SurogateAndOrListSelectBuilder having() {
126        return havings;
127}
128 
129public MultiJoinOnExpr innerJoin(ITableName table) {
130        return innerJoin(table.toString());
131}
132 
133public MultiJoinOnExpr innerJoin(ITableName table, String alias) {
134        return innerJoin(table.toString(), alias);
135}
136 
137public MultiJoinOnExpr innerJoin(final String table) {
138        return (MultiJoinOnExpr) addList(new MultiJoinOnExpr(MultiJoinOnExpr.JoinType.INNER_JOIN, table), froms);
139}
140 
141public MultiJoinOnExpr innerJoin(final String table, final String alias) {
142        return (MultiJoinOnExpr) addList(new MultiJoinOnExpr(MultiJoinOnExpr.JoinType.INNER_JOIN, table, alias), froms);
143}
144 
145public ItfSelectBuilder internal_setAlias(final String alias) {
146        this.selectAlias = alias;
147        return this;
148}
149 
150public ItfSelectBuilder internal_setIsNestedSelect() {
151        this.isNestedSelect = true;
152        return this;
153}
154 
155public MultiJoinOnExpr leftJoin(ITableName table) {
156        return leftJoin(table.toString());
157}
158 
159public MultiJoinOnExpr leftJoin(ITableName table, String alias) {
160        return leftJoin(table.toString(), alias);
161}
162 
163public MultiJoinOnExpr leftJoin(final String table) {
164        return (MultiJoinOnExpr) addList(new MultiJoinOnExpr(MultiJoinOnExpr.JoinType.LEFT_JOIN, table), froms);
165}
166 
167public MultiJoinOnExpr leftJoin(final String table, final String alias) {
168        return (MultiJoinOnExpr) addList(new MultiJoinOnExpr(MultiJoinOnExpr.JoinType.LEFT_JOIN, table, alias), froms);
169}
170 
171public ItfSelectBuilder orderBy(ITableName table) {
172        return orderBy(table.toString());
173}
174 
175public ItfSelectBuilder orderBy(final String tableName) {
176        orderBys.add(tableName, OrderByExpr.Ordering.NOTHING);
177        return this;
178}
179 
180public ItfSelectBuilder orderByAsc(ITableName table) {
181        return orderByAsc(table.toString());
182}
183 
184public ItfSelectBuilder orderByAsc(final String tableName) {
185        orderBys.add(tableName, OrderByExpr.Ordering.ASCENDING);
186        return this;
187}
188 
189public ItfSelectBuilder orderByDesc(ITableName table) {
190        return orderByDesc(table.toString());
191}
192 
193public ItfSelectBuilder orderByDesc(final String tableName) {
194        orderBys.add(tableName, OrderByExpr.Ordering.DESCENDING);
195        return this;
196}
197 
198public MultiJoinOnExpr outerJoin(ITableName table) {
199        return outerJoin(table.toString());
200}
201 
202public MultiJoinOnExpr outerJoin(ITableName table, String alias) {
203        return outerJoin(table.toString(), alias);
204}
205 
206public MultiJoinOnExpr outerJoin(final String table) {
207        return (MultiJoinOnExpr) addList(new MultiJoinOnExpr(MultiJoinOnExpr.JoinType.OUTER_JOIN, table), froms);
208}
209 
210public MultiJoinOnExpr outerJoin(final String table, final String alias) {
211        return (MultiJoinOnExpr) addList(new MultiJoinOnExpr(MultiJoinOnExpr.JoinType.OUTER_JOIN, table, alias), froms);
212}
213 
214public MultiJoinOnExpr rightJoin(ITableName table) {
215        return rightJoin(table.toString());
216}
217 
218public MultiJoinOnExpr rightJoin(ITableName table, String alias) {
219        return rightJoin(table.toString(), alias);
220}
221 
222public MultiJoinOnExpr rightJoin(final String table) {
223        return (MultiJoinOnExpr) addList(new MultiJoinOnExpr(MultiJoinOnExpr.JoinType.RIGHT_JOIN, table), froms);
224}
225 
226public MultiJoinOnExpr rightJoin(final String table, final String alias) {
227        return (MultiJoinOnExpr) addList(new MultiJoinOnExpr(MultiJoinOnExpr.JoinType.RIGHT_JOIN, table, alias), froms);
228}
229 
230/**
231 * Select a column
232 * 
233 * @param column
234 *            the column to add to the SELECT part of an SQL expression
235 * @return this
236 */
237public ItfSelectBuilder select(final String column) {
238        ColumnIdentifierExpr expr = new ColumnIdentifierExpr(column);
239        if(selectColumns.contains(expr) == false) {
240                selectColumns.add(expr);
241        }
242        return this;
243}
244 
245/**
246 * Select a column
247 * 
248 * @param column
249 *            The column to add to the SELECT part of an SQL expression
250 * @param alias
251 *            the AS part when aliasing
252 * @return this
253 */
254public ItfSelectBuilder select(final String column, final String alias) {
255        ColumnIdentifierExpr expr = new ColumnIdentifierExpr(column, alias);
256        if(selectColumns.contains(expr) == false) {
257                selectColumns.add(expr);
258        }
259        return this;
260}
261 
262/**
263 * Call this method for generating an SQL expression from your object.
264 * 
265 * @return An SQL expresion
266 */
267public String toSql() {
268        final StringBuilder sb = new StringBuilder();
269        toSql(sb, "");
270        return sb.toString();
271}
272 
273/**
274 * Internal method for sql generation. Use <code>toSql(String)</code> instead.
275 * 
276 * @see toSql()
277 */
278public void toSql(final StringBuilder sb, String indent) {
279        if(isNestedSelect) {
280                sb.append("(\n");
281                indent = indent + indentDelta;
282                sb.append(indent);
283        }
284 
285        toSqlSelect(sb, indent);
286        toSqlFrom(sb, indent);
287        toSqlWhere(sb, indent);
288 
289        toSqlGroupBy(sb, indent);
290        toSqlHaving(sb, indent);
291        toSqlOrderBy(sb, indent);
292        if(isNestedSelect) {
293                sb.append(")");
294        }
295 
296        // selectAlias
297        sb.append(selectAlias.equals("") ? "" : " AS " + selectAlias);
298}
299 
300/**
301 * @param sb
302 * @param indent
303 * @throws IllegalArgumentException
304 */
305protected void toSqlFrom(final StringBuilder sb, final String indent) throws IllegalArgumentException {
306        sb.append("\n");
307        sb.append(indent);
308        sb.append("FROM ");
309        // special case for first entry as it must be a FROM
310        boolean firstEntry = true;
311        for(final IPositionSelectFrom from : froms) {
312                if(firstEntry) {
313                        firstEntry = false;
314                        if(from instanceof TableIdentifierExpr == false && from instanceof SelectBuilder == false) {
315                                final StringBuilder sb2 = new StringBuilder();
316                                from.toSql(sb2, "");
317                                throw new IllegalArgumentException("First entry in a FROM must be a table name! got '" + sb2.toString()
318                                                + "'");
319                        }
320                        from.toSql(sb, "");
321                        continue;
322                }
323 
324                if(from instanceof TableIdentifierExpr || from instanceof SelectBuilder) {
325                        sb.append(", "); // prepend comma on normal table names or subselects, but not for inner join or outer
326                        // join
327                }
328                from.toSql(sb, indent);
329        }
330}
331 
332/**
333 * @param sb
334 * @param indent
335 */
336protected void toSqlGroupBy(final StringBuilder sb, final String indent) {
337        if(groupByTableNames.size() == 0) {
338                return;
339        }
340 
341        sb.append("\n");
342        sb.append(indent);
343        sb.append("GROUP BY ");
344        sb.append(StringHelper.join(",", groupByTableNames.iterator()));
345}
346 
347protected void toSqlHaving(final StringBuilder sb, final String indent) {
348        if(havings.internal_size() == 0) {
349                return;
350        }
351 
352        sb.append("\n");
353        sb.append(indent);
354        sb.append("HAVING ");
355        havings.toSql(sb, indent);
356}
357 
358protected void toSqlOrderBy(final StringBuilder sb, final String indent) {
359        orderBys.toSql(sb, indent);
360}
361 
362/**
363 * @param sb
364 * @param indent
365 */
366protected void toSqlSelect(final StringBuilder sb, final String indent) {
367        sb.append(indent);
368        sb.append("SELECT ");
369 
370        // distinct
371        if(isDistinct) {
372                sb.append("DISTINCT ");
373        }
374 
375        for(final IPositionSelectColumn col : selectColumns) {
376                col.toSql(sb, indent);
377                sb.append(", ");
378        }
379        sb.deleteCharAt(sb.length() - 2); // delete last comma
380        sb.deleteCharAt(sb.length() - 1); // delete last space
381}
382 
383protected void toSqlWhere(final StringBuilder sb, final String indent) {
384        if(wheres.internal_size() == 0) {
385                return;
386        }
387 
388        sb.append("\n");
389        sb.append(indent);
390        sb.append("WHERE ");
391        wheres.toSql(sb, indent);
392}
393 
394public SurogateAndOrListSelectBuilder where() {
395        return wheres;
396}
397 
398public ItfSelectBuilder select(IColumnName column) {
399        return select(column.toString());
400}
401 
402public ItfSelectBuilder select(IColumnName column, String alias) {
403        return select(column.toString(), alias);
404}
405 
406}

[all classes][org.sqlorm.querybuilder]
EMMA 2.0.5312 (C) Vladimir Roubtsov