FATS - Fast Access Tree System
Inhaltsverzeichnis
Programmierschnittstellen
Watcom C/C++ für Windows 3.x


Mit den  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.

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:

 "MC" Create Matchcode File
(Matchcode-Indexdatei definieren, erstellen und öffnen.)
 "MB" Build Matchcode
(Inhalte der Datenspalten in den Matchcode-Index einfügen.)
 "O" Open Indexfile
(Indexdatei öffnen.)
 "MS" Search in Matchcode
(Matchcode-Suchabfrage durchführen.)

/*
   FATS Extended Demo für Watcom C

   Dieses Testprogramm benötigt die erweiterte Version von FATS (FATSXWIN.DLL)
   Es zeigt die Verwendung der Befehle: 'MC', 'MB', 'MS' und 'MA'

*/ 

#include <stdio.h>
#include <io.h>
#include <fcntl.h>
#include <stdlib.h>
#include <sys\stat.h>
#include <string.h>
#include "FATS.h"


  struct kdat {
    char LOESCHKENNZ;
    char ANREDE[6];
    char NAME[26];
    char BRANCHE[26];
    char STRASSE[26];
    char PLZ[6];
    char ORT[21];
  };


  char          szCmnd[512];
  char          szKey[256];
  unsigned int  uErrorcode;
  unsigned long dwRecno;
  void _far *   lpFATSData;

  struct kdat   kdata;


