phpmysqldoctrine-ormdoctrinezend-framework2

INET_ATON in where statement doctrine2 querybuilder zend2


Question: I want to run a query with querybuilder in Doctrine2 like:

SELECT * FROM TABLE WHERE `column1` = 'x' and (`column2` = INET_ATON('1.1.1.1') OR `column3` like '%bla%'...)

How should I do this in Doctrine2 with Zend2?

I tried this:

$where->add($qb->expr()->eq('column2', $qb->expr()->literal('inet_aton('1.1.1.1'))));

But that doen't work. Doctrine still adds quotes around the inet_aton function.


Solution

  • Ok I figured it out myself:

    A few things you should do:

    First make a DQL function

    <?php
    
    namespace Application\DQL;
    
    use Doctrine\ORM\Query\Lexer;
    
    class InetAtonFunction extends \Doctrine\ORM\Query\AST\Functions\FunctionNode
    {
        public $valueExpression = null;
    
        /**
         * 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->valueExpression = $parser->StringPrimary();
            $parser->match(Lexer::T_CLOSE_PARENTHESIS);
        }
    
        /**
         * getSql
         *
         * @param \Doctrine\ORM\Query\SqlWalker $sqlWalker
         * @access public
         * @return string
         */
        public function getSql(\Doctrine\ORM\Query\SqlWalker $sqlWalker)
        {
            return 'INET_ATON('. $this->valueExpression->dispatch($sqlWalker) . ')'; 
        }
    }
    

    After that add the function to the Doctrine ORM

    <?php
    namespace Observer;
    
    //...
    
    class Module implements
        AutoloaderProviderInterface,
        ConfigProviderInterface,
        ServiceProviderInterface
    {
    //...
        public function onBootstrap($e)
        {
    
            $application = $e->getParam('application');
            $sm  = $application->getServiceManager();
            $em  = $application->getEventManager();
    
            $entityManager = $sm->get('doctrine.entitymanager.orm_default');
            $entityManager->getConfiguration()->addCustomStringFunction('inet_aton', 'Application\DQL\InetAtonFunction');       
        }
    ...
    

    After this your good to go. Now you can run queries with querybuilder like

    SELECT whatever FROM someting where cloumn = inet_aton(:?)
    

    I hope this helps others with special function in Doctrine and Zend Framework2