/****************************************************************************/
/*                                                                          */
/*                                                                          */
/*      db.h          (c) 1987  Ken Harris                                  */
/*                                                                          */
/*                                                                          */
/****************************************************************************/
/*                                                                          */
/*      This software is made available on an AS-IS basis. Unrestricted     */
/*      use is granted provided that the copywrite notice remains intack.   */
/*      The author makes no warranties expressed or implied.                */
/*                                                                          */
/****************************************************************************/
/*                                                                          */
/*  09/12/87 - Change the alloc's to calloc's and movmem's to memcpy        */
/*             Make pointer changes for Large Model                         */
/*                                                                          */
/*  11/02/87 - Fix index file corruption problem			    */
/*									    */
/*  11/15/87 - Add Read Last/Prev routines				    */
/*									    */
/****************************************************************************/


#define DB_VERSION    12	      /* Version 1.2			*/
#define FILE_NAME_MAX 50

#define YES -1
#define NO   0

typedef unsigned long  ulong;
typedef unsigned short ushort;
typedef unsigned int   uint;
typedef unsigned char  uchar;

/*
 *      db_file_hdr  -  File Header Record
 */

struct db_file_hdr
{       ushort fh_db_version;           /* Data Base Version #          */
        ushort fh_file_type;            /* File Type                    */
#define                                    DB_SEQ       1
#define                                    DB_RANDOM    2
#define                                    DB_INDEX     3

        ushort fh_file_stat;            /* File Status                  */
#define                                    DB_CLOSED       0
#define                                    DB_OPEN         1
#define                                    DB_DUP_ALLOWED  2

        ulong  fh_last_block;           /* Last Allocated Block         */
        ushort fh_block_size;           /* Block Size in bytes          */
        ushort fh_rec_size;             /* Record Size in bytes         */
        ushort fh_ctl_size;             /* Control part of rec size     */
        ushort fh_data_size;            /* User data part of rec size   */
        ulong  fh_rec_cnt;              /* Live Record Cnt              */
        ushort fh_recs_per_blk;         /* Records Per Block            */
        ushort fh_root_ptr;             /* Index File Root Pointer      */
        ushort fh_base_size;            /* Random File Base Size        */
        ushort fh_key_size;             /* Size of record key           */
        ulong  fh_next_avail;           /* First Available Record       */
        ushort fh_atr_size;             /* Size of Attribute Block      */
        char   fh_reserved[220];        /* Reserved for Future Use      */
        char   fh_user_data[256];       /* User Control Info            */
};

typedef  struct db_file_hdr *FILE_HDR;

/*
 *      db_data_buf  -  Data buffer
 */

struct db_data_buf
{       struct db_data_buf *buf_prev;   /* Previous Buffer in list      */
        struct db_data_buf *buf_next;   /* Next Buffer in list          */
        ushort buf_size;                /* Size of Buffer in Bytes      */
        ulong  buf_cur_blk;             /* Current Block (0 = none)     */
        ushort buf_cur_size;            /* Current Block Size           */
        ushort buf_rec_inx;             /* Record index into block      */
        char  *buf_data;                /* Pointer to data              */
};

typedef  struct db_data_buf *BUFFER;


/*
 *      db_data_set  -  Data Set Descriptor Block
 */

struct db_data_set
{       ushort ds_stat;                 /* Data Set Status              */
        BUFFER ds_fhdr;                 /* File Header Buffer           */
        int    ds_fd;                   /* File descriptor              */
        char   ds_fname[FILE_NAME_MAX]; /* File name                    */
        ulong  ds_prev_blk;             /* Prev Block Read              */
        ushort ds_prev_rec;             /* Prev Record Read             */
        struct db_data_buf *ds_buf;     /* Data Buffer                  */
        struct db_data_buf *ds_tmp;     /* Tmp Data Buffer              */
        struct db_data_buf *ds_aux;     /* Another Tmp Data Buffer      */
};

typedef  struct db_data_set *DATA_SET;
                           

/*
 *      Record types
 */

struct db_free_rec
{       char  fre_stat;                 /* Status                       */
#define                                    DB_FREE   '0'
#define                                    DB_INUSE  '1'
        ulong fre_next;                 /* Next Available               */
};

struct db_seq_rec
{       char  seq_stat;                 /* Status                       */
};

struct db_index_hdr
{       char   idx_stat;                /* Status                       */
        ushort idx_parent;              /* Pointer to Parent            */
        ushort idx_rec_cnt;             /* Keys in this block           */
};

struct db_index_rec
{       ushort idx_idx_ptr;             /* Pointer to index block       */
};

struct db_random_hdr
{       char   ran_stat;                /* Status                       */
        ushort ran_next;                /* Overflow pointer             */
        ushort ran_rec_cnt;             /* Live Recs in this block      */
};
          
struct db_random_rec
{       char   ran_stat;                /* Status                       */
};
          
typedef struct db_free_rec   *FREE_REC;
typedef struct db_seq_rec    *SEQ_REC;
typedef struct db_index_hdr  *INDEX_HDR;
typedef struct db_index_rec  *INDEX_REC;
typedef struct db_random_hdr *RANDOM_HDR;
typedef struct db_random_rec *RANDOM_REC;


