src/BuildSqlUpdateSetCapableTrait.php
<?php
namespace RebelCode\Storage\Resource\Sql;
use Dhii\Expression\ExpressionInterface;
use Dhii\Expression\TermInterface;
use Dhii\Output\Exception\RendererExceptionInterface;
use Dhii\Output\Exception\TemplateRenderExceptionInterface;
use Dhii\Util\String\StringableInterface as Stringable;
use InvalidArgumentException;
use OutOfRangeException;
use Traversable;
/**
* Provides functionality for building the SET portion of an SQL UPDATE query.
*
* @since [*next-version*]
*/
trait BuildSqlUpdateSetCapableTrait
{
/**
* Builds the SET portion of an SQL UPDATE query.
*
* @since [*next-version*]
*
* @param array|ExpressionInterface[]|Traversable $changeSet The change set, mapping field names to their new
* values or value expressions.
* @param array $valueHashMap Optional map of value names and their hashes.
*
* @return string The built SET portion string.
*/
protected function _buildSqlUpdateSet($changeSet, array $valueHashMap)
{
$changes = [];
foreach ($changeSet as $_column => $_value) {
if ($_value instanceof ExpressionInterface) {
// Render expression value
$_value = $this->_renderSqlExpression($_value, $valueHashMap);
} elseif (is_scalar($_value)) {
// Change scalar values to hashes, if they exist
$_valueStr = $this->_normalizeString($_value);
$_value = isset($valueHashMap[$_valueStr])
? $valueHashMap[$_valueStr]
: $this->_normalizeSqlValue($_value, $_column);
} else {
// Otherwise just normalize
$_value = $this->_normalizeSqlValue($_value, $_column);
}
$changes[] = sprintf('`%1$s` = %2$s', $_column, $_value);
}
$updateSet = implode(', ', $changes);
return $updateSet;
}
/**
* Normalizes an SQL value, quoting it if it's a string.
*
* @since [*next-version*]
*
* @param string|int|float|bool|Stringable $value The input value.
* @param string|Stringable|null $column Optional column name, used for normalizing for a specific
* column's type.
*
* @throws OutOfRangeException If the value cannot be normalized.
*
* @return string The normalized value.
*/
abstract protected function _normalizeSqlValue($value, $column = null);
/**
* Normalizes a value to its string representation.
*
* The values that can be normalized are any scalar values, as well as
* {@see StringableInterface).
*
* @since [*next-version*]
*
* @param string|int|float|bool|Stringable $subject The value to normalize to string.
*
* @throws InvalidArgumentException If the value cannot be normalized.
*
* @return string The string that resulted from normalization.
*/
abstract protected function _normalizeString($subject);
/**
* Renders an SQL expression.
*
* @since [*next-version*]
*
* @param TermInterface $expression The expression to render.
* @param string[]|Stringable[] $valueHashMap Optional mapping of term names to their hashes.
*
* @throws RendererExceptionInterface If an error occurred while rendering.
* @throws TemplateRenderExceptionInterface If the renderer failed to render the expression and context.
*
* @return string|Stringable The rendered expression.
*/
abstract protected function _renderSqlExpression(TermInterface $expression, array $valueHashMap = []);
}