Tjsonfield, just as Tblob

Looking the record Tblob I was thinking of have a new type of field for JSON DB fields that can expose a TJsonObject instance with its data, if loaded.
For the moment I am using a Tblob and a separate not mapped record in the entity class that reads the blob field and provides the TJsonObject (Managed records are very helpful). Is it possible to "register" this new TJsonfield to use it as we do with Tblob? Having a Tcustomfield managed record that can create-manage-expose any kind of user defined class inside it, can be also very helpful and use a BLOB or JSON field in the database.

A Tcustomblob record available only to last Delphi versions that support managed records can include a TObject variable and anonymous procedures to be set for Initialization/finalization of the record(for the Tobject variable) and import/export of data to deal with the FIntData Tarray when loading/saving.

I am evaluating also the Linq.Sql for querying Json Pairs inside the DB's JSON field. But it is limited to Aurelius and not available to Xdata Crud endpoints as I can understand.
Thank you in advance

We plan to allow registration of custom types in Aurelius, but it's not done yet. But indeed, we plan to do a better support for JSON, supporting TJSONObject, for example.

Why did you used a record instead of a simple, direct TJSONObject type in the class member? Do you want to share more information, how your record was built and what are the advantages?

I have created a managed Record type that has initialization/finalization to create/destroy its object instances and provide functions to deal with JSON content and import/export Tblob's data from/to database.
Now I just declare such a record in the public section of the entity and init it with the Tblob contents when returned by Aurelius. Before save or update the entity, I export to Tblob the content from this record.
And I can leave the destruction of the entity to Aurelius. This record can be used in multiple entities.

See the following as example:

type DJsonrec=record
    private

    public
      js:TJSONObject;
      class operator initialize( out Dest: DJsonrec);
      class operator Finalize( var Dest: DJsonrec);
      function pgetstrvalue(const p:string):string;
end;

{ DJsonrec }

class operator DJsonrec.Finalize(var Dest: DJsonrec);
begin 
     if assigned(dest.js) then dest.js.Free; 
end;

class operator DJsonrec.initialize(out Dest: DJsonrec);
begin 
     dest.js:=nil; 
end;

function DJsonrec.pgetstrvalue(const p: string): string; 
var jj:Tjsonvalue;
begin 
   if not jj.TryGetValue<String>(p,result) then result:=''; 
end;

The other possibility is to override and implement in each entity its constructor/destructor and have a class instance to do the same.

1 Like

An other idea could be, using Generics, to have a Tblob<CustomType> that Tblob will create/destroy and serialize/deserialize with database field content.
I am using also the following:

type Dcustom<T>=record
    private
    public
      v:T;
      function init(bl:tblob):boolean;
      function exportjson:tbytes;
end;

For the above, I usually use a record type and I do not change anything in the entity. Anyway, I have to serialiaze/deserialize the record to Tbytes for Tblob after loading/before saving the entity.
I use the TNeonSerializerJSON/TNeonDeserializerJSON from NEON framework (GitHub - paolo-rossi/delphi-neon: JSON Serialization library for Delphi) that can handle records with array of records inside.
A supported Tblob<CustomRecord> by Aurelius does not need anything more to use json Object fields in Database and representeted as a custom record in the entity.

1 Like