unit CustomerServiceImpl;

interface

uses
  Generics.Collections,
  XData.Server.Module,
  XData.Service.Common,
  Data.DB, FireDAC.Comp.Client, FireDAC.Stan.Param,
  CustomerService, dDatabase;

type
  [ServiceImplementation]
  TCustomerService = class(TInterfacedObject, ICustomerService)
  strict private
    DB: TDatabaseModule;
    function GetQuery: TFDQuery;
  public
    procedure AfterConstruction; override;
    procedure BeforeDestruction; override;
    property Query: TFDQuery read GetQuery;
  public
    { implementation of ICustomerService interface }
    procedure CreateCustomer(Customer: TCustomer);
    function GetCustomers: TList<TCustomer>;
    function GetCustomer(Id: Integer): TCustomer;
    procedure UpdateCustomer(Id: Integer; Customer: TCustomer);
    procedure DeleteCustomer(Id: Integer);
  end;

implementation

{ TCustomerService }

procedure TCustomerService.AfterConstruction;
begin
  inherited;
  DB := TDatabaseModule.Create(nil);
end;

procedure TCustomerService.BeforeDestruction;
begin
  DB.Free;
  inherited;
end;

procedure TCustomerService.CreateCustomer(Customer: TCustomer);
begin
  Query.SQL.Text := 'INSERT INTO CUSTOMERS VALUES (:id, :name, :country)';
  Query.ParamByName('id').AsInteger := Customer.Id;
  Query.ParamByName('name').AsString := Customer.Name;
  Query.ParamByName('country').AsString := Customer.Country;
  Query.ExecSQL;
end;

procedure TCustomerService.DeleteCustomer(Id: Integer);
begin
  Query.SQL.Text := 'DELETE FROM CUSTOMERS WHERE ID = :id';
  Query.ParamByName('id').AsInteger := Id;
  Query.ExecSQL;
end;

function TCustomerService.GetCustomer(Id: Integer): TCustomer;
begin
  Query.SQL.Text := 'SELECT * FROM CUSTOMERS WHERE ID = :id';
  Query.ParamByName('id').AsInteger := Id;
  Query.Open;
  if Query.IsEmpty then Exit(nil);

  Result := TCustomer.Create;
  TXDataOperationContext.Current.Handler.ManagedObjects.Add(Result);
  Result.Id := Query.FieldByName('ID').AsInteger;
  Result.Name := Query.FieldByName('NAME').AsString;
  Result.Country := Query.FieldByName('COUNTRY').AsString;
end;

function TCustomerService.GetCustomers: TList<TCustomer>;
var
  Customer: TCustomer;
begin
  Result := TList<TCustomer>.Create;
  TXDataOperationContext.Current.Handler.ManagedObjects.Add(Result);
  Query.SQL.Text := 'SELECT * FROM CUSTOMERS';
  Query.Open;
  while not Query.Eof do
  begin
    Customer := TCustomer.Create;
    TXDataOperationContext.Current.Handler.ManagedObjects.Add(Customer);
    Result.Add(Customer);
    Customer.Id := Query.FieldByName('ID').AsInteger;
    Customer.Name := Query.FieldByName('NAME').AsString;
    Customer.Country := Query.FieldByName('COUNTRY').AsString;
    Query.Next;
  end;
end;

function TCustomerService.GetQuery: TFDQuery;
begin
  Result := DB.FDQuery1;
end;

procedure TCustomerService.UpdateCustomer(Id: Integer; Customer: TCustomer);
begin
  Query.SQL.Text := 'UPDATE CUSTOMERS SET NAME = :name, COUNTRY = :country ' +
    'WHERE ID = :id';
  Query.ParamByName('id').AsInteger := Id;
  Query.ParamByName('name').AsString := Customer.Name;
  Query.ParamByName('country').AsString := Customer.Country;
  Query.ExecSQL;
end;

initialization
  RegisterServiceType(TCustomerService);

end.
