FATS - Fast Access Tree System
Inhaltsverzeichnis
Programmierschnittstellen
Borland Delphi für Windows 3.x


Das nachfolgende Delphi Beispiel demonstriert die Verwendung der von FATS bereitgestellten  Index-Befehle:

 "C" Create Indexfile
(Indexdatei definieren, erstellen und öffnen.)
 "O" Open Indexfile
(Indexdatei öffnen.)
 "K" Close Indexfile
(Eine oder alle Indexdateien schließen.)
 "I" Insert Record
((Haupt)-Schlüssel in Indexdatei einfügen und Datensatznummer besetzen.)
 "F" Search First
(Suchen des ersten Schlüssels.)
 "L" Search Last
(Suchen des letzten Schlüssels.)
 "N" Search Next
(Suchen des nächsten Schlüssels in Folge.)
 "A" Search Next After
(Suchen des auf den angegebenen Schlüssel folgenden Schlüssels.)
 "E" Search Previous Before
(Suchen des dem angegebenen Schlüssel vorangehenden Schlüssels.)
 "Y" Auto Refresh
(Bestimmt das Verhalten der Bibliothek im Netzwerk- und Einzelplatzbetrieb.)

(*

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

   Testprogramm (Borland Delphi 1.0)
 
   Erstellen der Testdateien KUNDEN.DAT / KUNDEN.KEY

   19-03-2009 U.Gertz
*) 

program TST1_GER;

uses WinCrt,
     sysutils;


type

  FATScmndstr = string[255];
  FATSkeystr = string[255];


  (*

     FATS Bibliotheken
     =================

     Im Lieferumfang der FATS-Version für Windows 3.x befinden sich
     die Dynamischen Bibliotheken FATS_WIN.DLL (Basisversion) bzw.
     FATSXWIN.DLL (Erweiterte Version), die Sie entweder in das
     Systemverzeichnis von Windows oder in das Verzeichnis Ihrer
     Applikation kopieren müssen.

  *) 

     function FATSLibInit(nSize: integer; nSign: integer): Pointer;
              far; external 'FATS_WIN';

     function FATSLibExit(lpFATSdata: Pointer): Pointer;
              far; external 'FATS_WIN';

  (*
     FATS Befehle ausführen
     ======================

     Alle FATS Befehle werden mit einer Funktion ausgeführt:

  *) 

     function FATSLibCall(var szCmnd: FATScmndstr; var uErrorCode: word;
              var szFATSkey: FATSkeystr; lpFATSdata: Pointer): longint;
              far; external 'FATS_WIN';

  (*
     Bedeutung der verwendeten Parameter:

        szCmnd         Dieser String definiert den auszuführenden FATS-
                       Befehl sowie die dazugehörenden Parameter.
   
        nErrorcode     Über diese Variable wird die Anwendung über
                       Erfolg (0) oder Mißerfolg (<> 0) der letzten
                       FATS-Aktion unterrichtet.
   
        szReturnKey    Ein gefundener Schlüssel wird in diesem String
                       gespeichert.
   
        Rückgabewert:  Datensatznummer

  *) 


const

  fn_demo = '..\..\..\DEMODATA\KUNDEN.ANS';
  fn_kund = 'KUNDEN.DAT';
  demolen = 105;


type

  kundenrec = record
      LOESCHKENNZ: char;
      ANREDE: string[5];
      NAME: string[25];
      BRANCHE: string[25];
      STRASSE: string[25];
      PLZ: string[5];
      ORT: string[20];
   end;


var

  hKunden: file of kundenrec;
  hDemodata: file;
  kpuffer: kundenrec;
  dpuffer: array[1..demolen] of char;
  lpFATSdata: Pointer;
  szCmnd: FATScmndstr;
  szFATSkey: FATSkeystr;
  szRecno: string[8];
  uFATSError: word;
  wCount: word;
  dwFATSRecno: longint;
  cChar: char;




