Page 1 of 1

[patch_done] Patch for TZOracleBlob.ReadBlob

Posted: 02.09.2009, 14:22
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

Posted: 02.09.2009, 23:43
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

Posted: 03.09.2009, 11:31
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

Posted: 04.09.2009, 23:37
by mdaems
Bon soir,

This was precise enough, thanks :mrgreen:

SVN Rev. 684 (testing branch)

This will move to 6.6-patches too.

Mark