[patch_done] Patch for TZOracleBlob.ReadBlob

Code patches written by our users to solve certain "problems" that were not solved, yet.

Moderators: gto, cipto_kh, EgonHugeist, mdaems

Post Reply
ymarenne
Fresh Boarder
Fresh Boarder
Posts: 4
Joined: 02.09.2009, 14:01
Location: Namur

[patch_done] Patch for TZOracleBlob.ReadBlob

Post by ymarenne »

Hello,

I have a memory leak when i read a lob field on oracle

To fix the leak, I have add

Code: Select all

ReadStream.Free;


at the end of the procedure
User avatar
mdaems
Zeos Project Manager
Zeos Project Manager
Posts: 2766
Joined: 20.09.2005, 15:28
Location: Brussels, Belgium
Contact:

Post by mdaems »

Thanks, but can you be more specific about the exact location (eg add the full procedure or a significant part of it. Don't forget to name the procedure name. I can't test against Oracle, so I have to trust what you tell me.

Mark
Image
ymarenne
Fresh Boarder
Fresh Boarder
Posts: 4
Joined: 02.09.2009, 14:01
Location: Namur

Post by ymarenne »

The procedure is located on ZDbcOracleResultSet.pas file

Code: Select all

procedure TZOracleBlob.ReadBlob;
var
  Status: Integer;
  Buffer: array[0..1024] of Char;
  ReadNum, Offset: ub4;
  ReadStream: TMemoryStream;
  Connection: IZOracleConnection;
begin
  if not Updated and (FLobLocator <> nil)
    and (BlobData = nil) and (not FTemporary) then
  begin
    Connection := FHandle as IZOracleConnection;

    { Opens a large object or file for read. }
    Status := FPlainDriver.LobOpen(Connection.GetContextHandle,
      Connection.GetErrorHandle, FLobLocator, OCI_LOB_READONLY);
    CheckOracleError(FPlainDriver, Connection.GetErrorHandle,
      Status, lcOther, 'Open Large Object');

    { Reads data in chunks. }
    ReadStream := TMemoryStream.Create;
    Offset := 0;
    repeat
      ReadNum := 1024;
      Status := FPlainDriver.LobRead(Connection.GetContextHandle,
        Connection.GetErrorHandle, FLobLocator, ReadNum, Offset + 1,
        @Buffer, 1024, nil, nil, 0, SQLCS_IMPLICIT);
      CheckOracleError(FPlainDriver, Connection.GetErrorHandle,
        Status, lcOther, 'Read Large Object');
      if ReadNum > 0 then
      begin
        ReadStream.SetSize(ReadStream.Size + ReadNum);
        ReadStream.Write(Buffer, ReadNum);
        Inc(Offset, 1024);
      end;
    until ReadNum < 1024;

    { Closes large object or file. }
    Status := FPlainDriver.LobClose(Connection.GetContextHandle,
      Connection.GetErrorHandle, FLobLocator);
    CheckOracleError(FPlainDriver, Connection.GetErrorHandle,
      Status, lcOther, 'Close Large Object');

    { Assigns a retrieved data stream. }
    ReadStream.Position := 0;
    SetStream(ReadStream);

    ReadStream.Free; // <---Here

  end;
end;
Ask for more precision if needed
User avatar
mdaems
Zeos Project Manager
Zeos Project Manager
Posts: 2766
Joined: 20.09.2005, 15:28
Location: Brussels, Belgium
Contact:

Post by mdaems »

Bon soir,

This was precise enough, thanks :mrgreen:

SVN Rev. 684 (testing branch)

This will move to 6.6-patches too.

Mark
Image
Post Reply