/* d4go.c (c)Copyright Sequiter Software Inc., 1988-1996. All rights reserved. */ #include "d4all.h" #ifndef S4UNIX #ifdef __TURBOC__ #pragma hdrstop #endif #endif #ifdef S4CLIENT /* d4go, d4skip, d4seek, after complete, perform the record information transferral... */ int d4goVirtual( DATA4 *data, const long recNo, const int rc, const void *outVoid, void *connectionVoid ) { const CONNECTION4GO_INFO_OUT *out ; CONNECTION4 *connection ; CODE4 *c4 ; out = (CONNECTION4GO_INFO_OUT *)outVoid ; connection = (CONNECTION4 *)connectionVoid ; c4 = data->codeBase ; if ( rc == r4entry ) /* invalid record (beyond eof) */ { data->recNum = -1 ; memset( data->record, ' ', dfile4recWidth( data->dataFile ) ) ; if ( c4->errGo ) return error4describe( c4, e4read, E93101, d4alias( data ), 0, 0 ) ; } if ( rc > 0 ) /* eg. r4entry */ return rc ; if ( rc < 0 ) { data->recNum = -1 ; if ( c4->errGo ) connection4errorDescribe( connection, c4, rc, E93101, d4alias( data ), 0, 0 ) ; return rc ; } if ( out->recNo != recNo ) return error4( c4, e4info, E83101 ) ; /* now copy the data into the record */ memcpy( data->record, ((char *)out) + sizeof( CONNECTION4GO_INFO_OUT ), dfile4recWidth( data->dataFile ) ) ; data->recNum = recNo ; data->bofFlag = data->eofFlag = 0 ; if ( out->recordLocked == 1 ) { d4localLockSet( data, recNo ) ; memcpy( data->recordOld, data->record, dfile4recWidth( data->dataFile ) ) ; data->recNumOld = recNo ; #ifndef S4OFF_MULTI #ifndef S4OFF_MEMO data->memoValidated = 1 ; #endif #endif } return 0 ; } int S4FUNCTION d4go( DATA4 *data, const long recNo ) { int rc ; CONNECTION4 *connection ; CONNECTION4GO_INFO_IN info ; CODE4 *c4 ; #ifdef S4VBASIC if ( c4parm_check( data, 2, E93101 ) ) return -1 ; #endif #ifdef E4PARM_HIGH if ( data == 0 ) return error4( 0, e4parm_null, E93101 ) ; #endif c4 = data->codeBase ; #ifdef S4OFF_WRITE if ( error4code( c4 ) < 0 ) return e4codeBase ; #else rc = d4updateRecord( data, 0 ) ; /* returns -1 if error4code( codeBase ) < 0 */ if ( rc ) return rc ; #endif connection = data->dataFile->connection ; if ( connection == 0 ) return e4connection ; connection4assign( connection, CON4GO, data4clientId( data ), data4serverId( data ) ) ; info.recNo = recNo ; connection4addData( connection, &info, sizeof( CONNECTION4GO_INFO_IN ), 0 ) ; rc = connection4repeat( connection, -2, -1, -1, data ) ; if ( rc == r4locked ) return rc ; return d4goVirtual( data, recNo, rc, connection4data( connection ), connection ) ; } #else int S4FUNCTION d4go( DATA4 *data, const long recNo ) { int rc, fromDisk ; CODE4 *c4 ; #ifndef S4OFF_MULTI int didLock ; #endif #ifndef S4OFF_MEMO int i ; #endif #ifdef S4VBASIC if ( c4parm_check( data, 2, E93101 ) ) return -1 ; #endif #ifdef EPARM_HIGH if ( data == 0 ) return error4( 0, e4parm_null, E93101 ) ; #endif c4 = data->codeBase ; rc = 0 ; if ( error4code( c4 ) < 0 ) return e4codeBase ; #ifndef S4OFF_WRITE if ( data->recordChanged ) { rc = d4updateRecord( data, 0 ) ; if ( rc ) return rc ; } #ifndef S4OFF_MEMO else #endif #endif #ifndef S4OFF_MEMO if ( data->fieldsMemo != 0 ) for ( i = 0; i < data->dataFile->nFieldsMemo; i++ ) f4memoReset( data->fieldsMemo[i].field ) ; #endif if ( d4recCountLessEq( data, recNo ) == 0 ) /* past eof */ { data->recNum = -1 ; /* at an invalid position */ memset( data->record, ' ', data->dataFile->recWidth ) ; /* clear the record to avoid corruption */ #ifndef S4SERVER if ( c4->errGo ) return error4describe( c4, e4read, E91102, d4alias( data ), 0, 0 ) ; #endif return r4entry ; } fromDisk = 0 ; #ifndef S4OFF_MULTI didLock = 0 ; #ifdef S4SERVER if ( !dfile4lockTest( data->dataFile, data4clientId( data ), data4serverId(data ), recNo ) ) /* record not already locked */ #else if ( !d4lockTest( data, recNo ) ) /* record not already locked */ #endif { switch( code4unlockAuto( c4 ) ) { case LOCK4ALL : rc = code4unlockDo( tran4dataList( data->trans ) ) ; break ; case LOCK4DATA : rc = d4unlock( data ) ; break ; default: break ; } if ( rc < 0 ) return error4stack( c4, rc, E93101 ) ; if ( c4->readLock ) { #ifdef S4SERVER rc = dfile4lock( data->dataFile, data4clientId( data ), data4serverId( data ), recNo ) ; #else rc = d4lock( data, recNo ) ; #endif if ( rc ) return rc ; didLock = 1 ; } } #ifndef S4OFF_MEMO if ( !data->memoValidated ) #ifdef S4SERVER if ( dfile4lockTest( data->dataFile, data4clientId( data ), data4serverId( data ), recNo ) ) /* record not already locked */ #else #ifndef S4OFF_MULTI if ( d4lockTest( data, recNo ) ) /* record not already locked */ #endif #endif fromDisk = 1 ; #endif /* S4OFF_MEMO */ #endif rc = dfile4goData( data->dataFile, recNo, data->record, fromDisk ) ; if ( rc ) { data->recNum = -1 ; /* at an invalid position */ #ifndef S4OFF_MULTI if ( didLock == 1 ) #ifdef S4SERVER dfile4unlockRecord( data->dataFile, data4clientId( data ), data4serverId( data ), recNo ) ; #else d4unlockRecord( data, recNo ) ; #endif #endif return rc ; } else data->recNum = recNo ; data->bofFlag = data->eofFlag = 0 ; #ifndef S4OFF_MULTI #ifdef S4SERVER if ( dfile4lockTest( data->dataFile, data4clientId( data ), data4serverId( data ), recNo ) ) /* record not already locked */ #else if ( d4lockTest( data, recNo ) ) /* record not already locked */ #endif { #endif memcpy( data->recordOld, data->record, dfile4recWidth( data->dataFile ) ) ; data->recNumOld = data->recNum ; #ifndef S4OFF_MULTI #ifndef S4OFF_MEMO data->memoValidated = 1 ; #endif } #ifndef S4OFF_MEMO else data->memoValidated = 0 ; #endif #endif return 0 ; } /* fromDisk is set to true if a disk read is desired from the go */ #ifdef P4ARGS_USED #pragma argsused #endif int dfile4goData( DATA4FILE *data, long rec, void *record, int fromDisk ) { unsigned len ; CODE4 *cb ; #ifdef E4PARM_HIGH if ( data == 0 ) return error4( 0, e4parm_null, E91102 ) ; #endif cb = data->c4 ; if( error4code( cb ) < 0 ) return e4codeBase ; if ( rec <= 0 ) len = 0 ; else { #ifndef S4OFF_MULTI #ifndef S4OPTIMIZE_OFF if ( fromDisk == 1 ) /* if bufferred old, and only record is locked, read from disk */ if ( data->file.doBuffer && data->fileServerLock != 0 ) cb->opt.forceCurrent = 1 ; #endif #endif len = file4read( &data->file, dfile4recordPosition( data, rec ), record, data->recWidth ) ; #ifndef S4OFF_MULTI #ifndef S4OPTIMIZE_OFF if ( fromDisk == 1 ) cb->opt.forceCurrent = 0 ; #endif #endif if( error4code( cb ) < 0 ) return -1 ; } if ( len != data->recWidth ) { memset( record, ' ', data->recWidth ) ; /* clear the partially read record to avoid corruption */ #ifndef S4SERVER if ( cb->errGo ) return error4describe( cb, e4read, E91102, data->file.name, 0, 0 ) ; #endif return r4entry ; } return 0 ; } int d4goData( DATA4 *data, long rec ) { int rc ; rc = dfile4goData( data->dataFile, rec, data->record, 0 ) ; if ( rc != 0 ) data->recNum = -1 ; /* at an invalid position */ else data->recNum = rec ; return rc ; } #endif /* S4CLIENT */ int S4FUNCTION d4goEof( DATA4 *data ) { long count ; #ifndef S4OFF_WRITE int rc ; #endif #ifdef E4PARM_HIGH if ( data == 0 ) return error4( 0, e4parm_null, E93103 ) ; #endif if ( error4code( data->codeBase ) < 0 ) return e4codeBase ; #ifndef S4OFF_WRITE rc = d4updateRecord( data, 0 ) ; /* was 1 */ if ( rc ) return rc ; #endif count = d4recCount( data ) ; if ( count < 0 ) return -1 ; data->recNum = count + 1L ; data->eofFlag = 1 ; if ( data->recNum == 1 ) data->bofFlag = 1 ; memset( data->record, ' ', dfile4recWidth( data->dataFile ) ) ; return r4eof ; }