af15e0698b
git-svn-id: svn://10.65.10.50/trunk@4679 c028cbd2-c16b-5b4b-a496-9718f37d4682
240 lines
6.7 KiB
C
Executable File
240 lines
6.7 KiB
C
Executable File
/* d4file.c (c)Copyright Sequiter Software Inc., 1988-1996. All rights reserved. */
|
|
|
|
#include "d4all.h"
|
|
#ifndef S4UNIX
|
|
#ifdef __TURBOC__
|
|
#pragma hdrstop
|
|
#endif /* __TUROBC__ */
|
|
#endif /* S4UNIX */
|
|
|
|
#ifndef S4CLIENT
|
|
/* fromDisk set to 1 if ensure that a disk read is done, instead of a buffer read */
|
|
int dfile4read( DATA4FILE *data, long recNum, char *ptr, int fromDisk )
|
|
{
|
|
#ifdef S4CLIENT
|
|
return dfile4goData( data, recNum, ptr, 1 ) ;
|
|
#else
|
|
unsigned len ;
|
|
|
|
#ifdef E4PARM_LOW
|
|
if ( data == 0 || recNum <= 0 || ptr == 0 )
|
|
return error4( 0, e4parm_null, E91102 ) ;
|
|
#endif
|
|
|
|
if ( error4code( data->c4 ) < 0 )
|
|
return e4codeBase ;
|
|
|
|
#ifndef S4OPTIMIZE_OFF
|
|
/* make sure read from disk unless file locked, etc. */
|
|
if ( fromDisk )
|
|
if ( data->file.doBuffer )
|
|
data->c4->opt.forceCurrent = 1 ;
|
|
#endif
|
|
len = file4read( &data->file, dfile4recordPosition( data, recNum ), ptr, data->recWidth ) ;
|
|
#ifndef S4OPTIMIZE_OFF
|
|
if ( fromDisk )
|
|
if ( data->file.doBuffer )
|
|
data->c4->opt.forceCurrent = 0 ;
|
|
#endif
|
|
|
|
if ( error4code( data->c4 ) < 0 )
|
|
return error4code( data->c4 ) ;
|
|
|
|
if ( len != data->recWidth )
|
|
return r4entry ;
|
|
|
|
return 0 ;
|
|
#endif
|
|
}
|
|
#endif /* S4CLIENT */
|
|
|
|
/* set serverId to -2 to get the actual count if possible for example,
|
|
b4leafInit needs to know how many may potentially exist */
|
|
#ifdef P4ARGS_USED
|
|
#pragma argsused
|
|
#endif
|
|
long S4FUNCTION dfile4recCount( DATA4FILE *data, const long serverId )
|
|
{
|
|
#ifdef S4CLIENT
|
|
int rc ;
|
|
CONNECTION4 *connection ;
|
|
CONNECTION4RECCOUNT_INFO_OUT *info ;
|
|
#else
|
|
unsigned len ;
|
|
#endif
|
|
S4LONG tmpCount ;
|
|
|
|
#ifdef E4PARM_HIGH
|
|
/* PARM_HIGH because called directly in S4OFF_MULTI case */
|
|
if ( data == 0 )
|
|
return error4( 0, e4parm_null, E91102 ) ;
|
|
#endif
|
|
|
|
if ( error4code( data->c4 ) < 0 )
|
|
return e4codeBase ;
|
|
|
|
/* client checks current count in d4recCount */
|
|
#ifndef S4CLIENT
|
|
if ( data->numRecs >= 0L )
|
|
{
|
|
#ifndef S4SINGLE
|
|
if ( serverId == -2L )
|
|
return data->numRecs ;
|
|
if ( dfile4lockTestAppend( data, 0L, serverId ) != 1 )
|
|
return data->minCount ;
|
|
else
|
|
#endif
|
|
return data->numRecs ;
|
|
}
|
|
#endif
|
|
|
|
#ifdef S4CLIENT
|
|
connection = data->connection ;
|
|
if ( connection == 0 )
|
|
return e4connection ;
|
|
|
|
connection4assign( connection, CON4RECCOUNT, 0, data->serverId ) ;
|
|
connection4send( connection ) ;
|
|
rc = connection4receive( connection ) ;
|
|
if ( rc < 0 )
|
|
return rc ;
|
|
rc = connection4status( connection ) ;
|
|
if ( rc != 0 )
|
|
return connection4error( connection, data->c4, rc, E91102 ) ;
|
|
|
|
if ( connection4len( connection ) != sizeof( CONNECTION4RECCOUNT_INFO_OUT ) )
|
|
return error4( data->c4, e4packetLen, E91102 ) ;
|
|
info = (CONNECTION4RECCOUNT_INFO_OUT *)connection4data( connection ) ;
|
|
tmpCount = info->recCount ;
|
|
if ( info->recCount < 0 )
|
|
return -1L ;
|
|
data->minCount = tmpCount ;
|
|
#ifndef S4SINGLE
|
|
if ( info->appendLocked == 1 )
|
|
#endif /* S4SINGLE */
|
|
data->numRecs = tmpCount ;
|
|
#else
|
|
#ifdef S464BIT
|
|
len = file4read( &data->file, 4L, &tmpCount, sizeof(S4LONG) ) ;
|
|
#ifdef S4BYTE_SWAP
|
|
tmpCount = x4reverseLong((void *)&tmpCount) ;
|
|
#endif
|
|
#else
|
|
len = file4read( &data->file, 4L, &tmpCount, sizeof( long ) ) ;
|
|
#ifdef S4BYTE_SWAP
|
|
tmpCount = x4reverseLong((void *)&tmpCount) ;
|
|
#endif
|
|
#endif
|
|
if ( tmpCount < 0L || len != 4 )
|
|
return -1L ;
|
|
|
|
#ifndef S4SINGLE
|
|
if ( dfile4lockTestAppend( data, 0L, 0L ) )
|
|
#endif /* S4SINGLE */
|
|
data->numRecs = tmpCount ;
|
|
|
|
/* this minCount is used as the actual record count in instances where
|
|
transactions are taking place and the append bytes are locked, and
|
|
data handles of other datafiles are performing the access */
|
|
data->minCount = tmpCount ; /* used for multi-user ensured sequencing */
|
|
#endif
|
|
|
|
return tmpCount ;
|
|
}
|
|
|
|
#ifndef S4INLINE
|
|
unsigned long dfile4recordPosition( DATA4FILE *data, const long rec )
|
|
{
|
|
#ifdef E4PARM_LOW
|
|
if ( data == 0 || rec <= 0L )
|
|
return error4( 0, e4parm, E91102 ) ;
|
|
#endif
|
|
|
|
return (unsigned long)data->headerLen + (unsigned long)data->recWidth * ( rec - 1 ) ;
|
|
}
|
|
|
|
unsigned int dfile4recWidth( DATA4FILE *data )
|
|
{
|
|
#ifdef E4PARM_LOW
|
|
if ( data == 0 )
|
|
return error4( 0, e4parm_null, E91102 ) ;
|
|
#endif
|
|
|
|
return (unsigned int)data->recWidth ;
|
|
}
|
|
#endif
|
|
|
|
S4CONST char *dfile4name( S4CONST DATA4FILE *data )
|
|
{
|
|
#ifdef E4PARM_LOW
|
|
if ( data == 0 )
|
|
{
|
|
error4( 0, e4parm_null, E93205 ) ;
|
|
return 0 ;
|
|
}
|
|
#endif
|
|
#ifdef S4CLIENT
|
|
return data->accessName ;
|
|
#else
|
|
return data->file.name ;
|
|
#endif
|
|
}
|
|
|
|
#ifndef S4CLIENT
|
|
#ifndef S4OFF_WRITE
|
|
int dfile4updateHeader( DATA4FILE *data, int doTimeStamp, int doCount )
|
|
{
|
|
long pos ;
|
|
unsigned len ;
|
|
|
|
if ( code4trans( data->c4 )->currentTranStatus == r4active || code4trans( data->c4 )->currentTranStatus == r4rollback ) /* delay to avoid append rollback problems */
|
|
return 0 ;
|
|
|
|
#ifdef E4PARM_LOW
|
|
if ( data == 0 )
|
|
return error4( 0, e4parm_null, E91102 ) ;
|
|
#endif
|
|
|
|
#ifdef E4ANALYZE
|
|
#ifndef S4SINGLE
|
|
#ifndef S4SERVER
|
|
/* note that the server doesn't need it locked since that is a data level, not
|
|
a data4file level lock for server --> can't make this check */
|
|
if ( doCount && ( dfile4lockTestAppend( data, 0, 0 ) == 0 ) )
|
|
return error4( data->c4, e4info, E83201 ) ;
|
|
#endif
|
|
#endif
|
|
#endif
|
|
|
|
pos = 0L ;
|
|
len = 4 + ( sizeof(S4LONG) ) + ( sizeof( short ) ) ;
|
|
if ( doTimeStamp )
|
|
data->doDate = 1 ;
|
|
else
|
|
{
|
|
pos += 4 ;
|
|
len -= 4 ;
|
|
}
|
|
|
|
if ( !doCount || data->numRecs < 0 )
|
|
len -= (sizeof( data->numRecs ) + sizeof( data->headerLen ) ) ;
|
|
|
|
#ifdef S4BYTE_SWAP
|
|
data->numRecs = x4reverseLong( (void *)&data->numRecs ) ;
|
|
data->headerLen = x4reverseShort( (void *)&data->headerLen ) ;
|
|
#endif
|
|
if ( file4write( &data->file, pos, (char *)&data->version + pos, len ) < 0 )
|
|
return -1 ;
|
|
#ifdef S4BYTE_SWAP
|
|
data->numRecs = x4reverseLong( (void *)&data->numRecs ) ;
|
|
data->headerLen = x4reverseShort( (void *)&data->headerLen ) ;
|
|
#endif
|
|
|
|
if ( doCount )
|
|
data->minCount = data->numRecs ;
|
|
data->fileChanged = 0 ;
|
|
return 0 ;
|
|
}
|
|
#endif
|
|
#endif /* S4OFF_WRITE */
|