campo-sirio/cb/source/d4file.c
alex af15e0698b Codebase
git-svn-id: svn://10.65.10.50/trunk@4679 c028cbd2-c16b-5b4b-a496-9718f37d4682
1997-06-16 13:01:08 +00:00

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 */