9.3 9.4 9.5 9.6 10 11 12 13 14 15 Current(16) 17
问题报告 纠错本页面
35.5. 例子程序
上一页 上一级 第 35 章 大对象起始页 下一页

35.5. 例子程序

例 35.1是一个展示libpq中大对象接口如何使用的例子程序。部分程序被注释但仍保留在代码中,用户可以利用之。该程序可以在源代码的src/test/examples/testlo.c中找到。

例 35.1. 用libpq操作大对象的例子程序

/*-----------------------------------------------------------------
 *
 * testlo.c
 * 测试通过libpq实用大对象
 *
 * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group
 * Portions Copyright (c) 1994, Regents of the University of California
 *
 *
 * IDENTIFICATION
 * src/test/examples/testlo.c
 *
 *-----------------------------------------------------------------
 */
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include "libpq-fe.h"
#include "libpq/libpq-fs.h"
#define BUFSIZE 1024
/*
 * importFile -
 * 把文件 "in_filename" 作为一个大对象 "lobjOid" 载入到数据库
 *
 */
static Oid
importFile(PGconn *conn, char *filename)
{
 Oid lobjId;
 int lobj_fd;
 char buf[BUFSIZE];
 int nbytes,
 tmp;
 int fd;
 /*
 * 打开要读入的文件
 */
 fd = open(filename, O_RDONLY, 0666);
 if (fd < 0)
 { /* error */
 fprintf(stderr, "cannot open unix file\"%s\"\n", filename);
 }
 /*
 * 创建大对象
 */
 lobjId = lo_creat(conn, INV_READ | INV_WRITE);
 if (lobjId == 0)
 fprintf(stderr, "cannot create large object");
 lobj_fd = lo_open(conn, lobjId, INV_WRITE);
 /*
 * 从该 Unix 文件读取并写入到大对象
 */
 while ((nbytes = read(fd, buf, BUFSIZE)) > 0)
 {
 tmp = lo_write(conn, lobj_fd, buf, nbytes);
 if (tmp < nbytes)
 fprintf(stderr, "error while reading \"%s\"", filename);
 }
 close(fd);
 lo_close(conn, lobj_fd);
 return lobjId;
}
static void
pickout(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, "cannot open large object %u", 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] = '0円';
 fprintf(stderr, ">>> %s", buf);
 nread += nbytes;
 if (nbytes <= 0)
 break; /* no more data? */
 }
 free(buf);
 fprintf(stderr, "\n");
 lo_close(conn, lobj_fd);
}
static void
overwrite(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, "cannot open large object %u", lobjId);
 lo_lseek(conn, lobj_fd, start, SEEK_SET);
 buf = malloc(len + 1);
 for (i = 0; i < len; i++)
 buf[i] = 'X';
 buf[i] = '0円';
 nwritten = 0;
 while (len - nwritten > 0)
 {
 nbytes = lo_write(conn, lobj_fd, buf + nwritten, len - nwritten);
 nwritten += nbytes;
 if (nbytes <= 0)
 {
 fprintf(stderr, "\nWRITE FAILED!\n");
 break;
 }
 }
 free(buf);
 fprintf(stderr, "\n");
 lo_close(conn, lobj_fd);
}
/*
 * exportFile -
 * 把大对象 "lobjOid" 导出成文件 "out_filename"
 *
 */
static void
exportFile(PGconn *conn, Oid lobjId, char *filename)
{
 int lobj_fd;
 char buf[BUFSIZE];
 int nbytes,
 tmp;
 int fd;
 /*
 * 打开大对象
 */
 lobj_fd = lo_open(conn, lobjId, INV_READ);
 if (lobj_fd < 0)
 fprintf(stderr, "cannot open large object %u", lobjId);
 /*
 * 打开要写入的文件
 */
 fd = open(filename, O_CREAT | O_WRONLY | O_TRUNC, 0666);
 if (fd < 0)
 { /* 错误 */
 fprintf(stderr, "cannot open unix file\"%s\"",
 filename);
 }
 /*
 * 从大对象读入并写出到 Unix 文件
 */
 while ((nbytes = lo_read(conn, lobj_fd, buf, BUFSIZE)) > 0)
 {
 tmp = write(fd, buf, nbytes);
 if (tmp < nbytes)
 {
 fprintf(stderr, "error while writing \"%s\"",
 filename);
 }
 }
 lo_close(conn, lobj_fd);
 close(fd);
}
static void
exit_nicely(PGconn *conn)
{
 PQfinish(conn);
 exit(1);
}
int
main(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];
 /*
 * 设置连接
 */
 conn = PQsetdb(NULL, NULL, NULL, NULL, database);
 /* 检查看看后端连接是否成功建立 */
 if (PQstatus(conn) != CONNECTION_OK)
 {
 fprintf(stderr, "%s", PQerrorMessage(conn));
 exit_nicely(conn);
 }
 /* 设置总是安全的搜索路径,这样恶意用户就无法取得控制权。 */
 res = PQexec(conn,
 "SELECT pg_catalog.set_config('search_path', '', false)");
 if (PQresultStatus(res) != PGRES_TUPLES_OK)
 {
 fprintf(stderr, "SET failed: %s", PQerrorMessage(conn));
 PQclear(res);
 exit_nicely(conn);
 }
 PQclear(res);
 res = PQexec(conn, "begin");
 PQclear(res);
 printf("importing file \"%s\" ...\n", in_filename);
/* lobjOid = importFile(conn, in_filename); */
 lobjOid = lo_import(conn, in_filename);
 if (lobjOid == 0)
 fprintf(stderr, "%s\n", PQerrorMessage(conn));
 else
 {
 printf("\tas large object %u.\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); */
 if (lo_export(conn, lobjOid, out_filename) < 0)
 fprintf(stderr, "%s\n", PQerrorMessage(conn));
 }
 res = PQexec(conn, "end");
 PQclear(res);
 PQfinish(conn);
 return 0;
}

上一页 上一级 下一页
35.4. 服务器端函数 起始页 第 36 章 ECPG — C中的嵌入式 SQL

AltStyle によって変換されたページ (->オリジナル) /