Вход Регистрация
Файл: framework/model/queries/SQLAssignmentRow.php
Строк: 270
<?php

/**
 * Represents a list of updates / inserts made to a single row in a table
 *
 * @package framework
 * @subpackage model
 */
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);
            }
        }

        
user_error("Nested field assignments should be given as a single parameterised item array in "
                
.  "array('?' => array('value')) format)"E_USER_ERROR);
    }

    
/**
     * Given a list of assignments in any user-acceptible format, normalise the
     * value to a common array('SQL' => array(parameters)) format
     *
     * @param array $predicates 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 self 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 self 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 self 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 self 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 self The self reference to this row
     */
    
public function clear() {
        
$this->assignments = array();
        return 
$this;
    }
}
Онлайн: 0
Реклама