#1 2014-06-30 13:38:56

corchi72
Member
Registered: 2010-12-10
Posts: 232

Error to read a boolean value (RecordClass.Create).GetFieldVariant

With the last 2 updates I have verified that there is a conversion error in the values of the boolean fields when I execute "GetFieldVariant".
I read the value for implement a cell (boolean) of  a grid.

the stable version worked until 11/2013

this is my code:

var
  TmpRec: TSQLRecord;
  FRec: TSQLFile;
  col: TcxGridColumn;
  row: Integer;


begin
  
  fRecordClass := TSQLField;
  TmpRec := fRecordClass.Create;
      
     row := FRec.FillTable.RowFromID(FList.Items[fRecordIndex].IDlookup);
     FRec.FillRow(row, TmpRec);
     result := TmpRec.GetFieldVariant(col.Name);
       

sorry, the error is not in the function "GetFieldVariant" I suppose that it's in the general conversion of the recordclass expression, I have tested that the same function and it worked if I write

  //result := TmpRec.GetFieldVariant(AName); not working
  result := TSQLField(TmpRec).IsBoolean;


  result :=  TSQLField(TmpRec).GetFieldVariant('IsBoolean'); //not working


thanks
corchi

Last edited by corchi72 (2014-06-30 15:43:54)

Offline

#2 2014-06-30 15:59:21

ab
Administrator
From: France
Registered: 2010-06-21
Posts: 14,603
Website

Re: Error to read a boolean value (RecordClass.Create).GetFieldVariant

I honestly can't find out what you want to do...
sad

Offline

#3 2014-07-01 08:50:33

corchi72
Member
Registered: 2010-12-10
Posts: 232

Re: Error to read a boolean value (RecordClass.Create).GetFieldVariant

I have create a generic datasource for showing data into a QuantumnGrid

I have a base table that is called TSQLfile and a derived table that is called TSQLField. I created a generic datasource based on which step TSQLfield array and read the data with the function :

function TFieldDataSource.GetValue (ARecordHandle: TcxDataRecordHandle;
   AItemHandle: TcxDataItemHandle): Variant;


My TcxCustomDataSource is :

-----FileTable-----

 TSQLFile = class(TSQLRecordSigned)
  private
    fOwner: RawUTF8;
    fCheck: Boolean;
    fIsSystem: Boolean;
    fAssociatedRecord: TRecordReference;
    fAssociatedID: Integer;
    function GetDisplayName: RawUTF8; virtual;
  public
    fName: RawUTF8;
    fModified: TTimeLog;
    fCreated: TTimeLog;
    fPicture: TSQLRawBlob;
    fKeyWords: RawUTF8;
    fLabel: RawUTF8;
    fImageIndex: Integer;
    fEnabled: Boolean;

...
end;

 TSQLField = class(TSQLFile)
  private
    fOwner: RawUTF8;
    fIsMeasure: Boolean;
    fCategory: RawUTF8;
end;

// then fIsMeasure   is not present in parent class (TSQLFile )


----unit UFieldDS;
type
  TFieldDataSource= class(TcxCustomDataSource)
  private

    fClient: TSQLRestClientURI;
    fRecordClass: TSQLRecordClass;
    TmpRec: TSQLRecord;
    FRec: TSQLFile;

  protected

    fRecordIndex: Integer;

   
    function GetValue(ARecordHandle: TcxDataRecordHandle;
      AItemHandle: TcxDataItemHandle): Variant; override;
    procedure SetValue(ARecordHandle: TcxDataRecordHandle;
      AItemHandle: TcxDataItemHandle; const AValue: Variant); override;
  public
    
     constructor Create(aOwner: TcxGridTableView; Client: TSQLRestClientURI;
      ARec: TSQLField); overload;
    Destructor Destroy; override;
  end;
 implementation
..

constructor TFieldDataSource.Create(aOwner: TcxGridTableView;
  Client: TSQLRestClientURI; ARec: TSQLField;
  );
begin

  FRec := ARec; //here I assign the TSQLfield to var ARec that it's a TSQLfile type
  fClient := TSQLRestClientURI(Client);
  fRecordClass := ARec.RecordClass;//here I read the class of origin (TSQLfield)
  TmpRec := fRecordClass.Create;//here I create the object from oringin class(TSQLfield)
end;


//Then when the datasource reads the column values I use the object: TmpRec 

function TFieldDataSource.GetValue(ARecordHandle: TcxDataRecordHandle;
  AItemHandle: TcxDataItemHandle): Variant;
