25 |
|
* |
26 |
|
*) |
27 |
|
unit FB30ClientAPI; |
28 |
< |
{$IFDEF MSWINDOWS} |
29 |
< |
{$DEFINE WINDOWS} |
28 |
> |
{$IFDEF MSWINDOWS} |
29 |
> |
{$DEFINE WINDOWS} |
30 |
|
{$ENDIF} |
31 |
|
|
32 |
|
{$IFDEF FPC} |
41 |
|
FBActivityMonitor; |
42 |
|
|
43 |
|
type |
44 |
– |
|
44 |
|
{ TFB30Status } |
45 |
|
|
46 |
|
TFB30Status = class(TFBStatus,IStatus) |
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 |
|
|
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; |
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; |
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 |
|
|
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; |
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; |
859 |
|
Result := true; |
860 |
|
end; |
861 |
|
|
862 |
+ |
initialization |
863 |
+ |
PerThreadFirebirdStatusIntf := nil; |
864 |
+ |
StatusIntfRefCount := 0; |
865 |
|
end. |
866 |
|
|
867 |
|
|
868 |
+ |
|