/************ DAE: OS/2 Database Access Engine *************/
/************ daedef.h: DAE Global Definitions *************/


/***********************************************************/
/******************* fundamental types *********************/
/***********************************************************/

#include "os.h"

/***********************************************************/
/****************** global configuration macros ************/
/***********************************************************/

#ifndef WIN16                                   /* for OS/2 or Win32 */
#define ASYNC_IO_PROC           /* asynchronous IO */
#define ASYNC_LOG_FLUSH         /* asynchronous LOG FLUSH */

#define ASYNC_BF_CLEANUP        /* asynchorouse Buffer clean up */
#define ASYNC_VER_CLEANUP       /* asynchronous Bucket clean up */
#define ASYNC_BM_CLEANUP        /* asynchorouse Bookmark clean up */
#endif

#define CHECKSUM                        /* check sum for read/write page validation */
//#define PERFCNT                       /* enable performance counter */
//#define NOLOG                         /* Log disabled? */
#define REUSEDBID                       /* Reuse DBID */
//#define RFS2
//#define MEM_CHECK                     /*      Check for resource and memory leakage */
//#define KEYCHANGED
#define BULK_INSERT_ITEM
#define MOVEABLEDATANODE

/***********************************************************/
/******************* declaration macros ********************/
/***********************************************************/

#ifdef JETINTERNAL                      /* Start of definitions copied from vtapi.h */

#ifndef NJETNT
#ifdef  WIN32                                /* 0:32 Flat Model (Intel 80x86) */
        #define VTAPI __cdecl
#elif   defined(M_MRX000)            /* 0:32 Flat Model (MIPS Rx000) */
        #define VTAPI
#elif   defined(_M_PPC)              /* 0:32 Flat Model (PowerPC) */
        #define VTAPI
#else   /* WIN16 */                          /* 16:16 Segmented Model */
        #define VTAPI __far __pascal
#endif
#endif

#endif                                          /* End of definitions copied from vtapi.h */


#include "daedebug.h"

#define LOCAL static
#ifdef DEBUG
#define INLINE
#else
#define INLINE __inline
#endif

/***********************************************************/
/************ global types and associated macros ***********/
/***********************************************************/

typedef struct _res                     /* resource, defined in sysinit.c and daeutil.h */
        {
        const INT       cbSize;
        INT                     cblockAlloc;
        BYTE                    *pbAlloc;
        INT                     cblockAvail;
        BYTE                    *pbAvail;
        INT                     iblockCommit;
        INT                     iblockFail;
        } RES;

typedef struct _pib             PIB;
typedef struct _ssib            SSIB;
typedef struct _fucb            FUCB;
typedef struct _csr             CSR;
typedef struct _fcb             FCB;
typedef struct _fdb             FDB;
typedef struct _idb             IDB;
typedef struct _dib             DIB;
typedef struct _scb             SCB;
typedef struct _rcehead RCEHEAD;
typedef struct _rce             RCE;
typedef struct _bucket  BUCKET;
typedef struct _dab             DAB;
typedef struct _rmpage  RMPAGE;
typedef struct _bmfix   BMFIX;

typedef unsigned short LANGID;
typedef ULONG                   LRID;
#if WIN32
typedef ULONG                   PROCID;
#else
typedef TID                             PROCID;
#endif

#define pNil                    ((void *)0)
#define pbNil                   ((BYTE *)0)
#define plineNil                ((LINE *)0)
#define pkeyNil                 ((KEY *)0)
#define ppibNil                 ((PIB *)0)
#define pwaitNil                ((WAIT *)0)
#define pssibNil                ((SSIB *)0)
#define pfucbNil                ((FUCB *)0)
#define pcsrNil                 ((CSR *)0)
#define pfcbNil                 ((FCB *)0)
#define pfdbNil                 ((FDB *)0)
#define pfieldNil               ((FIELD *)0)
#define pidbNil                 ((IDB *)0)
#define pscbNil                 ((SCB *)0)
#define procidNil               ((PROCID) 0xffff)
#define pbucketNil              ((BUCKET *)0)
#define prceheadNil             ((RCEHEAD *)0)
#define prceNil                 ((RCE *)0)
#define pdabNil                 ((DAB *)0)
#define prmpageNil              ((RMPAGE *) 0)

