/***************************************
*    ISAM File System demo program
****************************************
*    Copyright © 1989 by Kai Ploog
*          A.d. Huehnerhecke 1
*          D-6074 Roedermark
*
****************************************
*  Functions: ISAM.c
*  V0.9 beta rev 02  04/05/1989
*  first version:    01/15/1989
***************************************/


#include <exec/types.h>
#include "ISAM.h"		/* include structure definitions and symbols */
#include <stdio.h>
#include <stdlib.h>
#include <error.h>
#include <string.h>
#include <fcntl.h>



/***************** sample test program *****************/

void TurnOver(Hd)
 struct ISAMHeader *Hd;
{
	char c;
	struct ISAMKey *key;

	puts("\nselect the records with f, l, n, p. exit with e.\n");
	for(;;) {
		c = getchar();
		switch (c) {
			case 'f':
				if (ISAMFirstKey(Hd) == EOF) {
					putchar('\x07');
				}
				break;
			case 'l':
				if (ISAMLastKey(Hd) == EOF) {
					putchar('\x07');
				}
				break;
			case 'n':
				if (ISAMNextKey(Hd) == EOF) {
					putchar('\x07');
				}
				break;
			case 'p':
				if (ISAMPrevKey(Hd) == EOF) {
					putchar('\x07');
				}
				break;
			case 'e':
				return;
			default:
				continue;
		}

		key = Hd->Keys->Current;
		printf("%s    %d   Next: %d Prev: %d\n",key->Key, key, key->NextKey, key->PrevKey);
	}
}


void PrintRecord (Hd, data)
 struct ISAMHeader *Hd;
 STRPTR data;
{
	if (ISAMRead(Hd, (APTR) data) == 0) {
		puts(data);
		puts(data + 20);
		puts(data + 35);
		puts(data + 45);
	}
	else {
		puts("**** read error");
	}
}

/* With the following declaration, you can reference the ISAMField structures
 * as additional array fields of the ISAMDataHeader.ISAMField[] structure.
 */
struct {
	struct ISAMDataHeader head;
	struct ISAMField field[3];
} MyData;
#define mydata MyData.head	/* reference direct to ISAMDataHeader struct */

#define ENTRIES (4)		/* sample key entries */
struct {
	struct ISAMKey key;
	char string[20];
} mykey[ENTRIES];

struct ISAMHeader *Hd;
struct ISAMNewFile newfile;

