Recent

Author Topic: TBufDataset.First issue.  (Read 1002 times)

dmitryb

  • Jr. Member
  • **
  • Posts: 59
TBufDataset.First issue.
« on: January 24, 2023, 07:18:16 pm »
Lazarus 2.2.4 (rev lazarus_2_2_4) FPC 3.2.2 x86_64-win64-win32/win64

Next code in Lazarus 2.2.4  shows empty string.

Code: Pascal  [Select][+][-]
  1. procedure TForm1.Button4Click(Sender: TObject);
  2. var
  3.   s: String;
  4. begin
  5.   BufDataset1 := TBufDataset.Create(Self);
  6.  
  7.   BufDataset1.FieldDefs.Add('Str5Field', ftString, 5, -1, False, False, 0, CP_UTF8);
  8.   BufDataset1.CreateDataset;
  9.  
  10.   BufDataset1.Append;
  11.   BufDataset1.FieldByName('Str5Field').AsString := 'ABCDEFG';
  12.   BufDataset1.Post;
  13.   BufDataset1.First;
  14.  
  15.   s := VarToStr(BufDataset1.FieldByName('Str5Field').AsVariant);
  16.  
  17.   ShowMessage(s);
  18. end;
  19.  

Is this a feature or a bug?

egsuh

  • Hero Member
  • *****
  • Posts: 1067
Re: TBufDataset.First issue.
« Reply #1 on: January 25, 2023, 04:26:46 am »
Why not simply

     s := BufDataset1.FieldByName('Str5Field').AsString;

?

Zvoni

  • Hero Member
  • *****
  • Posts: 1591
Re: TBufDataset.First issue.
« Reply #2 on: January 25, 2023, 09:21:08 am »
Why not simply

     s := BufDataset1.FieldByName('Str5Field').AsString;

?
Same issue.

I can confirm
Code: Pascal  [Select][+][-]
  1. program Project1;
  2. Uses bufdataset,db;
  3.  
  4. Var
  5.   s:String;
  6.   bd:TBufDataset;
  7.  
  8. begin
  9.   bd:=TBufDataset.Create(Nil);
  10.   bd.FieldDefs.Add('Str5Field',ftString,5,-1,False,False,0,CP_UTF8);
  11.   bd.CreateDataset;
  12.   Writeln('RecCount=',bd.RecordCount);
  13.   bd.Append;
  14.   bd.FieldByName('Str5Field').AsString:='ABCDEFG';
  15.   bd.Post;
  16.   Writeln('RecCount=',bd.RecordCount);
  17.   Writeln('BOF=',bd.BOF,' - EOF=',bd.EOF);
  18.   s:=bd.Fieldbyname('Str5Field').AsString;
  19.   Writeln('recNo=',bd.RecNo,' - s=',s);
  20.   bd.First;
  21.   Writeln('BOF=',bd.BOF,' - EOF=',bd.EOF);
  22.   s:=bd.Fieldbyname('Str5Field').AsString;
  23.   Writeln('recNo=',bd.RecNo,' - s=',s);
  24.   bd.Last;
  25.   Writeln('BOF=',bd.BOF,' - EOF=',bd.EOF);
  26.   s:=bd.Fieldbyname('Str5Field').AsString;
  27.   Writeln('recNo=',bd.RecNo,' - s=',s);
  28.   bd.First;
  29.   Writeln('BOF=',bd.BOF,' - EOF=',bd.EOF);
  30.   s:=bd.Fieldbyname('Str5Field').AsString;
  31.   Writeln('recNo=',bd.RecNo,' - s=',s);
  32. end.

Result
Quote
RecCount=0
RecCount=1
BOF=FALSE - EOF=FALSE
recNo=1 - s=ABCDEFG
BOF=TRUE - EOF=FALSE
recNo=1 - s=
BOF=FALSE - EOF=TRUE
recNo=1 - s=ABCDEFG
BOF=TRUE - EOF=FALSE
recNo=1 - s=
One System to rule them all, One Code to find them,
One IDE to bring them all, and to the Framework bind them,
in the Land of Redmond, where the Windows lie
---------------------------------------------------------------------
Code is like a joke: If you have to explain it, it's bad

TRon

  • Hero Member
  • *****
  • Posts: 662
Re: TBufDataset.First issue.
« Reply #3 on: January 25, 2023, 09:46:15 am »
In addition to Zvoni's findings:
- it leaks memory
- it creates an access violation when not using a exception block to free the instantiated class.

I get very strange output characters instead of receiving empty strings (unlike Zvoni)

Zvoni

  • Hero Member
  • *****
  • Posts: 1591
