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.
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);
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.
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.
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);
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.
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.
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.
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.
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.
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.