View Javadoc

1   package org.apache.torque.util.functions;
2   
3   /*
4    * Licensed to the Apache Software Foundation (ASF) under one
5    * or more contributor license agreements.  See the NOTICE file
6    * distributed with this work for additional information
7    * regarding copyright ownership.  The ASF licenses this file
8    * to you under the Apache License, Version 2.0 (the
9    * "License"); you may not use this file except in compliance
10   * with the License.  You may obtain a copy of the License at
11   *
12   *   http://www.apache.org/licenses/LICENSE-2.0
13   *
14   * Unless required by applicable law or agreed to in writing,
15   * software distributed under the License is distributed on an
16   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
17   * KIND, either express or implied.  See the License for the
18   * specific language governing permissions and limitations
19   * under the License.
20   */
21  
22  import org.apache.torque.adapter.DB;
23  
24  /***
25   * <p>A container for classes that will generate SQL for the SQL99 Standard 
26   * Aggregate functions. These can be used via the Criteria.addAsColumn
27   * method to produce SQL statements that can be called via the 
28   * BasePeer.doSelect methods.</p>  
29   * <p>
30   * Note database servers that use non-standard function names  
31   * can be supported by using the setFunction(String) method.</p>
32   * <p>
33   * E.g., older MySQL servers use LEAST instead of MIN. This can be 
34   * supported by creating a Aggregate.Min instance and then calling
35   * the setFunction("LEAST") method.</p>
36   * 
37   * @see org.apache.torque.util.SummaryHelper
38   * @author <a href="mailto:greg.monroe@dukece.com">Greg Monroe</a>
39   * @version $Id
40   */
41  public class Aggregate
42  {
43  
44      /***
45       * The base class for all the standard aggregate function classes.
46       */
47      public abstract class AgregateFunction 
48                          extends AbstractFunction 
49                          implements SQLFunction
50      {
51          /*** Should the column have DISTINCT added before it */
52          private boolean distinct;
53          /*** The function to use */
54          private String function;
55          /*** Flag to determine if arguments have been set */
56          private boolean argumentsSet = false;
57          
58          /***
59           * Base constructor for aggregate functions which must be created
60           * via the FunctionFactory / DB classes.<p>  
61           * 
62           * @see FunctionFactory
63           * @see DB
64           */
65          protected AgregateFunction ( ) 
66          {
67              super();
68          }
69          
70         /***
71          * Assumes that there are one or two arguments being specified.  The
72          * first being a column identifier. (TODO: handle expressions) 
73          * and the second being an optional boolean indicating if DISTINCT 
74          * needs to be added.
75          * 
76          * @param args The column to apply the function to.
77          * @throws IllegalArgumentException If at least one argument has not 
78          *                              been supplied or the second argument 
79          *                              object is not Boolean.
80          */                              
81          public void setArguments( Object[] args )
82                                              throws IllegalArgumentException
83          {
84  
85              if ( args.length < 1 ) 
86              {
87                  throw new IllegalArgumentException(
88                        "There must be at least one argument object specified!");
89              }
90              if ( args.length < 2 ) 
91              {
92                  this.distinct = false;
93              } 
94              else 
95              {
96                  if ( ! ( args[1] instanceof Boolean ) ) 
97                  {
98                      throw new IllegalArgumentException(
99                             "Second argument object is not type Boolean!");
100                 }
101                 this.distinct = ((Boolean) args[1]).booleanValue();
102             }
103             addArgument( args[0].toString() );
104             this.argumentsSet = true;
105         }
106         
107         /***
108          * Should the column have DISTINCT added in front of it?
109          * 
110          * @return True if DISTINCT is needed.
111          */
112         public boolean isDistinct() 
113         {
114             return this.distinct;
115         }
116         
117         /***
118          * Get the function name to use, e.g. AVG, MIN, LEAST.
119          * 
120          * @return The function.
121          */
122         protected String getFunction() 
123         {
124             return this.function;
125         }
126         
127         /***
128          * Set the function to use.
129          *  
130          * @param value The function to use.
131          */
132         public void setFunction( String value ) 
133         {
134             this.function = value;
135         }
136         
137         /***
138          * Generate the SQL for this function.
139          */
140         public String toSQL() 
141                     throws IllegalStateException
142         {
143             if ( ! argumentsSet ) 
144             {
145                 throw new IllegalStateException ( 
146                                "Function arguments have not been set!");
147             }
148             StringBuffer sb = new StringBuffer();
149             sb.append(getFunction()).append("(");
150             if ( isDistinct() ) 
151             {
152                 sb.append("DISTINCT ");
153             }
154             sb.append( getArgument(0).toString() ).append( ")" );
155             return sb.toString();
156         }
157 
158         /* (non-Javadoc)
159          * @see org.apache.torque.util.functions.AbstractFunction#getArgument(int)
160          */
161         public String getArgument(int index)
162         {
163             return (String) getArgumentObject(index);
164         }
165         
166     }
167 
168     /***
169      * SQL99 Standard Average a column function.
170      */
171     public class Avg extends Aggregate.AgregateFunction
172     {
173         /***
174          * Construct an AVG function class.
175          * 
176          * @see Aggregate.AgregateFunction
177          * @see FunctionFactory
178          */
179         protected Avg() 
180         {
181             super();
182             setFunction("AVG");
183         }
184     }
185 
186     /***
187      * SQL99 Standard Count records function.
188      */
189     public class Count extends Aggregate.AgregateFunction 
190     {
191         /***
192          * Construct a COUNT function class.
193          * 
194          * @see Aggregate.AgregateFunction
195          * @see FunctionFactory
196          */
197         protected Count() 
198         {
199             super();
200             setFunction("COUNT");
201         }
202     }
203 
204     /***
205      * SQL99 Standard Minimum value of column function.
206      */
207     public class Min extends Aggregate.AgregateFunction 
208     {
209         /***
210          * Construct a MIN function class.
211          * 
212          * @see Aggregate.AgregateFunction
213          * @see FunctionFactory
214          */
215         protected Min() 
216         {
217             super();
218             setFunction("MIN");
219         }
220     }
221 
222     /***
223      * SQL99 Standard maximum value of column function.
224      */
225     public class Max extends Aggregate.AgregateFunction 
226     {
227         /***
228          * Construct a MAX function class.
229          * 
230          * @see FunctionFactory
231          * @see Aggregate.AgregateFunction
232          */
233         protected Max( ) 
234         {
235             super();
236             setFunction("MAX");
237         }
238     }
239 
240     /***
241      * SQL99 Standard sum column values function.
242      */
243     public class Sum extends Aggregate.AgregateFunction 
244     {
245         /***
246          * Construct a SUM function class.
247          * 
248          * @see FunctionFactory
249          * @see Aggregate.AgregateFunction
250          */
251         protected Sum( ) 
252         {
253             super();
254             setFunction("SUM");
255         }
256     }
257 }