Subject | No way to append to BLOBs using CreateBlobStream |
---|---|
Author | mjmyllym |
Post date | 2012-11-07T15:31:58Z |
Hello,
I have a critical problem in appending data to binary BLOBs using CreateBlobStream.
I am using IBO4_9_14_b52, Delphi 6. Tried both Firebird 2.1 and 2.0; different BLOB types etc.
The thing is I can read from a BLOB and write to a BLOB but cannot append. Opening a BLOB with existing data with CreateBlobStream in bsmWrite/bsmReadWrite mdoe always results in a stream of size 0! So I cannot seek the stream and append to the end. If I look at the query's data in string format I can see the existing data but not in Stream format.
Very simple database:
create table curves (
rown integer,
datax blob sub_type 0,
primary key (rown));
Then, I have a form with TIBODatabase, IBOQuery or IB_Query (neither works), and a simple test that first reads from a BLOB (ok), then writes a simple array of byte data to a BLOB (ok) and finally tries to append to it => fails.
procedure TForm1.Button5Click(Sender: TObject);
var
Buff : array of byte;
F : TField;
St : TIB_BlobStream;
I : integer;
begin
SetLength (Buff, 10);
for I := 0 to 10 do Buff [I] := I;
// First read from the BLOB, might be empty
IB_Query1.SQL.Text := 'select * from curves where rown = 1';
IB_Query1.Open;
St := TIB_BlobStream (IB_Query1.CreateBlobStream (IB_Query1.FieldByName ('datax'), bsmRead));
ShowMessage (IntToStr (St.Size)); // => Result in "0" on the first round, "10" on the second
St.Free;
// Then write to:
IB_Query1.Close;
IB_QUery1.RequestLive := true;
IB_Query1.Open;
IB_Query1.Edit;
St := TIB_BlobStream (IB_Query1.CreateBlobStream (IB_Query1.FieldByName ('datax'), bsmReadWrite));
ShowMessage (IntToStr (St.Size)); // => Result in "0"
St.WriteBuffer (Buff [0], 10);
ShowMessage (IntToStr (St.Size)); // => Results in "10", as it should
IB_Query1.Post;
St.Free;
// Now let's try to append:
IB_Query1.Close;
IB_QUery1.RequestLive := true;
IB_Query1.Open;
IB_Query1.Edit;
St := TIB_BlobStream (IB_Query1.CreateBlobStream (IB_Query1.FieldByName ('datax'), bsmWrite));
ShowMessage (IntToStr (St.Size)); // => Results in "0".. like there is no data!
St.WriteBuffer (Buff [0], 10);
IB_Query1.Post;
St.Free;
end;
Frustrating.
I CAN append to the blob if I use e.g.
St := TMemoryStream.Create;
TBlobField (F).SaveToStream (St);
..
St.WriteBuffer (Data, Length);
TBlobField (F).LoadFromStream (St);
but this is very ineffective because I need to write to the BLOBs all the time, i.e. several times a minute. Also this results in a huge database bloating.
Thank you in advance for help.
Best regards,
Marko Myllymaki
I have a critical problem in appending data to binary BLOBs using CreateBlobStream.
I am using IBO4_9_14_b52, Delphi 6. Tried both Firebird 2.1 and 2.0; different BLOB types etc.
The thing is I can read from a BLOB and write to a BLOB but cannot append. Opening a BLOB with existing data with CreateBlobStream in bsmWrite/bsmReadWrite mdoe always results in a stream of size 0! So I cannot seek the stream and append to the end. If I look at the query's data in string format I can see the existing data but not in Stream format.
Very simple database:
create table curves (
rown integer,
datax blob sub_type 0,
primary key (rown));
Then, I have a form with TIBODatabase, IBOQuery or IB_Query (neither works), and a simple test that first reads from a BLOB (ok), then writes a simple array of byte data to a BLOB (ok) and finally tries to append to it => fails.
procedure TForm1.Button5Click(Sender: TObject);
var
Buff : array of byte;
F : TField;
St : TIB_BlobStream;
I : integer;
begin
SetLength (Buff, 10);
for I := 0 to 10 do Buff [I] := I;
// First read from the BLOB, might be empty
IB_Query1.SQL.Text := 'select * from curves where rown = 1';
IB_Query1.Open;
St := TIB_BlobStream (IB_Query1.CreateBlobStream (IB_Query1.FieldByName ('datax'), bsmRead));
ShowMessage (IntToStr (St.Size)); // => Result in "0" on the first round, "10" on the second
St.Free;
// Then write to:
IB_Query1.Close;
IB_QUery1.RequestLive := true;
IB_Query1.Open;
IB_Query1.Edit;
St := TIB_BlobStream (IB_Query1.CreateBlobStream (IB_Query1.FieldByName ('datax'), bsmReadWrite));
ShowMessage (IntToStr (St.Size)); // => Result in "0"
St.WriteBuffer (Buff [0], 10);
ShowMessage (IntToStr (St.Size)); // => Results in "10", as it should
IB_Query1.Post;
St.Free;
// Now let's try to append:
IB_Query1.Close;
IB_QUery1.RequestLive := true;
IB_Query1.Open;
IB_Query1.Edit;
St := TIB_BlobStream (IB_Query1.CreateBlobStream (IB_Query1.FieldByName ('datax'), bsmWrite));
ShowMessage (IntToStr (St.Size)); // => Results in "0".. like there is no data!
St.WriteBuffer (Buff [0], 10);
IB_Query1.Post;
St.Free;
end;
Frustrating.
I CAN append to the blob if I use e.g.
St := TMemoryStream.Create;
TBlobField (F).SaveToStream (St);
..
St.WriteBuffer (Data, Length);
TBlobField (F).LoadFromStream (St);
but this is very ineffective because I need to write to the BLOBs all the time, i.e. several times a minute. Also this results in a huge database bloating.
Thank you in advance for help.
Best regards,
Marko Myllymaki