unit XData.Query.Exceptions;

interface

uses
  XData.Query.Expression,
  XData.Query.Tokenizer,
  XData.Sys.Exceptions;

type
  EQueryError = class(EXDataHttpException)
  public
  end;

  EBaseQuerySyntaxError = class(EQueryError)
  public
    constructor Create(AToken: TQueryTokenizer; Msg: string);
  end;

  EQuerySyntaxError = class(EBaseQuerySyntaxError)
  public
    constructor Create(AToken: TQueryTokenizer);
  end;

  EQueryUnterminatedStringError = class(EBaseQuerySyntaxError)
  public
    constructor Create(AToken: TQueryTokenizer);
  end;

  EQueryInvalidCharError = class(EBaseQuerySyntaxError)
  public
    constructor Create(AToken: TQueryTokenizer; C: Char);
  end;

  EQueryInvalidDateTimeError = class(EBaseQuerySyntaxError)
  public
    constructor Create(AToken: TQueryTokenizer);
  end;

  EQueryInvalidGuidError = class(EBaseQuerySyntaxError)
  public
    constructor Create(AToken: TQueryTokenizer);
  end;

  EQueryInvalidNumberError = class(EBaseQuerySyntaxError)
  public
    constructor Create(AToken: TQueryTokenizer);
  end;

  EQueryInvalidOperatorSyntaxError = class(EBaseQuerySyntaxError)
  public
    constructor Create(AToken: TQueryTokenizer; const Oper: string);
  end;

  EQueryInternalUnsupportedLiteralTypeError = class(EBaseQuerySyntaxError)
  public
    constructor Create(AToken: TQueryTokenizer);
  end;

  EQueryParenCloseExpectedError = class(EBaseQuerySyntaxError)
  public
    constructor Create(AToken: TQueryTokenizer);
  end;

  EQueryIndentifierExpectedError = class(EBaseQuerySyntaxError)
  public
    constructor Create(AToken: TQueryTokenizer);
  end;

  EQueryUnknownMethodError = class(EBaseQuerySyntaxError)
  public
    constructor Create(AToken: TQueryTokenizer; const MethodName: string);
  end;

  EQueryWrongArgumentCountError = class(EBaseQuerySyntaxError)
  public
    constructor Create(AToken: TQueryTokenizer; AActual, AMin, AMax: Integer);
  end;

  EQueryNoBooleanMethodError = class(EBaseQuerySyntaxError)
  public
    constructor Create(const Expr: TMethodCallExpression);
  end;

  EQueryInvalidSkip = class(EQueryError)
  public
    constructor Create(const Value: string);
  end;

  EQueryInvalidTop = class(EQueryError)
  public
    constructor Create(const Value: string);
  end;

  EQueryInvalidInlineCount = class(EQueryError)
  public
    constructor Create(const Value: string);
  end;

  EQueryUnsupportedProjection = class(EQueryError)
  public
    constructor Create(const Expr: TQueryExpression);
  end;

  EQueryUnsupportedCondition = class(EQueryError)
  public
    constructor Create(const Expr: TQueryExpression);
  end;

  EQueryUnsupportedExpand = class(EQueryError)
  public
    constructor Create(const Expr: TQueryExpression);
  end;

  EQueryInvalidExpand = class(EQueryError)
  public
    constructor Create(const Name: string);
  end;

  EQueryInvalidOperatorError = class(EQueryError)
  public
    constructor Create(const Oper: string);
  end;

  EQueryUnknownProperty = class(EQueryError)
  public
    constructor Create(const AName: string);
  end;

implementation

uses
  SysUtils;

{ EBaseQuerySyntaxError }

constructor EBaseQuerySyntaxError.Create(AToken: TQueryTokenizer; Msg: string);
begin
  if Msg = '' then
    case AToken.TokenType of
      TQueryTokenType.Identifier:
        Msg := Format('Invalid identifier "%s"', [AToken.IdValue]);
      TQueryTokenType.TextLiteral:
        Msg := 'Invalid string literal';
      TQueryTokenType.IntegerLiteral:
        Msg := 'Invalid integer literal';
      TQueryTokenType.Int64Literal:
        Msg := 'Invalid int64 literal';
      TQueryTokenType.DoubleLiteral:
        Msg := 'Invalid double literal';
      TQueryTokenType.BooleanLiteral:
        Msg := 'Invalid boolean literal';
      TQueryTokenType.NullLiteral:
        Msg := 'Invalid null literal';
      TQueryTokenType.DateTimeLiteral:
        Msg := 'Invalid datetime literal';
      TQueryTokenType.GuidLiteral:
        Msg := 'Invalid guid literal';
      TQueryTokenType.OpenParen:
        Msg := 'Invalid char "("';
      TQueryTokenType.CloseParen:
        Msg := 'Invalid char ")"';
      TQueryTokenType.Slash:
        Msg := 'Invalid char "/"';
      TQueryTokenType.Comma:
        Msg := 'Invalid char ","';
      TQueryTokenType.Negate:
        Msg := 'Invalid char "-"';
      TQueryTokenType.EOF:
        Msg := 'Unterminated expression';
    else
      Msg := 'Syntax error';
    end;
  inherited CreateFmt(400, '%s at position %d', [Msg, AToken.LastPosition]);
