1、EDBS简介
——基于TRIP数据库系统的电子文档的建库操作
Introduction to Creation of E-files DataBase System in TRIP
2009-12-04
文本数据的大批量装入TRIP数据库问题, TRIP系统已经提供有现成的TDBS(Text DataBase System)解决方案,只要把待装入的数据生成tform格式的文本文件,然后,或则调用、运行load/loadix程序,或则进入TRIP系统通过后台菜单操作,即可将大批的数据倒入进TRIP系统。对于电子格式文档(E-formatted Files),如Word、PDF、PPT…
2、 TRIP亦提供现成的开发平台——TRIPview,据此用户可以开发出自己的电子文档数据库系统(EDBS),在把电子文档装入数据库的一个string字段的同时,还将文档中的文字内容抽取出来放在一个文本text字段,进行倒排处理,以实现对全文内容的快速查找,并显示出原有的文件格式。
利用TRIPview来建立用户自己的EDBS系统需要一定的开发量。若对原文的内容需要进行查找的应用,TRIPview是最好的选择,目前它可以处理多达220多种格式的电子文档。如果对原文内容不需要进行查找(例如是jpg、gif等无文字内容的电子文件),亦即不需对原文件抽取文字内容的情况,则不必用TRIPview而
3、是利用TRIPtoolkit提供开发工具开发简单的应用程序,就可以将它们写进TRIP记录中的string字段。下面介绍两种如何把电子文件写入TRIP数据库的方法,一种属于B/S方式,通过浏览器将一个或多个图片文件,一次一个记录的装进本地或远程的TRIP数据库,另一种是在TRIP服务器端(Server-side)批量的将文件写入TRIP数据库。前者通过CGI(公共网关接口)程序调用TRIPtoolkit,后者直接访问TRIP底层,两者均用标准C语言开发,效率相当高。最后介绍如何利用CGI程序对已有的记录,添加新的电子文件或者替换旧有的的文件。
数据库的字段约定(Conventions)
与文
4、字数据不同,一个电子文件存放在TRIP数据库记录中时,少则需两个字段多则需四个字段来描述。少则者一:存放文件名的词组phrase字段,二:存放全部文件内容信息的string字段。多则者第三:存文件大小的数值int字段,第四:存放从原格式文件抽取出来的文字内容的文本text字段。
鉴于程序访问TRIP时往往是通过字段号来定位的,本文介绍的程序对上述的文件名字段、文件大小字段以及string字段的段号安排均作了如下约定:如果文件名字段号取n的话,文件大小字段号则为n+1,string字段号则为n+2。因此用户在利用本程序进行数据库字段设计时务必遵循这一约定,否则程序不能正常运行。对于已经有内容的
5、数据库,如果字段顺序不符合本约定,必须预先把数据库设计改变过来,才能使用此处介绍的程序继续给TRIP数据库追加电子文档。至于原先的数据(假定还没有string字段的数据),需要编写一个输出格式把它生成tform文件,然后再装入结构已经更新的数据库。
一、 B/S模式的EDBS建库方法
通过浏览器的上传表单和Web服务器上的cgi程序upload,将本地数据(包括文字及二进制文件)装入Web服务器所在的TRIP数据库。每次只能上传、建成一个记录。要做的准备工作是:
制作上传表单;
修改上传配置文件upload.cfg;
设置权限。
1、制作上传表单
上传表单是一个HTML文件,
6、它可以从现用的上传文件复制、修改而成。它不仅用作录入数据的界面,即工作单,还用来控制上传的数据的走向,包括存入到库里的哪些字段,以及上传文件将存放在什么地方:是直接进入字段?还是存放在哪一个目录下。上传表单中有几行是专作上传控制用的,再有若干行作录入数据 用。
命名 表单名最好与库名相同,这样给不同的数据库上传可采用不同的表单,实现各个库各自独特的设置要求。如上传的数据要写入TRIP的bch库,则上传表单名可定为bch.html。该表单放在web服务器的文件根目录下(在Linux Apach服务器情况下,…/www/html/ 往往被设置成web文件的根目录)。如下以bch.html为例对
7、上传表单作一简要说明。
控制行 带有“hidden”标签的value值,是控制上传行为用的:
Base值指定给哪个数据库上传,没有它则不知装给哪个数据库。
DocRoot定义上传文件将存放的目录,后面一定要用斜线结尾,否则文件将放在上一个目录,而上传文件名字也将改变。如无DocR
8、oot的内容,上传文件将放在upload.cfg设定的目录。
WriteStr这行设置上传的文件要写进TRIP数据库的STRING字段,其value可不设定,只要有name=WriteStr的这一行,上传来的文件就会写入STRING字段中。若无此行,文件将存放在前述(DocRoot或upload.cfg中root)指定的目录中,并不写入TRIP数据库。
如果需要记录上传的时间,则需加上如下一行:
其中,name=date 表示要把上传的时间记录在数据库中编号为n的字段,当然设计数据库时要设立这
9、字段,其字段名可随意定,程序会自动把上传的时间写入n字段中。
数据录入行
数据录入行将决定用户录入的数据将存到哪一个字段。录入的数据包括两种,一种是通过屏幕直接录入到TRIP字段中的文字数据,这包括文本字段、词组字段、数字、日期、时间等,第二种是录入想要上传文件的文件名。
文字数据字段录入行按照如下配置:
字段的name必须是^nf。此处n为数据库结构中该“字段名”的编号。注意这里并不用库中的字段名,而用字段号。在TRIP库中,一旦库结构被设计好后,字段名还是可以改变的,字段号就不能改。所以这里用字段
10、号作name。
上传文件名字段的配置是:
上述配置用于输写上传文件的文件名。上传文件在本地的路径及文件名将被上传到TRIP服务器,并存放在字段编号为m的phrase字段中。注意,上传表单的类型file和TRIP数据库的字段类型不是一回事, 前者,是告诉HTTP要用file传输协议,后者是TRIP数据库中存放上传来的文件名的字段。上传表单上的字段号m一旦被设定,将涉及到另外两个TRIP字段的设计。第一个是紧接着字段号m之后的m+1字段,它用于存放文件的大小,字段数据类型需为数值num型。再下一个编号是m+2
11、的字段,将存放上传文件的真正内容,类型为STRING。在设计TRIP数据库结构时,上述三个字段的字段名可以随意设定,但字段的编号必须按照上述m, m+1, m+2的规则,这种约定是由上传程序upload规定的。
上传表单(工作单)样例
假定制作的表单要给BCH数据库的文字字段1、2、3、4、5、6、9写数据,还要上传原格式文件(文件名字段是15), 那么设计成如下布局的表单即可:
上述布局工作单的html代码如下:
12、
2、修改上传配置文件upload.cfg
该文件放在cgi-bin的目录下,其名称必须和上传程序upload同名。亦即上传程序upload和配置文件upload.cfg是一一对应的,否则将出错。上传配置文件主要用
16、来控制谁允许上传,上传数据放在什么地方,要不要把上传文件写入TRIP数据库。内容如下:
Config = Default
Root = /data/
FileMask = *
IgnoreSubdirs = YES
OverWrite = yes
WriteStrField = no
OkPage = OkPage.html
BadPage = BadPage.html
Debug = 0
IP =
17、 168.160.111.111中信所
IP = 168.160.222.222化工信息
IP =
此处也有root行和WriteStrField行。但它们只是上传表单的备用设置行,上传表单的设置优先。即上传表单已经设置过了的话,此处的设置则不起作用;上传表单上没有设置,则用此处的值。Upload程序要调用的OkPage.html 和 BadPage.html 文件放在cgi-bin 目录下。
IP行是控制上传工作站用的。只有此处列有的IP地址工作站才允许上传数据。
如果从cgi-bin目录下的upload 中考贝生成另
18、外一个名为upl的程序,同样放在cgi-bin目录下,用来上传文件给mybase数据库,那么配置文件名应该取名upl.cfg。上传表单的文件名改动与否均可,但其中的
程序名upload 必须取名upl,以便调用upl程序, 同时在 中的base 值应改为mybase,这是告诉upl要与数据库mybase打交道。
3、权限设置
此处涉及三个地方的权限设置。
3.1 目录 上传程序首先将上传的文件存放在由上传表单中的 DocRoot 指定的磁19、盘目录下,或者是由upload.cfg配置文件中root指定的目录下,因此该目录必须对web程序执行者赋予写的权限,否则文件将存不下来。web程序的执行者是谁,要有httpd.conf文件中的定义而定,例如httpd, nobody, apache或者是对web程序的执行者所在的小组。
3.2 数据库 上传程序用了名叫 tripnet 的TRIP用户去访存TRIP系统。因此用户要上传的目标数据库必须给tripnet授予写的权限,否则上传的数据不会被TRIP系统接受。
3.3 数据库文件 数据写入TRIP数据库是由web程序通过TRIP的授权用户tripnet进行的。web程序执
20、行者(如httpd)或者它所属的小组必须能够对该数据库的三个文件有写的权限。否则由于Unix的写保护,录入的数据将写不进TRIP数据库中。
上传C程序 upload.c的关键语句
上传的数据分两部分,一是文字的、能用ASCII字符表示的,如各个字段的文字信息,包括上传文件名,文件大小等等,这些数据要形成tform格式,因为文字信息进入TRIP数据库最后都得通过tform文件的格式。另一部分是上传的文件,它将在服务器端临时存成一个文件。Tform格式的文字信息要么用通过TRIP的菜单、要么通过系统命令loadix装入TRIP系统,或者通过程序写入。用C程序upload.c写入时,关键语句如下
21、
TdbSetBase (rec_ctl, BaseName, 2); // 将数据库设置成可以写入
TdbSetCursor (&Cursor, rec_ctl, 0, 0, 0); // 把写指针指向整个记录
TdbPutRecordBuffer (Cursor, TformBuf, BufLen, &ErrPartNo, &ErrFieldNo, &ErrItemNo);
// 上面这一句将待写入的记录与将待写入的tform数据关联起来
TdbSetCursor (&Cursor,
22、 rec_ctl, FieldNo, 0,0)); // 把写指针指向记录特定的string字段
TdbImportBlob(Cursor, Path)); // 把指针和待写入的文件(地址+文件名)关联起来
TdbPutRecord (rec_ctl, &Rid);
最后这一语句才是真正执行把tform格式的文字信息和上传的文件写入数据库。Rid返回的是被写入的记录号。
二、 批量EDBS数据处理
在记录中已经有文字内容,但string字段还是空的,或者是string字段虽有内容但需补充或修改的情况下,就要利用程序loadef
23、Loading E-files)来批量地给现有的记录装入电子文件。loadef程序放在cgi-bin 目录下,要用时可以把它拷贝到工作目录中。
程序要求的参数
loadef是用C语言编写的TRIP应用程序,运行时必须附带3个参数,用法是:
loadef base_name TF_filename Y|N
2.1 第一参数: base_name
数据库名,指要往哪一个数据库追加电子文件。
2.2 第二参数:TF_filename
批次处理文件名。该文件包含一行行如下所示的tform格式的内容:
5R^16F/粮食作物/水稻病害/水稻恶苗病/水稻恶苗病1.JPG
24、^
5R^23F/粮食作物/水稻病害/水稻恶苗病/水稻恶苗病2.JPG^
5R^30F/粮食作物/水稻病害/水稻恶苗病/水稻恶苗病3.JPG^
5R^37F/粮食作物/水稻病害/水稻恶苗病/水稻恶苗病4.JPG^
上述每一行标识装入一个电子文件,第一行是把“水稻恶苗病1.JPG”作为文件名写入记录5的16字段,第二行是把“水稻恶苗病2.JPG” 作为文件名写入记录5的23字段,如此类推…。Loadef会自动把电子文件名前面的目录名丢弃,只取文件名本身。同时,程序loadef在对每一行执行操作时会把二进制文件的大小和内容分别写进相对应的数值型字段(17、24、31、38)及string型
25、字段(18、25、32、39)。
注意,TF_filename文件以及文件中每行所标示的电子文件必须与loadef程序处于同一目录,否则将出现找不着文件的错误。
2.3 第三参数:Y|N
原有的名可能带有一系列的目录名称,选此参数为Y表示用现有的文件名去替换原有的数据;选N时表示不覆盖原有数据,而是将现有的文件名加在原有文件的末尾,彼此用“|”号隔开。
TF_filename 的生成
为避免编辑引起的错误,loadef程序所需的TF_filename应从base_name所指的数据库中通过输出格式生成。以数据库BCHLL为例,所需的输出格式列举如下:
<
26、),1 R^F>
dt1name dt2name dt3name dt4name dt5name
dt6name dt7name dt8name dt9name dt10name
>
>
上面输出格式将每一字段(即每个文件名)输出一行。格式的第一行将形成: 记录号R^字段号F; 第二行是每个字段结束时写^;第三、四行表示输出字段内容(文件名),只要所列的字段有文件名存在,便(连同第一、二行)输出数据,如果没有内容,第一、二行也不输出。该格式可拷贝给别的数据库, 用于其他数据库时,只需更换第三、四
27、行的电子文件名称即可。
Loadef.c程序的关键语句
loadef是C语言程序,除了启动TRIP,打开数据库等通用的语句外不再赘述外,特列出如何插入新的图片的语句:
TdbGetRecordInBase (rec_ctl, rid); //锁定要插入图片的记录
TdbCheckField (rec_ctl, fieldname, &FieldNo, &type, &flg);
if ((strstr(argv[3], "Y")) || (strstr(argv[3], "y"))){ //覆盖原有的图片名和写入图片大小
sprintf(
28、TformBuf, "^%dF^0F%s^%dF%s^", FieldNo, filename, FieldNo+1, fsize);
}else{ //在原有的图片名后写入新的图片名和写入图片大小
sprintf(TformBuf, "^%dF|%s^%dF%s^", FieldNo, filename, FieldNo+1, fsize); }
BufLen=strlen(TformBuf); // 量出tform数据的长度
TdbSetCursor (&
29、Cursor, rec_ctl, 0, 0,0)); // 把写指针指向整个记录,以下面这条命令把tform格式数据写入库
TdbPutRecordBuffer(Cursor, TformBuf, BufLen, &ErrPartNo, &ErrFieldNo, &ErrItemNo));
TdbSetCursor (&Cursor, rec_ctl, FieldNo+2, 0,0)); // 把写指针指向整个string字段
TdbImportBlob(Cursor, filename)); // 将上传来的图形文件与指针联系起来 (
30、尚未写入)
TdbPutRecord (rec_ctl, &rid)); // 正式输入图形数据内容
三、 通过浏览器修改已有的记录
前面介绍的B/S模式的EDBS建库方法只能每上传一次便生成一个新的记录,而批量EDBS数据处理方法又是针对批量记录的,而且必须登录到服务器去执行命令行程序。假如要对现有个别记录的某些字段添加新的数据,特别是添加图片,则也可以通过浏览器,即采用B/S的工作模式调用CGI程序来实现。为此目的,要在上传表单上增加如下一行标签,用于人工输入待修改记录的记录号:
RecordNo: 31、nput name=recordid value=>
上面的标签名recordid将告诉上传程序upload,上传来的数据是属于recordid指定的记录,而非去生成新的记录。因此,程序upload在遇到有recordid值时,在写数据之前,先按照这个记录号去数据库中锁定该记录,然后再把传上来的数据写进去,如果上传表单中没有recordid值,程序无法去锁定已存在的记录,便自动当作新记录来处理。但目前程序只能对图片文件实现添加、替换,而对文字字段只能添加,不能替换,亦即新的数据将写入下一个子字段(phrase字段),或追加到数据的末尾(text字段)。如果要替换,需要生成的tform格式文
32、件必须能够将现有数据先行清除,然后再插入,例如,要对第20字段的数据先删后加上“New information”的tform格式是: ^20f^0fNew information^。
Upload.c程序相关语句:
TdbSetBase (rec_ctl, BaseName, 2); // 将数据库设置成可以写入
if ((stricmp(FieldName, "recordid") == 0) Rid=atoi(ContentAsString); //判定若有recordid,则取出记录号Rid
if (Rid) TdbGetRecordInBase (
33、rec_ctl, Rid); // 按给定记录号锁定记录;若不锁定,下句视为插入新记录
TdbSetCursor (&Cursor, rec_ctl, 0, 0, 0); // 把指针指向整个记录
TdbPutRecordBuffer (Cursor, TformBuf, BufLen, &ErrPartNo, &ErrFieldNo, &ErrItemNo));
// 上面这一句将待写入的记录与将待写入的tform数据关联起来
TdbSetCursor (&Cursor, rec_ctl, FieldNo, 0,0)); // 把写指针指向记录特定的string字段
TdbImportBlob(Cursor, Path)); // 把指针和待写入的文件(地址+文件名)关联起来
TdbPutRecord (rec_ctl, &Rid); // 最后将ASCII和电子文件写入TRIP数据库