unit uDASQL92QueryBuilder; {----------------------------------------------------------------------------} { Data Abstract Library - Core Library } { } { compiler: Delphi 6 and up, Kylix 3 and up } { platform: Win32, Linux } { } { (c)opyright RemObjects Software. all rights reserved. } { } { Using this code requires a valid license of the Data Abstract } { which can be obtained at http://www.remobjects.com. } {----------------------------------------------------------------------------} {$I DataAbstract.inc} interface uses Classes, uDAInterfaces, uDAWhere; type TDASQL92WhereBuilder = class(TDASQLWhereBuilder) protected function ProcessBinaryExpression(AExpression: TDAWhereExpression): string; override; function ProcessUnaryExpression(AExpression: TDAWhereExpression): string; override; function ProcessNullExpression(AExpression: TDAWhereExpression): string; override; end; TDASQL92QueryBuilder = class(TDAQueryBuilder) protected function CreateWhereBuilder: TDASQLWhereBuilder; override; function CreateTableClause: string; override; function IdentifierNeedsQuoting(const iIdentifier: string):boolean;override; function QuoteStringId(aValue: string): string; end; implementation uses SysUtils, uROXMLIntf, uDASQL92Interfaces; const c_Indent = ' '; { TDASQL92QueryBuilder } function TDASQL92QueryBuilder.CreateTableClause: string; var i, j: integer; s: string; begin Result := QuoteIdentifierIfNeeded(MainTable.MasterTable); for i := 0 to MainTable.JoinSourceTables.Count - 1 do with TDAJoinSourceTable(MainTable.JoinSourceTables.Items[i]) do begin if (JoinConditions.Count = 0) or (JoinType = jtCross) then Result := Result + ',' + QuoteIdentifierIfNeeded(Name) else begin case JoinType of jtInner: s := 'INNER'; jtLeftOuter: s := 'LEFT OUTER'; jtRightOuter: s := 'RIGHT OUTER'; jtFullOuter: s := 'FULL OUTER'; end; Result := Result + sLineBreak + c_Indent + Format('%s JOIN %s ON (', [s, QuoteIdentifierIfNeeded(Name)]); for j := 0 to JoinConditions.Count - 1 do begin if J > 0 then Result := Result + ' and '; with TDAJoinCondition(JoinConditions.Items[j]) do begin Result := Result + Format('(%s = %s)', [ GenerateFieldName(FromTableName, FromFieldName), GenerateFieldName(ToTableName, ToFieldName)]); end; Result := Result + ')'; end; end; end; end; function TDASQL92QueryBuilder.CreateWhereBuilder: TDASQLWhereBuilder; begin Result := TDASQL92WhereBuilder.Create(Self); end; function TDASQL92QueryBuilder.IdentifierNeedsQuoting( const iIdentifier: string): boolean; begin Result:= inherited IdentifierNeedsQuoting(iIdentifier) or SQL92_IdentifierNeedsQuoting(iIdentifier); end; function TDASQL92QueryBuilder.QuoteStringId(aValue: string): string; begin Result:= AnsiQuotedStr(aValue,''''); end; { TDASQL92WhereBuilder } function TDASQL92WhereBuilder.ProcessBinaryExpression( AExpression: TDAWhereExpression): string; const TDABinaryOperatorStr: array[TDABinaryOperator] of string = ('AND', 'OR', '' {dboXor}, '<', '=<', '>', '>=', '<>', '=', 'LIKE', '' {dboIn}, '+', '-', '*', '/'); function ExpressionisNull(aExpr: TDAWhereExpression): boolean; begin result := (AExpr is TDANullExpression) or ((AExpr is TDAUnaryExpression) and (TDAUnaryExpression(AExpr).Operator = duoNot) and (TDAUnaryExpression(AExpr).Expression is TDANullExpression)); end; var lLeft, lRight: string; lLeftisNull, lRightisNull: boolean; begin Result := ''; With TDABinaryExpression(AExpression) do begin lLeft := ProcessExpression(Left); lRight := ProcessExpression(Right); lRightisNull := ExpressionisNull(Right); lLeftisNull := ExpressionisNull(Left); if Operator = dboXor then // A xor B = (A and not B) or (not A and B) result := Format('((%s AND NOT %s) OR' + sLineBreak + '(NOT %0:s AND %1:s))', [lLeft, lRight]) else if lRightisNull then result := Format('(%s IS %s)', [lLeft, lRight]) else if lLeftisNull then result := Format('(%s IS %s)', [lRight, lLeft]) else if Operator = dboIn then result := Format('(%s IN (%s))', [lLeft, lRight]) else result := Format('(%s %s %s)', [lLeft, TDABinaryOperatorStr[Operator], lRight]); end; end; function TDASQL92WhereBuilder.ProcessNullExpression( AExpression: TDAWhereExpression): string; begin Result := 'NULL'; end; function TDASQL92WhereBuilder.ProcessUnaryExpression( AExpression: TDAWhereExpression): string; var lExpr: string; begin with TDAUnaryExpression(AExpression) do begin lExpr := ProcessExpression(Expression); case Operator of duoNot: Result := 'NOT ' + lExpr; duoMinus: Result := '-' + lExpr; else Result := ''; end; end; end; end.