View Issue Details

IDProjectCategoryView StatusLast Update
0001661Common[All Projects] Generalpublic2016-08-08 01:32
ReporterXenosAssigned ToXenos 
PrioritynormalSeverityfeatureReproducibilityN/A
Status CloseResolutionfixed 
Product Version1.0.4 
Target VersionFixed in Version2.0.0 
Summary0001661: Gérer les exceptions SQL natives
DescriptionLes procédures peuvent rencontrer des erreurs comme des foreign key empêchant une action (INSERT/UPDATE). Ces exceptions doivent proprement remonter au PHP.

A mon sens, c'est au SQL de faire la colle et non à PHP: je ne vais pas stocker en PHP des trucs pour parser l'exception SQL et, en fonction du nom de la constraint qui a fail, renvoyer telle ou telle exception.

Le SQL devrait faire cette colle et me renvoyer directement le nom de l'exception à gérer. Comme cela, si je change mes foreign key ou des trucs dans le MySQL, cela n'impactera pas le PHP (dans le cas contraire, cela l'impacterait puisqu'il faudrait mettre à jour les noms de FK stockés [par génération] dans PHP).

---

Je ne peux pas utiliser les handlers car ils ne catchent les erreurs de FK que dans MySQL 5.7 ( http://bugs.mysql.com/bug.php?id=68831 ), qui n'est pas déployé sur OVH. Donc ceci n'est pas utilisable (même si ce serait la meilleur solution):

  DECLARE code CHAR(5) DEFAULT '00000';
  DECLARE msg TEXT;
  -- Declare exception handler for failed insert
  DECLARE EXIT HANDLER FOR SQLEXCEPTION
    BEGIN
      GET DIAGNOSTICS CONDITION 1
        code = RETURNED_SQLSTATE, msg = MESSAGE_TEXT;
        SELECT code, msg;
      CALL throw(...)
    END;
TagsNo tags attached.
Attach Tags

Activities

Xenos

Xenos

2016-08-07 23:22

administrator   ~0002127

Finalement, je vais devoir utiliser PHP et SQL. Le principe est le suivant:

MySQL ne donne pas de noms aux result set, donc j'étais passé par un "SELECT 'view' AS attribute, TRUE AS unic;" qui permet de dire que le prochain resultset aura ce nom d'attribut dans le Bean de résultat, et qu'il est ou non unique (donc, l'attribut est ou non un tableau). Le générateur de code peut alors facilement faire le parsing de ce genre de ligne.

Pour les exceptions, même principe. Il suffit d'utiliser la ligne "SELECT 'FK_map_element_isometric_map_element_country' AS keyname, 'Gnagna' as exception;" pour déclarer que la foreign key "keyname" doit entrainer un "throw new GnagnaException" dans le PHP. Le QueryExecutor s'occupe de faire la colle entre les deux (comme pour l'absence de noms aux resultset) et renvoie une "PDOContraintException" avec la constraint et la keyname comme infos. Le PDOCatchAll se charge alors de prendre l'exception que l'executor renvoie et de la transformer en exception métier (en GnagnaException) que je peux alors catcher coté client.


Du coup, PHP n'a pas connaissance (dans ses codes) du nom de la foreign key, et quand MySQL prendra mieux en charge les HANDLERS (5.7.2), alors je pourrai basculer facilement. Comme le générateur de code prend en charge cette nouvelle petite ligne, j'ai la classe de l'exception qui est créée, et l'auto-complétion qui va avec.

Enfin, si la même foreign key peut fail à plusieurs endroits, pour différentes raisons, alors il suffit d'ajouter plusieurs lignes "keyname/exception", c'est à dire que je peux avoir, dans une procédure, une "keyname" (une constraint) qui renverra un coup une "GnagnaException" et, plus loin, une "ProutproutException".

Le même genre de principe sera à appliquer par la suite aux autres exceptions courantes que je pourrai rencontrer (inutile de trop prendre les devants pour le coup).

Issue History

Date Modified Username Field Change
2016-08-07 22:53 Xenos New Issue
2016-08-07 22:53 Xenos Status New => Accepted
2016-08-07 22:54 Xenos Assigned To => Xenos
2016-08-07 22:54 Xenos Status Accepted => In progress
2016-08-07 23:22 Xenos Note Added: 0002127
2016-08-07 23:22 Xenos Status In progress => Ready
2016-08-07 23:22 Xenos Resolution open => fixed
2016-08-08 01:30 AutoUpdater Status Ready => Resolved
2016-08-08 01:31 AutoUpdater Fixed in Version => 2.0.0
2016-08-08 01:32 Xenos Status Resolved => Close