home *** CD-ROM | disk | FTP | other *** search
- PROGRAM Example2; { (C) 1993 John C. Leon last updated 6/10/93 }
-
- { This is another arbitrary, but simple, program. Like EXAMPLE1, it uses the
- EXAMPLE file created by CREATE1. It demonstrates the use of BTP with the
- GetNextExtended call. }
-
- {$IFDEF production} {$D-,R-,L-,S-} {$ENDIF}
- {$A-}
-
- USES
- BTP;
-
- TYPE
- {Note that declaration of type MyFields is identical to that in EXAMPLE1.}
- MyFields = record
- case integer of {Note that string fields are set }
- 1: (First : string[9]; {to (KeyLen-1) to leave room for }
- Last : string[19]; {the length byte. }
- Salary : double;
- KeyBuf : array[1..20] of char);{size to largest key }
- 2: (DBuffer : array[1..38] of char);{size to rec length }
- 3: (Position: array[1..2] of word); {high word first! }
- end; {useful after GETPOS }
- PExample = ^ExampleFile;
- ExampleFile = object(BFileExt)
- Fields: MyFields;
- function BT(OpCode, Key: integer): integer; virtual;
- function BTExt(OpCode, Key: integer): integer; virtual;
- end;
-
-
- VAR
- Example : PExample;
- NumberRecords,
- NumMatchingRecords: longint;
- x : string;
- Value : TByteArray; {defined in BTP.TPU}
- Counter : integer;
-
-
- (* Define methods of ExampleFile *)
- (* ------------------------------------------------------------------------ *)
-
- function ExampleFile.BT(OpCode, Key:integer):integer;
- begin
- {DO NOT call ancestor function, as it is abstract.}
- DBufferLen := Specs.RecLen;
- BT := Btrv(OpCode, PosBlk, Fields, DBufferLen, Fields.KeyBuf, Key);
- end;
-
- function ExampleFile.BTExt(OpCode, Key: integer): integer;
- begin
- {MUST call ancestor function, to set up buffers.}
- inherited BTExt(OpCode, Key);
- BTExt := Btrv(OpCode, PosBlk, ExtDBuffer^.Entire, DBufferLen, Fields.KeyBuf,
- Key);
- end;
-
-
- (* begin MAIN PROGRAM code *)
- (* ------------------------------------------------------------------------ *)
- BEGIN
-
- if not IsBtrieveLoaded then
- begin
- writeln('Please load Btrieve before running this program ...');
- writeln('Program aborted.');
- halt(1);
- end;
-
- Example := new(PExample, Init('Example', ReadOnly, ''));
- if BStatus <> 0 then
- begin
- writeln('Error ... Status: ', BStatus);
- dispose(Example, Done);
- halt(2);
- end;
- if Example^.NumRecs < 2 then
- begin
- writeln('Please run Example1.EXE to put at least two records in EXAMPLE');
- BStatus := Example^.Close;
- dispose(Example, Done);
- halt(3);
- end;
-
- {The SetTerms procedure is just a convenient way to set the 4 required
- parameters (Filter.MaxSkip, Filter.NumLogicTerms, Extractor.NumRecords, and
- Extractor.NumFields).}
-
- Example^.SetTerms(50, 2, 5, 1);
-
- {Since the 'Value' parameter to the PFilterSpec.InitV constructor is an open
- array of byte, we are using the TByteArray (255 bytes) defined in BTP.TPU as
- a buffer. That is, we are forced to move our filter criteria into a buffer,
- which here is the Value variable. We put two elements into the PFilterSpec
- collection, and specify that the first element is to be ANDed with the
- second, and that the second is the last term in the filter condition. }
-
- X := 'Leon';
- move(X, Value, sizeof(X)+1);
- with Example^.FilterSpec^ do
- insert(new(PFilterSpec, InitV(BLString, 20, 10, Equal, NextTermAnd, Value)));
-
- X := 'John';
- move(X, Value, sizeof(X)+1);
- with Example^.FilterSpec^ do
- insert(new(PFilterSpec, InitV(BLString, 10, 0, Equal, LastTerm, Value)));
-
- {
- Now put the required minimum of 1 extractor spec into the appropriate
- collection. This is where we tell Btrieve exactly WHAT "field(s)" to
- retrieve from each record that meets the filter criteria. In this case,
- we're specifying the entire record length. We've already specified that
- we're gonna be getting only one field (by setting
- Example^.Extractor.NumFields to 1 above). The INCREDIBLE drudgery of
- putting the filter specs and extractor specs and other required data into
- the appropriate buffer for the GetNextExt call ( i.e. the BTExt() call ),
- is handled internally by BTP. Specifically, it is handled by the inherited
- BTExt function, which calls:
-
- BFileExt.SetExtDBufferLen and
- BFileExt.MakeExtDBuffer.
- }
-
- with Example^.ExtractorSpec^ do
- insert(new(PExtSpec, Init(Example^.Specs.RecLen, 0)));
-
- BStatus := Example^.BT(BGetFirst, 0);
- writeln('Status of get first is ', BStatus);
-
- BStatus := Example^.BTExt(BGetNextExt, 0);
- writeln('Status of first ExtGetNext is ', BStatus);
- if BStatus = 9 then
- begin
- writeln('It is normal to get status 9 (EOF) if the number of records');
- writeln('actually returned by the GetNextExt call is less than the');
- writeln('number of records specified in the extractor. If you run the');
- writeln('EXAMPLE1 program a total of 5 times, then there will be 5');
- writeln('records matching the filter criteria, and you''ll get a status 0');
- writeln('on the GetNextExt call. I.e., status 9 does NOT necessarily');
- writeln('mean an error!');
- end;
-
- writeln('Number of records extracted on first GetNextExt call having name ');
- writeln('''John Leon'' is ', Example^.ExtDBuffer^.NumRecs);
-
- NumMatchingRecords := Example^.ExtDBuffer^.NumRecs;
-
- while BStatus = 0 do
- begin
- BStatus := Example^.BTExt(BGetNextExt, 0);
- inc(NumMatchingRecords, Example^.ExtDBuffer^.NumRecs);
- end;
-
- write('TOTAL number of records in file having name ''John Leon'' is ');
- writeln(NumMatchingRecords);
-
- BStatus := Example^.Close;
- dispose(Example, Done);
-
- END.
-
-
-