27.7. Fonctions associ�es avec la commande COPY

La commande COPY dans PostgreSQL a des options pour lire ou �crire � partir de la connexion r�seau utilis�e par libpq. Les fonctions d�crites dans cette section permettent aux applications d'utiliser cette capacit� en apportant ou en consommant des donn�es copi�es.

Le processus complet de COPY 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) est 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 doit 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 est PGRES_COMMAND_OK en cas de succ�s et PGRES_FATAL_ERROR si un probl�me a �t� rencontr�. � ce moment seulement, une autre commande SQL peut �tre lanc�e 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 ne doivent �tre ex�cut�es qu'apr�s avoir obtenu un statut de r�sultat PGRES_COPY_OUT ou PGRES_COPY_IN � partir de PQexec ou PQgetResult.

Un objet PGresult contenant un de ces statuts comporte quelques donn�es suppl�mentaires sur l'op�ration COPY qui commence. La donn�es suppl�mentaire est disponible en utilisant les fonctions qui sont aussi utilis�es en relation avec les r�sultats de requ�tes :

PQnfields

Renvoie le nombre de colonnes (champs) � copier.

PQbinaryTuples

0 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� � chaque colonne de l'op�ration de copie. Les codes de format par colonne sont 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 des colonnes binaires apparaissent dans une copie binaire  donc actuellement, les formats par colonnes correspondent toujours au format complet.)

Note�: 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.

27.7.1. Fonctions d'envoi de donn�es pour COPY

Ces fonctions sont utilis�es pour envoyer des donn�es lors d'un COPY FROM STDIN. Elles �chouent 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 du buffer sp�cifi�, sur nbytesoctets, au serveur. Le r�sultat vaut 1 si les donn�es ont �t� envoy�es, z�ro si elles n'ont pas �t� envoy�es car la tentative pourrait bloquer (ce cas n'est possible que dans le cas d'une connexion 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 que la connexion soit disponible en �criture et r�-essayez.)

L'application peut diviser le flux de donn�es de COPY en tampons de taille quelconque. Les tailles de 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 �choue, la cha�ne point�e par errormsg �tant utilis�e comme message d'erreur. Il ne faut pas supposer que ce message d'erreur pr�cis reviendra du serveur car le serveur peut avoir d�j� �chou�e sur la commande COPY pour des raisons qui lui sont propres. Notez aussi que l'option for�ant l'�chec ne fonctionne pas lors de l'utilisation de connexions avec un protocole pre-3.0.

Le r�sultat est 1 si les donn�es de fin ont �t� envoy�es, z�ro si elles ne l'ont pas �t� car cette tentative serait bloquante (ce cas est uniquement possible si la connexion est dans un mode non bloquant) ou -1 si une erreur est survenue. (Utilisez PQerrorMessage pour r�cup�rer les d�tails si le code de retour est -1. Si la valeur vaut z�ro, attendez que le serveur soit pr�t en �criture et r�-essayez de nouveau.)

Apr�s un appel r�ussi � PQputCopyEnd, appelez PQgetResult pour obtenir le statut de r�sultat final de la commande COPY. Vous pourriez attendre que le r�sultat soit disponible de la m�me fa�on. Puis, retournez aux op�rations normales.

27.7.2. Fonctions pour recevoir des donn�es de COPY

Ces fonctions sont utilis�es pour recevoir des donn�es lors d'un COPY TO STDOUT. Elles �chouent si elles sont appel�es alors que la connexion n'est pas dans l'�tat COPY_OUT

PQgetCopyData

Re�oit des donn�es 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 seule 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 doit �tre lib�r� en utilisant PQfreemem lorsqu'il n'est plus utile.

Lorsqu'une ligne est renvoy�e avec succ�s, le code de retour est le nombre d'octets de la donn�e dans la ligne (et est donc 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 n'est possible que lorsque async est vrai). Un r�sultat de -1 indique que COPY a termin�. Un r�sultat de -2 indique qu'une erreur est survenue (consultez PQerrorMessage pour en conna�tre la raison).

Lorsque async est vrai (diff�rent de z�ro), PQgetCopyData ne bloque pas en attente d'entr�e ; elle renvoie z�ro si COPY est toujours en cours mais qu'aucune ligne n'est encore disponible. Dans ce cas, attendez que le connexion soit pr�te en lecture puis appelez PQconsumeInput avant d'appeler de nouveau PQgetCopyData). Quand async est faux (z�ro), PQgetCopyData bloque tant que les donn�es ne sont pas disponibles ou tant que l'op�ration n'est pas termin�e.

Apr�s que PQgetCopyData ait renvoy� -1, appelez PQgetResult pour obtenir le statut de r�sultat final de la commande COPY. Vous pourriez attendre la disponibilit� de ce r�sultat, comme d'habitude. Puis, retournez aux op�rations habituelles.

27.7.3. Fonctions obsol�tes pour 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 m�diocre gestion des erreurs, des m�thodes peu commodes de d�tection d'une fin de transmission, et de l'absence de support des transferts binaires et des transferts non bloquants.

PQgetline

Lit une ligne de caract�res termin�e par un retour chariot (transmise 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 tampin 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� lu 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 la confonde pas, par exemple, avec la fin d'une longue ligne de donn�es).

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 doit appeler PQconsumeInput et PQgetlineAsync jusqu'� ce que le signal de fin de donn�es soit d�tect�.

Contrairement � PQgetline, cette fonction prend la responsabilit� de d�tecter la fin de donn�es.

� chaque appel, PQgetlineAsync renvoie 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 ou 0 si aucune donn�e n'est disponible ou un nombre positif indiquant le nombre d'octets renvoy�s. Si -1 est renvoy�, l'appeleur doit ensuite appeler PQendcopy puis retourner aux traitements habituels.

Les donn�es renvoy�es ne renvoie pas plus d'une ligne � la fois. Si possible, une ligne compl�te est 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 est 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 est 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 possible d'envoyer une ligne partielle ou plusieurs lignes par appel.

Note�: Avant le protocole 3.0 de PostgreSQL, il �tait n�cessaire que l'application envoie explicitement les deux caract�res \. comme ligne finale pour indiquer la fin de l'envoi des donn�es du COPY data. Bien que ceci fonctionne toujours, cette m�thode est abandonn�e 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� possible 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 indiqu� directement. Utilisez cette proc�dure pour envoyer des donn�es binaires.

PQendcopy

Se synchronise avec le serveur.

int PQendcopy(PGconn *conn);

Cette fonction attend jusqu'� ce que le serveur ait termin� la copie. Elle doit �tre appel�e pour indiquer quand la derni�re cha�ne a �t� envoy�e au serveur en utilisant PQputline ou quand la derni�re cha�ne a �t� re�ue du serveur en utilisant PGgetline. Si PQendcopy est omise, le serveur se <<�d�synchronisera�>> du 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 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 doit r�pondre � un r�sultat PGRES_COPY_OUT en ex�cutant PQgetline de fa�on r�p�t�e, suivie par un PQendcopy une fois la ligne de terminaison re�ue. Il doit ensuite retourner � la boucle PQgetResult jusqu'� ce que PQgetResult renvoie un pointeur nul. 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. Cette vous assure qu'une commande COPY int�gr�e dans une s�rie de commandes SQL est ex�cut�e correctement.

Les anciennes applications soumettaient un COPY via PQexec et assument que la transaction est termin�e apr�s un PQendcopy. Ceci fonctionne toujours correctement si et seulement si COPY est la seule commande SQL dans la cha�ne de commandes.