silverstripe-framework/model/queries/SQLQuery.php

184 lines
4.5 KiB
PHP
Raw Normal View History

<?php
2015-08-24 06:15:38 +02:00
/**
* @package framework
* @subpackage model
*/
/**
* Object representing a SQL SELECT query.
* The various parts of the SQL query can be manipulated individually.
*
2014-12-03 21:20:39 +01:00
* @deprecated since version 4.0
*/
class SQLQuery extends SQLSelect {
2015-06-15 08:35:01 +02:00
/**
* If this is true, this statement will delete rather than select.
*
2015-06-15 08:35:01 +02:00
* @deprecated since version 4.0
* @var boolean
*/
protected $isDelete = false;
/**
2014-12-03 21:20:39 +01:00
* @deprecated since version 4.0
*/
public function __construct($select = "*", $from = array(), $where = array(), $orderby = array(),
$groupby = array(), $having = array(), $limit = array()
) {
parent::__construct($select, $from, $where, $orderby, $groupby, $having, $limit);
2014-12-03 21:20:39 +01:00
Deprecation::notice('4.0', 'Use SQLSelect instead');
}
/**
2015-06-15 08:35:01 +02:00
* @deprecated since version 4.0
*/
public function setDelete($value) {
2015-06-15 08:35:01 +02:00
Deprecation::notice('4.0', 'SQLQuery::setDelete is deprecated. Use toDelete instead');
$this->isDelete = $value;
}
/**
2015-06-15 08:35:01 +02:00
* @deprecated since version 4.0
*/
public function getDelete() {
2015-06-15 08:35:01 +02:00
Deprecation::notice('4.0', 'SQLQuery::getDelete is deprecated. Use SQLSelect or SQLDelete instead');
return $this->isDelete;
}
public function sql(&$parameters = array()) {
return $this->toAppropriateExpression()->sql($parameters);
}
2015-06-15 08:35:01 +02:00
/**
* Get helper class for flattening parameterised conditions
*
2015-06-15 08:35:01 +02:00
* @return SQLQuery_ParameterInjector
*/
protected function getParameterInjector() {
return Injector::inst()->get('SQLQuery_ParameterInjector');
}
/**
* Return a list of SQL where conditions (flattened as a list of strings)
*
2015-06-15 08:35:01 +02:00
* @return array
*/
public function getWhere() {
Deprecation::notice(
'4.0',
'SQLQuery::getWhere is non-parameterised for backwards compatibility. '.
'Use ->toAppropriateExpression()->getWhere() instead'
);
$conditions = parent::getWhere();
2015-06-15 08:35:01 +02:00
// This is where any benefits of parameterised queries die
return $this
->getParameterInjector()
->injectConditions($conditions);
}
/**
* Convert this SQLQuery to a SQLExpression based on its
2015-06-15 08:35:01 +02:00
* internal $delete state (Normally SQLSelect or SQLDelete)
*
2015-06-15 08:35:01 +02:00
* @return SQLExpression
*/
public function toAppropriateExpression() {
if($this->isDelete) {
return parent::toDelete();
} else {
return parent::toSelect();
}
}
public function toSelect() {
if($this->isDelete) {
user_error(
'SQLQuery::toSelect called when $isDelete is true. Use ' .
'toAppropriateExpression() instead',
E_USER_WARNING
);
}
return parent::toSelect();
}
public function toDelete() {
if(!$this->isDelete) {
user_error(
'SQLQuery::toDelete called when $isDelete is false. Use ' .
'toAppropriateExpression() instead',
E_USER_WARNING
);
}
parent::toDelete();
}
}
/**
* Provides conversion of parameterised SQL to flattened SQL strings
*
2015-06-15 08:35:01 +02:00
* @deprecated since version 4.0
*/
class SQLQuery_ParameterInjector {
2015-06-15 08:35:01 +02:00
public function __construct() {
Deprecation::notice('4.0', "Use SQLSelect / SQLDelete instead of SQLQuery");
}
/**
* Given a list of parameterised conditions, return a flattened
* list of condition strings
*
2015-06-15 08:35:01 +02:00
* @param array $conditions
* @return array
*/
public function injectConditions($conditions) {
$result = array();
foreach($conditions as $condition) {
// Evaluate the result of SQLConditionGroup here
if($condition instanceof SQLConditionGroup) {
$predicate = $condition->conditionSQL($parameters);
if(!empty($predicate)) {
$result[] = $this->injectValues($predicate, $parameters);
}
} else {
foreach($condition as $predicate => $parameters) {
$result[] = $this->injectValues($predicate, $parameters);
}
}
}
return $result;
}
/**
* Merge parameters into a SQL prepared condition
*
2015-06-15 08:35:01 +02:00
* @param string $sql
* @param array $parameters
* @return string
*/
protected function injectValues($sql, $parameters) {
return DB::inline_parameters($sql, $parameters);
2015-06-15 08:35:01 +02:00
}
/**
* Determines if the SQL fragment either breaks into or out of a string literal
* by counting single quotes
*
2015-06-15 08:35:01 +02:00
* Handles double-quote escaped quotes as well as slash escaped quotes
*
2015-06-15 08:35:01 +02:00
* @param string $input The SQL fragment
* @return boolean True if the string breaks into or out of a string literal
*/
protected function checkStringTogglesLiteral($input) {
// Remove escaped backslashes, count them!
$input = preg_replace('/\\\\\\\\/', '', $input);
// Count quotes
$totalQuotes = substr_count($input, "'"); // Includes double quote escaped quotes
$escapedQuotes = substr_count($input, "\\'");
return (($totalQuotes - $escapedQuotes) % 2) !== 0;
}
}