Firebird 1.5 and BLOB (as text)

Forum related to version 6.5.1 (alpha) and 6.6.x (beta) of ZeosLib's DBOs

Moderators: gto, cipto_kh, EgonHugeist

Post Reply
gto
Zeos Dev Team
Zeos Dev Team
Posts: 278
Joined: 11.11.2005, 18:35
Location: Porto Alegre / Brasil

Firebird 1.5 and BLOB (as text)

Post 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!? :shock:
Use the FU!!!!!IN Google !

gto's Zeos Quick Start Guide

Te Amo Taís!
DavidVTaylor
Zeos Dev Team
Zeos Dev Team
Posts: 13
Joined: 04.02.2006, 05:34
Location: Virginia
Contact:

Post 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
gto
Zeos Dev Team
Zeos Dev Team
Posts: 278
Joined: 11.11.2005, 18:35
Location: Porto Alegre / Brasil

Post by gto »

Yeah! Works like a charm :thanks:

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;
Use the FU!!!!!IN Google !

gto's Zeos Quick Start Guide

Te Amo Taís!
User avatar
mdaems
Zeos Project Manager
Zeos Project Manager
Posts: 2766
Joined: 20.09.2005, 15:28
Location: Brussels, Belgium
Contact:

Post 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
Post Reply