| ![]() | ||||||||||||||||||||
Mit den Dieser Index ermöglicht es FATS, jeden Datensatz durch Angabe beliebiger Begriffe in Sekundenbruchteilen zu finden. FATS stellt dem Anwendungsprogramm unmittelbar nach der Suche eine Liste aller gefundener Satznummern bzw. Primary-Keys zur Verfügung. Das nachfolgende C/C++ Beispiel demonstriert die Verwendung der FATS Matchcode-Befehle:
 FATS-Matchcode Befehlen läßt sich auf einfachste Weise ein Volltext-Index mit dem Inhalt der von Ihnen gewünschten Spalten bzw. Felder einer Datentabelle bzw. -datei erstellen.
Jedes Wort und jede Zahl wird in den Index aufgenommen, es wird eine "invertierte Liste" erstellt.
/*
FATS Extended Demo for Watcom-C
This program needs the extended version of FATS (FATSXO16.DLL)
Use the logical order of an FATS index file to build
the matchcode index.
*/
#include <stdio.h>
#include <io.h>
#include <fcntl.h>
#include <sys\stat.h>
#include <string.h>
#include <mem.h>
void _far * _far __pascal FATSLibInit(unsigned int uDatasize, unsigned int uSign);
void _far * _far __pascal FATSLibExit(void _far *lpFATSData);
unsigned long __pascal FATSLibCall(char _far *szCmnd, unsigned int _far *lpErrorcode,
char _far *szReturnKey, void _far *lpFATSData);
struct custdat {
char DELETEDMARK;
char ID[6];
char NAME[26];
char JOB[26];
char STREET[26];
char ZIP[6];
char CITY[21];
};
char szCmnd[512];
char szFATSkey[256];
unsigned int uFATSError;
unsigned long dwFATSRecno;
void _far * lpFATSData;
struct custdat cust;
/*
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.
This example program uses the flag K#:# ("MC"-command)
to create the matchcode index in sorted order.
*/
int main ()
{
int hCustomer;
unsigned long dwCurRecno;
unsigned long dwHitId;
char cChar;
printf( "\nFATS Extended testprogram (Command 'MC', 'MB', 'MS' and 'MA')\n" );
printf( "\nThis Test Program was designed for Watcom C\n\n" );
printf( "To compile and link the test program, use the following command:\n\n" );
printf( " WCL /m[?] /l=os2 /bt=os2 TST2_ENG.c FATSXO16.LIB \n\n" );
printf( "\nPlease press the [ENTER] key ...\n\n" );
cChar = getchar();
/*
init FATS dataseg
*/
lpFATSData = FATSLibInit(0, 2);
/*
-------> 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).
*/
dwFATSRecno = FATSLibCall( "Y\\2", &uFATSError, szFATSkey, lpFATSData );
/*
-------> Open data file
*/
printf( "Opening data file ...\n" );
hCustomer = open( "CUSTOMER.DAT", O_RDWR );
setmode( hCustomer, O_BINARY );
/*
-------> Opening key file
*/
dwFATSRecno = FATSLibCall( "O\\CUSTOMER.KEY\\2", &uFATSError, szFATSkey, lpFATSData );
if ( uFATSError ) {
printf( "\n" );
printf( "Error opening the file CUSTOMER.KEY\n" );
return ( -1 );
}
/*
========================================================================
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.
K#:# This switch activates the management of a primary key
for this matchcode index file. The first value after
the 'K' is the position of the data column within the
key (1 == first part), the second value specifies the
length of the data column valid as the key.
Further adjustments are possible and described in detail
in the user manual.
*/
printf( "\n" );
printf( "Creating matchcode index file ...\n" );
dwFATSRecno = FATSLibCall( "MC\\CUSTSORT.FTS\\\\1\\K1:5\\I1\\I2\\I3", &uFATSError, szFATSkey, lpFATSData );
/*
"MC\{Filename}\\{FileNo}\K#:#\I1\I2\I3"
The flag K#:# enables the management of a primary key within
the matchcode file. FATS normaly only uses the record number
during the generation of a result set. In specific situations,
if e.g. the physical record number is not known, or does not
correspond to the ID specified with the MB-command, the generation
of a primary key becomes necessary. The browser commands then also
make in addition to the record- or ID-number this key available via
the FATSKEY-variable to the application.
With the use of this flag, FATS generates a supplementary file with
the file extension .FMK which is used for the sequential storage of
the key.
*/
if ( uFATSError ) {
printf( "\nFATS Errorcode: %i (Command: MC)\n", uFATSError );
return ( uFATSError );
}
/*
-------> 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:
*/
printf( "\n" );
printf( "Building matchcode index in sorted order\n" );
printf( "\nPlease press the [ENTER] key ...\n\n" );
cChar = getchar();
dwCurRecno = 0L;
strcpy( szCmnd, "F\\2\\2" );
/*
*/
for ( ;; ) {
dwFATSRecno = FATSLibCall( szCmnd, &uFATSError, szFATSkey, lpFATSData );
if ( !uFATSError ) {
lseek( hCustomer, (dwFATSRecno - 1) * sizeof(cust), SEEK_SET );
read( hCustomer, &cust, sizeof(cust) );
dwCurRecno++;
sprintf( szCmnd, "MB\\1\\%lu\\", dwCurRecno );
/*
Add the primary key to the command string
*/
strcat ( szCmnd, cust.ID );
sprintf( &szCmnd[ strlen(szCmnd) ], "\\%s\\%s\\%s %s",
cust.NAME,
cust.JOB,
cust.ZIP, cust.CITY );
dwFATSRecno = FATSLibCall( szCmnd, &uFATSError, szFATSkey, lpFATSData );
if ( uFATSError ) {
/*
If an error occurred during the execution of the "MB" command,
the matchcode index file is already closed by FATS.
*/
printf( "FATS Errorcode: %i (Command: MB)\n", uFATSError );
break;
}
printf( " %s --> RecNo %lu\n", cust.NAME, dwCurRecno );
strcpy( szCmnd, "N\\2" );
} else {
/*
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.
*/
dwFATSRecno = FATSLibCall( "MB\\1\\0", &uFATSError, szFATSkey, lpFATSData );
break;
}
}
/*
========================================================================
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.
*/
dwFATSRecno = FATSLibCall( "O\\CUSTSORT.FTS\\1", &uFATSError, szFATSkey, lpFATSData );
/*
-------> Search in Search-Group 1 (NAME)
*/
printf( "\n" );
printf( "We now search for all customers with the first name Michael.\n" );
printf( "\nPlease press the [ENTER] key ...\n\n" );
cChar = getchar();
strcpy( szCmnd, "MS\\1\\\\0\\michael" );
do {
dwHitId = FATSLibCall( szCmnd, &uFATSError, szFATSkey, lpFATSData );
if ( !uFATSError ) {
/*
*/
sprintf( szCmnd, "S\\1\\2\\%s", szFATSkey );
dwFATSRecno = FATSLibCall( szCmnd, &uFATSError, szFATSkey, lpFATSData );
if ( !uFATSError ) {
lseek( hCustomer, (dwFATSRecno - 1) * sizeof(cust), SEEK_SET );
read( hCustomer, &cust, sizeof(cust) );
printf( "%s | %s\n%s %s (#%lu)\n\n", cust.NAME, cust.JOB,
cust.ZIP, cust.CITY, dwFATSRecno );
}
sprintf( szCmnd, "MA\\1\\%lu", dwHitId );
}
} while ( !uFATSError );
/*
--------> Close all fats files
*/
dwFATSRecno = FATSLibCall( "K", &uFATSError, szFATSkey, lpFATSData );
close( hCustomer );
/*
free FATS dataseg
*/
lpFATSData = FATSLibExit( lpFATSData );
return ( 0 );
}
© 2008
GCS Software, Udo Gertz