mirror of
https://github.com/silverstripe/silverstripe-framework
synced 2024-10-22 14:05:37 +02:00
8dd644d25d
Namespace all templates Move difflib and BBCodeParser2 to thirdparty Remove deprecated API marked for removal in 4.0
224 lines
6.2 KiB
PHP
224 lines
6.2 KiB
PHP
<?php
|
|
|
|
namespace SilverStripe\ORM\Queries;
|
|
|
|
use InvalidArgumentException;
|
|
|
|
/**
|
|
* Represents a list of updates / inserts made to a single row in a table
|
|
*/
|
|
class SQLAssignmentRow {
|
|
|
|
/**
|
|
* List of field values to store for this query
|
|
*
|
|
* Each item in this array will be in the form of a single-length array
|
|
* in the format array('sql' => array($parameters)).
|
|
* The field name is stored as the key
|
|
*
|
|
* E.g.
|
|
*
|
|
* <code>$assignments['ID'] = array('?' => array(1));</code>
|
|
*
|
|
* This allows for complex, parameterised updates, or explict field values set
|
|
* without any prameters
|
|
*
|
|
* @var array
|
|
*/
|
|
protected $assignments = array();
|
|
|
|
/**
|
|
* Instantiate a new SQLAssignmentRow object with the given values
|
|
*
|
|
* @param array $values
|
|
*/
|
|
function __construct(array $values = array()) {
|
|
$this->setAssignments($values);
|
|
}
|
|
|
|
|
|
/**
|
|
* Given a key / value pair, extract the predicate and any potential paramaters
|
|
* in a format suitable for storing internally as a list of paramaterised conditions.
|
|
*
|
|
* @param mixed $value Either a literal field value, or an array with
|
|
* placeholder => parameter(s) as a pair
|
|
* @return array A single item array in the format array($sql => array($parameters))
|
|
*/
|
|
protected function parseAssignment($value) {
|
|
// Assume string values (or values saved as customised array objects)
|
|
// represent simple assignment
|
|
if(!is_array($value) || isset($value['type'])) {
|
|
return array('?' => array($value));
|
|
}
|
|
|
|
// If given as array then extract and check both the SQL as well as the parameter(s)
|
|
// Note that there could be multiple parameters, e.g.
|
|
// array('MAX(?,?)' => array(1,2)) although the container should
|
|
// have a single item
|
|
if(count($value) == 1) {
|
|
foreach($value as $sql => $parameters) {
|
|
if(!is_string($sql)) continue;
|
|
if(!is_array($parameters)) $parameters = array($parameters);
|
|
|
|
// @todo Some input sanitisation checking the key contains the
|
|
// correct number of ? placeholders as the number of parameters
|
|
return array($sql => $parameters);
|
|
}
|
|
}
|
|
|
|
throw new InvalidArgumentException(
|
|
"Nested field assignments should be given as a single parameterised item array in "
|
|
. "array('?' => array('value')) format)"
|
|
);
|
|
}
|
|
|
|
/**
|
|
* Given a list of assignments in any user-acceptible format, normalise the
|
|
* value to a common array('SQL' => array(parameters)) format
|
|
*
|
|
* @param array $assignments List of assignments.
|
|
* The key of this array should be the field name, and the value the assigned
|
|
* literal value, or an array with parameterised information.
|
|
* @return array List of normalised assignments
|
|
*/
|
|
protected function normaliseAssignments(array $assignments) {
|
|
$normalised = array();
|
|
foreach($assignments as $field => $value) {
|
|
$normalised[$field] = $this->parseAssignment($value);
|
|
}
|
|
return $normalised;
|
|
}
|
|
|
|
/**
|
|
* Adds assignments for a list of several fields
|
|
*
|
|
* Note that field values must not be escaped, as these will be internally
|
|
* parameterised by the database engine.
|
|
*
|
|
* <code>
|
|
*
|
|
* // Basic assignments
|
|
* $query->addAssignments(array(
|
|
* '"Object"."Title"' => 'Bob',
|
|
* '"Object"."Description"' => 'Bob was here'
|
|
* ))
|
|
*
|
|
* // Parameterised assignments
|
|
* $query->addAssignments(array(
|
|
* '"Object"."Title"' => array('?' => 'Bob')),
|
|
* '"Object"."Description"' => array('?' => null))
|
|
* ))
|
|
*
|
|
* // Complex parameters
|
|
* $query->addAssignments(array(
|
|
* '"Object"."Score"' => array('MAX(?,?)' => array(1, 3))
|
|
* ));
|
|
*
|
|
* // Assigment of literal SQL for a field. The empty array is
|
|
* // important to denote the zero-number paramater list
|
|
* $query->addAssignments(array(
|
|
* '"Object"."Score"' => array('NOW()' => array())
|
|
* ));
|
|
*
|
|
* </code>
|
|
*
|
|
* @param array $assignments The list of fields to assign
|
|
* @return $this The self reference to this row
|
|
*/
|
|
public function addAssignments(array $assignments) {
|
|
$assignments = $this->normaliseAssignments($assignments);
|
|
$this->assignments = array_merge($this->assignments, $assignments);
|
|
return $this;
|
|
}
|
|
|
|
/**
|
|
* Sets the list of assignments to the given list
|
|
*
|
|
* @see SQLWriteExpression::addAssignments() for syntax examples
|
|
*
|
|
* @param array $assignments
|
|
* @return $this The self reference to this row
|
|
*/
|
|
public function setAssignments(array $assignments) {
|
|
return $this->clear()->addAssignments($assignments);
|
|
}
|
|
|
|
/**
|
|
* Retrieves the list of assignments in parameterised format
|
|
*
|
|
* @return array List of assigments. The key of this array will be the
|
|
* column to assign, and the value a parameterised array in the format
|
|
* array('SQL' => array(parameters));
|
|
*/
|
|
public function getAssignments() {
|
|
return $this->assignments;
|
|
}
|
|
|
|
/**
|
|
* Set the value for a single field
|
|
*
|
|
* E.g.
|
|
* <code>
|
|
*
|
|
* // Literal assignment
|
|
* $query->assign('"Object"."Description"', 'lorum ipsum');
|
|
*
|
|
* // Single parameter
|
|
* $query->assign('"Object"."Title"', array('?' => 'Bob'));
|
|
*
|
|
* // Complex parameters
|
|
* $query->assign('"Object"."Score"', array('MAX(?,?)' => array(1, 3));
|
|
* </code>
|
|
*
|
|
* @param string $field The field name to update
|
|
* @param mixed $value The value to assign to this field. This could be an
|
|
* array containing a parameterised SQL query of any number of parameters,
|
|
* or a single literal value.
|
|
* @return $this The self reference to this row
|
|
*/
|
|
public function assign($field, $value) {
|
|
return $this->addAssignments(array($field => $value));
|
|
}
|
|
|
|
/**
|
|
* Assigns a value to a field using the literal SQL expression, rather than
|
|
* a value to be escaped
|
|
*
|
|
* @param string $field The field name to update
|
|
* @param string $sql The SQL to use for this update. E.g. "NOW()"
|
|
* @return $this The self reference to this row
|
|
*/
|
|
public function assignSQL($field, $sql) {
|
|
return $this->assign($field, array($sql => array()));
|
|
}
|
|
|
|
/**
|
|
* Determine if this assignment is empty
|
|
*
|
|
* @return boolean Flag indicating that this assignment is empty
|
|
*/
|
|
public function isEmpty() {
|
|
return empty($this->assignments);
|
|
}
|
|
|
|
/**
|
|
* Retrieves the list of columns updated
|
|
*
|
|
* @return array
|
|
*/
|
|
public function getColumns() {
|
|
return array_keys($this->assignments);
|
|
}
|
|
|
|
/**
|
|
* Clears all assignment values
|
|
*
|
|
* @return $this The self reference to this row
|
|
*/
|
|
public function clear() {
|
|
$this->assignments = array();
|
|
return $this;
|
|
}
|
|
}
|