📄 lobj.sgml
字号:
<para> To remove a large object from the database, call<synopsis>int lo_unlink(PGconn *conn, Oid lobjId);</synopsis> <indexterm><primary>lo_unlink</></> The <parameter>lobjId</parameter> argument specifies the OID of the large object to remove. Returns 1 if successful, -1 on failure. </para> </sect2></sect1><sect1 id="lo-funcs"><title>Server-Side Functions</title> <para> There are server-side functions callable from SQL that correspond to each of the client-side functions described above; indeed, for the most part the client-side functions are simply interfaces to the equivalent server-side functions. The ones that are actually useful to call via SQL commands are <function>lo_creat</function><indexterm><primary>lo_creat</></>, <function>lo_create</function><indexterm><primary>lo_create</></>, <function>lo_unlink</function><indexterm><primary>lo_unlink</></>, <function>lo_import</function><indexterm><primary>lo_import</></>, and <function>lo_export</function><indexterm><primary>lo_export</></>. Here are examples of their use:<programlisting>CREATE TABLE image ( name text, raster oid);SELECT lo_creat(-1); -- returns OID of new, empty large objectSELECT lo_create(43213); -- attempts to create large object with OID 43213SELECT lo_unlink(173454); -- deletes large object with OID 173454INSERT INTO image (name, raster) VALUES ('beautiful image', lo_import('/etc/motd'));SELECT lo_export(image.raster, '/tmp/motd') FROM image WHERE name = 'beautiful image';</programlisting> </para> <para> The server-side <function>lo_import</function> and <function>lo_export</function> functions behave considerably differently from their client-side analogs. These two functions read and write files in the server's file system, using the permissions of the database's owning user. Therefore, their use is restricted to superusers. In contrast, the client-side import and export functions read and write files in the client's file system, using the permissions of the client program. The client-side functions can be used by any <productname>PostgreSQL</productname> user. </para></sect1><sect1 id="lo-examplesect"><title>Example Program</title><para> <xref linkend="lo-example"> is a sample program which shows how the large object interface in <application>libpq</> can be used. Parts of the program are commented out but are left in the source for the reader's benefit. This program can also be found in <filename>src/test/examples/testlo.c</filename> in the source distribution.</para> <example id="lo-example"> <title>Large Objects with <application>libpq</application> Example Program</title><programlisting>/*-------------------------------------------------------------- * * testlo.c-- * test using large objects with libpq * * Copyright (c) 1994, Regents of the University of California * *-------------------------------------------------------------- */#include <stdio.h>#include "libpq-fe.h"#include "libpq/libpq-fs.h"#define BUFSIZE 1024/* * importFile * import file "in_filename" into database as large object "lobjOid" * */OidimportFile(PGconn *conn, char *filename){ Oid lobjId; int lobj_fd; char buf[BUFSIZE]; int nbytes, tmp; int fd; /* * open the file to be read in */ fd = open(filename, O_RDONLY, 0666); if (fd < 0) { /* error */ fprintf(stderr, "can't open unix file %s\n", filename); } /* * create the large object */ lobjId = lo_creat(conn, INV_READ | INV_WRITE); if (lobjId == 0) fprintf(stderr, "can't create large object\n"); lobj_fd = lo_open(conn, lobjId, INV_WRITE); /* * read in from the Unix file and write to the inversion file */ while ((nbytes = read(fd, buf, BUFSIZE)) > 0) { tmp = lo_write(conn, lobj_fd, buf, nbytes); if (tmp < nbytes) fprintf(stderr, "error while reading large object\n"); } (void) close(fd); (void) lo_close(conn, lobj_fd); return lobjId;}voidpickout(PGconn *conn, Oid lobjId, int start, int len){ int lobj_fd; char *buf; int nbytes; int nread; lobj_fd = lo_open(conn, lobjId, INV_READ); if (lobj_fd < 0) { fprintf(stderr, "can't open large object %d\n", lobjId); } lo_lseek(conn, lobj_fd, start, SEEK_SET); buf = malloc(len + 1); nread = 0; while (len - nread > 0) { nbytes = lo_read(conn, lobj_fd, buf, len - nread); buf[nbytes] = ' '; fprintf(stderr, ">>> %s", buf); nread += nbytes; } free(buf); fprintf(stderr, "\n"); lo_close(conn, lobj_fd);}voidoverwrite(PGconn *conn, Oid lobjId, int start, int len){ int lobj_fd; char *buf; int nbytes; int nwritten; int i; lobj_fd = lo_open(conn, lobjId, INV_WRITE); if (lobj_fd < 0) { fprintf(stderr, "can't open large object %d\n", lobjId); } lo_lseek(conn, lobj_fd, start, SEEK_SET); buf = malloc(len + 1); for (i = 0; i < len; i++) buf[i] = 'X'; buf[i] = ' '; nwritten = 0; while (len - nwritten > 0) { nbytes = lo_write(conn, lobj_fd, buf + nwritten, len - nwritten); nwritten += nbytes; } free(buf); fprintf(stderr, "\n"); lo_close(conn, lobj_fd);}/* * exportFile * export large object "lobjOid" to file "out_filename" * */voidexportFile(PGconn *conn, Oid lobjId, char *filename){ int lobj_fd; char buf[BUFSIZE]; int nbytes, tmp; int fd; /* * open the large object */ lobj_fd = lo_open(conn, lobjId, INV_READ); if (lobj_fd < 0) { fprintf(stderr, "can't open large object %d\n", lobjId); } /* * open the file to be written to */ fd = open(filename, O_CREAT | O_WRONLY, 0666); if (fd < 0) { /* error */ fprintf(stderr, "can't open unix file %s\n", filename); } /* * read in from the inversion file and write to the Unix file */ while ((nbytes = lo_read(conn, lobj_fd, buf, BUFSIZE)) > 0) { tmp = write(fd, buf, nbytes); if (tmp < nbytes) { fprintf(stderr, "error while writing %s\n", filename); } } (void) lo_close(conn, lobj_fd); (void) close(fd); return;}voidexit_nicely(PGconn *conn){ PQfinish(conn); exit(1);}intmain(int argc, char **argv){ char *in_filename, *out_filename; char *database; Oid lobjOid; PGconn *conn; PGresult *res; if (argc != 4) { fprintf(stderr, "Usage: %s database_name in_filename out_filename\n", argv[0]); exit(1); } database = argv[1]; in_filename = argv[2]; out_filename = argv[3]; /* * set up the connection */ conn = PQsetdb(NULL, NULL, NULL, NULL, database); /* check to see that the backend connection was successfully made */ if (PQstatus(conn) == CONNECTION_BAD) { fprintf(stderr, "Connection to database '%s' failed.\n", database); fprintf(stderr, "%s", PQerrorMessage(conn)); exit_nicely(conn); } res = PQexec(conn, "begin"); PQclear(res); printf("importing file %s\n", in_filename);/* lobjOid = importFile(conn, in_filename); */ lobjOid = lo_import(conn, in_filename);/* printf("as large object %d.\n", lobjOid); printf("picking out bytes 1000-2000 of the large object\n"); pickout(conn, lobjOid, 1000, 1000); printf("overwriting bytes 1000-2000 of the large object with X's\n"); overwrite(conn, lobjOid, 1000, 1000);*/ printf("exporting large object to file %s\n", out_filename);/* exportFile(conn, lobjOid, out_filename); */ lo_export(conn, lobjOid, out_filename); res = PQexec(conn, "end"); PQclear(res); PQfinish(conn); exit(0);}</programlisting></example></sect1></chapter><!-- Keep this comment at the end of the fileLocal variables:mode:sgmlsgml-omittag:nilsgml-shorttag:tsgml-minimize-attributes:nilsgml-always-quote-attributes:tsgml-indent-step:1sgml-indent-data:tsgml-parent-document:nilsgml-default-dtd-file:"./reference.ced"sgml-exposed-tags:nilsgml-local-catalogs:("/usr/lib/sgml/catalog")sgml-local-ecat-files:nilEnd:-->
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -