Cette section explique comment ECPG fonctionne en interne. Cette information peut être utile pour comprendre comment utiliser ECPG.
Les quatre premières lignes écrites sur la sortie par
ecpg
sont des lignes fixes. Deux sont des
commentaires et deux sont des lignes d'inclusion nécessaires pour
s'interfacer avec la librairie. Puis le préprocesseur lit le fichier
et écrit la sortie. La plupart du temps, il répète simplement
tout dans la sortie.
Quand il voit un ordre EXEC SQL
, il intervient
et le modifie. La commande débute par EXEC SQL
et se termine par ;
. Tout ce qui se trouve entre
deux est traité comme un ordre SQL et analysé
pour substitution de variables.
Une substitution de variable se produit quand un symbole commence
par un deux-points (:
). La variable dont c'est le
nom est recherchée parmi les variables qui ont été précédemment
déclarées dans une section EXEC SQL DECLARE
.
La fonction la plus importante de la librairie est
ECPGdo
, qui s'occupe de l'exécution de la
plupart des commandes. Elle prend un nombre variable d'arguments. Le
nombre de ces arguments peut rapidement dépasser la cinquantaine, et
nous espérons que cela ne posera de problème sur aucune plateforme.
Les arguments sont:
C'est le numéro de la ligne originale; c'est utilisé uniquement pour les messages d'erreu.
C'est la commande SQL à exécuter. Elle est
modifiée par les variables d'entrée, c'est à dire les variables
qui n'étaient pas connues au moment de la compilation mais qui
doivent tout de même faire partie de la commande. Aux endroits
où ces variables doivent être positionnées, la chaîne contient
des ?
.
Chaque variable d'entrée entraîne la création de dix arguments. (Voir plus bas.)
ECPGt_EOIT
#
Un enum
annonçant qu'il n'y a pas de variable
d'entrées supplémentaires.
Chaque variable de sortie entraîne la création de dix arguments. (Voir plus bas.) Ces variables sont renseignées par la fonction.
ECPGt_EORT
#
Un enum
annonçant qu'il n'y a plus de variables.
Pour chaque variable qui fait partie d'une commande SQL, la fonction reçoit dix arguments:
Le type sous forme de symbole spécial.
Un pointeur vers la valeur ou un pointeur vers le pointeur.
La taille de la variable si elle est char
ou varchar
.
Le nombre d'éléments du tableau (pour les fetch sur tableau).
Le décalage vers le prochain élément du tableau (pour les fetch sur tableau).
Le type de la variable indicateur sous forme de symbole special.
Un pointeur vers la variable indicateur.
0
Le nombre d'éléments du tableau d'indicateurs (pour les fetch sur tableau).
Le décalage vers le prochain élément du tableau d'indicateurs (pour les fetch sur tableau).
Notez que toutes les commandes SQL ne sont pas traitées de cette façon. Par exemple, un ordre d'ouverture de curseur comme:
EXEC SQL OPEN cursor
;
n'est pas copié vers la sortie. À la place, la commande de curseur
DECLARE
est utilisée à l'endroit de la commande
OPEN
parce qu'elle ouvre effectivement le curseur.
Voici un exemple complet expliquant la sortie du préprocesseur sur
un fichier foo.pgc
(quelques détails pourraient
changer en fonction de la version exacte du préprocesseur):
EXEC SQL BEGIN DECLARE SECTION; int index; int result; EXEC SQL END DECLARE SECTION; ... EXEC SQL SELECT res INTO :result FROM mytable 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 result; /* exec sql end declare section */ ... ECPGdo(__LINE__, NULL, "SELECT res FROM mytable WHERE index = ? ", ECPGt_int,&(index),1L,1L,sizeof(int), ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, ECPGt_int,&(result),1L,1L,sizeof(int), ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EORT); #line 147 "foo.pgc"
(L'indentation est ajoutée ici pour améliorer la lisibilité et n'est pas quelque chose que le préprocesseur effectue).