<?php
/**
 * File containing the ezcQueryExpression class.
 *
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 * 
 *   http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 *
 * @package Database
 * @version //autogentag//
 * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License, Version 2.0
 */

/**
 * The ezcQueryExpression class is used to create database independent SQL expression.
 *
 * The QueryExpression class is usually used through the 'expr' variable in
 * one of the Select, Insert, Update or Delete classes.
 *
 * Note that the methods for logical or and and are
 * named lOr and lAnd respectively. This is because and and or are reserved names
 * in PHP and can not be used in method names.
 *
 * @package Database
 * @version //autogentag//
 * @mainclass
 */
class ezcQueryExpression
{
    /**
     * A pointer to the database handler to use for this query.
     *
     * @var PDO
     */
    protected $db;

    /**
     * The column and table name aliases.
     *
     * Format: array('alias' => 'realName')
     * @var array(string=>string)
     */
    private $aliases = null;

    /**
     * The flag that switch quoting mode for
     * values provided by user in miscelaneous SQL functions.
     *
     * @var boolean
     */
    protected $quoteValues = true;

    /**
     * Contains an interval map from generic intervals to MySQL native intervals.
     *
     * @var array(string=>string)
     */
    protected $intervalMap = array(
        'SECOND' => 'SECOND',
        'MINUTE' => 'MINUTE',
        'HOUR' => 'HOUR',
        'DAY' => 'DAY',
        'MONTH' => 'MONTH',
        'YEAR' => 'YEAR',
    );

    /**
     * Constructs an empty ezcQueryExpression
     *
     * @param PDO $db
     * @param array(string=>string) $aliases
     */
    public function __construct( PDO $db, array $aliases = array() )
    {
        $this->db = $db;
        if ( !empty( $aliases ) )
        {
            $this->aliases = $aliases;
        }
    }

    /**
     * Sets the aliases $aliases for this object.
     *
     * The aliases can be used to substitute the column and table names with more
     * friendly names. E.g PersistentObject uses it to allow using property and class
     * names instead of column and table names.
     *
     * @param array(string=>string) $aliases
     * @return void
     */
    public function setAliases( array $aliases )
    {
        $this->aliases = $aliases;
    }

    /**
     * Returns true if this object has aliases.
     *
     * @return bool
     */
    public function hasAliases()
    {
        return $this->aliases !== null ? true : false;
    }

    /**
     * Returns the correct identifier for the alias $alias.
     *
     * If the alias does not exists in the list of aliases
     * it is returned unchanged.
     *
     * @param string $alias
     * @return string
     */
    protected function getIdentifier( $alias )
    {
        $aliasParts = explode( '.', $alias );
        $identifiers = array();
        // If the alias consists of one part, then we just look it up in the
        // array. If we find it, we use it, otherwise we return the name as-is
        // and assume it's just a column name. The alias target can be a fully
        // qualified name (table.column).
        if ( count( $aliasParts ) == 1 )
        {
            if ( $this->aliases !== null &&
                array_key_exists( $alias, $this->aliases ) )
            {
                $alias = $this->aliases[$alias];
            }
            return $alias;
        }
        // If the passed name consist of two parts, we need to check all parts
        // of the passed-in name for aliases, because an alias can be made for
        // both a table name and a column name. For each element we try to find
        // whether we have an alias mapping. Unlike the above case, the alias
        // target can in this case *not* consist of a fully qualified name as
        // this would introduce another part of the name (with two dots).
        for ( $i = 0; $i < count( $aliasParts ); $i++ )
        {
            if ( $this->aliases !== null &&
                array_key_exists( $aliasParts[$i], $this->aliases ) )
            {
                // We only use the found alias if the alias target is not a fully
                // qualified name (table.column).
                $tmpAlias = $this->aliases[$aliasParts[$i]];
                if ( count( explode( '.', $tmpAlias ) ) === 1 )
                {
                    $aliasParts[$i] = $this->aliases[$aliasParts[$i]];
                }
            }
        }
        $alias = join( '.', $aliasParts );
        return $alias;
    }

    /**
     * Returns the correct identifiers for the aliases found in $aliases.
     *
     * This method is similar to getIdentifier except that it works on an array.
     *
     * @param array(string) $aliasList
     * @return array(string)
     */
    protected function getIdentifiers( array $aliasList )
    {
        if ( $this->aliases !== null )
        {
            foreach ( $aliasList as $key => $alias )
            {
                $aliasList[$key] = $this->getIdentifier( $alias );
            }
        }
        return $aliasList;
    }

