problems with IBCQuery and blob fields?

Discussion of open issues, suggestions and bugs regarding IBDAC (InterBase Data Access Components) for Delphi, C++Builder, Lazarus (and FPC)
Post Reply
Bjarke_Moholt
Posts: 39
Joined: Thu 21 Nov 2013 12:51

problems with IBCQuery and blob fields?

Post by Bjarke_Moholt » Wed 04 Feb 2015 13:16

I am experiencing changed behaviour with blob fields after porting from BDE to IBC.
I've tested a bit and find that blob fields appear to be written differently in IBC than they were in BDE.

I'm wondering if there are any known issues - and hopefully solutions - to this?

ViktorV
Devart Team
Posts: 3168
Joined: Wed 30 Jul 2014 07:16

Re: problems with IBCQuery and blob fields?

Post by ViktorV » Thu 05 Feb 2015 05:42

Please describe the problem in more details. Try to compose a small sample to demonstrate the problem and send it to viktorv*devart*com.

Bjarke_Moholt
Posts: 39
Joined: Thu 21 Nov 2013 12:51

Re: problems with IBCQuery and blob fields?

Post by Bjarke_Moholt » Tue 17 Feb 2015 09:34

OK, this might be a bit long so I'll start with the abstract:
I have a question. Is there a property on the IBCQuery that may affect the size of the blob when it is written/read?


I have some problems reproducing my problem in an isolated project. I have a suspicion of where things go wrong though and have a question that may clear things up

This is what I do:

Code: Select all

   
   MS := TMemoryStream.Create;
   MS.LoadFromFile('e:\Shares\bjarke.moeholt\MemoryStream');

    MS.Position := 0;
    IBCQuery.SQL.LoadFromFile('e:\Shares\bjarke.moeholt\skydatvalSQL');
    //INSERT INTO @SomeTable@([Index],[BLOBVAL])
    //VALUES( :Index,:BlobVal )
    IBCQuery.Params[0].asInteger := 1;
    IBCQuery.Params[1].SetBlobData( MS.Memory, MS.Size );
    IBCQuery.ExecSQL;

    //read it back
    Q.SQL.Clear;
    Q.SQL.Add('SELECT * FROM SomeTable');
    Q.Open;
    Q.First;

    FileBlobs := IBCQuery.FieldByName('BLOBVAL') as TBlobField;
    Stream:=IBCQuery.CreateBlobStream(FileBlobs,bmRead);
    ValSize := 4; //sizeof(single)
    NumVal := Trunc(Stream.Size/ValSize); //Stream.Size is double the expected!!
    setLength(resultSIArray, NumVal);
    Stream.ReadBuffer(pointer(resultSIArray)^, NumVal * ValSize);

The symptom of the problem is that Stream.size returns a value twice as big as the expected value (the value we saw in MS.size, the size of the written blob), and the contents of the blob are not consistent with the values I put in
By testing with BDE as a reference I have established that the problem is in the write section, However as I said earlier I cannot reproduce the problem in an isolated case.
Now my question comes up: Is there a property on the IBCQuery that may affect the size of the blob when it is written/read?

ViktorV
Devart Team
Posts: 3168
Joined: Wed 30 Jul 2014 07:16

Re: problems with IBCQuery and blob fields?

Post by ViktorV » Tue 17 Feb 2015 12:18

Unfortunately, we can't reproduce the issue in the way you have described it. The Stream.size value is equal to the MS.size value. You can ensure this by executing the following code:

Code: Select all

program TestBlob;

{$APPTYPE CONSOLE}

uses
  System.SysUtils, IBC, System.Classes, Data.DB;

var
  IBCConnection: TIBCConnection;
  IBCQuery: TIBCQuery;
  MS: TMemoryStream;
  Stream : TStream;
  FileBlobs: TField;

begin
  IBCConnection := TIBCConnection.Create(nil);
  try
    IBCConnection.Server := Server;
    IBCConnection.Port := Port;
    IBCConnection.Database := NEW_TEST_DATABASE;
    IBCConnection.ClientLibrary := ClientLibrary;
    IBCConnection.Username := 'sysdba';
    IBCConnection.Password := 'masterkey';
    IBCConnection.Params.Clear;
    IBCConnection.Params.Add('USER ''SYSDBA''');
    IBCConnection.Params.Add('PASSWORD ''masterkey''');
    IBCConnection.Params.Add('PAGE_SIZE 4096');
    IBCConnection.Params.Add('DEFAULT CHARACTER SET WIN1251');

    try
      IBCConnection.Connect;
      IBCConnection.DropDatabase;
    except
    end;

    IBCConnection.CreateDatabase;
    IBCConnection.ExecSQL('CREATE TABLE Test_BLOB (ID INTEGER, F_BLOB BLOB)');
    WriteLn('Create Ok');

    IBCQuery := TIBCQuery.Create(nil);
      try
        IBCQuery.Connection := IBCConnection;
        MS := TMemoryStream.Create;
        MS.LoadFromFile('d:\ofs.txt');
        MS.Position := 0;
        IBCQuery.SQL.Text := 'INSERT INTO TEST_BLOB (ID, F_BLOB) VALUES( :ID,:F_BLOB)';
        IBCQuery.Params[0].asInteger := 1;
        IBCQuery.Params[1].SetBlobData( MS.Memory, MS.Size );
        IBCQuery.ExecSQL;
        WriteLn('MS.Size = ' + IntToStr(MS.Size));

        IBCQuery.SQL.Text := 'SELECT * FROM TEST_BLOB';
        IBCQuery.Open;

        FileBlobs := IBCQuery.FieldByName('F_BLOB') as TBlobField;
        Stream:=IBCQuery.CreateBlobStream(FileBlobs, bmRead);
        WriteLn('Stream.Size = ' + IntToStr(Stream.Size));
      finally
        IBCConnection.Disconnect;
        IBCQuery.Free;
      end;

    ReadLn;

  finally
    IBCConnection.Free;
  end;
end.

Bjarke_Moholt
Posts: 39
Joined: Thu 21 Nov 2013 12:51

Re: problems with IBCQuery and blob fields?

Post by Bjarke_Moholt » Tue 17 Feb 2015 12:34

Yes, I get the same result in an isolated project. I am now trying to ensure that the relevant environment variables are the identical in the two projects..
Does the IBCQuery have a property that may influence the perceived size of an incoming/outgoing stream?

(Edit) Just saw the lines regarding charset and pagesize, will try with these

ViktorV
Devart Team
Posts: 3168
Joined: Wed 30 Jul 2014 07:16

Re: problems with IBCQuery and blob fields?

Post by ViktorV » Thu 19 Feb 2015 09:31

IBCQuery has no property that may influence the perceived size of an incoming/outgoing stream.

Post Reply