Extend TMyTable

Discussion of open issues, suggestions and bugs regarding MyDAC (Data Access Components for MySQL) for Delphi, C++Builder, Lazarus (and FPC)
Post Reply
SoftTouch.Pieter
Posts: 3
Joined: Wed 19 Sep 2012 14:22

Extend TMyTable

Post by SoftTouch.Pieter » Mon 15 Oct 2012 15:02

Hi all,

Only working with Delphi (delphi xe) for 2 months now and I'm stumbling across a problem extending the MyAccess.TMyTable class and implementing an extra generics based interface. If you consider the first code block below you'll notice at the end that I call the save function for each mapper. The save function of the last mapper is never called and just skipped. I suspect it has something to do with the interface implementation of the TMyTable class. Could someone point out to me why this is happening?

Main application:

Code: Select all

program Project1;
uses
  Forms, classes,
  Unit1 in 'Unit1.pas' {Form1} ,
  Unit2 in 'Unit2.pas',
  Unit3 in 'Unit3.pas';

{$R *.res}

var
  Mapper1: Unit3.TObjectMapper1;
  Mapper2: Unit3.TObjectMapper2;
  Mapper3: Unit3.TObjectMapper3;
  Object1,Object2,Object3: Unit3.Tobject1;
  Main: Unit3.TObject4;
begin
  Application.Initialize;
  Application.MainFormOnTaskbar := True;
  Application.CreateForm(TForm1, Form1);

  Mapper1 := Unit3.TObjectMapper1.Create(Application as TComponent);
  Mapper2 := Unit3.TObjectMapper2.Create(Application as TComponent);
  Mapper3 := Unit3.TObjectMapper3.Create(Application as TComponent);

  Main := TObject4.Create;
  Main.Mapper1 := Mapper1;
  Main.Mapper2 := Mapper2;
  Main.Mapper3 := Mapper3;

  Object1 := Main.Mapper1.Save(nil);
  Object2 := Main.Mapper2.Save(nil);
  Object3 := Main.Mapper3.Save(nil);

  Application.Run;

end.
Interface implemented by the mappers:

Code: Select all

unit Unit2;
interface
uses Generics.Collections;
type
  IAbstract<T> = Interface
    ['{9825427D-25CB-47B0-8549-4D2810AEDB16}']
    function FindAll(): TObjectDictionary<String, T>;
    function Find(Select: String): T;
    function Save(Obj: T): T;
    function Remove(Obj: T): Boolean;
  End;
implementation
end.
Main unit with mappers:

Code: Select all

unit Unit3;

interface

uses Unit2, Generics.collections, MyAccess;

type
  Tobject1 = Class
  End;

  TObject4 = Class
    mapper1: IAbstract<Tobject1>;
    mapper2: IAbstract<Tobject1>;
    mapper3: IAbstract<Tobject1>;
  End;

  TObjectMapper1 = class(MyAccess.TMyTable, IAbstract<Tobject1>)
    function FindAll(): TObjectDictionary<String, Tobject1>;
    function Find(Select: String): Tobject1;
    function Save(Obj: Tobject1): Tobject1;
    function Remove(Obj: Tobject1): Boolean;
  End;

  TObjectMapper2 = class(MyAccess.TMyTable, IAbstract<Tobject1>)
    function FindAll(): TObjectDictionary<String, Tobject1>;
    function Find(Select: String): Tobject1;
    function Save(Obj: Tobject1): Tobject1;
    function Remove(Obj: Tobject1): Boolean;
  End;

  TObjectMapper3 = class(MyAccess.TMyTable, IAbstract<Tobject1>)
    function FindAll(): TObjectDictionary<String, Tobject1>;
    function Find(Select: String): Tobject1;
    function Save(Obj: Tobject1): Tobject1;
    function Remove(Obj: Tobject1): Boolean;
  End;

implementation

function TObjectMapper1.FindAll(): TObjectDictionary<String, Tobject1>;
begin

end;

function TObjectMapper1.Find(Select: String): Tobject1;
begin

end;

function TObjectMapper1.Save(Obj: Tobject1): Tobject1;
begin

end;

function TObjectMapper1.Remove(Obj: Tobject1): Boolean;
begin

end;

function TObjectMapper2.FindAll(): TObjectDictionary<String, Tobject1>;
begin

end;

function TObjectMapper2.Find(Select: String): Tobject1;
begin

end;

function TObjectMapper2.Save(Obj: Tobject1): Tobject1;
begin

end;

function TObjectMapper2.Remove(Obj: Tobject1): Boolean;
begin

end;

function TObjectMapper3.FindAll(): TObjectDictionary<String, Tobject1>;
begin

end;

function TObjectMapper3.Find(Select: String): Tobject1;
begin

end;

function TObjectMapper3.Save(Obj: Tobject1): Tobject1;
begin

end;

function TObjectMapper3.Remove(Obj: Tobject1): Boolean;
begin

end;

end.

SoftTouch.Pieter
Posts: 3
Joined: Wed 19 Sep 2012 14:22

Re: Extend TMyTable

Post by SoftTouch.Pieter » Tue 16 Oct 2012 08:22

Seems like this has little to do with the TMyTable class. Same thing happens when extending the TComponent instead of the TMyTable class. I assume this to be a XE bug. In the XE3 trial, the code is executed like expected.

Hack:
In XE, when I add an extra 'ghost' class in the type declaration, the three mapper save functions are executed.

Code: Select all

  TObjectMapperGhost = class(MyAccess.TMyTable, IAbstract<Tobject>)
    function FindAll(): TObjectDictionary<String, Tobject1>; virtual; abstract;
    function Find(Select: String): Tobject1; virtual; abstract;
    function Save(Obj: Tobject1): Tobject1; virtual; abstract;
    function Remove(Obj: Tobject1): Boolean; virtual; abstract;
  End;

AndreyZ

Re: Extend TMyTable

Post by AndreyZ » Tue 16 Oct 2012 09:46

Hello,

I have checked your code in the following environment:
Windows 7
Delphi XE Version 15.0.3953.35171 Architect
, and there were no problems with the Save method calling, it was called for all three mappers. Please make sure you are using the same version of Delphi XE.

SoftTouch.Pieter
Posts: 3
Joined: Wed 19 Sep 2012 14:22

Re: Extend TMyTable

Post by SoftTouch.Pieter » Tue 16 Oct 2012 10:40

Thanks for your effort in testing this out Andrey.

I'm using Embarcadero® RAD Studio XE Version 15.0.3953.35171 Enterprise on a Windows 7 SP1 64bit machine.

So I take it you don't see a real coding issue here?

AndreyZ

Re: Extend TMyTable

Post by AndreyZ » Tue 16 Oct 2012 13:52

I do not see the coding issue that can cause the problem you encountered. You can write about this problem to the Embarcadero support. Maybe they will give you a more valid answer.

Post Reply