<?php
/**
 * File containing the ezcQuerySelectSqlite 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
 */

/**
 * SQLite specific implementation of ezcQuery.
 *
 * This class reimplements methods where SQLite differs from the standard
 * implementation in ezcQuery. The only difference is the right join syntax.
 *
 * @see ezcQuery
 * @package Database
 * @version //autogentag//
 */
class ezcQuerySelectSqlite extends ezcQuerySelect
{
    /**
     * Store info for building emulation of right joins in FROM clause.
     * 
     * This array contains null if there was no calls to rightJoin().
     * When call to rightJoin() occurs an item of right join info added.
     * Right join info is array that consists of two arrays: 'tables' and 'conditions'.
     * These arrays filled with values from parameters of rightJoin().
     * If from() was called then new right join info item added to $rightJoins.
     */
    protected $rightJoins = array( null );

    /**
     * Store tables that appear in FROM clause.
     * 
     * Used for building fromString every time when it requested
     */
    protected $fromTables = array();

    /**
     * Constructs a new ezcQuerySelectSqlite object.
     *
     * @param PDO $db
     */
    public function __construct( PDO $db )
    {
        parent::__construct( $db );
    }


    /**
     * Resets the query object for reuse.
     *
     * @return void
     */
    public function reset()
    {
        parent::reset();
        $this->fromTables = array();
        $this->rightJoins = array( null );
    }

    /**
     * Select which tables you want to select from.
     *
     * from() accepts an arbitrary number of parameters. Each parameter
     * must contain either the name of a table or an array containing
     * the names of tables..
     * from() could be invoked several times. All provided arguments 
     * added to the end of $fromString.
     * 
     * Additional actions performed to emulate right joins in SQLite.
     *
     * Example:
     * <code>
     * // the following code will produce the SQL
     * // SELECT id FROM t2 LEFT JOIN t1 ON t1.id = t2.id
     * $q->select( 'id' )->from( $q->rightJoin( 't1', 't2', 't1.id', 't2.id' ) );
     * 
     * // the following code will produce the same SQL
     * // SELECT id FROM t2 LEFT JOIN t1 ON t1.id = t2.id
     * $q->select( 'id' )->from( 't1' )->rightJoin( 't2', 't1.id', 't2.id' );
     * </code>
     *
     * @throws ezcQueryVariableParameterException if called with no parameters.
     * @param string|array(string) $... Either a string with a table name or an array of table names.
     * @return a pointer to $this
     */
    public function from()
    {
        $args = func_get_args();
        $tables = self::arrayFlatten( $args );
        if ( count( $tables ) < 1 )
        {
            throw new ezcQueryVariableParameterException( 'from', count( $args ), 1 );
        }
        $this->lastInvokedMethod = 'from';
        $tables = $this->getIdentifiers( $tables );

        $this->fromTables = array_merge( $this->fromTables, $tables );

        $this->fromString ='FROM '.join( ', ', $this->fromTables );

        // adding right join part of query to the end of fromString.
        $rightJoinPart = $this->buildRightJoins();
        if ( $rightJoinPart != '' ) 
        {
            $this->fromString .= ', '.$rightJoinPart;
        }

        // adding new empty entry to $rightJoins if last entry was already filled
        $lastRightJoin = end( $this->rightJoins );
        if ( $lastRightJoin != null ) 
        {
            $this->rightJoins[] = null; // adding empty stub to the rightJoins
                                        // it could be filled by next rightJoin()
        }
        return $this;
    }

    /**
     * Returns SQL string with part of FROM clause that performs right join emulation. 
     * 
     * SQLite don't support right joins directly but there is workaround.
     * identical result could be acheived using right joins for tables in reverce order.
     * 
     * String created from entries of $rightJoins. 
     * One entry is a complete table_reference clause of SQL FROM clause.
     * 
     * <code>
     * rightJoins[0][tables] = array( 'table1', 'table2', 'table3' )
     * rightJoins[0][conditions] = array( condition1, condition2 )
     * </code>
     * forms SQL: 'table3 LEFT JOIN table2 condition2 ON LEFT JOIN table1 ON condition1'.
     * 
     * 
     * @return string the SQL call including all right joins set in query.
     */
    private function buildRightJoins()
    {
        $resultArray = array();

        foreach ( $this->rightJoins as $rJoinPart )
        {
            $oneItemResult = '';
            if ( $rJoinPart === null ) 
            {
                break; // this is last empty entry so cancel adding.
            }

            // reverse lists of tables and conditions to make LEFT JOIN 
            // that will produce result equal to original right join.
            $reversedTables = array_reverse( $rJoinPart['tables'] );
            $reversedConditions = array_reverse( $rJoinPart['conditions'] );

            // adding first table.
            list( $key, $val ) = each( $reversedTables ); 
            $oneItemResult .= $val;

            while ( list( $key, $nextCondition ) = each( $reversedConditions ) )
            {
                list( $key2, $nextTable ) = each( $reversedTables );   
               $oneItemResult .= " LEFT JOIN {$nextTable} ON {$nextCondition}";
            }
            $resultArray[] = $oneItemResult;
        }

        return join( ', ', $resultArray );
    }

