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); } $return = array( 'sql' => '', 'parameters' => array() ); // initialize variables $parts = $expression->getExpressionData(); $expressionParamIndex = 1; foreach ($parts as $part) { // if it is a string, simply tack it onto the return sql "specification" string if (is_string($part)) { $return['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) { // 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++; $return['parameters'][$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) $return['sql'] .= vsprintf($part[0], $values); } return $return; }
/** * * @staticvar int $runtimeExpressionPrefix * @param ExpressionInterface $expression * @param PlatformInterface $platform * @param null|DriverInterface $driver * @param null|ParameterContainer $parameterContainer * @param null|string $namedParameterPrefix * * @return string * * @throws Exception\RuntimeException */ protected function processExpression(ExpressionInterface $expression, PlatformInterface $platform, DriverInterface $driver = null, ParameterContainer $parameterContainer = null, $namedParameterPrefix = null) { $namedParameterPrefix = !$namedParameterPrefix ? $namedParameterPrefix : $this->processInfo['paramPrefix'] . $namedParameterPrefix; // static counter for the number of times this method was invoked across the PHP runtime static $runtimeExpressionPrefix = 0; if ($parameterContainer && (!is_string($namedParameterPrefix) || $namedParameterPrefix == '')) { $namedParameterPrefix = sprintf('expr%04dParam', ++$runtimeExpressionPrefix); } $sql = ''; // 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])) { continue; } $type = $types[$vIndex]; if ($value instanceof Select) { // process sub-select $values[$vIndex] = '(' . $this->processSubSelect($value, $platform, $driver, $parameterContainer) . ')'; } elseif ($value instanceof ExpressionInterface) { // recursive call to satisfy nested expressions $values[$vIndex] = $this->processExpression($value, $platform, $driver, $parameterContainer, $namedParameterPrefix . $vIndex . 'subpart'); } elseif ($type == ExpressionInterface::TYPE_IDENTIFIER) { $values[$vIndex] = $platform->quoteIdentifierInFragment($value); } elseif ($type == 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 ($parameterContainer) { $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 ($type == 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); } return $sql; }
/** * * @return array of array|string should return an array in the format: * * array ( * // a sprintf formatted string * string $specification, * * // the values for the above sprintf formatted string * array $values, * * // an array of equal length of the $values array, with either TYPE_IDENTIFIER or TYPE_VALUE for each value * array $types, * ) * */ public function getExpressionData() { $expressionData = $this->subject->getExpressionData(); foreach ($expressionData as &$expressionPart) { if (!is_array($expressionPart)) { continue; } $parametersCount = count($expressionPart[1]); for ($i = 0; $i < $parametersCount; $i++) { if ($this->platform->isFloatConversionEnabled() && is_float($expressionPart[1][$i]) && $expressionPart[2][$i] == Expression::TYPE_VALUE) { $expressionPart[1][$i] = $this->platform->toFloatSinglePrecision($expressionPart[1][$i]); $expressionPart[2][$i] = Expression::TYPE_LITERAL; } if (is_bool($expressionPart[1][$i]) && $expressionPart[2][$i] == Expression::TYPE_VALUE) { $expressionPart[1][$i] = (int) $expressionPart[1][$i]; } } } return $expressionData; }