Welcome

首页 / 软件开发 / Delphi / 第二十章-开发Delphi对象式数据管理功能(二)(4)

第二十章-开发Delphi对象式数据管理功能(二)(4)2007-05-072. Read和Write方法的实现

Read和Write方法都调用BDE API函数完成数据库BLOB字段的读写,其实现如下:

function TBlobStream.Read(var Buffer; Count: Longint): Longint;

var

Status: DBIResult;

begin

Result := 0;

if FOpened then

begin

Status := DbiGetBlob(FDataSet.Handle, FRecord, FFieldNo, FPosition,

Count, @Buffer, Result);

case Status of

DBIERR_NONE, DBIERR_ENDOFBLOB:

begin

if FField.FTransliterate then

NativeToAnsiBuf(FDataSet.Locale, @Buffer, @Buffer, Result);

Inc(FPosition, Result);

end;

DBIERR_INVALIDBLOBOFFSET:

{Nothing};

else

DbiError(Status);

end;

end;

end;

Read方法使用了BDE API的DbiGetBlob函数从FDataSet中读取数据,在本函数中,各参数的含义是这样的:FDataSet.Handle代表DataSet的BDE句柄,FReacord表示BLOB字段所在记录,FFieldNo表示BLOB字段号,FPosition表示要读的的数据的起始位置,Count表示要读的字节数,Buffer是读出数据所占的内存,Result是实际读出的字节数。该BDE函数返回函数调用的错误状态信息。

Read方法还调用了NativeToAnsiBuf进行字符集的转换。

function TBlobStream.Write(const Buffer; Count: Longint): Longint;

var

Temp: Pointer;

begin

Result := 0;

if FOpened then

begin

if FField.FTransliterate then

begin

GetMem(Temp, Count);

try

AnsiToNativeBuf(FDataSet.Locale, @Buffer, Temp, Count);

Check(DbiPutBlob(FDataSet.Handle, FRecord, FFieldNo, FPosition,

Count, Temp));

finally

FreeMem(Temp, Count);

end;

end else

Check(DbiPutBlob(FDataSet.Handle, FRecord, FFieldNo, FPosition,

Count, @Buffer));

Inc(FPosition, Count);

Result := Count;

FModified := True;

end;

end;

Write方法调用了BDE API的DbiPutBlob函数实现往数据库BLOB字段存储数据。

该函数的各参数含义如下:

表20.2 调用函数DbiPutBlob的各传入参数的含义

━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

参数名 含义

──────────────────────────────

FDataSetHandle 写入的数据库的BDE句柄

FRecord 写入数据的BLOB字段所在的记录

FFieldNo BLOB字段号

FPosition 写入的起始位置

Count 写入的数据的字节数

Buffer 所写入的数据占有的内存地址

━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

方法中还根据FField和FTransliterate的值判断是否进行相应的字符集转换,最后移动BLOB流的位置指针,并将修改标志FModified置为True。

3. Seek和GetBlobSize方法的实现

Seek方法的功能主要是移动BLOB流的位置指针。GetBlobSize方法是私有的,在Seek方法中被调用,其功能是得到BLOB数据的大小。它们的实现如下:

function TBlobStream.GetBlobSize: Longint;

begin

Result := 0;

if FOpened then

Check(DbiGetBlobSize(FDataSet.Handle, FRecord, FFieldNo, Result));

end;

function TBlobStream.Seek(Offset: Longint; Origin: Word): Longint;

begin

case Origin of

0: FPosition := Offset;

1: Inc(FPosition, Offset);

2: FPosition := GetBlobSize + Offset;

end;

Result := FPosition;

end;

GetBlobSize调用了BDE API的DbiGetBlobSize函数,该函数的参数的含义同前面的API函数相同。