Rational Open Access , RPG Edition
Rational Open Access, RPG edition (5733OAR) est un produit apparu
en 7.1 et disponible aussi pour la V6R1(avec PTF).
Il permet de passer la main à un "driver" externe lors des ordres
d'entrée sortie RPG, plutôt que d'appeler les routines historiques d'IBM.
Par exemple:
-
Vous avez actuellement un programme RPG écrivant dans un
fichier physique.
-
Vous écrivez ou achetez un Handler qui reçoit
les données et qui les écrit au format CSV ou XML dans l'IFS à
la place de
l'écriture dans le fichier physique.
-
Vous ajoutez le mot-clé HANDLER
sur la déclaration du fichier en sortie de votre programme initial
et le tour est joué, ce dernier écrit dans l'IFS.
- Ajout au pgm applicatif de HANDLER('le-nom' : info)
- le nom peut être noté
- ma_variable : un nom de variable
- 'PGM' : le nom du programme
- 'BIB/PGM' : le nom qualifié du programme
- 'SRVPGM(nom)' le nom d'une procédure dans un pgm de service
- 'BIB/SRVPGM(nom)' le nom d'une procédure dans un pgm de service
qualifié
- info, paramètre facultatif permettant de passer des informations au Handler
(coordonnées dans l'IFS par exemple)
le fichier auquel vous avez ajouté HANLDER doit être présent à la
compilation ET à l'exécution (malgré que vous ne vous
en serviez pas vraiment, il fournit le format)
le produit 5733OAR (facturable) doit être présent à la
compilation ET à l'exécution.
- Ecriture du Handler
- le Handler est appelé à chaque opération (open, close,
read, etc...) et reçoit une DS d'information structurée (QrnOpenAccess_T,
voir QRNOPENACC )
décrivant l'Entrée/sortie et permettant aussi un retour d'informations
auprès
des couches système.
// Exemple
// Standard IBM supplied Open Access definitions
/copy QOAR/QRPGLESRC,QRNOPENACC
// paramètre recu par le pgm
// de type QrnOpenAccess_T
D CVS_HDLR PI
D info likeds(QrnOpenAccess_T) |
zones de QrnOpenAccess_T remarquables :
- structLen : lg totale de cette structure
- parameterFormat : toujours 'ROAC0100'
- userArea : pointeur vers l'espace mémoire fourni en 2ème paramètre
du mot-clé
Handler par le pgm (libre)
- stateInfo : pointeur vers un espace mémoire permettant au Handler
de mémoriser
quelque chose entre deux appels (libre)
- RecordName : nom du format
- rpgOperation : Opération en cours, voir les constantes QrnOperation_xxx
dans QRNOPENACC
- rpgStatus : s'il est appelé pour une opération qu'il ne
sait pas gérer,
il doit signaler une erreur (QrnOpenAccess_T.rpgStatus <> 0).
- Eof : à mettre à *ON pour signaler une fin de fichier
- Found : à mettre à *ON pour signaler une opération d'accès directe réussie
- Equal : à mettre à *ON pour signaler une opération
de positionnement par égalité réussie
- inputBuffer (pointeur vers un buffer mémoire si useNamesValues=*OFF)
- NamesValue (pointeur vers un espace mémoire structuré de type
QrnNamesValues_T, si useNamesValues=*ON)
lors de l'OPEN le Handler doit signaler comment il veut recevoir les données
(QrnOpenAccess_T.useNamesValues)
- *OFF ('0') les données sont fournies dans un buffer identique à celui
reçu par les routines systèmes (suite d'octets)
- *ON ('1') les données sont fournies dans une structure contenant
la description de la zone et les données en clair (en caractère,
même pour le numérique)
QrnNamesvalues_T (si useNamesvalues est à *ON) :
- nombre de zones (binaire sur 4 octets)
- tableau de n occurrences (suivant zone précédente) de type QrnNameValue_T
//Exemple
// déclaration de la structure basée sur Qrnnamesvalues_T
//D QrnNamesValues_T...
//D DS QUALIFIED TEMPLATE ALIGN
//D num 10I 0
//D field LIKEDS(QrnNameValue_T)
//D DIM(32767)
D nvInput ds likeds(QrnNamesValues_T)
D based(pNvInput)
/free
// utilisation du pointeur lu dans info (QrnOpenAccess_T)
if info.rpgOperation = QrnOperation_WRITE;
pNvInput = info.namesValues;
// contenant elle même QrnNameValue_T autant de fois
// qu'il y a de zones, qq infos et des pointeurs
//D QrnNameValue_T...
//D DS QUALIFIED TEMPLATE
//D externalName...
//D 10A
//D dataType...
//D 3U 0
//D numericDefinedLen...
//D 3U 0
//D decimals...
//D 3U 0
//D dtzFormat...
//D 3U 0
//D dtSeparator...
//D 1A
//D input...
//D N
//D output...
//D N
//D isNullCapable...
//D N
//D hasNullValue...
//D N
//D reserved1...
//D 13A
//D valueLenBytes...
//D 10U 0
//D valueMaxLenBytes...
//D 10U 0
//D valueCcsid...
//D 10I 0
//D reserved2...
//D 10U 0
//D value...
//D *
//D reserved3...
//D * |
QrnNamevalue_T (description d'une zone) , les lg sont données en
nombre d'octets :
- Nom, CHAR(10)
- Type de données, Integer(1), voir les constante dans QRNOPENACC
- Longueur définie (numérique uniquement) , Integer(1)
- Décimales, Integer(1)
- Format (date/heure), Integer(1)
- Séparateur (date/heure), CHAR(1)
- Input ? (*ON/*OFF), CHAR(1)
- Output ? (*ON/*OFF), CHAR(1)
- NULL possible ? (*ON/*OFF), CHAR(1)
- Contient NULL ? (*ON/*OFF), CHAR(1)
- Lg de la valeur (peut être renseignée par RPG), Integer(4)
- Lg maxi de la valeur (fixée par le système), Integer(4)
- CCSID de la valeur, Integer(4)
- Valeur, pointeur vers cette dernière, qui elle est en clair (résultat
de %CHAR si numérique, de %DATE si c'est une date, etc ...).
//Exemple, suite
// boucle autours du nbr de variables
// pour récupérer les valeurs et les traiter
D pvaleur s *
D valeur s 32470a Based(pvaleur)
/free
For i = 1 to nvInput.num;
pvaleur = nvInput.field(i).value; // accès aux données
If ( nvInput.field(i).dataType = QrnDatatype_Alpha );
...
manipulation de "valeur"
...
EndIf;
EndFor; |
Ces exemples sont d'abord inspirés de celui fourni
par
Partner400 ,
puis de la
documentation
- TEST1 Pgm initial d'écriture
dans un fichier Physique
- TEST2 Pgm initial
modifié pour utiliser le Handler qui suit (CSV_HDLR)
- CSV_HDLR Handler
pour générer un fichier CSV dans l'IFS
- TEST3 Pgm initial
modifié pour utiliser le Handler qui suit (XML_HDLR)
- XML_HDLR Handler
pour générer un fichier XML dans l'IFS
- TEST4 Pgm
initial de lecture d'un fichier Physique
avec impression
- TEST5 TEST4 modifié
pour utiliser le Handler CSV_HDLRI en lecture
- CSV_HDLRI Handler
pour lire le contenu d'un fichier CSV dans l'IFS