Log On
Embarcadero Home
Watch, Follow, &
Connect with Us
Share This
QualityCentral
Communities
Articles
Blogs
Resources
Downloads
Help
QualityCentral
Delphi-BCB
Midas
Install
Java Midas
Socket Server
TClientDataSet
TDataSetProvider
TDCOMConnection
TMidasConnection
TOLEEnterpriseConnection
TProvider
TRemoteServer
TSimpleObjectBroker
TSocketConnection
TWebConnection
WebMidas
XML Midas
You are not logged in.
Help
Print
Public Report
Report From:
Delphi-BCB/Midas/TDataSetProvider
[ Add a report in this area ]
Report #:
8606
Status:
Closed
DSP.AfterApplyUpdates event should *always* be fired.
Project:
Delphi
Build #:
7.0.8.1
Version:
7.0
Submitted By:
Dave Rowntree
Report Type:
Minor failure / Design problem
Date Reported:
7/9/2004 6:54:34 AM
Severity:
Commonly encountered problem
Last Updated:
3/20/2012 2:24:39 AM
Platform:
All versions
Internal Tracking #:
204458
Resolution:
Fixed
(Resolution Comments)
Resolved in Build:
:
7.0.8.1
Duplicate of:
None
Voting and Rating
Overall Rating:
No Ratings Yet
0.00 out of 5
Total Votes:
None
Description
Currently, if an unhandled exception is raised in DSP.ApplyUpdates, the DSP.AfterApplyUpdates event is not called.
This prevents the use of DSP.AfterApplyUpdates to de-allocate resources (probably obtained in the DSP.BeforeApplyUpdates event) since it is not guaranteed to be called.
Please make the DSP.AfterApplyUpdates event always fire.
Please make the currently active exception available in the AfterApplyUpdates event, so appropriate action can be taken by app code in the event.
Steps to Reproduce:
None
Workarounds
PROVIDER.PAS
Dave Rowntree 09 July 2004
QC#8606 and QC#8607 amendments.
TCustomProvider = class(TComponent)
private
FExported: Boolean;
FOnDataRequest: TDataRequestEvent;
FBeforeApplyUpdates: TRemoteEvent;
FAfterApplyUpdates: TRemoteEvent;
FBeforeGetRecords: TRemoteEvent;
FAfterGetRecords: TRemoteEvent;
FBeforeRowRequest: TRemoteEvent;
FAfterRowRequest: TRemoteEvent;
FBeforeExecute: TRemoteEvent;
FAfterExecute: TRemoteEvent;
FBeforeGetParams: TRemoteEvent;
FAfterGetParams: TRemoteEvent;
FActiveUpdateAbortException: Exception; (**)(* QC#8606 - add this line *)
FOwnerData: OleVariant; (**)(* QC#8607 - add this line *)
function GetData: OleVariant;
protected
function InternalApplyUpdates(const Delta: OleVariant; MaxErrors: Integer;
out ErrorCount: Integer): OleVariant; virtual; abstract;
function InternalGetRecords(Count: Integer; out RecsOut: Integer;
Options: TGetRecordOptions; const CommandText: WideString;
var Params: OleVariant): OleVariant; virtual;
function InternalRowRequest(const Row: OleVariant; RequestType: TFetchOptions): OleVariant; virtual;
procedure InternalExecute(const CommandText: WideString; var Params: OleVariant); virtual;
function InternalGetParams(Types: TParamTypes = AllParamTypes): OleVariant; virtual;
procedure SetActiveUpdateException(E: Exception); (**)(* QC#8606 - add this line *)
property ActiveUpdateException: Exception read FActiveUpdateAbortException; (**)(* QC#8606 - add this line *)
property OwnerData: OleVariant read FOwnerData write FOwnerData; (**)(* QC#8607 - add this line *)
........
TDataSetProvider = class(TBaseProvider)
private
........
public
constructor Create(AOwner: TComponent); override;
destructor Destroy; override;
property ActiveUpdateException; (**)(* QC#8606 - add this line *)
property OwnerData; (**)(* QC#8607 - add this line *)
published
........
(**)(* QC#8606 and QC#8607 - replacement function *)
(* Since FActiveUpdateException is only required by the AfterApplyUpdates event,
it would be better as a local variable in TCustomProvider.ApplyUpdates
if/when this is rolled into the live VCL. It could passed as a parameter
through the DoAfterApplyUpdates handler, into the AfterApplyUpdates event.*)
function TCustomProvider.ApplyUpdates(const Delta: OleVariant; MaxErrors: Integer;
out ErrorCount: Integer; var OwnerData: OleVariant): OleVariant;
begin
SetActiveUpdateException(nil);
try
try
DoBeforeApplyUpdates(OwnerData);
Self.OwnerData := OwnerData;
try
Result := InternalApplyUpdates(Delta, MaxErrors, ErrorCount);
finally
OwnerData := Self.OwnerData;
Self.OwnerData := unassigned;
end;
except
SetActiveUpdateException(AcquireExceptionObject);
raise;
end;
finally
try
DoAfterApplyUpdates(OwnerData);
finally
SetActiveUpdateException(nil);
end;
end;
end;
(**)(* QC#8616 and QC#8617 - rem out this original function *)
{function TCustomProvider.ApplyUpdates(const Delta: OleVariant; MaxErrors: Integer;
out ErrorCount: Integer; var OwnerData: OleVariant): OleVariant;
begin
DoBeforeApplyUpdates(OwnerData);
Result := InternalApplyUpdates(Delta, MaxErrors, ErrorCount);
DoAfterApplyUpdates(OwnerData);
end;}
........
(**)(* QC#8606 - add this proc *)
procedure TCustomProvider.SetActiveUpdateException(E: Exception);
begin
FActiveUpdateAbortException := E;
end;
{ TBaseProvider }
........
Attachment
None
Comments
Dave Rowntree at 7/9/2004 7:33:06 AM
-
The VCL amendments in the Workaround address this QC report and QC#8607.
View Your Reports
Search
Server Response from: ETNACODE01
Developer Tools
Blackfish SQL
C++Builder
Delphi
FireMonkey
Prism
InterBase
JBuilder
J Optimizer
HTML5 Builder
3rdRail & TurboRuby
Database Tools
Change Manager
DBArtisan
DB Optimizer
ER/Studio
Performance Center
Rapid SQL
Technical Articles
Tutorials
White Papers
Press Releases
Newsletters
Add Content (GetPublished)
Audio
Audio & Video
Video
Bugs & Suggestions (QualityCentral)
Discussion Forums
Examples (CodeCentral)
Tags
Technology Partners
Downloads
Free Trials
Registered User Downloads
Beta Programs
Add Content (GetPublished)
Articles
Blogs
Bugs & Suggestions (QualityCentral)
Discussion Forums
Examples (CodeCentral)
Member Services
About
Connect with Us