181 lines
6.7 KiB
C
181 lines
6.7 KiB
C
// Flags for field descriptor
|
|
/* note that these flags are stored persistantly in database
|
|
/* catalogs and cannot be changed without a database format change
|
|
/**/
|
|
#define ffieldNotNull (1<<0) // NULL values not allowed
|
|
#define ffieldVersion (1<<2) // Version field
|
|
#define ffieldAutoInc (1<<3) // Auto increment field
|
|
#define ffieldMultivalue (1<<4) // Multi-valued column
|
|
#define ffieldDefault (1<<5) // Column has ISAM default value
|
|
|
|
#define FIELDSetNotNull( field ) ((field) |= ffieldNotNull)
|
|
#define FIELDResetNotNull( field ) ((field) &= ~ffieldNotNull)
|
|
#define FFIELDNotNull( field ) ((field) & ffieldNotNull)
|
|
|
|
#define FIELDSetVersion( field ) ((field) |= ffieldVersion)
|
|
#define FIELDResetVersion( field ) ((field) &= ~ffieldVersion)
|
|
#define FFIELDVersion( field ) ((field) & ffieldVersion)
|
|
|
|
#define FIELDSetAutoInc( field ) ((field) |= ffieldAutoInc)
|
|
#define FIELDResetAutoInc( field ) ((field) &= ~ffieldAutoInc)
|
|
#define FFIELDAutoInc( field ) ((field) & ffieldAutoInc)
|
|
|
|
#define FIELDSetMultivalue( field ) ((field) |= ffieldMultivalue)
|
|
#define FIELDResetMultivalue( field ) ((field) &= ~ffieldMultivalue)
|
|
#define FFIELDMultivalue( field ) ((field) & ffieldMultivalue)
|
|
|
|
#define FIELDSetDefault( field ) ((field) |= ffieldDefault)
|
|
#define FIELDResetDefault( field ) ((field) &= ~ffieldDefault)
|
|
#define FFIELDDefault( field ) ((field) & ffieldDefault)
|
|
|
|
#define FIELDSetFlag( field, flag ) ((field).ffield |= (flag))
|
|
#define FIELDResetFlag( field, flag ) ((field).ffield &= ~(flag))
|
|
|
|
#define FRECLongValue( coltyp ) \
|
|
( (coltyp) == JET_coltypLongText || (coltyp) == JET_coltypLongBinary )
|
|
|
|
#define FRECTextColumn( coltyp ) \
|
|
( (coltyp) == JET_coltypText || (coltyp) == JET_coltypLongText )
|
|
|
|
#define FRECBinaryColumn( coltyp ) \
|
|
( (coltyp) == JET_coltypBinary || (coltyp) == JET_coltypLongBinary )
|
|
|
|
#define cbAvgColName 10 // Average length of a column name
|
|
|
|
/* entry in field descriptor tables found in an FDB
|
|
/**/
|
|
typedef struct _field
|
|
{
|
|
JET_COLTYP coltyp; // column data type
|
|
ULONG cbMaxLen; // maximum length
|
|
ULONG itagFieldName; // Offset into FDB's buffer
|
|
USHORT cp; // code page of language
|
|
BYTE ffield; // various flags
|
|
} FIELD;
|
|
|
|
|
|
|
|
typedef struct tagFIELDEX // Extended field info.
|
|
{
|
|
FIELD field; // Standard field info (see above)
|
|
FID fid; // field id
|
|
WORD ibRecordOffset; // Record offset (for fixed fields only)
|
|
} FIELDEX;
|
|
|
|
|
|
#define itagFDBFields 1 // Tag into FDB's buffer for field info
|
|
// (FIELD structures and fixed offsets table)
|
|
|
|
// The fixed offsets table is also the beginning of the field info (ie. the FIELD
|
|
// structures follow the fixed offsets table).
|
|
#define PibFDBFixedOffsets( pfdb ) ( (WORD *)PbMEMGet( (pfdb)->rgb, itagFDBFields ) )
|
|
|
|
// Get the appropriate FIELD structure based on the previous FIELD structure.
|
|
// NOTE: Be wary of the alignment fixup for the fixed offsets table.
|
|
#define PfieldFDBFixedFromOffsets( pfdb, pibFixedOffsets ) \
|
|
( (FIELD *)( Pb4ByteAlign( (BYTE *) ( pibFixedOffsets + (pfdb)->fidFixedLast + 1 ) ) ) )
|
|
#define PfieldFDBVarFromFixed( pfdb, pfieldFixed ) \
|
|
( pfieldFixed + (pfdb)->fidFixedLast + 1 - fidFixedLeast )
|
|
#define PfieldFDBTaggedFromVar( pfdb, pfieldVar ) \
|
|
( pfieldVar + (pfdb)->fidVarLast + 1 - fidVarLeast )
|
|
|
|
// Get the appropriate FIELD strcture, starting from the beginning of the field info.
|
|
#define PfieldFDBFixed( pfdb ) PfieldFDBFixedFromOffsets( pfdb, PibFDBFixedOffsets( pfdb ) )
|
|
#define PfieldFDBVar( pfdb ) PfieldFDBVarFromFixed( pfdb, PfieldFDBFixed( pfdb ) )
|
|
#define PfieldFDBTagged( pfdb ) PfieldFDBTaggedFromVar( pfdb, PfieldFDBVar( pfdb ) )
|
|
|
|
|
|
/* field descriptor block: information about all columns of a table
|
|
/**/
|
|
struct _fdb
|
|
{
|
|
BYTE *rgb; // Buffer for FIELD structures, fixed
|
|
// offsets table, and column names
|
|
FID fidFixedLast; // Highest fixed field id in use
|
|
FID fidVarLast; // Highest variable field id in use
|
|
FID fidTaggedLast; // Highest tagged field id in use
|
|
USHORT ffdb; // FDB flags. NOTE: This field is currently
|
|
// no longer used, but keep it here anyways
|
|
// for alignment purposes.
|
|
FID fidVersion; // fid of version field
|
|
FID fidAutoInc; // fid of auto increment field
|
|
LINE lineDefaultRecord; // default record
|
|
};
|
|
|
|
|
|
typedef struct tagMEMBUFHDR
|
|
{
|
|
ULONG cbBufSize; // Length of buffer.
|
|
ULONG ibBufFree; // Beginning of free space in buffer
|
|
// (if ibBufFree==cbBufSize, then buffer is full)
|
|
ULONG cTotalTags; // Size of tag array
|
|
ULONG iTagUnused; // Next unused tag (never been used or freed)
|
|
ULONG iTagFreed; // Next freed tag (previously used, but since freed)
|
|
} MEMBUFHDR;
|
|
|
|
|
|
typedef struct tagMEMBUFTAG
|
|
{
|
|
ULONG ib; // UNDONE: Should these be SHORT's instead?
|
|
ULONG cb;
|
|
} MEMBUFTAG;
|
|
|
|
typedef struct tagMEMBUF
|
|
{
|
|
MEMBUFHDR bufhdr;
|
|
BYTE *pbuf;
|
|
} MEMBUF;
|
|
|
|
|
|
ERR ErrMEMCreateMemBuf( BYTE **prgbBuffer, ULONG cbInitialSize, ULONG cInitialEntries );
|
|
ERR ErrMEMCopyMemBuf( BYTE **prgbBufferDest, BYTE *rgbBufferSrc );
|
|
VOID MEMFreeMemBuf( BYTE *rgbBuffer );
|
|
ERR ErrMEMAdd( BYTE *rgbBuffer, BYTE *rgb, ULONG cb, ULONG *pitag );
|
|
ERR ErrMEMReplace( BYTE *rgbBuffer, ULONG iTagEntry, BYTE *rgb, ULONG cb );
|
|
VOID MEMDelete( BYTE *rgbBuffer, ULONG iTagEntry );
|
|
|
|
#ifdef DEBUG
|
|
BYTE *SzMEMGetString( BYTE *rgbBuffer, ULONG iTagEntry );
|
|
VOID MEMAssertMemBuf( MEMBUF *pmembuf );
|
|
VOID MEMAssertMemBufTag( MEMBUF *pmembuf, ULONG iTagEntry );
|
|
#else
|
|
#define SzMEMGetString( rgbBuffer, iTagEntry ) PbMEMGet( rgbBuffer, iTagEntry )
|
|
#define MEMAssertMemBuf( pmembuf )
|
|
#define MEMAssertMemBufTag( pmembuf, iTagEntry )
|
|
#endif
|
|
|
|
// Retrieve a pointer to the desired entry in the buffer.
|
|
// WARNING: Pointers into the contents of the buffer are very
|
|
// volatile -- they may be invalidated the next time the buffer
|
|
// is reallocated. Ideally, we should never allow direct access via
|
|
// pointers -- we should only allow indirect access via itags which we
|
|
// will dereference for the user and copy to a user-provided buffer. However,
|
|
// there would be a size and speed hit with such a method.
|
|
INLINE STATIC BYTE *PbMEMGet( BYTE *rgbBuffer, ULONG iTagEntry )
|
|
{
|
|
MEMBUF *pmembuf = (MEMBUF *)rgbBuffer;
|
|
MEMBUFTAG *rgbTags;
|
|
|
|
MEMAssertMemBuf( pmembuf ); // Validate integrity of string buffer.
|
|
MEMAssertMemBufTag( pmembuf, iTagEntry ); // Validate integrity of itag.
|
|
|
|
rgbTags = (MEMBUFTAG *)pmembuf->pbuf;
|
|
|
|
return pmembuf->pbuf + rgbTags[iTagEntry].ib;
|
|
}
|
|
|
|
|
|
INLINE STATIC ULONG CbMEMGet( BYTE *rgbBuffer, ULONG iTagEntry )
|
|
{
|
|
MEMBUF *pmembuf = (MEMBUF *)rgbBuffer;
|
|
MEMBUFTAG *rgbTags;
|
|
|
|
MEMAssertMemBuf( pmembuf ); // Validate integrity of string buffer.
|
|
MEMAssertMemBufTag( pmembuf, iTagEntry ); // Validate integrity of itag.
|
|
|
|
rgbTags = (MEMBUFTAG *)pmembuf->pbuf;
|
|
|
|
return rgbTags[iTagEntry].cb;
|
|
}
|
|
|