unit XData.Query;

interface

uses
  SysUtils,
  Bcl.Utils,
  Bcl.Json.Attributes;

type
  [JsonInclude(TInclusionMode.NonDefault)]
  TXDataQuery = class
  strict private
    [JsonProperty('$filter')]
    FFilter: string;
    [JsonProperty('$orderby')]
    FOrderBy: string;
    [JsonProperty('$top')]
    FTop: Integer;
    [JsonProperty('$skip')]
    FSkip: Integer;
    procedure AddParam(var Query: string; const Name, Value: string);
  public
    constructor Create(const AFilter: string = ''; const AOrderBy: string = '';
      const ATop: Integer = 0; const ASkip: Integer = 0);
    function IsEmpty: Boolean;
    function QueryString: string;
    property Filter: string read FFilter write FFilter;
    property OrderBy: string read FOrderBy write FOrderBy;
    property Top: Integer read FTop write FTop;
    property Skip: Integer read FSkip write FSkip;
  end;

implementation

{ TXDataQuery }

procedure TXDataQuery.AddParam(var Query: string; const Name, Value: string);
begin
  if Query <> '' then
    Query := Query + '&';
  Query := Query + TBclUtils.PercentEncode(Name) + '=' + TBclUtils.PercentEncode(Value);
end;

constructor TXDataQuery.Create(const AFilter, AOrderBy: string; const ATop, ASkip: Integer);
begin
  inherited Create;
  FFilter := AFilter;
  FOrderBy := AOrderBy;
  FTop := ATop;
  FSkip := ASkip;
end;

function TXDataQuery.IsEmpty: Boolean;
begin
  Result := (Filter = '') and (OrderBy = '') and (Top = 0) and (Skip = 0);
end;

function TXDataQuery.QueryString: string;
begin
  Result := '';
  if Filter <> '' then
    AddParam(Result, '$filter', Filter);
  if OrderBy <> '' then
    AddParam(Result, '$orderby', OrderBy);
  if Top > 0 then
    AddParam(Result, '$top', IntToStr(Top));
  if Skip > 0 then
    AddParam(Result, '$skip', IntToStr(Skip));
end;

end.
