web-dev-qa-db-fra.com

Citation automatique des mots réservés avec Doctrine 2

Est-il possible de citer automatiquement des mots réservés avec Doctrine 2 en utilisant $entityManager->find('entity', id)?

Lorsque vous utilisez le générateur de requêtes, cela peut être fait, mais un paramètre de configuration global doit le faire Je ne veux pas avoir à le spécifier dans les annotations pour les mots réservés.

38
Sam French

C’était un problème que j’avais soulevé il ya quelque temps avec l’équipe Doctrine.

https://github.com/doctrine/doctrine2/issues/2409

Le billet était fermé avec le commentaire:

Vous devez manuellement échapper des caractères avec @Column (name = "` integer` ")

Donc, je suppose que vous devez gérer tous les mots clés réservés dans vos annotations.

63
Lee Davis

4.6. Citer des mots réservés

Parfois, il est nécessaire de citer un nom de colonne ou de table en raison de conflits de mots réservés. Doctrine ne cite pas automatiquement les identifiants, car cela pose plus de problèmes qu'il n'en résoudrait. Les citations de tables et de noms de colonnes doivent être effectuées explicitement à l'aide de graduations dans la définition.

<?php
/** @Column(name="`number`", type="integer") */
private $number;

Doctrine citera ensuite ce nom de colonne dans toutes les instructions SQL en fonction de la plateforme de base de données utilisée.

La citation des identificateurs ne fonctionne pas pour les noms de colonne de jointure ou les noms de colonne de discriminateur, sauf si vous utilisez une QuoteStrategy personnalisée.

Pour plus de contrôle sur les colonnes citant l'interface Doctrine\ORM\Mapping\QuoteStrategy a été introduite dans la version 2.3. Il est appelé pour chaque colonne, table, alias et autres noms SQL. Vous pouvez implémenter QuoteStrategy et le définir en appelant Doctrine\ORM\Configuration#setQuoteStrategy().

La stratégie de cotes ANSI a été ajoutée, ce qui suppose que les guillemets ne sont nécessaires pour aucun nom SQL. Vous pouvez l'utiliser avec le code suivant:

<?php
use Doctrine\ORM\Mapping\AnsiQuoteStrategy;

$configuration->setQuoteStrategy(new AnsiQuoteStrategy());

http://docs.doctrine-project.org/projects/doctrine-orm/en/latest/reference/basic-mapping.html#quoting-reserved-words

7
Stan Fad

Ce n'est pas mis en œuvre par Doctrine simplement parce que cela dépend trop de la plate-forme.

Tout ce dont vous avez besoin, c'est de mettre en œuvre votre propre QuoteStrategy.

Par exemple, pour le projet symfony:


Copiez-collez la classe de fournisseur AnsiQuoteStrategy, renommez-la et faites des citations 

AppBundle/ORM/QuoteStrategy.php  

namespace AppBundle\ORM;

use Doctrine\DBAL\Platforms\AbstractPlatform;
use Doctrine\ORM\Mapping as M;

class QuoteStrategy implements M\QuoteStrategy
{
  private function quote($token, AbstractPlatform $platform)
  {
    // implement your quote strategy
    switch ($platform->getName()) {
      case 'mysql':
      default:
        return '`' . $token . '`';
    }
  }

  // add quoting to appropriate methods
  public function getColumnName($fieldName, M\ClassMetadata $class, AbstractPlatform $platform)
  {
    return $this->quote($class->fieldMappings[$fieldName]['columnName'], $platform);
  }
  // ... Rest methods
}  

Ensuite, enregistrez votre stratégie de devis en tant que service: 

src/AppBundle/Ressources/config/services.yml

  app.orm.quote_strategy:
    class: AppBundle\ORM\QuoteStrategy
    public: false

Ensuite, utilisez-le pour votre configuration entitymanager:
app/config/config.yml  

orm:
  entity_managers:
    default:
      quote_strategy: app.orm.quote_strategy

C'est tout :)

1
vp_arth

D'après la déclaration de @ tim-lytle, j'ai de nouveau soulevé la question. Cela devrait vraiment être inclus dans le champ de sécurité de Doctrine ORM.

https://github.com/doctrine/doctrine2/issues/5874

0
Alex Gurrola