Source of file AbstractSql.php
Size: 8,349 Bytes - Last Modified: 2014-03-12T23:21:18+01:00
/home/theseer/Downloads/ZendFramework-2.3.0/library/Zend/Db/Sql/AbstractSql.php
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189 | <?php /** * Zend Framework (http://framework.zend.com/) * * @link http://github.com/zendframework/zf2 for the canonical source repository * @copyright Copyright (c) 2005-2014 Zend Technologies USA Inc. (http://www.zend.com) * @license http://framework.zend.com/license/new-bsd New BSD License */ namespace Zend\Db\Sql; use Zend\Db\Adapter\Driver\DriverInterface; use Zend\Db\Adapter\ParameterContainer; use Zend\Db\Adapter\Platform\PlatformInterface; use Zend\Db\Adapter\StatementContainer; abstract class AbstractSql { /** * @var array */ protected $specifications = array(); /** * @var string */ protected $processInfo = array('paramPrefix' => '', 'subselectCount' => 0); /** * @var array */ protected $instanceParameterIndex = array(); protected function processExpression(ExpressionInterface $expression, PlatformInterface $platform, DriverInterface $driver = null, $namedParameterPrefix = null) { // static counter for the number of times this method was invoked across the PHP runtime static $runtimeExpressionPrefix = 0; if ($driver && ((!is_string($namedParameterPrefix) || $namedParameterPrefix == ''))) { $namedParameterPrefix = sprintf('expr%04dParam', ++$runtimeExpressionPrefix); } $sql = ''; $statementContainer = new StatementContainer; $parameterContainer = $statementContainer->getParameterContainer(); // initialize variables $parts = $expression->getExpressionData(); if (!isset($this->instanceParameterIndex[$namedParameterPrefix])) { $this->instanceParameterIndex[$namedParameterPrefix] = 1; } $expressionParamIndex = &$this->instanceParameterIndex[$namedParameterPrefix]; foreach ($parts as $part) { // if it is a string, simply tack it onto the return sql "specification" string if (is_string($part)) { $sql .= $part; continue; } if (!is_array($part)) { throw new Exception\RuntimeException('Elements returned from getExpressionData() array must be a string or array.'); } // process values and types (the middle and last position of the expression data) $values = $part[1]; $types = (isset($part[2])) ? $part[2] : array(); foreach ($values as $vIndex => $value) { if (isset($types[$vIndex]) && $types[$vIndex] == ExpressionInterface::TYPE_IDENTIFIER) { $values[$vIndex] = $platform->quoteIdentifierInFragment($value); } elseif (isset($types[$vIndex]) && $types[$vIndex] == ExpressionInterface::TYPE_VALUE && $value instanceof Select) { // process sub-select if ($driver) { $values[$vIndex] = '(' . $this->processSubSelect($value, $platform, $driver, $parameterContainer) . ')'; } else { $values[$vIndex] = '(' . $this->processSubSelect($value, $platform) . ')'; } } elseif (isset($types[$vIndex]) && $types[$vIndex] == ExpressionInterface::TYPE_VALUE && $value instanceof ExpressionInterface) { // recursive call to satisfy nested expressions $innerStatementContainer = $this->processExpression($value, $platform, $driver, $namedParameterPrefix . $vIndex . 'subpart'); $values[$vIndex] = $innerStatementContainer->getSql(); if ($driver) { $parameterContainer->merge($innerStatementContainer->getParameterContainer()); } } elseif (isset($types[$vIndex]) && $types[$vIndex] == ExpressionInterface::TYPE_VALUE) { // if prepareType is set, it means that this particular value must be // passed back to the statement in a way it can be used as a placeholder value if ($driver) { $name = $namedParameterPrefix . $expressionParamIndex++; $parameterContainer->offsetSet($name, $value); $values[$vIndex] = $driver->formatParameterName($name); continue; } // if not a preparable statement, simply quote the value and move on $values[$vIndex] = $platform->quoteValue($value); } elseif (isset($types[$vIndex]) && $types[$vIndex] == ExpressionInterface::TYPE_LITERAL) { $values[$vIndex] = $value; } } // after looping the values, interpolate them into the sql string (they might be placeholder names, or values) $sql .= vsprintf($part[0], $values); } $statementContainer->setSql($sql); return $statementContainer; } /** * @param $specifications * @param $parameters * @return string * @throws Exception\RuntimeException */ protected function createSqlFromSpecificationAndParameters($specifications, $parameters) { if (is_string($specifications)) { return vsprintf($specifications, $parameters); } $parametersCount = count($parameters); foreach ($specifications as $specificationString => $paramSpecs) { if ($parametersCount == count($paramSpecs)) { break; } unset($specificationString, $paramSpecs); } if (!isset($specificationString)) { throw new Exception\RuntimeException( 'A number of parameters was found that is not supported by this specification' ); } $topParameters = array(); foreach ($parameters as $position => $paramsForPosition) { if (isset($paramSpecs[$position]['combinedby'])) { $multiParamValues = array(); foreach ($paramsForPosition as $multiParamsForPosition) { $ppCount = count($multiParamsForPosition); if (!isset($paramSpecs[$position][$ppCount])) { throw new Exception\RuntimeException('A number of parameters (' . $ppCount . ') was found that is not supported by this specification'); } $multiParamValues[] = vsprintf($paramSpecs[$position][$ppCount], $multiParamsForPosition); } $topParameters[] = implode($paramSpecs[$position]['combinedby'], $multiParamValues); } elseif ($paramSpecs[$position] !== null) { $ppCount = count($paramsForPosition); if (!isset($paramSpecs[$position][$ppCount])) { throw new Exception\RuntimeException('A number of parameters (' . $ppCount . ') was found that is not supported by this specification'); } $topParameters[] = vsprintf($paramSpecs[$position][$ppCount], $paramsForPosition); } else { $topParameters[] = $paramsForPosition; } } return vsprintf($specificationString, $topParameters); } protected function processSubSelect(Select $subselect, PlatformInterface $platform, DriverInterface $driver = null, ParameterContainer $parameterContainer = null) { if ($driver) { $stmtContainer = new StatementContainer; // Track subselect prefix and count for parameters $this->processInfo['subselectCount']++; $subselect->processInfo['subselectCount'] = $this->processInfo['subselectCount']; $subselect->processInfo['paramPrefix'] = 'subselect' . $subselect->processInfo['subselectCount']; // call subselect $subselect->prepareStatement(new \Zend\Db\Adapter\Adapter($driver, $platform), $stmtContainer); // copy count $this->processInfo['subselectCount'] = $subselect->processInfo['subselectCount']; $parameterContainer->merge($stmtContainer->getParameterContainer()->getNamedArray()); $sql = $stmtContainer->getSql(); } else { $sql = $subselect->getSqlString($platform); } return $sql; } } |