typedef unsigned long   PGNO;
typedef unsigned long   PGDISCONT;
typedef unsigned long   PN;
#define pnNull                  ((PN) 0)
#define pgnoNull                ((PGNO) 0)

/* UNDONE: should be in storage.h */
#define FVersionPage(pbf)  (pbf->ppage->pghdr.cVersion)

#define CPG                                     LONG                                    /* count of pages */

typedef BYTE                            LEVEL;                          /* transaction levels */
#define levelNil                        ((LEVEL)0xff)           /*      flag for inactive PIB */

typedef WORD                            DBID;
typedef WORD                            FID;
typedef SHORT                           IDXSEG;

/* Standard Record IDs */
typedef ULONG SRID;                                                             /* standard record id */
typedef ULONG LINK;
#define PgnoOfSrid(srid) ((srid)>>8)
#define ItagOfSrid(srid) ((BYTE)((srid) & 0x000000FF))
#define SridOfPgnoItag(pgno, itag) ((pgno)<<8 | (LONG)(itag))
#define itagNil ((INT)0x0fff)
#define sridNull SridOfPgnoItag(pgnoNull, ((BYTE)itagNil))
#define sridNullLink    0


/*      position within current series
 *      note order of field is of the essence as log position used by
 *      storage as timestamp, must in ib, isec, usGen order so that we can
 *  use long value compare.
 */
typedef struct
        {
        USHORT ib;                                      /* must be the last so that lgpos can */
        USHORT isec;                            /* index of disksec starting logsec      */
        USHORT usGeneration;            /* generation of logsec */
        } LGPOS;                                        /* be casted to TIME. */
extern LGPOS lgposMax;
extern LGPOS lgposMin;
extern INT fRecovering;         /* to turn off logging during Redo */


/***********************************************************/
/*********************** DAE macros ************************/
/***********************************************************/

/*  per database operation counter, ulDBTime is logged, used to compare
 *  with the ulDBTime of a page to decide if a redo of the logged operation
 *  is necessary.
 */
#define ulDBTimeMin     (0x00000000)
#define ulDBTimeMax     (0xffffffff)

/*  Transaction counter, used to keep track of the oldest transaction.
 */
typedef ULONG           TRX;
#define trxMin          0
#define trxMax          (0xffffffff)


typedef struct
        {
        ULONG cb;
        BYTE *pb;
        } LINE;

#define FLineNull(pline) \
        ((pline) == NULL || (pline)->cb == 0 || (pline)->pb == NULL)

#define LineCopy(plineTo, plineFrom)                                                            \
        {                                                                                                                               \
        (plineTo)->cb = (plineFrom)->cb;                                                                \
        memcpy((plineTo)->pb, (plineFrom)->pb, (plineFrom)->cb);                \
        }
#define CbLine(pline) ((pline) ? (pline)->cb : 0)

typedef LINE KEY;                               // Directory Key
#define FKeyNull(pkey) FLineNull(pkey)
#define KeyCopy(pkeyTo, pkeyFrom) LineCopy(pkeyTo, pkeyFrom)
#define CbKey(pkey) CbLine(pkey)

typedef struct
        {
        ULONG cbMax;                            // size of buffer
        ULONG cbActual;                         // true size of return value
        ULONG cbReturned;                       // length of value returned
        BYTE *pb;                                       // pointer to buffer for return value
        } OUTLINE;

