ACC SHELL

Path : /srv/www/vhosts/centrumlb/3rdparty/Nette/Database/
File Upload :
Current File : /srv/www/vhosts/centrumlb/3rdparty/Nette/Database/SqlPreprocessor.php

<?php

/**
 * This file is part of the Nette Framework (http://nette.org)
 * Copyright (c) 2004 David Grudl (http://davidgrudl.com)
 * @package Nette\Database
 */



/**
 * SQL preprocessor.
 *
 * @author     David Grudl
 * @package Nette\Database
 */
class NSqlPreprocessor extends NObject
{
	/** @var NConnection */
	private $connection;

	/** @var ISupplementalDriver */
	private $driver;

	/** @var array of input parameters */
	private $params;

	/** @var array of parameters to be processed by PDO */
	private $remaining;

	/** @var int */
	private $counter;

	/** @var string values|assoc|multi */
	private $arrayMode;


	public function __construct(NConnection $connection)
	{
		$this->connection = $connection;
		$this->driver = $connection->getSupplementalDriver();
	}


	/**
	 * @param  string
	 * @param  array
	 * @return array of [sql, params]
	 */
	public function process($sql, $params)
	{
		$this->params = $params;
		$this->counter = 0;
		$this->remaining = array();
		$this->arrayMode = 'assoc';

		$sql = NStrings::replace($sql, '~\'.*?\'|".*?"|\?|\b(?:INSERT|REPLACE|UPDATE)\b|/\*.*?\*/|--[^\n]*~si', array($this, 'callback'));

		while ($this->counter < count($params)) {
			$sql .= ' ' . $this->formatValue($params[$this->counter++]);
		}

		return array($sql, $this->remaining);
	}


	/** @internal */
	public function callback($m)
	{
		$m = $m[0];
		if ($m[0] === "'" || $m[0] === '"' || $m[0] === '/' || $m[0] === '-') { // string or comment
			return $m;

		} elseif ($m === '?') { // placeholder
			if ($this->counter >= count($this->params)) {
				throw new InvalidArgumentException('There are more placeholders than passed parameters.');
			}
			return $this->formatValue($this->params[$this->counter++]);

		} else { // INSERT, REPLACE, UPDATE
			$this->arrayMode = strtoupper($m) === 'UPDATE' ? 'assoc' : 'values';
			return $m;
		}
	}


	private function formatValue($value)
	{
		if (is_string($value)) {
			if (strlen($value) > 20) {
				$this->remaining[] = $value;
				return '?';

			} else {
				return $this->connection->quote($value);
			}

		} elseif (is_int($value)) {
			return (string) $value;

		} elseif (is_float($value)) {
			return rtrim(rtrim(number_format($value, 10, '.', ''), '0'), '.');

		} elseif (is_bool($value)) {
			return $this->driver->formatBool($value);

		} elseif ($value === NULL) {
			return 'NULL';

		} elseif ($value instanceof NTableRow) {
			return $value->getPrimary();

		} elseif (is_array($value) || $value instanceof Traversable) {
			$vx = $kx = array();

			if ($value instanceof Traversable) {
				$value = iterator_to_array($value);
			}

			if (isset($value[0])) { // non-associative; value, value, value
				foreach ($value as $v) {
					$vx[] = $this->formatValue($v);
				}
				return implode(', ', $vx);

			} elseif ($this->arrayMode === 'values') { // (key, key, ...) VALUES (value, value, ...)
				$this->arrayMode = 'multi';
				foreach ($value as $k => $v) {
					$kx[] = $this->driver->delimite($k);
					$vx[] = $this->formatValue($v);
				}
				return '(' . implode(', ', $kx) . ') VALUES (' . implode(', ', $vx) . ')';

			} elseif ($this->arrayMode === 'assoc') { // key=value, key=value, ...
				foreach ($value as $k => $v) {
					$vx[] = $this->driver->delimite($k) . '=' . $this->formatValue($v);
				}
				return implode(', ', $vx);

			} elseif ($this->arrayMode === 'multi') { // multiple insert (value, value, ...), ...
				foreach ($value as $v) {
					$vx[] = $this->formatValue($v);
				}
				return '(' . implode(', ', $vx) . ')';
			}

		} elseif ($value instanceof DateTime) {
			return $this->driver->formatDateTime($value);

		} elseif ($value instanceof NSqlLiteral) {
			return $value->__toString();

		} else {
			$this->remaining[] = $value;
			return '?';
		}
	}

}

ACC SHELL 2018