var
  row: Integer;
  AColumnName: string;
  fRecordIndex :Integer;
begin
  result := inherited;

  row := 0;

  AColumnName:= TcxCustomGridTableItem  (DataController.GetItem(integer(AItemHandle))).Name;

  fRecordIndex := integer(ARecordHandle);

  row := fRecordIndex +1

  FRec.FillRow(row, TmpRec); // the TmpRec is corrected

  result :=  TmpRec.GetFieldVariant(AColumnName); //this does not work .. once worked

  //Now this works

  result :=  TSQLField(TmpRec).GetFieldVariant(AColumnName);  

end;

I have to cast the variable but the variable must already be in type TSQLField when I execute this in a constructor function:

fRecordClass := ARec.RecordClass;//here I read the class of origin (TSQLfield)
  TmpRec := fRecordClass.Create;//here I create the object from oringin class(TSQLfield)"


I'm writing because I once worked and now no longer works. I have many classes that use this datasource is the basis for what I wanted to keep it generic.

thanks corchi

ps sorry for my english but I hope that you have understand my problem

Offline

#4 2014-07-01 10:47:36

mingda
Member
Registered: 2013-01-04
Posts: 121

Re: Error to read a boolean value (RecordClass.Create).GetFieldVariant

perhaps interrelated the boolean value in json, i remember before Mongo integration, boolean value in json is true or false, but now is 0 or 1.

Offline

#5 2014-07-01 12:36:03

ab
Administrator
From: France
Registered: 2010-06-21
Posts: 14,603
Website

Re: Error to read a boolean value (RecordClass.Create).GetFieldVariant

What is the exact error?

Offline

#6 2014-07-01 13:13:06

corchi72
Member
Registered: 2010-12-10
Posts: 232

Re: Error to read a boolean value (RecordClass.Create).GetFieldVariant

I may have found the error and tell me if it's true. thank you

if I'm not mistaken  1 = true and 0 = false

In this function if I passed  value=1 (true) the funcion turned me False ;

{$ifndef NOVARIANTS}
procedure ValueVarToVariant(Value: PUTF8Char; FT: TSQLFieldType;
  var result: TVarData; createValueTempCopy: boolean);
const
....
sftBoolean:
    result.VBoolean := (Value=nil) or (PWord(Value)^=ord('0')) or
      (PInteger(Value)^=FALSE_LOW);
...

Offline

#7 2014-07-01 13:31:39

corchi72
Member
Registered: 2010-12-10
Posts: 232

Re: Error to read a boolean value (RecordClass.Create).GetFieldVariant

this is the error
sftBoolean:
   (Value=nil) or (PWord(Value)^=ord('0')) or
     (PInteger(Value)^=FALSE_LOW);

was once written:

sftBoolean:
      Dest := boolean(GetInteger(pointer(result)));

see this:

http://synopse.info/fossil/info/fca6a4a … 623bcd1349

corchi

Offline

#8 2014-07-01 17:42:28

ab
Administrator
From: France
Registered: 2010-06-21
Posts: 14,603
Website

Re: Error to read a boolean value (RecordClass.Create).GetFieldVariant

Offline

#9 2014-07-02 07:15:30

corchi72
Member
Registered: 2010-12-10
Posts: 232

Re: Error to read a boolean value (RecordClass.Create).GetFieldVariant

the error always happens ... the important thing is to find it as soon as possible .... I'm glad that this time I was the first to find it, so I made it useful to your work of which we are all benefiting ... . than to say thank you.

corchi

Offline

#10 2014-07-02 07:24:09

ab
Administrator
From: France
Registered: 2010-06-21
Posts: 14,603
Website

Re: Error to read a boolean value (RecordClass.Create).GetFieldVariant

When I run the following:

procedure Test;
var v: Variant;
begin
  ValueVarToVariant('0',sftBoolean,TVarData(v),false);
  assert(not boolean(v));
  ValueVarToVariant('false',sftBoolean,TVarData(v),false);
  assert(not boolean(v));
  ValueVarToVariant('1',sftBoolean,TVarData(v),false);
  assert(boolean(v));
  ValueVarToVariant('true',sftBoolean,TVarData(v),false);
  assert(boolean(v));
end;

There is no error when reading the property.
So ValueVarToVariant() sound working as expected now.

See http://synopse.info/fossil/info/da7141e … deed8bed60 for the corresponding regression tests.

Offline

Board footer

Powered by FluxBB