home *** CD-ROM | disk | FTP | other *** search
/ Programmer 7500 / MAX_PROGRAMMERS.iso / PASCAL / BTP20.ZIP / EXAMPLE2.PAS < prev    next >
Encoding:
Pascal/Delphi Source File  |  1993-06-10  |  5.7 KB  |  164 lines

  1. PROGRAM Example2;             { (C) 1993 John C. Leon   last updated 6/10/93 }
  2.  
  3. { This is another arbitrary, but simple, program.  Like EXAMPLE1, it uses the
  4.   EXAMPLE file created by CREATE1.  It demonstrates the use of BTP with the
  5.   GetNextExtended call. }
  6.  
  7. {$IFDEF production} {$D-,R-,L-,S-} {$ENDIF}
  8. {$A-}
  9.  
  10. USES
  11.     BTP;
  12.  
  13. TYPE
  14.    {Note that declaration of type MyFields is identical to that in EXAMPLE1.}
  15.    MyFields = record
  16.                  case integer of           {Note that string fields are set }
  17.                  1: (First   : string[9];  {to (KeyLen-1) to leave room for }
  18.                      Last    : string[19]; {the length byte.                }
  19.                      Salary  : double;
  20.                      KeyBuf  : array[1..20] of char);{size to largest key }
  21.                  2: (DBuffer : array[1..38] of char);{size to rec length  }
  22.                  3: (Position: array[1..2] of word); {high word first!    }
  23.                  end;                                {useful after GETPOS }
  24.    PExample      = ^ExampleFile;
  25.    ExampleFile   = object(BFileExt)
  26.                       Fields: MyFields;
  27.                       function BT(OpCode, Key: integer): integer; virtual;
  28.                       function BTExt(OpCode, Key: integer): integer; virtual;
  29.                       end;
  30.  
  31.  
  32. VAR
  33.    Example : PExample;
  34.    NumberRecords,
  35.    NumMatchingRecords: longint;
  36.    x       : string;
  37.    Value   : TByteArray;   {defined in BTP.TPU}
  38.    Counter : integer;
  39.  
  40.  
  41. (* Define methods of ExampleFile *)
  42. (* ------------------------------------------------------------------------ *)
  43.  
  44. function ExampleFile.BT(OpCode, Key:integer):integer;
  45. begin
  46.    {DO NOT call ancestor function, as it is abstract.}
  47.    DBufferLen := Specs.RecLen;
  48.    BT := Btrv(OpCode, PosBlk, Fields, DBufferLen, Fields.KeyBuf, Key);
  49. end;
  50.  
  51. function ExampleFile.BTExt(OpCode, Key: integer): integer;
  52. begin
  53.    {MUST call ancestor function, to set up buffers.}
  54.    inherited BTExt(OpCode, Key);
  55.    BTExt := Btrv(OpCode, PosBlk, ExtDBuffer^.Entire, DBufferLen, Fields.KeyBuf,
  56.                  Key);
  57. end;
  58.  
  59.  
  60. (* begin MAIN PROGRAM code *)
  61. (* ------------------------------------------------------------------------ *)
  62. BEGIN
  63.  
  64. if not IsBtrieveLoaded then
  65.    begin
  66.    writeln('Please load Btrieve before running this program ...');
  67.    writeln('Program aborted.');
  68.    halt(1);
  69.    end;
  70.  
  71. Example := new(PExample, Init('Example', ReadOnly, ''));
  72. if BStatus <> 0 then
  73.    begin
  74.    writeln('Error ... Status: ', BStatus);
  75.    dispose(Example, Done);
  76.    halt(2);
  77.    end;
  78. if Example^.NumRecs < 2 then
  79.    begin
  80.    writeln('Please run Example1.EXE to put at least two records in EXAMPLE');
  81.    BStatus := Example^.Close;
  82.    dispose(Example, Done);
  83.    halt(3);
  84.    end;
  85.  
  86. {The SetTerms procedure is just a convenient way to set the 4 required
  87.  parameters (Filter.MaxSkip, Filter.NumLogicTerms, Extractor.NumRecords, and
  88.  Extractor.NumFields).}
  89.  
  90. Example^.SetTerms(50, 2, 5, 1);
  91.  
  92. {Since the 'Value' parameter to the PFilterSpec.InitV constructor is an open
  93.  array of byte, we are using the TByteArray (255 bytes) defined in BTP.TPU as
  94.  a buffer.  That is, we are forced to move our filter criteria into a buffer,
  95.  which here is the Value variable.  We put two elements into the PFilterSpec
  96.  collection, and specify that the first element is to be ANDed with the
  97.  second, and that the second is the last term in the filter condition. }
  98.  
  99. X := 'Leon';
  100. move(X, Value, sizeof(X)+1);
  101. with Example^.FilterSpec^ do
  102.    insert(new(PFilterSpec, InitV(BLString, 20, 10, Equal, NextTermAnd, Value)));
  103.  
  104. X := 'John';
  105. move(X, Value, sizeof(X)+1);
  106. with Example^.FilterSpec^ do
  107.    insert(new(PFilterSpec, InitV(BLString, 10, 0, Equal, LastTerm, Value)));
  108.  
  109. {
  110.   Now put the required minimum of 1 extractor spec into the appropriate
  111.   collection.  This is where we tell Btrieve exactly WHAT "field(s)" to
  112.   retrieve from each record that meets the filter criteria.  In this case,
  113.   we're specifying the entire record length.  We've already specified that
  114.   we're gonna be getting only one field (by setting
  115.   Example^.Extractor.NumFields to 1 above). The INCREDIBLE drudgery of
  116.   putting the filter specs and extractor specs and other required data into
  117.   the appropriate buffer for the GetNextExt call ( i.e. the BTExt() call ),
  118.   is handled internally by BTP.  Specifically, it is handled by the inherited
  119.   BTExt function, which calls:
  120.  
  121.      BFileExt.SetExtDBufferLen and
  122.      BFileExt.MakeExtDBuffer.
  123. }
  124.  
  125. with Example^.ExtractorSpec^ do
  126.    insert(new(PExtSpec, Init(Example^.Specs.RecLen, 0)));
  127.  
  128. BStatus := Example^.BT(BGetFirst, 0);
  129. writeln('Status of get first is ', BStatus);
  130.  
  131. BStatus := Example^.BTExt(BGetNextExt, 0);
  132. writeln('Status of first ExtGetNext is ', BStatus);
  133. if BStatus = 9 then
  134.    begin
  135.    writeln('It is normal to get status 9 (EOF) if the number of records');
  136.    writeln('actually returned by the GetNextExt call is less than the');
  137.    writeln('number of records specified in the extractor.  If you run the');
  138.    writeln('EXAMPLE1 program a total of 5 times, then there will be 5');
  139.    writeln('records matching the filter criteria, and you''ll get a status 0');
  140.    writeln('on the GetNextExt call. I.e., status 9 does NOT necessarily');
  141.    writeln('mean an error!');
  142.    end;
  143.  
  144. writeln('Number of records extracted on first GetNextExt call having name ');
  145. writeln('''John Leon'' is ', Example^.ExtDBuffer^.NumRecs);
  146.  
  147. NumMatchingRecords := Example^.ExtDBuffer^.NumRecs;
  148.  
  149. while BStatus = 0 do
  150.    begin
  151.    BStatus := Example^.BTExt(BGetNextExt, 0);
  152.    inc(NumMatchingRecords, Example^.ExtDBuffer^.NumRecs);
  153.    end;
  154.  
  155. write('TOTAL number of records in file having name ''John Leon'' is ');
  156. writeln(NumMatchingRecords);
  157.  
  158. BStatus := Example^.Close;
  159. dispose(Example, Done);
  160.  
  161. END.
  162.  
  163.  
  164.