Si des utilisateurs pour lesquels nous n'avons pas confiance ont accès à
une base de données qui n'a pas adopté une méthode sécurisée d'usage des
schemas, commencez chaque session en supprimant les schémas
modifiables par tout le monde du paramètre search_path
.
Par exemple, ajoutez options=-c search_path=
à
ou exécutez
options
EXEC SQL SELECT pg_catalog.set_config('search_path', '',
false);
tout de suite après la connexion. Cette considération
n'est pas spécifique à ECPG ; elle s'applique à chaque interface
permettant d'exécuter des commandes SQL arbitraires.
Cette section explique comment ouvrir, fermer, et changer de connexion à la base.
On se connecte à la base de données avec l'ordre suivant:
EXEC SQL CONNECT TOcible
[ASnom-connexion
] [USERnom-utilisateur
];
La cible
peut être spécifiée des façons
suivantes:
nomdb
[@nomhôte
][:port
]
tcp:postgresql://nomhôte
[:port
][/nomdb
][?options
]
unix:postgresql://nomhôte
[:port
][/nomdb
][?options
]
DEFAULT
Si vous spécifiez la chaine de connection de façon littérale (c'est à dire,
pas par une référence à une variable) et que vous ne mettez pas la valeur
entre guillemets, alors les règles d'insensibilité à la casse du SQL normal
sont appliquées. Dans ce cas, vous pouvez aussi mettre entre guillemets doubles
chaue paramètre individuel séparément au besoin. En pratique, il y a probablement
moins de risques d'erreur à utiliser une chaîne de caractères entre simples
guillemets, ou une référence à une variable. La cible de connexion
DEFAULT
initie une connexion à la base de données par défaut
avec l'utilisateur par défaut. Il n'est pas nécessaire de préciser séparément
un nom d'utilisateur ou un nom de connexion dans ce cas.
Il y a aussi plusieurs façons de spécifier le nom de l'utilisateur:
nomutilisateur
nomutilisateur
/motdepasse
nomutilisateur
IDENTIFIED BY motdepasse
nomutilisateur
USING motdepasse
Comme précédemment, les paramètres nomutilisateur
et
motdepasse
peuvent être un identifiant SQL,
une chaîne SQL littérale, ou une référence à une variable caractère.
Si la cible de connexion indiclut des options
,
ils doivent consister en des paires
séparées par un point-virgule (motclé
=valeur
&
).
Les mots-clés autorisés sont les mêmes que ceux reconnus par
libpq (voir
Section 34.1.2). Les espaces sont ignorés avant tout
motclé
ou valeur
, mais
pas à l'intérieur de l'un ou l'autre. Notez qu'il n'existe pas de moyens
d'écrire &
dans une valeur
.
Le nom-connexion
est utilisé pour gérer
plusieurs connexions dans un programme. Il peut être omis si le programme
n'utilise qu'une connexion. La connexion la plus récemment ouverte devient
la connexion courante, qui est utilisée par défaut quand un ordre SQL doit
être exécuté (voyez plus bas dans ce chapitre).
Voici quelques exemples d'ordres CONNECT
:
EXEC SQL CONNECT TO mabase@sql.mondomaine.com; EXEC SQL CONNECT TO unix:postgresql://sql.mondomaine.com/mabase AS maconnexion USER john; EXEC SQL BEGIN DECLARE SECTION; const char *cible = "mabase@sql.mondomaine.com"; const char *utilisateur = "john"; const char *motdepasse = "secret"; EXEC SQL END DECLARE SECTION; ... EXEC SQL CONNECT TO :cible USER :utilisateur USING :motdepasse; /* or EXEC SQL CONNECT TO :cible USER :utilisateur/:motdepasse; */
La dernière forme utilise la variante dont on parlait précédemment sous le nom de référence par variable. Vous verrez dans les sections finales comment des variables C peuvent être utilisées dans des ordres SQL quand vous les préfixez par deux-points.
Notez que le format de la cible de connexion n'est pas spécifié dans le standard SQL. Par conséquent si vous voulez développer des applications portables, vous pourriez vouloir utiliser quelque chose ressemblant au dernier exemple pour encapsuler la cible de connexion quelque part.
Les ordres des programmes SQL embarqué sont par défaut exécutés dans la connexion courante, c'est à dire la plus récemment ouverte. Si une application a besoin de gérer plusieurs connexions, alors il y a deux façons de le gérer.
La première solution est de choisir explicitement une connexion pour chaque ordre SQL, par exemple:
EXEC SQL AT nom-connexion
SELECT ...;
Cette option est particulièrement appropriée si l'application a besoin d'alterner les accès à plusieurs connexions.
Si votre application utilise plusieurs threads d'exécution, ils ne peuvent pas utiliser une connexion simultanément. Vous devez soit contrôler explicitement l'accès à la connexion (en utilisant des mutexes), ou utiliser une connexion pour chaque thread.
La seconde option est d'exécuter un ordre pour changer de connexion courante. Cet ordre est:
EXEC SQL SET CONNECTION nom-connexion
;
Cette option est particulièrement pratique si de nombreux ordres doivent être exécutés sur la même connexion.
Voici un programme exemple qui gère plusieurs connexions à base de données:
#include <stdio.h> EXEC SQL BEGIN DECLARE SECTION; char nomdb[1024]; EXEC SQL END DECLARE SECTION; int main() { EXEC SQL CONNECT TO basetest1 AS con1 USER utilisateurtest; EXEC SQL SELECT pg_catalog.set_config('search_path', '', false); EXEC SQL COMMIT; EXEC SQL CONNECT TO basetest2 AS con2 USER utilisateurtest; EXEC SQL SELECT pg_catalog.set_config('search_path', '', false); EXEC SQL COMMIT; EXEC SQL CONNECT TO basetest3 AS con3 USER utilisateurtest; EXEC SQL SELECT pg_catalog.set_config('search_path', '', false); EXEC SQL COMMIT; /* Cette requête serait exécuté dans la dernière base ouverte "basetest3". */ EXEC SQL SELECT current_database() INTO :nomdb; printf("courante=%s (devrait être basetest3)\n", nomdb); /* Utiliser "AT" pour exécuter une requête dans "basetest2" */ EXEC SQL AT con2 SELECT current_database() INTO :nomdb; printf("courante=%s (devrait être basetest2)\n", nomdb); /* Basculer la connexion courante à "basetest1". */ EXEC SQL SET CONNECTION con1; EXEC SQL SELECT current_database() INTO :nomdb; printf("courante=%s (devrait être basetest1)\n", nomdb); EXEC SQL DISCONNECT ALL; return 0; }
Cet exemple devrait produire cette sortie:
courante=basetest3 (devrait être basetest3) courante=basetest2 (devrait être basetest2) courante=basetest1 (devrait être basetest1)
Pour fermer une connexion, utilisez l'ordre suivant:
EXEC SQL DISCONNECT [connexion
];
La connexion
peut être spécifiée des façons
suivantes:
nom-connexion
CURRENT
ALL
Si aucun nom de connexion n'est spécifié, la connexion courante est fermée.
C'est une bonne pratique qu'une application ferme toujours explicitement toute connexion qu'elle a ouverte.