%GEN
Générateur de DATA-GEN
Indique le programme qui écrit le document (JSON par exemple) dans un DATA-GEN, et lui transmet des options de présentation sous forme de texte.
Syntaxe
%GEN(générateur)
%GEN(générateur : options-du-générateur)
générateur- Le nom du programme (éventuellement qualifié par sa bibliothèque, comme
'YAJLLIB/YAJLDTAGEN') ou un pointeur de procédure. options-du-générateur- Un texte transmis tel quel au générateur. Pour YAJLDTAGEN, c'est un objet JSON : par exemple
{"beautify":true}pour obtenir un document indenté. - Résultat
- %GEN ne renvoie rien : elle complète DATA-GEN, qui écrit le document dans la zone désignée par
%DATA.
À quoi ça sert
DATA-GEN fait le chemin inverse de DATA-INTO : à partir d'une structure de données, il produit le texte d'un document. Le format vient du générateur choisi par %GEN. Fabriquer un JSON à la main, avec des guillemets à échapper et des virgules à placer, est une source d'erreurs ; ici tout est géré.
Exemple 1 : Générer le JSON d'une commande
**free
// %GEN : produire un document JSON a partir d'une structure de donnees avec DATA-GEN et YAJL.
ctl-opt dftactgrp(*no) actgrp(*new);
dcl-pr qcmdexc extpgm('QCMDEXC');
commande char(200) const;
longueur packed(15:5) const;
end-pr;
dcl-ds ligne_t qualified template;
article varchar(20);
qte int(10);
end-ds;
dcl-ds commande qualified;
numero int(10) inz(4521);
client varchar(30) inz('Dupont SA');
total packed(9:2) inz(1250.50);
urgent ind inz(*on);
lignes likeds(ligne_t) dim(2);
end-ds;
dcl-s json varchar(1000);
dcl-s cmd char(200);
monitor;
cmd = 'ADDLIBLE YAJLLIB';
qcmdexc(cmd : %len(%trim(cmd)));
on-error;
endmon;
commande.lignes(1).article = 'Cable RJ45';
commande.lignes(1).qte = 10;
commande.lignes(2).article = 'Switch';
commande.lignes(2).qte = 2;
data-gen commande %data(json : 'doc=string') %gen('YAJLLIB/YAJLDTAGEN');
snd-msg 'Compact : ' + json;
// beautify : le meme document, indente
data-gen commande %data(json : 'doc=string')
%gen('YAJLLIB/YAJLDTAGEN' : '{"beautify":true}');
snd-msg 'Longueur indente : ' + %char(%len(json));
*inlr = *on;
Résultat réel, compilé et exécuté sur IBM i 7.5 :
Compact : {"numero":4521,"client":"Dupont SA","total":1250.50,"urgent":true,"lignes":[{"article":"Cable RJ45","qte":10},{"article":"Switch","qte":2}]}
Longueur indente : 269
La structure commande devient un objet JSON : les nombres restent des nombres (1250.50), l'indicateur devient true, le tableau de deux structures devient un tableau de deux objets. Les noms de clés sortent en minuscules. Avec l'option beautify, le document est indenté, donc plus long (269 caractères).
Exemple 2 : Guillemets, tableau partiel et indentation
**free
// %GEN : options du generateur (indentation), guillemets a echapper, tableau partiellement rempli.
ctl-opt dftactgrp(*no) actgrp(*new);
dcl-pr qcmdexc extpgm('QCMDEXC');
commande char(200) const;
longueur packed(15:5) const;
end-pr;
dcl-ds client qualified;
nom varchar(30) inz('Martin "et fils"');
ville varchar(20) inz('Lyon');
encours packed(7:2) inz(0);
tels varchar(10) dim(3);
nb_tels int(10) inz(2);
end-ds;
dcl-s json varchar(1000);
dcl-s cmd char(200);
dcl-s lf char(1) inz(x'25');
monitor;
cmd = 'ADDLIBLE YAJLLIB';
qcmdexc(cmd : %len(%trim(cmd)));
on-error;
endmon;
client.tels(1) = '0467000001';
client.tels(2) = '0467000002';
// countprefix : nb_tels dit combien d'elements du tableau sont ecrits
data-gen client %data(json : 'doc=string countprefix=nb_') %gen('YAJLLIB/YAJLDTAGEN');
snd-msg 'Compact : ' + json;
data-gen client %data(json : 'doc=string countprefix=nb_')
%gen('YAJLLIB/YAJLDTAGEN' : '{"beautify":true}');
snd-msg 'Indente : ' + %scanrpl(lf : '|' : json);
*inlr = *on;
Résultat réel, compilé et exécuté sur IBM i 7.5 :
Compact : {"nom":"Martin \"et fils\"","ville":"Lyon","encours":0.00,"tels":["0467000001","0467000002"]}
Indente : {| "nom": "Martin \"et fils\"",| "ville": "Lyon",| "encours": 0.00,| "tels": [| "0467000001",| "0467000002"| ]|}|
Les guillemets du nom sont échappés (\"). Le tableau tels a 3 éléments mais nb_tels vaut 2, et countprefix=nb_ (dans %DATA) n'écrit que 2 numéros ; la zone nb_tels elle-même n'apparaît pas dans le document. Les sauts de ligne du document indenté sont remplacés par des barres verticales pour l'affichage.
Le piège
Un tableau est écrit en entier, sauf indication. Sans countprefix, les éléments vides d'un tableau de texte sortent aussi dans le JSON, sous la forme "" (par exemple ["0467000001","",""]). L'exemple 2 fixe le nombre à écrire avec une sous-zone nb_tels.
Et la structure doit être initialisée : avec un tableau de zones varchar dont on n'a rempli qu'un élément, dans une structure déclarée sans inz, DATA-GEN s'arrête sur l'erreur RNQ0361 (code raison 1). Enfin, comme pour DATA-INTO, la bibliothèque YAJLLIB doit être dans la liste des bibliothèques du travail, sinon l'exécution s'arrête sur MCH3401.