View Javadoc

1   package org.apache.torque.util;
2   
3   /* ====================================================================
4    * The Apache Software License, Version 1.1
5    *
6    * Copyright (c) 2001-2003 The Apache Software Foundation.  All rights
7    * reserved.
8    *
9    * Redistribution and use in source and binary forms, with or without
10   * modification, are permitted provided that the following conditions
11   * are met:
12   *
13   * 1. Redistributions of source code must retain the above copyright
14   *    notice, this list of conditions and the following disclaimer.
15   *
16   * 2. Redistributions in binary form must reproduce the above copyright
17   *    notice, this list of conditions and the following disclaimer in
18   *    the documentation and/or other materials provided with the
19   *    distribution.
20   *
21   * 3. The end-user documentation included with the redistribution,
22   *    if any, must include the following acknowledgment:
23   *       "This product includes software developed by the
24   *        Apache Software Foundation (http://www.apache.org/)."
25   *    Alternately, this acknowledgment may appear in the software itself,
26   *    if and wherever such third-party acknowledgments normally appear.
27   *
28   * 4. The names "Apache" and "Apache Software Foundation" and
29   *    "Apache Turbine" must not be used to endorse or promote products
30   *    derived from this software without prior written permission. For
31   *    written permission, please contact apache@apache.org.
32   *
33   * 5. Products derived from this software may not be called "Apache",
34   *    "Apache Turbine", nor may "Apache" appear in their name, without
35   *    prior written permission of the Apache Software Foundation.
36   *
37   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
38   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
39   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
40   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
41   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
42   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
43   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
44   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
45   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
46   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
47   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
48   * SUCH DAMAGE.
49   * ====================================================================
50   *
51   * This software consists of voluntary contributions made by many
52   * individuals on behalf of the Apache Software Foundation.  For more
53   * information on the Apache Software Foundation, please see
54   * <http://www.apache.org/>.
55   */
56  
57  import org.apache.commons.lang.StringUtils;
58  
59  /***
60   * Used to assemble an SQL SELECT query.  Attributes exist for the
61   * sections of a SELECT: modifiers, columns, from clause, where
62   * clause, and order by clause.  The various parts of the query are
63   * appended to buffers which only accept unique entries.  This class
64   * is used primarily by BasePeer.
65   *
66   * @author <a href="mailto:jmcnally@collab.net">John D. McNally</a>
67   * @author <a href="mailto:sam@neurogrid.com">Sam Joseph</a>
68   * @author <a href="mailto:mpoeschl@marmot.at">Martin Poeschl</a>
69   * @version $Id: Query.java,v 1.12 2003/03/24 21:53:42 mpoeschl Exp $
70   */
71  public class Query
72  {
73      private static final String SELECT = "SELECT ";
74      private static final String FROM = " FROM ";
75      private static final String WHERE = " WHERE ";
76      private static final String AND = " AND ";
77      private static final String ORDER_BY = " ORDER BY ";
78      private static final String GROUP_BY = " GROUP BY ";
79      private static final String HAVING = " HAVING ";
80      private static final String LIMIT = " LIMIT ";
81      private static final String ROWCOUNT = " SET ROWCOUNT ";
82  
83      private UniqueList selectModifiers = new UniqueList();
84      private UniqueList selectColumns = new UniqueList();
85      private UniqueList fromTables = new UniqueList();
86      private UniqueList whereCriteria = new UniqueList();
87      private UniqueList orderByColumns = new UniqueList();
88      private UniqueList groupByColumns = new UniqueList();
89      private String having;
90      private String limit;
91      private String rowcount;
92  
93      /***
94       * Retrieve the modifier buffer in order to add modifiers to this
95       * query.  E.g. DISTINCT and ALL.
96       *
97       * @return An UniqueList used to add modifiers.
98       */
99      public UniqueList getSelectModifiers()
100     {
101         return selectModifiers;
102     }
103 
104     /***
105      * Set the modifiers. E.g. DISTINCT and ALL.
106      *
107      * @param modifiers the modifiers
108      */
109     public void setSelectModifiers(UniqueList modifiers)
110     {
111         selectModifiers = modifiers;
112     }
113 
114     /***
115      * Retrieve the columns buffer in order to specify which columns
116      * are returned in this query.
117      *
118      *
119      * @return An UniqueList used to add columns to be selected.
120      */
121     public UniqueList getSelectClause()
122     {
123         return selectColumns;
124     }
125 
126     /***
127      * Set the columns.
128      *
129      * @param columns columns list
130      */
131     public void setSelectClause(UniqueList columns)
132     {
133         selectColumns = columns;
134     }
135 
136     /***
137      * Retrieve the from buffer in order to specify which tables are
138      * involved in this query.
139      *
140      * @return An UniqueList used to add tables involved in the query.
141      */
142     public UniqueList getFromClause()
143     {
144         return fromTables;
145     }
146 
147     /***
148      * Set the from clause.
149      *
150      * @param tables the tables
151      */
152     public void setFromClause(UniqueList tables)
153     {
154         fromTables = tables;
155     }
156 
157     /***
158      * Retrieve the where buffer in order to specify the selection
159      * criteria E.g. column_a=3.  Expressions added to the buffer will
160      * be separated using AND.
161      *
162      * @return An UniqueList used to add selection criteria.
163      */
164     public UniqueList getWhereClause()
165     {
166         return whereCriteria;
167     }
168 
169     /***
170      * Set the where clause.
171      *
172      * @param where where clause
173      */
174     public void setWhereClause(UniqueList where)
175     {
176         whereCriteria = where;
177     }
178 
179     /***
180      * Retrieve the order by columns buffer in order to specify which
181      * columns are used to sort the results of the query.
182      *
183      * @return An UniqueList used to add columns to sort on.
184      */
185     public UniqueList getOrderByClause()
186     {
187         return orderByColumns;
188     }
189 
190     /***
191      * Retrieve the group by columns buffer in order to specify which
192      * columns are used to group the results of the query.
193      *
194      * @return An UniqueList used to add columns to group on.
195      */
196     public UniqueList getGroupByClause()
197     {
198         return groupByColumns;
199     }
200 
201     /***
202      * Set the having clause.  This is used to restrict which rows
203      * are returned.
204      *
205      * @param having A String.
206      */
207     public void setHaving(String having)
208     {
209         this.having = having;
210     }
211 
212     /***
213      * Set the limit number.  This is used to limit the number of rows
214      * returned by a query, and the row where the resultset starts.
215      *
216      * @param limit A String.
217      */
218     public void setLimit(String limit)
219     {
220         this.limit = limit;
221     }
222 
223     /***
224      * Set the rowcount number.  This is used to limit the number of
225      * rows returned by Sybase and MS SQL/Server.
226      *
227      * @param rowcount A String.
228      */
229     public void setRowcount(String rowcount)
230     {
231         this.rowcount = rowcount;
232     }
233 
234     /***
235      * Get the having clause.  This is used to restrict which
236      * rows are returned based on some condition.
237      *
238      * @return A String that is the having clause.
239      */
240     public String getHaving()
241     {
242         return having;
243     }
244 
245     /***
246      * Get the limit number.  This is used to limit the number of
247      * returned by a query in Postgres.
248      *
249      * @return A String with the limit.
250      */
251     public String getLimit()
252     {
253         return limit;
254     }
255 
256     /***
257      * Get the rowcount number.  This is used to limit the number of
258      * returned by a query in Sybase and MS SQL/Server.
259      *
260      * @return A String with the row count.
261      */
262     public String getRowcount()
263     {
264         return rowcount;
265     }
266 
267     /***
268      * Outputs the query statement.
269      *
270      * @return A String with the query statement.
271      */
272     public String toString()
273     {
274         StringBuffer stmt = new StringBuffer();
275         if (rowcount != null)
276         {
277             stmt.append(ROWCOUNT)
278                 .append(rowcount)
279                 .append(" ");
280         }
281         stmt.append(SELECT)
282             .append(StringUtils.join(selectModifiers.iterator(), " "))
283             .append(StringUtils.join(selectColumns.iterator(), ", "))
284             .append(FROM)
285             .append(StringUtils.join(fromTables.iterator(), ", "));
286         if (!whereCriteria.isEmpty())
287         {
288             stmt.append(WHERE)
289                 .append(StringUtils.join(whereCriteria.iterator(), AND));
290         }
291         if (!groupByColumns.isEmpty())
292         {
293             stmt.append(GROUP_BY)
294                 .append(StringUtils.join(groupByColumns.iterator(), ", "));
295         }
296         if (having != null)
297         {
298             stmt.append(HAVING)
299                 .append(having);
300         }
301         if (!orderByColumns.isEmpty())
302         {
303             stmt.append(ORDER_BY)
304                 .append(StringUtils.join(orderByColumns.iterator(), ", "));
305         }
306         if (limit != null)
307         {
308             stmt.append(LIMIT)
309                 .append(limit);
310         }
311         if (rowcount != null)
312         {
313             stmt.append(ROWCOUNT)
314                 .append("0");
315         }
316         return stmt.toString();
317     }
318 }