Chapitre 27. libpq - Bibliothèque C

Table des matières
27.1. Fonctions de contrôle de connexion à la base de données
27.2. Fonctions de statut de connexion
27.3. Fonctions de commandes d'exécution
27.3.1. Fonctions principales
27.3.2. Récupérer l'informations provenant des résultats des requêtes
27.3.3. Récupérer les informations de résultats pour les autres commandes
27.3.4. Chaînes d'échappement à inclure dans les commandes SQL
27.3.5. Échapper des chaînes binaires pour une inclusion dans des commandes SQL
27.4. Traitement des commandes asynchrones
27.5. Interface à chemin rapide
27.6. Notification asynchrone
27.7. Fonctions associées avec la commande COPY
27.7.1. Fonctions d'envoi de données pour COPY
27.7.2. Fonctions pour recevoir des données de COPY
27.7.3. Fonctions obsolètes pour COPY
27.8. Fonctions de contrôle
27.9. Traitement des messages
27.10. Variables d'environnement
27.11. Fichier de mots de passe
27.12. Comportement des programmes threadés
27.13. Construire des applications avec libpq
27.14. Exemples de programmes

libpq est l'interface de programmation pour les applications C avec PostgreSQL. libpq est un ensemble de fonctions permettant aux programmes clients d'envoyer des requêtes au serveur PostgreSQL et de recevoir les résultats de ces requêtes. libpq est aussi le moteur sous-jacent de plusieurs autres interfaces de programmation de PostgreSQL comme libpq++ (C++), libpgtcl (Tcl), Perl et ECPG. Donc, certains aspects du comportement de libpq seront importants pour vous si vous utilisez un de ces paquets.

Quelques petits programmes sont inclus à la fin de ce chapitre (Section 27.14) pour montrer comment écrire des programmes utilisant libpq. Il existe aussi quelques exemples complets d'applications libpq dans le répertoire src/test/examples venant avec la distribution des sources.

Les programmes clients utilisant libpq doivent inclure le fichier d'en-tête libpq-fe.h et doivent être liés avec la bibliothèque libpq.

27.1. Fonctions de contrôle de connexion à la base de données

Les fonctions suivantes concernent la réalisation d'une connexion avec un serveur PostgreSQL. Un programme peut avoir plusieurs connexions ouvertes sur des serveurs à un même moment. (Une raison de la faire est d'accéder à plusieurs bases de données.) Chaque connexion est représentée par un objet PGconn, obtenu avec la fonction PQconnectdb ou PQsetdbLogin. Notez que ces fonctions renverront toujours un pointeur d'objet non nul, sauf peut-être dans un cas de manque de mémoire pour l'allocation de l'objet PGconn. La fonction PQstatus doit être appelée pour vérifier si la connexion s'est bien effectuée avant de lancer des requêtes via l'objet de connexion.

PQconnectdb

Crée une nouvelle connexion au serveur de bases de données.

PGconn *PQconnectdb(const char *conninfo);

Cette fonction ouvre une nouvelle connexion à la base de données en utilisant les paramètres à partir de la chaîne conninfo. Contrairement à PQsetdbLogin ci-dessous, l'ensemble de paramètres peut être étendu sans changer la signature de la fonction, donc utiliser cette fonction (ou son analogue non bloquant, PQconnectStart et PQconnectPoll) est préféré pour la programmation de nouvelles applications.

La chaîne passée peut être vide pour utiliser tous les paramètres par défaut ou elle peut contenir un ou plusieurs paramétrages séparés par des espaces blancs. Chaque paramètre est de la forme motclé = valeur. (Pour écrire une valeur vide ou une valeur contenant des espaces, entourez-les de guillemets simples, c'est-à-dire motclé = 'une valeur'. Des guillemets simples et des anti-slashs à l'intérieur de la valeur peuvent être échappés avec un antislash, par exemple \' et \\.) Les espaces autour du signe égal sont optionnels.

Les mots clés actuellement reconnus sont :

host

Nom de l'hôte sur lequel se connecter. S'il commence avec un slash, il spécifie une communication par domaine Unix plutôt qu'une communication TCP/IP ; la valeur est le nom du répertoire où le fichier socket est stocké. Par défaut, il s'agit d'une communication par socket de domaine Unnix dans /tmp.

hostaddr

Adresse IP numérique de l'hôte de connexion. Elle devrait être au format d'adresse standard IPv4, c'est-à-dire 172.28.40.9. Si votre machine supporte IPv6, vous pouvez aussi utiliser ces adresses. La communication TCP/IP est toujours utilisée lorsqu'une chaîne non vide est spécifiée pour ce paramètre.

Utiliser hostaddr au lieu de host permet à l'application d'éviter une recherche de nom d'hôte, qui pourrait être importante pour les applications ayant des contraintes de temps. Néanmoins, l'authentification Kerberos requiert un nom d'hôte. Du coup, la recherche s'effectue comme suit: si host est indiqué sans hostaddr, une recherche de nom d'hôte a lieu. Si hostaddr est spécifié sans host, la valeur de hostaddr donne l'adresse distante. Lorsque Kerberos est utilisée, une recherche de nom inverse est effectuée pour obtenir le nom d'hôte pour Kerberos. Si à la fois host et hostaddr sont spécifiés, la valeur de hostaddr donne l'adresse distante ; la valeur de host est ignorée sauf si Kerberos est utilisé, auquel cas il s'agit de la valeur utilisée pour l'authentification Kerberos. (Notez que l'authentification a des chances d'échouer si libpq se voit donner un nom qui n'est pas le nom de la machine sur hostaddr.) De même, host plutôt que hostaddr est utilisé pour identifier la connexion dans $HOME/.pgpass.

Sans un nom ou une adresse d'hôte, libpq se connectera en utilisant une socket locale de domaine Unix.

port

Numéro de port pour la connexion au serveur ou extension du nom de fichier pour des connexions de domaine Unix.

dbname

Le nom de la base de données. Par défaut, la même que le nom d'utilisateur.

user

Nom de l'utilisateur PostgreSQL qui se connecte.

password

Mot de passe à utiliser si le serveur demande une authentification par mot de passe.

connect_timeout

Attente maximum pour une connexion, en secondes (saisie comme une chaîne d'entier décimaux). Zéro ou non spécifié signifie une attente infinie. Utiliser une attente de moins de deux secondes n'est pas recommandé.

options

Options en ligne de commande à envoyer au serveur.

tty

Ignoré (auparavant, ceci indiquait où envoyer les traces de débogage du serveur).

sslmode

Cette option détermine si ou avec quelle priorité une connexion SSL sera négociée avec le serveur. Il existe quatre modes : disable essaie uniquement une connexion non cryptée SSL ; allow négocie, en essayant tout d'abord une connexion sans SSL puis, si cela échoue, une connexion SSL ; prefer (la valeur par défaut) négocie en essayant d'abord une connexion SSL puis, en cas d'échec, une connexion non SSL ; require essaie uniquement une connexion SSL.

Si PostgreSQL est compilé sans le support de SSL, l'utilisation de l'option require cause une erreur et les options allow et prefer sont tolérées mais libpq est incapable de négorctier une connexion SSL.

requiressl

Cette option est obsolète et remplacée par l'option sslmode.

Si initialisée à 1, une connexion SSL au serveur est requise (ce qui est équivalent à un sslmode require). libpq refuse alors de se connecter si le serveur n'accepte pas une connexion SSL. Si initialisée à 0 (la valeur par défaut), libpq négocie le type de connexion avec le serveur (équivalent à un sslmode prefer). Cette option est seulement disponible si PostgreSQL est compilé avec le support SSL.

service

Nom du service à utiliser pour des paramètres supplémentaires. Il indique un nom de service dans pg_service.conf contenant des paramètres de connexion supplémentaires. Ceci permet aux applications de ne spécifier qu'un nom de service afin de permettre une maintenance centralisée des paramètres de connexion. Voir PREFIX/share/pg_service.conf.sample pour plus d'informations sur le configuration de ce fichier.

Si un paramètre manque, alors la variable d'environnement correspondante (voir Section 27.10) est testée. Si elle n'est pas disponible, alors la valeur par défaut est utilisée.

PQsetdbLogin

Crée une nouvelle connexion sur le serveur de bases de données.

PGconn *PQsetdbLogin(const char *pghost,
                     const char *pgport,
                     const char *pgoptions,
                     const char *pgtty,
                     const char *dbName,
                     const char *login,
                     const char *pwd);

C'est le prédécesseur de PQconnectdb avec un ensemble de paramètres fixe. Cette fonction a les mêmes fonctionnalités sauf que les paramètres manquants seront toujours initialisées avec leur valeurs par défaut. Écrire NULL ou un chaîne vide pour un de ces paramètres fixes dont vous souhaitez utiliser la valeur par défaut.

PQsetdb

Crée une nouvelle connexion sur le serveur de bases de données.

PGconn *PQsetdb(char *pghost,
                char *pgport,
                char *pgoptions,
                char *pgtty,
                char *dbName);

C'est une macro faisant appel à PQsetdbLogin avec des pointeurs nuls pour les paramètres login et pwd. Elle est fournie pour une compatibilité ascendante des très vieux programmes.

PQconnectStart
PQconnectPoll

Crée une connexion au serveur de bases de données d'une façon non bloquante.

PGconn *PQconnectStart(const char *conninfo);

PostgresPollingStatusType PQconnectPoll(PGconn *conn);

Ces deux fonctions sont utilisées pour ouvrir une connexion au serveur de bases de données d'une façon telle que le thread de votre application n'est pas bloqué sur les entrées/sorties distantes en demandant la connexion. Le principe de cette approche est que l'attente de la fin des entrées/sorties se fait dans la boucle principale de l'application plutôt qu'à l'intérieur de PQconnectdb, ce qui permet à l'application de gérer cette opération en parallèle d'autres activités.

La connexion à la base de données est faite en utilisant les paramètres pris dans la chaîne conninfo, passée à PQconnectStart. Cette chaîne est du même format que celle décrite pour PQconnectdb.

Ni PQconnectStart ni PQconnectPoll ne sont bloquantes, si les restictions suivantes sont respectées :

  • Les paramètres hostaddr et host sont utilisés de façon appropriée pour vous assurer que la requête de nom et la requête inverse ne soient pas lancées. Voir la documentation de ces paramètres avec PQconnectdb ci-dessus pour les détails.

  • Si vous appelez PQtrace, assurez-vous que l'objet de flux dans lequel vous enregistrez les traces ne bloque pas.

  • Assurez-vous que la socket soit dans l'état approprié avant d'appeler PQconnectPoll, comme décrit ci-dessous.

Pour commencer une demande de connexion non bloquante, appelez conn = PQconnectStart("connection_info_string"). Si conn est nul, alors libpq a été incapable d'allouer une nouvelle structure PGconn. Sinon, un pointeur valide vers une structure PGconn est renvoyé (bien qu'il ne représente pas encore une connexion valide vers la base de données). Au retour de PQconnectStart, appelez status = PQstatus(conn). Si status vaut CONNECTION_BAD, PQconnectStart a échoué.

Si PQconnectStart réussit, la prochaine étape est d'appeler souvent libpq de façon à ce qu'il continue la séquence de connexion. Utilisez PQsocket(conn) pour obtenir le descripteur de socket de la connexion à la base de données. Du coup, une boucle : si le dernier retour de PQconnectPoll(conn) est PGRES_POLLING_READING, attendez que la socket soit prête pour lire (comme indiqué par select(), poll() ou une fonction système similaire). Puis, appelez de nouveau PQconnectPoll(conn). Par contre, si le dernier retour de PQconnectPoll(conn) est PGRES_POLLING_WRITING, attendez que la socket soit prête pour écrire, puis appelez de nouveau PQconnectPoll(conn). Si vous devez encore appeler PQconnectPoll, c'est-à-dire juste après l'appel de PQconnectStart, continuez comme si il avait renvoyé PGRES_POLLING_WRITING. Continuez cette boucle jusqu'à ce que PQconnectPoll(conn) renvoie PGRES_POLLING_FAILED, indiquant que la procédure de connexion a échoué ou, ou PGRES_POLLING_OK, indiquant le succès de la procédure de connexion.

À tout moment pendant la connexion, le statut de cette connexion peut être vérifié en appelant PQstatus. Si le résultat est CONNECTION_BAD, alors la procédure de connexion a échoué ; si, au contraire, elle renvoie CONNECTION_OK, alors la connexion est prête. Ces deux états sont détectables à partir de la valeur de retour de PQconnectPoll, décrite ci-dessus. D'autres états pourraient survenir lors (et seulement dans ce cas) d'une procédure de connexion asynchrone. Ils indiquent l'état actuel de la procédure de connexion et peuvent être utile pour fournir un retour à l'utilisateur. Ces statuts sont :

CONNECTION_STARTED

Attente que la connexion se fasse.

CONNECTION_MADE

Connexion OK ; attente d'un envoi.

CONNECTION_AWAITING_RESPONSE

Attente d'une réponse du serveur.

CONNECTION_AUTH_OK

Authentification reçue ; attente de la fin du lancement du moteur.

CONNECTION_SSL_STARTUP

Négociation du cryptage SSL.

CONNECTION_SETENV

Négociation des paramétrages liés à l'environnement.

Notez que, bien que ces constantes resteront (pour maintenir une compatibilité), une application ne doit jamais se baser sur leur ordre d'aparition ou ni croire que seules ces valeurs documentées sont susceptibles d'aparaitre. Une application devrait au contraire faire quelque chose comme ça :

switch(PQstatus(conn))
{
    case CONNECTION_STARTED:
        feedback = "Connexion en cours...";
        break;

    case CONNECTION_MADE:
        feedback = "Connecté au serveur...";
        break;
.
.
.
    default:
        feedback = "Connexion...";
}

Le paramètre de connexion connect_timeout est ignoré lors de l'utilisation de PQconnectPoll ; c'est de la responsabilité de l'application de décider quand une période de temps excessive s'est écoulée. Sinon, PQconnectStart suivi par une boucle PQconnectPoll est équivalent à PQconnectdb.

Notez que si PQconnectStart renvoie un pointeur non nul, vous devez appeler PQfinish lorsque vous en avez terminé avec lui, pour supprimer la structure et tous les blocs mémoires qui lui sont associés. Ceci doit être fait même si la tentative de connexion échoue ou est abandonnée.

PQconndefaults

Renvoie les options de connexion par défaut.

PQconninfoOption *PQconndefaults(void);

typedef struct
{
    char   *keyword;   /* Le mot clé de l'option */
    char   *envvar;    /* Nom de la variable d'environnement équivalente */
    char   *compiled;  /* Valeur par défaut interne */
    char   *val;       /* Valeur actuelle de l'option ou NULL */
    char   *label;     /* Label du champ pour la dialogue de connexion */
    char   *dispchar;  /* Caractère à afficher pour ce champ
                        * dans un dialogue de connexion. Les valeurs sont :
                        * ""        Affiche la valeur entrée sans modification
                        * "*"       Champ de mot de passe - cache la valeur
                        * "D"       Option de débogage - non affiché par défaut
                        */
    int     dispsize;  /* Taille du champ en caractère pour le dialogue */
} PQconninfoOption;

Renvoie un tableau d'options de connexion. Ceci pourrait être utiliser pour déterminer toutes les options possibles de PQconnectdb et leur valeur par défaut. La valeur de retour pointe vers un tableau de structures PQconninfoOption qui se termine avec une entrée utilisant un pointeur nul pour keyword. Notez que les valeurs par défaut actuelles (champs val) dépendront des variables d'environnement et d'autres contextes. Les demandeurs doivent traiter les données des options de connexion en lecture seule.

Après le traitement du tableau d'options, libérez-le en le passant à la fonction PQconninfoFree. Si cela n'est pas fait, un petit bloc de mémoire est perdu à chaque appel de PQconndefaults.

PQfinish

Ferme la connexion au serveur. Libère aussi la mémoire utilisée par l'objet PGconn.

void PQfinish(PGconn *conn);

Notez que même si la connexion au serveur a échoué (d'après l'indication de PQstatus), l'application doit appeler PQfinish pour libérer la mémoire utilisée par l'objet PGconn. Le pointeur PGconn ne doit plus être utilisé après l'appel à PQfinish.

PQreset

Réinitialise le canal de communication avec le serveur.

void PQreset(PGconn *conn);

Cette fonction ferme la connexion au serveur et tente le rétablissement d'une nouvelle connexion au même serveur en utilisant tous les paramètres utilisés précédemment. Ceci peut être utile pour récupérer une erreur en cas de perte de connexion.

PQresetStart
PQresetPoll

Réinitialise la canal de communication avec le serveur d'une façon non bloquante.

int PQresetStart(PGconn *conn);

PostgresPollingStatusType PQresetPoll(PGconn *conn);

Ces fonctions ferment la connexion au serveur et tentent de rétablir une nouvelle connexion au même serveur en utilisant les mêmes paramètres que précédemment. Ceci peut être utile en cas de récupération après une erreur si une connexion est perdue. Elles diffèrent de PQreset (ci-dessus) car elles agissent d'une façon non bloquante. Ces fonctions souffrent des mêmes restrictions que PQconnectStart et PQconnectPoll.

Pour initier une réinitialisation de la connexion, appelez PQresetStart. S'il renvoie 0, la réinitialisation a échoué. S'il renvoie 1, activez la réinitialisation en utilisant PQresetPoll exactement de la même façon que vous créeriez la connexion en utilisant PQconnectPoll.