Doctrine TimeStamp Error : Importer des tables SQL Server 2008

Comment importer une table SQL Server avec un champs Timestamp avec Doctrine ? Quand les tutoriels de-ci de-là ne suffise pas, il n’y a souvent qu’un moyen pour parvenir à ses fins… Mettre les mains dans le cambouis ! Aujourd’hui je vous propose une solution, qui je l’espère sera rapidement intégré par la Communauté en charge du développement de Doctrine, qui permette de créer des entités Symfony2 depuis une base SQL Server qui contiennent un champs de type Timestamp.

Qu’est-ce que le type Timestamp ?

Il me semble nécessaire de préciser quelques petites informations sur le type Timestamp. Je ne suis pas un expert MySQL mais des informations que j’ai pu croiser un peu partout, le Timestamp de MySQL ressemble à une date, ce qui le rend plus facilement convertissable. Or, le même type pour SQL Server est un peu plus subtile dans sa compréhension. Le documentation est disponible sur le Technet de Microsoft.

Type de données qui expose des nombres binaires à caractère unique générés automatiquement dans une base de données.
Intéressant… Et comment je fais pour dire à Doctrine de ne me convertir ça ? Je vous propose une solution pour détourner le problème…

Trouver une solution « custom »

Je vois déjà venir les messages me disant qu’il existe déjà une méthode toute faite et qui fonctionne. OUI ! D’ailleurs il s’agit de cette tâche Symfony2 que l’on peut appeler de cette manière :

php app/console doctrine:mapping:import
Cette tâche fonctionne très bien, mais comme je l’ai lu ici, Doctrine fonctionne pour environ 70-80% des mappings possibles sur une base de donnée. Dans mon cas, je voulais exporter le mapping d’une table SQL Server (2008), qui contenait un fameux champs TimeStamp. Et dans les 20% des mappings restants, justement il y a ce type de champs.

Je vais lancer la commande et tenter d’importer le mappaqe.

1
php app/console doctrine:mapping:import — force NamespaceNameBundle xml

Dans mon cas, j’avais utiliser deux options supplémentaires, à savoir :

  1. –em= »… » pour spécifier l’Entity Manager en charge de ma base de donnée SQL Server ;
  2. –filter= »table ». Je voulais utiliser cette option qui fonctionnait avec MariaDB mais qui semblait être ignoré quand utilisé avec MSSQL. Cela permet de spécifier une table à exporter. Dans mon cas, j’avais copié ma BDD, j’avais supprimé les tables qui ne m’intéressaient pas et créer un nouveau profil d’Entity Manager.
    Et voici l’exception levé :
1
2
[DoctrineDBALDBALException]
Unknown database type timestamp requested, DoctrineDBALPlatformsSQLServer2008Platform may not support it.

À compter de maintenant, nous allons devoir truquer les dés.
Le type Timestamp n’est pas supporté – et j’avoue ne pas vraiment savoir à quel type de champs PHP l’associer -, nous allons temporairement indiquer à Doctrine que ce type doit être convertie datetime.

  • Rendez-vous dans le dossier indiqué par l’arborescence, vendordoctrinedballibDoctrineDBALPlatforms.
  • Dans ce dossier se trouve les classes permettant de supporter la majorité des SGBD existant.
  • Dans mon cas je travallais sur SQL Server 2008 R2, donc j’édite le fichier SQLServer2008Platform.php, mais libre à vous d’éditer un autre fichier si celui-ci correspond à votre configuration.
  • Nous allons éditer la méthode initializeDoctrineTypeMappings. Dans la variable doctrineTypeMapping est présent les informations pour convertir les types. Ajoutez la ligne :
    $this->doctrineTypeMapping[‘timestamp’] = ‘datetime’;
  • Relancer l’importation du mappage. Le mappage de tous les champs ont été importés.
  • Vous devez bien penser à enlever la ligne que vous avez ajouter dans le fichier. Si vous n’êtes pas sûr, supprimez tous les vendor et ré-installez les.
  • Maintenant, rendez-vous successivement dans les fichiers qui ont été générés. Le chemin de chacun est indiqué, et à tour de rôle, suivez les indications ci-dessous.

    • Vous avez désormais l’équivalent de vos tables en XML.
    • Supprimez les lignes qui correspondent à un champs de type TimeStamp. De cette manière, Doctrine ignorera ces champs.
    • Une petite précaution avec SQL Server est d’ajouter autour de chaque valeur contenu par « column » ayant un ou plusieurs espaces, des crochets.
      Pour cette ligne,

      La column SQL Server est « My Infos ». Doctrine ne sait pas géré les espaces avec MSSQL. Vous devez donc ajouter des crochest comme ceci :
  • Lorsque vos fichiers ont été corrigés, nous lancons la génération des entités.

    1
    php app/console doctrine:mapping:convert annotation ./src

Vous devrez peut-être indiquer l’Entity Manager à utiliser, comme ceci : –em= »… ».

  • Vous pouvez maintenant supprimer le mappage, soit les fichiers .xml présent dans les Ressources.
    Voilà, vous avez désormais des entités valides et générées par Doctrine. Cette solution un peu … « brian fuck » serte valide tant que l’équipe est charge du développement de Doctrine n’aura pas intégrée une solution viable qui permettrait de supporter nativement au sein de PHP le type TimeStamp.

Bon courage, et à bientôt !