ViewVC Help
View File | Revision Log | Show Annotations | Download File | View Changeset | Root Listing
root/public/ibx/trunk/runtime/IB.pas
(Generate patch)

Comparing ibx/trunk/runtime/IB.pas (file contents):
Revision 26 by tony, Thu Feb 26 10:33:34 2015 UTC vs.
Revision 27 by tony, Tue Apr 14 13:10:23 2015 UTC

# Line 188 | Line 188 | type
188      ibxeSV5APIError,
189      ibxeThreadFailed,
190      ibxeFieldSizeError,
191 <    ibxTransactionNotEnding
191 >    ibxeTransactionNotEnding,
192 >    ibxeDscInfoTokenMissing
193      );
194  
195    TStatusVector              = array[0..19] of ISC_STATUS;
196    PStatusVector              = ^TStatusVector;
197  
198 +  {TResultBuffer inspired by IBPP RB class - access a isc_dsql_sql_info result buffer}
199 +
200 +  TResultBuffer = class
201 +  private
202 +    mBuffer: PChar;
203 +    mSize: short;
204 +    function FindToken(token: char): PChar; overload;
205 +    function FindToken(token: char; subtoken: char): PChar; overload;
206 +  public
207 +    constructor Create(aSize: integer = 1024);
208 +    destructor Destroy; override;
209 +    function Size: short;
210 +    procedure Reset;
211 +    function GetValue(token: char): integer; overload;
212 +    function GetValue(token: char; subtoken: char): integer; overload;
213 +    function GetCountValue(token: char): integer;
214 +    function GetBool(token: char): boolean;
215 +    function GetString(token: char; var data: string): integer;
216 +    function buffer: PChar;
217 +  end;
218  
219   const
220    IBPalette1 = 'Firebird'; {do not localize}
# Line 324 | Line 345 | const
345      SSV5APIError,
346      SThreadFailed,
347      SFieldSizeError,
348 <    STransactionNotEnding
348 >    STransactionNotEnding,
349 >    SDscInfoTokenMissing
350    );
351  
352   var
# Line 346 | Line 368 | function GetIBDataBaseErrorMessages: TIB
368   implementation
369  
370   uses
371 <  IBIntf;
371 >  IBIntf, IBHeader;
372  
373   var
374    IBDataBaseErrorMessages: TIBDataBaseErrorMessages;
# Line 478 | Line 500 | begin
500      end;
501   end;
502  
503 + { TResultBuffer }
504 +
505 + constructor TResultBuffer.Create(aSize: integer);
506 + begin
507 +  inherited Create;
508 +  mSize := aSize;
509 +  GetMem(mBuffer,aSize);
510 +  FillChar(mBuffer^,mSize,255);
511 + end;
512 +
513 + destructor TResultBuffer.Destroy;
514 + begin
515 +  if mBuffer <> nil then FreeMem(mBuffer);
516 +  inherited;
517 + end;
518 +
519 + function TResultBuffer.buffer: PChar;
520 + begin
521 +  Result := mBuffer;
522 + end;
523 +
524 + function TResultBuffer.FindToken(token: char): PChar;
525 + var p: PChar;
526 +    len: integer;
527 + begin
528 +  Result := nil;
529 +  p := mBuffer;
530 +
531 +  while p^ <> char(isc_info_end) do
532 +  begin
533 +    if p^ = token then
534 +    begin
535 +      Result := p;
536 +      Exit;
537 +    end;
538 +    len := isc_vax_integer(p+1,2);
539 +    Inc(p,len+3);
540 +  end;
541 + end;
542 +
543 + function TResultBuffer.FindToken(token: char; subtoken: char): PChar;
544 + var p: PChar;
545 +    len, inlen: integer;
546 + begin
547 +  Result := nil;
548 +  p := mBuffer;
549 +
550 +  while p^ <> char(isc_info_end) do
551 +  begin
552 +    if p^ = token then
553 +    begin
554 +      {Found token, now find subtoken}
555 +      inlen := isc_vax_integer(p+1, 2);
556 +      Inc(p,3);
557 +      while inlen > 0 do
558 +      begin
559 +        if p^ = subtoken then
560 +        begin
561 +          Result := p;
562 +          Exit;
563 +        end;
564 +        len := isc_vax_integer(p+1, 2);
565 +        Inc(p,len + 3);
566 +        Dec(inlen,len + 3);
567 +      end;
568 +      Exit;
569 +    end;
570 +    len := isc_vax_integer(p+1, 2);
571 +    inc(p,len+3);
572 +  end;
573 + end;
574 +
575 + function TResultBuffer.GetBool(token: char): boolean;
576 + var aValue: integer;
577 +    p: PChar;
578 + begin
579 +  p := FindToken(token);
580 +
581 +  if p = nil then
582 +    IBError(ibxeDscInfoTokenMissing,[token]);
583 +
584 +  aValue := isc_vax_integer(p+1, 4);
585 +  Result := aValue <> 0;
586 + end;
587 +
588 + function TResultBuffer.GetCountValue(token: char): integer;
589 + var len: integer;
590 +    p: PChar;
591 + begin
592 +  {Specifically used on tokens like isc_info_insert_count and the like
593 +   which return detailed counts per relation. We sum up the values.}
594 +
595 +  p := FindToken(token);
596 +
597 +  if p = nil then
598 +    IBError(ibxeDscInfoTokenMissing,[token]);
599 +
600 +  {len is the number of bytes in the following array}
601 +
602 +  len := isc_vax_integer(p+1, 2);
603 +  Inc(p,3);
604 +  Result := 0;
605 +  while len > 0 do
606 +  begin
607 +    {Each array item is 6 bytes : 2 bytes for the relation_id which
608 +     we skip, and 4 bytes for the count value which we sum up across
609 +     all tables.}
610 +
611 +     Inc(Result,isc_vax_integer(p+2, 4));
612 +     Inc(p,6);
613 +     Dec(len,6);
614 +  end;
615 + end;
616 +
617 + function TResultBuffer.GetString(token: char; var data: string): integer;
618 + var p: PChar;
619 + begin
620 +  Result := 0;
621 +  p := FindToken(token);
622 +
623 +  if p = nil then
624 +    IBError(ibxeDscInfoTokenMissing,[token]);
625 +
626 +  Result := isc_vax_integer(p+1, 2);
627 +  SetString(data,p+3,Result);
628 + end;
629 +
630 + function TResultBuffer.GetValue(token: char): integer;
631 + var len: integer;
632 +    p: PChar;
633 + begin
634 +  Result := 0;
635 +  p := FindToken(token);
636 +
637 +  if p = nil then
638 +    IBError(ibxeDscInfoTokenMissing,[token]);
639 +
640 +  len := isc_vax_integer(p+1, 2);
641 +  if (len <> 0) then
642 +    Result := isc_vax_integer(p+3, len);
643 + end;
644 +
645 + function TResultBuffer.GetValue(token: char; subtoken: char): integer;
646 + var len: integer;
647 +    p: PChar;
648 + begin
649 +  Result := 0;
650 +  p := FindToken(token, subtoken);
651 +
652 +  if p = nil then
653 +    IBError(ibxeDscInfoTokenMissing,[token]);
654 +
655 +  len := isc_vax_integer(p+1, 2);
656 +  if (len <> 0) then
657 +    Result := isc_vax_integer(p+3, len);
658 + end;
659 +
660 + function TResultBuffer.Size: short;
661 + begin
662 +  Result := mSize;
663 + end;
664 +
665 + procedure TResultBuffer.Reset;
666 + begin
667 +  if mBuffer <> nil then FreeMem(mBuffer);
668 +  GetMem(mBuffer,mSize);
669 +  FillChar(mBuffer^,mSize,255);
670 + end;
671 +
672  
673   { EIBError }
674   constructor EIBError.Create(ASQLCode: Long; Msg: string);
# Line 521 | Line 712 | initialization
712   finalization
713    DoneCriticalSection(IBCS);
714  
715 < end.
715 > end.

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines