COPY
   Dans PostgreSQL, la commande COPY
   a des options pour lire ou écrire à
   partir de la connexion réseau utilisée par libpq.
   Les fonctions décrites dans cette section autorisent les applications à prendre
   avantage de cette capacité en apportant ou en consommant les données copiées.
  
   Le traitement complet est le suivant. L'application lance tout d'abord la
   commande SQL COPY via PQexec ou une
   des fonctions équivalentes. La réponse à ceci (s'il n'y a pas d'erreur dans la
   commande) sera un objet PGresult avec un code de retour
   PGRES_COPY_OUT ou PGRES_COPY_IN (suivant
   la direction spécifiée pour la copie). L'application devrait alors utiliser les
   fonctions de cette section pour recevoir ou transmettre des lignes de données.
   Quand le transfert de données est terminé, un autre objet
   PGresult est renvoyé pour indiquer le succès ou l'échec du
   transfert. Son statut sera PGRES_COMMAND_OK en cas de succès
   et PGRES_FATAL_ERROR si un problème a été rencontré. À ce
   point, d'autres commandes SQL peuvent être exécutées via
   PQexec (il n'est pas possible d'exécuter d'autres
   commandes SQL en utilisant la même connexion tant que l'opération
   COPY est en cours).
  
   Si une commande COPY est lancée via
   PQexec dans une chaîne qui pourrait contenir d'autres
   commandes supplémentaires, l'application doit continuer à récupérer les
   résultats via PQgetResult après avoir terminé la séquence
   COPY. C'est seulement quand PQgetResult renvoie
   NULL que vous pouvez être certain que la chaîne de commandes
   PQexec est terminée et qu'il est possible de lancer
   d'autres commandes.
  
   Les fonctions de cette section devraient seulement être exécutées pour obtenir
   un statut de résultat PGRES_COPY_OUT ou
   PGRES_COPY_IN à partir de PQexec ou
   PQgetResult.
  
   Un objet PGresult gérant un de ces statuts comporte quelques
   données supplémentaires sur l'opération COPY qui commence.
   Les données supplémentaires sont disponibles en utilisant les fonctions qui sont
   aussi utilisées en relation avec les résultats de requêtes :
   
PQnfieldsRenvoie le nombre de colonnes (champs) à copier.
PQbinaryTuples0 indique que le format de copie complet est textuel (lignes séparées par des retours chariots, colonnes séparées par des caractères de séparation, etc). 1 indique que le format de copie complet est binaire. Voir COPY pour plus d'informations.
PQfformat
       Renvoie le code de format (0 pour le texte, 1 pour le binaire)
       associé avec chaque colonne de l'opération de copie. Les codes de
       format par colonne seront toujours zéro si le format de copie complet
       est textuel, mais le format binaire supporte à la fois des colonnes
       textuelles et des colonnes binaires (néanmoins, avec l'implémentation
       actuelle de COPY, seules les colonnes binaires
       apparaissent dans une copie binaire  donc pour le moment
       les formats par colonnes correspondent toujours au format complet).
      
Ces valeurs de données supplémentaires sont seulement disponibles en utilisant le protocole 3.0. Lors de l'utilisation du protocole 2.0, toutes ces fonctions renvoient 0.
COPY
    Ces fonctions sont utilisées pour envoyer des données lors d'un COPY
     FROM STDIN. Elles échoueront si elles sont appelées alors que la connexion
    ne se trouve pas dans l'état COPY_IN.
   
PQputCopyData
       Envoie des données au serveur pendant un état COPY_IN.
       