typedef struct _threebytes { BYTE b[3]; } THREEBYTES;
#define ThreeBytesFromL(tb, l)                                                  \
        {                                                                                                                               \
        ULONG DAE_ul = l;                                                                                       \
        BYTE *DAE_ptb = (BYTE *)&(tb);                                          \
        *DAE_ptb        = (BYTE)DAE_ul;                                                                 \
        *++DAE_ptb = (BYTE)( DAE_ul >>= 8 );                            \
        *++DAE_ptb = (BYTE)( DAE_ul >>= 8 );                            \
        }

#define LFromThreeBytes(l, tb)                                                  \
        {                                                                                                                               \
        ULONG DAE_ul;                                                                                           \
        BYTE *DAE_ptb = (BYTE *)&(tb) + 2;                                      \
        DAE_ul = (ULONG) *DAE_ptb;                                                              \
        DAE_ul <<= 8;                                                                                           \
        DAE_ul |= *--DAE_ptb;                                                                   \
        DAE_ul <<=8;                                                                                            \
        DAE_ul |= *--DAE_ptb;                                                                   \
        l = DAE_ul;                                                                                                     \
        }

#define TbKeyFromPgno(tbLast, pgno)                                                     \
        {                                                                                                                                       \
        ULONG DAE_ul = pgno;                                                                                    \
        BYTE * DAE_ptb = ((BYTE *)&(tbLast)) + 2;                               \
        *DAE_ptb = (BYTE) (DAE_ul);                                                             \
        *--DAE_ptb = (BYTE) (DAE_ul >>= 8);                                             \
        *--DAE_ptb = (BYTE) (DAE_ul >>= 8);                                             \
        }

#define PgnoFromTbKey(pgno, tbKey)                                                      \
        {                                                                                                                                       \
        ULONG DAE_ul;                                                                                                   \
        BYTE * DAE_ptb = (BYTE *) & (tbKey);                                    \
        DAE_ul = (ULONG) *DAE_ptb;                                                                      \
        DAE_ul <<= 8;                                                                                                   \
        DAE_ul |= *++DAE_ptb;                                                                           \
        DAE_ul <<= 8;                                                                                                   \
        DAE_ul |= *++DAE_ptb;                                                                           \
        pgno = DAE_ul;                                                                                                  \
        }

#define Pb4ByteAlign( pb )              ( ((LONG)pb + 3) & 0xfffffffc )
#define Pb4ByteTruncate( pb )   ( (LONG)pb & 0xfffffffc )

/***********************************************************/
/******************** general C macros *********************/
/***********************************************************/

#define forever                                 for(;;)

#ifdef  DEBUG

#ifdef  RFS2

/*  RFS/JET call logging
/*
/*      RFS allocator:  returns 0 if allocation is disallowed.  Also handles RFS logging.
/*      cRFSAlloc is the global allocation counter.  A value of -1 disables RFS in debug mode.
/**/

#define RFSAlloc(type) (UtilRFSAlloc(#type))

        /*  RFS disable/enable macros  */

#define RFSDisable()    (fDisableRFS = 1)
#define RFSEnable()             (fDisableRFS = 0)

/*  JET call logging (log on failure)
/**/

#define LogJETCall(func,err) (UtilRFSLogJETCall(#func,err,szAssertFilename,__LINE__))

/*  JET call macros
/**/

#define Call(func)                      {LogJETCall(func,err = (func)); if (err < 0) {goto HandleError;}}
#define CallR(func)                     {LogJETCall(func,err = (func)); if (err < 0) {return err;}}
#define CallJ(func,label)       {LogJETCall(func,err = (func)); if (err < 0) {goto label;}}
#define CallS(func)                     {ERR errT; LogJETCall(func,errT = (func)); Assert(errT == JET_errSuccess);}

/*  JET inline error logging (logging controlled by JET call flags)
/**/

#define LogJETErr(err,label) (UtilRFSLogJETErr(err,#label,szAssertFilename,__LINE__))

/*  JET inline error macros
/**/