int main ()
{

  int            hKunden;
  unsigned long  dwCurRecno;
  char           cChar;

  printf( "\nFATS Extended Testprogramm (Kommandos 'MC', 'MB', 'MS' und 'MA')\n" );
  printf( "\nDieses Programm wurde für Watcom C entworfen.\n\n" );
  printf( "Folgende Kommandos generieren die ausführbare Datei:\n\n" );
  printf( "wcl /ml /l=win /bt=win /c tst2_ger.c\n" );
  printf( "wlink @tst2_ger\n\n" );
  printf( "Linkfile: system   windows\n" );
  printf( "          name     tst2_ger\n" );
  printf( "          file     tst2_ger.obj\n" );
  printf( "          library  fatsxwin.lib\n\n" );
  printf( "\nBitte [ENTER] drücken...\n\n" );

  cChar = getchar();


  /*
     FATS Datensegment allocieren
  */ 

  lpFATSData = FATSLibInit(0, 2);


  /*
     -------> Datendatei öffnen
  */ 

  printf( "Datendatei wird geöffnet ...\n" );

  hKunden = open( "KUNDEN.DAT", O_RDWR );
  setmode( hKunden, O_BINARY );


  /*
     ========================================================================
               Matchcode generieren
     ========================================================================
  */ 


  /*
     -------> Matchcode Datei erstellen
   
     Der Matchcode wird mit dem Kommando  "MC" Create Matchcode File
     generiert. Dabei geben Sie die logischen Suchgruppen und deren
     Eigenschaften an. Eine Suchgruppe besteht aus dem Inhalt eines
     oder mehrerer Datenfelder, in denen bei Angabe der Suchbegriffe
     gemeinsam gesucht werden soll.
   
     In diesem Beispiel werden folgende Suchgruppen definiert:
   
       Suchgruppe      Felder
   
           I1          NAME
           I2          BRANCHE
           I3          PLZ & ORT
   
     Der Aufbau des Kommandostrings:
   
       szCmnd = "MC\{FileName}\{Flags}\{FileNo}\{Col1def}[\{Col2def}]"
   
         FileName   Name der Matchcode-Datei, eventuell mit Pfadangabe
                    (z.B. C:/DATEN/KUNDEN.FMS oder KUNDEN.FMS)
   
         Flags      Momentan noch nicht benutzt
   
         FileNo     Nummer der Matchcode-Indexdatei
   
         Col#def    Definition der Datenspalte # (Flags, durch Komma getrennt).
                    Der Inhalt der entsprechenden Datenspalten wird später den
                    Befehlen "MB", "MI" und "MD" in der durch diesen Befehl
                    festgelegten Reihenfolge übergeben.
   
                    I#  Spalteninhalt in der Suchgruppe # (1-32) indizieren.
                        Sie können mehrere Spalten zu einer logischen Suchgruppe
                        zusammenfassen (z.B. Vorname, Nachname).
   
                    An dieser Stelle sind noch weitere Einstellungen möglich,
                    die ausführlich im Benutzerhandbuch beschrieben sind.

  */  

  printf( "\n" );
  printf( "Matchcode-Datei wird erstellt ...\n" );

  dwRecno = FATSLibCall( "MC\\KUNDEN.FTS\\\\1\\I1\\I2\\I3", &uErrorcode, szKey, lpFATSData );

  if ( uErrorcode ) {

    printf( "\nFATS Fehlercode: %i (Kommando: MC)\n", uErrorcode );
    return ( uErrorcode );
  }


  /*
     -------> Texte einfügen
   
     Nachdem die Datei definiert und erzeugt wurde, wird der Inhalt der
     Datensätze mit dem Kommando  "MB" Build Matchcode in die Datei
     eingefügt. Dabei dient die Definition, welche Sie über den Befehl
     "MC" festgelegt haben, als Schablone für dieses Kommando.
   
     Syntax des Kommandostrings:
   
       szCmnd = "MB\{FileNo}\{RecNo}\{Col1data}[\{Col2data}[\{Col3data}]]"
   
       FileNo     Nummer der Matchcode-Indexdatei
   
       RecNo      <> 0 Datensatz- bzw. ID-Nummer
                  == 0 Matchcode-Indizierung beenden
   
       Col#data   Inhalt der Datenspalte X

  */  

  printf( "\n" );
  printf( "Der Matchcode wird jetzt aufgebaut\n" );
  printf( "\nBitte [ENTER] drücken...\n\n" );

  cChar = getchar();


  dwCurRecno = 0L;

  for ( ;; ) {

    lseek( hKunden, dwCurRecno * sizeof(kdata), SEEK_SET );

    if ( read(hKunden, &kdata, sizeof(kdata)) == sizeof(kdata) ) {

      dwCurRecno++;

      sprintf( szCmnd, "MB\\1\\%lu", dwCurRecno );

      if ( !kdata.LOESCHKENNZ ) {

        sprintf( &szCmnd[ strlen(szCmnd) ], "\\%s\\%s\\%s %s",
                 kdata.NAME,
                 kdata.BRANCHE,
                 kdata.PLZ, kdata.ORT );
      }
      dwRecno = FATSLibCall( szCmnd, &uErrorcode, szKey, lpFATSData );

      if ( uErrorcode ) {

        /*
           Wenn bei der Generierung des Matchcode-Indizes ein Fehler
           auftritt, dann wird die entsprechende Datei automatisch
           geschlossen.
        */ 

        printf( "FATS Fehlercode: %i (Kommando: MB)\n", uErrorcode );
        break;
      }

      printf( "  %s  --> Satznummer %lu\n", kdata.NAME, dwCurRecno );

    } else {


      /*
         Nachdem der letzte Datensatz indiziert wurde, wird die
         Indizierung durch die Angabe einer Null anstelle einer
         gültigen Datensatznummer beendet ("MB\{Dateinummer}\0").
         Die Datei wird dabei geschlossen - ein Close-Befehl ist
         danach nicht mehr nötig.
      */ 

      dwRecno = FATSLibCall( "MB\\1\\0", &uErrorcode, szKey, lpFATSData );
      break;
    }

  }


  if ( !dwCurRecno ) {

    printf( "\n" );
    printf( "Die Datendatei KUNDEN.DAT existiert nicht oder enthält keine\n" );
    printf( "Datensätze. Bitte generieren Sie diese Datei mit dem Test-\n" );
    printf( "programm TST1_GER.C\n" );
    return ( -1 );
  }


  /*
     ========================================================================
               Matchcode Suche
     ========================================================================
  */ 


  /*
     -------> Matchcode Datei öffnen
   
     Mit dem Befehl  "O" Open Indexfile wird eine Matchcode-
     Indexdatei mit den über den Befehl Auto Refresh ("Y")
     definierten Öffnungsflags geöffnet und der Dateinummer
     "FileNo" zugewiesen. Diese Nummer muß bei allen nach-
     folgenden FATS-Befehlen angegeben werden, um mit der
     Indexdatei zu arbeiten.

  */  

  dwRecno = FATSLibCall( "O\\KUNDEN.FTS\\1", &uErrorcode, szKey, lpFATSData );


  /*
     -------> In der Suchgruppe 1 (NAME) suchen
   
     Der Befehl  "MS" Search in Matchcode führt eine Matchcode-Abfrage
     durch und erstellt eine Ergebnistabelle mit den Datensatz- bzw.
     ID-Nummern der Datensätze, welche die gesuchten Begriffe beinhalten.
     Bei erfolgreicher Verarbeitung (Errorcode == 0) wird der Applikation
     die Datensatz- bzw. ID-Nummer des ersten Treffers über die Variable
     "dwRecno" zur weiteren Verarbeitung zur Verfügung gestellt.
     Die Ergebnistabelle kann anschließend mit den Browserbefehlen
     ("MA", "ME", "MN", "MP" etc.) ausgelesen werden.
   
     Der Aufbau des Kommandostrings:
   
       szCmnd = "MS\{FileNo}\{Flags}\{Total}\{SearchGrp1}[\{SearchGrp2}...]"
   
         FileNo     Nummer der Indexdatei
   
         Flags      Der Suchvorgang kann durch die Angabe verschiedener
                    Flags beeinflußt werden. Eine Beschreibung der Flags
                    finden Sie in der Befehlsreferenz.
   
         Total      Maximale Anzahl Treffer in der Ergebnistabelle:
   
                      0   Es werden alle Treffer in die Ergebnistabelle
                          gestellt. Diese Einstellung arbeitet sehr schnell,
                          es findet aber auch keine Sortierung anhand der
                          Trefferqualität statt.
   
                    > 0   Es wird versucht, die angegebene Anzahl Treffer in
                          die Ergebnistabelle zu stellen. Diese Treffer werden
                          einer Sortierung bezüglich ihrer Qualität unterzogen
                          und dann in eine von 7 Sortiergruppen eingeordnet.
   
         SearchGrp#  Hier werden die in der Suchgruppe # gesuchten Begriffe
                     angegeben.
   
     Für die Auswertung der Ergebnistabelle können abhängig von der
     Programmlogik verschiedene FATS-Befehle verwendet werden.
     In dem folgenden Beispiel werden alle Treffer auf den Bildschirm
     ausgegeben:

  */  

  printf( "\n" );
  printf( "Es wird jetzt in der Suchgruppe 1 (NAME) nach GMBH gesucht\n" );
  printf( "\nBitte [ENTER] drücken...\n\n" );

  cChar = getchar();


  strcpy( szCmnd, "MS\\1\\\\0\\GMBH" );

  do {

    dwRecno = FATSLibCall( szCmnd, &uErrorcode, szKey, lpFATSData );

    if ( !uErrorcode ) {

      lseek( hKunden, (dwRecno - 1) * sizeof(kdata), SEEK_SET );

      if ( read(hKunden, &kdata, sizeof(kdata)) == sizeof(kdata) ) {

        printf( "%s | %s\n%s %s (#%lu)\n\n", kdata.NAME, kdata.BRANCHE,
                kdata.PLZ, kdata.ORT, dwRecno );
      }
      sprintf( szCmnd, "MA\\1\\%lu", dwRecno );

    }

  } while ( !uErrorcode );


  /*
     --------> Verknüpfte Suche über Branche / Ort
  */ 

  printf( "\n" );
  printf( "Es wird jetzt eine verknüpfte Suche über die Suchgruppen\n" );
  printf( "2 (Branche) und 3 (PLZ, Ort) gestartet.\n" );
  printf( "Gesucht werden alle GROßHANDlungen in STUTTgart.\n" );
  printf( "\nBitte [ENTER] drücken...\n\n" );

  cChar = getchar();


  strcpy( szCmnd, "MS\\1\\\\0\\\\großhand\\stutt" );

  do {

    dwRecno = FATSLibCall( szCmnd, &uErrorcode, szKey, lpFATSData );

    if ( !uErrorcode ) {

      lseek( hKunden, (dwRecno - 1) * sizeof(kdata), SEEK_SET );

      if ( read(hKunden, &kdata, sizeof(kdata)) == sizeof(kdata) ) {

        printf( "%s | %s\n%s %s (#%lu)\n\n", kdata.NAME, kdata.BRANCHE,
                kdata.PLZ, kdata.ORT, dwRecno );
      }
      sprintf( szCmnd, "MA\\1\\%lu", dwRecno );

    }

  } while ( !uErrorcode );


  /*
     --------> Matchcode Datei schließen
  */ 

  dwRecno = FATSLibCall( "K\\1", &uErrorcode, szKey, lpFATSData );

  close( hKunden );


  /*
     FATS Datensegment freigeben
  */ 

  lpFATSData = FATSLibExit( lpFATSData );


  return ( 0 );

}

© 2008  GCS Software, Udo Gertz