30.3. Interfaces client
Cette section décrit les possibilités que les bibliothèques
d'interfaces client de PostgreSQL™ fournissent pour accéder aux
objets larges. Toutes les manipulations d'objets larges utilisant ces
fonctions
doivent
prendre
place dans un bloc de transaction SQL. L'interface des objets larges
de PostgreSQL™ prend comme
modèle l'interface des systèmes de fichiers Unix avec des fonctions analogues pour open, read, write, lseek, etc.
Les applications clients utilisant l'interface des objets larges dans
libpq doivent inclure le fichier
d'en-tête libpq/libpq-fs.h et établir un
lien avec la bibliothèque libpq.
30.3.1. Créer un objet large
La fonction
Oid lo_creat(PGconn *conn, int mode);
crée un nouvel objet large. La valeur de retour est l'OID assigné
au nouvel objet large ou InvalidOid
(zéro) en cas d'erreur.
mode
est inutilisée et ignorée sur PostgreSQL™ 8.1 ; néanmoins, pour la
compatibilité avec les anciennes versions, il est préférable de
l'initialiser à INV_READ, INV_WRITE, ou INV_READ
|
INV_WRITE
(ces constantes symboliques sont définies dans le fichier d'en-tête
libpq/libpq-fs.h).
Un exemple :
inv_oid = lo_creat(conn, INV_READ|INV_WRITE);
La fonction
Oid lo_create(PGconn *conn, Oid lobjId);
crée aussi un nouvel objet large. L'OID à affecter peut être
spécifié par
lobjId
; dans ce
cas, un échec survient si l'OID est déjà utilisé pour un autre
objet large. Si
lobjId
vaut
InvalidOid (zero), alors lo_create affecte un OID inutilisé (ceci est le
même comportement que lo_creat). La
valeur de retour est l'OID qui a été affecté au nouvel objet large
ou InvalidOid (zero) en cas d'échec.
lo_create est nouveau depuis PostgreSQL™ 8.1 ; si cette fonction est
utilisée à partir d'un serveur d'une version plus ancienne, elle
échouera et renverra InvalidOid.
Un exemple :
inv_oid = lo_create(conn, desired_oid);
30.3.2. Importer un objet large
Pour importer un fichier du système d'exploitation en tant qu'objet
large, appelez
Oid lo_import(PGconn *conn, const char *filename);
filename
spécifie le nom du
fichier à importer comme objet large. Le code de retour est l'OID
assigné au nouvel objet large ou InvalidOid (zero) en cas d'échec. Notez que le
fichier est lu par la bibliothèque d'interface du client, pas par
le serveur. Donc il doit exister dans le système de fichier du
client et lisible par l'application du client.
30.3.3. Exporter un objet large
Pour exporter un objet large en tant que fichier du système
d'exploitation, appelez
int lo_export(PGconn *conn, Oid lobjId, const char *filename);
L'argument
lobjId
spécifie
l'OID de l'objet large à exporter et l'argument
filename
spécifie le nom du fichier.
Notez que le fichier est écrit par la bibliothèque d'interface du
client, pas par le serveur. Renvoie 1 en cas de succès, -1 en cas
d'échec.
30.3.4. Ouvrir un objet large existant
Pour ouvrir un objet large existant pour lire ou écrire, appelez
int lo_open(PGconn *conn, Oid lobjId, int mode);
L'argument
lobjId
spécifie
l'OID de l'objet large à ouvrir. Les bits
mode
contrôlent si l'objet est ouvert en
lecture (INV_READ), écriture
(INV_WRITE) ou les deux (ces constantes
symboliques sont définies dans le fichier d'en-tête libpq/libpq-fs.h). Un objet large ne peut pas être
ouvert avant d'avoir été créé. lo_open
renvoie un descripteur (positif) d'objet large pour une utilisation
future avec lo_read, lo_write, lo_lseek,
lo_tell et lo_close. Le descripteur est uniquement valide pour
la durée de la transaction en cours. En cas d'échec, -1 est
renvoyé.
Actuellement, le serveur ne fait pas de distinction entre les modes
INV_WRITE et INV_READ
|
INV_WRITE : vous êtes autorisé à lire à partir du
descripteur dans les deux cas. Néanmoins, il existe une différence
significative entre ces modes et INV_READ seul : avec INV_READ, vous ne pouvez pas écrire sur le
descripteur et la donnée lue à partir de ce dernier reflètera le
contenu de l'objet large au moment où lo_open a été exécuté dans la transaction active,
quelque soient les possibles écritures par cette transaction ou par
d'autres. Lire à partir d'un descripteur ouvert avec INV_WRITE renvoie des données reflétant toutes les
écritures des autres transactions validées ainsi que les écritures
de la transaction en cours. Ceci est similaire à la différence de
comportement entre les modes de transaction SERIALIZABLE et READ
COMMITTED pour les requêtes SQL
SELECT
.
Un exemple :
inv_fd = lo_open(conn, inv_oid, INV_READ|INV_WRITE);
30.3.5. Écrire des données dans un objet large
La fonction
int lo_write(PGconn *conn, int fd, const char *buf, size_t len);
écrit
len
octets de
buf
dans le descripteur
fd
de l'objet large. L'argument
fd
doit avoir été renvoyé par
un appel précédent à lo_open. Le nombre
d'octets réellement écrits est renvoyé. Dans le cas d'une erreur,
une valeur négative est renvoyée.
30.3.6. Lire des données à partir d'un objet large
La fonction
int lo_read(PGconn *conn, int fd, char *buf, size_t len);
lit
len
octets du descripteur
de l'objet large
fd
et les
place dans
buf
. L'argument
fd
doit avoir été renvoyé par
un appel précédent à lo_open. Le nombre
d'octets réellement lus est renvoyé. Dans le cas d'une erreur, une
valeur négative est renvoyée.
30.3.7. Recherche dans un objet large
Pour modifier l'emplacement courant de lecture ou écriture associé
au descripteur d'un objet large, appelez
int lo_lseek(PGconn *conn, int fd, int offset, int whence);
Cette fonction déplace le pointeur d'emplacement courant pour le
descripteur de l'objet large identifié par
fd
au nouvel emplacement spécifié avec le
décalage (
offset
). Les valeurs
valides pour
whence
sont
SEEK_SET (rechercher depuis le début de
l'objet), SEEK_CUR (rechercher depuis
la position courante) et SEEK_END
(rechercher depuis la fin de l'objet). Le code de retour est le
nouvel emplacement du pointeur ou -1 en cas d'erreur.
30.3.8. Obtenir la position de recherche d'un objet large
Pour obtenir la position actuelle de lecture ou écriture d'un
descripteur d'objet large, appelez
int lo_tell(PGconn *conn, int fd);
S'il y a une erreur, le code de retour est négatif.
30.3.9. Fermer un descripteur d'objet large
Un descripteur d'objet large peut être fermé en appelant
int lo_close(PGconn *conn, int fd);
où
fd
est un descripteur
d'objet large renvoyé par lo_open. En cas
de succès, lo_close renvoie zéro. En cas
d'erreur, elle renvoie une valeur négative.
Tous les descripteurs d'objets larges restant ouverts à la fin
d'une transaction seront automatiquement fermés.
30.3.10. Supprimer un objet large
Pour supprimer un objet large de la base de données, appelez
int lo_unlink(PGconn *conn, Oid lobjId);
L'argument
lobjId
spécifie
l'OID de l'objet large à supprimer. Dans le cas d'une erreur, le
code de retour est négatif.