Файл: onlinepoisk.wm-scripts.ru/vendor/AR/lib/Expressions.php
Строк: 186
<?php
/**
* @package ActiveRecord
*/
namespace ActiveRecord;
/**
* Templating like class for building SQL statements.
*
* Examples:
* 'name = :name AND author = :author'
* 'id = IN(:ids)'
* 'id IN(:subselect)'
*
* @package ActiveRecord
*/
class Expressions
{
const ParameterMarker = '?';
private $expressions;
private $values = array();
private $connection;
public function __construct($connection, $expressions=null /* [, $values ... ] */)
{
$values = null;
$this->connection = $connection;
if (is_array($expressions))
{
$glue = func_num_args() > 2 ? func_get_arg(2) : ' AND ';
list($expressions,$values) = $this->build_sql_from_hash($expressions,$glue);
}
if ($expressions != '')
{
if (!$values)
$values = array_slice(func_get_args(),2);
$this->values = $values;
$this->expressions = $expressions;
}
}
/**
* Bind a value to the specific one based index. There must be a bind marker
* for each value bound or to_s() will throw an exception.
*/
public function bind($parameter_number, $value)
{
if ($parameter_number <= 0)
throw new ExpressionsException("Invalid parameter index: $parameter_number");
$this->values[$parameter_number-1] = $value;
}
public function bind_values($values)
{
$this->values = $values;
}
/**
* Returns all the values currently bound.
*/
public function values()
{
return $this->values;
}
/**
* Returns the connection object.
*/
public function get_connection()
{
return $this->connection;
}
/**
* Sets the connection object. It is highly recommended to set this so we can
* use the adapter's native escaping mechanism.
*
* @param string $connection a Connection instance
*/
public function set_connection($connection)
{
$this->connection = $connection;
}
public function to_s($substitute=false, &$options=null)
{
if (!$options) $options = array();
$values = array_key_exists('values',$options) ? $options['values'] : $this->values;
$ret = "";
$replace = array();
$num_values = count($values);
$len = strlen($this->expressions);
$quotes = 0;
for ($i=0,$n=strlen($this->expressions),$j=0; $i<$n; ++$i)
{
$ch = $this->expressions[$i];
if ($ch == self::ParameterMarker)
{
if ($quotes % 2 == 0)
{
if ($j > $num_values-1)
throw new ExpressionsException("No bound parameter for index $j");
$ch = $this->substitute($values,$substitute,$i,$j++);
}
}
elseif ($ch == ''' && $i > 0 && $this->expressions[$i-1] != '\')
++$quotes;
$ret .= $ch;
}
return $ret;
}
private function build_sql_from_hash(&$hash, $glue)
{
$sql = $g = "";
foreach ($hash as $name => $value)
{
if ($this->connection)
$name = $this->connection->quote_name($name);
if (is_array($value))
$sql .= "$g$name IN(?)";
else
$sql .= "$g$name=?";
$g = $glue;
}
return array($sql,array_values($hash));
}
private function substitute(&$values, $substitute, $pos, $parameter_index)
{
$value = $values[$parameter_index];
if (is_array($value))
{
if ($substitute)
{
$ret = '';
for ($i=0,$n=count($value); $i<$n; ++$i)
$ret .= ($i > 0 ? ',' : '') . $this->stringify_value($value[$i]);
return $ret;
}
return join(',',array_fill(0,count($value),self::ParameterMarker));
}
if ($substitute)
return $this->stringify_value($value);
return $this->expressions[$pos];
}
private function stringify_value($value)
{
if (is_null($value))
return "NULL";
return is_string($value) ? $this->quote_string($value) : $value;
}
private function quote_string($value)
{
if ($this->connection)
return $this->connection->escape($value);
return "'" . str_replace("'","''",$value) . "'";
}
}
?>