propel-util
[ class tree: propel-util ] [ index: propel-util ] [ all elements ]

Source for file Criteria.php

Documentation is available at Criteria.php

  1. <?php
  2. /*
  3.  *  $Id: Criteria.php 816 2007-11-18 23:29:44Z heltem $
  4.  *
  5.  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  6.  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  7.  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  8.  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
  9.  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  10.  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  11.  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  12.  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  13.  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  14.  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  15.  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  16.  *
  17.  * This software consists of voluntary contributions made by many individuals
  18.  * and is licensed under the LGPL. For more information please see
  19.  * <http://propel.phpdb.org>.
  20.  */
  21.  
  22. /**
  23.  * This is a utility class for holding criteria information for a query.
  24.  *
  25.  * BasePeer constructs SQL statements based on the values in this class.
  26.  *
  27.  * @author     Hans Lellelid <hans@xmpl.org> (Propel)
  28.  * @author     Kaspars Jaudzems <kaspars.jaudzems@inbox.lv> (Propel)
  29.  * @author     Frank Y. Kim <frank.kim@clearink.com> (Torque)
  30.  * @author     John D. McNally <jmcnally@collab.net> (Torque)
  31.  * @author     Brett McLaughlin <bmclaugh@algx.net> (Torque)
  32.  * @author     Eric Dobbs <eric@dobbse.net> (Torque)
  33.  * @author     Henning P. Schmiedehausen <hps@intermeta.de> (Torque)
  34.  * @author     Sam Joseph <sam@neurogrid.com> (Torque)
  35.  * @version    $Revision: 816 $
  36.  * @package    propel.util
  37.  */
  38. class Criteria implements IteratorAggregate {
  39.  
  40.     /** Comparison type. */
  41.     const EQUAL "=";
  42.  
  43.     /** Comparison type. */
  44.     const NOT_EQUAL "<>";
  45.  
  46.     /** Comparison type. */
  47.     const ALT_NOT_EQUAL "!=";
  48.  
  49.     /** Comparison type. */
  50.     const GREATER_THAN ">";
  51.  
  52.     /** Comparison type. */
  53.     const LESS_THAN "<";
  54.  
  55.     /** Comparison type. */
  56.     const GREATER_EQUAL ">=";
  57.  
  58.     /** Comparison type. */
  59.     const LESS_EQUAL "<=";
  60.  
  61.     /** Comparison type. */
  62.     const LIKE " LIKE ";
  63.  
  64.     /** Comparison type. */
  65.     const NOT_LIKE " NOT LIKE ";
  66.  
  67.     /** PostgreSQL comparison type */
  68.     const ILIKE " ILIKE ";
  69.  
  70.     /** PostgreSQL comparison type */
  71.     const NOT_ILIKE " NOT ILIKE ";
  72.  
  73.     /** Comparison type. */
  74.     const CUSTOM "CUSTOM";
  75.  
  76.     /** Comparison type. */
  77.     const DISTINCT "DISTINCT ";
  78.  
  79.     /** Comparison type. */
  80.     const IN " IN ";
  81.  
  82.     /** Comparison type. */
  83.     const NOT_IN " NOT IN ";
  84.  
  85.     /** Comparison type. */
  86.     const ALL "ALL ";
  87.  
  88.     /** Comparison type. */
  89.     const JOIN "JOIN";
  90.  
  91.     /** Binary math operator: AND */
  92.     const BINARY_AND "&";
  93.  
  94.     /** Binary math operator: OR */
  95.     const BINARY_OR "|";
  96.  
  97.     /** "Order by" qualifier - ascending */
  98.     const ASC "ASC";
  99.  
  100.     /** "Order by" qualifier - descending */
  101.     const DESC "DESC";
  102.  
  103.     /** "IS NULL" null comparison */
  104.     const ISNULL " IS NULL ";
  105.  
  106.     /** "IS NOT NULL" null comparison */
  107.     const ISNOTNULL " IS NOT NULL ";
  108.  
  109.     /** "CURRENT_DATE" ANSI SQL function */
  110.     const CURRENT_DATE "CURRENT_DATE";
  111.  
  112.     /** "CURRENT_TIME" ANSI SQL function */
  113.     const CURRENT_TIME "CURRENT_TIME";
  114.  
  115.     /** "CURRENT_TIMESTAMP" ANSI SQL function */
  116.     const CURRENT_TIMESTAMP "CURRENT_TIMESTAMP";
  117.  
  118.     /** "LEFT JOIN" SQL statement */
  119.     const LEFT_JOIN "LEFT JOIN";
  120.  
  121.     /** "RIGHT JOIN" SQL statement */
  122.     const RIGHT_JOIN "RIGHT JOIN";
  123.  
  124.     /** "INNER JOIN" SQL statement */
  125.     const INNER_JOIN "INNER JOIN";
  126.  
  127.     private $ignoreCase false;
  128.     private $singleRecord false;
  129.     private $selectModifiers array();
  130.     private $selectColumns array();
  131.     private $orderByColumns array();
  132.     private $groupByColumns array();
  133.     private $having null;
  134.     private $asColumns array();
  135.     private $joins array();
  136.  
  137.     /** The name of the database. */
  138.     private $dbName;
  139.  
  140.     /** The name of the database as given in the contructor. */
  141.     private $originalDbName;
  142.  
  143.     /**
  144.      * To limit the number of rows to return.  <code>0</code> means return all
  145.      * rows.
  146.      */
  147.     private $limit 0;
  148.  
  149.     /** To start the results at a row other than the first one. */
  150.     private $offset 0;
  151.  
  152.     // flag to note that the criteria involves a blob.
  153.     private $blobFlag null;
  154.  
  155.     private $aliases array();
  156.  
  157.     private $useTransaction false;
  158.  
  159.     /**
  160.      * Primary storage of criteria data.
  161.      * @var        array 
  162.      */
  163.     private $map array();
  164.  
  165.     /**
  166.      * Creates a new instance with the default capacity which corresponds to
  167.      * the specified database.
  168.      *
  169.      * @param      dbName The dabase name.
  170.      */
  171.     public function __construct($dbName null)
  172.     {
  173.         $this->setDbName($dbName);
  174.         $this->originalDbName $dbName;
  175.     }
  176.  
  177.     /**
  178.      * Implementing SPL IteratorAggregate interface.  This allows
  179.      * you to foreach () over a Criteria object.
  180.      */
  181.     public function getIterator()
  182.     {
  183.         return new CriterionIterator($this);
  184.     }
  185.  
  186.     /**
  187.      * Get the criteria map.
  188.      * @return     array 
  189.      */
  190.     public function getMap()
  191.     {
  192.         return $this->map;
  193.     }
  194.  
  195.     /**
  196.      * Brings this criteria back to its initial state, so that it
  197.      * can be reused as if it was new. Except if the criteria has grown in
  198.      * capacity, it is left at the current capacity.
  199.      * @return     void 
  200.      */
  201.     public function clear()
  202.     {
  203.         $this->map array();
  204.         $this->ignoreCase false;
  205.         $this->singleRecord false;
  206.         $this->selectModifiers array();
  207.         $this->selectColumns array();
  208.         $this->orderByColumns array();
  209.         $this->groupByColumns array();
  210.         $this->having null;
  211.         $this->asColumns array();
  212.         $this->joins array();
  213.         $this->dbName $this->originalDbName;
  214.         $this->offset 0;
  215.         $this->limit = -1;
  216.         $this->blobFlag null;
  217.         $this->aliases array();
  218.         $this->useTransaction false;
  219.     }
  220.  
  221.     /**
  222.      * Add an AS clause to the select columns. Usage:
  223.      *
  224.      * <code>
  225.      * Criteria myCrit = new Criteria();
  226.      * myCrit->addAsColumn("alias", "ALIAS(".MyPeer::ID.")");
  227.      * </code>
  228.      *
  229.      * @param      string $name Wanted Name of the column (alias).
  230.      * @param      string $clause SQL clause to select from the table
  231.      *
  232.      *  If the name already exists, it is replaced by the new clause.
  233.      *
  234.      * @return     Criteria A modified Criteria object.
  235.      */
  236.     public function addAsColumn($name$clause)
  237.     {
  238.         $this->asColumns[$name$clause;
  239.         return $this;
  240.     }
  241.  
  242.     /**
  243.      * Get the column aliases.
  244.      *
  245.      * @return     array An assoc array which map the column alias names
  246.      *  to the alias clauses.
  247.      */
  248.     public function getAsColumns()
  249.     {
  250.         return $this->asColumns;
  251.     }
  252.  
  253.         /**
  254.      * Returns the column name associated with an alias (AS-column).
  255.      *
  256.      * @param      string $alias 
  257.      * @return     string $string
  258.      */
  259.     public function getColumnForAs($as)
  260.     {
  261.         if (isset($this->asColumns[$as])) {
  262.             return $this->asColumns[$as];
  263.         }
  264.     }
  265.  
  266.     /**
  267.      * Allows one to specify an alias for a table that can
  268.      * be used in various parts of the SQL.
  269.      *
  270.      * @param      string $alias 
  271.      * @param      string $table 
  272.      * @return     void 
  273.      */
  274.     public function addAlias($alias$table)
  275.     {
  276.         $this->aliases[$alias$table;
  277.     }
  278.  
  279.     /**
  280.      * Returns the table name associated with an alias.
  281.      *
  282.      * @param      string $alias 
  283.      * @return     string $string
  284.      */
  285.     public function getTableForAlias($alias)
  286.     {
  287.         if (isset($this->aliases[$alias])) {
  288.             return $this->aliases[$alias];
  289.         }
  290.     }
  291.  
  292.     /**
  293.      * Get the keys for the criteria map.
  294.      * @return     array 
  295.      */
  296.     public function keys()
  297.     {
  298.         return array_keys($this->map);
  299.     }
  300.  
  301.     /**
  302.      * Does this Criteria object contain the specified key?
  303.      *
  304.      * @param      string $column [table.]column
  305.      * @return     boolean True if this Criteria object contain the specified key.
  306.      */
  307.     public function containsKey($column)
  308.     {
  309.         // must use array_key_exists() because the key could
  310.         // exist but have a NULL value (that'd be valid).
  311.         return array_key_exists($column$this->map);
  312.     }
  313.  
  314.     /**
  315.      * Will force the sql represented by this criteria to be executed within
  316.      * a transaction.  This is here primarily to support the oid type in
  317.      * postgresql.  Though it can be used to require any single sql statement
  318.      * to use a transaction.
  319.      * @return     void 
  320.      */
  321.     public function setUseTransaction($v)
  322.     {
  323.         $this->useTransaction = (boolean) $v;
  324.     }
  325.  
  326.     /**
  327.      * Whether the sql command specified by this criteria must be wrapped
  328.      * in a transaction.
  329.      *
  330.      * @return     boolean 
  331.      */
  332.     public function isUseTransaction()
  333.     {
  334.         return $this->useTransaction;
  335.     }
  336.  
  337.     /**
  338.      * Method to return criteria related to columns in a table.
  339.      *
  340.      * @param      string $column Column name.
  341.      * @return     Criterion A Criterion or null if $column is invalid.
  342.      */
  343.     public function getCriterion($column)
  344.     {
  345.         if isset $this->map[$column) ) {
  346.             return $this->map[$column];
  347.         }
  348.         return null;
  349.     }
  350.  
  351.     /**
  352.      * Method to return criterion that is not added automatically
  353.      * to this Criteria.  This can be used to chain the
  354.      * Criterions to form a more complex where clause.
  355.      *
  356.      * @param      string $column Full name of column (for example TABLE.COLUMN).
  357.      * @param      mixed $value 
  358.      * @param      string $comparison 
  359.      * @return     Criterion 
  360.      */
  361.     public function getNewCriterion($column$value$comparison null)
  362.     {
  363.         return new Criterion($this$column$value$comparison);
  364.     }
  365.  
  366.     /**
  367.      * Method to return a String table name.
  368.      *
  369.      * @param      string $name Name of the key.
  370.      * @return     string The value of the object at key.
  371.      */
  372.     public function getColumnName($name)
  373.     {
  374.         if (isset($this->map[$name])) {
  375.             return $this->map[$name]->getColumn();
  376.         }
  377.         return null;
  378.     }
  379.  
  380.     /**
  381.      * Shortcut method to get an array of columns indexed by table.
  382.      * @return     array array(table => array(table.column1, table.column2))
  383.      */
  384.     public function getTablesColumns()
  385.     {
  386.         $tables array();
  387.         foreach array_keys $this->map as $key{
  388.             $t substr $key0strpos $key'.' ) );
  389.             if isset $tables[$t) ) {
  390.                 $tables[$tarray$key );
  391.             else {
  392.                 $tables[$t][$key;
  393.             }
  394.         }
  395.         return $tables;
  396.     }
  397.  
  398.     /**
  399.      * Method to return a comparison String.
  400.      *
  401.      * @param      string $key String name of the key.
  402.      * @return     string A String with the value of the object at key.
  403.      */
  404.     public function getComparison($key)
  405.     {
  406.         if isset $this->map[$key) ) {
  407.             return $this->map[$key]->getComparison();
  408.         }
  409.         return null;
  410.     }
  411.  
  412.     /**
  413.      * Get the Database(Map) name.
  414.      *
  415.      * @return     string A String with the Database(Map) name.
  416.      */
  417.     public function getDbName()
  418.     {
  419.         return $this->dbName;
  420.     }
  421.  
  422.     /**
  423.      * Set the DatabaseMap name.  If <code>null</code> is supplied, uses value
  424.      * provided by <code>Propel::getDefaultDB()</code>.
  425.      *
  426.      * @param      string $dbName The Database (Map) name.
  427.      * @return     void 
  428.      */
  429.     public function setDbName($dbName null)
  430.     {
  431.         $this->dbName ($dbName === null Propel::getDefaultDB($dbName);
  432.     }
  433.  
  434.     /**
  435.      * Method to return a String table name.
  436.      *
  437.      * @param      string $name The name of the key.
  438.      * @return     string The value of table for criterion at key.
  439.      */
  440.     public function getTableName($name)
  441.     {
  442.         if (isset($this->map[$name])) {
  443.             return $this->map[$name]->getTable();
  444.         }
  445.         return null;
  446.     }
  447.  
  448.     /**
  449.      * Method to return the value that was added to Criteria.
  450.      *
  451.      * @param      string $name A String with the name of the key.
  452.      * @return     mixed The value of object at key.
  453.      */
  454.     public function getValue($name)
  455.     {
  456.         if (isset($this->map[$name])) {
  457.             return $this->map[$name]->getValue();
  458.         }
  459.         return null;
  460.     }
  461.  
  462.     /**
  463.      * An alias to getValue() -- exposing a Hashtable-like interface.
  464.      *
  465.      * @param      string $key An Object.
  466.      * @return     mixed The value within the Criterion (not the Criterion object).
  467.      */
  468.     public function get($key)
  469.     {
  470.         return $this->getValue($key);
  471.     }
  472.  
  473.     /**
  474.      * Overrides Hashtable put, so that this object is returned
  475.      * instead of the value previously in the Criteria object.
  476.      * The reason is so that it more closely matches the behavior
  477.      * of the add() methods. If you want to get the previous value
  478.      * then you should first Criteria.get() it yourself. Note, if
  479.      * you attempt to pass in an Object that is not a String, it will
  480.      * throw a NPE. The reason for this is that none of the add()
  481.      * methods support adding anything other than a String as a key.
  482.      *
  483.      * @param      string $key 
  484.      * @param      mixed $value 
  485.      * @return     Instance of self.
  486.      */
  487.     public function put($key$value)
  488.     {
  489.         return $this->add($key$value);
  490.     }
  491.  
  492.     /**
  493.      * Copies all of the mappings from the specified Map to this Criteria
  494.      * These mappings will replace any mappings that this Criteria had for any
  495.      * of the keys currently in the specified Map.
  496.      *
  497.      * if the map was another Criteria, its attributes are copied to this
  498.      * Criteria, overwriting previous settings.
  499.      *
  500.      * @param      mixed $t Mappings to be stored in this map.
  501.      */
  502.     public function putAll($t)
  503.     {
  504.  
  505.         if (is_array($t)) {
  506.  
  507.             foreach ($t as $key=>$value{
  508.  
  509.                 if ($value instanceof Criterion{
  510.  
  511.                     $this->map[$key$value;
  512.  
  513.                 else {
  514.  
  515.                     $this->put($key$value);
  516.  
  517.                 }
  518.  
  519.             }
  520.  
  521.         elseif ($t instanceof Criteria{
  522.  
  523.             $this->joins $t->joins;
  524.  
  525.         }
  526.  
  527.     }
  528.  
  529.  
  530.     /**
  531.      * This method adds a new criterion to the list of criterias.
  532.      * If a criterion for the requested column already exists, it is
  533.      * replaced. If is used as follow:
  534.      *
  535.      * <p>
  536.      * <code>
  537.      * $crit = new Criteria();
  538.      * $crit->add(&quot;column&quot;,
  539.      *                                      &quot;value&quot;
  540.      *                                      &quot;Criteria::GREATER_THAN&quot;);
  541.      * </code>
  542.      *
  543.      * Any comparison can be used.
  544.      *
  545.      * The name of the table must be used implicitly in the column name,
  546.      * so the Column name must be something like 'TABLE.id'. If you
  547.      * don't like this, you can use the add(table, column, value) method.
  548.      *
  549.      * @param      string $critOrColumn The column to run the comparison on, or Criterion object.
  550.      * @param      mixed $value 
  551.      * @param      string $comparison A String.
  552.      *
  553.      * @return     modified Criteria object.
  554.      */
  555.     public function add($p1$value null$comparison null)
  556.     {
  557.         if ($p1 instanceof Criterion{
  558.             $this->map[$p1->getTable('.' $p1->getColumn()$p1;
  559.         else {
  560.             $this->map[$p1new Criterion($this$p1$value$comparison);
  561.         }
  562.         return $this;
  563.     }
  564.  
  565.     /**
  566.      * This is the way that you should add a straight (inner) join of two tables.  For
  567.      * example:
  568.      *
  569.      * <p>
  570.      * AND PROJECT.PROJECT_ID=FOO.PROJECT_ID
  571.      * <p>
  572.      *
  573.      * left = PROJECT.PROJECT_ID
  574.      * right = FOO.PROJECT_ID
  575.      *
  576.      * @param      string $left A String with the left side of the join.
  577.      * @param      string $right A String with the right side of the join.
  578.          * @param      string $operator A String with the join operator e.g. LEFT JOIN, ...
  579.      * @return     Criteria A modified Criteria object.
  580.      */
  581.     public function addJoin($left$right$operator null)
  582.     {
  583.         $this->joins[new Join($left$right$operator);
  584.         return $this;
  585.     }
  586.  
  587.     /**
  588.      * Get the array of Joins.
  589.      * @return     array Join[]
  590.      */
  591.     public function getJoins()
  592.     {
  593.         return $this->joins;
  594.     }
  595.  
  596.     /**
  597.      * Adds "ALL" modifier to the SQL statement.
  598.      * @return     Criteria Modified Criteria object (for fluent API)
  599.      */
  600.     public function setAll()
  601.     {
  602.         $this->selectModifiers[self::ALL;
  603.         return $this;
  604.     }
  605.  
  606.     /**
  607.      * Adds "DISTINCT" modifier to the SQL statement.
  608.      * @return     Criteria Modified Criteria object (for fluent API)
  609.      */
  610.     public function setDistinct()
  611.     {
  612.         $this->selectModifiers[self::DISTINCT;
  613.         return $this;
  614.     }
  615.  
  616.     /**
  617.      * Sets ignore case.
  618.      *
  619.      * @param      boolean $b True if case should be ignored.
  620.      * @return     Criteria Modified Criteria object (for fluent API)
  621.      */
  622.     public function setIgnoreCase($b)
  623.     {
  624.         $this->ignoreCase = (boolean) $b;
  625.         return $this;