ViewVC Help
View File | Revision Log | Show Annotations | Download File | View Changeset | Root Listing
root/public/ibx/branches/udr/client/3.0/FB30ClientAPI.pas
(Generate patch)

Comparing ibx/branches/udr/client/3.0/FB30ClientAPI.pas (file contents):
Revision 389 by tony, Tue Jan 18 12:05:35 2022 UTC vs.
Revision 390 by tony, Sat Jan 22 16:15:12 2022 UTC

# Line 25 | Line 25
25   *
26   *)
27   unit FB30ClientAPI;
28 < {$IFDEF MSWINDOWS}
29 < {$DEFINE WINDOWS}
28 > {$IFDEF MSWINDOWS}
29 > {$DEFINE WINDOWS}
30   {$ENDIF}
31  
32   {$IFDEF FPC}
# Line 41 | Line 41 | uses
41    FBActivityMonitor;
42  
43   type
44
44    { TFB30Status }
45  
46    TFB30Status = class(TFBStatus,IStatus)
# Line 50 | Line 49 | type
49      FDirty: boolean;
50      function GetIBMessage: Ansistring; override;
51    public
52 +    constructor Create(aOwner: TFBClientAPI; prefix: AnsiString=''); overload;
53 +    constructor Create(aOwner: TFBClientAPI; aStatus: Firebird.IStatus); overload;
54 +    constructor Copy(src: TFB30Status);
55      destructor Destroy; override;
54    procedure Assign(src: TFBStatus); override;
56      function Clone: IStatus; override;
57      procedure Init;
58      procedure FreeHandle;
59 <    function InErrorState: boolean;
59 >    function InErrorState: boolean; override;
60      function Warning: boolean;
61      function GetStatus: Firebird.IStatus;
62      function StatusVector: PStatusVector; override;
63      property Dirty: boolean read FDirty;
64    end;
65  
65  { TFB30StatusObject }
66
67  TFB30StatusObject = class(TFB30Status)
68  public
69    constructor Create(aOwner: TFBClientAPI; status: Firebird.IStatus; prefix: Ansistring='');
70  end;
71
66    Tfb_get_master_interface = function: IMaster;
67                                {$IFDEF WINDOWS} stdcall; {$ELSE} cdecl; {$ENDIF}
68  
# Line 259 | Line 253 | end;
253  
254   { TFB30StatusObject }
255  
256 < constructor TFB30StatusObject.Create(aOwner: TFBClientAPI;
257 <  status: Firebird.IStatus; prefix: Ansistring);
256 > threadvar
257 >  PerThreadFirebirdStatusIntf: Firebird.IStatus;
258 >  StatusIntfRefCount: integer;
259 >
260 > { TFB30Status }
261 >
262 > function TFB30Status.GetIBMessage: Ansistring;
263 > begin
264 >  Result := (FOwner as TFB30ClientAPI).FormatStatus(GetStatus);
265 > end;
266 >
267 > constructor TFB30Status.Create(aOwner: TFBClientAPI; prefix: AnsiString);
268   begin
269    inherited Create(aOwner,prefix);
270 <  FStatus := status.clone;
270 >  if aOwner <> nil then
271 >  begin
272 >    Inc(StatusIntfRefCount);
273 >  end;
274   end;
275  
276 < { TFB30Status }
276 > constructor TFB30Status.Create(aOwner: TFBClientAPI; aStatus: Firebird.IStatus);
277 > begin
278 >  inherited Create(aOwner);
279 >  FStatus := aStatus.clone;
280 > end;
281  
282 < function TFB30Status.GetIBMessage: Ansistring;
282 > constructor TFB30Status.Copy(src: TFB30Status);
283   begin
284 <  Result := (FOwner as TFB30ClientAPI).FormatStatus(FStatus);
284 >  inherited Copy(src);
285 >  FStatus := src.GetStatus.clone;
286   end;
287  
288   destructor TFB30Status.Destroy;
# Line 279 | Line 291 | begin
291    inherited Destroy;
292   end;
293  
282 procedure TFB30Status.Assign(src: TFBStatus);
283 begin
284  inherited Assign(src);
285  FStatus := (src as TFB30Status).GetStatus.clone;
286 end;
287
294   function TFB30Status.Clone: IStatus;
289 var aResult: TFB30Status;
295   begin
296 <  aResult := TFB30Status.Create(nil);
292 <  aResult.Assign(self);
293 <  Result := aResult;
296 >  Result := TFB30Status.Copy(self);
297   end;
298  
299   procedure TFB30Status.Init;
300   begin
301 <  if assigned(FStatus) and Dirty then
301 >  if (GetStatus <> nil) and Dirty then
302    begin
303 <    FStatus.Init;
303 >    GetStatus.Init;
304      FDirty := false;
305    end;
306   end;
# Line 307 | Line 310 | begin
310    if FStatus <> nil then
311    begin
312      FStatus.dispose;
313 <    FStatus := nil;
313 >    FStatus := nil
314 >  end
315 >  else
316 >  begin
317 >    Dec(StatusIntfRefCount);
318 >    if (StatusIntfRefCount = 0) and (PerThreadFirebirdStatusIntf <> nil) then
319 >    begin
320 >      PerThreadFirebirdStatusIntf.dispose();
321 >      PerThreadFirebirdStatusIntf := nil;
322 >    end;
323    end;
324   end;
325  
# Line 329 | Line 341 | end;
341  
342   function TFB30Status.GetStatus: Firebird.IStatus;
343   begin
344 <  if FStatus = nil then
345 <    with FOwner do
346 <      FStatus := (FOwner as TFB30ClientAPI).MasterIntf.GetStatus;
347 <  Result := FStatus;
344 >  if FStatus <> nil then
345 >    Result := FStatus
346 >  else
347 >  begin
348 >    {Create the FStatus per thread}
349 >    if PerThreadFirebirdStatusIntf = nil then
350 >    begin
351 >      with FOwner do
352 >        PerThreadFirebirdStatusIntf :=  (FOwner as TFB30ClientAPI).GetIMasterIntf.getStatus();
353 >    end;
354 >    Result := PerThreadFirebirdStatusIntf;
355 >  end;
356   end;
357  
358   function TFB30Status.StatusVector: PStatusVector;
# Line 464 | Line 484 | begin
484   end;
485  
486   procedure TFB30ClientAPI.Check4DataBaseError(st: Firebird.IStatus);
487 + var aStatus: IStatus;
488   begin
489 <  if ((st.getState and st.STATE_ERRORS) <> 0) then
490 <    raise EIBInterBaseError.Create(TFB30StatusObject.Create(self,st));
489 >  aStatus := TFB30Status.Create(self,st);
490 >  if aStatus.InErrorState then
491 >    raise EIBInterBaseError.Create(aStatus);
492   end;
493  
494   function TFB30ClientAPI.FormatStatus(Status: Firebird.IStatus): AnsiString;
# Line 837 | Line 859 | begin
859    Result := true;
860   end;
861  
862 + initialization
863 +  PerThreadFirebirdStatusIntf := nil;
864 +  StatusIntfRefCount := 0;
865   end.
866  
867  
868 +

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines