/*----------------------------------------------------------------------------
   dbtype.h: Standard Velocis header file containing:

      - DDL dictionary type definitions
      - Machine dependent constant definitions
      - Miscellaneous constants used by runtime functions
      - Virtual memory page table type definitions

   (An #include "rdm.h" must precede this include)

   Copyright (c) 1984-1994 Raima Corporation.  All Rights Reserved.
----------------------------------------------------------------------------*/

#ifndef DBTYPE_H
#define DBTYPE_H

#include "dpldata.h"

/*
----------------------------------------------------------------------------
    Internal function (keyfcns.c, dio.c) status, options
----------------------------------------------------------------------------
*/

#define PGHOLD 1
#define NOPGHOLD 0
#define PGFREE 1
#define NOPGFREE 0

#define KEYFIND 0
#define KEYNEXT 1
#define KEYPREV 2
#define KEYFRST 3
#define KEYLAST 4

/* last status value for key functions */
#define KEYEOF (-1)
#define KEYINIT 0
#define KEYFOUND 1
#define KEYNOTFOUND 2
#define KEYREPOS 3

#ifndef YES
#define YES TRUE
#define NO FALSE
#endif

#define BITS_PER_BYTE 8

#define DBD_COMPAT_LEN 6
#define SHORT_SIZE sizeof(short)
#define LONG_SIZE sizeof(long)
#define CTBNAME "rdm.ctb"
#define IND_NAME "rdm.chi"
#define CAT_NAME "catalog"

#define INVALID 32767
#define NONE (-1L)
#define OPTKEYNDX 0x003F
#define OPTKEY_LIMIT 63

#if DB_SHORT_LEN == 4
#define SORTSHIFT 22
#define SORTMASK 0x3C00000
#define OPTKEYSHIFT 26
#define OPTKEYMASK 0xFC000000
#define RLBMASK 0x40000000
#elif DB_SHORT_LEN == 2
#define SORTSHIFT 6
#define SORTMASK 0x3C0
#define OPTKEYSHIFT 10
#define OPTKEYMASK 0xFC00
#define RLBMASK 0x4000
#endif

/* set pointer structure definition */
typedef struct {
    long  total;                /* total number of members in set */
    DB_ADDR first;              /* database address of first member in set */
    DB_ADDR last;               /* database address of last member in set */
} SET_PTR;

/* member pointer structure definition */
typedef struct {
    DB_ADDR owner;              /* database address of owner record */
    DB_ADDR prev;               /* database address of previous member in set */
    DB_ADDR next;               /* database address of next member in set */
} MEM_PTR;

/* Offset to total members in set ptr */
#define SP_MEMBERS 0
/* Offset to first member ptr in set ptr */
#define SP_FIRST   sizeof(long)
/* Offset to last member ptr in set ptr */
#define SP_LAST    (SP_FIRST+DB_ADDR_SIZE)
/* Offset to owner ptr in member ptr */
#define MP_OWNER   0
/* Offset to previous member ptr in member ptr */
#define MP_PREV    (MP_OWNER+DB_ADDR_SIZE)
/* Offset to next member ptr in member ptr */
#define MP_NEXT    (MP_PREV+DB_ADDR_SIZE)

/* maximum length of a database file name */
#ifndef LOGFILELEN
#define LOGFILELEN 48
#endif
#ifdef UNIX                     /* UNIX */
/* maximum length of a database name */
#define DBNMLEN 12
/* maximum length of a database path */
#define PATHLEN (FILENMLEN-15)
#else                           /* ! UNIX */
/* maximum length of a database name */
#define DBNMLEN 9
/* maximum length of a database path */
#define PATHLEN (FILENMLEN-11)
#endif                          /* */

#define FULLPATHLEN 81

#define DEFDBPAGES 32           /* default number of database cache pages */

/* in-memory dictionary structure (for d_openTempDB) */
typedef struct {
    DB_USHORT page_size;
    DB_USHORT size_ft;
    DB_USHORT size_rt;
    DB_USHORT size_fd;
    DB_USHORT size_st;
    DB_USHORT size_mt;
    DB_USHORT size_srt;
    DB_USHORT size_kt;
    FILE_ENTRY   *file_table;   /* file table */
    RECORD_ENTRY *record_table; /* record table */
    FIELD_ENTRY  *field_table;  /* field table */
    SET_ENTRY    *set_table;    /* set table */
    MEMBER_ENTRY *member_table; /* member table */
    SORT_ENTRY   *sort_table;   /* sort table */
    KEY_ENTRY    *key_table;    /* key table */
} RDM_DBD;

/* node key search path stack entry: one per level per key field */
typedef struct {
    F_ADDR node;        /* node (page) number  */
    short slot;         /* slot number of key */
    long   version;     /* current version of key node */
    short  locked;      /* TRUE when a node lock is held */
} NODE_PATH;

/* key slot structure */
/* index key information: one entry per key field */
typedef struct {
    char       kn_flags;        /* flags (0 if nothing set) */
    NODE_PATH *node_path;       /* stack of node #s in search path */
    short      level;           /* current level # in node path */
    unsigned short max_lvls;    /* maximum possible levels for key */
    short      lstat;           /* last key function status */
    unsigned short fldno;       /* field number of key */
    FILE_NO    keyfile;         /* key file containing this key */
    char      *keyval;          /* ptr to last key value */
    DB_ADDR    dba;             /* db address of last key */
} KEY_INFO;

/* values for kn_flags */
#define KEY_REVERSE     0x01    /* reverse direction of keynext, etc. */

typedef struct {
    F_ADDR  child;              /* child node pointer */
    short   keyno;              /* key number */
    char    data[1];            /* start of key data */
} KEY_SLOT;

/* key location locking actions (parameter to key_locpos) */
#define K_READ   0x01
#define K_UPDATE 0x02
#define K_INSERT 0x0100  /* OR'ed with K_UPDATE */
#define K_DELETE 0x0200  /* OR'ed with K_UPDATE */

/* file rename table entry declarations */
typedef union {
    char   kd[256];             /* This makes KEY_TYPE 256 bytes long. */
    KEY_SLOT ks;
} KEY_TYPE;

typedef struct SK_S {
    unsigned short sk_fld;
    char *sk_val;
    struct SK_S *sk_next;
} SK_LIST;



/* database table entry declaration */
typedef struct _DB_ENTRY {
    unsigned short dbn;         /* Unique database number in this task */

    unsigned short odn;         /* open_db_table[odn] */
    unsigned short hSess;       /* task_table[hSess] */

    short    open_mode;         /* SHAREABLE(1), EXCLUSIVE(2), TEMPORARY(4)
                                   TRANSON(8) */
    DB_ADDR  curr_rec;          /* this db's current record */
    DB_ADDR *curr_own;          /* Current set owner array */
    DB_ADDR *curr_mem;          /* Current set member array */
    SK_LIST *sk_list;           /* This database's key value list */
    short    rn_type;           /* Type of current 'recnext' record */
    DB_ADDR  rn_dba;            /* Address of current 'recnext' record */
    KEY_INFO *key_info;         /* Key stack */
    short    permaccess;        /* type of dbacces 0=rd 1=up 2=cr 3=del */
    short    modified;          /* 0=database unchanged by tx, 1=changed */

    struct _DB_ENTRY *nextSessDb; /* list of open databases for a task */
    struct _DB_ENTRY *prevSessDb;

    struct _DB_ENTRY *nextOpenDb; /* list of open databases for a schema */
    struct _DB_ENTRY *prevOpenDb;

} DB_ENTRY;


/* page zero table entry */
typedef struct {
    F_ADDR pz_dchain;           /* delete chain pointer */
    F_ADDR pz_next;             /* next available record number */
    DB_ULONG pz_backstamp;      /* file's backup stamp value */
    short pz_modified;          /* TRUE if page zero has been modified */
} PGZERO;

/* NOTE -- this is SHORTER than the structure above, because it represents
 * only the elements which are written to disk -- pz_modified is used only
 * in memory:
 */
#define PGZEROSZ (2*sizeof(F_ADDR)+sizeof(DB_ULONG))

