mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-04-15 13:19:27 +02:00
* Implemented the sqEscapeSlash and sqescapeRepeat connection options
* Adapted and added a test git-svn-id: trunk@6085 -
This commit is contained in:
parent
3594230958
commit
90a6bdcdd4
fcl
@ -1624,9 +1624,9 @@ type
|
||||
Function IsEqual(Value: TParams): Boolean;
|
||||
Function ParamByName(const Value: string): TParam;
|
||||
Function ParseSQL(SQL: String; DoCreate: Boolean): String;
|
||||
Function ParseSQL(SQL: String; DoCreate: Boolean; ParameterStyle : TParamStyle): String; overload;
|
||||
Function ParseSQL(SQL: String; DoCreate: Boolean; ParameterStyle : TParamStyle; var ParamBinding: TParambinding): String; overload;
|
||||
Function ParseSQL(SQL: String; DoCreate: Boolean; ParameterStyle : TParamStyle; var ParamBinding: TParambinding; var ReplaceString : string): String;
|
||||
Function ParseSQL(SQL: String; DoCreate, EscapeSlash, EscapeRepeat : Boolean; ParameterStyle : TParamStyle): String; overload;
|
||||
Function ParseSQL(SQL: String; DoCreate, EscapeSlash, EscapeRepeat : Boolean; ParameterStyle : TParamStyle; var ParamBinding: TParambinding): String; overload;
|
||||
Function ParseSQL(SQL: String; DoCreate, EscapeSlash, EscapeRepeat : Boolean; ParameterStyle : TParamStyle; var ParamBinding: TParambinding; var ReplaceString : string): String;
|
||||
Procedure RemoveParam(Value: TParam);
|
||||
Procedure CopyParamValuesFromDataset(ADataset : TDataset; CopyBound : Boolean);
|
||||
Property Dataset : TDataset Read GetDataset;
|
||||
|
@ -156,24 +156,24 @@ var pb : TParamBinding;
|
||||
rs : string;
|
||||
|
||||
begin
|
||||
Result := ParseSQL(SQL,DoCreate,psInterbase, pb, rs);
|
||||
Result := ParseSQL(SQL,DoCreate,True,True,psInterbase, pb, rs);
|
||||
end;
|
||||
|
||||
Function TParams.ParseSQL(SQL: String; DoCreate: Boolean; ParameterStyle : TParamStyle): String;
|
||||
Function TParams.ParseSQL(SQL: String; DoCreate, EscapeSlash, EscapeRepeat : Boolean; ParameterStyle : TParamStyle): String;
|
||||
|
||||
var pb : TParamBinding;
|
||||
rs : string;
|
||||
|
||||
begin
|
||||
Result := ParseSQL(SQL,DoCreate,ParameterStyle,pb, rs);
|
||||
Result := ParseSQL(SQL,DoCreate,EscapeSlash,EscapeRepeat,ParameterStyle,pb, rs);
|
||||
end;
|
||||
|
||||
Function TParams.ParseSQL(SQL: String; DoCreate: Boolean; ParameterStyle : TParamStyle; var ParamBinding: TParambinding): String;
|
||||
Function TParams.ParseSQL(SQL: String; DoCreate, EscapeSlash, EscapeRepeat : Boolean; ParameterStyle : TParamStyle; var ParamBinding: TParambinding): String;
|
||||
|
||||
var rs : string;
|
||||
|
||||
begin
|
||||
Result := ParseSQL(SQL,DoCreate,ParameterStyle,ParamBinding, rs);
|
||||
Result := ParseSQL(SQL,DoCreate,EscapeSlash, EscapeRepeat, ParameterStyle,ParamBinding, rs);
|
||||
end;
|
||||
|
||||
function SkipComments(var p: PChar; EscapeSlash, EscapeRepeat : Boolean) : Boolean;
|
||||
@ -187,7 +187,7 @@ var notRepeatEscaped : boolean;
|
||||
notRepeatEscaped := True;
|
||||
while not (p^ in [#0, QuoteChar]) do
|
||||
begin
|
||||
if EscapeSlash and (p^='\') then Inc(p,2) // make sure we handle \' and \\ correct
|
||||
if EscapeSlash and (p^='\') and (p[1] <> #0) then Inc(p,2) // make sure we handle \' and \\ correct
|
||||
else Inc(p);
|
||||
end;
|
||||
if p^=QuoteChar then
|
||||
@ -238,7 +238,7 @@ begin
|
||||
end; {case}
|
||||
end;
|
||||
|
||||
Function TParams.ParseSQL(SQL: String; DoCreate: Boolean; ParameterStyle : TParamStyle; var ParamBinding: TParambinding; var ReplaceString : string): String;
|
||||
Function TParams.ParseSQL(SQL: String; DoCreate, EscapeSlash, EscapeRepeat: Boolean; ParameterStyle : TParamStyle; var ParamBinding: TParambinding; var ReplaceString : string): String;
|
||||
|
||||
type
|
||||
// used for ParamPart
|
||||
@ -280,10 +280,7 @@ begin
|
||||
p:=PChar(SQL);
|
||||
BufStart:=p; // used to calculate ParamPart.Start values
|
||||
repeat
|
||||
// This doesn't work, since ParseSQL passes psInterbase as default. This need
|
||||
// some more advanced solution. Now temporary fix, to fix at least fpcbot...
|
||||
// SkipComments(p,ParameterStyle<>psPostgreSQL,ParameterStyle=psPostgreSQL);
|
||||
SkipComments(p,True,True);
|
||||
SkipComments(p,EscapeSlash,EscapeRepeat);
|
||||
case p^ of
|
||||
':','?': // parameter
|
||||
begin
|
||||
|
@ -144,7 +144,7 @@ constructor TIBConnection.Create(AOwner : TComponent);
|
||||
|
||||
begin
|
||||
inherited;
|
||||
FConnOptions := FConnOptions + [sqSupportParams];
|
||||
FConnOptions := FConnOptions + [sqSupportParams] + [sqEscapeRepeat];
|
||||
FBLobSegmentSize := 80;
|
||||
end;
|
||||
|
||||
@ -508,7 +508,7 @@ begin
|
||||
tr := aTransaction.Handle;
|
||||
|
||||
if assigned(AParams) and (AParams.count > 0) then
|
||||
buf := AParams.ParseSQL(buf,false,psInterbase,paramBinding);
|
||||
buf := AParams.ParseSQL(buf,false,sqEscapeSlash in ConnOptions, sqEscapeRepeat in ConnOptions,psInterbase,paramBinding);
|
||||
|
||||
if isc_dsql_prepare(@Status[0], @tr, @Statement, 0, @Buf[1], Dialect, nil) <> 0 then
|
||||
CheckError('PrepareStatement', Status);
|
||||
|
@ -53,6 +53,8 @@ Type
|
||||
MapDSRowToMSQLRow : array of integer;
|
||||
end;
|
||||
|
||||
{ TConnectionName }
|
||||
|
||||
TConnectionName = class (TSQLConnection)
|
||||
private
|
||||
FDialect: integer;
|
||||
@ -97,6 +99,7 @@ Type
|
||||
procedure RollBackRetaining(trans : TSQLHandle); override;
|
||||
procedure UpdateIndexDefs(var IndexDefs : TIndexDefs;TableName : string); override;
|
||||
Public
|
||||
constructor Create(AOwner : TComponent); override;
|
||||
procedure CreateDB; override;
|
||||
procedure DropDB; override;
|
||||
Property ServerInfo : String Read FServerInfo;
|
||||
@ -348,7 +351,7 @@ begin
|
||||
begin
|
||||
FStatement:=Buf;
|
||||
if assigned(AParams) and (AParams.count > 0) then
|
||||
FStatement := AParams.ParseSQL(FStatement,false,psSimulated,paramBinding,ParamReplaceString);
|
||||
FStatement := AParams.ParseSQL(FStatement,false,sqEscapeSlash in ConnOptions, sqEscapeRepeat in ConnOptions,psSimulated,paramBinding,ParamReplaceString);
|
||||
if FStatementType=stSelect then
|
||||
FNeedData:=True;
|
||||
ConnectMySQL(FQMySQL,FMySQL^.host,FMySQL^.user,FMySQL^.passwd);
|
||||
@ -803,6 +806,12 @@ begin
|
||||
qry.free;
|
||||
end;
|
||||
|
||||
constructor TConnectionName.Create(AOwner: TComponent);
|
||||
begin
|
||||
inherited Create(AOwner);
|
||||
FConnOptions := FConnOptions + [sqEscapeRepeat] + [sqEscapeSlash];
|
||||
end;
|
||||
|
||||
function TConnectionName.GetTransactionHandle(trans: TSQLHandle): pointer;
|
||||
begin
|
||||
Result:=Nil;
|
||||
|
@ -100,6 +100,7 @@ type
|
||||
// Internal utility functions
|
||||
function CreateConnectionString:string;
|
||||
public
|
||||
constructor Create(AOwner : TComponent); override;
|
||||
property Environment:TODBCEnvironment read FEnvironment;
|
||||
published
|
||||
property Driver:string read FDriver write FDriver; // will be passed as DRIVER connection parameter
|
||||
@ -256,6 +257,12 @@ begin
|
||||
end;
|
||||
end;
|
||||
|
||||
constructor TODBCConnection.Create(AOwner: TComponent);
|
||||
begin
|
||||
inherited Create(AOwner);
|
||||
FConnOptions := FConnOptions + [sqEscapeRepeat] + [sqEscapeSlash];
|
||||
end;
|
||||
|
||||
procedure TODBCConnection.SetParameters(ODBCCursor: TODBCCursor; AParams: TParams);
|
||||
var
|
||||
ParamIndex:integer;
|
||||
@ -440,7 +447,7 @@ begin
|
||||
|
||||
// Parse the SQL and build FParamIndex
|
||||
if assigned(AParams) and (AParams.count > 0) then
|
||||
buf := AParams.ParseSQL(buf,false,psInterbase,ODBCCursor.FParamIndex);
|
||||
buf := AParams.ParseSQL(buf,false,sqEscapeSlash in ConnOptions, sqEscapeRepeat in ConnOptions,psInterbase,ODBCCursor.FParamIndex);
|
||||
|
||||
// prepare statement
|
||||
ODBCCheckResult(
|
||||
|
@ -112,7 +112,7 @@ constructor TPQConnection.Create(AOwner : TComponent);
|
||||
|
||||
begin
|
||||
inherited;
|
||||
FConnOptions := FConnOptions + [sqSupportParams];
|
||||
FConnOptions := FConnOptions + [sqSupportParams] + [sqEscapeRepeat] + [sqEscapeSlash];
|
||||
end;
|
||||
|
||||
procedure TPQConnection.CreateDB;
|
||||
@ -480,7 +480,7 @@ begin
|
||||
else DatabaseErrorFmt(SUnsupportedParameter,[Fieldtypenames[AParams[i].DataType]],self);
|
||||
end;
|
||||
s[length(s)] := ')';
|
||||
buf := AParams.ParseSQL(buf,false,psPostgreSQL);
|
||||
buf := AParams.ParseSQL(buf,false,sqEscapeSlash in ConnOptions, sqEscapeRepeat in ConnOptions,psPostgreSQL);
|
||||
end;
|
||||
s := s + ' as ' + buf;
|
||||
res := pqexec(tr.PGConn,pchar(s));
|
||||
|
@ -23,7 +23,7 @@ interface
|
||||
uses SysUtils, Classes, DB, bufdataset;
|
||||
|
||||
type TSchemaType = (stNoSchema, stTables, stSysTables, stProcedures, stColumns, stProcedureParams, stIndexes, stPackages);
|
||||
TConnOption = (sqSupportParams);
|
||||
TConnOption = (sqSupportParams,sqEscapeSlash,sqEscapeRepeat);
|
||||
TConnOptions= set of TConnOption;
|
||||
|
||||
type
|
||||
@ -632,11 +632,14 @@ end;
|
||||
{ TSQLQuery }
|
||||
procedure TSQLQuery.OnChangeSQL(Sender : TObject);
|
||||
|
||||
var ConnOptions : TConnOptions;
|
||||
|
||||
begin
|
||||
UnPrepare;
|
||||
if (FSQL <> nil) then
|
||||
begin
|
||||
FParams.ParseSQL(FSQL.Text,True);
|
||||
ConnOptions := (DataBase as TSQLConnection).ConnOptions;
|
||||
Fparams.ParseSQL(FSQL.Text,True, sqEscapeSlash in ConnOptions, sqEscapeRepeat in ConnOptions,psInterbase);
|
||||
If Assigned(FMasterLink) then
|
||||
FMasterLink.RefreshParamNames;
|
||||
end;
|
||||
@ -866,6 +869,7 @@ Var
|
||||
StrLength : Integer;
|
||||
EndOfComment : Boolean;
|
||||
BracketCount : Integer;
|
||||
ConnOptions : TConnOptions;
|
||||
|
||||
begin
|
||||
PSQL:=Pchar(ASQL);
|
||||
@ -876,12 +880,14 @@ begin
|
||||
|
||||
FWhereStartPos := 0;
|
||||
FWhereStopPos := 0;
|
||||
|
||||
ConnOptions := (DataBase as TSQLConnection).ConnOptions;
|
||||
|
||||
repeat
|
||||
begin
|
||||
inc(CurrentP);
|
||||
|
||||
EndOfComment := SkipComments(CurrentP,True,False);
|
||||
|
||||
EndOfComment := SkipComments(CurrentP,sqEscapeSlash in ConnOptions, sqEscapeRepeat in ConnOptions);
|
||||
if EndOfcomment then dec(currentp);
|
||||
if EndOfComment and (ParsePart = ppStart) then PhraseP := CurrentP;
|
||||
|
||||
|
@ -35,49 +35,58 @@ var Params : TParams;
|
||||
begin
|
||||
Params := TParams.Create;
|
||||
AssertEquals( 'select * from table where id = $1',
|
||||
params.ParseSQL('select * from table where id = :id',true,psPostgreSQL));
|
||||
params.ParseSQL('select * from table where id = :id',true,True,True,psPostgreSQL));
|
||||
|
||||
AssertEquals( 'select * from table where id = $1',
|
||||
params.ParseSQL('select * from table where id = :id',false,psPostgreSQL));
|
||||
params.ParseSQL('select * from table where id = :id',false,True,True,psPostgreSQL));
|
||||
|
||||
AssertEquals( 'update test set 1=$1 2=$2 3=$3 4=$4 5=$5 6=$6 7=$7 8=$8 9=$9 where (id = $2)',
|
||||
params.ParseSQL('update test set 1=:1 2=:2 3=:par3 4=:par4 5=:par5 6=:par6 7=:par7 8=:par8 9=:par9 where (id = :2)',true,psPostgreSQL));
|
||||
params.ParseSQL('update test set 1=:1 2=:2 3=:par3 4=:par4 5=:par5 6=:par6 7=:par7 8=:par8 9=:par9 where (id = :2)',true,True,True,psPostgreSQL));
|
||||
|
||||
AssertEquals( 'update test set 1=$1 2=$2 3=$3 4=$4 5=$5 6=$6 7=$7 8=$8 9=$9 where (id = $3) and (test=''$test'')',
|
||||
params.ParseSQL('update test set 1=:1 2=:2 3=:par3 4=:par4 5=:par5 6=:par6 7=:par7 8=:par8 9=:par9 where (id = :par3) and (test=''$test'')',true,psPostgreSQL));
|
||||
params.ParseSQL('update test set 1=:1 2=:2 3=:par3 4=:par4 5=:par5 6=:par6 7=:par7 8=:par8 9=:par9 where (id = :par3) and (test=''$test'')',true,true,true,psPostgreSQL));
|
||||
|
||||
AssertEquals( 'update test set 1=$1 2=$2 3=$3 4=$4 5=$5 6=$6 7=$7 8=$8 9=$9 10=$10 11=$11 12=$5 where (id = $3) and (test=''$test'')',
|
||||
params.ParseSQL('update test set 1=:1 2=:2 3=:par3 4=:par4 5=:par5 6=:par6 7=:par7 8=:par8 9=:par9 10=:par10 11=:11 12=:par5 where (id = :par3) and (test=''$test'')',true,psPostgreSQL));
|
||||
|
||||
AssertEquals( 'select * from table where ''id '''' = :id''',
|
||||
params.ParseSQL('select * from table where ''id '''' = :id''',true,psPostgreSQL));
|
||||
|
||||
AssertEquals( 'select * from table where "id "" = :id"',
|
||||
params.ParseSQL('select * from table where "id "" = :id"',true,psPostgreSQL));
|
||||
params.ParseSQL('update test set 1=:1 2=:2 3=:par3 4=:par4 5=:par5 6=:par6 7=:par7 8=:par8 9=:par9 10=:par10 11=:11 12=:par5 where (id = :par3) and (test=''$test'')',true,true,true,psPostgreSQL));
|
||||
|
||||
AssertEquals( 'select * from table where id = $1',
|
||||
params.ParseSQL('select * from table where id = :id',true,psSimulated,pb,ReplStr));
|
||||
params.ParseSQL('select * from table where id = :id',true,true,false,psSimulated,pb,ReplStr));
|
||||
AssertEquals('$',ReplStr);
|
||||
|
||||
AssertEquals( 'update test set 1=$1 2=$2 3=$3 4=$4 5=$5 6=$6 7=$7 8=$8 9=$9 where (id = $2)',
|
||||
params.ParseSQL('update test set 1=:1 2=:2 3=:par3 4=:par4 5=:par5 6=:par6 7=:par7 8=:par8 9=:par9 where (id = :2)',true,psSimulated,pb,ReplStr));
|
||||
params.ParseSQL('update test set 1=:1 2=:2 3=:par3 4=:par4 5=:par5 6=:par6 7=:par7 8=:par8 9=:par9 where (id = :2)',true,true,false,psSimulated,pb,ReplStr));
|
||||
AssertEquals('$',ReplStr);
|
||||
|
||||
AssertEquals( 'update test set 1=$$1 2=$$2 3=$$3 4=$$4 5=$$5 6=$$6 7=$$7 8=$$8 9=$$9 where (id = $$3) and (test=''$test'')',
|
||||
params.ParseSQL('update test set 1=:1 2=:2 3=:par3 4=:par4 5=:par5 6=:par6 7=:par7 8=:par8 9=:par9 where (id = :par3) and (test=''$test'')',true,psSimulated,pb,ReplStr));
|
||||
params.ParseSQL('update test set 1=:1 2=:2 3=:par3 4=:par4 5=:par5 6=:par6 7=:par7 8=:par8 9=:par9 where (id = :par3) and (test=''$test'')',true,true,false,psSimulated,pb,ReplStr));
|
||||
AssertEquals('$$',ReplStr);
|
||||
|
||||
AssertEquals( 'update test set 1=$$1 2=$$2 3=$$3 4=$$4 5=$$5 6=$$6 7=$$7 8=$$8 9=$$9 10=$$10 11=$$11 12=$$5 where (id = $$3) and (test=''$test'')',
|
||||
params.ParseSQL('update test set 1=:1 2=:2 3=:par3 4=:par4 5=:par5 6=:par6 7=:par7 8=:par8 9=:par9 10=:par10 11=:11 12=:par5 where (id = :par3) and (test=''$test'')',true,psSimulated));
|
||||
params.ParseSQL('update test set 1=:1 2=:2 3=:par3 4=:par4 5=:par5 6=:par6 7=:par7 8=:par8 9=:par9 10=:par10 11=:11 12=:par5 where (id = :par3) and (test=''$test'')',true,True,True,psSimulated));
|
||||
AssertEquals('$$',ReplStr);
|
||||
|
||||
AssertEquals( 'update test set 1=$$$1 2=$$$2 3=$$$3 4=$$$4 5=$$$5 6=$$$6 7=$$$7 8=$$$8 9=$$$9 10=$$$10 11=$$$11 12=$$$5 where (id$$ = $$$3) and (test$=''$test'')',
|
||||
params.ParseSQL('update test set 1=:1 2=:2 3=:par3 4=:par4 5=:par5 6=:par6 7=:par7 8=:par8 9=:par9 10=:par10 11=:11 12=:par5 where (id$$ = :par3) and (test$=''$test'')',true,psSimulated,pb,ReplStr));
|
||||
params.ParseSQL('update test set 1=:1 2=:2 3=:par3 4=:par4 5=:par5 6=:par6 7=:par7 8=:par8 9=:par9 10=:par10 11=:11 12=:par5 where (id$$ = :par3) and (test$=''$test'')',true,true,False,psSimulated,pb,ReplStr));
|
||||
AssertEquals('$$$',ReplStr);
|
||||
|
||||
AssertEquals( 'select * from table where id = ?',
|
||||
params.ParseSQL('select * from table where id = :id',true,psInterbase));
|
||||
params.ParseSQL('select * from table where id = :id',true,true,true,psInterbase));
|
||||
|
||||
// Test escape-sequences:
|
||||
AssertEquals( 'select * from table where ''id '''' = :id''',
|
||||
params.ParseSQL('select * from table where ''id '''' = :id''',true,False,True,psPostgreSQL));
|
||||
|
||||
AssertEquals( 'select * from table where "id "" = :id"',
|
||||
params.ParseSQL('select * from table where "id "" = :id"',true,False,True,psPostgreSQL));
|
||||
|
||||
AssertEquals( 'select * from table where "id \" = :id"',
|
||||
params.ParseSQL('select * from table where "id \" = :id"',true,True,False,psPostgreSQL));
|
||||
|
||||
AssertEquals( 'select * from table where "id \" = $1',
|
||||
params.ParseSQL('select * from table where "id \" = :id',true,False,False,psPostgreSQL));
|
||||
|
||||
AssertEquals( 'select * from table where "id = :id\',
|
||||
params.ParseSQL('select * from table where "id = :id\',true,True,True,psInterbase));
|
||||
|
||||
Params.Free;
|
||||
end;
|
||||
|
@ -27,6 +27,7 @@ type
|
||||
procedure RunTest; override;
|
||||
published
|
||||
|
||||
procedure TestDoubleQuoteEscapeComments;
|
||||
procedure TestpfInUpdateFlag; // bug 7565
|
||||
procedure TestInt;
|
||||
procedure TestScript;
|
||||
@ -801,6 +802,17 @@ begin
|
||||
inherited RunTest;
|
||||
end;
|
||||
|
||||
procedure TTestFieldTypes.TestDoubleQuoteEscapeComments;
|
||||
begin
|
||||
with TSQLDBConnector(DBConnector).Query do
|
||||
begin
|
||||
SQL.Clear;
|
||||
SQL.Add('select * from FPDEV where name=''test '''' and :ThisIsNotAParameter ''');
|
||||
open;
|
||||
close;
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure TTestFieldTypes.TestParametersAndDates;
|
||||
begin
|
||||
with TSQLDBConnector(DBConnector).Query do
|
||||
|
Loading…
Reference in New Issue
Block a user