    /**
     * Sets the mode of quoting for parameters passed 
     * to SQL functions and operators.
     * 
     * Quoting mode is set to ON by default.
     * $q->expr->in( 'column1', 'Hello', 'world' ) will
     * produce SQL "column1 IN ( 'Hello', 'world' )" 
     * ( note quotes in SQL ).
     * 
     * User must execute setValuesQuoting( false ) before call 
     * to function where quoting of parameters is not desirable.
     * Example:
     * <code>
     * $q->expr->setValuesQuoting( false );
     * $q->expr->in( 'column1', 'SELECT * FROM table' ) 
     * </code>
     * This will produce SQL "column1 IN ( SELECT * FROM table )".
     * 
     * Quoting mode will remain unchanged until next call 
     * to setValuesQuoting().
     *
     * @param boolean $doQuoting - flag that switch quoting.
     * @return void
     */
    public function setValuesQuoting( $doQuoting )
    {
        $this->quoteValues = $doQuoting;
    }


    /**
     * Returns the SQL to bind logical expressions together using a logical or.
     *
     * lOr() accepts an arbitrary number of parameters. Each parameter
     * must contain a logical expression or an array with logical expressions.
     *
     * Example:
     * <code>
     * $q = ezcDbInstance::get()->createSelectQuery();
     * $e = $q->expr;
     * $q->select( '*' )->from( 'table' )
     *                  ->where( $e->lOr( $e->eq( 'id', $q->bindValue( 1 ) ),
     *                                    $e->eq( 'id', $q->bindValue( 2 ) ) ) );
     * </code>
     *
     * @throws ezcDbAbstractionException if called with no parameters.
     * @return string a logical expression
     */
    public function lOr()
    {
        $args = func_get_args();
        if ( count( $args ) < 1 )
        {
            throw new ezcQueryVariableParameterException( 'lOr', count( $args ), 1 );
        }

        $elements = ezcQuerySelect::arrayFlatten( $args );
        if ( count( $elements ) == 1 )
        {
            return $elements[0];
        }
        else
        {
            return '( ' . join( ' OR ', $elements ) . ' )';
        }
    }

    /**
     * Returns the SQL to bind logical expressions together using a logical and.
     *
     * lAnd() accepts an arbitrary number of parameters. Each parameter
     * must contain a logical expression or an array with logical expressions.
     *
     * Example:
     * <code>
     * $q = ezcDbInstance::get()->createSelectQuery();
     * $e = $q->expr;
     * $q->select( '*' )->from( 'table' )
     *                  ->where( $e->lAnd( $e->eq( 'id', $q->bindValue( 1 ) ),
     *                                     $e->eq( 'id', $q->bindValue( 2 ) ) ) );
     * </code>
     *
     * @throws ezcDbAbstractionException if called with no parameters.
     * @return string a logical expression
     */
    public function lAnd()
    {
        $args = func_get_args();
        if ( count( $args ) < 1 )
        {
            throw new ezcQueryVariableParameterException( 'lAnd', count( $args ), 1 );
        }

        $elements = ezcQuerySelect::arrayFlatten( $args );
        if ( count( $elements ) == 1 )
        {
            return $elements[0];
        }
        else
        {
            return '( ' . join( ' AND ', $elements ) . ' )';
        }
    }

    /**
     * Returns the SQL for a logical not, negating the $expression.
     *
     * Example:
     * <code>
     * $q = ezcDbInstance::get()->createSelectQuery();
     * $e = $q->expr;
     * $q->select( '*' )->from( 'table' )
     *                  ->where( $e->eq( 'id', $e->not( 'null' ) ) );
     * </code>
     *
     * @param string $expression
     * @return string a logical expression
     */
    public function not( $expression )
    {
        $expression = $this->getIdentifier( $expression );
        return "NOT ( {$expression} )";
    }

    // math

    /**
     * Returns the SQL to perform the same mathematical operation over an array
     * of values or expressions.
     *
     * basicMath() accepts an arbitrary number of parameters. Each parameter
     * must contain a value or an expression or an array with values or
     * expressions.
     *
     * @throws ezcDbAbstractionException if called with no parameters.
     * @param string $type the type of operation, can be '+', '-', '*' or '/'.
     * @param string|array(string) $...
     * @return string an expression
     */
    private function basicMath( $type )
    {
        $args = func_get_args();
        $elements = ezcQuerySelect::arrayFlatten( array_slice( $args, 1 ) );
        $elements = $this->getIdentifiers( $elements );
        if ( count( $elements ) < 1 )
        {
            throw new ezcQueryVariableParameterException( $type, count( $args ), 1 );
        }
        if ( count( $elements ) == 1 )
        {
            return $elements[0];
        }
        else
        {
            return '( ' . join( " $type ", $elements ) . ' )';
        }
    }

    /**
     * Returns the SQL to add values or expressions together.
     *
     * add() accepts an arbitrary number of parameters. Each parameter
     * must contain a value or an expression or an array with values or
     * expressions.
     *
     * Example:
     * <code>
     * $q = ezcDbInstance::get()->createSelectQuery();
     * $q->select( '*' )->from( 'table' )
     *                  ->where( $q->expr->add( 'id', 2 )  );
     * </code>
     *
     * @throws ezcDbAbstractionException if called with no parameters.
     * @param string|array(string) $...
     * @return string an expression
     */
    public function add()
    {
        $args = func_get_args();
        return $this->basicMath( '+', $args  );
    }

    /**
     * Returns the SQL to subtract values or expressions from eachother.
     *
     * subtract() accepts an arbitrary number of parameters. Each parameter
     * must contain a value or an expression or an array with values or
     * expressions.
     *
     * Example:
     * <code>
     * $q = ezcDbInstance::get()->createSelectQuery();
     * $q->select( '*' )->from( 'table' )
     *                  ->where( $q->expr->subtract( 'id', 2 )  );
     * </code>
     *
     * @throws ezcDbAbstractionException if called with no parameters.
     * @param string|array(string) $...
     * @return string an expression
     */
    public function sub()
    {
        $args = func_get_args();
        return $this->basicMath( '-', $args );
    }

    /**
     * Returns the SQL to multiply values or expressions by eachother.
     *
     * multiply() accepts an arbitrary number of parameters. Each parameter
     * must contain a value or an expression or an array with values or
     * expressions.
     *
     * Example:
     * <code>
     * $q = ezcDbInstance::get()->createSelectQuery();
     * $q->select( '*' )->from( 'table' )
     *                  ->where( $q->expr->multiply( 'id', 2 )  );
     * </code>
     *
     * @throws ezcDbAbstractionException if called with no parameters.
     * @param string|array(string) $...
     * @return string an expression
     */
    public function mul()
    {
        $args = func_get_args();
        return $this->basicMath( '*', $args );
    }

    /**
     * Returns the SQL to divide values or expressions by eachother.
     *
     * divide() accepts an arbitrary number of parameters. Each parameter
     * must contain a value or an expression or an array with values or
     * expressions.
     *
     * Example:
     * <code>
     * $q = ezcDbInstance::get()->createSelectQuery();
     * $q->select( '*' )->from( 'table' )
     *                  ->where( $q->expr->divide( 'id', 2 )  );
     * </code>
     *
     * @throws ezcDbAbstractionException if called with no parameters.
     * @param string|array(string) $...
     * @return string an expression
     */
    public function div()
    {
        $args = func_get_args();
        return $this->basicMath( '/', $args );
    }

    /**
     * Returns the SQL to check if two values are equal.
     *
     * Example:
     * <code>
     * $q = ezcDbInstance::get()->createSelectQuery();
     * $q->select( '*' )->from( 'table' )
     *                  ->where( $q->expr->eq( 'id', $q->bindValue( 1 ) ) );
     * </code>
     *
     * @param string $value1 logical expression to compare
     * @param string $value2 logical expression to compare with
     * @return string logical expression
     */
    public function eq( $value1, $value2 )
    {
        $value1 = $this->getIdentifier( $value1 );
        $value2 = $this->getIdentifier( $value2 );
        return "{$value1} = {$value2}";
    }

