Title: ObjectFromVariant
Post by: vkorshun on October 17, 2011, 01:55:31 PM
Hi Danijel,
I had some problems with (class function TRtcValueObject.ObjectFromVariant). My client dataset has TBCDfield. When it was changing I had an error -'Unsupported Variant type.' I resolved my problem by adding next code
if (TVarData(V).VType = varSQLTimeStamp) or ( TVarData(V).VType = varSQLTimeStampOffset) or ( TVarData(V).VType = varFMTBcd ) then begin Result:=TRtcTextValue.Create; TRtcTextValue(Result).SetText(v); end else raise EConvertError.Create('Unsupported Variant type.'); end;
What is your opinion about this?
Best regards, Victor Korshun
Title: Re: ObjectFromVariant
Post by: D.Tkalcec (RTC) on October 17, 2011, 05:30:05 PM
The exception message you are getting is correct, because there is no TRtcValueObject descendant which can hold these data types natively and I wouldn't convert all these types to Text silently either, because these conversions need to be known on both sides (sender and receiver). But ... since you have mentioned a dataset and the BCDField, I think your problem is in the "rtcDB.pas" unit and can be solved by extending the "RtcDataSetRowsToDelphi", "DelphiDataSetToRtc" and "DelphiRowToRtc" procedures to handle unsupported types. Please locate the "RtcDataSetRowsToDelphi" procedure in the "rtcDB.pas" unit and replace it, as well as the following 3 procedures, with the code below: procedure RtcDataSetRowsToDelphi(rtcDS:TRtcDataSet; DelphiDS:TDataSet); var flds:integer; fldname:string; field:TField; fstream:TStream; begin DelphiDS.Active:=True; rtcDS.First; while not rtcDS.EOF do begin DelphiDS.Append; for flds:=0 to rtcDS.FieldCount-1 do begin fldname:=rtcDS.FieldName[flds]; field:=DelphiDS.FindField(fldname); if assigned(field) then if not rtcDS.isNull[fldname] then if field.isBlob then begin fstream:=DelphiDS.CreateBlobStream(field,bmWrite); try fstream.CopyFrom(rtcDS.asByteStream[fldname], rtcDS.asByteStream[fldname].Size); finally fstream.Free; end; end else case RTC_FIELD2VALUE_TYPES[rtcDS.FieldType[fldname]] of rtc_Currency: field.AsCurrency:=rtcDS.asCurrency[fldname]; rtc_DateTime: field.AsDateTime:=rtcDS.asDateTime[fldname]; rtc_String: field.AsString:=rtcDS.asString[fldname]; else field.Value:=rtcDS.Value[fldname]; end; end; DelphiDS.Post; rtcDS.Next; end; end;
procedure DelphiDataSetToRtc(DelphiDS:TDataSet; rtcDS:TRtcDataSet; ClearFieldDefs:boolean=True); var fdef:TFieldDef; flds:integer; fldname:string; field:TField; fstream:TStream; begin if ClearFieldDefs then begin rtcDS.Clear; for flds:=0 to DelphiDS.FieldDefs.Count-1 do begin fdef:=DelphiDS.FieldDefs.Items[flds]; fldname:=fdef.Name;
field:=DelphiDS.FindField(fldname); if assigned(field) then if field.FieldKind=fkData then rtcDS.SetField(fldname, RTC_DB2FIELD_TYPE(fdef.DataType), fdef.Size, fdef.Required); end; end;
DelphiDS.First; while not DelphiDS.EOF do begin rtcDS.Append; for flds:=0 to rtcDS.FieldCount-1 do begin fldname:=rtcDS.FieldName[flds]; field:=DelphiDS.FindField(fldname); if assigned(field) then if (field.FieldKind=fkData) and not field.IsNull then if field.isBlob then begin fstream:=DelphiDS.CreateBlobStream(field,bmRead); try if {$IFNDEF FPC} TBlobField(field).GraphicHeader and {$ENDIF} ( (field.DataType = ftGraphic) or (field.DataType = ftTypedBinary) ) then RtcSkipGraphicFieldHeader(fstream); rtcDS.NewByteStream(fldname).CopyFrom(fstream,fstream.Size-fstream.Position); finally fstream.Free; end; end else case RTC_FIELD2VALUE_TYPES[rtcDS.FieldType[fldname]] of rtc_Currency: rtcDS.asCurrency[fldname]:=field.AsCurrency; rtc_DateTime: rtcDS.asDateTime[fldname]:=field.AsDateTime; rtc_String: rtcDS.asString[fldname]:=field.AsString; else rtcDS.Value[fldname]:=field.Value; end; end; DelphiDS.Next; end; end;
procedure DelphiFieldsToRtc(const DelphiDS:TDataSet; const rtcDS:TRtcDataSet); var fdef:TFieldDef; flds:integer; fldname:string; field:TField; begin for flds:=0 to DelphiDS.FieldDefs.Count-1 do begin fdef:=DelphiDS.FieldDefs.Items[flds]; fldname:=fdef.Name;
field:=DelphiDS.FindField(fldname); if assigned(field) then if field.FieldKind=fkData then rtcDS.SetField(fldname, RTC_DB2FIELD_TYPE(fdef.DataType), fdef.Size, fdef.Required); end; end;
procedure DelphiRowToRtc(const DelphiDS:TDataSet; const rtcDS:TRtcDataSet); var flds:integer; fldname:string; field:TField; fstream:TStream; begin rtcDS.Append; for flds:=0 to rtcDS.FieldCount-1 do begin fldname:=rtcDS.FieldName[flds]; field:=DelphiDS.FindField(fldname); if assigned(field) then if (field.FieldKind=fkData) and not field.IsNull then if field.isBlob then begin fstream:=DelphiDS.CreateBlobStream(field,bmRead); try if {$IFNDEF FPC} TBlobField(field).GraphicHeader and {$ENDIF} ( (field.DataType = ftGraphic) or (field.DataType = ftTypedBinary) ) then RtcSkipGraphicFieldHeader(fstream); rtcDS.NewByteStream(fldname).CopyFrom(fstream,fstream.Size-fstream.Position); finally fstream.Free; end; end else case RTC_FIELD2VALUE_TYPES[rtcDS.FieldType[fldname]] of rtc_Currency: rtcDS.asCurrency[fldname]:=field.AsCurrency; rtc_DateTime: rtcDS.asDateTime[fldname]:=field.AsDateTime; rtc_String: rtcDS.asString[fldname]:=field.AsString; else rtcDS.Value[fldname]:=field.Value; end; end; end;
That should solve your problem. Naturally, you should also remove your changes/additions from the "rtcInfo.pas" unit in order to test if the above changes work for you. If it works, then I will release the same changes in the next RTC SDK update (v4.50). Best Regards, Danijel Tkalcec
Title: Re: ObjectFromVariant
Post by: vkorshun on October 17, 2011, 07:23:01 PM
Many thanks. It works.
Best regards, Victor Korshun
|