<?php
/*******************************************************************************
* Copyright 2008 Rafael Marques Martins
*
* This file is part of SQLReactor.
*
* SQLReactor is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* SQLReactor is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with SQLReactor; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*
*******************************************************************************/
class SQLReactorClause{
public $query;
public $leftOperand;
public $operator;
public $rightOperand;
public function __construct( &$query, $leftOperand, $operator, $rightOperand ){
$this->query = $query;
$this->leftOperand = $leftOperand;
$this->operator = $operator;
$this->rightOperand = $rightOperand;
}
protected function getColumn( $operand ){
$tmpClause = explode( "->", $operand );
$tmpInstance = $this->query->from;
foreach( $tmpClause as $tmpName ){
$column = $tmpInstance->_table->columns->$tmpName;
if( $column instanceOf Backref || $column instanceOf ForeignKey ){
$className = $column->config[ 'target' ][ 0 ];
$tmpInstance = new $className();
}
}
return $column;
}
protected function parseClause( $clause ){
$operator = strtoupper( $clause->operator );
if( $operator == 'OR' ){
$leftClauses = array();
$rightClauses = array();
foreach( array( 'left', 'right' ) as $side ){
$oper = "{$side}Operand";
foreach( $clause->$oper as $tmpClause ){
$clauseName = "{$side}Clauses";
${$clauseName}[] = $this->parseClause( $tmpClause );
}
$$clauseName = implode( ' AND ', $$clauseName );
}
return "( ( {$leftClauses} ) OR ( {$rightClauses} ) )";
}
$escapeChar = $this->query->from->_connection->engine->escapeName;
$column = $this->getColumn( $clause->leftOperand );
$className = get_class( $column );
$tmpColumn = new $className();
$tmpColumn->setValueFromPHP( $clause->rightOperand );
$rightOperand = $tmpColumn->getValueToDB();
switch( $operator ){
case 'IN':
$valueList = array();
foreach( $clause->rightOperand as $value ){
$tmpColumn->setValueFromPHP( $value );
$valueList[] = $tmpColumn->getValueToDB();
}
$rightOperand = '( ' . implode( ', ', $valueList ) . ' )';
break;
case 'BETWEEN':
$tmpColumn->setValueFromPHP( $clause->rightOperand[0] );
$value1 = $tmpColumn->getValueToDB();
$tmpColumn->setValueFromPHP( $clause->rightOperand[1] );
$value2 = $tmpColumn->getValueToDB();
$rightOperand = '( ' . $value1 . ' ) AND ( ' . $value2 . ' )';
case 'OR':
case '=':
case '>':
case '>=':
case '<':
case '<=':
case 'LIKE':
break;
case '==':
$operator = '=';
break;
case '!=':
$operator = '<>';
break;
default:
throw new Exception( "Invalid operator \"{$operator}\"" );
}
if( $rightOperand === 'NULL' ){
if( $operator == '=' ){
$operator = 'IS';
}else if( $operator == '!=' ){
$operator = 'IS NOT';
}
}
$tmpLeftOperand = implode( "->", array_slice( explode( "->", $clause->leftOperand ), 0, -1 ) );
if( $this->query->sqlStructure->join[ $tmpLeftOperand ] ){
$tmpName = $this->query->getTableName( $this->query->sqlStructure->join[ $tmpLeftOperand ] );
return "( {$escapeChar}{$tmpName}{$escapeChar}.{$escapeChar}{$column->name}{$escapeChar} {$operator} " . $rightOperand . ' )';
}
return "( {$escapeChar}{$column->table->name}{$escapeChar}.{$escapeChar}{$column->name}{$escapeChar} {$operator} " . $rightOperand . ' )';
}
public function parse(){
return $this->parseClause( $this );
}
}
?>