unit ormbr.container.objectset;

interface

uses
  Rtti,
  Generics.Collections,
  /// ormbr
  ormbr.container.objectset.interfaces,
  dbebr.factory.interfaces,
  ormbr.objectset.adapter,
  ormbr.register.middleware;

type
  TContainerObjectSet<M: class, constructor> = class(TInterfacedObject, IContainerObjectSet<M>)
  protected
    FObjectSetAdapter: TObjectSetAdapter<M>;
  public
    constructor Create(const AConnection: IDBConnection; const APageSize: Integer = -1);
    destructor Destroy; override;
    function ExistSequence: Boolean;
    function ModifiedFields: TDictionary<String, TDictionary<String, String>>;
    function Find: TObjectList<M>; overload;
    function Find(const AID: Int64): M; overload;
    function Find(const AID: String): M; overload;
    function FindWhere(const AWhere: String; const AOrderBy: String = ''): TObjectList<M>;
    procedure Insert(const AObject: M);
    procedure Update(const AObject: M);
    procedure Delete(const AObject: M);
    procedure Modify(const AObject: M);
    procedure LoadLazy(const AOwner, AObject: TObject);
    procedure NextPacket(const AObjectList: TObjectList<M>); overload; virtual;
    function NextPacket: TObjectList<M>; overload; virtual;
    function NextPacket(const APageSize, APageNext: Integer): TObjectList<M>; overload; virtual;
    function NextPacket(const AWhere, AOrderBy: String; const APageSize, APageNext: Integer): TObjectList<M>; overload; virtual;
  end;

implementation

{ TContainerObjectSet<M> }

constructor TContainerObjectSet<M>.Create(const AConnection: IDBConnection;
  const APageSize: Integer);
begin
  FObjectSetAdapter := TObjectSetAdapter<M>.Create(AConnection, APageSize);
end;

destructor TContainerObjectSet<M>.Destroy;
begin
  FObjectSetAdapter.Free;
  inherited;
end;

procedure TContainerObjectSet<M>.Delete(const AObject: M);
var
  LBeforeDelete: TEvent;
  LAfterDelete: TEvent;
begin
  inherited;
  LBeforeDelete := TORMBrMiddlewares.ExecuteEventCallback(M, 'BeforeDelete');
  if Assigned(LBeforeDelete) then
    LBeforeDelete(AObject);
  FObjectSetAdapter.Delete(AObject);
  LAfterDelete := TORMBrMiddlewares.ExecuteEventCallback(M, 'AfterDelete');
  if Assigned(LAfterDelete) then
    LAfterDelete(AObject);
end;

function TContainerObjectSet<M>.ExistSequence: Boolean;
begin
  inherited;
  Result := FObjectSetAdapter.ExistSequence;
end;

function TContainerObjectSet<M>.Find(const AID: String): M;
begin
  Result := FObjectSetAdapter.Find(AID);
end;

function TContainerObjectSet<M>.FindWhere(const AWhere, AOrderBy: String): TObjectList<M>;
begin
  inherited;
  Result := FObjectSetAdapter.FindWhere(AWhere, AOrderBy);
end;

function TContainerObjectSet<M>.Find(const AID: Int64): M;
begin
  inherited;
  Result := FObjectSetAdapter.Find(AID);
end;

function TContainerObjectSet<M>.Find: TObjectList<M>;
begin
  inherited;
  Result := FObjectSetAdapter.Find;
end;

procedure TContainerObjectSet<M>.Insert(const AObject: M);
var
  LBeforeInsert: TEvent;
  LAfterInsert: TEvent;
begin
  inherited;
  LBeforeInsert := TORMBrMiddlewares.ExecuteEventCallback(M, 'BeforeInsert');
  if Assigned(LBeforeInsert) then
    LBeforeInsert(AObject);
  FObjectSetAdapter.Insert(AObject);
  LAfterInsert := TORMBrMiddlewares.ExecuteEventCallback(M, 'AfterInsert');
  if Assigned(LAfterInsert) then
    LAfterInsert(AObject);
end;

procedure TContainerObjectSet<M>.LoadLazy(const AOwner, AObject: TObject);
begin
  FObjectSetAdapter.LoadLazy(AOwner, AObject);
end;

function TContainerObjectSet<M>.ModifiedFields: TDictionary<String, TDictionary<String, String>>;
begin
  Result := FObjectSetAdapter.ModifiedFields;
end;

procedure TContainerObjectSet<M>.Modify(const AObject: M);
begin
  inherited;
  FObjectSetAdapter.Modify(AObject);
end;

function TContainerObjectSet<M>.NextPacket(const APageSize, APageNext: Integer): TObjectList<M>;
begin
  Result := FObjectSetAdapter.NextPacket(APageSize, APageNext);
end;

function TContainerObjectSet<M>.NextPacket(const AWhere, AOrderBy: String;
  const APageSize, APageNext: Integer): TObjectList<M>;
begin
  Result := FObjectSetAdapter.NextPacket(AWhere, AOrderBy, APageSize, APageNext);
end;

procedure TContainerObjectSet<M>.NextPacket(const AObjectList: TObjectList<M>);
begin
  inherited;
  FObjectSetAdapter.NextPacket(AObjectList);
end;

procedure TContainerObjectSet<M>.Update(const AObject: M);
var
  LBeforeUpdate: TEvent;
  LAfterUpdate: TEvent;
begin
  inherited;
  LBeforeUpdate := TORMBrMiddlewares.ExecuteEventCallback(M, 'BeforeUpdate');
  if Assigned(LBeforeUpdate) then
    LBeforeUpdate(AObject);
  FObjectSetAdapter.Update(AObject);
  LAfterUpdate := TORMBrMiddlewares.ExecuteEventCallback(M, 'AfterUpdate');
  if Assigned(LAfterUpdate) then
    LAfterUpdate(AObject);
end;

function TContainerObjectSet<M>.NextPacket: TObjectList<M>;
begin
  Result := FObjectSetAdapter.NextPacket;
end;

end.
