RebelCode/sql-cqrs-resource-models-abstract

View on GitHub
src/BuildSqlUpdateSetCapableTrait.php

Summary

Maintainability
A
0 mins
Test Coverage
<?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 = []);
}