#define Error(errT,label)       {LogJETErr(errT,label); err = (errT); goto label;}

#else

#define RFSAlloc(type)                          (1)
#define RFSDisable()                            (1)
#define RFSEnable()                                     (0)
#define Call(func)                                      {if ((err = (func)) < 0) {goto HandleError;}}
#define CallR(func)                                     {if ((err = (func)) < 0) {return err;}}
#define CallJ( func, label )            {if ((err = (func)) < 0) goto label;}
#define Error( errToReturn, label )     {err = errToReturn; goto label;}
#define CallS(func)                                     { ERR errT; Assert( (errT = (func)) == JET_errSuccess ); }

#endif

#else

#define RFSAlloc(type)          (1)
#define RFSDisable()            (1)
#define RFSEnable()                     (0)
#define Call(func)                      {if ((err = (func)) < 0) {goto HandleError;}}
#define CallR(func)                     {if ((err = (func)) < 0) {return err;}}
#define CallJ(func,label)       {if ((err = (func)) < 0) {goto label;}}
#define CallS(func)                     {ERR errT; errT = (func);}
#define Error(errT,label)       {err = (errT); goto label;}

#endif

#define NotUsed(p)      p==p;


/***********************************************************/
/***** include Jet Project prototypes and constants ********/
/***********************************************************/

#include "jet.h"
#include "_jet.h"
#include "_jetstr.h"
#include "jetdef.h"
#include "sesmgr.h"
#include "isamapi.h"
#include "vdbapi.h"
#include "vtapi.h"
#include "disp.h"
#include "taskmgr.h"

#include "vdbmgr.h"
extern CODECONST(VDBFNDEF) vdbfndefIsam;

#include "vtmgr.h"
extern CODECONST(VTFNDEF) vtfndefIsam;
extern CODECONST(VTFNDEF) vtfndefIsamInfo;
extern CODECONST(VTFNDEF) vtfndefTTSortIns;
extern CODECONST(VTFNDEF) vtfndefTTSortRet;
extern CODECONST(VTFNDEF) vtfndefTTBase;

JET_TABLEID TableidOfVtid( FUCB *pfucb );

ERR VTAPI ErrDispPrepareUpdate( JET_SESID sesid, JET_TABLEID tableid,
        JET_GRBIT grbit );
ERR VTAPI ErrDispSetColumn( JET_SESID sesid, JET_TABLEID tableid,
        JET_COLUMNID columnid, const void *pb, unsigned long cb, JET_GRBIT grbit,
        JET_SETINFO *psetinfo );
ERR VTAPI ErrDispCloseTable( JET_SESID sesid, JET_TABLEID tableid );
ERR VTAPI ErrDispUpdate( JET_SESID sesid, JET_TABLEID tableid, void *pb,
        unsigned long cbMax, unsigned long *pcbActual );
ERR VTAPI ErrDispMove( JET_SESID sesid, JET_TABLEID tableid, long crows, JET_GRBIT grbit );

/***********************************************************/
/******************* mutual exclusion **********************/
/***********************************************************/

typedef void * SEM;
typedef void * SIG;
typedef void * CRIT;

/*      enable multiple MUTEX resource
/**/
#ifdef WIN16

#define SemDefine( s )
#define ErrSemCreate( s, sz )                                   JET_errSuccess
#define SemRequest( s )                                                 0
#define SemRelease( s )                                                 0
#define SemAssert( s )                                                  0
#define ErrSignalCreate( s, sz )                                JET_errSuccess
#define ErrSignalCreateAutoReset( s, sz )               JET_errSuccess
#define SignalReset( s )                                                0
#define SignalSend( s )                                                 0
#define SignalWait( s, t )                                              0
#define SignalWaitEx( s, t )                                    0
#define MultipleSignalWait( i, rg, f, t )               0
#define SignalClose( s )                                                0
#define ErrInitializeCriticalSection( s )               JET_errSuccess
#define EnterCriticalSection( s )                               0
#define LeaveCriticalSection( s )                               0
#define EnterNestableCriticalSection( s )               0
#define LeaveNestableCriticalSection( s )               0
#define AssertCriticalSection( s )                              0
#define DeleteCriticalSection( s )                              0

