#1 2011-03-19 04:46:38

thunya
Member
Registered: 2011-03-14
Posts: 6

Object Inheritance Mapping

Hard to believe no one ask these question.
Is this framework support "Object Inheritance Mapping" ?

How? or When?

Offline

#2 2011-03-19 07:57:10

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

Re: Object Inheritance Mapping

As far as I understand those concepts, the framework can implement:
- table per class hierarchy
- table per subclass
- table per concrete class.

In fact, the MVC architecture used, implemented via the TSQLModel class, expects a list of classes to be supplied. Those classes will have their own table in the database (either in SQLite, either in other database engine, if it was marked as "static").
So the DB tables are not directly following the class hierarchy, but can take advantage of it.
You can have classes in the hierarchy without any table, but with tables

Since revision 1.13, the published properties of the parents are also added to the table schema.
It makes the ORM classes definition even more simplier than before.

Take a look at the class definitions in our main sample (just updated to reflect the parent properties inclusion):

type
  /// an abstract class, with common fields
  TSQLFile = class(TSQLRecordSigned)
  public
    fName: RawUTF8;
    fModified: TTimeLog;
    fCreated: TTimeLog;
    fPicture: TSQLRawBlob;
    fKeyWords: RawUTF8;
  published
    property Name: RawUTF8 read fName write fName;
    property Created: TTimeLog read fCreated write fCreated;
    property Modified: TTimeLog read fModified write fModified;
    property Picture: TSQLRawBlob read fPicture write fPicture;
    property KeyWords: RawUTF8 read fKeyWords write fKeyWords;
    property SignatureTime;
    property Signature;
  end;

  /// an uncrypted Memo table
  // - will contain some text
  TSQLMemo = class(TSQLFile)
  public
    fContent: RawUTF8;
  published
    property Content: RawUTF8 read fContent write fContent;
  end;

  /// an uncrypted Data table
  // - can contain any binary file content
  // - is also used a parent for all cyphered tables (since the
  // content is crypted, it should be binary, i.e. a BLOB field)
  TSQLData = class(TSQLFile)
  public
    fData: TSQLRawBlob;
  published
    property Data: TSQLRawBlob read fData write fData;
  end;

  /// a crypted SafeMemo table
  // - will contain some text after AES-256 cypher
  // - just a direct sub class ot TSQLData to create the "SafeMemo" table
  // with the exact same fields as the "Data" table
  TSQLSafeMemo = class(TSQLData);

  /// a crypted SafeData table
  // - will contain some binary file content after AES-256 cypher
  // - just a direct sub class ot TSQLData to create the "SafeData" table
  // with the exact same fields as the "Data" table
  TSQLSafeData = class(TSQLData);

  /// an AuditTrail table, used to track events and status
  TSQLAuditTrail = class(TSQLRecord)
  protected
    fStatusMessage: RawUTF8;
    fStatus: TFileEvent;
    fAssociatedRecord: TRecordReference;
    fTime: TTimeLog;
  published
    property Time: TTimeLog read fTime write fTime;
    property Status: TFileEvent read fStatus write fStatus;
    property StatusMessage: RawUTF8 read fStatusMessage write fStatusMessage;
    property AssociatedRecord: TRecordReference read fAssociatedRecord write fAssociatedRecord;
  end;

Only TSQLMemo, TSQLData, TSQLSafeMemo, TSQLSafeData, TSQLAuditTrail will be added to the TSQLModel list.
So TSQLFile won't have any table in the DB, and is used only to provide some common fields/columns, via inheritance.
See http://synopse.info/fossil/finfo?name=S … Tables.pas

Offline

#3 2011-03-20 15:09:40

thunya
Member
Registered: 2011-03-14
Posts: 6

Re: Object Inheritance Mapping

Maybe I doing some mistake. I extend "HTTP Client-Server" sample.
My class model is..

  TSQLSampleRecord = class(TSQLRecord)
  private
    fName: RawUTF8;
    fQuestion: RawUTF8;
    fTime: TDateTime;
  published
    property Name: RawUTF8 read fName write fName;
    property Question: RawUTF8 read fQuestion write fQuestion;
    property Time: TDateTime read fTime write fTime;
  end;

  TSQLInherited = class(TSQLSampleRecord)
  private
    FValue: Integer;
  published
    property Value: Integer read FValue write FValue;
  end;

