mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-04-07 08:48:08 +02:00
* Fix bug #0036461, parameters not correctly refreshed in Mysql
git-svn-id: trunk@43702 -
This commit is contained in:
parent
3440d166ae
commit
b2957b92f4
@ -92,7 +92,10 @@ Type
|
||||
TCursorName = Class(TSQLCursor)
|
||||
protected
|
||||
FRes: PMYSQL_RES; { Record pointer }
|
||||
FStatement : String;
|
||||
// Statement with param placeholders $1 $2 etc.
|
||||
FPreparedStatement : String;
|
||||
// Statement with param placeholders replaced with actual values.
|
||||
FActualStatement : String;
|
||||
Row : MYSQL_ROW;
|
||||
Lengths : pculong; { Lengths of the columns of the current row }
|
||||
RowsAffected : QWord;
|
||||
@ -589,9 +592,9 @@ begin
|
||||
// DatabaseError('Parameters (not) yet supported for the MySQL SqlDB connection.',self);
|
||||
With Cursor as TCursorName do
|
||||
begin
|
||||
FStatement:=Buf;
|
||||
FPreparedStatement:=Buf;
|
||||
if assigned(AParams) and (AParams.count > 0) then
|
||||
FStatement := AParams.ParseSQL(FStatement,false,sqEscapeSlash in ConnOptions, sqEscapeRepeat in ConnOptions,psSimulated,paramBinding,ParamReplaceString);
|
||||
FPreparedStatement := AParams.ParseSQL(FPreparedStatement,false,sqEscapeSlash in ConnOptions, sqEscapeRepeat in ConnOptions,psSimulated,paramBinding,ParamReplaceString);
|
||||
FPrepared:=True;
|
||||
end
|
||||
end;
|
||||
@ -621,6 +624,7 @@ begin
|
||||
mysql_free_result(C.FRes);
|
||||
C.FRes:=Nil;
|
||||
end;
|
||||
C.FInitFieldDef:=True;
|
||||
SetLength(c.MapDSRowToMSQLRow,0);
|
||||
inherited;
|
||||
end;
|
||||
@ -648,18 +652,19 @@ begin
|
||||
ParamNames[AParams.count-i-1] := C.ParamReplaceString+inttostr(AParams[i].Index+1);
|
||||
ParamValues[AParams.count-i-1] := GetAsSQLText(AParams[i]);
|
||||
end;
|
||||
// paramreplacestring kan een probleem geven bij postgres als hij niet meer gewoon $ is?
|
||||
C.FStatement := stringsreplace(C.FStatement,ParamNames,ParamValues,[rfReplaceAll]);
|
||||
end;
|
||||
C.FActualStatement := stringsreplace(C.FPreparedStatement,ParamNames,ParamValues,[rfReplaceAll]);
|
||||
end
|
||||
else
|
||||
C.FActualStatement:=C.FPreparedStatement;
|
||||
|
||||
if LogEvent(detParamValue) then
|
||||
LogParams(AParams);
|
||||
if LogEvent(detExecute) then
|
||||
Log(detExecute, C.FStatement);
|
||||
Log(detExecute, C.FPreparedStatement);
|
||||
if LogEvent(detActualSQL) then
|
||||
Log(detActualSQL,C.FStatement);
|
||||
Log(detActualSQL,C.FActualStatement);
|
||||
|
||||
if mysql_query(FMySQL,Pchar(C.FStatement))<>0 then
|
||||
if mysql_query(FMySQL,Pchar(C.FActualStatement))<>0 then
|
||||
begin
|
||||
if not ForcedClose then
|
||||
MySQLError(FMYSQL,SErrExecuting,Self)
|
||||
|
@ -31,6 +31,7 @@ type
|
||||
private
|
||||
FMyQ: TSQLQuery;
|
||||
FPrepareCount:Integer;
|
||||
procedure CreateAndFillIDField;
|
||||
procedure DoAfterPost(DataSet: TDataSet);
|
||||
Procedure DoApplyUpdates;
|
||||
procedure DoCount(Sender: TSQLConnection; EventType: TDBEventType; const Msg: String);
|
||||
@ -60,6 +61,7 @@ type
|
||||
procedure TestReturningUpdate;
|
||||
procedure TestMacros;
|
||||
Procedure TestPrepareCount;
|
||||
Procedure TestPrepareCount2;
|
||||
end;
|
||||
|
||||
{ TTestTSQLConnection }
|
||||
@ -761,40 +763,80 @@ begin
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure TTestTSQLQuery.TestPrepareCount;
|
||||
procedure TTestTSQLQuery.CreateAndFillIDField;
|
||||
|
||||
Var
|
||||
I : Integer;
|
||||
|
||||
begin
|
||||
with SQLDBConnector do
|
||||
begin
|
||||
TryDropIfExist('FPDEV2');
|
||||
ExecuteDirect('create table FPDEV2 (id integer not null, constraint PK_FPDEV2 primary key(id))');
|
||||
CommitDDL;
|
||||
ExecuteDirect('insert into FPDEV2 (id) values (1)');
|
||||
ExecuteDirect('insert into FPDEV2 (id) values (2)');
|
||||
for I:=1 to 10 do
|
||||
ExecuteDirect('insert into FPDEV2 (id) values ('+IntToStr(I)+')');
|
||||
Connection.OnLog:=@DoCount;
|
||||
Connection.LogEvents:=[detPrepare];
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure TTestTSQLQuery.TestPrepareCount;
|
||||
|
||||
begin
|
||||
CreateAndFillIDField;
|
||||
try
|
||||
With SQLDBConnector.Query do
|
||||
begin
|
||||
Unidirectional:=True; // Disable server index defs etc
|
||||
UsePrimaryKeyAsKey:=False; // Idem
|
||||
SQL.Text:='Select ID from FPDEV2 where (ID=:ID)';
|
||||
UsePrimaryKeyAsKey:=False; // Disable server index defs etc
|
||||
SQL.Text:='Select ID from FPDEV2 where (ID>=:ID) order by ID';
|
||||
ParamByname('ID').AsInteger:=1;
|
||||
Prepare;
|
||||
AssertFalse('Not Prepared',SQLDBConnector.Query.Prepared);
|
||||
Open;
|
||||
AssertEquals('Correct record count param 1',1,RecordCount);
|
||||
AssertEquals('Correct SQL executed, correct paramete: ',1,Fields[0].AsInteger);
|
||||
AssertEquals('Correct record count param 1',10,RecordCount);
|
||||
AssertEquals('Correct SQL executed, correct parameter: ',1,Fields[0].AsInteger);
|
||||
Close;
|
||||
AssertFalse('Still not prepared',SQLDBConnector.Query.Prepared);
|
||||
ParamByname('ID').AsInteger:=2;
|
||||
Open;
|
||||
AssertEquals('Correct record count param 2',1,RecordCount);
|
||||
AssertEquals('Correct record count param 2',9,RecordCount);
|
||||
AssertEquals('Correct SQL executed, macro value changed: ',2,Fields[0].AsInteger);
|
||||
Close;
|
||||
AssertFalse('Still not prepared',SQLDBConnector.Query.Prepared);
|
||||
end;
|
||||
AssertEquals('Prepare called only once ',2,FPrepareCount);
|
||||
finally
|
||||
SQLDBConnector.Connection.OnLog:=Nil;
|
||||
end;
|
||||
|
||||
end;
|
||||
|
||||
procedure TTestTSQLQuery.TestPrepareCount2;
|
||||
|
||||
begin
|
||||
CreateAndFillIDField;
|
||||
try
|
||||
With SQLDBConnector.Query do
|
||||
begin
|
||||
UsePrimaryKeyAsKey:=False; // Disable server index defs etc
|
||||
SQL.Text:='Select ID from FPDEV2 where (ID>=:ID) order by ID';
|
||||
ParamByname('ID').AsInteger:=1;
|
||||
Prepare;
|
||||
AssertTrue('Prepared',SQLDBConnector.Query.Prepared);
|
||||
Open;
|
||||
AssertEquals('Correct record count param 1',10,RecordCount);
|
||||
AssertEquals('Correct SQL executed, correct parameter: ',1,Fields[0].AsInteger);
|
||||
Close;
|
||||
AssertTrue('Still prepared',SQLDBConnector.Query.Prepared);
|
||||
ParamByname('ID').AsInteger:=2;
|
||||
Open;
|
||||
AssertEquals('Correct record count param 2',9,RecordCount);
|
||||
AssertEquals('Correct SQL executed, macro value changed: ',2,Fields[0].AsInteger);
|
||||
end;
|
||||
AssertEquals('Prepare called only once ',1,FPrepareCount);
|
||||
finally
|
||||
SQLDBConnector.Connection.OnLog:=Nil;
|
||||
end;
|
||||
|
||||
end;
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user