30.13. Internes

Cette section explique comment ECPG fonctionne en interne. Quelque fois, cette information peut être utile pour aider les utilisateurs à comprendre l'utilisation d'ECPG.

Les quatre premières lignes écrites par ecpg sur la sortie sont des lignes figées. Deux sont des commentaires et deux sont des lignes d'inclusion de fichiers d'en-tête nécessaires pour l'interfaçage avec la bibliothèque. Ensuite, le préprocesseur lit le fichier et écrit la sortie. Normalement, il répète tout sur la sortie.

Lorsqu'ecpg lit une instruction EXEC SQL, il intervient et la modifie. La commande commence avec EXEC SQL et se termine avec ;. Tout ce qui se trouve entre est traité comme une instruction SQL et est analysé pour la substitution de variable.

La substitution de variable intervient quand un symbole commence avec un caractère deux-points (:). La variable possédant ce nom est recherchée parmi toutes les variables précédemment déclarées dans une section EXEC SQL DECLARE.

La fonction la plus importante de la bibliothèque est ECPGdo, qui prend en charge l'exécution de la plupart des commandes. Elle prend un nombre variable d'arguments. Ceci permet d'aller jusqu'à environ 50 arguments, et nous espérons que cela ne posera de problème sur aucune plateforme.

Les arguments sont :

Un numéro de ligne

C'est le numéro de ligne de la ligne originale ; utilisé seulement dans les messages d'erreur.

Une chaîne

C'est la commande SQL à exécuter. Elle est modifiée par les variables en entrée, c'est-à-dire les variables qui n'étaient pas connues au moment de la compilation mais qui doivent être précisées dans la commande. À l'emplacement des variables, la chaîne contient le signe ?.

Variables en entrée

Chaque variable en entrée entraîne la création de dix arguments (voir ci-dessous).

ECPGt_EOIT

Un enum indiquant qu'il n'y a plus de variables en entrée.

Variables en sortie

Chaque variable en sortie entraîne la création de dix arguments (voir ci-dessous). La valeur des variables est fournie par la fonction.

ECPGt_EORT

Un enum indiquant qu'il n'y a plus de variables.

Pour chaque variable faisant partie de la commande SQL, la fonction récupère dix arguments :

  1. Le type comme symbole spécial.

  2. Un pointeur vers la valeur ou un pointeur vers le pointeur.

  3. La taille de la variable dans le cas d'un type char ou varchar.

  4. Le nombre d'éléments du tableau (pour les parcours de tableaux).

  5. Le décalage pour obtenir le prochain élément dans le tableau (pour les parcours de tableaux).

  6. Le type de variable indicateur comme un symbole spécial.

  7. Un pointeur vers la variable indicateur.

  8. 0

  9. Le nombre d'éléments dans le tableau indicateur (pour les parcours de tableaux).

  10. Le décalage pour obtenir le prochain élément dans le tableau indicateur (pour les parcours de tableaux).

Il est à noter que toutes les commandes SQL ne sont pas traitées ainsi. Par exemple, une instruction d'ouverture de curseur comme

EXEC SQL OPEN curseur;

n'est pas copiée sur la sortie. À la place, la commande DECLARE de déclaration du curseur est utilisée à la position de la commande OPEN car, en fait, elle ouvre le curseur.

Voici un exemple complet décrivant la sortie du préprocesseur d'un fichier foo.pgc (les détails pourraient varier avec chaque version particulière du préprocesseur) :

EXEC SQL BEGIN DECLARE SECTION;
int index;
int resultat;
EXEC SQL END DECLARE SECTION;
...
EXEC SQL SELECT res INTO :resultat FROM matable WHERE index = :index;

est traduit en :

/* Processed by ecpg (2.6.0) */
/* These two include files are added by the preprocessor */
#include <ecpgtype.h>;
#include <ecpglib.h>;

/* exec sql begin declare section */

#line 1 "foo.pgc"

 int index;
 int resultat;
/* exec sql end declare section */
...
ECPGdo(__LINE__, NULL, "SELECT res FROM matable WHERE index = ?     ",
        ECPGt_int,&(index),1L,1L,sizeof(int),
        ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT,
        ECPGt_int,&(resultat),1L,1L,sizeof(int),
        ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EORT);
#line 147 "foo.pgc"

(l'indentation a été ajoutée ici pour des raisons de lisibilité et n'est pas réalisée par le préprocesseur)