#1 2017-03-16 16:07:04

nostroyo
Member
Registered: 2015-08-19
Posts: 16

Recursive nested array pb

Hi!

I'm back to mORMot, I'm doing some test on nested array :
My business object is :

  TTag = class;
// pas d objectlist ds Mormot seulement des array
  TTagDynArray = array of TTag;

  TTag = class(TSQLRecord)
  private
    FSubCat: TTagDynArray;
    FDisplayStr: rawUTF8;
  published
    property SubCategory: TTagDynArray read FSubCat write FSubCat;
    property DisplayStr: rawUTF8 index 200 read FDisplayStr write FDisplayStr;
  end;

I try to use the ORM to store it on a DB
I create a tag sport wich has two subtags (bike and footing)

    FServer := TDbUtility.CreateDb;
    LTag := TTag.Create;
    LTag.DisplayStr := 'Sport';
    LTag2 := TTag.Create;
    LTag2.DisplayStr := 'bike';
    LTag.DynArray('SubCat').Add(LTag2);
    LTag2 := TTag.Create;
    LTag2.DisplayStr := 'footing';
    LTag.DynArray('SubCat').Add(LTag2);
    LID := FServer.Add(LTag, True);
    FreeAndNil(LTag);
    FreeAndNil(Ltag2);
    LTag := TTag.Create(FServer, LID);
    LTag2 := LTag.SubCat[1];

When i fetch the parent tag, the array Subcat[0] is good (bike) but the Subcat[1] always contain the parent tag (sport) himself.

Did i make a mistake somewhere?

Offline

#2 2017-03-16 19:37:13

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

Re: Recursive nested array pb

You need to register the TTagDynArray as T*ObjArray.

Offline

#3 2017-03-17 09:31:36

nostroyo
Member
Registered: 2015-08-19
Posts: 16

Re: Recursive nested array pb

OK, It's work better but with this code :

    LTag := TTag.Create;
    LTag.DisplayStr := 'Sport';
    LTag2 := TTag.Create;
    LTag2.DisplayStr := 'bike';
    FServer.Add(LTag2, True);
    LTag.DynArray('SubCat').Add(LTag2);
    LTag2 := TTag.Create;
    LTag2.DisplayStr := 'footing';
    FServer.Add(LTag2, True);
    LTag.DynArray('SubCat').Add(LTag2);
    LID := FServer.Add(LTag, True);
    FreeAndNil(LTag);
    LTag := TTag.Create(FServer, LID);
    // !subCat is empty!
    LTag2 := LTag.SubCat[1];

The SubCat array is empty, i check the blob on Db it contain the Json object. May i miss someting?

Even if i think i'm going to use a pivot table for these kind of recursive data, i want to make it work for future object wich  contains "regular" dynarray.

Offline

#4 2017-03-17 10:01:47

StxLog
Member
From: France
Registered: 2015-09-14
Posts: 58

Re: Recursive nested array pb

I think dynamic array are saved as BLOB in DB, so you need either to force the retreive by record:

LTag := TTag.Create(FServer, LID);
FServer.RetrieveBlobFields(LTag);
//Access your LTag.SubCat[1] here

or enable forceblobfield at table or DB level with TSQLRestClientURI.ForceBlobTransfert or TSQLRestClientURI.ForceBlobTransfertTable[]

By default, Blob fields aren't retrieved to save bandwith.

Offline

#5 2017-03-17 10:55:55

nostroyo
Member
Registered: 2015-08-19
Posts: 16

Re: Recursive nested array pb

Infortunatly i tried RetrieveBlobFields but its not working either.

Offline

#6 2017-03-18 08:03:31

nostroyo
Member
Registered: 2015-08-19
Posts: 16

Re: Recursive nested array pb

I notice something, the JSON response is not correct the array its a string like this : aXNwbGF5U3RyIjoiYmlrZSJ9LHsiSUQiOjg5LCJTdWJDYXQiOltdLCJEaXNwbGF5U3RyIjoiZm9vdGluZyJ9XQ==

Although if i inspect my blob as text on the DB the string is good : [{"ID":88,"SubCat":[],"DisplayStr":"bike"},{"ID":89,"SubCat":[],"DisplayStr":"footing"}]

Any suggestion?

Offline

#7 2017-03-18 08:06:23

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

Re: Recursive nested array pb

As I wrote above:

You need to register the TTagDynArray as T*ObjArray.

Did you do that?

Offline

#8 2017-03-18 09:21:15

nostroyo
Member
Registered: 2015-08-19
Posts: 16

Re: Recursive nested array pb

you mean by doing this :

initialization
  TJSONSerializer.RegisterObjArrayForJSON(TypeInfo(TTagDynArray), TTag);

Yes i did.

Offline

#9 2017-03-18 12:57:00

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

Re: Recursive nested array pb

Which kind of storage are you using?

Offline

#10 2017-03-18 17:33:12

nostroyo
Member
Registered: 2015-08-19
Posts: 16

Re: Recursive nested array pb

I use firebird

class function TDbUtility.CreateDb: TSQLRestServerDb;
var
  FProp: TSQLDBZEOSConnectionProperties;
begin
  FProp := TSQLDBZEOSConnectionProperties.Create
    (TSQLDBZEOSConnectionProperties.URI(dFirebird, '',
    'D:\Program Files\Firebird\Firebird_2_5\WOW64\fbclient.dll', False),
    'D:\delphi\FriendZone\TestYoann.fdb', 'SYSDBA', 'masterkey');
  VirtualTableExternalRegisterAll(TModelUtility.GetModel, FProp);
  Result := TSQLRestServerDB.Create(TModelUtility.GetModel, 'Test.json');
  Result.CreateMissingTables;

Offline

#11 2017-03-19 09:50:25

nostroyo
Member
Registered: 2015-08-19
Posts: 16

Re: Recursive nested array pb

OK it's a firebird problem because if i use the standard SQLite without VirtualTableExternalRegisterAll, all works fine. I'me going to track what's the problem or switch to the in-built standard sqlite engine.

Last edited by nostroyo (2017-03-19 09:53:22)

Offline

#12 2017-03-19 10:18:58

nostroyo
Member
Registered: 2015-08-19
Posts: 16

Re: Recursive nested array pb

Do you want me to provide my test application for debug?

Offline

Board footer

Powered by FluxBB