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

Comparing:
ibx/trunk/fbintf/client/FBTransaction.pas (file contents), Revision 56 by tony, Mon Mar 6 10:20:02 2017 UTC vs.
ibx/branches/udr/client/FBTransaction.pas (file contents), Revision 379 by tony, Mon Jan 10 10:08:03 2022 UTC

# Line 72 | Line 72 | unit FBTransaction;
72   interface
73  
74   uses
75 <  Classes, SysUtils, IB, FBParamBlock, FBActivityMonitor;
75 >  Classes, SysUtils, IB, FBParamBlock, FBActivityMonitor, FBClientAPI, FBOutputBlock;
76  
77   type
78    { TFBTransaction }
79  
80    TFBTransaction = class(TActivityReporter, IActivityMonitor,ITransaction)
81    private
82 +    FFirebirdAPI: TFBClientAPI;
83      function GenerateTPB(sl: array of byte): ITPB;
84    protected
85      FTPB: ITPB;
86      FSeqNo: integer;
87 <    FDefaultCompletion: TTransactionAction;
87 >    FDefaultCompletion: TTransactionCompletion;
88      FAttachments: array of IAttachment; {Keep reference to attachment - ensures
89                                            attachment cannot be freed before transaction}
90 +    FTransactionName: AnsiString;
91 +    FForeignHandle: boolean;
92 +    procedure CheckHandle;
93      function GetActivityIntf(att: IAttachment): IActivityMonitor; virtual; abstract;
94 +    function GetJournalIntf(Attachment: IAttachment): IJournallingHook;
95 +    procedure SetInterface(api: TFBClientAPI); virtual;
96 +    function GetTrInfo(ReqBuffer: PByte; ReqBufLen: integer): ITrInformation; virtual; abstract;
97 +    procedure InternalStartSingle(attachment: IAttachment); virtual; abstract;
98 +    procedure InternalStartMultiple; virtual; abstract;
99 +    procedure InternalCommit(Force: boolean); virtual; abstract;
100 +    procedure InternalCommitRetaining; virtual; abstract;
101 +    procedure InternalRollback(Force: boolean); virtual; abstract;
102 +    procedure InternalRollbackRetaining; virtual; abstract;
103    public
104 <    constructor Create(Attachments: array of IAttachment; Params: array of byte; DefaultCompletion: TTransactionAction); overload;
105 <    constructor Create(Attachments: array of IAttachment; TPB: ITPB; DefaultCompletion: TTransactionAction); overload;
106 <    constructor Create(Attachment: IAttachment; Params: array of byte; DefaultCompletion: TTransactionAction); overload;
107 <    constructor Create(Attachment: IAttachment; TPB: ITPB; DefaultCompletion: TTransactionAction); overload;
104 >    constructor Create(api: TFBClientAPI; Attachments: array of IAttachment; Params: array of byte; DefaultCompletion: TTransactionAction; aName: AnsiString); overload;
105 >    constructor Create(api: TFBClientAPI; Attachments: array of IAttachment; TPB: ITPB; DefaultCompletion: TTransactionAction; aName: AnsiString); overload;
106 >    constructor Create(api: TFBClientAPI; Attachment: IAttachment; Params: array of byte; DefaultCompletion: TTransactionAction; aName: AnsiString); overload;
107 >    constructor Create(api: TFBClientAPI; Attachment: IAttachment; TPB: ITPB; DefaultCompletion: TTransactionAction; aName: AnsiString); overload;
108      destructor Destroy; override;
109      procedure DoDefaultTransactionEnd(Force: boolean);
110 +    property FirebirdAPI: TFBClientAPI read FFirebirdAPI;
111  
112    public
113      {ITransaction}
114      function getTPB: ITPB;
115      procedure PrepareForCommit;virtual; abstract;
116 <    procedure Commit(Force: boolean=false);  virtual; abstract;
117 <    procedure CommitRetaining;  virtual; abstract;
116 >    procedure Commit(Force: boolean=false);
117 >    procedure CommitRetaining;
118      function GetInTransaction: boolean; virtual; abstract;
119 +    function GetIsReadOnly: boolean;
120 +    function GetTransactionID: integer;
121      function GetAttachmentCount: integer;
122      function GetAttachment(index: integer): IAttachment;
123 <    procedure Rollback(Force: boolean=false);  virtual; abstract;
124 <    procedure RollbackRetaining;  virtual; abstract;
125 <    procedure Start(DefaultCompletion: TTransactionCompletion=taCommit); overload; virtual; abstract;
123 >    function GetJournalingActive(attachment: IAttachment): boolean;
124 >    function GetDefaultCompletion: TTransactionCompletion;
125 >    procedure Rollback(Force: boolean=false);
126 >    procedure RollbackRetaining;
127 >    procedure Start(DefaultCompletion: TTransactionCompletion=taCommit); overload;
128      procedure Start(TPB: ITPB; DefaultCompletion: TTransactionCompletion=taCommit); overload;
129 +    function GetTrInformation(Requests: array of byte): ITrInformation; overload;
130 +    function GetTrInformation(Request: byte): ITrInformation; overload;
131 +    function GetTransactionName: AnsiString;
132 +    procedure SetTransactionName(aValue: AnsiString);
133  
134      property InTransaction: boolean read GetInTransaction;
135      property TransactionSeqNo: integer read FSeqNo;
136    end;
137  
138 +  {The transaction user interface is used to force an action on the end of the
139 +   transaction.}
140 +
141 +  ITransactionUser = interface
142 +    ['{156fcdc9-a326-44b3-a82d-f23c6fb9f97c}']
143 +    procedure TransactionEnding(aTransaction: ITransaction; Force: boolean);
144 +  end;
145 +
146 +  { TTPBItem }
147 +
148 +  TTPBItem = class(TParamBlockItem,ITPBItem)
149 +  public
150 +    function getParamTypeName: AnsiString; override;
151 +  end;
152 +
153 +  { TTPB }
154 +
155 +  TTPB = class (TCustomParamBlock<TTPBItem,ITPBItem>, ITPB)
156 +  protected
157 +    function LookupItemType(ParamTypeName: AnsiString): byte; override;
158 +  public
159 +    constructor Create(api: TFBClientAPI);
160 +    function GetParamTypeName(ParamType: byte): Ansistring;
161 +    {$IFDEF FPC}
162 +    function ITPB.GetDPBParamTypeName = GetParamTypeName;
163 +    {$ELSE}
164 +    function GetDPBParamTypeName(ParamType: byte): Ansistring;
165 +    {$ENDIF}
166 +    function AsText: AnsiString;
167 + end;
168 +
169 +  {$IFDEF FPC}
170 +  TTrInfoItem = class;
171 +
172 +  { TTrInfoItem }
173 +
174 +  TTrInfoItem = class(TOutputBlockItemGroup<TTrInfoItem,ITrInfoItem>,ITrInfoItem)
175 +  {$ELSE}
176 +    TTrInfoItem = class(TOutputBlockItemGroup<TOutputBlockItem,ITrInfoItem>,ITrInfoItem)
177 +  {$ENDIF}
178 +    public
179 +      procedure DecodeTraIsolation(var IsolationType, RecVersion: byte);
180 +  end;
181 +
182 +  { TTrInformation }
183 +
184 +  TTrInformation = class(TCustomOutputBlock<TTrInfoItem,ITrInfoItem>, ITrInformation)
185 +  protected
186 +    procedure DoParseBuffer; override;
187 +  public
188 +    constructor Create(api: TFBClientAPI; aSize: integer = DefaultBufferSize);
189 +    {$IFNDEF FPC}
190 +    function Find(ItemType: byte): ITrInfoItem;
191 +    {$ENDIF}
192 +  end;
193 +
194 +
195   implementation
196  
197 < uses FBMessages, FBStatement;
197 > uses FBMessages;
198 >
199 > const
200 >  isc_tpb_last_tpb_constant = isc_tpb_at_snapshot_number;
201 >
202 >  TPBConstantNames: array[1..isc_tpb_last_tpb_constant] of string = (
203 >    'consistency',
204 >    'concurrency',
205 >    'shared',
206 >    'protected',
207 >    'exclusive',
208 >    'wait',
209 >    'nowait',
210 >    'read',
211 >    'write',
212 >    'lock_read',
213 >    'lock_write',
214 >    'verb_time',
215 >    'commit_time',
216 >    'ignore_limbo',
217 >    'read_committed',
218 >    'autocommit',
219 >    'rec_version',
220 >    'no_rec_version',
221 >    'restart_requests',
222 >    'no_auto_undo',
223 >    'lock_timeout',
224 >    'read_consistency',
225 >    'at_snapshot_number'
226 >  );
227  
228   { TFBTransaction }
229  
# Line 123 | Line 231 | function TFBTransaction.GenerateTPB(sl:
231   var
232    i: Integer;
233   begin
234 <  Result := TTPB.Create;
234 >  Result := TTPB.Create(FFirebirdAPI);
235    for i := 0 to Length(sl) - 1 do
236      Result.Add(sl[i]);
237   end;
238  
239 < constructor TFBTransaction.Create(Attachments: array of IAttachment;
240 <  Params: array of byte; DefaultCompletion: TTransactionAction);
239 > procedure TFBTransaction.CheckHandle;
240 > begin
241 >  if not InTransaction then
242 >    IBError(ibxeNotInTransaction,[]);
243 > end;
244 >
245 > function TFBTransaction.GetJournalIntf(Attachment: IAttachment): IJournallingHook;
246 > begin
247 >  Attachment.QueryInterface(IJournallingHook,Result)
248 > end;
249 >
250 > procedure TFBTransaction.SetInterface(api: TFBClientAPI);
251   begin
252 <  Create(Attachments,GenerateTPB(Params), DefaultCompletion);
252 >  FFirebirdAPI := api;
253   end;
254  
255 < constructor TFBTransaction.Create(Attachments: array of IAttachment; TPB: ITPB;
256 <  DefaultCompletion: TTransactionAction);
255 > constructor TFBTransaction.Create(api: TFBClientAPI; Attachments: array of IAttachment;
256 >  Params: array of byte; DefaultCompletion: TTransactionAction; aName: AnsiString);
257 > begin
258 >  Create(api, Attachments,GenerateTPB(Params), DefaultCompletion, aName);
259 > end;
260 >
261 > constructor TFBTransaction.Create(api: TFBClientAPI; Attachments: array of IAttachment; TPB: ITPB;
262 >  DefaultCompletion: TTransactionAction; aName: AnsiString);
263   var
264    i: Integer;
265   begin
266    inherited Create(nil);
267 +  FTransactionName := aName;
268 +  SetInterface(api);
269    if Length(Attachments) = 0 then
270      IBError(ibxeEmptyAttachmentsList,[nil]);
271  
272 +  {make sure all attachments use same Firebird API}
273 +  for i := 0 to Length(Attachments) - 1 do
274 +    if Attachments[i].getFirebirdAPI.GetFBLibrary.GetHandle <> FFirebirdAPI.GetFBLibrary.GetHandle then
275 +      IBError(ibxeDifferentAPIs,[nil]);
276 +
277    SetLength(FAttachments,Length(Attachments));
278    for i := 0 to Length(Attachments) - 1 do
279    begin
# Line 153 | Line 284 | begin
284    Start(DefaultCompletion);
285   end;
286  
287 < constructor TFBTransaction.Create(Attachment: IAttachment;
288 <  Params: array of byte; DefaultCompletion: TTransactionAction);
287 > constructor TFBTransaction.Create(api: TFBClientAPI; Attachment: IAttachment;
288 >  Params: array of byte; DefaultCompletion: TTransactionAction; aName: AnsiString);
289   begin
290 <  Create(Attachment,GenerateTPB(Params),DefaultCompletion);
290 >  Create(api,Attachment,GenerateTPB(Params),DefaultCompletion,aName);
291   end;
292  
293 < constructor TFBTransaction.Create(Attachment: IAttachment; TPB: ITPB;
294 <  DefaultCompletion: TTransactionAction);
293 > constructor TFBTransaction.Create(api: TFBClientAPI; Attachment: IAttachment; TPB: ITPB;
294 >  DefaultCompletion: TTransactionAction; aName: AnsiString);
295   begin
296    inherited Create(nil);
297 +  SetInterface(api);
298    AddMonitor(GetActivityIntf(Attachment));
299    SetLength(FAttachments,1);
300    FAttachments[0] := Attachment;
301    FTPB := TPB;
302 +  FTransactionName := aName;
303    Start(DefaultCompletion);
304   end;
305  
# Line 178 | Line 311 | end;
311  
312   procedure TFBTransaction.DoDefaultTransactionEnd(Force: boolean);
313   var i: integer;
314 <    intf: TInterfacedObject;
314 >    intf: IUnknown;
315 >    user: ITransactionUser;
316   begin
317 <  if InTransaction then
317 >  if InTransaction and not FForeignHandle then
318    begin
319      for i := 0 to InterfaceCount - 1 do
320      begin
321        intf := GetInterface(i);
322 <      if (intf <> nil) and  (intf is TFBStatement) then
323 <        TFBStatement(intf).TransactionEnding(self,Force);
322 >      if (intf <> nil) and  (intf.QueryInterface(ITransactionUser,user) = S_OK) then
323 >        user.TransactionEnding(self,Force);
324      end;
325      case FDefaultCompletion of
326      taRollback:
# Line 202 | Line 336 | begin
336    Result := FTPB;
337   end;
338  
339 + procedure TFBTransaction.Commit(Force: boolean);
340 + var i: integer;
341 +    TransactionID: integer;
342 +    TransactionEndNeeded: array of boolean;
343 + begin
344 +  if not GetInTransaction then Exit;
345 +
346 +  if FForeignHandle then
347 +    IBError(ibxeTransactionNotOwned,[nil]);
348 +
349 +  SetLength(TransactionEndNeeded,Length(FAttachments));
350 +  TransactionID := GetTransactionID;
351 +  for i := 0 to Length(FAttachments) - 1 do
352 +    if (FAttachments[i] <> nil)  then
353 +      TransactionEndNeeded[i] := GetJournalingActive(FAttachments[i])
354 +    else
355 +      TransactionEndNeeded[i] := false;
356 +  InternalCommit(Force);
357 +  for i := 0 to Length(FAttachments) - 1 do
358 +    if TransactionEndNeeded[i] then
359 +       GetJournalIntf(FAttachments[i]).TransactionEnd(TransactionID, TACommit);
360 + end;
361 +
362 + procedure TFBTransaction.CommitRetaining;
363 + var i: integer;
364 +    TransactionID: integer;
365 + begin
366 +  if not GetInTransaction then Exit;
367 +
368 +  TransactionID := GetTransactionID;
369 +  InternalCommitRetaining;
370 +  for i := 0 to Length(FAttachments) - 1 do
371 +    if (FAttachments[i] <> nil) and GetJournalingActive(FAttachments[i]) then
372 +       GetJournalIntf(FAttachments[i]).TransactionRetained(self,TransactionID, TACommitRetaining);
373 + end;
374 +
375 + function TFBTransaction.GetIsReadOnly: boolean;
376 + var Info: ITrInformation;
377 + begin
378 +  Info := GetTrInformation(isc_info_tra_access);
379 +  if (Info.Count > 0) and (Info[0].getItemType = isc_info_tra_access) then
380 +    Result := Info[0].getAsInteger = isc_info_tra_readonly
381 +  else
382 +    Result := false;
383 + end;
384 +
385 + function TFBTransaction.GetTransactionID: integer;
386 + var Info: ITrInformation;
387 + begin
388 +  Result := -1;
389 +  Info := GetTrInformation(isc_info_tra_id);
390 +  if (Info.Count > 0) and (Info[0].getItemType = isc_info_tra_id) then
391 +    Result := Info[0].getAsInteger;
392 + end;
393 +
394   function TFBTransaction.GetAttachmentCount: integer;
395   begin
396    Result := Length(FAttachments);
# Line 215 | Line 404 | begin
404      IBError(ibxeAttachmentListIndexError,[index]);
405   end;
406  
407 + function TFBTransaction.GetJournalingActive(attachment: IAttachment): boolean;
408 + begin
409 +  Result := false;
410 +  if (attachment = nil) and (length(FAttachments) > 0) then
411 +    attachment := FAttachments[0];
412 +  if attachment <> nil then
413 +  with attachment do
414 +  Result := self.GetInTransaction and JournalingActive and
415 +     ((((joReadOnlyTransactions in GetJournalOptions) and self.GetIsReadOnly)) or
416 +     ((joReadWriteTransactions in GetJournalOptions) and not self.GetIsReadOnly));
417 + end;
418 +
419 + function TFBTransaction.GetDefaultCompletion: TTransactionCompletion;
420 + begin
421 +  Result := FDefaultCompletion;
422 + end;
423 +
424 + procedure TFBTransaction.Rollback(Force: boolean);
425 + var i: integer;
426 +    TransactionID: integer;
427 +    TransactionEndNeeded: array of boolean;
428 + begin
429 +  if not GetInTransaction then Exit;
430 +
431 +  if FForeignHandle then
432 +    IBError(ibxeTransactionNotOwned,[nil]);
433 +
434 +  SetLength(TransactionEndNeeded,Length(FAttachments));
435 +  TransactionID := GetTransactionID;
436 +  for i := 0 to Length(FAttachments) - 1 do
437 +    if (FAttachments[i] <> nil)  then
438 +      TransactionEndNeeded[i] := GetJournalingActive(FAttachments[i])
439 +    else
440 +      TransactionEndNeeded[i] := false;
441 +  InternalRollback(Force);
442 +  for i := 0 to Length(FAttachments) - 1 do
443 +    if TransactionEndNeeded[i] then
444 +       GetJournalIntf(FAttachments[i]).TransactionEnd(TransactionID, TARollback);
445 + end;
446 +
447 + procedure TFBTransaction.RollbackRetaining;
448 + var i: integer;
449 +    TransactionID: integer;
450 + begin
451 +  if not GetInTransaction then Exit;
452 +
453 +  TransactionID := GetTransactionID;
454 +  InternalRollbackRetaining;
455 +  for i := 0 to Length(FAttachments) - 1 do
456 +    if (FAttachments[i] <> nil) and GetJournalingActive(FAttachments[i]) then
457 +       GetJournalIntf(FAttachments[i]).TransactionRetained(self,TransactionID,TARollbackRetaining);
458 + end;
459 +
460 + procedure TFBTransaction.Start(DefaultCompletion: TTransactionCompletion);
461 + var i: integer;
462 + begin
463 +  if GetInTransaction then
464 +    Exit;
465 +
466 +  FDefaultCompletion := DefaultCompletion;
467 +
468 +  if Length(FAttachments) = 1 then
469 +    InternalStartSingle(FAttachments[0])
470 +  else
471 +    InternalStartMultiple;
472 +  for i := 0 to Length(FAttachments) - 1 do
473 +    if (FAttachments[i] <> nil) and GetJournalingActive(FAttachments[i]) then
474 +      GetJournalIntf(FAttachments[i]).TransactionStart(self);
475 +  Inc(FSeqNo);
476 + end;
477 +
478   procedure TFBTransaction.Start(TPB: ITPB; DefaultCompletion: TTransactionCompletion
479    );
480   begin
# Line 222 | Line 482 | begin
482    Start(DefaultCompletion);
483   end;
484  
485 + function TFBTransaction.GetTrInformation(Requests: array of byte
486 +  ): ITrInformation;
487 + var ReqBuffer: PByte;
488 +    i: integer;
489 + begin
490 +  CheckHandle;
491 +  if Length(Requests) = 1 then
492 +    Result := GetTrInformation(Requests[0])
493 +  else
494 +  begin
495 +    GetMem(ReqBuffer,Length(Requests));
496 +    try
497 +      for i := 0 to Length(Requests) - 1 do
498 +        ReqBuffer[i] := Requests[i];
499 +
500 +      Result := GetTrInfo(ReqBuffer,Length(Requests));
501 +
502 +    finally
503 +      FreeMem(ReqBuffer);
504 +    end;
505 +  end;
506 + end;
507 +
508 + function TFBTransaction.GetTrInformation(Request: byte): ITrInformation;
509 + begin
510 +  CheckHandle;
511 +  Result := GetTrInfo(@Request,1);
512 + end;
513 +
514 + function TFBTransaction.GetTransactionName: AnsiString;
515 + begin
516 +  Result := FTransactionName;
517 + end;
518 +
519 + procedure TFBTransaction.SetTransactionName(aValue: AnsiString);
520 + begin
521 +  FTransactionName := aValue;
522 + end;
523 +
524 + { TTPBItem }
525 +
526 + function TTPBItem.getParamTypeName: AnsiString;
527 + begin
528 +  Result :=  TPBPrefix + TPBConstantNames[getParamType];
529 + end;
530 +
531 +
532 + {TTPB}
533 +
534 + constructor TTPB.Create(api: TFBClientAPI);
535 + begin
536 +  inherited Create(api);
537 +  FDataLength := 1;
538 +  FBuffer^ := isc_tpb_version3;
539 + end;
540 +
541 + function TTPB.GetParamTypeName(ParamType: byte): Ansistring;
542 + begin
543 +  if ParamType <= isc_tpb_last_tpb_constant then
544 +    Result := TPBPrefix + TPBConstantNames[ParamType]
545 +  else
546 +    Result := '';
547 + end;
548 +
549 + function TTPB.AsText: AnsiString;
550 + var i: integer;
551 + begin
552 +  Result := '[';
553 +  for i := 0 to getCount - 1 do
554 +  begin
555 +    Result := Result + GetParamTypeName(getItems(i).getParamType);
556 +    if i < getCount - 1 then
557 +      Result := Result + ',';
558 +  end;
559 +  Result := Result + ']';
560 + end;
561 +
562 + {$IFNDEF FPC}
563 + function TTPB.GetDPBParamTypeName(ParamType: byte): Ansistring;
564 + begin
565 +  Result := GetParamTypeName(ParamType);
566 + end;
567 + {$ENDIF}
568 +
569 +
570 + function TTPB.LookupItemType(ParamTypeName: AnsiString): byte;
571 + var i: byte;
572 + begin
573 +  Result := 0;
574 +  ParamTypeName := LowerCase(ParamTypeName);
575 +  if (Pos(TPBPrefix, ParamTypeName) = 1) then
576 +    Delete(ParamTypeName, 1, Length(TPBPrefix));
577 +
578 +  for i := 1 to isc_tpb_last_tpb_constant do
579 +    if (ParamTypeName = TPBConstantNames[i]) then
580 +    begin
581 +      Result := i;
582 +      break;
583 +    end;
584 + end;
585 +
586 + { TTrInfoItem }
587 +
588 + procedure TTrInfoItem.DecodeTraIsolation(var IsolationType, RecVersion: byte);
589 + begin
590 +  with FFirebirdClientAPI, ItemData^ do
591 +  if getItemType = isc_info_tra_isolation then
592 +  begin
593 +    if FDataLength = 1 then
594 +    begin
595 +      IsolationType := getAsInteger;
596 +      RecVersion := 0;
597 +    end
598 +    else
599 +    begin
600 +      IsolationType := (FBufPtr + 3)^;
601 +      RecVersion := (FBufPtr + 4)^;
602 +    end
603 +  end
604 +  else
605 +    IBError(ibxeInfoBufferTypeError,[integer(FBufPtr^)]);
606 + end;
607 +
608 + { TTrInformation }
609 +
610 + procedure TTrInformation.DoParseBuffer;
611 + var P: PByte;
612 +    index: integer;
613 + begin
614 +  P := Buffer;
615 +  index := 0;
616 +  SetLength(FItems,0);
617 +  while (P^ <> isc_info_end) and (P < Buffer + getBufSize) do
618 +  begin
619 +    SetLength(FItems,index+1);
620 +    case byte(P^) of
621 +    isc_info_tra_id,
622 +    isc_info_tra_oldest_interesting,
623 +    isc_info_tra_oldest_active,
624 +    isc_info_tra_oldest_snapshot,
625 +    fb_info_tra_snapshot_number,
626 +    isc_info_tra_lock_timeout:
627 +      FItems[index] := AddIntegerItem(P);
628 +
629 +    isc_info_tra_isolation,
630 +      {return transaction isolation mode of current transaction.
631 +        format of returned clumplets is following:
632 +
633 +        isc_info_tra_isolation,
634 +                1, isc_info_tra_consistency | isc_info_tra_concurrency
635 +        |
636 +                2, isc_info_tra_read_committed,
637 +                         isc_info_tra_no_rec_version | isc_info_tra_rec_version
638 +
639 +        i.e. for read committed transactions returned 2 items while for
640 +        other transactions returned 1 item}
641 +
642 +    isc_info_tra_access:
643 +      FItems[index] := AddIntegerItem(P);
644 +    fb_info_tra_dbpath:
645 +      FItems[index] := AddStringItem(P);
646 +    else
647 +      FItems[index] := AddItem(P);
648 +    end;
649 +    P := P + FItems[index]^.FSize;
650 +    Inc(index);
651 +  end;
652 + end;
653 +
654 + constructor TTrInformation.Create(api: TFBClientAPI; aSize: integer);
655 + begin
656 +  inherited Create(api,aSize);
657 +  FIntegerType := dtInteger;
658 + end;
659 +
660 + {$IFNDEF FPC}
661 + function TTrInformation.Find(ItemType: byte): ITrInfoItem;
662 + begin
663 +  Result := inherited Find(ItemType);
664 +  if Result.GetSize = 0 then
665 +    Result := nil;
666 + end;
667 + {$ENDIF}
668 +
669   end.
670  

Comparing:
ibx/trunk/fbintf/client/FBTransaction.pas (property svn:eol-style), Revision 56 by tony, Mon Mar 6 10:20:02 2017 UTC vs.
ibx/branches/udr/client/FBTransaction.pas (property svn:eol-style), Revision 379 by tony, Mon Jan 10 10:08:03 2022 UTC

# Line 0 | Line 1
1 + native

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines