PostgreSQLLa base de données la plus sophistiquée au monde.

31. libpq - Bibliothèque C

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 ceux écrits pour C++, Perl, Python, Tcl et ECPG. Donc, certains aspects du comportement de libpq seront importants pour vous si vous utilisez un de ces paquetages. En particulier, la Section 31.13, « Variables d'environnement », la Section 31.14, « Fichier de mots de passe » et la Section 31.17, « Support de SSL » décrivent le comportement que verra l'utilisateur de toute application utilisant libpq.

Quelques petits programmes sont inclus à la fin de ce chapitre (Section 31.20, « Exemples de programmes ») 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é avec la bibliothèque libpq.

31.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, PQconnectdbParams, 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.

[Avertissement]

Avertissement

Sur Unix, la création d'un processus via l'appel système fork() avec des connexions libpq ouvertes peut amener à des résultats imprévisibles car les processus parent et enfants partagent les même sockets et les mêmes ressources du système d'exploitation. Pour cette raison, un tel usage n'est pas recommandé, alors qu'exécuter un exec à partir du processus enfant pour charger un nouvel exécutable est sûr.

[Note]

Note

Sur Windows, il existe un moyen pour améliorer les performances si une connexion seule à la base de données est ouverte puis fermée de façon répétée. En interne, libpq appelle WSAStartup() et WSACleanup() respectivement pour le début et la fin de la transaction. WSAStartup() incrémente un compteur de référence interne à la bibliothèque Windows. Ce compteur est décrémenté par WSACleanup(). Quand le compteur arrive à un, appeler WSACleanup() libère toutes les ressources et toutes les DLL associées. C'est une opération coûteuse. Pour éviter cela, une application peut appeler manuellement WSAStartup() afin que les ressources ne soient pas libérées quand la dernière connexion est fermée.

PQconnectdbParams

Établit une nouvelle connexion au serveur de base de données.

        PGconn *PQconnectdbParams(const char **keywords, const char **values, int expand_dbname);
       

Cette fonction ouvre une nouvelle connexion à la base de données en utilisant les paramètres à partir des deux tableaux terminés par un NULL. Le premier, keywords, est défini comme un tableau de chaînes, chacune étant un mot-clé. Le second, values, donne la valeur pour chaque mot-clé. Contrairement à PQsetdbLogin ci-dessous, l'ensemble des paramètres peut être étendu sans changer la signature de la fonction donc son utilisation (ou ses versions non bloquantes, à savoir PQconnectStartParams et PQconnectPoll) est recommendée pour les nouvelles applications.

Quand expand_dbname est différent de zéro, la valeur du mot-clé dbname peut être reconnue comme une chaîne conninfo. Voir ci-dessous pour les détails.

Les tableaux fournis peuvent être vides pour utiliser tous les paramètres par défaut ou peuvent contenir un ou plusieurs paramètres. Ils doivent avoir la même longueur. Le traitement stoppera au premier élément NULL découvert dans le tableau keywords.

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, quand host n'est pas spécifié, il s'agit d'une communication par socket de domaine Unix dans /tmp (ou tout autre répertoire de socket spécifié lors de la construction de PostgreSQL™). Sur les machines sans sockets de domaine Unix, la valeur par défaut est de se connecter à localhost.

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. Un nom d'hôte est requis pour les authentifications Kerberos, GSSAPI et SSPI, ainsi que pour les vérifications complètes de certificats SSL. Les règles suivantes sont utilisées : : si host est spécifié 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 du serveur. La tentative de connexion échouera dans tous les cas où un nom d'hôte est requis. Si à la fois host et hostaddr sont spécifiés, la valeur de hostaddr donne l'adresse du serveur ; la valeur de host est ignorée, sauf si Kerberos est utilisé, auquel cas cette valeur est utilisée pour l'authentification Kerberos. Notez que l'authentification a des risques d'échouer, host est le nom de la machine sur hostaddr). De même, host plutôt que hostaddr est utilisé pour identifier la connexion dans ~/.pgpass (voir la Section 31.14, « Fichier de mots de passe »).

Sans un nom ou une adresse d'hôte, libpq se connectera en utilisant un socket local de domaine Unix. Sur des machines sans sockets de domaine Unix, il tentera une connexion sur localhost.

port

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

dbname

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

user

Nom de l'utilisateur PostgreSQL™ qui se connecte. Par défaut, il s'agit du nom de l'utilisateur ayant lancé l'application.

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 indéfinie. Utiliser un décompte de moins de deux secondes n'est pas recommandé.

options

Ajout d'options en ligne de commande à envoyer au serveur à l'exécution. Par exemple, en le configurant à -c geqo=off, cela configure la valeur de la session pour le paramètre geqo à off. Pour une discussion détaillée des options disponibles, voir Chapitre 18, Configuration du serveur.

application_name

Précise une valeur pour le paramètre de configuration application_name.

fallback_application_name

Indique une valeur de secours pour le paramètre de configuration application_name. Cette valeur sera utilisée si aucune valeur n'est donnée à application_name via un paramètre de connexion ou la variable d'environnement. L'indication d'un nom de secours est utile pour les programmes outils génériques qui souhaitent configurer un nom d'application par défaut mais permettrait sa surcharge par l'utilisateur.

keepalives

Contrôle si les paramètres TCP keepalives côté client sont utilisés. La valeur par défaut est de 1, signifiant ainsi qu'ils sont utilisés. Vous pouvez le configurer à 0, ce qui aura pour effet de les désactiver si vous n'en voulez pas. Ce paramètre est ignoré pour les connexions réalisées via un socket de domaine Unix.

keepalives_idle

Contrôle le nombre de secondes d'inactivité après lequel TCP doit envoyer un message keepalive au server. Une valeur de zéro utilise la valeur par défaut du système. Ce paramètre est ignoré pour les connexions réalisées via un socket de domaine Unix ou si les paramètres keepalives sont désactivés. Ce paramètre est uniquement supporté sur les systèmes où les options TCP_KEEPIDLE ou TCP_KEEPALIVE sont disponibles et sur Windows ; pour les autres systèmes, ce paramètre n'a pas d'effet.

keepalives_interval

Contrôle le nombre de secondes après lequel un message TCP keepalive doit être retransmis si le serveur ne l'a pas acquitté. Une valeur de zéro utilise la valeur par défaut du système. Ce paramètre est uniquement supporté sur les systèmes où l'option TCP_KEEPINTVL est disponible et sur Windows ; pour les autres systèmes, ce paramètre n'a pas d'effet.

keepalives_count

Contrôle le nombre de messages TCP keepalives pouvant être perdus avant que la connexion du client au serveur ne soit considérée comme perdue. Une valeur de zéro utilise la valeur par défaut du système. Ce paramètre est uniquement supporté sur les systèmes où l'option TCP_KEEPCNT est disponible et sur Windows ; pour les autres systèmes, ce paramètre n'a pas d'effet.

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 TCP/IP SSL sécurisée sera négociée avec le serveur. Il existe six modes :

Tableau 31.1. Options de sslmode

Option Description
disable essaie seulement une connexion non SSL
allow essaie en premier lieu une connexion non SSL ; si cette tentative échoue, essaie une connexion SSL
prefer (default) essaie en premier lieu une connexion SSL ; si cette tentative échoue, essaie une connexion non SSL
require essaie seulement une connexion SSL. Si un certificat racine d'autorité est présent, vérifie le certificat de la même façon que si verify-ca était spécifié
verify-ca essaie seulement une connexion SSL et vérifie que le certificat client est créé par un CA de confiance.
verify-full essaie seulement une connexion SSL, vérifie que le certificat client est créé par un CA de confiance et que le nom du serveur correspond bien à celui du certificat.

Voir Section 31.17, « Support de SSL » pour une description détaillée de comment ces options fonctionnent.

sslmode est ignoré pour la communication par socket de domaine Unix. Si PostgreSQL™ est compilé sans le support de SSL, l'utilisation des options require, verify-ca et verify-full causera une erreur alors que les options allow et prefer seront acceptées mais libpq ne sera pas capable de négocier une connexion SSL.

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 refusera alors de se connecter si le serveur n'accepte pas une connexion SSL. Si initialisée à 0 (la valeur par défaut), libpq négociera le type de connexion avec le serveur (équivalent à un sslmode prefer). Cette option est seulement disponible si PostgreSQL™ est compilé avec le support SSL.

sslcert

Ce paramètre indique le nom du fichier du certificat SSL client, remplaçant le fichier par défaut, ~/.postgresql/postgresql.crt. Ce paramètre est ignoré si la connexion n'utilise pas SSL.

sslkey

Ce paramètre indique l'emplacement de la clé secrète utilisée pour le certificat client. Il peut soit indiquer un nom de fichier qui sera utilisé à la place du fichier ~/.postgresql/postgresql.key par défaut, soit indiquer un clé obtenue par un moteur externe (les moteurs sont des modules chargeables d'OpenSSL™). La spécification d'un moteur externe devrait consister en un nom de moteur et un identifiant de clé spécifique au moteur, les deux séparés par une virgule. Ce paramètre est ignoré si la connexion n'utilise pas SSL.

sslrootcert

Ce paramètre indique le nom d'un fichier contenant le ou les certificats de l'autorité de certificats SSL (CA). Si le fichier existe, le certificat du serveur sera vérifié. La signature devra appartenir à une de ces autorités. La valeur par défaut de ce paramètre est ~/.postgresql/root.crt.

sslcrl

Ce paramètre indique le nom du fichier de la liste de révocation du certificat SSL. Les certificats listés dans ce fichier, s'il existe bien, seront rejetés lors d'une tentative d'authentification avec le certificat du serveur. La valeur par défaut de ce paramètre est ~/.postgresql/root.crl.

krbsrvname

Nom du service Kerberos à utiliser lors de l'authentification avec Kerberos 5 et GSSAPI. Il doit correspondre avec le nom du service spécifié dans la configuration du serveur pour que l'authentification Kerberos puisse réussir (voir aussi la Section 19.3.5, « Authentification Kerberos » et Section 19.3.3, « Authentification GSSAPI ».)

gsslib

Bibliothèque GSS à utiliser pour l'authentification GSSAPI. Utilisée seulement sur Windows. Configurer à gssapi pour forcer libpq à utiliser la bibliothèque GSSAPI pour l'authentification au lieu de SSPI par défaut.

service

Nom du service à utiliser pour des paramètres supplémentaires. Il spécifie un nom de service dans pg_service.conf contenant des paramètres de connexion supplémentaires. Ceci permet aux applications de spécifier uniquement un nom de service, donc les paramètres de connexion peuvent être maintenus de façon centrale. Voir Section 31.15, « Fichier des connexions de service ».

Si un paramètre manque, alors la variable d'environnement correspondante est vérifiée (voir la Section 31.13, « Variables d'environnement »). Si elle n'est pas disponible, alors la valeur par défaut indiquée est utilisée.

Si expand_dbname est différent de zéro et que dbname contient un signe =, il est pris en tant que chaîne conninfo exactement de la même façon qu'il a été passé à PQconnectdb (voir ci-dessous). Les mots-clés traités précédemment seront surchargés par les mots-clés de la chaîne conninfo.

En général, les mots-clés sont traités à partir du début de ces tableaux dans l'ordre de l'index. L'effet qui en découle est que, quand les mots-clés sont répétés, la valeur correspondant au dernier traitement est conservée. Du coup, via un placement attentionné du mot-clé dbname, il est possible de déterminer ce qui pourrait être surchargé par une chaîne conninfo et ce qui ne le sera pas.

PQconnectdb

Établit une nouvelle connexion à un 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 pris à partir de la chaîne conninfo.

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ètres, séparés par des espaces blancs. Chaque configuration est de la forme motclé = valeur. Les espaces autour du signe égal sont optionnels. Pour écrire une valeur vide ou une valeur contenant des espaces, il est nécessaire de la placer entre guillemets simples, par exemple motclé = 'une valeur'. Les guillemets simples et les antislashs dans la valeur doivent être échappés avec un antislash, donc \' et \\.

Les mots-clés actuellement reconnus sont identiques à ceux indiqués ci-dessus.

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 fixe de paramètres. Cette fonction a les mêmes fonctionnalités sauf que les paramètres manquants seront toujours initialisés avec leur valeurs par défaut. Écrire NULL ou une chaîne vide pour un de ces paramètres fixes dont vous souhaitez utiliser la valeur par défaut.

Si dbName contient un signe =, il est pris pour une chaîne conninfo exactement de la même façon que si elle était passée à PQconnectdb, et le reste des paramètres est ensuite appliqué comme ci-dessus.

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.

PQconnectStartParams, PQconnectStart, PQconnectPoll

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

PGconn *PQconnectStartParams(const char **keywords, const char **values, int expand_dbname);

PGconn *PQconnectStart(const char *conninfo);

PostgresPollingStatusType PQconnectPoll(PGconn *conn);

Ces trois 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 but de cette approche est que l'attente de la fin des entrées/sorties peut se faire dans la boucle principale de l'application plutôt qu'à l'intérieur de PQconnectdbParams ou PQconnectdb, et donc l'application peut gérer des opérations en parallèle à d'autres activités.

Avec PQconnectStartParams, la connexion à la base de données est faite en utilisant les paramètres à partir des tableaux keywords et values, et contrôlée par expand_dbname, comme décrit ci-dessus pour PQconnectdbParams.

Avec PQconnectStart, la connexion à la base de données est faite en utilisant les paramètres provenant de la chaîne conninfo comme décrit ci-dessus pour PQconnectdb.

Ni PQconnectStartParams ni PQconnectStart ni PQconnectPoll ne bloqueront, aussi longtemps qu'un certain nombre de restrictions est respecté :

  • 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 PQconnectdbParams ci-dessus pour les détails.

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

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

Note : l'utilisation de PQconnectStartParams est analogue à PQconnectStart affichée 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 sous 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). En revanche, 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 s'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 PGRES_POLLING_OK, indiquant le succès de la procédure de connexion.

À tout moment pendant la connexion, le statut de cette connexion pourrait ê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 pourraient être utile pour fournir un retour à l'utilisateur. Ces statuts sont :

CONNECTION_STARTED

Attente de la connexion à réaliser.

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 de l'environnement.

Notez que, bien que ces constantes resteront (pour maintenir une compatibilité), une application ne devrait jamais se baser sur un ordre pour celles-ci ou sur tout ou sur le fait que le statut fait partie de ces valeurs documentés. Une application pourrait 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 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.