#define SgSemDefine( s )
#define SgErrSemCreate( s, sz )                                 JET_errSuccess
#define SgSemRequest( s )                                               0
#define SgSemRelease( s )                                               0
#define SgSemAssert( s )                                                0

#define LgSemDefine( s )
#define LgErrSemCreate( s, sz )                                 JET_errSuccess
#define LgSemRequest( s )                                               0
#define LgSemRelease( s )                                               0
#define LgSemAssert( s )                                                0
#define LgErrInitializeCriticalSection( s, c )  JET_errSuccess
#define LgEnterCriticalSection( s )                             0
#define LgLeaveCriticalSection( s )                             0
#define LgEnterNestableCriticalSection( s )             0
#define LgLeaveNestableCriticalSection( s )             0
#define LgAssertCriticalSection( s )                    0
#define LgDeleteCriticalSection( s )                    0

#else /* !WIN16 */

#ifdef SGSEM                                    /* small grain */

#define SemDefine( s )                                                  __near SEM s
#define ErrSemCreate( s, sz )                                   UtilSemCreate( s )
#define SemRequest( s )                                                 UtilSemRequest( s )
#define SemRelease( s )                                                 UtilSemRelease( s )
#define SemAssert( s )                                                  UtilAssertSEM( s )
#define ErrSignalCreate( s, sz )                                ErrUtilSignalCreate( s, sz )
#define ErrSignalCreateAutoReset( s, sz )               ErrUtilSignalCreateAutoReset( s, sz )
#define SignalReset( s )                                                UtilSignalReset( s )
#define SignalSend( s )                                                 UtilSignalSend( s )
#define SignalWait( s, t )                                              UtilSignalWait( s, t )
#define SignalWaitEx( s, t, f )                                 UtilSignalWaitEx( s, t, f )
#define MultipleSignalWait( i, rg, f, t )               UtilMultipleSignalWait( i, rg, f, t )
#define SignalClose( s )                                                UtilCloseSignal( s )
#define ErrInitializeCriticalSection( s )               ErrUtilInitializeCriticalSection( s )
#define EnterCriticalSection( s )                               UtilEnterCriticalSection( s )
#define LeaveCriticalSection( s )                               UtilLeaveCriticalSection( s )
#define EnterNestableCriticalSection( s )               UtilEnterNestableCriticalSection( s )
#define LeaveNestableCriticalSection( s )               UtilLeaveNestableCriticalSection( s )
#define AssertCriticalSection( s )                              UtilAssertCrit( s )
#define HoldCriticalSection( s )        \
        {                                                               \
        UtilAssertCrit( s );                    \
        UtilHoldCriticalSection( s );   \
        }
#define ReleaseCriticalSection( s )
        {                                                               \
        UtilAssertCrit( s );                    \
        UtilReleaseCriticalSection( s );\
        }
#define DeleteCriticalSection( s )                              UtilDeleteCriticalSection( s )

#define SgSemDefine( s )                                                __near SEM s
#define SgErrSemCreate( s, sz )                                 UtilSemCreate( s, sz )
#define SgSemRequest( s )                                               UtilSemRequest( s )
#define SgSemRelease( s )                                               UtilSemRelease( s )
#define SgSemAssert( s )                                                UtilAssertSEM( s )

#define LgSemDefine( s )
#define LgErrSemCreate( s, sz )                                 0
#define LgSemRequest( s )                                               0
#define LgSemRelease( s )                                               0
#define LgSemAssert( s )                                                0
#define LgErrInitializeCriticalSection( s )             JET_errSuccess
#define LgEnterCriticalSection( s )                             0
#define LgLeaveCriticalSection( s )                             0
#define LgEnterNestableCriticalSection( s )             0
#define LgLeaveNestableCriticalSection( s )             0
#define LgAssertCriticalSection( s )                    0
#define LgDeleteCriticalSection( s )                    0