Re: TBufDataset.First issue.
« Reply #4 on: January 25, 2023, 10:14:43 am »
In addition to Zvoni's findings:
- it leaks memory
- it creates an access violation when not using a exception block to free the instantiated class.
Yes, it's the reason why i left out bd.free in above code (and i don't care about memory-leaks when just testing around and it's basically the end of the program anyway)

Something that baffles me: RecCount is 1, shouldn't BOF and EOF both be true, irrespective if i move Next, Prior, First or Last??
« Last Edit: January 25, 2023, 10:17:07 am by Zvoni »
One System to rule them all, One Code to find them,
One IDE to bring them all, and to the Framework bind them,
in the Land of Redmond, where the Windows lie
---------------------------------------------------------------------
Code is like a joke: If you have to explain it, it's bad

rvk

  • Hero Member
  • *****
  • Posts: 5070
Re: TBufDataset.First issue.
« Reply #5 on: January 25, 2023, 10:22:21 am »
The problem might be that you are trying to stuff a string of 7 characters "ABCDEFG" in a field defined with Size = 5 !! %)

That really messes things up.

Just define the stringfield as a field of 20 characters and the code should work fine.

Code: Pascal  [Select][+][-]
  1.   // bd.FieldDefs.Add('Str5Field',ftString,5,-1,False,False,0,CP_UTF8);
  2.   bd.FieldDefs.Add('Str5Field', ftString, 20);
  3.  
(I'm also not sure about the other parameters you used in the field-def. But the simple version I used above works.)

Zvoni

  • Hero Member
  • *****
  • Posts: 1591
Re: TBufDataset.First issue.
« Reply #6 on: January 25, 2023, 10:24:08 am »
The problem might be that you are trying to stuff a string of 7 characters "ABCDEFG" in a field defined with Size = 5 !! %)

That really messes things up.

Just define the stringfield as a field of 20 characters and the code should work fine.

Code: Pascal  [Select][+][-]
  1.   // bd.FieldDefs.Add('Str5Field',ftString,5,-1,False,False,0,CP_UTF8);
  2.   bd.FieldDefs.Add('Str5Field', ftString, 20);
  3.  
Was my first thought, too, but doesn't make a difference if you shorten the String to "ABCDE" - same issue.
Just try it.

EDIT: What i noticed: The issue appears when BOF=True, irrespective of the Value of EOF
It returns the correct Value for BOF=False
« Last Edit: January 25, 2023, 10:26:46 am by Zvoni »
One System to rule them all, One Code to find them,
One IDE to bring them all, and to the Framework bind them,
in the Land of Redmond, where the Windows lie
---------------------------------------------------------------------
Code is like a joke: If you have to explain it, it's bad

rvk

  • Hero Member
  • *****
  • Posts: 5070
Re: TBufDataset.First issue.
« Reply #7 on: January 25, 2023, 10:26:08 am »
The problem might be that you are trying to stuff a string of 7 characters "ABCDEFG" in a field defined with Size = 5 !! %)

That really messes things up.

Just define the stringfield as a field of 20 characters and the code should work fine.

Code: Pascal  [Select][+][-]
  1.   // bd.FieldDefs.Add('Str5Field',ftString,5,-1,False,False,0,CP_UTF8);
  2.   bd.FieldDefs.Add('Str5Field', ftString, 20);
  3.  
Was my first thought, too, but doesn't make a difference if you shorten the String to "ABCDE" - same issue.
Just try it.
And what happens if you use this??
Code: Pascal  [Select][+][-]
  1.  bd.FieldDefs.Add('Str5Field', ftString, 20);

The problem could also be in the precision of -1 or something else.
Using the simple Add() version works for me.

O, or FieldNo. Why is 0 used here?
Shouldn't this be 1????
« Last Edit: January 25, 2023, 10:29:14 am by rvk »

Zvoni

  • Hero Member
  • *****
  • Posts: 1591
Re: TBufDataset.First issue.
« Reply #8 on: January 25, 2023, 10:28:27 am »
The problem might be that you are trying to stuff a string of 7 characters "ABCDEFG" in a field defined with Size = 5 !! %)

That really messes things up.

Just define the stringfield as a field of 20 characters and the code should work fine.

Code: Pascal  [Select][+][-]
  1.   // bd.FieldDefs.Add('Str5Field',ftString,5,-1,False,False,0,CP_UTF8);
  2.   bd.FieldDefs.Add('Str5Field', ftString, 20);
  3.  
Was my first thought, too, but doesn't make a difference if you shorten the String to "ABCDE" - same issue.
Just try it.
And what happens if you use this??
Code: Pascal  [Select][+][-]
  1.  bd.FieldDefs.Add('Str5Field', ftString, 20);

