160 lines
5.4 KiB
ObjectPascal
160 lines
5.4 KiB
ObjectPascal
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.
|
|
|