Coverage report

  %line %branch
org.apache.torque.util.Query
74% 
100% 

 1  
 package org.apache.torque.util;
 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 java.util.Iterator;
 23  
 
 24  
 import org.apache.commons.lang.StringUtils;
 25  
 
 26  
 /**
 27  
  * Used to assemble an SQL SELECT query.  Attributes exist for the
 28  
  * sections of a SELECT: modifiers, columns, from clause, where
 29  
  * clause, and order by clause.  The various parts of the query are
 30  
  * appended to buffers which only accept unique entries.  This class
 31  
  * is used primarily by BasePeer.
 32  
  *
 33  
  * @author <a href="mailto:jmcnally@collab.net">John D. McNally</a>
 34  
  * @author <a href="mailto:sam@neurogrid.com">Sam Joseph</a>
 35  
  * @author <a href="mailto:mpoeschl@marmot.at">Martin Poeschl</a>
 36  
  * @author <a href="mailto:fischer@seitenbau.de">Thomas Fischer</a>
 37  
  * @version $Id: Query.java 522044 2007-03-24 16:00:57Z tfischer $
 38  
  */
 39  120
 public class Query
 40  
 {
 41  
     private static final String SELECT = "SELECT ";
 42  
     private static final String FROM = " FROM ";
 43  
     private static final String WHERE = " WHERE ";
 44  
     private static final String AND = " AND ";
 45  
     private static final String ORDER_BY = " ORDER BY ";
 46  
     private static final String GROUP_BY = " GROUP BY ";
 47  
     private static final String HAVING = " HAVING ";
 48  
     private static final String LIMIT = " LIMIT ";
 49  
     private static final String OFFSET = " OFFSET ";
 50  
     private static final String ROWCOUNT = " SET ROWCOUNT ";
 51  
 
 52  120
     private UniqueList selectModifiers = new UniqueList();
 53  120
     private UniqueList selectColumns = new UniqueList();
 54  120
     private UniqueList fromTables = new UniqueList();
 55  120
     private UniqueList whereCriteria = new UniqueList();
 56  120
     private UniqueList orderByColumns = new UniqueList();
 57  120
     private UniqueList groupByColumns = new UniqueList();
 58  
     private String having;
 59  
     private String limit;
 60  
     private String preLimit;
 61  
     private String postLimit;
 62  
     private String offset;
 63  
     private String rowcount;
 64  
 
 65  
     /**
 66  
      * Retrieve the modifier buffer in order to add modifiers to this
 67  
      * query.  E.g. DISTINCT and ALL.
 68  
      *
 69  
      * @return An UniqueList used to add modifiers.
 70  
      */
 71  
     public UniqueList getSelectModifiers()
 72  
     {
 73  102
         return selectModifiers;
 74  
     }
 75  
 
 76  
     /**
 77  
      * Set the modifiers. E.g. DISTINCT and ALL.
 78  
      *
 79  
      * @param modifiers the modifiers
 80  
      */
 81  
     public void setSelectModifiers(UniqueList modifiers)
 82  
     {
 83  0
         selectModifiers = modifiers;
 84  0
     }
 85  
 
 86  
     /**
 87  
      * Retrieve the columns buffer in order to specify which columns
 88  
      * are returned in this query.
 89  
      *
 90  
      *
 91  
      * @return An UniqueList used to add columns to be selected.
 92  
      */
 93  
     public UniqueList getSelectClause()
 94  
     {
 95  354
         return selectColumns;
 96  
     }
 97  
 
 98  
     /**
 99  
      * Set the columns.
 100  
      *
 101  
      * @param columns columns list
 102  
      */
 103  
     public void setSelectClause(UniqueList columns)
 104  
     {
 105  36
         selectColumns = columns;
 106  36
     }
 107  
 
 108  
     /**
 109  
      * Retrieve the from buffer in order to specify which tables are
 110  
      * involved in this query.
 111  
      *
 112  
      * @return An UniqueList used to add tables involved in the query.
 113  
      */
 114  
     public UniqueList getFromClause()
 115  
     {
 116  156
         return fromTables;
 117  
     }
 118  
 
 119  
     /**
 120  
      * Set the from clause.
 121  
      *
 122  
      * @param tables the tables
 123  
      */
 124  
     public void setFromClause(UniqueList tables)
 125  
     {
 126  6
         fromTables = tables;
 127  6
     }
 128  
 
 129  
     /**
 130  
      * Retrieve the where buffer in order to specify the selection
 131  
      * criteria E.g. column_a=3.  Expressions added to the buffer will
 132  
      * be separated using AND.
 133  
      *
 134  
      * @return An UniqueList used to add selection criteria.
 135  
      */
 136  
     public UniqueList getWhereClause()
 137  
     {
 138  108
         return whereCriteria;
 139  
     }
 140  
 
 141  
     /**
 142  
      * Set the where clause.
 143  
      *
 144  
      * @param where where clause
 145  
      */
 146  
     public void setWhereClause(UniqueList where)
 147  
     {
 148  6
         whereCriteria = where;
 149  6
     }
 150  
 
 151  
     /**
 152  
      * Retrieve the order by columns buffer in order to specify which
 153  
      * columns are used to sort the results of the query.
 154  
      *
 155  
      * @return An UniqueList used to add columns to sort on.
 156  
      */
 157  
     public UniqueList getOrderByClause()
 158  
     {
 159  102
         return orderByColumns;
 160  
     }
 161  
 
 162  
     /**
 163  
      * Retrieve the group by columns buffer in order to specify which
 164  
      * columns are used to group the results of the query.
 165  
      *
 166  
      * @return An UniqueList used to add columns to group on.
 167  
      */
 168  
     public UniqueList getGroupByClause()
 169  
     {
 170  102
         return groupByColumns;
 171  
     }
 172  
 
 173  
     /**
 174  
      * Set the having clause.  This is used to restrict which rows
 175  
      * are returned.
 176  
      *
 177  
      * @param having A String.
 178  
      */
 179  
     public void setHaving(String having)
 180  
     {
 181  0
         this.having = having;
 182  0
     }
 183  
 
 184  
     /**
 185  
      * Set the limit number.  This is used to limit the number of rows
 186  
      * returned by a query.
 187  
      *
 188  
      * @param limit A String.
 189  
      */
 190  
     public void setLimit(String limit)
 191  
     {
 192  60
         this.limit = limit;
 193  60
     }
 194  
 
 195  
     /**
 196  
      * Get the Pre limit String. Oracle and DB2 want to encapsulate
 197  
      * a query into a subquery for limiting.
 198  
      *
 199  
      * @param preLimit A String with the preLimit.
 200  
      */
 201  
     public void setPreLimit(String preLimit)
 202  
     {
 203  60
         this.preLimit = preLimit;
 204  60
     }
 205  
 
 206  
     /**
 207  
      * Set the Post limit String. Oracle and DB2 want to encapsulate
 208  
      * a query into a subquery for limiting.
 209  
      *
 210  
      * @param postLimit A String with the postLimit.
 211  
      */
 212  
     public void setPostLimit(String postLimit)
 213  
     {
 214  60
         this.postLimit = postLimit;
 215  60
     }
 216  
 
 217  
     /**
 218  
      * Set the offset number.  This is used to set the row where the 
 219  
      * resultset starts.
 220  
      *
 221  
      * @param offset A String.
 222  
      */
 223  
     public void setOffset(String offset)
 224  
     {
 225  24
         this.offset = offset;
 226  24
     }
 227  
 
 228  
     /**
 229  
      * Set the rowcount number.  This is used to limit the number of
 230  
      * rows returned by Sybase and MS SQL/Server.
 231  
      *
 232  
      * @param rowcount A String.
 233  
      */
 234  
     public void setRowcount(String rowcount)
 235  
     {
 236  0
         this.rowcount = rowcount;
 237  0
     }
 238  
 
 239  
     /**
 240  
      * Get the having clause.  This is used to restrict which
 241  
      * rows are returned based on some condition.
 242  
      *
 243  
      * @return A String that is the having clause.
 244  
      */
 245  
     public String getHaving()
 246  
     {
 247  0
         return having;
 248  
     }
 249  
 
 250  
     /**
 251  
      * Get the limit number.  This is used to limit the number of
 252  
      * returned by a query in Postgres.
 253  
      *
 254  
      * @return A String with the limit.
 255  
      */
 256  
     public String getLimit()
 257  
     {
 258  0
         return limit;
 259  
     }
 260  
 
 261  
     /**
 262  
      * Get the Post limit String. Oracle and DB2 want to encapsulate
 263  
      * a query into a subquery for limiting.
 264  
      *
 265  
      * @return A String with the preLimit.
 266  
      */
 267  
     public String getPostLimit()
 268  
     {
 269  0
         return postLimit;
 270  
     }
 271  
 
 272  
     /**
 273  
      * Get the Pre limit String. Oracle and DB2 want to encapsulate
 274  
      * a query into a subquery for limiting.
 275  
      *
 276  
      * @return A String with the preLimit.
 277  
      */
 278  
     public String getPreLimit()
 279  
     {
 280  0
         return preLimit;
 281  
     }
 282  
 
 283  
     /**
 284  
      * Get the offset number.  This is used to set the row where the 
 285  
      * resultset starts.
 286  
      *
 287  
      * @return A String with the offset, or null if no offset is set.
 288  
      */
 289  
     public String getOffset()
 290  
     {
 291  0
         return offset;
 292  
     }
 293  
 
 294  
     /**
 295  
      * True if this query has a limit clause registered.
 296  
      *
 297  
      * @return true if a limit clause exists.
 298  
      */
 299  
     public boolean hasLimit()
 300  
     {
 301  0
         return ((preLimit != null)
 302  
                 || (postLimit != null)
 303  
                 || (limit != null));
 304  
     }
 305  
 
 306  
     /**
 307  
      * Get the rowcount number.  This is used to limit the number of
 308  
      * returned by a query in Sybase and MS SQL/Server.
 309  
      *
 310  
      * @return A String with the row count.
 311  
      */
 312  
     public String getRowcount()
 313  
     {
 314  0
         return rowcount;
 315  
     }
 316  
 
 317  
     /**
 318  
      * Outputs the query statement.
 319  
      *
 320  
      * @return A String with the query statement.
 321  
      */
 322  
     public String toString()
 323  
     {
 324  216
         return toStringBuffer(new StringBuffer()).toString();
 325  
     }
 326  
 
 327  
     public StringBuffer toStringBuffer(StringBuffer stmt)
 328  
     {
 329  216
         if (preLimit != null)
 330  
         {
 331  0
             stmt.append(preLimit);
 332  
         }
 333  
 
 334  216
         if (rowcount != null)
 335  
         {
 336  0
             stmt.append(ROWCOUNT)
 337  
                 .append(rowcount)
 338  
                 .append(" ");
 339  
         }
 340  216
         stmt.append(SELECT)
 341  
             .append(StringUtils.join(selectModifiers.iterator(), " "))
 342  
             .append(StringUtils.join(selectColumns.iterator(), ", "))
 343  
             .append(FROM);
 344  
 
 345  216
         boolean first = true;
 346  216
         for (Iterator it = fromTables.iterator(); it.hasNext();)
 347  
         {
 348  228
             FromElement fromElement = (FromElement) it.next();
 349  
 
 350  228
             if (!first && fromElement.getJoinCondition() == null)
 351  
             {
 352  18
                 stmt.append(", ");
 353  
             }
 354  228
             first = false;
 355  228
             stmt.append(fromElement.toString());
 356  114
         }
 357  
 
 358  216
         if (!whereCriteria.isEmpty())
 359  
         {
 360  210
             stmt.append(WHERE)
 361  
                 .append(StringUtils.join(whereCriteria.iterator(), AND));
 362  
         }
 363  216
         if (!groupByColumns.isEmpty())
 364  
         {
 365  0
             stmt.append(GROUP_BY)
 366  
                 .append(StringUtils.join(groupByColumns.iterator(), ", "));
 367  
         }
 368  216
         if (having != null)
 369  
         {
 370  0
             stmt.append(HAVING)
 371  
                 .append(having);
 372  
         }
 373  216
         if (!orderByColumns.isEmpty())
 374  
         {
 375  12
             stmt.append(ORDER_BY)
 376  
                 .append(StringUtils.join(orderByColumns.iterator(), ", "));
 377  
         }
 378  216
         if (limit != null)
 379  
         {
 380  72
             stmt.append(LIMIT)
 381  
                 .append(limit);
 382  
         }
 383  216
         if (offset != null)
 384  
         {
 385  48
             stmt.append(OFFSET)
 386  
                 .append(offset);
 387  
         }
 388  216
         if (rowcount != null)
 389  
         {
 390  0
             stmt.append(ROWCOUNT)
 391  
                 .append("0");
 392  
         }
 393  216
         if (postLimit != null)
 394  
         {
 395  0
             stmt.append(postLimit);
 396  
         }
 397  
 
 398  216
         return stmt;
 399  
     }
 400  
 
 401  
     /**
 402  
      * This class describes an Element in the From-part of a SQL clause.
 403  
      * It must contain the name of the database table.
 404  
      * It might contain an alias for the table name, a join type
 405  
      * and a join condition.
 406  
      * The class is package visible, as it is used in BasePeer,
 407  
      * and is immutable.
 408  
      */
 409  120
     public static class FromElement
 410  
     {
 411  
 
 412  
         /** the tablename, might contain an appended alias name */
 413  
         private String tableName = null;
 414  
 
 415  
         /** the type of the join, e.g. SqlEnum.LEFT_JOIN */
 416  
         private SqlEnum joinType = null;
 417  
 
 418  
         /** the join condition, e.g. table_a.id = table_b.a_id */
 419  
         private String joinCondition = null;
 420  
 
 421  
         /**
 422  
          * Constructor
 423  
          * @param tableName the tablename, might contain an appended alias name
 424  
          *        e.g. <br />
 425  
          *        table_1<br />
 426  
          *        table_1 alias_for_table_1
 427  
          * @param joinType the type of the join, e.g. SqlEnum.LEFT_JOIN,
 428  
          *        or null if no excplicit join is wanted
 429  
          * @param joinCondition the join condition,
 430  
          *        e.g. table_a.id = table_b.a_id,
 431  
          *        or null if no explicit join is wanted
 432  
          *        (In this case, the join condition is appended to the
 433  
          *         whereClause instead)
 434  
          */
 435  
         public FromElement(String tableName,
 436  
                 SqlEnum joinType,
 437  
                 String joinCondition)
 438  
         {
 439  
             this.tableName = tableName;
 440  
             this.joinType = joinType;
 441  
             this.joinCondition = joinCondition;
 442  
         }
 443  
 
 444  
 
 445  
         /**
 446  
          * @return the join condition, e.g. table_a.id = table_b.a_id,
 447  
          *         or null if the join is not an explicit join
 448  
          */
 449  
         public String getJoinCondition()
 450  
         {
 451  
             return joinCondition;
 452  
         }
 453  
 
 454  
         /**
 455  
          * @return the type of the join, e.g. SqlEnum.LEFT_JOIN,
 456  
          *         or null if the join is not an explicit join
 457  
          */
 458  
         public SqlEnum getJoinType()
 459  
         {
 460  
             return joinType;
 461  
         }
 462  
 
 463  
         /**
 464  
          * @return the tablename, might contain an appended alias name,
 465  
          *         e.g. <br />
 466  
          *         table_1<br />
 467  
          *         table_1 alias_for_table_1
 468  
          *
 469  
          */
 470  
         public String getTableName()
 471  
         {
 472  
             return tableName;
 473  
         }
 474  
 
 475  
         /**
 476  
          * Returns a SQL representation of the element
 477  
          * @return a SQL representation of the element
 478  
          */
 479  
         public String toString()
 480  
         {
 481  
             StringBuffer result = new StringBuffer();
 482  
             if (joinType != null)
 483  
             {
 484  
                 result.append(joinType);
 485  
             }
 486  
             result.append(tableName);
 487  
             if (joinCondition != null)
 488  
             {
 489  
                 result.append(SqlEnum.ON);
 490  
                 result.append(joinCondition);
 491  
             }
 492  
             return result.toString();
 493  
         }
 494  
     } // end of inner class FromElement
 495  
 }

This report is generated by jcoverage, Maven and Maven JCoverage Plugin.