Chinaunix首页 | 论坛 | 博客
  • 博客访问: 205333
  • 博文数量: 21
  • 博客积分: 1546
  • 博客等级: 上尉
  • 技术积分: 290
  • 用 户 组: 普通用户
  • 注册时间: 2006-10-10 14:54
文章分类

全部博文(21)

文章存档

2020年(1)

2019年(3)

2015年(2)

2014年(1)

2011年(1)

2009年(7)

2008年(4)

2007年(2)

我的朋友

分类:

2008-03-01 10:53:43

在postgresql的8.2后,加了一个函数pg_read_file,可以读取服务器上的文件返回给客户端。
 
该文件返回类型为TEXT类型,所以只能读取文本文件,对于二进制文件或者字符集与数据库默认字符集不兼容的文本文件,所读的数据将被截断。
 
如何能读二进制文件,返回bytea类型呢?经源代码分析,该函数的内置函数其实是可以读取二进制的,只是接口被转化为文本类型,而在PG内部TEXT型和BYTEA类型的指针结构是一样的。
 
所以可以自定义函数
CREATE OR REPLACE FUNCTION "public"."pg_read_file_binary" (text, bigint, bigint) RETURNS bytea AS
'pg_read_file'
LANGUAGE 'internal' VOLATILE CALLED ON NULL INPUT SECURITY INVOKER;
 
该函数就可以返回二进制函数了,也可以用CONVERT转化为自己需要的文本类型.
在具体应用中,如在数据主目录下建立一个graph目录,可以通过SQL语句下载该目录下的图形文件。
 
安全问题
本函数必须为超级用户(或授权超级角色的用户)才能使用。且只能读取数据主目录下的文件。
 
让普通用户拥有超级权限,是危险的。同时让用户不加选择的可以读取数据目录下的任何文件,也是危险的。
 
最好的方法是,让普通用户只读取某个特定目录下的文件。所以再建立一个函数
CREATE OR REPLACE FUNCTION "public"."pg_read_file_binary_s" (S_FILE text, I_SEEK bigint, I_LENGTH bigint) RETURNS bytea AS
$BODY$
DECLARE
    I BIGINT; 
BEGIN
    IF I_LENGTH=0 then  -- 获取文件的长度
       I=(pg_stat_file(S_FILE)).size;
    else
       i=i_length;
    endif
    IF substr(S_FILE,0,5)<>'graph'
       raise exception '只能读取graph目录';
    end if;
    return pg_read_file_binary(s_file,i_seek,i);
END
$BODY$
LANGUAGE 'plpgsql' VOLATILE CALLED ON NULL INPUT SECURITY DEFINER;
 
 
注意用超级用户建立该函数,并且将security设为definer.
 
则普通用户只用在调用该函数时会拥有超级权限,且该函数中已经进行了些限制.
 
阅读(4171) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~