B
B
BonBon Slick2021-08-04 00:58:18
Doctrine ORM
BonBon Slick, 2021-08-04 00:58:18

Doctrine FunctionNode not found?

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

final class StringSimilarity extends FunctionNode {
...

    public function parse(Parser $parser): void {
   ...
    }

    public function getSql(SqlWalker $sqlWalker): string {
        return sprintf(
            "SIMILARITY(LOWER(%s), LOWER(%s))",
            $sqlWalker->walkStateFieldPathExpression($this->fieldName),
            $sqlWalker->walkInParameter($this->similarStr)
        );
    }
}


For dev + prod env works, but for tests it throws an error

SQLSTATE[HY000]: General error: 1 no such function: SIMILARITY. Code: 0 [] []


So the problem is somewhere in the configs.
Here are the usual configs, global root->config->packages->doctrine.yml
imports:
  - { resource: '../parameters.xml' }

parameters:
  # Adds a fallback DATABASE_URL if the env var is not set.
  # This allows you to run cache:warmup even if your
  # environment variables are not available yet.
  # You should not need to set this value.
  env(DATABASE_URL): ''

doctrine:
  dbal:
    driver: "%app.database_driver%"
    dbname: "%app.database_name%"
    host: "%app.database_host%"
    port: "%app.database_port%"
    user: "%app.database_user%"
    password: "%app.database_password%"
    charset: UTF8
    default_table_options:
      charset: UTF8
      collate: utf8_unicode_ci
    server_version: '13.0'
  #        unix_socket: /tmp/mysql.sock
  orm:
    auto_generate_proxy_classes: '%kernel.debug%'
    naming_strategy: doctrine.orm.naming_strategy.underscore
    auto_mapping: false
    second_level_cache:
      enabled: true
    mappings: # https://symfony.com/doc/current/reference/configuration/doctrine.html#mapping-configuration
      App: # Kernel.php improves mappings
        is_bundle: false
        type: xml
        dir: '%kernel.project_dir%/src/Infrastructure/Mapping/'
        prefix: 'App\Domain'
        alias: App
      # Register new DQL functions
    dql:
      datetime_functions:
        date_format: DoctrineExtensions\Query\Postgresql\DateFormat
        at_time_zone: DoctrineExtensions\Query\Postgresql\AtTimeZoneFunction
      string_functions:
        similarity: App\Infrastructure\Persistence\FunctionsExtensions\StringSimilarity


Package configs for tests root->config->packages->test->doctrine.yml
imports:
  - { resource: '../../parameters.xml' }

doctrine:
  dbal:
    default_connection: default
    connections:
      default:
        driver: pdo_sqlite
        path: '%kernel.cache_dir%/test.db'
        memory: false
        charset: UTF8

  orm:
      # Register new DQL functions
    dql:
      datetime_functions:
        date_format: DoctrineExtensions\Query\Postgresql\DateFormat
        at_time_zone: DoctrineExtensions\Query\Postgresql\AtTimeZoneFunction
      string_functions:
        similarity: App\Infrastructure\Persistence\FunctionsExtensions\StringSimilarity

There is a suspicion that pdo_sqlite does not support the pg_trgm SIMILARITY
extension. If so, then the error points to the wrong place at all, because it is registered both globally and for tests specifically, I doubt that the matter is in the phpunit.xml config, because there are project configs.

The question arises, how to be?
Using the same database for tests will increase the test time by several times. Testing purely in memory will not check queries for validity.

Answer the question

In order to leave comments, you need to log in

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question