/* dynamic file status table */
typedef struct {
    short    fs_desc;           /* file descriptor */
    char     fs_status;         /* 'o'=opened, 'c'=closed, 'x'=initialize */
    char     fs_modified;       /* 1= modified  0 = clear */
    char *   fs_name;           /* file truename (including prepended
                                 * "device") */
    PGZERO   pgzero;            /* the page zero */
    struct _page_entry *pg_ptr; /* list of pages in cache for this file */
} FILE_STAT;

/* storage for Uncommitted Unique Key values */
typedef struct _UUK {
    unsigned short uuk_tid;
    struct _UUK *uuk_next;
    void *uuk_val;
} UUK;

typedef struct {
    short        sItemCnt;      /* Number of Data Items */
    DPLDATAITEM  *pDD;
} DD_ENTRY;

typedef struct {
    unsigned short dbd_inUse;   /* usage count -- number of open db's
                                 * referring to this template */
    char dbd_name[FILENMLEN];   /* name of database template */
    DB_USHORT page_size;        /* size of this db's page */
    FILE_ENTRY *file_table;     /* file table */
    DB_USHORT size_ft;
    RECORD_ENTRY *record_table; /* record table */
    DB_USHORT size_rt;
    char **rtName;              /* list of record names (ASCII) */
    DD_ENTRY *rt_dd;            /* list of RPC Data Descriptor Entries for
                                 * Record Entries */

    FIELD_ENTRY *field_table;   /* field table */
    DB_USHORT size_fd;
    char **fdName;              /* list of field names (ASCII) */
    DD_ENTRY *fd_dd;            /* list of RPC Data Descriptor Entries for
                                 * Field Entries */

    SET_ENTRY *set_table;       /* set table */
    DB_USHORT size_st;
    char **stName;              /* list of set names (ASCII) */

    MEMBER_ENTRY *member_table; /* member table */
    DB_USHORT size_mt;

    SORT_ENTRY *sort_table;     /* sort table */
    DB_USHORT size_srt;

    KEY_ENTRY *key_table;       /* key table */
    DB_USHORT size_kt;
    unsigned short no_of_keys;  /* value is derived at open time */
    DD_ENTRY *pkt_dd;           /* list of RPC Data Descriptor Entries for
                                 * Key Entries */
} OPEN_DBD;


typedef struct {
    char od_name[FILENMLEN];    /* name of database */
    short od_opencount;         /* number of tasks with this db open */
    short od_nonrdrcount;       /* number of non reader tasks */
    unsigned short dbID;        /* the database ID (from catalog) */
    OPEN_DBD *openDbd;          /* template for this database */
    FILE_STAT *file_stat;       /* file status table */
    UUK **unCommittedKeys;

    DB_ENTRY *openDbList;       /* list of open DB_ENTRY */
} OPEN_DB_ENTRY;


/* Country code table definition */

/* CNTRY_TBL translates a one or a pair of characters 
   into one character or another pair 
*/
#define TABLE_ALLOC_EXT 10    /* Table extension (in rows) */
/* Country code tables definition */

/* Table 1 translates a pair of chars into one char or another pair */
typedef struct {
    unsigned char in_char_1;
    unsigned char in_char_2;
    unsigned char out_char_1;
    unsigned char out_char_2;
    unsigned char sort_as1;
    unsigned char sort_as2;
    unsigned char sub_sort;
} CNTRY_TBL_1;

/* Table 2 translates 1 char into one or two chars */
typedef struct {
    unsigned char in_char;
    unsigned char out_char;
    unsigned char sort_as1;
    unsigned char sort_as2;
    unsigned char sub_sort;
} CNTRY_TBL_2;

/* Sort-as code */
typedef struct {
      unsigned char ch0;
      unsigned char ch1;
      unsigned int sub;
} SORT_AS;

typedef struct {
    unsigned short maxdbopen;
    unsigned short dbid_seq;
    unsigned short syncon;
    unsigned short archon;
    unsigned long maxchksize;
    unsigned long maxlogsize;
    char chlog_cycle[8];
} RPARMS;

/*
----------------------------------------------------------------------------
    Cache management, I/O structures (dio.c)
----------------------------------------------------------------------------
*/

/* to maintain a linked list of threads waiting for a page to be read */
typedef struct _PAGE_BLOCK {
    struct _PAGE_BLOCK *next;
    short block_handle;
} PAGE_BLOCK;

/* image of the buffer read or written to database file */
typedef struct {
    long version;               /* current version (incremented when page changes */
    char contents[1];           /* actually much longer */
} BUFF_ENTRY;

/* container for database page */
typedef struct _page_entry {
    unsigned short opdn;        /* database owning this file */
    FILE_NO     file;           /* file table entry number (0..size_ft-1) */
    F_ADDR      pageno;         /* database page number */
    short       status;         /* see values below */
    short       holdcnt;        /* "hold-in-cache" counter */
    PAGE_BLOCK *first_block;    /* pointer to linked-list of blocked threads */
    BUFF_ENTRY  *buff;          /* page buffer pointer */
    struct _page_entry *next_bkt;/* next bucket in hash */
    struct _page_entry *prev_bkt;/* previous bucket in hash */
    struct _page_entry *next_dpg;/* next page in database */
    struct _page_entry *prev_dpg;/* previous page in database */
} PAGE_ENTRY;

/* hash table for PAGE_ENTRY structures */
typedef struct _hash_entry {
    short buckets;              /* number of buckets in list */
    short max_buckets;          /* maximum number of buckets ever in list */
    PAGE_ENTRY *pg_ptr;         /* list of PAGE_ENTRY for this hash */
} HASH_ENTRY;

/* 'status' values */
#define PG_MODIFIED      0x01
#define PG_CHK_IN_PROG   0x02
#define PG_READ_IN_PROG  0x04
#define PG_RECENTLY_USED 0x08
#define PG_BEING_READ    0x10
#define PG_BEING_REMOVED 0x20

/*
----------------------------------------------------------------------------
*/

typedef struct {
    OPEN_DB_ENTRY *od;
    DB_ENTRY      *db;
} SAVE_ENTRY;

typedef struct _dberrhandler {
    struct _dberrhandler *next;          /* next error handler on stack */
    ERRORPROC             error_func;    /* error function */
    void                 *service_ptr;   /* user's error context ptr */
} DBERRHANDLER;

/* task-specific variables */
typedef struct _TASK {
    char           usname[USERNAMELEN]; /* User's login name */
    char           dbopen;        /* 0=no open db, 1=open db(s) */
    unsigned char  localModes;    /* freeable readlocks, dirty reads */
    short          d_stat;        /* return status of function */
    DBERRHANDLER  *errstack;      /* dberr handler stack */
    char          *db_errbuf;     /* Error buffer for task */
    short          db_api;        /* RDM API Number */
    short          db_level;      /* depth of API calls */
    short          mod_level;     /* depth of BeginCacheMods calls */
    RDM_SESS       my_sess;       /* my session handle */
    RDM_DB         catDb;         /* my handle to the catalog */
    unsigned short txID;          /* current transactions id */
    DB_ENTRY      *sessDbList;    /* list of open DB_ENTRY */
    unsigned short no_of_dbs;     /* size of db_table */
    unsigned short last_dbn;      /* last-referenced database number */
    DB_ENTRY      *last_dbt;      /* corresponds to last_dbn */
    SAVE_ENTRY    *save_stack;    /* global pointer save stack */
    GROUPLOCK     *xGLock;        /* copy of current group lock */
    unsigned short xGLockSize;    /* number of elements in xGLock */
    char          *xvalue;        /* Auxiliary buffer */
    unsigned short xvalue_len;    /* length of auxiliary buffer */
    PAGE_ENTRY    *last_datapage; /* last-found data file page */
    PAGE_ENTRY    *last_keypage;  /* last-found key file page */

    KEY_TYPE       key_type;
    FILE_NO        working_file;  /* current key file being processed */
    unsigned short fldNum;        /* keyfcns.c field number */
    unsigned short key_len;       /* keyfcns.c current key length */
    unsigned short key_data;
    unsigned short slot_len;
    unsigned short max_slots;
    unsigned short mid_slot;
    unsigned short curr_keyfile;
    DB_SHORT       curr_keyno;
    DB_SHORT       prefix;
    short          unique;
    KEY_INFO      *curkey;
    FIELD_ENTRY   *cfld_ptr;
} TASK;