    /**
     * Returns the SQL to check if two values are unequal.
     *
     * Example:
     * <code>
     * $q = ezcDbInstance::get()->createSelectQuery();
     * $q->select( '*' )->from( 'table' )
     *                  ->where( $q->expr->neq( 'id', $q->bindValue( 1 ) ) );
     * </code>
     *
     * @param string $value1 logical expression to compare
     * @param string $value2 logical expression to compare with
     * @return string logical expression
     */
    public function neq( $value1, $value2 )
    {
        $value1 = $this->getIdentifier( $value1 );
        $value2 = $this->getIdentifier( $value2 );
        return "{$value1} <> {$value2}";
    }

    /**
     * Returns the SQL to check if one value is greater than another value.
     *
     * Example:
     * <code>
     * $q = ezcDbInstance::get()->createSelectQuery();
     * $q->select( '*' )->from( 'table' )
     *                  ->where( $q->expr->gt( 'id', $q->bindValue( 1 ) ) );
     * </code>
     *
     * @param string $value1 logical expression to compare
     * @param string $value2 logical expression to compare with
     * @return string logical expression
     */
    public function gt( $value1, $value2 )
    {
        $value1 = $this->getIdentifier( $value1 );
        $value2 = $this->getIdentifier( $value2 );
        return "{$value1} > {$value2}";
    }

    /**
     * Returns the SQL to check if one value is greater than or equal to
     * another value.
     *
     * Example:
     * <code>
     * $q = ezcDbInstance::get()->createSelectQuery();
     * $q->select( '*' )->from( 'table' )
     *                  ->where( $q->expr->gte( 'id', $q->bindValue( 1 ) ) );
     * </code>
     *
     * @param string $value1 logical expression to compare
     * @param string $value2 logical expression to compare with
     * @return string logical expression
     */
    public function gte( $value1, $value2 )
    {
        $value1 = $this->getIdentifier( $value1 );
        $value2 = $this->getIdentifier( $value2 );
        return "{$value1} >= {$value2}";
    }

    /**
     * Returns the SQL to check if one value is less than another value.
     *
     * Example:
     * <code>
     * $q = ezcDbInstance::get()->createSelectQuery();
     * $q->select( '*' )->from( 'table' )
     *                  ->where( $q->expr->lt( 'id', $q->bindValue( 1 ) ) );
     * </code>
     *
     * @param string $value1 logical expression to compare
     * @param string $value2 logical expression to compare with
     * @return string logical expression
     */
    public function lt( $value1, $value2 )
    {
        $value1 = $this->getIdentifier( $value1 );
        $value2 = $this->getIdentifier( $value2 );
        return "{$value1} < {$value2}";
    }

    /**
     * Returns the SQL to check if one value is less than or equal to
     * another value.
     *
     * Example:
     * <code>
     * $q = ezcDbInstance::get()->createSelectQuery();
     * $q->select( '*' )->from( 'table' )
     *                  ->where( $q->expr->lte( 'id', $q->bindValue( 1 ) ) );
     * </code>
     *
     * @param string $value1 logical expression to compare
     * @param string $value2 logical expression to compare with
     * @return string logical expression
     */
    public function lte( $value1, $value2 )
    {
        $value1 = $this->getIdentifier( $value1 );
        $value2 = $this->getIdentifier( $value2 );
        return "{$value1} <= {$value2}";
    }

    /**
     * Returns the SQL to check if a value is one in a set of
     * given values..
     *
     * in() accepts an arbitrary number of parameters. The first parameter
     * must always specify the value that should be matched against. Successive
     * parameters must contain a logical expression or an array with logical
     * expressions.  These expressions will be matched against the first
     * parameter.
     *
     * Example:
     * <code>
     * $q->select( '*' )->from( 'table' )
     *                  ->where( $q->expr->in( 'id', 1, 2, 3 ) );
     * </code>
     *
     * Optimization note: Call setQuotingValues( false ) before using in() with
     * big lists of numeric parameters. This avoid redundant quoting of numbers
     * in resulting SQL query and saves time of converting strings to
     * numbers inside RDBMS.
     *
     * @throws ezcQueryVariableParameterException if called with less than two
     *         parameters.
     * @throws ezcQueryInvalidParameterException if the 2nd parameter is an
     *         empty array.
     * @param string $column the value that should be matched against
     * @param string|array(string) $... values that will be matched against $column
     * @return string logical expression
     */
    public function in( $column )
    {
        $args = func_get_args();
        if ( count( $args ) < 2 )
        {
            throw new ezcQueryVariableParameterException( 'in', count( $args ), 2 );
        }

        if ( is_array( $args[1] ) && count( $args[1] ) == 0 )
        {
            throw new ezcQueryInvalidParameterException( 'in', 2, 'an empty array', 'a non-empty array' );
        }

        $values = ezcQuerySelect::arrayFlatten( array_slice( $args, 1 ) );

        $column = $this->getIdentifier( $column );
        
        // Special handling of sub selects to avoid double braces
        if ( count( $values ) === 1 && $values[0] instanceof ezcQuerySubSelect )
        {
            return "{$column} IN " . $values[0]->getQuery();
        }

        $values = $this->getIdentifiers( $values );

        if ( count( $values ) == 0 )
        {
            throw new ezcQueryVariableParameterException( 'in', count( $args ), 2 );
        }

        if ( $this->quoteValues )
        {
            foreach ( $values as $key => $value )
            {
                switch ( true )
                {
                    case $value instanceof ezcQuerySubSelect:
                        $values[$key] = $value->getQuery();  // fix for PHP 5.1.6 because typecasting to string not working there.
                        break;
                    case is_int( $value ):
                    case is_float( $value ):
                        $values[$key] = (string) $value;
                        break;
                    default:
                        $values[$key] = $this->db->quote( $value );
                }
            }
        }
        
        return "{$column} IN ( " . join( ', ', $values ) . ' )';
    }

    /**
     * Returns SQL that checks if a expression is null.
     *
     * Example:
     * <code>
     * $q = ezcDbInstance::get()->createSelectQuery();
     * $q->select( '*' )->from( 'table' )
     *                  ->where( $q->expr->isNull( 'id' ) );
     * </code>
     *
     * @param string $expression the expression that should be compared to null
     * @return string logical expression
     */
    public function isNull( $expression )
    {
        $expression = $this->getIdentifier( $expression );
        return "{$expression} IS NULL";
    }

    /**
     * Returns SQL that checks if an expression evaluates to a value between
     * two values.
     *
     * The parameter $expression is checked if it is between $value1 and $value2.
     *
     * Note: There is a slight difference in the way BETWEEN works on some databases.
     * http://www.w3schools.com/sql/sql_between.asp. If you want complete database
     * independence you should avoid using between().
     *
     * Example:
     * <code>
     * $q = ezcDbInstance::get()->createSelectQuery();
     * $q->select( '*' )->from( 'table' )
     *                  ->where( $q->expr->between( 'id', $q->bindValue( 1 ), $q->bindValue( 5 ) ) );
     * </code>
     *
     * @param string $expression the value to compare to
     * @param string $value1 the lower value to compare with
     * @param string $value2 the higher value to compare with
     * @return string logical expression
     */
    public function between( $expression, $value1, $value2 )
    {
        $expression = $this->getIdentifier( $expression );
        $value1 = $this->getIdentifier( $value1 );
        $value2 = $this->getIdentifier( $value2 );
        return "{$expression} BETWEEN {$value1} AND {$value2}";
    }

    /**
     * Match a partial string in a column.
     *
     * Like will look for the pattern in the column given. Like accepts
     * the wildcards '_' matching a single character and '%' matching
     * any number of characters.
     *
     * @param string $expression the name of the expression to match on
     * @param string $pattern the pattern to match with.
     */
    public function like( $expression, $pattern )
    {
        $expression = $this->getIdentifier( $expression );
        return "{$expression} LIKE {$pattern}";
    }
    // aggregate functions
    /**
     * Returns the average value of a column
     *
     * @param string $column the column to use
     * @return string
     */
    public function avg( $column )
    {
        $column = $this->getIdentifier( $column );
        return "AVG( {$column} )";
    }

    /**
     * Returns the number of rows (without a NULL value) of a column
     *
     * If a '*' is used instead of a column the number of selected rows
     * is returned.
     *
     * @param string $column the column to use
     * @return string
     */
    public function count( $column )
    {
        $column = $this->getIdentifier( $column );
        return "COUNT( {$column} )";
    }

    /**
     * Returns the highest value of a column
     *
     * @param string $column the column to use
     * @return string
     */
    public function max( $column )
    {
        $column = $this->getIdentifier( $column );
        return "MAX( {$column} )";
    }

    /**
     * Returns the lowest value of a column
     *
     * @param string $column the column to use
     * @return string
     */
    public function min( $column )
    {
        $column = $this->getIdentifier( $column );
        return "MIN( {$column} )";
    }

    /**
     * Returns the total sum of a column
     *
     * @param string $column the column to use
     * @return string
     */
    public function sum( $column )
    {
        $column = $this->getIdentifier( $column );
        return "SUM( {$column} )";
    }

    // scalar functions

    /**
     * Returns the md5 sum of $column.
     *
     * Note: Not SQL92, but common functionality
     *
     * @param string $column
     * @return string
     */
    public function md5( $column )
    {
        $column = $this->getIdentifier( $column );
        return "MD5( {$column} )";
    }

    /**
     * Returns the length of text field $column
     *
     * @param string $column
     * @return string
     */
    public function length( $column )
    {
        $column = $this->getIdentifier( $column );
        return "LENGTH( {$column} )";
    }

    /**
     * Rounds a numeric field to the number of decimals specified.
     *
     * @param string $column
     * @param int $decimals
     * @return string
     */
    public function round( $column, $decimals )
    {
        $column = $this->getIdentifier( $column );

        return "ROUND( {$column}, {$decimals} )";
    }

    /**
     * Returns the remainder of the division operation
     * $expression1 / $expression2.
     *
     * @param string $expression1
     * @param string $expression2
     * @return string
     */
    public function mod( $expression1, $expression2 )
    {
        $expression1 = $this->getIdentifier( $expression1 );
        $expression2 = $this->getIdentifier( $expression2 );
        return "MOD( {$expression1}, {$expression2} )";
    }

    /**
     * Returns the current system date and time in the database internal
     * format.
     *
     * @return string
     */
    public function now()
    {
        return "NOW()";
    }

    // string functions
    /**
     * Returns part of a string.
     *
     * Note: Not SQL92, but common functionality.
     *
     * @param string $value the target $value the string or the string column.
     * @param int $from extract from this characeter.
     * @param int $len extract this amount of characters.
     * @return string sql that extracts part of a string.
     */
    public function subString( $value, $from, $len = null )
    {
        $value = $this->getIdentifier( $value );
        if ( $len === null )
        {
            return "substring( {$value} from {$from} )";
        }
        else
        {
            $len = $this->getIdentifier( $len );
            return "substring( {$value} from {$from} for {$len} )";
        }
    }

    /**
     * Returns a series of strings concatinated
     *
     * concat() accepts an arbitrary number of parameters. Each parameter
     * must contain an expression or an array with expressions.
     *
     * @param string|array(string) $... strings that will be concatinated.
     */
    public function concat()
    {
        $args = func_get_args();
        $cols = ezcQuerySelect::arrayFlatten( $args );

        if ( count( $cols ) < 1 )
        {
            throw new ezcQueryVariableParameterException( 'concat', count( $args ), 1 );
        }

        $cols = $this->getIdentifiers( $cols );
        return "CONCAT( " . join( ', ', $cols ) . ' )';
    }

    /**
     * Returns the SQL to locate the position of the first occurrence of a substring
     *
     * @param string $substr
     * @param string $value
     * @return string
     */
    public function position( $substr, $value )
    {
        $value = $this->getIdentifier( $value );
        return "LOCATE( '{$substr}', {$value} )";
    }

    /**
     * Returns the SQL to change all characters to lowercase
     *
     * @param string $value
     * @return string
     */
    public function lower( $value )
    {
        $value = $this->getIdentifier( $value );
        return "LOWER( {$value} )";
    }

    /**
     * Returns the SQL to change all characters to uppercase
     * 
     * @param string $value
     * @return string
     */
    public function upper( $value )
    {
        $value = $this->getIdentifier( $value );
        return "UPPER( {$value} )";
    }

    /**
     * Returns the SQL to calculate the next lowest integer value from the number.
     * 
     * @param string $number
     * @return string
     */
    public function floor( $number )
    {
        $number = $this->getIdentifier( $number );
        return " FLOOR( {$number} ) ";
    }

    /**
     * Returns the SQL to calculate the next highest integer value from the number.
     *
     * @param string $number
     * @return string
     */
    public function ceil( $number )
    {
        $number = $this->getIdentifier( $number );
        return " CEIL( {$number} ) ";
    }

