#1 2021-03-19 12:33:36

w0rker
Member
Registered: 2021-03-19
Posts: 5

mORMot to save interface composition classes into database?

Hey ab,
I already use mORMot for stuff like

  TSQLNamesRecord = class(TSQLRecordNoCase)
  private
    FName: RawUTF8;
  published
    property Name: RawUTF8 read FName write FName stored AS_UNIQUE;
  end;

but I also have some classes that use composition with interfaces so e.g.

  IDirInfo = interface
  ['{10101010-1010-0101-1001-111110110110}']
    function GetDirname(): String;

    property DirName: String read GetDirname;
  end;

  IFileInfo = interface
  ['{10101010-1010-0101-1001-111110110110}']
    function GetFilename(): Integer;
    function GetFileDate(): Integer;

    property Filename: Integer read GetFilename;
    property FileDate: Integer read GetFileDate;
  end;

  // and some other interfaces

and different classes that use these interfaces (implemented as own TAggregatedObject class to reuse them by delegation) as following

  TDirs = class(TInterfacedObject, IDirInfo)
  private
    FDirInfo: IDirInfo;
  public
    constructor Create(...);

    property DirInfo: IDirInfo read FDirInfo implements IDirInfo;
  end;

  TFilesDirs = class(TInterfacedObject, IDirInfo, IFileInfo)
  private
    FDirInfo: IDirInfo;
    FFileInfo: IFileInfo;
  public
    constructor Create(...);

    property DirInfo: IDirInfo read FDirInfo implements IDirInfo;
    property FileInfo: IFileInfo read FFileInfo implements IFileInfo;
  end;

My question is now
1. how to store this info with mORMot
2. how to know if it was TDirs or TFilesDirs if I want to create the class based on my saved data

Thanks in advance!

Offline

#2 2021-03-19 12:38:11

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

Re: mORMot to save interface composition classes into database?

First point is that if you use interface just to store some values, without any try..finally..free block, then use a record instead.
Interfaces were not meant for making DTO, but mostly for abstraction / SOLID code against processing classes.

Currently, interface can't be serialized. They can only be recognized as calbacks for interface-based services.
So interface as properties, or interface with properties are not serialized yet.

The big problem is how to unserialize the interface values?
It is fine to convert into JSON (calling the properties getters and writing the JSON value).
To unserialize the interfaces, we would need to have the interface values already existing, then call the setter methods... but in a lot of cases, we won't have interface instances created.

IMHO this becomes very complicated.
The idea/workaround is to define record/class DTOs or TSQLRecord/TOrm types for SOA or ORM work, and keep the interfaces in the existing business logic.

Offline

#3 2021-03-19 13:14:43

w0rker
Member
Registered: 2021-03-19
Posts: 5

Re: mORMot to save interface composition classes into database?

ab wrote:

First point is that if you use interface just to store some values, without any try..finally..free block, then use a record instead.
Interfaces were not meant for making DTO, but mostly for abstraction / SOLID code against processing classes.

Interfaces are the only way to make sure that all composition classes provide the same properties I need to access in some places in my code, no? With records I could easily forget one and then my program will crash *shrug*

  TDirInfo = record
    FDirName: String;
  end;
  TDirs = class
  private
    FDirInfo: TDirInfo;
  public
    constructor Create(...);
    function ReadDirName: String; // needed because property can't be FDirInfo.FDirName

    property DirName: String read ReadDirName;
  end;

How to reuse all this code in TFilesDirs?

And actually I'm not sending any data or so, it should just be saved to database and reloaded/be available after a restart of it.

Last edited by w0rker (2021-03-19 13:16:29)

Offline

#4 2021-03-19 17:16:32

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

Re: mORMot to save interface composition classes into database?

I am not sure I can really see the benefit of interfaces here - it seems overly complicated to me.
You can compose your objects using regular code, and the factory / aggregate patterns.

Use a set of TSQLRecord/TOrm classes in a (separated) persistence layer, to read and write your business classes like TDirs.
Otherwise, it is not possible for the ORM to know that DirName should be filled from FDirInfo.FDirName.

Offline

Board footer

Powered by FluxBB