Sign in Join

Live chat for Free Pascal, Lazarus, Delphi and every Pascal programmer.

Mailing lists / fpc-pascal / 2011-08

Trouble setting/getting ftVarBytes field data in TBufDataset

5 messages · 3 people · –

Reply by email Subscribe to this list Your subscription

Read-only archive. Use j and k to move between messages.

Reinier Olislagers

I've got trouble finding out how to fill and retrieve data for a ftVarBytes field in a TBufDataset.

.AsString doesn't seem to work well - if I fill it with the string How do I fill this field?
I get back
How

I tried SetData, which takes a buffer as data, so I tried filling a PChar with the string data. Retrieving it leads to a big dump of memory, so I wonder how you define the end of the buffer in the SetData call.

Hope somebody can point me to some documentation or tell me the proper way to do this. I've looked at Delphi docs, but that dealt mostly with general BLOB fields, don't know if that includes varBytes.

Below some test code and output:
program varbytesproject;
{$mode objfpc}{$H+}
{$APPTYPE CONSOLE}

uses

  {$IFDEF UNIX}{$IFDEF UseCThreads}
  cthreads,
  {$ENDIF}{$ENDIF}
  Classes, SysUtils,
  { you can add units after this }
  DB, BufDataSet;
var
  TestDataset: TBufDataset;
  FieldDef: TFieldDef;
  TestString: String;
  TempPChar: PChar;
begin
  TestDataset := TBufDataset.Create(nil);
  FieldDef := TestDataset.FieldDefs.AddFieldDef;
  FieldDef.Name := 'ftVarBytes';
  FieldDef.DataType := ftVarBytes;
  FieldDef.Size := 2;
  TestDataset.CreateDataSet;
  TestDataset.Open;
  TestDataset.Append;
  writeln('1. How do I fill an ftVarBytes field?');
  Teststring:='How do I fill this field?';
  writeln('2. Like this?');
  TestDataset.FieldByName('ftVarBytes').Asstring := Teststring;
  writeln('ftVarbytes.AsString: ' +
TestDataset.FieldByName('ftVarBytes').AsString);
  writeln('3. Or like this?');
  TempPChar:=PChar(TestString);
  TestDataSet.FieldByName('ftVarBytes').SetData(TempPChar);
  writeln('ftVarbytes.AsString: ' +
TestDataset.FieldByName('ftVarBytes').AsString);
  TestDataset.Post;
  writeln('4. Get data using this:');
  writeln('ftVarbytes.AsString: ' +
TestDataset.FieldByName('ftVarBytes').AsString);
  writeln('5. Or get data using this:');
  TempPchar:='';
  if TestDataset.FieldByName('ftVarBytes').GetData(TempPChar) then
  begin
    writeln('We filled TempPChar with: ' + TempPChar);
  end
  else
  begin
    writeln('The Getdata function didn''t work.');
  end;
  TestDataset.Close;
  TestDataset.Free;
end.

Output:
1. How do I fill an ftVarBytes field?
2. Like this?
ftVarbytes field contains: How
3. Or like this?
ftVarbytes field contains: How
4. Get data using this:
ftVarbytes field contains: How
5. Or get data using this:
We filled TempPChar with:

!The Getdata function didn't work.

TObject♦
<snip more data from memory>

Reinier Olislagers
to Reinier Olislagers
Reinier Olislagers wrote 95 lines
I've got trouble finding out how to fill and retrieve data for a ftVarBytes field in a TBufDataset. .AsString doesn't seem to work well - if I fill it with the string How do I fill this field? I get back How I tried SetData, which takes a buffer as data, so I tried filling a PChar with the string data. Retrieving it leads to a big dump of memory, so I wonder how you define the end of the buffer in the SetData call. Hope somebody can point me to some documentation or tell me the proper way to do this. I've looked at Delphi docs, but that dealt mostly with general BLOB fields, don't know if that includes varBytes. Below some test code and output: program varbytesproject; {$mode objfpc}{$H+} {$APPTYPE CONSOLE} uses {$IFDEF UNIX}{$IFDEF UseCThreads} cthreads, {$ENDIF}{$ENDIF} Classes, SysUtils, { you can add units after this } DB, BufDataSet; var TestDataset: TBufDataset; FieldDef: TFieldDef; TestString: String; TempPChar: PChar; begin TestDataset := TBufDataset.Create(nil); FieldDef := TestDataset.FieldDefs.AddFieldDef; FieldDef.Name := 'ftVarBytes'; FieldDef.DataType := ftVarBytes; FieldDef.Size := 2; TestDataset.CreateDataSet; TestDataset.Open; TestDataset.Append; writeln('1. How do I fill an ftVarBytes field?'); Teststring:='How do I fill this field?'; writeln('2. Like this?'); TestDataset.FieldByName('ftVarBytes').Asstring := Teststring; writeln('ftVarbytes.AsString: ' + TestDataset.FieldByName('ftVarBytes').AsString); writeln('3. Or like this?'); TempPChar:=PChar(TestString); TestDataSet.FieldByName('ftVarBytes').SetData(TempPChar); writeln('ftVarbytes.AsString: ' + TestDataset.FieldByName('ftVarBytes').AsString); TestDataset.Post; writeln('4. Get data using this:'); writeln('ftVarbytes.AsString: ' + TestDataset.FieldByName('ftVarBytes').AsString); writeln('5. Or get data using this:'); TempPchar:=''; if TestDataset.FieldByName('ftVarBytes').GetData(TempPChar) then begin writeln('We filled TempPChar with: ' + TempPChar); end else begin writeln('The Getdata function didn''t work.'); end; TestDataset.Close; TestDataset.Free; end. Output: 1. How do I fill an ftVarBytes field? 2. Like this? ftVarbytes field contains: How 3. Or like this? ftVarbytes field contains: How 4. Get data using this: ftVarbytes field contains: How 5. Or get data using this: We filled TempPChar with: !The Getdata function didn't work. TObject♦ <snip more data from memory>

