25 |
|
* |
26 |
|
*) |
27 |
|
unit FBActivityMonitor; |
28 |
+ |
{$IFDEF MSWINDOWS} |
29 |
+ |
{$DEFINE WINDOWS} |
30 |
+ |
{$ENDIF} |
31 |
|
|
32 |
|
{$IFDEF FPC} |
33 |
< |
{$mode objfpc}{$H+} |
33 |
> |
{$mode delphi} |
34 |
|
{$interfaces COM} |
35 |
|
{$ENDIF} |
36 |
|
|
50 |
|
|
51 |
|
{$IFDEF DEBUGINTERFACES} |
52 |
|
TMonitoredObject = class(TInterfacedObject) |
50 |
– |
private |
51 |
– |
FObjectCount: integer; static; |
53 |
|
public |
54 |
|
constructor Create; |
55 |
|
destructor Destroy; override; |
91 |
|
reports.} |
92 |
|
|
93 |
|
IActivityMonitor = interface |
94 |
+ |
['{8261840a-741b-4c1c-94ea-c5c66ba72f22}'] |
95 |
|
procedure AddObject(obj: TInterfacedObject); |
96 |
|
procedure Remove(intf: TInterfacedObject); |
97 |
|
procedure SignalActivity; |
108 |
|
interface, implemented through the helper object TTransactionMonitor. |
109 |
|
} |
110 |
|
|
111 |
+ |
TOnDatabaseError = procedure of object; |
112 |
+ |
|
113 |
|
TActivityReporter = class(TInterfaceOwner) |
114 |
|
private |
115 |
|
FHasActivity: boolean; |
116 |
|
FMonitors: array of IActivityMonitor; |
117 |
+ |
FOnDatabaseError: TOnDatabaseError; |
118 |
|
function FindMonitor(aMonitor: IActivityMonitor): integer; |
119 |
|
protected |
120 |
|
function Call(ErrCode: ISC_STATUS; RaiseError: Boolean = true): ISC_STATUS; |
125 |
|
destructor Destroy; override; |
126 |
|
function HasActivity: boolean; |
127 |
|
procedure SignalActivity; |
128 |
+ |
property OnDatabaseError: TOnDatabaseError read FOnDatabaseError write FOnDatabaseError; |
129 |
|
end; |
130 |
|
|
131 |
|
{ TActivityHandler is a base class for classes that receive activity reports.} |
140 |
|
|
141 |
|
implementation |
142 |
|
|
143 |
< |
uses FB25ClientAPI; |
143 |
> |
uses FBClientAPI; |
144 |
|
|
145 |
|
{ TActivityHandler } |
146 |
|
|
158 |
|
{ TMonitoredObject } |
159 |
|
|
160 |
|
{$IFDEF DEBUGINTERFACES} |
161 |
+ |
var |
162 |
+ |
FObjectCount: integer; |
163 |
+ |
|
164 |
|
constructor TMonitoredObject.Create; |
165 |
|
begin |
166 |
|
inherited Create; |
194 |
|
begin |
195 |
|
result := ErrCode; |
196 |
|
SignalActivity; |
197 |
< |
if RaiseError and (ErrCode > 0) then |
198 |
< |
Firebird25ClientAPI.IBDataBaseError; |
197 |
> |
if RaiseError and (ErrCode > 0) and assigned(FOnDatabaseError) then |
198 |
> |
OnDatabaseError; |
199 |
|
end; |
200 |
|
|
201 |
|
procedure TActivityReporter.AddMonitor(aMonitor: IActivityMonitor); |
313 |
|
|
314 |
|
function TInterfaceOwner.HasInterface(index: integer): boolean; |
315 |
|
begin |
316 |
< |
Result := FInterfaces[index] <> nil; |
316 |
> |
Result := (Length(FInterfaces) > 0) and (FInterfaces[index] <> nil); |
317 |
|
end; |
318 |
|
|
319 |
|
procedure TInterfaceOwner.Remove(intf: TInterfacedObject); |
345 |
|
var i: integer; |
346 |
|
begin |
347 |
|
for i := 0 to Length(FInterfaces) - 1 do |
348 |
+ |
begin |
349 |
+ |
{$IFNDEF FPC} |
350 |
+ |
{With Delphi we need to explicitly null the object reference when it is |
351 |
+ |
going to be disposed of. This is because Delphi does not drop the reference |
352 |
+ |
count until after the containing object is released.} |
353 |
+ |
if (FInterfaces[i] <> nil) and (FInterfaces[i].RefCount <= 2) then |
354 |
+ |
FInterfaces[i] := nil; |
355 |
+ |
{$ENDIF} |
356 |
|
FInterfaceRefs[i] := nil; |
357 |
+ |
end; |
358 |
|
end; |
359 |
|
|
360 |
|
end. |