/*
----------------------------------------------------------------------------
    Useful macros
----------------------------------------------------------------------------
*/

/* NOTE: db_status is a global variable, returned by db_enter.  After db_enter
         returns, gl is set up correctly, and gl->d_stat is used.
*/
#define DB_ENTER(hDb, hSess, apifcn) if ( (db_status=db_enter(hDb, hSess, apifcn)) != S_OKAY ) { return( db_status ); } else
#define DB_EXIT(x)  return (db_exit(x))

/* Common questions which may change in representation */
#define LOCKING_NEEDED(m) (!((m) & OPM_EXCLUSIVE) && ((m)!=TEMPORARY))
/*
----------------------------------------------------------------------------
    Checkpointing
----------------------------------------------------------------------------
*/

#define CHK_FILE "rdm.chk"
#define CHKFILENMLEN 500	/* long file name limit */

/* format of checkpoint file records */

typedef struct {
    char  chk_FileName[CHKFILENMLEN]; /* full file name */
    short chk_Desc;                   /* resource mgr handle of file */
} CHECKPOINT_HDR;

typedef struct {
    unsigned short chk_PageSize;
    unsigned long chk_PageAddr;    /* page address on database file */
    unsigned long chk_PageOffset;  /* page offset in checkpoint file */
} CHECKPOINT_ENTRY;

/* Used by dataPad() */
#define COPY   TRUE
#define NOCOPY FALSE

/*
-----------------------------------------------------------------------------
     Task specific modes
         stored in localModes
-----------------------------------------------------------------------------
*/
#define TRANS_ACTIVE       0x01
#define FREEABLE_READLOCKS 0x02
#define DIRTY_READS        0x04
#define ABORT_ACTIVE       0x08
#define UUK_SET            0x10
#define ADMIN_TASK         0x20
#define SUPER_TASK         0x40
#define VOID_TRANSACTION   0x80
/*
------------------------------------------------------------------------------
     Database Open Modes
        stored in od_mode
------------------------------------------------------------------------------
*/
#define OPM_SHAREABLE 0x01
#define OPM_EXCLUSIVE 0x02
#define OPM_READONLY  0x04
#define TEMPORARY     0x08
#define TRANSON       0x10

/*  
-----------------------------------------------------------------------------
    Lock Arbiter Internal  Values
-----------------------------------------------------------------------------
*/
#define PAGEMARK 30000

#define LAUPDATE 1
#define LAREAD   2
#define LACREATE 3

#define TABLE    1
#define INSTANCE 2

#define LSFREE   0x01
#define LSWRITE  0x02
#define LSREAD   0x04

#define LA_LOCKCONFLICT 1       /* table and instance locks are in conflict */
#define LA_LOCKGRANTED  2       /* lock granted */
#define LA_LOCKDENIED   3       /* lock timed out or was denied */
#define LA_NOTLOCKED    4       /* attempt to free unlocked entity */
#define LA_LOCKFREED    5       /* successful free of lock */
#define LA_LOCKUPGRADE  6       /* lock was granted as an upgrade */
#define LA_LOCKDOWNGRADE 7      /* lock is a downgrade of existing lock */
#define LA_LOCKINCONSISTENT  8  /* table/instance lock conflict, but allowed */
#define LA_QUELOCKUPGRADE    9  /* queue table/instance lock upgrade */
#define LA_LOCKUPGRADEDENIED 10 /* deny the whole group lock */
#define LA_LOCKALREADYGRANTED 11/* deny the whole group lock */
#define LA_STATIC       12      /* attempted to write lock static entity */

#ifndef NO_NESTED_H
#ifdef UNIX
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#else
#include <io.h>
#endif

#endif

#endif
/*
$Header:   P:/PAT/INCLUDE/VCS/DBTYPE.H_V   1.75   16 Feb 1995 13:38:06   BRADB  $
*/