void main()
{
	int i;
	struct ISAMKey *key;
	UBYTE data[55];

/*** initialize mydata structure ***/

	mydata.Fields = 4;
	mydata.KeyPos = 0;
	mydata.Field[0].Size = 20;
	mydata.Field[0].Type = ISAM_TEXT | ISAM_KEY;
	mydata.Field[1].Size = 15;
	mydata.Field[1].Type = ISAM_TEXT;
	mydata.Field[2].Size = 10;
	mydata.Field[2].Type = ISAM_TEXT;
	mydata.Field[3].Size = 5;
	mydata.Field[3].Type = ISAM_TEXT;

/* initialize newfile structure */

	newfile.IndexName = "dat.idx";
	newfile.DataName = "dat.dat";
	newfile.DefName = "dat.def";
	newfile.Type = ISAM_SINGLEFILE | ISAM_AUTOUPDATE | ISAM_DUPLICATEKEYS;
	newfile.DBase = 0;
	newfile.Data = &mydata;
	newfile.MaxKeys = ~0;	/* as many keys as possible allowed (2^32) */

/* initialize keys

	mykey[0].key.NextKey = &mykey[1];
	mykey[0].key.PrevKey = 0;
	strcpy(mykey[0].key.Key, "Amiga");

	mykey[1].key.NextKey = &mykey[2];
	mykey[1].key.PrevKey = &mykey[0];
	strcpy(mykey[1].key.Key, "Atari");

	mykey[2].key.NextKey = &mykey[3];
	mykey[2].key.PrevKey = &mykey[1];
	strcpy(mykey[2].key.Key, "Commodore");

	mykey[3].key.NextKey = 0;
	mykey[3].key.PrevKey = &mykey[2];
	mykey[3].key.Position = 0;
	strcpy(mykey[3].key.Key,"IBM");
*/

/*** create new ISAM file ***/

	setnbf(stdout);	/* no buffering of output */


puts("create new ISAM file...");

	Hd = ISAMOpen(&newfile, ISAM_NEWFILE | ISAM_REPLACE);

	if (Hd) {

		TurnOver(Hd);

puts("add 4 records...");

		printf("Amiga rtn code: %d - %d\n", ISAMAdd(Hd, (APTR) &"Amiga\0              Am.1\0          Am.2\0     Am.3"),Hd->Error);
puts("\nthe keys:");

		/* output all keys */
		key = Hd->Keys->FirstKey;
		for (i = 0;key != 0;i++) {
			printf("%s    %d   Next: %d Prev: %d\n",key->Key, key, key->NextKey, key->PrevKey);
			key = key->NextKey;
		}

		printf("IBM   rtn code: %d - %d\n", ISAMAdd(Hd, (APTR) &"IBM\0                IB.1\0          IB.2\0     IB.3"),Hd->Error);
puts("\nthe keys:");

		/* output all keys */
		key = Hd->Keys->FirstKey;
		for (i = 0;key != 0;i++) {
			printf("%s    %d   Next: %d Prev: %d\n",key->Key, key, key->NextKey, key->PrevKey);
			key = key->NextKey;
		}

		printf("Commo rtn code: %d - %d\n", ISAMAdd(Hd, (APTR) &"Commodore\0          Co.1\0          Co.2\0     Co.3"),Hd->Error);
puts("\nthe keys:");

		/* output all keys */
		key = Hd->Keys->FirstKey;
		for (i = 0;key != 0;i++) {
			printf("%s    %d   Next: %d Prev: %d\n",key->Key, key, key->NextKey, key->PrevKey);
			key = key->NextKey;
		}

		printf("Atari rtn code: %d - %d\n", ISAMAdd(Hd, (APTR) &"Atari\0              At.1\0          At.2\0     At.3"),Hd->Error);
puts("\nthe keys:");

		/* output all keys */
		key = Hd->Keys->FirstKey;
		for (i = 0;key != 0;i++) {
			printf("%s    %d   Next: %d Prev: %d\n",key->Key, key, key->NextKey, key->PrevKey);
			key = key->NextKey;
		}

		printf("Keys     %d \n",Hd->Keys->Keys);
		printf("Records  %d \n",Hd->Keys->Records);

puts("update...");

		ISAMUpdate(Hd);

puts("replace...");

		ISAMReplace(Hd, (APTR) &"Atari\0              Re.1\0          Re.2\0     Re.3");

puts("close...");

		ISAMClose(Hd);
	}

getchar();

puts("open again...");

	Hd = ISAMOpen(&newfile, ISAM_OLDFILE);

	if (Hd) {

puts("some structure items:");

		printf("Keys     %d \n",Hd->Keys->Keys);
		printf("Records  %d \n",Hd->Keys->Records);
		printf("KeyLen   %d \n",Hd->Keys->KeyLength);
		printf("MaxKeys  %d \n",Hd->Keys->MaxKeys);
		printf("FirstKey %d \n",Hd->Keys->FirstKey);
		printf("LastKey  %d \n",Hd->Keys->LastKey);
		printf("Fields   %d \n",Hd->Data->Fields);
		printf("KeyPos   %d \n",Hd->Data->KeyPos);
		for (i = 0;i < Hd->Data->Fields;i++) {
			printf("\nSize %d \n",Hd->Data->Field[i].Size);
			printf("FieldType %d \n",Hd->Data->Field[i].Type);
		}

puts("\nthe keys:");

		/* output all keys */
		key = Hd->Keys->FirstKey;
		for (i = 0;key != 0;i++) {
			printf("%s    %d\n",key->Key, key);
			key = key->NextKey;
		}

		TurnOver(Hd);


puts("\nadd existing key (Amiga)...");

		ISAMAdd(Hd, (APTR) &"Amiga\0              Test2\0         Test3\0    T4\0 ");
		printf("	Keys     %d \n",Hd->Keys->Keys);
		printf("	Records  %d \n",Hd->Keys->Records);

		TurnOver(Hd);

puts("\ndelete Atari...");

		if (isamSearchKey(Hd, "Atari", 0) == 1) {
			ISAMDelete(Hd);
		}
		printf("	Keys     %d \n",Hd->Keys->Keys);
		printf("	Records  %d \n",Hd->Keys->Records);

		TurnOver(Hd);

puts("\nthe keys:");

		/* output all keys */
		key = Hd->Keys->FirstKey;
		for (i = 0;key != 0;i++) {
			printf("%s    %d\n",key->Key, key);
			key = key->NextKey;
		}

puts("\nadd new key that is too long (Amiga500   )...");

		ISAMAdd(Hd, (APTR) &"Amiga500            Test2\0         Test3\0    T4\0 ");
		printf("	Keys     %d \n",Hd->Keys->Keys);
		printf("	Records  %d \n",Hd->Keys->Records);

		TurnOver(Hd);

puts("now backwards:");

		/* output all keys backwards */
		key = Hd->Keys->LastKey;
		for (i = 0;key != 0;i++) {
			printf("%s    %d\n",key->Key, key);
			key = key->PrevKey;
		}

puts("\nsome ISAMSearch and ISAMRead calls...\n");

		printf("Commo         %d  %d\n",ISAMSearch(Hd, "Commo", 0), Hd->Keys->Current);
		PrintRecord(Hd, data);
		printf("Commodore     %d  %d\n",ISAMSearch(Hd, "Commodore", 0), Hd->Keys->Current);
		PrintRecord(Hd, data);
		printf("Amiga2000     %d  %d\n",ISAMSearch(Hd, "Amiga2000", 0), Hd->Keys->Current);
		PrintRecord(Hd, data);
		printf("0             %d  %d\n",ISAMSearch(Hd, "0", 0), Hd->Keys->Current);
		PrintRecord(Hd, data);
		printf("a             %d  %d\n",ISAMSearch(Hd, "a", 0), Hd->Keys->Current);
		PrintRecord(Hd, data);
		printf("Z             %d  %d\n",ISAMSearch(Hd, "Z", 0), Hd->Keys->Current);
		PrintRecord(Hd, data);

puts("\nISAMSearch for (Amiga)...");

		printf("Amiga         %d  %d\n",ISAMSearch(Hd, "Amiga", 0), Hd->Keys->Current);
		PrintRecord(Hd, data);

puts("ISAMSearch for (Amiga) mode 1...");

		printf("Amiga         %d  %d\n",ISAMSearch(Hd, "Amiga", 1), Hd->Keys->Current);
		PrintRecord(Hd, data);

puts("\nclose again");

		ISAMClose(Hd);
	}
	else {
		printf("errno = %d\n", errno);
	}
}