end;

{ EQueryUnknownProperty }

constructor EQueryUnknownProperty.Create(const AName: string);
begin
  inherited CreateFmt(400, 'Unknown property "%s" in query string', [AName]);
end;

{ TQueryUnsupportedProjection }

constructor EQueryUnsupportedProjection.Create(const Expr: TQueryExpression);
begin
  inherited CreateFmt(400, 'Invalid or unsupported query projection: "%s"', [Expr.ClassName]);
end;

{ EQueryInvalidOperatorError }

constructor EQueryInvalidOperatorError.Create(const Oper: string);
begin
  inherited CreateFmt(400, 'Internal error: unsupported operator "%s" in condition', [Oper]);
end;

{ EQueryUnsupportedCondition }

constructor EQueryUnsupportedCondition.Create(const Expr: TQueryExpression);
begin
  inherited CreateFmt(400, 'Invalid or unsupported query condition: "%s"', [Expr.ClassName]);
end;

{ EQueryInvalidTop }

constructor EQueryInvalidTop.Create(const Value: string);
begin
  inherited CreateFmt(400, 'Invalid $top value: "%s"', [Value]);
end;

{ EQueryInvalidSkip }

constructor EQueryInvalidSkip.Create(const Value: string);
begin
  inherited CreateFmt(400, 'Invalid $skip value: "%s"', [Value]);
end;

{ EQueryUnterminatedStringError }

constructor EQueryUnterminatedStringError.Create(AToken: TQueryTokenizer);
begin
  inherited Create(AToken, 'Unterminated string');
end;

{ EQueryInvalidNumberError }

constructor EQueryInvalidNumberError.Create(AToken: TQueryTokenizer);
begin
  inherited Create(AToken, 'Invalid number');
end;

{ EQueryInvalidDateTimeError }

constructor EQueryInvalidDateTimeError.Create(AToken: TQueryTokenizer);
begin
  inherited Create(AToken, 'Invalid date time');
end;

{ EQueryInvalidGuidError }

constructor EQueryInvalidGuidError.Create(AToken: TQueryTokenizer);
begin
  inherited Create(AToken, 'Invalid guid');
end;

{ EQueryInvalidOperatorSyntaxError }

constructor EQueryInvalidOperatorSyntaxError.Create(AToken: TQueryTokenizer; const Oper: string);
begin
  inherited Create(AToken, Format('Invalid operator "%s"', [Oper]));
end;

{ EQueryParenCloseExpectedError }

constructor EQueryParenCloseExpectedError.Create(AToken: TQueryTokenizer);
begin
  inherited Create(AToken, 'Parenthesis close ")" expected');
end;

{ EQueryIndentifierExpectedError }

constructor EQueryIndentifierExpectedError.Create(AToken: TQueryTokenizer);
begin
  inherited Create(AToken, 'Identifier expected');
end;

{ EQueryInternalUnsupportedLiteralTypeError }

constructor EQueryInternalUnsupportedLiteralTypeError.Create(AToken: TQueryTokenizer);
begin
  inherited Create(AToken, 'Internal error: unsupported literal type');
end;

{ EQueryWrongArgumentCountError }

constructor EQueryWrongArgumentCountError.Create(AToken: TQueryTokenizer; AActual, AMin, AMax: Integer);
begin
  if AMin = AMax then
    inherited Create(AToken,
      Format('Wrong argument count in method call. Expected: %d; Actual: %d',
      [AMin, AActual]))
  else
    inherited Create(AToken,
      Format('Wrong argument count in method call. Expected: %d to %d; Actual: %d',
      [AMin, AMax, AActual]));
end;

{ EQueryUnknownMethodError }

constructor EQueryUnknownMethodError.Create(AToken: TQueryTokenizer; const MethodName: string);
begin
  inherited Create(AToken, Format('Unknown method "%s"', [MethodName]));
end;

{ EQuerySyntaxError }

constructor EQuerySyntaxError.Create(AToken: TQueryTokenizer);
begin
  inherited Create(AToken, '');
end;

{ EQueryInvalidCharError }

constructor EQueryInvalidCharError.Create(AToken: TQueryTokenizer; C: Char);
begin
  inherited Create(AToken, Format('Invalid char "%s"', [C]));
end;

{ EQueryInvalidInlineCount }

constructor EQueryInvalidInlineCount.Create(const Value: string);
begin
  inherited CreateFmt(400, 'Invalid $inlinecount value: "%s"', [Value]);
end;

{ EQueryUnsupportedExpand }

constructor EQueryUnsupportedExpand.Create(const Expr: TQueryExpression);
begin
  inherited CreateFmt(400, 'Invalid or unsupported expand expression: "%s"', [Expr.ClassName]);
end;

{ EQueryInvalidExpand }

constructor EQueryInvalidExpand.Create(const Name: string);
begin
  inherited CreateFmt(400, 'Property "%s" cannot be expanded', [Name]);
end;

{ EQueryNoBooleanMethodError }

constructor EQueryNoBooleanMethodError.Create(const Expr: TMethodCallExpression);
begin
  inherited CreateFmt(400, 'Method "%s" does not return a boolean value',
    [Expr.Method.SQLFunctionName]);
end;

end.
