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; |
995 |
|
Result := StringReplace(s,'''','''''',[rfReplaceAll]); |
996 |
|
end; |
997 |
|
|
998 |
+ |
{ TSQLParamProcessor } |
999 |
+ |
|
1000 |
+ |
function TSQLParamProcessor.DoExecute(GenerateParamNames: boolean; |
1001 |
+ |
var slNames: TStrings): AnsiString; |
1002 |
+ |
var token: TSQLTokens; |
1003 |
+ |
iParamSuffix: Integer; |
1004 |
+ |
begin |
1005 |
+ |
Result := ''; |
1006 |
+ |
iParamSuffix := 0; |
1007 |
+ |
|
1008 |
+ |
while not EOF do |
1009 |
+ |
begin |
1010 |
+ |
token := GetNextToken; |
1011 |
+ |
case token of |
1012 |
+ |
sqltParam, |
1013 |
+ |
sqltQuotedParam: |
1014 |
+ |
begin |
1015 |
+ |
Result := Result + '?'; |
1016 |
+ |
slNames.Add(TokenText); |
1017 |
+ |
end; |
1018 |
+ |
|
1019 |
+ |
sqltPlaceHolder: |
1020 |
+ |
if GenerateParamNames then |
1021 |
+ |
begin |
1022 |
+ |
Inc(iParamSuffix); |
1023 |
+ |
slNames.AddObject(sIBXParam + IntToStr(iParamSuffix),self); //Note local convention |
1024 |
+ |
//add pointer to self to mark entry |
1025 |
+ |
Result := Result + '?'; |
1026 |
+ |
end |
1027 |
+ |
else |
1028 |
+ |
IBError(ibxeSQLParseError, [SParamNameExpected]); |
1029 |
+ |
|
1030 |
+ |
sqltQuotedString: |
1031 |
+ |
Result := Result + '''' + SQLSafeString(TokenText) + ''''; |
1032 |
+ |
|
1033 |
+ |
sqltIdentifierInDoubleQuotes: |
1034 |
+ |
Result := Result + '"' + StringReplace(TokenText,'"','""',[rfReplaceAll]) + '"'; |
1035 |
+ |
|
1036 |
+ |
sqltComment: |
1037 |
+ |
Result := Result + '/*' + TokenText + '*/'; |
1038 |
+ |
|
1039 |
+ |
sqltCommentLine: |
1040 |
+ |
Result := Result + '--' + TokenText + LineEnding; |
1041 |
+ |
|
1042 |
+ |
sqltEOL: |
1043 |
+ |
Result := Result + LineEnding; |
1044 |
+ |
|
1045 |
+ |
else |
1046 |
+ |
Result := Result + TokenText; |
1047 |
+ |
end; |
1048 |
+ |
end; |
1049 |
+ |
end; |
1050 |
+ |
|
1051 |
+ |
function TSQLParamProcessor.GetChar: AnsiChar; |
1052 |
+ |
begin |
1053 |
+ |
if FIndex <= Length(FInString) then |
1054 |
+ |
begin |
1055 |
+ |
Result := FInString[FIndex]; |
1056 |
+ |
Inc(FIndex); |
1057 |
+ |
end |
1058 |
+ |
else |
1059 |
+ |
Result := #0; |
1060 |
+ |
end; |
1061 |
+ |
|
1062 |
+ |
class function TSQLParamProcessor.Execute(sSQL: AnsiString; |
1063 |
+ |
GenerateParamNames: boolean; var slNames: TStrings): AnsiString; |
1064 |
+ |
begin |
1065 |
+ |
with self.Create do |
1066 |
+ |
try |
1067 |
+ |
FInString := sSQL; |
1068 |
+ |
FIndex := 1; |
1069 |
+ |
Result := DoExecute(GenerateParamNames,slNames); |
1070 |
+ |
finally |
1071 |
+ |
Free; |
1072 |
+ |
end; |
1073 |
+ |
end; |
1074 |
+ |
|
1075 |
|
{ TSQLwithNamedParamsTokeniser } |
1076 |
|
|
1077 |
|
procedure TSQLwithNamedParamsTokeniser.Assign(source: TSQLTokeniser); |
1191 |
|
Result := sqltSingleQuotes; |
1192 |
|
'/': |
1193 |
|
Result := sqltForwardSlash; |
1194 |
+ |
'\': |
1195 |
+ |
Result := sqltBackslash; |
1196 |
|
'*': |
1197 |
|
Result := sqltAsterisk; |
1198 |
|
'(': |
1211 |
|
Result := sqltOpenSquareBracket; |
1212 |
|
']': |
1213 |
|
Result := sqltCloseSquareBracket; |
1214 |
+ |
'-': |
1215 |
+ |
Result := sqltMinus; |
1216 |
|
'<': |
1217 |
|
Result := sqltLT; |
1218 |
|
'>': |
1485 |
|
GetNext; |
1486 |
|
FState := stInComment; |
1487 |
|
end |
1488 |
< |
else |
1489 |
< |
if FNextToken = sqltForwardSlash then |
1488 |
> |
end; |
1489 |
> |
|
1490 |
> |
sqltMinus: |
1491 |
> |
begin |
1492 |
> |
if FNextToken = sqltMinus then |
1493 |
|
begin |
1494 |
|
FString := ''; |
1495 |
|
GetNext; |
1510 |
|
end; |
1511 |
|
|
1512 |
|
sqltIdentifier: |
1513 |
< |
if FNextToken = sqltIdentifier then |
1513 |
> |
if FNextToken in [sqltIdentifier,sqltNumberString] then |
1514 |
|
FState := stInIdentifier; |
1515 |
|
|
1516 |
|
sqltNumberString: |