You are not logged in.
Pages: 1
Methods of interface inherited from IInvokable do not accept params of array of const.
So I pass array of variant, and make revert convertion at server side.
Interface.Method
function Query(out ItemList: TObjectList; const Sample: TSQLRecord;
const Params: string; const Bounds: array of Variant): Integer;
invert convertion
procedure MakeBounds(Variants: array of Variant; var VarRecs: TVarRecArray);
var
I: Integer;
begin
SetLength(VarRecs, Length(Variants));
for I := Low(Variants) to High(Variants) do
VariantToVarRec(Variants[i], VarRecs[i]);
end;
function TCoreResources.Query(out ItemList: TObjectList; const Sample: TSQLRecord;
const Params: string; const Bounds: array of Variant): Integer;
var
vBounds: TVarRecArray;
begin
MakeBounds(Bounds, vBounds);
ItemList := GetCoreService.RetrieveList(PSQLRecordClass(Sample)^,
Params, vBounds);
if Assigned(ItemList) then Result := ItemList.Count else Result := 0;
end;
Exception
20150523 19303823 ! EXC ESynException ("TJSONSerializer.AddVariantJSON(VType=
64808)") at 004361D9 stack trace API 004429A2 0040492C
! Core service - Test got interface core resources
! Exception ESynException raised with messsage:
! TJSONSerializer.AddVariantJSON(VType=64808)
Exception occured in TTextWriter.AddVariantJSON, where variant.VType = 64808,but param passed is just AnsiString 'Hello'.
Somebody help?
Offline
You need a true fixed type for each parameter, e.g. TVariantDynArray type in this case.
But I think that the best is just to use a single variant as parameter, passing a TDocVariant custom type, using e.g. _ArrFast([...]).
_ArrFast([...]) will allow to use an array of const, convert it into a TDocVariant custom variant type, passed as variant kind of parameter, and serialized properly as JSON on the wire.
BTW, do not forget to use "const" for array parameters:
MakeBounds(const Variants: array of Variant...
for best performance.
Offline
You need a true fixed type for each parameter, e.g. TVariantDynArray type in this case.
But I think that the best is just to use a single variant as parameter, passing a TDocVariant custom type, using e.g. _ArrFast([...]).
_ArrFast([...]) will allow to use an array of const, convert it into a TDocVariant custom variant type, passed as variant kind of parameter, and serialized properly as JSON on the wire.BTW, do not forget to use "const" for array parameters:
MakeBounds(const Variants: array of Variant...
for best performance.
Thanks ab.
For the params accept by FormatUTF8 is only array of const.
I dident found any method that make the conversion from TDocVariant to array of const.
Some hints?
Or make a choice of using RetrieveListJSON method for the absence of SQLWhereBounds?
Offline
I've added the new TDocVariantData.ToArrayOfConst overloaded functions, which are able to be passed as FormatUTF8() parameter.
See http://synopse.info/fossil/info/d3f44776ea
var vr: TTVarRecDynArray;
....
Doc.ToArrayOfConst(vr);
s := FormatUTF8('[?,?,?]',[],vr,true);
check(s='["one",2,3]');
s := FormatUTF8('[%,%,%]',vr,[],true);
check(s='[one,2,3]');
s := FormatUTF8('[?,?,?]',[],Doc.ToArrayOfConst,true);
check(s='["one",2,3]');
s := FormatUTF8('[%,%,%]',Doc.ToArrayOfConst,[],true);
check(s='[one,2,3]');
Offline
I've added the new TDocVariantData.ToArrayOfConst overloaded functions, which are able to be passed as FormatUTF8() parameter.
See http://synopse.info/fossil/info/d3f44776ea
Thank you ab!
This patch really fix my situation.
My codes
function MakeBounds(Bounds: array of const): Variant; overload;
begin
Result := _ArrFast(Bounds);
end;
function MakeBounds(Bounds: Variant): TTVarRecDynArray; overload;
begin
Result := TDocVariantData(Bounds).ToArrayOfConst;
end;
Offline
Happy to help.
You may have coded:
function MakeBounds(const Bounds: array of const): Variant; overload; inline;
begin
Result := _ArrFast(Bounds);
end;
function MakeBounds(const Bounds: Variant): TTVarRecDynArray; overload; inline;
begin
DocVariantDataSafe^(Bounds).ToArrayOfConst(result);
end;
Offline
Happy to help.
You may have coded:
function MakeBounds(const Bounds: array of const): Variant; overload; inline; begin Result := _ArrFast(Bounds); end;
TYVM ab!
This inline is a key word I never ever uses.
Offline
Hi AB,
procedure TForm1.Button1Click(Sender: TObject);
var
vBounds : variant;
vArrOfConst : TTVarRecDynArray;
begin
vBounds := _ArrFast([1000,'HELLO WORLD',NOW]);
vArrOfConst := TDocVariantData(vBounds).ToArrayOfConst;
ShowMessage(String(vArrOfConst[1].vPChar));
end;
Why I don't see "HELLO WORLD" ?
Thank you.
Offline
Thank you AB.
It becomes,
ShowMessage(vArrOfConst[1].vVariant^);
It is a very useful feature for passing param Query.
Last edited by Cahaya (2015-06-30 06:37:48)
Offline
Hi AB,
vJSONContent := '{"Customer_No":1,"Name":"Cahaya Harapan"}';
v := _Json(vJsonContent);
how to convert DocVariantDataSafe(v)^.Values to array of const ? In this case [1,'Cahaya Harapan']
Thanks a lot
Offline
Sorry AB, I will answer my own question.
procedure TForm1.btVariantClick(Sender: TObject);
var
vVar : variant;
vVarRec : TTVarRecDynArray;
//vJsonContent : rawUTF8;
begin
//vJSONContent := '{"customers":[{"Customer_No":1,"Name":"Cahaya Harapan"},{"Customer_No":2,"Name":"Dustin Tsai"}]}';
//vJSONContent := '{"Customer_No":1,"Name":"Cahaya Harapan"}';
//v := _Json(vJsonContent);
vVar := _ArrFast([]); {Custom type of variant by mormot}
DocVariantData(vVar)^.AddItem(1);
DocVariantData(vVar)^.AddItem('Cahaya Harapan');
vVarRec := DocVariantData(vVar)^.ToArrayOfConst;
SQLValues(vVarRec);
end;
AB, I can not pass array of variant to DocVariantData.ToArrayOfConst. Is it normal because you use custom vartype in mormot variant.
Thank you alot.
Last edited by Cahaya (2015-07-25 02:33:14)
Offline
Pages: 1