FATS - Fast Access Tree System
Table of Contents
Programming Interfaces
IBM-Pascal, MS-Pascal, Quick Pascal


The  FATS matchcode commands create a full-text index with the content of your data tables or -files.
Every word and every number is incorporated into the index, an "inverted list" is generated.

This index enables FATS to find each data record by specification of any terms in fractions of a second.

The following Microsoft Pascal example demonstrates the use of the FATS matchcode commands:

 "MC" Create Matchcode File
(Define, create and open a Matchcode-Index-File.)
 "MB" Build Matchcode
(Build the Matchcode-Index.)
 "O" Open Indexfile
(Makes a index file available for access.)
 "MS" Search in Matchcode
(Query the matchcode index, and setup an result set.)

(*
   FATS 02.30
   (c) GCS Software, Udo Gertz 1993-1998

   Test program (Microsoft Pascal, IBM Pascal, Quick Pascal)

   This program needs the extended version of FATS (FATSXWE.EXE)
   It tests the 'MC', 'MB', 'MS' and 'MA' commands

   19-03-2009      Udo Gertz
*) 

program TST2_ENG (input, output);

type

  custrec = record
      DELETEDMARK: char;
      ID: lstring(5);
      NAME: lstring(25);
      JOB: lstring(25);
      STREET: lstring(25);
      ZIP: lstring(5);
      CITY: lstring(20);
   end;

const

  fn_cust = 'CUSTOMER.DAT';

var

  szCmnd: lstring(255);
  szFATSkey: lstring(255);
  uFATSError: word;
  dwFATSRecno: integer4;

  hCustomer: file of custrec;
  cdata: custrec;
  dwCurRecno: integer4;
  szRecno: lstring(8);
  cChar: char;


(*
   Calling FATS

   All commands provided by FATS can be executed with one function:

*) 
     function FATSCALL (vars szCmnd: lstring; vars nErrorcode: word;
                        vars szReturnKey: lstring) : integer4; extern;

(*
   The meaning of the used parameters:

      szCmnd         With this command string you specify the actual
                     FATS command. The available commands are described
                     in the user manual.
 
      nErrorcode     Your application must always pass this variable as
                     the status parameter on a FATS call. After the
                     FATS call, the application should always check the
                     value of this variable. FATS returns a errorcode of
                     0 after a successful operation. FATS indicates any
                     errors which occur during processing by returning a
                     nonzero value in the errorcode variable.
                     In the manual you can find a list of all FATS
                     errorcodes and their possible causes.
 
      szReturnKey    This variable will contain the key value of a found
                     key after any normal search command (S,G,F,L,N,P,A,E).
 
                     in the case of a matchcode command:
 
                     If a primary key was generated during the creation of
                     the matchcode index file with the "K#:#" flag, it is
                     made available via this variable to the application
                     program.
 
      Return Value:  Record Number
 
*) 


begin

  writeln ('FATS Extended test program (commands "MC", "MB", "MS" and "MA")');
  writeln ('This Test Program was designed for Microsoft Pascal');
  writeln;
  writeln ('To compile and link the test program, use the following commands:');
  writeln;
  writeln ('     PAS1 TST2_ENG');
  writeln ('     PAS2');
  writeln ('     LINK TST2_ENG FATSXMPR.LIB');
  writeln;
  writeln ('Please press the [ENTER] key ...');

  read( cChar );


  (*
     Load/Unload the FATS Extended Workstation Engine:
   
     Load:      FATSXWE
     Unload:    FATSXWE -unload
  *) 


  (*
     -------> Activation of Network Operation
   
     FATS is standardly equiped for the network environment.
     Nearly all commands can be executed both in single workstation
     and network environment. With the  "Y" Auto Refresh command you
     determine the behavior of FATS accessing all index files.
     Normally it is sufficient to apply this instruction one time at
     the program start whereby the specified access mode will apply
     to all coming opened files, i.e. they are accessed either with
     network (Y\2) or single workstation access (Y\0).

  *)  

  (* szCmnd:='Y\2';
     dwFATSRecno:=FATSCALL(szCmnd, uFATSError, szFATSkey); *) 


  (*
     -------> Open data file
  *) 

  writeln ('Opening data file ...');

  assign  (hCustomer, fn_cust);
  hCustomer.mode:=direct;
  reset (hCustomer);


  (*
     ========================================================================
               Creating Matchcode Index
     ========================================================================
  *) 


  (*
     -------> Creating Matchcode Index File
   
     With the command  "MC" Create Matchcode File, the most important
     query facilities are determined already while creating the
     matchcode index file. With the search-group flag ("I#"), several
     logically related data columns can be registered in a common index
     so that a query to this index resp. search group extends automatically
     over all these columns. A matchcode file manages up to 32 search
     groups that can be used for joined queries (using the "AND"-operator).
   
     In this example the following search groups are defined:
   
       Search Group    Fields
   
           I1          NAME
           I2          JOB
           I3          ZIP & CITY
   
     The syntax of the command string:
   
       szCmnd = "MC\{FileName}\{Flags}\{FileNo}\{Col1def}[\{Col2def}]"
   
         FileName   Filename, perhaps with an additional path
                    (i.e. C:/DATA/CUSTOMER.FMS or CUSTOMER.FMS)
   
         Flags      Reserved, not used at the moment
   
         FileNo     File number
   
         Col#def    Definition of data column # (flags, separated by comma).
                    The content of the corresponding data columns is transferred
                    the commands "MB", "MI" and "MD" later in the order determined
                    by this command.
   
                    I#  The content of the data column becomes part of search
                        group #. You can combine several columns into a logical
                        search group (e.g. first name, surname).
   
                    C   The content of the data column is edited for word overall
                        searching, i.e. a search for "motorca" e.g. finds
                        "motorcar" and "motor caravan".
   
                    N   Numbers are handled as words, i.e. during a search
                        according to "150", "12150" e.g. is also found.
   
                    Further adjustments are possible and described in detail
                    in the user manual.

  *)  

  writeln;
  writeln ('Creating matchcode index file ...');

  szCmnd:='MC\CUSTOMER.FTS\\1\I1\I2\I3';
  dwFATSRecno:=FATSCALL(szCmnd, uFATSError, szFATSkey);

  If uFATSError <> 0 Then Begin

    writeln;
    If uFATSError = -1 Then Begin

      writeln ('FATS workstation engine is not activated.');
      writeln ('Please start the program by entering FATSXWE at the command line.');

    End Else Begin

      write ('FATS Errorcode: '); write (uFATSError);
      writeln (' (Command: MC)');
      writeln;

    End;

    close( hCustomer );
    Return;

  End;


  (*
     -------> Insert text into the matchcode index
   
     After the matchcode file was generated, the content of the
     data columns may be with the command  "MB" Build Matchcode
     inserted into the matchcode index. The position of the
     data columns within the command string ("Col#data") corresponds
     to that with the call of command Create Matchcode File ("MC")
     determined definition.
   
     The syntax of the command string:
   
       szCmnd = "MB\{FileNo}\{RecNo}\{Col1data}[\{Col2data}[\{Col3data}]]"
   
         FileNo     File number
   
         RecNo      <> 0 Record- resp. id-number
                    == 0 Stop Build, no more records
   
         Col#data   Content of data column #
   
   
     The following sample program code indexes contents of the
     entire data file within a loop:

  *)  

  writeln;
  writeln ('Building matchcode index');
  writeln;
  writeln ('Please press the [ENTER] key ...');
  writeln;

  read( cChar );


  dwCurRecno:=0;

  (*
     While indexing sequential data resources, the number specified
     via "RecNo" should correspond to the physical record number
     i.e. the first data record has number 1, the second record number 2..,
     in the case of data records marked as deleted, the content of the
     data columns is not specified ("MB\{FileNo}\{RecNo}").
   
     The Build Matchcode (MB) command demands an ascending number as a
     "RecNo" argument i.e. the matchcode can not usually be indexed in
     the logical order of an index-key.
     The example program MCSORT.pas shows how an application
     program might use the "MC" command to create the
     matchcode index in sorted order.
  *) 

  Repeat

    seek(hCustomer, dwCurRecno + 1);
    get(hCustomer);

    If NOT EOF( hCustomer ) Then Begin

      dwCurRecno:=dwCurRecno + 1;
      cdata:=hCustomer^;

      szCmnd:='MB\1\';
      If encode(szRecno, dwCurRecno:8) Then concat(szCmnd, szRecno);

      If cdata.DELETEDMARK = ' ' Then Begin

        concat (szCmnd, '\');
        concat (szCmnd, cdata.NAME);
        concat (szCmnd, '\');
        concat (szCmnd, cdata.JOB);
        concat (szCmnd, '\');
        concat (szCmnd, cdata.ZIP);
        concat (szCmnd, ' ');
        concat (szCmnd, cdata.CITY);

      End;

      dwFATSRecno:=FATSCALL(szCmnd, uFATSError, szFATSkey);

      If uFATSError <> 0 Then Begin

        (*
           If an error occurred during the execution of the "MB" command,
           the matchcode index file is already closed by FATS.
        *) 

        write ('FATS Errorcode: '); write (uFATSError);
        writeln (' (Command: MB)');
        writeln;
        break;

      End;

      writeln (cdata.NAME,' --> RecNo ', dwCurRecno:-8);

    End Else Begin

      (*
         After the last record was inserted the creating process
         has to be terminated with the command "MB\{FileNo}\0".
         Because this command closes the matchcode index file you don't
         have to do a close command.
      *) 

      szCmnd:='MB\1\0';
      dwFATSRecno:=FATSCALL(szCmnd, uFATSError, szFATSkey);
      break;

    End;

  Until uFATSError <> 0;


  If dwCurRecno = 0 Then Begin

    writeln;
    writeln( 'Error opening the file CUSTOMER.DAT' );
    writeln( 'Please create the file using one of the test programs' );
    writeln( 'TST0_ENG.PAS or TST1_ENG.PAS' );
    return;
  End;


  (*
     ========================================================================
               Matchcode Search
     ========================================================================
  *) 


  (*
     -------> Open matchcode index file
   
     With the command  "O" Open Indexfile you open an existing
     matchcode index file with the opening flags defined with
     the command  "Y" Auto Refresh. After the file was opened
     it can be accessed under the file number you specified.

  *)  

  szCmnd:='O\CUSTOMER.FTS\1';
  dwFATSRecno:=FATSCALL(szCmnd, uFATSError, szFATSkey);


  (*
     -------> Search in Search-Group 1 (NAME)
   
     The command   "MS" Search in Matchcode searches the matchcode
     index and fills the result set with the record- resp. ID-numbers
     of data records which include the searched terms. If FATS finds
     the requested terms, it returns the record- resp. ID-number of
     the first hit in the "dwRecno" variable and a errorcode of 0.
     The result set can then be read out with the browser commands
     ("MA", "ME", "MN", "MP" ...).
   
     The syntax of the command string:
   
       szCmnd = "MS\{FileNo}\{Flags}\{Total}\{SearchGrp1}[\{SearchGrp2}...]"
   
       FileNo     File number
   
       Flags      The search procedure can be adjusted by the specification
                  of different flags. You find a description of the flags
                  in the command reference.
   
       Total      Maximum number of hits in the result set:
   
                    0  All hits are set into the result set. This regulation
                       works very fast, however, no sorting occurs by means of
                       hit quality.
   
                   >0  It is attempted to put the specified number of hits into
                       the result set. These hits are subjected to a sorting
                       concerning their quality and then put into one of
                       7 sorting groups.
   
       SearchGrp#  The in search group # searched terms.
   
   
     Different FATS commands can be used for further processing
     of the result table, depending on the program logic.
     The following example prints all hits on the output device:

  *)  

  writeln;
  writeln ('We now search for all customers with the first name Michael.');
  writeln;
  writeln ('Please press the [ENTER] key ...');
  writeln;

  read( cChar );


  szCmnd:='MS\1\\0\michael';

  Repeat

    dwFATSRecno:=FATSCALL(szCmnd, uFATSError, szFATSkey);

    If uFATSError = 0 Then Begin

      seek(hCustomer, dwFATSRecno);
      get(hCustomer);
      cdata:=hCustomer^;

      writeln(cdata.NAME, ' | ', cdata.JOB);
      writeln(cdata.ZIP, ' ', cdata.CITY, '(#', dwFATSRecno:-8, ')');
      writeln;

      szCmnd:='MA\1\';
      If encode(szRecno, dwFATSRecno:8) Then concat(szCmnd, szRecno);

    End;

  Until uFATSError <> 0;

  (*
     The following browser commands are supported by FATS:
   
       "MF" - Get First Result
       "ML" - Get Last Result
       "MP" - Get Previous Result
       "MN" - Get Next Result
       "MA" - Get Next Result After
       "ME" - Get Previous Result Before
  *) 


  (*
     --------> Joined search in Search-Groups 2 (JOB) and 3 (ZIP/CITY)
  *) 

  writeln;
  writeln ('We are now doing a joined search over the search groups');
  writeln ('2 (Job) and 3 (Zip, City) to find all people from nevada');
  writeln ('who are related to the transportation industry.');
  writeln;
  writeln ('Please press the [ENTER] key ...');
  writeln;

  read( cChar );


  szCmnd:='MS\1\\0\\trans\nev';

  Repeat

    dwFATSRecno:=FATSCALL(szCmnd, uFATSError, szFATSkey);

    If uFATSError = 0 Then Begin

      seek(hCustomer, dwFATSRecno);
      get(hCustomer);
      cdata:=hCustomer^;

      writeln(cdata.NAME, ' | ', cdata.JOB);
      writeln(cdata.ZIP, ' ', cdata.CITY, '(#', dwFATSRecno:-8, ')');
      writeln;

      szCmnd:='MA\1\';
      If encode(szRecno, dwFATSRecno:8) Then concat(szCmnd, szRecno);

    End;

  Until uFATSError <> 0;


  (*
     --------> Close matchcode index file
  *) 

  szCmnd:='K\1';
  dwFATSRecno:=FATSCALL(szCmnd, uFATSError, szFATSkey);

  close( hCustomer );

End.

© 2008  GCS Software, Udo Gertz