Skip to content

Instantly share code, notes, and snippets.

@webdevilopers
Last active August 29, 2015 14:06
Show Gist options
  • Save webdevilopers/de0a56da54bc90aec5a7 to your computer and use it in GitHub Desktop.
Save webdevilopers/de0a56da54bc90aec5a7 to your computer and use it in GitHub Desktop.
DoctrineExtensions\Query\Mysql\Cast.php
<?php
namespace Plusquam\Bundle\ContractBundle\DoctrineExtensions\Query\Mysql;
use Doctrine\ORM\Query\AST\Functions\FunctionNode;
use Doctrine\ORM\Query\AST\Literal;
use Doctrine\ORM\Query\Parser;
use Doctrine\ORM\Query\Lexer;
use Doctrine\ORM\Query\SqlWalker;
class Cast extends FunctionNode
{
const PARAMETER_KEY = 'expression';
const TYPE_KEY = 'type';
protected $supportedTypes = array(
'char',
'date',
'datetime',
'time',
'int',
'integer',
'decimal'
);
/**
* @var array
*/
public $parameters = array();
/**
* {@inheritdoc}
*/
public function getSql(SqlWalker $sqlWalker)
{
/** @var Node $value */
$value = $this->parameters[self::PARAMETER_KEY];
$type = $this->parameters[self::TYPE_KEY];
$type = strtolower($type);
if ($type == 'char') {
$type = 'char(1)';
} elseif ($type == 'int' || $type == 'integer') {
$type = 'unsigned';
}
return 'CAST(' . $sqlWalker->walkArithmeticPrimary($value) . ' AS ' . $type . ')';
}
/**
* {@inheritdoc}
*/
public function parse(Parser $parser)
{
$parser->match(Lexer::T_IDENTIFIER);
$parser->match(Lexer::T_OPEN_PARENTHESIS);
$this->parameters[self::PARAMETER_KEY] = $parser->ArithmeticPrimary();
$parser->match(Lexer::T_AS);
$parser->match(Lexer::T_IDENTIFIER);
$lexer = $parser->getLexer();
$type = $lexer->token['value'];
if ($lexer->isNextToken(Lexer::T_OPEN_PARENTHESIS)) {
$parser->match(Lexer::T_OPEN_PARENTHESIS);
/** @var Literal $parameter */
$parameter = $parser->Literal();
$parameters = array(
$parameter->value
);
if ($lexer->isNextToken(Lexer::T_COMMA)) {
while ($lexer->isNextToken(Lexer::T_COMMA)) {
$parser->match(Lexer::T_COMMA);
$parameter = $parser->Literal();
$parameters[] = $parameter->value;
}
}
$parser->match(Lexer::T_CLOSE_PARENTHESIS);
$type .= '(' . implode(', ', $parameters) . ')';
}
if (!$this->checkType($type)) {
$parser->syntaxError(
sprintf(
'Type unsupported. Supported types are: "%s"',
implode(', ', $this->supportedTypes)
),
$lexer->token
);
}
$this->parameters[self::TYPE_KEY] = $type;
$parser->match(Lexer::T_CLOSE_PARENTHESIS);
}
/**
* Check that given type is supported.
*
* @param string $type
* @return bool
*/
protected function checkType($type)
{
$type = strtolower(trim($type));
foreach ($this->supportedTypes as $supportedType) {
if (strpos($type, $supportedType) === 0) {
return true;
}
}
return false;
}
}