synopse / mORMot2

OpenSource RESTful ORM/SOA/MVC Framework for Delphi and FreePascal
https://synopse.info
Other
485 stars 122 forks source link

Variant and TSynDictionary #261

Closed zen010101 closed 2 weeks ago

zen010101 commented 2 weeks ago

It is a wired issue, see comment below:

procedure test_TSynDict;
var
  resp, cnt, soc: Variant;
  dict: TSynDictionary;
  i: integer;
begin
  //resp := api.GetAllNodeInfo;
  //cnt := resp.Content;
  cnt := _Json('[{"id":"01-ebbb3d826b384d54","mac":"02:09:06:00:25:00","position":"1-1"},{"id":"02-25b571e386107169","mac":"02:09:06:00:25:01","position":"1-2"},{"id":"03-6ff4b5f62d282f95","mac":"02:09:06:00:25:02","position":"1-3"},{"id":"04-ec2b895cccd50efc","mac":"02:09:06:00:25:03","position":"1-4"}]');
  // work
  dict := TSynDictionary.New<string, Variant>(True);
  // not work:
  // An unhandled exception occurred at $00000000004C60C0:
  // EDynArray: TDynArray.Init: Variant is rkVariant, expected rkDynArray
  //dict := TSynDictionary.Create(TypeInfo(string), TypeInfo(Variant), True);
  try
    for i := 0 to cnt._Count - 1 do begin
      soc := cnt.Value(i);
      dict.Add(string(soc.mac), soc);
    end;
    if dict.Exists(string(cnt.Value(2).mac)) then begin
       dict.FindAndCopy(string(cnt.Value(2).mac), soc);
       writeln('id: ', soc.id, ' mac: ', soc.mac, ' pos: ', soc.position);
    end else writeln('not found');
  finally
    dict.Free;
  end;
end;

There are two edtions of TSynDictionary creating object, but only the generic edition works. The second method that using Create() will cause an exception when executing cnt._Count

zen010101 commented 2 weeks ago

I have identified the issue and found the correct edition :

dict := TSynDictionary.Create(TypeInfo(TStringDynArray), TypeInfo(TVariantDynArray), True);