258 |
|
sqltPlaceholder, |
259 |
|
sqltSingleQuotes, |
260 |
|
sqltDoubleQuotes, |
261 |
+ |
sqltBackslash, |
262 |
|
sqltComma, |
263 |
|
sqltPeriod, |
264 |
|
sqltEquals, |
280 |
|
sqltOpenBracket, |
281 |
|
sqltCloseBracket, |
282 |
|
sqltPipe, |
283 |
+ |
sqltMinus, |
284 |
|
sqltConcatSymbol, |
285 |
|
sqltLT, |
286 |
|
sqltGT, |
594 |
|
function TokenFound(var token: TSQLTokens): boolean; override; |
595 |
|
end; |
596 |
|
|
597 |
+ |
{ TSQLParamProcessor } |
598 |
+ |
|
599 |
+ |
TSQLParamProcessor = class(TSQLwithNamedParamsTokeniser) |
600 |
+ |
private |
601 |
+ |
const |
602 |
+ |
sIBXParam = 'IBXParam'; {do not localize} |
603 |
+ |
private |
604 |
+ |
FInString: AnsiString; |
605 |
+ |
FIndex: integer; |
606 |
+ |
function DoExecute(GenerateParamNames: boolean; |
607 |
+ |
var slNames: TStrings): AnsiString; |
608 |
+ |
protected |
609 |
+ |
function GetChar: AnsiChar; override; |
610 |
+ |
public |
611 |
+ |
class function Execute(sSQL: AnsiString; GenerateParamNames: boolean; |
612 |
+ |
var slNames: TStrings): AnsiString; |
613 |
+ |
end; |
614 |
+ |
|
615 |
+ |
|
616 |
|
function Max(n1, n2: Integer): Integer; |
617 |
|
function Min(n1, n2: Integer): Integer; |
618 |
|
function RandomString(iLength: Integer): AnsiString; |
737 |
|
|
738 |
|
function QuoteIdentifier(Dialect: Integer; Value: AnsiString): AnsiString; |
739 |
|
begin |
740 |
+ |
Value := TrimRight(Value); |
741 |
|
if Dialect = 1 then |
742 |
< |
Value := AnsiUpperCase(Trim(Value)) |
742 |
> |
Value := AnsiUpperCase(Value) |
743 |
|
else |
744 |
|
Value := '"' + StringReplace (Value, '""', '"', [rfReplaceAll]) + '"'; |
745 |
|
Result := Value; |
970 |
|
|
971 |
|
function QuoteIdentifierIfNeeded(Dialect: Integer; Value: AnsiString): AnsiString; |
972 |
|
begin |
973 |
+ |
Value := TrimRight(Value); |
974 |
|
if (Dialect = 3) and |
975 |
|
(IsReservedWord(Value) or not IsSQLIdentifier(Value) or (AnsiUpperCase(Value) <> Value)) then |
976 |
|
Result := '"' + StringReplace (TrimRight(Value), '"', '""', [rfReplaceAll]) + '"' |
997 |
|
Result := StringReplace(s,'''','''''',[rfReplaceAll]); |
998 |
|
end; |
999 |
|
|
1000 |
+ |
{ TSQLParamProcessor } |
1001 |
+ |
|
1002 |
+ |
function TSQLParamProcessor.DoExecute(GenerateParamNames: boolean; |
1003 |
+ |
var slNames: TStrings): AnsiString; |
1004 |
+ |
var token: TSQLTokens; |
1005 |
+ |
iParamSuffix: Integer; |
1006 |
+ |
begin |
1007 |
+ |
Result := ''; |
1008 |
+ |
iParamSuffix := 0; |
1009 |
+ |
|
1010 |
+ |
while not EOF do |
1011 |
+ |
begin |
1012 |
+ |
token := GetNextToken; |
1013 |
+ |
case token of |
1014 |
+ |
sqltParam, |
1015 |
+ |
sqltQuotedParam: |
1016 |
+ |
begin |
1017 |
+ |
Result := Result + '?'; |
1018 |
+ |
slNames.Add(TokenText); |
1019 |
+ |
end; |
1020 |
+ |
|
1021 |
+ |
sqltPlaceHolder: |
1022 |
+ |
if GenerateParamNames then |
1023 |
+ |
begin |
1024 |
+ |
Inc(iParamSuffix); |
1025 |
+ |
slNames.AddObject(sIBXParam + IntToStr(iParamSuffix),self); //Note local convention |
1026 |
+ |
//add pointer to self to mark entry |
1027 |
+ |
Result := Result + '?'; |
1028 |
+ |
end |
1029 |
+ |
else |
1030 |
+ |
IBError(ibxeSQLParseError, [SParamNameExpected]); |
1031 |
+ |
|
1032 |
+ |
sqltQuotedString: |
1033 |
+ |
Result := Result + '''' + SQLSafeString(TokenText) + ''''; |
1034 |
+ |
|
1035 |
+ |
sqltIdentifierInDoubleQuotes: |
1036 |
+ |
Result := Result + '"' + StringReplace(TokenText,'"','""',[rfReplaceAll]) + '"'; |
1037 |
+ |
|
1038 |
+ |
sqltComment: |
1039 |
+ |
Result := Result + '/*' + TokenText + '*/'; |
1040 |
+ |
|
1041 |
+ |
sqltCommentLine: |
1042 |
+ |
Result := Result + '--' + TokenText + LineEnding; |
1043 |
+ |
|
1044 |
+ |
sqltEOL: |
1045 |
+ |
Result := Result + LineEnding; |
1046 |
+ |
|
1047 |
+ |
else |
1048 |
+ |
Result := Result + TokenText; |
1049 |
+ |
end; |
1050 |
+ |
end; |
1051 |
+ |
end; |
1052 |
+ |
|
1053 |
+ |
function TSQLParamProcessor.GetChar: AnsiChar; |
1054 |
+ |
begin |
1055 |
+ |
if FIndex <= Length(FInString) then |
1056 |
+ |
begin |
1057 |
+ |
Result := FInString[FIndex]; |
1058 |
+ |
Inc(FIndex); |
1059 |
+ |
end |
1060 |
+ |
else |
1061 |
+ |
Result := #0; |
1062 |
+ |
end; |
1063 |
+ |
|
1064 |
+ |
class function TSQLParamProcessor.Execute(sSQL: AnsiString; |
1065 |
+ |
GenerateParamNames: boolean; var slNames: TStrings): AnsiString; |
1066 |
+ |
begin |
1067 |
+ |
with self.Create do |
1068 |
+ |
try |
1069 |
+ |
FInString := sSQL; |
1070 |
+ |
FIndex := 1; |
1071 |
+ |
Result := DoExecute(GenerateParamNames,slNames); |
1072 |
+ |
finally |
1073 |
+ |
Free; |
1074 |
+ |
end; |
1075 |
+ |
end; |
1076 |
+ |
|
1077 |
|
{ TSQLwithNamedParamsTokeniser } |
1078 |
|
|
1079 |
|
procedure TSQLwithNamedParamsTokeniser.Assign(source: TSQLTokeniser); |
1193 |
|
Result := sqltSingleQuotes; |
1194 |
|
'/': |
1195 |
|
Result := sqltForwardSlash; |
1196 |
+ |
'\': |
1197 |
+ |
Result := sqltBackslash; |
1198 |
|
'*': |
1199 |
|
Result := sqltAsterisk; |
1200 |
|
'(': |
1213 |
|
Result := sqltOpenSquareBracket; |
1214 |
|
']': |
1215 |
|
Result := sqltCloseSquareBracket; |
1216 |
+ |
'-': |
1217 |
+ |
Result := sqltMinus; |
1218 |
|
'<': |
1219 |
|
Result := sqltLT; |
1220 |
|
'>': |
1487 |
|
GetNext; |
1488 |
|
FState := stInComment; |
1489 |
|
end |
1490 |
< |
else |
1491 |
< |
if FNextToken = sqltForwardSlash then |
1490 |
> |
end; |
1491 |
> |
|
1492 |
> |
sqltMinus: |
1493 |
> |
begin |
1494 |
> |
if FNextToken = sqltMinus then |
1495 |
|
begin |
1496 |
|
FString := ''; |
1497 |
|
GetNext; |