|
The  FATS matchcode commands create a full-text index with the content of your data tables or -files. This index enables FATS to find each data record by specification of any terms in fractions of a second. The following Delphi example demonstrates the use of the FATS matchcode commands:
Every word and every number is incorporated into the index, an "inverted list" is generated.
"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 (Borland Delphi 1.0) This program needs the extended version of FATS (FATSXWIN.DLL) It tests the 'MC', 'MB', 'MS' and 'MA' commands 19-03-2009 Udo Gertz *) program TST2_ENG; uses sysutils, WinCrt; type FATScmndstr = string[255]; FATSkeystr = string[255]; function FATSLibInit(nSize: integer; nSign: integer): Pointer; far; external 'FATSXWIN'; function FATSLibExit(lpFATSdata: Pointer): Pointer; far; external 'FATSXWIN'; (* Calling FATS All commands provided by FATS can be executed with one function: *) function FATSLibCall(var szCmnd: FATScmndstr; var nErrorcode: word; var szReturnKey: FATSkeystr; lpFATSdata: Pointer): longint; far; external 'FATSXWIN'; (* 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 *) const fn_cust = 'CUSTOMER.DAT'; type custrec = record DELETEDMARK: char; ID: string[5]; NAME: string[25]; JOB: string[25]; STREET: string[25]; ZIP: string[5]; CITY: string[20]; end; var szCmnd: FATScmndstr; szFATSkey: FATSkeystr; uFATSError: word; dwFATSRecno: longint; lpFATSdata: pointer; hCustomer: file of custrec; cdata: custrec; dwCurRecno: longint; szRecno: string[8]; cChar: char; begin (* init FATS data area *) lpFATSdata := FATSLibInit( 0, 1 ); if lpFATSdata = nil then exit; writeln ('FATS Extended test program (commands "MC", "MB", "MS" and "MA")'); writeln; writeln ('This Test Program was designed for Borland Delphi.'); writeln; writeln ('You need the dynamic link library FATSXWIN.DLL'); writeln; writeln ('Please press the [ENTER] key ...'); cChar:=readkey; (* -------> Open data file *) writeln ('Opening data file ...'); assign (hCustomer, fn_cust); 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:=FATSLibCall(szCmnd, uFATSError, szFATSkey, lpFATSdata); If uFATSError <> 0 Then Begin writeln; write ('FATS Errorcode: '); write (uFATSError); writeln (' (Command: MC)'); exit; 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; cChar:=readkey; 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.dpr shows how an application program might use the "MC" command to create the matchcode index in sorted order. *) Repeat If NOT EOF( hCustomer ) Then Begin seek(hCustomer, dwCurRecno); read(hCustomer, cdata); dwCurRecno:=dwCurRecno + 1; str(dwCurRecno, szRecno); szCmnd:='MB\1\' + szRecno; If cdata.DELETEDMARK = ' ' Then Begin szCmnd:=szCmnd + '\' + cdata.NAME; szCmnd:=szCmnd + '\' + cdata.JOB; szCmnd:=szCmnd + '\' + cdata.ZIP + ' ' + cdata.CITY; End; dwFATSRecno:=FATSLibCall(szCmnd, uFATSError, szFATSkey, lpFATSdata); 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; End Else begin writeln (cdata.NAME,' --> RecNo ', dwCurRecno:-8); End; 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:=FATSLibCall(szCmnd, uFATSError, szFATSkey, lpFATSdata); break; End; Until uFATSError <> 0; If dwCurRecno = 0 Then Begin writeln; writeln( 'Error opening the file CUSTOMER.DAT' ); writeln( 'Please create the file using the test program' ); writeln( 'TST1_BPE.dpr' ); exit; 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:=FATSLibCall(szCmnd, uFATSError, szFATSkey, lpFATSdata); (* -------> 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; cChar:=readkey; szCmnd:='MS\1\\0\michael'; Repeat dwFATSRecno:=FATSLibCall(szCmnd, uFATSError, szFATSkey, lpFATSdata); If uFATSError = 0 Then Begin seek(hCustomer, dwFATSRecno - 1); read(hCustomer, cdata); writeln(cdata.NAME, ' | ', cdata.JOB); writeln(cdata.ZIP, ' ', cdata.CITY, '(#', dwFATSRecno:-8, ')'); writeln; str(dwFATSRecno, szRecno); szCmnd:='MA\1\' + 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; cChar:=readkey; szCmnd:='MS\1\\0\\trans\nev'; Repeat dwFATSRecno:=FATSLibCall(szCmnd, uFATSError, szFATSkey, lpFATSdata); If uFATSError = 0 Then Begin seek(hCustomer, dwFATSRecno - 1); read(hCustomer, cdata); writeln(cdata.NAME, ' | ', cdata.JOB); writeln(cdata.ZIP, ' ', cdata.CITY, '(#', dwFATSRecno:-8, ')'); writeln; str(dwFATSRecno, szRecno); szCmnd:='MA\1\' + szRecno; End; Until uFATSError <> 0; (* --------> Close matchcode index file *) szCmnd:='K\1'; dwFATSRecno:=FATSLibCall(szCmnd, uFATSError, szFATSkey, lpFATSdata); close( hCustomer ); (* free FATS data area *) lpFATSdata := FATSLibExit( lpFATSdata ); End.
© 2008 GCS Software, Udo Gertz