Does anybody have a suggestion on how to use ftVarbytes fields or aren't they supported in FPC?

Marco van de Voort
to Reinier Olislagers

In our previous episode, Reinier Olislagers said:

Show quoted text 5 lines
> TObject? > <snip more data from memory> Does anybody have a suggestion on how to use ftVarbytes fields or aren't they supported in FPC?

Afaik currently mostly ftblob is used for variable binary storage. I'm not entirely sure what the difference is?

Ludo Brands
to Reinier Olislagers: Does anybody have a suggestion on how to use ftVarbytes fields or aren't they supported…
Show quoted text 55 lines
On 2-8-2011 7:39, Reinier Olislagers wrote: > I've got trouble finding out how to fill and retrieve data for a > ftVarBytes field in a TBufDataset. > > .AsString doesn't seem to work well - if I fill it with the string How > do I fill this field? I get back > How > > I tried SetData, which takes a buffer as data, so I tried filling a > PChar with the string data. Retrieving it leads to a big dump of > memory, so I wonder how you define the end of the buffer in the > SetData call. > > Hope somebody can point me to some documentation or tell me the proper > way to do this. I've looked at Delphi docs, but that dealt mostly with > general BLOB fields, don't know if that includes varBytes. > > Below some test code and output: > program varbytesproject; > > {$mode objfpc}{$H+} > {$APPTYPE CONSOLE} > > uses > {$IFDEF UNIX}{$IFDEF UseCThreads} > cthreads, > {$ENDIF}{$ENDIF} > Classes, SysUtils, > { you can add units after this } > DB, BufDataSet; > > var > TestDataset: TBufDataset; > FieldDef: TFieldDef; > TestString: String; > TempPChar: PChar; > begin > TestDataset := TBufDataset.Create(nil); > FieldDef := TestDataset.FieldDefs.AddFieldDef; > FieldDef.Name := 'ftVarBytes'; > FieldDef.DataType := ftVarBytes; > FieldDef.Size := 2; > TestDataset.CreateDataSet; > TestDataset.Open; > TestDataset.Append; > > writeln('1. How do I fill an ftVarBytes field?'); > Teststring:='How do I fill this field?'; > writeln('2. Like this?'); > TestDataset.FieldByName('ftVarBytes').Asstring := Teststring; > writeln('ftVarbytes.AsString: ' + > TestDataset.FieldByName('ftVarBytes').AsString);

This is the way to do it. However:
- FieldDef.Size := 2; You only store 2 characters.
- TCustomBufDataset.GetFieldSize doesn't recognise TBinaryField descendants and fixes their length arbitrary as 10 bytes... Setting fieldsize to more than 10 bytes won't store more than 10 chars. TMemDataset handles this more elegantly by raising a SErrFieldTypeNotSupported.
So the answer is that TBufDataset doesn' support TBinaryField descendants correctly.

For test purposes, limit field size to 10 bytes ;)

Ludo

Reinier Olislagers
to Ludo Brands
Ludo Brands wrote 9 lines
> On 2-8-2011 7:39, Reinier Olislagers wrote: >> I've got trouble finding out how to fill and retrieve data for a >> ftVarBytes field in a TBufDataset. >> TestDataset.FieldByName('ftVarBytes').Asstring := Teststring; >> writeln('ftVarbytes.AsString: ' + >> TestDataset.FieldByName('ftVarBytes').AsString); This is the way to do it. However: - FieldDef.Size := 2; You only store 2 characters.

Oops. Correct.

Show quoted text 8 lines
- TCustomBufDataset.GetFieldSize doesn't recognise TBinaryField descendants and fixes their length arbitrary as 10 bytes... Setting fieldsize to more than 10 bytes won't store more than 10 chars. TMemDataset handles this more elegantly by raising a SErrFieldTypeNotSupported. So the answer is that TBufDataset doesn' support TBinaryField descendants correctly. For test purposes, limit field size to 10 bytes ;)

Thanks for the answer, I will ;)
(I'll have a go at adding this info to the wiki as well)

Reinier