Then... CreateSampleModel

function CreateSampleModel: TSQLModel;
begin
  result := TSQLModel.Create([TSQLSampleRecord, TSQLInherited]);
end;

On client side....

procedure TForm1.InheritedButtonClick(Sender: TObject);
var Rec: TSQLInherited;
begin
  Rec := TSQLInherited.Create;
  try
    Rec.Time := Now;
    // we use explicit StringToUTF8() for conversion below
    // a real application should use TLanguageFile.StringToUTF8() in SQLite3i18n
    Rec.Name := StringToUTF8(NameEdit.Text);
    Rec.Question := StringToUTF8(QuestionMemo.Text);
    Rec.Value := Random(100);
    if Database.Add(Rec,true)=0 then
      ShowMessage('Error adding the data') else begin
      NameEdit.Text := '';
      QuestionMemo.Text := '';
      NameEdit.SetFocus;
    end;
  finally
    Rec.Free;
  end;
end;

Result in database
inherited.jpg

The data saved to Inherited table with 1 property(Value), Other property is missing
inherited_Value.jpg

Offline

#4 2011-03-21 07:14:39

edwinsn
Member
Registered: 2010-07-02
Posts: 1,218

Re: Object Inheritance Mapping

This is an interesting question.

@thunya, I haven't tried it myself, but have you tried? Just a guess...

function CreateSampleModel: TSQLModel;
begin
  result := TSQLModel.Create([TSQLInherited, TSQLInherited]);
end;


Delphi XE4 Pro on Windows 7 64bit.
Lazarus trunk built with fpcupdelux on Windows with cross-compile for Linux 64bit.

Offline

#5 2011-03-21 07:30:06

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

Re: Object Inheritance Mapping

I suspect inherited properties handling is handled in the source code repository only (up to come revision 1.13).

I think you don't have this version, but the 1.12 version, which does not handle this: you must publish all need properties for each class.

@edwinsn: Your TSQLModel.Create is not correct: there is no need to write the same name twice.

Only the classes which need a table in the database need to be listed in TSQLModel. If TSQLSampleRecord  is not used as it is, but only as TSQLInherited, only TSQLInherited should be in the list.

As I wrote above, e.g. in the main sample, TSQLFile  is not included in TSQLModel.Create():

Offline

#6 2011-03-21 15:22:58

thunya
Member
Registered: 2011-03-14
Posts: 6

Re: Object Inheritance Mapping

1.13? really? Can't wait to see it!!!
I really like this framework. It's ORM, Testable, JSON, Http, Fast, Smart etc.

Could you add some sample to show how to implement custom logic on http server when receiving JSON object?
I plan to inherit TSQLite3HttpServer and override Request function.
But the code is too complicate for me to decode smile

Offline

#7 2011-03-21 15:55:35

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

Re: Object Inheritance Mapping

To implement custom logic on server, and use JSON serialization, you've already server-side RESTful services features included in the framework.

See http://synopse.info/forum/viewtopic.php?pid=233

If you follow this way, you don't need to overload TSQLite3HttpServer Request function.
Just add a published method to the server class, and it will add the corresponding service.
It will work for all kind of communication: direct access, GDI messages, named pipes or HTTP.

Full sample code is available in "SQLite3\Samples\06 - Remote JSON REST Service" subfolder of the source code delivery.

Offline

#8 2011-03-21 15:57:36

edwinsn
Member
Registered: 2010-07-02
Posts: 1,218

Re: Object Inheritance Mapping

Oops, I was in a hurry, sorry.


Delphi XE4 Pro on Windows 7 64bit.
Lazarus trunk built with fpcupdelux on Windows with cross-compile for Linux 64bit.

Offline

#9 2011-03-21 18:43:43

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

Re: Object Inheritance Mapping

edwinsn wrote:

Oops, I was in a hurry, sorry.

wink

Offline

#10 2011-03-22 02:42:54

thunya
Member
Registered: 2011-03-14
Posts: 6

Re: Object Inheritance Mapping

Now I get the latest version in repository. It's work like charm. The mapping is table per concrete class.
I can use it now in my little project smile

To implement custom logic on server, and use JSON serialization, you've already server-side RESTful services features included in the framework.

If you recommended this method I will try it smile
I have some question about this method, I will post in new topic for easy to find wink

Offline

Board footer

Powered by FluxBB