ACC SHELL

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

<?php

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



/**
 * Reflection metadata class with discovery for a database.
 *
 * @author     Jan Skrasek
 * @property-write NConnection $connection
 * @package Nette\Database\Reflection
 */
class NDiscoveredReflection extends NObject implements IReflection
{
	/** @var NCache */
	protected $cache;

	/** @var ICacheStorage */
	protected $cacheStorage;

	/** @var NConnection */
	protected $connection;

	/** @var array */
	protected $structure = array();

	/** @var array */
	protected $loadedStructure;


	/**
	 * Create autodiscovery structure.
	 */
	public function __construct(ICacheStorage $storage = NULL)
	{
		$this->cacheStorage = $storage;
	}


	public function setConnection(NConnection $connection)
	{
		$this->connection = $connection;
		if ($this->cacheStorage) {
			$this->cache = new NCache($this->cacheStorage, 'Nette.Database.' . md5($connection->getDsn()));
			$this->structure = $this->loadedStructure = ($tmp=$this->cache->load('structure')) ? $tmp : $this->structure;
		}
	}


	public function __destruct()
	{
		if ($this->cache && $this->structure !== $this->loadedStructure) {
			$this->cache->save('structure', $this->structure);
		}
	}


	public function getPrimary($table)
	{
		$primary = & $this->structure['primary'][strtolower($table)];
		if (isset($primary)) {
			return empty($primary) ? NULL : $primary;
		}

		$columns = $this->connection->getSupplementalDriver()->getColumns($table);
		$primary = array();
		foreach ($columns as $column) {
			if ($column['primary']) {
				$primary[] = $column['name'];
			}
		}

		if (count($primary) === 0) {
			return NULL;
		} elseif (count($primary) === 1) {
			$primary = reset($primary);
		}

		return $primary;
	}


	public function getHasManyReference($table, $key, $refresh = TRUE)
	{
		if (isset($this->structure['hasMany'][strtolower($table)])) {
			$candidates = $columnCandidates = array();
			foreach ($this->structure['hasMany'][strtolower($table)] as $targetPair) {
				list($targetColumn, $targetTable) = $targetPair;
				if (stripos($targetTable, $key) === FALSE) {
					continue;
				}

				$candidates[] = array($targetTable, $targetColumn);
				if (stripos($targetColumn, $table) !== FALSE) {
					$columnCandidates[] = $candidate = array($targetTable, $targetColumn);
					if (strtolower($targetTable) === strtolower($key)) {
						return $candidate;
					}
				}
			}

			if (count($columnCandidates) === 1) {
				return reset($columnCandidates);
			} elseif (count($candidates) === 1) {
				return reset($candidates);
			}

			foreach ($candidates as $candidate) {
				if (strtolower($candidate[0]) === strtolower($key)) {
					return $candidate;
				}
			}
		}

		if ($refresh) {
			$this->reloadAllForeignKeys();
			return $this->getHasManyReference($table, $key, FALSE);
		}

		if (empty($candidates)) {
			throw new NMissingReferenceException("No reference found for \${$table}->related({$key}).");
		} else {
			throw new NAmbiguousReferenceKeyException('Ambiguous joining column in related call.');
		}
	}


	public function getBelongsToReference($table, $key, $refresh = TRUE)
	{
		if (isset($this->structure['belongsTo'][strtolower($table)])) {
			foreach ($this->structure['belongsTo'][strtolower($table)] as $column => $targetTable) {
				if (stripos($column, $key) !== FALSE) {
					return array($targetTable, $column);
				}
			}
		}

		if ($refresh) {
			$this->reloadForeignKeys($table);
			return $this->getBelongsToReference($table, $key, FALSE);
		}

		throw new NMissingReferenceException("No reference found for \${$table}->{$key}.");
	}


	protected function reloadAllForeignKeys()
	{
		$this->structure['hasMany'] = $this->structure['belongsTo'] = array();

		foreach ($this->connection->getSupplementalDriver()->getTables() as $table) {
			if ($table['view'] == FALSE) {
				$this->reloadForeignKeys($table['name']);
			}
		}

		foreach ($this->structure['hasMany'] as & $table) {
			uksort($table, create_function('$a, $b', '
				return strlen($a) - strlen($b);
			'));
		}
	}


	protected function reloadForeignKeys($table)
	{
		foreach ($this->connection->getSupplementalDriver()->getForeignKeys($table) as $row) {
			$this->structure['belongsTo'][strtolower($table)][$row['local']] = $row['table'];
			$this->structure['hasMany'][strtolower($row['table'])][$row['local'] . $table] = array($row['local'], $table);
		}

		if (isset($this->structure['belongsTo'][$table])) {
			uksort($this->structure['belongsTo'][$table], create_function('$a, $b', '
				return strlen($a) - strlen($b);
			'));
		}
	}

}

ACC SHELL 2018