home *** CD-ROM | disk | FTP | other *** search
/ Power-Programmierung / CD1.mdf / pascal / library / dos / btree / tree / exam2.pas < prev    next >
Encoding:
Pascal/Delphi Source File  |  1989-07-12  |  11.6 KB  |  263 lines

  1. (* EXAM2.PAS *)
  2.  
  3. program driver;
  4. {$R+}
  5.  
  6. uses
  7.     exam0,
  8.     Btree,
  9.     Compare,
  10.     FileBuff,
  11.     FileDecs,
  12.     Files,
  13.     LRecList,
  14.     Numbers,
  15.     Page,
  16.     Logical;
  17.  
  18. var
  19.     dataFile,
  20.     indexFile1,
  21.     indexFile2 : FnString;                      (* holds file name strings *)
  22.  
  23.     testRec : TestRecord;                (* variable to hold a data record *)
  24.  
  25.     lrLst1,
  26.     lrLst2 : LrList;        (* variable which user declares and passes in to
  27.                                LRLIST unit.  LRLIST will build a list of
  28.                                logical records which fulfill a query criteria.
  29.                                (Actually the list will be built by a call
  30.                                to the BTREE unit which in turn uses the LRLIST
  31.                                unit.                                         *)
  32.  
  33.     lrNum : LrNumber;       (* a couple of variable used in this demo program
  34.                                to keep track of logical record number
  35.                                currently being processed.                    *)
  36.  
  37.     tempByte : Byte;        (* this variable is used to pass in the selection
  38.                                criteria for retrievals.  A variable or typed
  39.                                constants must be used.  Constants do not work
  40.                                since the call is by reference and not by
  41.                                value                                         *)
  42.  
  43.     exitSave : Pointer;     (* used as pointer to my terminiation procedure  *)
  44.  
  45.  
  46. (* This procedure will be called prior to termination of the program whether
  47.    there is an error or not.  This is a demonstration of a good technique to
  48.    use in conjunction with TBTREE.  Calls to write the buffer to disk and
  49.    close the files should be included.  This is also a place top handle runtime
  50.    error since I do not attempt to deal with errors or maintain global error
  51.    variables in TBTREE.                                                      *)
  52.  
  53. {$F+} procedure MyExit; {$F-}
  54.  
  55.     begin
  56.     ExitProc := ExitSave;           (* reinstall the saved value of ExitProc *)
  57.     Writeln('Writing Records To Disk ...');        (* just a note so you can
  58.                                                       follow along           *)
  59.  
  60.     WriteEntireBufferToDisk;         (* very important step!!  Before leaving
  61.                                         the program the buffer must be written
  62.                                         to disk or some changes will be lost.
  63.                                         This will cause major problems and lost
  64.                                         data!!!  This is not really required in
  65.                                         in this program since nothing is
  66.                                         modified.  A logical record list is
  67.                                         created, but it happens to be small
  68.                                         enough that a temporary file is not
  69.                                         needed.  If a file was needed, it would
  70.                                         have been destroyed on the call to
  71.                                         DestroyLrList anyway.                *)
  72.  
  73.     Writeln('Closing Files ...');                  (* just a note so you can
  74.                                                       follow along           *)
  75.  
  76.     CloseAllFiles;               (* Close the files to clean up.  It is
  77.                                     important to realize that CloseAllFiles
  78.                                     DOES NOT write the buffer to disk, it only
  79.                                     deals with the files open list.          *)
  80.  
  81.     end;
  82.  
  83.  
  84. (* This routine should be called before anything else happens.  It calls
  85.    the various routines to set up parameters according to values applicable
  86.    to your particular application.                                           *)
  87.  
  88. procedure SetUp;
  89.  
  90.     begin
  91.     SetMaxBufferPages(100);  (* a call to the PAGE unit to set up the number
  92.                                 of pages in the buffer.  If this is not done a
  93.                                 default of one page is used.  This will cause
  94.                                 poor performance but will not cause any
  95.                                 runtime errors                               *)
  96.  
  97.     SetMaxOpenFiles(10);     (* a call to the FILEBUFF unit to set the number
  98.                                 of files the FILEBUFF unit can have open at
  99.                                 once.  See FILEBUFF unit for details.        *)
  100.  
  101.     SetImmediateDiskWrite(FALSE); (* changed and newly created pages will be
  102.                                      buffered in the page buffer and will only
  103.                                      written to disk when they are swapped out
  104.                                      or explicitly written out by a user
  105.                                      request                                 *)
  106.  
  107.     end;
  108.  
  109.  
  110. (* This procedure initializes the file names as required.  Also, if will
  111.    create the files if they do not exist.  Therefore, you can use one
  112.    initialization routine whether the file exists or must be created.        *)
  113.  
  114. procedure InitFiles;
  115.  
  116.     begin
  117.  
  118.     dataFile := 'myFile1.dat';
  119.     if not FileExists(dataFile) then
  120.         begin
  121.         CreateDataFile(dataFile,SizeOf(TestRecord));
  122.         end;
  123.  
  124.     indexFile1 := 'testByte.idx';
  125.     if not FileExists(indexFile1) then
  126.         begin
  127.         CreateIndexFile(indexfile1,SizeOf(BYTE),BYTEVALUE);
  128.         end;
  129.  
  130.     indexFile2 := 'testStrg.idx';
  131.     if not FileExists(indexFile2) then
  132.         begin
  133.         CreateIndexFile(indexfile2,SizeOf(TestString),STRINGVALUE);
  134.         end;
  135.     end;
  136.  
  137. (*****************************************************************************)
  138. (*                                                                           *)
  139. (*                         M A I N      P R O G R A M                        *)
  140. (*                                                                           *)
  141. (*****************************************************************************)
  142.  
  143. begin
  144.  
  145. Writeln('Setting up termination routine ...');     (* just a note so you can
  146.                                                       follow along           *)
  147.  
  148. exitSave := ExitProc;       (* see page 376 - 377 of Turbo Pascal 4.0 manual *)
  149. ExitProc := @MyExit;
  150.  
  151. Writeln('Initializing Parameters ...');            (* just a note so you can
  152.                                                       follow along           *)
  153.  
  154. SetUp;              (* set file open buffer size and page buffer size limits *)
  155.                     (* set immediate disk write parameter as well            *)
  156.  
  157.  
  158. InitFiles;
  159.  
  160. Writeln('Looking for logical records which match selection criterion and',
  161.          ' building logical record list ... this may take a minute ...' );
  162.                                                    (* just a note so you can
  163.                                                       follow along           *)
  164.  
  165. tempByte := 255;         (* since we are checking for existence, this is not
  166.                             required.  tempByte must still be included in the
  167.                             call however.  It will be ignored.               *)
  168.  
  169. GetValuesFromBTree(indexFile1,tempByte,EX,lrLst1); (* build list of logical
  170.                                                       record numbers which
  171.                                                       exist (ctriterion is
  172.                                                       EX which means exists *)
  173.  
  174.     (* The following loop will fetch the data records associated with the
  175.        record numbers found in the newly created logical record list.  Each
  176.        of the records will be printed.  Since the list was built using
  177.        indexFile1 which is the index corresponding to the randByte field in
  178.        testRec, the records will be printed in ascending order by
  179.        testRec.randByte.  If the opposite order was desired the list should
  180.        be traversed in reverse by using GetLastLr and GetPrevLr.             *)
  181.  
  182.  
  183. lrNum := GetFirstLr(lrLst1);  (* get the first record number and set the cursor
  184.                                  the front of the list.                      *)
  185.  
  186. while lrNum <> 0 do
  187.     begin
  188.  
  189.     GetALogicalRecord(dataFile,        (* variable holding name of data file *)
  190.                       lrNum,              (* logical record number from list *)
  191.                       testRec);                     (* place to put the data *)
  192.  
  193.     Writeln(lrNum,'        ',testRec.randByte,'       ',testrec.randString);
  194.  
  195.     lrNum := GetNextLr(lrLst1);        (* advance the cursor to next in list *)
  196.     end;
  197.  
  198.     (* The following three calls are for demo purposes to show a couple of
  199.        utilities available.                                                  *)
  200.  
  201. Writeln('Total records found matching criteria = ',GetCountLr(lrLst1));
  202. Writeln;
  203. Writeln('Now we will make a copy of the list and traverse it showing that');
  204. Writeln('CopyLrList routine works as advertised');
  205. Writeln;
  206.  
  207. CopyLrList(lrLst1,lrLst2);    (* make a copy of list 1 to see how this works *)
  208.  
  209. DestroyLrList(lrLst1);  (* we're done with list so let's get rid of it.  This
  210.                            is important so that there aren't a bunch of
  211.                            temporary files upon termination.  Also, lists
  212.                            take up data space and also space in the page
  213.                            buffer                                            *)
  214.  
  215. lrNum := GetFirstLr(lrLst2);  (* get the first record number and set the cursor
  216.                                  the front of the list.                      *)
  217.  
  218. while lrNum <> 0 do
  219.     begin
  220.  
  221.     GetALogicalRecord(dataFile,        (* variable holding name of data file *)
  222.                       lrNum,              (* logical record number from list *)
  223.                       testRec);                     (* place to put the data *)
  224.  
  225.     Writeln(lrNum,'        ',testRec.randByte,'       ',testrec.randString);
  226.  
  227.     lrNum := GetNextLr(lrLst2);        (* advance the cursor to next in list *)
  228.     end;
  229.  
  230.     (* The following three calls are for demo purposes to show a couple of
  231.        utilities available.                                                  *)
  232.  
  233. Writeln('Total records found matching criteria = ',GetCountLr(lrLst2));
  234.  
  235. DestroyLrList(lrLst2);  (* we're done with list so let's get rid of it.  This
  236.                            is important so that there aren't a bunch of
  237.                            temporary files upon termination.  Also, lists
  238.                            take up data space and also space in the page
  239.                            buffer                                            *)
  240.  
  241. Writeln;
  242. Writeln('Now, the same records will be retrieved.  However, this time the');
  243. Writeln('internal cursor and the associated routines are used.');
  244. Writeln;
  245.  
  246.     (* The following shows the retrieval of all the records in the index using
  247.        the internal cursor and associated routines.  No logical record list
  248.        is created.                                                           *)
  249.  
  250. lrNum := UsingCursorGetFirstLr(indexFile1);
  251. while lrNum <> 0 do
  252.     begin
  253.     GetALogicalRecord(dataFile,        (* variable holding name of data file *)
  254.                       lrNum,              (* logical record number from list *)
  255.                       testRec);                     (* place to put the data *)
  256.  
  257.     Writeln(lrNum,'        ',testRec.randByte,'       ',testrec.randString);
  258.  
  259.     lrNum := UsingCursorGetNextLr(indexFile1);
  260.     end;
  261.  
  262. end.
  263.