MOON
Server: Apache
System: Linux server1.studioinfinity.com.br 2.6.32-954.3.5.lve1.4.90.el6.x86_64 #1 SMP Tue Feb 21 12:26:30 UTC 2023 x86_64
User: artinside (517)
PHP: 7.4.33
Disabled: exec,passthru,shell_exec,system
Upload Files
File: /home/artinside/sites.artinside.com.br/paliar/vendor/aplus/database/src/Manipulation/Replace.php
<?php declare(strict_types=1);
/*
 * This file is part of Aplus Framework Database Library.
 *
 * (c) Natan Felles <natanfelles@gmail.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */
namespace Framework\Database\Manipulation;

use InvalidArgumentException;
use LogicException;

/**
 * Class Replace.
 *
 * @see https://mariadb.com/kb/en/replace/
 *
 * @package database
 */
class Replace extends Statement
{
    use Traits\Select;
    use Traits\Set;
    use Traits\Values;

    /**
     * @see https://mariadb.com/kb/en/insert-delayed/
     */
    public const string OPT_DELAYED = 'DELAYED';
    /**
     * @see https://mariadb.com/kb/en/high_priority-and-low_priority/
     */
    public const string OPT_LOW_PRIORITY = 'LOW_PRIORITY';

    /**
     * @param string $table
     *
     * @return static
     */
    public function into(string $table) : static
    {
        $this->sql['into'] = $table;
        return $this;
    }

    protected function renderInto() : string
    {
        if (!isset($this->sql['into'])) {
            throw new LogicException('INTO table must be set');
        }
        return ' INTO ' . $this->renderIdentifier($this->sql['into']);
    }

    /**
     * @param string $column
     * @param string ...$columns
     *
     * @return static
     */
    public function columns(string $column, string ...$columns) : static
    {
        $this->sql['columns'] = [$column, ...$columns];
        return $this;
    }

    protected function renderColumns() : ?string
    {
        if (!isset($this->sql['columns'])) {
            return null;
        }
        $columns = [];
        foreach ($this->sql['columns'] as $column) {
            $columns[] = $this->renderIdentifier($column);
        }
        $columns = \implode(', ', $columns);
        return " ({$columns})";
    }

    protected function renderOptions() : ?string
    {
        if (!$this->hasOptions()) {
            return null;
        }
        $options = $this->sql['options'];
        foreach ($options as &$option) {
            $input = $option;
            $option = \strtoupper($option);
            if (!\in_array($option, [
                static::OPT_DELAYED,
                static::OPT_LOW_PRIORITY,
            ], true)) {
                throw new InvalidArgumentException("Invalid option: {$input}");
            }
        }
        unset($option);
        $intersection = \array_intersect(
            $options,
            [static::OPT_DELAYED, static::OPT_LOW_PRIORITY]
        );
        if (\count($intersection) > 1) {
            throw new LogicException(
                'Options LOW_PRIORITY and DELAYED can not be used together'
            );
        }
        $options = \implode(' ', $options);
        return " {$options}";
    }

    protected function checkRowStatementsConflict() : void
    {
        if (!isset($this->sql['values'])
            && !isset($this->sql['select'])
            && !$this->hasSet()
        ) {
            throw new LogicException(
                'The REPLACE INTO must be followed by VALUES, SET or SELECT statement'
            );
        }
    }

    /**
     * Renders the REPLACE statement.
     *
     * @return string
     */
    public function sql() : string
    {
        $sql = 'REPLACE' . \PHP_EOL;
        $part = $this->renderOptions();
        if ($part) {
            $sql .= $part . \PHP_EOL;
        }
        $sql .= $this->renderInto() . \PHP_EOL;
        $part = $this->renderColumns();
        if ($part) {
            $sql .= $part . \PHP_EOL;
        }
        $this->checkRowStatementsConflict();
        $part = $this->renderValues();
        if ($part) {
            $sql .= $part . \PHP_EOL;
        }
        $part = $this->renderSetCheckingConflicts();
        if ($part) {
            $sql .= $part . \PHP_EOL;
        }
        $part = $this->renderSelect();
        if ($part) {
            $sql .= $part . \PHP_EOL;
        }
        return $sql;
    }

    /**
     * Runs the REPLACE statement.
     *
     * @return int|string The number of affected rows
     */
    public function run() : int | string
    {
        return $this->database->exec($this->sql());
    }
}