2015-11-18 19 views
5

Ich versuche verzweifelt, die Funktion LEVENSHTEIN in Symfony2 einzuschließen, aber ich erhalte immer noch Fehler. Specs +, was ich bisher getan habe:Symfony2 - Benutzerdefinierte DQL-Funktion registriert, aber existiert nicht

  • PostgreSQL 9.3 enthalten
  • levenshtein in fuzzystrmatch Erweiterung
  • die Funktion über Shell-Ausführung getestet. Funktioniert völlig in Ordnung:

    postgres=# SELECT levenshtein('test', 'text'); 
    levenshtein 
    ------------- 
          1 
    (1 row) 
    
  • Hinzugefügt wurde die Funktion in DQL:

    <?php 
    
    namespace AppBundle\DQL; 
    
    use Doctrine\ORM\Query\AST\Functions\FunctionNode; 
    use Doctrine\ORM\Query\Lexer; 
    use Doctrine\ORM\Query\Parser; 
    use Doctrine\ORM\Query\SqlWalker; 
    
    class LevenshteinFunction extends FunctionNode { 
    
        public $firstStringExpression = null; 
    
        public $secondStringExpression = null; 
    
        public function getSql(SqlWalker $sqlWalker) { 
         return 'LEVENSHTEIN(' . $this->firstStringExpression->dispatch($sqlWalker) . ', ' . $this->secondStringExpression->dispatch($sqlWalker) . ')'; 
        } 
    
        public function parse(Parser $parser) { 
         // levenshtein(str1, str2) 
         $parser->match(Lexer::T_IDENTIFIER); 
         $parser->match(Lexer::T_OPEN_PARENTHESIS); 
         $this->firstStringExpression = $parser->StringPrimary(); 
         $parser->match(Lexer::T_COMMA); 
         $this->secondStringExpression = $parser->StringPrimary(); 
         $parser->match(Lexer::T_CLOSE_PARENTHESIS); 
        } 
    } 
    

    config.yml

    orm: 
        auto_generate_proxy_classes: "%kernel.debug%" 
        auto_mapping: true 
        dql: 
         numeric_functions: 
          LEVENSHTEIN: AppBundle\DQL\LevenshteinFunction 
    
  • Problem: Bei der Ausführung der folgenden Codeblock in meinem Repository Folgende Fehler treten auf:

    $this->getEntityManager()->createQuery("SELECT LEVENSHTEIN('test', 'text') FROM AppBundle:User"); 
    return $query->getResult(); 
    

    SQLSTATE[42883]: Undefined function: 7 ERROR: function levenshtein(unknown, unknown) does not exist

Was bin ich? Warum erkennt DQL/Symfony/PDO/... die Funktion nicht? Jede Hilfe wird sehr geschätzt!

Antwort

1

Der Fehler kommt von Postgres, scheint ein Problem mit der Sichtbarkeit.

Das Zusatzmodul fuzzystrmatch muss natürlich installiert werden. Das hast du offensichtlich getan, oder dein Funktionsaufruf würde auch nicht in psql funktionieren.

Wenn es in psql funktioniert, aber nicht in der App, bleiben nur ein paar mögliche Erklärungen. Offensichtliche zuerst:

  • Sie sind mit derselben Datenbank verbunden? (Gleicher Server, gleicher Port, gleiche db?)

  • Sie verbinden sich mit demselben Benutzer? Wahrscheinlich nicht ...

  • Wenn Sie sich mit einem anderen Benutzer verbinden (aber auf jeden Fall), prüfen Sie, ob Sie den gleichen Suchpfad verwenden. Führen Sie entweder in Verbindung und vergleichen:

    SHOW search_path; 
    

    Details - und wie setzen die search_path:

Beachten Sie, dass Erweiterungen in jedem Schema installiert werden kann deine Entscheidung. Standard ist das erste Schema im search_path (das „aktuellen Schema“ zum Zeitpunkt der Installation, die typischerweise public, aber ich weiß nicht, dass über die Installation der Dokumentation:.

If not specified, and the extension's control file does not specify a schema either, the current default object creation schema is used.

Run dies zu ein paar Dinge diagnostizieren:

SELECT e.extname AS extension, nsp.nspname AS schema 
    , r.rolname AS schema_owner, nsp.nspacl AS schema_acl 
FROM pg_extension e 
JOIN pg_namespace nsp ON nsp.oid = e.extnamespace 
JOIN pg_roles  r ON r.oid = nsp.nspowner 

Sie erhalten so etwas wie:

extension | schema | schema_owner |    schema_acl 

---------------+------------+--------------+------------------------------------- 
adminpack  | pg_catalog | postgres  | {postgres=UC/postgres,=U/postgres} 
plpgsql  | pg_catalog | postgres  | {postgres=UC/postgres,=U/postgres} 
fuzzystrmatch | public  | postgres  | {postgres=UC/postgres,=UC/postgres} 
tablefunc  | public  | postgres  | {postgres=UC/postgres,=UC/postgres} 
... 

Wenn schema_acl umfasst =U/postgres (U for USAGE), dann hat die Rolle public Zugriff, d. H. Jeder.

Setzen Sie die search_path für Ihre Verbindung entsprechend oder (erneut) zu einem sichtbaren Schema installieren und es sollte funktionieren.

Theoretisch, die besitzende Rolle oder ein Super-User können die EXECUTE Erlaubnis von der Funktion selbst ...

haben widerrufen
1

Ihre Funktionsklasse scheint mir ok, aber Ihre Konfiguration könnte falsch sein. Dies ist, was ich für meine CAST Funktion haben:

doctrine: 
    orm: 
     dql: 
      string_functions: 
       CAST: App\MyBundle\Doctrine\DBAL\Functions\Porgres\Cast 

Sie sollten beachten, dass Sie verschiedene Kollektionen für die verschiedenen Arten von Funktionen haben das heißt string_functions, numeric_functions, datetime_functions. Alle von ihnen sind im offiziellen documentation aufgeführt.

Ansonsten sollte Ihr Code gut funktionieren, nachdem Sie Ihren Cache gereinigt haben.

Verwandte Themen