diff --git a/packages/fcl-db/src/base/bufdataset.pas b/packages/fcl-db/src/base/bufdataset.pas index de188f9cc7..5c719a82d5 100644 --- a/packages/fcl-db/src/base/bufdataset.pas +++ b/packages/fcl-db/src/base/bufdataset.pas @@ -438,6 +438,8 @@ type procedure SetOnUpdateError(const aValue: TResolverErrorEvent); procedure SetFilterText(const Value: String); override; {virtual;} procedure SetFiltered(Value: Boolean); override; {virtual;} + procedure InternalRefresh; override; + procedure BeforeRefreshOpenCursor; virtual; {abstracts, must be overidden by descendents} function Fetch : boolean; virtual; function LoadField(FieldDef : TFieldDef;buffer : pointer; out CreateBlob : boolean) : boolean; virtual; @@ -2622,7 +2624,7 @@ begin inherited; // refilter dataset if filtered - if IsCursorOpen and Filtered then Refresh; + if IsCursorOpen and Filtered then Resync([]); end; procedure TBufDataset.SetFiltered(Value: Boolean); {override;} @@ -2635,7 +2637,25 @@ begin // only refresh if active if IsCursorOpen then - Refresh; + Resync([]); +end; + +procedure TBufDataset.InternalRefresh; +var StoreDefaultFields: boolean; +begin + StoreDefaultFields:=DefaultFields; + SetDefaultFields(False); + FreeFieldBuffers; + ClearBuffers; + InternalClose; + BeforeRefreshOpenCursor; + InternalOpen; + SetDefaultFields(StoreDefaultFields); +end; + +procedure TBufDataset.BeforeRefreshOpenCursor; +begin + // Do nothing end; function TBufDataset.Fetch: boolean; diff --git a/packages/fcl-db/src/sqldb/sqldb.pp b/packages/fcl-db/src/sqldb/sqldb.pp index 5598d160e6..07be439d59 100644 --- a/packages/fcl-db/src/sqldb/sqldb.pp +++ b/packages/fcl-db/src/sqldb/sqldb.pp @@ -259,6 +259,7 @@ type Function GetDataSource : TDatasource; override; Procedure SetDataSource(AValue : TDatasource); procedure LoadBlobIntoBuffer(FieldDef: TFieldDef;ABlobBuf: PBufBlobField); override; + procedure BeforeRefreshOpenCursor; override; public procedure Prepare; virtual; procedure UnPrepare; virtual; @@ -1572,6 +1573,16 @@ begin TSQLConnection(DataBase).LoadBlobIntoBuffer(FieldDef, ABlobBuf, FCursor,(Transaction as tsqltransaction)); end; +procedure TCustomSQLQuery.BeforeRefreshOpenCursor; +begin + // This is only necessary because TIBConnection can not re-open a + // prepared cursor. In fact this is wrong, but has never led to + // problems because in SetActive(false) queries are always + // unprepared. (which is also wrong, but has to be fixed later) + if IsPrepared then with TSQLConnection(DataBase) do + UnPrepareStatement(FCursor); +end; + function TCustomSQLQuery.GetStatementType : TStatementType; begin diff --git a/packages/fcl-db/tests/testdbbasics.pas b/packages/fcl-db/tests/testdbbasics.pas index 15f5df8230..7d95a57297 100644 --- a/packages/fcl-db/tests/testdbbasics.pas +++ b/packages/fcl-db/tests/testdbbasics.pas @@ -139,7 +139,7 @@ begin begin open; delete; - refresh; + Resync([]); applyupdates; AssertTrue(IsEmpty); diff --git a/packages/fcl-db/tests/testfieldtypes.pas b/packages/fcl-db/tests/testfieldtypes.pas index 40cf4c8a2a..04bb89f3f7 100644 --- a/packages/fcl-db/tests/testfieldtypes.pas +++ b/packages/fcl-db/tests/testfieldtypes.pas @@ -57,6 +57,7 @@ type procedure TestInsertReturningQuery; procedure TestTemporaryTable; + procedure TestRefresh; procedure TestParametersAndDates; procedure TestExceptOnsecClose; @@ -925,6 +926,43 @@ begin inherited RunTest; end; +procedure TTestFieldTypes.TestRefresh; +var ADataset: TDataset; + i: integer; + AFldID, AFldName: TField; +begin + ADataset := TSQLDBConnector(DBConnector).GetNDataset(true,5); + + Adataset.Open; + AFldId:=Adataset.Fields[0]; + AFldName:=Adataset.Fields[1]; + for i := 1 to 5 do + begin + AssertEquals(i,AFldID.asinteger); + AssertEquals('TestName'+inttostr(i),AFldName.asstring); + ADataset.Next; + end; + + ADataset.Next; + AssertTrue(ADataset.EOF); + TSQLDBConnector(DBConnector).Connection.ExecuteDirect('update FPDEV set NAME=''test'' where ID=2'); + + ADataset.Refresh; + + ADataset.First; + for i := 1 to 5 do + begin + AssertEquals(i,AFldID.AsInteger); + if i = 2 then + AssertEquals('test',AFldName.AsString) + else + AssertEquals('TestName'+inttostr(i),AFldName.AsString); + ADataset.Next; + end; + ADataset.Next; + AssertTrue(ADataset.EOF); +end; + procedure TTestFieldTypes.TestEmptyUpdateQuery; begin TSQLDBConnector(DBConnector).Connection.ExecuteDirect('update FPDEV set name=''nothing'' where (1=0)');