#1 2015-02-23 11:24:17

xotox
Member
Registered: 2015-02-07
Posts: 18

SQLRecord.FillPrepareMany serialization to client

Hi,

i'm building an interface service based application using mORMot. Clients are not allowed to directly use TSQLRecord.Retrieve, Server.Add, Server.Update etc. methods. Client/Server communication is always done using the interface service.
I need some advice now...

My DataModel uses a lot of TSQLRecordMany classes. Inside the business logic theres a heavy use of SQLRecord.FillPrepareMany(fServer, 'DestList.Dest.ID=?', [id]);
This content has to be serialized and sent to the client somehow. Whats the best practice for doing this?

Similiar code is used on server-side:

  SQLRecord.FillPrepareMany(fServer, 'DestList.Dest.ID=?', [], [id]);
  while SQLRecord.FillOne do
  begin
    // should i serialize every single dataset using ObjectToJSON, append them one to each other, then send back to client?
    // problem is ObjectToJSON will not serialize the nested DestList.Dest object.

  end;

Is there a way to say: hey, take the whole SQLRecord thing, fill all rows, send to client using some kind of Table/RawJSON/whatever. Including the nested DestList.Dest class if possible?

Thanks in advance.

Offline

#2 2015-02-23 13:25:55

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

Re: SQLRecord.FillPrepareMany serialization to client

I've introduce the new TSQLRecord.EnginePrepareMany() method.

    /// compute a JOINed statement including TSQLRecordMany fields
    // - is called by FillPrepareMany() to retrieve the JSON of the corresponding
    // request: so you could use this method to retrieve directly the same
    // information, ready to be transmitted (e.g. as RawJSON) to a client  
    function EnginePrepareMany(aClient: TSQLRest; const aFormatSQLJoin: RawUTF8;
      const aParamsSQLJoin, aBoundsSQLJoin: array of const;
      out ObjectsClass: TSQLRecordClassDynArray; out SQL: RawUTF8): RawUTF8;

See http://synopse.info/fossil/info/49e187cbed

So you can send directly the JSON - as RawJSON variable - to the client.

There is no direct way of restoring the field mapping on the client side...
So I guess the easiest is to use a TSQLTableJSON on the client from the returned JSON, then retrieve the information using its corresponding methods: either a for ... loop with GetAs() methods, or using Step() + FieldAs*().

Offline

#3 2015-02-23 15:03:54

xotox
Member
Registered: 2015-02-07
Posts: 18

Re: SQLRecord.FillPrepareMany serialization to client

Thanks a lot!

I'll give it a try in a few mins...

Offline

#4 2015-02-23 15:25:12

xotox
Member
Registered: 2015-02-07
Posts: 18

Re: SQLRecord.FillPrepareMany serialization to client

There's a Problem, the returned JSON contains field names like "AID, A01, A02, ...", but not the real fieldnames. Is there a way to get the real fieldnames out of this?

Edit:
Ok, that was not the real Problem.

function TSQLRecord.EnginePrepareMany(aClient: TSQLRest; const aFormatSQLJoin: RawUTF8;
  const aParamsSQLJoin, aBoundsSQLJoin: array of const;
  out ObjectsClass: TSQLRecordClassDynArray; out SQL: RawUTF8): RawUTF8;

I could pass ObjectsClass and SQL back to the client. On client side following code is executed

var
  T: TSQLTable;
  source: TSQLSource;
  SQL, JSON: RawUTF8; 

...
  
  T := TSQLTableJSON.CreateFromTables([TSQLSource, TSQLDestList, TSQLDest], SQL, JSON);
  for i:=0 to T.RowCount-1 do
  begin
    source.FillFrom(T, i);
    CheckNot(source.SourceField1 = '');  // success, SourceField1 filled.                
    CheckNot(source.DestList.PivotField1 = ''); // success, Pivot field filled.
    CheckNot(source.DestList.Dest.DestField1 = '');  // this crashes, source.DestList.Dest is not initialized.
  end;

Is there some way to let TSQLRecord.FillFrom create Dest instances? The JSON RawUTF8 String contains all necessary informations to do this ...in theory at least smile

Last edited by xotox (2015-02-23 18:26:51)

Offline

Board footer

Powered by FluxBB