#define DB_FILE_NOT_FOUND      1
#define DB_READ_ERROR          2
#define DB_END_OF_FILE         3
#define DB_WRITE_ERROR         4
#define DB_FILE_NOT_CREATED    5
#define DB_FILE_NOT_OPEN       6
#define DB_INVALID_BLOCK       7
#define DB_BUFFER_ERROR        8
#define DB_NO_CURRENT_REC      9
#define DB_DELETED_REC        10
#define DB_INVALID_FREE       11
#define DB_INVALID_BLK_SIZE   12
#define DB_INVALID_INDEX      13
#define DB_REC_NOT_FOUND      14
#define DB_DUP_NOT_ALLOWED    15
#define DB_INVALID_REQUEST    16
#define DB_INVALID_RANDOM     17
#define DB_INVALID_FHDR       18
#define DB_VERSION_ERROR      19

extern int    db_error;
extern ulong  db_match_blk;
extern ushort db_match_rec;
extern ulong  db_add_blk;
extern ushort db_add_rec;

/*
 *	db_main defs
 */

/*global*/  struct db_data_set *db_create(char *,char *,struct db_file_hdr *);
/*global*/  void db_fhdr_create(struct db_file_hdr *);
/*global*/  struct db_data_set *db_open(char *,char *);
/*global*/  void db_fhdr_open(struct db_file_hdr *);
/*global*/  struct db_data_set *db_close(struct db_data_set *);
/*global*/  unsigned long db_add(struct db_data_set *,);
/*global*/  void db_read_first(struct db_data_set *,);
/*global*/  void db_read_next(struct db_data_set *,);
/*global*/  void db_read_last(struct db_data_set *,);
/*global*/  void db_read_prev(struct db_data_set *,);
/*global*/  void db_find(struct db_data_set *,);
/*global*/  void db_update(struct db_data_set *,);
/*global*/  void db_delete(struct db_data_set *);
/*global*/  unsigned long db_get_rec_no(struct db_data_set *);
/*global*/  void db_read_direct(struct db_data_set *,unsigned long ,);
/*global*/  void db_read_atr(struct db_data_set *,);
/*global*/  void db_update_atr(struct db_data_set *,);
/*global*/  void db_check_ds(struct db_data_set *);
/*global*/  void db_extend(struct db_data_set *,struct db_data_buf *);
/*global*/  void db_get_next_avail(struct db_data_set *,struct db_data_buf *);
/*global*/  void db_free_rec(struct db_data_set *,struct db_data_buf *);
/*global*/  void db_get_blk(struct db_data_set *,long ,struct db_data_buf *);
/*global*/  void db_put_blk(struct db_data_set *,struct db_data_buf *);
/*global*/  struct db_data_buf *db_alloc_buf(int );
/*global*/  struct db_data_buf *db_free_buf(struct db_data_buf *);
/*global*/  void db_free_ds(struct db_data_set *);
/*global*/  char *db_error_msg(int );

/*
 *	db_seq defs
 */

/*global*/  void db_add_seq(struct db_data_set *,char *);
/*global*/  void db_read_first_seq(struct db_data_set *,char *);
/*global*/  void db_read_next_seq(struct db_data_set *,char *);
/*global*/  void db_read_last_seq(struct db_data_set *,char *);
/*global*/  void db_read_prev_seq(struct db_data_set *,char *);
/*global*/  void db_update_seq(struct db_data_set *,char *);

/*
 *	db_ran defs
 */

/*global*/  void db_add_ran(struct db_data_set *,char *);
/*global*/  void db_find_ran(struct db_data_set *,char *,char *);
/*global*/  void db_read_first_ran(struct db_data_set *,char *);
/*global*/  void db_read_next_ran(struct db_data_set *,char *);
/*global*/  void db_read_last_ran(struct db_data_set *,char *);
/*global*/  void db_read_prev_ran(struct db_data_set *,char *);
/*global*/  void db_update_ran(struct db_data_set *,char *);
/*global*/  void db_delete_ran(struct db_data_set *);
/*global*/  void db_delete_blk_ran(struct db_data_set *,unsigned long );
/*global*/  short db_hash_ran(struct db_data_set *,char *);
/*global*/  short db_search_blk_ran(struct db_data_set *,char *,struct db_data_buf *);

/*
 *	db_idx defs
 */

/*global*/  void db_add_idx(struct db_data_set *,char *);
/*global*/  void db_find_insert_idx(struct db_data_set *,char *,int );
/*global*/  void db_split_blk_idx(struct db_data_set *);
/*global*/  void db_read_first_idx(struct db_data_set *,unsigned short ,char *);
/*global*/  void db_read_next_idx(struct db_data_set *,char *);
/*global*/  void db_read_last_idx(struct db_data_set *,unsigned short ,char *);
/*global*/  void db_read_prev_idx(struct db_data_set *,char *);
/*global*/  void db_get_parent_idx(struct db_data_set *);
/*global*/  void db_find_first_idx(struct db_data_set *,char *,char *,int );
/*global*/  void db_delete_idx(struct db_data_set *);
/*global*/  short db_move_to_leaf_idx(struct db_data_set *);
/*global*/  void db_balance_idx(struct db_data_set *);
/*global*/  void db_update_idx(struct db_data_set *,char *);

