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