int PQputCopyData(PGconn *conn,
                         const char *buffer,
                         int nbytes);
       
       Transmet les données de COPY dans le tampon spécifié
       (buffer), sur nbytes octets, au serveur. Le résultat
       vaut 1 si les données ont été placées dans la queue, zéro si elles n'ont
       pas été placées dans la queue à cause de tampons pleins (cela n'arrivera
       qu'en mode non bloquant) ou -1 si une erreur s'est produite. (Utilisez
       PQerrorMessage pour récupérer des détails si la valeur de
       retour vaut -1. Si la valeur vaut zéro, attendez qu'il soit prêt à écrire et
       ré-essayez).
      
       L'application peut diviser le flux de données de COPY
       dans des tampons de taille adéquate. Les limites des tampons n'ont pas de
       signification sémantique lors de l'envoi. Le contenu du flux de données doit
       correspondre au format de données attendu par la commande
       COPY ; voir COPY
       pour des détails.
      
PQputCopyEnd
       Envoie une indication de fin de transfert au serveur lors de l'état
       COPY_IN.
       
int PQputCopyEnd(PGconn *conn,
                        const char *errormsg);
       
       Termine l'opération COPY_IN avec succès si errormsg
       est NULL. Si errormsg n'est pas
       NULL alors COPY est passé en échec,
       avec la chaîne pointée par errormsg
       comme message d'erreur. (Mais ne pas supposer que ce message d'erreur précis
       proviendra du serveur car le serveur pourrait avoir déjà échoué sur la commande
       COPY pour des raisons qui lui sont propres). Notez aussi que
       l'option forçant l'échec ne fonctionnera pas lors de l'utilisation de
       connexions avec un protocole pre-3.0.
      
       Le résultat est 1 si le message de terminaison a été envoyé ; ou en
       mode non bloquant, cela peut seulement indiquer que le message de
       terminaison a été correctement mis en file d'attente. (En mode non
       bloquant, pour être certain que les données ont été correctement
       envoyées, vous devriez ensuite attendre que le mode écriture soit
       disponible puis appeler PQflush, à répéter
       jusqu'à ce que 0 soit renvoyé). Zéro indique que la fonction n'a
       pas pu mettre en file d'attente le message de terminaison à cause d'une
       file pleine ; ceci ne peut survenir qu'en mode non bloquant. (Dans ce
       cas, attendez que le mode écriture soit disponible puis rappelez
       à nouveau la fonction PQputCopyEnd). Si
       une erreur physique survient, -1 est renvoyé ; vous pouvez alors
       appeler PQerrorMessage pour avoir plus de
       détails sur l'erreur.
      
       Après un appel réussi à PQputCopyEnd, appelez
       PQgetResult pour obtenir le statut de résultat final de la commande
       COPY. Vous pouvez attendre que le résultat soit disponible de la
       même façon. Puis, retournez au fonctionnement normal.
      
COPY
    Ces fonctions sont utilisées pour recevoir des données lors d'un COPY
     TO STDOUT. Elles échoueront si elles sont appelées alors que la connexion
    n'est pas dans l'état COPY_OUT
   
PQgetCopyData
       Reçoit des données à partir du serveur lors d'un état COPY_OUT.
       
int PQgetCopyData(PGconn *conn,
                         char **buffer,
                         int async);
       
       Tente d'obtenir une autre ligne de données du serveur lors d'une
       opération COPY. Les données ne sont renvoyées qu'une ligne à
       la fois ; si seulement une ligne partielle est disponible, elle n'est pas
       renvoyée. Le retour d'une ligne avec succès implique l'allocation d'une portion
       de mémoire pour contenir les données. Le paramètre buffer ne doit
       pas être NULL. *buffer est initialisé pour
       pointer vers la mémoire allouée ou vers NULL au cas où aucun
       tampon n'est renvoyé. Un tampon résultat non NULL devra être
       libéré en utilisant PQfreemem lorsqu'il ne sera plus utile.
      
       Lorsqu'une ligne est renvoyée avec succès, la valeur de retour est le
       nombre d'octets de la donnée dans la ligne (et sera donc toujours supérieur
       à zéro). La chaîne renvoyée est toujours terminée par un octet nul bien que ce
       ne soit utile que pour les COPY textuels. Un résultat
       zéro indique que la commande COPY est toujours en cours mais
       qu'aucune ligne n'est encore disponible (ceci est seulement possible lorsque
       async est vrai). Un résultat -1 indique que
       COPY a terminé. Un résultat -2 indique qu'une erreur est
       survenue (consultez PQerrorMessage pour en connaître la raison).
      
       Lorsque async est vraie (différent de zéro),
       PQgetCopyData ne bloquera pas en attente d'entrée ; il
       renverra zéro si COPY est toujours en cours mais qu'aucune
       ligne n'est encore disponible. (Dans ce cas, attendez qu'il soit prêt à
       lire puis appelez PQconsumeInput avant d'appeler
       PQgetCopyData de nouveau). Quand async est faux (zéro),
       PQgetCopyData bloquera tant que les données ne seront pas
       disponibles ou tant que l'opération n'aura pas terminée.
      
       Après que PQgetCopyData a renvoyé -1, appelez
       PQgetResult pour obtenir le statut de résultat final de la commande
       COPY. On peut attendre la disponibilité de ce résultat comme
       d'habitude. Puis, retournez aux opérations habituelles.
      
