ViewVC Help
View File | Revision Log | Show Annotations | Download File | View Changeset | Root Listing
root/public/ibx/trunk/fbintf/client/FBTransaction.pas
Revision: 421
Committed: Sat Oct 21 14:22:28 2023 UTC (6 months, 1 week ago) by tony
Content type: text/x-pascal
File size: 21273 byte(s)
Log Message:
Release 2.6.3 Merged

File Contents

# Content
1 (*
2 * Firebird Interface (fbintf). The fbintf components provide a set of
3 * Pascal language bindings for the Firebird API. Although predominantly
4 * a new development they include source code taken from IBX and may be
5 * considered a derived product. This software thus also includes the copyright
6 * notice and license conditions from IBX.
7 *
8 * Except for those parts dervied from IBX, contents of this file are subject
9 * to the Initial Developer's Public License Version 1.0 (the "License"); you
10 * may not use this file except in compliance with the License. You may obtain a
11 * copy of the License here:
12 *
13 * http://www.firebirdsql.org/index.php?op=doc&id=idpl
14 *
15 * Software distributed under the License is distributed on an "AS
16 * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
17 * implied. See the License for the specific language governing rights
18 * and limitations under the License.
19 *
20 * The Initial Developer of the Original Code is Tony Whyman.
21 *
22 * The Original Code is (C) 2016 Tony Whyman, MWA Software
23 * (http://www.mwasoftware.co.uk).
24 *
25 * All Rights Reserved.
26 *
27 * Contributor(s): ______________________________________.
28 *
29 *)
30 {************************************************************************}
31 { }
32 { Borland Delphi Visual Component Library }
33 { InterBase Express core components }
34 { }
35 { Copyright (c) 1998-2000 Inprise Corporation }
36 { }
37 { InterBase Express is based in part on the product }
38 { Free IB Components, written by Gregory H. Deatz for }
39 { Hoagland, Longo, Moran, Dunst & Doukas Company. }
40 { Free IB Components is used under license. }
41 { }
42 { The contents of this file are subject to the InterBase }
43 { Public License Version 1.0 (the "License"); you may not }
44 { use this file except in compliance with the License. You }
45 { may obtain a copy of the License at http://www.Inprise.com/IPL.html }
46 { Software distributed under the License is distributed on }
47 { an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either }
48 { express or implied. See the License for the specific language }
49 { governing rights and limitations under the License. }
50 { The Original Code was created by InterBase Software Corporation }
51 { and its successors. }
52 { Portions created by Inprise Corporation are Copyright (C) Inprise }
53 { Corporation. All Rights Reserved. }
54 { Contributor(s): Jeff Overcash }
55 { }
56 { IBX For Lazarus (Firebird Express) }
57 { Contributor: Tony Whyman, MWA Software http://www.mwasoftware.co.uk }
58 { Portions created by MWA Software are copyright McCallum Whyman }
59 { Associates Ltd 2011 - 2015 }
60 { }
61 {************************************************************************}
62 unit FBTransaction;
63 {$IFDEF MSWINDOWS}
64 {$DEFINE WINDOWS}
65 {$ENDIF}
66
67 {$IFDEF FPC}
68 {$mode delphi}
69 {$interfaces COM}
70 {$ENDIF}
71
72 interface
73
74 uses
75 Classes, SysUtils, IB, FBParamBlock, FBActivityMonitor, FBClientAPI, FBOutputBlock;
76
77 type
78 { TFBTransaction }
79
80 TFBTransaction = class(TActivityReporter, IActivityMonitor,ITransaction)
81 private
82 FConnectionCodePage: TSystemCodePage;
83 FFirebirdAPI: TFBClientAPI;
84 function GenerateTPB(sl: array of byte): ITPB;
85 protected
86 FTPB: ITPB;
87 FSeqNo: integer;
88 FDefaultCompletion: TTransactionCompletion;
89 FAttachments: array of IAttachment; {Keep reference to attachment - ensures
90 attachment cannot be freed before transaction}
91 FTransactionName: AnsiString;
92 FForeignHandle: boolean;
93 procedure CheckHandle;
94 function GetActivityIntf(att: IAttachment): IActivityMonitor; virtual; abstract;
95 function GetJournalIntf(Attachment: IAttachment): IJournallingHook;
96 procedure SetInterface(api: TFBClientAPI); virtual;
97 procedure SetErrorHandler(Attachment: IAttachment); virtual;
98 function GetTrInfo(ReqBuffer: PByte; ReqBufLen: integer): ITrInformation; virtual; abstract;
99 procedure InternalStartSingle(attachment: IAttachment); virtual; abstract;
100 procedure InternalStartMultiple; virtual; abstract;
101 function InternalCommit(Force: boolean): TTrCompletionState; virtual; abstract;
102 procedure InternalCommitRetaining; virtual; abstract;
103 function InternalRollback(Force: boolean): TTrCompletionState; virtual; abstract;
104 procedure InternalRollbackRetaining; virtual; abstract;
105 public
106 constructor Create(api: TFBClientAPI; Attachments: array of IAttachment; Params: array of byte; DefaultCompletion: TTransactionAction; aName: AnsiString); overload;
107 constructor Create(api: TFBClientAPI; Attachments: array of IAttachment; TPB: ITPB; DefaultCompletion: TTransactionAction; aName: AnsiString); overload;
108 constructor Create(api: TFBClientAPI; Attachment: IAttachment; Params: array of byte; DefaultCompletion: TTransactionAction; aName: AnsiString); overload;
109 constructor Create(api: TFBClientAPI; Attachment: IAttachment; TPB: ITPB; DefaultCompletion: TTransactionAction; aName: AnsiString); overload;
110 destructor Destroy; override;
111 procedure DoDefaultTransactionEnd(Force: boolean);
112 property FirebirdAPI: TFBClientAPI read FFirebirdAPI;
113 property ConnectionCodePage: TSystemCodePage read FConnectionCodePage;
114
115 public
116 {ITransaction}
117 function getTPB: ITPB;
118 procedure PrepareForCommit;virtual; abstract;
119 function Commit(Force: boolean=false): TTrCompletionState;
120 procedure CommitRetaining;
121 function GetInTransaction: boolean; virtual; abstract;
122 function GetIsReadOnly: boolean;
123 function GetTransactionID: integer;
124 function GetAttachmentCount: integer;
125 function GetAttachment(index: integer): IAttachment;
126 function GetJournalingActive(attachment: IAttachment): boolean;
127 function GetDefaultCompletion: TTransactionCompletion;
128 function Rollback(Force: boolean=false): TTrCompletionState;
129 procedure RollbackRetaining;
130 procedure Start(DefaultCompletion: TTransactionCompletion=taCommit); overload;
131 procedure Start(TPB: ITPB; DefaultCompletion: TTransactionCompletion=taCommit); overload;
132 function GetTrInformation(Requests: array of byte): ITrInformation; overload;
133 function GetTrInformation(Request: byte): ITrInformation; overload;
134 function GetTransactionName: AnsiString;
135 procedure SetTransactionName(aValue: AnsiString);
136
137 property InTransaction: boolean read GetInTransaction;
138 property TransactionSeqNo: integer read FSeqNo;
139 end;
140
141 {The transaction user interface is used to force an action on the end of the
142 transaction.}
143
144 ITransactionUser = interface
145 ['{156fcdc9-a326-44b3-a82d-f23c6fb9f97c}']
146 procedure TransactionEnding(aTransaction: ITransaction; Force: boolean);
147 end;
148
149 { TTPBItem }
150
151 TTPBItem = class(TParamBlockItem,ITPBItem)
152 public
153 function getParamTypeName: AnsiString; override;
154 end;
155
156 { TTPB }
157
158 TTPB = class (TCustomParamBlock<TTPBItem,ITPBItem>, ITPB)
159 protected
160 function LookupItemType(ParamTypeName: AnsiString): byte; override;
161 public
162 constructor Create(api: TFBClientAPI);
163 function GetParamTypeName(ParamType: byte): Ansistring;
164 {$IFDEF FPC}
165 function ITPB.GetDPBParamTypeName = GetParamTypeName;
166 {$ELSE}
167 function GetDPBParamTypeName(ParamType: byte): Ansistring;
168 {$ENDIF}
169 function AsText: AnsiString;
170 end;
171
172 {$IFDEF FPC}
173 TTrInfoItem = class;
174
175 { TTrInfoItem }
176
177 TTrInfoItem = class(TOutputBlockItemGroup<TTrInfoItem,ITrInfoItem>,ITrInfoItem)
178 {$ELSE}
179 TTrInfoItem = class(TOutputBlockItemGroup<TOutputBlockItem,ITrInfoItem>,ITrInfoItem)
180 {$ENDIF}
181 public
182 procedure DecodeTraIsolation(var IsolationType, RecVersion: byte);
183 end;
184
185 { TTrInformation }
186
187 TTrInformation = class(TCustomOutputBlock<TTrInfoItem,ITrInfoItem>, ITrInformation)
188 protected
189 procedure DoParseBuffer; override;
190 public
191 constructor Create(api: TFBClientAPI; aSize: integer = DefaultBufferSize);
192 {$IFNDEF FPC}
193 function Find(ItemType: byte): ITrInfoItem;
194 {$ENDIF}
195 end;
196
197
198 implementation
199
200 uses FBMessages;
201
202 const
203 isc_tpb_last_tpb_constant = isc_tpb_at_snapshot_number;
204
205 TPBConstantNames: array[1..isc_tpb_last_tpb_constant] of string = (
206 'consistency',
207 'concurrency',
208 'shared',
209 'protected',
210 'exclusive',
211 'wait',
212 'nowait',
213 'read',
214 'write',
215 'lock_read',
216 'lock_write',
217 'verb_time',
218 'commit_time',
219 'ignore_limbo',
220 'read_committed',
221 'autocommit',
222 'rec_version',
223 'no_rec_version',
224 'restart_requests',
225 'no_auto_undo',
226 'lock_timeout',
227 'read_consistency',
228 'at_snapshot_number'
229 );
230
231 { TFBTransaction }
232
233 function TFBTransaction.GenerateTPB(sl: array of byte): ITPB;
234 var
235 i: Integer;
236 begin
237 Result := TTPB.Create(FFirebirdAPI);
238 for i := 0 to Length(sl) - 1 do
239 Result.Add(sl[i]);
240 end;
241
242 procedure TFBTransaction.CheckHandle;
243 begin
244 if not InTransaction then
245 IBError(ibxeNotInTransaction,[]);
246 end;
247
248 function TFBTransaction.GetJournalIntf(Attachment: IAttachment): IJournallingHook;
249 begin
250 Attachment.QueryInterface(IJournallingHook,Result)
251 end;
252
253 procedure TFBTransaction.SetInterface(api: TFBClientAPI);
254 begin
255 FFirebirdAPI := api;
256 end;
257
258 procedure TFBTransaction.SetErrorHandler(Attachment: IAttachment);
259 begin
260 //Do nothing
261 end;
262
263 constructor TFBTransaction.Create(api: TFBClientAPI; Attachments: array of IAttachment;
264 Params: array of byte; DefaultCompletion: TTransactionAction; aName: AnsiString);
265 begin
266 Create(api, Attachments,GenerateTPB(Params), DefaultCompletion, aName);
267 end;
268
269 constructor TFBTransaction.Create(api: TFBClientAPI; Attachments: array of IAttachment; TPB: ITPB;
270 DefaultCompletion: TTransactionAction; aName: AnsiString);
271 var
272 i: Integer;
273 begin
274 inherited Create(nil);
275 FTransactionName := aName;
276 SetInterface(api);
277 if Length(Attachments) = 0 then
278 IBError(ibxeEmptyAttachmentsList,[nil]);
279
280 {make sure all attachments use same Firebird API}
281 for i := 0 to Length(Attachments) - 1 do
282 if Attachments[i].getFirebirdAPI.GetFBLibrary.GetHandle <> FFirebirdAPI.GetFBLibrary.GetHandle then
283 IBError(ibxeDifferentAPIs,[nil]);
284
285 SetLength(FAttachments,Length(Attachments));
286 for i := 0 to Length(Attachments) - 1 do
287 begin
288 AddMonitor(GetActivityIntf(Attachments[i]));
289 FAttachments[i] := Attachments[i];
290 end;
291 FTPB := TPB;
292 FConnectionCodePage := FAttachments[0].GetCodePage; {Use first attachment}
293 SetErrorHandler(FAttachments[0]);
294 Start(DefaultCompletion);
295 end;
296
297 constructor TFBTransaction.Create(api: TFBClientAPI; Attachment: IAttachment;
298 Params: array of byte; DefaultCompletion: TTransactionAction; aName: AnsiString);
299 begin
300 Create(api,Attachment,GenerateTPB(Params),DefaultCompletion,aName);
301 end;
302
303 constructor TFBTransaction.Create(api: TFBClientAPI; Attachment: IAttachment; TPB: ITPB;
304 DefaultCompletion: TTransactionAction; aName: AnsiString);
305 begin
306 inherited Create(nil);
307 SetInterface(api);
308 AddMonitor(GetActivityIntf(Attachment));
309 SetLength(FAttachments,1);
310 FAttachments[0] := Attachment;
311 FTPB := TPB;
312 FTransactionName := aName;
313 FConnectionCodePage := Attachment.GetCodePage;
314 SetErrorHandler(Attachment);
315 Start(DefaultCompletion);
316 end;
317
318 destructor TFBTransaction.Destroy;
319 begin
320 DoDefaultTransactionEnd(false);
321 inherited Destroy;
322 end;
323
324 procedure TFBTransaction.DoDefaultTransactionEnd(Force: boolean);
325 var i: integer;
326 intf: IUnknown;
327 user: ITransactionUser;
328 begin
329 if InTransaction and not FForeignHandle then
330 begin
331 for i := 0 to InterfaceCount - 1 do
332 begin
333 intf := GetInterface(i);
334 if (intf <> nil) and (intf.QueryInterface(ITransactionUser,user) = S_OK) then
335 user.TransactionEnding(self,Force);
336 end;
337 case FDefaultCompletion of
338 taRollback:
339 Rollback(Force);
340 taCommit:
341 Commit(Force);
342 end;
343 end;
344 end;
345
346 function TFBTransaction.getTPB: ITPB;
347 begin
348 Result := FTPB;
349 end;
350
351 function TFBTransaction.Commit(Force: boolean): TTrCompletionState;
352 var i: integer;
353 TransactionID: integer;
354 TransactionEndNeeded: array of boolean;
355 begin
356 if not GetInTransaction then Exit;
357
358 if FForeignHandle then
359 IBError(ibxeTransactionNotOwned,[nil]);
360
361 SetLength(TransactionEndNeeded,Length(FAttachments));
362 TransactionID := GetTransactionID;
363 for i := 0 to Length(FAttachments) - 1 do
364 if (FAttachments[i] <> nil) then
365 TransactionEndNeeded[i] := GetJournalingActive(FAttachments[i])
366 else
367 TransactionEndNeeded[i] := false;
368 Result := InternalCommit(Force);
369 for i := 0 to Length(FAttachments) - 1 do
370 if TransactionEndNeeded[i] then
371 GetJournalIntf(FAttachments[i]).TransactionEnd(TransactionID, Result);
372 end;
373
374 procedure TFBTransaction.CommitRetaining;
375 var i: integer;
376 TransactionID: integer;
377 begin
378 if not GetInTransaction then Exit;
379
380 TransactionID := GetTransactionID;
381 InternalCommitRetaining;
382 for i := 0 to Length(FAttachments) - 1 do
383 if (FAttachments[i] <> nil) and GetJournalingActive(FAttachments[i]) then
384 GetJournalIntf(FAttachments[i]).TransactionRetained(self,TransactionID, TACommitRetaining);
385 end;
386
387 function TFBTransaction.GetIsReadOnly: boolean;
388 var Info: ITrInformation;
389 begin
390 Info := GetTrInformation(isc_info_tra_access);
391 if (Info.Count > 0) and (Info[0].getItemType = isc_info_tra_access) then
392 Result := Info[0].getAsInteger = isc_info_tra_readonly
393 else
394 Result := false;
395 end;
396
397 function TFBTransaction.GetTransactionID: integer;
398 var Info: ITrInformation;
399 begin
400 Result := -1;
401 Info := GetTrInformation(isc_info_tra_id);
402 if (Info.Count > 0) and (Info[0].getItemType = isc_info_tra_id) then
403 Result := Info[0].getAsInteger;
404 end;
405
406 function TFBTransaction.GetAttachmentCount: integer;
407 begin
408 Result := Length(FAttachments);
409 end;
410
411 function TFBTransaction.GetAttachment(index: integer): IAttachment;
412 begin
413 if (index >= 0) and (index < Length(FAttachments)) then
414 Result := FAttachments[index]
415 else
416 IBError(ibxeAttachmentListIndexError,[index]);
417 end;
418
419 function TFBTransaction.GetJournalingActive(attachment: IAttachment): boolean;
420 begin
421 Result := false;
422 if (attachment = nil) and (length(FAttachments) > 0) then
423 attachment := FAttachments[0];
424 if attachment <> nil then
425 with attachment do
426 Result := self.GetInTransaction and JournalingActive and
427 ((((joReadOnlyTransactions in GetJournalOptions) and self.GetIsReadOnly)) or
428 ((joReadWriteTransactions in GetJournalOptions) and not self.GetIsReadOnly));
429 end;
430
431 function TFBTransaction.GetDefaultCompletion: TTransactionCompletion;
432 begin
433 Result := FDefaultCompletion;
434 end;
435
436 function TFBTransaction.Rollback(Force: boolean): TTrCompletionState;
437 var i: integer;
438 TransactionID: integer;
439 TransactionEndNeeded: array of boolean;
440 begin
441 if not GetInTransaction then Exit;
442
443 if FForeignHandle then
444 IBError(ibxeTransactionNotOwned,[nil]);
445
446 SetLength(TransactionEndNeeded,Length(FAttachments));
447 TransactionID := GetTransactionID;
448 for i := 0 to Length(FAttachments) - 1 do
449 if (FAttachments[i] <> nil) then
450 TransactionEndNeeded[i] := GetJournalingActive(FAttachments[i])
451 else
452 TransactionEndNeeded[i] := false;
453 Result := InternalRollback(Force);
454 for i := 0 to Length(FAttachments) - 1 do
455 if TransactionEndNeeded[i] then
456 GetJournalIntf(FAttachments[i]).TransactionEnd(TransactionID, Result);
457 end;
458
459 procedure TFBTransaction.RollbackRetaining;
460 var i: integer;
461 TransactionID: integer;
462 begin
463 if not GetInTransaction then Exit;
464
465 TransactionID := GetTransactionID;
466 InternalRollbackRetaining;
467 for i := 0 to Length(FAttachments) - 1 do
468 if (FAttachments[i] <> nil) and GetJournalingActive(FAttachments[i]) then
469 GetJournalIntf(FAttachments[i]).TransactionRetained(self,TransactionID,TARollbackRetaining);
470 end;
471
472 procedure TFBTransaction.Start(DefaultCompletion: TTransactionCompletion);
473 var i: integer;
474 begin
475 if GetInTransaction then
476 Exit;
477
478 FDefaultCompletion := DefaultCompletion;
479
480 if Length(FAttachments) = 1 then
481 InternalStartSingle(FAttachments[0])
482 else
483 InternalStartMultiple;
484 for i := 0 to Length(FAttachments) - 1 do
485 if (FAttachments[i] <> nil) and GetJournalingActive(FAttachments[i]) then
486 GetJournalIntf(FAttachments[i]).TransactionStart(self);
487 Inc(FSeqNo);
488 end;
489
490 procedure TFBTransaction.Start(TPB: ITPB; DefaultCompletion: TTransactionCompletion
491 );
492 begin
493 FTPB := TPB;
494 Start(DefaultCompletion);
495 end;
496
497 function TFBTransaction.GetTrInformation(Requests: array of byte
498 ): ITrInformation;
499 var ReqBuffer: PByte;
500 i: integer;
501 begin
502 CheckHandle;
503 if Length(Requests) = 1 then
504 Result := GetTrInformation(Requests[0])
505 else
506 begin
507 GetMem(ReqBuffer,Length(Requests));
508 try
509 for i := 0 to Length(Requests) - 1 do
510 ReqBuffer[i] := Requests[i];
511
512 Result := GetTrInfo(ReqBuffer,Length(Requests));
513
514 finally
515 FreeMem(ReqBuffer);
516 end;
517 end;
518 end;
519
520 function TFBTransaction.GetTrInformation(Request: byte): ITrInformation;
521 begin
522 CheckHandle;
523 Result := GetTrInfo(@Request,1);
524 end;
525
526 function TFBTransaction.GetTransactionName: AnsiString;
527 begin
528 Result := FTransactionName;
529 end;
530
531 procedure TFBTransaction.SetTransactionName(aValue: AnsiString);
532 begin
533 FTransactionName := aValue;
534 end;
535
536 { TTPBItem }
537
538 function TTPBItem.getParamTypeName: AnsiString;
539 begin
540 Result := TPBPrefix + TPBConstantNames[getParamType];
541 end;
542
543
544 {TTPB}
545
546 constructor TTPB.Create(api: TFBClientAPI);
547 begin
548 inherited Create(api);
549 FDataLength := 1;
550 FBuffer^ := isc_tpb_version3;
551 end;
552
553 function TTPB.GetParamTypeName(ParamType: byte): Ansistring;
554 begin
555 if ParamType <= isc_tpb_last_tpb_constant then
556 Result := TPBPrefix + TPBConstantNames[ParamType]
557 else
558 Result := '';
559 end;
560
561 function TTPB.AsText: AnsiString;
562 var i: integer;
563 begin
564 Result := '[';
565 for i := 0 to getCount - 1 do
566 begin
567 Result := Result + GetParamTypeName(getItems(i).getParamType);
568 if i < getCount - 1 then
569 Result := Result + ',';
570 end;
571 Result := Result + ']';
572 end;
573
574 {$IFNDEF FPC}
575 function TTPB.GetDPBParamTypeName(ParamType: byte): Ansistring;
576 begin
577 Result := GetParamTypeName(ParamType);
578 end;
579 {$ENDIF}
580
581
582 function TTPB.LookupItemType(ParamTypeName: AnsiString): byte;
583 var i: byte;
584 begin
585 Result := 0;
586 ParamTypeName := LowerCase(ParamTypeName);
587 if (Pos(TPBPrefix, ParamTypeName) = 1) then
588 Delete(ParamTypeName, 1, Length(TPBPrefix));
589
590 for i := 1 to isc_tpb_last_tpb_constant do
591 if (ParamTypeName = TPBConstantNames[i]) then
592 begin
593 Result := i;
594 break;
595 end;
596 end;
597
598 { TTrInfoItem }
599
600 procedure TTrInfoItem.DecodeTraIsolation(var IsolationType, RecVersion: byte);
601 begin
602 with FFirebirdClientAPI, ItemData^ do
603 if getItemType = isc_info_tra_isolation then
604 begin
605 if FDataLength = 1 then
606 begin
607 IsolationType := getAsInteger;
608 RecVersion := 0;
609 end
610 else
611 begin
612 IsolationType := (FBufPtr + 3)^;
613 RecVersion := (FBufPtr + 4)^;
614 end
615 end
616 else
617 IBError(ibxeInfoBufferTypeError,[integer(FBufPtr^)]);
618 end;
619
620 { TTrInformation }
621
622 procedure TTrInformation.DoParseBuffer;
623 var P: PByte;
624 index: integer;
625 begin
626 P := Buffer;
627 index := 0;
628 SetLength(FItems,0);
629 while (P^ <> isc_info_end) and (P < Buffer + getBufSize) do
630 begin
631 SetLength(FItems,index+1);
632 case byte(P^) of
633 isc_info_tra_id,
634 isc_info_tra_oldest_interesting,
635 isc_info_tra_oldest_active,
636 isc_info_tra_oldest_snapshot,
637 fb_info_tra_snapshot_number,
638 isc_info_tra_lock_timeout:
639 FItems[index] := AddIntegerItem(P);
640
641 isc_info_tra_isolation,
642 {return transaction isolation mode of current transaction.
643 format of returned clumplets is following:
644
645 isc_info_tra_isolation,
646 1, isc_info_tra_consistency | isc_info_tra_concurrency
647 |
648 2, isc_info_tra_read_committed,
649 isc_info_tra_no_rec_version | isc_info_tra_rec_version
650
651 i.e. for read committed transactions returned 2 items while for
652 other transactions returned 1 item}
653
654 isc_info_tra_access:
655 FItems[index] := AddIntegerItem(P);
656 fb_info_tra_dbpath:
657 FItems[index] := AddStringItem(P);
658 else
659 FItems[index] := AddItem(P);
660 end;
661 P := P + FItems[index]^.FSize;
662 Inc(index);
663 end;
664 end;
665
666 constructor TTrInformation.Create(api: TFBClientAPI; aSize: integer);
667 begin
668 inherited Create(api,aSize);
669 FIntegerType := dtInteger;
670 end;
671
672 {$IFNDEF FPC}
673 function TTrInformation.Find(ItemType: byte): ITrInfoItem;
674 begin
675 Result := inherited Find(ItemType);
676 if Result.GetSize = 0 then
677 Result := nil;
678 end;
679 {$ENDIF}
680
681 end.
682

Properties

Name Value
svn:eol-style native