    /**
     * Returns the SQL for a right join or prepares $fromString for a right join.
     * 
     * This method could be used in two forms:
     *
     * <b>rightJoin( 't2', $joinCondition )</b>
     * 
     * Takes 2 string arguments and returns ezcQuery.
     *
     * The first parameter is the name of the table to join with. The table to
     * which is joined should have been previously set with the from() method.
     *
     * The second parameter should be a string containing a join condition that
     * is returned by an ezcQueryExpression.
     *
     * Example:
     * <code>
     * // the following code will produce the SQL
     * // SELECT id FROM t1 LEFT JOIN t2 ON t1.id = t2.id
     * $q->select( 'id' )->from( 't1' )->rightJoin( 't2', $q->expr->eq('t1.id', 't2.id' ) );
     * </code>
     *
     * <b>rightJoin( 't2', 't1.id', 't2.id' )</b>
     * 
     * Takes 3 string arguments and returns ezcQuery. This is a simplified form
     * of the 2 parameter version.  rightJoin( 't2', 't1.id', 't2.id' ) is
     * equal to rightJoin( 't2', $this->expr->eq('t1.id', 't2.id' ) );
     *
     * The first parameter is the name of the table to join with. The table to
     * which is joined should have been previously set with the from() method.
     * 
     * The second parameter is the name of the column on the table set
     * previously with the from() method and the third parameter the name of
     * the column to join with on the table that was specified in the first
     * parameter.
     *
     * Example:
     * <code>
     * // the following code will produce the SQL
     * // SELECT id FROM t1 LEFT JOIN t2 ON t1.id = t2.id
     * $q->select( 'id' )->from( 't1' )->rightJoin( 't2', 't1.id', 't2.id' );
     * </code>
     *
     * @apichange Remove 4 argument version.
     *
     * @throws ezcQueryInvalidException if called with inconsistent parameters or if
     *         invoked without preceding call to from().
     *
     * @param string $table2,... The table to join with, followed by either the
     *                           two join columns, or a join condition.
     * @return ezcQuery
     */
    public function rightJoin()
    {
        $args = func_get_args();
        $passedArgsCount = func_num_args();
        if ( $passedArgsCount < 2 || $passedArgsCount > 4 )
        {
            throw new ezcQueryInvalidException( 'SELECT', "Wrong argument count passed to {$type}Join(): {$passedArgsCount}" );
        }

        // deprecated syntax
        if ( $passedArgsCount == 4 ) 
        {
            if ( is_string( $args[0] ) && is_string( $args[1] ) &&
                 is_string( $args[2] ) && is_string( $args[3] ) 
               ) 
            {
                $table1 = $this->getIdentifier( $args[0] );
                $table2 = $this->getIdentifier( $args[1] );
                $column1 = $this->getIdentifier( $args[2] );
                $column2 = $this->getIdentifier( $args[3] );

                return "{$table2} LEFT JOIN {$table1} ON {$column1} = {$column2}";
            }
            else
            {
                throw new ezcQueryInvalidException( 'SELECT', 'Inconsistent types of arguments passed to rightJoin().' );
            }
        }

        // using from()->rightJoin() syntax assumed, so check if last call was to from()
        if ( $this->lastInvokedMethod != 'from' )
        {
            throw new ezcQueryInvalidException( 'SELECT', 'Invoking rightJoin() not immediately after from().' );
        }

        $table = '';
        if ( !is_string( $args[0] ) ) 
        {
            throw new ezcQueryInvalidException( 'SELECT', 
                     'Inconsistent type of first argument passed to rightJoin(). Should be string with name of table.' );
        }
        $table = $this->getIdentifier( $args[0] );

        $condition = '';
        if ( $passedArgsCount == 2 && is_string( $args[1] ) ) 
        {
            $condition = $args[1];
        }
        else if ( $passedArgsCount == 3 && is_string( $args[1] ) && is_string( $args[2] ) ) 
        {
            $arg1 = $this->getIdentifier( $args[1] );
            $arg2 = $this->getIdentifier( $args[2] );

            $condition = "{$arg1} = {$arg2}";
        }

        // If rightJoin info entry is empty than remove last table from
        // fromTables list and add it at first place to the list of tables in
        // correspondent rightJoin info entry.
        // Subsequent calls to rightJoin() without from() will just add one
        // table and one condition to the correspondent arrays.

        if ( end( $this->rightJoins ) === null ) // fill last rightJoin info entry with table name.
        {
            $lastTable = array_pop ( $this->fromTables );
            array_pop( $this->rightJoins );
            $this->rightJoins[count( $this->rightJoins )]['tables'][] = $lastTable;
        }
        
        if ( $table != '' && $condition != '' )
        {
            $this->rightJoins[count( $this->rightJoins ) - 1]['tables'][] = $table;
            $this->rightJoins[count( $this->rightJoins ) - 1]['conditions'][] = $condition;
        }
         
        // build fromString using fromTables and add right joins stuff to te end.
        $this->fromString = 'FROM ' . join( ', ', $this->fromTables );
        $this->fromString .= $this->buildRightJoins();

        return $this;
    }
}
?>
