You are not logged in.
Pages: 1
TD2:=_ObjFast(Product2,[woRawByteStringAsBase64Magic]);
json:=TDocVariantData(TD2).ToJson;
Result: json = 'null'
Very strange !
I am sorry, but I cannot get it to work unfortunately. I am doing something wrong, but have no clue.
Code.
TProduct2 = class(TCollectionItem)
strict private
fProductCode : RawUTF8;
fThumb : RawBlob;
published
property ProductCode : RawUTF8 read fProductCode write fProductCode;
property Thumb : RawBlob read fThumb write fThumb;
end;
Product2:=TProduct2.Create(nil);
Product2.ProductCode:='yolo';
Product2.Thumb:='don'#0'alfredo';
//TD2:=_ObjFast(Product2);
//TD2:=_ObjFast(Product2,[woRawBlobAsBase64]);
TD2:=_ObjFast(Product2,[woRawBlobAsBase64,woRawByteStringAsBase64Magic]);
json:=TDocVariantData(TD2).ToJson; // as check of raw contents
DocVariantToObject(_Safe(TD2)^,Product2);
I was hoping for something (some magic) I missed. But I will use manual detection on client and server as you suggest.
Thanks Ab.
Is woRawBlobAsBase64 really needed?
I am sending over some fields by converting them to a variant like this
rA := Rtti.RegisterClass(PClass(Product)^);
pa := rA.Props.Find(FieldName);
pa^.GetValueVariant(Product,TVarData(TD2), @JSON_[mDefault]);
TDocVariantData(TD).AddValue(FieldName,TD2);
Problem with the thumb: binary data containing zero's. So, when sending over (interface based), the zero's prevent correct json data when the variant is converted into json and back. The [json] data gets truncated at the first zero encountered.
Naturally, like rawblobs, using base64 solved this. As done by ObjectToVariant. But no auto-detection of base64 contents when converting back.
it is possible that a valid BASE-64 text is in fact a binary
Indeed !
Hello.
The following code does not work for RawBlobs.
Product is a CollectionItem with a RawBlob as one of its fields.
rA := Rtti.RegisterClass(PClass(Product)^);
ObjectToVariant(Product,TD2,[woRawBlobAsBase64]);
DocVariantToObject(_Safe(TD2)^,Product,rA);
After this conversion, the Rawblob field contains the Base64 encoded data and not the original contents.
Am I missing something ?
I have added a local connect and a remote connect button into the client.
That gives you the easy choice.
Also added some default database files with example data.
Correct !
Solved. Please update your sources from the Github demo.
:-)
And, the proceedings will be donated to the mORMot !
Working 100%. Thanks !!
I am trying to use DocVariantToObject to fill an object from a variant.
Looking at the code.
if prop <> nil then
prop^.Prop.SetValue(obj, doc.Values[p]);
This does not check the return-value of SetValue.
However, the return-value is false in case of complex fields.
So, when using this function with objects that contain classes like TCollection, then DocVariantToObject will not fill all fields.
Suggestion.
Valid := prop^.Prop.SetValue(obj,doc.Values[p]);
if (NOT Valid) then
begin
json:=TDocVariantData(doc.Values[p]).ToJson;
PropertyFromJson(prop,obj,pointer(json),Valid,JSONPARSER_TOLERANTOPTIONS);
end;
Works perfect. Thanks !!
Fields:=TOrmProduct.OrmProps.FieldBitsFromExcludingClass([TDataRunCollection],ooSelect,True);
Thanks Ab ! Solves.
If I may hack this thread for another TCollection question.
In my applications, I use TCollections a lot. They might contain a lot of data. And this data is stored as JSON in the database for external use by non-mORMot applications.
All very well.
However, I would like to consider these TCollection fields as a kind of blobs, due to their huge data-size. So, I want to exclude them when retrieving data from the database.
Code for that (please excuse me for a bit long code listing):
rA := Rtti.RegisterClass(TOrmProduct);
pa := pointer(rA.Props.List);
count:=rA.Props.Count;
SQL:='';
repeat
if pa^.Value.ValueRtlClass=vcCollection then
begin
if pa^.Value.ValueClass.ClassParent=TDataRunCollection then SQL:=SQL+','+pa^.Name;
end;
inc(pa);
dec(count);
until count = 0;
Delete(SQL,1,1);
Fields:=TOrmProduct.OrmProps.FieldBitsFromExcludingCsv(SQL);
Question. Or feature request.
Would it be possible to implement something like this ?
Fields:=TOrmProduct.OrmProps.FieldBitsFromExcludingFromDataType(TDataRunCollection);
Fields:=TOrmProduct.OrmProps.FieldBitsFromExcludingFromClassParent(TDataRunCollection);
Yes I guess. This occurs in an interface based client-server setting.
A memory leak is occurring when doing the following.
TResultsRun = class(TCollectionItem)
private
fTDC : TTestDataCollection;
protected
function GetNewerTestData:TTestDataCollection;
procedure SetNewerTestData(aValue:TTestDataCollection);
public
constructor Create(ACollection: TCollection); override;
destructor Destroy;override;
published
//property NewerTestData : TTestDataCollection read fTDC write fTDC; <----- all ok !!
property NewerTestData : TTestDataCollection read GetNewerTestData write SetNewerTestData; <----- memory leak
end;
(the getter and setter are simple assignments)
Are getters and setters supported for collections ?
I use the TRttiMap to map a DTO to ORM. Works very well.
But sometimes, we need to update a single value of the DTO/ORM.
Normally, the function Orm.Update(OrmEntity,FieldName) would be good. However, the DTO fieldname might be different from the ORM fieldname. Naturally, that is why the mapping is used.
To use this function, we need something like:
TRttiMap.FindField.ToB(FieldNameOfA):RawUTF8;
TRttiMap.FindField.ToA(FieldNameOfB):RawUTF8;
Thanks !
This might help.
https://reviews.freebsd.org/rS350481
Pages: 1