The problem could also be in the precision of -1 or something else.
Using the simple Add() version works for me.
Yes, i wondered about that, too (since when do you need precision for Strings?!?!), but i think OP used this overloaded function because of the following params after precision (required, readonly, codepage)
One System to rule them all, One Code to find them,
One IDE to bring them all, and to the Framework bind them,
in the Land of Redmond, where the Windows lie
---------------------------------------------------------------------
Code is like a joke: If you have to explain it, it's bad

rvk

  • Hero Member
  • *****
  • Posts: 5070
Re: TBufDataset.First issue.
« Reply #9 on: January 25, 2023, 10:29:57 am »
Yes, i wondered about that, too (since when do you need precision for Strings?!?!), but i think OP used this overloaded function because of the following params after precision (required, readonly, codepage)
I think the fieldNo of 0 is the problem.
Make it one (1) and it works.

Code: Pascal  [Select][+][-]
  1.   // bd.FieldDefs.Add('Str5Field', ftString, 20);
  2.   bd.FieldDefs.Add('Str5Field',ftString,5,-1,False,False,1,CP_UTF8);

rvk

  • Hero Member
  • *****
  • Posts: 5070
Re: TBufDataset.First issue.
« Reply #10 on: January 25, 2023, 10:34:34 am »
Yes, i wondered about that, too (since when do you need precision for Strings?!?!), but i think OP used this overloaded function because of the following params after precision (required, readonly, codepage)
I think the fieldNo of 0 is the problem.
Make it one (1) and it works.

Code: Pascal  [Select][+][-]
  1.   // bd.FieldDefs.Add('Str5Field', ftString, 20);
  2.   bd.FieldDefs.Add('Str5Field',ftString,5,-1,False,False,1,CP_UTF8);

Yep. From the source:
Quote
  // the fielddef will register itself here as an owned component.
  // fieldno is 1 based !
So don't use field 0 but start on 1 !!!!

Not sure if there is any documentation for this  :P

Zvoni

  • Hero Member
  • *****
  • Posts: 1591
Re: TBufDataset.First issue.
« Reply #11 on: January 25, 2023, 10:40:48 am »
Quote

Code: Pascal  [Select][+][-]
  1.   // bd.FieldDefs.Add('Str5Field', ftString, 20);
  2.   bd.FieldDefs.Add('Str5Field',ftString,5,-1,False,False,1,CP_UTF8);

Yep. From the source:
Quote
  // the fielddef will register itself here as an owned component.
  // fieldno is 1 based !
So don't use field 0 but start on 1 !!!!

Not sure if there is any documentation for this  :P
Yep, that's it.

Result
Quote
RecCount=0
RecCount=1
BOF=FALSE - EOF=FALSE
recNo=1 - s=ABCDEFG
BOF=TRUE - EOF=FALSE
recNo=1 - s=ABCDEFG
BOF=FALSE - EOF=TRUE
recNo=1 - s=ABCDEFG
BOF=TRUE - EOF=FALSE
recNo=1 - s=ABCDEFG
Still doesn't explain the BOF/EOF confusion
One System to rule them all, One Code to find them,
One IDE to bring them all, and to the Framework bind them,
in the Land of Redmond, where the Windows lie
---------------------------------------------------------------------
Code is like a joke: If you have to explain it, it's bad

TRon

  • Hero Member
  • *****
  • Posts: 662
Re: TBufDataset.First issue.
« Reply #12 on: January 25, 2023, 10:45:05 am »
Confirmed that rvk's solution works.

I agree with Zvoni wrt documentation (I was unable to locate it, though the property is named fielNo as in number not index). Even a exception on providing a 'illegal' field number would have been helpful.

I seem to remember there being something being off with eof/bof. From what I remember it was logical it acted this way (I seem unable to locate the conversation as I was not part of it, should be here on the forum)

rvk

  • Hero Member
  • *****
  • Posts: 5070
Re: TBufDataset.First issue.
« Reply #13 on: January 25, 2023, 10:45:44 am »
Result
Quote
RecCount=0
RecCount=1
BOF=FALSE - EOF=FALSE
recNo=1 - s=ABCDEFG
BOF=TRUE - EOF=FALSE
recNo=1 - s=ABCDEFG
BOF=FALSE - EOF=TRUE
recNo=1 - s=ABCDEFG
BOF=TRUE - EOF=FALSE
recNo=1 - s=ABCDEFG
Still doesn't explain the BOF/EOF confusion
What confusion?
They are correct in this example. (or am I missing something?)

BOF and EOF are not set until they are actually encountered.
With a POST they are not set. Only with Last, First, Next and Prior (and only in the direction you where going).

wp

  • Hero Member
  • *****
  • Posts: 10469
Re: TBufDataset.First issue.
« Reply #14 on: January 25, 2023, 10:45:58 am »
Not sure if there is any documentation for this  :P
https://www.freepascal.org/docs-html/fcl/db/tfield.fieldno.html ("It is a 1-based index")

 

TinyPortal © 2005-2018