2025-04-27 07:49:33 -04:00

2666 lines
79 KiB
C
Raw Permalink Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#include "config.h"
#include <stdlib.h>
#include <string.h>
#include "daedef.h"
#include "pib.h"
#include "ssib.h"
#include "util.h"
#include "page.h"
#include "fcb.h"
#include "fucb.h"
#include "stapi.h"
#include "fdb.h"
#include "dirapi.h"
#include "spaceapi.h"
#include "idb.h"
#include "recapi.h"
#include "fileapi.h"
#include "recint.h"
#include "fileint.h"
#include "fmp.h"
#include "info.h"
#include "dbapi.h"
#include "systab.h"
#include "stats.h"
#include "nver.h"
DeclAssertFile; /* Declare file name for assert macros */
extern CDESC * __near rgcdescSc;
/* Local data types */
typedef struct /* returned by FidLookupColumn */
{
JET_COLTYP coltyp;
JET_COLUMNID columnid;
JET_GRBIT grbit;
unsigned long cb;
char szName[ ( JET_cbNameMost + 1 ) ];
} COLINFO;
#ifdef SYSTABLES
/* Static data for ErrIsamGetObjectInfo */
CODECONST( JET_COLUMNDEF ) rgcolumndefGetObjects[] =
{
{ sizeof(JET_COLUMNDEF), 0, JET_coltypText, 0, 0, 0, 0, 0, JET_bitColumnTTKey },
{ sizeof(JET_COLUMNDEF), 0, JET_coltypText, 0, 0, 0, 0, 0, JET_bitColumnTTKey },
{ sizeof(JET_COLUMNDEF), 0, JET_coltypLong, 0, 0, 0, 0, 0, JET_bitColumnFixed },
{ sizeof(JET_COLUMNDEF), 0, JET_coltypDateTime, 0, 0, 0, 0, 0, JET_bitColumnFixed },
{ sizeof(JET_COLUMNDEF), 0, JET_coltypDateTime, 0, 0, 0, 0, 0, JET_bitColumnFixed },
{ sizeof(JET_COLUMNDEF), 0, JET_coltypLong, 0, 0, 0, 0, 0, JET_bitColumnFixed },
{ sizeof(JET_COLUMNDEF), 0, JET_coltypLong, 0, 0, 0, 0, 0, JET_bitColumnFixed },
{ sizeof(JET_COLUMNDEF), 0, JET_coltypLong, 0, 0, 0, 0, 0, JET_bitColumnFixed },
{ sizeof(JET_COLUMNDEF), 0, JET_coltypLong, 0, 0, 0, 0, 0, JET_bitColumnFixed }
};
#define ccolumndefGetObjectsMax \
( sizeof( rgcolumndefGetObjects ) / sizeof( JET_COLUMNDEF ) )
/* column indexes for rgcolumndefGetObjects */
#define iContainerName 0
#define iObjectName 1
#define iObjectType 2
#define iDtCreate 3
#define iDtUpdate 4
#define iCRecord 5
#define iCPage 6
#define iGrbit 7
#define iFlags 8
CODECONST(JET_COLUMNDEF) rgcolumndefObjectAcm[] =
{
/* SID */
{ sizeof(JET_COLUMNDEF), 0, JET_coltypBinary, 0, 0, 0, 0, 0, JET_bitColumnTTKey },
/* ACM */
{ sizeof(JET_COLUMNDEF), 0, JET_coltypLong, 0, 0, 0, 0, 0, JET_bitColumnFixed },
/* grbit */
{ sizeof(JET_COLUMNDEF), 0, JET_coltypLong, 0, 0, 0, 0, 0, JET_bitColumnFixed }
};
/* column indexes for rgcolumndefObjectAcm */
#define iAcmSid 0
#define iAcmAcm 1
#define iAcmGrbit 2
#define ccolumndefObjectAcmMax \
( sizeof( rgcolumndefObjectAcm ) / sizeof( JET_COLUMNDEF ) )
#endif /* SYSTABLES */
/* Static data for ErrIsamGetColumnInfo */
CODECONST( JET_COLUMNDEF ) rgcolumndefGetColumns[] =
{
{ sizeof(JET_COLUMNDEF), 0, JET_coltypLong, 0, 0, 0, 0, 0, JET_bitColumnTTKey },
{ sizeof(JET_COLUMNDEF), 0, JET_coltypText, 0, 0, 0, 0, 0, JET_bitColumnTTKey },
{ sizeof(JET_COLUMNDEF), 0, JET_coltypLong, 0, 0, 0, 0, 0, JET_bitColumnFixed },
{ sizeof(JET_COLUMNDEF), 0, JET_coltypLong, 0, 0, 0, 0, 0, JET_bitColumnFixed },
{ sizeof(JET_COLUMNDEF), 0, JET_coltypShort, 0, 0, 0, 0, 0, JET_bitColumnFixed },
{ sizeof(JET_COLUMNDEF), 0, JET_coltypShort, 0, 0, 0, 0, 0, JET_bitColumnFixed },
{ sizeof(JET_COLUMNDEF), 0, JET_coltypShort, 0, 0, 0, 0, 0, JET_bitColumnFixed },
{ sizeof(JET_COLUMNDEF), 0, JET_coltypShort, 0, 0, 0, 0, 0, JET_bitColumnFixed },
{ sizeof(JET_COLUMNDEF), 0, JET_coltypLong, 0, 0, 0, 0, 0, JET_bitColumnFixed },
{ sizeof(JET_COLUMNDEF), 0, JET_coltypLong, 0, 0, 0, 0, 0, JET_bitColumnFixed },
{ sizeof(JET_COLUMNDEF), 0, JET_coltypBinary, 0, 0, 0, 0, 0, 0 },
{ sizeof(JET_COLUMNDEF), 0, JET_coltypText, 0, 0, 0, 0, 0, 0 },
{ sizeof(JET_COLUMNDEF), 0, JET_coltypText, 0, 0, 0, 0, 0, 0 }
};
#define ccolumndefGetColumnsMax \
( sizeof( rgcolumndefGetColumns ) / sizeof( JET_COLUMNDEF ) )
#define iColumnPOrder 0
#define iColumnName 1
#define iColumnId 2
#define iColumnType 3
#define iColumnCountry 4
#define iColumnLangid 5
#define iColumnCp 6
#define iColumnCollate 7
#define iColumnSize 8
#define iColumnGrbit 9
#define iColumnDefault 10
#define iColumnTableName 11
#define iColumnColumnName 12
/* Static data for ErrIsamGetIndexInfo */
CODECONST( JET_COLUMNDEF ) rgcolumndefGetIndex[] =
{
{ sizeof(JET_COLUMNDEF), 0, JET_coltypText, 0, 0, 0, 0, 0, JET_bitColumnTTKey },
{ sizeof(JET_COLUMNDEF), 0, JET_coltypLong, 0, 0, 0, 0, 0, JET_bitColumnFixed },
{ sizeof(JET_COLUMNDEF), 0, JET_coltypLong, 0, 0, 0, 0, 0, JET_bitColumnFixed },
{ sizeof(JET_COLUMNDEF), 0, JET_coltypLong, 0, 0, 0, 0, 0, JET_bitColumnFixed },
{ sizeof(JET_COLUMNDEF), 0, JET_coltypLong, 0, 0, 0, 0, 0, JET_bitColumnFixed },
{ sizeof(JET_COLUMNDEF), 0, JET_coltypLong, 0, 0, 0, 0, 0, JET_bitColumnFixed },
{ sizeof(JET_COLUMNDEF), 0, JET_coltypLong, 0, 0, 0, 0, 0, JET_bitColumnFixed | JET_bitColumnTTKey },
{ sizeof(JET_COLUMNDEF), 0, JET_coltypLong, 0, 0, 0, 0, 0, JET_bitColumnFixed },
{ sizeof(JET_COLUMNDEF), 0, JET_coltypLong, 0, 0, 0, 0, 0, JET_bitColumnFixed },
{ sizeof(JET_COLUMNDEF), 0, JET_coltypShort, 0, 0, 0, 0, 0, JET_bitColumnFixed },
{ sizeof(JET_COLUMNDEF), 0, JET_coltypShort, 0, 0, 0, 0, 0, JET_bitColumnFixed },
{ sizeof(JET_COLUMNDEF), 0, JET_coltypShort, 0, 0, 0, 0, 0, JET_bitColumnFixed },
{ sizeof(JET_COLUMNDEF), 0, JET_coltypShort, 0, 0, 0, 0, 0, JET_bitColumnFixed },
{ sizeof(JET_COLUMNDEF), 0, JET_coltypLong, 0, 0, 0, 0, 0, JET_bitColumnFixed },
{ sizeof(JET_COLUMNDEF), 0, JET_coltypText, 0, 0, 0, 0, 0, 0 }
};
#define ccolumndefGetIndexMax ( sizeof( rgcolumndefGetIndex ) / sizeof( JET_COLUMNDEF ) )
#define iIndexName 0
#define iIndexGrbit 1
#define iIndexCKey 2
#define iIndexCEntry 3
#define iIndexCPage 4
#define iIndexCCol 5
#define iIndexICol 6
#define iIndexColId 7
#define iIndexColType 8
#define iIndexCountry 9
#define iIndexLangid 10
#define iIndexCp 11
#define iIndexCollate 12
#define iIndexColBits 13
#define iIndexColName 14
/* #ifdef DISPATCHING
ERR VDBAPI ErrIsamOpenTempTable(
JET_SESID sesid,
JET_COLUMNDEF *rgcolumndef,
unsigned long ccolumndef,
JET_GRBIT grbit,
JET_TABLEID *ptableid,
JET_COLUMNID *rgcolumnid );
#endif */ /* DISPATCHING */
/* Internal function prototypes
/**/
FID FidLookupColumn( FUCB * pfucb, FID fid, char * szColumnName, COLINFO * pcolinfo );
LOCAL ERR ErrGetObjectPermissions(
PIB *ppib,
DBID dbid,
OBJID objidCtr,
const char *szObjectName,
OUTLINE *pout);
#ifdef SYSTABLES
LOCAL ERR ErrInfoGetObjectInfo0(
PIB *ppib,
FUCB *pfucbMSO,
OBJID objidCtr,
JET_OBJTYP objtyp,
char *szContainerName,
char *szObjectName,
OUTLINE *pout );
LOCAL ERR ErrInfoGetObjectInfo12(
PIB *ppib,
FUCB *pfucbMSO,
OBJID objidCtr,
JET_OBJTYP objtyp,
char *szContainerName,
char *szObjectName,
OUTLINE *pout,
long lInfoLevel );
LOCAL ERR ErrInfoGetObjectInfo3(
PIB *ppib,
FUCB *pfucbMSO,
OBJID objidCtr,
JET_OBJTYP objtyp,
char *szContainerName,
char *szObjectName,
OUTLINE *pout,
BOOL fReadOnly );
#endif /* SYSTABLES */
LOCAL ERR ErrInfoGetTableColumnInfo0( PIB *ppib, FUCB *pfucb,
CHAR *szColumnName, OUTLINE *pout );
LOCAL ERR ErrInfoGetTableColumnInfo1( PIB *ppib, FUCB *pfucb,
CHAR *szColumnName, OUTLINE *pout );
LOCAL ERR ErrInfoGetTableColumnInfo3( PIB *ppib, FUCB *pfucb, CHAR *szColumnName, OUTLINE *pout );
LOCAL ERR ErrInfoGetTableColumnInfo4( PIB *ppib, FUCB *pfucb,
CHAR *szColumnName, OUTLINE *pout );
LOCAL ERR ErrInfoGetTableIndexInfo01( PIB *ppib, FUCB *pfucb,
CHAR *szIndexName, OUTLINE *pout, LONG lInfoLevel );
LOCAL ERR ErrInfoGetTableIndexInfo2( PIB *ppib, FUCB *pfucb,
CHAR *szIndexName, OUTLINE *pout );
/*=================================================================
ErrIsamGetObjectInfo
Description: Returns information about all objects or a specified object
Parameters: ppib pointer to PIB for current session
dbid database id containing objects
objtyp type of object or objtypNil for all objects
szContainer container name or NULL for all objects
szObjectName object name or NULL for all objects
pout output buffer
lInfoLevel level of information ( 0, 1, or 2 )
Return Value: JET_errSuccess if the oubput buffer is valid
Errors/Warnings:
Side Effects:
=================================================================*/
ERR VDBAPI ErrIsamGetObjectInfo(
JET_VSESID vsesid, /* pointer to PIB for current session */
JET_DBID vdbid, /* database id containing objects */
JET_OBJTYP objtyp, /* type of object or objtypNil for all */
const char *szContainer, /* container name or NULL for all */
const char *szObject, /* object name or NULL for all */
OLD_OUTDATA *poutdata, /* output buffer */
unsigned long lInfoLevel ) /* information level */
{
PIB *ppib = (PIB *) vsesid;
OUTLINE *pout = (OUTLINE *) poutdata;
#ifdef SYSTABLES
ERR err;
DBID dbid = DbidOfVDbid( vdbid );
FUCB *pfucbMSO;
CHAR szContainerName[( JET_cbNameMost + 1 )];
CHAR szObjectName[( JET_cbNameMost + 1 )];
OBJID objidCtr;
ULONG cbActual;
JET_COLUMNID columnidObjectId;
CheckPIB( ppib );
CheckDBID( ppib, ( DBID )dbid );
if ( szContainer == NULL || *szContainer == '\0' )
*szContainerName = '\0';
else
CallR( ErrCheckName( szContainerName, szContainer, ( JET_cbNameMost + 1 ) ) );
if ( szObject == NULL || *szObject == '\0' )
*szObjectName = '\0';
else
CallR( ErrCheckName( szObjectName, szObject, ( JET_cbNameMost + 1 ) ) );
/* check for invalid information level
/**/
switch( lInfoLevel )
{
case JET_ObjInfo:
case JET_ObjInfoListNoStats:
case JET_ObjInfoList:
case JET_ObjInfoSysTabCursor:
case JET_ObjInfoListACM:
case JET_ObjInfoNoStats:
case JET_ObjInfoSysTabReadOnly:
case JET_ObjInfoRulesLoaded:
break;
default:
return JET_errInvalidParameter;
}
/* MSysObjects will be accessed directly or scanned for all object info
/**/
CallR( ErrFILEOpenTable( ppib, dbid, &pfucbMSO, szSoTable, 0 ) );
if ( lInfoLevel == JET_ObjInfo
|| lInfoLevel == JET_ObjInfoListNoStats
|| lInfoLevel == JET_ObjInfoList
|| FVDbidReadOnly( vdbid ) )
FUCBResetUpdatable( pfucbMSO );
Call( ErrFILEGetColumnId( ppib, pfucbMSO, szSoIdColumn, &columnidObjectId ) );
/* use the object name index for both direct access and scanning
/**/
Call( ErrIsamSetCurrentIndex( ppib, pfucbMSO, szSoNameIndex ) );
/* get the object id for the specified container
/**/
objidCtr = objidRoot;
if ( szContainerName != NULL && *szContainerName != '\0' )
{
Call( ErrIsamMakeKey( ppib, pfucbMSO, (void *)&objidCtr, sizeof( objidCtr ), JET_bitNewKey ) );
Call( ErrIsamMakeKey( ppib, pfucbMSO, szContainerName, strlen( szContainerName ), 0 ) );
err = ErrIsamSeek( ppib, pfucbMSO, JET_bitSeekEQ );
if ( err < 0 )
{
if ( err == JET_errRecordNotFound )
err = JET_errObjectNotFound;
goto HandleError;
}
/* retrieve the container object id
/**/
Call( ErrIsamRetrieveColumn( ppib, pfucbMSO, columnidObjectId,
(BYTE *)&objidCtr, sizeof( objidCtr ), &cbActual, 0, NULL ) );
Assert( objidCtr != objidNil );
}
switch ( lInfoLevel )
{
case JET_ObjInfoNoStats:
case JET_ObjInfo:
err = ErrInfoGetObjectInfo0(
ppib,
pfucbMSO,
objidCtr,
objtyp,
szContainerName,
szObjectName,
pout );
break;
case JET_ObjInfoListNoStats:
case JET_ObjInfoList:
err = ErrInfoGetObjectInfo12(
ppib,
pfucbMSO,
objidCtr,
objtyp,
szContainerName,
szObjectName,
pout,
lInfoLevel );
break;
case JET_ObjInfoSysTabCursor:
case JET_ObjInfoSysTabReadOnly:
err = ErrInfoGetObjectInfo3(
ppib,
pfucbMSO,
objidCtr,
objtyp,
szContainerName,
szObjectName,
pout,
FVDbidReadOnly( vdbid ) );
break;
case JET_ObjInfoListACM:
err = ErrGetObjectPermissions(
ppib,
dbid,
objidCtr,
szObjectName,
pout );
break;
default:
Assert( lInfoLevel == JET_ObjInfoRulesLoaded );
// UNDONE: implement this
// err = ErrINFOGetRuleStatus( ppib, dbid, objidCtr, szObjectName );
err = JET_wrnNyi;
break;
}
HandleError:
CallS( ErrFILECloseTable( ppib, pfucbMSO ) );
return err;
#else /* !SYSTABLES */
return JET_errFeatureNotAvailable;
#endif /* !SYSTABLES */
}
#ifdef SYSTABLES
LOCAL ERR ErrInfoGetObjectInfo0(
PIB *ppib,
FUCB *pfucbMSO,
OBJID objidCtr,
JET_OBJTYP objtyp,
char *szContainerName,
char *szObjectName,
OUTLINE *pout )
{
ERR err;
BYTE *pb;
ULONG cbMax;
ULONG cbActual;
JET_COLUMNID columnidParentId; /* columnid for ParentId column in MSysObjects */
JET_COLUMNID columnidObjectName; /* columnid for Name column in MSysObjects */
JET_COLUMNID columnidObjectType; /* columnid for Type column in MSysObjects */
JET_COLUMNID columnidObjectId; /* columnid for Id column in MSysObjects */
JET_COLUMNID columnidCreate; /* columnid for DateCreate column in MSysObjects */
JET_COLUMNID columnidUpdate; /* columnid for DateUpdate column in MSysObjects */
JET_COLUMNID columnidFlags; /* columnid for Flags column in MSysObjects */
OBJTYP objtypObject;
pout->cbReturned = 0;
/* get columnids
/**/
Call( ErrFILEGetColumnId( ppib, pfucbMSO, szSoParentIdColumn, &columnidParentId ) );
Call( ErrFILEGetColumnId( ppib, pfucbMSO, szSoObjectNameColumn, &columnidObjectName ) );
Call( ErrFILEGetColumnId( ppib, pfucbMSO, szSoObjectTypeColumn, &columnidObjectType ) );
Call( ErrFILEGetColumnId( ppib, pfucbMSO, szSoIdColumn, &columnidObjectId ) );
Call( ErrFILEGetColumnId( ppib, pfucbMSO, szSoDateCreateColumn, &columnidCreate ) );
Call( ErrFILEGetColumnId( ppib, pfucbMSO, szSoDateUpdateColumn, &columnidUpdate ) );
Call( ErrFILEGetColumnId( ppib, pfucbMSO, szSoFlagsColumn, &columnidFlags ) );
/* use the object name index for both direct access and scanning
/**/
Call( ErrIsamSetCurrentIndex( ppib, pfucbMSO, szSoNameIndex ) );
/* return error if the output buffer is too small
/**/
if ( pout->cbMax < sizeof(JET_OBJECTINFO) )
{
return JET_errInvalidParameter;
}
/* seek to key ( ParentId = container id, Name = object name )
/**/
Call( ErrIsamMakeKey( ppib, pfucbMSO, (void *)&objidCtr, sizeof( objidCtr ), JET_bitNewKey ) );
Call( ErrIsamMakeKey( ppib, pfucbMSO, szObjectName, strlen( szObjectName ), 0 ) );
Call( ErrIsamSeek( ppib, pfucbMSO, JET_bitSeekEQ ) );
/* set cbStruct
/**/
((JET_OBJECTINFO *)pout->pb)->cbStruct = sizeof(JET_OBJECTINFO);
/* set output data
/**/
pb = (BYTE *)&objtypObject;
cbMax = sizeof(objtypObject);
Call( ErrIsamRetrieveColumn( ppib, pfucbMSO, columnidObjectType, pb, cbMax, &cbActual, 0, NULL ) );
*((JET_OBJTYP *)&(((JET_OBJECTINFO *)pout->pb)->objtyp)) = (JET_OBJTYP)objtypObject;
cbMax = sizeof(JET_DATESERIAL);
pb = (void *)&( ( JET_OBJECTINFO *)pout->pb )->dtCreate;
Call( ErrIsamRetrieveColumn( ppib, pfucbMSO, columnidCreate, pb, cbMax, &cbActual, 0, NULL ) );
pb = (void *)&( ( JET_OBJECTINFO *)pout->pb )->dtUpdate;
cbMax = sizeof(JET_DATESERIAL);
Call( ErrIsamRetrieveColumn( ppib, pfucbMSO, columnidUpdate, pb, cbMax,
&cbActual, 0, NULL ) );
pb = (void *)&( ( JET_OBJECTINFO *)pout->pb )->flags;
cbMax = sizeof(ULONG);
Call( ErrIsamRetrieveColumn( ppib, pfucbMSO, columnidFlags, pb, cbMax,
&cbActual, 0, NULL ) );
if ( cbActual == 0 )
( ( JET_OBJECTINFO *) pout->pb )->flags = 0;
/* set stats
/**/
if ( (JET_OBJTYP)objtypObject == JET_objtypTable )
{
Call( ErrSTATSRetrieveTableStats( ppib, pfucbMSO->dbid, szObjectName,
&((JET_OBJECTINFO *)pout->pb)->cRecord,
NULL,
&((JET_OBJECTINFO *)pout->pb)->cPage ) );
}
else
{
((JET_OBJECTINFO *)pout->pb )->cRecord = 0;
((JET_OBJECTINFO *)pout->pb )->cPage = 0;
}
// UNDONE: check this
((JET_OBJECTINFO *)pout->pb )->grbit = 0;
pout->cbActual = sizeof(JET_OBJECTINFO);
pout->cbReturned = sizeof(JET_OBJECTINFO);
err = JET_errSuccess;
HandleError:
if ( err == JET_errRecordNotFound )
err = JET_errObjectNotFound;
return err;
}
LOCAL ERR ErrInfoGetObjectInfo12(
PIB *ppib,
FUCB *pfucbMSO,
OBJID objidCtr,
JET_OBJTYP objtyp,
char *szContainerName,
char *szObjectName,
OUTLINE *pout,
long lInfoLevel )
{
#ifdef DISPATCHING
ERR err;
OUTLINE outline;
LINE line;
JET_COLUMNID columnidParentId; /* columnid for ParentId col in MSysObjects */
JET_COLUMNID columnidObjectName; /* columnid for Name column in MSysObjects */
JET_COLUMNID columnidObjectType; /* columnid for Type column in MSysObjects */
JET_COLUMNID columnidObjectId; /* columnid for Id column in MSysObjects */
JET_COLUMNID columnidCreate; /* columnid for DateCreate in MSysObjects */
JET_COLUMNID columnidUpdate; /* columnid for DateUpdate in MSysObjects */
JET_COLUMNID columnidFlags; /* columnid for Flags column in MSysObjects */
char szCtrName[( JET_cbNameMost + 1 )];
char szObjectNameCurrent[( JET_cbNameMost + 1 )+1];
JET_TABLEID tableid;
JET_COLUMNID rgcolumnid[ccolumndefGetObjectsMax];
JET_OBJTYP objtypObject; /* type of current object */
long cRows = 0; /* count of objects found */
long cRecord = 0; /* count of records in table */
long cPage = 0; /* count of pages in table */
BYTE *pbContainerName;
ULONG cbContainerName;
BYTE *pbObjectName;
ULONG cbObjectName;
BYTE *pbObjectType;
ULONG cbObjectType;
BYTE *pbDtCreate;
ULONG cbDtCreate;
BYTE *pbDtUpdate;
ULONG cbDtUpdate;
BYTE *pbCRecord;
ULONG cbCRecord;
BYTE *pbCPage;
ULONG cbCPage;
BYTE *pbFlags;
ULONG cbFlags;
JET_GRBIT grbit;
BYTE *pbGrbit;
ULONG cbGrbit;
pout->cbReturned = 0;
/* get columnids
/**/
CallR( ErrFILEGetColumnId( ppib, pfucbMSO, szSoParentIdColumn, &columnidParentId ) );
CallR( ErrFILEGetColumnId( ppib, pfucbMSO, szSoObjectNameColumn, &columnidObjectName ) );
CallR( ErrFILEGetColumnId( ppib, pfucbMSO, szSoObjectTypeColumn, &columnidObjectType ) );
CallR( ErrFILEGetColumnId( ppib, pfucbMSO, szSoIdColumn, &columnidObjectId ) );
CallR( ErrFILEGetColumnId( ppib, pfucbMSO, szSoDateCreateColumn, &columnidCreate ) );
CallR( ErrFILEGetColumnId( ppib, pfucbMSO, szSoDateUpdateColumn, &columnidUpdate ) );
CallR( ErrFILEGetColumnId( ppib, pfucbMSO, szSoFlagsColumn, &columnidFlags ) );
/* Use the object name index for both direct access and scanning */
CallR( ErrIsamSetCurrentIndex( ppib, pfucbMSO, szSoNameIndex ) );
/* Quit if the output buffer is too small */
if ( pout->cbMax < sizeof(JET_OBJECTLIST) )
{
return JET_errInvalidParameter;
}
pbCRecord = (BYTE *)&cRecord;
cbCRecord = sizeof( cRecord );
pbCPage = (BYTE *) &cPage;
cbCPage = sizeof( cPage );
pbObjectType = (BYTE *)&objtypObject;
cbObjectType = sizeof( objtypObject );
pbContainerName = szContainerName;
if ( szContainerName == NULL || *szContainerName == '\0' )
cbContainerName = 0;
else
cbContainerName = strlen( szContainerName );
/* Open the temporary table which will be returned to the caller
/**/
CallR( ErrIsamOpenTempTable( (JET_SESID)ppib,
(JET_COLUMNDEF *) rgcolumndefGetObjects,
ccolumndefGetObjectsMax, JET_bitTTScrollable | JET_bitTTScrollable,
&tableid, rgcolumnid ) );
/* Position to the record for the first object */
if ( szContainerName == NULL || *szContainerName == '\0' )
{
/* If container not specified, then use first record in table */
Call( ErrIsamMove( ppib, pfucbMSO, JET_MoveFirst, 0 ) );
}
else
{
/* move the first record for an object in the container
/**/
Call( ErrIsamMakeKey( ppib, pfucbMSO, (void *)&objidCtr,
sizeof( objidCtr ), JET_bitNewKey ) );
Call( ErrIsamSeek( ppib, pfucbMSO, JET_bitSeekGE ) );
}
do
{
/* get pointer to the object type
/**/
Call( ErrRECIRetrieve( pfucbMSO, (FID *)&columnidObjectType, 0, &line, 0 ) );
/* set objtypObject from line retrieval.
/**/
objtypObject = (JET_OBJTYP)(*(UNALIGNED OBJTYP *)line.pb);
/* get pointer to the ParentId ( container id )
/**/
Call( ErrRECIRetrieve( pfucbMSO, (FID *)&columnidParentId, 0, &line, 0 ) );
/* done if container specified and object isn't in it
/**/
if ( szContainerName != NULL && *szContainerName != '\0' && objidCtr != *(UNALIGNED OBJID *)line.pb )
goto ResetTempTblCursor;
Assert( objidCtr == objidRoot || objidCtr == *(UNALIGNED OBJID *)line.pb );
/* if desired object type and container
/**/
if ( objtyp == JET_objtypNil || objtyp == objtypObject )
{
/* get the container name
/**/
if ( *(UNALIGNED OBJID *)line.pb == objidRoot )
{
pbContainerName = NULL;
cbContainerName = 0;
}
else
{
outline.pb = szCtrName;
outline.cbMax = sizeof( szCtrName );
Call( ErrFindNameFromObjid( ppib, pfucbMSO->dbid, *(UNALIGNED OBJID *)line.pb, &outline ) );
/* save pointers to the container name
/**/
pbContainerName = outline.pb;
Assert( outline.cbActual <= outline.cbMax );
cbContainerName = outline.cbActual;
}
/* get pointer to the object name
/**/
Call( ErrRECIRetrieve( pfucbMSO, (FID *)&columnidObjectName, 0, &line, 0 ) );
pbObjectName = line.pb;
cbObjectName = line.cb;
/* get pointer to the object creation date
/**/
Call( ErrRECIRetrieve( pfucbMSO, (FID *)&columnidCreate, 0, &line, 0 ) );
pbDtCreate = line.pb;
cbDtCreate = line.cb;
/* get pointer to the last update date
/**/
Call( ErrRECIRetrieve( pfucbMSO, (FID *)&columnidUpdate, 0, &line, 0 ) );
pbDtUpdate = line.pb;
cbDtUpdate = line.cb;
/* get pointer to the last update date
/**/
Call( ErrRECIRetrieve( pfucbMSO, (FID *)&columnidFlags, 0, &line, 0 ) );
pbFlags = line.pb;
cbFlags = line.cb;
/* get pointer to the last update date
/**/
grbit = 0;
pbGrbit = (BYTE *)&grbit;
cbGrbit = sizeof(JET_GRBIT);
/* get statistics if requested and if object is table
/**/
Assert( lInfoLevel == JET_ObjInfoList ||
lInfoLevel == JET_ObjInfoListNoStats );
if ( lInfoLevel == JET_ObjInfoList && objtypObject == JET_objtypTable )
{
/* terminate the name
/**/
memcpy( szObjectNameCurrent, pbObjectName, ( size_t )cbObjectName );
szObjectNameCurrent[cbObjectName] = '\0';
Call( ErrSTATSRetrieveTableStats( ppib,
pfucbMSO->dbid,
szObjectNameCurrent,
&cRecord,
NULL,
&cPage ) );
}
/* add the current object info to the temporary table
/**/
Call( ErrDispPrepareUpdate( (JET_SESID)ppib, tableid, JET_prepInsert ) );
Call( ErrDispSetColumn( (JET_SESID)ppib, tableid,
rgcolumnid[iContainerName], pbContainerName,
cbContainerName, 0, NULL ) );
Call( ErrDispSetColumn( (JET_SESID)ppib, tableid,
rgcolumnid[iObjectName], pbObjectName,
cbObjectName, 0, NULL ) );
Call( ErrDispSetColumn( (JET_SESID)ppib, tableid,
rgcolumnid[iObjectType], pbObjectType,
cbObjectType, 0, NULL ) );
Call( ErrDispSetColumn( (JET_SESID)ppib, tableid,
rgcolumnid[iDtCreate], pbDtCreate,
cbDtCreate, 0, NULL ) );
Call( ErrDispSetColumn( (JET_SESID)ppib, tableid,
rgcolumnid[iDtUpdate], pbDtUpdate,
cbDtUpdate, 0, NULL ) );
Call( ErrDispSetColumn( (JET_SESID)ppib, tableid,
rgcolumnid[iCRecord], pbCRecord,
cbCRecord, 0, NULL ) );
Call( ErrDispSetColumn( (JET_SESID)ppib, tableid,
rgcolumnid[iCPage], pbCPage, cbCPage, 0, NULL ) );
Call( ErrDispSetColumn( (JET_SESID)ppib, tableid,
rgcolumnid[iFlags], pbFlags, cbFlags, 0, NULL ) );
Call( ErrDispSetColumn( (JET_SESID)ppib, tableid,
rgcolumnid[iGrbit], pbGrbit, cbGrbit, 0, NULL ) );
Call( ErrDispUpdate( (JET_SESID)ppib, tableid, NULL, 0, NULL ) );
/* set the number of objects found
/**/
cRows++;
}
/* move to the next record
/**/
err = ErrIsamMove( ppib, pfucbMSO, JET_MoveNext, 0 );
} while ( err >= 0 );
/* return if error other than end of range
/**/
if ( err != JET_errNoCurrentRecord )
goto HandleError;
ResetTempTblCursor:
/* move to first record in the temporary table
/**/
err = ErrDispMove( (JET_SESID)ppib, tableid, JET_MoveFirst, 0 );
if ( err < 0 )
{
if ( err != JET_errNoCurrentRecord )
goto HandleError;
err = JET_errSuccess;
}
/* set the return structure
/**/
((JET_OBJECTLIST *)pout->pb)->cbStruct = sizeof(JET_OBJECTLIST);
((JET_OBJECTLIST *)pout->pb)->tableid = tableid;
((JET_OBJECTLIST *)pout->pb)->cRecord = cRows;
((JET_OBJECTLIST *)pout->pb)->columnidcontainername = rgcolumnid[iContainerName];
((JET_OBJECTLIST *)pout->pb)->columnidobjectname = rgcolumnid[iObjectName];
((JET_OBJECTLIST *)pout->pb)->columnidobjtyp = rgcolumnid[iObjectType];
((JET_OBJECTLIST *)pout->pb)->columniddtCreate = rgcolumnid[iDtCreate];
((JET_OBJECTLIST *)pout->pb)->columniddtUpdate = rgcolumnid[iDtUpdate];
((JET_OBJECTLIST *)pout->pb)->columnidgrbit = rgcolumnid[iGrbit];
((JET_OBJECTLIST *)pout->pb)->columnidflags = rgcolumnid[iFlags];
((JET_OBJECTLIST *)pout->pb)->columnidcRecord = rgcolumnid[iCRecord];
((JET_OBJECTLIST *)pout->pb)->columnidcPage = rgcolumnid[iCPage];
pout->cbActual = sizeof(JET_OBJECTLIST);
pout->cbReturned = sizeof(JET_OBJECTLIST);
return JET_errSuccess;
HandleError:
(VOID)ErrDispCloseTable( (JET_SESID)ppib, tableid );
if ( err == JET_errRecordNotFound )
err = JET_errObjectNotFound;
return err;
#else /* !DISPATCHING */
return JET_errFeatureNotAvailable;
#endif /* !DISPATCHING */
}
LOCAL ERR ErrInfoGetObjectInfo3(
PIB *ppib,
FUCB *pfucbMSO,
OBJID objidCtr,
JET_OBJTYP objtyp,
char *szContainerName,
char *szObjectName,
OUTLINE *pout,
BOOL fReadOnly )
{
ERR err;
FUCB *pfucb;
#ifdef DISPATCHING
JET_TABLEID tableid;
#endif /* DISPATCHING */
if ( pout == NULL || pout->cbMax < sizeof(JET_TABLEID) )
return JET_errInvalidParameter;
CallR( ErrFILEOpenTable( ppib, pfucbMSO->dbid, &pfucb, szSoTable, 0 ) );
if ( fReadOnly )
FUCBResetUpdatable( pfucb );
Call( ErrIsamSetCurrentIndex( ppib, pfucb, szSoNameIndex ) );
Call( ErrIsamMakeKey( ppib, pfucb, (void *)&objidCtr, sizeof( objidCtr ), JET_bitNewKey ) );
Call( ErrIsamMakeKey( ppib, pfucb, szObjectName, strlen( szObjectName ), 0 ) );
Call( ErrIsamSeek( ppib, pfucb, JET_bitSeekEQ ) );
FUCBSetSystemTable( pfucb );
#ifdef DISPATCHING
Call( ErrAllocateTableid( &tableid, (JET_VTID)pfucb, &vtfndefIsamInfo ) );
pfucb->fVtid = fTrue;
*(JET_TABLEID *)(pout->pb) = tableid;
pout->cbReturned = sizeof(tableid);
pout->cbActual = sizeof(tableid);
#else /* !DISPATCHING */
*(FUCB **)(pout->pb) = pfucb;
pout->cbReturned = sizeof(pfucb);
pout->cbActual = sizeof(pfucb);
#endif /* !DISPATCHING */
return JET_errSuccess;
HandleError:
if ( err == JET_errRecordNotFound )
err = JET_errObjectNotFound;
CallS( ErrFILECloseTable( ppib, pfucb ) );
return err;
}
LOCAL ERR ErrGetObjectPermissions(
PIB *ppib,
DBID dbid,
OBJID objidCtr,
const char *szObjectName,
OUTLINE *pout)
{
#ifdef DISPATCHING
#ifdef SEC
ERR err; /* error codes from internal functions */
LINE line; /* general purpose usage */
OBJID objid; /* object id of object */
JET_OBJTYP objtyp; /* object type of object */
JET_COLUMNID columnidSid; /* columnid for SID column in MSysACEs */
JET_COLUMNID columnidFInheritable; /* columnid for FInheritable column in MSysACEs */
JET_COLUMNID columnidAcm; /* columnid for ACM in MSysACEs */
JET_TABLEID tableid;
JET_COLUMNID rgcolumnid[ccolumndefObjectAcmMax];
long cRows = 0; /* count of objects found */
BYTE *pbAcm;
ULONG cbAcm;
BYTE *pbSid;
ULONG cbSid;
FUCB *pfucbMSA;
pout->cbReturned = 0;
/* open MSysACEs and set object name index
/**/
CallR( ErrFILEOpenTable ( ppib, dbid, &pfucbMSA, szSpTable, 0 ) );
CallJ( ErrIsamSetCurrentIndex( ppib, pfucbMSA, szSpObjectIdIndex ), HandleError1 );
/* get columnids
/**/
CallJ( ErrFILEGetColumnId( ppib, pfucbMSA, szSpSidColumn, &columnidSid ), HandleError1 );
CallJ( ErrFILEGetColumnId( ppib, pfucbMSA, szSpAcmColumn, &columnidAcm ), HandleError1 );
CallJ( ErrFILEGetColumnId( ppib, pfucbMSA, szSpFInheritableColumn, &columnidFInheritable ), HandleError1 );
/* get object id from object name
/**/
CallJ( ErrFindObjidFromIdName( ppib, dbid, objidCtr, szObjectName, &objid, &objtyp ), HandleError1 );
/* quit if the output buffer is too small
/**/
if ( pout->cbMax < sizeof(JET_OBJECTACMLIST) )
{
return JET_errInvalidParameter;
}
/* open the temporary table which will be returned to the caller
/**/
CallJ( ErrIsamOpenTempTable( (JET_SESID)ppib,
(JET_COLUMNDEF *) rgcolumndefObjectAcm,
ccolumndefObjectAcmMax,
JET_bitTTScrollable | JET_bitTTScrollable,
&tableid,
rgcolumnid ),
HandleError1 );
/* Move the first record for the object
/* set range of index to be all objects in this container
/**/
Call( ErrIsamMakeKey( ppib, pfucbMSA, (void *)&objid, sizeof( objid ), JET_bitNewKey ) );
Call( ErrIsamSeek( ppib, pfucbMSA, JET_bitSeekEQ | JET_bitSetIndexRange ) );
do
{
JET_GRBIT grbit = 0;
/* get pointer to Sid
/**/
Call( ErrRECIRetrieve( pfucbMSA, (FID *)&columnidSid, 0, &line, 0 ) );
pbSid = line.pb;
cbSid = line.cb;
/* get pointer to FInheritable */
Call( ErrRECIRetrieve( pfucbMSA, (FID *)&columnidFInheritable, 0, &line, 0 ) );
if ( (BOOL) *line.pb )
grbit |= JET_bitACEInheritable;
Assert( line.cb == sizeof( BYTE ) );
/* Get pointer to Acm */
Call( ErrRECIRetrieve( pfucbMSA, (FID *)&columnidAcm, 0, &line, 0 ) );
pbAcm = line.pb;
cbAcm = line.cb;
Assert( cbAcm == sizeof(ULONG) );
/* Add the current object info to the temporary table
/**/
Call( ErrDispPrepareUpdate( (JET_SESID)ppib, tableid,
JET_prepInsert ) );
Call( ErrDispSetColumn( (JET_SESID)ppib, tableid,
rgcolumnid[iAcmSid], pbSid, cbSid, 0, NULL ) );
Call( ErrDispSetColumn( (JET_SESID)ppib, tableid,
rgcolumnid[iAcmAcm], pbAcm, cbAcm, 0, NULL ) );
Call( ErrDispSetColumn( (JET_SESID)ppib, tableid,
rgcolumnid[iAcmGrbit], &grbit, sizeof(grbit) , 0, NULL ) );
Call( ErrDispUpdate( (JET_SESID)ppib, tableid, NULL, 0, NULL ) );
/* update the number of objects found
/**/
cRows++;
/* Move to the next Record */
err = ErrIsamMove( ppib, pfucbMSA, JET_MoveNext, 0 );
} while ( err >= 0 );
/* return if error other than end of range
/**/
if ( err != JET_errNoCurrentRecord )
return err;
/* Position the temporary table to the first object record */
err = ErrDispMove( (JET_SESID)ppib, tableid, JET_MoveFirst, 0 );
if ( err < 0 )
{
if ( err != JET_errNoCurrentRecord )
goto HandleError;
err = JET_errSuccess;
}
/* fill up the return structure
/**/
(( JET_OBJECTACMLIST *)pout->pb )->cbStruct = sizeof(JET_OBJECTACMLIST);
((JET_OBJECTACMLIST *)pout->pb )->tableid = tableid;
((JET_OBJECTACMLIST *)pout->pb )->cRecord = cRows;
((JET_OBJECTACMLIST *)pout->pb )->columnidSid = rgcolumnid[iAcmSid];
((JET_OBJECTACMLIST *)pout->pb )->columnidACM = rgcolumnid[iAcmAcm];
((JET_OBJECTACMLIST *)pout->pb )->columnidgrbit = rgcolumnid[iAcmGrbit];
pout->cbActual = sizeof(JET_OBJECTACMLIST);
pout->cbReturned = sizeof(JET_OBJECTACMLIST);
return JET_errSuccess;
HandleError:
(VOID)ErrDispCloseTable( (JET_SESID)ppib, tableid );
HandleError1:
CallS( ErrFILECloseTable( ppib, pfucbMSA ) );
return err;
#else /* !SEC */
return JET_errFeatureNotAvailable;
#endif /* SEC */
#else /* !DISPATCHING */
return JET_errFeatureNotAvailable;
#endif /* !DISPATCHING */
}
#endif /* SYSTABLES */
ERR VTAPI ErrIsamGetTableInfo(
JET_VSESID vsesid,
JET_VTID vtid,
void *pvResult,
unsigned long cbMax,
unsigned long lInfoLevel )
{
ERR err = JET_errSuccess;
PIB *ppib = (PIB *)vsesid;
FUCB *pfucb = (FUCB *)vtid;
#ifdef SYSTABLES
FUCB *pfucbMSO;
ULONG cbActual;
OBJID objidCtr;
OBJTYP objtypObject;
JET_COLUMNID columnidParentId; /* columnid for ParentId column in MSysObjects */
JET_COLUMNID columnidObjectName; /* columnid for Name column in MSysObjects */
JET_COLUMNID columnidObjectType; /* columnid for Type column in MSysObjects */
JET_COLUMNID columnidObjectId; /* columnid for Id column in MSysObjects */
JET_COLUMNID columnidCreate; /* columnid for DateCreate column in MSysObjects */
JET_COLUMNID columnidUpdate; /* columnid for DateUpdate column in MSysObjects */
JET_COLUMNID columnidFlags; /* columnid for Flags column in MSysObjects */
CheckPIB( ppib );
CheckTable( ppib, pfucb );
/* if OLCStats info/reset can be done now
/**/
if ( lInfoLevel == JET_TblInfoOLC )
{
FCB *pfcb = pfucb->u.pfcb;
if ( cbMax < sizeof(JET_OLCSTAT) )
return JET_errBufferTooSmall;
cbActual = sizeof(JET_OLCSTAT);
memcpy( (BYTE *) pvResult, (BYTE * ) &pfcb->olcStat, sizeof( PERS_OLCSTAT ) );
( (JET_OLCSTAT *) pvResult )->cpgCompactFreed = pfcb->cpgCompactFreed;
return JET_errSuccess;
}
else if ( lInfoLevel == JET_TblInfoResetOLC )
{
pfucb->u.pfcb->cpgCompactFreed = 0;
return JET_errSuccess;
}
#ifndef NJETNT
else if ( lInfoLevel == JET_TblInfoSpaceUsage )
{
err = ErrSPGetInfo( pfucb, pvResult, cbMax );
return err;
}
else if ( lInfoLevel == JET_TblInfoDumpTable )
{
#ifdef DEBUG
err = ErrFILEDumpTable( ppib, pfucb->dbid, pfucb->u.pfcb->szFileName );
return err;
#else
return JET_errFeatureNotAvailable;
#endif
}
#endif
CallR( ErrFILEOpenTable( ppib, pfucb->dbid, &pfucbMSO, szSoTable, 0 ) );
FUCBResetUpdatable( pfucbMSO );
/* get columnids
/**/
Call( ErrFILEGetColumnId( ppib, pfucbMSO, szSoParentIdColumn, &columnidParentId ) );
Call( ErrFILEGetColumnId( ppib, pfucbMSO, szSoObjectNameColumn, &columnidObjectName ) );
Call( ErrFILEGetColumnId( ppib, pfucbMSO, szSoObjectTypeColumn, &columnidObjectType ) );
Call( ErrFILEGetColumnId( ppib, pfucbMSO, szSoIdColumn, &columnidObjectId ) );
Call( ErrFILEGetColumnId( ppib, pfucbMSO, szSoDateCreateColumn, &columnidCreate ) );
Call( ErrFILEGetColumnId( ppib, pfucbMSO, szSoDateUpdateColumn, &columnidUpdate ) );
Call( ErrFILEGetColumnId( ppib, pfucbMSO, szSoFlagsColumn, &columnidFlags ) );
Call( ErrIsamSetCurrentIndex( ppib, pfucbMSO, szSoNameIndex ) );
switch ( lInfoLevel )
{
case JET_TblInfo:
/* check buffer size
/**/
if ( cbMax < sizeof(JET_OBJECTINFO) )
{
err = JET_errInvalidParameter;
goto HandleError;
}
if ( FFCBTemporaryTable( pfucb->u.pfcb ) )
{
err = JET_errObjectNotFound;
goto HandleError;
}
/* seek on made key ( ParentId = container id, Name = object name )
/**/
objidCtr = objidTblContainer;
Call( ErrIsamMakeKey( ppib, pfucbMSO, (void *)&objidCtr,
sizeof( objidCtr ), JET_bitNewKey ) );
Call( ErrIsamMakeKey( ppib, pfucbMSO, pfucb->u.pfcb->szFileName,
strlen( pfucb->u.pfcb->szFileName ), 0 ) );
Call( ErrIsamSeek( ppib, pfucbMSO, JET_bitSeekEQ ) );
/* set data to return
/**/
((JET_OBJECTINFO *)pvResult)->cbStruct = sizeof(JET_OBJECTINFO);
Call( ErrIsamRetrieveColumn( ppib, pfucbMSO, columnidObjectType, (void *)&objtypObject,
sizeof( objtypObject ), &cbActual, 0, NULL ) );
Assert( cbActual == sizeof(objtypObject) );
*((JET_OBJTYP *)&(((JET_OBJECTINFO *)pvResult)->objtyp)) = (JET_OBJTYP) objtypObject;
Call( ErrIsamRetrieveColumn( ppib, pfucbMSO, columnidCreate,
(void *)&( ( JET_OBJECTINFO *)pvResult )->dtCreate,
sizeof( JET_DATESERIAL ),
&cbActual, 0, NULL ) );
Assert( cbActual == sizeof( JET_DATESERIAL ) );
Call( ErrIsamRetrieveColumn( ppib, pfucbMSO, columnidUpdate,
(void *)&( ( JET_OBJECTINFO *)pvResult )->dtUpdate,
sizeof(JET_DATESERIAL), &cbActual, 0, NULL ) );
Assert( cbActual == sizeof( JET_DATESERIAL ) );
Call( ErrIsamRetrieveColumn( ppib, pfucbMSO, columnidFlags,
(void *)&((JET_OBJECTINFO *)pvResult )->flags,
sizeof(JET_GRBIT), &cbActual, 0, NULL ) );
if ( cbActual == 0 )
((JET_OBJECTINFO *) pvResult)->flags = 0;
/* UNDONE: Don't return updatable as appropriate with security/readonly */
((JET_OBJECTINFO *) pvResult)->grbit = JET_bitTableInfoBookmark;
((JET_OBJECTINFO *) pvResult)->grbit |= JET_bitTableInfoUpdatable | JET_bitTableInfoRollback;
Call( ErrSTATSRetrieveTableStats( pfucb->ppib,
pfucb->dbid,
pfucb->u.pfcb->szFileName,
&((JET_OBJECTINFO *)pvResult )->cRecord,
NULL,
&((JET_OBJECTINFO *)pvResult)->cPage ) );
break;
case JET_TblInfoRvt:
err = JET_errQueryIsSnapshot;
break;
case JET_TblInfoName:
case JET_TblInfoMostMany:
// UNDONE: add support for most many
if ( FFCBTemporaryTable( pfucb->u.pfcb ) )
{
err = JET_errInvalidOperation;
goto HandleError;
}
if ( strlen( pfucb->u.pfcb->szFileName ) >= cbMax )
err = JET_errBufferTooSmall;
else
{
strcpy( pvResult, pfucb->u.pfcb->szFileName );
}
break;
case JET_TblInfoDbid:
if ( FFCBTemporaryTable( pfucb->u.pfcb ) )
{
err = JET_errInvalidOperation;
goto HandleError;
}
/* check buffer size
/**/
if ( cbMax < sizeof(JET_DBID) + sizeof(JET_VDBID) )
{
err = JET_errInvalidParameter;
goto HandleError;
}
else
{
DAB *pdab = pfucb->ppib->pdabList;
JET_DBID dbid;
// UNDONE: this is bogus, link FUCB to DAB
for (; pdab->dbid != pfucb->dbid; pdab = pdab->pdabNext )
;
dbid = DbidOfVdbid( (JET_VDBID)pdab, &vdbfndefIsam );
*(JET_DBID *)pvResult = dbid;
*(JET_VDBID *)((char *)pvResult + sizeof(JET_DBID)) = (JET_VDBID)pdab;
}
break;
default:
err = JET_errInvalidParameter;
}
HandleError:
CallS( ErrFILECloseTable( ppib, pfucbMSO ) );
if ( err == JET_errRecordNotFound )
err = JET_errObjectNotFound;
return err;
#else /* !SYSTABLES */
return JET_errFeatureNotAvailable;
#endif /* !SYSTABLES */
}
/*=================================================================
ErrIsamGetColumnInfo
Description: Returns information about all columns for the table named
Parameters:
ppib pointer to PIB for current session
dbid id of database containing the table
szTableName table name
szColumnName column name or NULL for all columns
pout output buffer
lInfoLevel level of information ( 0, 1, or 2 )
Return Value: JET_errSuccess
Errors/Warnings:
Side Effects:
=================================================================*/
ERR VDBAPI
ErrIsamGetColumnInfo(
JET_VSESID vsesid, /* pointer to PIB for current session */
JET_DBID vdbid, /* id of database containing the table */
const char *szTable, /* table name */
const char *szColumnName, /* column name or NULL for all columns */
OLD_OUTDATA *poutdata, /* output buffer */
unsigned long lInfoLevel ) /* information level ( 0, 1, or 2 ) */
{
PIB *ppib = (PIB *) vsesid;
OUTLINE *pout = (OUTLINE *) poutdata;
ERR err;
DBID dbid = DbidOfVDbid( vdbid );
CHAR szTableName[ ( JET_cbNameMost + 1 ) ];
FUCB *pfucb = NULL;
CheckPIB( ppib );
CheckDBID( ppib, ( DBID )dbid );
CallR( ErrCheckName( szTableName, szTable, ( JET_cbNameMost + 1 ) ) );
err = ErrFILEOpenTable( ppib, dbid, &pfucb, szTableName, 0 );
if ( err >= 0 )
{
if ( lInfoLevel == 0 || lInfoLevel == 1 || lInfoLevel == 4
|| FVDbidReadOnly( vdbid ) )
{
FUCBResetUpdatable( pfucb );
}
}
#ifdef SYSTABLES
if ( err == JET_errObjectNotFound )
{
ERR err;
OBJID objid;
JET_OBJTYP objtyp;
err = ErrFindObjidFromIdName( ppib, dbid, objidTblContainer, szTableName, &objid, &objtyp );
if ( err >= JET_errSuccess )
{
if ( objtyp == JET_objtypQuery )
return JET_errQueryNotSupported;
if ( objtyp == JET_objtypLink )
return JET_errLinkNotSupported;
if ( objtyp == JET_objtypSQLLink )
return JET_errSQLLinkNotSupported;
}
else
return err;
}
#endif /* SYSTABLES */
Call( ErrIsamGetTableColumnInfo( (JET_VSESID) ppib, (JET_VTID) pfucb,
szColumnName, pout->pb, pout->cbMax, lInfoLevel ) );
CallS( ErrFILECloseTable( ppib, pfucb ) );
HandleError:
if ( err >= 0 )
{
pout->cbActual = ( (JET_COLUMNLIST *)pout->pb )->cbStruct;
pout->cbReturned = ( pout->cbMax < pout->cbActual ) ?
pout->cbMax: pout->cbActual;
}
return err;
}
/*=================================================================
ErrIsamGetTableColumnInfo
Description: Returns column information for the table id passed
Parameters: ppib pointer to PIB for the current session
pfucb pointer to FUCB for the table
szColumnName column name or NULL for all columns
pout output buffer
lInfoLevel level of information ( 0, 1, or 2 )
Return Value: JET_errSuccess
Errors/Warnings:
Side Effects:
=================================================================*/
ERR VTAPI
ErrIsamGetTableColumnInfo(
JET_VSESID vsesid, /* pointer to PIB for current session */
JET_VTID vtid, /* pointer to FUCB for the table */
const char *szColumn, /* column name or NULL for all columns */
void *pb,
unsigned long cbMax,
unsigned long lInfoLevel ) /* information level ( 0, 1, or 2 ) */
{
PIB *ppib = ( PIB * ) vsesid;
FUCB *pfucb = ( FUCB * ) vtid;
ERR err;
CHAR szColumnName[ ( JET_cbNameMost + 1 ) ];
OUTLINE out;
out.pb = pb;
out.cbMax = cbMax;
CheckPIB( ppib );
CheckTable( ppib, pfucb );
if ( szColumn == NULL || *szColumn == '\0' )
*szColumnName = '\0';
else
CallR( ErrCheckName( szColumnName, szColumn, ( JET_cbNameMost + 1 ) ) );
switch ( lInfoLevel )
{
case JET_ObjInfo:
err = ErrInfoGetTableColumnInfo0( ppib, pfucb, szColumnName, &out );
break;
case JET_ObjInfoListNoStats:
case JET_ObjInfoList:
err = ErrInfoGetTableColumnInfo1( ppib, pfucb, szColumnName, &out );
break;
case JET_ObjInfoSysTabCursor:
#ifdef SYSTABLES
err = ErrInfoGetTableColumnInfo3( ppib, pfucb, szColumnName, &out );
#else /* !SYSTABLES */
err = JET_errFeatureNotAvailable;
#endif /* !SYSTABLES */
break;
case JET_ObjInfoListACM:
err = ErrInfoGetTableColumnInfo4( ppib, pfucb, szColumnName, &out );
break;
default:
err = JET_errInvalidParameter;
}
return err;
}
LOCAL ERR ErrInfoGetTableColumnInfo0( PIB *ppib, FUCB *pfucb, CHAR *szColumnName, OUTLINE *pout )
{
FID fid;
COLINFO colinfo;
pout->cbReturned = 0;
if ( pout->cbMax < sizeof(JET_COLUMNDEF) || szColumnName == NULL )
{
return JET_errInvalidParameter;
}
fid = FidLookupColumn( pfucb, fidFixedLeast, szColumnName, &colinfo );
if ( fid >= fidTaggedMost )
{
return JET_errColumnNotFound;
}
((JET_COLUMNDEF *)pout->pb)->cbStruct = sizeof(JET_COLUMNDEF);
((JET_COLUMNDEF *)pout->pb)->columnid = colinfo.columnid;
((JET_COLUMNDEF *)pout->pb)->coltyp = colinfo.coltyp;
((JET_COLUMNDEF *)pout->pb)->cbMax = colinfo.cb;
((JET_COLUMNDEF *)pout->pb)->grbit = colinfo.grbit;
((JET_COLUMNDEF *)pout->pb)->wCollate = 0;
// UNDONE: support these fields;
((JET_COLUMNDEF *)pout->pb)->cp = usEnglishCodePage;
((JET_COLUMNDEF *)pout->pb)->wCountry = 1;
((JET_COLUMNDEF *)pout->pb)->langid = 0x409;
pout->cbActual = sizeof(JET_COLUMNDEF);
pout->cbReturned = sizeof(JET_COLUMNDEF);
return JET_errSuccess;
}
LOCAL ERR ErrInfoGetTableColumnInfo1( PIB *ppib, FUCB *pfucb, CHAR *szColumnName, OUTLINE *pout )
{
#ifdef DISPATCHING
ERR err;
JET_TABLEID tableid;
JET_COLUMNID rgcolumnid[ccolumndefGetColumnsMax];
#if 0
FUCB *pfucbMSC = pfucbNil;
JET_TABLEID tableidMSC;
CPCOL rgcpcol[ccolumndefGetColumnsMax];
INT icpcol;
LINE line;
#endif
BYTE *pbColumnName;
ULONG cbColumnName;
BYTE *pbColumnId;
ULONG cbColumnId;
BYTE *pbColumnType;
ULONG cbColumnType;
BYTE *pbColumnSize;
ULONG cbColumnSize;
BYTE *pbColumnGrbit;
ULONG cbColumnGrbit;
BYTE *pbTableName;
ULONG cbTableName;
FID fid;
COLINFO colinfo;
// UNDONE: support these fields;
WORD cp = usEnglishCodePage;
WORD wCountry = 1;
LANGID langid = 0x409;
WORD iCollate = JET_sortEFGPI;
long cRows = 0;
/* initialize variables
/**/
pout->cbReturned = 0;
if ( pout->cbMax < sizeof(JET_COLUMNLIST) )
{
return JET_errInvalidParameter;
}
/* create temporary table
/**/
CallR( ErrIsamOpenTempTable( (JET_SESID)ppib,
(JET_COLUMNDEF *) rgcolumndefGetColumns,
ccolumndefGetColumnsMax,
JET_bitTTScrollable | JET_bitTTScrollable,
&tableid,
rgcolumnid ) );
#if 0
/* for base tables, inspect MSysColumns. For sorts, inspect
/* directory structures.
/**/
if ( FFUCBIndex( pfucb ) )
{
ULONG ulPgnoFDP = pfucb->u.pfcb->pgnoFDP;
Call( ErrFILEOpenTable( ppib, pfucb->dbid, &pfucbMSC, szScTable, 0 ) );
Call( ErrIsamSetCurrentIndex( ppib, pfucbMSC, szScObjectIdNameIndex ) );
/* seek to first row in MSC for given table, and set index range
/* within current range. Copy records to result table and close
/* MSC table cursor.
/**/
Call( ErrIsamMakeKey( ppib, pfucbMSC, (void *)&ulPgnoFDP, sizeof( ulPgnoFDP ), JET_bitNewKey ) );
Call( ErrIsamSeek( ppib, pfucbMSC, JET_bitSeekGE ) );
Call( ErrIsamSetIndexRange( ppib, pfucbMSC, JET_bitRangeInclusive | JET_bitRangeUpperLimit ) );
/* setup copy column structure. Source column ids must correspond
/* to temporary table column order.
/**/
for( icpcol = 0; icpcol < ccolumndefGetColumnsMax; icpcol++ )
rgcpcol[icpcol].columnidDest = rgcolumnid[icpcol];
Call( ErrFILEGetColumnId( ppib, pfucb, szScPresentationOrder, &rgcpcol[].columnidSrc ) );
Call( ErrFILEGetColumnId( ppib, pfucb, szScName, &rgcpcol[].columnidSrc ) );
Call( ErrFILEGetColumnId( ppib, pfucb, szScId, &rgcpcol[].columnidSrc ) );
Call( ErrFILEGetColumnId( ppib, pfucb, szScType, &rgcpcol[].columnidSrc ) );
Call( ErrFILEGetColumnId( ppib, pfucb, szScCountry, &rgcpcol[].columnidSrc ) );
Call( ErrFILEGetColumnId( ppib, pfucb, szScLanguageId, &rgcpcol[].columnidSrc ) );
Call( ErrFILEGetColumnId( ppib, pfucb, szScCp, &rgcpcol[].columnidSrc ) );
Call( ErrFILEGetColumnId( ppib, pfucb, szScCollate, &rgcpcol[].columnidSrc ) );
Call( ErrFILEGetColumnId( ppib, pfucb, szScSize, &rgcpcol[].columnidSrc ) );
Call( ErrFILEGetColumnId( ppib, pfucb, szScGrbit, &rgcpcol[].columnidSrc ) );
Call( ErrFILEGetColumnId( ppib, pfucb, szScDefault, &rgcpcol[].columnidSrc ) );
Call( ErrFILEGetColumnId( ppib, pfucb, szScTableName, &rgcpcol[].columnidSrc ) );
Call( ErrFILEGetColumnId( ppib, pfucb, szScColumnName, &rgcpcol[].columnidSrc ) );
/* allocate tableid for copy records
/**/
FUCBSetSystemTable( pfucbMSC );
Call( ErrAllocateTableid( &tableidMSC, (JET_VTID)pfucbMSC, &vtfndefIsamInfo ) );
err = ErrIsamCopyRecords( ppib, tableidMSC, tableid, rgcpcol, ccolumndefGetColumnsMax, JET_MoveLast );
ReleaseTableid( tableidMSC );
Call( err );
/* close MSC table
/**/
CallS( ErrFILECloseTable( ppib, pfucbMSC ) );
pfucbMSC = pfucbNil;
}
else
#endif
{
/* set length later
/**/
cbColumnName = 0;
pbColumnName = colinfo.szName;
cbColumnId = sizeof( colinfo.columnid );
pbColumnId = (BYTE *) &colinfo.columnid;
cbColumnType = sizeof( colinfo.coltyp );
pbColumnType = (BYTE *) &colinfo.coltyp;
cbColumnSize = sizeof( colinfo.cb );
pbColumnSize = (BYTE *) &colinfo.cb;
cbColumnGrbit = sizeof( colinfo.grbit );
pbColumnGrbit = (BYTE *) &colinfo.grbit;
cbTableName = strlen( pfucb->u.pfcb->szFileName );
pbTableName = pfucb->u.pfcb->szFileName;
for ( fid = fidFixedLeast; fid < fidTaggedMost; fid++ )
{
fid = FidLookupColumn( pfucb, fid, NULL, &colinfo );
if ( fid >= fidTaggedMost )
break;
cbColumnName = strlen( colinfo.szName );
Call( ErrDispPrepareUpdate( (JET_SESID)ppib, tableid, JET_prepInsert ) );
// UNDONE: clean this up
/* get presentation order for this column and set in
/* output table. For temp tables, no order will be available.
/**/
{
OUTLINE out;
JET_TABLEID tableidInfo;
out.pb = (BYTE *)&tableidInfo;
out.cbMax = sizeof(tableidInfo);
err = ErrInfoGetTableColumnInfo3( ppib, pfucb, colinfo.szName, &out );
if ( err == JET_errSuccess )
{
LONG l;
LONG cbT;
Call( ErrDispRetrieveColumn( (JET_SESID)ppib, tableidInfo, 11L, &l, sizeof(l), &cbT, 0, NULL ) );
Call( ErrDispSetColumn( (JET_SESID)ppib, tableid, rgcolumnid[iColumnPOrder], &l, sizeof(l), 0, NULL ) );
CallS( ErrDispCloseTable( (JET_SESID)ppib, tableidInfo ) );
}
}
Call( ErrDispSetColumn( (JET_SESID)ppib, tableid,
rgcolumnid[iColumnName], pbColumnName,
cbColumnName, 0 , NULL ) );
Call( ErrDispSetColumn( (JET_SESID)ppib, tableid,
rgcolumnid[iColumnId], pbColumnId,
cbColumnId, 0 , NULL ) );
Call( ErrDispSetColumn( (JET_SESID)ppib, tableid,
rgcolumnid[iColumnType], pbColumnType,
cbColumnType, 0 , NULL ) );
Call( ErrDispSetColumn( (JET_SESID)ppib, tableid,
rgcolumnid[iColumnSize], pbColumnSize,
cbColumnSize, 0 , NULL ) );
Call( ErrDispSetColumn( (JET_SESID)ppib, tableid,
rgcolumnid[iColumnGrbit], pbColumnGrbit,
cbColumnGrbit, 0 , NULL ) );
Call( ErrDispSetColumn( (JET_SESID)ppib, tableid,
rgcolumnid[iColumnTableName], pbTableName,
cbTableName, 0 , NULL ) );
Call( ErrDispSetColumn( (JET_SESID)ppib, tableid,
rgcolumnid[iColumnColumnName], pbColumnName,
cbColumnName, 0 , NULL ) );
// UNDONE: support these columns
Call( ErrDispSetColumn( (JET_SESID)ppib, tableid,
rgcolumnid[iColumnCountry], &wCountry,
sizeof( wCountry ), 0 , NULL ) );
Call( ErrDispSetColumn( (JET_SESID)ppib, tableid,
rgcolumnid[iColumnLangid], &langid,
sizeof( langid ), 0 , NULL ) );
Call( ErrDispSetColumn( (JET_SESID)ppib, tableid,
rgcolumnid[iColumnCp], &cp,
sizeof( cp ), 0 , NULL ) );
Call( ErrDispSetColumn( (JET_SESID)ppib, tableid,
rgcolumnid[iColumnCollate], &iCollate,
sizeof(iCollate), 0 , NULL ) );
Call( ErrDispUpdate( (JET_SESID)ppib, tableid, NULL, 0, NULL ) );
cRows++;
}
}
/* move temporary table cursor to first row and return column list
/**/
err = ErrDispMove( (JET_SESID)ppib, tableid, JET_MoveFirst, 0 );
if ( err < 0 )
{
if ( err != JET_errNoCurrentRecord )
goto HandleError;
err = JET_errSuccess;
}
((JET_COLUMNLIST *)pout->pb)->cbStruct = sizeof(JET_COLUMNLIST);
((JET_COLUMNLIST *)pout->pb)->tableid = tableid;
((JET_COLUMNLIST *)pout->pb)->cRecord = cRows;
((JET_COLUMNLIST *)pout->pb)->columnidPresentationOrder =
rgcolumnid[iColumnPOrder];
((JET_COLUMNLIST *)pout->pb)->columnidcolumnname =
rgcolumnid[iColumnName];
((JET_COLUMNLIST *)pout->pb)->columnidcolumnid =
rgcolumnid[iColumnId];
((JET_COLUMNLIST *)pout->pb)->columnidcoltyp =
rgcolumnid[iColumnType];
((JET_COLUMNLIST *)pout->pb)->columnidCountry =
rgcolumnid[iColumnCountry];
((JET_COLUMNLIST *)pout->pb)->columnidLangid =
rgcolumnid[iColumnLangid];
((JET_COLUMNLIST *)pout->pb)->columnidCp =
rgcolumnid[iColumnCp];
((JET_COLUMNLIST *)pout->pb)->columnidCollate =
rgcolumnid[iColumnCollate];
((JET_COLUMNLIST *)pout->pb)->columnidcbMax =
rgcolumnid[iColumnSize];
((JET_COLUMNLIST *)pout->pb)->columnidgrbit =
rgcolumnid[iColumnGrbit];
((JET_COLUMNLIST *)pout->pb)->columnidDefault =
rgcolumnid[iColumnDefault];
((JET_COLUMNLIST *)pout->pb)->columnidBaseTableName =
rgcolumnid[iColumnTableName];
((JET_COLUMNLIST *)pout->pb)->columnidBaseColumnName =
rgcolumnid[iColumnColumnName];
((JET_COLUMNLIST *)pout->pb)->columnidDefinitionName =
rgcolumnid[iColumnName];
pout->cbActual = sizeof(JET_COLUMNLIST);
pout->cbReturned = sizeof(JET_COLUMNLIST);
return JET_errSuccess;
HandleError:
#if 0
if ( pfucbMSC != pfucbNil )
CassS( ErrFILECloseTable( ppib, pfucbMSC ) );
#endif
(VOID)ErrDispCloseTable( (JET_SESID)ppib, tableid );
return err;
#else /* !DISPATCHING */
return JET_errFeatureNotAvailable;
#endif /* !DISPATCHING */
}
#ifdef SYSTABLES
LOCAL ERR
ErrInfoGetTableColumnInfo3( PIB *ppib,
FUCB *pfucb,
CHAR *szColumnName,
OUTLINE *pout )
{
ERR err;
ULONG ulPgnoFDP = pfucb->u.pfcb->pgnoFDP;
FUCB *pfucbMSC;
#ifdef DISPATCHING
JET_TABLEID tableid;
#endif /* DISPATCHING */
if ( szColumnName == NULL || pout->cbMax < sizeof(JET_TABLEID) )
{
return JET_errInvalidParameter;
}
CallR( ErrFILEOpenTable( ppib, pfucb->dbid, &pfucbMSC, szScTable, 0 ) );
Call( ErrIsamSetCurrentIndex( ppib, pfucbMSC, szScObjectIdNameIndex ) );
Call( ErrIsamMakeKey( ppib, pfucbMSC, (void *)&ulPgnoFDP, sizeof( ulPgnoFDP ), JET_bitNewKey ) );
Call( ErrIsamMakeKey( ppib, pfucbMSC, szColumnName, strlen( szColumnName ), 0 ) );
Call( ErrIsamSeek( ppib, pfucbMSC, JET_bitSeekEQ ) );
FUCBSetSystemTable( pfucbMSC );
#ifdef DISPATCHING
Call( ErrAllocateTableid( &tableid, ( JET_VTID )pfucbMSC, &vtfndefIsamInfo ) );
pfucbMSC->fVtid = fTrue;
*(JET_TABLEID *)(pout->pb) = tableid;
pout->cbReturned = sizeof(tableid);
pout->cbActual = sizeof(tableid);
#else /* !DISPATCHING */
*( FUCB * *)( pout->pb ) = pfucbMSC;
pout->cbReturned = sizeof(pfucbMSC);
pout->cbActual = sizeof(pfucbMSC);
#endif /* !DISPATCHING */
return JET_errSuccess;
HandleError:
CallS( ErrFILECloseTable( ppib, pfucbMSC ) );
if ( err == JET_errRecordNotFound )
err = JET_errColumnNotFound;
return err;
}
#endif /* SYSTABLES */
LOCAL ERR
ErrInfoGetTableColumnInfo4( PIB *ppib, FUCB *pfucb, CHAR *szColumnName,
OUTLINE *pout )
{
FID fid;
COLINFO colinfo;
pout->cbActual = sizeof(JET_COLUMNBASE);
pout->cbReturned = 0;
if ( pout->cbMax < sizeof(JET_COLUMNBASE) || szColumnName == NULL )
{
pout->cbReturned = 0;
return JET_errInvalidParameter;
}
fid = FidLookupColumn( pfucb, fidFixedLeast, szColumnName, &colinfo );
if ( fid >= fidTaggedMost )
{
return JET_errColumnNotFound;
}
((JET_COLUMNBASE *)pout->pb)->cbStruct = sizeof(JET_COLUMNBASE);
((JET_COLUMNBASE *)pout->pb)->columnid = colinfo.columnid;
((JET_COLUMNBASE *)pout->pb)->coltyp = colinfo.coltyp;
((JET_COLUMNBASE *)pout->pb)->wFiller = 0;
((JET_COLUMNBASE *)pout->pb)->cbMax = colinfo.cb;
((JET_COLUMNBASE *)pout->pb)->grbit = colinfo.grbit;
strcpy( ( ( JET_COLUMNBASE *)pout->pb )->szBaseTableName, pfucb->u.pfcb->szFileName );
strcpy( ( ( JET_COLUMNBASE *)pout->pb )->szBaseColumnName, szColumnName );
// UNDONE: support these fields;
((JET_COLUMNBASE *)pout->pb)->wCountry = 1;
((JET_COLUMNBASE *)pout->pb)->langid = 0x409;
((JET_COLUMNBASE *)pout->pb)->cp = usEnglishCodePage;
pout->cbReturned = sizeof(JET_COLUMNBASE);
return JET_errSuccess;
}
/*=================================================================
ErrIsamGetIndexInfo
Description: Returns a temporary file containing index definition
Parameters: ppib pointer to PIB for the current session
dbid id of database containing the table
szTableName name of table owning the index
szIndexName index name
pout output buffer
lInfoLevel level of information ( 0, 1, or 2 )
Return Value: JET_errSuccess
Errors/Warnings:
Side Effects:
=================================================================*/
ERR VDBAPI
ErrIsamGetIndexInfo(
JET_VSESID vsesid, /* pointer to PIB for current session */
JET_DBID vdbid, /* id of database containing table */
const char *szTable, /* name of table owning the index */
const char *szIndexName, /* index name */
OLD_OUTDATA *poutdata, /* output buffer */
unsigned long lInfoLevel ) /* information level ( 0, 1, or 2 ) */
{
PIB *ppib = (PIB *) vsesid;
OUTLINE *pout = (OUTLINE *) poutdata;
ERR err;
DBID dbid = DbidOfVDbid( vdbid );
CHAR szTableName[ ( JET_cbNameMost + 1 ) ];
FUCB *pfucb;
CheckPIB( ppib );
CheckDBID( ppib, ( DBID )dbid );
CallR( ErrCheckName( szTableName, szTable, ( JET_cbNameMost + 1 ) ) );
CallR( ErrFILEOpenTable( ppib, dbid, &pfucb, szTableName, 0 ) );
if ( lInfoLevel == 0 || lInfoLevel == 1 || FVDbidReadOnly( vdbid ) )
FUCBResetUpdatable( pfucb );
err = ErrIsamGetTableIndexInfo( (JET_VSESID) ppib, (JET_VTID) pfucb,
szIndexName, pout->pb, pout->cbMax, lInfoLevel );
CallS( ErrFILECloseTable( ppib, pfucb ) );
return err;
}
/*=================================================================
ErrIsamGetTableIndexInfo
Description: Returns a temporary table containing the index definition
Parameters: ppib pointer to PIB for the current session
pfucb FUCB for table owning the index
szIndexName index name
pout output buffer
lInfoLevel level of information ( 0, 1, or 2 )
Return Value: JET_errSuccess
Errors/Warnings:
Side Effects:
=================================================================*/
ERR VTAPI
ErrIsamGetTableIndexInfo(
JET_VSESID vsesid, /* pointer to PIB for current session */
JET_VTID vtid, /* FUCB for the table owning the index */
const char *szIndex, /* index name */
void *pb,
unsigned long cbMax,
unsigned long lInfoLevel ) /* information level ( 0, 1, or 2 ) */
{
PIB *ppib = (PIB *) vsesid;
FUCB *pfucb = (FUCB *) vtid;
ERR err;
CHAR szIndexName[ ( JET_cbNameMost + 1 ) ];
OUTLINE out;
/* Validate the arguments */
CheckPIB( ppib );
CheckTable( ppib, pfucb );
if ( szIndex == NULL || *szIndex == '\0' )
*szIndexName = '\0';
else
CallR( ErrCheckName( szIndexName, szIndex, ( JET_cbNameMost + 1 ) ) );
out.pb = pb;
out.cbMax = cbMax;
out.cbReturned = 0;
switch ( lInfoLevel )
{
case JET_IdxInfo:
case JET_IdxInfoList:
case JET_IdxInfoOLC:
err = ErrInfoGetTableIndexInfo01( ppib, pfucb, szIndexName, &out, lInfoLevel );
break;
case JET_IdxInfoSysTabCursor:
#ifdef SYSTABLES
err = ErrInfoGetTableIndexInfo2( ppib, pfucb, szIndexName, &out );
#else /* !SYSTABLES */
err = JET_errFeatureNotAvailable;
#endif /* !SYSTABLES */
break;
default:
return JET_errInvalidParameter;
}
return err;
}
LOCAL ERR ErrInfoGetTableIndexInfo01( PIB *ppib,
FUCB *pfucb,
CHAR *szIndexName,
OUTLINE *pout,
LONG lInfoLevel )
{
#ifdef DISPATCHING
ERR err; /* return code from internal functions */
FCB *pfcb; /* file control block for the index */
IDB *pidb; /* current index control block */
FDB *pfdb; /* field descriptor block for column */
FID fid; /* column id */
FIELD *pfield; /* pointer to current field definition */
IDXSEG *rgidxseg; /* pointer to current index key defintion */
long cRecord; /* number of index entries */
long cKey; /* number of unique index entries */
long cPage; /* number of pages in the index */
long cRows; /* number of index definition records */
long cColumn; /* number of columns in current index */
long iidxseg; /* segment number of current column */
JET_TABLEID tableid; /* table id for the VT */
JET_COLUMNID columnid; /* column id of the current column */
JET_GRBIT grbit; /* flags for the current index */
JET_GRBIT grbitColumn; /* flags for the current column */
JET_COLUMNID rgcolumnid[ccolumndefGetIndexMax];
// UNDONE: support these fields;
WORD wCountry = 1;
LANGID langid = 0x409;
WORD cp = usEnglishCodePage;
WORD iCollate = JET_sortEFGPI;
/* Initialize the return value */
pout->cbActual = sizeof(JET_INDEXLIST);
pout->cbReturned = 0;
/* Return nothing if the buffer is too small */
if ( pout->cbMax < sizeof(JET_INDEXLIST) )
return JET_wrnBufferTruncated;
/* Set the pointer to the field definitions for the table */
pfdb = (FDB *)pfucb->u.pfcb->pfdb;
/* Locate the FCB for the specified index ( clustered index if null name ) */
for ( pfcb = pfucb->u.pfcb; pfcb != pfcbNil; pfcb = pfcb->pfcbNextIndex )
if ( pfcb->pidb != pidbNil && ( *szIndexName == '\0' ||
SysCmpText( szIndexName, pfcb->pidb->szName ) == 0 ) )
break;
if ( pfcb == pfcbNil && *szIndexName != '\0' )
return JET_errIndexNotFound;
/* if OLCStats info/reset, we can do it now
/**/
if ( lInfoLevel == JET_IdxInfoOLC )
{
if ( pout->cbMax < sizeof(JET_OLCSTAT) )
return JET_errBufferTooSmall;
pout->cbReturned = sizeof(JET_OLCSTAT);
memcpy( (BYTE *) pout->pb, (BYTE * ) &pfcb->olcStat, sizeof( PERS_OLCSTAT ) );
( (JET_OLCSTAT *) pout )->cpgCompactFreed = pfcb->cpgCompactFreed;
return JET_errSuccess;
}
if ( lInfoLevel == JET_IdxInfoResetOLC )
{
pfcb->cpgCompactFreed = 0;
return JET_errSuccess;
}
/* Open the temporary table ( fills in the column ids in rgcolumndef )
/**/
CallR( ErrIsamOpenTempTable( (JET_SESID)ppib,
(JET_COLUMNDEF *) rgcolumndefGetIndex,
ccolumndefGetIndexMax,
JET_bitTTScrollable | JET_bitTTScrollable,
&tableid,
rgcolumnid ) );
cRows = 0;
/* As long as there is a valid index, add its definition to the VT */
while ( pfcb != pfcbNil )
{
pidb = pfcb->pidb; /* point to the IDB for the index */
cColumn = pidb->iidxsegMac; /* get number of columns in the key */
/* set the index flags
/**/
grbit = ( pfcb == pfucb->u.pfcb ) ? JET_bitIndexClustered: 0;
#ifndef JETSER
grbit |= ( pidb->fidb & fidbPrimary ) ? JET_bitIndexPrimary: 0;
#endif
grbit |= ( pidb->fidb & fidbUnique ) ? JET_bitIndexUnique: 0;
grbit |= ( pidb->fidb & fidbNoNullSeg ) ? JET_bitIndexDisallowNull: 0;
if ( !( pidb->fidb & fidbNoNullSeg ) )
{
grbit |= ( pidb->fidb & fidbAllowAllNulls ) ? 0: JET_bitIndexIgnoreNull;
grbit |= ( pidb->fidb & fidbAllowSomeNulls ) ? 0: JET_bitIndexIgnoreAnyNull;
}
/* Process each column in the index key
/**/
for ( iidxseg = 0; iidxseg < cColumn; iidxseg++ )
{
Call( ErrDispPrepareUpdate( (JET_SESID)ppib, tableid, JET_prepInsert ) );
/* index name
/**/
Call( ErrDispSetColumn( (JET_SESID)ppib, tableid,
rgcolumnid[iIndexName], pidb->szName, strlen( pidb->szName ),
0, NULL ) );
/* index flags
/**/
Call( ErrDispSetColumn( (JET_SESID)ppib, tableid,
rgcolumnid[iIndexGrbit], &grbit, sizeof( grbit ), 0, NULL ) );
/* get statistics
/**/
Call( ErrSTATSRetrieveIndexStats( pfucb, pidb->szName, &cRecord, &cKey, &cPage ) );
Call( ErrDispSetColumn( (JET_SESID)ppib, tableid,
rgcolumnid[iIndexCKey], &cKey, sizeof( cKey ), 0, NULL ) );
Call( ErrDispSetColumn( (JET_SESID)ppib, tableid,
rgcolumnid[iIndexCEntry], &cRecord, sizeof( cRecord ), 0, NULL ) );
Call( ErrDispSetColumn( (JET_SESID)ppib, tableid,
rgcolumnid[iIndexCPage], &cPage, sizeof( cPage ), 0, NULL ) );
/* number of key columns
/**/
Call( ErrDispSetColumn( (JET_SESID)ppib, tableid,
rgcolumnid[iIndexCCol], &cColumn, sizeof( cColumn ), 0, NULL ) );
/* column number within key
/* required by CLI and JET spec
/**/
Call( ErrDispSetColumn( (JET_SESID)ppib, tableid,
rgcolumnid[iIndexICol], &iidxseg, sizeof( iidxseg ), 0, NULL ) );
/* get the column id and ascending/descending flag
/**/
rgidxseg = pidb->rgidxseg;
if ( rgidxseg[iidxseg] < 0 )
{
grbitColumn = JET_bitKeyDescending;
fid = -rgidxseg[iidxseg];
}
else
{
grbitColumn = JET_bitKeyAscending;
fid = rgidxseg[iidxseg];
}
/* column id
/**/
columnid = fid;
Call( ErrDispSetColumn( (JET_SESID)ppib, tableid,
rgcolumnid[iIndexColId], &columnid, sizeof( columnid ),
0, NULL ) );
/* Set the pointer to the column definition
/**/
if ( fid < fidFixedMost )
{
pfield = pfdb->pfieldFixed + ( fid - fidFixedLeast );
}
else if ( fid < fidVarMost )
{
pfield = pfdb->pfieldVar + ( fid - fidVarLeast );
}
else
{
pfield = pfdb->pfieldTagged + ( fid - fidTaggedLeast );
}
/* column type
/**/
Call( ErrDispSetColumn( (JET_SESID)ppib, tableid,
rgcolumnid[iIndexColType], &pfield->coltyp, sizeof( pfield->coltyp ), 0, NULL ) );
/* Country
/**/
Call( ErrDispSetColumn( (JET_SESID)ppib, tableid,
rgcolumnid[iIndexCountry], &wCountry, sizeof(wCountry), 0, NULL ) );
/* Langid
/**/
Call( ErrDispSetColumn( (JET_SESID)ppib, tableid,
rgcolumnid[iIndexLangid], &langid, sizeof(langid), 0, NULL ) );
/* Cp
/**/
Call( ErrDispSetColumn( (JET_SESID)ppib, tableid,
rgcolumnid[iIndexCp], &cp, sizeof(cp), 0, NULL ) );
/* Collate
/**/
Call( ErrDispSetColumn( (JET_SESID)ppib, tableid,
rgcolumnid[iIndexCollate], &iCollate, sizeof(iCollate), 0, NULL ) );
/* column flags
/**/
Call( ErrDispSetColumn( (JET_SESID)ppib, tableid,
rgcolumnid[iIndexColBits], &grbitColumn,
sizeof( grbitColumn ), 0, NULL ) );
/* column name
/**/
Call( ErrDispSetColumn( (JET_SESID)ppib, tableid,
rgcolumnid[iIndexColName], pfield->szFieldName,
strlen( pfield->szFieldName ), 0, NULL ) );
Call( ErrDispUpdate( (JET_SESID)ppib, tableid, NULL, 0, NULL ) );
/* count the number of VT rows
/**/
cRows++;
}
/* Quit if an index name was specified; otherwise do the next index
/**/
if ( *szIndexName != '\0' )
break;
else
pfcb = pfcb->pfcbNextIndex;
}
/* Position to the first entry in the VT ( ignore error if no rows ) */
err = ErrDispMove( (JET_SESID)ppib, tableid, JET_MoveFirst, 0 );
if ( err < 0 )
{
if ( err != JET_errNoCurrentRecord )
goto HandleError;
err = JET_errSuccess;
}
/* Set up the return structure */
((JET_INDEXLIST *)pout->pb)->cbStruct = sizeof(JET_INDEXLIST);
((JET_INDEXLIST *)pout->pb)->tableid = tableid;
((JET_INDEXLIST *)pout->pb)->cRecord = cRows;
((JET_INDEXLIST *)pout->pb)->columnidindexname =
rgcolumnid[iIndexName];
((JET_INDEXLIST *)pout->pb)->columnidgrbitIndex =
rgcolumnid[iIndexGrbit];
((JET_INDEXLIST *)pout->pb)->columnidcEntry =
rgcolumnid[iIndexCEntry];
((JET_INDEXLIST *)pout->pb)->columnidcKey =
rgcolumnid[iIndexCKey];
((JET_INDEXLIST *)pout->pb)->columnidcPage =
rgcolumnid[iIndexCPage];
((JET_INDEXLIST *)pout->pb)->columnidcColumn =
rgcolumnid[iIndexCCol];
((JET_INDEXLIST *)pout->pb)->columnidiColumn =
rgcolumnid[iIndexICol];
((JET_INDEXLIST *)pout->pb)->columnidcolumnid =
rgcolumnid[iIndexColId];
((JET_INDEXLIST *)pout->pb)->columnidcoltyp =
rgcolumnid[iIndexColType];
((JET_INDEXLIST *)pout->pb)->columnidCountry =
rgcolumnid[iIndexCountry];
((JET_INDEXLIST *)pout->pb)->columnidLangid =
rgcolumnid[iIndexLangid];
((JET_INDEXLIST *)pout->pb)->columnidCp =
rgcolumnid[iIndexCp];
((JET_INDEXLIST *)pout->pb)->columnidCollate =
rgcolumnid[iIndexCollate];
((JET_INDEXLIST *)pout->pb)->columnidgrbitColumn =
rgcolumnid[iIndexColBits];
((JET_INDEXLIST *)pout->pb)->columnidcolumnname =
rgcolumnid[iIndexColName];
pout->cbReturned = sizeof(JET_INDEXLIST);
return JET_errSuccess;
HandleError:
(VOID)ErrDispCloseTable( (JET_SESID)ppib, tableid );
return err;
#else /* !DISPATCHING */
return JET_errFeatureNotAvailable;
#endif /* !DISPATCHING */
}
#ifdef SYSTABLES
LOCAL ERR
ErrInfoGetTableIndexInfo2( PIB *ppib, FUCB *pfucb, CHAR *szIndexName,
OUTLINE *pout )
{
ERR err;
ULONG ulPgnoFDP = pfucb->u.pfcb->pgnoFDP;
FUCB *pfucbMSI;
#ifdef DISPATCHING
JET_TABLEID tableid;
#endif /* DISPATCHING */
if ( *szIndexName == '\0' || pout->cbMax < sizeof(JET_TABLEID) )
{
return JET_errInvalidParameter;
}
CallR( ErrFILEOpenTable( ppib, pfucb->dbid, &pfucbMSI, szSiTable, 0 ) );
Call( ErrIsamSetCurrentIndex( ppib, pfucbMSI, szSiObjectIdNameIndex ) );
Call( ErrIsamMakeKey( ppib, pfucbMSI, (void *)&ulPgnoFDP, sizeof( ulPgnoFDP ), JET_bitNewKey ) );
Call( ErrIsamMakeKey( ppib, pfucbMSI, szIndexName, strlen( szIndexName ), 0 ) );
Call( ErrIsamSeek( ppib, pfucbMSI, JET_bitSeekEQ ) );
FUCBSetSystemTable( pfucbMSI );
#ifdef DISPATCHING
Call( ErrAllocateTableid( &tableid, ( JET_VTID )pfucbMSI, &vtfndefIsamInfo ) );
pfucbMSI->fVtid = fTrue;
*(JET_TABLEID *)(pout->pb) = tableid;
pout->cbReturned = sizeof(tableid);
pout->cbActual = sizeof(tableid);
#else /* !DISPATCHING */
*(FUCB **)( pout->pb ) = pfucbMSI;
pout->cbReturned = sizeof(pfucbMSI);
pout->cbActual = sizeof(pfucbMSI);
#endif /* !DISPATCHING */
return JET_errSuccess;
HandleError:
if ( err == JET_errRecordNotFound )
err = JET_errIndexNotFound;
CallS( ErrFILECloseTable( ppib, pfucbMSI ) );
return err;
}
#endif /* SYSTABLES */
ERR VDBAPI ErrIsamGetDatabaseInfo(
JET_VSESID vsesid,
JET_DBID vdbid,
void *pv,
unsigned long cbMax,
unsigned long ulInfoLevel )
{
PIB *ppib = (PIB *) vsesid;
ERR err;
DBID dbid = DbidOfVDbid( vdbid );
// UNDONE: support these fields;
WORD cp = usEnglishCodePage;
WORD wCountry = 1;
LANGID langid = 0x409;
WORD iCollate = JET_sortEFGPI;
CheckPIB( ppib );
// If cbMax != 0, then pv mustn't be NULL
Assert ( cbMax == 0 || pv != NULL );
/* returns database name and connect string given dbid
/**/
SgSemRequest( semST );
if ( rgfmp[dbid].szDatabaseName == NULL )
{
err = JET_errInvalidParameter;
goto HandleError;
}
switch ( ulInfoLevel )
{
case JET_DbInfoFilename:
{
if ( strlen( rgfmp[dbid].szDatabaseName ) + 1UL > cbMax )
{
err = JET_errBufferTooSmall;
goto HandleError;
}
strcpy( (CHAR *)pv, rgfmp[dbid].szDatabaseName );
break;
}
case JET_DbInfoConnect:
{
// UNDONE: support this parameter
if ( 1UL > cbMax )
{
err = JET_errBufferTooSmall;
goto HandleError;
}
*(CHAR *)pv = '\0';
break;
}
case JET_DbInfoCountry:
{
if ( cbMax != sizeof(long) )
return JET_errInvalidBufferSize;
*(long *)pv = wCountry;
break;
}
case JET_DbInfoLangid:
{
if ( cbMax != sizeof(long) )
return JET_errInvalidBufferSize;
*(long *)pv = langid;
break;
}
case JET_DbInfoCp:
{
if ( cbMax != sizeof(long) )
return JET_errInvalidBufferSize;
*(long *)pv = cp;
break;
}
case JET_DbInfoCollate:
{
/* Check the buffer size */
if ( cbMax != sizeof(long) )
return JET_errInvalidBufferSize;
*(long *)pv = iCollate;
break;
}
case JET_DbInfoOptions:
{
/* check the buffer size
/**/
if ( cbMax != sizeof(JET_GRBIT) )
return JET_errInvalidBufferSize;
/* return the open options for the current database
/**/
*(JET_GRBIT *)pv = ((VDBID)vdbid)->grbit;
break;
}
case JET_DbInfoTransactions:
{
/* Check the buffer size */
if ( cbMax != sizeof(long) )
return JET_errInvalidBufferSize;
*(long*)pv = levelUserMost;
break;
}
case JET_DbInfoVersion:
{
/* Check the buffer size */
if ( cbMax != sizeof(long) )
return JET_errInvalidBufferSize;
*(long*)pv = JET_DbVersion20;
break;
}
case JET_DbInfoIsam:
{
/* Check the buffer size */
if ( cbMax != sizeof(long) + sizeof(long) )
return JET_errInvalidBufferSize;
*(long *)pv = JET_IsamBuiltinBlue;
*( (long *)pv + 1 ) = JET_bitFourByteBookmark;
break;
}
default:
return JET_errInvalidParameter;
}
err = JET_errSuccess;
HandleError:
SgSemRelease( semST );
return err;
}
ERR VTAPI
ErrIsamGetSysTableColumnInfo(
PIB *ppib,
FUCB *pfucb,
char *szColumnName,
OUTLINE *pout,
long lInfoLevel )
{
ERR err;
if ( lInfoLevel > 0 )
return JET_errInvalidParameter;
err = ErrIsamGetTableColumnInfo( (JET_VSESID) ppib,
(JET_VTID) pfucb, szColumnName, pout->pb, pout->cbMax, lInfoLevel );
return err;
}
ERR ErrFILEGetColumnId( PIB *ppib, FUCB *pfucb, const CHAR *szColumn, JET_COLUMNID *pcolumnid )
{
FDB *pfdb;
FIELD *pfield;
FIELD *pfieldMax;
CheckPIB( ppib );
CheckTable( ppib, pfucb );
Assert( pfucb->u.pfcb != pfcbNil );
Assert( pfucb->u.pfcb->pfdb != pfdbNil );
Assert( pcolumnid != NULL );
pfdb = (FDB *)pfucb->u.pfcb->pfdb;
/*** Search fixed field names ***/
pfieldMax = pfdb->pfieldFixed + ( pfdb->fidFixedLast+1-fidFixedLeast );
for ( pfield = pfdb->pfieldFixed; pfield < pfieldMax; pfield++ )
if ( pfield->coltyp != JET_coltypNil &&
SysCmpText( pfield->szFieldName, szColumn ) == 0 )
{
*pcolumnid = (DWORD)( pfield-pfdb->pfieldFixed ) + fidFixedLeast;
return JET_errSuccess;
}
/*** Search variable field names ***/
pfieldMax = pfdb->pfieldVar + ( (int)pfdb->fidVarLast+1-fidVarLeast );
for ( pfield = pfdb->pfieldVar; pfield < pfieldMax; pfield++ )
if ( pfield->coltyp != JET_coltypNil &&
SysCmpText( pfield->szFieldName, szColumn ) == 0 )
{
*pcolumnid = (DWORD)( pfield - pfdb->pfieldVar ) + fidVarLeast;
return JET_errSuccess;
}
/*** Search tagged field names ***/
pfieldMax = pfdb->pfieldTagged +
( (int)pfdb->fidTaggedLast+1-fidTaggedLeast );
for ( pfield = pfdb->pfieldTagged; pfield < pfieldMax; pfield++ )
if ( pfield->coltyp != JET_coltypNil &&
SysCmpText( pfield->szFieldName, szColumn ) == 0 )
{
*pcolumnid = (DWORD)( pfield-pfdb->pfieldTagged )+fidTaggedLeast;
return JET_errSuccess;
}
return JET_errColumnNotFound;
}
/*=================================================================
FidLookupColumn
Description: Looks up next column ( matching given name if any )
Parameters: pfucb pointer to FUCB for table containing columns
fid field id to start search at
szColumnName column name or NULL for next column
pcolinfo output buffer containing column info
Return Value: Field id of column found ( fidTaggedMost if none )
Errors/Warnings:
Side Effects:
=================================================================*/
FID FidLookupColumn(
FUCB *pfucb, /* FUCB for table containing columns */
FID fid, /* field id where search is to start */
char *szColumnName, /* column name or NULL for next column */
COLINFO *pcolinfo ) /* output buffer for column info */
{
FDB *pfdb; /* pointer to table definition */
FIELD *pfield; /* first element of specific field type */
FID ifield; /* index to current element of field type */
FID fidLast; /* column id of last field defined for type */
int iSource; /* index to source character in column name */
int iDest; /* index to destination character */
JET_GRBIT grbit; /* flags for the field */
pfdb = (FDB *)pfucb->u.pfcb->pfdb;
/* Check the fixed fields first */
if ( fid <= fidFixedMost )
{
ifield = fid - fidFixedLeast;
fidLast = pfdb->fidFixedLast - fidFixedLeast + 1;
pfield = pfdb->pfieldFixed;
while ( ifield < fidLast &&
( pfield[ifield].coltyp == JET_coltypNil ||
( szColumnName != NULL &&
SysCmpText( szColumnName, pfield[ifield].szFieldName ) != 0 ) ) )
{
ifield++;
}
if ( ifield < fidLast )
{
fid = ifield + fidFixedLeast;
grbit = FFUCBUpdatable( pfucb ) ? JET_bitColumnFixed | JET_bitColumnUpdatable : JET_bitColumnFixed;
}
else
fid = fidVarLeast;
}
/* Check the variable fields */
if ( fid >= fidVarLeast && fid <= fidVarMost )
{
ifield = fid - fidVarLeast;
fidLast = pfdb->fidVarLast - fidVarLeast + 1;
pfield = pfdb->pfieldVar;
while ( ifield < fidLast &&
( pfield[ifield].coltyp == JET_coltypNil ||
( szColumnName != NULL &&
SysCmpText( szColumnName, pfield[ifield].szFieldName ) != 0 ) ) )
ifield++;
if ( ifield < fidLast )
{
fid = ifield + fidVarLeast;
grbit = FFUCBUpdatable( pfucb ) ? JET_bitColumnUpdatable : 0;
}
else
fid = fidTaggedLeast;
}
/* Check the tagged fields */
if ( fid >= fidTaggedLeast )
{
ifield = fid - fidTaggedLeast;
fidLast = pfdb->fidTaggedLast - fidTaggedLeast + 1;
pfield = pfdb->pfieldTagged;
while ( ifield < fidLast &&
( pfield[ifield].coltyp == JET_coltypNil ||
( szColumnName != NULL &&
SysCmpText( szColumnName, pfield[ifield].szFieldName ) != 0 ) ) )
{
ifield++;
}
if ( ifield < fidLast )
{
fid = ifield + fidTaggedLeast;
grbit = FFUCBUpdatable( pfucb ) ? JET_bitColumnTagged | JET_bitColumnUpdatable : JET_bitColumnTagged;
}
else
fid = fidTaggedMost;
}
/* If a field was found, then return the information about it */
if ( fid < fidTaggedMost )
{
if ( pfield[ifield].ffield & ffieldNotNull )
grbit |= JET_bitColumnNotNULL;
if ( pfield[ifield].ffield & ffieldAutoInc )
grbit |= JET_bitColumnAutoincrement;
if ( pfield[ifield].ffield & ffieldVersion )
grbit |= JET_bitColumnVersion;
if ( pfield[ifield].ffield & ffieldMultivalue )
grbit |= JET_bitColumnMultiValued;
pcolinfo->columnid = fid;
pcolinfo->grbit = grbit;
pcolinfo->coltyp = pfield[ifield].coltyp;
pcolinfo->cb = pfield[ifield].cbMaxLen;
iSource = 0;
iDest = 0;
while ( iSource < ( JET_cbNameMost + 1 ) &&
pfield[ifield].szFieldName[iSource] != '\0' )
pcolinfo->szName[iDest++] = pfield[ifield].szFieldName[iSource++];
pcolinfo->szName[iDest] = '\0';
}
return fid;
}
ERR VTAPI ErrIsamInfoRetrieveColumn(
PIB *ppib,
FUCB *pfucb,
JET_COLUMNID columnid,
BYTE *pb,
unsigned long cbMax,
unsigned long *pcbActual,
JET_GRBIT grbit,
JET_RETINFO *pretinfo )
{
ERR err;
err = ErrIsamRetrieveColumn( ppib, pfucb, columnid, pb, cbMax, pcbActual, grbit, pretinfo );
return err;
}
ERR VTAPI ErrIsamInfoSetColumn(
PIB *ppib,
FUCB *pfucb,
JET_COLUMNID columnid,
const void *pbData,
unsigned long cbData,
JET_GRBIT grbit,
JET_SETINFO *psetinfo )
{
ERR err;
/* check table updatable
/**/
CallR( FUCBCheckUpdatable( pfucb ) );
err = ErrIsamSetColumn( ppib, pfucb, columnid, (BYTE *)pbData, cbData, grbit, psetinfo );
return err;
}
ERR VTAPI ErrIsamInfoUpdate(
JET_VSESID vsesid,
JET_VTID vtid,
void *pb,
unsigned long cbMax,
unsigned long *pcbActual )
{
ERR err;
/* Ensure that table is updatable */
/**/
CallR( FUCBCheckUpdatable( (FUCB *) vtid ) );
return ErrIsamUpdate( (PIB *) vsesid, (FUCB *) vtid, pb, cbMax, pcbActual );
}
ERR VTAPI ErrIsamGetCursorInfo(
JET_VSESID vsesid,
JET_VTID vtid,
void *pvResult,
unsigned long cbMax,
unsigned long InfoLevel )
{
PIB *ppib = (PIB *) vsesid;
FUCB *pfucb = (FUCB *) vtid;
ERR err = JET_errSuccess;
CSR *pcsr = PcsrCurrent( pfucb );
VS vs;
CheckPIB( ppib );
CheckFUCB( pfucb->ppib, pfucb );
if ( cbMax != 0 || InfoLevel != 0 )
return JET_errInvalidParameter;
if ( pcsr->csrstat != csrstatOnCurNode )
return JET_errNoCurrentRecord;
/* temporary tables are never visible to other sessions
/**/
if ( FFCBTemporaryTable( pfucb->u.pfcb ) )
return JET_errSuccess;
/* Check if this record is being updated by another cursor
/**/
Call( ErrDIRGet( pfucb ) );
if ( FNDVersion( *( pfucb->ssib.line.pb ) ) )
{
SRID srid;
NDGetBookmark( pfucb, &srid );
vs = VsVERCheck( pfucb, srid );
if ( vs == vsUncommittedByOther )
return JET_errSessionWriteConflict;
}
HandleError:
return err;
}