Page 1 of 1
Firebird 1.5 and BLOB (as text)
Posted: 09.03.2006, 20:34
by gto
Hallo =)
here I'm, again and again
Today, my problem is with BLOB type (firebird 1.5)
Every time that I post a text to my BlobField (subtype :1 - text, BlobType: ftMemo) through a DbMemo, FastMM4 reports it as leaked memory (all the text from the DbMemo).
I tried to go deep into zeos code, but wasn't found anything good.
Some idea!?
Posted: 24.03.2006, 01:59
by DavidVTaylor
The leak is caused by a known bug in ZDbcInterbase6Utils. The problem is in the WriteBlob(const Index: Integer; Stream: TStream) of TZParamsSQLDA.
If you are feeling adventurous, the fix is simply to add a try finally block and a call to FreeMem as shown below:
.....
.....
Buffer := AllocMem(BlobSize);
try
Stream.ReadBuffer(Buffer^, BlobSize);
{ put data to blob }
CurPos := 0;
.....
.....
.....
Stream.Seek(0, 0);
UpdateQuad(Index, BlobId);
finally
FreeMem(Buffer); <-- Fix is here
end;
.....
.....
I have used this fix in production code for several months so I know it works properly.
Hopes this helps,
David
Posted: 24.03.2006, 13:48
by gto
Yeah! Works like a charm
I'm posting the procedure here, if someone want copy it:
Code: Select all
procedure TZParamsSQLDA.WriteBlob(const Index: Integer; Stream: TStream);
var
Buffer: PChar;
BlobId: TISC_QUAD;
BlobHandle: TISC_BLOB_HANDLE;
StatusVector: TARRAY_ISC_STATUS;
BlobSize, CurPos, SegLen: Integer;
begin
BlobHandle := nil;
Stream.Seek(0, 0);
{ create blob handle }
FPlainDriver.isc_create_blob2(@StatusVector, FHandle, FTransactionHandle,
@BlobHandle, @BlobId, 0, nil);
CheckInterbase6Error(FPlainDriver, StatusVector);
Stream.Position := 0;
BlobSize := Stream.Size;
Buffer := AllocMem(BlobSize);
try
Stream.ReadBuffer(Buffer^, BlobSize);
{ put data to blob }
CurPos := 0;
SegLen := DefaultBlobSegmentSize;
while (CurPos < BlobSize) do
begin
if (CurPos + SegLen > BlobSize) then
SegLen := BlobSize - CurPos;
if FPlainDriver.isc_put_segment(@StatusVector, @BlobHandle, SegLen,
PChar(@Buffer[CurPos])) > 0 then
CheckInterbase6Error(FPlainDriver, StatusVector);
Inc(CurPos, SegLen);
end;
{ close blob handle }
FPlainDriver.isc_close_blob(@StatusVector, @BlobHandle);
CheckInterbase6Error(FPlainDriver, StatusVector);
Stream.Seek(0, 0);
UpdateQuad(Index, BlobId);
finally
FreeMem(Buffer);
end;
end;
Posted: 19.04.2006, 00:28
by mdaems
Hi,
Added this small bugfix to the testing branch of theSVN repository. Can you please check if this works the way you expected? I don't use interbase and only compiled in D7 and Lazarus.
So, please test and report.....
Mark