begin

  (*
     Bevor Sie die FATS-Befehle in Ihrem Programm verwenden können,
     müssen Sie FATS einen Datenbereich zuweisen:
  *) 

  lpFATSdata := FATSLibInit( 0, 1 );
  if lpFATSdata = nil then exit;

  (*
     Der erste Parameter bestimmt die Größe des FATS-Datenbereichs.
     Wenn Sie hier eine Null angeben, dann wird der minimal benötigte
     Speicherplatz reserviert (ca. 18-20 KB). Der zweite Parameter
     bestimmt die eingesetzte Programmiersprache. Die Adresse des
     Datenbereichs wird in der Variable lpFatsdata zurückgegeben.
  *) 


  writeln ('FATS Testprogramm');
  writeln;
  writeln ('Dieses Programm muß mit Borland-Delphi als');
  writeln ('16 Bit Windows Applikation erstellt werden.');
  writeln;
  writeln ('Bitte [ENTER] drücken...');

  cChar:=readkey;


  (*
     -------> Aktivierung des Netzwerkbetriebes
   
      "Y" Auto Refresh Kommando
   
     FATS ist standardmäßig für den Betrieb im Netzwerk ausgestattet.
     Beinahe alle Befehle können sowohl im Einzelplatz- als auch im
     Netzwerkbetrieb ausgeführt werden.
     Standardmäßig sind die Netzfunktionen ausgeschaltet. Sie können
     diese mit dem Befehl "Y\2" initialisieren.
     Diese Initialisierung wird normalerweise beim Programmstart
     erledigt und gilt dann für die gesamte Laufzeit des Programmes.

  *)  

  szCmnd:='Y\2';
  dwFATSRecno:=FATSLibCall(szCmnd, uFATSError, szFATSkey, lpFATSdata);


  (*
     -------> ASCII-Datei mit Demodaten öffnen
  *) 


  assign (hDemodata, fn_demo);
  reset (hDemodata, 1);


  (*
     -------> Datendatei erstellen
  *) 

  writeln ('Datendatei wird erstellt ...');

  assign  (hKunden, fn_kund);
  rewrite (hKunden);


  (*
     -------> Indexdatei erstellen
  *) 

  (*
      "C" Create Indexfile
   
     Mit diesem Befehl erstellen Sie eine Indexdatei, wobei eine
     eventuell bereits vorhandene Datei mit demselben Dateinamen
     gelöscht wird.
     Die Indexdatei wird dabei gleichzeitig mit den über den
     Befehl Auto Refresh (Y) definierten Öffnungsflags geöffnet
     und der Dateinummer "FileNo" zugewiesen. Diese Nummer muß bei
     allen nachfolgenden FATS-Befehlen angegeben werden, um mit
     der Indexdatei zu arbeiten.
   
     Maximal 200 Schlüssel pro Datensatz können in einer Indexdatei
     verwaltet werden, wobei die maximale Schlüssellänge 240 Zeichen
     beträgt.
   
     Beachten Sie bei der Dateipfadangabe, daß der Backslash (\) von
     FATS als Trennzeichen behandelt wird und daher im Pfad durch
     einen normalen Schrägstrich ersetzt werden sollte.
     Alternativ dazu können Sie auch das Trennzeichen umdefinieren,
     indem Sie dieses als erstes Zeichen im Befehlsstring angeben,
     z.B. szCmnd = "&C&C:\ARTIKEL.KEY&1&1&A&1" (das Trennzeichen muß
     ein ASCII-Zeichen kleiner als 48 sein).
   
     Der Aufbau des Kommandostrings:
   
       szCmnd = "C\{Filename}\{KeyLength}\{KeyCount}\{KeyType}\{FileNo}"
   
         FileName   Name der Datei, eventuell mit Pfadangabe
                    (z.B. C:/DATEN/ARTIKEL.KEY oder ARTIKEL.KEY)
   
         KeyLength  Maximale Länge der Schlüssel
   
         KeyCount   Anzahl Schlüssel (1-200)
   
         KeyType    Art der Schlüssel (A=ASCII Textschlüssel, I=Integer)
   
         FileNo     Nummer der Indexdatei (1-40)

  *)  

  writeln ('Indexdatei wird erstellt ...');

  szCmnd:='C\KUNDEN.KEY\25\3\A\1';
  dwFATSRecno:=FATSLibCall(szCmnd, uFATSError, szFATSkey, lpFATSdata);


  (*
     ========================================================================
               Datensätze einfügen
     ========================================================================
  *) 

  writeln;
  writeln ('Es werden jetzt 222 Datensätze in die Datei eingefügt. Für jeden');
  writeln ('Datensatz werden 3 Schlüssel in die Indexdatei eingefügt.');
  writeln;
  writeln ('Bitte [ENTER] drücken...');
  cChar:=readkey;

  kpuffer.ANREDE[0]:=char(5);
  kpuffer.NAME[0]:=char(25);
  kpuffer.BRANCHE[0]:=char(25);
  kpuffer.STRASSE[0]:=char(25);
  kpuffer.PLZ[0]:=char(5);
  kpuffer.ORT[0]:=char(20);


  repeat

    blockread(hDemodata, dpuffer, demolen, wCount);
    If wCount = demolen Then Begin

    kpuffer.LOESCHKENNZ:=' ';
    move(dpuffer[1],kpuffer.ANREDE[1],5);
    move(dpuffer[6],kpuffer.NAME[1],25);
    move(dpuffer[31],kpuffer.BRANCHE[1],25);
    move(dpuffer[56],kpuffer.STRASSE[1],25);
    move(dpuffer[81],kpuffer.PLZ[1],5);
    move(dpuffer[86],kpuffer.ORT[1],20);

      (*
          "I" Insert Record
       
         Diesem Befehl wird die im "Create Indexfile"-Befehl
         angegebene Anzahl Schlüssel im Kommandostring übergeben.
         Die Schlüssel werden in die Indexdatei einsortiert und
         einer Satznummer zugeordnet, welche in der "RECNO"
         Variable an das Anwenderprogramm zurückgegeben wird.
       
         Anschließend sollte das aufrufende Programm den zugehörigen
         Datensatz entsprechend der zurückgegebenen Satznummer in
         die Datendatei speichern.
       
         Die Länge der übergebenen Schlüssel darf die beim
         "Create-Indexfile" angegebene Länge nicht überschreiten,
         kürzere Schlüssel werden mit dem ASCII-Zeichen 00h auf die
         maximale Schlüssellänge erweitert.
       
         Der Aufbau des Kommandostrings:
       
           szCmnd = "I\{FileNo}\{KeyStr1}[\{KeyStr2}[\{KeyStr3}]]"
       
             FileNo     Nummer der Indexdatei
       
             KeyStr#    Schlüssel

      *)  

      szCmnd:='I\1';
      szCmnd:=szCmnd + '\' + kpuffer.NAME;
      szCmnd:=szCmnd + '\' + kpuffer.BRANCHE;
      szCmnd:=szCmnd + '\' + kpuffer.PLZ + kpuffer.ORT;

      dwFATSRecno:=FATSLibCall(szCmnd, uFATSError, szFATSkey, lpFATSdata);

      If (uFATSError = 0) Then Begin

        seek(hKunden, dwFATSRecno - 1);
        write(hKunden, kpuffer);

        writeln(kpuffer.NAME,' --> Satznummer ', dwFATSRecno);
      End;
    End;

  until (wCount < demolen) or (uFATSError <> 0);

  close(hDemodata);

  (*
      "K" Close Indexfile
   
     Mit diesem Befehl schließen Sie die über "FileNo"
     angegebene Indexdatei.
   
     Wenn Sie den Datencache mit dem Befehl Auto Refresh (Y)
     aktiviert haben, dann werden eventuell noch im Cachepuffer
     befindliche Daten automatisch auf die Platte geschrieben,
     was Sie jedoch auch jederzeit mit dem Befehl Write Page
     Map (W) erzwingen können.
   
     Wenn der Datencache inaktiv ist, dann werden nach jedem
     FATS-Befehl sämtliche veränderten Daten auf die Platte
     geschrieben. Das Schließen der Dateien ist daher nur vor dem
     Beenden des aufrufenden Programmes notwendig.
   
     Wenn Sie den Parameter "FileNo" weglassen, dann werden alle
     geöffneten Indexdateien geschlossen. Diese Variante empfiehlt
     sich vor der Beendigung des Anwendungsprogrammes.
   
     Der Aufbau des Kommandostrings:
   
       szCmnd = "K\{FileNo}"
   
         FileNo     Nummer der Indexdatei

  *)  

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


  (*
     ========================================================================
               Suche im Index
     ========================================================================
  *) 


  (*
      "O" Open Indexfile
   
     Mit diesem Befehl wird die über "FileName" bestimmte
     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.
     Eine eventuell mit der gleichen Dateinummer bereits
     geöffnete Indexdatei wird zuvor geschlossen.
   
     Beachten Sie bei der Dateipfadangabe, daß der Backslash
     (\) von FATS als Trennzeichen behandelt wird und daher
     im Pfad durch einen normalen Schrägstrich ersetzt werden
     sollte.
     Alternativ dazu können Sie auch das Trennzeichen
     umdefinieren, indem Sie dieses als erstes Zeichen im
     Befehlsstring angeben, z.B. szCmnd = "&O&C:\ARTIKEL.KEY&1"
     (das Trennzeichen muß ein ASCII-Zeichen kleiner als 48 sein).
   
     Der Aufbau des Kommandostrings:
   
       szCmnd = "O\{FileName}\{FileNo}"
   
         FileName   Name der Datei, eventuell mit Pfadangabe
                    (z.B. C:/DATEN/ARTIKEL.KEY oder ARTIKEL.KEY)
   
         FileNo     Nummer der Indexdatei

  *)  

  szCmnd:='O\KUNDEN.KEY\1';
  dwFATSRecno:=FATSLibCall(szCmnd, uFATSError, szFATSkey, lpFATSdata);


  (*
     -------> Datensätze nach Name sortiert ausgeben
  *) 

  writeln;
  writeln ('Die Datensätze werden jetzt anhand des ersten Schlüssels (NAME)');
  writeln ('aufsteigend sortiert ausgegeben. Der dabei verwendete FATS-Befehl');
  writeln ('SEARCH NEXT AFTER kann im Einzelplatz und im Netzwerk verwendet');
  writeln ('werden.');
  writeln;
  writeln ('Bitte [ENTER] drücken...');
  cChar:=readkey;

  (*
      "F" Search First
   
     Dieser Befehl gibt die Datensatznummer und den Schlüsselwert
     des kleinsten Schlüssels der angegebenen Schlüsselnummer
     zurück.
   
     Der Aufbau des Kommandostrings:
   
       szCmnd = "F\{KeyNo}\{FileNo}"
   
         KeyNo      Schlüsselnummer
   
         FileNo     Nummer der Indexdatei

  *)  

  szCmnd:='F\1\1';

  repeat

    dwFATSRecno:=FATSLibCall(szCmnd, uFATSError, szFATSkey, lpFATSdata);

    if (uFATSError = 0) then begin

      seek(hKunden, dwFATSRecno - 1);
      read(hKunden, kpuffer);

      writeln(kpuffer.NAME, ' --> Satznummer ', dwFATSRecno);

      (*
          "A" Search Next After
       
         Dieser Befehl sucht den über "KeyString" und "RecNo"
         spezifizierten Schlüssel in der Indexdatei und blättert dann
         um eine Position weiter.
         Als Ergebnis wird der auf den angegebenen Schlüssel folgende
         Schlüssel zurückgegeben. Der Aufruf entspricht daher den
         Befehlen Search Generic (G) mit anschließendem Search Next (N).
       
         Im Gegensatz zum Befehl "Search Next" kann dieser Befehl auch
         problemlos im Netzwerk verwendet werden.
       
         Der Aufbau des Kommandostrings:
       
           szCmnd = "A\{KeyNo}\{RecNo}\{FileNo}\{KeyString}"
       
             KeyNo      Schlüsselnummer
       
             RecNo      Datensatznummer
       
             FileNo     Nummer der Indexdatei
       
             KeyString  Schlüssel

      *)  

      str(dwFATSRecno, szRecno);
      szCmnd:='A\1\' + szRecno + '\1\' + szFATSkey;
    end;

  until uFATSError <> 0;


  (*
     --------> Datensätze nach Branche sortiert ausgeben
  *) 

  writeln;
  writeln ('Die Datensätze werden jetzt anhand des zweiten Schlüssels (BRANCHE)');
  writeln ('aufsteigend sortiert ausgegeben.');
  writeln;
  writeln ('Bitte [ENTER] drücken...');
  cChar:=readkey;

  szCmnd:='F\2\1';

  repeat

    dwFATSRecno:=FATSLibCall(szCmnd, uFATSError, szFATSkey, lpFATSdata);

    if uFATSError = 0 then begin

      seek(hKunden, dwFATSRecno - 1);
      read(hKunden, kpuffer);

      writeln(kpuffer.BRANCHE, ' ', kpuffer.NAME, ' --> Satznummer ', dwFATSRecno);

      (*
          "N" Search Next
       
         Dieser Befehl gibt die Datensatznummer und den
         Schlüsselwert des nächsten Schlüssels zurück.
         Ausgegangen wird dabei vom Ergebnis des letzten
         Suchbefehls, d.h. unmittelbar vor der Anwendung
         dieses Befehls muß ein beliebiger Such-Befehl,
         ausgeführt worden sein.
       
         Jede Veränderung der Indexdatei durch das Einfügen
         oder Löschen von Schlüsseln macht einen für diesen
         Befehl notwendigen internen Zeiger ungültig, wodurch
         der Next-Befehl fehlschlägt. Da dies im Netzwerk auch
         von einer anderen Station aus passieren kann, sollte
         in Netzwerkumgebungen der Befehl Search Next After (A)
         verwendet werden.
       
         Wenn es keinen nächsten Schlüssel gibt, d.h. der zuletzt
         gefundene Schlüssel der Letzte in Folge war, wird der
         Fehlercode #15 zurückgegeben.
       
         Der Aufbau des Kommandostrings:
       
           szCmnd = "N\{FileNo}"
       
             FileNo     Nummer der Indexdatei

      *)  

      szCmnd:='N\1';
    end;

  until uFATSError <> 0;


  (*
     --------> Datensätze nach PLZ & Ort sortiert ausgeben
  *) 

  writeln;
  writeln ('Die Datensätze werden jetzt anhand des dritten Schlüssels (PLZ/ORT)');
  writeln ('absteigend sortiert ausgegeben.');
  writeln;
  writeln ('Bitte [ENTER] drücken...');
  cChar:=readkey;

  (*
      "L" Search Last
   
     Dieser Befehl gibt die Datensatznummer und den Schlüsselwert
     des größten Schlüssels der angegebenen Schlüsselnummer zurück.
   
     Der Aufbau des Kommandostrings:
   
       szCmnd = "L\{KeyNo}\{FileNo}"
   
         KeyNo      Schlüsselnummer
   
         FileNo     Nummer der Indexdatei

  *)  

  szCmnd:='L\3\1';

  repeat

    dwFATSRecno:=FATSLibCall(szCmnd, uFATSError, szFATSkey, lpFATSdata);

    if (uFATSError = 0) then begin

      seek(hKunden, dwFATSRecno - 1);
      read(hKunden, kpuffer);

      writeln(kpuffer.PLZ,' ', kpuffer.ORT, ' ', kpuffer.NAME, ' --> Satznummer ', dwFATSRecno);

      (*
          "E" Search Previous Before
       
         Dieser Befehl sucht den über "KeyString" und "RecNo"
         spezifizierten Schlüssel in der Indexdatei und blättert dann
         um eine Position zurück.
         Als Ergebnis wird der dem angegebenen Schlüssel vorangehende
         Schlüssel zurückgegeben. Der Aufruf entspricht daher den
         Befehlen "Search Generic" mit anschließendem "Search Prev".
       
         Im Gegensatz zum Befehl "Search Previous" kann dieser Befehl
         auch problemlos im Netzwerk verwendet werden.
       
         Der Aufbau des Kommandostrings:
       
           szCmnd = "E\{KeyNo}\{RecNo}\{FileNo}\{KeyString}"
       
             KeyNo      Schlüsselnummer
       
             RecNo      Datensatznummer
       
             FileNo     Nummer der Indexdatei
       
             KeyString  Schlüssel

      *)  

      str(dwFATSRecno, szRecno);
      szCmnd:='E\3\' + szRecno + '\1\' + szFATSkey;
    end;

  until uFATSError <> 0;


  (*
     --------> Indexdatei schließen
  *) 

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

  close(hKunden);


  (*
     Vor dem Beenden des Anwendungsprogrammes sollten Sie den mit der
     Funktion FATSLibInit reservierten Speicherbereich wieder freigeben.
     Dafür steht die Funktion FATSLibExit zur Verfügung:
  *) 

  lpFATSdata := FATSLibExit( lpFATSdata );

  (*
     Obwohl der Speicherbereich notfalls auch vom Betriebssystem
     automatisch freigegeben würde, ist dieser Befehl nützlich, da
     er sämtliche noch geöffneten FATS-Dateien ordnungsgemäß schließt.
  *) 

end.

© 2008  GCS Software, Udo Gertz