#else /* !SGSEM */

#define SemDefine( s )                                                  __near SEM s
#define SemErrCreate( s, sz )                                   UtilSemCreate( s, sz )
#define SemRequest( s )                                                 UtilSemRequest( s )
#define SemRelease( s )                                                 UtilSemRelease( s )
#define SemAssert( s )                                                  UtilAssertSEM( s )
#define ErrSignalCreate( s, sz )                                ErrUtilSignalCreate( s, sz )
#define ErrSignalCreateAutoReset( s, sz )               ErrUtilSignalCreateAutoReset( s, sz )
#define SignalReset( s )                                                UtilSignalReset( s )
#define SignalSend( s )                                                 UtilSignalSend( s )
#define SignalWait( s, t )                                              UtilSignalWait( s, t )
#define SignalWaitEx( s, t, f )                                 UtilSignalWaitEx( s, t, f )
#define MultipleSignalWait( i, rg, f, t )               UtilMultipleSignalWait( i, rg, f, t )
#define SignalClose( s )                                                UtilCloseSignal( s )
#define ErrInitializeCriticalSection( s )               ErrUtilInitializeCriticalSection( s )
#define EnterCriticalSection( s )                               UtilEnterCriticalSection( s )
#define LeaveCriticalSection( s )                               UtilLeaveCriticalSection( s )
#define EnterNestableCriticalSection( s )               UtilEnterNestableCriticalSection( s )
#define LeaveNestableCriticalSection( s )               UtilLeaveNestableCriticalSection( s )
#define AssertCriticalSection( s )                              UtilAssertCrit( s )
#define HoldCriticalSection( s )        \
        {                                                               \
        UtilAssertCrit( s );                    \
        UtilHoldCriticalSection( s );   \
        }
#define ReleaseCriticalSection( s )     \
        {                                                               \
        UtilAssertCrit( s );                    \
        UtilReleaseCriticalSection( s );\
        }
#define DeleteCriticalSection( s )                              UtilDeleteCriticalSection( s )

#define SgSemDefine( s )
#define SgErrSemCreate( s, sz )                                 0
#define SgSemRequest( s )                                               UtilAssertCrit( critJet )
#define SgSemRelease( s )                                               UtilAssertCrit( critJet )
#define SgSemAssert( s )                                                UtilAssertCrit( critJet )

#define LgSemDefine( s )                                                __near SEM s;
#define LgErrSemCreate( s, sz )                                 SemCreate( s, sz )
#define LgSemRequest( s )                                               SemRequest( s )
#define LgSemRelease( s )                                               SemRelease( s )
#define LgSemAssert( s )                                                UtilAssertCrit( s )
#define LgErrInitializeCriticalSection( s )             ErrUtilInitializeCriticalSection( s )
#define LgEnterCriticalSection( s )                             UtilEnterCriticalSection( s )
#define LgLeaveCriticalSection( s )                             UtilLeaveCriticalSection( s )
#define LgEnterNestableCriticalSection( s )             UtilEnterNestableCriticalSection( s )
#define LgLeaveNestableCriticalSection( s )             UtilLeaveNestableCriticalSection( s )
#define LgAssertCriticalSection( s )                    UtilAssertCrit( s )
#define LgDeleteCriticalSection( s )                    UtilDeleteCriticalSection( s )

#endif /* !SGSEM */

#endif /* !WIN16 */

/*      include other global DAE headers
/**/
#include        "sys.h"
#include        "err.h"
#include        "daeconst.h"

#define fSTInitNotDone          0
#define fSTInitInProgress       1
#define fSTInitDone                     2
extern BOOL __near fSTInit;
