gadeletestm.pas

来自「一个sql语法分析程序」· PAS 代码 · 共 204 行

PAS
204
字号
{*******************************************************}
{                                                       }
{       Advanced SQL statement parser                   }
{       Copyright (c) 2001 AS Gaiasoft                  }
{       Created by Gert Kello                           }
{                                                       }
{*******************************************************}

unit gaDeleteStm;

interface

uses
  gaBasicSQLParser, gaAdvancedSQLParser, gaSQLParserHelperClasses;

type
  TDeleteStatementState = (dssNone, dssDeleteTable, dssWhereClause,
    dssStatementComplete);
  TDeleteStatementStates = set of TDeleteStatementState;

  TgaDeleteSQLStatement = class (TgaCustomSQLStatement)
  private
    FStatementState: TDeleteStatementState;
    FStatementTable: TgaSQLTable;
    FWhereClause: TgaSQLWhereExpression;
    procedure SetStatementState(const Value: TDeleteStatementState);
  protected
    procedure DoAfterStatementStateChange; override;
    procedure DoBeforeStatementStateChange(const NewStateOrd: LongInt); 
            override;
    function GetNewStatementState: TDeleteStatementState;
    function GetStatementType: TSQLStatementType; override;
    procedure ModifyStatementInNormalState(Sender: TObject; AToken: 
            TgaSQLTokenObj); override;
    procedure ParseDeleteTable(Sender: TObject; AToken: TgaSQLTokenObj);
    property StatementState: TDeleteStatementState read FStatementState write 
            SetStatementState;
  public
    constructor Create(AOwner: TgaAdvancedSQLParser); override;
    constructor CreateFromStatement(AOwner: TgaAdvancedSQLParser; AStatement: 
            TgaNoSQLStatement); override;
    destructor Destroy; override;
    property StatementTable: TgaSQLTable read FStatementTable;
    property WhereClause: TgaSQLWhereExpression read FWhereClause;
  end;
  
const
  DeleteAllowedNextState: array [TDeleteStatementState] of TDeleteStatementStates =
    ({dssNone} [dssDeleteTable],
     {dssDeleteTable} [dssWhereClause, dssStatementComplete],
     {dssWhereClause} [dssStatementComplete],
     {dssStatementComplete} []);

implementation

uses
  SysUtils, TypInfo, gaSQLParserConsts;

{
**************************** TgaDeleteSQLStatement *****************************
}
constructor TgaDeleteSQLStatement.Create(AOwner: TgaAdvancedSQLParser);
begin
  inherited Create(AOwner);
  FStatementTable := TgaSQLTable.Create(Self);
  FStatementTable.IsAliasAllowed := False;
end;

constructor TgaDeleteSQLStatement.CreateFromStatement(AOwner: 
        TgaAdvancedSQLParser; AStatement: TgaNoSQLStatement);
begin
  inherited CreateFromStatement(AOwner, AStatement);
  FStatementTable := TgaSQLTable.Create(Self);
  FStatementTable.IsAliasAllowed := False;
end;

destructor TgaDeleteSQLStatement.Destroy;
begin
  FStatementTable.Free;
  inherited Destroy;
end;

procedure TgaDeleteSQLStatement.DoAfterStatementStateChange;
begin
  inherited;
  if (StatementState > dssDeleteTable) and (not Assigned(FWhereClause)) then
  begin
    if StatementState = dssWhereClause then
      FWhereClause := TgaSQLWhereExpression.Create(Self)
    else begin
      CurrentSQL.Previous;
      CurrentSQL.InsertAfterCurrent(TgaSQLTokenObj.CreatePlaceHolder, True);
      FWhereClause := TgaSQLWhereExpression.Create(Self);
      FWhereClause.ParseComplete := True;
      CurrentSQL.Next;
    end;
  end;
end;

procedure TgaDeleteSQLStatement.DoBeforeStatementStateChange(const NewStateOrd: 
        LongInt);
begin
  inherited DoBeforeStatementStateChange(NewStateOrd);
  case StatementState of
    dssWhereClause: begin
      WhereClause.Last;
      WhereClause.Previous;
      WhereClause.ParseComplete := True;
    end;
  end;
end;

function TgaDeleteSQLStatement.GetNewStatementState: TDeleteStatementState;
var
  TokenStr: string;
begin
  Result := StatementState;
  TokenStr := UpperCase(OwnerParser.TokenString);
  if OwnerParser.TokenType = stSymbol then
  begin
    if TokenStr = 'DELETE' then
      Result := dssDeleteTable
    else if TokenStr = 'WHERE' then
      Result := dssWhereClause
  end else
  if OwnerParser.TokenType = stEnd then
    Result := dssStatementComplete;
end;

function TgaDeleteSQLStatement.GetStatementType: TSQLStatementType;
begin
  Result := sstDelete;
end;

procedure TgaDeleteSQLStatement.ModifyStatementInNormalState(Sender: TObject; 
        AToken: TgaSQLTokenObj);
begin
  inherited;
  StatementState := GetNewStatementState;
  if InternalStatementState > 0 then
    case StatementState of
      dssNone:
        {the statement starts with comment or whitespace};
      dssDeleteTable:
        ParseDeleteTable(Sender, AToken);
      dssWhereClause:
        WhereClause.ExecuteTokenAdded(Sender, AToken);
      dssStatementComplete:
        DoStatementComplete;
      else
        raise Exception.CreateFmt(SUnknownStatementState,
          [ClassName, GetEnumName(TypeInfo(TDeleteStatementState), Ord(StatementState))]);
    end
  else
    InternalStatementState := 1;
end;

procedure TgaDeleteSQLStatement.ParseDeleteTable(Sender: TObject; AToken: 
        TgaSQLTokenObj);
begin
  case InternalStatementState of
    1: { delete* FROM* ....}
      case CurrentToken.TokenType of
        stComment, stDelimitier:
          ;
        stSymbol:
          if CurrentToken.TokenSymbolIs('FROM') then
            InternalStatementState := 2
          else
            StatusCode := errWrongKeywordSequence;
        else
          StatusCode := errUnexpectedTokenInStatement;
      end;
    2: { delete from *....*}
      StatementTable.ExecuteTokenAdded(Sender, AToken);
  end;
end;

procedure TgaDeleteSQLStatement.SetStatementState(const Value: 
        TDeleteStatementState);
begin
  if StatementState <> Value then
  begin
    if StatusCode = 0 then
      if Value in DeleteAllowedNextState[FStatementState] then
      begin
        DoBeforeStatementStateChange(Ord(Value));
        FStatementState := Value;
        InternalStatementState := 0;
        DoAfterStatementStateChange;
      end else
        StatusCode := errWrongKeywordSequence;
    if Value = dssStatementComplete then
    begin
      DoBeforeStatementStateChange(Ord(Value));
      FStatementState := Value;
      InternalStatementState := 0;
      DoAfterStatementStateChange;
    end;
  end;
end;

end.

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?