| 1 |
<?xml version="1.0" encoding="ISO-8859-15"?> |
|---|
| 2 |
<!-- Dernière modification |
|---|
| 3 |
le $Date$ |
|---|
| 4 |
par $Author$ |
|---|
| 5 |
révision $Revision$ --> |
|---|
| 6 |
|
|---|
| 7 |
<sect1 id="contrib-spi"> |
|---|
| 8 |
<title>spi</title> |
|---|
| 9 |
|
|---|
| 10 |
<indexterm zone="contrib-spi"> |
|---|
| 11 |
<primary>SPI</primary> |
|---|
| 12 |
<secondary>examples</secondary> |
|---|
| 13 |
</indexterm> |
|---|
| 14 |
|
|---|
| 15 |
<para> |
|---|
| 16 |
Le module <filename>contrib/spi</filename> fournit plusieurs exemples |
|---|
| 17 |
fonctionnels d'utilisation de SPI et des déclencheurs. Bien que ces fonctions aient un |
|---|
| 18 |
intérêt certain, elles sont encore plus utiles en tant qu'exemples |
|---|
| 19 |
à modifier pour atteindre ses propres buts. Les fonctions sont suffisamment |
|---|
| 20 |
généralistes pour être utilisées avec une table quelconque, mais la création d'un |
|---|
| 21 |
déclencheur impose que les noms des tables et des champs soient précisés |
|---|
| 22 |
(comme cela est décrit ci-dessous). |
|---|
| 23 |
</para> |
|---|
| 24 |
|
|---|
| 25 |
<sect2> |
|---|
| 26 |
<title>refint.c — fonctions de codage de l'intégrité |
|---|
| 27 |
référentielle</title> |
|---|
| 28 |
|
|---|
| 29 |
<para> |
|---|
| 30 |
<function>check_primary_key()</function> et |
|---|
| 31 |
<function>check_foreign_key()</function> sont utilisées pour vérifier les |
|---|
| 32 |
contraintes de clé étrangère. (Cette fonctionnalité est dépassée depuis |
|---|
| 33 |
longtemps par le mécanisme interne, mais le module conserve un rôle |
|---|
| 34 |
d'exemple.) |
|---|
| 35 |
</para> |
|---|
| 36 |
|
|---|
| 37 |
<para> |
|---|
| 38 |
<function>check_primary_key()</function> vérifie la table de référence. |
|---|
| 39 |
Pour l'utiliser, on crée un déclencheur <literal>BEFORE INSERT OR UPDATE</literal> |
|---|
| 40 |
qui utilise cette fonction sur une table référençant une autre table. |
|---|
| 41 |
En arguments du déclencheur, on trouve : le nom de la colonne |
|---|
| 42 |
de la table référençant qui forme la clé étrangère, le nom de la table |
|---|
| 43 |
référencée et le nom de la colonne de la table référencée qui forme la |
|---|
| 44 |
clé primaire/unique. Il peut y avoir plusieurs colonnes. Pour gérer |
|---|
| 45 |
plusieurs clés étrangères, on crée un déclencheur pour chaque référence. |
|---|
| 46 |
</para> |
|---|
| 47 |
|
|---|
| 48 |
<para> |
|---|
| 49 |
<function>check_foreign_key()</function> vérifie la table référencée. |
|---|
| 50 |
Pour l'utiliser, on crée un déclencheur <literal>BEFORE DELETE OR UPDATE</literal> |
|---|
| 51 |
qui utilise cette fonction sur une table référencée par d'autres tables. |
|---|
| 52 |
En arguments du déclencheur, on trouve : le nombre de tables référençant pour |
|---|
| 53 |
lesquelles la fonction réalise la vérification, l'action à exécuter si une clé |
|---|
| 54 |
de référence est trouvée (<literal>cascade</literal> — pour supprimer |
|---|
| 55 |
une ligne qui référence, <literal>restrict</literal> — pour annuler la |
|---|
| 56 |
transaction si des clés de référence existent, <literal>setnull</literal> |
|---|
| 57 |
— pour initialiser les champs des clés référençant à NULL), les noms |
|---|
| 58 |
des colonnes de la table surveillées par le déclencheur, colonnes qui |
|---|
| 59 |
forment la clé primaire/unique, puis le nom de la table référençant et les noms des |
|---|
| 60 |
colonnes (répétés pour autant de tables référençant que cela est précisé par |
|---|
| 61 |
le premier argument). Les colonnes de clé |
|---|
| 62 |
primaire/unique doivent être marquées NOT NULL et posséder un index |
|---|
| 63 |
d'unicité. |
|---|
| 64 |
</para> |
|---|
| 65 |
|
|---|
| 66 |
<para> |
|---|
| 67 |
Il y a des exemples dans <filename>refint.example</filename>. |
|---|
| 68 |
</para> |
|---|
| 69 |
</sect2> |
|---|
| 70 |
|
|---|
| 71 |
<sect2> |
|---|
| 72 |
<title>timetravel.c — fonctions de codage du voyage dans le |
|---|
| 73 |
temps</title> |
|---|
| 74 |
|
|---|
| 75 |
<para> |
|---|
| 76 |
Dans le passé, <productname>PostgreSQL</productname> disposait d'une fonctionnalité |
|---|
| 77 |
de voyage dans le temps, permettant de conserver l'heure d'insertion et |
|---|
| 78 |
de suppression de chaque ligne. Ce comportement peut être émulé en |
|---|
| 79 |
utilisant ces fonctions. Pour les utiliser, il faut ajouter deux champs |
|---|
| 80 |
de type <type>abstime</type> à la table pour stocker le moment où une |
|---|
| 81 |
ligne a été insérée (start_date) et le moment où elle a été |
|---|
| 82 |
modifiée/supprimée (stop_date) : |
|---|
| 83 |
|
|---|
| 84 |
<programlisting> |
|---|
| 85 |
CREATE TABLE mytab ( |
|---|
| 86 |
... ... |
|---|
| 87 |
start_date abstime, |
|---|
| 88 |
stop_date abstime |
|---|
| 89 |
... ... |
|---|
| 90 |
); |
|---|
| 91 |
</programlisting> |
|---|
| 92 |
|
|---|
| 93 |
Le nom des colonnes n'a aucune importance, mais dans ce |
|---|
| 94 |
chapitre, elles sont nommées start_date et stop_date. |
|---|
| 95 |
</para> |
|---|
| 96 |
|
|---|
| 97 |
<para> |
|---|
| 98 |
À l'insertion d'une nouvelle ligne, start_date doit normalement |
|---|
| 99 |
être initialisée à l'heure courante et stop_date à |
|---|
| 100 |
<literal>infinity</literal>. Le déclencheur substitue automatiquement ces |
|---|
| 101 |
valeurs si les données insérées sont NULL pour ces colonnes. |
|---|
| 102 |
L'insertion de données explicitement non-NULL dans ces colonnes n'intervient |
|---|
| 103 |
qu'au rechargement de données sauvegardées. |
|---|
| 104 |
</para> |
|---|
| 105 |
|
|---|
| 106 |
<para> |
|---|
| 107 |
Les lignes pour lesquelles stop_date vaut <literal>infinity</literal> sont des |
|---|
| 108 |
lignes <quote>actuellement valides</quote>, et peuvent être modifiées. |
|---|
| 109 |
Les lignes dont stop_date est fini ne peuvent plus être modifiées — |
|---|
| 110 |
le déclencheur les protège. (Pour les modifier, il est nécessaire de |
|---|
| 111 |
désactiver le voyage dans le temps comme indiqué ci-dessous.) |
|---|
| 112 |
</para> |
|---|
| 113 |
|
|---|
| 114 |
<para> |
|---|
| 115 |
Pour une ligne modifiable en mise à jour, seul stop_date est |
|---|
| 116 |
modifié (positionné à l'heure courante) et une nouvelle ligne avec la donnée modifiée |
|---|
| 117 |
est insérée. Pour cette nouvelle ligne, start_date est positionné à |
|---|
| 118 |
l'heure courante et stop_date à <literal>infinity</literal>. |
|---|
| 119 |
</para> |
|---|
| 120 |
|
|---|
| 121 |
<para> |
|---|
| 122 |
Une suppression ne supprime pas réellement la ligne mais positionne |
|---|
| 123 |
stop_date à l'heure courante. |
|---|
| 124 |
</para> |
|---|
| 125 |
|
|---|
| 126 |
<para> |
|---|
| 127 |
Pour trouver les lignes <quote>actuellement valides</quote>, on ajoute la |
|---|
| 128 |
clause <literal>stop_date = 'infinity'</literal> dans la condition |
|---|
| 129 |
WHERE de la requête. (Cela peut se faire au travers d'une vue.) De façon |
|---|
| 130 |
similaire, une requête peut être exécutée sur les lignes valides à |
|---|
| 131 |
un moment du passé si des conditions adéquates sont posées sur |
|---|
| 132 |
start_date et stop_date. |
|---|
| 133 |
</para> |
|---|
| 134 |
|
|---|
| 135 |
<para> |
|---|
| 136 |
<function>timetravel()</function> est la fonction déclencheur générique |
|---|
| 137 |
associée à ce fonctionnement. |
|---|
| 138 |
On crée un déclencheur <literal>BEFORE INSERT OR UPDATE |
|---|
| 139 |
OR DELETE</literal> qui utilise cette fonction pour chaque table sur laquelle |
|---|
| 140 |
la fonctionnalité de voyage dans le temps est activée. Le déclencheur |
|---|
| 141 |
accepte deux arguments : les noms réels des colonnes start_date et |
|---|
| 142 |
stop_date. La fonction accepte jusqu'à trois arguments optionnels |
|---|
| 143 |
qui doivent faire référence à des colonnes de type |
|---|
| 144 |
<type>text</type>. Le déclencheur stocke le nom de l'utilisateur courant |
|---|
| 145 |
dans la première de ces colonnes lors d'un INSERT, dans la seconde lors |
|---|
| 146 |
d'un UPDATE et dans la troisième lors un DELETE. |
|---|
| 147 |
</para> |
|---|
| 148 |
|
|---|
| 149 |
<para> |
|---|
| 150 |
<function>set_timetravel()</function> permet d'activer et de |
|---|
| 151 |
désactiver la fonctionnalité de voyage dans le temps pour une table. |
|---|
| 152 |
<literal>set_timetravel('ma_table', 1)</literal> l'active pour la table |
|---|
| 153 |
ma_table. |
|---|
| 154 |
<literal>set_timetravel('ma_table', 0)</literal> la désactive pour la table |
|---|
| 155 |
ma_table. |
|---|
| 156 |
Dans les deux cas, l'ancien statut est rapporté. Quand elle est |
|---|
| 157 |
désactivée, les colonnes start_date et stop_date peuvent être librement |
|---|
| 158 |
modifiées. Le statut actif/inactif est local à la session |
|---|
| 159 |
courante — toute session commence avec cette |
|---|
| 160 |
fonctionnalité activée sur toutes les tables. |
|---|
| 161 |
</para> |
|---|
| 162 |
|
|---|
| 163 |
<para> |
|---|
| 164 |
<function>get_timetravel()</function> renvoie l'état de la fonctionnalité |
|---|
| 165 |
du voyage dans le temps pour une table sans le modifier. |
|---|
| 166 |
</para> |
|---|
| 167 |
|
|---|
| 168 |
<para> |
|---|
| 169 |
Il y a un exemple dans <filename>timetravel.example</filename>. |
|---|
| 170 |
</para> |
|---|
| 171 |
</sect2> |
|---|
| 172 |
|
|---|
| 173 |
<sect2> |
|---|
| 174 |
<title>autoinc.c — fonctions pour l'incrémentation automatique |
|---|
| 175 |
d'un champ</title> |
|---|
| 176 |
|
|---|
| 177 |
<para> |
|---|
| 178 |
<function>autoinc()</function> est un déclencheur qui stocke la prochaine valeur |
|---|
| 179 |
d'une séquence dans un champ de type integer. Cela recouvre quelque peu |
|---|
| 180 |
la fonctionnalité interne de la colonne <quote>serial</quote>, mais |
|---|
| 181 |
ce n'est pas strictement identique : <function>autoinc()</function> |
|---|
| 182 |
surcharge les tentatives de substitution d'une valeur différente pour ce |
|---|
| 183 |
champ lors des insertions et, optionnellement, peut aussi être utilisé pour |
|---|
| 184 |
incrémenter le champ lors des mises à jour. |
|---|
| 185 |
</para> |
|---|
| 186 |
|
|---|
| 187 |
<para> |
|---|
| 188 |
Pour l'utiliser, on crée un déclencheur <literal>BEFORE INSERT</literal> (ou |
|---|
| 189 |
en option <literal>BEFORE INSERT OR UPDATE</literal>) qui utilise cette |
|---|
| 190 |
fonction. Le déclencheur accepte deux arguments : le nom de la |
|---|
| 191 |
colonne de type integer à modifier et le nom de la séquence qui fournit |
|---|
| 192 |
les valeurs. (En fait, plusieurs paires de noms peuvent être indiquées pour |
|---|
| 193 |
actualiser plusieurs colonnes.) |
|---|
| 194 |
</para> |
|---|
| 195 |
|
|---|
| 196 |
<para> |
|---|
| 197 |
Un exemple est fourni dans <filename>autoinc.example</filename>. |
|---|
| 198 |
</para> |
|---|
| 199 |
|
|---|
| 200 |
</sect2> |
|---|
| 201 |
|
|---|
| 202 |
<sect2> |
|---|
| 203 |
<title>insert_username.c — fonctions pour tracer les utilisateurs qui |
|---|
| 204 |
ont modifié une table</title> |
|---|
| 205 |
|
|---|
| 206 |
<para> |
|---|
| 207 |
<function>insert_username()</function> est un déclencheur qui stocke le |
|---|
| 208 |
nom de l'utilisateur courant dans un champ texte. C'est utile pour |
|---|
| 209 |
savoir quel est le dernier utilisateur à avoir modifié une ligne particulière d'une |
|---|
| 210 |
table. |
|---|
| 211 |
</para> |
|---|
| 212 |
|
|---|
| 213 |
<para> |
|---|
| 214 |
Pour l'utiliser, on crée un déclencheur <literal>BEFORE INSERT</literal> et/ou |
|---|
| 215 |
<literal>UPDATE</literal> qui utilise cette fonction. Le déclencheur prend |
|---|
| 216 |
pour seul argument le nom de la colonne texte à modifier. |
|---|
| 217 |
</para> |
|---|
| 218 |
|
|---|
| 219 |
<para> |
|---|
| 220 |
Un exemple est fourni dans <filename>insert_username.example</filename>. |
|---|
| 221 |
</para> |
|---|
| 222 |
|
|---|
| 223 |
</sect2> |
|---|
| 224 |
|
|---|
| 225 |
<sect2> |
|---|
| 226 |
<title>moddatetime.c — fonctions pour tracer la date et l'heure |
|---|
| 227 |
de la dernière modification</title> |
|---|
| 228 |
|
|---|
| 229 |
<para> |
|---|
| 230 |
<function>moddatetime()</function> est un déclencheur qui stocke la date et |
|---|
| 231 |
l'heure de la dernière modification dans un champ de type |
|---|
| 232 |
<type>timestamp</type>. C'est utile pour savoir quand a eu lieu la |
|---|
| 233 |
dernière modification sur une ligne particulière d'une table. |
|---|
| 234 |
</para> |
|---|
| 235 |
|
|---|
| 236 |
<para> |
|---|
| 237 |
Pour l'utiliser, on crée un déclencheur <literal>BEFORE UPDATE</literal> qui |
|---|
| 238 |
utilise cette fonction. Le déclencheur prend pour seul argument le |
|---|
| 239 |
nom de la colonne de type <type>timestamp</type> à modifier. |
|---|
| 240 |
</para> |
|---|
| 241 |
|
|---|
| 242 |
<para> |
|---|
| 243 |
Un exemple est fourni dans <filename>moddatetime.example</filename>. |
|---|
| 244 |
</para> |
|---|
| 245 |
|
|---|
| 246 |
</sect2> |
|---|
| 247 |
|
|---|
| 248 |
</sect1> |
|---|