COPY
    Ces fonctions représentent d'anciennes méthodes de gestion de
    COPY. Bien qu'elles fonctionnent toujours, elles sont obsolètes à
    cause de leur pauvre gestion des erreurs, des méthodes inadéquates de
    détection d'une fin de transmission, et du manque de support des transferts
    binaires et des transferts non bloquants.
   
PQgetline
       Lit une ligne de caractères terminée par un retour chariot (transmis
       par le serveur) dans un tampon de taille length.
       
int PQgetline(PGconn *conn,
                     char *buffer,
                     int length);
       
       Cette fonction copie jusqu'à length-1 caractères dans le tampon
       et convertit le retour chariot en un octet nul. PQgetline
       renvoie EOF à la fin de l'entrée, 0 si la ligne entière a été
       lue et 1 si le tampon est complet mais que le retour chariot à la fin n'a pas
       encore été lu.
      
       Notez que l'application doit vérifier si un retour chariot est constitué de
       deux caractères \., ce qui indique que le serveur a terminé
       l'envoi des résultats de la commande COPY. Si l'application
       peut recevoir des lignes de plus de length-1 caractères, une
       attention toute particulière est nécessaire pour s'assurer qu'elle reconnaisse
       la ligne \. correctement (et ne confond pas, par exemple,
       la fin d'une longue ligne de données pour une ligne de terminaison).
      
PQgetlineAsync
       Lit une ligne de données COPY
       (transmise par le serveur) dans un tampon sans blocage.
       
int PQgetlineAsync(PGconn *conn,
                          char *buffer,
                          int bufsize);
       
       Cette fonction est similaire à PQgetline mais elle peut
       être utilisée par des applications qui doivent lire les données de
       COPY de façon asynchrone, c'est-à-dire sans blocage. Après
       avoir lancé la commande COPY et obtenu une réponse
       PGRES_COPY_OUT, l'application devrait appeler
       PQconsumeInput et
       PQgetlineAsync jusqu'à ce que le signal de fin des données
       soit détecté.
      
       Contrairement à PQgetline, cette fonction prend la
       responsabilité de détecter la fin de données.
      
       À chaque appel, PQgetlineAsync renverra des données si une
       ligne de données complète est disponible dans le tampon d'entrée de
       libpq. Sinon, aucune ligne n'est renvoyée jusqu'à l'arrivée du
       reste de la ligne. La fonction renvoie -1 si le marqueur de fin de copie des
       données a été reconnu, 0 si aucune donnée n'est disponible ou un nombre
       positif indiquant le nombre d'octets renvoyés. Si -1 est renvoyé, l'appelant
       doit ensuite appeler PQendcopy puis retourner aux
       traitements habituels.
      
       Les données renvoyées ne seront pas étendues au-delà de la limite de la ligne.
       Si possible, une ligne complète sera retournée en une fois. Mais si le tampon
       offert par l'appelant est trop petit pour contenir une ligne envoyée par le
       serveur, alors une ligne de données partielle sera renvoyée. Avec des données
       textuelles, ceci peut être détecté en testant si le dernier octet renvoyé est
       \n ou non (dans un COPY binaire, l'analyse
       réelle du format de données COPY sera nécessaire pour faire la
       détermination équivalente). La chaîne renvoyée n'est pas terminée par un
       octet nul. (Si vous voulez ajouter un octet nul de terminaison, assurez-vous de
       passer un bufsize inférieur de 1 par rapport à l'espace
       réellement disponible).
      
PQputline
       Envoie une chaîne terminée par un octet nul au serveur. Renvoie 0 si tout va
       bien et EOF s'il est incapable d'envoyer la chaîne.
       
int PQputline(PGconn *conn,
                     const char *string);
       
       Le flux de données de COPY envoyé par une série d'appels à
       PQputline a le même format que celui renvoyé par
       PQgetlineAsync, sauf que les applications ne sont pas
       obligées d'envoyer exactement une ligne de données par appel à
       PQputline ; il est correct d'envoyer une ligne
       partielle ou plusieurs lignes par appel.
      
        Avant le protocole 3.0 de PostgreSQL, il était
        nécessaire pour l'application d'envoyer explicitement les deux caractères
        \. comme ligne finale pour indiquer au serveur
        qu'elle a terminé l'envoi des données du COPY.
        Bien que ceci fonctionne toujours, cette
        méthode est obsolète et la signification spéciale de \.
        pourrait être supprimée dans une prochaine version. Il est suffisant d'appeler
        PQendcopy après avoir envoyé les vraies données.
       
PQputnbytes
       Envoie une chaîne non terminée par un octet nul au serveur. Renvoie 0 si tout
       va bien et EOF s'il n'a pas été capable d'envoyer la chaîne.
       
int PQputnbytes(PGconn *conn,
                       const char *buffer,
                       int nbytes);
       
       C'est exactement comme PQputline, sauf que le tampon de
       données n'a pas besoin d'être terminé avec un octet nul car le nombre d'octets
       envoyés est spécifié directement. Utilisez cette procédure pour envoyer des
       données binaires.
      
PQendcopySe synchronise avec le serveur.
int PQendcopy(PGconn *conn);
       
       Cette fonction attend que le serveur ait terminé la copie. Elle devrait
       indiquer soit le moment où la dernière chaîne a été envoyée au serveur en utilisant
       PQputline, soit le moment où la dernière chaîne a été reçue
       du serveur en utilisant PQgetline. Si ce n'est pas fait,
       le serveur renverra un « out of sync » (perte de
       synchronisation) au client. Au retour de cette fonction, le serveur est
       prêt à recevoir la prochaine commande SQL. Le code de retour 0 indique un
       succès complet et est différent de zéro dans le cas contraire (utilisez
       PQerrorMessage pour récupérer des détails sur l'échec).
      
       Lors de l'utilisation de PQgetResult, l'application
       devrait répondre à un résultat PGRES_COPY_OUT en exécutant
       PQgetline de façon répétée, suivi par un
       PQendcopy une fois la ligne de terminaison aperçue.
       Il devrait ensuite retourner à la boucle PQgetResult
       jusqu'à ce que PQgetResult renvoie un pointeur NULL. De
       façon similaire, un résultat PGRES_COPY_IN est traité par une
       série d'appels à PQputline suivis par un
       PQendcopy, ensuite retour à la boucle
       PQgetResult. Cet arrangement vous assurera qu'une commande
       COPY intégrée dans une série de commandes
       SQL sera exécutée correctement.
      
       Les anciennes applications sont susceptibles de soumettre un
       COPY via PQexec et supposent que
       la transaction est faite après un
       PQendcopy. Ceci fonctionnera correctement seulement si
       COPY est la seule commande SQL dans la
       chaîne de commandes.