    /**
     * Returns the SQL that performs the bitwise AND on two values.
     *
     * @param string $value1
     * @param string $value2
     * @return string
     */
    public function bitAnd( $value1, $value2 )
    {
        $value1 = $this->getIdentifier( $value1 );
        $value2 = $this->getIdentifier( $value2 );
        return "( {$value1} & {$value2} )";
    }

    /**
     * Returns the SQL that performs the bitwise OR on two values.
     *
     * @param string $value1
     * @param string $value2
     * @return string
     */
    public function bitOr( $value1, $value2 )
    {
        $value1 = $this->getIdentifier( $value1 );
        $value2 = $this->getIdentifier( $value2 );
        return "( {$value1} | {$value2} )";
    }

    /**
     * Returns the SQL that performs the bitwise XOR on two values.
     *
     * @param string $value1
     * @param string $value2
     * @return string
     */
    public function bitXor( $value1, $value2 )
    {
        $value1 = $this->getIdentifier( $value1 );
        $value2 = $this->getIdentifier( $value2 );
        return "( {$value1} ^ {$value2} )";
    }

    /**
     * Returns the SQL that converts a timestamp value to a unix timestamp.
     *
     * @param string $column
     * @return string
     */
    public function unixTimestamp( $column )
    {
        $column = $this->getIdentifier( $column );
        return " UNIX_TIMESTAMP( {$column} ) ";
    }

    /**
     * Returns the SQL that subtracts an interval from a timestamp value.
     *
     * @param string $column
     * @param numeric $expr
     * @param string $type one of SECOND, MINUTE, HOUR, DAY, MONTH, or YEAR
     * @return string
     */
    public function dateSub( $column, $expr, $type )
    {
        $type = $this->intervalMap[$type];

        $column = $this->getIdentifier( $column );
        return " {$column} - INTERVAL {$expr} {$type} ";
    }

    /**
     * Returns the SQL that adds an interval to a timestamp value.
     *
     * @param string $column
     * @param numeric $expr
     * @param string $type one of SECOND, MINUTE, HOUR, DAY, MONTH, or YEAR
     * @return string
     */
    public function dateAdd( $column, $expr, $type )
    {
        $type = $this->intervalMap[$type];

        $column = $this->getIdentifier( $column );
        return " {$column} + INTERVAL {$expr} {$type} ";
    }

    /**
     * Returns the SQL that extracts parts from a timestamp value.
     *
     * @param string $column The column to operate on
     * @param string $type one of SECOND, MINUTE, HOUR, DAY, MONTH, or YEAR
     * @return string
     */
    public function dateExtract( $column, $type )
    {
        $type = $this->intervalMap[$type];

        $column = $this->getIdentifier( $column );
        return " EXTRACT( {$type} FROM {$column} ) ";
    }

    /**
     * Returns a searched CASE statement.
     *
     * Accepts an arbitrary number of parameters. 
     * The first parameter (array) must always be specified, the last 
     * parameter (string) specifies the ELSE result.
     *
     * Example:
     * <code>
     * $q = ezcDbInstance::get()->createSelectQuery();
     * $q->select(
     *      $q->expr->searchedCase(
     *            array( $q->expr->gte( 'column1', 20 ), 'column1' )
     *          , array( $q->expr->gte( 'column2', 50 ), 'column2' )
     *          , 'column3'
     *      )
     *  )
     *     ->from( 'table' );
     * </code>
     *
     * @throws ezcQueryVariableParameterException
     * @return string
     */
    public function searchedCase()
    {
        $args = func_get_args();
        if ( count( $args ) === 0 )
        {
            throw new ezcQueryVariableParameterException( 'searchedCase', count( $args ), 1 );
        }

        $expr = ' CASE';
        foreach ( $args as $arg )
        {
            if ( is_array( $arg ) && count( $arg ) == 2 )
            {
                $column1 = $this->getIdentifier( $arg[0] );
                $column2 = $this->getIdentifier( $arg[1] );
                $expr .= " WHEN {$column1} THEN {$column2}";
            }
            else if ( is_scalar( $arg ) )
            {
                $column = $this->getIdentifier( $arg );
                $expr .= " ELSE {$column}";
            }
        }
        $expr .= ' END ';

        return $expr;
    }
}
?>
