2013-03-25 17 views

Antwort

6

Sie müssen eine custom DQL function dafür implementieren.

Es gibt einige Beispiele in DoctrineExtensions.

Sie können es umsetzen wie folgt vor:

<?php 

namespace MyApp\DQL; 

use Doctrine\ORM\Query\AST\Functions\FunctionNode; 
use Doctrine\ORM\Query\Lexer; 
use Doctrine\ORM\Query\SqlWalker; 

class Round extends FunctionNode 
{ 
    private $arithmeticExpression; 

    public function getSql(SqlWalker $sqlWalker) 
    { 

     return 'ROUND(' . $sqlWalker->walkSimpleArithmeticExpression(
      $this->arithmeticExpression 
     ) . ')'; 
    } 

    public function parse(\Doctrine\ORM\Query\Parser $parser) 
    { 

     $lexer = $parser->getLexer(); 

     $parser->match(Lexer::T_IDENTIFIER); 
     $parser->match(Lexer::T_OPEN_PARENTHESIS); 

     $this->arithmeticExpression = $parser->SimpleArithmeticExpression(); 

     $parser->match(Lexer::T_CLOSE_PARENTHESIS); 
    } 
} 

Sie können dann in der Konfiguration registrieren, während die ORM Bootstrapping:

$config = new \Doctrine\ORM\Configuration(); 

$config->addCustomNumericFunction('ROUND', 'MyApp\DQL\Round'); 
+0

Ja, das wie der einzige Weg, es zu tun aussieht. Ich schätze die Anweisungen. – Shawn

6

etwas sauberer Ansatz leicht unter Verwendung würde modifizierter @Ocramius-Code.

Dieses Stück Code in: src/YourNamespace/YourMainBundle/DoctrineFunctions/ Verzeichnis als Round.php Dateiname:

<?php 
namespace YourApp\YourMainBundle\DoctrineFunctions; 

use Doctrine\ORM\Query\AST\Functions\FunctionNode, 
    Doctrine\ORM\Query\Lexer; 

class Round extends FunctionNode 
{ 
    private $arithmeticExpression; 

    public function parse(\Doctrine\ORM\Query\Parser $parser) 
    { 

     $lexer = $parser->getLexer(); 

     $parser->match(Lexer::T_IDENTIFIER); 
     $parser->match(Lexer::T_OPEN_PARENTHESIS); 

     $this->arithmeticExpression = $parser->SimpleArithmeticExpression(); 

     $parser->match(Lexer::T_CLOSE_PARENTHESIS); 
    } 

    public function getSql(\Doctrine\ORM\Query\SqlWalker $sqlWalker) 
    { 
     return 'ROUND(' . $sqlWalker->walkSimpleArithmeticExpression($this->arithmeticExpression) . ')'; 
    } 
} 

diese dann in Ihrem app/config/config.yml setzen:

doctrine: 
    dql: 
     numeric_functions: 
      round: YourApp\YourMainBundle\DoctrineFunctions\Round 

, dass Sie die ROUND() Funktion direkt verwenden, würde es in Ihre DQL SELECT-Abfragen; egal ob mit QueryBuilder oder direkt über createQuery()

+2

Thx viel für den Hinweis, aber die Config "dql" muss unter "Orm" sein (Lehre: Orm: dql: ...). – ownking

3

Wenn Sie Rundungsgenauigkeit angeben möchten, können Sie die Klasse here verwenden. Wenn Sie Symfony verwenden, installieren Sie das Bundle, da Sie auch zusätzliche Standard-MySQL-Funktionen erhalten.

Der Code der verknüpften Ressource ist auch unten zur Verfügung:

<?php 
namespace Mapado\MysqlDoctrineFunctions\DQL; 
use \Doctrine\ORM\Query\AST\Functions\FunctionNode; 
use \Doctrine\ORM\Query\Lexer; 
/** 
* MysqlRound 
* 
* @uses FunctionNode 
* @author Julien DENIAU <[email protected]> 
*/ 
class MysqlRound extends FunctionNode 
{ 
    /** 
    * simpleArithmeticExpression 
    * 
    * @var mixed 
    * @access public 
    */ 
    public $simpleArithmeticExpression; 
    /** 
    * roundPrecission 
    * 
    * @var mixed 
    * @access public 
    */ 
    public $roundPrecission; 
    /** 
    * getSql 
    * 
    * @param \Doctrine\ORM\Query\SqlWalker $sqlWalker 
    * @access public 
    * @return string 
    */ 
    public function getSql(\Doctrine\ORM\Query\SqlWalker $sqlWalker) 
    { 
     return 'ROUND(' . 
       $sqlWalker->walkSimpleArithmeticExpression($this->simpleArithmeticExpression) .','. 
       $sqlWalker->walkStringPrimary($this->roundPrecission) . 
     ')'; 
    } 
    /** 
    * parse 
    * 
    * @param \Doctrine\ORM\Query\Parser $parser 
    * @access public 
    * @return void 
    */ 
    public function parse(\Doctrine\ORM\Query\Parser $parser) 
    { 
     $parser->match(Lexer::T_IDENTIFIER); 
     $parser->match(Lexer::T_OPEN_PARENTHESIS); 
     $this->simpleArithmeticExpression = $parser->SimpleArithmeticExpression(); 
     $parser->match(Lexer::T_COMMA); 
     $this->roundPrecission = $parser->ArithmeticExpression(); 
     if ($this->roundPrecission == null) { 
      $this->roundPrecission = 0; 
     } 
     $parser->match(Lexer::T_CLOSE_PARENTHESIS); 
    } 
} 
Verwandte Themen